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: Mitch Williams <mitch.a.williams@intel.com> Tested-by: Sibai Li <sibai.li@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
03f52a0a55
commit
2c1a101965
|
@ -46,6 +46,7 @@
|
|||
#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
|
||||
#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_SE 0x02000000
|
||||
#define E1000_RXDEXT_STATERR_SEQ 0x04000000
|
||||
|
|
|
@ -295,7 +295,7 @@ struct igbvf_info {
|
|||
|
||||
/* hardware capability, feature, and workaround flags */
|
||||
#define IGBVF_FLAG_RX_CSUM_DISABLED (1 << 0)
|
||||
|
||||
#define IGBVF_FLAG_RX_LB_VLAN_BSWAP (1 << 1)
|
||||
#define IGBVF_RX_DESC_ADV(R, i) \
|
||||
(&((((R).desc))[i].rx_desc))
|
||||
#define IGBVF_TX_DESC_ADV(R, i) \
|
||||
|
|
|
@ -107,12 +107,19 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter,
|
|||
struct sk_buff *skb,
|
||||
u32 status, u16 vlan)
|
||||
{
|
||||
u16 vid;
|
||||
|
||||
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))
|
||||
__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,
|
||||
|
@ -2767,6 +2774,10 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
|
|||
/* reset the hardware with the new settings */
|
||||
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");
|
||||
err = register_netdev(netdev);
|
||||
if (err)
|
||||
|
|
Loading…
Reference in New Issue