[LEDE-DEV] [PATCH 7/7] ag71xx: support for descriptors in SRAM

Rosen Penev rosenp at gmail.com
Thu Dec 7 18:37:17 PST 2017


A good performance improvement. As I have not tested this, I'm keeping the Qualcomm default to no.
Original commit below:

From: Ben Menchaca <ben.menchaca at qca.qualcomm.com>
Date: Fri, 7 Jun 2013 15:25:00 -0500
Subject: [ag71xx] support for descriptors in SRAM

Adds support to the ag71xx to use SRAM for descriptors for a limited
number of ag71xx instances.  This is a significant performance
improvement over using non-cacheable RAM (~4% overall bridging
performance).

Signed-off-by: Ben Menchaca <ben.menchaca at qca.qualcomm.com>
Signed-off-by: Rosen Penev <rosenp at gmail.com>
---
 target/linux/ar71xx/config-4.4                     |  1 +
 target/linux/ar71xx/config-4.9                     |  1 +
 .../drivers/net/ethernet/atheros/ag71xx/Kconfig    |  8 +++
 .../drivers/net/ethernet/atheros/ag71xx/ag71xx.h   |  1 +
 .../net/ethernet/atheros/ag71xx/ag71xx_main.c      | 57 +++++++++++++++++++---
 5 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/target/linux/ar71xx/config-4.4 b/target/linux/ar71xx/config-4.4
index 3ba3853..3bfcd17 100644
--- a/target/linux/ar71xx/config-4.4
+++ b/target/linux/ar71xx/config-4.4
@@ -2,6 +2,7 @@ CONFIG_AG71XX=y
 CONFIG_AG71XX_AR8216_SUPPORT=y
 # CONFIG_AG71XX_DEBUG is not set
 # CONFIG_AG71XX_DEBUG_FS is not set
+# CONFIG_AG71XX_SRAM_DESCRIPTORS is not set
 CONFIG_AR8216_PHY=y
 CONFIG_AR8216_PHY_LEDS=y
 CONFIG_ARCH_BINFMT_ELF_STATE=y
diff --git a/target/linux/ar71xx/config-4.9 b/target/linux/ar71xx/config-4.9
index 1d47246..7ef78b3 100644
--- a/target/linux/ar71xx/config-4.9
+++ b/target/linux/ar71xx/config-4.9
@@ -2,6 +2,7 @@ CONFIG_AG71XX=y
 CONFIG_AG71XX_AR8216_SUPPORT=y
 # CONFIG_AG71XX_DEBUG is not set
 # CONFIG_AG71XX_DEBUG_FS is not set
+# CONFIG_AG71XX_SRAM_DESCRIPTORS is not set
 CONFIG_AR8216_PHY=y
 CONFIG_AR8216_PHY_LEDS=y
 CONFIG_ARCH_BINFMT_ELF_STATE=y
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig
index 42d544f..b859b2b 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig
@@ -8,6 +8,14 @@ config AG71XX
 
 if AG71XX
 
+config AG71XX_SRAM_DESCRIPTORS
+        bool "Atheros AR71xx built-in ethernet driver SRAM descriptor rings"
+        default n
+        help
+          Atheros AR71xx built-in ethernet driver normally uses non-cached RAM
+          for descriptor rings.  If set to 'y', this option puts those rings in
+          SRAM, improving performance.
+
 config AG71XX_DEBUG
 	bool "Atheros AR71xx built-in ethernet driver debugging"
 	default n
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
index f85e43d..1b2026b 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
@@ -115,6 +115,7 @@ struct ag71xx_ring {
 	dma_addr_t		descs_dma;
 	u16			desc_split;
 	u16			order;
+	void __iomem		*iomem;
 };
 
 struct ag71xx_mdio {
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index 8ce777c..74bf524 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -13,6 +13,10 @@
 
 #include "ag71xx.h"
 
+#ifndef UNUSED
+#define UNUSED(__x)	(void)(__x)
+#endif
+
 static int ag71xx_gmac_num = 0;
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0)
@@ -39,6 +43,17 @@ MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
 
 #define ETH_SWITCH_HEADER_LEN	2
 
+#ifdef CONFIG_AG71XX_SRAM_DESCRIPTORS
+#define MAX_AG71XX_USING_SRAM		2
+#define MAX_AG71XX_SRAM_RINGS		(MAX_AG71XX_USING_SRAM) * 2
+static unsigned long ag71xx_ring_bufs[MAX_AG71XX_SRAM_RINGS] = {
+	0x1d000000UL,
+	0x1d001000UL,
+	0x1d002000UL,
+	0x1d003000UL
+};
+#endif /* CONFIG_AG71XX_SRAM_DESCRIPTORS */
+
 static int ag71xx_tx_packets(struct ag71xx *ag, bool flush);
 
 static inline unsigned int ag71xx_max_frame_len(unsigned int mtu)
@@ -103,12 +118,17 @@ static void ag71xx_ring_free(struct ag71xx_ring *ring)
 {
 	kfree(ring->buf);
 
-	if (ring->descs_cpu)
-		dma_free_coherent(NULL, ring->size * ring->desc_size,
-				  ring->descs_cpu, ring->descs_dma);
+	if (ring->descs_cpu) {
+		if (ring->iomem) {
+			iounmap(ring->iomem);
+		} else {
+			dma_free_coherent(NULL, ring->size * ring->desc_size,
+					  ring->descs_cpu, ring->descs_dma);
+		}
+	}
 }
 
-static int ag71xx_ring_alloc(struct ag71xx_ring *ring)
+static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int id)
 {
 	ring->desc_size = sizeof(struct ag71xx_desc);
 	if (ring->desc_size % cache_line_size()) {
@@ -118,11 +138,32 @@ static int ag71xx_ring_alloc(struct ag71xx_ring *ring)
 		ring->desc_size = roundup(ring->desc_size, cache_line_size());
 	}
 
-	ring->descs_cpu = dma_alloc_coherent(NULL, ring->size * ring->desc_size,
-					     &ring->descs_dma, GFP_ATOMIC);
+#ifdef CONFIG_AG71XX_SRAM_DESCRIPTORS
+	if (id < MAX_AG71XX_USING_SRAM) {
+		DBG("ag71xx: descriptors in SRAM\n");
+		ring->iomem = ioremap_nocache(ag71xx_ring_bufs[id], 0x1000);
+		if (ring->iomem == NULL)
+			return -ENOMEM;
+
+		ring->descs_cpu = (u8 *)ring->iomem;
+		ring->descs_dma = ((dma_addr_t)(ring->iomem) & 0x1fffffff);
+		goto descs_allocated;
+	}
+#else
+	UNUSED(id);
+#endif /* CONFIG_AG71XX_SRAM_DESCRIPTORS */
+	ring->iomem = NULL;
+	ring->descs_cpu = dma_alloc_coherent(NULL,
+					     ring->size * ring->desc_size,
+					     &ring->descs_dma,
+					     GFP_ATOMIC);
+
 	if (!ring->descs_cpu)
 		return -ENOMEM;
 
+#ifdef CONFIG_AG71XX_SRAM_DESCRIPTORS
+descs_allocated:
+#endif /* CONFIG_AG71XX_SRAM_DESCRIPTORS */
 	ring->buf = kzalloc(ring->size * sizeof(*ring->buf), GFP_KERNEL);
 	if (!ring->buf)
 		return -ENOMEM;
@@ -320,13 +361,13 @@ static int ag71xx_rings_init(struct ag71xx *ag)
 {
 	int ret;
 
-	ret = ag71xx_ring_alloc(&ag->tx_ring);
+	ret = ag71xx_ring_alloc(&ag->tx_ring, (ag->gmac_num * 2));
 	if (ret)
 		return ret;
 
 	ag71xx_ring_tx_init(ag);
 
-	ret = ag71xx_ring_alloc(&ag->rx_ring);
+	ret = ag71xx_ring_alloc(&ag->rx_ring, (ag->gmac_num * 2) + 1);
 	if (ret)
 		return ret;
 
-- 
2.7.4




More information about the Lede-dev mailing list