
From: Chiqijun <chiqijun@huawei.com> driver inclusion category: feature bugzilla: 4472 ----------------------------------------------------------------------- Add the 'ethtool -K ethx rx-vlan-filter on/off' command to turn on/off the vlan filter. Signed-off-by: Chiqijun <chiqijun@huawei.com> Reviewed-by: Wangxiaoyun <cloud.wangxiaoyun@huawei.com> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Signed-off-by: Cheng Jian <cj.chengjian@huawei.com> --- .../net/ethernet/huawei/hinic/hinic_main.c | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index d0c4bdf7383c..6797d50d1bd4 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -1331,6 +1331,9 @@ hinic_vlan_rx_add_vid(struct net_device *netdev, u32 col, line; int err; + if (vid == 0) + return 0; + col = VID_COL(nic_dev, vid); line = VID_LINE(nic_dev, vid); @@ -1362,6 +1365,12 @@ hinic_vlan_rx_kill_vid(struct net_device *netdev, u16 func_id; int err, col, line; + /* vlan 0 is used internally by the firmware and must always exist + * after netdev open + */ + if (vid == 0) + return 0; + col = VID_COL(nic_dev, vid); line = VID_LINE(nic_dev, vid); @@ -1490,6 +1499,31 @@ static int set_feature_lro(struct hinic_nic_dev *nic_dev, return err; } +static int set_feature_vlan_filter(struct hinic_nic_dev *nic_dev, + netdev_features_t wanted_features, + netdev_features_t features, + netdev_features_t *failed_features) +{ + netdev_features_t changed = wanted_features ^ features; + bool en = !!(wanted_features & NETIF_F_HW_VLAN_CTAG_FILTER); + int err; + + if (!(changed & NETIF_F_HW_VLAN_CTAG_FILTER)) + return 0; + + err = hinic_set_vlan_fliter(nic_dev->hwdev, en); + if (err) { + hinic_err(nic_dev, drv, "%s rx vlan filter failed\n", + FEATURES_OP_STR(en)); + *failed_features |= NETIF_F_HW_VLAN_CTAG_FILTER; + } else { + hinic_info(nic_dev, drv, "%s rx vlan filter success\n", + FEATURES_OP_STR(en)); + } + + return err; +} + static int set_features(struct hinic_nic_dev *nic_dev, netdev_features_t pre_features, netdev_features_t features) @@ -1505,6 +1539,8 @@ static int set_features(struct hinic_nic_dev *nic_dev, &failed_features); err |= (u32)set_feature_lro(nic_dev, features, pre_features, &failed_features); + err |= (u32)set_feature_vlan_filter(nic_dev, features, pre_features, + &failed_features); if (err) { nic_dev->netdev->features = features ^ failed_features; return -EIO; @@ -2100,6 +2136,8 @@ static void netdev_feature_init(struct net_device *netdev) netdev->features |= NETIF_F_HW_VLAN_CTAG_RX; } + netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; + /* copy netdev features into list of user selectable features */ hw_features = netdev->hw_features; hw_features |= netdev->features; @@ -2116,11 +2154,6 @@ static void netdev_feature_init(struct net_device *netdev) netdev->hw_features = hw_features; - /* Set after hw_features because this could not be part of - * hw_features - */ - netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; - netdev->priv_flags |= IFF_UNICAST_FLT; if (FUNC_SUPPORT_ENCAP_TSO_CSUM(nic_dev->hwdev)) { -- 2.25.1