]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
net: hns3: add handshake with hardware while doing reset
authorHuazhong Tan <tanhuazhong@huawei.com>
Tue, 28 May 2019 09:02:59 +0000 (17:02 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 29 May 2019 00:39:01 +0000 (17:39 -0700)
When reset happens, the hardware reset should begin after the
driver has finished its preparatory work, otherwise it may cause
some hardware error.

Before Hardware's reset, it will wait for the driver to write
bit HCLGE_NIC_CMQ_ENABLE of register HCLGE_NIC_CSQ_DEPTH_REG
to 1, while the driver finishes its preparatory work will do that.
BTW, since some cases this register will be cleared, so it needs
some sync time before driver's writing.

Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

index fbd904e3077cf6219b270df37a0058140a946784..e5329053842bc26c135bc2927d609a0e7baa8df4 100644 (file)
@@ -110,8 +110,7 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring)
                hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG,
                                upper_32_bits(dma));
                hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG,
-                               (ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S) |
-                               HCLGE_NIC_CMQ_ENABLE);
+                               ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S);
                hclge_write_dev(hw, HCLGE_NIC_CSQ_HEAD_REG, 0);
                hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0);
        } else {
@@ -120,8 +119,7 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring)
                hclge_write_dev(hw, HCLGE_NIC_CRQ_BASEADDR_H_REG,
                                upper_32_bits(dma));
                hclge_write_dev(hw, HCLGE_NIC_CRQ_DEPTH_REG,
-                               (ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S) |
-                               HCLGE_NIC_CMQ_ENABLE);
+                               ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S);
                hclge_write_dev(hw, HCLGE_NIC_CRQ_HEAD_REG, 0);
                hclge_write_dev(hw, HCLGE_NIC_CRQ_TAIL_REG, 0);
        }
index b7106a5528ee1197da1b7c3a380e2beb701cc0f7..a563815e5ed17318957433b8e06993e479c97652 100644 (file)
@@ -3197,6 +3197,8 @@ static int hclge_reset_prepare_down(struct hclge_dev *hdev)
 
 static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
 {
+#define HCLGE_RESET_SYNC_TIME 100
+
        u32 reg_val;
        int ret = 0;
 
@@ -3205,7 +3207,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
                /* There is no mechanism for PF to know if VF has stopped IO
                 * for now, just wait 100 ms for VF to stop IO
                 */
-               msleep(100);
+               msleep(HCLGE_RESET_SYNC_TIME);
                ret = hclge_func_reset_cmd(hdev, 0);
                if (ret) {
                        dev_err(&hdev->pdev->dev,
@@ -3225,7 +3227,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
                /* There is no mechanism for PF to know if VF has stopped IO
                 * for now, just wait 100 ms for VF to stop IO
                 */
-               msleep(100);
+               msleep(HCLGE_RESET_SYNC_TIME);
                set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);
                set_bit(HNAE3_FLR_DOWN, &hdev->flr_state);
                hdev->rst_stats.flr_rst_cnt++;
@@ -3239,6 +3241,10 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
                break;
        }
 
+       /* 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);
        dev_info(&hdev->pdev->dev, "prepare wait ok\n");
 
        return ret;
index 71f356fc24462415cb9770efa1388bf1f2fd4fca..e1588c0e8bb9f872c637c72ace57029e9ffe0feb 100644 (file)
@@ -98,7 +98,6 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring)
                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_NIC_CMQ_ENABLE;
                hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_DEPTH_REG, reg_val);
 
                hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG, 0);
@@ -110,7 +109,6 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring)
                hclgevf_write_dev(hw, HCLGEVF_NIC_CRQ_BASEADDR_H_REG, reg_val);
 
                reg_val = (ring->desc_num >> HCLGEVF_NIC_CMQ_DESC_NUM_S);
-               reg_val |= HCLGEVF_NIC_CMQ_ENABLE;
                hclgevf_write_dev(hw, HCLGEVF_NIC_CRQ_DEPTH_REG, reg_val);
 
                hclgevf_write_dev(hw, HCLGEVF_NIC_CRQ_HEAD_REG, 0);
index 9d5a4f817048daa2b3ed81178d3c7be74d91f3fd..ee1eecad3b8d7b8aa7b70df653a6420697848048 100644 (file)
@@ -1414,6 +1414,8 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
 
 static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
 {
+#define HCLGEVF_RESET_SYNC_TIME 100
+
        int ret = 0;
 
        switch (hdev->reset_type) {
@@ -1431,7 +1433,10 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
        }
 
        set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
-
+       /* inform hardware that preparatory work is done */
+       msleep(HCLGEVF_RESET_SYNC_TIME);
+       hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG,
+                         HCLGEVF_NIC_CMQ_ENABLE);
        dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done, ret:%d\n",
                 hdev->reset_type, ret);