| 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); |
| } |
| |