net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs [Linux 4.14.129]

net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs [Linux 4.14.129]

This Linux kernel change "net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs" is included in the Linux 4.14.129 release. This change is authored by Yoshihiro Shimoda <yoshihiro.shimoda.uh [at] renesas.com> on Tue May 28 13:10:46 2019 +0900. The commit for this change in Linux stable tree is da39ca3 (patch) which is from upstream commit 315ca92. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 315ca92.

net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs

[ Upstream commit 315ca92dd863fecbffc0bb52ae0ac11e0398726a ]

The sh_eth_close() resets the MAC and then calls phy_stop()
so that mdio read access result is incorrect without any error
according to kernel trace like below:

ifconfig-216   [003] .n..   109.133124: mdio_access: ee700000.ethernet-ffffffff read  phy:0x01 reg:0x00 val:0xffff

According to the hardware manual, the RMII mode should be set to 1
before operation the Ethernet MAC. However, the previous code was not
set to 1 after the driver issued the soft_reset in sh_eth_dev_exit()
so that the mdio read access result seemed incorrect. To fix the issue,
this patch adds a condition and set the RMII mode register in
sh_eth_dev_exit() for R-Car Gen2 and RZ/A1 SoCs.

Note that when I have tried to move the sh_eth_dev_exit() calling
after phy_stop() on sh_eth_close(), but it gets worse (kernel panic
happened and it seems that a register is accessed while the clock is
off).

Signed-off-by: Yoshihiro Shimoda <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>

There are 4 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/ethernet/renesas/sh_eth.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index abfb9fa..9b1906a 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1458,6 +1458,10 @@ static void sh_eth_dev_exit(struct net_device *ndev)
    sh_eth_get_stats(ndev);
    sh_eth_reset(ndev);

+   /* Set the RMII mode again if required */
+   if (mdp->cd->rmiimode)
+       sh_eth_write(ndev, 0x1, RMIIMODE);
+
    /* Set MAC address again */
    update_mac_address(ndev);
 }

Leave a Reply

Your email address will not be published. Required fields are marked *