***************************************************************************/
 
 #define SPQ_HIGH_PRI_RESERVE_DEFAULT    (1)
-#define SPQ_BLOCK_SLEEP_LENGTH          (1000)
+
+#define SPQ_BLOCK_DELAY_MAX_ITER        (10)
+#define SPQ_BLOCK_DELAY_US              (10)
+#define SPQ_BLOCK_SLEEP_MAX_ITER        (1000)
+#define SPQ_BLOCK_SLEEP_MS              (5)
 
 /***************************************************************************
 * Blocking Imp. (BLOCK/EBLOCK mode)
        smp_wmb();
 }
 
-static int qed_spq_block(struct qed_hwfn *p_hwfn,
-                        struct qed_spq_entry *p_ent,
-                        u8 *p_fw_ret)
+static int __qed_spq_block(struct qed_hwfn *p_hwfn,
+                          struct qed_spq_entry *p_ent,
+                          u8 *p_fw_ret, bool sleep_between_iter)
 {
-       int sleep_count = SPQ_BLOCK_SLEEP_LENGTH;
        struct qed_spq_comp_done *comp_done;
-       int rc;
+       u32 iter_cnt;
 
        comp_done = (struct qed_spq_comp_done *)p_ent->comp_cb.cookie;
-       while (sleep_count) {
-               /* validate we receive completion update */
+       iter_cnt = sleep_between_iter ? SPQ_BLOCK_SLEEP_MAX_ITER
+                                     : SPQ_BLOCK_DELAY_MAX_ITER;
+
+       while (iter_cnt--) {
+               /* Validate we receive completion update */
                smp_rmb();
                if (comp_done->done == 1) {
                        if (p_fw_ret)
                                *p_fw_ret = comp_done->fw_return_code;
                        return 0;
                }
-               usleep_range(5000, 10000);
-               sleep_count--;
+
+               if (sleep_between_iter)
+                       msleep(SPQ_BLOCK_SLEEP_MS);
+               else
+                       udelay(SPQ_BLOCK_DELAY_US);
        }
 
+       return -EBUSY;
+}
+
+static int qed_spq_block(struct qed_hwfn *p_hwfn,
+                        struct qed_spq_entry *p_ent,
+                        u8 *p_fw_ret, bool skip_quick_poll)
+{
+       struct qed_spq_comp_done *comp_done;
+       int rc;
+
+       /* A relatively short polling period w/o sleeping, to allow the FW to
+        * complete the ramrod and thus possibly to avoid the following sleeps.
+        */
+       if (!skip_quick_poll) {
+               rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, false);
+               if (!rc)
+                       return 0;
+       }
+
+       /* Move to polling with a sleeping period between iterations */
+       rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true);
+       if (!rc)
+               return 0;
+
        DP_INFO(p_hwfn, "Ramrod is stuck, requesting MCP drain\n");
        rc = qed_mcp_drain(p_hwfn, p_hwfn->p_main_ptt);
-       if (rc != 0)
+       if (rc) {
                DP_NOTICE(p_hwfn, "MCP drain failed\n");
+               goto err;
+       }
 
        /* Retry after drain */
-       sleep_count = SPQ_BLOCK_SLEEP_LENGTH;
-       while (sleep_count) {
-               /* validate we receive completion update */
-               smp_rmb();
-               if (comp_done->done == 1) {
-                       if (p_fw_ret)
-                               *p_fw_ret = comp_done->fw_return_code;
-                       return 0;
-               }
-               usleep_range(5000, 10000);
-               sleep_count--;
-       }
+       rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true);
+       if (!rc)
+               return 0;
 
+       comp_done = (struct qed_spq_comp_done *)p_ent->comp_cb.cookie;
        if (comp_done->done == 1) {
                if (p_fw_ret)
                        *p_fw_ret = comp_done->fw_return_code;
                return 0;
        }
-
-       DP_NOTICE(p_hwfn, "Ramrod is stuck, MCP drain failed\n");
+err:
+       DP_NOTICE(p_hwfn,
+                 "Ramrod is stuck [CID %08x cmd %02x protocol %02x echo %04x]\n",
+                 le32_to_cpu(p_ent->elem.hdr.cid),
+                 p_ent->elem.hdr.cmd_id,
+                 p_ent->elem.hdr.protocol_id,
+                 le16_to_cpu(p_ent->elem.hdr.echo));
 
        return -EBUSY;
 }
                 * access p_ent here to see whether it's successful or not.
                 * Thus, after gaining the answer perform the cleanup here.
                 */
-               rc = qed_spq_block(p_hwfn, p_ent, fw_return_code);
+               rc = qed_spq_block(p_hwfn, p_ent, fw_return_code,
+                                  p_ent->queue == &p_spq->unlimited_pending);
 
                if (p_ent->queue == &p_spq->unlimited_pending) {
                        /* This is an allocated p_ent which does not need to