ieee80211_iter_keys(mld->hw, vif, iwl_mld_cleanup_keys_iter, NULL);
 
+       wiphy_delayed_work_cancel(mld->wiphy, &mld_vif->mlo_scan_start_wk);
+
        CLEANUP_STRUCT(mld_vif);
 }
 
        return iwl_mld_send_mac_cmd(mld, &cmd);
 }
 
+static void iwl_mld_mlo_scan_start_wk(struct wiphy *wiphy,
+                                     struct wiphy_work *wk)
+{
+       struct iwl_mld_vif *mld_vif = container_of(wk, struct iwl_mld_vif,
+                                                  mlo_scan_start_wk.work);
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
+
+       iwl_mld_int_mlo_scan(mld, iwl_mld_vif_to_mac80211(mld_vif));
+}
+
 IWL_MLD_ALLOC_FN(vif, vif)
 
 /* Constructor function for struct iwl_mld_vif */
                                        iwl_mld_emlsr_prevent_done_wk);
                wiphy_delayed_work_init(&mld_vif->emlsr.tmp_non_bss_done_wk,
                                        iwl_mld_emlsr_tmp_non_bss_done_wk);
+               wiphy_delayed_work_init(&mld_vif->mlo_scan_start_wk,
+                                       iwl_mld_mlo_scan_start_wk);
        }
        iwl_mld_init_internal_sta(&mld_vif->aux_sta);
 
 
  * @low_latency_causes: bit flags, indicating the causes for low-latency,
  *     see @iwl_mld_low_latency_cause.
  * @ps_disabled: indicates that PS is disabled for this interface
+ * @last_link_activation_time: last time a link was activated, for
+ *     deferring MLO scans (to make them more reliable)
  * @mld: pointer to the mld structure.
  * @deflink: default link data, for use in non-MLO,
  * @link: reference to link data for each valid link, for use in MLO.
  * @roc_activity: the id of the roc_activity running. Relevant for STA and
  *     p2p device only. Set to %ROC_NUM_ACTIVITIES when not in use.
  * @aux_sta: station used for remain on channel. Used in P2P device.
+ * @mlo_scan_start_wk: worker to start a deferred MLO scan
  */
 struct iwl_mld_vif {
        /* Add here fields that need clean up on restart */
 #endif
                u8 low_latency_causes;
                bool ps_disabled;
+               time64_t last_link_activation_time;
        );
        /* And here fields that survive a fw restart */
        struct iwl_mld *mld;
 #endif
        enum iwl_roc_activity roc_activity;
        struct iwl_mld_int_sta aux_sta;
+
+       struct wiphy_delayed_work mlo_scan_start_wk;
 };
 
 static inline struct iwl_mld_vif *
        return (void *)vif->drv_priv;
 }
 
+static inline struct ieee80211_vif *
+iwl_mld_vif_to_mac80211(struct iwl_mld_vif *mld_vif)
+{
+       return container_of((void *)mld_vif, struct ieee80211_vif, drv_priv);
+}
+
 #define iwl_mld_link_dereference_check(mld_vif, link_id)               \
        rcu_dereference_check((mld_vif)->link[link_id],                 \
                              lockdep_is_held(&mld_vif->mld->wiphy->mtx))
 
                          struct ieee80211_bss_conf *link)
 {
        struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link);
+       struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(mld_link->vif);
        int ret;
 
        lockdep_assert_wiphy(mld->wiphy);
                                        LINK_CONTEXT_MODIFY_ACTIVE);
        if (ret)
                mld_link->active = false;
+       else
+               mld_vif->last_link_activation_time =
+                       ktime_get_boottime_seconds();
 
        return ret;
 }
 
        IWL_DEBUG_SCAN(mld, "Internal MLO scan: ret=%d\n", ret);
 }
 
+#define IWL_MLD_MLO_SCAN_BLOCKOUT_TIME         5 /* seconds */
+
 void iwl_mld_int_mlo_scan(struct iwl_mld *mld, struct ieee80211_vif *vif)
 {
        struct ieee80211_channel *channels[IEEE80211_MLD_MAX_NUM_LINKS];
+       struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
        unsigned long usable_links = ieee80211_vif_usable_links(vif);
        size_t n_channels = 0;
        u8 link_id;
                return;
        }
 
+       if (mld_vif->last_link_activation_time > ktime_get_boottime_seconds() -
+                                                IWL_MLD_MLO_SCAN_BLOCKOUT_TIME) {
+               /* timing doesn't matter much, so use the blockout time */
+               wiphy_delayed_work_queue(mld->wiphy,
+                                        &mld_vif->mlo_scan_start_wk,
+                                        IWL_MLD_MLO_SCAN_BLOCKOUT_TIME);
+               return;
+       }
+
        for_each_set_bit(link_id, &usable_links, IEEE80211_MLD_MAX_NUM_LINKS) {
                struct ieee80211_bss_conf *link_conf =
                        link_conf_dereference_check(vif, link_id);