net/hns3: fix default VLAN filter configuration for PF
authorChengchang Tang <tangchengchang@huawei.com>
Fri, 10 Apr 2020 11:09:29 +0000 (19:09 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 21 Apr 2020 11:57:07 +0000 (13:57 +0200)
Currently, By default VLAN filter is enabled during initialization and
couldn't be turned off based on hns3 PF device. If upper applications
don't call rte_eth_dev_vlan_filter API function to set vlan based on
hns3 PF device, hns3 PF PMD driver will can't receive the packets with
vlan tag.  It will leads to some compatibility issues, the behaviors of
using hns3 network engine and other NICs are different.

This patch disables the VLAN filter during initialization and allows the
upper level applications to enable or disable the VLAN filter.

Fixes: 411d23b9eafb ("net/hns3: support VLAN")
Cc: stable@dpdk.org
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
drivers/net/hns3/hns3_ethdev.c

index 0b8fa0e..bab4312 100644 (file)
@@ -558,7 +558,7 @@ hns3_set_vlan_filter_ctrl(struct hns3_hw *hw, uint8_t vlan_type,
 }
 
 static int
-hns3_enable_vlan_filter(struct hns3_adapter *hns, bool enable)
+hns3_vlan_filter_init(struct hns3_adapter *hns)
 {
        struct hns3_hw *hw = &hns->hw;
        int ret;
@@ -566,14 +566,29 @@ hns3_enable_vlan_filter(struct hns3_adapter *hns, bool enable)
        ret = hns3_set_vlan_filter_ctrl(hw, HNS3_FILTER_TYPE_VF,
                                        HNS3_FILTER_FE_EGRESS, false, 0);
        if (ret) {
-               hns3_err(hw, "hns3 enable filter fail, ret =%d", ret);
+               hns3_err(hw, "failed to init vf vlan filter, ret = %d", ret);
                return ret;
        }
 
+       ret = hns3_set_vlan_filter_ctrl(hw, HNS3_FILTER_TYPE_PORT,
+                                       HNS3_FILTER_FE_INGRESS, false, 0);
+       if (ret)
+               hns3_err(hw, "failed to init port vlan filter, ret = %d", ret);
+
+       return ret;
+}
+
+static int
+hns3_enable_vlan_filter(struct hns3_adapter *hns, bool enable)
+{
+       struct hns3_hw *hw = &hns->hw;
+       int ret;
+
        ret = hns3_set_vlan_filter_ctrl(hw, HNS3_FILTER_TYPE_PORT,
                                        HNS3_FILTER_FE_INGRESS, enable, 0);
        if (ret)
-               hns3_err(hw, "hns3 enable filter fail, ret =%d", ret);
+               hns3_err(hw, "failed to %s port vlan filter, ret = %d",
+                        enable ? "enable" : "disable", ret);
 
        return ret;
 }
@@ -591,6 +606,20 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask)
        rte_spinlock_lock(&hw->lock);
        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;
+
+               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;
+               }
+       }
+
        if (tmp_mask & ETH_VLAN_STRIP_MASK) {
                /* Enable or disable VLAN stripping */
                enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP ?
@@ -599,7 +628,8 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask)
                ret = hns3_en_hw_strip_rxvtag(hns, enable);
                if (ret) {
                        rte_spinlock_unlock(&hw->lock);
-                       hns3_err(hw, "failed to enable rx strip, ret =%d", ret);
+                       hns3_err(hw, "failed to %s rx strip, ret = %d",
+                                enable ? "enable" : "disable", ret);
                        return ret;
                }
        }
@@ -926,7 +956,7 @@ hns3_init_vlan_config(struct hns3_adapter *hns)
        if (rte_atomic16_read(&hw->reset.resetting) == 0)
                init_port_base_vlan_info(hw);
 
-       ret = hns3_enable_vlan_filter(hns, true);
+       ret = hns3_vlan_filter_init(hns);
        if (ret) {
                hns3_err(hw, "vlan init fail in pf, ret =%d", ret);
                return ret;
@@ -968,17 +998,29 @@ hns3_restore_vlan_conf(struct hns3_adapter *hns)
 {
        struct hns3_pf *pf = &hns->pf;
        struct hns3_hw *hw = &hns->hw;
+       uint64_t offloads;
+       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;
+       }
+
        ret = hns3_set_vlan_rx_offload_cfg(hns, &pf->vtag_config.rx_vcfg);
        if (ret) {
-               hns3_err(hw, "hns3 restore vlan rx conf fail, ret =%d", ret);
+               hns3_err(hw, "failed to restore vlan rx conf, ret = %d", ret);
                return ret;
        }
 
        ret = hns3_set_vlan_tx_offload_cfg(hns, &pf->vtag_config.tx_vcfg);
        if (ret)
-               hns3_err(hw, "hns3 restore vlan tx conf fail, ret =%d", ret);
+               hns3_err(hw, "failed to restore vlan tx conf, ret = %d", ret);
 
        return ret;
 }
@@ -990,6 +1032,7 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev)
        struct rte_eth_dev_data *data = dev->data;
        struct rte_eth_txmode *txmode;
        struct hns3_hw *hw = &hns->hw;
+       int mask;
        int ret;
 
        txmode = &data->dev_conf.txmode;
@@ -1003,9 +1046,11 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev)
                          txmode->hw_vlan_reject_untagged);
 
        /* Apply vlan offload setting */
-       ret = hns3_vlan_offload_set(dev, ETH_VLAN_STRIP_MASK);
+       mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK;
+       ret = hns3_vlan_offload_set(dev, mask);
        if (ret) {
-               hns3_err(hw, "dev config vlan Strip failed, ret =%d", ret);
+               hns3_err(hw, "dev config rx vlan offload failed, ret = %d",
+                        ret);
                return ret;
        }
 
@@ -1013,7 +1058,7 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev)
        ret = hns3_vlan_pvid_set(dev, txmode->pvid,
                                 txmode->hw_vlan_insert_pvid);
        if (ret)
-               hns3_err(hw, "dev config vlan pvid(%d) failed, ret =%d",
+               hns3_err(hw, "dev config vlan pvid(%d) failed, ret = %d",
                         txmode->pvid, ret);
 
        return ret;