Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ath9k: add support for endian swap of eeprom from platform data

On some devices (especially little-endian ones), the flash EEPROM data
has a different endian, which needs to be detected.
Add a flag to the platform data to allow overriding that behavior

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Felix Fietkau and committed by
John W. Linville
a59dadbe 7b89fccf

+14 -21
+10 -21
drivers/net/wireless/ath/ath9k/eeprom_def.c
··· 262 262 { 263 263 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 264 264 struct ath_common *common = ath9k_hw_common(ah); 265 - u16 *eepdata, temp, magic, magic2; 265 + u16 *eepdata, temp, magic; 266 266 u32 sum = 0, el; 267 267 bool need_swap = false; 268 268 int i, addr, size; ··· 272 272 return false; 273 273 } 274 274 275 - if (!ath9k_hw_use_flash(ah)) { 276 - ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); 275 + if (swab16(magic) == AR5416_EEPROM_MAGIC && 276 + !(ah->ah_flags & AH_NO_EEP_SWAP)) { 277 + size = sizeof(struct ar5416_eeprom_def); 278 + need_swap = true; 279 + eepdata = (u16 *) (&ah->eeprom); 277 280 278 - if (magic != AR5416_EEPROM_MAGIC) { 279 - magic2 = swab16(magic); 280 - 281 - if (magic2 == AR5416_EEPROM_MAGIC) { 282 - size = sizeof(struct ar5416_eeprom_def); 283 - need_swap = true; 284 - eepdata = (u16 *) (&ah->eeprom); 285 - 286 - for (addr = 0; addr < size / sizeof(u16); addr++) { 287 - temp = swab16(*eepdata); 288 - *eepdata = temp; 289 - eepdata++; 290 - } 291 - } else { 292 - ath_err(common, 293 - "Invalid EEPROM Magic. Endianness mismatch.\n"); 294 - return -EINVAL; 295 - } 281 + for (addr = 0; addr < size / sizeof(u16); addr++) { 282 + temp = swab16(*eepdata); 283 + *eepdata = temp; 284 + eepdata++; 296 285 } 297 286 } 298 287
+1
drivers/net/wireless/ath/ath9k/hw.h
··· 731 731 #define AH_USE_EEPROM 0x1 732 732 #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ 733 733 #define AH_FASTCC 0x4 734 + #define AH_NO_EEP_SWAP 0x8 /* Do not swap EEPROM data */ 734 735 735 736 struct ath_hw { 736 737 struct ath_ops reg_ops;
+2
drivers/net/wireless/ath/ath9k/init.c
··· 531 531 ah->is_clk_25mhz = pdata->is_clk_25mhz; 532 532 ah->get_mac_revision = pdata->get_mac_revision; 533 533 ah->external_reset = pdata->external_reset; 534 + if (!pdata->endian_check) 535 + ah->ah_flags |= AH_NO_EEP_SWAP; 534 536 } 535 537 536 538 common->ops = &ah->reg_ops;
+1
include/linux/ath9k_platform.h
··· 31 31 u32 gpio_mask; 32 32 u32 gpio_val; 33 33 34 + bool endian_check; 34 35 bool is_clk_25mhz; 35 36 bool tx_gain_buffalo; 36 37