aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSalil Mehta <salil.mehta@huawei.com>2018-03-22 10:28:52 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-22 15:29:03 -0400
commit6d4c3981a8d815466de081138f2e31e9d044c669 (patch)
tree77f9d06a7c587b0107b1ec6292b3e081c6e7f3a0
parent1a2e10a24039147047cc21759ec57314c333c1ac (diff)
net: hns3: Changes to make enet watchdog timeout func common for PF/VF
HNS3 drivers enet layer, used for the ring management and stack interaction, is common to both VF and PF. PF already supports reset functionality to handle the network stack watchdog timeout trigger but the existing code is not generic enough to be used to support VF reset as well. This patch does following: 1. Makes the existing watchdog timeout handler in enet layer generic i.e. suitable for both VF and PF and 2. Introduces the new reset event handler for the VF code. 3. Changes existing reset event handler of PF code to initialize the reset level Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hnae3.h7
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c30
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.h2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c36
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c14
5 files changed, 46 insertions, 43 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 9daa88d9041e..56f9e650d964 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -118,6 +118,7 @@ enum hnae3_reset_notify_type {
118}; 118};
119 119
120enum hnae3_reset_type { 120enum hnae3_reset_type {
121 HNAE3_VF_RESET,
121 HNAE3_FUNC_RESET, 122 HNAE3_FUNC_RESET,
122 HNAE3_CORE_RESET, 123 HNAE3_CORE_RESET,
123 HNAE3_GLOBAL_RESET, 124 HNAE3_GLOBAL_RESET,
@@ -400,8 +401,7 @@ struct hnae3_ae_ops {
400 int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid, 401 int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid,
401 u16 vlan, u8 qos, __be16 proto); 402 u16 vlan, u8 qos, __be16 proto);
402 int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable); 403 int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable);
403 void (*reset_event)(struct hnae3_handle *handle, 404 void (*reset_event)(struct hnae3_handle *handle);
404 enum hnae3_reset_type reset);
405 void (*get_channels)(struct hnae3_handle *handle, 405 void (*get_channels)(struct hnae3_handle *handle,
406 struct ethtool_channels *ch); 406 struct ethtool_channels *ch);
407 void (*get_tqps_and_rss_info)(struct hnae3_handle *h, 407 void (*get_tqps_and_rss_info)(struct hnae3_handle *h,
@@ -495,6 +495,9 @@ struct hnae3_handle {
495 struct hnae3_ae_algo *ae_algo; /* the class who provides this handle */ 495 struct hnae3_ae_algo *ae_algo; /* the class who provides this handle */
496 u64 flags; /* Indicate the capabilities for this handle*/ 496 u64 flags; /* Indicate the capabilities for this handle*/
497 497
498 unsigned long last_reset_time;
499 enum hnae3_reset_type reset_level;
500
498 union { 501 union {
499 struct net_device *netdev; /* first member */ 502 struct net_device *netdev; /* first member */
500 struct hnae3_knic_private_info kinfo; 503 struct hnae3_knic_private_info kinfo;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 0b4a676999ca..40a3eb70629e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -320,7 +320,7 @@ static int hns3_nic_net_open(struct net_device *netdev)
320 return ret; 320 return ret;
321 } 321 }
322 322
323 priv->last_reset_time = jiffies; 323 priv->ae_handle->last_reset_time = jiffies;
324 return 0; 324 return 0;
325} 325}
326 326
@@ -1543,7 +1543,6 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
1543static void hns3_nic_net_timeout(struct net_device *ndev) 1543static void hns3_nic_net_timeout(struct net_device *ndev)
1544{ 1544{
1545 struct hns3_nic_priv *priv = netdev_priv(ndev); 1545 struct hns3_nic_priv *priv = netdev_priv(ndev);
1546 unsigned long last_reset_time = priv->last_reset_time;
1547 struct hnae3_handle *h = priv->ae_handle; 1546 struct hnae3_handle *h = priv->ae_handle;
1548 1547
1549 if (!hns3_get_tx_timeo_queue_info(ndev)) 1548 if (!hns3_get_tx_timeo_queue_info(ndev))
@@ -1551,24 +1550,12 @@ static void hns3_nic_net_timeout(struct net_device *ndev)
1551 1550
1552 priv->tx_timeout_count++; 1551 priv->tx_timeout_count++;
1553 1552
1554 /* This timeout is far away enough from last timeout, 1553 if (time_before(jiffies, (h->last_reset_time + ndev->watchdog_timeo)))
1555 * if timeout again,set the reset type to PF reset
1556 */
1557 if (time_after(jiffies, (last_reset_time + 20 * HZ)))
1558 priv->reset_level = HNAE3_FUNC_RESET;
1559
1560 /* Don't do any new action before the next timeout */
1561 else if (time_before(jiffies, (last_reset_time + ndev->watchdog_timeo)))
1562 return; 1554 return;
1563 1555
1564 priv->last_reset_time = jiffies; 1556 /* request the reset */
1565
1566 if (h->ae_algo->ops->reset_event) 1557 if (h->ae_algo->ops->reset_event)
1567 h->ae_algo->ops->reset_event(h, priv->reset_level); 1558 h->ae_algo->ops->reset_event(h);
1568
1569 priv->reset_level++;
1570 if (priv->reset_level > HNAE3_GLOBAL_RESET)
1571 priv->reset_level = HNAE3_GLOBAL_RESET;
1572} 1559}
1573 1560
1574static const struct net_device_ops hns3_nic_netdev_ops = { 1561static const struct net_device_ops hns3_nic_netdev_ops = {
@@ -3122,8 +3109,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
3122 priv->dev = &pdev->dev; 3109 priv->dev = &pdev->dev;
3123 priv->netdev = netdev; 3110 priv->netdev = netdev;
3124 priv->ae_handle = handle; 3111 priv->ae_handle = handle;
3125 priv->last_reset_time = jiffies; 3112 priv->ae_handle->reset_level = HNAE3_NONE_RESET;
3126 priv->reset_level = HNAE3_FUNC_RESET; 3113 priv->ae_handle->last_reset_time = jiffies;
3127 priv->tx_timeout_count = 0; 3114 priv->tx_timeout_count = 0;
3128 3115
3129 handle->kinfo.netdev = netdev; 3116 handle->kinfo.netdev = netdev;
@@ -3355,7 +3342,6 @@ static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
3355static int hns3_reset_notify_up_enet(struct hnae3_handle *handle) 3342static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
3356{ 3343{
3357 struct hnae3_knic_private_info *kinfo = &handle->kinfo; 3344 struct hnae3_knic_private_info *kinfo = &handle->kinfo;
3358 struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev);
3359 int ret = 0; 3345 int ret = 0;
3360 3346
3361 if (netif_running(kinfo->netdev)) { 3347 if (netif_running(kinfo->netdev)) {
@@ -3365,8 +3351,7 @@ static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
3365 "hns net up fail, ret=%d!\n", ret); 3351 "hns net up fail, ret=%d!\n", ret);
3366 return ret; 3352 return ret;
3367 } 3353 }
3368 3354 handle->last_reset_time = jiffies;
3369 priv->last_reset_time = jiffies;
3370 } 3355 }
3371 3356
3372 return ret; 3357 return ret;
@@ -3378,7 +3363,6 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
3378 struct hns3_nic_priv *priv = netdev_priv(netdev); 3363 struct hns3_nic_priv *priv = netdev_priv(netdev);
3379 int ret; 3364 int ret;
3380 3365
3381 priv->reset_level = 1;
3382 hns3_init_mac_addr(netdev); 3366 hns3_init_mac_addr(netdev);
3383 hns3_nic_set_rx_mode(netdev); 3367 hns3_nic_set_rx_mode(netdev);
3384 hns3_recover_hw_addr(netdev); 3368 hns3_recover_hw_addr(netdev);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 39daa01f08d5..9e4cfbbf8dcd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -532,8 +532,6 @@ struct hns3_nic_priv {
532 /* The most recently read link state */ 532 /* The most recently read link state */
533 int link; 533 int link;
534 u64 tx_timeout_count; 534 u64 tx_timeout_count;
535 enum hnae3_reset_type reset_level;
536 unsigned long last_reset_time;
537 535
538 unsigned long state; 536 unsigned long state;
539 537
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 31e90b588e92..a3e00da3dff0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2845,27 +2845,31 @@ static void hclge_reset(struct hclge_dev *hdev)
2845 hclge_notify_client(hdev, HNAE3_UP_CLIENT); 2845 hclge_notify_client(hdev, HNAE3_UP_CLIENT);
2846} 2846}
2847 2847
2848static void hclge_reset_event(struct hnae3_handle *handle, 2848static void hclge_reset_event(struct hnae3_handle *handle)
2849 enum hnae3_reset_type reset)
2850{ 2849{
2851 struct hclge_vport *vport = hclge_get_vport(handle); 2850 struct hclge_vport *vport = hclge_get_vport(handle);
2852 struct hclge_dev *hdev = vport->back; 2851 struct hclge_dev *hdev = vport->back;
2853 2852
2854 dev_info(&hdev->pdev->dev, 2853 /* check if this is a new reset request and we are not here just because
2855 "Receive reset event , reset_type is %d", reset); 2854 * last reset attempt did not succeed and watchdog hit us again. We will
2855 * know this if last reset request did not occur very recently (watchdog
2856 * timer = 5*HZ, let us check after sufficiently large time, say 4*5*Hz)
2857 * In case of new request we reset the "reset level" to PF reset.
2858 */
2859 if (time_after(jiffies, (handle->last_reset_time + 4 * 5 * HZ)))
2860 handle->reset_level = HNAE3_FUNC_RESET;
2856 2861
2857 switch (reset) { 2862 dev_info(&hdev->pdev->dev, "received reset event , reset type is %d",
2858 case HNAE3_FUNC_RESET: 2863 handle->reset_level);
2859 case HNAE3_CORE_RESET: 2864
2860 case HNAE3_GLOBAL_RESET: 2865 /* request reset & schedule reset task */
2861 /* request reset & schedule reset task */ 2866 set_bit(handle->reset_level, &hdev->reset_request);
2862 set_bit(reset, &hdev->reset_request); 2867 hclge_reset_task_schedule(hdev);
2863 hclge_reset_task_schedule(hdev); 2868
2864 break; 2869 if (handle->reset_level < HNAE3_GLOBAL_RESET)
2865 default: 2870 handle->reset_level++;
2866 dev_warn(&hdev->pdev->dev, "Unsupported reset event:%d", reset); 2871
2867 break; 2872 handle->last_reset_time = jiffies;
2868 }
2869} 2873}
2870 2874
2871static void hclge_reset_subtask(struct hclge_dev *hdev) 2875static void hclge_reset_subtask(struct hclge_dev *hdev)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index 906dfa3d0fc6..6c3881d5dbf2 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -832,6 +832,19 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
832 2, true, NULL, 0); 832 2, true, NULL, 0);
833} 833}
834 834
835static void hclgevf_reset_event(struct hnae3_handle *handle)
836{
837 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
838
839 dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
840
841 handle->reset_level = HNAE3_VF_RESET;
842
843 /* request VF reset here. Code added later */
844
845 handle->last_reset_time = jiffies;
846}
847
835static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) 848static u32 hclgevf_get_fw_version(struct hnae3_handle *handle)
836{ 849{
837 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 850 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
@@ -1526,6 +1539,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
1526 .get_tc_size = hclgevf_get_tc_size, 1539 .get_tc_size = hclgevf_get_tc_size,
1527 .get_fw_version = hclgevf_get_fw_version, 1540 .get_fw_version = hclgevf_get_fw_version,
1528 .set_vlan_filter = hclgevf_set_vlan_filter, 1541 .set_vlan_filter = hclgevf_set_vlan_filter,
1542 .reset_event = hclgevf_reset_event,
1529 .get_channels = hclgevf_get_channels, 1543 .get_channels = hclgevf_get_channels,
1530 .get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info, 1544 .get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info,
1531 .get_status = hclgevf_get_status, 1545 .get_status = hclgevf_get_status,