summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/huawei/hinic/hinic_hw_if.c')
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_if.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
index 3fbd2eb80582..cf127d896ba6 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
@@ -10,6 +10,7 @@
#include <linux/io.h>
#include <linux/types.h>
#include <linux/bitops.h>
+#include <linux/delay.h>
#include "hinic_hw_csr.h"
#include "hinic_hw_if.h"
@@ -18,6 +19,8 @@
#define VALID_MSIX_IDX(attr, msix_index) ((msix_index) < (attr)->num_irqs)
+#define WAIT_HWIF_READY_TIMEOUT 10000
+
/**
* hinic_msix_attr_set - set message attribute for msix entry
* @hwif: the HW interface of a pci function device
@@ -187,20 +190,39 @@ void hinic_set_msix_state(struct hinic_hwif *hwif, u16 msix_idx,
**/
static int hwif_ready(struct hinic_hwif *hwif)
{
- struct pci_dev *pdev = hwif->pdev;
u32 addr, attr1;
addr = HINIC_CSR_FUNC_ATTR1_ADDR;
attr1 = hinic_hwif_read_reg(hwif, addr);
- if (!HINIC_FA1_GET(attr1, INIT_STATUS)) {
- dev_err(&pdev->dev, "hwif status is not ready\n");
- return -EFAULT;
+ if (!HINIC_FA1_GET(attr1, MGMT_INIT_STATUS))
+ return -EBUSY;
+
+ if (HINIC_IS_VF(hwif)) {
+ if (!HINIC_FA1_GET(attr1, PF_INIT_STATUS))
+ return -EBUSY;
}
return 0;
}
+static int wait_hwif_ready(struct hinic_hwif *hwif)
+{
+ unsigned long timeout = 0;
+
+ do {
+ if (!hwif_ready(hwif))
+ return 0;
+
+ usleep_range(999, 1000);
+ timeout++;
+ } while (timeout <= WAIT_HWIF_READY_TIMEOUT);
+
+ dev_err(&hwif->pdev->dev, "Wait for hwif timeout\n");
+
+ return -EBUSY;
+}
+
/**
* set_hwif_attr - set the attributes in the relevant members in hwif
* @hwif: the HW interface of a pci function device
@@ -373,7 +395,7 @@ int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev)
goto err_map_intr_bar;
}
- err = hwif_ready(hwif);
+ err = wait_hwif_ready(hwif);
if (err) {
dev_err(&pdev->dev, "HW interface is not ready\n");
goto err_hwif_ready;