summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c10
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_common.c6
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_common.h1
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c7
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c5
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h1
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c2
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c12
-rw-r--r--drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c16
9 files changed, 52 insertions, 8 deletions
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c
index 946e699cbe10..1b0ba244a68f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c
@@ -353,7 +353,8 @@ static int wait_cmdqs_enable(struct hinic3_cmdqs *cmdqs)
if (cmdqs->status & HINIC3_CMDQ_ENABLE)
return 0;
usleep_range(1000, 2000);
- } while (time_before(jiffies, end) && !cmdqs->disable_flag);
+ } while (time_before(jiffies, end) && !cmdqs->disable_flag &&
+ cmdqs->hwdev->chip_present_flag);
cmdqs->disable_flag = 1;
@@ -681,6 +682,10 @@ int hinic3_cmdq_direct_resp(struct hinic3_hwdev *hwdev, u8 mod, u8 cmd,
{
struct hinic3_cmdqs *cmdqs;
int err;
+
+ if (!hwdev->chip_present_flag)
+ return -ETIMEDOUT;
+
err = cmdq_params_valid(hwdev, buf_in);
if (err) {
dev_err(hwdev->dev, "Invalid CMDQ parameters\n");
@@ -712,6 +717,9 @@ int hinic3_cmdq_detail_resp(struct hinic3_hwdev *hwdev, u8 mod, u8 cmd,
struct hinic3_cmdqs *cmdqs;
int err;
+ if (!hwdev->chip_present_flag)
+ return -ETIMEDOUT;
+
err = cmdq_params_valid(hwdev, buf_in);
if (err)
goto err_out;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.c b/drivers/net/ethernet/huawei/hinic3/hinic3_common.c
index fe4778d152cf..b28576debdc8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_common.c
@@ -59,10 +59,14 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
enum hinic3_wait_return ret;
int err;
- err = read_poll_timeout(handler, ret, ret == HINIC3_WAIT_PROCESS_CPL,
+ err = read_poll_timeout(handler, ret,
+ !(ret & HINIC3_WAIT_PROCESS_WAITING),
wait_once_us, wait_total_ms * USEC_PER_MSEC,
false, priv_data);
+ if (ret == HINIC3_WAIT_PROCESS_ERR)
+ return -EIO;
+
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
index a8fabfae90fb..c892439fa3cd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
@@ -21,6 +21,7 @@ struct hinic3_dma_addr_align {
enum hinic3_wait_return {
HINIC3_WAIT_PROCESS_CPL = 0,
HINIC3_WAIT_PROCESS_WAITING = 1,
+ HINIC3_WAIT_PROCESS_ERR = 2,
};
struct hinic3_sge {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c
index ecfe6265954e..1defd6800790 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c
@@ -300,6 +300,10 @@ static enum hinic3_wait_return check_cmdq_stop_handler(void *priv_data)
enum hinic3_cmdq_type cmdq_type;
struct hinic3_cmdqs *cmdqs;
+ /* Stop waiting when card unpresent */
+ if (!hwdev->chip_present_flag)
+ return HINIC3_WAIT_PROCESS_ERR;
+
cmdqs = hwdev->cmdqs;
for (cmdq_type = 0; cmdq_type < cmdqs->cmdq_num; cmdq_type++) {
if (!hinic3_cmdq_idle(&cmdqs->cmdq[cmdq_type]))
@@ -347,6 +351,9 @@ int hinic3_func_rx_tx_flush(struct hinic3_hwdev *hwdev)
int ret = 0;
int err;
+ if (!hwdev->chip_present_flag)
+ return 0;
+
err = wait_cmdq_stop(hwdev);
if (err) {
dev_warn(hwdev->dev, "CMDQ is still working, CMDQ timeout value is unreasonable\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c
index 0074d0c6dbaf..04c0385b3344 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c
@@ -32,6 +32,9 @@
#define HINIC3_PCIE_PH_DISABLE 0
#define HINIC3_PCIE_MSIX_ATTR_ENTRY 0
+#define HINIC3_CHIP_PRESENT 1
+#define HINIC3_CHIP_ABSENT 0
+
#define HINIC3_DEFAULT_EQ_MSIX_PENDING_LIMIT 0
#define HINIC3_DEFAULT_EQ_MSIX_COALESC_TIMER_CFG 0xFF
#define HINIC3_DEFAULT_EQ_MSIX_RESEND_TIMER_CFG 7
@@ -545,6 +548,7 @@ int hinic3_init_hwdev(struct pci_dev *pdev)
dev_err(hwdev->dev, "Failed to init hwif\n");
goto err_free_hwdev;
}
+ hwdev->chip_present_flag = HINIC3_CHIP_PRESENT;
hwdev->workq = alloc_workqueue(HINIC3_HWDEV_WQ_NAME, WQ_MEM_RECLAIM | WQ_PERCPU,
HINIC3_WQ_MAX_REQ);
@@ -621,6 +625,7 @@ void hinic3_set_api_stop(struct hinic3_hwdev *hwdev)
struct hinic3_recv_msg *recv_resp_msg;
struct hinic3_mbox *mbox;
+ hwdev->chip_present_flag = HINIC3_CHIP_ABSENT;
spin_lock_bh(&hwdev->channel_lock);
if (HINIC3_IS_PF(hwdev) &&
test_bit(HINIC3_HWDEV_MGMT_INITED, &hwdev->func_state)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h
index 9686c2600b46..4276ac136464 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.h
@@ -76,6 +76,7 @@ struct hinic3_hwdev {
u32 wq_page_size;
u8 max_cmdq;
ulong func_state;
+ int chip_present_flag;
};
struct hinic3_event_info {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c
index 771883174b3b..70d70556dca6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c
@@ -97,6 +97,8 @@ static enum hinic3_wait_return check_hwif_ready_handler(void *priv_data)
u32 attr1;
attr1 = hinic3_hwif_read_reg(hwdev->hwif, HINIC3_CSR_FUNC_ATTR1_ADDR);
+ if (attr1 == HINIC3_PCIE_LINK_DOWN)
+ return HINIC3_WAIT_PROCESS_ERR;
return HINIC3_AF1_GET(attr1, MGMT_INIT_STATUS) ?
HINIC3_WAIT_PROCESS_CPL : HINIC3_WAIT_PROCESS_WAITING;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c
index 7d31e215b14f..c82370cf401d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c
@@ -646,6 +646,9 @@ static enum hinic3_wait_return check_mbox_wb_status(void *priv_data)
struct hinic3_mbox *mbox = priv_data;
u16 wb_status;
+ if (!mbox->hwdev->chip_present_flag)
+ return HINIC3_WAIT_PROCESS_ERR;
+
wb_status = get_mbox_status(&mbox->send_mbox);
return MBOX_STATUS_FINISHED(wb_status) ?
@@ -788,6 +791,9 @@ static enum hinic3_wait_return check_mbox_msg_finish(void *priv_data)
{
struct hinic3_mbox *mbox = priv_data;
+ if (!mbox->hwdev->chip_present_flag)
+ return HINIC3_WAIT_PROCESS_ERR;
+
return (mbox->event_flag == MBOX_EVENT_SUCCESS) ?
HINIC3_WAIT_PROCESS_CPL : HINIC3_WAIT_PROCESS_WAITING;
}
@@ -819,6 +825,9 @@ int hinic3_send_mbox_to_mgmt(struct hinic3_hwdev *hwdev, u8 mod, u16 cmd,
u32 msg_len;
int err;
+ if (!hwdev->chip_present_flag)
+ return -EPERM;
+
/* expect response message */
msg_desc = get_mbox_msg_desc(mbox, MBOX_MSG_RESP, MBOX_MGMT_FUNC_ID);
mutex_lock(&mbox->mbox_send_lock);
@@ -897,6 +906,9 @@ int hinic3_send_mbox_to_mgmt_no_ack(struct hinic3_hwdev *hwdev, u8 mod, u16 cmd,
struct mbox_msg_info msg_info = {};
int err;
+ if (!hwdev->chip_present_flag)
+ return -EPERM;
+
mutex_lock(&mbox->mbox_send_lock);
err = send_mbox_msg(mbox, mod, cmd, msg_params->buf_in,
msg_params->in_size, MBOX_MGMT_FUNC_ID,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index cabb8523f246..da73811641a9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -415,13 +415,17 @@ static void hinic3_vport_down(struct net_device *netdev)
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
- hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false);
+ if (nic_dev->hwdev->chip_present_flag) {
+ hinic3_maybe_set_port_state(netdev, false);
- hinic3_flush_txqs(netdev);
- /* wait to guarantee that no packets will be sent to host */
- msleep(100);
- hinic3_flush_qps_res(nic_dev->hwdev);
+ glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
+ hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false);
+
+ hinic3_flush_txqs(netdev);
+ /* wait to guarantee that no packets will be sent to host */
+ msleep(100);
+ hinic3_flush_qps_res(nic_dev->hwdev);
+ }
}
static int hinic3_open(struct net_device *netdev)