net: hns3: add recovery for the H/W errors occurred before the HNS dev initialization
authorShiju Jose <shiju.jose@huawei.com>
Thu, 13 Jun 2019 09:12:24 +0000 (17:12 +0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 15 Jun 2019 02:26:15 +0000 (19:26 -0700)
This patch adds the recovery for the HNS H/W errors which occurred
before the driver initialization.

Reported-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

index d9863c300b1d21cf4e5a880b5c26b0cb52d7f0ed..6761d725bb12762514b6717bf80f317f89e52615 100644 (file)
@@ -3236,6 +3236,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev, bool is_timeout)
 
                dev_info(&hdev->pdev->dev, "Upgrade reset level\n");
                hclge_clear_reset_cause(hdev);
+               set_bit(HNAE3_GLOBAL_RESET, &hdev->default_reset_request);
                mod_timer(&hdev->reset_timer,
                          jiffies + HCLGE_RESET_INTERVAL);
 
@@ -3430,8 +3431,7 @@ static void hclge_reset_timer(struct timer_list *t)
        struct hclge_dev *hdev = from_timer(hdev, t, reset_timer);
 
        dev_info(&hdev->pdev->dev,
-                "triggering global reset in reset timer\n");
-       set_bit(HNAE3_GLOBAL_RESET, &hdev->default_reset_request);
+                "triggering reset in reset timer\n");
        hclge_reset_event(hdev->pdev, NULL);
 }
 
@@ -8614,6 +8614,18 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
        /* Log and clear the hw errors those already occurred */
        hclge_handle_all_hns_hw_errors(ae_dev);
 
+       /* request delayed reset for the error recovery because an immediate
+        * global reset on a PF affecting pending initialization of other PFs
+        */
+       if (ae_dev->hw_err_reset_req) {
+               enum hnae3_reset_type reset_level;
+
+               reset_level = hclge_get_reset_level(ae_dev,
+                                                   &ae_dev->hw_err_reset_req);
+               hclge_set_def_reset_request(ae_dev, reset_level);
+               mod_timer(&hdev->reset_timer, jiffies + HCLGE_RESET_INTERVAL);
+       }
+
        /* Enable MISC vector(vector0) */
        hclge_enable_vector(&hdev->misc_vector, true);