[package] madwifi: remove cruft from madwifi.sh introduced by r15954, thanks Vasilis...
[openwrt.git] / 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  }