aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
diff options
context:
space:
mode:
authorHuazhong Tan <tanhuazhong@huawei.com>2019-08-01 11:55:43 +0800
committerDavid S. Miller <davem@davemloft.net>2019-08-01 13:32:13 -0400
commit6b428b4fbf986077d218287dd6f805f371cdf48f (patch)
tree84948689e6dc4bab827ba86d242ef3b15b6c4579 /drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
parentnet: hns3: rename a member in struct hclge_mac_ethertype_idx_rd_cmd (diff)
downloadlinux-dev-6b428b4fbf986077d218287dd6f805f371cdf48f.tar.xz
linux-dev-6b428b4fbf986077d218287dd6f805f371cdf48f.zip
net: hns3: fix some reset handshake issue
Currently, the driver sets handshake status to tell the hardware that the driver have downed the netdev and it can continue with reset process. The driver will clear the handshake status when re-initializing the CMDQ, and does not recover this status when reset fail, which may cause the hardware to wait for the handshake status to be set and not being able to continue with reset process. So this patch delays clearing handshake status just before UP, and recovers this status when reset fail. BTW, this patch adds a new function hclge(vf)_reset_handshake() to deal with the reset handshake issue, and renames HCLGE(VF)_NIC_CMQ_ENABLE to HCLGE(VF)_NIC_SW_RST_RDY which represents this register bit more accurately. Fixes: ada13ee3db7b ("net: hns3: add handshake with hardware while doing reset") Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com> Reviewed-by: Peng Li <lipeng321@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c')
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 4317c8fe68f3..abe4cee06d4a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -3274,6 +3274,19 @@ static int hclge_reset_prepare_down(struct hclge_dev *hdev)
return ret;
}
+static void hclge_reset_handshake(struct hclge_dev *hdev, bool enable)
+{
+ u32 reg_val;
+
+ reg_val = hclge_read_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG);
+ if (enable)
+ reg_val |= HCLGE_NIC_SW_RST_RDY;
+ else
+ reg_val &= ~HCLGE_NIC_SW_RST_RDY;
+
+ hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val);
+}
+
static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
{
#define HCLGE_RESET_SYNC_TIME 100
@@ -3322,8 +3335,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
/* inform hardware that preparatory work is done */
msleep(HCLGE_RESET_SYNC_TIME);
- hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG,
- HCLGE_NIC_CMQ_ENABLE);
+ hclge_reset_handshake(hdev, true);
dev_info(&hdev->pdev->dev, "prepare wait ok\n");
return ret;
@@ -3354,6 +3366,10 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
}
hclge_clear_reset_cause(hdev);
+
+ /* recover the handshake status when reset fail */
+ hclge_reset_handshake(hdev, true);
+
dev_err(&hdev->pdev->dev, "Reset fail!\n");
return false;
}
@@ -3372,6 +3388,9 @@ static int hclge_reset_prepare_up(struct hclge_dev *hdev)
break;
}
+ /* clear up the handshake status after re-initialize done */
+ hclge_reset_handshake(hdev, false);
+
return ret;
}