diff options
author | Anton Vorontsov <avorontsov@mvista.com> | 2010-06-30 02:39:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-30 14:35:42 -0400 |
commit | 7d3509774c2ef4ffd1c5fd2fac65dc4e071a6f21 (patch) | |
tree | 54d32c6f6f6c72fee208ab8dea9879697b613765 /drivers/net/gianfar.h | |
parent | 70777d03466e7a8a41b0d34677454c92f4e93d89 (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.h')
-rw-r--r-- | drivers/net/gianfar.h | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index ac4a92e08c09..0a0483ce21d2 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -1025,6 +1025,10 @@ struct gfar_priv_grp { | |||
1025 | char int_name_er[GFAR_INT_NAME_MAX]; | 1025 | char int_name_er[GFAR_INT_NAME_MAX]; |
1026 | }; | 1026 | }; |
1027 | 1027 | ||
1028 | enum gfar_errata { | ||
1029 | GFAR_ERRATA_74 = 0x01, | ||
1030 | }; | ||
1031 | |||
1028 | /* Struct stolen almost completely (and shamelessly) from the FCC enet source | 1032 | /* Struct stolen almost completely (and shamelessly) from the FCC enet source |
1029 | * (Ok, that's not so true anymore, but there is a family resemblence) | 1033 | * (Ok, that's not so true anymore, but there is a family resemblence) |
1030 | * The GFAR buffer descriptors track the ring buffers. The rx_bd_base | 1034 | * The GFAR buffer descriptors track the ring buffers. The rx_bd_base |
@@ -1049,6 +1053,7 @@ struct gfar_private { | |||
1049 | struct device_node *node; | 1053 | struct device_node *node; |
1050 | struct net_device *ndev; | 1054 | struct net_device *ndev; |
1051 | struct of_device *ofdev; | 1055 | struct of_device *ofdev; |
1056 | enum gfar_errata errata; | ||
1052 | 1057 | ||
1053 | struct gfar_priv_grp gfargrp[MAXGROUPS]; | 1058 | struct gfar_priv_grp gfargrp[MAXGROUPS]; |
1054 | struct gfar_priv_tx_q *tx_queue[MAX_TX_QS]; | 1059 | struct gfar_priv_tx_q *tx_queue[MAX_TX_QS]; |
@@ -1111,6 +1116,12 @@ struct gfar_private { | |||
1111 | extern unsigned int ftp_rqfpr[MAX_FILER_IDX + 1]; | 1116 | extern unsigned int ftp_rqfpr[MAX_FILER_IDX + 1]; |
1112 | extern unsigned int ftp_rqfcr[MAX_FILER_IDX + 1]; | 1117 | extern unsigned int ftp_rqfcr[MAX_FILER_IDX + 1]; |
1113 | 1118 | ||
1119 | static inline int gfar_has_errata(struct gfar_private *priv, | ||
1120 | enum gfar_errata err) | ||
1121 | { | ||
1122 | return priv->errata & err; | ||
1123 | } | ||
1124 | |||
1114 | static inline u32 gfar_read(volatile unsigned __iomem *addr) | 1125 | static inline u32 gfar_read(volatile unsigned __iomem *addr) |
1115 | { | 1126 | { |
1116 | u32 val; | 1127 | u32 val; |