aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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))