|
@@ -97,7 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
|
|
|
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
|
|
|
int ret;
|
|
|
u16 val;
|
|
|
- u32 cksum, offset;
|
|
|
+ u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
|
|
|
|
|
|
/*
|
|
|
* Read values from EEPROM and store them in the capability structure
|
|
@@ -116,12 +116,38 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
|
|
|
* Validate the checksum of the EEPROM date. There are some
|
|
|
* devices with invalid EEPROMs.
|
|
|
*/
|
|
|
- for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
|
|
|
+ AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val);
|
|
|
+ if (val) {
|
|
|
+ eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
|
|
|
+ AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
|
|
|
+ AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val);
|
|
|
+ eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Fail safe check to prevent stupid loops due
|
|
|
+ * to busted EEPROMs. XXX: This value is likely too
|
|
|
+ * big still, waiting on a better value.
|
|
|
+ */
|
|
|
+ if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
|
|
|
+ ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: "
|
|
|
+ "%d (0x%04x) max expected: %d (0x%04x)\n",
|
|
|
+ eep_max, eep_max,
|
|
|
+ 3 * AR5K_EEPROM_INFO_MAX,
|
|
|
+ 3 * AR5K_EEPROM_INFO_MAX);
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (cksum = 0, offset = 0; offset < eep_max; offset++) {
|
|
|
AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
|
|
|
cksum ^= val;
|
|
|
}
|
|
|
if (cksum != AR5K_EEPROM_INFO_CKSUM) {
|
|
|
- ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
|
|
|
+ ATH5K_ERR(ah->ah_sc, "Invalid EEPROM "
|
|
|
+ "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
|
|
|
+ cksum, eep_max,
|
|
|
+ eep_max == AR5K_EEPROM_INFO_MAX ?
|
|
|
+ "default size" : "custom size");
|
|
|
return -EIO;
|
|
|
}
|
|
|
|