__IAVF_RUNNING,         /* opened, working */
 };
 
+enum iavf_critical_section_t {
+       __IAVF_IN_REMOVE_TASK,  /* device being removed */
+};
+
 #define IAVF_CLOUD_FIELD_OMAC          0x01
 #define IAVF_CLOUD_FIELD_IMAC          0x02
 #define IAVF_CLOUD_FIELD_IVLAN 0x04
 
                                   msecs_to_jiffies(1));
                return;
        case __IAVF_INIT_FAILED:
+               if (test_bit(__IAVF_IN_REMOVE_TASK,
+                            &adapter->crit_section)) {
+                       /* Do not update the state and do not reschedule
+                        * watchdog task, iavf_remove should handle this state
+                        * as it can loop forever
+                        */
+                       mutex_unlock(&adapter->crit_lock);
+                       return;
+               }
                if (++adapter->aq_wait_count > IAVF_AQ_MAX_ERR) {
                        dev_err(&adapter->pdev->dev,
                                "Failed to communicate with PF; waiting before retry\n");
                queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ);
                return;
        case __IAVF_COMM_FAILED:
+               if (test_bit(__IAVF_IN_REMOVE_TASK,
+                            &adapter->crit_section)) {
+                       /* Set state to __IAVF_INIT_FAILED and perform remove
+                        * steps. Remove IAVF_FLAG_PF_COMMS_FAILED so the task
+                        * doesn't bring the state back to __IAVF_COMM_FAILED.
+                        */
+                       iavf_change_state(adapter, __IAVF_INIT_FAILED);
+                       adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED;
+                       mutex_unlock(&adapter->crit_lock);
+                       return;
+               }
                reg_val = rd32(hw, IAVF_VFGEN_RSTAT) &
                          IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
                if (reg_val == VIRTCHNL_VFR_VFACTIVE ||
        struct iavf_hw *hw = &adapter->hw;
        int err;
 
+       set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
        /* Wait until port initialization is complete.
         * There are flows where register/unregister netdev may race.
         */
        while (1) {
                mutex_lock(&adapter->crit_lock);
                if (adapter->state == __IAVF_RUNNING ||
-                   adapter->state == __IAVF_DOWN) {
+                   adapter->state == __IAVF_DOWN ||
+                   adapter->state == __IAVF_INIT_FAILED) {
                        mutex_unlock(&adapter->crit_lock);
                        break;
                }