2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 /*************************************\
21 * EEPROM access functions and helpers *
22 \*************************************/
32 static int ath5k_hw_eeprom_read(struct ath5k_hw
*ah
, u32 offset
, u16
*data
)
36 ATH5K_TRACE(ah
->ah_sc
);
38 * Initialize EEPROM access
40 if (ah
->ah_version
== AR5K_AR5210
) {
41 AR5K_REG_ENABLE_BITS(ah
, AR5K_PCICFG
, AR5K_PCICFG_EEAE
);
42 (void)ath5k_hw_reg_read(ah
, AR5K_EEPROM_BASE
+ (4 * offset
));
44 ath5k_hw_reg_write(ah
, offset
, AR5K_EEPROM_BASE
);
45 AR5K_REG_ENABLE_BITS(ah
, AR5K_EEPROM_CMD
,
46 AR5K_EEPROM_CMD_READ
);
49 for (timeout
= AR5K_TUNE_REGISTER_TIMEOUT
; timeout
> 0; timeout
--) {
50 status
= ath5k_hw_reg_read(ah
, AR5K_EEPROM_STATUS
);
51 if (status
& AR5K_EEPROM_STAT_RDDONE
) {
52 if (status
& AR5K_EEPROM_STAT_RDERR
)
54 *data
= (u16
)(ath5k_hw_reg_read(ah
, AR5K_EEPROM_DATA
) &
65 * Translate binary channel representation in EEPROM to frequency
67 static u16
ath5k_eeprom_bin2freq(struct ath5k_eeprom_info
*ee
, u16 bin
,
72 if (bin
== AR5K_EEPROM_CHANNEL_DIS
)
75 if (mode
== AR5K_EEPROM_MODE_11A
) {
76 if (ee
->ee_version
> AR5K_EEPROM_VERSION_3_2
)
77 val
= (5 * bin
) + 4800;
79 val
= bin
> 62 ? (10 * 62) + (5 * (bin
- 62)) + 5100 :
82 if (ee
->ee_version
> AR5K_EEPROM_VERSION_3_2
)
92 * Initialize eeprom & capabilities structs
95 ath5k_eeprom_init_header(struct ath5k_hw
*ah
)
97 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
101 /* Initial TX thermal adjustment values */
103 ee
->ee_pwd_84
= ee
->ee_pwd_90
= 1;
104 ee
->ee_gain_select
= 1;
107 * Read values from EEPROM and store them in the capability structure
109 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC
, ee_magic
);
110 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT
, ee_protect
);
111 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN
, ee_regdomain
);
112 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION
, ee_version
);
113 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR
, ee_header
);
115 /* Return if we have an old EEPROM */
116 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_3_0
)
121 * Validate the checksum of the EEPROM date. There are some
122 * devices with invalid EEPROMs.
124 for (cksum
= 0, offset
= 0; offset
< AR5K_EEPROM_INFO_MAX
; offset
++) {
125 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset
), val
);
128 if (cksum
!= AR5K_EEPROM_INFO_CKSUM
) {
129 ATH5K_ERR(ah
->ah_sc
, "Invalid EEPROM checksum 0x%04x\n", cksum
);
134 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah
->ah_ee_version
),
137 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_0
) {
138 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0
, ee_misc0
);
139 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1
, ee_misc1
);
142 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_3_3
) {
143 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ
, val
);
144 ee
->ee_ob
[AR5K_EEPROM_MODE_11B
][0] = val
& 0x7;
145 ee
->ee_db
[AR5K_EEPROM_MODE_11B
][0] = (val
>> 3) & 0x7;
147 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ
, val
);
148 ee
->ee_ob
[AR5K_EEPROM_MODE_11G
][0] = val
& 0x7;
149 ee
->ee_db
[AR5K_EEPROM_MODE_11G
][0] = (val
>> 3) & 0x7;
157 * Read antenna infos from eeprom
159 static int ath5k_eeprom_read_ants(struct ath5k_hw
*ah
, u32
*offset
,
162 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
167 AR5K_EEPROM_READ(o
++, val
);
168 ee
->ee_switch_settling
[mode
] = (val
>> 8) & 0x7f;
169 ee
->ee_atn_tx_rx
[mode
] = (val
>> 2) & 0x3f;
170 ee
->ee_ant_control
[mode
][i
] = (val
<< 4) & 0x3f;
172 AR5K_EEPROM_READ(o
++, val
);
173 ee
->ee_ant_control
[mode
][i
++] |= (val
>> 12) & 0xf;
174 ee
->ee_ant_control
[mode
][i
++] = (val
>> 6) & 0x3f;
175 ee
->ee_ant_control
[mode
][i
++] = val
& 0x3f;
177 AR5K_EEPROM_READ(o
++, val
);
178 ee
->ee_ant_control
[mode
][i
++] = (val
>> 10) & 0x3f;
179 ee
->ee_ant_control
[mode
][i
++] = (val
>> 4) & 0x3f;
180 ee
->ee_ant_control
[mode
][i
] = (val
<< 2) & 0x3f;
182 AR5K_EEPROM_READ(o
++, val
);
183 ee
->ee_ant_control
[mode
][i
++] |= (val
>> 14) & 0x3;
184 ee
->ee_ant_control
[mode
][i
++] = (val
>> 8) & 0x3f;
185 ee
->ee_ant_control
[mode
][i
++] = (val
>> 2) & 0x3f;
186 ee
->ee_ant_control
[mode
][i
] = (val
<< 4) & 0x3f;
188 AR5K_EEPROM_READ(o
++, val
);
189 ee
->ee_ant_control
[mode
][i
++] |= (val
>> 12) & 0xf;
190 ee
->ee_ant_control
[mode
][i
++] = (val
>> 6) & 0x3f;
191 ee
->ee_ant_control
[mode
][i
++] = val
& 0x3f;
193 /* Get antenna modes */
194 ah
->ah_antenna
[mode
][0] =
195 (ee
->ee_ant_control
[mode
][0] << 4) | 0x1;
196 ah
->ah_antenna
[mode
][AR5K_ANT_FIXED_A
] =
197 ee
->ee_ant_control
[mode
][1] |
198 (ee
->ee_ant_control
[mode
][2] << 6) |
199 (ee
->ee_ant_control
[mode
][3] << 12) |
200 (ee
->ee_ant_control
[mode
][4] << 18) |
201 (ee
->ee_ant_control
[mode
][5] << 24);
202 ah
->ah_antenna
[mode
][AR5K_ANT_FIXED_B
] =
203 ee
->ee_ant_control
[mode
][6] |
204 (ee
->ee_ant_control
[mode
][7] << 6) |
205 (ee
->ee_ant_control
[mode
][8] << 12) |
206 (ee
->ee_ant_control
[mode
][9] << 18) |
207 (ee
->ee_ant_control
[mode
][10] << 24);
209 /* return new offset */
216 * Read supported modes from eeprom
218 static int ath5k_eeprom_read_modes(struct ath5k_hw
*ah
, u32
*offset
,
221 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
226 ee
->ee_n_piers
[mode
] = 0;
227 AR5K_EEPROM_READ(o
++, val
);
228 ee
->ee_adc_desired_size
[mode
] = (s8
)((val
>> 8) & 0xff);
230 case AR5K_EEPROM_MODE_11A
:
231 ee
->ee_ob
[mode
][3] = (val
>> 5) & 0x7;
232 ee
->ee_db
[mode
][3] = (val
>> 2) & 0x7;
233 ee
->ee_ob
[mode
][2] = (val
<< 1) & 0x7;
235 AR5K_EEPROM_READ(o
++, val
);
236 ee
->ee_ob
[mode
][2] |= (val
>> 15) & 0x1;
237 ee
->ee_db
[mode
][2] = (val
>> 12) & 0x7;
238 ee
->ee_ob
[mode
][1] = (val
>> 9) & 0x7;
239 ee
->ee_db
[mode
][1] = (val
>> 6) & 0x7;
240 ee
->ee_ob
[mode
][0] = (val
>> 3) & 0x7;
241 ee
->ee_db
[mode
][0] = val
& 0x7;
243 case AR5K_EEPROM_MODE_11G
:
244 case AR5K_EEPROM_MODE_11B
:
245 ee
->ee_ob
[mode
][1] = (val
>> 4) & 0x7;
246 ee
->ee_db
[mode
][1] = val
& 0x7;
250 AR5K_EEPROM_READ(o
++, val
);
251 ee
->ee_tx_end2xlna_enable
[mode
] = (val
>> 8) & 0xff;
252 ee
->ee_thr_62
[mode
] = val
& 0xff;
254 if (ah
->ah_ee_version
<= AR5K_EEPROM_VERSION_3_2
)
255 ee
->ee_thr_62
[mode
] = mode
== AR5K_EEPROM_MODE_11A
? 15 : 28;
257 AR5K_EEPROM_READ(o
++, val
);
258 ee
->ee_tx_end2xpa_disable
[mode
] = (val
>> 8) & 0xff;
259 ee
->ee_tx_frm2xpa_enable
[mode
] = val
& 0xff;
261 AR5K_EEPROM_READ(o
++, val
);
262 ee
->ee_pga_desired_size
[mode
] = (val
>> 8) & 0xff;
264 if ((val
& 0xff) & 0x80)
265 ee
->ee_noise_floor_thr
[mode
] = -((((val
& 0xff) ^ 0xff)) + 1);
267 ee
->ee_noise_floor_thr
[mode
] = val
& 0xff;
269 if (ah
->ah_ee_version
<= AR5K_EEPROM_VERSION_3_2
)
270 ee
->ee_noise_floor_thr
[mode
] =
271 mode
== AR5K_EEPROM_MODE_11A
? -54 : -1;
273 AR5K_EEPROM_READ(o
++, val
);
274 ee
->ee_xlna_gain
[mode
] = (val
>> 5) & 0xff;
275 ee
->ee_x_gain
[mode
] = (val
>> 1) & 0xf;
276 ee
->ee_xpd
[mode
] = val
& 0x1;
278 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_0
)
279 ee
->ee_fixed_bias
[mode
] = (val
>> 13) & 0x1;
281 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_3_3
) {
282 AR5K_EEPROM_READ(o
++, val
);
283 ee
->ee_false_detect
[mode
] = (val
>> 6) & 0x7f;
285 if (mode
== AR5K_EEPROM_MODE_11A
)
286 ee
->ee_xr_power
[mode
] = val
& 0x3f;
288 ee
->ee_ob
[mode
][0] = val
& 0x7;
289 ee
->ee_db
[mode
][0] = (val
>> 3) & 0x7;
293 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_3_4
) {
294 ee
->ee_i_gain
[mode
] = AR5K_EEPROM_I_GAIN
;
295 ee
->ee_cck_ofdm_power_delta
= AR5K_EEPROM_CCK_OFDM_DELTA
;
297 ee
->ee_i_gain
[mode
] = (val
>> 13) & 0x7;
299 AR5K_EEPROM_READ(o
++, val
);
300 ee
->ee_i_gain
[mode
] |= (val
<< 3) & 0x38;
302 if (mode
== AR5K_EEPROM_MODE_11G
) {
303 ee
->ee_cck_ofdm_power_delta
= (val
>> 3) & 0xff;
304 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_6
)
305 ee
->ee_scaled_cck_delta
= (val
>> 11) & 0x1f;
309 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_0
&&
310 mode
== AR5K_EEPROM_MODE_11A
) {
311 ee
->ee_i_cal
[mode
] = (val
>> 8) & 0x3f;
312 ee
->ee_q_cal
[mode
] = (val
>> 3) & 0x1f;
315 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_4_0
)
319 case AR5K_EEPROM_MODE_11A
:
320 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_4_1
)
323 AR5K_EEPROM_READ(o
++, val
);
324 ee
->ee_margin_tx_rx
[mode
] = val
& 0x3f;
326 case AR5K_EEPROM_MODE_11B
:
327 AR5K_EEPROM_READ(o
++, val
);
329 ee
->ee_pwr_cal_b
[0].freq
=
330 ath5k_eeprom_bin2freq(ee
, val
& 0xff, mode
);
331 if (ee
->ee_pwr_cal_b
[0].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
332 ee
->ee_n_piers
[mode
]++;
334 ee
->ee_pwr_cal_b
[1].freq
=
335 ath5k_eeprom_bin2freq(ee
, (val
>> 8) & 0xff, mode
);
336 if (ee
->ee_pwr_cal_b
[1].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
337 ee
->ee_n_piers
[mode
]++;
339 AR5K_EEPROM_READ(o
++, val
);
340 ee
->ee_pwr_cal_b
[2].freq
=
341 ath5k_eeprom_bin2freq(ee
, val
& 0xff, mode
);
342 if (ee
->ee_pwr_cal_b
[2].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
343 ee
->ee_n_piers
[mode
]++;
345 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_1
)
346 ee
->ee_margin_tx_rx
[mode
] = (val
>> 8) & 0x3f;
348 case AR5K_EEPROM_MODE_11G
:
349 AR5K_EEPROM_READ(o
++, val
);
351 ee
->ee_pwr_cal_g
[0].freq
=
352 ath5k_eeprom_bin2freq(ee
, val
& 0xff, mode
);
353 if (ee
->ee_pwr_cal_g
[0].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
354 ee
->ee_n_piers
[mode
]++;
356 ee
->ee_pwr_cal_g
[1].freq
=
357 ath5k_eeprom_bin2freq(ee
, (val
>> 8) & 0xff, mode
);
358 if (ee
->ee_pwr_cal_g
[1].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
359 ee
->ee_n_piers
[mode
]++;
361 AR5K_EEPROM_READ(o
++, val
);
362 ee
->ee_turbo_max_power
[mode
] = val
& 0x7f;
363 ee
->ee_xr_power
[mode
] = (val
>> 7) & 0x3f;
365 AR5K_EEPROM_READ(o
++, val
);
366 ee
->ee_pwr_cal_g
[2].freq
=
367 ath5k_eeprom_bin2freq(ee
, val
& 0xff, mode
);
368 if (ee
->ee_pwr_cal_g
[2].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
369 ee
->ee_n_piers
[mode
]++;
371 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_1
)
372 ee
->ee_margin_tx_rx
[mode
] = (val
>> 8) & 0x3f;
374 AR5K_EEPROM_READ(o
++, val
);
375 ee
->ee_i_cal
[mode
] = (val
>> 8) & 0x3f;
376 ee
->ee_q_cal
[mode
] = (val
>> 3) & 0x1f;
378 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_2
) {
379 AR5K_EEPROM_READ(o
++, val
);
380 ee
->ee_cck_ofdm_gain_delta
= val
& 0xff;
386 /* return new offset */
393 * Read turbo mode information on newer EEPROM versions
396 ath5k_eeprom_read_turbo_modes(struct ath5k_hw
*ah
,
397 u32
*offset
, unsigned int mode
)
399 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
404 if (ee
->ee_version
< AR5K_EEPROM_VERSION_5_0
)
408 case AR5K_EEPROM_MODE_11A
:
409 ee
->ee_switch_settling_turbo
[mode
] = (val
>> 6) & 0x7f;
411 ee
->ee_atn_tx_rx_turbo
[mode
] = (val
>> 13) & 0x7;
412 AR5K_EEPROM_READ(o
++, val
);
413 ee
->ee_atn_tx_rx_turbo
[mode
] |= (val
& 0x7) << 3;
414 ee
->ee_margin_tx_rx_turbo
[mode
] = (val
>> 3) & 0x3f;
416 ee
->ee_adc_desired_size_turbo
[mode
] = (val
>> 9) & 0x7f;
417 AR5K_EEPROM_READ(o
++, val
);
418 ee
->ee_adc_desired_size_turbo
[mode
] |= (val
& 0x1) << 7;
419 ee
->ee_pga_desired_size_turbo
[mode
] = (val
>> 1) & 0xff;
421 if (AR5K_EEPROM_EEMAP(ee
->ee_misc0
) >=2)
422 ee
->ee_pd_gain_overlap
= (val
>> 9) & 0xf;
424 case AR5K_EEPROM_MODE_11G
:
425 ee
->ee_switch_settling_turbo
[mode
] = (val
>> 8) & 0x7f;
427 ee
->ee_atn_tx_rx_turbo
[mode
] = (val
>> 15) & 0x7;
428 AR5K_EEPROM_READ(o
++, val
);
429 ee
->ee_atn_tx_rx_turbo
[mode
] |= (val
& 0x1f) << 1;
430 ee
->ee_margin_tx_rx_turbo
[mode
] = (val
>> 5) & 0x3f;
432 ee
->ee_adc_desired_size_turbo
[mode
] = (val
>> 11) & 0x7f;
433 AR5K_EEPROM_READ(o
++, val
);
434 ee
->ee_adc_desired_size_turbo
[mode
] |= (val
& 0x7) << 5;
435 ee
->ee_pga_desired_size_turbo
[mode
] = (val
>> 3) & 0xff;
439 /* return new offset */
447 ath5k_eeprom_init_modes(struct ath5k_hw
*ah
)
449 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
456 * Get values for all modes
458 mode_offset
[AR5K_EEPROM_MODE_11A
] = AR5K_EEPROM_MODES_11A(ah
->ah_ee_version
);
459 mode_offset
[AR5K_EEPROM_MODE_11B
] = AR5K_EEPROM_MODES_11B(ah
->ah_ee_version
);
460 mode_offset
[AR5K_EEPROM_MODE_11G
] = AR5K_EEPROM_MODES_11G(ah
->ah_ee_version
);
462 ee
->ee_turbo_max_power
[AR5K_EEPROM_MODE_11A
] =
463 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee
->ee_header
);
465 for (mode
= AR5K_EEPROM_MODE_11A
; mode
<= AR5K_EEPROM_MODE_11G
; mode
++) {
466 offset
= mode_offset
[mode
];
468 ret
= ath5k_eeprom_read_ants(ah
, &offset
, mode
);
472 ret
= ath5k_eeprom_read_modes(ah
, &offset
, mode
);
476 ret
= ath5k_eeprom_read_turbo_modes(ah
, &offset
, mode
);
481 /* override for older eeprom versions for better performance */
482 if (ah
->ah_ee_version
<= AR5K_EEPROM_VERSION_3_2
) {
483 ee
->ee_thr_62
[AR5K_EEPROM_MODE_11A
] = 15;
484 ee
->ee_thr_62
[AR5K_EEPROM_MODE_11B
] = 28;
485 ee
->ee_thr_62
[AR5K_EEPROM_MODE_11G
] = 28;
492 ath5k_get_pcdac_intercepts(struct ath5k_hw
*ah
, u8 min
, u8 max
, u8
*vp
)
494 const static u16 intercepts3
[] =
495 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
496 const static u16 intercepts3_2
[] =
497 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
501 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_3_2
)
506 for (i
= 0; i
< ARRAY_SIZE(intercepts3
); i
++)
507 *vp
++ = (ip
[i
] * max
+ (100 - ip
[i
]) * min
) / 100;
511 ath5k_eeprom_read_freq_list(struct ath5k_hw
*ah
, int *offset
, int max
,
512 struct ath5k_chan_pcal_info
*pc
, u8
*count
)
521 AR5K_EEPROM_READ(o
++, val
);
523 f1
= (val
>> 8) & 0xff;
542 ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw
*ah
, int offset
)
544 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
545 struct ath5k_chan_pcal_info
*pcal
= ee
->ee_pwr_cal_a
;
550 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_3_3
) {
551 ath5k_eeprom_read_freq_list(ah
, &offset
,
552 AR5K_EEPROM_N_5GHZ_CHAN
, pcal
,
553 &ee
->ee_n_piers
[AR5K_EEPROM_MODE_11A
]);
555 mask
= AR5K_EEPROM_FREQ_M(ah
->ah_ee_version
);
557 AR5K_EEPROM_READ(offset
++, val
);
558 pcal
[0].freq
= (val
>> 9) & mask
;
559 pcal
[1].freq
= (val
>> 2) & mask
;
560 pcal
[2].freq
= (val
<< 5) & mask
;
562 AR5K_EEPROM_READ(offset
++, val
);
563 pcal
[2].freq
|= (val
>> 11) & 0x1f;
564 pcal
[3].freq
= (val
>> 4) & mask
;
565 pcal
[4].freq
= (val
<< 3) & mask
;
567 AR5K_EEPROM_READ(offset
++, val
);
568 pcal
[4].freq
|= (val
>> 13) & 0x7;
569 pcal
[5].freq
= (val
>> 6) & mask
;
570 pcal
[6].freq
= (val
<< 1) & mask
;
572 AR5K_EEPROM_READ(offset
++, val
);
573 pcal
[6].freq
|= (val
>> 15) & 0x1;
574 pcal
[7].freq
= (val
>> 8) & mask
;
575 pcal
[8].freq
= (val
>> 1) & mask
;
576 pcal
[9].freq
= (val
<< 6) & mask
;
578 AR5K_EEPROM_READ(offset
++, val
);
579 pcal
[9].freq
|= (val
>> 10) & 0x3f;
580 ee
->ee_n_piers
[AR5K_EEPROM_MODE_11A
] = 10;
583 for(i
= 0; i
< AR5K_EEPROM_N_5GHZ_CHAN
; i
+= 1) {
584 pcal
[i
].freq
= ath5k_eeprom_bin2freq(ee
,
585 pcal
[i
].freq
, AR5K_EEPROM_MODE_11A
);
592 ath5k_eeprom_init_11bg_2413(struct ath5k_hw
*ah
, unsigned int mode
, int offset
)
594 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
595 struct ath5k_chan_pcal_info
*pcal
;
599 case AR5K_EEPROM_MODE_11B
:
600 pcal
= ee
->ee_pwr_cal_b
;
602 case AR5K_EEPROM_MODE_11G
:
603 pcal
= ee
->ee_pwr_cal_g
;
609 ath5k_eeprom_read_freq_list(ah
, &offset
,
610 AR5K_EEPROM_N_2GHZ_CHAN_2413
, pcal
,
611 &ee
->ee_n_piers
[mode
]);
612 for(i
= 0; i
< AR5K_EEPROM_N_2GHZ_CHAN_2413
; i
+= 1) {
613 pcal
[i
].freq
= ath5k_eeprom_bin2freq(ee
,
622 ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw
*ah
, int mode
)
624 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
625 struct ath5k_chan_pcal_info
*pcal
;
630 offset
= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
632 case AR5K_EEPROM_MODE_11A
:
633 if (!AR5K_EEPROM_HDR_11A(ee
->ee_header
))
636 ret
= ath5k_eeprom_init_11a_pcal_freq(ah
,
637 offset
+ AR5K_EEPROM_GROUP1_OFFSET
);
641 offset
+= AR5K_EEPROM_GROUP2_OFFSET
;
642 pcal
= ee
->ee_pwr_cal_a
;
644 case AR5K_EEPROM_MODE_11B
:
645 if (!AR5K_EEPROM_HDR_11B(ee
->ee_header
) &&
646 !AR5K_EEPROM_HDR_11G(ee
->ee_header
))
649 pcal
= ee
->ee_pwr_cal_b
;
650 offset
+= AR5K_EEPROM_GROUP3_OFFSET
;
656 ee
->ee_n_piers
[mode
] = 3;
658 case AR5K_EEPROM_MODE_11G
:
659 if (!AR5K_EEPROM_HDR_11G(ee
->ee_header
))
662 pcal
= ee
->ee_pwr_cal_g
;
663 offset
+= AR5K_EEPROM_GROUP4_OFFSET
;
669 ee
->ee_n_piers
[mode
] = 3;
675 for (i
= 0; i
< ee
->ee_n_piers
[mode
]; i
++) {
676 struct ath5k_chan_pcal_info_rf5111
*cdata
=
677 &pcal
[i
].rf5111_info
;
679 AR5K_EEPROM_READ(offset
++, val
);
680 cdata
->pcdac_max
= ((val
>> 10) & AR5K_EEPROM_PCDAC_M
);
681 cdata
->pcdac_min
= ((val
>> 4) & AR5K_EEPROM_PCDAC_M
);
682 cdata
->pwr
[0] = ((val
<< 2) & AR5K_EEPROM_POWER_M
);
684 AR5K_EEPROM_READ(offset
++, val
);
685 cdata
->pwr
[0] |= ((val
>> 14) & 0x3);
686 cdata
->pwr
[1] = ((val
>> 8) & AR5K_EEPROM_POWER_M
);
687 cdata
->pwr
[2] = ((val
>> 2) & AR5K_EEPROM_POWER_M
);
688 cdata
->pwr
[3] = ((val
<< 4) & AR5K_EEPROM_POWER_M
);
690 AR5K_EEPROM_READ(offset
++, val
);
691 cdata
->pwr
[3] |= ((val
>> 12) & 0xf);
692 cdata
->pwr
[4] = ((val
>> 6) & AR5K_EEPROM_POWER_M
);
693 cdata
->pwr
[5] = (val
& AR5K_EEPROM_POWER_M
);
695 AR5K_EEPROM_READ(offset
++, val
);
696 cdata
->pwr
[6] = ((val
>> 10) & AR5K_EEPROM_POWER_M
);
697 cdata
->pwr
[7] = ((val
>> 4) & AR5K_EEPROM_POWER_M
);
698 cdata
->pwr
[8] = ((val
<< 2) & AR5K_EEPROM_POWER_M
);
700 AR5K_EEPROM_READ(offset
++, val
);
701 cdata
->pwr
[8] |= ((val
>> 14) & 0x3);
702 cdata
->pwr
[9] = ((val
>> 8) & AR5K_EEPROM_POWER_M
);
703 cdata
->pwr
[10] = ((val
>> 2) & AR5K_EEPROM_POWER_M
);
705 ath5k_get_pcdac_intercepts(ah
, cdata
->pcdac_min
,
706 cdata
->pcdac_max
, cdata
->pcdac
);
708 for (j
= 0; j
< AR5K_EEPROM_N_PCDAC
; j
++) {
709 cdata
->pwr
[j
] = (u16
)
710 (AR5K_EEPROM_POWER_STEP
* cdata
->pwr
[j
]);
718 ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw
*ah
, int mode
)
720 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
721 struct ath5k_chan_pcal_info_rf5112
*chan_pcal_info
;
722 struct ath5k_chan_pcal_info
*gen_chan_info
;
729 case AR5K_EEPROM_MODE_11A
:
731 * Read 5GHz EEPROM channels
733 offset
= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
734 ath5k_eeprom_init_11a_pcal_freq(ah
, offset
);
736 offset
+= AR5K_EEPROM_GROUP2_OFFSET
;
737 gen_chan_info
= ee
->ee_pwr_cal_a
;
739 case AR5K_EEPROM_MODE_11B
:
740 offset
= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
741 if (AR5K_EEPROM_HDR_11A(ee
->ee_header
))
742 offset
+= AR5K_EEPROM_GROUP3_OFFSET
;
744 /* NB: frequency piers parsed during mode init */
745 gen_chan_info
= ee
->ee_pwr_cal_b
;
747 case AR5K_EEPROM_MODE_11G
:
748 offset
= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
749 if (AR5K_EEPROM_HDR_11A(ee
->ee_header
))
750 offset
+= AR5K_EEPROM_GROUP4_OFFSET
;
751 else if (AR5K_EEPROM_HDR_11B(ee
->ee_header
))
752 offset
+= AR5K_EEPROM_GROUP2_OFFSET
;
754 /* NB: frequency piers parsed during mode init */
755 gen_chan_info
= ee
->ee_pwr_cal_g
;
761 for (i
= 0; i
< ee
->ee_n_piers
[mode
]; i
++) {
762 chan_pcal_info
= &gen_chan_info
[i
].rf5112_info
;
764 /* Power values in dBm * 4
765 * for the lower xpd gain curve
766 * (0 dBm -> higher output power) */
767 for (c
= 0; c
< AR5K_EEPROM_N_XPD0_POINTS
; c
++) {
768 AR5K_EEPROM_READ(offset
++, val
);
769 chan_pcal_info
->pwr_x0
[c
] = (val
& 0xff);
770 chan_pcal_info
->pwr_x0
[++c
] = ((val
>> 8) & 0xff);
774 * corresponding to the above power
776 AR5K_EEPROM_READ(offset
++, val
);
777 chan_pcal_info
->pcdac_x0
[1] = (val
& 0x1f);
778 chan_pcal_info
->pcdac_x0
[2] = ((val
>> 5) & 0x1f);
779 chan_pcal_info
->pcdac_x0
[3] = ((val
>> 10) & 0x1f);
781 /* Power values in dBm * 4
782 * for the higher xpd gain curve
783 * (18 dBm -> lower output power) */
784 AR5K_EEPROM_READ(offset
++, val
);
785 chan_pcal_info
->pwr_x3
[0] = (val
& 0xff);
786 chan_pcal_info
->pwr_x3
[1] = ((val
>> 8) & 0xff);
788 AR5K_EEPROM_READ(offset
++, val
);
789 chan_pcal_info
->pwr_x3
[2] = (val
& 0xff);
792 * corresponding to the above power
793 * measurements (static) */
794 chan_pcal_info
->pcdac_x3
[0] = 20;
795 chan_pcal_info
->pcdac_x3
[1] = 35;
796 chan_pcal_info
->pcdac_x3
[2] = 63;
798 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_4_3
) {
799 chan_pcal_info
->pcdac_x0
[0] = ((val
>> 8) & 0xff);
801 /* Last xpd0 power level is also channel maximum */
802 gen_chan_info
[i
].max_pwr
= chan_pcal_info
->pwr_x0
[3];
804 chan_pcal_info
->pcdac_x0
[0] = 1;
805 gen_chan_info
[i
].max_pwr
= ((val
>> 8) & 0xff);
808 /* Recreate pcdac_x0 table for this channel using pcdac steps */
809 chan_pcal_info
->pcdac_x0
[1] += chan_pcal_info
->pcdac_x0
[0];
810 chan_pcal_info
->pcdac_x0
[2] += chan_pcal_info
->pcdac_x0
[1];
811 chan_pcal_info
->pcdac_x0
[3] += chan_pcal_info
->pcdac_x0
[2];
817 static inline unsigned int
818 ath5k_pdgains_size_2413(struct ath5k_eeprom_info
*ee
, unsigned int mode
)
820 static const unsigned int pdgains_size
[] = { 4, 6, 9, 12 };
823 sz
= pdgains_size
[ee
->ee_pd_gains
[mode
] - 1];
824 sz
*= ee
->ee_n_piers
[mode
];
830 ath5k_cal_data_offset_2413(struct ath5k_eeprom_info
*ee
, int mode
)
832 u32 offset
= AR5K_EEPROM_CAL_DATA_START(ee
->ee_misc4
);
835 case AR5K_EEPROM_MODE_11G
:
836 if (AR5K_EEPROM_HDR_11B(ee
->ee_header
))
837 offset
+= ath5k_pdgains_size_2413(ee
, AR5K_EEPROM_MODE_11B
) + 2;
839 case AR5K_EEPROM_MODE_11B
:
840 if (AR5K_EEPROM_HDR_11A(ee
->ee_header
))
841 offset
+= ath5k_pdgains_size_2413(ee
, AR5K_EEPROM_MODE_11A
) + 5;
843 case AR5K_EEPROM_MODE_11A
:
853 ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw
*ah
, int mode
)
855 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
856 struct ath5k_chan_pcal_info_rf2413
*chan_pcal_info
;
857 struct ath5k_chan_pcal_info
*gen_chan_info
;
864 if (ee
->ee_x_gain
[mode
] & 0x1) pd_gains
++;
865 if ((ee
->ee_x_gain
[mode
] >> 1) & 0x1) pd_gains
++;
866 if ((ee
->ee_x_gain
[mode
] >> 2) & 0x1) pd_gains
++;
867 if ((ee
->ee_x_gain
[mode
] >> 3) & 0x1) pd_gains
++;
868 ee
->ee_pd_gains
[mode
] = pd_gains
;
870 offset
= ath5k_cal_data_offset_2413(ee
, mode
);
872 case AR5K_EEPROM_MODE_11A
:
873 if (!AR5K_EEPROM_HDR_11A(ee
->ee_header
))
876 ath5k_eeprom_init_11a_pcal_freq(ah
, offset
);
877 offset
+= AR5K_EEPROM_N_5GHZ_CHAN
/ 2;
878 gen_chan_info
= ee
->ee_pwr_cal_a
;
880 case AR5K_EEPROM_MODE_11B
:
881 if (!AR5K_EEPROM_HDR_11B(ee
->ee_header
))
884 ath5k_eeprom_init_11bg_2413(ah
, mode
, offset
);
885 offset
+= AR5K_EEPROM_N_2GHZ_CHAN_2413
/ 2;
886 gen_chan_info
= ee
->ee_pwr_cal_b
;
888 case AR5K_EEPROM_MODE_11G
:
889 if (!AR5K_EEPROM_HDR_11G(ee
->ee_header
))
892 ath5k_eeprom_init_11bg_2413(ah
, mode
, offset
);
893 offset
+= AR5K_EEPROM_N_2GHZ_CHAN_2413
/ 2;
894 gen_chan_info
= ee
->ee_pwr_cal_g
;
903 for (i
= 0; i
< ee
->ee_n_piers
[mode
]; i
++) {
904 chan_pcal_info
= &gen_chan_info
[i
].rf2413_info
;
907 * Read pwr_i, pddac_i and the first
908 * 2 pd points (pwr, pddac)
910 AR5K_EEPROM_READ(offset
++, val
);
911 chan_pcal_info
->pwr_i
[0] = val
& 0x1f;
912 chan_pcal_info
->pddac_i
[0] = (val
>> 5) & 0x7f;
913 chan_pcal_info
->pwr
[0][0] =
916 AR5K_EEPROM_READ(offset
++, val
);
917 chan_pcal_info
->pddac
[0][0] = val
& 0x3f;
918 chan_pcal_info
->pwr
[0][1] = (val
>> 6) & 0xf;
919 chan_pcal_info
->pddac
[0][1] =
922 AR5K_EEPROM_READ(offset
++, val
);
923 chan_pcal_info
->pwr
[0][2] = val
& 0xf;
924 chan_pcal_info
->pddac
[0][2] =
927 chan_pcal_info
->pwr
[0][3] = 0;
928 chan_pcal_info
->pddac
[0][3] = 0;
932 * Pd gain 0 is not the last pd gain
933 * so it only has 2 pd points.
934 * Continue wih pd gain 1.
936 chan_pcal_info
->pwr_i
[1] = (val
>> 10) & 0x1f;
938 chan_pcal_info
->pddac_i
[1] = (val
>> 15) & 0x1;
939 AR5K_EEPROM_READ(offset
++, val
);
940 chan_pcal_info
->pddac_i
[1] |= (val
& 0x3F) << 1;
942 chan_pcal_info
->pwr
[1][0] = (val
>> 6) & 0xf;
943 chan_pcal_info
->pddac
[1][0] =
946 AR5K_EEPROM_READ(offset
++, val
);
947 chan_pcal_info
->pwr
[1][1] = val
& 0xf;
948 chan_pcal_info
->pddac
[1][1] =
950 chan_pcal_info
->pwr
[1][2] =
953 chan_pcal_info
->pddac
[1][2] =
955 AR5K_EEPROM_READ(offset
++, val
);
956 chan_pcal_info
->pddac
[1][2] |=
959 chan_pcal_info
->pwr
[1][3] = 0;
960 chan_pcal_info
->pddac
[1][3] = 0;
961 } else if (pd_gains
== 1) {
963 * Pd gain 0 is the last one so
964 * read the extra point.
966 chan_pcal_info
->pwr
[0][3] =
969 chan_pcal_info
->pddac
[0][3] =
971 AR5K_EEPROM_READ(offset
++, val
);
972 chan_pcal_info
->pddac
[0][3] |=
977 * Proceed with the other pd_gains
981 chan_pcal_info
->pwr_i
[2] = (val
>> 4) & 0x1f;
982 chan_pcal_info
->pddac_i
[2] = (val
>> 9) & 0x7f;
984 AR5K_EEPROM_READ(offset
++, val
);
985 chan_pcal_info
->pwr
[2][0] =
987 chan_pcal_info
->pddac
[2][0] =
989 chan_pcal_info
->pwr
[2][1] =
992 chan_pcal_info
->pddac
[2][1] =
994 AR5K_EEPROM_READ(offset
++, val
);
995 chan_pcal_info
->pddac
[2][1] |=
998 chan_pcal_info
->pwr
[2][2] =
1000 chan_pcal_info
->pddac
[2][2] =
1003 chan_pcal_info
->pwr
[2][3] = 0;
1004 chan_pcal_info
->pddac
[2][3] = 0;
1005 } else if (pd_gains
== 2) {
1006 chan_pcal_info
->pwr
[1][3] =
1008 chan_pcal_info
->pddac
[1][3] =
1013 chan_pcal_info
->pwr_i
[3] = (val
>> 14) & 0x3;
1014 AR5K_EEPROM_READ(offset
++, val
);
1015 chan_pcal_info
->pwr_i
[3] |= ((val
>> 0) & 0x7) << 2;
1017 chan_pcal_info
->pddac_i
[3] = (val
>> 3) & 0x7f;
1018 chan_pcal_info
->pwr
[3][0] =
1020 chan_pcal_info
->pddac
[3][0] =
1023 AR5K_EEPROM_READ(offset
++, val
);
1024 chan_pcal_info
->pddac
[3][0] |=
1026 chan_pcal_info
->pwr
[3][1] =
1028 chan_pcal_info
->pddac
[3][1] =
1031 chan_pcal_info
->pwr
[3][2] =
1033 AR5K_EEPROM_READ(offset
++, val
);
1034 chan_pcal_info
->pwr
[3][2] |=
1035 ((val
>> 0) & 0x3) << 2;
1037 chan_pcal_info
->pddac
[3][2] =
1039 chan_pcal_info
->pwr
[3][3] =
1042 chan_pcal_info
->pddac
[3][3] =
1044 AR5K_EEPROM_READ(offset
++, val
);
1045 chan_pcal_info
->pddac
[3][3] |=
1046 ((val
>> 0) & 0x3) << 4;
1047 } else if (pd_gains
== 3) {
1048 chan_pcal_info
->pwr
[2][3] =
1050 AR5K_EEPROM_READ(offset
++, val
);
1051 chan_pcal_info
->pwr
[2][3] |=
1052 ((val
>> 0) & 0x3) << 2;
1054 chan_pcal_info
->pddac
[2][3] =
1058 for (c
= 0; c
< pd_gains
; c
++) {
1059 /* Recreate pwr table for this channel using pwr steps */
1060 chan_pcal_info
->pwr
[c
][0] += chan_pcal_info
->pwr_i
[c
] * 2;
1061 chan_pcal_info
->pwr
[c
][1] += chan_pcal_info
->pwr
[c
][0];
1062 chan_pcal_info
->pwr
[c
][2] += chan_pcal_info
->pwr
[c
][1];
1063 chan_pcal_info
->pwr
[c
][3] += chan_pcal_info
->pwr
[c
][2];
1064 if (chan_pcal_info
->pwr
[c
][3] == chan_pcal_info
->pwr
[c
][2])
1065 chan_pcal_info
->pwr
[c
][3] = 0;
1067 /* Recreate pddac table for this channel using pddac steps */
1068 chan_pcal_info
->pddac
[c
][0] += chan_pcal_info
->pddac_i
[c
];
1069 chan_pcal_info
->pddac
[c
][1] += chan_pcal_info
->pddac
[c
][0];
1070 chan_pcal_info
->pddac
[c
][2] += chan_pcal_info
->pddac
[c
][1];
1071 chan_pcal_info
->pddac
[c
][3] += chan_pcal_info
->pddac
[c
][2];
1072 if (chan_pcal_info
->pddac
[c
][3] == chan_pcal_info
->pddac
[c
][2])
1073 chan_pcal_info
->pddac
[c
][3] = 0;
1081 * Read per rate target power (this is the maximum tx power
1082 * supported by the card). This info is used when setting
1083 * tx power, no matter the channel.
1085 * This also works for v5 EEPROMs.
1087 static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw
*ah
, unsigned int mode
)
1089 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
1090 struct ath5k_rate_pcal_info
*rate_pcal_info
;
1091 u16
*rate_target_pwr_num
;
1096 offset
= AR5K_EEPROM_TARGET_PWRSTART(ee
->ee_misc1
);
1097 rate_target_pwr_num
= &ee
->ee_rate_target_pwr_num
[mode
];
1099 case AR5K_EEPROM_MODE_11A
:
1100 offset
+= AR5K_EEPROM_TARGET_PWR_OFF_11A(ee
->ee_version
);
1101 rate_pcal_info
= ee
->ee_rate_tpwr_a
;
1102 ee
->ee_rate_target_pwr_num
[mode
] = AR5K_EEPROM_N_5GHZ_CHAN
;
1104 case AR5K_EEPROM_MODE_11B
:
1105 offset
+= AR5K_EEPROM_TARGET_PWR_OFF_11B(ee
->ee_version
);
1106 rate_pcal_info
= ee
->ee_rate_tpwr_b
;
1107 ee
->ee_rate_target_pwr_num
[mode
] = 2; /* 3rd is g mode's 1st */
1109 case AR5K_EEPROM_MODE_11G
:
1110 offset
+= AR5K_EEPROM_TARGET_PWR_OFF_11G(ee
->ee_version
);
1111 rate_pcal_info
= ee
->ee_rate_tpwr_g
;
1112 ee
->ee_rate_target_pwr_num
[mode
] = AR5K_EEPROM_N_2GHZ_CHAN
;
1118 /* Different freq mask for older eeproms (<= v3.2) */
1119 if (ee
->ee_version
<= AR5K_EEPROM_VERSION_3_2
) {
1120 for (i
= 0; i
< (*rate_target_pwr_num
); i
++) {
1121 AR5K_EEPROM_READ(offset
++, val
);
1122 rate_pcal_info
[i
].freq
=
1123 ath5k_eeprom_bin2freq(ee
, (val
>> 9) & 0x7f, mode
);
1125 rate_pcal_info
[i
].target_power_6to24
= ((val
>> 3) & 0x3f);
1126 rate_pcal_info
[i
].target_power_36
= (val
<< 3) & 0x3f;
1128 AR5K_EEPROM_READ(offset
++, val
);
1130 if (rate_pcal_info
[i
].freq
== AR5K_EEPROM_CHANNEL_DIS
||
1132 (*rate_target_pwr_num
) = i
;
1136 rate_pcal_info
[i
].target_power_36
|= ((val
>> 13) & 0x7);
1137 rate_pcal_info
[i
].target_power_48
= ((val
>> 7) & 0x3f);
1138 rate_pcal_info
[i
].target_power_54
= ((val
>> 1) & 0x3f);
1141 for (i
= 0; i
< (*rate_target_pwr_num
); i
++) {
1142 AR5K_EEPROM_READ(offset
++, val
);
1143 rate_pcal_info
[i
].freq
=
1144 ath5k_eeprom_bin2freq(ee
, (val
>> 8) & 0xff, mode
);
1146 rate_pcal_info
[i
].target_power_6to24
= ((val
>> 2) & 0x3f);
1147 rate_pcal_info
[i
].target_power_36
= (val
<< 4) & 0x3f;
1149 AR5K_EEPROM_READ(offset
++, val
);
1151 if (rate_pcal_info
[i
].freq
== AR5K_EEPROM_CHANNEL_DIS
||
1153 (*rate_target_pwr_num
) = i
;
1157 rate_pcal_info
[i
].target_power_36
|= (val
>> 12) & 0xf;
1158 rate_pcal_info
[i
].target_power_48
= ((val
>> 6) & 0x3f);
1159 rate_pcal_info
[i
].target_power_54
= (val
& 0x3f);
1167 ath5k_eeprom_read_pcal_info(struct ath5k_hw
*ah
)
1169 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
1170 int (*read_pcal
)(struct ath5k_hw
*hw
, int mode
);
1174 if ((ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_0
) &&
1175 (AR5K_EEPROM_EEMAP(ee
->ee_misc0
) == 1))
1176 read_pcal
= ath5k_eeprom_read_pcal_info_5112
;
1177 else if ((ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_5_0
) &&
1178 (AR5K_EEPROM_EEMAP(ee
->ee_misc0
) == 2))
1179 read_pcal
= ath5k_eeprom_read_pcal_info_2413
;
1181 read_pcal
= ath5k_eeprom_read_pcal_info_5111
;
1183 for (mode
= AR5K_EEPROM_MODE_11A
; mode
<= AR5K_EEPROM_MODE_11G
; mode
++) {
1184 err
= read_pcal(ah
, mode
);
1188 err
= ath5k_eeprom_read_target_rate_pwr_info(ah
, mode
);
1196 /* Read conformance test limits */
1198 ath5k_eeprom_read_ctl_info(struct ath5k_hw
*ah
)
1200 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
1201 struct ath5k_edge_power
*rep
;
1202 unsigned int fmask
, pmask
;
1203 unsigned int ctl_mode
;
1208 pmask
= AR5K_EEPROM_POWER_M
;
1209 fmask
= AR5K_EEPROM_FREQ_M(ee
->ee_version
);
1210 offset
= AR5K_EEPROM_CTL(ee
->ee_version
);
1211 ee
->ee_ctls
= AR5K_EEPROM_N_CTLS(ee
->ee_version
);
1212 for (i
= 0; i
< ee
->ee_ctls
; i
+= 2) {
1213 AR5K_EEPROM_READ(offset
++, val
);
1214 ee
->ee_ctl
[i
] = (val
>> 8) & 0xff;
1215 ee
->ee_ctl
[i
+ 1] = val
& 0xff;
1218 offset
= AR5K_EEPROM_GROUP8_OFFSET
;
1219 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_4_0
)
1220 offset
+= AR5K_EEPROM_TARGET_PWRSTART(ee
->ee_misc1
) -
1221 AR5K_EEPROM_GROUP5_OFFSET
;
1223 offset
+= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
1225 rep
= ee
->ee_ctl_pwr
;
1226 for(i
= 0; i
< ee
->ee_ctls
; i
++) {
1227 switch(ee
->ee_ctl
[i
] & AR5K_CTL_MODE_M
) {
1229 case AR5K_CTL_TURBO
:
1230 ctl_mode
= AR5K_EEPROM_MODE_11A
;
1233 ctl_mode
= AR5K_EEPROM_MODE_11G
;
1236 if (ee
->ee_ctl
[i
] == 0) {
1237 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_3_3
)
1241 rep
+= AR5K_EEPROM_N_EDGES
;
1244 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_3_3
) {
1245 for (j
= 0; j
< AR5K_EEPROM_N_EDGES
; j
+= 2) {
1246 AR5K_EEPROM_READ(offset
++, val
);
1247 rep
[j
].freq
= (val
>> 8) & fmask
;
1248 rep
[j
+ 1].freq
= val
& fmask
;
1250 for (j
= 0; j
< AR5K_EEPROM_N_EDGES
; j
+= 2) {
1251 AR5K_EEPROM_READ(offset
++, val
);
1252 rep
[j
].edge
= (val
>> 8) & pmask
;
1253 rep
[j
].flag
= (val
>> 14) & 1;
1254 rep
[j
+ 1].edge
= val
& pmask
;
1255 rep
[j
+ 1].flag
= (val
>> 6) & 1;
1258 AR5K_EEPROM_READ(offset
++, val
);
1259 rep
[0].freq
= (val
>> 9) & fmask
;
1260 rep
[1].freq
= (val
>> 2) & fmask
;
1261 rep
[2].freq
= (val
<< 5) & fmask
;
1263 AR5K_EEPROM_READ(offset
++, val
);
1264 rep
[2].freq
|= (val
>> 11) & 0x1f;
1265 rep
[3].freq
= (val
>> 4) & fmask
;
1266 rep
[4].freq
= (val
<< 3) & fmask
;
1268 AR5K_EEPROM_READ(offset
++, val
);
1269 rep
[4].freq
|= (val
>> 13) & 0x7;
1270 rep
[5].freq
= (val
>> 6) & fmask
;
1271 rep
[6].freq
= (val
<< 1) & fmask
;
1273 AR5K_EEPROM_READ(offset
++, val
);
1274 rep
[6].freq
|= (val
>> 15) & 0x1;
1275 rep
[7].freq
= (val
>> 8) & fmask
;
1277 rep
[0].edge
= (val
>> 2) & pmask
;
1278 rep
[1].edge
= (val
<< 4) & pmask
;
1280 AR5K_EEPROM_READ(offset
++, val
);
1281 rep
[1].edge
|= (val
>> 12) & 0xf;
1282 rep
[2].edge
= (val
>> 6) & pmask
;
1283 rep
[3].edge
= val
& pmask
;
1285 AR5K_EEPROM_READ(offset
++, val
);
1286 rep
[4].edge
= (val
>> 10) & pmask
;
1287 rep
[5].edge
= (val
>> 4) & pmask
;
1288 rep
[6].edge
= (val
<< 2) & pmask
;
1290 AR5K_EEPROM_READ(offset
++, val
);
1291 rep
[6].edge
|= (val
>> 14) & 0x3;
1292 rep
[7].edge
= (val
>> 8) & pmask
;
1294 for (j
= 0; j
< AR5K_EEPROM_N_EDGES
; j
++) {
1295 rep
[j
].freq
= ath5k_eeprom_bin2freq(ee
,
1296 rep
[j
].freq
, ctl_mode
);
1298 rep
+= AR5K_EEPROM_N_EDGES
;
1306 * Initialize eeprom power tables
1309 ath5k_eeprom_init(struct ath5k_hw
*ah
)
1313 err
= ath5k_eeprom_init_header(ah
);
1317 err
= ath5k_eeprom_init_modes(ah
);
1321 err
= ath5k_eeprom_read_pcal_info(ah
);
1325 err
= ath5k_eeprom_read_ctl_info(ah
);
1332 * Read the MAC address from eeprom
1334 int ath5k_eeprom_read_mac(struct ath5k_hw
*ah
, u8
*mac
)
1341 memset(mac
, 0, ETH_ALEN
);
1342 memset(mac_d
, 0, ETH_ALEN
);
1344 ret
= ath5k_hw_eeprom_read(ah
, 0x20, &data
);
1348 for (offset
= 0x1f, octet
= 0, total
= 0; offset
>= 0x1d; offset
--) {
1349 ret
= ath5k_hw_eeprom_read(ah
, offset
, &data
);
1354 mac_d
[octet
+ 1] = data
& 0xff;
1355 mac_d
[octet
] = data
>> 8;
1359 memcpy(mac
, mac_d
, ETH_ALEN
);
1361 if (!total
|| total
== 3 * 0xffff)