summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/igbvf/netdev.c
diff options
context:
space:
mode:
authorMitch A Williams <mitch.a.williams@intel.com>2012-11-17 07:10:16 +0000
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-11-28 03:57:23 -0800
commit2c1a10196511a2c1af612a59aa1e5385afca0533 (patch)
tree543cfd7a73f6367e204220dc590f2b339696e663 /drivers/net/ethernet/intel/igbvf/netdev.c
parent03f52a0a554210d5049eeed9f1bb29047dc807cb (diff)
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>
Diffstat (limited to 'drivers/net/ethernet/intel/igbvf/netdev.c')
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 4051ec404613..b44b9d3d07f4 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -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)