From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 38198A059F; Fri, 10 Apr 2020 13:11:23 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3478F1D534; Fri, 10 Apr 2020 13:10:14 +0200 (CEST) Received: from mail.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id 63F101D421 for ; Fri, 10 Apr 2020 13:10:10 +0200 (CEST) Received: from localhost.localdomain (114.119.4.74) by INCCAS002.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Fri, 10 Apr 2020 19:09:44 +0800 From: "Wei Hu (Xavier)" To: Date: Fri, 10 Apr 2020 19:09:30 +0800 Message-ID: <20200410110930.15717-10-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200410110930.15717-1-huwei013@chinasoftinc.com> References: <20200410110930.15717-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [114.119.4.74] Subject: [dpdk-dev] [PATCH 9/9] net/hns3: fix VLAN filter when setting promisucous mode X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Chengchang Tang Currently, when upper level application call the API function named rte_eth_dev_set_vlan_offload to configure the hardware vlan filter offload and call the rte_eth_promiscuous_enable API to enable promiscuous mode based on hns3 PF device, driver can't receive the packets with a vlan tag which has not been added by calling the API function named rte_eth_dev_vlan_filter. This patch fixes it by disabling the vlan filter when setting the promiscuous mode and enabling the vlan filter again after the promiscuous mode are disabled. Fixes: 19a3ca4c99cf ("net/hns3: add start/stop and configure operations") Cc: stable@dpdk.org Signed-off-by: Chengchang Tang Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_ethdev.c | 119 +++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 28 deletions(-) diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index b7601455c..037ca4604 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -607,16 +607,19 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask) rxmode = &dev->data->dev_conf.rxmode; tmp_mask = (unsigned int)mask; if (tmp_mask & ETH_VLAN_FILTER_MASK) { - /* Enable or disable VLAN filter */ - enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? - true : false; + /* ignore vlan filter configuration during promiscuous mode */ + if (!dev->data->promiscuous) { + /* Enable or disable VLAN filter */ + enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? + true : false; - ret = hns3_enable_vlan_filter(hns, enable); - if (ret) { - rte_spinlock_unlock(&hw->lock); - hns3_err(hw, "failed to %s rx filter, ret = %d", - enable ? "enable" : "disable", ret); - return ret; + ret = hns3_enable_vlan_filter(hns, enable); + if (ret) { + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "failed to %s rx filter, ret = %d", + enable ? "enable" : "disable", ret); + return ret; + } } } @@ -1002,14 +1005,16 @@ hns3_restore_vlan_conf(struct hns3_adapter *hns) bool enable; int ret; - /* restore vlan filter states */ - offloads = hw->data->dev_conf.rxmode.offloads; - enable = offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? true : false; - ret = hns3_enable_vlan_filter(hns, enable); - if (ret) { - hns3_err(hw, "failed to restore vlan rx filter conf, ret = %d", - ret); - return ret; + if (!hw->data->promiscuous) { + /* restore vlan filter states */ + offloads = hw->data->dev_conf.rxmode.offloads; + enable = offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? true : false; + ret = hns3_enable_vlan_filter(hns, enable); + if (ret) { + hns3_err(hw, "failed to restore vlan rx filter conf, " + "ret = %d", ret); + return ret; + } } ret = hns3_set_vlan_rx_offload_cfg(hns, &pf->vtag_config.rx_vcfg); @@ -3830,16 +3835,43 @@ hns3_clear_all_vfs_promisc_mode(struct hns3_hw *hw) static int hns3_dev_promiscuous_enable(struct rte_eth_dev *dev) { + bool allmulti = dev->data->all_multicast ? true : false; struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; + uint64_t offloads; + int err; int ret; rte_spinlock_lock(&hw->lock); ret = hns3_set_promisc_mode(hw, true, true); - rte_spinlock_unlock(&hw->lock); - if (ret) - hns3_err(hw, "Failed to enable promiscuous mode, ret = %d", + if (ret) { + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "failed to enable promiscuous mode, ret = %d", ret); + return ret; + } + + /* + * When promiscuous mode was enabled, disable the vlan filter to let + * all packets coming in in the receiving direction. + */ + offloads = dev->data->dev_conf.rxmode.offloads; + if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { + ret = hns3_enable_vlan_filter(hns, false); + if (ret) { + hns3_err(hw, "failed to enable promiscuous mode due to " + "failure to disable vlan filter, ret = %d", + ret); + err = hns3_set_promisc_mode(hw, false, allmulti); + if (err) + hns3_err(hw, "failed to restore promiscuous " + "status after disable vlan filter " + "failed during enabling promiscuous " + "mode, ret = %d", ret); + } + } + + rte_spinlock_unlock(&hw->lock); return ret; } @@ -3850,15 +3882,36 @@ hns3_dev_promiscuous_disable(struct rte_eth_dev *dev) bool allmulti = dev->data->all_multicast ? true : false; struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; + uint64_t offloads; + int err; int ret; /* If now in all_multicast mode, must remain in all_multicast mode. */ rte_spinlock_lock(&hw->lock); ret = hns3_set_promisc_mode(hw, false, allmulti); - rte_spinlock_unlock(&hw->lock); - if (ret) - hns3_err(hw, "Failed to disable promiscuous mode, ret = %d", + if (ret) { + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "failed to disable promiscuous mode, ret = %d", ret); + return ret; + } + /* when promiscuous mode was disabled, restore the vlan filter status */ + offloads = dev->data->dev_conf.rxmode.offloads; + if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { + ret = hns3_enable_vlan_filter(hns, true); + if (ret) { + hns3_err(hw, "failed to disable promiscuous mode due to" + " failure to restore vlan filter, ret = %d", + ret); + err = hns3_set_promisc_mode(hw, true, true); + if (err) + hns3_err(hw, "failed to restore promiscuous " + "status after enabling vlan filter " + "failed during disabling promiscuous " + "mode, ret = %d", ret); + } + } + rte_spinlock_unlock(&hw->lock); return ret; } @@ -3877,7 +3930,7 @@ hns3_dev_allmulticast_enable(struct rte_eth_dev *dev) ret = hns3_set_promisc_mode(hw, false, true); rte_spinlock_unlock(&hw->lock); if (ret) - hns3_err(hw, "Failed to enable allmulticast mode, ret = %d", + hns3_err(hw, "failed to enable allmulticast mode, ret = %d", ret); return ret; @@ -3898,7 +3951,7 @@ hns3_dev_allmulticast_disable(struct rte_eth_dev *dev) ret = hns3_set_promisc_mode(hw, false, false); rte_spinlock_unlock(&hw->lock); if (ret) - hns3_err(hw, "Failed to disable allmulticast mode, ret = %d", + hns3_err(hw, "failed to disable allmulticast mode, ret = %d", ret); return ret; @@ -3909,11 +3962,21 @@ hns3_dev_promisc_restore(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; bool allmulti = hw->data->all_multicast ? true : false; + int ret; - if (hw->data->promiscuous) - return hns3_set_promisc_mode(hw, true, true); + if (hw->data->promiscuous) { + ret = hns3_set_promisc_mode(hw, true, true); + if (ret) + hns3_err(hw, "failed to restore promiscuous mode, " + "ret = %d", ret); + return ret; + } - return hns3_set_promisc_mode(hw, false, allmulti); + ret = hns3_set_promisc_mode(hw, false, allmulti); + if (ret) + hns3_err(hw, "failed to restore allmulticast mode, ret = %d", + ret); + return ret; } static int -- 2.23.0