blob: 8c71e5b5ca4fd2c42043504479103dbc825e8a4b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001
2From: Jonas Gorski <jogo@openwrt.org>
3Date: Tue, 16 Jun 2015 13:15:08 +0200
4Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command
5
6It seems some phys have some maximum timings for accessing the MDIO line,
7resulting in bit errors under cpu stress. Prevent this from happening by
8disabling interrupts when sending commands.
9
10Signed-off-by: Jonas Gorski <jogo@openwrt.org>
11---
12 drivers/net/phy/mdio-bitbang.c | 9 +++++++++
13 1 file changed, 9 insertions(+)
14
15--- a/drivers/net/phy/mdio-bitbang.c
16+++ b/drivers/net/phy/mdio-bitbang.c
17@@ -14,6 +14,7 @@
18 * Vitaly Bordug <vbordug@ru.mvista.com>
19 */
20
21+#include <linux/irqflags.h>
22 #include <linux/module.h>
23 #include <linux/mdio-bitbang.h>
24 #include <linux/types.h>
25@@ -153,7 +154,9 @@ static int mdiobb_read(struct mii_bus *b
26 {
27 struct mdiobb_ctrl *ctrl = bus->priv;
28 int ret;
29+ unsigned long flags;
30
31+ local_irq_save(flags);
32 if (reg & MII_ADDR_C45) {
33 reg = mdiobb_cmd_addr(ctrl, phy, reg);
34 mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
35@@ -166,13 +169,17 @@ static int mdiobb_read(struct mii_bus *b
36
37 ret = mdiobb_get_num(ctrl, 16);
38 mdiobb_get_bit(ctrl);
39+ local_irq_restore(flags);
40+
41 return ret;
42 }
43
44 static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
45 {
46 struct mdiobb_ctrl *ctrl = bus->priv;
47+ unsigned long flags;
48
49+ local_irq_save(flags);
50 if (reg & MII_ADDR_C45) {
51 reg = mdiobb_cmd_addr(ctrl, phy, reg);
52 mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
53@@ -187,6 +194,8 @@ static int mdiobb_write(struct mii_bus *
54
55 ctrl->ops->set_mdio_dir(ctrl, 0);
56 mdiobb_get_bit(ctrl);
57+ local_irq_restore(flags);
58+
59 return 0;
60 }
61