aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ar71xx/files
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-09-10 12:56:24 +0000
committerFelix Fietkau <nbd@openwrt.org>2014-09-10 12:56:24 +0000
commitcc1bd10ed4170e1af202614ec9fe2bdfea2d6bd5 (patch)
tree3e97d59c75daf7d588abf650e391b4426234b0d8 /target/linux/ar71xx/files
parent8b55a6de7484a9a2c6a4c5984684849ce16e0205 (diff)
downloadupstream-cc1bd10ed4170e1af202614ec9fe2bdfea2d6bd5.tar.gz
upstream-cc1bd10ed4170e1af202614ec9fe2bdfea2d6bd5.tar.bz2
upstream-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
Diffstat (limited to 'target/linux/ar71xx/files')
-rw-r--r--target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c26
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);