diff options
author | Felix Fietkau <nbd@openwrt.org> | 2008-11-20 09:16:22 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-26 09:47:41 -0500 |
commit | 1048643ea94d742bd409f343e284af430656fd6c (patch) | |
tree | 90e6231e39deffa3c1b8263facb6f45ebf1ee606 /drivers/net/wireless/ath5k | |
parent | 7ac47010a444d9f4285cf1ae06780633a112489b (diff) |
ath5k: Clean up eeprom parsing and add missing calibration data
This patch brings the ath5k eeprom parsing code in sync with the work
done on ath_info by Nick Kossifidis and integrates the missing parts
based on the code of the Atheros Legacy HAL release.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k')
-rw-r--r-- | drivers/net/wireless/ath5k/ath5k.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/eeprom.c | 1194 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/eeprom.h | 253 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reset.c | 2 |
4 files changed, 1264 insertions, 192 deletions
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index a725bb94a52d..5ee2dd1814c2 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h | |||
@@ -821,13 +821,6 @@ struct ath5k_athchan_2ghz { | |||
821 | return (false); \ | 821 | return (false); \ |
822 | } while (0) | 822 | } while (0) |
823 | 823 | ||
824 | enum ath5k_ant_setting { | ||
825 | AR5K_ANT_VARIABLE = 0, /* variable by programming */ | ||
826 | AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */ | ||
827 | AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */ | ||
828 | AR5K_ANT_MAX = 3, | ||
829 | }; | ||
830 | |||
831 | /* | 824 | /* |
832 | * Hardware interrupt abstraction | 825 | * Hardware interrupt abstraction |
833 | */ | 826 | */ |
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 | */ |
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h index a468ecfbb18a..09eb7d0176a4 100644 --- a/drivers/net/wireless/ath5k/eeprom.h +++ b/drivers/net/wireless/ath5k/eeprom.h | |||
@@ -25,24 +25,8 @@ | |||
25 | #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ | 25 | #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ |
26 | #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ | 26 | #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ |
27 | 27 | ||
28 | #define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */ | ||
29 | #define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */ | ||
30 | #define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */ | ||
31 | #define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */ | ||
32 | #define AR5K_EEPROM_PROTECT_WR_32_63 0x0008 | ||
33 | #define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */ | ||
34 | #define AR5K_EEPROM_PROTECT_WR_64_127 0x0020 | ||
35 | #define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */ | ||
36 | #define AR5K_EEPROM_PROTECT_WR_128_191 0x0080 | ||
37 | #define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */ | ||
38 | #define AR5K_EEPROM_PROTECT_WR_192_207 0x0200 | ||
39 | #define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */ | ||
40 | #define AR5K_EEPROM_PROTECT_WR_208_223 0x0800 | ||
41 | #define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */ | ||
42 | #define AR5K_EEPROM_PROTECT_WR_224_239 0x2000 | ||
43 | #define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */ | ||
44 | #define AR5K_EEPROM_PROTECT_WR_240_255 0x8000 | ||
45 | #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ | 28 | #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ |
29 | #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ | ||
46 | #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ | 30 | #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ |
47 | #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) | 31 | #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) |
48 | #define AR5K_EEPROM_INFO_CKSUM 0xffff | 32 | #define AR5K_EEPROM_INFO_CKSUM 0xffff |
@@ -53,15 +37,19 @@ | |||
53 | #define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */ | 37 | #define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */ |
54 | #define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */ | 38 | #define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */ |
55 | #define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */ | 39 | #define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */ |
56 | #define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */ | 40 | #define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */ |
57 | #define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */ | 41 | #define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */ |
58 | #define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */ | 42 | #define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */ |
59 | #define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */ | 43 | #define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */ |
60 | #define AR5K_EEPROM_VERSION_4_3 0x4003 | 44 | #define AR5K_EEPROM_VERSION_4_3 0x4003 /* power calibration changes */ |
61 | #define AR5K_EEPROM_VERSION_4_4 0x4004 | 45 | #define AR5K_EEPROM_VERSION_4_4 0x4004 |
62 | #define AR5K_EEPROM_VERSION_4_5 0x4005 | 46 | #define AR5K_EEPROM_VERSION_4_5 0x4005 |
63 | #define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */ | 47 | #define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */ |
64 | #define AR5K_EEPROM_VERSION_4_7 0x4007 | 48 | #define AR5K_EEPROM_VERSION_4_7 0x3007 /* 4007 ? */ |
49 | #define AR5K_EEPROM_VERSION_4_9 0x4009 /* EAR futureproofing */ | ||
50 | #define AR5K_EEPROM_VERSION_5_0 0x5000 /* Has 2413 PDADC calibration etc */ | ||
51 | #define AR5K_EEPROM_VERSION_5_1 0x5001 /* Has capability values */ | ||
52 | #define AR5K_EEPROM_VERSION_5_3 0x5003 /* Has spur mitigation tables */ | ||
65 | 53 | ||
66 | #define AR5K_EEPROM_MODE_11A 0 | 54 | #define AR5K_EEPROM_MODE_11A 0 |
67 | #define AR5K_EEPROM_MODE_11B 1 | 55 | #define AR5K_EEPROM_MODE_11B 1 |
@@ -74,8 +62,8 @@ | |||
74 | #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ | 62 | #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ |
75 | #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ | 63 | #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ |
76 | #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) | 64 | #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) |
77 | #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */ | ||
78 | #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ | 65 | #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ |
66 | #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ | ||
79 | 67 | ||
80 | #define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c | 68 | #define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c |
81 | #define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2 | 69 | #define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2 |
@@ -87,27 +75,95 @@ | |||
87 | (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0) | 75 | (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0) |
88 | 76 | ||
89 | #define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3) | 77 | #define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3) |
90 | #define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff)) | 78 | #define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((s8)(((_v) >> 8) & 0xff)) |
91 | #define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff)) | 79 | #define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((s8)((_v) & 0xff)) |
80 | |||
81 | /* Misc values available since EEPROM 4.0 */ | ||
82 | #define AR5K_EEPROM_MISC0 AR5K_EEPROM_INFO(4) | ||
83 | #define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff) | ||
84 | #define AR5K_EEPROM_HDR_XR2_DIS(_v) (((_v) >> 12) & 0x1) | ||
85 | #define AR5K_EEPROM_HDR_XR5_DIS(_v) (((_v) >> 13) & 0x1) | ||
86 | #define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3) | ||
87 | |||
88 | #define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) | ||
89 | #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) | ||
90 | #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) | ||
91 | #define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) | ||
92 | |||
93 | #define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) | ||
94 | #define AR5K_EEPROM_EEP_FILE_VERSION(_v) (((_v) >> 8) & 0xff) | ||
95 | #define AR5K_EEPROM_EAR_FILE_VERSION(_v) ((_v) & 0xff) | ||
96 | |||
97 | #define AR5K_EEPROM_MISC3 AR5K_EEPROM_INFO(7) | ||
98 | #define AR5K_EEPROM_ART_BUILD_NUM(_v) (((_v) >> 10) & 0x3f) | ||
99 | #define AR5K_EEPROM_EAR_FILE_ID(_v) ((_v) & 0xff) | ||
100 | |||
101 | #define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) | ||
102 | #define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) | ||
103 | #define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) | ||
104 | #define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) | ||
105 | |||
106 | #define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) | ||
107 | #define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) | ||
108 | #define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) | ||
109 | #define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) | ||
110 | #define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) | ||
111 | #define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) | ||
112 | #define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) | ||
113 | #define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) | ||
114 | |||
115 | #define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) | ||
116 | #define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x8) | ||
117 | #define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x8) | ||
118 | #define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) | ||
119 | #define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) | ||
120 | #define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) | ||
121 | #define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 9) & 0x1) | ||
122 | #define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 10) & 0x1) | ||
92 | 123 | ||
93 | /* calibration settings */ | 124 | /* calibration settings */ |
94 | #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) | 125 | #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) |
95 | #define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2) | 126 | #define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2) |
96 | #define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d) | 127 | #define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d) |
97 | #define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */ | 128 | #define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */ |
129 | #define AR5K_EEPROM_GROUPS_START(_v) AR5K_EEPROM_OFF(_v, 0x0100, 0x0150) /* Start of Groups */ | ||
130 | #define AR5K_EEPROM_GROUP1_OFFSET 0x0 | ||
131 | #define AR5K_EEPROM_GROUP2_OFFSET 0x5 | ||
132 | #define AR5K_EEPROM_GROUP3_OFFSET 0x37 | ||
133 | #define AR5K_EEPROM_GROUP4_OFFSET 0x46 | ||
134 | #define AR5K_EEPROM_GROUP5_OFFSET 0x55 | ||
135 | #define AR5K_EEPROM_GROUP6_OFFSET 0x65 | ||
136 | #define AR5K_EEPROM_GROUP7_OFFSET 0x69 | ||
137 | #define AR5K_EEPROM_GROUP8_OFFSET 0x6f | ||
138 | |||
139 | #define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ | ||
140 | AR5K_EEPROM_GROUP5_OFFSET, 0x0000) | ||
141 | #define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ | ||
142 | AR5K_EEPROM_GROUP6_OFFSET, 0x0010) | ||
143 | #define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ | ||
144 | AR5K_EEPROM_GROUP7_OFFSET, 0x0014) | ||
98 | 145 | ||
99 | /* [3.1 - 3.3] */ | 146 | /* [3.1 - 3.3] */ |
100 | #define AR5K_EEPROM_OBDB0_2GHZ 0x00ec | 147 | #define AR5K_EEPROM_OBDB0_2GHZ 0x00ec |
101 | #define AR5K_EEPROM_OBDB1_2GHZ 0x00ed | 148 | #define AR5K_EEPROM_OBDB1_2GHZ 0x00ed |
102 | 149 | ||
103 | /* Misc values available since EEPROM 4.0 */ | 150 | #define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */ |
104 | #define AR5K_EEPROM_MISC0 0x00c4 | 151 | #define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */ |
105 | #define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff) | 152 | #define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */ |
106 | #define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3) | 153 | #define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */ |
107 | #define AR5K_EEPROM_MISC1 0x00c5 | 154 | #define AR5K_EEPROM_PROTECT_WR_32_63 0x0008 |
108 | #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) | 155 | #define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */ |
109 | #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) | 156 | #define AR5K_EEPROM_PROTECT_WR_64_127 0x0020 |
110 | 157 | #define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */ | |
158 | #define AR5K_EEPROM_PROTECT_WR_128_191 0x0080 | ||
159 | #define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */ | ||
160 | #define AR5K_EEPROM_PROTECT_WR_192_207 0x0200 | ||
161 | #define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */ | ||
162 | #define AR5K_EEPROM_PROTECT_WR_208_223 0x0800 | ||
163 | #define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */ | ||
164 | #define AR5K_EEPROM_PROTECT_WR_224_239 0x2000 | ||
165 | #define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */ | ||
166 | #define AR5K_EEPROM_PROTECT_WR_240_255 0x8000 | ||
111 | 167 | ||
112 | /* Some EEPROM defines */ | 168 | /* Some EEPROM defines */ |
113 | #define AR5K_EEPROM_EEP_SCALE 100 | 169 | #define AR5K_EEPROM_EEP_SCALE 100 |
@@ -115,8 +171,11 @@ | |||
115 | #define AR5K_EEPROM_N_MODES 3 | 171 | #define AR5K_EEPROM_N_MODES 3 |
116 | #define AR5K_EEPROM_N_5GHZ_CHAN 10 | 172 | #define AR5K_EEPROM_N_5GHZ_CHAN 10 |
117 | #define AR5K_EEPROM_N_2GHZ_CHAN 3 | 173 | #define AR5K_EEPROM_N_2GHZ_CHAN 3 |
174 | #define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 | ||
118 | #define AR5K_EEPROM_MAX_CHAN 10 | 175 | #define AR5K_EEPROM_MAX_CHAN 10 |
176 | #define AR5K_EEPROM_N_PWR_POINTS_5111 11 | ||
119 | #define AR5K_EEPROM_N_PCDAC 11 | 177 | #define AR5K_EEPROM_N_PCDAC 11 |
178 | #define AR5K_EEPROM_N_PHASE_CAL 5 | ||
120 | #define AR5K_EEPROM_N_TEST_FREQ 8 | 179 | #define AR5K_EEPROM_N_TEST_FREQ 8 |
121 | #define AR5K_EEPROM_N_EDGES 8 | 180 | #define AR5K_EEPROM_N_EDGES 8 |
122 | #define AR5K_EEPROM_N_INTERCEPTS 11 | 181 | #define AR5K_EEPROM_N_INTERCEPTS 11 |
@@ -136,6 +195,8 @@ | |||
136 | #define AR5K_EEPROM_N_XPD_PER_CHANNEL 4 | 195 | #define AR5K_EEPROM_N_XPD_PER_CHANNEL 4 |
137 | #define AR5K_EEPROM_N_XPD0_POINTS 4 | 196 | #define AR5K_EEPROM_N_XPD0_POINTS 4 |
138 | #define AR5K_EEPROM_N_XPD3_POINTS 3 | 197 | #define AR5K_EEPROM_N_XPD3_POINTS 3 |
198 | #define AR5K_EEPROM_N_PD_GAINS 4 | ||
199 | #define AR5K_EEPROM_N_PD_POINTS 5 | ||
139 | #define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35 | 200 | #define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35 |
140 | #define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55 | 201 | #define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55 |
141 | #define AR5K_EEPROM_POWER_M 0x3f | 202 | #define AR5K_EEPROM_POWER_M 0x3f |
@@ -158,8 +219,99 @@ | |||
158 | #define AR5K_EEPROM_READ_HDR(_o, _v) \ | 219 | #define AR5K_EEPROM_READ_HDR(_o, _v) \ |
159 | AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \ | 220 | AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \ |
160 | 221 | ||
161 | /* Struct to hold EEPROM calibration data */ | 222 | enum ath5k_ant_setting { |
223 | AR5K_ANT_VARIABLE = 0, /* variable by programming */ | ||
224 | AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */ | ||
225 | AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */ | ||
226 | AR5K_ANT_MAX = 3, | ||
227 | }; | ||
228 | |||
229 | enum ath5k_ctl_mode { | ||
230 | AR5K_CTL_11A = 0, | ||
231 | AR5K_CTL_11B = 1, | ||
232 | AR5K_CTL_11G = 2, | ||
233 | AR5K_CTL_TURBO = 3, | ||
234 | AR5K_CTL_108G = 4, | ||
235 | AR5K_CTL_2GHT20 = 5, | ||
236 | AR5K_CTL_5GHT20 = 6, | ||
237 | AR5K_CTL_2GHT40 = 7, | ||
238 | AR5K_CTL_5GHT40 = 8, | ||
239 | AR5K_CTL_MODE_M = 15, | ||
240 | }; | ||
241 | |||
242 | /* Per channel calibration data, used for power table setup */ | ||
243 | struct ath5k_chan_pcal_info_rf5111 { | ||
244 | /* Power levels in half dbm units | ||
245 | * for one power curve. */ | ||
246 | u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111]; | ||
247 | /* PCDAC table steps | ||
248 | * for the above values */ | ||
249 | u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111]; | ||
250 | /* Starting PCDAC step */ | ||
251 | u8 pcdac_min; | ||
252 | /* Final PCDAC step */ | ||
253 | u8 pcdac_max; | ||
254 | }; | ||
255 | |||
256 | struct ath5k_chan_pcal_info_rf5112 { | ||
257 | /* Power levels in quarter dBm units | ||
258 | * for lower (0) and higher (3) | ||
259 | * level curves */ | ||
260 | s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS]; | ||
261 | s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS]; | ||
262 | /* PCDAC table steps | ||
263 | * for the above values */ | ||
264 | u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS]; | ||
265 | u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS]; | ||
266 | }; | ||
267 | |||
268 | struct ath5k_chan_pcal_info_rf2413 { | ||
269 | /* Starting pwr/pddac values */ | ||
270 | s8 pwr_i[AR5K_EEPROM_N_PD_GAINS]; | ||
271 | u8 pddac_i[AR5K_EEPROM_N_PD_GAINS]; | ||
272 | /* (pwr,pddac) points */ | ||
273 | s8 pwr[AR5K_EEPROM_N_PD_GAINS] | ||
274 | [AR5K_EEPROM_N_PD_POINTS]; | ||
275 | u8 pddac[AR5K_EEPROM_N_PD_GAINS] | ||
276 | [AR5K_EEPROM_N_PD_POINTS]; | ||
277 | }; | ||
278 | |||
279 | struct ath5k_chan_pcal_info { | ||
280 | /* Frequency */ | ||
281 | u16 freq; | ||
282 | /* Max available power */ | ||
283 | s8 max_pwr; | ||
284 | union { | ||
285 | struct ath5k_chan_pcal_info_rf5111 rf5111_info; | ||
286 | struct ath5k_chan_pcal_info_rf5112 rf5112_info; | ||
287 | struct ath5k_chan_pcal_info_rf2413 rf2413_info; | ||
288 | }; | ||
289 | }; | ||
290 | |||
291 | /* Per rate calibration data for each mode, used for power table setup */ | ||
292 | struct ath5k_rate_pcal_info { | ||
293 | u16 freq; /* Frequency */ | ||
294 | /* Power level for 6-24Mbit/s rates */ | ||
295 | u16 target_power_6to24; | ||
296 | /* Power level for 36Mbit rate */ | ||
297 | u16 target_power_36; | ||
298 | /* Power level for 48Mbit rate */ | ||
299 | u16 target_power_48; | ||
300 | /* Power level for 54Mbit rate */ | ||
301 | u16 target_power_54; | ||
302 | }; | ||
303 | |||
304 | /* Power edges for conformance test limits */ | ||
305 | struct ath5k_edge_power { | ||
306 | u16 freq; | ||
307 | u16 edge; /* in half dBm */ | ||
308 | bool flag; | ||
309 | }; | ||
310 | |||
311 | /* EEPROM calibration data */ | ||
162 | struct ath5k_eeprom_info { | 312 | struct ath5k_eeprom_info { |
313 | |||
314 | /* Header information */ | ||
163 | u16 ee_magic; | 315 | u16 ee_magic; |
164 | u16 ee_protect; | 316 | u16 ee_protect; |
165 | u16 ee_regdomain; | 317 | u16 ee_regdomain; |
@@ -168,6 +320,11 @@ struct ath5k_eeprom_info { | |||
168 | u16 ee_ant_gain; | 320 | u16 ee_ant_gain; |
169 | u16 ee_misc0; | 321 | u16 ee_misc0; |
170 | u16 ee_misc1; | 322 | u16 ee_misc1; |
323 | u16 ee_misc2; | ||
324 | u16 ee_misc3; | ||
325 | u16 ee_misc4; | ||
326 | u16 ee_misc5; | ||
327 | u16 ee_misc6; | ||
171 | u16 ee_cck_ofdm_gain_delta; | 328 | u16 ee_cck_ofdm_gain_delta; |
172 | u16 ee_cck_ofdm_power_delta; | 329 | u16 ee_cck_ofdm_power_delta; |
173 | u16 ee_scaled_cck_delta; | 330 | u16 ee_scaled_cck_delta; |
@@ -185,7 +342,7 @@ struct ath5k_eeprom_info { | |||
185 | u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES]; | 342 | u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES]; |
186 | u16 ee_xr_power[AR5K_EEPROM_N_MODES]; | 343 | u16 ee_xr_power[AR5K_EEPROM_N_MODES]; |
187 | u16 ee_switch_settling[AR5K_EEPROM_N_MODES]; | 344 | u16 ee_switch_settling[AR5K_EEPROM_N_MODES]; |
188 | u16 ee_ant_tx_rx[AR5K_EEPROM_N_MODES]; | 345 | u16 ee_atn_tx_rx[AR5K_EEPROM_N_MODES]; |
189 | u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC]; | 346 | u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC]; |
190 | u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; | 347 | u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; |
191 | u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; | 348 | u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; |
@@ -198,18 +355,40 @@ struct ath5k_eeprom_info { | |||
198 | u16 ee_x_gain[AR5K_EEPROM_N_MODES]; | 355 | u16 ee_x_gain[AR5K_EEPROM_N_MODES]; |
199 | u16 ee_i_gain[AR5K_EEPROM_N_MODES]; | 356 | u16 ee_i_gain[AR5K_EEPROM_N_MODES]; |
200 | u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES]; | 357 | u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES]; |
358 | u16 ee_switch_settling_turbo[AR5K_EEPROM_N_MODES]; | ||
359 | u16 ee_margin_tx_rx_turbo[AR5K_EEPROM_N_MODES]; | ||
360 | u16 ee_atn_tx_rx_turbo[AR5K_EEPROM_N_MODES]; | ||
201 | 361 | ||
202 | /* Unused */ | 362 | /* Power calibration data */ |
203 | u16 ee_false_detect[AR5K_EEPROM_N_MODES]; | 363 | u16 ee_false_detect[AR5K_EEPROM_N_MODES]; |
204 | u16 ee_cal_pier[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_2GHZ_CHAN]; | 364 | |
205 | u16 ee_channel[AR5K_EEPROM_N_MODES][AR5K_EEPROM_MAX_CHAN]; /*empty*/ | 365 | /* Number of pd gain curves per mode (RF2413) */ |
366 | u8 ee_pd_gains[AR5K_EEPROM_N_MODES]; | ||
367 | |||
368 | u8 ee_n_piers[AR5K_EEPROM_N_MODES]; | ||
369 | struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN]; | ||
370 | struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN]; | ||
371 | struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN]; | ||
372 | |||
373 | /* Per rate target power levels */ | ||
374 | u16 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES]; | ||
375 | struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN]; | ||
376 | struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN]; | ||
377 | struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN]; | ||
206 | 378 | ||
207 | /* Conformance test limits (Unused) */ | 379 | /* Conformance test limits (Unused) */ |
208 | u16 ee_ctls; | 380 | u16 ee_ctls; |
209 | u16 ee_ctl[AR5K_EEPROM_MAX_CTLS]; | 381 | u16 ee_ctl[AR5K_EEPROM_MAX_CTLS]; |
382 | struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS]; | ||
210 | 383 | ||
211 | /* Noise Floor Calibration settings */ | 384 | /* Noise Floor Calibration settings */ |
212 | s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES]; | 385 | s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES]; |
213 | s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES]; | 386 | s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES]; |
214 | s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES]; | 387 | s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES]; |
388 | s8 ee_adc_desired_size_turbo[AR5K_EEPROM_N_MODES]; | ||
389 | s8 ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES]; | ||
390 | s8 ee_pd_gain_overlap; | ||
391 | |||
392 | u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; | ||
215 | }; | 393 | }; |
394 | |||
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c index 5003263c9ea4..dc2d7d8bdb7a 100644 --- a/drivers/net/wireless/ath5k/reset.c +++ b/drivers/net/wireless/ath5k/reset.c | |||
@@ -674,7 +674,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
674 | (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, | 674 | (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, |
675 | 0xffffc07f); | 675 | 0xffffc07f); |
676 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN, | 676 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN, |
677 | (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, | 677 | (ee->ee_atn_tx_rx[ee_mode] << 12) & 0x3f000, |
678 | 0xfffc0fff); | 678 | 0xfffc0fff); |
679 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE, | 679 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE, |
680 | (ee->ee_adc_desired_size[ee_mode] & 0x00ff) | | 680 | (ee->ee_adc_desired_size[ee_mode] & 0x00ff) | |