aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mpc85xx
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-02-22 14:42:48 +0000
committerFelix Fietkau <nbd@openwrt.org>2014-02-22 14:42:48 +0000
commit171273a04023cd360167a71b63e306313a44c76e (patch)
tree320164894a8528a1bf56b1f51b1be7c2e14fa98a /target/linux/mpc85xx
parenta2db25951f6b17e42e94ae9f9ad412d6bcefecf2 (diff)
downloadupstream-171273a04023cd360167a71b63e306313a44c76e.tar.gz
upstream-171273a04023cd360167a71b63e306313a44c76e.tar.bz2
upstream-171273a04023cd360167a71b63e306313a44c76e.zip
gianfar: Fix reported number of sent bytes to BQL
This is a backported patch for the gianfar ethernet driver used in TPLink 4900 v1. It is supposed to fix the error which show up in dmesg with: NETDEV WATCHDOG: eth0 (fsl-gianfar): transmit queue xy timed out Full upstream patch is at: http://patchwork.ozlabs.org/patch/271242 Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@39692 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/mpc85xx')
-rw-r--r--target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch77
1 files changed, 77 insertions, 0 deletions
diff --git a/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch b/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch
new file mode 100644
index 0000000000..d0380ff8ac
--- /dev/null
+++ b/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch
@@ -0,0 +1,77 @@
+--- a/drivers/net/ethernet/freescale/gianfar.c
++++ b/drivers/net/ethernet/freescale/gianfar.c
+@@ -2064,7 +2064,7 @@ static int gfar_start_xmit(struct sk_buf
+ int i, rq = 0, do_tstamp = 0;
+ u32 bufaddr;
+ unsigned long flags;
+- unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN;
++ unsigned int nr_frags, nr_txbds, bytes_sent, fcb_length = GMAC_FCB_LEN;
+
+ /* TOE=1 frames larger than 2500 bytes may see excess delays
+ * before start of transmission.
+@@ -2130,7 +2130,10 @@ static int gfar_start_xmit(struct sk_buf
+ }
+
+ /* Update transmit stats */
+- tx_queue->stats.tx_bytes += skb->len;
++ bytes_sent = skb->len;
++ tx_queue->stats.tx_bytes += bytes_sent;
++ /* keep Tx bytes on wire for BQL accounting */
++ GFAR_CB(skb)->bytes_sent = bytes_sent;
+ tx_queue->stats.tx_packets++;
+
+ txbdp = txbdp_start = tx_queue->cur_tx;
+@@ -2150,12 +2153,13 @@ static int gfar_start_xmit(struct sk_buf
+ } else {
+ /* Place the fragment addresses and lengths into the TxBDs */
+ for (i = 0; i < nr_frags; i++) {
++ unsigned int frag_len;
+ /* Point at the next BD, wrapping as needed */
+ txbdp = next_txbd(txbdp, base, tx_queue->tx_ring_size);
+
+- length = skb_shinfo(skb)->frags[i].size;
++ frag_len = skb_shinfo(skb)->frags[i].size;
+
+- lstatus = txbdp->lstatus | length |
++ lstatus = txbdp->lstatus | frag_len |
+ BD_LFLAG(TXBD_READY);
+
+ /* Handle the last BD specially */
+@@ -2165,7 +2169,7 @@ static int gfar_start_xmit(struct sk_buf
+ bufaddr = skb_frag_dma_map(priv->dev,
+ &skb_shinfo(skb)->frags[i],
+ 0,
+- length,
++ frag_len,
+ DMA_TO_DEVICE);
+
+ /* set the TxBD length and buffer pointer */
+@@ -2231,7 +2235,7 @@ static int gfar_start_xmit(struct sk_buf
+ lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
+ }
+
+- netdev_tx_sent_queue(txq, skb->len);
++ netdev_tx_sent_queue(txq, bytes_sent);
+
+ /* We can work in parallel with gfar_clean_tx_ring(), except
+ * when modifying num_txbdfree. Note that we didn't grab the lock
+@@ -2551,7 +2555,7 @@ static void gfar_clean_tx_ring(struct gf
+ bdp = next_txbd(bdp, base, tx_ring_size);
+ }
+
+- bytes_sent += skb->len;
++ bytes_sent += GFAR_CB(skb)->bytes_sent;
+
+ dev_kfree_skb_any(skb);
+
+--- a/drivers/net/ethernet/freescale/gianfar.h
++++ b/drivers/net/ethernet/freescale/gianfar.h
+@@ -571,7 +571,7 @@ struct rxfcb {
+ };
+
+ struct gianfar_skb_cb {
+- int alignamount;
++ unsigned int bytes_sent; /* bytes-on-wire (i.e. no FCB) */
+ };
+
+ #define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb))