aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-08-12 17:26:00 +0000
committerFelix Fietkau <nbd@openwrt.org>2013-08-12 17:26:00 +0000
commit7fff30d5b92629253f4c4f42bab22d9d14b0edec (patch)
tree54186c62c68b8948acb074592c006aff3ec0b096
parentb10717fee91d46a3a441c67aceaae42b1b91caf4 (diff)
downloadupstream-7fff30d5b92629253f4c4f42bab22d9d14b0edec.tar.gz
upstream-7fff30d5b92629253f4c4f42bab22d9d14b0edec.tar.bz2
upstream-7fff30d5b92629253f4c4f42bab22d9d14b0edec.zip
ar71xx: ethernet: cache skb->len in the tx function to avoid accessing it again in completion
Improves ethernet performance, especially during bridging Signed-off-by: Felix Fietkau <nbd@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@37761 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h7
-rw-r--r--target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c8
2 files changed, 10 insertions, 5 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 b9d95adaf6..6d51e722b0 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
@@ -91,8 +91,11 @@ struct ag71xx_buf {
void *rx_buf;
};
struct ag71xx_desc *desc;
- dma_addr_t dma_addr;
- unsigned long timestamp;
+ union {
+ dma_addr_t dma_addr;
+ unsigned long timestamp;
+ };
+ unsigned int len;
};
struct ag71xx_ring {
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 93071690e8..fc6be0e001 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
@@ -145,7 +145,7 @@ static void ag71xx_ring_tx_clean(struct ag71xx *ag)
}
if (ring->buf[i].skb) {
- bytes_compl += ring->buf[i].skb->len;
+ bytes_compl += ring->buf[i].len;
pkts_compl++;
dev_kfree_skb_any(ring->buf[i].skb);
}
@@ -684,6 +684,7 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
DMA_TO_DEVICE);
netdev_sent_queue(dev, skb->len);
+ ring->buf[i].len = skb->len;
ring->buf[i].skb = skb;
ring->buf[i].timestamp = jiffies;
@@ -824,6 +825,7 @@ static int ag71xx_tx_packets(struct ag71xx *ag)
unsigned int i = ring->dirty % ring->size;
struct ag71xx_desc *desc = ring->buf[i].desc;
struct sk_buff *skb = ring->buf[i].skb;
+ int len = ring->buf[i].len;
if (!ag71xx_desc_empty(desc)) {
if (pdata->is_ar7240 &&
@@ -834,8 +836,8 @@ static int ag71xx_tx_packets(struct ag71xx *ag)
ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
- bytes_compl += skb->len;
- ag->dev->stats.tx_bytes += skb->len;
+ bytes_compl += len;
+ ag->dev->stats.tx_bytes += len;
ag->dev->stats.tx_packets++;
dev_kfree_skb_any(skb);