@@ -4294,9 +4294,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
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
@@ -4342,9 +4339,6 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
lockdep_assert_wiphy(sdata->local->hw.wiphy);
- if (WARN_ON_ONCE(ieee80211_vif_is_mld(&sdata->vif)))
- return;
-
if (!ieee80211_sdata_running(sdata))
return;
@@ -8439,36 +8433,71 @@ static void ieee80211_sta_bcn_mon_timer(struct timer_list *t)
&sdata->u.mgd.beacon_connection_loss_work);
}
+static bool
+ieee80211_is_all_links_timed_out(struct ieee80211_sub_if_data *sdata,
+ unsigned long *latest_timeout)
+{
+ bool all_links_timed_out = true;
+ unsigned int link_id;
+ struct sta_info *sta;
+
+ guard(rcu)();
+ sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
+ if (!sta)
+ return true;
+
+ 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)) {
+ all_links_timed_out = false;
+ if (time_after(timeout, *latest_timeout))
+ *latest_timeout = timeout;
+ }
+ }
+
+ return all_links_timed_out;
+}
+
static void ieee80211_sta_conn_mon_timer(struct timer_list *t)
{
struct ieee80211_sub_if_data *sdata =
from_timer(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;
-
- 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;
+ unsigned long latest_timeout = 0;
+ bool all_links_timed_out = true;
- 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;
-
- /* If timeout is after now, then update timer to fire at
+ all_links_timed_out = ieee80211_is_all_links_timed_out(sdata,
+ &latest_timeout);
+ /* 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 (!all_links_timed_out) {
+ mod_timer(&ifmgd->conn_mon_timer,
+ round_jiffies_up(latest_timeout));
return;
}
Currently, reset connection monitor (ieee80211_sta_reset_conn_monitor()) timer is handled only for non-AP non-MLD STA and do not support non-AP MLD STA. The current implementation checks for the CSA active and update the monitor timer with the timeout value of deflink and reset the timer based on the deflink's timeout value else schedule the connection loss work when the deflink is timed out and it won't work for the non-AP MLD STA. Handle the reset connection monitor timer for non-AP MLD STA by updating the monitor timer with the timeout value which is determined based on the link that will expire last among all the links in MLO. If at least one link has not timed out, the timer is updated accordingly with the latest timeout value else schedule the connection loss work when all links have timed out. Remove the MLO-related WARN_ON() checks in the beacon and connection monitoring logic code paths as they support MLO now. Signed-off-by: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com> --- net/mac80211/mlme.c | 79 +++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 25 deletions(-)