net: hns3: Fix loss of coal configuration while doing reset
authorHuazhong Tan <tanhuazhong@huawei.com>
Wed, 26 Sep 2018 18:28:40 +0000 (19:28 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 24 Nov 2019 07:19:20 +0000 (08:19 +0100)
[ Upstream commit e4fd75022c24eb28cc1034e97e60cecc24f325f3 ]

The user's coal configuration will be lost after reset, so the tx_coal
and rx_coal fields are added to the struct hns_nic_priv to save the coal
configuration and used to restore the user's configuration after the reset
is complete.

Fixes: bb6b94a896d4 ("net: hns3: Add reset interface implementation in client")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h

index a5e3d38..15030df 100644 (file)
@@ -195,8 +195,6 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector,
 static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
                                   struct hns3_nic_priv *priv)
 {
-       struct hnae3_handle *h = priv->ae_handle;
-
        /* initialize the configuration for interrupt coalescing.
         * 1. GL (Interrupt Gap Limiter)
         * 2. RL (Interrupt Rate Limiter)
@@ -209,9 +207,6 @@ static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
        tqp_vector->tx_group.coal.int_gl = HNS3_INT_GL_50K;
        tqp_vector->rx_group.coal.int_gl = HNS3_INT_GL_50K;
 
-       /* Default: disable RL */
-       h->kinfo.int_rl_setting = 0;
-
        tqp_vector->int_adapt_down = HNS3_INT_ADAPT_DOWN_START;
        tqp_vector->rx_group.coal.flow_level = HNS3_FLOW_LOW;
        tqp_vector->tx_group.coal.flow_level = HNS3_FLOW_LOW;
@@ -3423,6 +3418,31 @@ int hns3_nic_reset_all_ring(struct hnae3_handle *h)
        return 0;
 }
 
+static void hns3_store_coal(struct hns3_nic_priv *priv)
+{
+       /* ethtool only support setting and querying one coal
+        * configuation for now, so save the vector 0' coal
+        * configuation here in order to restore it.
+        */
+       memcpy(&priv->tx_coal, &priv->tqp_vector[0].tx_group.coal,
+              sizeof(struct hns3_enet_coalesce));
+       memcpy(&priv->rx_coal, &priv->tqp_vector[0].rx_group.coal,
+              sizeof(struct hns3_enet_coalesce));
+}
+
+static void hns3_restore_coal(struct hns3_nic_priv *priv)
+{
+       u16 vector_num = priv->vector_num;
+       int i;
+
+       for (i = 0; i < vector_num; i++) {
+               memcpy(&priv->tqp_vector[i].tx_group.coal, &priv->tx_coal,
+                      sizeof(struct hns3_enet_coalesce));
+               memcpy(&priv->tqp_vector[i].rx_group.coal, &priv->rx_coal,
+                      sizeof(struct hns3_enet_coalesce));
+       }
+}
+
 static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
 {
        struct hnae3_knic_private_info *kinfo = &handle->kinfo;
@@ -3469,6 +3489,8 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
        /* Carrier off reporting is important to ethtool even BEFORE open */
        netif_carrier_off(netdev);
 
+       hns3_restore_coal(priv);
+
        ret = hns3_nic_init_vector_data(priv);
        if (ret)
                return ret;
@@ -3496,6 +3518,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
                return ret;
        }
 
+       hns3_store_coal(priv);
+
        ret = hns3_uninit_all_ring(priv);
        if (ret)
                netdev_err(netdev, "uninit ring error\n");
@@ -3530,24 +3554,7 @@ static int hns3_reset_notify(struct hnae3_handle *handle,
        return ret;
 }
 
-static void hns3_restore_coal(struct hns3_nic_priv *priv,
-                             struct hns3_enet_coalesce *tx,
-                             struct hns3_enet_coalesce *rx)
-{
-       u16 vector_num = priv->vector_num;
-       int i;
-
-       for (i = 0; i < vector_num; i++) {
-               memcpy(&priv->tqp_vector[i].tx_group.coal, tx,
-                      sizeof(struct hns3_enet_coalesce));
-               memcpy(&priv->tqp_vector[i].rx_group.coal, rx,
-                      sizeof(struct hns3_enet_coalesce));
-       }
-}
-
-static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num,
-                              struct hns3_enet_coalesce *tx,
-                              struct hns3_enet_coalesce *rx)
+static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num)
 {
        struct hns3_nic_priv *priv = netdev_priv(netdev);
        struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -3565,7 +3572,7 @@ static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num,
        if (ret)
                goto err_alloc_vector;
 
-       hns3_restore_coal(priv, tx, rx);
+       hns3_restore_coal(priv);
 
        ret = hns3_nic_init_vector_data(priv);
        if (ret)
@@ -3597,7 +3604,6 @@ int hns3_set_channels(struct net_device *netdev,
        struct hns3_nic_priv *priv = netdev_priv(netdev);
        struct hnae3_handle *h = hns3_get_handle(netdev);
        struct hnae3_knic_private_info *kinfo = &h->kinfo;
-       struct hns3_enet_coalesce tx_coal, rx_coal;
        bool if_running = netif_running(netdev);
        u32 new_tqp_num = ch->combined_count;
        u16 org_tqp_num;
@@ -3629,15 +3635,7 @@ int hns3_set_channels(struct net_device *netdev,
                goto open_netdev;
        }
 
-       /* Changing the tqp num may also change the vector num,
-        * ethtool only support setting and querying one coal
-        * configuation for now, so save the vector 0' coal
-        * configuation here in order to restore it.
-        */
-       memcpy(&tx_coal, &priv->tqp_vector[0].tx_group.coal,
-              sizeof(struct hns3_enet_coalesce));
-       memcpy(&rx_coal, &priv->tqp_vector[0].rx_group.coal,
-              sizeof(struct hns3_enet_coalesce));
+       hns3_store_coal(priv);
 
        hns3_nic_dealloc_vector_data(priv);
 
@@ -3645,10 +3643,9 @@ int hns3_set_channels(struct net_device *netdev,
        hns3_put_ring_config(priv);
 
        org_tqp_num = h->kinfo.num_tqps;
-       ret = hns3_modify_tqp_num(netdev, new_tqp_num, &tx_coal, &rx_coal);
+       ret = hns3_modify_tqp_num(netdev, new_tqp_num);
        if (ret) {
-               ret = hns3_modify_tqp_num(netdev, org_tqp_num,
-                                         &tx_coal, &rx_coal);
+               ret = hns3_modify_tqp_num(netdev, org_tqp_num);
                if (ret) {
                        /* If revert to old tqp failed, fatal error occurred */
                        dev_err(&netdev->dev,
index cb450d7..94d7446 100644 (file)
@@ -541,6 +541,8 @@ struct hns3_nic_priv {
        /* Vxlan/Geneve information */
        struct hns3_udp_tunnel udp_tnl[HNS3_UDP_TNL_MAX];
        unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+       struct hns3_enet_coalesce tx_coal;
+       struct hns3_enet_coalesce rx_coal;
 };
 
 union l3_hdr_info {