static void ath12k_peer_assoc_h_basic(struct ath12k *ar,
                                      struct ath12k_link_vif *arvif,
-                                     struct ieee80211_sta *sta,
+                                     struct ath12k_link_sta *arsta,
                                      struct ath12k_wmi_peer_assoc_arg *arg)
 {
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
        u32 aid;
 
 
 static void ath12k_peer_assoc_h_crypto(struct ath12k *ar,
                                       struct ath12k_link_vif *arvif,
-                                      struct ieee80211_sta *sta,
+                                      struct ath12k_link_sta *arsta,
                                       struct ath12k_wmi_peer_assoc_arg *arg)
 {
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct ieee80211_bss_conf *info = &vif->bss_conf;
        struct cfg80211_chan_def def;
        struct cfg80211_bss *bss;
 
 static void ath12k_peer_assoc_h_rates(struct ath12k *ar,
                                      struct ath12k_link_vif *arvif,
-                                     struct ieee80211_sta *sta,
+                                     struct ath12k_link_sta *arsta,
                                      struct ath12k_wmi_peer_assoc_arg *arg)
 {
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
        struct cfg80211_chan_def def;
        const struct ieee80211_supported_band *sband;
 
 static void ath12k_peer_assoc_h_ht(struct ath12k *ar,
                                   struct ath12k_link_vif *arvif,
-                                  struct ieee80211_sta *sta,
+                                  struct ath12k_link_sta *arsta,
                                   struct ath12k_wmi_peer_assoc_arg *arg)
 {
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;
        struct cfg80211_chan_def def;
        enum nl80211_band band;
 
 static void ath12k_peer_assoc_h_vht(struct ath12k *ar,
                                    struct ath12k_link_vif *arvif,
-                                   struct ieee80211_sta *sta,
+                                   struct ath12k_link_sta *arsta,
                                    struct ath12k_wmi_peer_assoc_arg *arg)
 {
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;
        struct cfg80211_chan_def def;
        enum nl80211_band band;
 
 static void ath12k_peer_assoc_h_he(struct ath12k *ar,
                                   struct ath12k_link_vif *arvif,
-                                  struct ieee80211_sta *sta,
+                                  struct ath12k_link_sta *arsta,
                                   struct ath12k_wmi_peer_assoc_arg *arg)
 {
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
        int i;
        u8 ampdu_factor, max_nss;
 
 static void ath12k_peer_assoc_h_he_6ghz(struct ath12k *ar,
                                        struct ath12k_link_vif *arvif,
-                                       struct ieee80211_sta *sta,
+                                       struct ath12k_link_sta *arsta,
                                        struct ath12k_wmi_peer_assoc_arg *arg)
 {
-       const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
+       const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
        struct cfg80211_chan_def def;
        enum nl80211_band band;
        u8 ampdu_factor, mpdu_density;
        return 0;
 }
 
-static void ath12k_peer_assoc_h_smps(struct ieee80211_sta *sta,
+static void ath12k_peer_assoc_h_smps(struct ath12k_link_sta *arsta,
                                     struct ath12k_wmi_peer_assoc_arg *arg)
 {
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        const struct ieee80211_he_6ghz_capa *he_6ghz_capa = &sta->deflink.he_6ghz_capa;
        const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;
        int smps;
 
 static void ath12k_peer_assoc_h_qos(struct ath12k *ar,
                                    struct ath12k_link_vif *arvif,
-                                   struct ieee80211_sta *sta,
+                                   struct ath12k_link_sta *arsta,
                                    struct ath12k_wmi_peer_assoc_arg *arg)
 {
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
+
        switch (arvif->ahvif->vdev_type) {
        case WMI_VDEV_TYPE_AP:
                if (sta->wme) {
 
 static int ath12k_peer_assoc_qos_ap(struct ath12k *ar,
                                    struct ath12k_link_vif *arvif,
-                                   struct ieee80211_sta *sta)
+                                   struct ath12k_link_sta *arsta)
 {
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct ath12k_wmi_ap_ps_arg arg;
        u32 max_sp;
        u32 uapsd;
 
 static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
                                        struct ath12k_link_vif *arvif,
-                                       struct ieee80211_sta *sta,
+                                       struct ath12k_link_sta *arsta,
                                        struct ath12k_wmi_peer_assoc_arg *arg)
 {
        struct cfg80211_chan_def def;
        lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
 
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
 
        if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
                return;
 
 static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
                                    struct ath12k_link_vif *arvif,
-                                   struct ieee80211_sta *sta,
+                                   struct ath12k_link_sta *arsta,
                                    struct ath12k_wmi_peer_assoc_arg *arg)
 {
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        const struct ieee80211_sta_eht_cap *eht_cap = &sta->deflink.eht_cap;
        const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
        const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20;
 
 static void ath12k_peer_assoc_prepare(struct ath12k *ar,
                                      struct ath12k_link_vif *arvif,
-                                     struct ieee80211_sta *sta,
+                                     struct ath12k_link_sta *arsta,
                                      struct ath12k_wmi_peer_assoc_arg *arg,
                                      bool reassoc)
 {
        reinit_completion(&ar->peer_assoc_done);
 
        arg->peer_new_assoc = !reassoc;
-       ath12k_peer_assoc_h_basic(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_crypto(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_rates(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_ht(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_vht(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_he(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_he_6ghz(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_eht(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_qos(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_phymode(ar, arvif, sta, arg);
-       ath12k_peer_assoc_h_smps(sta, arg);
+       ath12k_peer_assoc_h_basic(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_crypto(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_rates(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_ht(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_vht(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_he(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_he_6ghz(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_eht(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_qos(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_phymode(ar, arvif, arsta, arg);
+       ath12k_peer_assoc_h_smps(arsta, arg);
 
        /* TODO: amsdu_disable req? */
 }
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif);
        struct ath12k_wmi_vdev_up_params params = {};
        struct ath12k_wmi_peer_assoc_arg peer_arg;
+       struct ath12k_link_sta *arsta;
        struct ieee80211_sta *ap_sta;
+       struct ath12k_sta *ahsta;
        struct ath12k_peer *peer;
        bool is_auth = false;
        int ret;
                return;
        }
 
-       ath12k_peer_assoc_prepare(ar, arvif, ap_sta, &peer_arg, false);
+       ahsta = ath12k_sta_to_ahsta(ap_sta);
+       arsta = &ahsta->deflink;
+
+       if (WARN_ON(!arsta)) {
+               rcu_read_unlock();
+               return;
+       }
+
+       ath12k_peer_assoc_prepare(ar, arvif, arsta, &peer_arg, false);
 
        rcu_read_unlock();
 
 }
 
 static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd,
-                             struct ath12k_link_vif *arvif, struct ieee80211_sta *sta,
+                             struct ath12k_link_vif *arvif,
+                             struct ath12k_link_sta *arsta,
                              struct ieee80211_key_conf *key)
 {
        struct ath12k_vif *ahvif = arvif->ahvif;
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif);
+       struct ieee80211_sta *sta = NULL;
        struct ath12k_base *ab = ar->ab;
        struct ath12k_peer *peer;
-       struct ath12k_sta *arsta;
+       struct ath12k_sta *ahsta;
        const u8 *peer_addr;
        int ret;
        u32 flags = 0;
 
        lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
 
+       if (arsta)
+               sta = ath12k_ahsta_to_sta(arsta->ahsta);
+
        if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags))
                return 1;
 
                ath12k_warn(ab, "peer %pM disappeared!\n", peer_addr);
 
        if (sta) {
-               arsta = ath12k_sta_to_arsta(sta);
+               ahsta = ath12k_sta_to_ahsta(sta);
 
                switch (key->cipher) {
                case WLAN_CIPHER_SUITE_TKIP:
                case WLAN_CIPHER_SUITE_GCMP:
                case WLAN_CIPHER_SUITE_GCMP_256:
                        if (cmd == SET_KEY)
-                               arsta->pn_type = HAL_PN_TYPE_WPA;
+                               ahsta->pn_type = HAL_PN_TYPE_WPA;
                        else
-                               arsta->pn_type = HAL_PN_TYPE_NONE;
+                               ahsta->pn_type = HAL_PN_TYPE_NONE;
                        break;
                default:
-                       arsta->pn_type = HAL_PN_TYPE_NONE;
+                       ahsta->pn_type = HAL_PN_TYPE_NONE;
                        break;
                }
        }
 {
        struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
        struct ath12k_link_vif *arvif;
+       struct ath12k_link_sta *arsta = NULL;
        struct ath12k_vif_cache *cache;
+       struct ath12k_sta *ahsta;
        struct ath12k *ar;
        int ret;
 
                return 0;
        }
 
-       /* Note: Currently only deflink of ahvif is used here, once MLO
-        * support is added the allocated links (i.e ahvif->links[])
+       if (sta) {
+               ahsta = ath12k_sta_to_ahsta(sta);
+               arsta = &ahsta->deflink;
+       }
+
+       /* Note: Currently only deflink of ahvif and ahsta are used here,
+        * once MLO support is added the allocated links (i.e ahvif->links[])
         * should be use based on link id passed from mac80211 and such link
         * access needs to be protected with ah->conf_mutex.
         */
-       ret = ath12k_mac_set_key(ar, cmd, arvif, sta, key);
+       ret = ath12k_mac_set_key(ar, cmd, arvif, arsta, key);
 
        return ret;
 }
 
 static int
 ath12k_mac_set_peer_vht_fixed_rate(struct ath12k_link_vif *arvif,
-                                  struct ieee80211_sta *sta,
+                                  struct ath12k_link_sta *arsta,
                                   const struct cfg80211_bitrate_mask *mask,
                                   enum nl80211_band band)
 {
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct ath12k *ar = arvif->ar;
        u8 vht_rate, nss;
        u32 rate_code;
 
 static int ath12k_station_assoc(struct ath12k *ar,
                                struct ath12k_link_vif *arvif,
-                               struct ieee80211_sta *sta,
+                               struct ath12k_link_sta *arsta,
                                bool reassoc)
 {
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct ath12k_wmi_peer_assoc_arg peer_arg;
        int ret;
        struct cfg80211_chan_def def;
        band = def.chan->band;
        mask = &arvif->bitrate_mask;
 
-       ath12k_peer_assoc_prepare(ar, arvif, sta, &peer_arg, reassoc);
+       ath12k_peer_assoc_prepare(ar, arvif, arsta, &peer_arg, reassoc);
 
        if (peer_arg.peer_nss < 1) {
                ath12k_warn(ar->ab,
         * Note that all other rates and NSS will be disabled for this peer.
         */
        if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) {
-               ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,
+               ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, arsta, mask,
                                                         band);
                if (ret)
                        return ret;
        }
 
        if (sta->wme && sta->uapsd_queues) {
-               ret = ath12k_peer_assoc_qos_ap(ar, arvif, sta);
+               ret = ath12k_peer_assoc_qos_ap(ar, arvif, arsta);
                if (ret) {
                        ath12k_warn(ar->ab, "failed to set qos params for STA %pM for vdev %i: %d\n",
                                    sta->addr, arvif->vdev_id, ret);
 
 static int ath12k_station_disassoc(struct ath12k *ar,
                                   struct ath12k_link_vif *arvif,
-                                  struct ieee80211_sta *sta)
+                                  struct ath12k_link_sta *arsta)
 {
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        int ret;
 
        lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
 static void ath12k_sta_rc_update_wk(struct wiphy *wiphy, struct wiphy_work *wk)
 {
        struct ath12k *ar;
-       struct ath12k_sta *arsta;
        struct ath12k_link_vif *arvif;
        struct ieee80211_sta *sta;
        struct cfg80211_chan_def def;
        const struct cfg80211_bitrate_mask *mask;
        struct ath12k_wmi_peer_assoc_arg peer_arg;
        enum wmi_phy_mode peer_phymode;
+       struct ath12k_link_sta *arsta;
        struct ieee80211_vif *vif;
 
        lockdep_assert_wiphy(wiphy);
 
-       arsta = container_of(wk, struct ath12k_sta, update_wk);
-       sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
+       arsta = container_of(wk, struct ath12k_link_sta, update_wk);
+       sta = ath12k_ahsta_to_sta(arsta->ahsta);
        arvif = arsta->arvif;
        vif = ath12k_ahvif_to_vif(arvif->ahvif);
        ar = arvif->ar;
                           ath12k_mac_max_vht_nss(vht_mcs_mask)));
 
        if (changed & IEEE80211_RC_BW_CHANGED) {
-               ath12k_peer_assoc_h_phymode(ar, arvif, sta, &peer_arg);
+               ath12k_peer_assoc_h_phymode(ar, arvif, arsta, &peer_arg);
                peer_phymode = peer_arg.peer_phymode;
 
                if (bw > bw_prev) {
                 * across HT/VHT and for multiple VHT MCS support.
                 */
                if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) {
-                       ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,
+                       ath12k_mac_set_peer_vht_fixed_rate(arvif, arsta, mask,
                                                           band);
                } else {
                        /* If the peer is non-VHT or no fixed VHT rate
                         * is provided in the new bitrate mask we set the
                         * other rates using peer_assoc command.
                         */
-                       ath12k_peer_assoc_prepare(ar, arvif, sta,
+                       ath12k_peer_assoc_prepare(ar, arvif, arsta,
                                                  &peer_arg, true);
 
                        err = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
 }
 
 static int ath12k_mac_inc_num_stations(struct ath12k_link_vif *arvif,
-                                      struct ieee80211_sta *sta)
+                                      struct ath12k_link_sta *arsta)
 {
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct ath12k *ar = arvif->ar;
 
        lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
 }
 
 static void ath12k_mac_dec_num_stations(struct ath12k_link_vif *arvif,
-                                       struct ieee80211_sta *sta)
+                                       struct ath12k_link_sta *arsta)
 {
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct ath12k *ar = arvif->ar;
 
        lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
 
 static int ath12k_mac_station_add(struct ath12k *ar,
                                  struct ath12k_link_vif *arvif,
-                                 struct ieee80211_sta *sta)
+                                 struct ath12k_link_sta *arsta)
 {
        struct ath12k_base *ab = ar->ab;
        struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
-       struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta);
+       struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
        struct ath12k_wmi_peer_create_arg peer_param;
        int ret;
 
        lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
 
-       ret = ath12k_mac_inc_num_stations(arvif, sta);
+       ret = ath12k_mac_inc_num_stations(arvif, arsta);
        if (ret) {
                ath12k_warn(ab, "refusing to associate station: too many connected already (%d)\n",
                            ar->max_num_stations);
 free_peer:
        ath12k_peer_delete(ar, arvif->vdev_id, sta->addr);
 dec_num_station:
-       ath12k_mac_dec_num_stations(arvif, sta);
+       ath12k_mac_dec_num_stations(arvif, arsta);
 exit:
        return ret;
 }
                                   enum ieee80211_sta_state new_state)
 {
        struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
+       struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta);
        struct ath12k *ar;
-       struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta);
        struct ath12k_link_vif *arvif;
+       struct ath12k_link_sta *arsta;
        struct ath12k_peer *peer;
        int ret = 0;
 
        lockdep_assert_wiphy(hw->wiphy);
 
        arvif = &ahvif->deflink;
+       arsta = &ahsta->deflink;
 
        ar = ath12k_get_ar_by_vif(hw, vif);
        if (!ar) {
        if (old_state == IEEE80211_STA_NOTEXIST &&
            new_state == IEEE80211_STA_NONE) {
                memset(arsta, 0, sizeof(*arsta));
+               rcu_assign_pointer(ahsta->link[0], arsta);
+               /* TODO use appropriate link id once MLO support is added  */
+               arsta->link_id = ATH12K_DEFAULT_LINK_ID;
+               ahsta->links_map = BIT(arsta->link_id);
+               arsta->ahsta = ahsta;
                arsta->arvif = arvif;
                wiphy_work_init(&arsta->update_wk, ath12k_sta_rc_update_wk);
 
-               ret = ath12k_mac_station_add(ar, arvif, sta);
+               synchronize_rcu();
+
+               ret = ath12k_mac_station_add(ar, arvif, arsta);
                if (ret)
                        ath12k_warn(ar->ab, "Failed to add station: %pM for VDEV: %d\n",
                                    sta->addr, arvif->vdev_id);
                        ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "Removed peer: %pM for VDEV: %d\n",
                                   sta->addr, arvif->vdev_id);
 
-               ath12k_mac_dec_num_stations(arvif, sta);
+               ath12k_mac_dec_num_stations(arvif, arsta);
                spin_lock_bh(&ar->ab->base_lock);
                peer = ath12k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
                if (peer && peer->sta == sta) {
 
                kfree(arsta->rx_stats);
                arsta->rx_stats = NULL;
+
+               if (arsta->link_id < IEEE80211_MLD_MAX_NUM_LINKS) {
+                       rcu_assign_pointer(ahsta->link[arsta->link_id], NULL);
+                       synchronize_rcu();
+                       ahsta->links_map &= ~(BIT(arsta->link_id));
+                       arsta->link_id = ATH12K_INVALID_LINK_ID;
+                       arsta->ahsta = NULL;
+               }
        } else if (old_state == IEEE80211_STA_AUTH &&
                   new_state == IEEE80211_STA_ASSOC &&
                   (vif->type == NL80211_IFTYPE_AP ||
                    vif->type == NL80211_IFTYPE_MESH_POINT ||
                    vif->type == NL80211_IFTYPE_ADHOC)) {
-               ret = ath12k_station_assoc(ar, arvif, sta, false);
+               ret = ath12k_station_assoc(ar, arvif, arsta, false);
                if (ret)
                        ath12k_warn(ar->ab, "Failed to associate station: %pM\n",
                                    sta->addr);
                   (vif->type == NL80211_IFTYPE_AP ||
                    vif->type == NL80211_IFTYPE_MESH_POINT ||
                    vif->type == NL80211_IFTYPE_ADHOC)) {
-               ret = ath12k_station_disassoc(ar, arvif, sta);
+               ret = ath12k_station_disassoc(ar, arvif, arsta);
                if (ret)
                        ath12k_warn(ar->ab, "Failed to disassociate station: %pM\n",
                                    sta->addr);
                                        u32 changed)
 {
        struct ath12k *ar;
-       struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta);
+       struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta);
        struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
+       struct ath12k_link_sta *arsta;
        struct ath12k_link_vif *arvif;
        struct ath12k_peer *peer;
        u32 bw, smps;
                rcu_read_unlock();
                return;
        }
+       arsta = rcu_dereference(ahsta->link[link_id]);
+       if (!arsta) {
+               rcu_read_unlock();
+               ath12k_warn(ar->ab, "mac sta rc update failed to fetch link sta on link id %u for peer %pM\n",
+                           link_id, sta->addr);
+               return;
+       }
        spin_lock_bh(&ar->ab->base_lock);
 
        peer = ath12k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
                                             struct ieee80211_sta *sta)
 {
        struct ath12k_link_vif *arvif = data;
-       struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta);
+       struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta);
+       struct ath12k_link_sta *arsta = &ahsta->deflink;
        struct ath12k *ar = arvif->ar;
 
        if (arsta->arvif != arvif)
                                               struct ieee80211_sta *sta)
 {
        struct ath12k_link_vif *arvif = data;
-       struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta);
+       struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta);
+       struct ath12k_link_sta *arsta = &ahsta->deflink;
        struct ath12k *ar = arvif->ar;
        int ret;
 
                                         struct ieee80211_sta *sta,
                                         struct station_info *sinfo)
 {
-       struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta);
+       struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta);
+       struct ath12k_link_sta *arsta;
 
        lockdep_assert_wiphy(hw->wiphy);
 
+       arsta = &ahsta->deflink;
+
        sinfo->rx_duration = arsta->rx_duration;
        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);