/*
  * Copyright (C) 2012-2014, 2020 Intel Corporation
  * Copyright (C) 2016 Intel Deutschland GmbH
+ * Copyright (C) 2022 Intel Corporation
  */
 #include <net/mac80211.h>
 #include "fw-api.h"
        if (vif == data->ignore_vif)
                return;
 
-       if (mvmvif->phy_ctxt != data->phyctxt)
+       if (mvmvif->deflink.phy_ctxt != data->phyctxt)
                return;
 
        if (WARN_ON_ONCE(data->idx >= MAX_MACS_IN_BINDING))
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-       if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
+       if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt))
                return -EINVAL;
 
        /*
        if (iwl_mvm_sf_update(mvm, vif, false))
                return -EINVAL;
 
-       return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, true);
+       return iwl_mvm_binding_update(mvm, vif, mvmvif->deflink.phy_ctxt,
+                                     true);
 }
 
 int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        int ret;
 
-       if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
+       if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt))
                return -EINVAL;
 
-       ret = iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, false);
+       ret = iwl_mvm_binding_update(mvm, vif, mvmvif->deflink.phy_ctxt,
+                                    false);
 
        if (!ret)
                if (iwl_mvm_sf_update(mvm, vif, true))
 
                        /* ... relax constraints and disable rssi events */
                        iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
                                            smps_mode);
-                       iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
+                       iwl_mvm_bt_coex_reduced_txp(mvm,
+                                                   mvmvif->deflink.ap_sta_id,
                                                    false);
                        iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
                }
        if (!vif->cfg.assoc)
                smps_mode = IEEE80211_SMPS_AUTOMATIC;
 
-       if (mvmvif->phy_ctxt &&
-           (mvm->last_bt_notif.rrc_status & BIT(mvmvif->phy_ctxt->id)))
+       if (mvmvif->deflink.phy_ctxt &&
+           (mvm->last_bt_notif.rrc_status & BIT(mvmvif->deflink.phy_ctxt->id)))
                smps_mode = IEEE80211_SMPS_AUTOMATIC;
 
        IWL_DEBUG_COEX(data->mvm,
        if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT ||
            mvm->cfg->bt_shared_single_ant || !vif->cfg.assoc ||
            le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF) {
-               iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false);
+               iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->deflink.ap_sta_id,
+                                           false);
                iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
                return;
        }
        if (!ave_rssi)
                ave_rssi = -100;
        if (ave_rssi > -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH) {
-               if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true))
+               if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->deflink.ap_sta_id,
+                                               true))
                        IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
        } else if (ave_rssi < -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH) {
-               if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
+               if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->deflink.ap_sta_id,
+                                               false))
                        IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
        }
 
         * Rssi update while not associated - can happen since the statistics
         * are handled asynchronously
         */
-       if (mvmvif->ap_sta_id == IWL_MVM_INVALID_STA)
+       if (mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA)
                return;
 
        /* No BT - reports should be disabled */
         */
        if (rssi_event == RSSI_EVENT_LOW || mvm->cfg->bt_shared_single_ant ||
            iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT)
-               ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
+               ret = iwl_mvm_bt_coex_reduced_txp(mvm,
+                                                 mvmvif->deflink.ap_sta_id,
                                                  false);
        else
-               ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true);
+               ret = iwl_mvm_bt_coex_reduced_txp(mvm,
+                                                 mvmvif->deflink.ap_sta_id,
+                                                 true);
 
        if (ret)
                IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n");
 {
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
-       struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
+       struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->deflink.phy_ctxt;
        enum iwl_bt_coex_lut_type lut_type;
 
        if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id))
 {
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
-       struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
+       struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->deflink.phy_ctxt;
        enum iwl_bt_coex_lut_type lut_type;
 
        if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id))
 
                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->ap_sta_id);
+               data.rsc->sta_id = cpu_to_le32(mvmvif->deflink.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->ap_sta_id);
+                       data.rsc_tsc->sta_id =
+                               cpu_to_le32(mvmvif->deflink.ap_sta_id);
                } else {
                        /* ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN */
                        size = sizeof(data.rsc_tsc->params);
 
        pattern_cmd->n_patterns = wowlan->n_patterns;
        if (ver >= 3)
-               pattern_cmd->sta_id = mvmvif->ap_sta_id;
+               pattern_cmd->sta_id = mvmvif->deflink.ap_sta_id;
 
        for (i = 0; i < wowlan->n_patterns; i++) {
                int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
                return -EINVAL;
 
        /* add back the PHY */
-       if (WARN_ON(!mvmvif->phy_ctxt))
+       if (WARN_ON(!mvmvif->deflink.phy_ctxt))
                return -EINVAL;
 
        rcu_read_lock();
        chains_dynamic = ctx->rx_chains_dynamic;
        rcu_read_unlock();
 
-       ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt, &chandef,
+       ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt, &chandef,
                                   chains_static, chains_dynamic);
        if (ret)
                return ret;
 
        /* add back binding - XXX refactor? */
        binding_cmd.id_and_color =
-               cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
-                                               mvmvif->phy_ctxt->color));
+               cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
+                                               mvmvif->deflink.phy_ctxt->color));
        binding_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
        binding_cmd.phy =
-               cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
-                                               mvmvif->phy_ctxt->color));
+               cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
+                                               mvmvif->deflink.phy_ctxt->color));
        binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
                                                              mvmvif->color));
        for (i = 1; i < MAX_MACS_IN_BINDING; i++)
        ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false, 0);
        if (ret)
                return ret;
-       rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
+       rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id],
+                          ap_sta);
 
        ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
        if (ret)
        /* and some quota */
        quota = iwl_mvm_quota_cmd_get_quota(mvm, "a_cmd, 0);
        quota->id_and_color =
-               cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
-                                               mvmvif->phy_ctxt->color));
+               cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
+                                               mvmvif->deflink.phy_ctxt->color));
        quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
        quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
 
                if (ver == 2) {
                        size = sizeof(tkip_data.tkip);
                        tkip_data.tkip.sta_id =
-                               cpu_to_le32(mvmvif->ap_sta_id);
+                               cpu_to_le32(mvmvif->deflink.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->ap_sta_id);
+               kek_kck_cmd.sta_id = cpu_to_le32(mvmvif->deflink.ap_sta_id);
 
                if (cmd_ver == 4) {
                        cmd_size = sizeof(struct iwl_wowlan_kek_kck_material_cmd_v4);
 
        mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-       if (mvmvif->ap_sta_id == IWL_MVM_INVALID_STA) {
+       if (mvmvif->deflink.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->ap_sta_id;
+               wowlan_config_cmd.sta_id = mvmvif->deflink.ap_sta_id;
 
                ap_sta = rcu_dereference_protected(
-                       mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
+                       mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id],
                        lockdep_is_held(&mvm->mutex));
                if (IS_ERR_OR_NULL(ap_sta)) {
                        ret = -EINVAL;
        /* if FW uses status notification, status shouldn't be NULL here */
        if (!d3_data->status) {
                struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-               u8 sta_id = mvm->net_detect ? IWL_MVM_INVALID_STA : mvmvif->ap_sta_id;
+               u8 sta_id = mvm->net_detect ? IWL_MVM_INVALID_STA :
+                                             mvmvif->deflink.ap_sta_id;
 
                d3_data->status = iwl_mvm_send_wowlan_get_status(mvm, sta_id);
        }
 
 
        mutex_lock(&mvm->mutex);
 
-       ap_sta_id = mvmvif->ap_sta_id;
+       ap_sta_id = mvmvif->deflink.ap_sta_id;
 
        switch (ieee80211_vif_type_p2p(vif)) {
        case NL80211_IFTYPE_ADHOC:
        pos += scnprintf(buf+pos, bufsz-pos, "Load: %d\n",
                         mvm->tcm.result.load[mvmvif->id]);
        pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
-       for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++)
+       for (i = 0; i < ARRAY_SIZE(mvmvif->deflink.queue_params); i++)
                pos += scnprintf(buf+pos, bufsz-pos,
                                 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
-                                i, mvmvif->queue_params[i].txop,
-                                mvmvif->queue_params[i].cw_min,
-                                mvmvif->queue_params[i].cw_max,
-                                mvmvif->queue_params[i].aifs,
-                                mvmvif->queue_params[i].uapsd);
+                                i, mvmvif->deflink.queue_params[i].txop,
+                                mvmvif->deflink.queue_params[i].cw_min,
+                                mvmvif->deflink.queue_params[i].cw_max,
+                                mvmvif->deflink.queue_params[i].aifs,
+                                mvmvif->deflink.queue_params[i].uapsd);
 
        if (vif->type == NL80211_IFTYPE_STATION &&
            ap_sta_id != IWL_MVM_INVALID_STA) {
 
                struct ieee80211_sta *sta;
 
                rcu_read_lock();
-               sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id]);
+               sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id]);
                if (!IS_ERR_OR_NULL(sta) && sta->mfp)
                        expected_tk_len = 0;
                rcu_read_unlock();
 
                rcu_read_lock();
 
-               sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id]);
+               sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id]);
                if (sta->mfp && (peer->ftm.trigger_based || peer->ftm.non_trigger_based))
                        FTM_PUT_FLAG(PMF);
 
                rcu_read_unlock();
 
-               target->sta_id = mvmvif->ap_sta_id;
+               target->sta_id = mvmvif->deflink.ap_sta_id;
        } else {
                target->sta_id = IWL_MVM_INVALID_STA;
        }
 
                        cpu_to_le32(IWL_TOF_RESPONDER_CMD_VALID_CHAN_INFO |
                                    IWL_TOF_RESPONDER_CMD_VALID_BSSID |
                                    IWL_TOF_RESPONDER_CMD_VALID_STA_ID),
-               .sta_id = mvmvif->bcast_sta.sta_id,
+               .sta_id = mvmvif->deflink.bcast_sta.sta_id,
        };
        u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 6);
        int err;
 
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct iwl_link_config_cmd cmd = {};
 
-       if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
+       if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt))
                return -EINVAL;
 
        /* Update SF - Disable if needed. if this fails, SF might still be on
        if (iwl_mvm_sf_update(mvm, vif, false))
                return -EINVAL;
 
-       cmd.link_id = cpu_to_le32(mvmvif->phy_ctxt->id);
+       cmd.link_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id);
        cmd.mac_id = cpu_to_le32(mvmvif->id);
-       cmd.phy_id = cpu_to_le32(mvmvif->phy_ctxt->id);
+       cmd.phy_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id);
 
        memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN);
 
                         u32 changes, bool active)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       struct iwl_mvm_phy_ctxt *phyctxt = mvmvif->phy_ctxt;
+       struct iwl_mvm_phy_ctxt *phyctxt = mvmvif->deflink.phy_ctxt;
        struct iwl_link_config_cmd cmd = {};
        u32 ht_flag, flags = 0, flags_mask = 0;
 
        cmd.frame_time_rts_th = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
 
        /* Block 26-tone RU OFDMA transmissions */
-       if (mvmvif->he_ru_2mhz_block) {
+       if (mvmvif->deflink.he_ru_2mhz_block) {
                flags |= LINK_FLG_RU_2MHZ_BLOCK;
                flags_mask |= LINK_FLG_RU_2MHZ_BLOCK;
        }
        struct iwl_link_config_cmd cmd = {};
        int ret;
 
-       if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
+       if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt))
                return -EINVAL;
 
-       cmd.link_id = cpu_to_le32(mvmvif->phy_ctxt->id);
+       cmd.link_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id);
        ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE);
 
        if (!ret)
 
                 * For TVQM this will be overwritten later with the FW assigned
                 * queue value (when queue is enabled).
                 */
-               mvmvif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
+               mvmvif->deflink.cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
        }
 
-       mvmvif->bcast_sta.sta_id = IWL_MVM_INVALID_STA;
-       mvmvif->mcast_sta.sta_id = IWL_MVM_INVALID_STA;
-       mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
+       mvmvif->deflink.bcast_sta.sta_id = IWL_MVM_INVALID_STA;
+       mvmvif->deflink.mcast_sta.sta_id = IWL_MVM_INVALID_STA;
+       mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA;
 
        for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++)
-               mvmvif->smps_requests[i] = IEEE80211_SMPS_AUTOMATIC;
+               mvmvif->deflink.smps_requests[i] = IEEE80211_SMPS_AUTOMATIC;
 
        return 0;
 
                u8 ucode_ac = iwl_mvm_mac80211_ac_to_ucode_ac(i);
 
                ac[ucode_ac].cw_min =
-                       cpu_to_le16(mvmvif->queue_params[i].cw_min);
+                       cpu_to_le16(mvmvif->deflink.queue_params[i].cw_min);
                ac[ucode_ac].cw_max =
-                       cpu_to_le16(mvmvif->queue_params[i].cw_max);
+                       cpu_to_le16(mvmvif->deflink.queue_params[i].cw_max);
                ac[ucode_ac].edca_txop =
-                       cpu_to_le16(mvmvif->queue_params[i].txop * 32);
-               ac[ucode_ac].aifsn = mvmvif->queue_params[i].aifs;
+                       cpu_to_le16(mvmvif->deflink.queue_params[i].txop * 32);
+               ac[ucode_ac].aifsn = mvmvif->deflink.queue_params[i].aifs;
                ac[ucode_ac].fifos_mask = BIT(txf);
        }
 
 
        /* Set up TX command fields */
        tx->len = cpu_to_le16((u16)beacon->len);
-       tx->sta_id = mvmvif->bcast_sta.sta_id;
+       tx->sta_id = mvmvif->deflink.bcast_sta.sta_id;
        tx->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
        tx_flags = TX_CMD_FLG_SEQ_CTL | TX_CMD_FLG_TSF;
        tx_flags |=
 
        if (!fw_has_api(&mvm->fw->ucode_capa,
                        IWL_UCODE_TLV_API_STA_TYPE))
-               ctxt_ap->mcast_qid = cpu_to_le32(mvmvif->cab_queue);
+               ctxt_ap->mcast_qid = cpu_to_le32(mvmvif->deflink.cab_queue);
 
        /*
         * Only set the beacon time when the MAC is being added, when we
            sizeof(struct ieee80211_p2p_noa_desc) + 2)
                new_data->noa_len -= sizeof(struct ieee80211_p2p_noa_desc);
 
-       old_data = rcu_dereference_protected(mvmvif->probe_resp_data,
-                                       lockdep_is_held(&mvmvif->mvm->mutex));
-       rcu_assign_pointer(mvmvif->probe_resp_data, new_data);
+       old_data = rcu_dereference_protected(mvmvif->deflink.probe_resp_data,
+                                            lockdep_is_held(&mvmvif->mvm->mutex));
+       rcu_assign_pointer(mvmvif->deflink.probe_resp_data, new_data);
 
        if (old_data)
                kfree_rcu(old_data, rcu_head);
 
            !offchannel) {
                struct iwl_mvm_vif *mvmvif =
                        iwl_mvm_vif_from_mac80211(info->control.vif);
-               u8 ap_sta_id = READ_ONCE(mvmvif->ap_sta_id);
+               u8 ap_sta_id = READ_ONCE(mvmvif->deflink.ap_sta_id);
 
                if (ap_sta_id < mvm->fw->ucode_capa.num_stations) {
                        /* mac80211 holds rcu read lock */
 
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
-               if (iwl_mvm_vif_from_mac80211(vif)->ap_sta_id ==
+               if (iwl_mvm_vif_from_mac80211(vif)->deflink.ap_sta_id ==
                                iwl_mvm_sta_from_mac80211(sta)->sta_id) {
                        struct iwl_mvm_vif *mvmvif;
                        u16 macid = iwl_mvm_vif_from_mac80211(vif)->id;
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
        mvmvif->uploaded = false;
-       mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
+       mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA;
 
        spin_lock_bh(&mvm->time_event_lock);
        iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
        spin_unlock_bh(&mvm->time_event_lock);
 
-       mvmvif->phy_ctxt = NULL;
+       mvmvif->deflink.phy_ctxt = NULL;
        memset(&mvmvif->bf_data, 0, sizeof(mvmvif->bf_data));
-       memset(&mvmvif->probe_resp_data, 0, sizeof(mvmvif->probe_resp_data));
+       memset(&mvmvif->deflink.probe_resp_data, 0,
+              sizeof(mvmvif->deflink.probe_resp_data));
 }
 
 static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
 
                mvmvif->csa_bcn_pending = false;
                mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
-                                                         mvmvif->ap_sta_id);
+                                                         mvmvif->deflink.ap_sta_id);
 
                if (WARN_ON(!mvmsta)) {
                        ret = -EIO;
        lockdep_assert_held(&mvm->mutex);
 
        mvmvif->mvm = mvm;
-       RCU_INIT_POINTER(mvmvif->probe_resp_data, NULL);
+       RCU_INIT_POINTER(mvmvif->deflink.probe_resp_data, NULL);
+
+       /* the first link always points to the default one */
+       mvmvif->link[0] = &mvmvif->deflink;
 
        /*
         * Not much to do here. The stack will not allow interface
 
        /* make sure that beacon statistics don't go backwards with FW reset */
        if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
-               mvmvif->beacon_stats.accu_num_beacons +=
-                       mvmvif->beacon_stats.num_beacons;
+               mvmvif->deflink.beacon_stats.accu_num_beacons +=
+                       mvmvif->deflink.beacon_stats.num_beacons;
 
        /* Allocate resources for the MAC context, and add it to the fw  */
        *ret = iwl_mvm_mac_ctxt_init(mvm, vif);
        }
 
        mvmvif->features |= hw->netdev_features;
+
        return false;
 }
 
         * Only queue for this station is the mcast queue,
         * which shouldn't be in TFD mask anyway
         */
-       return iwl_mvm_allocate_int_sta(mvm, &mvmvif->mcast_sta, 0, vif->type,
+       return iwl_mvm_allocate_int_sta(mvm, &mvmvif->deflink.mcast_sta, 0,
+                                       vif->type,
                                        IWL_STA_MULTICAST);
 }
 
         */
        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
 
-               mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
-               if (!mvmvif->phy_ctxt) {
+               mvmvif->deflink.phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
+               if (!mvmvif->deflink.phy_ctxt) {
                        ret = -ENOSPC;
                        goto out_free_bf;
                }
 
-               iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
+               iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt);
                ret = iwl_mvm_binding_add_vif(mvm, vif);
                if (ret)
                        goto out_unref_phy;
  out_unbind:
        iwl_mvm_binding_remove_vif(mvm, vif);
  out_unref_phy:
-       iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
+       iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
  out_free_bf:
        if (mvm->bf_allowed_vif == mvmvif) {
                mvm->bf_allowed_vif = NULL;
                                       IEEE80211_VIF_SUPPORTS_CQM_RSSI);
        }
  out_remove_mac:
-       mvmvif->phy_ctxt = NULL;
+       mvmvif->deflink.phy_ctxt = NULL;
        iwl_mvm_mac_ctxt_remove(mvm, vif);
  out_unlock:
        mutex_unlock(&mvm->mutex);
                mvm->csme_vif = NULL;
        }
 
-       probe_data = rcu_dereference_protected(mvmvif->probe_resp_data,
+       probe_data = rcu_dereference_protected(mvmvif->deflink.probe_resp_data,
                                               lockdep_is_held(&mvm->mutex));
-       RCU_INIT_POINTER(mvmvif->probe_resp_data, NULL);
+       RCU_INIT_POINTER(mvmvif->deflink.probe_resp_data, NULL);
        if (probe_data)
                kfree_rcu(probe_data, rcu_head);
 
                mvm->p2p_device_vif = NULL;
                iwl_mvm_rm_p2p_bcast_sta(mvm, vif);
                iwl_mvm_binding_remove_vif(mvm, vif);
-               iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
-               mvmvif->phy_ctxt = NULL;
+               iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
+               mvmvif->deflink.phy_ctxt = NULL;
        }
 
        iwl_mvm_mac_ctxt_remove(mvm, vif);
 out:
        if (vif->type == NL80211_IFTYPE_AP ||
            vif->type == NL80211_IFTYPE_ADHOC) {
-               iwl_mvm_dealloc_int_sta(mvm, &mvmvif->mcast_sta);
+               iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta);
                iwl_mvm_dealloc_bcast_sta(mvm, vif);
        }
 
 
        for (i = 0; i < IEEE80211_NUM_ACS; i++) {
                struct ieee80211_he_mu_edca_param_ac_rec *mu_edca =
-                       &mvmvif->queue_params[i].mu_edca_param_rec;
+                       &mvmvif->deflink.queue_params[i].mu_edca_param_rec;
                u8 ac = iwl_mvm_mac80211_ac_to_ucode_ac(i);
 
-               if (!mvmvif->queue_params[i].mu_edca) {
+               if (!mvmvif->deflink.queue_params[i].mu_edca) {
                        mu_edca_enabled = false;
                        break;
                }
        flags = 0;
 
        /* Block 26-tone RU OFDMA transmissions */
-       if (mvmvif->he_ru_2mhz_block)
+       if (mvmvif->deflink.he_ru_2mhz_block)
                flags |= STA_CTXT_HE_RU_2MHZ_BLOCK;
 
        /* HTC flags */
                     !iwlwifi_mod_params.disable_11ax) ||
                    (vif->bss_conf.eht_support &&
                     !iwlwifi_mod_params.disable_11be))
-                       iwl_mvm_cfg_he_sta(mvm, vif, mvmvif->ap_sta_id);
+                       iwl_mvm_cfg_he_sta(mvm, vif, mvmvif->deflink.ap_sta_id);
 
                iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
        }
              !iwlwifi_mod_params.disable_11ax) ||
             (vif->bss_conf.eht_support &&
              !iwlwifi_mod_params.disable_11be)))
-               iwl_mvm_cfg_he_sta(mvm, vif, mvmvif->ap_sta_id);
+               iwl_mvm_cfg_he_sta(mvm, vif, mvmvif->deflink.ap_sta_id);
 
        /*
         * If we're not associated yet, take the (new) BSSID before associating
         * branch for disassociation below.
         */
        if (changes & BSS_CHANGED_BSSID && !mvmvif->associated)
-               memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
+               memcpy(mvmvif->deflink.bssid, bss_conf->bssid, ETH_ALEN);
 
-       ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->bssid);
+       ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->deflink.bssid);
        if (ret)
                IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
 
        /* after sending it once, adopt mac80211 data */
-       memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
+       memcpy(mvmvif->deflink.bssid, bss_conf->bssid, ETH_ALEN);
        mvmvif->associated = vif->cfg.assoc;
 
        if (changes & BSS_CHANGED_ASSOC) {
                if (vif->cfg.assoc) {
                        /* clear statistics to get clean beacon counter */
                        iwl_mvm_request_statistics(mvm, true);
-                       memset(&mvmvif->beacon_stats, 0,
-                              sizeof(mvmvif->beacon_stats));
+                       memset(&mvmvif->deflink.beacon_stats, 0,
+                              sizeof(mvmvif->deflink.beacon_stats));
 
                        /* add quota for this interface */
                        ret = iwl_mvm_update_quotas(mvm, true, NULL);
                                                    IWL_MVM_SMPS_REQ_PROT,
                                                    IEEE80211_SMPS_DYNAMIC);
                        }
-               } else if (mvmvif->ap_sta_id != IWL_MVM_INVALID_STA) {
+               } else if (mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
                        iwl_mvm_mei_host_disassociated(mvm);
                        /*
                         * If update fails - SF might be running in associated
                                 * the MAC is unassoc
                                 */
                                ret = iwl_mvm_rm_sta_id(mvm, vif,
-                                                       mvmvif->ap_sta_id);
+                                                       mvmvif->deflink.ap_sta_id);
                                if (ret)
                                        IWL_ERR(mvm,
                                                "failed to remove AP station\n");
 
-                               mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
+                               mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA;
                        }
 
                        /* remove quota for this interface */
        };
 
        if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR)) {
-               mvmvif->he_ru_2mhz_block = false;
+               mvmvif->deflink.he_ru_2mhz_block = false;
                return;
        }
 
         * If there is at least one AP on radar channel that cannot
         * tolerate 26-tone RU UL OFDMA transmissions using HE TB PPDU.
         */
-       mvmvif->he_ru_2mhz_block = !iter_data.tolerated;
+       mvmvif->deflink.he_ru_2mhz_block = !iter_data.tolerated;
 }
 
 static void iwl_mvm_reset_cca_40mhz_workaround(struct iwl_mvm *mvm,
                           sta->addr, old_state, new_state);
 
        /* this would be a mac80211 bug ... but don't crash */
-       if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
+       if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt))
                return test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) ? 0 : -EINVAL;
 
        /*
                } else if (vif->type == NL80211_IFTYPE_STATION) {
                        vif->bss_conf.he_support = sta->deflink.he_cap.has_he;
 
-                       mvmvif->he_ru_2mhz_block = false;
+                       mvmvif->deflink.he_ru_2mhz_block = false;
                        if (sta->deflink.he_cap.has_he)
                                iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif);
 
                        iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
                }
 
-               iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+               iwl_mvm_rs_rate_init(mvm, sta,
+                                    mvmvif->deflink.phy_ctxt->channel->band,
                                     false);
                ret = iwl_mvm_update_sta(mvm, vif, sta);
        } else if (old_state == IEEE80211_STA_ASSOC &&
                        iwl_mvm_mei_host_associated(mvm, vif, mvm_sta);
                }
 
-               iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+               iwl_mvm_rs_rate_init(mvm, sta,
+                                    mvmvif->deflink.phy_ctxt->channel->band,
                                     true);
        } else if (old_state == IEEE80211_STA_AUTHORIZED &&
                   new_state == IEEE80211_STA_ASSOC) {
                /* once we move into assoc state, need to update rate scale to
                 * disable using wide bandwidth
                 */
-               iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+               iwl_mvm_rs_rate_init(mvm, sta,
+                                    mvmvif->deflink.phy_ctxt->channel->band,
                                     false);
                if (!sta->tdls) {
                        /*
        if (changed & (IEEE80211_RC_BW_CHANGED |
                       IEEE80211_RC_SUPP_RATES_CHANGED |
                       IEEE80211_RC_NSS_CHANGED))
-               iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+               iwl_mvm_rs_rate_init(mvm, sta,
+                                    mvmvif->deflink.phy_ctxt->channel->band,
                                     true);
 
        if (vif->type == NL80211_IFTYPE_STATION &&
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-       mvmvif->queue_params[ac] = *params;
+       mvmvif->deflink.queue_params[ac] = *params;
 
        /*
         * No need to update right away, we'll get BSS_CHANGED_QOS
 
        for (i = 0; i < NUM_PHY_CTX; i++) {
                phy_ctxt = &mvm->phy_ctxts[i];
-               if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
+               if (phy_ctxt->ref == 0 || mvmvif->deflink.phy_ctxt == phy_ctxt)
                        continue;
 
                if (phy_ctxt->ref && channel == phy_ctxt->channel) {
                        if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
                                goto out_unlock;
 
-                       iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
+                       iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
 
                        /* Bind the P2P_DEVICE to the current PHY Context */
-                       mvmvif->phy_ctxt = phy_ctxt;
+                       mvmvif->deflink.phy_ctxt = phy_ctxt;
 
                        ret = iwl_mvm_binding_add_vif(mvm, vif);
                        if (WARN(ret, "Failed binding P2P_DEVICE\n"))
                                goto out_unlock;
 
-                       iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
+                       iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt);
                        goto schedule_time_event;
                }
        }
 
        /* Need to update the PHY context only if the ROC channel changed */
-       if (channel == mvmvif->phy_ctxt->channel)
+       if (channel == mvmvif->deflink.phy_ctxt->channel)
                goto schedule_time_event;
 
        cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
        band_change_removal =
                fw_has_capa(&mvm->fw->ucode_capa,
                            IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
-               mvmvif->phy_ctxt->channel->band != chandef.chan->band;
+               mvmvif->deflink.phy_ctxt->channel->band != chandef.chan->band;
 
-       if (mvmvif->phy_ctxt->ref == 1 && !band_change_removal) {
+       if (mvmvif->deflink.phy_ctxt->ref == 1 && !band_change_removal) {
                /*
                 * Change the PHY context configuration as it is currently
                 * referenced only by the P2P Device MAC (and we can modify it)
                 */
-               ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
+               ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->deflink.phy_ctxt,
                                               &chandef, 1, 1);
                if (ret)
                        goto out_unlock;
                if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
                        goto out_unlock;
 
-               iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
+               iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
 
                /* Bind the P2P_DEVICE to the new allocated PHY context */
-               mvmvif->phy_ctxt = phy_ctxt;
+               mvmvif->deflink.phy_ctxt = phy_ctxt;
 
                ret = iwl_mvm_binding_add_vif(mvm, vif);
                if (WARN(ret, "Failed binding P2P_DEVICE\n"))
                        goto out_unlock;
 
-               iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
+               iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt);
        }
 
 schedule_time_event:
 
        lockdep_assert_held(&mvm->mutex);
 
-       mvmvif->phy_ctxt = phy_ctxt;
+       mvmvif->deflink.phy_ctxt = phy_ctxt;
 
        switch (vif->type) {
        case NL80211_IFTYPE_AP:
        iwl_mvm_power_update_mac(mvm);
 out:
        if (ret)
-               mvmvif->phy_ctxt = NULL;
+               mvmvif->deflink.phy_ctxt = NULL;
        return ret;
 }
 
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
        lockdep_assert_held(&mvm->mutex);
-       iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
+       iwl_mvm_remove_time_event(mvm, mvmvif,
+                                 &mvmvif->time_event_data);
 
        switch (vif->type) {
        case NL80211_IFTYPE_ADHOC:
        if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD) &&
            switching_chanctx)
                return;
-       mvmvif->phy_ctxt = NULL;
+       mvmvif->deflink.phy_ctxt = NULL;
        iwl_mvm_power_update_mac(mvm);
 }
 
                        continue;
 
                /* make sure only TDLS peers or the AP are flushed */
-               WARN_ON(i != mvmvif->ap_sta_id && !sta->tdls);
+               WARN_ON(i != mvmvif->deflink.ap_sta_id && !sta->tdls);
 
                if (drop) {
                        if (iwl_mvm_flush_sta(mvm, mvmsta, false))
 
        mutex_lock(&mvm->mutex);
 
-       if (mvmvif->ap_sta_id != mvmsta->sta_id)
+       if (mvmvif->deflink.ap_sta_id != mvmsta->sta_id)
                goto unlock;
 
        if (iwl_mvm_request_statistics(mvm, false))
                goto unlock;
 
-       sinfo->rx_beacon = mvmvif->beacon_stats.num_beacons +
-                          mvmvif->beacon_stats.accu_num_beacons;
+       sinfo->rx_beacon = mvmvif->deflink.beacon_stats.num_beacons +
+                          mvmvif->deflink.beacon_stats.accu_num_beacons;
        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX);
-       if (mvmvif->beacon_stats.avg_signal) {
+       if (mvmvif->deflink.beacon_stats.avg_signal) {
                /* firmware only reports a value after RXing a few beacons */
-               sinfo->rx_beacon_signal_avg = mvmvif->beacon_stats.avg_signal;
+               sinfo->rx_beacon_signal_avg =
+                       mvmvif->deflink.beacon_stats.avg_signal;
                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG);
        }
  unlock:
 
 
        if (vif->type == NL80211_IFTYPE_AP &&
            !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
-               return BIT(mvmvif->mcast_sta.sta_id);
+               return BIT(mvmvif->deflink.mcast_sta.sta_id);
 
        if (sta) {
                struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
        }
 
        if (vif->type == NL80211_IFTYPE_STATION &&
-           mvmvif->ap_sta_id != IWL_MVM_INVALID_STA)
-               return BIT(mvmvif->ap_sta_id);
+           mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA)
+               return BIT(mvmvif->deflink.ap_sta_id);
 
        /* invalid */
        return 0;
 
        rcu_read_lock();
        if (!sta && vif->type == NL80211_IFTYPE_STATION &&
-           mvmvif->ap_sta_id != IWL_MVM_INVALID_STA) {
-               u8 sta_id = mvmvif->ap_sta_id;
+           mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
+               u8 sta_id = mvmvif->deflink.ap_sta_id;
 
                sta = rcu_dereference_check(mvm->fw_id_to_mac_id[sta_id],
                                            lockdep_is_held(&mvm->mutex));
        u8 sec_key_ver = iwl_fw_lookup_cmd_ver(mvm->fw, sec_key_id, 0);
 
        if (WARN_ON(vif->type != NL80211_IFTYPE_STATION ||
-                   mvmvif->ap_sta_id == IWL_MVM_INVALID_STA))
+                   mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA))
                return;
 
        if (!sec_key_ver)
 
         * MAC context is bound to it at this stage.
         */
        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
-               mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
-               if (!mvmvif->phy_ctxt) {
+               mvmvif->deflink.phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
+               if (!mvmvif->deflink.phy_ctxt) {
                        ret = -ENOSPC;
                        goto out_free_bf;
                }
 
-               iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
+               iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt);
                ret = iwl_mvm_add_link(mvm, vif);
                if (ret)
                        goto out_unref_phy;
        iwl_mvm_link_changed(mvm, vif, LINK_CONTEXT_MODIFY_ACTIVE, false);
        iwl_mvm_remove_link(mvm, vif);
  out_unref_phy:
-       iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
+       iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
  out_free_bf:
        if (mvm->bf_allowed_vif == mvmvif) {
                mvm->bf_allowed_vif = NULL;
                                       IEEE80211_VIF_SUPPORTS_CQM_RSSI);
        }
  out_remove_mac:
-       mvmvif->phy_ctxt = NULL;
+       mvmvif->deflink.phy_ctxt = NULL;
+       mvmvif->link[0] = NULL;
        iwl_mvm_mld_mac_ctxt_remove(mvm, vif);
  out_unlock:
        mutex_unlock(&mvm->mutex);
                iwl_mvm_link_changed(mvm, vif, LINK_CONTEXT_MODIFY_ACTIVE,
                                     false);
                iwl_mvm_remove_link(mvm, vif);
-               iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
-               mvmvif->phy_ctxt = NULL;
+               iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
+               mvmvif->deflink.phy_ctxt = NULL;
        }
 
        iwl_mvm_mld_mac_ctxt_remove(mvm, vif);
        iwl_mvm_power_update_mac(mvm);
 out:
        if (ret)
-               mvmvif->phy_ctxt = NULL;
+               mvmvif->deflink.phy_ctxt = NULL;
        return ret;
 }
 
 out:
        if (switching_chanctx)
                return;
-       mvmvif->phy_ctxt = NULL;
+       mvmvif->deflink.phy_ctxt = NULL;
        iwl_mvm_power_update_mac(mvm);
 }
 
 
 int iwl_mvm_mld_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
+       struct iwl_mvm_int_sta *bsta = &mvmvif->deflink.bcast_sta;
        static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
        const u8 *baddr = _baddr;
        unsigned int wdg_timeout =
        return iwl_mvm_mld_add_int_sta(mvm, bsta, queue,
                                       ieee80211_vif_type_p2p(vif),
                                       STATION_TYPE_BCAST_MGMT,
-                                      mvmvif->phy_ctxt->id, baddr,
+                                      mvmvif->deflink.phy_ctxt->id, baddr,
                                       IWL_MAX_TID_COUNT, &wdg_timeout);
 }
 
 int iwl_mvm_mld_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       struct iwl_mvm_int_sta *msta = &mvmvif->mcast_sta;
+       struct iwl_mvm_int_sta *msta = &mvmvif->deflink.mcast_sta;
        static const u8 _maddr[] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
        const u8 *maddr = _maddr;
        unsigned int timeout = iwl_mvm_get_wd_timeout(mvm, vif, false, false);
         * changes in mac80211 layer.
         */
        if (vif->type == NL80211_IFTYPE_ADHOC)
-               mvmvif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
+               mvmvif->deflink.cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
 
-       return iwl_mvm_mld_add_int_sta(mvm, msta, &mvmvif->cab_queue,
+       return iwl_mvm_mld_add_int_sta(mvm, msta, &mvmvif->deflink.cab_queue,
                                       vif->type, STATION_TYPE_MCAST,
-                                      mvmvif->phy_ctxt->id, maddr, 0,
+                                      mvmvif->deflink.phy_ctxt->id, maddr, 0,
                                       &timeout);
 }
 
 
        return iwl_mvm_mld_add_int_sta(mvm, &mvm->snif_sta, &mvm->snif_queue,
                                       vif->type, STATION_TYPE_BCAST_MGMT,
-                                      mvmvif->phy_ctxt->id, NULL,
+                                      mvmvif->deflink.phy_ctxt->id, NULL,
                                       IWL_MAX_TID_COUNT, NULL);
 }
 
                return -EINVAL;
        }
 
-       return iwl_mvm_mld_rm_int_sta(mvm, &mvmvif->bcast_sta, true,
+       return iwl_mvm_mld_rm_int_sta(mvm, &mvmvif->deflink.bcast_sta, true,
                                      IWL_MAX_TID_COUNT, queueptr);
 }
 
 
        lockdep_assert_held(&mvm->mutex);
 
-       return iwl_mvm_mld_rm_int_sta(mvm, &mvmvif->mcast_sta, true, 0,
-                                     &mvmvif->cab_queue);
+       return iwl_mvm_mld_rm_int_sta(mvm, &mvmvif->deflink.mcast_sta, true,
+                                     0,
+                                     &mvmvif->deflink.cab_queue);
 }
 
 int iwl_mvm_mld_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 
        int noa_len;
 };
 
+/**
+ * struct iwl_mvm_vif_link_info - per link data in Virtual Interface
+ * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
+ * @bssid: BSSID for this (client) interface
+ * @bcast_sta: station used for broadcast packets. Used by the following
+ *     vifs: P2P_DEVICE, GO and AP.
+ * @beacon_stats: beacon statistics, containing the # of received beacons,
+ *     # of received beacons accumulated over FW restart, and the current
+ *     average signal of beacons retrieved from the firmware
+ * @smps_requests: the SMPS requests of different parts of the driver,
+ *     combined on update to yield the overall request to mac80211.
+ * @probe_resp_data: data from FW notification to store NOA and CSA related
+ *     data to be inserted into probe response.
+ * @he_ru_2mhz_block: 26-tone RU OFDMA transmissions should be blocked
+ * @queue_params: QoS params for this MAC
+ */
+struct iwl_mvm_vif_link_info {
+       u8 bssid[ETH_ALEN];
+       u8 ap_sta_id;
+
+       struct iwl_mvm_int_sta bcast_sta;
+       struct iwl_mvm_int_sta mcast_sta;
+
+       struct {
+               u32 num_beacons, accu_num_beacons;
+               u8 avg_signal;
+       } beacon_stats;
+
+       enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
+       struct iwl_probe_resp_data __rcu *probe_resp_data;
+
+       bool he_ru_2mhz_block;
+
+       u16 cab_queue;
+       /* Assigned while mac80211 has the link in a channel context,
+        * or, for P2P Device, while it exists.
+        */
+       struct iwl_mvm_phy_ctxt *phy_ctxt;
+       /* QoS data from mac80211, need to store this here
+        * as mac80211 has a separate callback but we need
+        * to have the data for the MAC context
+        */
+       struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
+};
+
 /**
  * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
  * @id: between 0 and 3
  * @color: to solve races upon MAC addition and removal
- * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
- * @bssid: BSSID for this (client) interface
  * @associated: indicates that we're currently associated, used only for
  *     managing the firmware state in iwl_mvm_bss_info_changed_station()
  * @ap_assoc_sta_count: count of stations associated to us - valid only
  * @uploaded: indicates the MAC context has been added to the device
  * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface
  *     should get quota etc.
- * @pm_enabled - Indicate if MAC power management is allowed
+ * @pm_enabled - indicate if MAC power management is allowed
  * @monitor_active: indicates that monitor context is configured, and that the
  *     interface should get quota etc.
  * @low_latency: bit flags for low latency
  *     as a result from low_latency bit flags and takes force into account.
  * @authorized: indicates the AP station was set to authorized
  * @ps_disabled: indicates that this interface requires PS to be disabled
- * @queue_params: QoS params for this MAC
- * @bcast_sta: station used for broadcast packets. Used by the following
- *  vifs: P2P_DEVICE, GO and AP.
- * @beacon_skb: the skb used to hold the AP/GO beacon template
- * @smps_requests: the SMPS requests of different parts of the driver,
- *     combined on update to yield the overall request to mac80211.
- * @beacon_stats: beacon statistics, containing the # of received beacons,
- *     # of received beacons accumulated over FW restart, and the current
- *     average signal of beacons retrieved from the firmware
+ * @csa_countdown: indicates that CSA countdown may be started
  * @csa_failed: CSA failed to schedule time event, report an error later
+ * @csa_bcn_pending: indicates that we are waiting for a beacon on a new channel
  * @features: hw features active for this vif
- * @probe_resp_data: data from FW notification to store NOA and CSA related
- *     data to be inserted into probe response.
  */
 struct iwl_mvm_vif {
        struct iwl_mvm *mvm;
        u16 id;
        u16 color;
-       u8 ap_sta_id;
 
-       u8 bssid[ETH_ALEN];
        bool associated;
        u8 ap_assoc_sta_count;
-
-       u16 cab_queue;
-
        bool uploaded;
        bool ap_ibss_active;
        bool pm_enabled;
        bool monitor_active;
+
        u8 low_latency: 6;
        u8 low_latency_actual: 1;
+
        u8 authorized:1;
        bool ps_disabled;
-       struct iwl_mvm_vif_bf_data bf_data;
-
-       struct {
-               u32 num_beacons, accu_num_beacons;
-               u8 avg_signal;
-       } beacon_stats;
 
        u32 ap_beacon_time;
-
-       enum iwl_tsf_id tsf_id;
-
-       /*
-        * QoS data from mac80211, need to store this here
-        * as mac80211 has a separate callback but we need
-        * to have the data for the MAC context
-        */
-       struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
-       struct iwl_mvm_time_event_data time_event_data;
-       struct iwl_mvm_time_event_data hs_time_event_data;
-
-       struct iwl_mvm_int_sta bcast_sta;
-       struct iwl_mvm_int_sta mcast_sta;
-
-       /*
-        * Assigned while mac80211 has the interface in a channel context,
-        * or, for P2P Device, while it exists.
-        */
-       struct iwl_mvm_phy_ctxt *phy_ctxt;
+       struct iwl_mvm_vif_bf_data bf_data;
 
 #ifdef CONFIG_PM
        /* WoWLAN GTK rekey data */
        int dbgfs_quota_min;
 #endif
 
-       enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
-
        /* FW identified misbehaving AP */
        u8 uapsd_misbehaving_bssid[ETH_ALEN];
-
        struct delayed_work uapsd_nonagg_detected_wk;
 
-       /* Indicates that CSA countdown may be started */
        bool csa_countdown;
        bool csa_failed;
+       bool csa_bcn_pending;
        u16 csa_target_freq;
        u16 csa_count;
        u16 csa_misbehave;
        struct delayed_work csa_work;
 
-       /* Indicates that we are waiting for a beacon on a new channel */
-       bool csa_bcn_pending;
+       enum iwl_tsf_id tsf_id;
+
+       struct iwl_mvm_time_event_data time_event_data;
+       struct iwl_mvm_time_event_data hs_time_event_data;
 
        /* TCP Checksum Offload */
        netdev_features_t features;
 
-       struct iwl_probe_resp_data __rcu *probe_resp_data;
-
        /* we can only have 2 GTK + 2 IGTK active at a time */
        struct ieee80211_key_conf *ap_early_keys[4];
 
-       /* 26-tone RU OFDMA transmissions should be blocked */
-       bool he_ru_2mhz_block;
-
        struct {
                struct ieee80211_key_conf __rcu *keys[2];
        } bcn_prot;
+
+       struct iwl_mvm_vif_link_info deflink;
+       struct iwl_mvm_vif_link_info *link[IEEE80211_MLD_MAX_NUM_LINKS];
 };
 
+#define for_each_mvm_vif_valid_link(mvm_vif, link_id)                  \
+       for (link_id = 0;                                               \
+            link_id < ARRAY_SIZE((mvm_vif)->link);                     \
+            link_id++)                                                 \
+               if ((mvm_vif)->link[link_id])
+
 static inline struct iwl_mvm_vif *
 iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
 {
 
        unsigned long *data = _data;
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-       if (!mvmvif->phy_ctxt)
+       if (!mvmvif->deflink.phy_ctxt)
                return;
 
        if (vif->type == NL80211_IFTYPE_STATION ||
            vif->type == NL80211_IFTYPE_AP)
-               __set_bit(mvmvif->phy_ctxt->id, data);
+               __set_bit(mvmvif->deflink.phy_ctxt->id, data);
 }
 
 int iwl_mvm_phy_ctx_count(struct iwl_mvm *mvm)
 
 #endif
 
        for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) {
-               if (!mvmvif->queue_params[ac].uapsd)
+               if (!mvmvif->deflink.queue_params[ac].uapsd)
                        continue;
 
                if (!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status))
                cmd->uapsd_ac_flags |= BIT(ac);
 
                /* QNDP TID - the highest TID with no admission control */
-               if (!tid_found && !mvmvif->queue_params[ac].acm) {
+               if (!tid_found && !mvmvif->deflink.queue_params[ac].acm) {
                        tid_found = true;
                        switch (ac) {
                        case IEEE80211_AC_VO:
        /* The ap_sta_id is not expected to change during current association
         * so no explicit protection is needed
         */
-       if (mvmvif->ap_sta_id == *ap_sta_id)
-               memcpy(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
+       if (mvmvif->deflink.ap_sta_id == *ap_sta_id)
+               memcpy(mvmvif->uapsd_misbehaving_bssid,
+                      vif->bss_conf.bssid,
                       ETH_ALEN);
 }
 
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        bool *disable_ps = _data;
 
-       if (mvmvif->phy_ctxt && mvmvif->phy_ctxt->id < NUM_PHY_CTX)
+       if (mvmvif->deflink.phy_ctxt &&
+           mvmvif->deflink.phy_ctxt->id < NUM_PHY_CTX)
                *disable_ps |= mvmvif->ps_disabled;
 }
 
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct iwl_power_vifs *power_iterator = _data;
-       bool active = mvmvif->phy_ctxt && mvmvif->phy_ctxt->id < NUM_PHY_CTX;
+       bool active = mvmvif->deflink.phy_ctxt && mvmvif->deflink.phy_ctxt->id < NUM_PHY_CTX;
 
        if (!mvmvif->uploaded)
                return;
        }
 
        if (vifs->bss_active && vifs->p2p_active)
-               client_same_channel = (bss_mvmvif->phy_ctxt->id ==
-                                      p2p_mvmvif->phy_ctxt->id);
+               client_same_channel = (bss_mvmvif->deflink.phy_ctxt->id ==
+                                      p2p_mvmvif->deflink.phy_ctxt->id);
        if (vifs->bss_active && vifs->ap_active)
-               ap_same_channel = (bss_mvmvif->phy_ctxt->id ==
-                                  ap_mvmvif->phy_ctxt->id);
+               ap_same_channel = (bss_mvmvif->deflink.phy_ctxt->id ==
+                                  ap_mvmvif->deflink.phy_ctxt->id);
 
        /* clients are not stand alone: enable PM if DCM */
        if (!(client_same_channel || ap_same_channel)) {
 
        if (vif == data->disabled_vif)
                return;
 
-       if (!mvmvif->phy_ctxt)
+       if (!mvmvif->deflink.phy_ctxt)
                return;
 
        /* currently, PHY ID == binding ID */
-       id = mvmvif->phy_ctxt->id;
+       id = mvmvif->deflink.phy_ctxt->id;
 
        /* need at least one binding per PHY */
        BUILD_BUG_ON(NUM_PHY_CTX > MAX_BINDINGS);
        }
 
        if (data->colors[id] < 0)
-               data->colors[id] = mvmvif->phy_ctxt->color;
+               data->colors[id] = mvmvif->deflink.phy_ctxt->color;
        else
-               WARN_ON_ONCE(data->colors[id] != mvmvif->phy_ctxt->color);
+               WARN_ON_ONCE(data->colors[id] !=
+                            mvmvif->deflink.phy_ctxt->color);
 
        data->n_interfaces[id]++;
 
        if (!mvmvif->ap_ibss_active)
                return;
 
-       phy_id = mvmvif->phy_ctxt->id;
+       phy_id = mvmvif->deflink.phy_ctxt->id;
        beacon_int = mvm->noa_vif->bss_conf.beacon_int;
 
        for (i = 0; i < MAX_BINDINGS; i++) {
 
 
        if (mdata->opened_rx_ba_sessions ||
            mdata->uapsd_nonagg_detect.detected ||
-           (!mvmvif->queue_params[IEEE80211_AC_VO].uapsd &&
-            !mvmvif->queue_params[IEEE80211_AC_VI].uapsd &&
-            !mvmvif->queue_params[IEEE80211_AC_BE].uapsd &&
-            !mvmvif->queue_params[IEEE80211_AC_BK].uapsd) ||
-           mvmsta->sta_id != mvmvif->ap_sta_id)
+           (!mvmvif->deflink.queue_params[IEEE80211_AC_VO].uapsd &&
+            !mvmvif->deflink.queue_params[IEEE80211_AC_VI].uapsd &&
+            !mvmvif->deflink.queue_params[IEEE80211_AC_BE].uapsd &&
+            !mvmvif->deflink.queue_params[IEEE80211_AC_BK].uapsd) ||
+           mvmsta->sta_id != mvmvif->deflink.ap_sta_id)
                return;
 
        if (rate_n_flags & RATE_MCS_HT_MSK_V1) {
         * data copied into the "data" struct, but rather the data from
         * the notification directly.
         */
-       mvmvif->beacon_stats.num_beacons =
+       mvmvif->deflink.beacon_stats.num_beacons =
                le32_to_cpu(data->beacon_counter[vif_id]);
-       mvmvif->beacon_stats.avg_signal =
+       mvmvif->deflink.beacon_stats.avg_signal =
                -data->beacon_average_energy[vif_id];
 
        if (mvmvif->id != id)
         * request to clear statistics
         */
        if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
-               mvmvif->beacon_stats.accu_num_beacons +=
-                       mvmvif->beacon_stats.num_beacons;
+               mvmvif->deflink.beacon_stats.accu_num_beacons +=
+                       mvmvif->deflink.beacon_stats.num_beacons;
 
        iwl_mvm_update_vif_sig(vif, sig);
 }
 
        mac_stats = &data->per_mac_stats[vif_id];
 
-       mvmvif->beacon_stats.num_beacons =
+       mvmvif->deflink.beacon_stats.num_beacons =
                le32_to_cpu(mac_stats->beacon_counter);
-       mvmvif->beacon_stats.avg_signal =
+       mvmvif->deflink.beacon_stats.avg_signal =
                -le32_to_cpu(mac_stats->beacon_average_energy);
 
        /* make sure that beacon statistics don't go backwards with TCM
         * request to clear statistics
         */
        if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
-               mvmvif->beacon_stats.accu_num_beacons +=
-                       mvmvif->beacon_stats.num_beacons;
+               mvmvif->deflink.beacon_stats.accu_num_beacons +=
+                       mvmvif->deflink.beacon_stats.num_beacons;
 
        sig = -le32_to_cpu(mac_stats->beacon_filter_average_energy);
        iwl_mvm_update_vif_sig(vif, sig);
 
        struct iwl_mvm_scan_iter_data *data = _data;
        struct iwl_mvm_vif *curr_mvmvif;
 
-       if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt &&
-           mvmvif->phy_ctxt->id < NUM_PHY_CTX)
+       if (vif->type != NL80211_IFTYPE_P2P_DEVICE &&
+           mvmvif->deflink.phy_ctxt &&
+           mvmvif->deflink.phy_ctxt->id < NUM_PHY_CTX)
                data->global_cnt += 1;
 
        if (!data->current_vif || vif == data->current_vif)
        curr_mvmvif = iwl_mvm_vif_from_mac80211(data->current_vif);
 
        if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
-           mvmvif->phy_ctxt && curr_mvmvif->phy_ctxt &&
-           mvmvif->phy_ctxt->id != curr_mvmvif->phy_ctxt->id)
+           mvmvif->deflink.phy_ctxt && curr_mvmvif->deflink.phy_ctxt &&
+           mvmvif->deflink.phy_ctxt->id != curr_mvmvif->deflink.phy_ctxt->id)
                data->is_dcm_with_p2p_go = true;
 }
 
                return;
 
        if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
-           mvmvif->phy_ctxt->id < NUM_PHY_CTX &&
+           mvmvif->deflink.phy_ctxt->id < NUM_PHY_CTX &&
            (data->band == NUM_NL80211_BANDS ||
-            mvmvif->phy_ctxt->channel->band == data->band))
+            mvmvif->deflink.phy_ctxt->channel->band == data->band))
                data->p2p_go = true;
 }
 
                        .scan_start_tsf = mvm->scan_start,
                };
 
-               memcpy(info.tsf_bssid, mvm->scan_vif->bssid, ETH_ALEN);
+               memcpy(info.tsf_bssid, mvm->scan_vif->deflink.bssid, ETH_ALEN);
                ieee80211_scan_completed(mvm->hw, &info);
                mvm->scan_vif = NULL;
                cancel_delayed_work(&mvm->scan_timeout_dwork);
 
        struct iwl_mvm_active_iface_iterator_data *data = _data;
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-       if (vif == data->ignore_vif || !mvmvif->phy_ctxt ||
+       if (vif == data->ignore_vif || !mvmvif->deflink.phy_ctxt ||
            vif->type == NL80211_IFTYPE_P2P_DEVICE)
                return;
 
        data->num_active_macs++;
 
        if (vif->type == NL80211_IFTYPE_STATION) {
-               data->sta_vif_ap_sta_id = mvmvif->ap_sta_id;
+               data->sta_vif_ap_sta_id = mvmvif->deflink.ap_sta_id;
                if (vif->cfg.assoc)
                        data->sta_vif_state = SF_FULL_ON;
                else
                        } else if (changed_vif->cfg.assoc &&
                                   changed_vif->bss_conf.dtim_period) {
                                mvmvif = iwl_mvm_vif_from_mac80211(changed_vif);
-                               sta_id = mvmvif->ap_sta_id;
+                               sta_id = mvmvif->deflink.ap_sta_id;
                                new_state = SF_FULL_ON;
                        } else {
                                new_state = SF_INIT_OFF;
 
 
        if (vif->type == NL80211_IFTYPE_STATION) {
                if (!sta->tdls) {
-                       WARN_ON(mvmvif->ap_sta_id != IWL_MVM_INVALID_STA);
-                       mvmvif->ap_sta_id = sta_id;
+                       WARN_ON(mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA);
+                       mvmvif->deflink.ap_sta_id = sta_id;
                } else {
-                       WARN_ON(mvmvif->ap_sta_id == IWL_MVM_INVALID_STA);
+                       WARN_ON(mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA);
                }
        }
 
        }
 
        if (vif->type == NL80211_IFTYPE_STATION &&
-           mvmvif->ap_sta_id == sta_id) {
+           mvmvif->deflink.ap_sta_id == sta_id) {
                /* if associated - we can't remove the AP STA now */
                if (vif->cfg.assoc)
                        return true;
                iwl_mvm_sec_key_remove_ap(mvm, vif);
 
                /* unassoc - go ahead - remove the AP STA now */
-               mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
+               mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA;
        }
 
        /*
 int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
+       struct iwl_mvm_int_sta *bsta = &mvmvif->deflink.bcast_sta;
        static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
        const u8 *baddr = _baddr;
        int queue;
                iwl_mvm_get_wd_timeout(mvm, vif, false, false);
        struct iwl_trans_txq_scd_cfg cfg = {
                .fifo = IWL_MVM_TX_FIFO_VO,
-               .sta_id = mvmvif->bcast_sta.sta_id,
+               .sta_id = mvmvif->deflink.bcast_sta.sta_id,
                .tid = IWL_MAX_TID_COUNT,
                .aggregate = false,
                .frame_limit = IWL_FRAME_LIMIT,
 
        lockdep_assert_held(&mvm->mutex);
 
-       iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true);
+       iwl_mvm_flush_sta(mvm, &mvmvif->deflink.bcast_sta, true);
 
        switch (vif->type) {
        case NL80211_IFTYPE_AP:
        }
 
        queue = *queueptr;
-       iwl_mvm_disable_txq(mvm, NULL, mvmvif->bcast_sta.sta_id,
+       iwl_mvm_disable_txq(mvm, NULL, mvmvif->deflink.bcast_sta.sta_id,
                            queueptr, IWL_MAX_TID_COUNT);
        if (iwl_mvm_has_new_tx_api(mvm))
                return;
 
-       WARN_ON(!(mvmvif->bcast_sta.tfd_queue_msk & BIT(queue)));
-       mvmvif->bcast_sta.tfd_queue_msk &= ~BIT(queue);
+       WARN_ON(!(mvmvif->deflink.bcast_sta.tfd_queue_msk & BIT(queue)));
+       mvmvif->deflink.bcast_sta.tfd_queue_msk &= ~BIT(queue);
 }
 
 /* Send the FW a request to remove the station from it's internal data
 
        iwl_mvm_free_bcast_sta_queues(mvm, vif);
 
-       ret = iwl_mvm_rm_sta_common(mvm, mvmvif->bcast_sta.sta_id);
+       ret = iwl_mvm_rm_sta_common(mvm, mvmvif->deflink.bcast_sta.sta_id);
        if (ret)
                IWL_WARN(mvm, "Failed sending remove station\n");
        return ret;
 
        lockdep_assert_held(&mvm->mutex);
 
-       return iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, 0,
+       return iwl_mvm_allocate_int_sta(mvm, &mvmvif->deflink.bcast_sta, 0,
                                        ieee80211_vif_type_p2p(vif),
                                        IWL_STA_GENERAL_PURPOSE);
 }
 int iwl_mvm_add_p2p_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
+       struct iwl_mvm_int_sta *bsta = &mvmvif->deflink.bcast_sta;
        int ret;
 
        lockdep_assert_held(&mvm->mutex);
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-       iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
+       iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.bcast_sta);
 }
 
 /*
 int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       struct iwl_mvm_int_sta *msta = &mvmvif->mcast_sta;
+       struct iwl_mvm_int_sta *msta = &mvmvif->deflink.mcast_sta;
        static const u8 _maddr[] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
        const u8 *maddr = _maddr;
        struct iwl_trans_txq_scd_cfg cfg = {
         * changes in mac80211 layer.
         */
        if (vif->type == NL80211_IFTYPE_ADHOC)
-               mvmvif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
+               mvmvif->deflink.cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
 
        /*
         * While in previous FWs we had to exclude cab queue from TFD queue
         */
        if (!iwl_mvm_has_new_tx_api(mvm) &&
            fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE)) {
-               iwl_mvm_enable_txq(mvm, NULL, mvmvif->cab_queue, 0, &cfg,
+               iwl_mvm_enable_txq(mvm, NULL, mvmvif->deflink.cab_queue, 0,
+                                  &cfg,
                                   timeout);
-               msta->tfd_queue_msk |= BIT(mvmvif->cab_queue);
+               msta->tfd_queue_msk |= BIT(mvmvif->deflink.cab_queue);
        }
        ret = iwl_mvm_add_int_sta_common(mvm, msta, maddr,
                                         mvmvif->id, mvmvif->color);
                        ret = queue;
                        goto err;
                }
-               mvmvif->cab_queue = queue;
+               mvmvif->deflink.cab_queue = queue;
        } else if (!fw_has_api(&mvm->fw->ucode_capa,
                               IWL_UCODE_TLV_API_STA_TYPE))
-               iwl_mvm_enable_txq(mvm, NULL, mvmvif->cab_queue, 0, &cfg,
+               iwl_mvm_enable_txq(mvm, NULL, mvmvif->deflink.cab_queue, 0,
+                                  &cfg,
                                   timeout);
 
        return 0;
 
        lockdep_assert_held(&mvm->mutex);
 
-       iwl_mvm_flush_sta(mvm, &mvmvif->mcast_sta, true);
+       iwl_mvm_flush_sta(mvm, &mvmvif->deflink.mcast_sta, true);
 
-       iwl_mvm_disable_txq(mvm, NULL, mvmvif->mcast_sta.sta_id,
-                           &mvmvif->cab_queue, 0);
+       iwl_mvm_disable_txq(mvm, NULL, mvmvif->deflink.mcast_sta.sta_id,
+                           &mvmvif->deflink.cab_queue, 0);
 
-       ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id);
+       ret = iwl_mvm_rm_sta_common(mvm, mvmvif->deflink.mcast_sta.sta_id);
        if (ret)
                IWL_WARN(mvm, "Failed sending remove station\n");
 
         * station ID, then use AP's station ID.
         */
        if (vif->type == NL80211_IFTYPE_STATION &&
-           mvmvif->ap_sta_id != IWL_MVM_INVALID_STA) {
-               u8 sta_id = mvmvif->ap_sta_id;
+           mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
+               u8 sta_id = mvmvif->deflink.ap_sta_id;
 
                sta = rcu_dereference_check(mvm->fw_id_to_mac_id[sta_id],
                                            lockdep_is_held(&mvm->mutex));
                return sta->addr;
 
        if (vif->type == NL80211_IFTYPE_STATION &&
-           mvmvif->ap_sta_id != IWL_MVM_INVALID_STA) {
-               u8 sta_id = mvmvif->ap_sta_id;
+           mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
+               u8 sta_id = mvmvif->deflink.ap_sta_id;
                sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
                                                lockdep_is_held(&mvm->mutex));
                return sta->addr;
                   !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
                struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-               sta_id = mvmvif->mcast_sta.sta_id;
+               sta_id = mvmvif->deflink.mcast_sta.sta_id;
        } else {
                IWL_ERR(mvm, "Failed to find station id\n");
                return -EINVAL;
        } else {
                struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-               sta_id = mvmvif->mcast_sta.sta_id;
+               sta_id = mvmvif->deflink.mcast_sta.sta_id;
        }
 
        if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
        if (mvm_sta)
                sta_id = mvm_sta->sta_id;
        else if (!sta && vif->type == NL80211_IFTYPE_AP && mcast)
-               sta_id = iwl_mvm_vif_from_mac80211(vif)->mcast_sta.sta_id;
+               sta_id = iwl_mvm_vif_from_mac80211(vif)->deflink.mcast_sta.sta_id;
 
 
        IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
                return;
 
        /* Need to block/unblock also multicast station */
-       if (mvmvif->mcast_sta.sta_id != IWL_MVM_INVALID_STA)
+       if (mvmvif->deflink.mcast_sta.sta_id != IWL_MVM_INVALID_STA)
                iwl_mvm_int_sta_modify_disable_tx(mvm, mvmvif,
-                                                 &mvmvif->mcast_sta, disable);
+                                                 &mvmvif->deflink.mcast_sta,
+                                                 disable);
 
        /*
         * Only unblock the broadcast station (FW blocks it for immediate
         * quiet, not the driver)
         */
-       if (!disable && mvmvif->bcast_sta.sta_id != IWL_MVM_INVALID_STA)
+       if (!disable && mvmvif->deflink.bcast_sta.sta_id != IWL_MVM_INVALID_STA)
                iwl_mvm_int_sta_modify_disable_tx(mvm, mvmvif,
-                                                 &mvmvif->bcast_sta, disable);
+                                                 &mvmvif->deflink.bcast_sta,
+                                                 disable);
 }
 
 void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 
        rcu_read_lock();
 
-       mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->ap_sta_id);
+       mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->deflink.ap_sta_id);
 
        if (mvmsta)
                iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true);
 
 
                if (!WARN_ON(!mvm->p2p_device_vif)) {
                        mvmvif = iwl_mvm_vif_from_mac80211(mvm->p2p_device_vif);
-                       iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true);
+                       iwl_mvm_flush_sta(mvm, &mvmvif->deflink.bcast_sta,
+                                         true);
                }
        }
 
                struct iwl_mvm_sta *mvmsta;
 
                rcu_read_lock();
-               mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->ap_sta_id);
+               mvmsta = iwl_mvm_sta_from_staid_rcu(mvm,
+                                                   mvmvif->deflink.ap_sta_id);
                if (!WARN_ON(!mvmsta))
                        iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
                rcu_read_unlock();
 
 
                if (!ieee80211_has_order(fc) && !ieee80211_is_probe_req(fc) &&
                    is_multicast_ether_addr(hdr->addr1))
-                       return mvmvif->cab_queue;
+                       return mvmvif->deflink.cab_queue;
 
                WARN_ONCE(info->control.vif->type != NL80211_IFTYPE_ADHOC,
                          "fc=0x%02x", le16_to_cpu(fc));
 
        rcu_read_lock();
 
-       resp_data = rcu_dereference(mvmvif->probe_resp_data);
+       resp_data = rcu_dereference(mvmvif->deflink.probe_resp_data);
        if (!resp_data)
                goto out;
 
                    info.control.vif->type == NL80211_IFTYPE_AP ||
                    info.control.vif->type == NL80211_IFTYPE_ADHOC) {
                        if (!ieee80211_is_data(hdr->frame_control))
-                               sta_id = mvmvif->bcast_sta.sta_id;
+                               sta_id = mvmvif->deflink.bcast_sta.sta_id;
                        else
-                               sta_id = mvmvif->mcast_sta.sta_id;
+                               sta_id = mvmvif->deflink.mcast_sta.sta_id;
 
                        queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, hdr);
                } else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) {
 
                return;
 
        mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       mvmvif->smps_requests[req_type] = smps_request;
+       mvmvif->deflink.smps_requests[req_type] = smps_request;
        for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
-               if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC) {
+               if (mvmvif->deflink.smps_requests[i] == IEEE80211_SMPS_STATIC) {
                        smps_mode = IEEE80211_SMPS_STATIC;
                        break;
                }
-               if (mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
+               if (mvmvif->deflink.smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
                        smps_mode = IEEE80211_SMPS_DYNAMIC;
        }
 
        struct iwl_mvm_diversity_iter_data *data = _data;
        int i;
 
-       if (mvmvif->phy_ctxt != data->ctxt)
+       if (mvmvif->deflink.phy_ctxt != data->ctxt)
                return;
 
        for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
-               if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC ||
-                   mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC) {
+               if (mvmvif->deflink.smps_requests[i] == IEEE80211_SMPS_STATIC ||
+                   mvmvif->deflink.smps_requests[i] == IEEE80211_SMPS_DYNAMIC) {
                        data->result = false;
                        break;
                }
        if (iwl_mvm_vif_low_latency(mvmvif)) {
                result->result = true;
 
-               if (!mvmvif->phy_ctxt)
+               if (!mvmvif->deflink.phy_ctxt)
                        return;
 
-               band = mvmvif->phy_ctxt->channel->band;
+               band = mvmvif->deflink.phy_ctxt->channel->band;
                result->result_per_band[band] = true;
        }
 }
        if (!vif->cfg.assoc)
                return;
 
-       if (!mvmvif->queue_params[IEEE80211_AC_VO].uapsd &&
-           !mvmvif->queue_params[IEEE80211_AC_VI].uapsd &&
-           !mvmvif->queue_params[IEEE80211_AC_BE].uapsd &&
-           !mvmvif->queue_params[IEEE80211_AC_BK].uapsd)
+       if (!mvmvif->deflink.queue_params[IEEE80211_AC_VO].uapsd &&
+           !mvmvif->deflink.queue_params[IEEE80211_AC_VI].uapsd &&
+           !mvmvif->deflink.queue_params[IEEE80211_AC_BE].uapsd &&
+           !mvmvif->deflink.queue_params[IEEE80211_AC_BK].uapsd)
                return;
 
        if (mvm->tcm.data[mvmvif->id].uapsd_nonagg_detect.detected)
        mvm->tcm.data[mvmvif->id].uapsd_nonagg_detect.detected = true;
        IWL_INFO(mvm,
                 "detected AP should do aggregation but isn't, likely due to U-APSD\n");
-       schedule_delayed_work(&mvmvif->uapsd_nonagg_detected_wk, 15 * HZ);
+       schedule_delayed_work(&mvmvif->uapsd_nonagg_detected_wk,
+                             15 * HZ);
 }
 
 static void iwl_mvm_check_uapsd_agg_expected_tpt(struct iwl_mvm *mvm,
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        u32 *band = _data;
 
-       if (!mvmvif->phy_ctxt)
+       if (!mvmvif->deflink.phy_ctxt)
                return;
 
-       band[mvmvif->id] = mvmvif->phy_ctxt->channel->band;
+       band[mvmvif->id] = mvmvif->deflink.phy_ctxt->channel->band;
 }
 
 static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,