提交 c03aa9dd 编写于 作者: H Huazhong Tan 提交者: Xie XiuQi

net: hns3: fix some reset handshake issue

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

Currently, the driver will clear the handshake status when
re-intializing the CMDQ, and does not recover this status when
reset fail. This will cause the hardware cannot get the handshake
and do nothing anymore.

So this patch delays clearing handshake status just before UP,
and recovers this status when reset fail.

Fixes: ada13ee3db7b ("net: hns3: add handshake with hardware while doing reset")
Feature or Bugfix:Bugfix
Signed-off-by: NHuazhong Tan <tanhuazhong@huawei.com>
Reviewed-by: Nlipeng <lipeng321@huawei.com>
Reviewed-by: NYunsheng Lin <linyunsheng@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 d510f706
...@@ -105,14 +105,17 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring) ...@@ -105,14 +105,17 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring)
dma_addr_t dma = ring->desc_dma_addr; dma_addr_t dma = ring->desc_dma_addr;
struct hclge_dev *hdev = ring->dev; struct hclge_dev *hdev = ring->dev;
struct hclge_hw *hw = &hdev->hw; struct hclge_hw *hw = &hdev->hw;
u32 reg_val;
if (ring->ring_type == HCLGE_TYPE_CSQ) { if (ring->ring_type == HCLGE_TYPE_CSQ) {
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_L_REG, hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_L_REG,
lower_32_bits(dma)); lower_32_bits(dma));
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG, hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG,
upper_32_bits(dma)); upper_32_bits(dma));
hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val = hclge_read_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG);
ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S); reg_val &= HCLGE_NIC_CMQ_ENABLE;
reg_val |= ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S;
hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val);
hclge_write_dev(hw, HCLGE_NIC_CSQ_HEAD_REG, 0); hclge_write_dev(hw, HCLGE_NIC_CSQ_HEAD_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0); hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0);
} else { } else {
......
...@@ -3461,6 +3461,7 @@ static int hclge_set_rst_done(struct hclge_dev *hdev) ...@@ -3461,6 +3461,7 @@ static int hclge_set_rst_done(struct hclge_dev *hdev)
static int hclge_reset_prepare_up(struct hclge_dev *hdev) static int hclge_reset_prepare_up(struct hclge_dev *hdev)
{ {
u32 reg_val;
int ret = 0; int ret = 0;
switch (hdev->reset_type) { switch (hdev->reset_type) {
...@@ -3478,6 +3479,11 @@ static int hclge_reset_prepare_up(struct hclge_dev *hdev) ...@@ -3478,6 +3479,11 @@ static int hclge_reset_prepare_up(struct hclge_dev *hdev)
break; break;
} }
/* clear handshake status with IMP */
reg_val = hclge_read_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG) &
~HCLGE_NIC_CMQ_ENABLE;
hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val);
return ret; return ret;
} }
......
...@@ -99,7 +99,9 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring) ...@@ -99,7 +99,9 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring)
HCLGEVF_RING_BASEADDR_SHIFT); HCLGEVF_RING_BASEADDR_SHIFT);
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_BASEADDR_H_REG, reg_val); hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_BASEADDR_H_REG, reg_val);
reg_val = (ring->desc_num >> HCLGEVF_NIC_CMQ_DESC_NUM_S); reg_val = hclgevf_read_dev(hw, HCLGEVF_NIC_CSQ_DEPTH_REG);
reg_val &= HCLGEVF_NIC_CMQ_ENABLE;
reg_val |= (ring->desc_num >> HCLGEVF_NIC_CMQ_DESC_NUM_S);
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_DEPTH_REG, reg_val); hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_DEPTH_REG, reg_val);
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG, 0); hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG, 0);
......
...@@ -1412,6 +1412,7 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev) ...@@ -1412,6 +1412,7 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
static int hclgevf_reset_stack(struct hclgevf_dev *hdev) static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
{ {
u32 reg_val;
int ret; int ret;
/* uninitialize the nic client */ /* uninitialize the nic client */
...@@ -1436,6 +1437,10 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev) ...@@ -1436,6 +1437,10 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
if (ret) if (ret)
return ret; return ret;
/* clear handshake status with IMP */
reg_val = hclgevf_read_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG) &
~HCLGEVF_NIC_CMQ_ENABLE;
hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG, reg_val);
return 0; return 0;
} }
...@@ -1473,11 +1478,9 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) ...@@ -1473,11 +1478,9 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
{ {
/* When VF reset failed, only the higher level reset asserted by PF /* recover handshake status with IMP when reset fail */
* can restore it, so re-initialize the command queue to receive hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG,
* this higher reset event. HCLGEVF_NIC_CMQ_ENABLE);
*/
hclgevf_cmd_init(hdev);
hdev->rst_stats.rst_fail_cnt++; hdev->rst_stats.rst_fail_cnt++;
dev_err(&hdev->pdev->dev, "failed to reset VF(%d)\n", dev_err(&hdev->pdev->dev, "failed to reset VF(%d)\n",
hdev->rst_stats.rst_fail_cnt); hdev->rst_stats.rst_fail_cnt);
...@@ -1488,9 +1491,6 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) ...@@ -1488,9 +1491,6 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
if (hclgevf_is_reset_pending(hdev)) { if (hclgevf_is_reset_pending(hdev)) {
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
hclgevf_reset_task_schedule(hdev); hclgevf_reset_task_schedule(hdev);
} else {
hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG,
HCLGEVF_NIC_CMQ_ENABLE);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册