diff options
Diffstat (limited to 'target/linux/ath79/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch')
-rw-r--r-- | target/linux/ath79/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/target/linux/ath79/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch b/target/linux/ath79/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch new file mode 100644 index 0000000..6151cc2 --- /dev/null +++ b/target/linux/ath79/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch @@ -0,0 +1,63 @@ +From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jogo@openwrt.org> +Date: Tue, 16 Jun 2015 13:15:08 +0200 +Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command + +It seems some phys have some maximum timings for accessing the MDIO line, +resulting in bit errors under cpu stress. Prevent this from happening by +disabling interrupts when sending commands. + +Signed-off-by: Jonas Gorski <jogo@openwrt.org> +--- + drivers/net/phy/mdio-bitbang.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: linux-4.14.18/drivers/net/phy/mdio-bitbang.c +=================================================================== +--- linux-4.14.18.orig/drivers/net/phy/mdio-bitbang.c ++++ linux-4.14.18/drivers/net/phy/mdio-bitbang.c +@@ -17,6 +17,7 @@ + * kind, whether express or implied. + */ + ++#include <linux/irqflags.h> + #include <linux/module.h> + #include <linux/mdio-bitbang.h> + #include <linux/types.h> +@@ -156,7 +157,9 @@ static int mdiobb_read(struct mii_bus *b + { + struct mdiobb_ctrl *ctrl = bus->priv; + int ret; ++ unsigned long flags; + ++ local_irq_save(flags); + if (reg & MII_ADDR_C45) { + reg = mdiobb_cmd_addr(ctrl, phy, reg); + mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg); +@@ -169,13 +172,17 @@ static int mdiobb_read(struct mii_bus *b + + ret = mdiobb_get_num(ctrl, 16); + mdiobb_get_bit(ctrl); ++ local_irq_restore(flags); ++ + return ret; + } + + static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) + { + struct mdiobb_ctrl *ctrl = bus->priv; ++ unsigned long flags; + ++ local_irq_save(flags); + if (reg & MII_ADDR_C45) { + reg = mdiobb_cmd_addr(ctrl, phy, reg); + mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg); +@@ -190,6 +197,8 @@ static int mdiobb_write(struct mii_bus * + + ctrl->ops->set_mdio_dir(ctrl, 0); + mdiobb_get_bit(ctrl); ++ local_irq_restore(flags); ++ + return 0; + } + |