summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/eeprom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/eeprom.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c57
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;