4 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7 -/* So here is how it works:
11 - * gcc ath_info.c -o ath_info
13 - * then find card's physical address
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
23 - * address here is 0xc2000000
25 - * load madwifi-ng or madwifi-old if not already loaded (be sure the
26 - * interface is down!)
33 - * setpci -s 02:02.0 command=0x41f cache_line_size=0x10
35 - * to enable access to the PCI device.
37 - * and we run the thing...
39 - * ./ath_info 0xc2000000
41 - * In order to change the regdomain to 0, call:
43 - * ./ath_info -w 0xc2000000 regdomain 0
45 - * to change any PCI ID value, say:
47 - * ./ath_info -w 0xc2000000 <name> X
49 - * with <name> ::= pci_dev_id | pci_vendor_id | pci_class |
50 - * pci_subsys_dev_id | pci_subsys_vendor_id
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:
59 - * ./ath_info -g 5:0 -w 0xc2000000 regdomain X
61 - * would set GPIO 5 to low (and wouldn't touch GPIO 4). -g can be given several times.
63 - * The write function is currently not tested with 5210 devices.
65 - * Use at your own risk, entering a false device address will have really
68 - * Writing wrong values to the PCI id fields may prevent the driver from
69 - * detecting the card!
71 - * Transmitting on illegal frequencies may violate state laws. Stick to the local
75 - * The authors are in no case responsible for damaged hardware or violation of
76 - * local laws by operating modified hardware.
79 +/* Try accepting 64-bit device address even with 32-bit userspace */
80 +#define _FILE_OFFSET_BITS 64
84 @@ -130,109 +60,103 @@ fprintf(stderr, "#ERR %s: " fmt "\n", __
86 #define AR5K_GPIODI 0x401c
89 - * Common silicon revision/version values
91 -enum ath5k_srev_type {
97 struct ath5k_srev_name {
99 - enum ath5k_srev_type sr_type;
104 -#define AR5K_SREV_UNKNOWN 0xffff
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
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 */
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
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 */
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},
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},
232 * Silicon revision register
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 */
243 * PHY chip revision register
245 -#define AR5K_PHY_CHIP_ID 0x9818
246 +#define AR5K_PHY_CHIP_ID 0x9818
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
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 */
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
277 #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status (5210) */
279 -#define AR5K_EEPROM_BASE 0x6000
280 +#define AR5K_EEPROM_BASE 0x6000
282 -#define AR5K_EEPROM_MAGIC 0x003d /* Offset for EEPROM Magic number */
284 + * Common AR5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
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 */
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))
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
330 +#define AR5K_EEPROM_MODE_11A 0
331 +#define AR5K_EEPROM_MODE_11B 1
332 +#define AR5K_EEPROM_MODE_11G 2
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 */
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)
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
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)
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))
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)
378 +#define AR5K_EEPROM_OBDB0_2GHZ 0x00ec
379 +#define AR5K_EEPROM_OBDB1_2GHZ 0x00ed
382 * EEPROM data register
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)
391 * EEPROM command register
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
400 * EEPROM status register
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 */
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
423 + * EEPROM config register (?)
425 +#define AR5K_EEPROM_CFG 0x6010
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
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 */
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 */
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;
517 +/* EEPROM calibration data */
518 +struct ath5k_eeprom_info {
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;
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;
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];
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];
576 + /* Conformance test limits (Unused) */
578 + u_int16_t ee_ctl[AR5K_EEPROM_MAX_CTLS];
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];
585 + u_int32_t ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
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))
595 #define AR5K_REG_ENABLE_BITS(_reg, _flags) \
596 AR5K_REG_WRITE(_reg, AR5K_REG_READ(_reg) | (_flags))
598 @@ -359,7 +494,12 @@ static const struct ath5k_srev_name ath5
600 #define AR5K_TUNE_REGISTER_TIMEOUT 20000
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) \
608 +/* Names for EEPROM fields */
609 struct eeprom_entry {
612 @@ -375,8 +515,6 @@ static const struct eeprom_entry eeprom_
613 {"regdomain", AR5K_EEPROM_REG_DOMAIN},
616 -static const int eeprom_addr_len = sizeof(eeprom_addr) / sizeof(eeprom_addr[0]);
618 static int force_write = 0;
619 static int verbose = 0;
621 @@ -398,8 +536,8 @@ static u_int32_t ath5k_hw_bitswap(u_int3
623 * Get the PHY Chip revision
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,
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);
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;
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
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)
651 u_int32_t status, timeout;
653 @@ -457,7 +594,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
654 * Initialize EEPROM access
657 - if (mac_version == AR5K_SREV_VER_AR5210) {
658 + if (mac_version == AR5K_SREV_MAC_AR5210) {
660 AR5K_REG_ENABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_EEAE);
662 @@ -466,7 +603,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
666 - /* reset eeprom access */
667 + /* reset EEPROM access */
668 AR5K_REG_WRITE(AR5K_EEPROM_CMD, AR5K_EEPROM_CMD_RESET);
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",
680 @@ -499,16 +636,15 @@ ath5k_hw_eeprom_write(void *mem, u_int32
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)
690 u_int32_t status, timeout;
693 * Initialize EEPROM access
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));
700 @@ -531,50 +667,701 @@ ath5k_hw_eeprom_read(void *mem, u_int32_
704 -static const char *ath5k_hw_get_part_name(enum ath5k_srev_type type,
707 + * Translate binary channel representation in EEPROM to frequency
709 +static u_int16_t ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee,
710 + u_int16_t bin, unsigned int mode)
712 - const char *name = "xxxxx";
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)
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)
725 + if (mode == AR5K_EEPROM_MODE_11A) {
726 + if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
727 + val = (5 * bin) + 4800;
729 + val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
732 + if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
742 + * Read antenna info from EEPROM
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)
748 + u_int32_t o = *offset;
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;
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;
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;
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;
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;
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);
794 + /* return new offset */
801 + * Read supported modes from EEPROM
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)
807 + u_int32_t o = *offset;
811 + AR5K_EEPROM_READ(o++, val);
812 + ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
813 + ee->ee_thr_62[mode] = val & 0xff;
815 + if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2)
816 + ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
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;
822 + AR5K_EEPROM_READ(o++, val);
823 + ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
825 + if ((val & 0xff) & 0x80)
826 + ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
828 + ee->ee_noise_floor_thr[mode] = val & 0xff;
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;
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;
839 + if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
840 + ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
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;
846 + if (mode == AR5K_EEPROM_MODE_11A)
847 + ee->ee_xr_power[mode] = val & 0x3f;
849 + ee->ee_ob[mode][0] = val & 0x7;
850 + ee->ee_db[mode][0] = (val >> 3) & 0x7;
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;
858 + ee->ee_i_gain[mode] = (val >> 13) & 0x7;
860 + AR5K_EEPROM_READ(o++, val);
861 + ee->ee_i_gain[mode] |= (val << 3) & 0x38;
863 + if (mode == AR5K_EEPROM_MODE_11G)
864 + ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
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;
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;
877 + /* return new offset */
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...
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).
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).
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)
903 + u_int32_t o = *offset;
907 + struct ath5k_chan_pcal_info *chan_pcal_info;
908 + u_int16_t cal_piers;
911 + case AR5K_EEPROM_MODE_11A:
912 + chan_pcal_info = ee->ee_pwr_cal_a;
913 + cal_piers = ee->ee_cal_piers_a;
915 + case AR5K_EEPROM_MODE_11B:
916 + chan_pcal_info = ee->ee_pwr_cal_b;
917 + cal_piers = ee->ee_cal_piers_b;
919 + case AR5K_EEPROM_MODE_11G:
920 + chan_pcal_info = ee->ee_pwr_cal_g;
921 + cal_piers = ee->ee_cal_piers_g;
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);
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);
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);
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);
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;
959 + /* Last xpd0 power level is also channel maximum */
960 + chan_pcal_info[i].max_pwr = chan_pcal_info[i].pwr_x0[3];
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];
968 + /* return new offset */
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.
979 + * This also works for v5 EEPROMs.
981 +static int ath5k_eeprom_read_target_rate_pwr_info(void *mem,
982 + u_int8_t mac_version,
983 + struct ath5k_eeprom_info *ee,
987 + u_int32_t o = *offset;
989 + struct ath5k_rate_pcal_info *rate_pcal_info;
990 + u_int16_t *rate_target_pwr_num;
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;
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;
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;
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);
1020 + rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
1021 + rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
1023 + AR5K_EEPROM_READ(o++, val);
1025 + if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1027 + (*rate_target_pwr_num) = i;
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);
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);
1041 + rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
1042 + rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
1044 + AR5K_EEPROM_READ(o++, val);
1046 + if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1048 + (*rate_target_pwr_num) = i;
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);
1057 + /* return new offset */
1064 + * Initialize EEPROM & capabilities data
1066 +static int ath5k_eeprom_init(void *mem, u_int8_t mac_version,
1067 + struct ath5k_eeprom_info *ee)
1069 + unsigned int mode, i;
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;
1080 + * Read values from EEPROM and store them in the capability structure
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);
1088 + /* Return if we have an old EEPROM */
1089 + if (ee->ee_version < AR5K_EEPROM_VERSION_3_0)
1094 + * Validate the checksum of the EEPROM date. There are some
1095 + * devices with invalid EEPROMs.
1097 + for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
1098 + AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
1101 + if (cksum != AR5K_EEPROM_INFO_CKSUM) {
1102 + AR5K_PRINTF("Invalid EEPROM checksum 0x%04x\n", cksum);
1107 + AR5K_EEPROM_READ(AR5K_EEPROM_ANT_GAIN(ee->ee_version), ee->ee_ant_gain);
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);
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;
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;
1125 + * Get conformance test limit values
1127 + offset = AR5K_EEPROM_CTL(ee->ee_version);
1130 + for (i = 0; i < AR5K_EEPROM_N_CTLS(ee->ee_version); i++) {
1131 + AR5K_EEPROM_READ(offset++, val);
1133 + if (((val >> 8) & 0xff) == 0)
1136 + ee->ee_ctl[i] = (val >> 8) & 0xff;
1139 + if ((val & 0xff) == 0)
1142 + ee->ee_ctl[i + 1] = val & 0xff;
1147 + * Get values for 802.11a (5GHz)
1149 + mode = AR5K_EEPROM_MODE_11A;
1151 + ee->ee_turbo_max_power[mode] =
1152 + AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
1154 + offset = AR5K_EEPROM_MODES_11A(ee->ee_version);
1156 + ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
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;
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;
1174 + ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
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;
1184 + * Get values for 802.11b (2.4GHz)
1186 + mode = AR5K_EEPROM_MODE_11B;
1187 + offset = AR5K_EEPROM_MODES_11B(ee->ee_version);
1189 + ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
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;
1198 + ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
1202 + if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
1203 + AR5K_EEPROM_READ(offset++, val);
1205 + ee->ee_cal_piers_b = 0;
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++;
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++;
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++;
1224 + if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1)
1225 + ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
1228 + * Get values for 802.11g (2.4GHz)
1230 + mode = AR5K_EEPROM_MODE_11G;
1231 + offset = AR5K_EEPROM_MODES_11G(ee->ee_version);
1233 + ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
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;
1242 + ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
1246 + if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
1247 + AR5K_EEPROM_READ(offset++, val);
1249 + ee->ee_cal_piers_g = 0;
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++;
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++;
1261 + AR5K_EEPROM_READ(offset++, val);
1262 + ee->ee_turbo_max_power[mode] = val & 0x7f;
1263 + ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
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++;
1271 + if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1)
1272 + ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
1274 + AR5K_EEPROM_READ(offset++, val);
1275 + ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1276 + ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
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;
1286 + * Read 5GHz EEPROM channels
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);
1293 + if ((val & 0xff) == 0)
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++;
1300 + if (((val >> 8) & 0xff) == 0)
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++;
1310 + * Read power calibration info
1312 + mode = AR5K_EEPROM_MODE_11A;
1313 + ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
1317 + mode = AR5K_EEPROM_MODE_11B;
1318 + ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
1322 + mode = AR5K_EEPROM_MODE_11G;
1323 + ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
1329 + * Read per rate target power info
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);
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);
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);
1352 +static const char *ath5k_hw_get_mac_name(u_int8_t val)
1354 + static char name[16];
1357 + for (i = 0; i < ARRAY_SIZE(ath5k_mac_names); i++) {
1358 + if (val <= ath5k_mac_names[i].sr_val)
1362 + if (val == ath5k_mac_names[i].sr_val)
1363 + return ath5k_mac_names[i].sr_name;
1365 + snprintf(name, sizeof(name), "%s+", ath5k_mac_names[i - 1].sr_name);
1369 +static const char *ath5k_hw_get_phy_name(u_int8_t val)
1371 + const char *name = "?????";
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;
1384 /* returns -1 on unknown name */
1385 static int eeprom_name2addr(const char *name)
1390 if (!name || !name[0])
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;
1397 -} /* eeprom_name2addr */
1400 /* returns "<unknown>" on unknown address */
1401 static const char *eeprom_addr2name(int addr)
1404 - for (i = 0; i < eeprom_addr_len; i++)
1407 + for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
1408 if (eeprom_addr[i].addr == addr)
1409 return eeprom_addr[i].name;
1411 -} /* eeprom_addr2name */
1415 -do_write_pairs(int anr, int argc, char **argv, unsigned char *mem,
1417 +static int do_write_pairs(int anr, int argc, char **argv, unsigned char *mem,
1420 #define MAX_NR_WRITES 16
1422 @@ -635,7 +1422,7 @@ do_write_pairs(int anr, int argc, char *
1426 - } /* while (anr < (argc-1)) */
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 *
1434 return errors ? 11 : 0;
1435 -} /* do_write_pairs */
1438 static void usage(const char *n)
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);
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");
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");
1469 @@ -739,19 +1528,457 @@ static void usage(const char *n)
1470 "unlawful radio transmissions!\n\n");
1473 +static void dump_capabilities(struct ath5k_eeprom_info *ee)
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;
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);
1488 + printf("|================= Capabilities ================|\n");
1490 + printf("| 802.11a Support: ");
1496 + printf(" Turbo-A disabled:");
1498 + printf(" yes |\n");
1500 + printf(" no |\n");
1502 + printf("| 802.11b Support: ");
1508 + printf(" Turbo-G disabled:");
1510 + printf(" yes |\n");
1512 + printf(" no |\n");
1514 + printf("| 802.11g Support: ");
1520 + printf(" 2GHz XR disabled:");
1522 + printf(" yes |\n");
1524 + printf(" no |\n");
1526 + printf("| RFKill Support: ");
1532 + printf(" 5GHz XR disabled:");
1534 + printf(" yes |\n");
1536 + printf(" no |\n");
1538 + if (has_crystal != 2) {
1539 + printf("| 32kHz Crystal: ");
1548 + printf("\\===============================================/\n");
1551 +static void dump_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
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]);
1580 + printf(" Antenna control %2i: 0x%02x |\n", i, ee->ee_ant_control[mode][i]);
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]);
1587 + printf("\\=========================================================/\n");
1590 +static void dump_power_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
1592 + struct ath5k_chan_pcal_info *chan_pcal_info;
1593 + u_int16_t cal_piers;
1597 + case AR5K_EEPROM_MODE_11A:
1598 + chan_pcal_info = ee->ee_pwr_cal_a;
1599 + cal_piers = ee->ee_cal_piers_a;
1601 + case AR5K_EEPROM_MODE_11B:
1602 + chan_pcal_info = ee->ee_pwr_cal_b;
1603 + cal_piers = ee->ee_cal_piers_b;
1605 + case AR5K_EEPROM_MODE_11G:
1606 + chan_pcal_info = ee->ee_pwr_cal_g;
1607 + cal_piers = ee->ee_cal_piers_g;
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");
1617 + for (i = 0; i < cal_piers; i++) {
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);
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);
1630 + printf(" %2i.%02i |\n", chan_pcal_info[i].max_pwr / 4,
1631 + chan_pcal_info[i].max_pwr % 4);
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);
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);
1647 + printf("\\======================================================================/\n");
1650 +static void dump_rate_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
1653 + struct ath5k_rate_pcal_info *rate_pcal_info;
1654 + u_int16_t rate_target_pwr_num;
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;
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;
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;
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");
1677 + printf("| Freq | 6-24Mbit/s | 36Mbit/s | 48Mbit/s | 54Mbit/s |\n");
1679 + for (i = 0; i < rate_target_pwr_num; i++) {
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);
1692 + printf("\\=====================================================/\n");
1695 +static u_int32_t extend_tu(u_int32_t base_tu, u_int32_t val, u_int32_t mask)
1699 + result = (base_tu & ~mask) | (val & mask);
1700 + if ((base_tu & mask) > (val & mask))
1701 + result += mask + 1;
1705 +static void dump_timers_register(void *mem, u_int16_t mac_version)
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)
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)
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)
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)
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)
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)
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)
1742 +#define AR5K_LAST_TSTP 0x8080
1744 + const int timer_mask = 0xffff;
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;
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 */
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);
1758 + now_tu = now_tsf >> 10;
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);
1775 + printf("BEACON: 0x%08x\n", AR5K_REG_READ(AR5K_BEACON));
1776 + printf("LAST_TSTP: 0x%08x\n", AR5K_REG_READ(AR5K_LAST_TSTP));
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)
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
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)
1795 +static void keycache_dump(void *mem, u_int16_t mac_version)
1798 + u_int32_t val0, val1, val2, val3, val4, keytype, ant, mac0, mac1;
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;
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;
1822 + mac0 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 6));
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",
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);
1846 +/* copy key index (0) to key index (idx) */
1848 +static void keycache_copy(void *mem, u_int16_t mac_version, int idx)
1850 + u_int32_t val0, val1, val2, val3, val4, keytype, mac0, mac1;
1852 + printf("Copying keycache entry 0 to %d\n", idx);
1853 + if (idx < 0 || idx >= AR5K_KEYTABLE_SIZE) {
1854 + printf("invalid keycache index\n");
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));
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);
1877 +static void sta_id0_id1_dump(void *mem)
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
1885 + u_int32_t sta_id0, sta_id1;
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",
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);
1904 CMD(athinfo)(int argc, char *argv[])
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;
1922 int do_write = 0; /* default: read only */
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;
1933 @@ -759,7 +1986,7 @@ CMD(athinfo)(int argc, char *argv[])
1934 } gpio_set[AR5K_NUM_GPIO];
1935 int nr_gpio_set = 0;
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;
1942 @@ -769,6 +1996,15 @@ CMD(athinfo)(int argc, char *argv[])
1944 while (anr < argc && argv[anr][0] == '-') {
1945 switch (argv[anr][1]) {
1947 + if (++anr < argc) {
1948 + timer_count = atoi(argv[anr]);
1949 + printf("timer_count:%d\n", timer_count);
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]);
1966 gpio_set[argv[anr][0] - '0'].valid = 1;
1967 @@ -797,6 +2033,25 @@ CMD(athinfo)(int argc, char *argv[])
1973 + reg_read = strtoul(argv[anr], NULL, 16);
1978 + reg_write = strtoul(argv[anr++], NULL, 16);
1979 + reg_write_val = strtoul(argv[anr], NULL, 16);
1983 + do_keycache_dump = 1;
1987 + keycache_copy_idx = atoi(argv[++anr]);
1993 @@ -805,10 +2060,10 @@ CMD(athinfo)(int argc, char *argv[])
1995 err("unknown option %s", argv[anr]);
1997 - } /* switch (argv[anr][1]) */
2001 - } /* while (anr < argc && ...) */
2005 err("missing device address");
2006 @@ -816,7 +2071,7 @@ CMD(athinfo)(int argc, char *argv[])
2010 - dev_addr = strtoul(argv[anr], NULL, 16);
2011 + dev_addr = strtoull(argv[anr], NULL, 16);
2013 fd = open("/dev/mem", O_RDWR);
2015 @@ -828,7 +2083,7 @@ CMD(athinfo)(int argc, char *argv[])
2016 MAP_SHARED | MAP_FILE, fd, dev_addr);
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));
2024 @@ -856,10 +2111,31 @@ CMD(athinfo)(int argc, char *argv[])
2025 AR5K_REG_DISABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_SPWR_DN);
2029 + printf("READ %04x = %08x\n", reg_read, AR5K_REG_READ(reg_read));
2034 + printf("WRITE %04x = %08x\n", reg_write, reg_write_val);
2035 + AR5K_REG_WRITE(reg_write, reg_write_val);
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);
2045 + mac_version = srev & AR5K_SREV_VER;
2046 + mac_revision = srev & AR5K_SREV_REV;
2048 - /* Verify eeprom magic value first */
2049 + printf(" -==Device Information==-\n");
2051 + printf("MAC Revision: %-5s (0x%02x)\n",
2052 + ath5k_hw_get_mac_name(mac_revision), mac_revision);
2054 + /* Verify EEPROM magic value first */
2055 error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_MAGIC, &ee_magic,
2058 @@ -872,157 +2148,114 @@ CMD(athinfo)(int argc, char *argv[])
2059 printf("Warning: Invalid EEPROM Magic number!\n");
2062 - error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_HDR, &eeprom_header,
2066 - printf("Unable to read EEPROM Header!\n");
2070 - error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_VERSION, &eeprom_version,
2074 - printf("Unable to read EEPROM version!\n");
2075 + ee = calloc(sizeof(struct ath5k_eeprom_info), 1);
2077 + printf("Cannot allocate memory for EEPROM information\n");
2081 - error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_REG_DOMAIN, ®domain,
2085 - printf("Unable to read Regdomain!\n");
2086 + if (ath5k_eeprom_init(mem, mac_version, ee)) {
2087 + printf("EEPROM init failed\n");
2091 - if (eeprom_version >= 0x4000) {
2092 - error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_MISC0,
2093 - &has_crystal, mac_version);
2096 - printf("Unable to read EEPROM Misc data!\n");
2100 - has_crystal = AR5K_EEPROM_HAS32KHZCRYSTAL(has_crystal);
2105 eeprom_size = AR5K_REG_MS(AR5K_REG_READ(AR5K_PCICFG),
2106 AR5K_PCICFG_EESIZE);
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);
2116 + /* 1 = ?? 2 = ?? 3 = card 4 = wmac */
2117 + printf("Device type: %1i\n", dev_type);
2119 + if (AR5K_EEPROM_HDR_11A(ee->ee_header))
2120 phy_rev_5ghz = ath5k_hw_radio_revision(mac_version, mem, 1);
2125 + if (AR5K_EEPROM_HDR_11B(ee->ee_header))
2126 phy_rev_2ghz = ath5k_hw_radio_revision(mac_version, mem, 0);
2130 - printf(" -==Device Information==-\n");
2132 - printf("MAC Version: %-5s (0x%02x)\n",
2133 - ath5k_hw_get_part_name(AR5K_VERSION_VER, mac_version),
2136 - printf("MAC Revision: %-5s (0x%02x)\n",
2137 - ath5k_hw_get_part_name(AR5K_VERSION_VER, srev), srev);
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),
2147 - /* Single-chip PHY with b/g support */
2149 - printf("PHY Revision: %-5s (0x%02x)\n",
2150 - ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_2ghz),
2155 - /* Different chip for 5Ghz and 2Ghz */
2157 - printf("5Ghz PHY Revision: %-5s (0x%2x)\n",
2158 - ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_5ghz),
2160 + printf("5GHz PHY Revision: %-5s (0x%02x)\n",
2161 + ath5k_hw_get_phy_name(phy_rev_5ghz), phy_rev_5ghz);
2164 - printf("2Ghz PHY Revision: %-5s (0x%2x)\n",
2165 - ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_2ghz),
2167 + printf("2GHz PHY Revision: %-5s (0x%02x)\n",
2168 + ath5k_hw_get_phy_name(phy_rev_2ghz), phy_rev_2ghz);
2171 - printf(" -==EEPROM Information==-\n");
2173 - printf("EEPROM Version: %x.%x\n",
2174 - (eeprom_version & 0xF000) >> 12, eeprom_version & 0xFFF);
2176 + printf("/============== EEPROM Information =============\\\n");
2177 + printf("| EEPROM Version: %1x.%1x |",
2178 + (ee->ee_version & 0xF000) >> 12, ee->ee_version & 0xFFF);
2180 - printf("EEPROM Size: ");
2181 + printf(" EEPROM Size: ");
2183 if (eeprom_size == 0) {
2186 + printf(" 4 kbit |\n");
2187 + byte_size = 4096 / 8;
2188 } else if (eeprom_size == 1) {
2191 + printf(" 8 kbit |\n");
2192 + byte_size = 8192 / 8;
2193 } else if (eeprom_size == 2) {
2195 - byte_size = 16384;
2196 + printf(" 16 kbit |\n");
2197 + byte_size = 16384 / 8;
2200 + printf(" unknown |\n");
2202 - printf("Regulatory Domain: 0x%X\n", regdomain);
2204 - printf(" -==== Capabilities ====-\n");
2206 - printf("| 802.11a Support: ");
2208 - printf("yes |\n");
2212 - printf("| 802.11b Support: ");
2214 - printf("yes |\n");
2217 + printf("| EEMAP: %i |", eemap);
2219 - printf("| 802.11g Support: ");
2221 - printf("yes |\n");
2224 + printf(" Reg. Domain: 0x%02X |\n", ee->ee_regdomain);
2226 - printf("| RFKill Support: ");
2228 - printf("yes |\n");
2231 + dump_capabilities(ee);
2234 - if (has_crystal != 2) {
2235 - printf("| 32KHz Crystal: ");
2237 - printf("yes |\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");
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);
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);
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);
2280 - printf(" ========================\n");
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));
2288 @@ -1030,18 +2263,18 @@ CMD(athinfo)(int argc, char *argv[])
2290 FILE *dumpfile = fopen("ath-eeprom-dump.bin", "w");
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++) {
2298 ath5k_hw_eeprom_read(mem, i, &data, mac_version);
2300 printf("\nUnable to read at %04x\n", i);
2303 - if (!((i - 1) % 8))
2304 - printf("\n%04x: ", i);
2305 - printf("%04x ", data);
2307 + printf("\n%04x: ", i);
2308 + printf(" %04x", data);
2309 fwrite(&data, 2, 1, dumpfile);
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;
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",
2321 gpio_set[4].valid = 1;
2322 gpio_set[4].value = 0;
2327 dbg("old GPIO CR %08x DO %08x DI %08x",
2328 rcr, rdo, AR5K_REG_READ(AR5K_GPIODI));
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[])
2340 + sta_id0_id1_dump(mem);
2342 + for (i = 0; i < timer_count; i++)
2343 + dump_timers_register(mem, mac_version);
2345 + if (do_keycache_dump)
2346 + keycache_dump(mem, mac_version);
2348 + if (keycache_copy_idx > 0)
2349 + keycache_copy(mem, mac_version, keycache_copy_idx);