Seems to remove a few instructions. Original message below:

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


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

Reply via email to