pds_core: check health in devcmd wait
authorShannon Nelson <shannon.nelson@amd.com>
Thu, 14 Sep 2023 22:31:57 +0000 (15:31 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 18 Sep 2023 08:28:22 +0000 (09:28 +0100)
Similar to what we do in the AdminQ, check for devcmd health
while waiting for an answer.

Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/amd/pds_core/dev.c
include/linux/pds/pds_core_if.h

index f77cd9f5a2fda53a05dcfe3d8b202bb98c513c0b..7c1b965d61a926df45a88e8c941f0806f12923ad 100644 (file)
@@ -42,6 +42,8 @@ int pdsc_err_to_errno(enum pds_core_status_code code)
                return -ERANGE;
        case PDS_RC_BAD_ADDR:
                return -EFAULT;
+       case PDS_RC_BAD_PCI:
+               return -ENXIO;
        case PDS_RC_EOPCODE:
        case PDS_RC_EINTR:
        case PDS_RC_DEV_CMD:
@@ -62,7 +64,7 @@ bool pdsc_is_fw_running(struct pdsc *pdsc)
        /* Firmware is useful only if the running bit is set and
         * fw_status != 0xff (bad PCI read)
         */
-       return (pdsc->fw_status != 0xff) &&
+       return (pdsc->fw_status != PDS_RC_BAD_PCI) &&
                (pdsc->fw_status & PDS_CORE_FW_STS_F_RUNNING);
 }
 
@@ -128,6 +130,7 @@ static int pdsc_devcmd_wait(struct pdsc *pdsc, u8 opcode, int max_seconds)
        unsigned long max_wait;
        unsigned long duration;
        int timeout = 0;
+       bool running;
        int done = 0;
        int err = 0;
        int status;
@@ -136,6 +139,10 @@ static int pdsc_devcmd_wait(struct pdsc *pdsc, u8 opcode, int max_seconds)
        max_wait = start_time + (max_seconds * HZ);
 
        while (!done && !timeout) {
+               running = pdsc_is_fw_running(pdsc);
+               if (!running)
+                       break;
+
                done = pdsc_devcmd_done(pdsc);
                if (done)
                        break;
@@ -152,7 +159,7 @@ static int pdsc_devcmd_wait(struct pdsc *pdsc, u8 opcode, int max_seconds)
                dev_dbg(dev, "DEVCMD %d %s after %ld secs\n",
                        opcode, pdsc_devcmd_str(opcode), duration / HZ);
 
-       if (!done || timeout) {
+       if ((!done || timeout) && running) {
                dev_err(dev, "DEVCMD %d %s timeout, done %d timeout %d max_seconds=%d\n",
                        opcode, pdsc_devcmd_str(opcode), done, timeout,
                        max_seconds);
index e838a2b90440ca0e8cc5f8d3e1e71bbd60cd4cfd..17a87c1a55d7c79f6b098d52a2b6f47b2d27a4d9 100644 (file)
@@ -79,6 +79,7 @@ enum pds_core_status_code {
        PDS_RC_EVFID    = 31,   /* VF ID does not exist */
        PDS_RC_BAD_FW   = 32,   /* FW file is invalid or corrupted */
        PDS_RC_ECLIENT  = 33,   /* No such client id */
+       PDS_RC_BAD_PCI  = 255,  /* Broken PCI when reading status */
 };
 
 /**