diff --git a/debian/changelog b/debian/changelog index 16585d769..3cd08676a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,8 @@ linux-2.6 (2.6.32-5) UNRELEASED; urgency=low [ Ben Hutchings ] * sfc: Apply fixes from 2.6.33-rc3 + * ath5k: Fix eeprom checksum check for custom sized eeproms + (Closes: #563136) -- Ben Hutchings Thu, 07 Jan 2010 19:19:32 +0000 diff --git a/debian/patches/bugfix/all/ath5k-Fix-eeprom-checksum-check-for-custom-sized-eeproms.patch b/debian/patches/bugfix/all/ath5k-Fix-eeprom-checksum-check-for-custom-sized-eeproms.patch new file mode 100644 index 000000000..7965f096f --- /dev/null +++ b/debian/patches/bugfix/all/ath5k-Fix-eeprom-checksum-check-for-custom-sized-eeproms.patch @@ -0,0 +1,104 @@ +From 608ad4393323f00eab79828bdfda3ff1d520532e Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Mon, 28 Dec 2009 15:40:42 -0800 +Subject: [PATCH] ath5k: Fix eeprom checksum check for custom sized eeproms + +Commit 8bf3d79bc401ca417ccf9fc076d3295d1a71dbf5 enabled EEPROM +checksum checks to avoid bogus bug reports but failed to address +updating the code to consider devices with custom EEPROM sizes. +Devices with custom sized EEPROMs have the upper limit size stuffed +in the EEPROM. Use this as the upper limit instead of the static +default size. In case of a checksum error also provide back the +max size and whether or not this was the default size or a custom +one. If the EEPROM is busted we add a failsafe check to ensure +we don't loop forever or try to read bogus areas of hardware. + +For details refer to the bugzilla entry: + +http://bugzilla.kernel.org/show_bug.cgi?id=14874 + +Cc: stable@kernel.org +Cc: David Quan +Reported-by: Joshua Covington +Signed-off-by: Luis R. Rodriguez +--- + drivers/net/wireless/ath/ath5k/eeprom.c | 32 ++++++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath5k/eeprom.h | 8 +++++++ + 2 files changed, 37 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c +index 5d1c867..6a3f4da 100644 +--- a/drivers/net/wireless/ath/ath5k/eeprom.c ++++ b/drivers/net/wireless/ath/ath5k/eeprom.c +@@ -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; + } + +diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h +index 0123f35..473a483 100644 +--- a/drivers/net/wireless/ath/ath5k/eeprom.h ++++ b/drivers/net/wireless/ath/ath5k/eeprom.h +@@ -37,6 +37,14 @@ + #define AR5K_EEPROM_RFKILL_POLARITY_S 1 + + #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ ++ ++/* FLASH(EEPROM) Defines for AR531X chips */ ++#define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */ ++#define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */ ++#define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0 ++#define AR5K_EEPROM_SIZE_UPPER_SHIFT 4 ++#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12 ++ + #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ + #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ + #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) +-- +1.6.3.3 + diff --git a/debian/patches/series/5 b/debian/patches/series/5 index 068dbbb62..f3637f88d 100644 --- a/debian/patches/series/5 +++ b/debian/patches/series/5 @@ -6,3 +6,4 @@ + bugfix/all/sfc-QT2025C-Work-around-PHY-firmware-initialisation.patch + bugfix/all/sfc-QT2025C-Add-error-message-for-suspected-bad-SFP-cable.patch + bugfix/all/sfc-Disable-TX-descriptor-prefetch-watchdog.patch ++ bugfix/all/ath5k-Fix-eeprom-checksum-check-for-custom-sized-eeproms.patch