aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@mvista.com>2010-06-30 02:39:13 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-30 14:35:42 -0400
commitdeb90eacd084d9edfeda2f714d99c29a86360077 (patch)
treee0bbd8c70d6f88674d047f2c107772ef63998e9c /drivers/net
parent7d3509774c2ef4ffd1c5fd2fac65dc4e071a6f21 (diff)
gianfar: Implement workaround for eTSEC76 erratum
MPC8313ECE says: "For TOE=1 huge or jumbo frames, the data required to generate the checksum may exceed the 2500-byte threshold beyond which the controller constrains itself to one memory fetch every 256 eTSEC system clocks. This throttling threshold is supposed to trigger only when the controller has sufficient data to keep transmit active for the duration of the memory fetches. The state machine handling this threshold, however, fails to take large TOE frames into account. As a result, TOE=1 frames larger than 2500 bytes often see excess delays before start of transmission." This patch implements the workaround as suggested by the errata document, i.e.: "Limit TOE=1 frames to less than 2500 bytes to avoid excess delays due to memory throttling. When using packets larger than 2700 bytes, it is recommended to turn TOE off." To be sure, we limit the TOE frames to 2500 bytes, and do software checksumming instead. Signed-off-by: Anton Vorontsov <avorontsov@mvista.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/gianfar.c19
-rw-r--r--drivers/net/gianfar.h1
2 files changed, 20 insertions, 0 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index cee8ae714731..c2fabc1853ad 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -942,6 +942,11 @@ static void gfar_detect_errata(struct gfar_private *priv)
942 (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) 942 (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
943 priv->errata |= GFAR_ERRATA_74; 943 priv->errata |= GFAR_ERRATA_74;
944 944
945 /* MPC8313 and MPC837x all rev */
946 if ((pvr == 0x80850010 && mod == 0x80b0) ||
947 (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
948 priv->errata |= GFAR_ERRATA_76;
949
945 if (priv->errata) 950 if (priv->errata)
946 dev_info(dev, "enabled errata workarounds, flags: 0x%x\n", 951 dev_info(dev, "enabled errata workarounds, flags: 0x%x\n",
947 priv->errata); 952 priv->errata);
@@ -2011,6 +2016,20 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2011 unsigned int nr_frags, nr_txbds, length; 2016 unsigned int nr_frags, nr_txbds, length;
2012 union skb_shared_tx *shtx; 2017 union skb_shared_tx *shtx;
2013 2018
2019 /*
2020 * TOE=1 frames larger than 2500 bytes may see excess delays
2021 * before start of transmission.
2022 */
2023 if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) &&
2024 skb->ip_summed == CHECKSUM_PARTIAL &&
2025 skb->len > 2500)) {
2026 int ret;
2027
2028 ret = skb_checksum_help(skb);
2029 if (ret)
2030 return ret;
2031 }
2032
2014 rq = skb->queue_mapping; 2033 rq = skb->queue_mapping;
2015 tx_queue = priv->tx_queue[rq]; 2034 tx_queue = priv->tx_queue[rq];
2016 txq = netdev_get_tx_queue(dev, rq); 2035 txq = netdev_get_tx_queue(dev, rq);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 0a0483ce21d2..c414374f407f 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1027,6 +1027,7 @@ struct gfar_priv_grp {
1027 1027
1028enum gfar_errata { 1028enum gfar_errata {
1029 GFAR_ERRATA_74 = 0x01, 1029 GFAR_ERRATA_74 = 0x01,
1030 GFAR_ERRATA_76 = 0x02,
1030}; 1031};
1031 1032
1032/* Struct stolen almost completely (and shamelessly) from the FCC enet source 1033/* Struct stolen almost completely (and shamelessly) from the FCC enet source