]> git.hungrycats.org Git - linux/commitdiff
net: wangxun: match VLAN CTAG and STAG features
authorJiawen Wu <jiawenwu@trustnetic.com>
Fri, 17 May 2024 06:51:39 +0000 (14:51 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 May 2024 07:49:51 +0000 (09:49 +0200)
[ Upstream commit ac71ab7816b675f1c9614015bd87bfccb456c394 ]

Hardware requires VLAN CTAG and STAG configuration always matches. And
whether VLAN CTAG or STAG changes, the configuration needs to be changed
as well.

Fixes: 6670f1ece2c8 ("net: txgbe: Add netdev features support")
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: Sai Krishna <saikrishnag@marvell.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/wangxun/libwx/wx_lib.c
drivers/net/ethernet/wangxun/libwx/wx_lib.h
drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c

index 6aa6073476f7d07470b2162309870258ed620b25..b2d5c3f05eed574eb729c9827393bdc3b1e967bc 100644 (file)
@@ -2705,6 +2705,52 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
 }
 EXPORT_SYMBOL(wx_set_features);
 
+#define NETIF_VLAN_STRIPPING_FEATURES  (NETIF_F_HW_VLAN_CTAG_RX | \
+                                        NETIF_F_HW_VLAN_STAG_RX)
+
+#define NETIF_VLAN_INSERTION_FEATURES  (NETIF_F_HW_VLAN_CTAG_TX | \
+                                        NETIF_F_HW_VLAN_STAG_TX)
+
+#define NETIF_VLAN_FILTERING_FEATURES  (NETIF_F_HW_VLAN_CTAG_FILTER | \
+                                        NETIF_F_HW_VLAN_STAG_FILTER)
+
+netdev_features_t wx_fix_features(struct net_device *netdev,
+                                 netdev_features_t features)
+{
+       netdev_features_t changed = netdev->features ^ features;
+       struct wx *wx = netdev_priv(netdev);
+
+       if (changed & NETIF_VLAN_STRIPPING_FEATURES) {
+               if ((features & NETIF_VLAN_STRIPPING_FEATURES) != NETIF_VLAN_STRIPPING_FEATURES &&
+                   (features & NETIF_VLAN_STRIPPING_FEATURES) != 0) {
+                       features &= ~NETIF_VLAN_STRIPPING_FEATURES;
+                       features |= netdev->features & NETIF_VLAN_STRIPPING_FEATURES;
+                       wx_err(wx, "802.1Q and 802.1ad VLAN stripping must be either both on or both off.");
+               }
+       }
+
+       if (changed & NETIF_VLAN_INSERTION_FEATURES) {
+               if ((features & NETIF_VLAN_INSERTION_FEATURES) != NETIF_VLAN_INSERTION_FEATURES &&
+                   (features & NETIF_VLAN_INSERTION_FEATURES) != 0) {
+                       features &= ~NETIF_VLAN_INSERTION_FEATURES;
+                       features |= netdev->features & NETIF_VLAN_INSERTION_FEATURES;
+                       wx_err(wx, "802.1Q and 802.1ad VLAN insertion must be either both on or both off.");
+               }
+       }
+
+       if (changed & NETIF_VLAN_FILTERING_FEATURES) {
+               if ((features & NETIF_VLAN_FILTERING_FEATURES) != NETIF_VLAN_FILTERING_FEATURES &&
+                   (features & NETIF_VLAN_FILTERING_FEATURES) != 0) {
+                       features &= ~NETIF_VLAN_FILTERING_FEATURES;
+                       features |= netdev->features & NETIF_VLAN_FILTERING_FEATURES;
+                       wx_err(wx, "802.1Q and 802.1ad VLAN filtering must be either both on or both off.");
+               }
+       }
+
+       return features;
+}
+EXPORT_SYMBOL(wx_fix_features);
+
 void wx_set_ring(struct wx *wx, u32 new_tx_count,
                 u32 new_rx_count, struct wx_ring *temp_ring)
 {
index ec909e876720ca05c709ffb59060d3a4e9546426..c41b29ea812ffb958eb6535b3beb33944cbd77c8 100644 (file)
@@ -30,6 +30,8 @@ int wx_setup_resources(struct wx *wx);
 void wx_get_stats64(struct net_device *netdev,
                    struct rtnl_link_stats64 *stats);
 int wx_set_features(struct net_device *netdev, netdev_features_t features);
+netdev_features_t wx_fix_features(struct net_device *netdev,
+                                 netdev_features_t features);
 void wx_set_ring(struct wx *wx, u32 new_tx_count,
                 u32 new_rx_count, struct wx_ring *temp_ring);
 
index fdd6b4f70b7a5c0ee4c50e5ba9218411107909be..e894e01d030d15bf28ae197ac698a8d44795168c 100644 (file)
@@ -499,6 +499,7 @@ static const struct net_device_ops ngbe_netdev_ops = {
        .ndo_start_xmit         = wx_xmit_frame,
        .ndo_set_rx_mode        = wx_set_rx_mode,
        .ndo_set_features       = wx_set_features,
+       .ndo_fix_features       = wx_fix_features,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = wx_set_mac,
        .ndo_get_stats64        = wx_get_stats64,
index 3b151c410a5c22845a4022e88723b2facb9ef9c2..c13c43e07a9939c7405ce1ba328268ec06f2459f 100644 (file)
@@ -550,6 +550,7 @@ static const struct net_device_ops txgbe_netdev_ops = {
        .ndo_start_xmit         = wx_xmit_frame,
        .ndo_set_rx_mode        = wx_set_rx_mode,
        .ndo_set_features       = wx_set_features,
+       .ndo_fix_features       = wx_fix_features,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = wx_set_mac,
        .ndo_get_stats64        = wx_get_stats64,