u32 mbox_ctl = T4VF_CIM_BASE_ADDR + CIM_VF_EXT_MAILBOX_CTRL;
        u32 cmd_op = FW_CMD_OP_G(be32_to_cpu(((struct fw_cmd_hdr *)cmd)->hi));
        __be64 cmd_rpl[MBOX_LEN / 8];
+       struct mbox_list entry;
 
        /* In T6, mailbox size is changed to 128 bytes to avoid
         * invalidating the entire prefetch buffer.
            size > NUM_CIM_VF_MAILBOX_DATA_INSTANCES * 4)
                return -EINVAL;
 
+       /* Queue ourselves onto the mailbox access list.  When our entry is at
+        * the front of the list, we have rights to access the mailbox.  So we
+        * wait [for a while] till we're at the front [or bail out with an
+        * EBUSY] ...
+        */
+       spin_lock(&adapter->mbox_lock);
+       list_add_tail(&entry.list, &adapter->mlist.list);
+       spin_unlock(&adapter->mbox_lock);
+
+       delay_idx = 0;
+       ms = delay[0];
+
+       for (i = 0; ; i += ms) {
+               /* If we've waited too long, return a busy indication.  This
+                * really ought to be based on our initial position in the
+                * mailbox access list but this is a start.  We very rearely
+                * contend on access to the mailbox ...
+                */
+               if (i > FW_CMD_MAX_TIMEOUT) {
+                       spin_lock(&adapter->mbox_lock);
+                       list_del(&entry.list);
+                       spin_unlock(&adapter->mbox_lock);
+                       ret = -EBUSY;
+                       t4vf_record_mbox(adapter, cmd, size, access, ret);
+                       return ret;
+               }
+
+               /* If we're at the head, break out and start the mailbox
+                * protocol.
+                */
+               if (list_first_entry(&adapter->mlist.list, struct mbox_list,
+                                    list) == &entry)
+                       break;
+
+               /* Delay for a bit before checking again ... */
+               if (sleep_ok) {
+                       ms = delay[delay_idx];  /* last element may repeat */
+                       if (delay_idx < ARRAY_SIZE(delay) - 1)
+                               delay_idx++;
+                       msleep(ms);
+               } else {
+                       mdelay(ms);
+               }
+       }
+
        /*
         * Loop trying to get ownership of the mailbox.  Return an error
         * if we can't gain ownership.
        for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
                v = MBOWNER_G(t4_read_reg(adapter, mbox_ctl));
        if (v != MBOX_OWNER_DRV) {
+               spin_lock(&adapter->mbox_lock);
+               list_del(&entry.list);
+               spin_unlock(&adapter->mbox_lock);
                ret = (v == MBOX_OWNER_FW) ? -EBUSY : -ETIMEDOUT;
                t4vf_record_mbox(adapter, cmd, size, access, ret);
                return ret;
                        if (cmd_op != FW_VI_STATS_CMD)
                                t4vf_record_mbox(adapter, cmd_rpl, size, access,
                                                 execute);
+                       spin_lock(&adapter->mbox_lock);
+                       list_del(&entry.list);
+                       spin_unlock(&adapter->mbox_lock);
                        return -FW_CMD_RETVAL_G(v);
                }
        }
        /* We timed out.  Return the error ... */
        ret = -ETIMEDOUT;
        t4vf_record_mbox(adapter, cmd, size, access, ret);
+       spin_lock(&adapter->mbox_lock);
+       list_del(&entry.list);
+       spin_unlock(&adapter->mbox_lock);
        return ret;
 }