static void log_physical_state(struct hfi1_pportdata *ppd, u32 state);
 static int wait_physical_linkstate(struct hfi1_pportdata *ppd, u32 state,
                                   int msecs);
+static int wait_phys_link_out_of_offline(struct hfi1_pportdata *ppd,
+                                        int msecs);
 static void read_planned_down_reason_code(struct hfi1_devdata *dd, u8 *pdrrc);
 static void read_link_down_reason(struct hfi1_devdata *dd, u8 *ldr);
 static void handle_temp_err(struct hfi1_devdata *dd);
                        break;
 
                ppd->port_error_action = 0;
-               ppd->host_link_state = HLS_DN_POLL;
 
                if (quick_linkup) {
                        /* quick linkup does not go into polling */
                        ret = do_quick_linkup(dd);
                } else {
                        ret1 = set_physical_link_state(dd, PLS_POLLING);
+                       if (!ret1)
+                               ret1 = wait_phys_link_out_of_offline(ppd,
+                                                                    3000);
                        if (ret1 != HCMD_SUCCESS) {
                                dd_dev_err(dd,
                                           "Failed to transition to Polling link state, return 0x%x\n",
                                ret = -EINVAL;
                        }
                }
+
+               /*
+                * Change the host link state after requesting DC8051 to
+                * change its physical state so that we can ignore any
+                * interrupt with stale LNI(XX) error, which will not be
+                * cleared until DC8051 transitions to Polling state.
+                */
+               ppd->host_link_state = HLS_DN_POLL;
                ppd->offline_disabled_reason =
                        HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE);
                /*
        return read_state;
 }
 
+/*
+ * wait_phys_link_out_of_offline - wait for any out of offline state
+ * @ppd: port device
+ * @msecs: the number of milliseconds to wait
+ *
+ * Wait up to msecs milliseconds for any out of offline physical link
+ * state change to occur.
+ * Returns 0 if at least one state is reached, otherwise -ETIMEDOUT.
+ */
+static int wait_phys_link_out_of_offline(struct hfi1_pportdata *ppd,
+                                        int msecs)
+{
+       u32 read_state;
+       unsigned long timeout;
+
+       timeout = jiffies + msecs_to_jiffies(msecs);
+       while (1) {
+               read_state = read_physical_state(ppd->dd);
+               if ((read_state & 0xF0) != PLS_OFFLINE)
+                       break;
+               if (time_after(jiffies, timeout)) {
+                       dd_dev_err(ppd->dd,
+                                  "timeout waiting for phy link out of offline. Read state 0x%x, %dms\n",
+                                  read_state, msecs);
+                       return -ETIMEDOUT;
+               }
+               usleep_range(1950, 2050); /* sleep 2ms-ish */
+       }
+
+       log_state_transition(ppd, read_state);
+       return read_state;
+}
+
 #define CLEAR_STATIC_RATE_CONTROL_SMASK(r) \
 (r &= ~SEND_CTXT_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK)