From patchwork Wed Sep 30 11:20:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: build_patches: backport fix for WAN disconnect on ath79 From: Adrian Schmutzler X-Patchwork-Id: 1435 Message-Id: <20200930112026.65126-1-freifunk@adrianschmutzler.de> To: franken-dev@freifunk.net Date: Wed, 30 Sep 2020 13:20:26 +0200 The switch driver on ath79 leads to occasional (sometimes even frequent) dis- and reconnects of the WAN port. This has finally been resolved by a workaround applied to OpenWrt master now. The problem also existed with ar71xx, but was fixed a long time ago already. This cherry-picks the relevant patch to 19.07 and adds it to our firmware (it will probably be included in 19.07.5). The problem as well as the resolution by the patch has been reproduced on device (with my FFF firmware and with 19.07.4 OpenWrt). Signed-off-by: Adrian Schmutzler --- ...6-make-switch-register-access-atomic.patch | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 build_patches/openwrt/0081-ath79-ar8216-make-switch-register-access-atomic.patch diff --git a/build_patches/openwrt/0081-ath79-ar8216-make-switch-register-access-atomic.patch b/build_patches/openwrt/0081-ath79-ar8216-make-switch-register-access-atomic.patch new file mode 100644 index 00000000..0cf7dc44 --- /dev/null +++ b/build_patches/openwrt/0081-ath79-ar8216-make-switch-register-access-atomic.patch @@ -0,0 +1,87 @@ +From: Chuanhong Guo +Date: Mon, 21 Sep 2020 14:57:44 +0800 +Subject: ath79: ar8216: make switch register access atomic + +reg accesses on integrated ar8229 sometimes fails. As a result, phy read +got incorrect port status and wan link goes down and up mysteriously. +After comparing ar8216 with the old driver, these local_irq_save/restore +calls are the only meaningful differences I could find and it does fix +the issue. +The same changes were added in svn r26856 by Gabor Juhos: +ar71xx: ag71xx: make switch register access atomic + +As I can't find the underlying problem either, this hack is broght +back to fix the unstable link issue. +This hack is only suitable for ath79 mdio and may easily break the +driver on other platform. Limit it to ath79-only as a target patch. + +Fixes: FS#2216 +Fixes: FS#3226 +Signed-off-by: Chuanhong Guo +(cherry picked from commit 86fdc8abed5992a74078b000b5ff9da723b6f46b) + +diff --git a/target/linux/ath79/patches-4.14/930-ar8216-make-reg-access-atomic.patch b/target/linux/ath79/patches-4.14/930-ar8216-make-reg-access-atomic.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..02f763534e43ab2e40e337afe66dd8d10cf1070a +--- /dev/null ++++ b/target/linux/ath79/patches-4.14/930-ar8216-make-reg-access-atomic.patch +@@ -0,0 +1,59 @@ ++From b3797d1a92afe97c173b00fdb7824cedba24eef0 Mon Sep 17 00:00:00 2001 ++From: Chuanhong Guo ++Date: Sun, 20 Sep 2020 01:00:45 +0800 ++Subject: [PATCH] ath79: ar8216: make switch register access atomic ++ ++due to some unknown reason these register accesses sometimes fail ++on the integrated switch without this patch. ++ ++THIS ONLY WORKS ON ATH79 AND MAY BREAK THE DRIVER ON OTHER PLATFORMS! ++The mdio bus on ath79 works in polling mode and doesn't rely on ++any interrupt. This patch breaks the driver on any mdio master ++with interrupts used. ++ ++--- ++--- a/drivers/net/phy/ar8216.c +++++ b/drivers/net/phy/ar8216.c ++@@ -252,6 +252,7 @@ ar8xxx_mii_write32(struct ar8xxx_priv *p ++ u32 ++ ar8xxx_read(struct ar8xxx_priv *priv, int reg) ++ { +++ unsigned long flags; ++ struct mii_bus *bus = priv->mii_bus; ++ u16 r1, r2, page; ++ u32 val; ++@@ -259,11 +260,13 @@ ar8xxx_read(struct ar8xxx_priv *priv, in ++ split_addr((u32) reg, &r1, &r2, &page); ++ ++ mutex_lock(&bus->mdio_lock); +++ local_irq_save(flags); ++ ++ bus->write(bus, 0x18, 0, page); ++ wait_for_page_switch(); ++ val = ar8xxx_mii_read32(priv, 0x10 | r2, r1); ++ +++ local_irq_restore(flags); ++ mutex_unlock(&bus->mdio_lock); ++ ++ return val; ++@@ -272,17 +275,20 @@ ar8xxx_read(struct ar8xxx_priv *priv, in ++ void ++ ar8xxx_write(struct ar8xxx_priv *priv, int reg, u32 val) ++ { +++ unsigned long flags; ++ struct mii_bus *bus = priv->mii_bus; ++ u16 r1, r2, page; ++ ++ split_addr((u32) reg, &r1, &r2, &page); ++ ++ mutex_lock(&bus->mdio_lock); +++ local_irq_save(flags); ++ ++ bus->write(bus, 0x18, 0, page); ++ wait_for_page_switch(); ++ ar8xxx_mii_write32(priv, 0x10 | r2, r1, val); ++ +++ local_irq_restore(flags); ++ mutex_unlock(&bus->mdio_lock); ++ } ++