Skip to content

Commit a3a57bf

Browse files
hkallweitkuba-moo
authored andcommitted
net: stmmac: work around sporadic tx issue on link-up
This is a follow-up to the discussion in [0]. It seems to me that at least the IP version used on Amlogic SoC's sometimes has a problem if register MAC_CTRL_REG is written whilst the chip is still processing a previous write. But that's just a guess. Adding a delay between two writes to this register helps, but we can also simply omit the offending second write. This patch uses the second approach and is based on a suggestion from Qi Duan. Benefit of this approach is that we can save few register writes, also on not affected chip versions. [0] https://www.spinics.net/lists/netdev/msg831526.html Fixes: bfab27a ("stmmac: add the experimental PCI support") Suggested-by: Qi Duan <[email protected]> Suggested-by: Jerome Brunet <[email protected]> Signed-off-by: Heiner Kallweit <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent ef332fe commit a3a57bf

File tree

2 files changed

+11
-6
lines changed

2 files changed

+11
-6
lines changed

drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,14 +258,18 @@ EXPORT_SYMBOL_GPL(stmmac_set_mac_addr);
258258
/* Enable disable MAC RX/TX */
259259
void stmmac_set_mac(void __iomem *ioaddr, bool enable)
260260
{
261-
u32 value = readl(ioaddr + MAC_CTRL_REG);
261+
u32 old_val, value;
262+
263+
old_val = readl(ioaddr + MAC_CTRL_REG);
264+
value = old_val;
262265

263266
if (enable)
264267
value |= MAC_ENABLE_RX | MAC_ENABLE_TX;
265268
else
266269
value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX);
267270

268-
writel(value, ioaddr + MAC_CTRL_REG);
271+
if (value != old_val)
272+
writel(value, ioaddr + MAC_CTRL_REG);
269273
}
270274

271275
void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -986,10 +986,10 @@ static void stmmac_mac_link_up(struct phylink_config *config,
986986
bool tx_pause, bool rx_pause)
987987
{
988988
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
989-
u32 ctrl;
989+
u32 old_ctrl, ctrl;
990990

991-
ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
992-
ctrl &= ~priv->hw->link.speed_mask;
991+
old_ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
992+
ctrl = old_ctrl & ~priv->hw->link.speed_mask;
993993

994994
if (interface == PHY_INTERFACE_MODE_USXGMII) {
995995
switch (speed) {
@@ -1064,7 +1064,8 @@ static void stmmac_mac_link_up(struct phylink_config *config,
10641064
if (tx_pause && rx_pause)
10651065
stmmac_mac_flow_ctrl(priv, duplex);
10661066

1067-
writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
1067+
if (ctrl != old_ctrl)
1068+
writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
10681069

10691070
stmmac_mac_set(priv, priv->ioaddr, true);
10701071
if (phy && priv->dma_cap.eee) {

0 commit comments

Comments
 (0)