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
);
141 /* XXX: Don't know which versions include these two */
142 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2
, ee_misc2
);
144 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_4_3
)
145 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3
, ee_misc3
);
147 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_5_0
) {
148 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4
, ee_misc4
);
149 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5
, ee_misc5
);
150 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6
, ee_misc6
);
154 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_3_3
) {
155 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ
, val
);
156 ee
->ee_ob
[AR5K_EEPROM_MODE_11B
][0] = val
& 0x7;
157 ee
->ee_db
[AR5K_EEPROM_MODE_11B
][0] = (val
>> 3) & 0x7;
159 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ
, val
);
160 ee
->ee_ob
[AR5K_EEPROM_MODE_11G
][0] = val
& 0x7;
161 ee
->ee_db
[AR5K_EEPROM_MODE_11G
][0] = (val
>> 3) & 0x7;
169 * Read antenna infos from eeprom
171 static int ath5k_eeprom_read_ants(struct ath5k_hw
*ah
, u32
*offset
,
174 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
179 AR5K_EEPROM_READ(o
++, val
);
180 ee
->ee_switch_settling
[mode
] = (val
>> 8) & 0x7f;
181 ee
->ee_atn_tx_rx
[mode
] = (val
>> 2) & 0x3f;
182 ee
->ee_ant_control
[mode
][i
] = (val
<< 4) & 0x3f;
184 AR5K_EEPROM_READ(o
++, val
);
185 ee
->ee_ant_control
[mode
][i
++] |= (val
>> 12) & 0xf;
186 ee
->ee_ant_control
[mode
][i
++] = (val
>> 6) & 0x3f;
187 ee
->ee_ant_control
[mode
][i
++] = val
& 0x3f;
189 AR5K_EEPROM_READ(o
++, val
);
190 ee
->ee_ant_control
[mode
][i
++] = (val
>> 10) & 0x3f;
191 ee
->ee_ant_control
[mode
][i
++] = (val
>> 4) & 0x3f;
192 ee
->ee_ant_control
[mode
][i
] = (val
<< 2) & 0x3f;
194 AR5K_EEPROM_READ(o
++, val
);
195 ee
->ee_ant_control
[mode
][i
++] |= (val
>> 14) & 0x3;
196 ee
->ee_ant_control
[mode
][i
++] = (val
>> 8) & 0x3f;
197 ee
->ee_ant_control
[mode
][i
++] = (val
>> 2) & 0x3f;
198 ee
->ee_ant_control
[mode
][i
] = (val
<< 4) & 0x3f;
200 AR5K_EEPROM_READ(o
++, val
);
201 ee
->ee_ant_control
[mode
][i
++] |= (val
>> 12) & 0xf;
202 ee
->ee_ant_control
[mode
][i
++] = (val
>> 6) & 0x3f;
203 ee
->ee_ant_control
[mode
][i
++] = val
& 0x3f;
205 /* Get antenna modes */
206 ah
->ah_antenna
[mode
][0] =
207 (ee
->ee_ant_control
[mode
][0] << 4);
208 ah
->ah_antenna
[mode
][AR5K_ANT_FIXED_A
] =
209 ee
->ee_ant_control
[mode
][1] |
210 (ee
->ee_ant_control
[mode
][2] << 6) |
211 (ee
->ee_ant_control
[mode
][3] << 12) |
212 (ee
->ee_ant_control
[mode
][4] << 18) |
213 (ee
->ee_ant_control
[mode
][5] << 24);
214 ah
->ah_antenna
[mode
][AR5K_ANT_FIXED_B
] =
215 ee
->ee_ant_control
[mode
][6] |
216 (ee
->ee_ant_control
[mode
][7] << 6) |
217 (ee
->ee_ant_control
[mode
][8] << 12) |
218 (ee
->ee_ant_control
[mode
][9] << 18) |
219 (ee
->ee_ant_control
[mode
][10] << 24);
221 /* return new offset */
228 * Read supported modes and some mode-specific calibration data
231 static int ath5k_eeprom_read_modes(struct ath5k_hw
*ah
, u32
*offset
,
234 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
239 ee
->ee_n_piers
[mode
] = 0;
240 AR5K_EEPROM_READ(o
++, val
);
241 ee
->ee_adc_desired_size
[mode
] = (s8
)((val
>> 8) & 0xff);
243 case AR5K_EEPROM_MODE_11A
:
244 ee
->ee_ob
[mode
][3] = (val
>> 5) & 0x7;
245 ee
->ee_db
[mode
][3] = (val
>> 2) & 0x7;
246 ee
->ee_ob
[mode
][2] = (val
<< 1) & 0x7;
248 AR5K_EEPROM_READ(o
++, val
);
249 ee
->ee_ob
[mode
][2] |= (val
>> 15) & 0x1;
250 ee
->ee_db
[mode
][2] = (val
>> 12) & 0x7;
251 ee
->ee_ob
[mode
][1] = (val
>> 9) & 0x7;
252 ee
->ee_db
[mode
][1] = (val
>> 6) & 0x7;
253 ee
->ee_ob
[mode
][0] = (val
>> 3) & 0x7;
254 ee
->ee_db
[mode
][0] = val
& 0x7;
256 case AR5K_EEPROM_MODE_11G
:
257 case AR5K_EEPROM_MODE_11B
:
258 ee
->ee_ob
[mode
][1] = (val
>> 4) & 0x7;
259 ee
->ee_db
[mode
][1] = val
& 0x7;
263 AR5K_EEPROM_READ(o
++, val
);
264 ee
->ee_tx_end2xlna_enable
[mode
] = (val
>> 8) & 0xff;
265 ee
->ee_thr_62
[mode
] = val
& 0xff;
267 if (ah
->ah_ee_version
<= AR5K_EEPROM_VERSION_3_2
)
268 ee
->ee_thr_62
[mode
] = mode
== AR5K_EEPROM_MODE_11A
? 15 : 28;
270 AR5K_EEPROM_READ(o
++, val
);
271 ee
->ee_tx_end2xpa_disable
[mode
] = (val
>> 8) & 0xff;
272 ee
->ee_tx_frm2xpa_enable
[mode
] = val
& 0xff;
274 AR5K_EEPROM_READ(o
++, val
);
275 ee
->ee_pga_desired_size
[mode
] = (val
>> 8) & 0xff;
277 if ((val
& 0xff) & 0x80)
278 ee
->ee_noise_floor_thr
[mode
] = -((((val
& 0xff) ^ 0xff)) + 1);
280 ee
->ee_noise_floor_thr
[mode
] = val
& 0xff;
282 if (ah
->ah_ee_version
<= AR5K_EEPROM_VERSION_3_2
)
283 ee
->ee_noise_floor_thr
[mode
] =
284 mode
== AR5K_EEPROM_MODE_11A
? -54 : -1;
286 AR5K_EEPROM_READ(o
++, val
);
287 ee
->ee_xlna_gain
[mode
] = (val
>> 5) & 0xff;
288 ee
->ee_x_gain
[mode
] = (val
>> 1) & 0xf;
289 ee
->ee_xpd
[mode
] = val
& 0x1;
291 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_0
)
292 ee
->ee_fixed_bias
[mode
] = (val
>> 13) & 0x1;
294 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_3_3
) {
295 AR5K_EEPROM_READ(o
++, val
);
296 ee
->ee_false_detect
[mode
] = (val
>> 6) & 0x7f;
298 if (mode
== AR5K_EEPROM_MODE_11A
)
299 ee
->ee_xr_power
[mode
] = val
& 0x3f;
301 ee
->ee_ob
[mode
][0] = val
& 0x7;
302 ee
->ee_db
[mode
][0] = (val
>> 3) & 0x7;
306 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_3_4
) {
307 ee
->ee_i_gain
[mode
] = AR5K_EEPROM_I_GAIN
;
308 ee
->ee_cck_ofdm_power_delta
= AR5K_EEPROM_CCK_OFDM_DELTA
;
310 ee
->ee_i_gain
[mode
] = (val
>> 13) & 0x7;
312 AR5K_EEPROM_READ(o
++, val
);
313 ee
->ee_i_gain
[mode
] |= (val
<< 3) & 0x38;
315 if (mode
== AR5K_EEPROM_MODE_11G
) {
316 ee
->ee_cck_ofdm_power_delta
= (val
>> 3) & 0xff;
317 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_6
)
318 ee
->ee_scaled_cck_delta
= (val
>> 11) & 0x1f;
322 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_0
&&
323 mode
== AR5K_EEPROM_MODE_11A
) {
324 ee
->ee_i_cal
[mode
] = (val
>> 8) & 0x3f;
325 ee
->ee_q_cal
[mode
] = (val
>> 3) & 0x1f;
328 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_4_0
)
331 /* Note: >= v5 have bg freq piers on another location
332 * so these freq piers are ignored for >= v5 (should be 0xff
335 case AR5K_EEPROM_MODE_11A
:
336 if (ah
->ah_ee_version
< AR5K_EEPROM_VERSION_4_1
)
339 AR5K_EEPROM_READ(o
++, val
);
340 ee
->ee_margin_tx_rx
[mode
] = val
& 0x3f;
342 case AR5K_EEPROM_MODE_11B
:
343 AR5K_EEPROM_READ(o
++, val
);
345 ee
->ee_pwr_cal_b
[0].freq
=
346 ath5k_eeprom_bin2freq(ee
, val
& 0xff, mode
);
347 if (ee
->ee_pwr_cal_b
[0].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
348 ee
->ee_n_piers
[mode
]++;
350 ee
->ee_pwr_cal_b
[1].freq
=
351 ath5k_eeprom_bin2freq(ee
, (val
>> 8) & 0xff, mode
);
352 if (ee
->ee_pwr_cal_b
[1].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
353 ee
->ee_n_piers
[mode
]++;
355 AR5K_EEPROM_READ(o
++, val
);
356 ee
->ee_pwr_cal_b
[2].freq
=
357 ath5k_eeprom_bin2freq(ee
, val
& 0xff, mode
);
358 if (ee
->ee_pwr_cal_b
[2].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
359 ee
->ee_n_piers
[mode
]++;
361 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_1
)
362 ee
->ee_margin_tx_rx
[mode
] = (val
>> 8) & 0x3f;
364 case AR5K_EEPROM_MODE_11G
:
365 AR5K_EEPROM_READ(o
++, val
);
367 ee
->ee_pwr_cal_g
[0].freq
=
368 ath5k_eeprom_bin2freq(ee
, val
& 0xff, mode
);
369 if (ee
->ee_pwr_cal_g
[0].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
370 ee
->ee_n_piers
[mode
]++;
372 ee
->ee_pwr_cal_g
[1].freq
=
373 ath5k_eeprom_bin2freq(ee
, (val
>> 8) & 0xff, mode
);
374 if (ee
->ee_pwr_cal_g
[1].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
375 ee
->ee_n_piers
[mode
]++;
377 AR5K_EEPROM_READ(o
++, val
);
378 ee
->ee_turbo_max_power
[mode
] = val
& 0x7f;
379 ee
->ee_xr_power
[mode
] = (val
>> 7) & 0x3f;
381 AR5K_EEPROM_READ(o
++, val
);
382 ee
->ee_pwr_cal_g
[2].freq
=
383 ath5k_eeprom_bin2freq(ee
, val
& 0xff, mode
);
384 if (ee
->ee_pwr_cal_g
[2].freq
!= AR5K_EEPROM_CHANNEL_DIS
)
385 ee
->ee_n_piers
[mode
]++;
387 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_1
)
388 ee
->ee_margin_tx_rx
[mode
] = (val
>> 8) & 0x3f;
390 AR5K_EEPROM_READ(o
++, val
);
391 ee
->ee_i_cal
[mode
] = (val
>> 8) & 0x3f;
392 ee
->ee_q_cal
[mode
] = (val
>> 3) & 0x1f;
394 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_2
) {
395 AR5K_EEPROM_READ(o
++, val
);
396 ee
->ee_cck_ofdm_gain_delta
= val
& 0xff;
402 /* return new offset */
409 * Read turbo mode information on newer EEPROM versions
412 ath5k_eeprom_read_turbo_modes(struct ath5k_hw
*ah
,
413 u32
*offset
, unsigned int mode
)
415 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
420 if (ee
->ee_version
< AR5K_EEPROM_VERSION_5_0
)
424 case AR5K_EEPROM_MODE_11A
:
425 ee
->ee_switch_settling_turbo
[mode
] = (val
>> 6) & 0x7f;
427 ee
->ee_atn_tx_rx_turbo
[mode
] = (val
>> 13) & 0x7;
428 AR5K_EEPROM_READ(o
++, val
);
429 ee
->ee_atn_tx_rx_turbo
[mode
] |= (val
& 0x7) << 3;
430 ee
->ee_margin_tx_rx_turbo
[mode
] = (val
>> 3) & 0x3f;
432 ee
->ee_adc_desired_size_turbo
[mode
] = (val
>> 9) & 0x7f;
433 AR5K_EEPROM_READ(o
++, val
);
434 ee
->ee_adc_desired_size_turbo
[mode
] |= (val
& 0x1) << 7;
435 ee
->ee_pga_desired_size_turbo
[mode
] = (val
>> 1) & 0xff;
437 if (AR5K_EEPROM_EEMAP(ee
->ee_misc0
) >=2)
438 ee
->ee_pd_gain_overlap
= (val
>> 9) & 0xf;
440 case AR5K_EEPROM_MODE_11G
:
441 ee
->ee_switch_settling_turbo
[mode
] = (val
>> 8) & 0x7f;
443 ee
->ee_atn_tx_rx_turbo
[mode
] = (val
>> 15) & 0x7;
444 AR5K_EEPROM_READ(o
++, val
);
445 ee
->ee_atn_tx_rx_turbo
[mode
] |= (val
& 0x1f) << 1;
446 ee
->ee_margin_tx_rx_turbo
[mode
] = (val
>> 5) & 0x3f;
448 ee
->ee_adc_desired_size_turbo
[mode
] = (val
>> 11) & 0x7f;
449 AR5K_EEPROM_READ(o
++, val
);
450 ee
->ee_adc_desired_size_turbo
[mode
] |= (val
& 0x7) << 5;
451 ee
->ee_pga_desired_size_turbo
[mode
] = (val
>> 3) & 0xff;
455 /* return new offset */
461 /* Read mode-specific data (except power calibration data) */
463 ath5k_eeprom_init_modes(struct ath5k_hw
*ah
)
465 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
472 * Get values for all modes
474 mode_offset
[AR5K_EEPROM_MODE_11A
] = AR5K_EEPROM_MODES_11A(ah
->ah_ee_version
);
475 mode_offset
[AR5K_EEPROM_MODE_11B
] = AR5K_EEPROM_MODES_11B(ah
->ah_ee_version
);
476 mode_offset
[AR5K_EEPROM_MODE_11G
] = AR5K_EEPROM_MODES_11G(ah
->ah_ee_version
);
478 ee
->ee_turbo_max_power
[AR5K_EEPROM_MODE_11A
] =
479 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee
->ee_header
);
481 for (mode
= AR5K_EEPROM_MODE_11A
; mode
<= AR5K_EEPROM_MODE_11G
; mode
++) {
482 offset
= mode_offset
[mode
];
484 ret
= ath5k_eeprom_read_ants(ah
, &offset
, mode
);
488 ret
= ath5k_eeprom_read_modes(ah
, &offset
, mode
);
492 ret
= ath5k_eeprom_read_turbo_modes(ah
, &offset
, mode
);
497 /* override for older eeprom versions for better performance */
498 if (ah
->ah_ee_version
<= AR5K_EEPROM_VERSION_3_2
) {
499 ee
->ee_thr_62
[AR5K_EEPROM_MODE_11A
] = 15;
500 ee
->ee_thr_62
[AR5K_EEPROM_MODE_11B
] = 28;
501 ee
->ee_thr_62
[AR5K_EEPROM_MODE_11G
] = 28;
507 /* Used to match PCDAC steps with power values on RF5111 chips
508 * (eeprom versions < 4). For RF5111 we have 10 pre-defined PCDAC
509 * steps that match with the power values we read from eeprom. On
510 * older eeprom versions (< 3.2) these steps are equaly spaced at
511 * 10% of the pcdac curve -until the curve reaches it's maximum-
512 * (10 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
513 * these 10 steps are spaced in a different way. This function returns
514 * the pcdac steps based on eeprom version and curve min/max so that we
515 * can have pcdac/pwr points.
518 ath5k_get_pcdac_intercepts(struct ath5k_hw
*ah
, u8 min
, u8 max
, u8
*vp
)
520 static const u16 intercepts3
[] =
521 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
522 static const u16 intercepts3_2
[] =
523 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
527 if (ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_3_2
)
532 for (i
= 0; i
< ARRAY_SIZE(intercepts3
); i
++)
533 *vp
++ = (ip
[i
] * max
+ (100 - ip
[i
]) * min
) / 100;
536 /* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
539 ath5k_eeprom_read_freq_list(struct ath5k_hw
*ah
, int *offset
, int max
,
540 struct ath5k_chan_pcal_info
*pc
, unsigned int mode
)
542 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
550 AR5K_EEPROM_READ(o
++, val
);
552 freq1
= (val
>> 8) & 0xff;
556 pc
[i
++].freq
= ath5k_eeprom_bin2freq(ee
,
558 ee
->ee_n_piers
[mode
]++;
562 pc
[i
++].freq
= ath5k_eeprom_bin2freq(ee
,
564 ee
->ee_n_piers
[mode
]++;
567 if (!freq1
|| !freq2
)
571 /* return new offset */
577 /* Read frequency piers for 802.11a */
579 ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw
*ah
, int offset
)
581 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
582 struct ath5k_chan_pcal_info
*pcal
= ee
->ee_pwr_cal_a
;
587 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_3_3
) {
588 ath5k_eeprom_read_freq_list(ah
, &offset
,
589 AR5K_EEPROM_N_5GHZ_CHAN
, pcal
,
590 AR5K_EEPROM_MODE_11A
);
592 mask
= AR5K_EEPROM_FREQ_M(ah
->ah_ee_version
);
594 AR5K_EEPROM_READ(offset
++, val
);
595 pcal
[0].freq
= (val
>> 9) & mask
;
596 pcal
[1].freq
= (val
>> 2) & mask
;
597 pcal
[2].freq
= (val
<< 5) & mask
;
599 AR5K_EEPROM_READ(offset
++, val
);
600 pcal
[2].freq
|= (val
>> 11) & 0x1f;
601 pcal
[3].freq
= (val
>> 4) & mask
;
602 pcal
[4].freq
= (val
<< 3) & mask
;
604 AR5K_EEPROM_READ(offset
++, val
);
605 pcal
[4].freq
|= (val
>> 13) & 0x7;
606 pcal
[5].freq
= (val
>> 6) & mask
;
607 pcal
[6].freq
= (val
<< 1) & mask
;
609 AR5K_EEPROM_READ(offset
++, val
);
610 pcal
[6].freq
|= (val
>> 15) & 0x1;
611 pcal
[7].freq
= (val
>> 8) & mask
;
612 pcal
[8].freq
= (val
>> 1) & mask
;
613 pcal
[9].freq
= (val
<< 6) & mask
;
615 AR5K_EEPROM_READ(offset
++, val
);
616 pcal
[9].freq
|= (val
>> 10) & 0x3f;
618 /* Fixed number of piers */
619 ee
->ee_n_piers
[AR5K_EEPROM_MODE_11A
] = 10;
621 for (i
= 0; i
< AR5K_EEPROM_N_5GHZ_CHAN
; i
++) {
622 pcal
[i
].freq
= ath5k_eeprom_bin2freq(ee
,
623 pcal
[i
].freq
, AR5K_EEPROM_MODE_11A
);
630 /* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
632 ath5k_eeprom_init_11bg_2413(struct ath5k_hw
*ah
, unsigned int mode
, int offset
)
634 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
635 struct ath5k_chan_pcal_info
*pcal
;
638 case AR5K_EEPROM_MODE_11B
:
639 pcal
= ee
->ee_pwr_cal_b
;
641 case AR5K_EEPROM_MODE_11G
:
642 pcal
= ee
->ee_pwr_cal_g
;
648 ath5k_eeprom_read_freq_list(ah
, &offset
,
649 AR5K_EEPROM_N_2GHZ_CHAN_2413
, pcal
,
655 /* Read power calibration for RF5111 chips
656 * For RF5111 we have an XPD -eXternal Power Detector- curve
657 * for each calibrated channel. Each curve has PCDAC steps on
658 * x axis and power on y axis and looks like a logarithmic
659 * function. To recreate the curve and pass the power values
660 * on the pcdac table, we read 10 points here and interpolate later.
663 ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw
*ah
, int mode
)
665 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
666 struct ath5k_chan_pcal_info
*pcal
;
671 offset
= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
673 case AR5K_EEPROM_MODE_11A
:
674 if (!AR5K_EEPROM_HDR_11A(ee
->ee_header
))
677 ret
= ath5k_eeprom_init_11a_pcal_freq(ah
,
678 offset
+ AR5K_EEPROM_GROUP1_OFFSET
);
682 offset
+= AR5K_EEPROM_GROUP2_OFFSET
;
683 pcal
= ee
->ee_pwr_cal_a
;
685 case AR5K_EEPROM_MODE_11B
:
686 if (!AR5K_EEPROM_HDR_11B(ee
->ee_header
) &&
687 !AR5K_EEPROM_HDR_11G(ee
->ee_header
))
690 pcal
= ee
->ee_pwr_cal_b
;
691 offset
+= AR5K_EEPROM_GROUP3_OFFSET
;
697 ee
->ee_n_piers
[mode
] = 3;
699 case AR5K_EEPROM_MODE_11G
:
700 if (!AR5K_EEPROM_HDR_11G(ee
->ee_header
))
703 pcal
= ee
->ee_pwr_cal_g
;
704 offset
+= AR5K_EEPROM_GROUP4_OFFSET
;
710 ee
->ee_n_piers
[mode
] = 3;
716 for (i
= 0; i
< ee
->ee_n_piers
[mode
]; i
++) {
717 struct ath5k_chan_pcal_info_rf5111
*cdata
=
718 &pcal
[i
].rf5111_info
;
720 AR5K_EEPROM_READ(offset
++, val
);
721 cdata
->pcdac_max
= ((val
>> 10) & AR5K_EEPROM_PCDAC_M
);
722 cdata
->pcdac_min
= ((val
>> 4) & AR5K_EEPROM_PCDAC_M
);
723 cdata
->pwr
[0] = ((val
<< 2) & AR5K_EEPROM_POWER_M
);
725 AR5K_EEPROM_READ(offset
++, val
);
726 cdata
->pwr
[0] |= ((val
>> 14) & 0x3);
727 cdata
->pwr
[1] = ((val
>> 8) & AR5K_EEPROM_POWER_M
);
728 cdata
->pwr
[2] = ((val
>> 2) & AR5K_EEPROM_POWER_M
);
729 cdata
->pwr
[3] = ((val
<< 4) & AR5K_EEPROM_POWER_M
);
731 AR5K_EEPROM_READ(offset
++, val
);
732 cdata
->pwr
[3] |= ((val
>> 12) & 0xf);
733 cdata
->pwr
[4] = ((val
>> 6) & AR5K_EEPROM_POWER_M
);
734 cdata
->pwr
[5] = (val
& AR5K_EEPROM_POWER_M
);
736 AR5K_EEPROM_READ(offset
++, val
);
737 cdata
->pwr
[6] = ((val
>> 10) & AR5K_EEPROM_POWER_M
);
738 cdata
->pwr
[7] = ((val
>> 4) & AR5K_EEPROM_POWER_M
);
739 cdata
->pwr
[8] = ((val
<< 2) & AR5K_EEPROM_POWER_M
);
741 AR5K_EEPROM_READ(offset
++, val
);
742 cdata
->pwr
[8] |= ((val
>> 14) & 0x3);
743 cdata
->pwr
[9] = ((val
>> 8) & AR5K_EEPROM_POWER_M
);
744 cdata
->pwr
[10] = ((val
>> 2) & AR5K_EEPROM_POWER_M
);
746 ath5k_get_pcdac_intercepts(ah
, cdata
->pcdac_min
,
747 cdata
->pcdac_max
, cdata
->pcdac
);
753 /* Read power calibration for RF5112 chips
754 * For RF5112 we have 4 XPD -eXternal Power Detector- curves
755 * for each calibrated channel on 0, -6, -12 and -18dbm but we only
756 * use the higher (3) and the lower (0) curves. Each curve has PCDAC
757 * steps on x axis and power on y axis and looks like a linear
758 * function. To recreate the curve and pass the power values
759 * on the pcdac table, we read 4 points for xpd 0 and 3 points
760 * for xpd 3 here and interpolate later.
762 * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
765 ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw
*ah
, int mode
)
767 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
768 struct ath5k_chan_pcal_info_rf5112
*chan_pcal_info
;
769 struct ath5k_chan_pcal_info
*gen_chan_info
;
776 case AR5K_EEPROM_MODE_11A
:
778 * Read 5GHz EEPROM channels
780 offset
= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
781 ath5k_eeprom_init_11a_pcal_freq(ah
, offset
);
783 offset
+= AR5K_EEPROM_GROUP2_OFFSET
;
784 gen_chan_info
= ee
->ee_pwr_cal_a
;
786 case AR5K_EEPROM_MODE_11B
:
787 offset
= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
788 if (AR5K_EEPROM_HDR_11A(ee
->ee_header
))
789 offset
+= AR5K_EEPROM_GROUP3_OFFSET
;
791 /* NB: frequency piers parsed during mode init */
792 gen_chan_info
= ee
->ee_pwr_cal_b
;
794 case AR5K_EEPROM_MODE_11G
:
795 offset
= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
796 if (AR5K_EEPROM_HDR_11A(ee
->ee_header
))
797 offset
+= AR5K_EEPROM_GROUP4_OFFSET
;
798 else if (AR5K_EEPROM_HDR_11B(ee
->ee_header
))
799 offset
+= AR5K_EEPROM_GROUP2_OFFSET
;
801 /* NB: frequency piers parsed during mode init */
802 gen_chan_info
= ee
->ee_pwr_cal_g
;
808 for (i
= 0; i
< ee
->ee_n_piers
[mode
]; i
++) {
809 chan_pcal_info
= &gen_chan_info
[i
].rf5112_info
;
811 /* Power values in dBm * 4
812 * for the lower xpd gain curve
813 * (0 dBm -> higher output power) */
814 for (c
= 0; c
< AR5K_EEPROM_N_XPD0_POINTS
; c
++) {
815 AR5K_EEPROM_READ(offset
++, val
);
816 chan_pcal_info
->pwr_x0
[c
] = (val
& 0xff);
817 chan_pcal_info
->pwr_x0
[++c
] = ((val
>> 8) & 0xff);
821 * corresponding to the above power
823 AR5K_EEPROM_READ(offset
++, val
);
824 chan_pcal_info
->pcdac_x0
[1] = (val
& 0x1f);
825 chan_pcal_info
->pcdac_x0
[2] = ((val
>> 5) & 0x1f);
826 chan_pcal_info
->pcdac_x0
[3] = ((val
>> 10) & 0x1f);
828 /* Power values in dBm * 4
829 * for the higher xpd gain curve
830 * (18 dBm -> lower output power) */
831 AR5K_EEPROM_READ(offset
++, val
);
832 chan_pcal_info
->pwr_x3
[0] = (val
& 0xff);
833 chan_pcal_info
->pwr_x3
[1] = ((val
>> 8) & 0xff);
835 AR5K_EEPROM_READ(offset
++, val
);
836 chan_pcal_info
->pwr_x3
[2] = (val
& 0xff);
839 * corresponding to the above power
840 * measurements (fixed) */
841 chan_pcal_info
->pcdac_x3
[0] = 20;
842 chan_pcal_info
->pcdac_x3
[1] = 35;
843 chan_pcal_info
->pcdac_x3
[2] = 63;
845 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_4_3
) {
846 chan_pcal_info
->pcdac_x0
[0] = ((val
>> 8) & 0xff);
848 /* Last xpd0 power level is also channel maximum */
849 gen_chan_info
[i
].max_pwr
= chan_pcal_info
->pwr_x0
[3];
851 chan_pcal_info
->pcdac_x0
[0] = 1;
852 gen_chan_info
[i
].max_pwr
= ((val
>> 8) & 0xff);
855 /* Recreate pcdac_x0 table for this channel using pcdac steps */
856 chan_pcal_info
->pcdac_x0
[1] += chan_pcal_info
->pcdac_x0
[0];
857 chan_pcal_info
->pcdac_x0
[2] += chan_pcal_info
->pcdac_x0
[1];
858 chan_pcal_info
->pcdac_x0
[3] += chan_pcal_info
->pcdac_x0
[2];
864 /* For RF2413 power calibration data doesn't start on a fixed location and
865 * if a mode is not supported, it's section is missing -not zeroed-.
866 * So we need to calculate the starting offset for each section by using
867 * these two functions */
869 /* Return the size of each section based on the mode and the number of pd
870 * gains available (maximum 4). */
871 static inline unsigned int
872 ath5k_pdgains_size_2413(struct ath5k_eeprom_info
*ee
, unsigned int mode
)
874 static const unsigned int pdgains_size
[] = { 4, 6, 9, 12 };
877 sz
= pdgains_size
[ee
->ee_pd_gains
[mode
] - 1];
878 sz
*= ee
->ee_n_piers
[mode
];
883 /* Return the starting offset for a section based on the modes supported
884 * and each section's size. */
886 ath5k_cal_data_offset_2413(struct ath5k_eeprom_info
*ee
, int mode
)
888 u32 offset
= AR5K_EEPROM_CAL_DATA_START(ee
->ee_misc4
);
891 case AR5K_EEPROM_MODE_11G
:
892 if (AR5K_EEPROM_HDR_11B(ee
->ee_header
))
893 offset
+= ath5k_pdgains_size_2413(ee
, AR5K_EEPROM_MODE_11B
) +
894 AR5K_EEPROM_N_2GHZ_CHAN_2413
/ 2;
896 case AR5K_EEPROM_MODE_11B
:
897 if (AR5K_EEPROM_HDR_11A(ee
->ee_header
))
898 offset
+= ath5k_pdgains_size_2413(ee
, AR5K_EEPROM_MODE_11A
) +
899 AR5K_EEPROM_N_5GHZ_CHAN
/ 2;
901 case AR5K_EEPROM_MODE_11A
:
910 /* Read power calibration for RF2413 chips
911 * For RF2413 we have a PDDAC table (Power Detector) instead
912 * of a PCDAC and 4 pd gain curves for each calibrated channel.
913 * Each curve has PDDAC steps on x axis and power on y axis and
914 * looks like an exponential function. To recreate the curves
915 * we read here the points and interpolate later. Note that
916 * in most cases only higher and lower curves are used (like
917 * RF5112) but vendors have the oportunity to include all 4
918 * curves on eeprom. The final curve (higher power) has an extra
919 * point for better accuracy like RF5112.
922 ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw
*ah
, int mode
)
924 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
925 struct ath5k_chan_pcal_info_rf2413
*chan_pcal_info
;
926 struct ath5k_chan_pcal_info
*gen_chan_info
;
933 if (ee
->ee_x_gain
[mode
] & 0x1) pd_gains
++;
934 if ((ee
->ee_x_gain
[mode
] >> 1) & 0x1) pd_gains
++;
935 if ((ee
->ee_x_gain
[mode
] >> 2) & 0x1) pd_gains
++;
936 if ((ee
->ee_x_gain
[mode
] >> 3) & 0x1) pd_gains
++;
937 ee
->ee_pd_gains
[mode
] = pd_gains
;
939 offset
= ath5k_cal_data_offset_2413(ee
, mode
);
940 ee
->ee_n_piers
[mode
] = 0;
942 case AR5K_EEPROM_MODE_11A
:
943 if (!AR5K_EEPROM_HDR_11A(ee
->ee_header
))
946 ath5k_eeprom_init_11a_pcal_freq(ah
, offset
);
947 offset
+= AR5K_EEPROM_N_5GHZ_CHAN
/ 2;
948 gen_chan_info
= ee
->ee_pwr_cal_a
;
950 case AR5K_EEPROM_MODE_11B
:
951 if (!AR5K_EEPROM_HDR_11B(ee
->ee_header
))
954 ath5k_eeprom_init_11bg_2413(ah
, mode
, offset
);
955 offset
+= AR5K_EEPROM_N_2GHZ_CHAN_2413
/ 2;
956 gen_chan_info
= ee
->ee_pwr_cal_b
;
958 case AR5K_EEPROM_MODE_11G
:
959 if (!AR5K_EEPROM_HDR_11G(ee
->ee_header
))
962 ath5k_eeprom_init_11bg_2413(ah
, mode
, offset
);
963 offset
+= AR5K_EEPROM_N_2GHZ_CHAN_2413
/ 2;
964 gen_chan_info
= ee
->ee_pwr_cal_g
;
973 for (i
= 0; i
< ee
->ee_n_piers
[mode
]; i
++) {
974 chan_pcal_info
= &gen_chan_info
[i
].rf2413_info
;
977 * Read pwr_i, pddac_i and the first
978 * 2 pd points (pwr, pddac)
980 AR5K_EEPROM_READ(offset
++, val
);
981 chan_pcal_info
->pwr_i
[0] = val
& 0x1f;
982 chan_pcal_info
->pddac_i
[0] = (val
>> 5) & 0x7f;
983 chan_pcal_info
->pwr
[0][0] =
986 AR5K_EEPROM_READ(offset
++, val
);
987 chan_pcal_info
->pddac
[0][0] = val
& 0x3f;
988 chan_pcal_info
->pwr
[0][1] = (val
>> 6) & 0xf;
989 chan_pcal_info
->pddac
[0][1] =
992 AR5K_EEPROM_READ(offset
++, val
);
993 chan_pcal_info
->pwr
[0][2] = val
& 0xf;
994 chan_pcal_info
->pddac
[0][2] =
997 chan_pcal_info
->pwr
[0][3] = 0;
998 chan_pcal_info
->pddac
[0][3] = 0;
1002 * Pd gain 0 is not the last pd gain
1003 * so it only has 2 pd points.
1004 * Continue wih pd gain 1.
1006 chan_pcal_info
->pwr_i
[1] = (val
>> 10) & 0x1f;
1008 chan_pcal_info
->pddac_i
[1] = (val
>> 15) & 0x1;
1009 AR5K_EEPROM_READ(offset
++, val
);
1010 chan_pcal_info
->pddac_i
[1] |= (val
& 0x3F) << 1;
1012 chan_pcal_info
->pwr
[1][0] = (val
>> 6) & 0xf;
1013 chan_pcal_info
->pddac
[1][0] =
1016 AR5K_EEPROM_READ(offset
++, val
);
1017 chan_pcal_info
->pwr
[1][1] = val
& 0xf;
1018 chan_pcal_info
->pddac
[1][1] =
1020 chan_pcal_info
->pwr
[1][2] =
1023 chan_pcal_info
->pddac
[1][2] =
1025 AR5K_EEPROM_READ(offset
++, val
);
1026 chan_pcal_info
->pddac
[1][2] |=
1029 chan_pcal_info
->pwr
[1][3] = 0;
1030 chan_pcal_info
->pddac
[1][3] = 0;
1031 } else if (pd_gains
== 1) {
1033 * Pd gain 0 is the last one so
1034 * read the extra point.
1036 chan_pcal_info
->pwr
[0][3] =
1039 chan_pcal_info
->pddac
[0][3] =
1041 AR5K_EEPROM_READ(offset
++, val
);
1042 chan_pcal_info
->pddac
[0][3] |=
1047 * Proceed with the other pd_gains
1051 chan_pcal_info
->pwr_i
[2] = (val
>> 4) & 0x1f;
1052 chan_pcal_info
->pddac_i
[2] = (val
>> 9) & 0x7f;
1054 AR5K_EEPROM_READ(offset
++, val
);
1055 chan_pcal_info
->pwr
[2][0] =
1057 chan_pcal_info
->pddac
[2][0] =
1059 chan_pcal_info
->pwr
[2][1] =
1062 chan_pcal_info
->pddac
[2][1] =
1064 AR5K_EEPROM_READ(offset
++, val
);
1065 chan_pcal_info
->pddac
[2][1] |=
1068 chan_pcal_info
->pwr
[2][2] =
1070 chan_pcal_info
->pddac
[2][2] =
1073 chan_pcal_info
->pwr
[2][3] = 0;
1074 chan_pcal_info
->pddac
[2][3] = 0;
1075 } else if (pd_gains
== 2) {
1076 chan_pcal_info
->pwr
[1][3] =
1078 chan_pcal_info
->pddac
[1][3] =
1083 chan_pcal_info
->pwr_i
[3] = (val
>> 14) & 0x3;
1084 AR5K_EEPROM_READ(offset
++, val
);
1085 chan_pcal_info
->pwr_i
[3] |= ((val
>> 0) & 0x7) << 2;
1087 chan_pcal_info
->pddac_i
[3] = (val
>> 3) & 0x7f;
1088 chan_pcal_info
->pwr
[3][0] =
1090 chan_pcal_info
->pddac
[3][0] =
1093 AR5K_EEPROM_READ(offset
++, val
);
1094 chan_pcal_info
->pddac
[3][0] |=
1096 chan_pcal_info
->pwr
[3][1] =
1098 chan_pcal_info
->pddac
[3][1] =
1101 chan_pcal_info
->pwr
[3][2] =
1103 AR5K_EEPROM_READ(offset
++, val
);
1104 chan_pcal_info
->pwr
[3][2] |=
1105 ((val
>> 0) & 0x3) << 2;
1107 chan_pcal_info
->pddac
[3][2] =
1109 chan_pcal_info
->pwr
[3][3] =
1112 chan_pcal_info
->pddac
[3][3] =
1114 AR5K_EEPROM_READ(offset
++, val
);
1115 chan_pcal_info
->pddac
[3][3] |=
1116 ((val
>> 0) & 0x3) << 4;
1117 } else if (pd_gains
== 3) {
1118 chan_pcal_info
->pwr
[2][3] =
1120 AR5K_EEPROM_READ(offset
++, val
);
1121 chan_pcal_info
->pwr
[2][3] |=
1122 ((val
>> 0) & 0x3) << 2;
1124 chan_pcal_info
->pddac
[2][3] =
1128 for (c
= 0; c
< pd_gains
; c
++) {
1129 /* Recreate pwr table for this channel using pwr steps */
1130 chan_pcal_info
->pwr
[c
][0] += chan_pcal_info
->pwr_i
[c
] * 2;
1131 chan_pcal_info
->pwr
[c
][1] += chan_pcal_info
->pwr
[c
][0];
1132 chan_pcal_info
->pwr
[c
][2] += chan_pcal_info
->pwr
[c
][1];
1133 chan_pcal_info
->pwr
[c
][3] += chan_pcal_info
->pwr
[c
][2];
1134 if (chan_pcal_info
->pwr
[c
][3] == chan_pcal_info
->pwr
[c
][2])
1135 chan_pcal_info
->pwr
[c
][3] = 0;
1137 /* Recreate pddac table for this channel using pddac steps */
1138 chan_pcal_info
->pddac
[c
][0] += chan_pcal_info
->pddac_i
[c
];
1139 chan_pcal_info
->pddac
[c
][1] += chan_pcal_info
->pddac
[c
][0];
1140 chan_pcal_info
->pddac
[c
][2] += chan_pcal_info
->pddac
[c
][1];
1141 chan_pcal_info
->pddac
[c
][3] += chan_pcal_info
->pddac
[c
][2];
1142 if (chan_pcal_info
->pddac
[c
][3] == chan_pcal_info
->pddac
[c
][2])
1143 chan_pcal_info
->pddac
[c
][3] = 0;
1151 * Read per rate target power (this is the maximum tx power
1152 * supported by the card). This info is used when setting
1153 * tx power, no matter the channel.
1155 * This also works for v5 EEPROMs.
1157 static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw
*ah
, unsigned int mode
)
1159 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
1160 struct ath5k_rate_pcal_info
*rate_pcal_info
;
1161 u16
*rate_target_pwr_num
;
1166 offset
= AR5K_EEPROM_TARGET_PWRSTART(ee
->ee_misc1
);
1167 rate_target_pwr_num
= &ee
->ee_rate_target_pwr_num
[mode
];
1169 case AR5K_EEPROM_MODE_11A
:
1170 offset
+= AR5K_EEPROM_TARGET_PWR_OFF_11A(ee
->ee_version
);
1171 rate_pcal_info
= ee
->ee_rate_tpwr_a
;
1172 ee
->ee_rate_target_pwr_num
[mode
] = AR5K_EEPROM_N_5GHZ_CHAN
;
1174 case AR5K_EEPROM_MODE_11B
:
1175 offset
+= AR5K_EEPROM_TARGET_PWR_OFF_11B(ee
->ee_version
);
1176 rate_pcal_info
= ee
->ee_rate_tpwr_b
;
1177 ee
->ee_rate_target_pwr_num
[mode
] = 2; /* 3rd is g mode's 1st */
1179 case AR5K_EEPROM_MODE_11G
:
1180 offset
+= AR5K_EEPROM_TARGET_PWR_OFF_11G(ee
->ee_version
);
1181 rate_pcal_info
= ee
->ee_rate_tpwr_g
;
1182 ee
->ee_rate_target_pwr_num
[mode
] = AR5K_EEPROM_N_2GHZ_CHAN
;
1188 /* Different freq mask for older eeproms (<= v3.2) */
1189 if (ee
->ee_version
<= AR5K_EEPROM_VERSION_3_2
) {
1190 for (i
= 0; i
< (*rate_target_pwr_num
); i
++) {
1191 AR5K_EEPROM_READ(offset
++, val
);
1192 rate_pcal_info
[i
].freq
=
1193 ath5k_eeprom_bin2freq(ee
, (val
>> 9) & 0x7f, mode
);
1195 rate_pcal_info
[i
].target_power_6to24
= ((val
>> 3) & 0x3f);
1196 rate_pcal_info
[i
].target_power_36
= (val
<< 3) & 0x3f;
1198 AR5K_EEPROM_READ(offset
++, val
);
1200 if (rate_pcal_info
[i
].freq
== AR5K_EEPROM_CHANNEL_DIS
||
1202 (*rate_target_pwr_num
) = i
;
1206 rate_pcal_info
[i
].target_power_36
|= ((val
>> 13) & 0x7);
1207 rate_pcal_info
[i
].target_power_48
= ((val
>> 7) & 0x3f);
1208 rate_pcal_info
[i
].target_power_54
= ((val
>> 1) & 0x3f);
1211 for (i
= 0; i
< (*rate_target_pwr_num
); i
++) {
1212 AR5K_EEPROM_READ(offset
++, val
);
1213 rate_pcal_info
[i
].freq
=
1214 ath5k_eeprom_bin2freq(ee
, (val
>> 8) & 0xff, mode
);
1216 rate_pcal_info
[i
].target_power_6to24
= ((val
>> 2) & 0x3f);
1217 rate_pcal_info
[i
].target_power_36
= (val
<< 4) & 0x3f;
1219 AR5K_EEPROM_READ(offset
++, val
);
1221 if (rate_pcal_info
[i
].freq
== AR5K_EEPROM_CHANNEL_DIS
||
1223 (*rate_target_pwr_num
) = i
;
1227 rate_pcal_info
[i
].target_power_36
|= (val
>> 12) & 0xf;
1228 rate_pcal_info
[i
].target_power_48
= ((val
>> 6) & 0x3f);
1229 rate_pcal_info
[i
].target_power_54
= (val
& 0x3f);
1237 * Read per channel calibration info from EEPROM
1239 * This info is used to calibrate the baseband power table. Imagine
1240 * that for each channel there is a power curve that's hw specific
1241 * (depends on amplifier etc) and we try to "correct" this curve using
1242 * offests we pass on to phy chip (baseband -> before amplifier) so that
1243 * it can use accurate power values when setting tx power (takes amplifier's
1244 * performance on each channel into account).
1246 * EEPROM provides us with the offsets for some pre-calibrated channels
1247 * and we have to interpolate to create the full table for these channels and
1248 * also the table for any channel.
1251 ath5k_eeprom_read_pcal_info(struct ath5k_hw
*ah
)
1253 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
1254 int (*read_pcal
)(struct ath5k_hw
*hw
, int mode
);
1258 if ((ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_4_0
) &&
1259 (AR5K_EEPROM_EEMAP(ee
->ee_misc0
) == 1))
1260 read_pcal
= ath5k_eeprom_read_pcal_info_5112
;
1261 else if ((ah
->ah_ee_version
>= AR5K_EEPROM_VERSION_5_0
) &&
1262 (AR5K_EEPROM_EEMAP(ee
->ee_misc0
) == 2))
1263 read_pcal
= ath5k_eeprom_read_pcal_info_2413
;
1265 read_pcal
= ath5k_eeprom_read_pcal_info_5111
;
1267 for (mode
= AR5K_EEPROM_MODE_11A
; mode
<= AR5K_EEPROM_MODE_11G
; mode
++) {
1268 err
= read_pcal(ah
, mode
);
1272 err
= ath5k_eeprom_read_target_rate_pwr_info(ah
, mode
);
1280 /* Read conformance test limits used for regulatory control */
1282 ath5k_eeprom_read_ctl_info(struct ath5k_hw
*ah
)
1284 struct ath5k_eeprom_info
*ee
= &ah
->ah_capabilities
.cap_eeprom
;
1285 struct ath5k_edge_power
*rep
;
1286 unsigned int fmask
, pmask
;
1287 unsigned int ctl_mode
;
1292 pmask
= AR5K_EEPROM_POWER_M
;
1293 fmask
= AR5K_EEPROM_FREQ_M(ee
->ee_version
);
1294 offset
= AR5K_EEPROM_CTL(ee
->ee_version
);
1295 ee
->ee_ctls
= AR5K_EEPROM_N_CTLS(ee
->ee_version
);
1296 for (i
= 0; i
< ee
->ee_ctls
; i
+= 2) {
1297 AR5K_EEPROM_READ(offset
++, val
);
1298 ee
->ee_ctl
[i
] = (val
>> 8) & 0xff;
1299 ee
->ee_ctl
[i
+ 1] = val
& 0xff;
1302 offset
= AR5K_EEPROM_GROUP8_OFFSET
;
1303 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_4_0
)
1304 offset
+= AR5K_EEPROM_TARGET_PWRSTART(ee
->ee_misc1
) -
1305 AR5K_EEPROM_GROUP5_OFFSET
;
1307 offset
+= AR5K_EEPROM_GROUPS_START(ee
->ee_version
);
1309 rep
= ee
->ee_ctl_pwr
;
1310 for(i
= 0; i
< ee
->ee_ctls
; i
++) {
1311 switch(ee
->ee_ctl
[i
] & AR5K_CTL_MODE_M
) {
1313 case AR5K_CTL_TURBO
:
1314 ctl_mode
= AR5K_EEPROM_MODE_11A
;
1317 ctl_mode
= AR5K_EEPROM_MODE_11G
;
1320 if (ee
->ee_ctl
[i
] == 0) {
1321 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_3_3
)
1325 rep
+= AR5K_EEPROM_N_EDGES
;
1328 if (ee
->ee_version
>= AR5K_EEPROM_VERSION_3_3
) {
1329 for (j
= 0; j
< AR5K_EEPROM_N_EDGES
; j
+= 2) {
1330 AR5K_EEPROM_READ(offset
++, val
);
1331 rep
[j
].freq
= (val
>> 8) & fmask
;
1332 rep
[j
+ 1].freq
= val
& fmask
;
1334 for (j
= 0; j
< AR5K_EEPROM_N_EDGES
; j
+= 2) {
1335 AR5K_EEPROM_READ(offset
++, val
);
1336 rep
[j
].edge
= (val
>> 8) & pmask
;
1337 rep
[j
].flag
= (val
>> 14) & 1;
1338 rep
[j
+ 1].edge
= val
& pmask
;
1339 rep
[j
+ 1].flag
= (val
>> 6) & 1;
1342 AR5K_EEPROM_READ(offset
++, val
);
1343 rep
[0].freq
= (val
>> 9) & fmask
;
1344 rep
[1].freq
= (val
>> 2) & fmask
;
1345 rep
[2].freq
= (val
<< 5) & fmask
;
1347 AR5K_EEPROM_READ(offset
++, val
);
1348 rep
[2].freq
|= (val
>> 11) & 0x1f;
1349 rep
[3].freq
= (val
>> 4) & fmask
;
1350 rep
[4].freq
= (val
<< 3) & fmask
;
1352 AR5K_EEPROM_READ(offset
++, val
);
1353 rep
[4].freq
|= (val
>> 13) & 0x7;
1354 rep
[5].freq
= (val
>> 6) & fmask
;
1355 rep
[6].freq
= (val
<< 1) & fmask
;
1357 AR5K_EEPROM_READ(offset
++, val
);
1358 rep
[6].freq
|= (val
>> 15) & 0x1;
1359 rep
[7].freq
= (val
>> 8) & fmask
;
1361 rep
[0].edge
= (val
>> 2) & pmask
;
1362 rep
[1].edge
= (val
<< 4) & pmask
;
1364 AR5K_EEPROM_READ(offset
++, val
);
1365 rep
[1].edge
|= (val
>> 12) & 0xf;
1366 rep
[2].edge
= (val
>> 6) & pmask
;
1367 rep
[3].edge
= val
& pmask
;
1369 AR5K_EEPROM_READ(offset
++, val
);
1370 rep
[4].edge
= (val
>> 10) & pmask
;
1371 rep
[5].edge
= (val
>> 4) & pmask
;
1372 rep
[6].edge
= (val
<< 2) & pmask
;
1374 AR5K_EEPROM_READ(offset
++, val
);
1375 rep
[6].edge
|= (val
>> 14) & 0x3;
1376 rep
[7].edge
= (val
>> 8) & pmask
;
1378 for (j
= 0; j
< AR5K_EEPROM_N_EDGES
; j
++) {
1379 rep
[j
].freq
= ath5k_eeprom_bin2freq(ee
,
1380 rep
[j
].freq
, ctl_mode
);
1382 rep
+= AR5K_EEPROM_N_EDGES
;
1390 * Initialize eeprom power tables
1393 ath5k_eeprom_init(struct ath5k_hw
*ah
)
1397 err
= ath5k_eeprom_init_header(ah
);
1401 err
= ath5k_eeprom_init_modes(ah
);
1405 err
= ath5k_eeprom_read_pcal_info(ah
);
1409 err
= ath5k_eeprom_read_ctl_info(ah
);
1417 * Read the MAC address from eeprom
1419 int ath5k_eeprom_read_mac(struct ath5k_hw
*ah
, u8
*mac
)
1421 u8 mac_d
[ETH_ALEN
] = {};
1426 ret
= ath5k_hw_eeprom_read(ah
, 0x20, &data
);
1430 for (offset
= 0x1f, octet
= 0, total
= 0; offset
>= 0x1d; offset
--) {
1431 ret
= ath5k_hw_eeprom_read(ah
, offset
, &data
);
1436 mac_d
[octet
+ 1] = data
& 0xff;
1437 mac_d
[octet
] = data
>> 8;
1441 if (!total
|| total
== 3 * 0xffff)
1444 memcpy(mac
, mac_d
, ETH_ALEN
);
1449 bool ath5k_eeprom_is_hb63(struct ath5k_hw
*ah
)
1453 ath5k_hw_eeprom_read(ah
, AR5K_EEPROM_IS_HB63
, &data
);
1455 if ((ah
->ah_mac_version
== (AR5K_SREV_AR2425
>> 4)) && data
)