From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jingjing Wu Subject: [PATCH] i40e: fix vlan filter in promiscuous mode Date: Fri, 27 May 2016 16:05:45 +0800 Message-ID: <1464336345-20529-1-git-send-email-jingjing.wu@intel.com> Cc: dev@dpdk.org, jingjing.wu@intel.com, yulong.pei@intel.com To: helin.zhang@intel.com Return-path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 0337C37B1 for ; Fri, 27 May 2016 10:05:54 +0200 (CEST) List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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