From patchwork Thu Feb 24 11:38:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Whitchurch X-Patchwork-Id: 12758413 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C6AFBC433EF for ; Thu, 24 Feb 2022 11:40:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:CC :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=HvUoDdDEqiGCU/B0OxXSvqUf67+HGcQctUAngroiLx8=; b=e9xI3ffcoZahK0 A4GIZH4DSBYlLqnwzjotfeuqFxjmzzZFsSqjSETEXrdZN4YFN/oeKhEOyhbvu0GBowMSOiafCcUcX m6mXYC7LbXZbthywB0qxnbHzGIgRq7t6TDbtvMJL+u1t3j/1Eqhg3bF8MlawQ59FM9qjSBVzsD5mb 32DHP6teTbZWvme77Qx3JA5XLxEDng2nDKkZGyEHSMO6E5GNjlfqCilSb7ftAqVfCiN9viMsO7m/I taJpoRp9JlULcQbaBEcoaIJuzwIzih4VuqyEaFglbFWPbmcwtENHArJUU8iUdxw/1U/OJjlGB7Iyo ExzmNO8dN5k0pt3B4IoA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nNCSQ-000aCm-VI; Thu, 24 Feb 2022 11:38:51 +0000 Received: from smtp1.axis.com ([195.60.68.17]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nNCSL-000aBN-Tk for linux-arm-kernel@lists.infradead.org; Thu, 24 Feb 2022 11:38:48 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1645702726; x=1677238726; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=JrRPEFKeXWcc6jAXtUVnif+wj03hnZPozhAYD5BNe3k=; b=D76sjWOKM/RjDjTm+B+u1yIyVzLSszJiMGPIU5NAoEQdxZa/NcHCU1cR 8Kastq7NdU6nJpAAPMSEBoL5PAKU8G95bDJYF4obCiCmsO93heJDee1ps MsXB14JfyHJJx3TGbbGYKCxh1y66JHKYs1Yb232Pvlb/Q2DWv357Vj3bM RXrVtoANKF6YbqnhT9IfdqMsIacRSN34VBFhsvIBE+8B0QcfyVI/trM7t vqulmRkXs5mtKh8kiu5qor5h/BLAZJhDqY2VJS/YGr1wWU9MKeezJSovu kDIXYEfqBwUly66gPqDAP9jCHaeDs9aKAqgDnt44c27OTNTtEhCNElw5z w==; From: Vincent Whitchurch To: Giuseppe Cavallaro , Alexandre Torgue , Jose Abreu , "David S. Miller" , Jakub Kicinski , Maxime Coquelin CC: , Vincent Whitchurch , Lars Persson , Srinivas Kandagatla , , , , Subject: [PATCH v2] net: stmmac: only enable DMA interrupts when ready Date: Thu, 24 Feb 2022 12:38:29 +0100 Message-ID: <20220224113829.1092859-1-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220224_033846_323023_FBAF522B X-CRM114-Status: GOOD ( 11.80 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org In this driver's ->ndo_open() callback, it enables DMA interrupts, starts the DMA channels, then requests interrupts with request_irq(), and then finally enables napi. If RX DMA interrupts are received before napi is enabled, no processing is done because napi_schedule_prep() will return false. If the network has a lot of broadcast/multicast traffic, then the RX ring could fill up completely before napi is enabled. When this happens, no further RX interrupts will be delivered, and the driver will fail to receive any packets. Fix this by only enabling DMA interrupts after all other initialization is complete. Fixes: 523f11b5d4fd72efb ("net: stmmac: move hardware setup for stmmac_open to new function") Reported-by: Lars Persson Signed-off-by: Vincent Whitchurch --- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 6708ca2aa4f7..43978558d6c0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2260,6 +2260,23 @@ static void stmmac_stop_tx_dma(struct stmmac_priv *priv, u32 chan) stmmac_stop_tx(priv, priv->ioaddr, chan); } +static void stmmac_enable_all_dma_irq(struct stmmac_priv *priv) +{ + u32 rx_channels_count = priv->plat->rx_queues_to_use; + u32 tx_channels_count = priv->plat->tx_queues_to_use; + u32 dma_csr_ch = max(rx_channels_count, tx_channels_count); + u32 chan; + + for (chan = 0; chan < dma_csr_ch; chan++) { + struct stmmac_channel *ch = &priv->channel[chan]; + unsigned long flags; + + spin_lock_irqsave(&ch->lock, flags); + stmmac_enable_dma_irq(priv, priv->ioaddr, chan, 1, 1); + spin_unlock_irqrestore(&ch->lock, flags); + } +} + /** * stmmac_start_all_dma - start all RX and TX DMA channels * @priv: driver private structure @@ -2902,8 +2919,10 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) stmmac_axi(priv, priv->ioaddr, priv->plat->axi); /* DMA CSR Channel configuration */ - for (chan = 0; chan < dma_csr_ch; chan++) + for (chan = 0; chan < dma_csr_ch; chan++) { stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan); + stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 1); + } /* DMA RX Channel Configuration */ for (chan = 0; chan < rx_channels_count; chan++) { @@ -3759,6 +3778,7 @@ static int stmmac_open(struct net_device *dev) stmmac_enable_all_queues(priv); netif_tx_start_all_queues(priv->dev); + stmmac_enable_all_dma_irq(priv); return 0; @@ -6508,8 +6528,10 @@ int stmmac_xdp_open(struct net_device *dev) } /* DMA CSR Channel configuration */ - for (chan = 0; chan < dma_csr_ch; chan++) + for (chan = 0; chan < dma_csr_ch; chan++) { stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan); + stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 1); + } /* Adjust Split header */ sph_en = (priv->hw->rx_csum > 0) && priv->sph; @@ -6570,6 +6592,7 @@ int stmmac_xdp_open(struct net_device *dev) stmmac_enable_all_queues(priv); netif_carrier_on(dev); netif_tx_start_all_queues(dev); + stmmac_enable_all_dma_irq(priv); return 0; @@ -7447,6 +7470,7 @@ int stmmac_resume(struct device *dev) stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw); stmmac_enable_all_queues(priv); + stmmac_enable_all_dma_irq(priv); mutex_unlock(&priv->lock); rtnl_unlock();