|
@@ -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
|