aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFrancois Romieu <romieu@fr.zoreil.com>2013-05-10 00:50:20 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-05-19 10:04:47 -0700
commite81164cfec2f578998670c8f00e5d0c33c06f20f (patch)
treeab856b742aea9e7958c6309da88f6fc27a47593c /drivers/net
parentb89396eaa22b921245b4d30f7e26e406e89aa51c (diff)
downloadkernel_samsung_smdk4412-e81164cfec2f578998670c8f00e5d0c33c06f20f.zip
kernel_samsung_smdk4412-e81164cfec2f578998670c8f00e5d0c33c06f20f.tar.gz
kernel_samsung_smdk4412-e81164cfec2f578998670c8f00e5d0c33c06f20f.tar.bz2
r8169: fix vlan tag read ordering.
commit ce11ff5e5963e441feb591e76278528f876c332d upstream. Control of receive descriptor must not be returned to ethernet chipset before vlan tag processing is done. VLAN tag receive word is now reset both in normal and error path. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Spotted-by: Timo Teras <timo.teras@iki.fi> Cc: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/r8169.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 8350f8d..bf67991 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1494,8 +1494,6 @@ static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
if (opts2 & RxVlanTag)
__vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff));
-
- desc->opts2 = 0;
}
static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -5188,7 +5186,6 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
rtl8169_schedule_work(dev, rtl8169_reset_task);
dev->stats.rx_fifo_errors++;
}
- rtl8169_mark_to_asic(desc, rx_buf_sz);
} else {
struct sk_buff *skb;
dma_addr_t addr = le64_to_cpu(desc->addr);
@@ -5202,16 +5199,14 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
if (unlikely(rtl8169_fragmented_frame(status))) {
dev->stats.rx_dropped++;
dev->stats.rx_length_errors++;
- rtl8169_mark_to_asic(desc, rx_buf_sz);
- continue;
+ goto release_descriptor;
}
skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry],
tp, pkt_size, addr);
- rtl8169_mark_to_asic(desc, rx_buf_sz);
if (!skb) {
dev->stats.rx_dropped++;
- continue;
+ goto release_descriptor;
}
rtl8169_rx_csum(skb, status);
@@ -5225,6 +5220,10 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
dev->stats.rx_bytes += pkt_size;
dev->stats.rx_packets++;
}
+release_descriptor:
+ desc->opts2 = 0;
+ wmb();
+ rtl8169_mark_to_asic(desc, rx_buf_sz);
}
count = cur_rx - tp->cur_rx;