lockdep_assert_wiphy(sdata->local->hw.wiphy);
 
-       if (WARN_ON(ieee80211_vif_is_mld(&sdata->vif)))
-               return;
-
        /*
         * Try sending broadcast probe requests for the last three
         * probe requests after the first ones failed since some
 
        lockdep_assert_wiphy(sdata->local->hw.wiphy);
 
-       if (WARN_ON_ONCE(ieee80211_vif_is_mld(&sdata->vif)))
-               return;
-
        if (!ieee80211_sdata_running(sdata))
                return;
 
                         &sdata->u.mgd.beacon_connection_loss_work);
 }
 
+static unsigned long
+ieee80211_latest_active_link_conn_timeout(struct ieee80211_sub_if_data *sdata)
+{
+       unsigned long latest_timeout;
+       unsigned int link_id;
+       struct sta_info *sta;
+
+       guard(rcu)();
+
+       sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
+       if (!sta)
+               return 0;
+
+       for (link_id = 0; link_id < ARRAY_SIZE(sta->link);
+            link_id++) {
+               struct link_sta_info *link_sta;
+               unsigned long timeout;
+
+               link_sta = rcu_dereference(sta->link[link_id]);
+               if (!link_sta)
+                       continue;
+
+               timeout = link_sta->status_stats.last_ack;
+               if (time_before(timeout, link_sta->rx_stats.last_rx))
+                       timeout = link_sta->rx_stats.last_rx;
+
+               timeout += IEEE80211_CONNECTION_IDLE_TIME;
+
+               /*
+                * latest_timeout holds the timeout of the link
+                * that will expire last among all links in an
+                * non-AP MLD STA. This ensures that the connection
+                * monitor timer is only reset if at least one link
+                * is still active, and it is scheduled to fire at
+                * the latest possible timeout.
+                */
+               if (time_is_after_jiffies(timeout) &&
+                   time_after(timeout, latest_timeout))
+                       latest_timeout = timeout;
+       }
+
+       return latest_timeout;
+}
+
 static void ieee80211_sta_conn_mon_timer(struct timer_list *t)
 {
        struct ieee80211_sub_if_data *sdata =
                timer_container_of(sdata, t, u.mgd.conn_mon_timer);
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-       unsigned long timeout;
+       unsigned long latest_timeout;
 
-       if (WARN_ON(ieee80211_vif_is_mld(&sdata->vif)))
-               return;
-
-       if (sdata->vif.bss_conf.csa_active &&
-           !sdata->deflink.u.mgd.csa.waiting_bcn)
-               return;
-
-       sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
-       if (!sta)
+       if (ieee80211_is_csa_in_progress(sdata))
                return;
 
-       timeout = sta->deflink.status_stats.last_ack;
-       if (time_before(sta->deflink.status_stats.last_ack, sta->deflink.rx_stats.last_rx))
-               timeout = sta->deflink.rx_stats.last_rx;
-       timeout += IEEE80211_CONNECTION_IDLE_TIME;
+       latest_timeout = ieee80211_latest_active_link_conn_timeout(sdata);
 
-       /* If timeout is after now, then update timer to fire at
+       /*
+        * If latest timeout is after now, then update timer to fire at
         * the later date, but do not actually probe at this time.
         */
-       if (time_is_after_jiffies(timeout)) {
-               mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout));
+       if (latest_timeout) {
+               mod_timer(&ifmgd->conn_mon_timer,
+                         round_jiffies_up(latest_timeout));
                return;
        }