!test_bit(IONIC_LIF_F_FW_RESET, lif->state))
                ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
 
-       if (test_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state)) {
+       if (test_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state) &&
+           !test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
                work = kzalloc(sizeof(*work), GFP_ATOMIC);
                if (!work) {
                        netdev_err(lif->netdev, "rxmode change dropped\n");
 
 int ionic_heartbeat_check(struct ionic *ionic)
 {
-       struct ionic_dev *idev = &ionic->idev;
        unsigned long check_time, last_check_time;
+       struct ionic_dev *idev = &ionic->idev;
+       struct ionic_lif *lif = ionic->lif;
        bool fw_status_ready = true;
        bool fw_hb_ready;
        u8 fw_generation;
                         * the down, the next watchdog will see the fw is up
                         * and the generation value stable, so will trigger
                         * the fw-up activity.
+                        *
+                        * If we had already moved to FW_RESET from a RESET event,
+                        * it is possible that we never saw the fw_status go to 0,
+                        * so we fake the current idev->fw_status_ready here to
+                        * force the transition and get FW up again.
                         */
-                       fw_status_ready = false;
+                       if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
+                               idev->fw_status_ready = false;  /* go to running */
+                       else
+                               fw_status_ready = false;        /* go to down */
                }
        }
 
        /* is this a transition? */
        if (fw_status_ready != idev->fw_status_ready) {
-               struct ionic_lif *lif = ionic->lif;
                bool trigger = false;
 
                if (!fw_status_ready && lif &&
 
                ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
                break;
        case IONIC_EVENT_RESET:
-               work = kzalloc(sizeof(*work), GFP_ATOMIC);
-               if (!work) {
-                       netdev_err(lif->netdev, "Reset event dropped\n");
-               } else {
-                       work->type = IONIC_DW_TYPE_LIF_RESET;
-                       ionic_lif_deferred_enqueue(&lif->deferred, work);
+               if (lif->ionic->idev.fw_status_ready &&
+                   !test_bit(IONIC_LIF_F_FW_RESET, lif->state) &&
+                   !test_and_set_bit(IONIC_LIF_F_FW_STOPPING, lif->state)) {
+                       work = kzalloc(sizeof(*work), GFP_ATOMIC);
+                       if (!work) {
+                               netdev_err(lif->netdev, "Reset event dropped\n");
+                               clear_bit(IONIC_LIF_F_FW_STOPPING, lif->state);
+                       } else {
+                               work->type = IONIC_DW_TYPE_LIF_RESET;
+                               ionic_lif_deferred_enqueue(&lif->deferred, work);
+                       }
                }
                break;
        default: