sky2: fix receive length error in mixed non-VLAN/VLAN traffic (Closes: #492853)
svn path=/dists/sid/linux-2.6/; revision=18992
This commit is contained in:
parent
79fb5c5107
commit
49bfc8e1cb
|
@ -8,6 +8,8 @@ linux-2.6 (3.2.17-1) UNRELEASED; urgency=low
|
||||||
* ext4: Report max_batch_time option correctly (Closes: #654206)
|
* ext4: Report max_batch_time option correctly (Closes: #654206)
|
||||||
* [i386/rt-686-pae] Enable HIGHMEM64G as intended for this configuration
|
* [i386/rt-686-pae] Enable HIGHMEM64G as intended for this configuration
|
||||||
* NFSv4: Revalidate uid/gid after open (Closes: #659111)
|
* NFSv4: Revalidate uid/gid after open (Closes: #659111)
|
||||||
|
* sky2: fix receive length error in mixed non-VLAN/VLAN traffic
|
||||||
|
(Closes: #492853)
|
||||||
|
|
||||||
[ Bastian Blank ]
|
[ Bastian Blank ]
|
||||||
* [s390] Enable IUCV special message support. (closes: #671238)
|
* [s390] Enable IUCV special message support. (closes: #671238)
|
||||||
|
|
137
debian/patches/bugfix/all/sky2-fix-receive-length-error-in-mixed-non-vlan-vlan.patch
vendored
Normal file
137
debian/patches/bugfix/all/sky2-fix-receive-length-error-in-mixed-non-vlan-vlan.patch
vendored
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
From dc7296f6dc82ac546b5006dcfff1b16967b6c234 Mon Sep 17 00:00:00 2001
|
||||||
|
From: stephen hemminger <shemminger@vyatta.com>
|
||||||
|
Date: Mon, 30 Apr 2012 06:47:37 +0000
|
||||||
|
Subject: [PATCH 06/10] sky2: fix receive length error in mixed non-VLAN/VLAN
|
||||||
|
traffic
|
||||||
|
|
||||||
|
[ Upstream commit e072b3fad5f3915102c94628b4971f52ff99dd05 ]
|
||||||
|
|
||||||
|
Bug: The VLAN bit of the MAC RX Status Word is unreliable in several older
|
||||||
|
supported chips. Sometimes the VLAN bit is not set for valid VLAN packets
|
||||||
|
and also sometimes the VLAN bit is set for non-VLAN packets that came after
|
||||||
|
a VLAN packet. This results in a receive length error when VLAN hardware
|
||||||
|
tagging is enabled.
|
||||||
|
|
||||||
|
Fix: Variation on original fix proposed by Mirko.
|
||||||
|
The VLAN information is decoded in the status loop, and can be
|
||||||
|
applied to the received SKB there. This eliminates the need for the
|
||||||
|
separate tag field in the interface data structure. The tag has to
|
||||||
|
be copied and cleared if packet is copied. This version checked out
|
||||||
|
with vlan and normal traffic.
|
||||||
|
|
||||||
|
Note: vlan_tx_tag_present should be renamed vlan_tag_present, but that
|
||||||
|
is outside scope of this.
|
||||||
|
|
||||||
|
Reported-by: Mirko Lindner <mlindner@marvell.com>
|
||||||
|
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/marvell/sky2.c | 28 +++++++++++++++++-----------
|
||||||
|
drivers/net/ethernet/marvell/sky2.h | 1 -
|
||||||
|
2 files changed, 17 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
|
||||||
|
index e1f4b65..65c51ff 100644
|
||||||
|
--- a/drivers/net/ethernet/marvell/sky2.c
|
||||||
|
+++ b/drivers/net/ethernet/marvell/sky2.c
|
||||||
|
@@ -2476,9 +2476,11 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
|
||||||
|
skb->ip_summed = re->skb->ip_summed;
|
||||||
|
skb->csum = re->skb->csum;
|
||||||
|
skb->rxhash = re->skb->rxhash;
|
||||||
|
+ skb->vlan_tci = re->skb->vlan_tci;
|
||||||
|
|
||||||
|
pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
|
||||||
|
length, PCI_DMA_FROMDEVICE);
|
||||||
|
+ re->skb->vlan_tci = 0;
|
||||||
|
re->skb->rxhash = 0;
|
||||||
|
re->skb->ip_summed = CHECKSUM_NONE;
|
||||||
|
skb_put(skb, length);
|
||||||
|
@@ -2564,9 +2566,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
|
||||||
|
struct sk_buff *skb = NULL;
|
||||||
|
u16 count = (status & GMR_FS_LEN) >> 16;
|
||||||
|
|
||||||
|
- if (status & GMR_FS_VLAN)
|
||||||
|
- count -= VLAN_HLEN; /* Account for vlan tag */
|
||||||
|
-
|
||||||
|
netif_printk(sky2, rx_status, KERN_DEBUG, dev,
|
||||||
|
"rx slot %u status 0x%x len %d\n",
|
||||||
|
sky2->rx_next, status, length);
|
||||||
|
@@ -2574,6 +2573,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
|
||||||
|
sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
|
||||||
|
prefetch(sky2->rx_ring + sky2->rx_next);
|
||||||
|
|
||||||
|
+ if (vlan_tx_tag_present(re->skb))
|
||||||
|
+ count -= VLAN_HLEN; /* Account for vlan tag */
|
||||||
|
+
|
||||||
|
/* This chip has hardware problems that generates bogus status.
|
||||||
|
* So do only marginal checking and expect higher level protocols
|
||||||
|
* to handle crap frames.
|
||||||
|
@@ -2631,11 +2633,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sky2_skb_rx(const struct sky2_port *sky2,
|
||||||
|
- u32 status, struct sk_buff *skb)
|
||||||
|
+ struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
- if (status & GMR_FS_VLAN)
|
||||||
|
- __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
|
||||||
|
-
|
||||||
|
if (skb->ip_summed == CHECKSUM_NONE)
|
||||||
|
netif_receive_skb(skb);
|
||||||
|
else
|
||||||
|
@@ -2689,6 +2688,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void sky2_rx_tag(struct sky2_port *sky2, u16 length)
|
||||||
|
+{
|
||||||
|
+ struct sk_buff *skb;
|
||||||
|
+
|
||||||
|
+ skb = sky2->rx_ring[sky2->rx_next].skb;
|
||||||
|
+ __vlan_hwaccel_put_tag(skb, be16_to_cpu(length));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void sky2_rx_hash(struct sky2_port *sky2, u32 status)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
@@ -2747,8 +2754,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
skb->protocol = eth_type_trans(skb, dev);
|
||||||
|
-
|
||||||
|
- sky2_skb_rx(sky2, status, skb);
|
||||||
|
+ sky2_skb_rx(sky2, skb);
|
||||||
|
|
||||||
|
/* Stop after net poll weight */
|
||||||
|
if (++work_done >= to_do)
|
||||||
|
@@ -2756,11 +2762,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_RXVLAN:
|
||||||
|
- sky2->rx_tag = length;
|
||||||
|
+ sky2_rx_tag(sky2, length);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_RXCHKSVLAN:
|
||||||
|
- sky2->rx_tag = length;
|
||||||
|
+ sky2_rx_tag(sky2, length);
|
||||||
|
/* fall through */
|
||||||
|
case OP_RXCHKS:
|
||||||
|
if (likely(dev->features & NETIF_F_RXCSUM))
|
||||||
|
diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h
|
||||||
|
index ff6f58b..3c896ce 100644
|
||||||
|
--- a/drivers/net/ethernet/marvell/sky2.h
|
||||||
|
+++ b/drivers/net/ethernet/marvell/sky2.h
|
||||||
|
@@ -2241,7 +2241,6 @@ struct sky2_port {
|
||||||
|
u16 rx_pending;
|
||||||
|
u16 rx_data_size;
|
||||||
|
u16 rx_nfrags;
|
||||||
|
- u16 rx_tag;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned long last;
|
||||||
|
--
|
||||||
|
1.7.10.1
|
||||||
|
|
||||||
|
|
|
@ -193,3 +193,4 @@
|
||||||
+ bugfix/all/ext4-Report-max_batch_time-option-correctly.patch
|
+ bugfix/all/ext4-Report-max_batch_time-option-correctly.patch
|
||||||
+ bugfix/all/brcm80211-smac-pass-missing-argument-to-brcms_b_mute.patch
|
+ bugfix/all/brcm80211-smac-pass-missing-argument-to-brcms_b_mute.patch
|
||||||
+ bugfix/all/nfsv4-revalidate-uid-gid-after-open.patch
|
+ bugfix/all/nfsv4-revalidate-uid-gid-after-open.patch
|
||||||
|
+ bugfix/all/sky2-fix-receive-length-error-in-mixed-non-vlan-vlan.patch
|
||||||
|
|
Loading…
Reference in New Issue