[LEDE-DEV] [PATCH 3/7] ag71xx: optimized iomapped register access
Rosen Penev
rosenp at gmail.com
Thu Dec 7 18:37:13 PST 2017
Seems to remove a few instructions. Original message below:
From: Ben Menchaca <ben.menchaca at qca.qualcomm.com>
Date: Tue, 11 Jun 2013 15:50:17 -0500
Subject: [ag71xx] optimize iomapped register access
Add register accessors that remove the per-register range check that
was done previously. Additionally, we separate the write from the
subsequent read that is designed to flush the write; this can now be
called separately.
Signed-off-by: Ben Menchaca <ben.menchaca at qca.qualcomm.com>
Signed-off-by: Rosen Penev <rosenp at gmail.com>
---
.../drivers/net/ethernet/atheros/ag71xx/ag71xx.h | 23 +++++++++++++++++++
.../net/ethernet/atheros/ag71xx/ag71xx_main.c | 26 +++++++++++++++-------
2 files changed, 41 insertions(+), 8 deletions(-)
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 c39beaf..39237aa 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
@@ -163,6 +163,12 @@ struct ag71xx {
struct ag71xx_ring rx_ring ____cacheline_aligned;
struct ag71xx_ring tx_ring ____cacheline_aligned;
+ void __iomem *rx_ctrl_reg;
+ void __iomem *rx_status_reg;
+ void __iomem *tx_ctrl_reg;
+ void __iomem *tx_status_reg;
+ void __iomem *int_status_reg;
+
unsigned int max_frame_len;
unsigned int desc_pktlen_mask;
unsigned int rx_buf_size;
@@ -400,6 +406,17 @@ static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg)
}
}
+static inline void ag71xx_wr_fast(void __iomem *r, u32 value)
+{
+ __raw_writel(value, r);
+}
+
+static inline void ag71xx_wr_flush(void __iomem *r)
+{
+ (void)__raw_readl(r);
+}
+
+
static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
{
ag71xx_check_reg_offset(ag, reg);
@@ -409,6 +426,12 @@ static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
(void) __raw_readl(ag->mac_base + reg);
}
+static inline u32 ag71xx_rr_fast(void __iomem *r)
+{
+ return __raw_readl(r);
+}
+
+
static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
{
ag71xx_check_reg_offset(ag, reg);
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 7760952..ffbe646 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
@@ -842,8 +842,8 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
DBG("%s: packet injected into TX queue\n", ag->dev->name);
/* enable TX engine */
- ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
-
+ ag71xx_wr_fast(ag->tx_ctrl_reg, TX_CTRL_TXE);
+ ag71xx_wr_flush(ag->tx_ctrl_reg);
return NETDEV_TX_OK;
err_drop_unmap:
@@ -994,7 +994,7 @@ static int ag71xx_tx_packets(struct ag71xx *ag, bool flush)
ring->dirty += n;
while (n > 0) {
- ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
+ ag71xx_wr_fast(ag->tx_status_reg, TX_STATUS_PS);
n--;
}
}
@@ -1048,7 +1048,7 @@ static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
break;
}
- ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
+ ag71xx_wr_fast(ag->rx_status_reg, RX_STATUS_PR);
pktlen = desc->ctrl & pktlen_mask;
pktlen -= ETH_FCS_LEN;
@@ -1087,6 +1087,8 @@ next:
ring->curr++;
}
+ ag71xx_wr_flush(ag->rx_status_reg);
+
ag71xx_ring_rx_refill(ag);
while ((skb = __skb_dequeue(&queue)) != NULL) {
@@ -1123,13 +1125,15 @@ static int ag71xx_poll(struct napi_struct *napi, int limit)
if (rx_ring->buf[rx_ring->dirty % rx_ring_size].rx_buf == NULL)
goto oom;
- status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
+ status = ag71xx_rr_fast(ag->rx_status_reg);
if (unlikely(status & RX_STATUS_OF)) {
- ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF);
+ ag71xx_wr_fast(ag->rx_status_reg, RX_STATUS_OF);
+ ag71xx_wr_flush(ag->rx_status_reg);
dev->stats.rx_fifo_errors++;
/* restart RX */
- ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
+ ag71xx_wr_fast(ag->rx_ctrl_reg, RX_CTRL_RXE);
+ ag71xx_wr_flush(ag->rx_ctrl_reg);
}
if (rx_done < limit) {
@@ -1172,7 +1176,7 @@ static irqreturn_t ag71xx_interrupt(int irq, void *dev_id)
struct ag71xx *ag = netdev_priv(dev);
u32 status;
- status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS);
+ status = ag71xx_rr_fast(ag->int_status_reg);
ag71xx_dump_intr(ag, "raw", status);
if (unlikely(!status))
@@ -1320,6 +1324,12 @@ static int ag71xx_probe(struct platform_device *pdev)
goto err_free_dev;
}
+ ag->rx_ctrl_reg = ag->mac_base + AG71XX_REG_RX_CTRL;
+ ag->rx_status_reg = ag->mac_base + AG71XX_REG_RX_STATUS;
+ ag->tx_ctrl_reg = ag->mac_base + AG71XX_REG_TX_CTRL;
+ ag->tx_status_reg = ag->mac_base + AG71XX_REG_TX_STATUS;
+ ag->int_status_reg = ag->mac_base + AG71XX_REG_INT_STATUS;
+
dev->irq = platform_get_irq(pdev, 0);
err = request_irq(dev->irq, ag71xx_interrupt,
0x0,
--
2.7.4
More information about the Lede-dev
mailing list