diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/eeprom.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/eeprom.c | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index a449588a8009..0e46797601be 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -155,11 +155,19 @@ bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) return ret; } +#ifdef __BIG_ENDIAN +#define EXPECTED_EEPMISC_ENDIAN AR5416_EEPMISC_BIG_ENDIAN +#else +#define EXPECTED_EEPMISC_ENDIAN 0 +#endif + int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size) { u16 magic; u16 *eepdata; + u8 eepmisc; int i; + bool needs_byteswap = false; struct ath_common *common = ath9k_hw_common(ah); if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { @@ -167,36 +175,53 @@ int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size) return -EIO; } - *swap_needed = false; if (swab16(magic) == AR5416_EEPROM_MAGIC) { + needs_byteswap = true; + ath_dbg(common, EEPROM, + "EEPROM needs byte-swapping to correct endianness.\n"); + } else if (magic != AR5416_EEPROM_MAGIC) { + if (ath9k_hw_use_flash(ah)) { + ath_dbg(common, EEPROM, + "Ignoring invalid EEPROM magic (0x%04x).\n", + magic); + } else { + ath_err(common, + "Invalid EEPROM magic (0x%04x).\n", magic); + return -EINVAL; + } + } + + if (needs_byteswap) { if (ah->ah_flags & AH_NO_EEP_SWAP) { ath_info(common, "Ignoring endianness difference in EEPROM magic bytes.\n"); } else { - *swap_needed = true; - } - } else if (magic != AR5416_EEPROM_MAGIC) { - if (ath9k_hw_use_flash(ah)) - return 0; + eepdata = (u16 *)(&ah->eeprom); - ath_err(common, - "Invalid EEPROM Magic (0x%04x).\n", magic); - return -EINVAL; + for (i = 0; i < size; i++) + eepdata[i] = swab16(eepdata[i]); + } } - eepdata = (u16 *)(&ah->eeprom); - - if (*swap_needed) { - ath_dbg(common, EEPROM, - "EEPROM Endianness is not native.. Changing.\n"); + *swap_needed = false; - for (i = 0; i < size; i++) - eepdata[i] = swab16(eepdata[i]); + eepmisc = ah->eep_ops->get_eepmisc(ah); + if ((eepmisc & AR5416_EEPMISC_BIG_ENDIAN) != EXPECTED_EEPMISC_ENDIAN) { + if (ah->ah_flags & AH_NO_EEP_SWAP) { + ath_info(common, + "Ignoring endianness difference in eepmisc register.\n"); + } else { + *swap_needed = true; + ath_dbg(common, EEPROM, + "EEPROM needs swapping according to the eepmisc register.\n"); + } } return 0; } +#undef EXPECTED_EEPMISC_VAL + bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size) { u32 i, sum = 0; |