return -EMSGSIZE;
 }
 
+static void cfg80211_sta_set_mld_sinfo(struct station_info *sinfo)
+{
+       struct link_station_info *link_sinfo;
+       int link_id, init = 0;
+       u32 link_inactive_time;
+
+       sinfo->signal = -99;
+
+       for_each_valid_link(sinfo, link_id) {
+               link_sinfo = sinfo->links[link_id];
+               if (!link_sinfo)
+                       continue;
+
+               if ((link_sinfo->filled &
+                    BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) {
+                       sinfo->tx_packets += link_sinfo->tx_packets;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
+               }
+
+               if ((link_sinfo->filled &
+                    BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) {
+                       sinfo->rx_packets += link_sinfo->rx_packets;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
+               }
+
+               if (link_sinfo->filled &
+                   (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
+                    BIT_ULL(NL80211_STA_INFO_TX_BYTES64))) {
+                       sinfo->tx_bytes += link_sinfo->tx_bytes;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES);
+               }
+
+               if (link_sinfo->filled &
+                   (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
+                    BIT_ULL(NL80211_STA_INFO_TX_BYTES64))) {
+                       sinfo->rx_bytes += link_sinfo->rx_bytes;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES);
+               }
+
+               if (link_sinfo->filled &
+                   BIT_ULL(NL80211_STA_INFO_TX_RETRIES)) {
+                       sinfo->tx_retries += link_sinfo->tx_retries;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
+               }
+
+               if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED)) {
+                       sinfo->tx_failed += link_sinfo->tx_failed;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
+               }
+
+               if (link_sinfo->filled &
+                   BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC)) {
+                       sinfo->rx_dropped_misc += link_sinfo->rx_dropped_misc;
+                       sinfo->filled |=
+                               BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC);
+               }
+
+               if (link_sinfo->filled &
+                   BIT_ULL(NL80211_STA_INFO_BEACON_LOSS)) {
+                       sinfo->beacon_loss_count +=
+                               link_sinfo->beacon_loss_count;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_LOSS);
+               }
+
+               if (link_sinfo->filled &
+                   BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) {
+                       sinfo->expected_throughput +=
+                               link_sinfo->expected_throughput;
+                       sinfo->filled |=
+                               BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT);
+               }
+
+               if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_MPDUS)) {
+                       sinfo->rx_mpdu_count += link_sinfo->rx_mpdu_count;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_MPDUS);
+               }
+
+               if (link_sinfo->filled &
+                   BIT_ULL(NL80211_STA_INFO_FCS_ERROR_COUNT)) {
+                       sinfo->fcs_err_count += link_sinfo->fcs_err_count;
+                       sinfo->filled |=
+                               BIT_ULL(NL80211_STA_INFO_FCS_ERROR_COUNT);
+               }
+
+               if (link_sinfo->filled &
+                   BIT_ULL(NL80211_STA_INFO_BEACON_RX)) {
+                       sinfo->rx_beacon += link_sinfo->rx_beacon;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX);
+               }
+
+               /* Update MLO signal, signal_avg as best among links */
+               if ((link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) &&
+                   link_sinfo->signal > sinfo->signal) {
+                       sinfo->signal = link_sinfo->signal;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
+               }
+
+               if ((link_sinfo->filled &
+                       BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG)) &&
+                   link_sinfo->signal_avg > sinfo->signal_avg) {
+                       sinfo->signal_avg = link_sinfo->signal_avg;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
+               }
+
+               /* Update MLO inactive_time, bss_param based on least
+                * value for corresponding field of link.
+                */
+               if ((link_sinfo->filled &
+                    BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME)) &&
+                   (!init ||
+                    link_inactive_time > link_sinfo->inactive_time)) {
+                       link_inactive_time = link_sinfo->inactive_time;
+                       sinfo->inactive_time = link_sinfo->inactive_time;
+                       sinfo->filled |= NL80211_STA_INFO_INACTIVE_TIME;
+               }
+
+               if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM) &&
+                   (!init ||
+                    sinfo->bss_param.dtim_period >
+                     link_sinfo->bss_param.dtim_period)) {
+                       sinfo->bss_param.dtim_period =
+                               link_sinfo->bss_param.dtim_period;
+                       sinfo->filled |= NL80211_STA_BSS_PARAM_DTIM_PERIOD;
+                       sinfo->bss_param.beacon_interval =
+                               link_sinfo->bss_param.beacon_interval;
+                       sinfo->filled |= NL80211_STA_BSS_PARAM_BEACON_INTERVAL;
+               }
+
+               /* Update MLO rates as per last updated link rate */
+               if ((link_sinfo->filled &
+                    BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) &&
+                   (!init ||
+                    link_inactive_time > link_sinfo->inactive_time)) {
+                       sinfo->txrate = link_sinfo->txrate;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+               }
+               if ((link_sinfo->filled &
+                    BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) &&
+                   (!init ||
+                    link_inactive_time > link_sinfo->inactive_time)) {
+                       sinfo->rxrate = link_sinfo->rxrate;
+                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
+               }
+
+               if (link_sinfo->filled &
+                   BIT_ULL(NL80211_STA_INFO_TX_DURATION) &&
+                   (!init ||
+                    link_inactive_time > link_sinfo->inactive_time)) {
+                       sinfo->tx_duration += link_sinfo->tx_duration;
+                       sinfo->filled |=
+                               BIT_ULL(NL80211_STA_INFO_TX_DURATION);
+               }
+               if (link_sinfo->filled &
+                   BIT_ULL(NL80211_STA_INFO_RX_DURATION) &&
+                   (!init ||
+                    link_inactive_time > link_sinfo->inactive_time)) {
+                       sinfo->rx_duration += link_sinfo->rx_duration;
+                       sinfo->filled |=
+                               BIT_ULL(NL80211_STA_INFO_RX_DURATION);
+               }
+               init++;
+
+               /* pertid stats accumulate for rx/tx fields */
+               if (sinfo->pertid) {
+                       sinfo->pertid->rx_msdu +=
+                               link_sinfo->pertid->rx_msdu;
+                       sinfo->pertid->tx_msdu +=
+                               link_sinfo->pertid->tx_msdu;
+                       sinfo->pertid->tx_msdu_retries +=
+                               link_sinfo->pertid->tx_msdu_retries;
+                       sinfo->pertid->tx_msdu_failed +=
+                               link_sinfo->pertid->tx_msdu_failed;
+
+                       sinfo->pertid->filled |=
+                               BIT(NL80211_TID_STATS_RX_MSDU) |
+                               BIT(NL80211_TID_STATS_TX_MSDU) |
+                               BIT(NL80211_TID_STATS_TX_MSDU_RETRIES) |
+                               BIT(NL80211_TID_STATS_TX_MSDU_FAILED);
+               }
+       }
+}
+
 static int nl80211_dump_station(struct sk_buff *skb,
                                struct netlink_callback *cb)
 {
                if (err)
                        goto out_err;
 
+               if (sinfo.valid_links)
+                       cfg80211_sta_set_mld_sinfo(&sinfo);
+
                if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
                                NETLINK_CB(cb->skb).portid,
                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
                return -ENOMEM;
        }
 
+       if (sinfo.valid_links)
+               cfg80211_sta_set_mld_sinfo(&sinfo);
+
        if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
                                 info->snd_portid, info->snd_seq, 0,
                                 rdev, dev, mac_addr, &sinfo) < 0) {