aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2010-07-26 20:09:47 -0400
committerDavid S. Miller <davem@davemloft.net>2010-07-27 23:43:50 -0400
commit3eeb29972b1139f733f7269def527900729f4cc7 (patch)
tree7189feaee380e0921c65935879e65030b01d9560 /drivers/net
parentca09c9760101b607cd2282c45b342655e26fa683 (diff)
stmmac: fix automatic PAD/FCS stripping
For Simple Ethernet frames (802.2 and 802.3) the GMAC Core never strips pad and fcs. This means the ACS has no effect on IPv4/6 frames. The FL bits, in the RDES0, include the FCS so the driver has to remove it in SW. For 802.3 frame format with LLC or LLC-SNAP, when set the ACS bit, the HW strips both PAD and FCS. The FL bits, in the RDES0, actually represents the frame length already stripped. This patch fixes this logic within the device driver that erroneously removed 4byte from 802.3 frames already stripped corrupting the payload. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/stmmac/common.h1
-rw-r--r--drivers/net/stmmac/dwmac1000.h2
-rw-r--r--drivers/net/stmmac/enh_desc.c2
-rw-r--r--drivers/net/stmmac/stmmac_main.c8
4 files changed, 9 insertions, 4 deletions
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index 144f76fd3e39..66b9da0260fe 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -108,6 +108,7 @@ enum rx_frame_status { /* IPC status */
108 good_frame = 0, 108 good_frame = 0,
109 discard_frame = 1, 109 discard_frame = 1,
110 csum_none = 2, 110 csum_none = 2,
111 llc_snap = 4,
111}; 112};
112 113
113enum tx_dma_irq_status { 114enum tx_dma_irq_status {
diff --git a/drivers/net/stmmac/dwmac1000.h b/drivers/net/stmmac/dwmac1000.h
index d8d0f3553770..8b20b19971cb 100644
--- a/drivers/net/stmmac/dwmac1000.h
+++ b/drivers/net/stmmac/dwmac1000.h
@@ -93,7 +93,7 @@ enum inter_frame_gap {
93#define GMAC_CONTROL_IPC 0x00000400 /* Checksum Offload */ 93#define GMAC_CONTROL_IPC 0x00000400 /* Checksum Offload */
94#define GMAC_CONTROL_DR 0x00000200 /* Disable Retry */ 94#define GMAC_CONTROL_DR 0x00000200 /* Disable Retry */
95#define GMAC_CONTROL_LUD 0x00000100 /* Link up/down */ 95#define GMAC_CONTROL_LUD 0x00000100 /* Link up/down */
96#define GMAC_CONTROL_ACS 0x00000080 /* Automatic Pad Stripping */ 96#define GMAC_CONTROL_ACS 0x00000080 /* Automatic Pad/FCS Stripping */
97#define GMAC_CONTROL_DC 0x00000010 /* Deferral Check */ 97#define GMAC_CONTROL_DC 0x00000010 /* Deferral Check */
98#define GMAC_CONTROL_TE 0x00000008 /* Transmitter Enable */ 98#define GMAC_CONTROL_TE 0x00000008 /* Transmitter Enable */
99#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */ 99#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */
diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c
index 3c18ebece043..f612f986a7e1 100644
--- a/drivers/net/stmmac/enh_desc.c
+++ b/drivers/net/stmmac/enh_desc.c
@@ -123,7 +123,7 @@ static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err)
123 */ 123 */
124 if (status == 0x0) { 124 if (status == 0x0) {
125 CHIP_DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n"); 125 CHIP_DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
126 ret = good_frame; 126 ret = llc_snap;
127 } else if (status == 0x4) { 127 } else if (status == 0x4) {
128 CHIP_DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n"); 128 CHIP_DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
129 ret = good_frame; 129 ret = good_frame;
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 1083334ccd21..bbb7951b9c4c 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -1216,9 +1216,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
1216 priv->dev->stats.rx_errors++; 1216 priv->dev->stats.rx_errors++;
1217 else { 1217 else {
1218 struct sk_buff *skb; 1218 struct sk_buff *skb;
1219 /* Length should omit the CRC */ 1219 int frame_len;
1220 int frame_len = priv->hw->desc->get_rx_frame_len(p) - 4;
1221 1220
1221 frame_len = priv->hw->desc->get_rx_frame_len(p);
1222 /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
1223 * Type frames (LLC/LLC-SNAP) */
1224 if (unlikely(status != llc_snap))
1225 frame_len -= ETH_FCS_LEN;
1222#ifdef STMMAC_RX_DEBUG 1226#ifdef STMMAC_RX_DEBUG
1223 if (frame_len > ETH_FRAME_LEN) 1227 if (frame_len > ETH_FRAME_LEN)
1224 pr_debug("\tRX frame size %d, COE status: %d\n", 1228 pr_debug("\tRX frame size %d, COE status: %d\n",