Skip to content

Commit

Permalink
ixgbe: fix bug with vlan strip in promsic mode
Browse files Browse the repository at this point in the history
The ixgbe driver was setting up 82598 hardware correctly, so that
when promiscuous mode was enabled hardware stripping was turned
off.  But on 82599 the logic to disable/enable hardware stripping
is different, and the code was not updated correctly when the
hardware vlan stripping was enabled as default.

This change comprises the creation of two new helper functions
and calling them from the right locations to disable and enable
hardware stripping of vlan tags at appropriate times.

Signed-off-by: Jesse Brandeburg <[email protected]>
Signed-off-by: Jeff Kirsher <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
jbrandeb authored and davem330 committed Apr 14, 2010
1 parent e743d31 commit 5f6c018
Showing 1 changed file with 72 additions and 43 deletions.
115 changes: 72 additions & 43 deletions drivers/net/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2482,12 +2482,74 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false);
}

/**
* ixgbe_vlan_filter_disable - helper to disable hw vlan filtering
* @adapter: driver data
*/
static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
int i, j;

switch (hw->mac.type) {
case ixgbe_mac_82598EB:
vlnctrl &= ~(IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE);
vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
break;
case ixgbe_mac_82599EB:
vlnctrl &= ~IXGBE_VLNCTRL_VFE;
vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i]->reg_idx;
vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
vlnctrl &= ~IXGBE_RXDCTL_VME;
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
}
break;
default:
break;
}
}

/**
* ixgbe_vlan_filter_enable - helper to enable hw vlan filtering
* @adapter: driver data
*/
static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
int i, j;

switch (hw->mac.type) {
case ixgbe_mac_82598EB:
vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
break;
case ixgbe_mac_82599EB:
vlnctrl |= IXGBE_VLNCTRL_VFE;
vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i]->reg_idx;
vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
vlnctrl |= IXGBE_RXDCTL_VME;
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
}
break;
default:
break;
}
}

static void ixgbe_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
u32 ctrl;
int i, j;

if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_disable(adapter);
Expand All @@ -2498,25 +2560,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
* still receive traffic from a DCB-enabled host even if we're
* not in DCB mode.
*/
ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);

/* Disable CFI check */
ctrl &= ~IXGBE_VLNCTRL_CFIEN;

/* enable VLAN tag stripping */
if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
ctrl |= IXGBE_VLNCTRL_VME;
} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
for (i = 0; i < adapter->num_rx_queues; i++) {
u32 ctrl;
j = adapter->rx_ring[i]->reg_idx;
ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(j));
ctrl |= IXGBE_RXDCTL_VME;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(j), ctrl);
}
}

IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
ixgbe_vlan_filter_enable(adapter);

ixgbe_vlan_rx_add_vid(netdev, 0);

Expand Down Expand Up @@ -2551,30 +2595,29 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
u32 fctrl, vlnctrl;
u32 fctrl;

/* Check for Promiscuous and All Multicast modes */

fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);

if (netdev->flags & IFF_PROMISC) {
hw->addr_ctrl.user_set_promisc = 1;
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
vlnctrl &= ~IXGBE_VLNCTRL_VFE;
/* don't hardware filter vlans in promisc mode */
ixgbe_vlan_filter_disable(adapter);
} else {
if (netdev->flags & IFF_ALLMULTI) {
fctrl |= IXGBE_FCTRL_MPE;
fctrl &= ~IXGBE_FCTRL_UPE;
} else {
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
}
vlnctrl |= IXGBE_VLNCTRL_VFE;
ixgbe_vlan_filter_enable(adapter);
hw->addr_ctrl.user_set_promisc = 0;
}

IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);

/* reprogram secondary unicast list */
hw->mac.ops.update_uc_addr_list(hw, netdev);
Expand Down Expand Up @@ -2641,7 +2684,7 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 txdctl, vlnctrl;
u32 txdctl;
int i, j;

ixgbe_dcb_check_config(&adapter->dcb_cfg);
Expand All @@ -2659,22 +2702,8 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
}
/* Enable VLAN tag insert/strip */
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
if (hw->mac.type == ixgbe_mac_82598EB) {
vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
} else if (hw->mac.type == ixgbe_mac_82599EB) {
vlnctrl |= IXGBE_VLNCTRL_VFE;
vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i]->reg_idx;
vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
vlnctrl |= IXGBE_RXDCTL_VME;
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
}
}
ixgbe_vlan_filter_enable(adapter);

hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
}

Expand Down

0 comments on commit 5f6c018

Please sign in to comment.