From: Lars Persson Date: Mon, 15 Apr 2019 07:50:34 +0000 (+0200) Subject: net: stmmac: Set dma ring length before enabling the DMA X-Git-Tag: v4.9.170~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b142075137c31c1009069f01d6882c06cf760156;p=thirdparty%2Fkernel%2Fstable.git net: stmmac: Set dma ring length before enabling the DMA This was fixed in upstream by commit 7d9e6c5afab6 ("net: stmmac: Integrate XGMAC into main driver flow") that is a new feature commit. We found a race condition in the DMA init sequence that hits if the PHY already has link up during stmmac_hw_setup. Since the ring length was programmed after enabling the RX path, we might receive a packet before the correct ring length is programmed. When that happened we could not get reliable interrupts for DMA RX and the MTL complained about RX FIFO overrun. Signed-off-by: Lars Persson Cc: stable@vger.kernel.org # 4.9.x Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Cc: Jose Abreu Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index fc437d75ac762..b46b56ad75175 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1747,11 +1747,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) if (ret < 0) pr_warn("%s: failed debugFS registration\n", __func__); #endif - /* Start the ball rolling... */ - pr_debug("%s: DMA RX/TX processes started...\n", dev->name); - priv->hw->dma->start_tx(priv->ioaddr); - priv->hw->dma->start_rx(priv->ioaddr); - /* Dump DMA/MAC registers */ if (netif_msg_hw(priv)) { priv->hw->mac->dump_regs(priv->hw); @@ -1779,6 +1774,11 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) if (priv->tso) priv->hw->dma->enable_tso(priv->ioaddr, 1, STMMAC_CHAN0); + /* Start the ball rolling... */ + pr_debug("%s: DMA RX/TX processes started...\n", dev->name); + priv->hw->dma->start_tx(priv->ioaddr); + priv->hw->dma->start_rx(priv->ioaddr); + return 0; }