Skip to content

Commit

Permalink
fm10k: send traffic on default VID to VLAN device if we have one
Browse files Browse the repository at this point in the history
This patch ensures that VLAN traffic on the default VID will go to the
corresponding VLAN device if it exists. To do this, mask the rx_ring VID
if we have an active VLAN on that VID.

For this to work correctly, we need to update fm10k_process_skb_fields
to correctly mask off the VLAN_PRIO_MASK bits and compare them
separately, otherwise we incorrectly compare the priority bits with the
cleared flag. This also happens to fix a related bug where having
priority bits set causes us to incorrectly classify traffic.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <krishneil.k.singh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Jacob Keller authored and Jeff Kirsher committed Sep 16, 2015
1 parent 6fbc6b3 commit e71c931
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/fm10k/fm10k_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,11 @@ static unsigned int fm10k_process_skb_fields(struct fm10k_ring *rx_ring,
if (rx_desc->w.vlan) {
u16 vid = le16_to_cpu(rx_desc->w.vlan);

if (vid != rx_ring->vid)
if ((vid & VLAN_VID_MASK) != rx_ring->vid)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
else if (vid & VLAN_PRIO_MASK)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
vid & VLAN_PRIO_MASK);
}

fm10k_type_trans(rx_ring, rx_desc, skb);
Expand Down
12 changes: 12 additions & 0 deletions drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set)
struct fm10k_intfc *interface = netdev_priv(netdev);
struct fm10k_hw *hw = &interface->hw;
s32 err;
int i;

/* updates do not apply to VLAN 0 */
if (!vid)
Expand All @@ -775,6 +776,17 @@ static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set)
if (!set)
clear_bit(vid, interface->active_vlans);

/* disable the default VID on ring if we have an active VLAN */
for (i = 0; i < interface->num_rx_queues; i++) {
struct fm10k_ring *rx_ring = interface->rx_ring[i];
u16 rx_vid = rx_ring->vid & (VLAN_N_VID - 1);

if (test_bit(rx_vid, interface->active_vlans))
rx_ring->vid |= FM10K_VLAN_CLEAR;
else
rx_ring->vid &= ~FM10K_VLAN_CLEAR;
}

/* Do not remove default VID related entries from VLAN and MAC tables */
if (!set && vid == hw->mac.default_vid)
return 0;
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/fm10k/fm10k_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,10 @@ static void fm10k_configure_rx_ring(struct fm10k_intfc *interface,
/* assign default VLAN to queue */
ring->vid = hw->mac.default_vid;

/* if we have an active VLAN, disable default VID */
if (test_bit(hw->mac.default_vid, interface->active_vlans))
ring->vid |= FM10K_VLAN_CLEAR;

/* Map interrupt */
if (ring->q_vector) {
rxint = ring->q_vector->v_idx + NON_Q_VECTORS(hw);
Expand Down

0 comments on commit e71c931

Please sign in to comment.