From patchwork Wed Jul 12 16:28:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Dahl X-Patchwork-Id: 9837157 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 296A9602D8 for ; Wed, 12 Jul 2017 16:45:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 133752842B for ; Wed, 12 Jul 2017 16:45:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0584528584; Wed, 12 Jul 2017 16:45:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 700192842B for ; Wed, 12 Jul 2017 16:45:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=rYmVHWOdhp0ZFFwyLLjglgas6tk09VhX/0n1t9el3QQ=; b=eJXBpRFnjVhJp3Q0BebV2D9l9h cGHsYySpNZWSfbT8D+wy/vFgW14dTzVUoZ7/KV1dwvFfH6fluv09PSUoZQTNo5dxI0Iml5Q8Jp2ly WSeLFgek/lYjgZUD/b7KBQtu1wbqN8OYiWDfkiJzpwVlZFHVj6jSQXfxhVr4CTtPmSFw22Rrov1QJ HyCp74kEU2YHzKh8OrkA/9GSP3m+n/DtEkNQXKCPI5NyMKFCUZWfHdoHYvHVddrpT0Il2o0a0lBIb 4j6LHCYKAHdVDrqkju9sUPK89rau+qRme6d8cB6QMljlv3cevJYVVMUyDAPXDYBDep/hiOjjicOOt O7GcxSLA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dVKl2-0001W3-Tn; Wed, 12 Jul 2017 16:45:00 +0000 Received: from mail.thorsis.com ([213.211.200.15]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dVKVf-0000Jt-SZ for linux-arm-kernel@lists.infradead.org; Wed, 12 Jul 2017 16:29:12 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.thorsis.com (Postfix) with ESMTP id A5A0D3A0E2E; Wed, 12 Jul 2017 18:29:25 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail.thorsis.com Received: from mail.thorsis.com ([127.0.0.1]) by localhost (mail.thorsis.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JHhqU9HhdF2M; Wed, 12 Jul 2017 18:29:21 +0200 (CEST) Received: from seven.thorsis.com (unknown [192.168.10.7]) by mail.thorsis.com (Postfix) with ESMTP id 92CE03A0E2F; Wed, 12 Jul 2017 18:29:19 +0200 (CEST) Received: from ada.ifak-system.com (ada.ifak-system.com [192.168.10.62]) by seven.thorsis.com (Postfix) with ESMTPSA id 045EEE0069C; Wed, 12 Jul 2017 18:29:05 +0200 (CEST) From: Alexander Dahl To: linux-kernel@vger.kernel.org Subject: [RFC 3/3] net: macb: Use sram for rx buffers Date: Wed, 12 Jul 2017 18:28:12 +0200 Message-Id: <1499876892-14423-4-git-send-email-ada@thorsis.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1499876892-14423-1-git-send-email-ada@thorsis.com> References: <1499876892-14423-1-git-send-email-ada@thorsis.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170712_092908_334939_A0C24C4B X-CRM114-Status: GOOD ( 14.56 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The default way for the driver is to use system memory for RX/TX DMA buffers and rings. For the AT91SAM9G20 this is SDRAM which is connected through the EBI bus, together with other memories like NAND-Flash or external SRAM. If a memory access to external SRAM using the NWAIT signal takes too long, the EMAC on the SoC throws receive overrun (ROVR) errors which means it can not put incoming packets into SDRAM (through DMA). Those errors add up in /proc/net/dev To circumvent those "dropped" ethernet frames, we put the RX buffers and rings into the small internal SRAM of the SoC, which are also usable for DMA but directly connected through the AHB without the path through the EBI. This way there are no lost ethernet frames anymore. (If there's too much load however packets can still be dropped by the kernel.) Signed-off-by: Alexander Dahl --- drivers/net/ethernet/cadence/macb.c | 66 ++++++++++++++++++++++++++++++------- drivers/net/ethernet/cadence/macb.h | 2 ++ 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 91f7492..8dacd9c 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -40,9 +41,9 @@ #define MACB_RX_BUFFER_SIZE 128 #define RX_BUFFER_MULTIPLE 64 /* bytes */ -#define DEFAULT_RX_RING_SIZE 512 /* must be power of 2 */ +#define DEFAULT_RX_RING_SIZE 128 /* must be power of 2 */ #define MIN_RX_RING_SIZE 64 -#define MAX_RX_RING_SIZE 8192 +#define MAX_RX_RING_SIZE 128 #define RX_RING_BYTES(bp) (macb_dma_desc_get_size(bp) \ * (bp)->rx_ring_size) @@ -1660,9 +1661,14 @@ static void gem_free_rx_buffers(struct macb *bp) static void macb_free_rx_buffers(struct macb *bp) { if (bp->rx_buffers) { - dma_free_coherent(&bp->pdev->dev, - bp->rx_ring_size * bp->rx_buffer_size, - bp->rx_buffers, bp->rx_buffers_dma); + if (bp->sram_pool) + gen_pool_free(bp->sram_pool, + (unsigned long)bp->rx_buffers, + bp->rx_ring_size * bp->rx_buffer_size); + else + dma_free_coherent(&bp->pdev->dev, + bp->rx_ring_size * bp->rx_buffer_size, + bp->rx_buffers, bp->rx_buffers_dma); bp->rx_buffers = NULL; } } @@ -1674,8 +1680,12 @@ static void macb_free_consistent(struct macb *bp) bp->macbgem_ops.mog_free_rx_buffers(bp); if (bp->rx_ring) { - dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES(bp), - bp->rx_ring, bp->rx_ring_dma); + if (bp->sram_pool) + gen_pool_free(bp->sram_pool, (unsigned long)bp->rx_ring, + RX_RING_BYTES(bp)); + else + dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES(bp), + bp->rx_ring, bp->rx_ring_dma); bp->rx_ring = NULL; } @@ -1690,6 +1700,28 @@ static void macb_free_consistent(struct macb *bp) } } +static void macb_init_sram(struct macb *bp) +{ + struct device_node *node; + struct platform_device *pdev = NULL; + + for_each_compatible_node(node, NULL, "mmio-sram") { + pdev = of_find_device_by_node(node); + if (pdev) { + of_node_put(node); + break; + } + } + + if (!pdev) { + netdev_warn(bp->dev, "Failed to find sram device!\n"); + bp->sram_pool = NULL; + return; + } + + bp->sram_pool = gen_pool_get(&pdev->dev, NULL); +} + static int gem_alloc_rx_buffers(struct macb *bp) { int size; @@ -1710,14 +1742,20 @@ static int macb_alloc_rx_buffers(struct macb *bp) int size; size = bp->rx_ring_size * bp->rx_buffer_size; - bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size, - &bp->rx_buffers_dma, GFP_KERNEL); + if (bp->sram_pool) + bp->rx_buffers = gen_pool_dma_alloc(bp->sram_pool, size, + &bp->rx_buffers_dma); + else + bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size, + &bp->rx_buffers_dma, + GFP_KERNEL); if (!bp->rx_buffers) return -ENOMEM; netdev_dbg(bp->dev, "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n", size, (unsigned long)bp->rx_buffers_dma, bp->rx_buffers); + return 0; } @@ -1746,8 +1784,12 @@ static int macb_alloc_consistent(struct macb *bp) } size = RX_RING_BYTES(bp); - bp->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size, - &bp->rx_ring_dma, GFP_KERNEL); + if (bp->sram_pool) + bp->rx_ring = gen_pool_dma_alloc(bp->sram_pool, size, + &bp->rx_ring_dma); + else + bp->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size, + &bp->rx_ring_dma, GFP_KERNEL); if (!bp->rx_ring) goto out_err; netdev_dbg(bp->dev, @@ -2698,6 +2740,8 @@ static int macb_init(struct platform_device *pdev) int err; u32 val; + macb_init_sram(bp); + bp->tx_ring_size = DEFAULT_TX_RING_SIZE; bp->rx_ring_size = DEFAULT_RX_RING_SIZE; diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 567c72d..d352181 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -957,6 +957,8 @@ struct macb { #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT enum macb_hw_dma_cap hw_dma_cap; #endif + + struct gen_pool *sram_pool; }; static inline bool macb_is_gem(struct macb *bp)