diff options
Diffstat (limited to 'drivers/net/ixgb/ixgb_main.c')
-rw-r--r-- | drivers/net/ixgb/ixgb_main.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 211a1694667e..2e98506d12e3 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -98,6 +98,8 @@ static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int); static void ixgb_tx_timeout(struct net_device *dev); static void ixgb_tx_timeout_task(struct work_struct *work); +static void ixgb_vlan_strip_enable(struct ixgb_adapter *adapter); +static void ixgb_vlan_strip_disable(struct ixgb_adapter *adapter); static void ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid); @@ -1076,6 +1078,8 @@ ixgb_set_multi(struct net_device *netdev) if (netdev->flags & IFF_PROMISC) { rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE); + /* disable VLAN filtering */ + rctl &= ~IXGB_RCTL_CFIEN; rctl &= ~IXGB_RCTL_VFE; } else { if (netdev->flags & IFF_ALLMULTI) { @@ -1084,7 +1088,9 @@ ixgb_set_multi(struct net_device *netdev) } else { rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE); } + /* enable VLAN filtering */ rctl |= IXGB_RCTL_VFE; + rctl &= ~IXGB_RCTL_CFIEN; } if (netdev_mc_count(netdev) > IXGB_MAX_NUM_MULTICAST_ADDRESSES) { @@ -1103,6 +1109,12 @@ ixgb_set_multi(struct net_device *netdev) ixgb_mc_addr_list_update(hw, mta, netdev_mc_count(netdev), 0); } + + if (netdev->features & NETIF_F_HW_VLAN_RX) + ixgb_vlan_strip_enable(adapter); + else + ixgb_vlan_strip_disable(adapter); + } /** @@ -2150,33 +2162,30 @@ static void ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { struct ixgb_adapter *adapter = netdev_priv(netdev); - u32 ctrl, rctl; - ixgb_irq_disable(adapter); adapter->vlgrp = grp; +} - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); - ctrl |= IXGB_CTRL0_VME; - IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); - - /* enable VLAN receive filtering */ +static void +ixgb_vlan_strip_enable(struct ixgb_adapter *adapter) +{ + u32 ctrl; - rctl = IXGB_READ_REG(&adapter->hw, RCTL); - rctl &= ~IXGB_RCTL_CFIEN; - IXGB_WRITE_REG(&adapter->hw, RCTL, rctl); - } else { - /* disable VLAN tag insert/strip */ + /* enable VLAN tag insert/strip */ + ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); + ctrl |= IXGB_CTRL0_VME; + IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); +} - ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); - ctrl &= ~IXGB_CTRL0_VME; - IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); - } +static void +ixgb_vlan_strip_disable(struct ixgb_adapter *adapter) +{ + u32 ctrl; - /* don't enable interrupts unless we are UP */ - if (adapter->netdev->flags & IFF_UP) - ixgb_irq_enable(adapter); + /* disable VLAN tag insert/strip */ + ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); + ctrl &= ~IXGB_CTRL0_VME; + IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); } static void |