blob: e11bb25066d1e95439e3d7a7534fca11dfdc6b81 [file] [log] [blame]
From bd62e65e77de5464c1014610d391699e9d8e1bb6 Mon Sep 17 00:00:00 2001
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
Date: Thu, 11 Jul 2024 09:21:45 +0530
Subject: [PATCH 14/89] bp: wifi: mac80211: handle DFS per link
In order to support DFS with MLO, handle the link ID now passed from
cfg80211, adjust the code to do everything per link and call the
notifications to cfg80211 correctly.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
net/mac80211/cfg.c | 26 ++++++++++++++++++--------
net/mac80211/link.c | 10 ++++++++++
net/mac80211/util.c | 29 +++++++++++++++++++++++------
3 files changed, 51 insertions(+), 14 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index cf60420..d5ddbce 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3460,6 +3460,7 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_chan_req chanreq = { .oper = *chandef };
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_link_data *link_data;
int err;
lockdep_assert_wiphy(local->hw.wiphy);
@@ -3467,16 +3468,20 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
if (!list_empty(&local->roc_list) || local->scanning)
return -EBUSY;
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
+ if (!link_data)
+ return -ENOLINK;
+
/* whatever, but channel contexts should not complain about that one */
- sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
- sdata->deflink.needed_rx_chains = local->rx_chains;
+ link_data->smps_mode = IEEE80211_SMPS_OFF;
+ link_data->needed_rx_chains = local->rx_chains;
- err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
+ err = ieee80211_link_use_channel(link_data, &chanreq,
IEEE80211_CHANCTX_SHARED);
if (err)
return err;
- wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
+ wiphy_delayed_work_queue(wiphy, &link_data->dfs_cac_timer_work,
msecs_to_jiffies(cac_time_ms));
return 0;
@@ -3487,16 +3492,21 @@ static void ieee80211_end_cac(struct wiphy *wiphy,
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_link_data *link_data;
lockdep_assert_wiphy(local->hw.wiphy);
list_for_each_entry(sdata, &local->interfaces, list) {
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
+ if (!link_data)
+ continue;
+
wiphy_delayed_work_cancel(wiphy,
- &sdata->deflink.dfs_cac_timer_work);
+ &link_data->dfs_cac_timer_work);
- if (sdata->wdev.links[0].cac_started) {
- ieee80211_link_release_channel(&sdata->deflink);
- sdata->wdev.links[0].cac_started = false;
+ if (sdata->wdev.links[link_id].cac_started) {
+ ieee80211_link_release_channel(link_data);
+ sdata->wdev.links[link_id].cac_started = false;
}
}
}
diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index b437896..0bbac64 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -77,6 +77,16 @@ void ieee80211_link_stop(struct ieee80211_link_data *link)
&link->color_change_finalize_work);
wiphy_work_cancel(link->sdata->local->hw.wiphy,
&link->csa.finalize_work);
+
+ if (link->sdata->wdev.links[link->link_id].cac_started) {
+ wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
+ &link->dfs_cac_timer_work);
+ cfg80211_cac_event(link->sdata->dev,
+ &link->conf->chanreq.oper,
+ NL80211_RADAR_CAC_ABORTED,
+ GFP_KERNEL, link->link_id);
+ }
+
ieee80211_link_release_channel(link);
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 5996ea7..59dde03 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3455,20 +3455,37 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata;
struct cfg80211_chan_def chandef;
+ struct ieee80211_link_data *link_data;
+ struct ieee80211_bss_conf *link_conf;
+ unsigned int link_id;
lockdep_assert_wiphy(local->hw.wiphy);
list_for_each_entry(sdata, &local->interfaces, list) {
- wiphy_delayed_work_cancel(local->hw.wiphy,
- &sdata->deflink.dfs_cac_timer_work);
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
+ link_id++) {
+ link_data = sdata_dereference(sdata->link[link_id],
+ sdata);
+ if (!link_data)
+ continue;
+
+ wiphy_delayed_work_cancel(local->hw.wiphy,
+ &link_data->dfs_cac_timer_work);
+
+ if (!sdata->wdev.links[link_id].cac_started)
+ continue;
+
+ link_conf =
+ rcu_dereference(sdata->vif.link_conf[link_id]);
+ if (!link_conf)
+ continue;
- if (sdata->wdev.links[0].cac_started) {
- chandef = sdata->vif.bss_conf.chanreq.oper;
- ieee80211_link_release_channel(&sdata->deflink);
+ chandef = link_conf->chanreq.oper;
+ ieee80211_link_release_channel(link_data);
cfg80211_cac_event(sdata->dev,
&chandef,
NL80211_RADAR_CAC_ABORTED,
- GFP_KERNEL, 0);
+ GFP_KERNEL, link_id);
}
}
}
--
2.18.0