diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/eeprom.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/eeprom.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 644962adda97..67665cdc7afe 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * EEPROM access functions and helpers * | 21 | * EEPROM access functions and helpers * |
22 | \*************************************/ | 22 | \*************************************/ |
23 | 23 | ||
24 | #include <linux/slab.h> | ||
25 | |||
24 | #include "ath5k.h" | 26 | #include "ath5k.h" |
25 | #include "reg.h" | 27 | #include "reg.h" |
26 | #include "debug.h" | 28 | #include "debug.h" |
@@ -97,6 +99,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | |||
97 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 99 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
98 | int ret; | 100 | int ret; |
99 | u16 val; | 101 | u16 val; |
102 | u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; | ||
100 | 103 | ||
101 | /* | 104 | /* |
102 | * Read values from EEPROM and store them in the capability structure | 105 | * Read values from EEPROM and store them in the capability structure |
@@ -111,20 +114,44 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | |||
111 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) | 114 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) |
112 | return 0; | 115 | return 0; |
113 | 116 | ||
114 | #ifdef notyet | ||
115 | /* | 117 | /* |
116 | * Validate the checksum of the EEPROM date. There are some | 118 | * Validate the checksum of the EEPROM date. There are some |
117 | * devices with invalid EEPROMs. | 119 | * devices with invalid EEPROMs. |
118 | */ | 120 | */ |
119 | for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { | 121 | AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val); |
122 | if (val) { | ||
123 | eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) << | ||
124 | AR5K_EEPROM_SIZE_ENDLOC_SHIFT; | ||
125 | AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val); | ||
126 | eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE; | ||
127 | |||
128 | /* | ||
129 | * Fail safe check to prevent stupid loops due | ||
130 | * to busted EEPROMs. XXX: This value is likely too | ||
131 | * big still, waiting on a better value. | ||
132 | */ | ||
133 | if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) { | ||
134 | ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: " | ||
135 | "%d (0x%04x) max expected: %d (0x%04x)\n", | ||
136 | eep_max, eep_max, | ||
137 | 3 * AR5K_EEPROM_INFO_MAX, | ||
138 | 3 * AR5K_EEPROM_INFO_MAX); | ||
139 | return -EIO; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | for (cksum = 0, offset = 0; offset < eep_max; offset++) { | ||
120 | AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); | 144 | AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); |
121 | cksum ^= val; | 145 | cksum ^= val; |
122 | } | 146 | } |
123 | if (cksum != AR5K_EEPROM_INFO_CKSUM) { | 147 | if (cksum != AR5K_EEPROM_INFO_CKSUM) { |
124 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); | 148 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM " |
149 | "checksum: 0x%04x eep_max: 0x%04x (%s)\n", | ||
150 | cksum, eep_max, | ||
151 | eep_max == AR5K_EEPROM_INFO_MAX ? | ||
152 | "default size" : "custom size"); | ||
125 | return -EIO; | 153 | return -EIO; |
126 | } | 154 | } |
127 | #endif | ||
128 | 155 | ||
129 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), | 156 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), |
130 | ee_ant_gain); | 157 | ee_ant_gain); |
@@ -404,8 +431,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
404 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | 431 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; |
405 | 432 | ||
406 | AR5K_EEPROM_READ(o++, val); | 433 | AR5K_EEPROM_READ(o++, val); |
407 | ee->ee_i_cal[mode] = (val >> 8) & 0x3f; | 434 | ee->ee_i_cal[mode] = (val >> 5) & 0x3f; |
408 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | 435 | ee->ee_q_cal[mode] = val & 0x1f; |
409 | 436 | ||
410 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { | 437 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { |
411 | AR5K_EEPROM_READ(o++, val); | 438 | AR5K_EEPROM_READ(o++, val); |
@@ -1492,7 +1519,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) | |||
1492 | * This info is used to calibrate the baseband power table. Imagine | 1519 | * This info is used to calibrate the baseband power table. Imagine |
1493 | * that for each channel there is a power curve that's hw specific | 1520 | * that for each channel there is a power curve that's hw specific |
1494 | * (depends on amplifier etc) and we try to "correct" this curve using | 1521 | * (depends on amplifier etc) and we try to "correct" this curve using |
1495 | * offests we pass on to phy chip (baseband -> before amplifier) so that | 1522 | * offsets we pass on to phy chip (baseband -> before amplifier) so that |
1496 | * it can use accurate power values when setting tx power (takes amplifier's | 1523 | * it can use accurate power values when setting tx power (takes amplifier's |
1497 | * performance on each channel into account). | 1524 | * performance on each channel into account). |
1498 | * | 1525 | * |