Commit 7cbac9d5 authored by Huazhong Tan's avatar Huazhong Tan Committed by Greg Kroah-Hartman

net: hns3: Fix loss of coal configuration while doing reset

[ Upstream commit e4fd7502 ]

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: bb6b94a8 ("net: hns3: Add reset interface implementation in client")
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: default avatarSalil Mehta <salil.mehta@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent af98283d
...@@ -195,8 +195,6 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector, ...@@ -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, static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
struct hns3_nic_priv *priv) struct hns3_nic_priv *priv)
{ {
struct hnae3_handle *h = priv->ae_handle;
/* initialize the configuration for interrupt coalescing. /* initialize the configuration for interrupt coalescing.
* 1. GL (Interrupt Gap Limiter) * 1. GL (Interrupt Gap Limiter)
* 2. RL (Interrupt Rate Limiter) * 2. RL (Interrupt Rate Limiter)
...@@ -209,9 +207,6 @@ static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector, ...@@ -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->tx_group.coal.int_gl = HNS3_INT_GL_50K;
tqp_vector->rx_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->int_adapt_down = HNS3_INT_ADAPT_DOWN_START;
tqp_vector->rx_group.coal.flow_level = HNS3_FLOW_LOW; tqp_vector->rx_group.coal.flow_level = HNS3_FLOW_LOW;
tqp_vector->tx_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) ...@@ -3423,6 +3418,31 @@ int hns3_nic_reset_all_ring(struct hnae3_handle *h)
return 0; 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) static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
{ {
struct hnae3_knic_private_info *kinfo = &handle->kinfo; struct hnae3_knic_private_info *kinfo = &handle->kinfo;
...@@ -3469,6 +3489,8 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle) ...@@ -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 */ /* Carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev); netif_carrier_off(netdev);
hns3_restore_coal(priv);
ret = hns3_nic_init_vector_data(priv); ret = hns3_nic_init_vector_data(priv);
if (ret) if (ret)
return ret; return ret;
...@@ -3496,6 +3518,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle) ...@@ -3496,6 +3518,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
return ret; return ret;
} }
hns3_store_coal(priv);
ret = hns3_uninit_all_ring(priv); ret = hns3_uninit_all_ring(priv);
if (ret) if (ret)
netdev_err(netdev, "uninit ring error\n"); netdev_err(netdev, "uninit ring error\n");
...@@ -3530,24 +3554,7 @@ static int hns3_reset_notify(struct hnae3_handle *handle, ...@@ -3530,24 +3554,7 @@ static int hns3_reset_notify(struct hnae3_handle *handle,
return ret; return ret;
} }
static void hns3_restore_coal(struct hns3_nic_priv *priv, static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num)
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)
{ {
struct hns3_nic_priv *priv = netdev_priv(netdev); struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = hns3_get_handle(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, ...@@ -3565,7 +3572,7 @@ static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num,
if (ret) if (ret)
goto err_alloc_vector; goto err_alloc_vector;
hns3_restore_coal(priv, tx, rx); hns3_restore_coal(priv);
ret = hns3_nic_init_vector_data(priv); ret = hns3_nic_init_vector_data(priv);
if (ret) if (ret)
...@@ -3597,7 +3604,6 @@ int hns3_set_channels(struct net_device *netdev, ...@@ -3597,7 +3604,6 @@ int hns3_set_channels(struct net_device *netdev,
struct hns3_nic_priv *priv = netdev_priv(netdev); struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = hns3_get_handle(netdev); struct hnae3_handle *h = hns3_get_handle(netdev);
struct hnae3_knic_private_info *kinfo = &h->kinfo; struct hnae3_knic_private_info *kinfo = &h->kinfo;
struct hns3_enet_coalesce tx_coal, rx_coal;
bool if_running = netif_running(netdev); bool if_running = netif_running(netdev);
u32 new_tqp_num = ch->combined_count; u32 new_tqp_num = ch->combined_count;
u16 org_tqp_num; u16 org_tqp_num;
...@@ -3629,15 +3635,7 @@ int hns3_set_channels(struct net_device *netdev, ...@@ -3629,15 +3635,7 @@ int hns3_set_channels(struct net_device *netdev,
goto open_netdev; goto open_netdev;
} }
/* Changing the tqp num may also change the vector num, hns3_store_coal(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(&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_nic_dealloc_vector_data(priv); hns3_nic_dealloc_vector_data(priv);
...@@ -3645,10 +3643,9 @@ int hns3_set_channels(struct net_device *netdev, ...@@ -3645,10 +3643,9 @@ int hns3_set_channels(struct net_device *netdev,
hns3_put_ring_config(priv); hns3_put_ring_config(priv);
org_tqp_num = h->kinfo.num_tqps; 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) { if (ret) {
ret = hns3_modify_tqp_num(netdev, org_tqp_num, ret = hns3_modify_tqp_num(netdev, org_tqp_num);
&tx_coal, &rx_coal);
if (ret) { if (ret) {
/* If revert to old tqp failed, fatal error occurred */ /* If revert to old tqp failed, fatal error occurred */
dev_err(&netdev->dev, dev_err(&netdev->dev,
......
...@@ -541,6 +541,8 @@ struct hns3_nic_priv { ...@@ -541,6 +541,8 @@ struct hns3_nic_priv {
/* Vxlan/Geneve information */ /* Vxlan/Geneve information */
struct hns3_udp_tunnel udp_tnl[HNS3_UDP_TNL_MAX]; struct hns3_udp_tunnel udp_tnl[HNS3_UDP_TNL_MAX];
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 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 { union l3_hdr_info {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment