[dpdk-dev] [PATCH] i40e: fix vlan filter in promiscuous mode

Jingjing Wu jingjing.wu at intel.com
Fri May 27 10:05:45 CEST 2016


Vlan filter didn't work if promiscuous mode is enabled. That is
because i40e driver uses MAC VLAN table for the l2 filtering and
internal switch. And the vlan table is disabled by default, till
the first time to add rule in vlan table.
This patch fixed this issue to enable vlan filter by using vlan table.

Fixes: 4861cde46116 (i40e: new poll mode driver)
Signed-off-by: Jingjing Wu <jingjing.wu at intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24777d5..0d91e29 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2443,12 +2443,16 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	if (mask & ETH_VLAN_FILTER_MASK) {
-		if (dev->data->dev_conf.rxmode.hw_vlan_filter)
+		if (dev->data->dev_conf.rxmode.hw_vlan_filter) {
+			i40e_aq_set_vsi_vlan_promisc(hw, vsi->seid, false, NULL);
 			i40e_vsi_config_vlan_filter(vsi, TRUE);
-		else
+		} else {
+			i40e_aq_set_vsi_vlan_promisc(hw, vsi->seid, true, NULL);
 			i40e_vsi_config_vlan_filter(vsi, FALSE);
+		}
 	}
 
 	if (mask & ETH_VLAN_STRIP_MASK) {
@@ -5419,17 +5423,28 @@ i40e_set_vlan_filter(struct i40e_vsi *vsi,
 			 uint16_t vlan_id, bool on)
 {
 	uint32_t vid_idx, vid_bit;
+	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+	struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
+	int ret;
 
 	if (vlan_id > ETH_VLAN_ID_MAX)
 		return;
 
 	vid_idx = I40E_VFTA_IDX(vlan_id);
 	vid_bit = I40E_VFTA_BIT(vlan_id);
+	vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
 
-	if (on)
+	if (on) {
+		ret = i40e_aq_add_vlan(hw, vsi->seid, &vlan_data, 1, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to add vlan filter");
 		vsi->vfta[vid_idx] |= vid_bit;
-	else
+	} else {
+		ret = i40e_aq_remove_vlan(hw, vsi->seid, &vlan_data, 1, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to remove vlan filter");
 		vsi->vfta[vid_idx] &= ~vid_bit;
+	}
 }
 
 /**
-- 
2.4.0



More information about the dev mailing list