kernel: add missing config symbols for 4.9
[openwrt/staging/yousong.git] / package / kernel / mac80211 / patches / 555-ath9k-Make-the-EEPROM-swapping-check-use-the-eepmisc.patch
1 From 1f796f9265c10384a274ac330f671ef4ac6d56e5 Mon Sep 17 00:00:00 2001
2 From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
3 Date: Mon, 3 Oct 2016 00:29:12 +0200
4 Subject: [v2 PATCH 6/7] ath9k: Make the EEPROM swapping check use the eepmisc
5 register
6
7 There are two ways of swapping the EEPROM data in the ath9k driver:
8 1) swab16 based on the first two EEPROM "magic" bytes (same for all
9 EEPROM formats)
10 2) field and EEPROM format specific swab16/swab32 (different for
11 eeprom_def, eeprom_4k and eeprom_9287)
12
13 The result of the first check was used to also enable the second swap.
14 This behavior seems incorrect, since the data may only be byte-swapped
15 (afterwards the data could be in the correct endianness).
16 Thus we introduce a separate check based on the "eepmisc" register
17 (which is part of the EEPROM data). When bit 0 is set, then the EEPROM
18 format specific values are in "big endian". This is also done by the
19 FreeBSD kernel, see [0] for example.
20
21 This allows us to parse EEPROMs with the "correct" magic bytes but
22 swapped EEPROM format specific values. These EEPROMs (mostly found in
23 lantiq and broadcom based big endian MIPS based devices) only worked
24 due to platform specific "hacks" which swapped the EEPROM so the
25 magic was inverted, which also enabled the format specific swapping.
26 With this patch the old behavior is still supported, but neither
27 recommended nor needed anymore.
28
29 [0]
30 https://github.com/freebsd/freebsd/blob/50719b56d9ce8d7d4beb53b16e9edb2e9a4a7a18/sys/dev/ath/ath_hal/ah_eeprom_9287.c#L351
31
32 Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
33 ---
34 drivers/net/wireless/ath/ath9k/eeprom.c | 57 ++++++++++++++++++++++++---------
35 1 file changed, 41 insertions(+), 16 deletions(-)
36
37 --- a/drivers/net/wireless/ath/ath9k/eeprom.c
38 +++ b/drivers/net/wireless/ath/ath9k/eeprom.c
39 @@ -155,11 +155,19 @@ bool ath9k_hw_nvram_read(struct ath_hw *
40 return ret;
41 }
42
43 +#ifdef __BIG_ENDIAN
44 +#define EXPECTED_EEPMISC_ENDIAN AR5416_EEPMISC_BIG_ENDIAN
45 +#else
46 +#define EXPECTED_EEPMISC_ENDIAN 0
47 +#endif
48 +
49 int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size)
50 {
51 u16 magic;
52 u16 *eepdata;
53 + u8 eepmisc;
54 int i;
55 + bool needs_byteswap = false;
56 struct ath_common *common = ath9k_hw_common(ah);
57
58 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
59 @@ -167,36 +175,53 @@ int ath9k_hw_nvram_swap_data(struct ath_
60 return -EIO;
61 }
62
63 - *swap_needed = false;
64 if (swab16(magic) == AR5416_EEPROM_MAGIC) {
65 + needs_byteswap = true;
66 + ath_dbg(common, EEPROM,
67 + "EEPROM needs byte-swapping to correct endianness.\n");
68 + } else if (magic != AR5416_EEPROM_MAGIC) {
69 + if (ath9k_hw_use_flash(ah)) {
70 + ath_dbg(common, EEPROM,
71 + "Ignoring invalid EEPROM magic (0x%04x).\n",
72 + magic);
73 + } else {
74 + ath_err(common,
75 + "Invalid EEPROM magic (0x%04x).\n", magic);
76 + return -EINVAL;
77 + }
78 + }
79 +
80 + if (needs_byteswap) {
81 if (ah->ah_flags & AH_NO_EEP_SWAP) {
82 ath_info(common,
83 "Ignoring endianness difference in EEPROM magic bytes.\n");
84 } else {
85 - *swap_needed = true;
86 - }
87 - } else if (magic != AR5416_EEPROM_MAGIC) {
88 - if (ath9k_hw_use_flash(ah))
89 - return 0;
90 + eepdata = (u16 *)(&ah->eeprom);
91
92 - ath_err(common,
93 - "Invalid EEPROM Magic (0x%04x).\n", magic);
94 - return -EINVAL;
95 + for (i = 0; i < size; i++)
96 + eepdata[i] = swab16(eepdata[i]);
97 + }
98 }
99
100 - eepdata = (u16 *)(&ah->eeprom);
101 -
102 - if (*swap_needed) {
103 - ath_dbg(common, EEPROM,
104 - "EEPROM Endianness is not native.. Changing.\n");
105 + *swap_needed = false;
106
107 - for (i = 0; i < size; i++)
108 - eepdata[i] = swab16(eepdata[i]);
109 + eepmisc = ah->eep_ops->get_eepmisc(ah);
110 + if ((eepmisc & AR5416_EEPMISC_BIG_ENDIAN) != EXPECTED_EEPMISC_ENDIAN) {
111 + if (ah->ah_flags & AH_NO_EEP_SWAP) {
112 + ath_info(common,
113 + "Ignoring endianness difference in eepmisc register.\n");
114 + } else {
115 + *swap_needed = true;
116 + ath_dbg(common, EEPROM,
117 + "EEPROM needs swapping according to the eepmisc register.\n");
118 + }
119 }
120
121 return 0;
122 }
123
124 +#undef EXPECTED_EEPMISC_VAL
125 +
126 bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size)
127 {
128 u32 i, sum = 0;