|
@@ -3589,6 +3589,28 @@ static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static inline void igb_set_vf_vlan_strip(struct igb_adapter *adapter,
|
|
|
+ int vfn, bool enable)
|
|
|
+{
|
|
|
+ struct e1000_hw *hw = &adapter->hw;
|
|
|
+ u32 val, reg;
|
|
|
+
|
|
|
+ if (hw->mac.type < e1000_82576)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (hw->mac.type == e1000_i350)
|
|
|
+ reg = E1000_DVMOLR(vfn);
|
|
|
+ else
|
|
|
+ reg = E1000_VMOLR(vfn);
|
|
|
+
|
|
|
+ val = rd32(reg);
|
|
|
+ if (enable)
|
|
|
+ val |= E1000_VMOLR_STRVLAN;
|
|
|
+ else
|
|
|
+ val &= ~(E1000_VMOLR_STRVLAN);
|
|
|
+ wr32(reg, val);
|
|
|
+}
|
|
|
+
|
|
|
static inline void igb_set_vmolr(struct igb_adapter *adapter,
|
|
|
int vfn, bool aupe)
|
|
|
{
|
|
@@ -3602,14 +3624,6 @@ static inline void igb_set_vmolr(struct igb_adapter *adapter,
|
|
|
return;
|
|
|
|
|
|
vmolr = rd32(E1000_VMOLR(vfn));
|
|
|
- vmolr |= E1000_VMOLR_STRVLAN; /* Strip vlan tags */
|
|
|
- if (hw->mac.type == e1000_i350) {
|
|
|
- u32 dvmolr;
|
|
|
-
|
|
|
- dvmolr = rd32(E1000_DVMOLR(vfn));
|
|
|
- dvmolr |= E1000_DVMOLR_STRVLAN;
|
|
|
- wr32(E1000_DVMOLR(vfn), dvmolr);
|
|
|
- }
|
|
|
if (aupe)
|
|
|
vmolr |= E1000_VMOLR_AUPE; /* Accept untagged packets */
|
|
|
else
|
|
@@ -6099,6 +6113,7 @@ static int igb_enable_port_vlan(struct igb_adapter *adapter, int vf,
|
|
|
|
|
|
adapter->vf_data[vf].pf_vlan = vlan;
|
|
|
adapter->vf_data[vf].pf_qos = qos;
|
|
|
+ igb_set_vf_vlan_strip(adapter, vf, true);
|
|
|
dev_info(&adapter->pdev->dev,
|
|
|
"Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf);
|
|
|
if (test_bit(__IGB_DOWN, &adapter->state)) {
|
|
@@ -6126,6 +6141,7 @@ static int igb_disable_port_vlan(struct igb_adapter *adapter, int vf)
|
|
|
|
|
|
adapter->vf_data[vf].pf_vlan = 0;
|
|
|
adapter->vf_data[vf].pf_qos = 0;
|
|
|
+ igb_set_vf_vlan_strip(adapter, vf, false);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -6146,6 +6162,7 @@ static int igb_set_vf_vlan_msg(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
|
|
|
{
|
|
|
int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
|
|
|
int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
|
|
|
+ int ret;
|
|
|
|
|
|
if (adapter->vf_data[vf].pf_vlan)
|
|
|
return -1;
|
|
@@ -6154,7 +6171,10 @@ static int igb_set_vf_vlan_msg(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
|
|
|
if (!vid && !add)
|
|
|
return 0;
|
|
|
|
|
|
- return igb_set_vf_vlan(adapter, vid, !!add, vf);
|
|
|
+ ret = igb_set_vf_vlan(adapter, vid, !!add, vf);
|
|
|
+ if (!ret)
|
|
|
+ igb_set_vf_vlan_strip(adapter, vf, !!vid);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
|
|
@@ -6171,6 +6191,7 @@ static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
|
|
|
igb_set_vmvir(adapter, vf_data->pf_vlan |
|
|
|
(vf_data->pf_qos << VLAN_PRIO_SHIFT), vf);
|
|
|
igb_set_vmolr(adapter, vf, !vf_data->pf_vlan);
|
|
|
+ igb_set_vf_vlan_strip(adapter, vf, !!(vf_data->pf_vlan));
|
|
|
|
|
|
/* reset multicast table array for vf */
|
|
|
adapter->vf_data[vf].num_vf_mc_hashes = 0;
|
|
@@ -7323,6 +7344,8 @@ static void igb_vlan_mode(struct net_device *netdev, netdev_features_t features)
|
|
|
ctrl &= ~E1000_CTRL_VME;
|
|
|
wr32(E1000_CTRL, ctrl);
|
|
|
}
|
|
|
+
|
|
|
+ igb_set_vf_vlan_strip(adapter, adapter->vfs_allocated_count, enable);
|
|
|
}
|
|
|
|
|
|
static int igb_vlan_rx_add_vid(struct net_device *netdev,
|