diff options
Diffstat (limited to 'drivers/net/wireless/ath5k/eeprom.c')
-rw-r--r-- | drivers/net/wireless/ath5k/eeprom.c | 1194 |
1 files changed, 1047 insertions, 147 deletions
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c index a883839b6a9f..1cb7edfae625 100644 --- a/drivers/net/wireless/ath5k/eeprom.c +++ b/drivers/net/wireless/ath5k/eeprom.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | 2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> |
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | 3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> |
4 | * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org> | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and distribute this software for any | 6 | * Permission to use, copy, modify, and distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -63,8 +64,8 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) | |||
63 | /* | 64 | /* |
64 | * Translate binary channel representation in EEPROM to frequency | 65 | * Translate binary channel representation in EEPROM to frequency |
65 | */ | 66 | */ |
66 | static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, | 67 | static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, |
67 | unsigned int mode) | 68 | unsigned int mode) |
68 | { | 69 | { |
69 | u16 val; | 70 | u16 val; |
70 | 71 | ||
@@ -72,13 +73,13 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, | |||
72 | return bin; | 73 | return bin; |
73 | 74 | ||
74 | if (mode == AR5K_EEPROM_MODE_11A) { | 75 | if (mode == AR5K_EEPROM_MODE_11A) { |
75 | if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2) | 76 | if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) |
76 | val = (5 * bin) + 4800; | 77 | val = (5 * bin) + 4800; |
77 | else | 78 | else |
78 | val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : | 79 | val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : |
79 | (bin * 10) + 5100; | 80 | (bin * 10) + 5100; |
80 | } else { | 81 | } else { |
81 | if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2) | 82 | if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) |
82 | val = bin + 2300; | 83 | val = bin + 2300; |
83 | else | 84 | else |
84 | val = bin + 2400; | 85 | val = bin + 2400; |
@@ -88,6 +89,71 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, | |||
88 | } | 89 | } |
89 | 90 | ||
90 | /* | 91 | /* |
92 | * Initialize eeprom & capabilities structs | ||
93 | */ | ||
94 | static int | ||
95 | ath5k_eeprom_init_header(struct ath5k_hw *ah) | ||
96 | { | ||
97 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
98 | int ret; | ||
99 | u16 val; | ||
100 | |||
101 | /* Initial TX thermal adjustment values */ | ||
102 | ee->ee_tx_clip = 4; | ||
103 | ee->ee_pwd_84 = ee->ee_pwd_90 = 1; | ||
104 | ee->ee_gain_select = 1; | ||
105 | |||
106 | /* | ||
107 | * Read values from EEPROM and store them in the capability structure | ||
108 | */ | ||
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); | ||
114 | |||
115 | /* Return if we have an old EEPROM */ | ||
116 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) | ||
117 | return 0; | ||
118 | |||
119 | #ifdef notyet | ||
120 | /* | ||
121 | * Validate the checksum of the EEPROM date. There are some | ||
122 | * devices with invalid EEPROMs. | ||
123 | */ | ||
124 | for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { | ||
125 | AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); | ||
126 | cksum ^= val; | ||
127 | } | ||
128 | if (cksum != AR5K_EEPROM_INFO_CKSUM) { | ||
129 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); | ||
130 | return -EIO; | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), | ||
135 | ee_ant_gain); | ||
136 | |||
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); | ||
140 | } | ||
141 | |||
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; | ||
146 | |||
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; | ||
150 | } | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | |||
156 | /* | ||
91 | * Read antenna infos from eeprom | 157 | * Read antenna infos from eeprom |
92 | */ | 158 | */ |
93 | static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, | 159 | static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, |
@@ -100,7 +166,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, | |||
100 | 166 | ||
101 | AR5K_EEPROM_READ(o++, val); | 167 | AR5K_EEPROM_READ(o++, val); |
102 | ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; | 168 | ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; |
103 | ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f; | 169 | ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f; |
104 | ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; | 170 | ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; |
105 | 171 | ||
106 | AR5K_EEPROM_READ(o++, val); | 172 | AR5K_EEPROM_READ(o++, val); |
@@ -157,6 +223,30 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
157 | u16 val; | 223 | u16 val; |
158 | int ret; | 224 | int ret; |
159 | 225 | ||
226 | ee->ee_n_piers[mode] = 0; | ||
227 | AR5K_EEPROM_READ(o++, val); | ||
228 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | ||
229 | switch(mode) { | ||
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; | ||
234 | |||
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; | ||
242 | break; | ||
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; | ||
247 | break; | ||
248 | } | ||
249 | |||
160 | AR5K_EEPROM_READ(o++, val); | 250 | AR5K_EEPROM_READ(o++, val); |
161 | ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; | 251 | ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; |
162 | ee->ee_thr_62[mode] = val & 0xff; | 252 | ee->ee_thr_62[mode] = val & 0xff; |
@@ -209,8 +299,11 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
209 | AR5K_EEPROM_READ(o++, val); | 299 | AR5K_EEPROM_READ(o++, val); |
210 | ee->ee_i_gain[mode] |= (val << 3) & 0x38; | 300 | ee->ee_i_gain[mode] |= (val << 3) & 0x38; |
211 | 301 | ||
212 | if (mode == AR5K_EEPROM_MODE_11G) | 302 | if (mode == AR5K_EEPROM_MODE_11G) { |
213 | ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff; | 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; | ||
306 | } | ||
214 | } | 307 | } |
215 | 308 | ||
216 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && | 309 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && |
@@ -219,10 +312,77 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
219 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | 312 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; |
220 | } | 313 | } |
221 | 314 | ||
222 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 && | 315 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0) |
223 | mode == AR5K_EEPROM_MODE_11G) | 316 | goto done; |
224 | ee->ee_scaled_cck_delta = (val >> 11) & 0x1f; | 317 | |
318 | switch(mode) { | ||
319 | case AR5K_EEPROM_MODE_11A: | ||
320 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1) | ||
321 | break; | ||
322 | |||
323 | AR5K_EEPROM_READ(o++, val); | ||
324 | ee->ee_margin_tx_rx[mode] = val & 0x3f; | ||
325 | break; | ||
326 | case AR5K_EEPROM_MODE_11B: | ||
327 | AR5K_EEPROM_READ(o++, val); | ||
328 | |||
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]++; | ||
333 | |||
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]++; | ||
338 | |||
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]++; | ||
344 | |||
345 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
346 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | ||
347 | break; | ||
348 | case AR5K_EEPROM_MODE_11G: | ||
349 | AR5K_EEPROM_READ(o++, val); | ||
350 | |||
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]++; | ||
355 | |||
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]++; | ||
360 | |||
361 | AR5K_EEPROM_READ(o++, val); | ||
362 | ee->ee_turbo_max_power[mode] = val & 0x7f; | ||
363 | ee->ee_xr_power[mode] = (val >> 7) & 0x3f; | ||
364 | |||
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]++; | ||
225 | 370 | ||
371 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
372 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | ||
373 | |||
374 | AR5K_EEPROM_READ(o++, val); | ||
375 | ee->ee_i_cal[mode] = (val >> 8) & 0x3f; | ||
376 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | ||
377 | |||
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; | ||
381 | } | ||
382 | break; | ||
383 | } | ||
384 | |||
385 | done: | ||
226 | /* return new offset */ | 386 | /* return new offset */ |
227 | *offset = o; | 387 | *offset = o; |
228 | 388 | ||
@@ -230,204 +390,944 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
230 | } | 390 | } |
231 | 391 | ||
232 | /* | 392 | /* |
233 | * Initialize eeprom & capabilities structs | 393 | * Read turbo mode information on newer EEPROM versions |
234 | */ | 394 | */ |
235 | int ath5k_eeprom_init(struct ath5k_hw *ah) | 395 | static int |
396 | ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah, | ||
397 | u32 *offset, unsigned int mode) | ||
236 | { | 398 | { |
237 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 399 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
238 | unsigned int mode, i; | 400 | u32 o = *offset; |
239 | int ret; | ||
240 | u32 offset; | ||
241 | u16 val; | 401 | u16 val; |
402 | int ret; | ||
242 | 403 | ||
243 | /* Initial TX thermal adjustment values */ | 404 | if (ee->ee_version < AR5K_EEPROM_VERSION_5_0) |
244 | ee->ee_tx_clip = 4; | 405 | return 0; |
245 | ee->ee_pwd_84 = ee->ee_pwd_90 = 1; | ||
246 | ee->ee_gain_select = 1; | ||
247 | 406 | ||
248 | /* | 407 | switch (mode){ |
249 | * Read values from EEPROM and store them in the capability structure | 408 | case AR5K_EEPROM_MODE_11A: |
250 | */ | 409 | ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f; |
251 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic); | ||
252 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect); | ||
253 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain); | ||
254 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version); | ||
255 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header); | ||
256 | 410 | ||
257 | /* Return if we have an old EEPROM */ | 411 | ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7; |
258 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) | 412 | AR5K_EEPROM_READ(o++, val); |
259 | return 0; | 413 | ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3; |
414 | ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f; | ||
415 | |||
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; | ||
420 | |||
421 | if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2) | ||
422 | ee->ee_pd_gain_overlap = (val >> 9) & 0xf; | ||
423 | break; | ||
424 | case AR5K_EEPROM_MODE_11G: | ||
425 | ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f; | ||
426 | |||
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; | ||
431 | |||
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; | ||
436 | break; | ||
437 | } | ||
438 | |||
439 | /* return new offset */ | ||
440 | *offset = o; | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | |||
446 | static int | ||
447 | ath5k_eeprom_init_modes(struct ath5k_hw *ah) | ||
448 | { | ||
449 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
450 | u32 mode_offset[3]; | ||
451 | unsigned int mode; | ||
452 | u32 offset; | ||
453 | int ret; | ||
260 | 454 | ||
261 | #ifdef notyet | ||
262 | /* | 455 | /* |
263 | * Validate the checksum of the EEPROM date. There are some | 456 | * Get values for all modes |
264 | * devices with invalid EEPROMs. | ||
265 | */ | 457 | */ |
266 | for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { | 458 | mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version); |
267 | AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); | 459 | mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version); |
268 | cksum ^= val; | 460 | mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version); |
461 | |||
462 | ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] = | ||
463 | AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header); | ||
464 | |||
465 | for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) { | ||
466 | offset = mode_offset[mode]; | ||
467 | |||
468 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | ||
469 | if (ret) | ||
470 | return ret; | ||
471 | |||
472 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | ||
473 | if (ret) | ||
474 | return ret; | ||
475 | |||
476 | ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode); | ||
477 | if (ret) | ||
478 | return ret; | ||
269 | } | 479 | } |
270 | if (cksum != AR5K_EEPROM_INFO_CKSUM) { | 480 | |
271 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); | 481 | /* override for older eeprom versions for better performance */ |
272 | return -EIO; | 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; | ||
273 | } | 486 | } |
274 | #endif | ||
275 | 487 | ||
276 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), | 488 | return 0; |
277 | ee_ant_gain); | 489 | } |
278 | 490 | ||
279 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | 491 | static inline void |
280 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); | 492 | ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) |
281 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); | 493 | { |
282 | } | 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 }; | ||
498 | const u16 *ip; | ||
499 | int i; | ||
500 | |||
501 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2) | ||
502 | ip = intercepts3_2; | ||
503 | else | ||
504 | ip = intercepts3; | ||
283 | 505 | ||
284 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { | 506 | for (i = 0; i < ARRAY_SIZE(intercepts3); i++) |
285 | AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val); | 507 | *vp++ = (ip[i] * max + (100 - ip[i]) * min) / 100; |
286 | ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7; | 508 | } |
287 | ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7; | ||
288 | 509 | ||
289 | AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val); | 510 | static inline int |
290 | ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7; | 511 | ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, |
291 | ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7; | 512 | struct ath5k_chan_pcal_info *pc, u8 *count) |
513 | { | ||
514 | int o = *offset; | ||
515 | int i = 0; | ||
516 | u8 f1, f2; | ||
517 | int ret; | ||
518 | u16 val; | ||
519 | |||
520 | while(i < max) { | ||
521 | AR5K_EEPROM_READ(o++, val); | ||
522 | |||
523 | f1 = (val >> 8) & 0xff; | ||
524 | f2 = val & 0xff; | ||
525 | |||
526 | if (f1) | ||
527 | pc[i++].freq = f1; | ||
528 | |||
529 | if (f2) | ||
530 | pc[i++].freq = f2; | ||
531 | |||
532 | if (!f1 || !f2) | ||
533 | break; | ||
292 | } | 534 | } |
535 | *offset = o; | ||
536 | *count = i; | ||
293 | 537 | ||
294 | /* | 538 | return 0; |
295 | * Get conformance test limit values | 539 | } |
296 | */ | 540 | |
297 | offset = AR5K_EEPROM_CTL(ah->ah_ee_version); | 541 | static int |
298 | ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version); | 542 | ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) |
543 | { | ||
544 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
545 | struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; | ||
546 | int i, ret; | ||
547 | u16 val; | ||
548 | u8 mask; | ||
549 | |||
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]); | ||
554 | } else { | ||
555 | mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version); | ||
299 | 556 | ||
300 | for (i = 0; i < ee->ee_ctls; i++) { | ||
301 | AR5K_EEPROM_READ(offset++, val); | 557 | AR5K_EEPROM_READ(offset++, val); |
302 | ee->ee_ctl[i] = (val >> 8) & 0xff; | 558 | pcal[0].freq = (val >> 9) & mask; |
303 | ee->ee_ctl[i + 1] = val & 0xff; | 559 | pcal[1].freq = (val >> 2) & mask; |
560 | pcal[2].freq = (val << 5) & mask; | ||
561 | |||
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; | ||
566 | |||
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; | ||
571 | |||
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; | ||
577 | |||
578 | AR5K_EEPROM_READ(offset++, val); | ||
579 | pcal[9].freq |= (val >> 10) & 0x3f; | ||
580 | ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10; | ||
304 | } | 581 | } |
305 | 582 | ||
306 | /* | 583 | for(i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i += 1) { |
307 | * Get values for 802.11a (5GHz) | 584 | pcal[i].freq = ath5k_eeprom_bin2freq(ee, |
308 | */ | 585 | pcal[i].freq, AR5K_EEPROM_MODE_11A); |
309 | mode = AR5K_EEPROM_MODE_11A; | 586 | } |
310 | 587 | ||
311 | ee->ee_turbo_max_power[mode] = | 588 | return 0; |
312 | AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header); | 589 | } |
313 | 590 | ||
314 | offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version); | 591 | static inline int |
592 | ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) | ||
593 | { | ||
594 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
595 | struct ath5k_chan_pcal_info *pcal; | ||
596 | int i; | ||
597 | |||
598 | switch(mode) { | ||
599 | case AR5K_EEPROM_MODE_11B: | ||
600 | pcal = ee->ee_pwr_cal_b; | ||
601 | break; | ||
602 | case AR5K_EEPROM_MODE_11G: | ||
603 | pcal = ee->ee_pwr_cal_g; | ||
604 | break; | ||
605 | default: | ||
606 | return -EINVAL; | ||
607 | } | ||
315 | 608 | ||
316 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | 609 | ath5k_eeprom_read_freq_list(ah, &offset, |
317 | if (ret) | 610 | AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal, |
318 | return ret; | 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, | ||
614 | pcal[i].freq, mode); | ||
615 | } | ||
319 | 616 | ||
320 | AR5K_EEPROM_READ(offset++, val); | 617 | return 0; |
321 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | 618 | } |
322 | ee->ee_ob[mode][3] = (val >> 5) & 0x7; | ||
323 | ee->ee_db[mode][3] = (val >> 2) & 0x7; | ||
324 | ee->ee_ob[mode][2] = (val << 1) & 0x7; | ||
325 | |||
326 | AR5K_EEPROM_READ(offset++, val); | ||
327 | ee->ee_ob[mode][2] |= (val >> 15) & 0x1; | ||
328 | ee->ee_db[mode][2] = (val >> 12) & 0x7; | ||
329 | ee->ee_ob[mode][1] = (val >> 9) & 0x7; | ||
330 | ee->ee_db[mode][1] = (val >> 6) & 0x7; | ||
331 | ee->ee_ob[mode][0] = (val >> 3) & 0x7; | ||
332 | ee->ee_db[mode][0] = val & 0x7; | ||
333 | |||
334 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | ||
335 | if (ret) | ||
336 | return ret; | ||
337 | 619 | ||
338 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) { | 620 | |
339 | AR5K_EEPROM_READ(offset++, val); | 621 | static int |
340 | ee->ee_margin_tx_rx[mode] = val & 0x3f; | 622 | ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) |
623 | { | ||
624 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
625 | struct ath5k_chan_pcal_info *pcal; | ||
626 | int offset, ret; | ||
627 | int i, j; | ||
628 | u16 val; | ||
629 | |||
630 | offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); | ||
631 | switch(mode) { | ||
632 | case AR5K_EEPROM_MODE_11A: | ||
633 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | ||
634 | return 0; | ||
635 | |||
636 | ret = ath5k_eeprom_init_11a_pcal_freq(ah, | ||
637 | offset + AR5K_EEPROM_GROUP1_OFFSET); | ||
638 | if (ret < 0) | ||
639 | return ret; | ||
640 | |||
641 | offset += AR5K_EEPROM_GROUP2_OFFSET; | ||
642 | pcal = ee->ee_pwr_cal_a; | ||
643 | break; | ||
644 | case AR5K_EEPROM_MODE_11B: | ||
645 | if (!AR5K_EEPROM_HDR_11B(ee->ee_header) && | ||
646 | !AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
647 | return 0; | ||
648 | |||
649 | pcal = ee->ee_pwr_cal_b; | ||
650 | offset += AR5K_EEPROM_GROUP3_OFFSET; | ||
651 | |||
652 | /* fixed piers */ | ||
653 | pcal[0].freq = 2412; | ||
654 | pcal[1].freq = 2447; | ||
655 | pcal[2].freq = 2484; | ||
656 | ee->ee_n_piers[mode] = 3; | ||
657 | break; | ||
658 | case AR5K_EEPROM_MODE_11G: | ||
659 | if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
660 | return 0; | ||
661 | |||
662 | pcal = ee->ee_pwr_cal_g; | ||
663 | offset += AR5K_EEPROM_GROUP4_OFFSET; | ||
664 | |||
665 | /* fixed piers */ | ||
666 | pcal[0].freq = 2312; | ||
667 | pcal[1].freq = 2412; | ||
668 | pcal[2].freq = 2484; | ||
669 | ee->ee_n_piers[mode] = 3; | ||
670 | break; | ||
671 | default: | ||
672 | return -EINVAL; | ||
341 | } | 673 | } |
342 | 674 | ||
343 | /* | 675 | for (i = 0; i < ee->ee_n_piers[mode]; i++) { |
344 | * Get values for 802.11b (2.4GHz) | 676 | struct ath5k_chan_pcal_info_rf5111 *cdata = |
345 | */ | 677 | &pcal[i].rf5111_info; |
346 | mode = AR5K_EEPROM_MODE_11B; | ||
347 | offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version); | ||
348 | 678 | ||
349 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | 679 | AR5K_EEPROM_READ(offset++, val); |
350 | if (ret) | 680 | cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M); |
351 | return ret; | 681 | cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M); |
682 | cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M); | ||
352 | 683 | ||
353 | AR5K_EEPROM_READ(offset++, val); | 684 | AR5K_EEPROM_READ(offset++, val); |
354 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | 685 | cdata->pwr[0] |= ((val >> 14) & 0x3); |
355 | ee->ee_ob[mode][1] = (val >> 4) & 0x7; | 686 | cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M); |
356 | ee->ee_db[mode][1] = val & 0x7; | 687 | cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M); |
688 | cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M); | ||
357 | 689 | ||
358 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | 690 | AR5K_EEPROM_READ(offset++, val); |
359 | if (ret) | 691 | cdata->pwr[3] |= ((val >> 12) & 0xf); |
360 | return ret; | 692 | cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M); |
693 | cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M); | ||
361 | 694 | ||
362 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | ||
363 | AR5K_EEPROM_READ(offset++, val); | 695 | AR5K_EEPROM_READ(offset++, val); |
364 | ee->ee_cal_pier[mode][0] = | 696 | cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M); |
365 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | 697 | cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M); |
366 | ee->ee_cal_pier[mode][1] = | 698 | cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M); |
367 | ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode); | ||
368 | 699 | ||
369 | AR5K_EEPROM_READ(offset++, val); | 700 | AR5K_EEPROM_READ(offset++, val); |
370 | ee->ee_cal_pier[mode][2] = | 701 | cdata->pwr[8] |= ((val >> 14) & 0x3); |
371 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | 702 | cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M); |
703 | cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M); | ||
704 | |||
705 | ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min, | ||
706 | cdata->pcdac_max, cdata->pcdac); | ||
707 | |||
708 | for (j = 0; j < AR5K_EEPROM_N_PCDAC; j++) { | ||
709 | cdata->pwr[j] = (u16) | ||
710 | (AR5K_EEPROM_POWER_STEP * cdata->pwr[j]); | ||
711 | } | ||
372 | } | 712 | } |
373 | 713 | ||
374 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | 714 | return 0; |
375 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | 715 | } |
376 | 716 | ||
377 | /* | 717 | static int |
378 | * Get values for 802.11g (2.4GHz) | 718 | ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) |
379 | */ | 719 | { |
380 | mode = AR5K_EEPROM_MODE_11G; | 720 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
381 | offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version); | 721 | struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info; |
722 | struct ath5k_chan_pcal_info *gen_chan_info; | ||
723 | u32 offset; | ||
724 | unsigned int i, c; | ||
725 | u16 val; | ||
726 | int ret; | ||
382 | 727 | ||
383 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | 728 | switch (mode) { |
384 | if (ret) | 729 | case AR5K_EEPROM_MODE_11A: |
385 | return ret; | 730 | /* |
731 | * Read 5GHz EEPROM channels | ||
732 | */ | ||
733 | offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); | ||
734 | ath5k_eeprom_init_11a_pcal_freq(ah, offset); | ||
735 | |||
736 | offset += AR5K_EEPROM_GROUP2_OFFSET; | ||
737 | gen_chan_info = ee->ee_pwr_cal_a; | ||
738 | break; | ||
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; | ||
743 | |||
744 | /* NB: frequency piers parsed during mode init */ | ||
745 | gen_chan_info = ee->ee_pwr_cal_b; | ||
746 | break; | ||
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; | ||
753 | |||
754 | /* NB: frequency piers parsed during mode init */ | ||
755 | gen_chan_info = ee->ee_pwr_cal_g; | ||
756 | break; | ||
757 | default: | ||
758 | return -EINVAL; | ||
759 | } | ||
386 | 760 | ||
387 | AR5K_EEPROM_READ(offset++, val); | 761 | for (i = 0; i < ee->ee_n_piers[mode]; i++) { |
388 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | 762 | chan_pcal_info = &gen_chan_info[i].rf5112_info; |
389 | ee->ee_ob[mode][1] = (val >> 4) & 0x7; | ||
390 | ee->ee_db[mode][1] = val & 0x7; | ||
391 | 763 | ||
392 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | 764 | /* Power values in dBm * 4 |
393 | if (ret) | 765 | * for the lower xpd gain curve |
394 | return ret; | 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); | ||
771 | } | ||
395 | 772 | ||
396 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | 773 | /* PCDAC steps |
774 | * corresponding to the above power | ||
775 | * measurements */ | ||
397 | AR5K_EEPROM_READ(offset++, val); | 776 | AR5K_EEPROM_READ(offset++, val); |
398 | ee->ee_cal_pier[mode][0] = | 777 | chan_pcal_info->pcdac_x0[1] = (val & 0x1f); |
399 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | 778 | chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f); |
400 | ee->ee_cal_pier[mode][1] = | 779 | chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f); |
401 | ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode); | ||
402 | 780 | ||
781 | /* Power values in dBm * 4 | ||
782 | * for the higher xpd gain curve | ||
783 | * (18 dBm -> lower output power) */ | ||
403 | AR5K_EEPROM_READ(offset++, val); | 784 | AR5K_EEPROM_READ(offset++, val); |
404 | ee->ee_turbo_max_power[mode] = val & 0x7f; | 785 | chan_pcal_info->pwr_x3[0] = (val & 0xff); |
405 | ee->ee_xr_power[mode] = (val >> 7) & 0x3f; | 786 | chan_pcal_info->pwr_x3[1] = ((val >> 8) & 0xff); |
406 | 787 | ||
407 | AR5K_EEPROM_READ(offset++, val); | 788 | AR5K_EEPROM_READ(offset++, val); |
408 | ee->ee_cal_pier[mode][2] = | 789 | chan_pcal_info->pwr_x3[2] = (val & 0xff); |
409 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | 790 | |
791 | /* PCDAC steps | ||
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; | ||
797 | |||
798 | if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) { | ||
799 | chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0xff); | ||
800 | |||
801 | /* Last xpd0 power level is also channel maximum */ | ||
802 | gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3]; | ||
803 | } else { | ||
804 | chan_pcal_info->pcdac_x0[0] = 1; | ||
805 | gen_chan_info[i].max_pwr = ((val >> 8) & 0xff); | ||
806 | } | ||
410 | 807 | ||
411 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | 808 | /* Recreate pcdac_x0 table for this channel using pcdac steps */ |
412 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | 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]; | ||
812 | } | ||
813 | |||
814 | return 0; | ||
815 | } | ||
816 | |||
817 | static inline unsigned int | ||
818 | ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode) | ||
819 | { | ||
820 | static const unsigned int pdgains_size[] = { 4, 6, 9, 12 }; | ||
821 | unsigned int sz; | ||
822 | |||
823 | sz = pdgains_size[ee->ee_pd_gains[mode] - 1]; | ||
824 | sz *= ee->ee_n_piers[mode]; | ||
825 | |||
826 | return sz; | ||
827 | } | ||
828 | |||
829 | static unsigned int | ||
830 | ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) | ||
831 | { | ||
832 | u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4); | ||
833 | |||
834 | switch(mode) { | ||
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; | ||
838 | /* fall through */ | ||
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; | ||
842 | /* fall through */ | ||
843 | case AR5K_EEPROM_MODE_11A: | ||
844 | break; | ||
845 | default: | ||
846 | break; | ||
847 | } | ||
848 | |||
849 | return offset; | ||
850 | } | ||
851 | |||
852 | static int | ||
853 | ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) | ||
854 | { | ||
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; | ||
858 | unsigned int i, c; | ||
859 | u32 offset; | ||
860 | int ret; | ||
861 | u16 val; | ||
862 | u8 pd_gains = 0; | ||
863 | |||
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; | ||
869 | |||
870 | offset = ath5k_cal_data_offset_2413(ee, mode); | ||
871 | switch (mode) { | ||
872 | case AR5K_EEPROM_MODE_11A: | ||
873 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | ||
874 | return 0; | ||
875 | |||
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; | ||
879 | break; | ||
880 | case AR5K_EEPROM_MODE_11B: | ||
881 | if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) | ||
882 | return 0; | ||
413 | 883 | ||
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; | ||
887 | break; | ||
888 | case AR5K_EEPROM_MODE_11G: | ||
889 | if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
890 | return 0; | ||
891 | |||
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; | ||
895 | break; | ||
896 | default: | ||
897 | return -EINVAL; | ||
898 | } | ||
899 | |||
900 | if (pd_gains == 0) | ||
901 | return 0; | ||
902 | |||
903 | for (i = 0; i < ee->ee_n_piers[mode]; i++) { | ||
904 | chan_pcal_info = &gen_chan_info[i].rf2413_info; | ||
905 | |||
906 | /* | ||
907 | * Read pwr_i, pddac_i and the first | ||
908 | * 2 pd points (pwr, pddac) | ||
909 | */ | ||
414 | AR5K_EEPROM_READ(offset++, val); | 910 | AR5K_EEPROM_READ(offset++, val); |
415 | ee->ee_i_cal[mode] = (val >> 8) & 0x3f; | 911 | chan_pcal_info->pwr_i[0] = val & 0x1f; |
416 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | 912 | chan_pcal_info->pddac_i[0] = (val >> 5) & 0x7f; |
913 | chan_pcal_info->pwr[0][0] = | ||
914 | (val >> 12) & 0xf; | ||
417 | 915 | ||
418 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { | 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] = | ||
920 | (val >> 10) & 0x3f; | ||
921 | |||
922 | AR5K_EEPROM_READ(offset++, val); | ||
923 | chan_pcal_info->pwr[0][2] = val & 0xf; | ||
924 | chan_pcal_info->pddac[0][2] = | ||
925 | (val >> 4) & 0x3f; | ||
926 | |||
927 | chan_pcal_info->pwr[0][3] = 0; | ||
928 | chan_pcal_info->pddac[0][3] = 0; | ||
929 | |||
930 | if (pd_gains > 1) { | ||
931 | /* | ||
932 | * Pd gain 0 is not the last pd gain | ||
933 | * so it only has 2 pd points. | ||
934 | * Continue wih pd gain 1. | ||
935 | */ | ||
936 | chan_pcal_info->pwr_i[1] = (val >> 10) & 0x1f; | ||
937 | |||
938 | chan_pcal_info->pddac_i[1] = (val >> 15) & 0x1; | ||
419 | AR5K_EEPROM_READ(offset++, val); | 939 | AR5K_EEPROM_READ(offset++, val); |
420 | ee->ee_cck_ofdm_gain_delta = val & 0xff; | 940 | chan_pcal_info->pddac_i[1] |= (val & 0x3F) << 1; |
941 | |||
942 | chan_pcal_info->pwr[1][0] = (val >> 6) & 0xf; | ||
943 | chan_pcal_info->pddac[1][0] = | ||
944 | (val >> 10) & 0x3f; | ||
945 | |||
946 | AR5K_EEPROM_READ(offset++, val); | ||
947 | chan_pcal_info->pwr[1][1] = val & 0xf; | ||
948 | chan_pcal_info->pddac[1][1] = | ||
949 | (val >> 4) & 0x3f; | ||
950 | chan_pcal_info->pwr[1][2] = | ||
951 | (val >> 10) & 0xf; | ||
952 | |||
953 | chan_pcal_info->pddac[1][2] = | ||
954 | (val >> 14) & 0x3; | ||
955 | AR5K_EEPROM_READ(offset++, val); | ||
956 | chan_pcal_info->pddac[1][2] |= | ||
957 | (val & 0xF) << 2; | ||
958 | |||
959 | chan_pcal_info->pwr[1][3] = 0; | ||
960 | chan_pcal_info->pddac[1][3] = 0; | ||
961 | } else if (pd_gains == 1) { | ||
962 | /* | ||
963 | * Pd gain 0 is the last one so | ||
964 | * read the extra point. | ||
965 | */ | ||
966 | chan_pcal_info->pwr[0][3] = | ||
967 | (val >> 10) & 0xf; | ||
968 | |||
969 | chan_pcal_info->pddac[0][3] = | ||
970 | (val >> 14) & 0x3; | ||
971 | AR5K_EEPROM_READ(offset++, val); | ||
972 | chan_pcal_info->pddac[0][3] |= | ||
973 | (val & 0xF) << 2; | ||
974 | } | ||
975 | |||
976 | /* | ||
977 | * Proceed with the other pd_gains | ||
978 | * as above. | ||
979 | */ | ||
980 | if (pd_gains > 2) { | ||
981 | chan_pcal_info->pwr_i[2] = (val >> 4) & 0x1f; | ||
982 | chan_pcal_info->pddac_i[2] = (val >> 9) & 0x7f; | ||
983 | |||
984 | AR5K_EEPROM_READ(offset++, val); | ||
985 | chan_pcal_info->pwr[2][0] = | ||
986 | (val >> 0) & 0xf; | ||
987 | chan_pcal_info->pddac[2][0] = | ||
988 | (val >> 4) & 0x3f; | ||
989 | chan_pcal_info->pwr[2][1] = | ||
990 | (val >> 10) & 0xf; | ||
991 | |||
992 | chan_pcal_info->pddac[2][1] = | ||
993 | (val >> 14) & 0x3; | ||
994 | AR5K_EEPROM_READ(offset++, val); | ||
995 | chan_pcal_info->pddac[2][1] |= | ||
996 | (val & 0xF) << 2; | ||
997 | |||
998 | chan_pcal_info->pwr[2][2] = | ||
999 | (val >> 4) & 0xf; | ||
1000 | chan_pcal_info->pddac[2][2] = | ||
1001 | (val >> 8) & 0x3f; | ||
1002 | |||
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] = | ||
1007 | (val >> 4) & 0xf; | ||
1008 | chan_pcal_info->pddac[1][3] = | ||
1009 | (val >> 8) & 0x3f; | ||
1010 | } | ||
1011 | |||
1012 | if (pd_gains > 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; | ||
1016 | |||
1017 | chan_pcal_info->pddac_i[3] = (val >> 3) & 0x7f; | ||
1018 | chan_pcal_info->pwr[3][0] = | ||
1019 | (val >> 10) & 0xf; | ||
1020 | chan_pcal_info->pddac[3][0] = | ||
1021 | (val >> 14) & 0x3; | ||
1022 | |||
1023 | AR5K_EEPROM_READ(offset++, val); | ||
1024 | chan_pcal_info->pddac[3][0] |= | ||
1025 | (val & 0xF) << 2; | ||
1026 | chan_pcal_info->pwr[3][1] = | ||
1027 | (val >> 4) & 0xf; | ||
1028 | chan_pcal_info->pddac[3][1] = | ||
1029 | (val >> 8) & 0x3f; | ||
1030 | |||
1031 | chan_pcal_info->pwr[3][2] = | ||
1032 | (val >> 14) & 0x3; | ||
1033 | AR5K_EEPROM_READ(offset++, val); | ||
1034 | chan_pcal_info->pwr[3][2] |= | ||
1035 | ((val >> 0) & 0x3) << 2; | ||
1036 | |||
1037 | chan_pcal_info->pddac[3][2] = | ||
1038 | (val >> 2) & 0x3f; | ||
1039 | chan_pcal_info->pwr[3][3] = | ||
1040 | (val >> 8) & 0xf; | ||
1041 | |||
1042 | chan_pcal_info->pddac[3][3] = | ||
1043 | (val >> 12) & 0xF; | ||
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] = | ||
1049 | (val >> 14) & 0x3; | ||
1050 | AR5K_EEPROM_READ(offset++, val); | ||
1051 | chan_pcal_info->pwr[2][3] |= | ||
1052 | ((val >> 0) & 0x3) << 2; | ||
1053 | |||
1054 | chan_pcal_info->pddac[2][3] = | ||
1055 | (val >> 2) & 0x3f; | ||
1056 | } | ||
1057 | |||
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; | ||
1066 | |||
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; | ||
421 | } | 1074 | } |
422 | } | 1075 | } |
423 | 1076 | ||
424 | /* | 1077 | return 0; |
425 | * Read 5GHz EEPROM channels | 1078 | } |
426 | */ | 1079 | |
1080 | /* | ||
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. | ||
1084 | * | ||
1085 | * This also works for v5 EEPROMs. | ||
1086 | */ | ||
1087 | static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) | ||
1088 | { | ||
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; | ||
1092 | u32 offset; | ||
1093 | u16 val; | ||
1094 | int ret, i; | ||
1095 | |||
1096 | offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); | ||
1097 | rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; | ||
1098 | switch (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; | ||
1103 | break; | ||
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 */ | ||
1108 | break; | ||
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; | ||
1113 | break; | ||
1114 | default: | ||
1115 | return -EINVAL; | ||
1116 | } | ||
1117 | |||
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); | ||
1124 | |||
1125 | rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f); | ||
1126 | rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f; | ||
1127 | |||
1128 | AR5K_EEPROM_READ(offset++, val); | ||
1129 | |||
1130 | if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || | ||
1131 | val == 0) { | ||
1132 | (*rate_target_pwr_num) = i; | ||
1133 | break; | ||
1134 | } | ||
1135 | |||
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); | ||
1139 | } | ||
1140 | } else { | ||
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); | ||
1145 | |||
1146 | rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f); | ||
1147 | rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f; | ||
1148 | |||
1149 | AR5K_EEPROM_READ(offset++, val); | ||
1150 | |||
1151 | if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || | ||
1152 | val == 0) { | ||
1153 | (*rate_target_pwr_num) = i; | ||
1154 | break; | ||
1155 | } | ||
1156 | |||
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); | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | static int | ||
1167 | ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) | ||
1168 | { | ||
1169 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
1170 | int (*read_pcal)(struct ath5k_hw *hw, int mode); | ||
1171 | int mode; | ||
1172 | int err; | ||
1173 | |||
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; | ||
1180 | else | ||
1181 | read_pcal = ath5k_eeprom_read_pcal_info_5111; | ||
1182 | |||
1183 | for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) { | ||
1184 | err = read_pcal(ah, mode); | ||
1185 | if (err) | ||
1186 | return err; | ||
1187 | |||
1188 | err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode); | ||
1189 | if (err < 0) | ||
1190 | return err; | ||
1191 | } | ||
1192 | |||
1193 | return 0; | ||
1194 | } | ||
1195 | |||
1196 | /* Read conformance test limits */ | ||
1197 | static int | ||
1198 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) | ||
1199 | { | ||
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; | ||
1204 | int ret, i, j; | ||
1205 | u32 offset; | ||
1206 | u16 val; | ||
1207 | |||
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; | ||
1216 | } | ||
1217 | |||
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; | ||
1222 | else | ||
1223 | offset += AR5K_EEPROM_GROUPS_START(ee->ee_version); | ||
1224 | |||
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) { | ||
1228 | case AR5K_CTL_11A: | ||
1229 | case AR5K_CTL_TURBO: | ||
1230 | ctl_mode = AR5K_EEPROM_MODE_11A; | ||
1231 | break; | ||
1232 | default: | ||
1233 | ctl_mode = AR5K_EEPROM_MODE_11G; | ||
1234 | break; | ||
1235 | } | ||
1236 | if (ee->ee_ctl[i] == 0) { | ||
1237 | if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) | ||
1238 | offset += 8; | ||
1239 | else | ||
1240 | offset += 7; | ||
1241 | rep += AR5K_EEPROM_N_EDGES; | ||
1242 | continue; | ||
1243 | } | ||
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; | ||
1249 | } | ||
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; | ||
1256 | } | ||
1257 | } else { | ||
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; | ||
1262 | |||
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; | ||
1267 | |||
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; | ||
1272 | |||
1273 | AR5K_EEPROM_READ(offset++, val); | ||
1274 | rep[6].freq |= (val >> 15) & 0x1; | ||
1275 | rep[7].freq = (val >> 8) & fmask; | ||
1276 | |||
1277 | rep[0].edge = (val >> 2) & pmask; | ||
1278 | rep[1].edge = (val << 4) & pmask; | ||
1279 | |||
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; | ||
1284 | |||
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; | ||
1289 | |||
1290 | AR5K_EEPROM_READ(offset++, val); | ||
1291 | rep[6].edge |= (val >> 14) & 0x3; | ||
1292 | rep[7].edge = (val >> 8) & pmask; | ||
1293 | } | ||
1294 | for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) { | ||
1295 | rep[j].freq = ath5k_eeprom_bin2freq(ee, | ||
1296 | rep[j].freq, ctl_mode); | ||
1297 | } | ||
1298 | rep += AR5K_EEPROM_N_EDGES; | ||
1299 | } | ||
427 | 1300 | ||
428 | return 0; | 1301 | return 0; |
429 | } | 1302 | } |
430 | 1303 | ||
1304 | |||
1305 | /* | ||
1306 | * Initialize eeprom power tables | ||
1307 | */ | ||
1308 | int | ||
1309 | ath5k_eeprom_init(struct ath5k_hw *ah) | ||
1310 | { | ||
1311 | int err; | ||
1312 | |||
1313 | err = ath5k_eeprom_init_header(ah); | ||
1314 | if (err < 0) | ||
1315 | return err; | ||
1316 | |||
1317 | err = ath5k_eeprom_init_modes(ah); | ||
1318 | if (err < 0) | ||
1319 | return err; | ||
1320 | |||
1321 | err = ath5k_eeprom_read_pcal_info(ah); | ||
1322 | if (err < 0) | ||
1323 | return err; | ||
1324 | |||
1325 | err = ath5k_eeprom_read_ctl_info(ah); | ||
1326 | if (err < 0) | ||
1327 | return err; | ||
1328 | |||
1329 | return 0; | ||
1330 | } | ||
431 | /* | 1331 | /* |
432 | * Read the MAC address from eeprom | 1332 | * Read the MAC address from eeprom |
433 | */ | 1333 | */ |