net: hinic: Add support for configuration of rx-vlan-filter by ethtool
authorCai Huoqing <cai.huoqing@linux.dev>
Thu, 3 Nov 2022 08:05:11 +0000 (16:05 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 7 Nov 2022 08:50:20 +0000 (08:50 +0000)
When ethtool config rx-vlan-filter, the driver will send
control command to firmware, then set to hardware in this patch.

Signed-off-by: Cai Huoqing <cai.huoqing@linux.dev>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/huawei/hinic/hinic_main.c
drivers/net/ethernet/huawei/hinic/hinic_port.c
drivers/net/ethernet/huawei/hinic/hinic_port.h

index 9d4d795e108145025497a9392e73c4d410964588..977c41473ab75acff15af42d3c967d526bfa8240 100644 (file)
@@ -1092,6 +1092,16 @@ static int set_features(struct hinic_dev *nic_dev,
                }
        }
 
+       if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
+               ret = hinic_set_vlan_fliter(nic_dev,
+                                           !!(features &
+                                              NETIF_F_HW_VLAN_CTAG_FILTER));
+               if (ret) {
+                       err = ret;
+                       failed_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+               }
+       }
+
        if (err) {
                nic_dev->netdev->features = features ^ failed_features;
                return -EIO;
index 0a39c3dffa9afd97eea816cc72df8ced619538b3..9406237c461e0c3664a40231d4cd6939002c7db4 100644 (file)
@@ -447,6 +447,39 @@ int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en)
        return 0;
 }
 
+int hinic_set_vlan_fliter(struct hinic_dev *nic_dev, u32 en)
+{
+       struct hinic_hwdev *hwdev = nic_dev->hwdev;
+       struct hinic_hwif *hwif = hwdev->hwif;
+       struct pci_dev *pdev = hwif->pdev;
+       struct hinic_vlan_filter vlan_filter;
+       u16 out_size = sizeof(vlan_filter);
+       int err;
+
+       if (!hwdev)
+               return -EINVAL;
+
+       vlan_filter.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
+       vlan_filter.enable = en;
+
+       err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_VLAN_FILTER,
+                                &vlan_filter, sizeof(vlan_filter),
+                                &vlan_filter, &out_size);
+       if (vlan_filter.status == HINIC_MGMT_CMD_UNSUPPORTED) {
+               err = HINIC_MGMT_CMD_UNSUPPORTED;
+       } else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
+                          HINIC_IS_VF(hwif)) {
+               err = HINIC_MGMT_CMD_UNSUPPORTED;
+       } else if (err || !out_size || vlan_filter.status) {
+               dev_err(&pdev->dev,
+                       "Failed to set vlan fliter, err: %d, status: 0x%x, out size: 0x%x\n",
+                       err, vlan_filter.status, out_size);
+               err = -EINVAL;
+       }
+
+       return err;
+}
+
 int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
 {
        struct hinic_hwdev *hwdev = nic_dev->hwdev;
index c9ae3d4dc5470365c78074641f4ca3ce5e1dedf4..c8694ac7c7021cad924fe1468a69cba163e195c2 100644 (file)
@@ -351,6 +351,16 @@ struct hinic_vlan_cfg {
        u8      rsvd1[5];
 };
 
+struct hinic_vlan_filter {
+       u8      status;
+       u8      version;
+       u8      rsvd0[6];
+
+       u16     func_idx;
+       u8      rsvd1[2];
+       u32     enable;
+};
+
 struct hinic_rss_template_mgmt {
        u8      status;
        u8      version;
@@ -831,6 +841,8 @@ int hinic_get_vport_stats(struct hinic_dev *nic_dev,
 
 int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en);
 
+int hinic_set_vlan_fliter(struct hinic_dev *nic_dev, u32 en);
+
 int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver);
 
 int hinic_set_link_settings(struct hinic_hwdev *hwdev,