aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-09-19 18:36:42 -0400
committerJeff Garzik <jeff@garzik.org>2007-09-20 15:22:59 -0400
commitd6532232cd3de79c852685823a9c52f723816d0a (patch)
treeff6fc85a36020202709dfb915a60f6941585b9e7
parent680e9fe9d69ea86e81c859932bfd751be91cc0e0 (diff)
sky2: fix VLAN receive processing (resend)
The length check for truncated frames was not correctly handling the case where VLAN acceleration had already read the tag. Also, the Yukon EX has some features that use high bit of status as security tag. Signed-off-by: Pierre-Yves Ritschard <pyr@spootnik.org> Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/sky2.c14
-rw-r--r--drivers/net/sky2.h2
2 files changed, 14 insertions, 2 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 5d812de65d90..8b1565453f08 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2103,6 +2103,13 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
2103 struct sky2_port *sky2 = netdev_priv(dev); 2103 struct sky2_port *sky2 = netdev_priv(dev);
2104 struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next; 2104 struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
2105 struct sk_buff *skb = NULL; 2105 struct sk_buff *skb = NULL;
2106 u16 count = (status & GMR_FS_LEN) >> 16;
2107
2108#ifdef SKY2_VLAN_TAG_USED
2109 /* Account for vlan tag */
2110 if (sky2->vlgrp && (status & GMR_FS_VLAN))
2111 count -= VLAN_HLEN;
2112#endif
2106 2113
2107 if (unlikely(netif_msg_rx_status(sky2))) 2114 if (unlikely(netif_msg_rx_status(sky2)))
2108 printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", 2115 printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
@@ -2117,7 +2124,8 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
2117 if (!(status & GMR_FS_RX_OK)) 2124 if (!(status & GMR_FS_RX_OK))
2118 goto resubmit; 2125 goto resubmit;
2119 2126
2120 if (status >> 16 != length) 2127 /* if length reported by DMA does not match PHY, packet was truncated */
2128 if (length != count)
2121 goto len_mismatch; 2129 goto len_mismatch;
2122 2130
2123 if (length < copybreak) 2131 if (length < copybreak)
@@ -2133,6 +2141,10 @@ len_mismatch:
2133 /* Truncation of overlength packets 2141 /* Truncation of overlength packets
2134 causes PHY length to not match MAC length */ 2142 causes PHY length to not match MAC length */
2135 ++sky2->net_stats.rx_length_errors; 2143 ++sky2->net_stats.rx_length_errors;
2144 if (netif_msg_rx_err(sky2) && net_ratelimit())
2145 pr_info(PFX "%s: rx length mismatch: length %d status %#x\n",
2146 dev->name, length, status);
2147 goto resubmit;
2136 2148
2137error: 2149error:
2138 ++sky2->net_stats.rx_errors; 2150 ++sky2->net_stats.rx_errors;
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 72e12b7cfa40..3baae48f8042 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1668,7 +1668,7 @@ enum {
1668 1668
1669/* Receive Frame Status Encoding */ 1669/* Receive Frame Status Encoding */
1670enum { 1670enum {
1671 GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */ 1671 GMR_FS_LEN = 0x7fff<<16, /* Bit 30..16: Rx Frame Length */
1672 GMR_FS_VLAN = 1<<13, /* VLAN Packet */ 1672 GMR_FS_VLAN = 1<<13, /* VLAN Packet */
1673 GMR_FS_JABBER = 1<<12, /* Jabber Packet */ 1673 GMR_FS_JABBER = 1<<12, /* Jabber Packet */
1674 GMR_FS_UN_SIZE = 1<<11, /* Undersize Packet */ 1674 GMR_FS_UN_SIZE = 1<<11, /* Undersize Packet */