提交 2c1a1019 编写于 作者: M Mitch A Williams 提交者: Jeff Kirsher

igbvf: work around i350 erratum

On i350 VF devices, VLAN tags will be byte-swapped in the receive
descriptor only when received packets are looped back from other
VFs. Check for this condition and swab the tag if needed.
Signed-off-by: NMitch Williams <mitch.a.williams@intel.com>
Tested-by: NSibai Li <sibai.li@intel.com>
Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
上级 03f52a0a
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ #define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
#define E1000_RXDEXT_STATERR_LB 0x00040000
#define E1000_RXDEXT_STATERR_CE 0x01000000 #define E1000_RXDEXT_STATERR_CE 0x01000000
#define E1000_RXDEXT_STATERR_SE 0x02000000 #define E1000_RXDEXT_STATERR_SE 0x02000000
#define E1000_RXDEXT_STATERR_SEQ 0x04000000 #define E1000_RXDEXT_STATERR_SEQ 0x04000000
......
...@@ -295,7 +295,7 @@ struct igbvf_info { ...@@ -295,7 +295,7 @@ struct igbvf_info {
/* hardware capability, feature, and workaround flags */ /* hardware capability, feature, and workaround flags */
#define IGBVF_FLAG_RX_CSUM_DISABLED (1 << 0) #define IGBVF_FLAG_RX_CSUM_DISABLED (1 << 0)
#define IGBVF_FLAG_RX_LB_VLAN_BSWAP (1 << 1)
#define IGBVF_RX_DESC_ADV(R, i) \ #define IGBVF_RX_DESC_ADV(R, i) \
(&((((R).desc))[i].rx_desc)) (&((((R).desc))[i].rx_desc))
#define IGBVF_TX_DESC_ADV(R, i) \ #define IGBVF_TX_DESC_ADV(R, i) \
......
...@@ -107,12 +107,19 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter, ...@@ -107,12 +107,19 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter,
struct sk_buff *skb, struct sk_buff *skb,
u32 status, u16 vlan) u32 status, u16 vlan)
{ {
u16 vid;
if (status & E1000_RXD_STAT_VP) { if (status & E1000_RXD_STAT_VP) {
u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; if ((adapter->flags & IGBVF_FLAG_RX_LB_VLAN_BSWAP) &&
(status & E1000_RXDEXT_STATERR_LB))
vid = be16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
else
vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
if (test_bit(vid, adapter->active_vlans)) if (test_bit(vid, adapter->active_vlans))
__vlan_hwaccel_put_tag(skb, vid); __vlan_hwaccel_put_tag(skb, vid);
} }
netif_receive_skb(skb);
napi_gro_receive(&adapter->rx_ring->napi, skb);
} }
static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter, static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
...@@ -2767,6 +2774,10 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, ...@@ -2767,6 +2774,10 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
/* reset the hardware with the new settings */ /* reset the hardware with the new settings */
igbvf_reset(adapter); igbvf_reset(adapter);
/* set hardware-specific flags */
if (adapter->hw.mac.type == e1000_vfadapt_i350)
adapter->flags |= IGBVF_FLAG_RX_LB_VLAN_BSWAP;
strcpy(netdev->name, "eth%d"); strcpy(netdev->name, "eth%d");
err = register_netdev(netdev); err = register_netdev(netdev);
if (err) if (err)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册