}
 
 static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
-                                        struct ieee80211_vif *vif)
+                                        struct ieee80211_vif *vif,
+                                        struct iwl_mvm_vif_link_info *mvm_link)
 {
-       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TSC_RSC_PARAM,
                                        IWL_FW_CMD_VER_UNKNOWN);
        int ret;
                for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++)
                        data.rsc->mcast_key_id_map[i] =
                                IWL_MCAST_KEY_MAP_INVALID;
-               data.rsc->sta_id = cpu_to_le32(mvmvif->deflink.ap_sta_id);
+               data.rsc->sta_id = cpu_to_le32(mvm_link->ap_sta_id);
 
                ieee80211_iter_keys(mvm->hw, vif,
                                    iwl_mvm_wowlan_get_rsc_v5_data,
                if (ver == 4) {
                        size = sizeof(*data.rsc_tsc);
                        data.rsc_tsc->sta_id =
-                               cpu_to_le32(mvmvif->deflink.ap_sta_id);
+                               cpu_to_le32(mvm_link->ap_sta_id);
                } else {
                        /* ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN */
                        size = sizeof(data.rsc_tsc->params);
 }
 
 static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
-                                struct ieee80211_vif *vif,
+                                struct iwl_mvm_vif_link_info *mvm_link,
                                 struct cfg80211_wowlan *wowlan)
 {
-       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct iwl_wowlan_patterns_cmd *pattern_cmd;
        struct iwl_host_cmd cmd = {
                .id = WOWLAN_PATTERNS,
 
        pattern_cmd->n_patterns = wowlan->n_patterns;
        if (ver >= 3)
-               pattern_cmd->sta_id = mvmvif->deflink.ap_sta_id;
+               pattern_cmd->sta_id = mvm_link->ap_sta_id;
 
        for (i = 0; i < wowlan->n_patterns; i++) {
                int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
        struct iwl_time_quota_data *quota;
        u32 status;
 
-       if (WARN_ON_ONCE(iwl_mvm_is_cdb_supported(mvm)))
+       if (WARN_ON_ONCE(iwl_mvm_is_cdb_supported(mvm) ||
+                        ieee80211_vif_is_mld(vif)))
                return -EINVAL;
 
        /* add back the PHY */
 }
 
 static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
-                                           struct ieee80211_vif *vif)
+                                           struct ieee80211_vif *vif,
+                                           struct iwl_mvm_vif_link_info *mvm_link)
 {
        bool unified = fw_has_capa(&mvm->fw->ucode_capa,
                                   IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
                        return -EIO;
        }
 
-       ret = iwl_mvm_wowlan_config_rsc_tsc(mvm, vif);
+       ret = iwl_mvm_wowlan_config_rsc_tsc(mvm, vif, mvm_link);
        if (ret)
                return ret;
 
                if (ver == 2) {
                        size = sizeof(tkip_data.tkip);
                        tkip_data.tkip.sta_id =
-                               cpu_to_le32(mvmvif->deflink.ap_sta_id);
+                               cpu_to_le32(mvm_link->ap_sta_id);
                } else if (ver == 1 || ver == IWL_FW_CMD_VER_UNKNOWN) {
                        size = sizeof(struct iwl_wowlan_tkip_params_cmd_ver_1);
                } else {
                kek_kck_cmd.kek_len = cpu_to_le16(mvmvif->rekey_data.kek_len);
                kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr;
                kek_kck_cmd.akm = cpu_to_le32(mvmvif->rekey_data.akm);
-               kek_kck_cmd.sta_id = cpu_to_le32(mvmvif->deflink.ap_sta_id);
+               kek_kck_cmd.sta_id = cpu_to_le32(mvm_link->ap_sta_id);
 
                if (cmd_ver == 4) {
                        cmd_size = sizeof(struct iwl_wowlan_kek_kck_material_cmd_v4);
                      struct cfg80211_wowlan *wowlan,
                      struct iwl_wowlan_config_cmd *wowlan_config_cmd,
                      struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
+                     struct iwl_mvm_vif_link_info *mvm_link,
                      struct ieee80211_sta *ap_sta)
 {
        int ret;
                        return ret;
        }
 
-       ret = iwl_mvm_wowlan_config_key_params(mvm, vif);
+       ret = iwl_mvm_wowlan_config_key_params(mvm, vif, mvm_link);
        if (ret)
                return ret;
 
 
        if (fw_has_api(&mvm->fw->ucode_capa,
                       IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE))
-               ret = iwl_mvm_send_patterns(mvm, vif, wowlan);
+               ret = iwl_mvm_send_patterns(mvm, mvm_link, wowlan);
        else
                ret = iwl_mvm_send_patterns_v1(mvm, wowlan);
        if (ret)
        struct ieee80211_vif *vif = NULL;
        struct iwl_mvm_vif *mvmvif = NULL;
        struct ieee80211_sta *ap_sta = NULL;
+       struct iwl_mvm_vif_link_info *mvm_link;
        struct iwl_d3_manager_config d3_cfg_cmd_data = {
                /*
                 * Program the minimum sleep time to 10 seconds, as many
                .data[0] = &d3_cfg_cmd_data,
                .len[0] = sizeof(d3_cfg_cmd_data),
        };
-       int ret;
+       int ret, primary_link;
        int len __maybe_unused;
        bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
                                         IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
                return -EINVAL;
        }
 
+       vif = iwl_mvm_get_bss_vif(mvm);
+       if (IS_ERR_OR_NULL(vif))
+               return 1;
+
+       if (ieee80211_vif_is_mld(vif) && vif->cfg.assoc) {
+               /*
+                * Select the 'best' link. May need to revisit, it seems
+                * better to not optimize for throughput but rather range,
+                * reliability and power here - and select 2.4 GHz ...
+                */
+               primary_link =
+                       iwl_mvm_mld_get_primary_link(mvm, vif,
+                                                    vif->active_links);
+
+               if (WARN_ONCE(primary_link < 0, "no primary link in 0x%x\n",
+                             vif->active_links))
+                       primary_link = __ffs(vif->active_links);
+
+               ret = ieee80211_set_active_links(vif, BIT(primary_link));
+               if (ret)
+                       return ret;
+       } else {
+               primary_link = 0;
+       }
+
        mutex_lock(&mvm->mutex);
 
        set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
 
        synchronize_net();
 
-       vif = iwl_mvm_get_bss_vif(mvm);
-       if (IS_ERR_OR_NULL(vif)) {
-               ret = 1;
-               goto out_noreset;
-       }
-
        mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-       if (mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA) {
+       mvm_link = mvmvif->link[primary_link];
+       if (WARN_ON_ONCE(!mvm_link))
+               return -EINVAL;
+
+       if (mvm_link->ap_sta_id == IWL_MVM_INVALID_STA) {
                /* if we're not associated, this must be netdetect */
                if (!wowlan->nd_config) {
                        ret = 1;
        } else {
                struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
 
-               wowlan_config_cmd.sta_id = mvmvif->deflink.ap_sta_id;
+               wowlan_config_cmd.sta_id = mvm_link->ap_sta_id;
 
                ap_sta = rcu_dereference_protected(
-                       mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id],
+                       mvm->fw_id_to_mac_id[mvm_link->ap_sta_id],
                        lockdep_is_held(&mvm->mutex));
                if (IS_ERR_OR_NULL(ap_sta)) {
                        ret = -EINVAL;
                if (ret)
                        goto out_noreset;
                ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd,
-                                           vif, mvmvif, ap_sta);
+                                           vif, mvmvif, mvm_link, ap_sta);
                if (ret)
                        goto out;
 
                u8 sta_id = mvm->net_detect ? IWL_MVM_INVALID_STA :
                                              mvmvif->deflink.ap_sta_id;
 
+               /* bug - FW with MLO has status notification */
+               WARN_ON(ieee80211_vif_is_mld(vif));
+
                d3_data->status = iwl_mvm_send_wowlan_get_status(mvm, sta_id);
        }