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.mench...@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.mench...@qca.qualcomm.com>
Signed-off-by: Rosen Penev <ros...@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


_______________________________________________
Lede-dev mailing list
Lede-dev@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/lede-dev

Reply via email to