|
@@ -0,0 +1,59 @@
|
|
|
+From b3797d1a92afe97c173b00fdb7824cedba24eef0 Mon Sep 17 00:00:00 2001
|
|
|
+From: Chuanhong Guo <gch981213@gmail.com>
|
|
|
+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);
|
|
|
+ }
|
|
|
+
|