From patchwork Tue Jun 14 02:24:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingjing Wu X-Patchwork-Id: 13591 X-Patchwork-Delegate: bruce.richardson@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id F15835A84; Tue, 14 Jun 2016 04:24:28 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id A234A5A7B for ; Tue, 14 Jun 2016 04:24:27 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP; 13 Jun 2016 19:24:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,469,1459839600"; d="scan'208";a="986850530" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga001.fm.intel.com with ESMTP; 13 Jun 2016 19:24:26 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id u5E2OOk4004535; Tue, 14 Jun 2016 10:24:24 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id u5E2OLVk020358; Tue, 14 Jun 2016 10:24:23 +0800 Received: (from wujingji@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id u5E2OLl1020354; Tue, 14 Jun 2016 10:24:21 +0800 From: Jingjing Wu To: bruce.richardson@intel.com Cc: dev@dpdk.org, jingjing.wu@intel.com, yuan.peng@intel.com, helin.zhang@intel.com Date: Tue, 14 Jun 2016 10:24:20 +0800 Message-Id: <1465871060-20324-1-git-send-email-jingjing.wu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1464336345-20529-1-git-send-email-jingjing.wu@intel.com> References: <1464336345-20529-1-git-send-email-jingjing.wu@intel.com> Subject: [dpdk-dev] [PATCH v2] i40e: fix VLAN filter in promiscuous mode X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list 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. So in promiscuous mode, the VSI can receive packets if they don't match any entry in MAC VLAN table, even their VLAN tags are unknown. According to l2 filtering and VEB Switching algorithm on X710/XL710, VLAN table can be used to filtering VLAN by: - Clear promiscuous VLAN flag on VSI. - Program VLAN table to enable it. This patch adds the promiscuous VLAN flag setting/clearing and VLAN programming when VLAN filtering is added/removed without any change on MAC VLAN table. Fixes: 4861cde46116 ("i40e: new poll mode driver") Signed-off-by: Jingjing Wu --- v2 change: - commit log reword. 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; + } } /**