diff options
author | Felix Fietkau <nbd@openwrt.org> | 2014-09-10 12:56:24 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2014-09-10 12:56:24 +0000 |
commit | cc1bd10ed4170e1af202614ec9fe2bdfea2d6bd5 (patch) | |
tree | 3e97d59c75daf7d588abf650e391b4426234b0d8 | |
parent | 8b55a6de7484a9a2c6a4c5984684849ce16e0205 (diff) | |
download | master-187ad058-cc1bd10ed4170e1af202614ec9fe2bdfea2d6bd5.tar.gz master-187ad058-cc1bd10ed4170e1af202614ec9fe2bdfea2d6bd5.tar.bz2 master-187ad058-cc1bd10ed4170e1af202614ec9fe2bdfea2d6bd5.zip |
ar71xx: ack completed tx descriptors only after the full frame has been completed
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@42457 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r-- | target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c | 26 |
1 files changed, 16 insertions, 10 deletions
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 2a7567ede5..892d5e69e9 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 @@ -901,11 +901,12 @@ static int ag71xx_tx_packets(struct ag71xx *ag) struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); int sent = 0; int bytes_compl = 0; + int n = 0; DBG("%s: processing TX ring\n", ag->dev->name); - while (ring->dirty != ring->curr) { - unsigned int i = ring->dirty % ring->size; + while (ring->dirty + n != ring->curr) { + unsigned int i = (ring->dirty + n) % ring->size; struct ag71xx_desc *desc = ring->buf[i].desc; struct sk_buff *skb = ring->buf[i].skb; @@ -916,17 +917,22 @@ static int ag71xx_tx_packets(struct ag71xx *ag) break; } - ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); + n++; + if (!skb) + continue; - if (skb) { - dev_kfree_skb_any(skb); - ring->buf[i].skb = NULL; + dev_kfree_skb_any(skb); + ring->buf[i].skb = NULL; - bytes_compl += ring->buf[i].len; - sent++; - } + bytes_compl += ring->buf[i].len; - ring->dirty++; + sent++; + ring->dirty += n; + + while (n > 0) { + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); + n--; + } } DBG("%s: %d packets sent out\n", ag->dev->name, sent); |