aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@mvista.com>2010-06-30 02:39:12 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-30 14:35:42 -0400
commit7d3509774c2ef4ffd1c5fd2fac65dc4e071a6f21 (patch)
tree54d32c6f6f6c72fee208ab8dea9879697b613765 /drivers/net/gianfar.c
parent70777d03466e7a8a41b0d34677454c92f4e93d89 (diff)
gianfar: Implement workaround for eTSEC74 erratum
MPC8313ECE says: "If MACCFG2[Huge Frame]=0 and the Ethernet controller receives frames which are larger than MAXFRM, the controller truncates the frames to length MAXFRM and marks RxBD[TR]=1 to indicate the error. The controller also erroneously marks RxBD[TR]=1 if the received frame length is MAXFRM or MAXFRM-1, even though those frames are not truncated. No truncation or truncation error occurs if MACCFG2[Huge Frame]=1." There are two options to workaround the issue: "1. Set MACCFG2[Huge Frame]=1, so no truncation occurs for invalid large frames. Software can determine if a frame is larger than MAXFRM by reading RxBD[LG] or RxBD[Data Length]. 2. Set MAXFRM to 1538 (0x602) instead of the default 1536 (0x600), so normal-length frames are not marked as truncated. Software can examine RxBD[Data Length] to determine if the frame was larger than MAXFRM-2." This patch implements the first workaround option by setting HUGEFRAME bit, and gfar_clean_rx_ring() already checks the RxBD[Data Length]. Signed-off-by: Anton Vorontsov <avorontsov@mvista.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r--drivers/net/gianfar.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index c52f3712ecd3..cee8ae714731 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -85,6 +85,7 @@
85#include <linux/net_tstamp.h> 85#include <linux/net_tstamp.h>
86 86
87#include <asm/io.h> 87#include <asm/io.h>
88#include <asm/reg.h>
88#include <asm/irq.h> 89#include <asm/irq.h>
89#include <asm/uaccess.h> 90#include <asm/uaccess.h>
90#include <linux/module.h> 91#include <linux/module.h>
@@ -928,6 +929,24 @@ static void gfar_init_filer_table(struct gfar_private *priv)
928 } 929 }
929} 930}
930 931
932static void gfar_detect_errata(struct gfar_private *priv)
933{
934 struct device *dev = &priv->ofdev->dev;
935 unsigned int pvr = mfspr(SPRN_PVR);
936 unsigned int svr = mfspr(SPRN_SVR);
937 unsigned int mod = (svr >> 16) & 0xfff6; /* w/o E suffix */
938 unsigned int rev = svr & 0xffff;
939
940 /* MPC8313 Rev 2.0 and higher; All MPC837x */
941 if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) ||
942 (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
943 priv->errata |= GFAR_ERRATA_74;
944
945 if (priv->errata)
946 dev_info(dev, "enabled errata workarounds, flags: 0x%x\n",
947 priv->errata);
948}
949
931/* Set up the ethernet device structure, private data, 950/* Set up the ethernet device structure, private data,
932 * and anything else we need before we start */ 951 * and anything else we need before we start */
933static int gfar_probe(struct of_device *ofdev, 952static int gfar_probe(struct of_device *ofdev,
@@ -960,6 +979,8 @@ static int gfar_probe(struct of_device *ofdev,
960 dev_set_drvdata(&ofdev->dev, priv); 979 dev_set_drvdata(&ofdev->dev, priv);
961 regs = priv->gfargrp[0].regs; 980 regs = priv->gfargrp[0].regs;
962 981
982 gfar_detect_errata(priv);
983
963 /* Stop the DMA engine now, in case it was running before */ 984 /* Stop the DMA engine now, in case it was running before */
964 /* (The firmware could have used it, and left it running). */ 985 /* (The firmware could have used it, and left it running). */
965 gfar_halt(dev); 986 gfar_halt(dev);
@@ -974,7 +995,10 @@ static int gfar_probe(struct of_device *ofdev,
974 gfar_write(&regs->maccfg1, tempval); 995 gfar_write(&regs->maccfg1, tempval);
975 996
976 /* Initialize MACCFG2. */ 997 /* Initialize MACCFG2. */
977 gfar_write(&regs->maccfg2, MACCFG2_INIT_SETTINGS); 998 tempval = MACCFG2_INIT_SETTINGS;
999 if (gfar_has_errata(priv, GFAR_ERRATA_74))
1000 tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
1001 gfar_write(&regs->maccfg2, tempval);
978 1002
979 /* Initialize ECNTRL */ 1003 /* Initialize ECNTRL */
980 gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS); 1004 gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
@@ -2300,7 +2324,8 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
2300 * to allow huge frames, and to check the length */ 2324 * to allow huge frames, and to check the length */
2301 tempval = gfar_read(&regs->maccfg2); 2325 tempval = gfar_read(&regs->maccfg2);
2302 2326
2303 if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE) 2327 if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
2328 gfar_has_errata(priv, GFAR_ERRATA_74))
2304 tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); 2329 tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
2305 else 2330 else
2306 tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); 2331 tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);