ath9k: Avoid OF no-eeprom quirks when no qca,no-eeprom
authorDaniel F. Dickinson <cshored@thecshore.com>
Mon, 17 Dec 2018 05:18:30 +0000 (00:18 -0500)
committerChristian Lamparter <chunkeey@gmail.com>
Sat, 22 Dec 2018 14:08:24 +0000 (15:08 +0100)
Based on the process of discovery in
https://github.com/openwrt/openwrt/pull/1613, it has become clear
that (at least) the PowerCloud System CR5000 was unable to get
working 5GHz wireless (PCIe) because AH_USE_EEPROM was unconditionally
masked out, not only when qca,noeeprom was in the DTS.

This patch moves mask AH_USE_EEPROM into the if ... qca,noeeprom
OF test.

Thanks to Christian Lampartar (@chunkeey) for the heavy lifting and help.

Patch has been prepared for upstream and will be submitted after review
by @chunkeey and @xdarklight.

Signed-off-by: Daniel F. Dickinson <cshored@thecshore.com>
package/kernel/mac80211/patches/ath/558-ath9k-only-mask-use_eeprom-on-of-noeeprom.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/ath/558-ath9k-only-mask-use_eeprom-on-of-noeeprom.patch b/package/kernel/mac80211/patches/ath/558-ath9k-only-mask-use_eeprom-on-of-noeeprom.patch
new file mode 100644 (file)
index 0000000..f0656de
--- /dev/null
@@ -0,0 +1,73 @@
+ath9k: Avoid OF no-EEPROM quirks without qca,no-eeprom
+
+ath9k_of_init() function[0] was initially written on the assumption that
+if someone had an explicit ath9k OF node that "there must be something
+wrong, why would someone add an OF node if everything is fine"[1]
+(Quoting Martin Blumenstingl)
+
+"it turns out it's not that simple. with your requirements I'm now aware
+of two use-cases where the current code in ath9k_of_init() doesn't work
+without modifications"[1]
+
+The "your requirements" Martin speaks of is the result of the fact that I
+have a device (PowerCloud Systems CR5000) that uses the EEPROM for
+caldata and firmware but for which the MAC address is take from the MTD
+"art" partition[2], or more succinctly:
+
+"some cards come with a physical EEPROM chip so "qca,no-eeprom" should not
+be set (your use-case). in this case AH_USE_EEPROM should be set (which
+is the default when there is no OF node)"[1]
+
+The other use case is:
+
+the firmware on some PowerMac G5 seems to add a OF node for the ath9k
+card automatically. depending on the EEPROM on the card AH_NO_EEP_SWAP
+should be unset (which is the default when there is no OF node). see [3]
+
+After this patch to ath9k_of_init() the new behavior will be:
+
+    if there's no OF node then everything is the same as before
+    if there's an empty OF node then ath9k will use the hardware EEPROM
+      (before ath9k would fail to initialize because no EEPROM data was
+      provided by userspace)
+    if there's an OF node with only a MAC address then ath9k will use
+      the MAC address and the hardware EEPROM (see the case above)
+    with "qca,no-eeprom" EEPROM data from userspace will be requested.
+      the behavior here will not change
+[1]
+
+Martin provides additional background on EEPROM swapping[1] which I have
+included in the patch annotation but not the commit message.
+
+Thanks to Christian Lampartar <chunkeey@gmail.com> for all his help on
+troubleshooting this issue and the basis for this patch.
+
+Fixes: 138b41253d9c ("ath9k: parse the device configuration from an OF node")
+
+[0]https://elixir.bootlin.com/linux/v4.20-rc7/source/drivers/net/wireless/ath/ath9k/init.c#L615
+[1]https://github.com/openwrt/openwrt/pull/1645#issuecomment-448027058
+[2]https://github.com/openwrt/openwrt/pull/1613
+[3]https://patchwork.kernel.org/patch/10241731/
+
+Signed-off-by: Daniel F. Dickinson <cshored@thecshore.com>
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -642,15 +642,15 @@ static int ath9k_of_init(struct ath_soft
+               ret = ath9k_eeprom_request(sc, eeprom_name);
+               if (ret)
+                       return ret;
++
++              ah->ah_flags &= ~AH_USE_EEPROM;
++              ah->ah_flags |= AH_NO_EEP_SWAP;
+       }
+       mac = of_get_mac_address(np);
+       if (mac)
+               ether_addr_copy(common->macaddr, mac);
+-      ah->ah_flags &= ~AH_USE_EEPROM;
+-      ah->ah_flags |= AH_NO_EEP_SWAP;
+-
+       return 0;
+ }