Skip to content

Commit

Permalink
net: hns3: Fix loss of coal configuration while doing reset
Browse files Browse the repository at this point in the history
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: bb6b94a ("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>
  • Loading branch information
Huazhong Tan authored and David S. Miller committed Sep 28, 2018
1 parent 0d43bf4 commit e4fd750
Showing 2 changed files with 36 additions and 37 deletions.
71 changes: 34 additions & 37 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
@@ -225,8 +225,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)
@@ -239,9 +237,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;
@@ -3490,6 +3485,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;
@@ -3536,6 +3556,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;
@@ -3563,6 +3585,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");
@@ -3597,24 +3621,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);
@@ -3632,7 +3639,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)
@@ -3664,7 +3671,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;
@@ -3696,26 +3702,17 @@ 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);

hns3_uninit_all_ring(priv);
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,
2 changes: 2 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
Original file line number Diff line number Diff line change
@@ -543,6 +543,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 {

0 comments on commit e4fd750

Please sign in to comment.