[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