]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
Merge tag 'nfc-next-4.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo...
[mirror_ubuntu-hirsute-kernel.git] / drivers / net / ethernet / chelsio / cxgb4 / t4_hw.c
index 49bcbf16c9caee11a1be5193362b87ee8339a347..a63addb4e72c619f16642891fb94631a17ce5d83 100644 (file)
@@ -293,6 +293,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
        u32 data_reg = PF_REG(mbox, CIM_PF_MAILBOX_DATA_A);
        u32 ctl_reg = PF_REG(mbox, CIM_PF_MAILBOX_CTRL_A);
        __be64 cmd_rpl[MBOX_LEN / 8];
+       u32 pcie_fw;
 
        if ((size & 15) || size > MBOX_LEN)
                return -EINVAL;
@@ -304,6 +305,12 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
        if (adap->pdev->error_state != pci_channel_io_normal)
                return -EIO;
 
+       /* If we have a negative timeout, that implies that we can't sleep. */
+       if (timeout < 0) {
+               sleep_ok = false;
+               timeout = -timeout;
+       }
+
        v = MBOWNER_G(t4_read_reg(adap, ctl_reg));
        for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
                v = MBOWNER_G(t4_read_reg(adap, ctl_reg));
@@ -325,7 +332,10 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
        delay_idx = 0;
        ms = delay[0];
 
-       for (i = 0; i < timeout; i += ms) {
+       for (i = 0;
+            !((pcie_fw = t4_read_reg(adap, PCIE_FW_A)) & PCIE_FW_ERR_F) &&
+            i < timeout;
+            i += ms) {
                if (sleep_ok) {
                        ms = delay[delay_idx];  /* last element may repeat */
                        if (delay_idx < ARRAY_SIZE(delay) - 1)
@@ -360,7 +370,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
                }
        }
 
-       ret = -ETIMEDOUT;
+       ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -ETIMEDOUT;
        t4_record_mbox(adap, cmd, MBOX_LEN, access, ret);
        dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
                *(const u8 *)cmd, mbox);