Root/package/madwifi/patches/407-new_athinfo.patch

1--- a/tools/ath_info.c
2+++ b/tools/ath_info.c
3@@ -16,78 +16,8 @@
4  * along with this program. If not, see <http://www.gnu.org/licenses/>.
5  */
6 
7-/* So here is how it works:
8- *
9- * First compile...
10- *
11- * gcc ath_info.c -o ath_info
12- *
13- * then find card's physical address
14- *
15- * lspci -v
16- *
17- * 02:02.0 Ethernet controller: Atheros Communications, Inc. AR5212 802.11abg NIC (rev 01)
18- * Subsystem: Fujitsu Limited. Unknown device 1234
19- * Flags: bus master, medium devsel, latency 168, IRQ 23
20- * Memory at c2000000 (32-bit, non-prefetchable) [size=64K]
21- * Capabilities: [44] Power Management version 2
22- *
23- * address here is 0xc2000000
24- *
25- * load madwifi-ng or madwifi-old if not already loaded (be sure the
26- * interface is down!)
27- *
28- * modprobe ath_pci
29- *
30- * OR
31- *
32- * call:
33- * setpci -s 02:02.0 command=0x41f cache_line_size=0x10
34- *
35- * to enable access to the PCI device.
36- *
37- * and we run the thing...
38- *
39- * ./ath_info 0xc2000000
40- *
41- * In order to change the regdomain to 0, call:
42- *
43- * ./ath_info -w 0xc2000000 regdomain 0
44- *
45- * to change any PCI ID value, say:
46- *
47- * ./ath_info -w 0xc2000000 <name> X
48- *
49- * with <name> ::= pci_dev_id | pci_vendor_id | pci_class |
50- * pci_subsys_dev_id | pci_subsys_vendor_id
51- *
52- * With newer chipsets (>= AR5004x, i.e. MAC >= AR5213), Atheros introduced
53- * write protection on the EEPROM. On a GIGABYTE GN-WI01HT you can set GPIO 4
54- * to low to be able to write the EEPROM. This depends highly on the PCB layout,
55- * so there may be different GPIO used.
56- * This program currently sets GPIO 4 to low for a MAC >= AR5213, but you can
57- * override this with the -g option:
58- *
59- * ./ath_info -g 5:0 -w 0xc2000000 regdomain X
60- *
61- * would set GPIO 5 to low (and wouldn't touch GPIO 4). -g can be given several times.
62- *
63- * The write function is currently not tested with 5210 devices.
64- *
65- * Use at your own risk, entering a false device address will have really
66- * nasty results!
67- *
68- * Writing wrong values to the PCI id fields may prevent the driver from
69- * detecting the card!
70- *
71- * Transmitting on illegal frequencies may violate state laws. Stick to the local
72- * regulations!
73- *
74- * DISCLAIMER:
75- * The authors are in no case responsible for damaged hardware or violation of
76- * local laws by operating modified hardware.
77- *
78- */
79+/* Try accepting 64-bit device address even with 32-bit userspace */
80+#define _FILE_OFFSET_BITS 64
81 
82 #include <stdio.h>
83 #include <stdlib.h>
84@@ -130,109 +60,103 @@ fprintf(stderr, "#ERR %s: " fmt "\n", __
85  */
86 #define AR5K_GPIODI 0x401c
87 
88-/*
89- * Common silicon revision/version values
90- */
91-enum ath5k_srev_type {
92- AR5K_VERSION_VER,
93- AR5K_VERSION_REV,
94- AR5K_VERSION_RAD,
95-};
96-
97 struct ath5k_srev_name {
98     const char *sr_name;
99- enum ath5k_srev_type sr_type;
100- u_int sr_val;
101+ u_int8_t sr_val;
102 };
103 
104-#define AR5K_SREV_UNKNOWN 0xffff
105-
106 /* Known MAC revision numbers */
107-#define AR5K_SREV_VER_AR5210 0x00
108-#define AR5K_SREV_VER_AR5311 0x10
109-#define AR5K_SREV_VER_AR5311A 0x20
110-#define AR5K_SREV_VER_AR5311B 0x30
111-#define AR5K_SREV_VER_AR5211 0x40
112-#define AR5K_SREV_VER_AR5212 0x50
113-#define AR5K_SREV_VER_AR5213 0x55
114-#define AR5K_SREV_VER_AR5213A 0x59
115-#define AR5K_SREV_VER_AR2424 0xa0
116-#define AR5K_SREV_VER_AR5424 0xa3
117-#define AR5K_SREV_VER_AR5413 0xa4
118-#define AR5K_SREV_VER_AR5414 0xa5
119-#define AR5K_SREV_VER_AR5416 0xc0
120-#define AR5K_SREV_VER_AR5418 0xca
121-#define AR5K_SREV_VER_AR2425 0xe0
122-
123-/* Known PHY revision nymbers */
124-#define AR5K_SREV_RAD_5110 0x00
125-#define AR5K_SREV_RAD_5111 0x10
126-#define AR5K_SREV_RAD_5111A 0x15
127-#define AR5K_SREV_RAD_2111 0x20
128-#define AR5K_SREV_RAD_5112 0x30
129-#define AR5K_SREV_RAD_5112A 0x35
130-#define AR5K_SREV_RAD_2112 0x40
131-#define AR5K_SREV_RAD_2112A 0x45
132-#define AR5K_SREV_RAD_SC1 0x63 /* Found on 5413/5414 */
133-#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424/5424 */
134-#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */
135-
136-static const struct ath5k_srev_name ath5k_srev_names[] = {
137- {"5210", AR5K_VERSION_VER, AR5K_SREV_VER_AR5210},
138- {"5311", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311},
139- {"5311A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311A},
140- {"5311B", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311B},
141- {"5211", AR5K_VERSION_VER, AR5K_SREV_VER_AR5211},
142- {"5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212},
143- {"5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213},
144- {"5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A},
145- {"2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424},
146- {"5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424},
147- {"5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413},
148- {"5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414},
149- {"5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416},
150- {"5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418},
151- {"2425", AR5K_VERSION_VER, AR5K_SREV_VER_AR2425},
152- {"xxxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN},
153- {"5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110},
154- {"5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111},
155- {"2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111},
156- {"5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112},
157- {"5112a", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A},
158- {"2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112},
159- {"2112a", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A},
160- {"SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1},
161- {"SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2},
162- {"5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133},
163- {"xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN},
164+#define AR5K_SREV_MAC_AR5210 0x00
165+#define AR5K_SREV_MAC_AR5311 0x10
166+#define AR5K_SREV_MAC_AR5311A 0x20
167+#define AR5K_SREV_MAC_AR5311B 0x30
168+#define AR5K_SREV_MAC_AR5211 0x40
169+#define AR5K_SREV_MAC_AR5212 0x50
170+#define AR5K_SREV_MAC_AR5213 0x55
171+#define AR5K_SREV_MAC_AR5213A 0x59
172+#define AR5K_SREV_MAC_AR5513 0x61
173+#define AR5K_SREV_MAC_AR2413 0x78
174+#define AR5K_SREV_MAC_AR2414 0x79
175+#define AR5K_SREV_MAC_AR2424 0xa0
176+#define AR5K_SREV_MAC_AR5424 0xa3
177+#define AR5K_SREV_MAC_AR5413 0xa4
178+#define AR5K_SREV_MAC_AR5414 0xa5
179+#define AR5K_SREV_MAC_AR5416 0xc0
180+#define AR5K_SREV_MAC_AR5418 0xca
181+#define AR5K_SREV_MAC_AR2425 0xe2
182+
183+/* Known PHY revision numbers */
184+#define AR5K_SREV_PHY_5110 0x00
185+#define AR5K_SREV_PHY_5111 0x10
186+#define AR5K_SREV_PHY_5111A 0x15
187+#define AR5K_SREV_PHY_2111 0x20
188+#define AR5K_SREV_PHY_5112 0x30
189+#define AR5K_SREV_PHY_5112A 0x35
190+#define AR5K_SREV_PHY_2112 0x40
191+#define AR5K_SREV_PHY_2112A 0x45
192+#define AR5K_SREV_PHY_SC0 0x56 /* Found on 2413/2414 */
193+#define AR5K_SREV_PHY_SC1 0x63 /* Found on 5413/5414 */
194+#define AR5K_SREV_PHY_SC2 0xa2 /* Found on 2424/5424 */
195+#define AR5K_SREV_PHY_5133 0xc0 /* MIMO found on 5418 */
196+
197+static const struct ath5k_srev_name ath5k_mac_names[] = {
198+ {"5210", AR5K_SREV_MAC_AR5210},
199+ {"5311", AR5K_SREV_MAC_AR5311},
200+ {"5311A", AR5K_SREV_MAC_AR5311A},
201+ {"5311B", AR5K_SREV_MAC_AR5311B},
202+ {"5211", AR5K_SREV_MAC_AR5211},
203+ {"5212", AR5K_SREV_MAC_AR5212},
204+ {"5213", AR5K_SREV_MAC_AR5213},
205+ {"5213A", AR5K_SREV_MAC_AR5213A},
206+ {"2413", AR5K_SREV_MAC_AR2413},
207+ {"2414", AR5K_SREV_MAC_AR2414},
208+ {"2424", AR5K_SREV_MAC_AR2424},
209+ {"5424", AR5K_SREV_MAC_AR5424},
210+ {"5413", AR5K_SREV_MAC_AR5413},
211+ {"5414", AR5K_SREV_MAC_AR5414},
212+ {"5416", AR5K_SREV_MAC_AR5416},
213+ {"5418", AR5K_SREV_MAC_AR5418},
214+ {"2425", AR5K_SREV_MAC_AR2425},
215+};
216+
217+static const struct ath5k_srev_name ath5k_phy_names[] = {
218+ {"5110", AR5K_SREV_PHY_5110},
219+ {"5111", AR5K_SREV_PHY_5111},
220+ {"2111", AR5K_SREV_PHY_2111},
221+ {"5112", AR5K_SREV_PHY_5112},
222+ {"5112A", AR5K_SREV_PHY_5112A},
223+ {"2112", AR5K_SREV_PHY_2112},
224+ {"2112A", AR5K_SREV_PHY_2112A},
225+ {"SChip", AR5K_SREV_PHY_SC0},
226+ {"SChip", AR5K_SREV_PHY_SC1},
227+ {"SChip", AR5K_SREV_PHY_SC2},
228+ {"5133", AR5K_SREV_PHY_5133},
229 };
230 
231 /*
232  * Silicon revision register
233  */
234 #define AR5K_SREV 0x4020 /* Register Address */
235-#define AR5K_SREV_REV 0x0000000f /* Mask for revision */
236-#define AR5K_SREV_REV_S 0
237-#define AR5K_SREV_VER 0x000000ff /* Mask for version */
238-#define AR5K_SREV_VER_S 4
239+#define AR5K_SREV_VER 0x000000f0 /* Mask for version */
240+#define AR5K_SREV_REV 0x000000ff /* Mask for revision */
241 
242 /*
243  * PHY chip revision register
244  */
245-#define AR5K_PHY_CHIP_ID 0x9818
246+#define AR5K_PHY_CHIP_ID 0x9818
247 
248 /*
249  * PHY register
250  */
251-#define AR5K_PHY_BASE 0x9800
252-#define AR5K_PHY(_n) (AR5K_PHY_BASE + ((_n) << 2))
253+#define AR5K_PHY_BASE 0x9800
254+#define AR5K_PHY(_n) (AR5K_PHY_BASE + ((_n) << 2))
255 #define AR5K_PHY_SHIFT_2GHZ 0x00004007
256 #define AR5K_PHY_SHIFT_5GHZ 0x00000007
257 
258 #define AR5K_RESET_CTL 0x4000 /* Register Address */
259 #define AR5K_RESET_CTL_PCU 0x00000001 /* Protocol Control Unit reset */
260 #define AR5K_RESET_CTL_DMA 0x00000002 /* DMA (Rx/Tx) reset -5210 only */
261-#define AR5K_RESET_CTL_BASEBAND 0x00000002 /* Baseband reset (5211/5212) */
262+#define AR5K_RESET_CTL_BASEBAND 0x00000002 /* Baseband reset (5211/5212) */
263 #define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband?) -5210 only */
264 #define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset -5210 only */
265 #define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */
266@@ -253,7 +177,7 @@ static const struct ath5k_srev_name ath5
267 #define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* not on 5210 */
268 
269 #define AR5K_PCICFG 0x4010 /* Register Address */
270-#define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */
271+#define AR5K_PCICFG_EEAE 0x00000001 /* EEPROM access enable [5210] */
272 #define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */
273 #define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */
274 #define AR5K_PCICFG_EESIZE_S 3
275@@ -264,26 +188,118 @@ static const struct ath5k_srev_name ath5
276 
277 #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status (5210) */
278 
279-#define AR5K_EEPROM_BASE 0x6000
280+#define AR5K_EEPROM_BASE 0x6000
281 
282-#define AR5K_EEPROM_MAGIC 0x003d /* Offset for EEPROM Magic number */
283+/*
284+ * Common AR5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
285+ */
286+#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
287 #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
288 #define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
289 #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
290 #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
291 
292+#define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */
293+#define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */
294+#define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */
295+#define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */
296+#define AR5K_EEPROM_PROTECT_WR_32_63 0x0008
297+#define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */
298+#define AR5K_EEPROM_PROTECT_WR_64_127 0x0020
299+#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */
300+#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
301+#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */
302+#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
303+#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */
304+#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
305+#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */
306+#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
307+#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */
308+#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
309+#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
310+#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
311+#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
312+#define AR5K_EEPROM_INFO_CKSUM 0xffff
313+#define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n))
314+
315+#define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */
316+#define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */
317+#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2GHz (AR5211_rfregs) */
318+#define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */
319+#define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
320+#define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */
321+#define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
322+#define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */
323+#define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */
324+#define AR5K_EEPROM_VERSION_4_3 0x4003
325+#define AR5K_EEPROM_VERSION_4_4 0x4004
326+#define AR5K_EEPROM_VERSION_4_5 0x4005
327+#define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */
328+#define AR5K_EEPROM_VERSION_4_7 0x3007
329+
330+#define AR5K_EEPROM_MODE_11A 0
331+#define AR5K_EEPROM_MODE_11B 1
332+#define AR5K_EEPROM_MODE_11G 2
333+
334+#define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */
335+#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
336+#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
337+#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
338+#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2GHz (?) */
339+#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */
340+#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7)
341+#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5GHz (?) */
342+#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
343+
344+/* Misc values available since EEPROM 4.0 */
345+#define AR5K_EEPROM_MISC0 AR5K_EEPROM_INFO(4)
346+#define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff)
347+#define AR5K_EEPROM_HDR_XR2_DIS(_v) (((_v) >> 12) & 0x1)
348+#define AR5K_EEPROM_HDR_XR5_DIS(_v) (((_v) >> 13) & 0x1)
349+#define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3)
350+#define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5)
351+#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
352+#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1)
353+
354+#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
355+#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
356+#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
357+#define AR5K_EEPROM_RFKILL_POLARITY_S 1
358+
359+/* Newer EEPROMs are using a different offset */
360+#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
361+ (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
362+
363+#define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
364+#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff))
365+#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff))
366+
367+/* calibration settings */
368+#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
369+#define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
370+#define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
371+#define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */
372+#define AR5K_EEPROM_CHANNELS_5GHZ(_v) AR5K_EEPROM_OFF(_v, 0x0100, 0x0150) /* List of calibrated 5GHz chans */
373+#define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0055, 0x0000)
374+#define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0065, 0x0010)
375+#define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0069, 0x0014)
376+
377+/* [3.1 - 3.3] */
378+#define AR5K_EEPROM_OBDB0_2GHZ 0x00ec
379+#define AR5K_EEPROM_OBDB1_2GHZ 0x00ed
380+
381 /*
382  * EEPROM data register
383  */
384 #define AR5K_EEPROM_DATA_5211 0x6004
385 #define AR5K_EEPROM_DATA_5210 0x6800
386-#define AR5K_EEPROM_DATA (mac_version == AR5K_SREV_VER_AR5210 ? \
387+#define AR5K_EEPROM_DATA (mac_version == AR5K_SREV_MAC_AR5210 ? \
388                 AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
389 
390 /*
391  * EEPROM command register
392  */
393-#define AR5K_EEPROM_CMD 0x6008 /* Register Addres */
394+#define AR5K_EEPROM_CMD 0x6008 /* Register Address */
395 #define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */
396 #define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */
397 #define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */
398@@ -291,43 +307,163 @@ static const struct ath5k_srev_name ath5
399 /*
400  * EEPROM status register
401  */
402-#define AR5K_EEPROM_STAT_5210 0x6c00 /* Register Address [5210] */
403-#define AR5K_EEPROM_STAT_5211 0x600c /* Register Address [5211+] */
404-#define AR5K_EEPROM_STATUS (mac_version == AR5K_SREV_VER_AR5210 ? \
405+#define AR5K_EEPROM_STAT_5210 0x6c00 /* Register Address [5210] */
406+#define AR5K_EEPROM_STAT_5211 0x600c /* Register Address [5211+] */
407+#define AR5K_EEPROM_STATUS (mac_version == AR5K_SREV_MAC_AR5210 ? \
408                 AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211)
409 #define AR5K_EEPROM_STAT_RDERR 0x00000001 /* EEPROM read failed */
410 #define AR5K_EEPROM_STAT_RDDONE 0x00000002 /* EEPROM read successful */
411 #define AR5K_EEPROM_STAT_WRERR 0x00000004 /* EEPROM write failed */
412 #define AR5K_EEPROM_STAT_WRDONE 0x00000008 /* EEPROM write successful */
413 
414-#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* Offset for EEPROM regulatory domain */
415-#define AR5K_EEPROM_INFO_BASE 0x00c0 /* Offset for EEPROM header */
416-#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
417-#define AR5K_EEPROM_INFO_CKSUM 0xffff
418-#define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n))
419-#define AR5K_EEPROM_MODE_11A 0
420-#define AR5K_EEPROM_MODE_11B 1
421-#define AR5K_EEPROM_MODE_11G 2
422+/*
423+ * EEPROM config register (?)
424+ */
425+#define AR5K_EEPROM_CFG 0x6010
426 
427-#define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1)
428+/* Some EEPROM defines */
429+#define AR5K_EEPROM_EEP_SCALE 100
430+#define AR5K_EEPROM_EEP_DELTA 10
431+#define AR5K_EEPROM_N_MODES 3
432+#define AR5K_EEPROM_N_5GHZ_CHAN 10
433+#define AR5K_EEPROM_N_2GHZ_CHAN 3
434+#define AR5K_EEPROM_MAX_CHAN 10
435+#define AR5K_EEPROM_N_PCDAC 11
436+#define AR5K_EEPROM_N_TEST_FREQ 8
437+#define AR5K_EEPROM_N_EDGES 8
438+#define AR5K_EEPROM_N_INTERCEPTS 11
439+#define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
440+#define AR5K_EEPROM_PCDAC_M 0x3f
441+#define AR5K_EEPROM_PCDAC_START 1
442+#define AR5K_EEPROM_PCDAC_STOP 63
443+#define AR5K_EEPROM_PCDAC_STEP 1
444+#define AR5K_EEPROM_NON_EDGE_M 0x40
445+#define AR5K_EEPROM_CHANNEL_POWER 8
446+#define AR5K_EEPROM_N_OBDB 4
447+#define AR5K_EEPROM_OBDB_DIS 0xffff
448+#define AR5K_EEPROM_CHANNEL_DIS 0xff
449+#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
450+#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32)
451+#define AR5K_EEPROM_MAX_CTLS 32
452+#define AR5K_EEPROM_N_XPD_PER_CHANNEL 4
453+#define AR5K_EEPROM_N_XPD0_POINTS 4
454+#define AR5K_EEPROM_N_XPD3_POINTS 3
455+#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35
456+#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55
457+#define AR5K_EEPROM_POWER_M 0x3f
458+#define AR5K_EEPROM_POWER_MIN 0
459+#define AR5K_EEPROM_POWER_MAX 3150
460+#define AR5K_EEPROM_POWER_STEP 50
461+#define AR5K_EEPROM_POWER_TABLE_SIZE 64
462+#define AR5K_EEPROM_N_POWER_LOC_11B 4
463+#define AR5K_EEPROM_N_POWER_LOC_11G 6
464+#define AR5K_EEPROM_I_GAIN 10
465+#define AR5K_EEPROM_CCK_OFDM_DELTA 15
466+#define AR5K_EEPROM_N_IQ_CAL 2
467+
468+enum ath5k_ant_setting {
469+ AR5K_ANT_VARIABLE = 0, /* variable by programming */
470+ AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */
471+ AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */
472+ AR5K_ANT_MAX = 3,
473+};
474 
475-#define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */
476-#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) /* Device has a support */
477-#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) /* Device has b support */
478-#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) /* Device has g support */
479-#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */
480-#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */
481-#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7)
482-#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */
483-#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
484+/* Per channel calibration data, used for power table setup */
485+struct ath5k_chan_pcal_info {
486+ u_int16_t freq; /* Frequency */
487+ /* Power levels in dBm * 4 units */
488+ int16_t pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
489+ int16_t pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
490+ /* PCDAC tables in dBm * 2 units */
491+ u_int16_t pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
492+ u_int16_t pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
493+ /* Max available power */
494+ u_int16_t max_pwr;
495+};
496 
497-/* Misc values available since EEPROM 4.0 */
498-#define AR5K_EEPROM_MISC0 0x00c4
499-#define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff)
500-#define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3)
501-#define AR5K_EEPROM_MISC1 0x00c5
502-#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
503-#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1)
504+/* Per rate calibration data for each mode, used for power table setup */
505+struct ath5k_rate_pcal_info {
506+ u_int16_t freq; /* Frequency */
507+ /* Power level for 6-24Mbit/s rates */
508+ u_int16_t target_power_6to24;
509+ /* Power level for 36Mbit rate */
510+ u_int16_t target_power_36;
511+ /* Power level for 48Mbit rate */
512+ u_int16_t target_power_48;
513+ /* Power level for 54Mbit rate */
514+ u_int16_t target_power_54;
515+};
516+
517+/* EEPROM calibration data */
518+struct ath5k_eeprom_info {
519+
520+ /* Header information */
521+ u_int16_t ee_magic;
522+ u_int16_t ee_protect;
523+ u_int16_t ee_regdomain;
524+ u_int16_t ee_version;
525+ u_int16_t ee_header;
526+ u_int16_t ee_ant_gain;
527+ u_int16_t ee_misc0;
528+ u_int16_t ee_misc1;
529+ u_int16_t ee_cck_ofdm_gain_delta;
530+ u_int16_t ee_cck_ofdm_power_delta;
531+ u_int16_t ee_scaled_cck_delta;
532+
533+ /* Used for tx thermal adjustment (eeprom_init, rfregs) */
534+ u_int16_t ee_tx_clip;
535+ u_int16_t ee_pwd_84;
536+ u_int16_t ee_pwd_90;
537+ u_int16_t ee_gain_select;
538+
539+ /* RF Calibration settings (reset, rfregs) */
540+ u_int16_t ee_i_cal[AR5K_EEPROM_N_MODES];
541+ u_int16_t ee_q_cal[AR5K_EEPROM_N_MODES];
542+ u_int16_t ee_fixed_bias[AR5K_EEPROM_N_MODES];
543+ u_int16_t ee_turbo_max_power[AR5K_EEPROM_N_MODES];
544+ u_int16_t ee_xr_power[AR5K_EEPROM_N_MODES];
545+ u_int16_t ee_switch_settling[AR5K_EEPROM_N_MODES];
546+ u_int16_t ee_ant_tx_rx[AR5K_EEPROM_N_MODES];
547+ u_int16_t ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
548+ u_int16_t ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
549+ u_int16_t ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
550+ u_int16_t ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
551+ u_int16_t ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
552+ u_int16_t ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
553+ u_int16_t ee_thr_62[AR5K_EEPROM_N_MODES];
554+ u_int16_t ee_xlna_gain[AR5K_EEPROM_N_MODES];
555+ u_int16_t ee_xpd[AR5K_EEPROM_N_MODES];
556+ u_int16_t ee_x_gain[AR5K_EEPROM_N_MODES];
557+ u_int16_t ee_i_gain[AR5K_EEPROM_N_MODES];
558+ u_int16_t ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
559+
560+ /* Power calibration data */
561+ u_int16_t ee_false_detect[AR5K_EEPROM_N_MODES];
562+ u_int16_t ee_cal_piers_a;
563+ struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
564+ u_int16_t ee_cal_piers_b;
565+ struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN];
566+ u_int16_t ee_cal_piers_g;
567+ struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN];
568+ /* Per rate target power levels */
569+ u_int16_t ee_rate_target_pwr_num_a;
570+ struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
571+ u_int16_t ee_rate_target_pwr_num_b;
572+ struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN];
573+ u_int16_t ee_rate_target_pwr_num_g;
574+ struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN];
575+
576+ /* Conformance test limits (Unused) */
577+ u_int16_t ee_ctls;
578+ u_int16_t ee_ctl[AR5K_EEPROM_MAX_CTLS];
579+
580+ /* Noise Floor Calibration settings */
581+ int16_t ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
582+ int8_t ee_adc_desired_size[AR5K_EEPROM_N_MODES];
583+ int8_t ee_pga_desired_size[AR5K_EEPROM_N_MODES];
584+
585+ u_int32_t ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
586+};
587 
588 /*
589  * Read data by masking
590@@ -350,7 +486,6 @@ static const struct ath5k_srev_name ath5
591     (*((volatile u_int32_t *)(mem + (_reg))) = (_val))
592 #endif
593 
594-
595 #define AR5K_REG_ENABLE_BITS(_reg, _flags) \
596     AR5K_REG_WRITE(_reg, AR5K_REG_READ(_reg) | (_flags))
597 
598@@ -359,7 +494,12 @@ static const struct ath5k_srev_name ath5
599 
600 #define AR5K_TUNE_REGISTER_TIMEOUT 20000
601 
602-/* names for eeprom fields */
603+#define AR5K_EEPROM_READ(_o, _v) do { \
604+ if ((ret = ath5k_hw_eeprom_read(mem, (_o), &(_v), mac_version)) != 0) \
605+ return (ret); \
606+} while (0)
607+
608+/* Names for EEPROM fields */
609 struct eeprom_entry {
610     const char *name;
611     int addr;
612@@ -375,8 +515,6 @@ static const struct eeprom_entry eeprom_
613     {"regdomain", AR5K_EEPROM_REG_DOMAIN},
614 };
615 
616-static const int eeprom_addr_len = sizeof(eeprom_addr) / sizeof(eeprom_addr[0]);
617-
618 static int force_write = 0;
619 static int verbose = 0;
620 
621@@ -398,8 +536,8 @@ static u_int32_t ath5k_hw_bitswap(u_int3
622 /*
623  * Get the PHY Chip revision
624  */
625-static u_int16_t
626-ath5k_hw_radio_revision(u_int16_t mac_version, void *mem, u_int8_t chip)
627+static u_int16_t ath5k_hw_radio_revision(u_int16_t mac_version, void *mem,
628+ u_int8_t chip)
629 {
630     int i;
631     u_int32_t srev;
632@@ -427,7 +565,7 @@ ath5k_hw_radio_revision(u_int16_t mac_ve
633     for (i = 0; i < 8; i++)
634         AR5K_REG_WRITE(AR5K_PHY(0x20), 0x00010000);
635 
636- if (mac_version == AR5K_SREV_VER_AR5210) {
637+ if (mac_version == AR5K_SREV_MAC_AR5210) {
638         srev = AR5K_REG_READ(AR5K_PHY(256) >> 28) & 0xf;
639 
640         ret = (u_int16_t)ath5k_hw_bitswap(srev, 4) + 1;
641@@ -447,9 +585,8 @@ ath5k_hw_radio_revision(u_int16_t mac_ve
642 /*
643  * Write to EEPROM
644  */
645-static int
646-ath5k_hw_eeprom_write(void *mem, u_int32_t offset, u_int16_t data,
647- u_int8_t mac_version)
648+static int ath5k_hw_eeprom_write(void *mem, u_int32_t offset, u_int16_t data,
649+ u_int8_t mac_version)
650 {
651     u_int32_t status, timeout;
652 
653@@ -457,7 +594,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
654      * Initialize EEPROM access
655      */
656 
657- if (mac_version == AR5K_SREV_VER_AR5210) {
658+ if (mac_version == AR5K_SREV_MAC_AR5210) {
659 
660         AR5K_REG_ENABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_EEAE);
661 
662@@ -466,7 +603,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
663 
664     } else {
665         /* not 5210 */
666- /* reset eeprom access */
667+ /* reset EEPROM access */
668         AR5K_REG_WRITE(AR5K_EEPROM_CMD, AR5K_EEPROM_CMD_RESET);
669         usleep(5);
670 
671@@ -484,7 +621,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
672         status = AR5K_REG_READ(AR5K_EEPROM_STATUS);
673         if (status & AR5K_EEPROM_STAT_WRDONE) {
674             if (status & AR5K_EEPROM_STAT_WRERR) {
675- err("eeprom write access to 0x%04x failed",
676+ err("EEPROM write access to 0x%04x failed",
677                     offset);
678                 return 1;
679             }
680@@ -499,16 +636,15 @@ ath5k_hw_eeprom_write(void *mem, u_int32
681 /*
682  * Read from EEPROM
683  */
684-static int
685-ath5k_hw_eeprom_read(void *mem, u_int32_t offset, u_int16_t *data,
686- u_int8_t mac_version)
687+static int ath5k_hw_eeprom_read(void *mem, u_int32_t offset, u_int16_t *data,
688+ u_int8_t mac_version)
689 {
690     u_int32_t status, timeout;
691 
692     /*
693      * Initialize EEPROM access
694      */
695- if (mac_version == AR5K_SREV_VER_AR5210) {
696+ if (mac_version == AR5K_SREV_MAC_AR5210) {
697         AR5K_REG_ENABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_EEAE);
698         (void)AR5K_REG_READ(AR5K_EEPROM_BASE + (4 * offset));
699     } else {
700@@ -531,50 +667,701 @@ ath5k_hw_eeprom_read(void *mem, u_int32_
701     return 1;
702 }
703 
704-static const char *ath5k_hw_get_part_name(enum ath5k_srev_type type,
705- u_int32_t val)
706+/*
707+ * Translate binary channel representation in EEPROM to frequency
708+ */
709+static u_int16_t ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee,
710+ u_int16_t bin, unsigned int mode)
711 {
712- const char *name = "xxxxx";
713- int i;
714+ u_int16_t val;
715 
716- for (i = 0; i < ARRAY_SIZE(ath5k_srev_names); i++) {
717- if (ath5k_srev_names[i].sr_type != type ||
718- ath5k_srev_names[i].sr_val == AR5K_SREV_UNKNOWN)
719- continue;
720- if ((val & 0xff) < ath5k_srev_names[i + 1].sr_val) {
721- name = ath5k_srev_names[i].sr_name;
722+ if (bin == AR5K_EEPROM_CHANNEL_DIS)
723+ return bin;
724+
725+ if (mode == AR5K_EEPROM_MODE_11A) {
726+ if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
727+ val = (5 * bin) + 4800;
728+ else
729+ val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
730+ (bin * 10) + 5100;
731+ } else {
732+ if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
733+ val = bin + 2300;
734+ else
735+ val = bin + 2400;
736+ }
737+
738+ return val;
739+}
740+
741+/*
742+ * Read antenna info from EEPROM
743+ */
744+static int ath5k_eeprom_read_ants(void *mem, u_int8_t mac_version,
745+ struct ath5k_eeprom_info *ee,
746+ u_int32_t *offset, unsigned int mode)
747+{
748+ u_int32_t o = *offset;
749+ u_int16_t val;
750+ int ret, i = 0;
751+
752+ AR5K_EEPROM_READ(o++, val);
753+ ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
754+ ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f;
755+ ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
756+
757+ AR5K_EEPROM_READ(o++, val);
758+ ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
759+ ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
760+ ee->ee_ant_control[mode][i++] = val & 0x3f;
761+
762+ AR5K_EEPROM_READ(o++, val);
763+ ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
764+ ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
765+ ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
766+
767+ AR5K_EEPROM_READ(o++, val);
768+ ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
769+ ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
770+ ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
771+ ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
772+
773+ AR5K_EEPROM_READ(o++, val);
774+ ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
775+ ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
776+ ee->ee_ant_control[mode][i++] = val & 0x3f;
777+
778+ /* Get antenna modes */
779+ ee->ee_antenna[mode][0] =
780+ (ee->ee_ant_control[mode][0] << 4) | 0x1;
781+ ee->ee_antenna[mode][AR5K_ANT_FIXED_A] =
782+ ee->ee_ant_control[mode][1] |
783+ (ee->ee_ant_control[mode][2] << 6) |
784+ (ee->ee_ant_control[mode][3] << 12) |
785+ (ee->ee_ant_control[mode][4] << 18) |
786+ (ee->ee_ant_control[mode][5] << 24);
787+ ee->ee_antenna[mode][AR5K_ANT_FIXED_B] =
788+ ee->ee_ant_control[mode][6] |
789+ (ee->ee_ant_control[mode][7] << 6) |
790+ (ee->ee_ant_control[mode][8] << 12) |
791+ (ee->ee_ant_control[mode][9] << 18) |
792+ (ee->ee_ant_control[mode][10] << 24);
793+
794+ /* return new offset */
795+ *offset = o;
796+
797+ return 0;
798+}
799+
800+/*
801+ * Read supported modes from EEPROM
802+ */
803+static int ath5k_eeprom_read_modes(void *mem, u_int8_t mac_version,
804+ struct ath5k_eeprom_info *ee,
805+ u_int32_t *offset, unsigned int mode)
806+{
807+ u_int32_t o = *offset;
808+ u_int16_t val;
809+ int ret;
810+
811+ AR5K_EEPROM_READ(o++, val);
812+ ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
813+ ee->ee_thr_62[mode] = val & 0xff;
814+
815+ if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2)
816+ ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
817+
818+ AR5K_EEPROM_READ(o++, val);
819+ ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
820+ ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
821+
822+ AR5K_EEPROM_READ(o++, val);
823+ ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
824+
825+ if ((val & 0xff) & 0x80)
826+ ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
827+ else
828+ ee->ee_noise_floor_thr[mode] = val & 0xff;
829+
830+ if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2)
831+ ee->ee_noise_floor_thr[mode] =
832+ mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
833+
834+ AR5K_EEPROM_READ(o++, val);
835+ ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
836+ ee->ee_x_gain[mode] = (val >> 1) & 0xf;
837+ ee->ee_xpd[mode] = val & 0x1;
838+
839+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
840+ ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
841+
842+ if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
843+ AR5K_EEPROM_READ(o++, val);
844+ ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
845+
846+ if (mode == AR5K_EEPROM_MODE_11A)
847+ ee->ee_xr_power[mode] = val & 0x3f;
848+ else {
849+ ee->ee_ob[mode][0] = val & 0x7;
850+ ee->ee_db[mode][0] = (val >> 3) & 0x7;
851+ }
852+ }
853+
854+ if (ee->ee_version < AR5K_EEPROM_VERSION_3_4) {
855+ ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
856+ ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
857+ } else {
858+ ee->ee_i_gain[mode] = (val >> 13) & 0x7;
859+
860+ AR5K_EEPROM_READ(o++, val);
861+ ee->ee_i_gain[mode] |= (val << 3) & 0x38;
862+
863+ if (mode == AR5K_EEPROM_MODE_11G)
864+ ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
865+ }
866+
867+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0 &&
868+ mode == AR5K_EEPROM_MODE_11A) {
869+ ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
870+ ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
871+ }
872+
873+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_6 &&
874+ mode == AR5K_EEPROM_MODE_11G)
875+ ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
876+
877+ /* return new offset */
878+ *offset = o;
879+
880+ return 0;
881+}
882+
883+/*
884+ * Read per channel calibration info from EEPROM
885+ * This doesn't work on 2112+ chips (EEPROM versions >= 4.6),
886+ * I only tested it on 5213 + 5112. This is still work in progress...
887+ *
888+ * This info is used to calibrate the baseband power table. Imagine
889+ * that for each channel there is a power curve that's hw specific
890+ * (depends on amplifier) and we try to "correct" this curve using offests
891+ * we pass on to phy chip (baseband -> before amplifier) so that it can
892+ * use acurate power values when setting tx power (takes amplifier's performance
893+ * on each channel into account).
894+ *
895+ * EEPROM provides us with the offsets for some pre-calibrated channels
896+ * and we have to scale (to create the full table for these channels) and
897+ * interpolate (in order to create the table for any channel).
898+ */
899+static int ath5k_eeprom_read_pcal_info(void *mem, u_int8_t mac_version,
900+ struct ath5k_eeprom_info *ee,
901+ u_int32_t *offset, unsigned int mode)
902+{
903+ u_int32_t o = *offset;
904+ unsigned int i, c;
905+ int ret;
906+ u_int16_t val;
907+ struct ath5k_chan_pcal_info *chan_pcal_info;
908+ u_int16_t cal_piers;
909+
910+ switch (mode) {
911+ case AR5K_EEPROM_MODE_11A:
912+ chan_pcal_info = ee->ee_pwr_cal_a;
913+ cal_piers = ee->ee_cal_piers_a;
914+ break;
915+ case AR5K_EEPROM_MODE_11B:
916+ chan_pcal_info = ee->ee_pwr_cal_b;
917+ cal_piers = ee->ee_cal_piers_b;
918+ break;
919+ case AR5K_EEPROM_MODE_11G:
920+ chan_pcal_info = ee->ee_pwr_cal_g;
921+ cal_piers = ee->ee_cal_piers_g;
922+ break;
923+ default:
924+ return -EINVAL;
925+ }
926+
927+ for (i = 0; i < cal_piers; i++) {
928+ /* Power values in dBm * 4 */
929+ for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
930+ AR5K_EEPROM_READ(o++, val);
931+ chan_pcal_info[i].pwr_x0[c] = (val & 0xff);
932+ chan_pcal_info[i].pwr_x0[++c] = ((val >> 8) & 0xff);
933+ }
934+
935+ /* PCDAC steps (dBm * 2) */
936+ AR5K_EEPROM_READ(o++, val);
937+ chan_pcal_info[i].pcdac_x0[1] = (val & 0x1f);
938+ chan_pcal_info[i].pcdac_x0[2] = ((val >> 5) & 0x1f);
939+ chan_pcal_info[i].pcdac_x0[3] = ((val >> 10) & 0x1f);
940+
941+ /* No idea what these power levels are for (4 xpds ?)
942+ I got zeroes on my card and the EEPROM info
943+ dumps we found on the net also have weird values */
944+ AR5K_EEPROM_READ(o++, val);
945+ chan_pcal_info[i].pwr_x3[0] = (val & 0xff);
946+ chan_pcal_info[i].pwr_x3[1] = ((val >> 8) & 0xff);
947+
948+ AR5K_EEPROM_READ(o++, val);
949+ chan_pcal_info[i].pwr_x3[2] = (val & 0xff);
950+ /* It's weird but they put it here, that's the
951+ PCDAC starting step */
952+ chan_pcal_info[i].pcdac_x0[0] = ((val >> 8) & 0xff);
953+
954+ /* Static values seen on EEPROM info dumps */
955+ chan_pcal_info[i].pcdac_x3[0] = 20;
956+ chan_pcal_info[i].pcdac_x3[1] = 35;
957+ chan_pcal_info[i].pcdac_x3[2] = 63;
958+
959+ /* Last xpd0 power level is also channel maximum */
960+ chan_pcal_info[i].max_pwr = chan_pcal_info[i].pwr_x0[3];
961+
962+ /* Recreate pcdac_x0 table for this channel using pcdac steps */
963+ chan_pcal_info[i].pcdac_x0[1] += chan_pcal_info[i].pcdac_x0[0];
964+ chan_pcal_info[i].pcdac_x0[2] += chan_pcal_info[i].pcdac_x0[1];
965+ chan_pcal_info[i].pcdac_x0[3] += chan_pcal_info[i].pcdac_x0[2];
966+ }
967+
968+ /* return new offset */
969+ (*offset) = o;
970+
971+ return 0;
972+}
973+
974+/*
975+ * Read per rate target power (this is the maximum tx power
976+ * supported by the card). This info is used when setting
977+ * tx power, no matter the channel.
978+ *
979+ * This also works for v5 EEPROMs.
980+ */
981+static int ath5k_eeprom_read_target_rate_pwr_info(void *mem,
982+ u_int8_t mac_version,
983+ struct ath5k_eeprom_info *ee,
984+ u_int32_t *offset,
985+ unsigned int mode)
986+{
987+ u_int32_t o = *offset;
988+ u_int16_t val;
989+ struct ath5k_rate_pcal_info *rate_pcal_info;
990+ u_int16_t *rate_target_pwr_num;
991+ int ret, i;
992+
993+ switch (mode) {
994+ case AR5K_EEPROM_MODE_11A:
995+ rate_pcal_info = ee->ee_rate_tpwr_a;
996+ ee->ee_rate_target_pwr_num_a = AR5K_EEPROM_N_5GHZ_CHAN;
997+ rate_target_pwr_num = &ee->ee_rate_target_pwr_num_a;
998+ break;
999+ case AR5K_EEPROM_MODE_11B:
1000+ rate_pcal_info = ee->ee_rate_tpwr_b;
1001+ ee->ee_rate_target_pwr_num_b = 2; /* 3rd is g mode'ss 1st */
1002+ rate_target_pwr_num = &ee->ee_rate_target_pwr_num_b;
1003+ break;
1004+ case AR5K_EEPROM_MODE_11G:
1005+ rate_pcal_info = ee->ee_rate_tpwr_g;
1006+ ee->ee_rate_target_pwr_num_g = AR5K_EEPROM_N_2GHZ_CHAN;
1007+ rate_target_pwr_num = &ee->ee_rate_target_pwr_num_g;
1008+ break;
1009+ default:
1010+ return -EINVAL;
1011+ }
1012+
1013+ /* Different freq mask for older eeproms (<= v3.2) */
1014+ if(ee->ee_version <= 0x3002){
1015+ for (i = 0; i < (*rate_target_pwr_num); i++) {
1016+ AR5K_EEPROM_READ(o++, val);
1017+ rate_pcal_info[i].freq =
1018+ ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
1019+
1020+ rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
1021+ rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
1022+
1023+ AR5K_EEPROM_READ(o++, val);
1024+
1025+ if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1026+ val == 0) {
1027+ (*rate_target_pwr_num) = i;
1028+ break;
1029+ }
1030+
1031+ rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
1032+ rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
1033+ rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
1034+ }
1035+ } else {
1036+ for (i = 0; i < (*rate_target_pwr_num); i++) {
1037+ AR5K_EEPROM_READ(o++, val);
1038+ rate_pcal_info[i].freq =
1039+ ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
1040+
1041+ rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
1042+ rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
1043+
1044+ AR5K_EEPROM_READ(o++, val);
1045+
1046+ if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1047+ val == 0) {
1048+ (*rate_target_pwr_num) = i;
1049+ break;
1050+ }
1051+
1052+ rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
1053+ rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
1054+ rate_pcal_info[i].target_power_54 = (val & 0x3f);
1055+ }
1056+ }
1057+ /* return new offset */
1058+ (*offset) = o;
1059+
1060+ return 0;
1061+}
1062+
1063+/*
1064+ * Initialize EEPROM & capabilities data
1065+ */
1066+static int ath5k_eeprom_init(void *mem, u_int8_t mac_version,
1067+ struct ath5k_eeprom_info *ee)
1068+{
1069+ unsigned int mode, i;
1070+ int ret;
1071+ u_int32_t offset;
1072+ u_int16_t val;
1073+
1074+ /* Initial TX thermal adjustment values */
1075+ ee->ee_tx_clip = 4;
1076+ ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
1077+ ee->ee_gain_select = 1;
1078+
1079+ /*
1080+ * Read values from EEPROM and store them in the capability structure
1081+ */
1082+ AR5K_EEPROM_READ(AR5K_EEPROM_MAGIC, ee->ee_magic);
1083+ AR5K_EEPROM_READ(AR5K_EEPROM_PROTECT, ee->ee_protect);
1084+ AR5K_EEPROM_READ(AR5K_EEPROM_REG_DOMAIN, ee->ee_regdomain);
1085+ AR5K_EEPROM_READ(AR5K_EEPROM_VERSION, ee->ee_version);
1086+ AR5K_EEPROM_READ(AR5K_EEPROM_HDR, ee->ee_header);
1087+
1088+ /* Return if we have an old EEPROM */
1089+ if (ee->ee_version < AR5K_EEPROM_VERSION_3_0)
1090+ return 0;
1091+
1092+#ifdef notyet
1093+ /*
1094+ * Validate the checksum of the EEPROM date. There are some
1095+ * devices with invalid EEPROMs.
1096+ */
1097+ for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
1098+ AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
1099+ cksum ^= val;
1100+ }
1101+ if (cksum != AR5K_EEPROM_INFO_CKSUM) {
1102+ AR5K_PRINTF("Invalid EEPROM checksum 0x%04x\n", cksum);
1103+ return -EIO;
1104+ }
1105+#endif
1106+
1107+ AR5K_EEPROM_READ(AR5K_EEPROM_ANT_GAIN(ee->ee_version), ee->ee_ant_gain);
1108+
1109+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
1110+ AR5K_EEPROM_READ(AR5K_EEPROM_MISC0, ee->ee_misc0);
1111+ AR5K_EEPROM_READ(AR5K_EEPROM_MISC1, ee->ee_misc1);
1112+ }
1113+
1114+ if (ee->ee_version < AR5K_EEPROM_VERSION_3_3) {
1115+ AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
1116+ ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
1117+ ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
1118+
1119+ AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
1120+ ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
1121+ ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
1122+ }
1123+
1124+ /*
1125+ * Get conformance test limit values
1126+ */
1127+ offset = AR5K_EEPROM_CTL(ee->ee_version);
1128+ ee->ee_ctls = 0;
1129+
1130+ for (i = 0; i < AR5K_EEPROM_N_CTLS(ee->ee_version); i++) {
1131+ AR5K_EEPROM_READ(offset++, val);
1132+
1133+ if (((val >> 8) & 0xff) == 0)
1134+ break;
1135+
1136+ ee->ee_ctl[i] = (val >> 8) & 0xff;
1137+ ee->ee_ctls++;
1138+
1139+ if ((val & 0xff) == 0)
1140             break;
1141+
1142+ ee->ee_ctl[i + 1] = val & 0xff;
1143+ ee->ee_ctls++;
1144+ }
1145+
1146+ /*
1147+ * Get values for 802.11a (5GHz)
1148+ */
1149+ mode = AR5K_EEPROM_MODE_11A;
1150+
1151+ ee->ee_turbo_max_power[mode] =
1152+ AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
1153+
1154+ offset = AR5K_EEPROM_MODES_11A(ee->ee_version);
1155+
1156+ ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
1157+ if (ret)
1158+ return ret;
1159+
1160+ AR5K_EEPROM_READ(offset++, val);
1161+ ee->ee_adc_desired_size[mode] = (int8_t)((val >> 8) & 0xff);
1162+ ee->ee_ob[mode][3] = (val >> 5) & 0x7;
1163+ ee->ee_db[mode][3] = (val >> 2) & 0x7;
1164+ ee->ee_ob[mode][2] = (val << 1) & 0x7;
1165+
1166+ AR5K_EEPROM_READ(offset++, val);
1167+ ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
1168+ ee->ee_db[mode][2] = (val >> 12) & 0x7;
1169+ ee->ee_ob[mode][1] = (val >> 9) & 0x7;
1170+ ee->ee_db[mode][1] = (val >> 6) & 0x7;
1171+ ee->ee_ob[mode][0] = (val >> 3) & 0x7;
1172+ ee->ee_db[mode][0] = val & 0x7;
1173+
1174+ ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
1175+ if (ret)
1176+ return ret;
1177+
1178+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1) {
1179+ AR5K_EEPROM_READ(offset++, val);
1180+ ee->ee_margin_tx_rx[mode] = val & 0x3f;
1181+ }
1182+
1183+ /*
1184+ * Get values for 802.11b (2.4GHz)
1185+ */
1186+ mode = AR5K_EEPROM_MODE_11B;
1187+ offset = AR5K_EEPROM_MODES_11B(ee->ee_version);
1188+
1189+ ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
1190+ if (ret)
1191+ return ret;
1192+
1193+ AR5K_EEPROM_READ(offset++, val);
1194+ ee->ee_adc_desired_size[mode] = (int8_t)((val >> 8) & 0xff);
1195+ ee->ee_ob[mode][1] = (val >> 4) & 0x7;
1196+ ee->ee_db[mode][1] = val & 0x7;
1197+
1198+ ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
1199+ if (ret)
1200+ return ret;
1201+
1202+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
1203+ AR5K_EEPROM_READ(offset++, val);
1204+
1205+ ee->ee_cal_piers_b = 0;
1206+
1207+ ee->ee_pwr_cal_b[0].freq =
1208+ ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
1209+ if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
1210+ ee->ee_cal_piers_b++;
1211+
1212+ ee->ee_pwr_cal_b[1].freq =
1213+ ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
1214+ if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
1215+ ee->ee_cal_piers_b++;
1216+
1217+ AR5K_EEPROM_READ(offset++, val);
1218+ ee->ee_pwr_cal_b[2].freq =
1219+ ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
1220+ if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
1221+ ee->ee_cal_piers_b++;
1222+ }
1223+
1224+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1)
1225+ ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
1226+
1227+ /*
1228+ * Get values for 802.11g (2.4GHz)
1229+ */
1230+ mode = AR5K_EEPROM_MODE_11G;
1231+ offset = AR5K_EEPROM_MODES_11G(ee->ee_version);
1232+
1233+ ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
1234+ if (ret)
1235+ return ret;
1236+
1237+ AR5K_EEPROM_READ(offset++, val);
1238+ ee->ee_adc_desired_size[mode] = (signed short int)((val >> 8) & 0xff);
1239+ ee->ee_ob[mode][1] = (val >> 4) & 0x7;
1240+ ee->ee_db[mode][1] = val & 0x7;
1241+
1242+ ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
1243+ if (ret)
1244+ return ret;
1245+
1246+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
1247+ AR5K_EEPROM_READ(offset++, val);
1248+
1249+ ee->ee_cal_piers_g = 0;
1250+
1251+ ee->ee_pwr_cal_g[0].freq =
1252+ ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
1253+ if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
1254+ ee->ee_cal_piers_g++;
1255+
1256+ ee->ee_pwr_cal_g[1].freq =
1257+ ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
1258+ if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
1259+ ee->ee_cal_piers_g++;
1260+
1261+ AR5K_EEPROM_READ(offset++, val);
1262+ ee->ee_turbo_max_power[mode] = val & 0x7f;
1263+ ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
1264+
1265+ AR5K_EEPROM_READ(offset++, val);
1266+ ee->ee_pwr_cal_g[2].freq =
1267+ ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
1268+ if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
1269+ ee->ee_cal_piers_g++;
1270+
1271+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1)
1272+ ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
1273+
1274+ AR5K_EEPROM_READ(offset++, val);
1275+ ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1276+ ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
1277+
1278+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_2) {
1279+ AR5K_EEPROM_READ(offset++, val);
1280+ ee->ee_cck_ofdm_gain_delta = val & 0xff;
1281         }
1282     }
1283 
1284- return (name);
1285+ /*
1286+ * Read 5GHz EEPROM channels
1287+ */
1288+ offset = AR5K_EEPROM_CHANNELS_5GHZ(ee->ee_version);
1289+ ee->ee_cal_piers_a = 0;
1290+ for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
1291+ AR5K_EEPROM_READ(offset++, val);
1292+
1293+ if ((val & 0xff) == 0)
1294+ break;
1295+
1296+ ee->ee_pwr_cal_a[i].freq =
1297+ ath5k_eeprom_bin2freq(ee, val & 0xff, AR5K_EEPROM_MODE_11A);
1298+ ee->ee_cal_piers_a++;
1299+
1300+ if (((val >> 8) & 0xff) == 0)
1301+ break;
1302+
1303+ ee->ee_pwr_cal_a[++i].freq =
1304+ ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, AR5K_EEPROM_MODE_11A);
1305+ ee->ee_cal_piers_a++;
1306+
1307+ }
1308+
1309+ /*
1310+ * Read power calibration info
1311+ */
1312+ mode = AR5K_EEPROM_MODE_11A;
1313+ ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
1314+ if (ret)
1315+ return ret;
1316+
1317+ mode = AR5K_EEPROM_MODE_11B;
1318+ ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
1319+ if (ret)
1320+ return ret;
1321+
1322+ mode = AR5K_EEPROM_MODE_11G;
1323+ ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
1324+ if (ret)
1325+ return ret;
1326+
1327+
1328+ /*
1329+ * Read per rate target power info
1330+ */
1331+ offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
1332+ mode = AR5K_EEPROM_MODE_11A;
1333+ ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
1334+ if (ret)
1335+ return ret;
1336+
1337+ offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
1338+ mode = AR5K_EEPROM_MODE_11B;
1339+ ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
1340+ if (ret)
1341+ return ret;
1342+
1343+ offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
1344+ mode = AR5K_EEPROM_MODE_11G;
1345+ ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
1346+ if (ret)
1347+ return ret;
1348+
1349+ return 0;
1350+}
1351+
1352+static const char *ath5k_hw_get_mac_name(u_int8_t val)
1353+{
1354+ static char name[16];
1355+ unsigned int i;
1356+
1357+ for (i = 0; i < ARRAY_SIZE(ath5k_mac_names); i++) {
1358+ if (val <= ath5k_mac_names[i].sr_val)
1359+ break;
1360+ }
1361+
1362+ if (val == ath5k_mac_names[i].sr_val)
1363+ return ath5k_mac_names[i].sr_name;
1364+
1365+ snprintf(name, sizeof(name), "%s+", ath5k_mac_names[i - 1].sr_name);
1366+ return name;
1367+}
1368+
1369+static const char *ath5k_hw_get_phy_name(u_int8_t val)
1370+{
1371+ const char *name = "?????";
1372+ unsigned int i;
1373+
1374+ for (i = 0; i < ARRAY_SIZE(ath5k_phy_names); i++) {
1375+ if (val < ath5k_phy_names[i + 1].sr_val) {
1376+ name = ath5k_phy_names[i].sr_name;
1377+ break;
1378+ }
1379+ }
1380+
1381+ return name;
1382 }
1383 
1384 /* returns -1 on unknown name */
1385 static int eeprom_name2addr(const char *name)
1386 {
1387- int i;
1388+ unsigned int i;
1389+
1390     if (!name || !name[0])
1391         return -1;
1392- for (i = 0; i < eeprom_addr_len; i++)
1393+ for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
1394         if (!strcmp(name, eeprom_addr[i].name))
1395             return eeprom_addr[i].addr;
1396     return -1;
1397-} /* eeprom_name2addr */
1398+}
1399 
1400 /* returns "<unknown>" on unknown address */
1401 static const char *eeprom_addr2name(int addr)
1402 {
1403- int i;
1404- for (i = 0; i < eeprom_addr_len; i++)
1405+ unsigned int i;
1406+
1407+ for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
1408         if (eeprom_addr[i].addr == addr)
1409             return eeprom_addr[i].name;
1410     return "<unknown>";
1411-} /* eeprom_addr2name */
1412+}
1413 
1414-static int
1415-do_write_pairs(int anr, int argc, char **argv, unsigned char *mem,
1416- int mac_version)
1417+static int do_write_pairs(int anr, int argc, char **argv, unsigned char *mem,
1418+ int mac_version)
1419 {
1420 #define MAX_NR_WRITES 16
1421     struct {
1422@@ -635,7 +1422,7 @@ do_write_pairs(int anr, int argc, char *
1423         }
1424         anr++;
1425         i++;
1426- } /* while (anr < (argc-1)) */
1427+ }
1428 
1429     if (!(wr_ops_len = i)) {
1430         err("no (addr,val) pairs given");
1431@@ -702,20 +1489,22 @@ do_write_pairs(int anr, int argc, char *
1432     }
1433 
1434     return errors ? 11 : 0;
1435-} /* do_write_pairs */
1436+}
1437 
1438 static void usage(const char *n)
1439 {
1440- int i;
1441+ unsigned int i;
1442 
1443- fprintf(stderr, "%s [-w [-g N:M]] [-v] [-f] [-d] <base_address> "
1444+ fprintf(stderr, "%s [-w [-g N:M]] [-v] [-f] [-d] [-R addr] [-W addr val] <base_address> "
1445         "[<name1> <val1> [<name2> <val2> ...]]\n\n", n);
1446     fprintf(stderr,
1447         "-w write values into EEPROM\n"
1448         "-g N:M set GPIO N to level M (only used with -w)\n"
1449         "-v verbose output\n"
1450         "-f force; suppress question before writing\n"
1451- "-d dump eeprom (file 'ath-eeprom-dump.bin' and screen)\n"
1452+ "-d dump EEPROM (file 'ath-eeprom-dump.bin' and screen)\n"
1453+ "-R <addr> read register at <addr> (hex)\n"
1454+ "-W <addr> <val> write <val> (hex) into register at <addr> (hex)\n"
1455         "<base_address> device base address (see lspci output)\n\n");
1456 
1457     fprintf(stderr,
1458@@ -725,8 +1514,8 @@ static void usage(const char *n)
1459         " %s -w <base_address> regdomain N\n\n"
1460         "- set a PCI id field to value N:\n"
1461         " %s -w <base_address> <field> N\n"
1462- " where <field> is on of:\n ", n, n, n);
1463- for (i = 0; i < eeprom_addr_len; i++)
1464+ " where <field> is one of:\n ", n, n, n);
1465+ for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
1466         fprintf(stderr, " %s", eeprom_addr[i].name);
1467     fprintf(stderr, "\n\n");
1468     fprintf(stderr,
1469@@ -739,19 +1528,457 @@ static void usage(const char *n)
1470         "unlawful radio transmissions!\n\n");
1471 }
1472 
1473+static void dump_capabilities(struct ath5k_eeprom_info *ee)
1474+{
1475+ u_int8_t has_a, has_b, has_g, has_rfkill, turbog_dis, turboa_dis;
1476+ u_int8_t xr2_dis, xr5_dis, has_crystal;
1477+
1478+ has_a = AR5K_EEPROM_HDR_11A(ee->ee_header);
1479+ has_b = AR5K_EEPROM_HDR_11B(ee->ee_header);
1480+ has_g = AR5K_EEPROM_HDR_11G(ee->ee_header);
1481+ has_rfkill = AR5K_EEPROM_HDR_RFKILL(ee->ee_header);
1482+ has_crystal = AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1);
1483+ turbog_dis = AR5K_EEPROM_HDR_T_2GHZ_DIS(ee->ee_header);
1484+ turboa_dis = AR5K_EEPROM_HDR_T_5GHZ_DIS(ee->ee_header);
1485+ xr2_dis = AR5K_EEPROM_HDR_XR2_DIS(ee->ee_misc0);
1486+ xr5_dis = AR5K_EEPROM_HDR_XR5_DIS(ee->ee_misc0);
1487+
1488+ printf("|================= Capabilities ================|\n");
1489+
1490+ printf("| 802.11a Support: ");
1491+ if (has_a)
1492+ printf(" yes |");
1493+ else
1494+ printf(" no |");
1495+
1496+ printf(" Turbo-A disabled:");
1497+ if (turboa_dis)
1498+ printf(" yes |\n");
1499+ else
1500+ printf(" no |\n");
1501+
1502+ printf("| 802.11b Support: ");
1503+ if (has_b)
1504+ printf(" yes |");
1505+ else
1506+ printf(" no |");
1507+
1508+ printf(" Turbo-G disabled:");
1509+ if (turbog_dis)
1510+ printf(" yes |\n");
1511+ else
1512+ printf(" no |\n");
1513+
1514+ printf("| 802.11g Support: ");
1515+ if (has_g)
1516+ printf(" yes |");
1517+ else
1518+ printf(" no |");
1519+
1520+ printf(" 2GHz XR disabled:");
1521+ if (xr2_dis)
1522+ printf(" yes |\n");
1523+ else
1524+ printf(" no |\n");
1525+
1526+ printf("| RFKill Support: ");
1527+ if (has_rfkill)
1528+ printf(" yes |");
1529+ else
1530+ printf(" no |");
1531+
1532+ printf(" 5GHz XR disabled:");
1533+ if (xr5_dis)
1534+ printf(" yes |\n");
1535+ else
1536+ printf(" no |\n");
1537+
1538+ if (has_crystal != 2) {
1539+ printf("| 32kHz Crystal: ");
1540+ if (has_crystal)
1541+ printf(" yes |");
1542+ else
1543+ printf(" no |");
1544+
1545+ printf(" |\n");
1546+ }
1547+
1548+ printf("\\===============================================/\n");
1549+}
1550+
1551+static void dump_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
1552+{
1553+ int i;
1554+
1555+ printf("|=========================================================|\n");
1556+ printf("| I power: 0x%02x |", ee->ee_i_cal[mode]);
1557+ printf(" Q power: 0x%02x |\n", ee->ee_q_cal[mode]);
1558+ printf("| Use fixed bias: 0x%02x |", ee->ee_fixed_bias[mode]);
1559+ printf(" Max turbo power: 0x%02x |\n", ee->ee_turbo_max_power[mode]);
1560+ printf("| Max XR power: 0x%02x |", ee->ee_xr_power[mode]);
1561+ printf(" Switch Settling Time: 0x%02x |\n", ee->ee_switch_settling[mode]);
1562+ printf("| Tx/Rx attenuation: 0x%02x |", ee->ee_ant_tx_rx[mode]);
1563+ printf(" TX end to XLNA On: 0x%02x |\n", ee->ee_tx_end2xlna_enable[mode]);
1564+ printf("| TX end to XPA Off: 0x%02x |", ee->ee_tx_end2xpa_disable[mode]);
1565+ printf(" TX end to XPA On: 0x%02x |\n", ee->ee_tx_frm2xpa_enable[mode]);
1566+ printf("| 62db Threshold: 0x%02x |", ee->ee_thr_62[mode]);
1567+ printf(" XLNA gain: 0x%02x |\n", ee->ee_xlna_gain[mode]);
1568+ printf("| XPD: 0x%02x |", ee->ee_xpd[mode]);
1569+ printf(" XPD gain: 0x%02x |\n", ee->ee_x_gain[mode]);
1570+ printf("| I gain: 0x%02x |", ee->ee_i_gain[mode]);
1571+ printf(" Tx/Rx margin: 0x%02x |\n", ee->ee_margin_tx_rx[mode]);
1572+ printf("| False detect backoff: 0x%02x |", ee->ee_false_detect[mode]);
1573+ printf(" Noise Floor Threshold: %3d |\n", ee->ee_noise_floor_thr[mode]);
1574+ printf("| ADC desired size: %3d |", ee->ee_adc_desired_size[mode]);
1575+ printf(" PGA desired size: %3d |\n", ee->ee_pga_desired_size[mode]);
1576+ printf("|=========================================================|\n");
1577+ for (i = 0; i < AR5K_EEPROM_N_PCDAC; i++) {
1578+ printf("| Antenna control %2i: 0x%02x |", i, ee->ee_ant_control[mode][i]);
1579+ i++;
1580+ printf(" Antenna control %2i: 0x%02x |\n", i, ee->ee_ant_control[mode][i]);
1581+ }
1582+ printf("|=========================================================|\n");
1583+ for (i = 0; i < AR5K_EEPROM_N_OBDB; i++) {
1584+ printf("| Octave Band %i: %2i |", i, ee->ee_ob[mode][i]);
1585+ printf(" db %i: %2i |\n", i, ee->ee_db[mode][i]);
1586+ }
1587+ printf("\\=========================================================/\n");
1588+}
1589+
1590+static void dump_power_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
1591+{
1592+ struct ath5k_chan_pcal_info *chan_pcal_info;
1593+ u_int16_t cal_piers;
1594+ int i, c;
1595+
1596+ switch (mode) {
1597+ case AR5K_EEPROM_MODE_11A:
1598+ chan_pcal_info = ee->ee_pwr_cal_a;
1599+ cal_piers = ee->ee_cal_piers_a;
1600+ break;
1601+ case AR5K_EEPROM_MODE_11B:
1602+ chan_pcal_info = ee->ee_pwr_cal_b;
1603+ cal_piers = ee->ee_cal_piers_b;
1604+ break;
1605+ case AR5K_EEPROM_MODE_11G:
1606+ chan_pcal_info = ee->ee_pwr_cal_g;
1607+ cal_piers = ee->ee_cal_piers_g;
1608+ break;
1609+ default:
1610+ return;
1611+ }
1612+
1613+ printf("/=================== Per channel power calibration ====================\\\n");
1614+ printf("| Freq | pwr_0 | pwr_1 | pwr_2 | pwr_3 |pwrx3_0|pwrx3_1|pwrx3_2|max_pwr|\n");
1615+ printf("| | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | |\n");
1616+
1617+ for (i = 0; i < cal_piers; i++) {
1618+ char buf[16];
1619+
1620+ printf("|======|=======|=======|=======|=======|=======|=======|=======|=======|\n");
1621+ printf("| %4i |", chan_pcal_info[i].freq);
1622+ for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
1623+ printf(" %2i.%02i |", chan_pcal_info[i].pwr_x0[c] / 4,
1624+ chan_pcal_info[i].pwr_x0[c] % 4);
1625+ }
1626+ for (c = 0; c < AR5K_EEPROM_N_XPD3_POINTS; c++) {
1627+ printf(" %2i.%02i |", chan_pcal_info[i].pwr_x3[c] / 4,
1628+ chan_pcal_info[i].pwr_x3[c] % 4);
1629+ }
1630+ printf(" %2i.%02i |\n", chan_pcal_info[i].max_pwr / 4,
1631+ chan_pcal_info[i].max_pwr % 4);
1632+
1633+ printf("| |");
1634+ for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
1635+ snprintf(buf, sizeof(buf), "[%i]",
1636+ chan_pcal_info[i].pcdac_x0[c]);
1637+ printf("%6s |", buf);
1638+ }
1639+ for (c = 0; c < AR5K_EEPROM_N_XPD3_POINTS; c++) {
1640+ snprintf(buf, sizeof(buf), "[%i]",
1641+ chan_pcal_info[i].pcdac_x3[c]);
1642+ printf("%6s |", buf);
1643+ }
1644+ printf(" |\n");
1645+
1646+ }
1647+ printf("\\======================================================================/\n");
1648+}
1649+
1650+static void dump_rate_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
1651+{
1652+ int i;
1653+ struct ath5k_rate_pcal_info *rate_pcal_info;
1654+ u_int16_t rate_target_pwr_num;
1655+
1656+ switch (mode) {
1657+ case AR5K_EEPROM_MODE_11A:
1658+ rate_pcal_info = ee->ee_rate_tpwr_a;
1659+ rate_target_pwr_num = ee->ee_rate_target_pwr_num_a;
1660+ break;
1661+ case AR5K_EEPROM_MODE_11B:
1662+ rate_pcal_info = ee->ee_rate_tpwr_b;
1663+ rate_target_pwr_num = ee->ee_rate_target_pwr_num_b;
1664+ break;
1665+ case AR5K_EEPROM_MODE_11G:
1666+ rate_pcal_info = ee->ee_rate_tpwr_g;
1667+ rate_target_pwr_num = ee->ee_rate_target_pwr_num_g;
1668+ break;
1669+ default:
1670+ return;
1671+ }
1672+
1673+ printf("/============== Per rate power calibration ===========\\\n");
1674+ if (mode == AR5K_EEPROM_MODE_11B)
1675+ printf("| Freq | 1Mbit/s | 2Mbit/s | 5.5Mbit/s | 11Mbit/s |\n");
1676+ else
1677+ printf("| Freq | 6-24Mbit/s | 36Mbit/s | 48Mbit/s | 54Mbit/s |\n");
1678+
1679+ for (i = 0; i < rate_target_pwr_num; i++) {
1680+
1681+ printf("|======|============|==========|===========|==========|\n");
1682+ printf("| %4i |", rate_pcal_info[i].freq);
1683+ printf(" %2i.%02i |",rate_pcal_info[i].target_power_6to24 /2,
1684+ rate_pcal_info[i].target_power_6to24 % 2);
1685+ printf(" %2i.%02i |",rate_pcal_info[i].target_power_36 /2,
1686+ rate_pcal_info[i].target_power_36 % 2);
1687+ printf(" %2i.%02i |",rate_pcal_info[i].target_power_48 /2,
1688+ rate_pcal_info[i].target_power_48 % 2);
1689+ printf(" %2i.%02i |\n",rate_pcal_info[i].target_power_54 /2,
1690+ rate_pcal_info[i].target_power_54 % 2);
1691+ }
1692+ printf("\\=====================================================/\n");
1693+}
1694+
1695+static u_int32_t extend_tu(u_int32_t base_tu, u_int32_t val, u_int32_t mask)
1696+{
1697+ u_int32_t result;
1698+
1699+ result = (base_tu & ~mask) | (val & mask);
1700+ if ((base_tu & mask) > (val & mask))
1701+ result += mask + 1;
1702+ return result;
1703+}
1704+
1705+static void dump_timers_register(void *mem, u_int16_t mac_version)
1706+{
1707+#define AR5K_TIMER0_5210 0x802c /* next TBTT */
1708+#define AR5K_TIMER0_5211 0x8028
1709+#define AR5K_TIMER0 (mac_version == AR5K_SREV_MAC_AR5210 ? \
1710+ AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
1711+
1712+#define AR5K_TIMER1_5210 0x8030 /* next DMA beacon */
1713+#define AR5K_TIMER1_5211 0x802c
1714+#define AR5K_TIMER1 (mac_version == AR5K_SREV_MAC_AR5210 ? \
1715+ AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
1716+
1717+#define AR5K_TIMER2_5210 0x8034 /* next SWBA interrupt */
1718+#define AR5K_TIMER2_5211 0x8030
1719+#define AR5K_TIMER2 (mac_version == AR5K_SREV_MAC_AR5210 ? \
1720+ AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
1721+
1722+#define AR5K_TIMER3_5210 0x8038 /* next ATIM window */
1723+#define AR5K_TIMER3_5211 0x8034
1724+#define AR5K_TIMER3 (mac_version == AR5K_SREV_MAC_AR5210 ? \
1725+ AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
1726+
1727+#define AR5K_TSF_L32_5210 0x806c /* TSF (lower 32 bits) */
1728+#define AR5K_TSF_L32_5211 0x804c
1729+#define AR5K_TSF_L32 (mac_version == AR5K_SREV_MAC_AR5210 ? \
1730+ AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
1731+
1732+#define AR5K_TSF_U32_5210 0x8070
1733+#define AR5K_TSF_U32_5211 0x8050
1734+#define AR5K_TSF_U32 (mac_version == AR5K_SREV_MAC_AR5210 ? \
1735+ AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
1736+
1737+#define AR5K_BEACON_5210 0x8024
1738+#define AR5K_BEACON_5211 0x8020
1739+#define AR5K_BEACON (mac_version == AR5K_SREV_MAC_AR5210 ? \
1740+ AR5K_BEACON_5210 : AR5K_BEACON_5211)
1741+
1742+#define AR5K_LAST_TSTP 0x8080
1743+
1744+ const int timer_mask = 0xffff;
1745+
1746+ u_int32_t timer0, timer1, timer2, timer3, now_tu;
1747+ u_int32_t timer0_tu, timer1_tu, timer2_tu, timer3_tu;
1748+ u_int64_t now_tsf;
1749+
1750+ timer0 = AR5K_REG_READ(AR5K_TIMER0); /* 0x0000ffff */
1751+ timer1 = AR5K_REG_READ(AR5K_TIMER1_5211); /* 0x0007ffff */
1752+ timer2 = AR5K_REG_READ(AR5K_TIMER2_5211); /* 0x?1ffffff */
1753+ timer3 = AR5K_REG_READ(AR5K_TIMER3_5211); /* 0x0000ffff */
1754+
1755+ now_tsf = ((u_int64_t)AR5K_REG_READ(AR5K_TSF_U32_5211) << 32)
1756+ | (u_int64_t)AR5K_REG_READ(AR5K_TSF_L32_5211);
1757+
1758+ now_tu = now_tsf >> 10;
1759+
1760+ timer0_tu = extend_tu(now_tu, timer0, 0xffff);
1761+ printf("TIMER0: 0x%08x, TBTT: %5u, TU: 0x%08x\n", timer0,
1762+ timer0 & timer_mask, timer0_tu);
1763+ timer1_tu = extend_tu(now_tu, timer1 >> 3, 0x7ffff >> 3);
1764+ printf("TIMER1: 0x%08x, DMAb: %5u, TU: 0x%08x (%+d)\n", timer1,
1765+ (timer1 >> 3) & timer_mask, timer1_tu, timer1_tu - timer0_tu);
1766+ timer2_tu = extend_tu(now_tu, timer2 >> 3, 0x1ffffff >> 3);
1767+ printf("TIMER2: 0x%08x, SWBA: %5u, TU: 0x%08x (%+d)\n", timer2,
1768+ (timer2 >> 3) & timer_mask, timer2_tu, timer2_tu - timer0_tu);
1769+ timer3_tu = extend_tu(now_tu, timer3, 0xffff);
1770+ printf("TIMER3: 0x%08x, ATIM: %5u, TU: 0x%08x (%+d)\n", timer3,
1771+ timer3 & timer_mask, timer3_tu, timer3_tu - timer0_tu);
1772+ printf("TSF: 0x%016llx, TSFTU: %5u, TU: 0x%08x\n",
1773+ (unsigned long long)now_tsf, now_tu & timer_mask, now_tu);
1774+
1775+ printf("BEACON: 0x%08x\n", AR5K_REG_READ(AR5K_BEACON));
1776+ printf("LAST_TSTP: 0x%08x\n", AR5K_REG_READ(AR5K_LAST_TSTP));
1777+}
1778+
1779+#define AR5K_KEYTABLE_0_5210 0x9000
1780+#define AR5K_KEYTABLE_0_5211 0x8800
1781+#define AR5K_KEYTABLE_0 (mac_version == AR5K_SREV_MAC_AR5210 ? \
1782+ AR5K_KEYTABLE_0_5210 : \
1783+ AR5K_KEYTABLE_0_5211)
1784+
1785+#define AR5K_KEYTABLE(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
1786+#define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + ((x) << 2))
1787+#define AR5K_KEYTABLE_VALID 0x00008000
1788+
1789+#define AR5K_KEYTABLE_SIZE_5210 64
1790+#define AR5K_KEYTABLE_SIZE_5211 128
1791+#define AR5K_KEYTABLE_SIZE (mac_version == AR5K_SREV_MAC_AR5210 ? \
1792+ AR5K_KEYTABLE_SIZE_5210 : \
1793+ AR5K_KEYTABLE_SIZE_5211)
1794+
1795+static void keycache_dump(void *mem, u_int16_t mac_version)
1796+{
1797+ int i, keylen;
1798+ u_int32_t val0, val1, val2, val3, val4, keytype, ant, mac0, mac1;
1799+
1800+ /* dump all 128 entries */
1801+ printf("Dumping keycache entries...\n");
1802+ for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) {
1803+ mac1 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 7));
1804+ if (mac1 & AR5K_KEYTABLE_VALID) {
1805+ val0 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 0));
1806+ val1 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 1));
1807+ val2 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 2));
1808+ val3 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 3));
1809+ val4 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 4));
1810+ keytype = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 5));
1811+ ant = keytype & 8;
1812+ keytype &= ~8;
1813+ switch (keytype) {
1814+ case 0: /* WEP40 */ keylen = 40 / 8; break;
1815+ case 1: /* WEP104 */ keylen = 104 / 8; break;
1816+ case 3: /* WEP128 */ keylen = 128 / 8; break;
1817+ case 4: /* TKIP */ keylen = 128 / 8; break;
1818+ case 5: /* AES */ keylen = 128 / 8; break;
1819+ case 6: /* CCM */ keylen = 128 / 8; break;
1820+ default: keylen = 0; break;
1821+ }
1822+ mac0 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 6));
1823+
1824+ printf("[%3u] keytype %d [%s%s%s%s%s%s%s%s] mac %02x:%02x:%02x:%02x:%02x:%02x key:%08x-%08x-%08x-%08x-%08x\n",
1825+ i,
1826+ keytype,
1827+ keytype == 0 ? "WEP40 " : "",
1828+ keytype == 1 ? "WEP104" : "",
1829+ keytype == 3 ? "WEP128" : "",
1830+ keytype == 4 ? "TKIP " : "",
1831+ keytype == 5 ? "AES " : "",
1832+ keytype == 6 ? "CCM " : "",
1833+ keytype == 7 ? "NULL " : "",
1834+ ant == 8 ? "+ANT" : "",
1835+ ((mac0 << 1) & 0xff),
1836+ ((mac0 >> 7) & 0xff),
1837+ ((mac0 >> 15) & 0xff),
1838+ ((mac0 >> 23) & 0xff),
1839+ ((mac1 << 1) & 0xff) | (mac0 >> 31),
1840+ ((mac1 >> 7) & 0xff),
1841+ val0, val1, val2, val3, val4);
1842+ }
1843+ }
1844+}
1845+
1846+/* copy key index (0) to key index (idx) */
1847+
1848+static void keycache_copy(void *mem, u_int16_t mac_version, int idx)
1849+{
1850+ u_int32_t val0, val1, val2, val3, val4, keytype, mac0, mac1;
1851+
1852+ printf("Copying keycache entry 0 to %d\n", idx);
1853+ if (idx < 0 || idx >= AR5K_KEYTABLE_SIZE) {
1854+ printf("invalid keycache index\n");
1855+ return;
1856+ }
1857+
1858+ val0 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 0));
1859+ val1 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 1));
1860+ val2 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 2));
1861+ val3 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 3));
1862+ val4 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 4));
1863+ keytype = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 5));
1864+ mac0 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 6));
1865+ mac1 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 7));
1866+
1867+ AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 0), val0);
1868+ AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 1), val1);
1869+ AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 2), val2);
1870+ AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 3), val3);
1871+ AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 4), val4);
1872+ AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 5), keytype);
1873+ AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 6), mac0);
1874+ AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 7), mac1);
1875+}
1876+
1877+static void sta_id0_id1_dump(void *mem)
1878+{
1879+#define AR5K_STA_ID0 0x8000
1880+#define AR5K_STA_ID1 0x8004
1881+#define AR5K_STA_ID1_AP 0x00010000
1882+#define AR5K_STA_ID1_ADHOC 0x00020000
1883+#define AR5K_STA_ID1_NO_KEYSRCH 0x00080000
1884+
1885+ u_int32_t sta_id0, sta_id1;
1886+
1887+ sta_id0 = AR5K_REG_READ(AR5K_STA_ID0);
1888+ sta_id1 = AR5K_REG_READ(AR5K_STA_ID1);
1889+ printf("STA_ID0: %02x:%02x:%02x:%02x:%02x:%02x\n",
1890+ (sta_id0 >> 0) & 0xff,
1891+ (sta_id0 >> 8) & 0xff,
1892+ (sta_id0 >> 16) & 0xff,
1893+ (sta_id0 >> 24) & 0xff,
1894+ (sta_id1 >> 0) & 0xff,
1895+ (sta_id1 >> 8) & 0xff);
1896+ printf("STA_ID1: 0x%08x, AP: %d, IBSS: %d, KeyCache Disable: %d\n",
1897+ sta_id1,
1898+ sta_id1 & AR5K_STA_ID1_AP ? 1 : 0,
1899+ sta_id1 & AR5K_STA_ID1_ADHOC ? 1 : 0,
1900+ sta_id1 & AR5K_STA_ID1_NO_KEYSRCH ? 1 : 0);
1901+}
1902+
1903 int
1904 CMD(athinfo)(int argc, char *argv[])
1905 {
1906- u_int32_t dev_addr;
1907- u_int16_t eeprom_header, srev, phy_rev_5ghz, phy_rev_2ghz;
1908- u_int16_t eeprom_version, mac_version, regdomain, has_crystal, ee_magic;
1909- u_int8_t error, has_a, has_b, has_g, has_rfkill, eeprom_size;
1910- int byte_size = 0;
1911+ unsigned long long dev_addr;
1912+ u_int16_t srev, phy_rev_5ghz, phy_rev_2ghz, ee_magic;
1913+ u_int8_t mac_version, mac_revision;
1914+ u_int8_t error, eeprom_size, dev_type, eemap;
1915+ struct ath5k_eeprom_info *ee;
1916+ unsigned int byte_size = 0;
1917     void *mem;
1918     int fd;
1919- int i, anr = 1;
1920+ unsigned int i;
1921+ int anr = 1;
1922     int do_write = 0; /* default: read only */
1923     int do_dump = 0;
1924+ int reg_read = 0;
1925+ int reg_write = 0;
1926+ unsigned int reg_write_val = 0;
1927+ unsigned int timer_count = 1;
1928+ int do_keycache_dump = 0;
1929+ int keycache_copy_idx = 0;
1930 
1931     struct {
1932         int valid;
1933@@ -759,7 +1986,7 @@ CMD(athinfo)(int argc, char *argv[])
1934     } gpio_set[AR5K_NUM_GPIO];
1935     int nr_gpio_set = 0;
1936 
1937- for (i = 0; i < sizeof(gpio_set) / sizeof(gpio_set[0]); i++)
1938+ for (i = 0; i < ARRAY_SIZE(gpio_set); i++)
1939         gpio_set[i].valid = 0;
1940 
1941     if (argc < 2) {
1942@@ -769,6 +1996,15 @@ CMD(athinfo)(int argc, char *argv[])
1943 
1944     while (anr < argc && argv[anr][0] == '-') {
1945         switch (argv[anr][1]) {
1946+ case 't':
1947+ if (++anr < argc) {
1948+ timer_count = atoi(argv[anr]);
1949+ printf("timer_count:%d\n", timer_count);
1950+ } else {
1951+ usage(argv[0]);
1952+ return 0;
1953+ }
1954+ break;
1955         case 'w':
1956             do_write = 1;
1957             break;
1958@@ -777,7 +2013,7 @@ CMD(athinfo)(int argc, char *argv[])
1959             if (strlen(argv[anr]) != 3 || argv[anr][1] != ':' ||
1960                 argv[anr][0] < '0' || argv[anr][0] > '5' ||
1961                 (argv[anr][2] != '0' && argv[anr][2] != '1')) {
1962- err("invalid gpio spec. %s", argv[anr]);
1963+ err("invalid GPIO spec. %s", argv[anr]);
1964                 return 2;
1965             }
1966             gpio_set[argv[anr][0] - '0'].valid = 1;
1967@@ -797,6 +2033,25 @@ CMD(athinfo)(int argc, char *argv[])
1968             do_dump = 1;
1969             break;
1970 
1971+ case 'R':
1972+ anr++;
1973+ reg_read = strtoul(argv[anr], NULL, 16);
1974+ break;
1975+
1976+ case 'W':
1977+ anr++;
1978+ reg_write = strtoul(argv[anr++], NULL, 16);
1979+ reg_write_val = strtoul(argv[anr], NULL, 16);
1980+ break;
1981+
1982+ case 'k':
1983+ do_keycache_dump = 1;
1984+ break;
1985+
1986+ case 'K':
1987+ keycache_copy_idx = atoi(argv[++anr]);
1988+ break;
1989+
1990         case 'h':
1991             usage(argv[0]);
1992             return 0;
1993@@ -805,10 +2060,10 @@ CMD(athinfo)(int argc, char *argv[])
1994         default:
1995             err("unknown option %s", argv[anr]);
1996             return 2;
1997- } /* switch (argv[anr][1]) */
1998+ }
1999 
2000         anr++;
2001- } /* while (anr < argc && ...) */
2002+ }
2003 
2004     if (anr >= argc) {
2005         err("missing device address");
2006@@ -816,7 +2071,7 @@ CMD(athinfo)(int argc, char *argv[])
2007         return 3;
2008     }
2009 
2010- dev_addr = strtoul(argv[anr], NULL, 16);
2011+ dev_addr = strtoull(argv[anr], NULL, 16);
2012 
2013     fd = open("/dev/mem", O_RDWR);
2014     if (fd < 0) {
2015@@ -828,7 +2083,7 @@ CMD(athinfo)(int argc, char *argv[])
2016            MAP_SHARED | MAP_FILE, fd, dev_addr);
2017 
2018     if (mem == MAP_FAILED) {
2019- printf("Mmap of device at 0x%08X for 0x%X bytes failed - "
2020+ printf("mmap of device at 0x%08llX for 0x%X bytes failed - "
2021                "%s\n", dev_addr, AR5K_PCI_MEM_SIZE, strerror(errno));
2022         return -3;
2023     }
2024@@ -856,10 +2111,31 @@ CMD(athinfo)(int argc, char *argv[])
2025     AR5K_REG_DISABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_SPWR_DN);
2026     usleep(500);
2027 
2028+ if (reg_read) {
2029+ printf("READ %04x = %08x\n", reg_read, AR5K_REG_READ(reg_read));
2030+ return 0;
2031+ }
2032+
2033+ if (reg_write) {
2034+ printf("WRITE %04x = %08x\n", reg_write, reg_write_val);
2035+ AR5K_REG_WRITE(reg_write, reg_write_val);
2036+ return 0;
2037+ }
2038+
2039     srev = AR5K_REG_READ(AR5K_SREV);
2040- mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER) << 4;
2041+ if (srev >= 0x0100) {
2042+ printf("MAC revision 0x%04x is not supported!\n", srev);
2043+ return -1;
2044+ }
2045+ mac_version = srev & AR5K_SREV_VER;
2046+ mac_revision = srev & AR5K_SREV_REV;
2047 
2048- /* Verify eeprom magic value first */
2049+ printf(" -==Device Information==-\n");
2050+
2051+ printf("MAC Revision: %-5s (0x%02x)\n",
2052+ ath5k_hw_get_mac_name(mac_revision), mac_revision);
2053+
2054+ /* Verify EEPROM magic value first */
2055     error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_MAGIC, &ee_magic,
2056                      mac_version);
2057 
2058@@ -872,157 +2148,114 @@ CMD(athinfo)(int argc, char *argv[])
2059         printf("Warning: Invalid EEPROM Magic number!\n");
2060     }
2061 
2062- error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_HDR, &eeprom_header,
2063- mac_version);
2064-
2065- if (error) {
2066- printf("Unable to read EEPROM Header!\n");
2067- return -1;
2068- }
2069-
2070- error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_VERSION, &eeprom_version,
2071- mac_version);
2072-
2073- if (error) {
2074- printf("Unable to read EEPROM version!\n");
2075+ ee = calloc(sizeof(struct ath5k_eeprom_info), 1);
2076+ if (!ee) {
2077+ printf("Cannot allocate memory for EEPROM information\n");
2078         return -1;
2079     }
2080 
2081- error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_REG_DOMAIN, &regdomain,
2082- mac_version);
2083-
2084- if (error) {
2085- printf("Unable to read Regdomain!\n");
2086+ if (ath5k_eeprom_init(mem, mac_version, ee)) {
2087+ printf("EEPROM init failed\n");
2088         return -1;
2089     }
2090 
2091- if (eeprom_version >= 0x4000) {
2092- error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_MISC0,
2093- &has_crystal, mac_version);
2094-
2095- if (error) {
2096- printf("Unable to read EEPROM Misc data!\n");
2097- return -1;
2098- }
2099-
2100- has_crystal = AR5K_EEPROM_HAS32KHZCRYSTAL(has_crystal);
2101- } else {
2102- has_crystal = 2;
2103- }
2104-
2105     eeprom_size = AR5K_REG_MS(AR5K_REG_READ(AR5K_PCICFG),
2106                   AR5K_PCICFG_EESIZE);
2107 
2108- has_a = AR5K_EEPROM_HDR_11A(eeprom_header);
2109- has_b = AR5K_EEPROM_HDR_11B(eeprom_header);
2110- has_g = AR5K_EEPROM_HDR_11G(eeprom_header);
2111- has_rfkill = AR5K_EEPROM_HDR_RFKILL(eeprom_header);
2112+ dev_type = AR5K_EEPROM_HDR_DEVICE(ee->ee_header);
2113+ eemap = AR5K_EEPROM_EEMAP(ee->ee_misc0);
2114 
2115- if (has_a)
2116+ /* 1 = ?? 2 = ?? 3 = card 4 = wmac */
2117+ printf("Device type: %1i\n", dev_type);
2118+
2119+ if (AR5K_EEPROM_HDR_11A(ee->ee_header))
2120         phy_rev_5ghz = ath5k_hw_radio_revision(mac_version, mem, 1);
2121     else
2122         phy_rev_5ghz = 0;
2123 
2124- if (has_b)
2125+ if (AR5K_EEPROM_HDR_11B(ee->ee_header))
2126         phy_rev_2ghz = ath5k_hw_radio_revision(mac_version, mem, 0);
2127     else
2128         phy_rev_2ghz = 0;
2129 
2130- printf(" -==Device Information==-\n");
2131-
2132- printf("MAC Version: %-5s (0x%02x)\n",
2133- ath5k_hw_get_part_name(AR5K_VERSION_VER, mac_version),
2134- mac_version);
2135-
2136- printf("MAC Revision: %-5s (0x%02x)\n",
2137- ath5k_hw_get_part_name(AR5K_VERSION_VER, srev), srev);
2138-
2139- /* Single-chip PHY with a/b/g support */
2140- if (has_b && !phy_rev_2ghz) {
2141- printf("PHY Revision: %-5s (0x%02x)\n",
2142- ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_5ghz),
2143- phy_rev_5ghz);
2144- phy_rev_5ghz = 0;
2145- }
2146-
2147- /* Single-chip PHY with b/g support */
2148- if (!has_a) {
2149- printf("PHY Revision: %-5s (0x%02x)\n",
2150- ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_2ghz),
2151- phy_rev_2ghz);
2152- phy_rev_2ghz = 0;
2153- }
2154-
2155- /* Different chip for 5Ghz and 2Ghz */
2156     if (phy_rev_5ghz) {
2157- printf("5Ghz PHY Revision: %-5s (0x%2x)\n",
2158- ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_5ghz),
2159- phy_rev_5ghz);
2160+ printf("5GHz PHY Revision: %-5s (0x%02x)\n",
2161+ ath5k_hw_get_phy_name(phy_rev_5ghz), phy_rev_5ghz);
2162     }
2163     if (phy_rev_2ghz) {
2164- printf("2Ghz PHY Revision: %-5s (0x%2x)\n",
2165- ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_2ghz),
2166- phy_rev_2ghz);
2167+ printf("2GHz PHY Revision: %-5s (0x%02x)\n",
2168+ ath5k_hw_get_phy_name(phy_rev_2ghz), phy_rev_2ghz);
2169     }
2170 
2171- printf(" -==EEPROM Information==-\n");
2172-
2173- printf("EEPROM Version: %x.%x\n",
2174- (eeprom_version & 0xF000) >> 12, eeprom_version & 0xFFF);
2175+ printf("\n");
2176+ printf("/============== EEPROM Information =============\\\n");
2177+ printf("| EEPROM Version: %1x.%1x |",
2178+ (ee->ee_version & 0xF000) >> 12, ee->ee_version & 0xFFF);
2179 
2180- printf("EEPROM Size: ");
2181+ printf(" EEPROM Size: ");
2182 
2183     if (eeprom_size == 0) {
2184- printf(" 4K\n");
2185- byte_size = 4096;
2186+ printf(" 4 kbit |\n");
2187+ byte_size = 4096 / 8;
2188     } else if (eeprom_size == 1) {
2189- printf(" 8K\n");
2190- byte_size = 8192;
2191+ printf(" 8 kbit |\n");
2192+ byte_size = 8192 / 8;
2193     } else if (eeprom_size == 2) {
2194- printf(" 16K\n");
2195- byte_size = 16384;
2196+ printf(" 16 kbit |\n");
2197+ byte_size = 16384 / 8;
2198     } else
2199- printf(" ??\n");
2200+ printf(" unknown |\n");
2201 
2202- printf("Regulatory Domain: 0x%X\n", regdomain);
2203-
2204- printf(" -==== Capabilities ====-\n");
2205-
2206- printf("| 802.11a Support: ");
2207- if (has_a)
2208- printf("yes |\n");
2209- else
2210- printf("no |\n");
2211-
2212- printf("| 802.11b Support: ");
2213- if (has_b)
2214- printf("yes |\n");
2215- else
2216- printf("no |\n");
2217+ printf("| EEMAP: %i |", eemap);
2218 
2219- printf("| 802.11g Support: ");
2220- if (has_g)
2221- printf("yes |\n");
2222- else
2223- printf("no |\n");
2224+ printf(" Reg. Domain: 0x%02X |\n", ee->ee_regdomain);
2225 
2226- printf("| RFKill Support: ");
2227- if (has_rfkill)
2228- printf("yes |\n");
2229- else
2230- printf("no |\n");
2231+ dump_capabilities(ee);
2232+ printf("\n");
2233 
2234- if (has_crystal != 2) {
2235- printf("| 32KHz Crystal: ");
2236- if (has_crystal)
2237- printf("yes |\n");
2238- else
2239- printf("no |\n");
2240+ printf("/=========================================================\\\n");
2241+ printf("| Calibration data common for all modes |\n");
2242+ printf("|=========================================================|\n");
2243+ printf("| CCK/OFDM gain delta: %2i |\n", ee->ee_cck_ofdm_gain_delta);
2244+ printf("| CCK/OFDM power delta: %2i |\n", ee->ee_cck_ofdm_power_delta);
2245+ printf("| Scaled CCK delta: %2i |\n", ee->ee_scaled_cck_delta);
2246+ printf("| 2GHz Antenna gain: %2i |\n", AR5K_EEPROM_ANT_GAIN_2GHZ(ee->ee_ant_gain));
2247+ printf("| 5GHz Antenna gain: %2i |\n", AR5K_EEPROM_ANT_GAIN_5GHZ(ee->ee_ant_gain));
2248+ printf("| Turbo 2W maximum dBm: %2i |\n", AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header));
2249+ printf("| Target power start: 0x%03x |\n", AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1));
2250+ printf("| EAR Start: 0x%03x |\n", AR5K_EEPROM_EARSTART(ee->ee_misc0));
2251+ printf("\\=========================================================/\n");
2252+
2253+ printf("\n");
2254+ if (AR5K_EEPROM_HDR_11A(ee->ee_header)) {
2255+ printf("/=========================================================\\\n");
2256+ printf("| Calibration data for 802.11a operation |\n");
2257+ dump_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
2258+ dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
2259+ dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
2260+ printf("\n");
2261+ }
2262+
2263+ if (AR5K_EEPROM_HDR_11B(ee->ee_header)) {
2264+ printf("/=========================================================\\\n");
2265+ printf("| Calibration data for 802.11b operation |\n");
2266+ dump_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
2267+ dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
2268+ dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
2269+ printf("\n");
2270+ }
2271+
2272+ if (AR5K_EEPROM_HDR_11G(ee->ee_header)) {
2273+ printf("/=========================================================\\\n");
2274+ printf("| Calibration data for 802.11g operation |\n");
2275+ dump_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
2276+ dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
2277+ dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
2278+ printf("\n");
2279     }
2280- printf(" ========================\n");
2281 
2282     /* print current GPIO settings */
2283- printf("GPIO registers: CR %08x DO %08x DI %08x\n",
2284+ printf("GPIO registers: CR 0x%08x, DO 0x%08x, DI 0x%08x\n",
2285            AR5K_REG_READ(AR5K_GPIOCR), AR5K_REG_READ(AR5K_GPIODO),
2286            AR5K_REG_READ(AR5K_GPIODI));
2287 
2288@@ -1030,18 +2263,18 @@ CMD(athinfo)(int argc, char *argv[])
2289         u_int16_t data;
2290         FILE *dumpfile = fopen("ath-eeprom-dump.bin", "w");
2291 
2292- printf("\nEEPROM dump (%d byte)\n", byte_size);
2293+ printf("\nEEPROM dump (%d bytes)\n", byte_size);
2294         printf("==============================================");
2295- for (i = 1; i <= (byte_size / 2); i++) {
2296+ for (i = 0; i < byte_size / 2; i++) {
2297             error =
2298                 ath5k_hw_eeprom_read(mem, i, &data, mac_version);
2299             if (error) {
2300                 printf("\nUnable to read at %04x\n", i);
2301                 continue;
2302             }
2303- if (!((i - 1) % 8))
2304- printf("\n%04x: ", i);
2305- printf("%04x ", data);
2306+ if (!(i % 8))
2307+ printf("\n%04x: ", i);
2308+ printf(" %04x", data);
2309             fwrite(&data, 2, 1, dumpfile);
2310         }
2311         printf("\n==============================================\n");
2312@@ -1054,18 +2287,18 @@ CMD(athinfo)(int argc, char *argv[])
2313         u_int32_t old_cr = rcr, old_do = rdo;
2314         int rc;
2315 
2316- if (mac_version >= AR5K_SREV_VER_AR5213 && !nr_gpio_set) {
2317- dbg("new MAC %x (>= AR5213) set gpio4 to low",
2318+ if (mac_version >= AR5K_SREV_MAC_AR5213 && !nr_gpio_set) {
2319+ dbg("new MAC %x (>= AR5213) set GPIO4 to low",
2320                 mac_version);
2321             gpio_set[4].valid = 1;
2322             gpio_set[4].value = 0;
2323         }
2324 
2325- /* set gpios */
2326+ /* set GPIOs */
2327         dbg("old GPIO CR %08x DO %08x DI %08x",
2328             rcr, rdo, AR5K_REG_READ(AR5K_GPIODI));
2329 
2330- for (i = 0; i < sizeof(gpio_set) / sizeof(gpio_set[0]); i++) {
2331+ for (i = 0; i < ARRAY_SIZE(gpio_set); i++) {
2332             if (gpio_set[i].valid) {
2333                 rcr |= AR5K_GPIOCR_OUT(i); /* we use mode 3 */
2334                 rcr &= ~AR5K_GPIOCR_INT_SEL(i);
2335@@ -1111,5 +2344,17 @@ CMD(athinfo)(int argc, char *argv[])
2336 
2337         return rc;
2338     }
2339+
2340+ sta_id0_id1_dump(mem);
2341+
2342+ for (i = 0; i < timer_count; i++)
2343+ dump_timers_register(mem, mac_version);
2344+
2345+ if (do_keycache_dump)
2346+ keycache_dump(mem, mac_version);
2347+
2348+ if (keycache_copy_idx > 0)
2349+ keycache_copy(mem, mac_version, keycache_copy_idx);
2350+
2351     return 0;
2352 }
2353

Archive Download this file



interactive