From 04f207fb0c2fa768da1fd30642bb83554c46847f Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Wed, 26 Jun 2019 12:35:49 +0000 Subject: net: aquantia: implement vlan offload configuration set_features should update flags and reinit hardware if vlan offload settings were changed. Signed-off-by: Igor Russkikh Tested-by: Nikita Danilov Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_main.c | 34 +++++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'drivers/net/ethernet/aquantia/atlantic/aq_main.c') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c index 5315df5ff6f8..100722ad5c2d 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c @@ -108,11 +108,16 @@ err_exit: static int aq_ndev_set_features(struct net_device *ndev, netdev_features_t features) { + bool is_vlan_rx_strip = !!(features & NETIF_F_HW_VLAN_CTAG_RX); + bool is_vlan_tx_insert = !!(features & NETIF_F_HW_VLAN_CTAG_TX); struct aq_nic_s *aq_nic = netdev_priv(ndev); - struct aq_nic_cfg_s *aq_cfg = aq_nic_get_cfg(aq_nic); + bool need_ndev_restart = false; + struct aq_nic_cfg_s *aq_cfg; bool is_lro = false; int err = 0; + aq_cfg = aq_nic_get_cfg(aq_nic); + if (!(features & NETIF_F_NTUPLE)) { if (aq_nic->ndev->features & NETIF_F_NTUPLE) { err = aq_clear_rxnfc_all_rules(aq_nic); @@ -135,17 +140,32 @@ static int aq_ndev_set_features(struct net_device *ndev, if (aq_cfg->is_lro != is_lro) { aq_cfg->is_lro = is_lro; - - if (netif_running(ndev)) { - aq_ndev_close(ndev); - aq_ndev_open(ndev); - } + need_ndev_restart = true; } } - if ((aq_nic->ndev->features ^ features) & NETIF_F_RXCSUM) + + if ((aq_nic->ndev->features ^ features) & NETIF_F_RXCSUM) { err = aq_nic->aq_hw_ops->hw_set_offload(aq_nic->aq_hw, aq_cfg); + if (unlikely(err)) + goto err_exit; + } + + if (aq_cfg->is_vlan_rx_strip != is_vlan_rx_strip) { + aq_cfg->is_vlan_rx_strip = is_vlan_rx_strip; + need_ndev_restart = true; + } + if (aq_cfg->is_vlan_tx_insert != is_vlan_tx_insert) { + aq_cfg->is_vlan_tx_insert = is_vlan_tx_insert; + need_ndev_restart = true; + } + + if (need_ndev_restart && netif_running(ndev)) { + aq_ndev_close(ndev); + aq_ndev_open(ndev); + } + err_exit: return err; } -- cgit