blob: 945a5bd52c6a2a86961871c73747f64c85e8548b [file] [log] [blame]
developer83ad30d2023-09-12 17:28:06 +08001From e2aa2e712fbebfbbb2338debd632d83157d72e92 Mon Sep 17 00:00:00 2001
developer8a6d4bd2023-06-12 13:23:37 +08002From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Mon, 20 Feb 2023 14:25:24 +0800
developer83ad30d2023-09-12 17:28:06 +08004Subject: [PATCH 16/21] mac80211: mtk: add sta-assisted DFS state update
5 mechanism
developer8a6d4bd2023-06-12 13:23:37 +08006
7Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
8---
9 include/net/cfg80211.h | 14 +++++++++
10 include/uapi/linux/nl80211.h | 6 ++++
11 net/mac80211/mlme.c | 12 ++++++++
12 net/wireless/chan.c | 60 ++++++++++++++++++++++++++++++++++++
13 4 files changed, 92 insertions(+)
14
15diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
developer83ad30d2023-09-12 17:28:06 +080016index cd0ec8a..2c51c3e 100644
developer8a6d4bd2023-06-12 13:23:37 +080017--- a/include/net/cfg80211.h
18+++ b/include/net/cfg80211.h
developer83ad30d2023-09-12 17:28:06 +080019@@ -8430,6 +8430,20 @@ void cfg80211_cac_event(struct net_device *netdev,
developer8a6d4bd2023-06-12 13:23:37 +080020 const struct cfg80211_chan_def *chandef,
21 enum nl80211_radar_event event, gfp_t gfp);
22
23+/**
24+ * cfg80211_sta_update_dfs_state - Update channel's DFS state during STA channel switch,
25+ * association, and disassociation
26+ * @wdev: the wireless device
27+ * @bss_chandef: the current BSS channel definition
28+ * @csa_chandef: the CSA channel definition
29+ * @associated: whether STA is during association or disassociation process
30+ *
31+ */
32+void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
33+ const struct cfg80211_chan_def *bss_chandef,
34+ const struct cfg80211_chan_def *csa_chandef,
35+ bool associated);
36+
37 /**
38 * cfg80211_background_cac_abort - Channel Availability Check offchan abort event
39 * @wiphy: the wiphy
40diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
developer83ad30d2023-09-12 17:28:06 +080041index 72ef4d9..60c6f79 100644
developer8a6d4bd2023-06-12 13:23:37 +080042--- a/include/uapi/linux/nl80211.h
43+++ b/include/uapi/linux/nl80211.h
developer83ad30d2023-09-12 17:28:06 +080044@@ -6671,6 +6671,10 @@ enum nl80211_smps_mode {
developer8a6d4bd2023-06-12 13:23:37 +080045 * applicable for ETSI dfs domain where pre-CAC is valid for ever.
46 * @NL80211_RADAR_CAC_STARTED: Channel Availability Check has been started,
47 * should be generated by HW if NL80211_EXT_FEATURE_DFS_OFFLOAD is enabled.
48+ * @NL80211_RADAR_STA_CAC_SKIPPED: STA set the DFS state to available
49+ * when receiving CSA/assoc resp
50+ * @NL80211_RADAR_STA_CAC_EXPIRED: STA set the DFS state to usable
51+ * when STA is disconnected or leaving the channel
52 */
53 enum nl80211_radar_event {
54 NL80211_RADAR_DETECTED,
developer83ad30d2023-09-12 17:28:06 +080055@@ -6679,6 +6683,8 @@ enum nl80211_radar_event {
developer8a6d4bd2023-06-12 13:23:37 +080056 NL80211_RADAR_NOP_FINISHED,
57 NL80211_RADAR_PRE_CAC_EXPIRED,
58 NL80211_RADAR_CAC_STARTED,
59+ NL80211_RADAR_STA_CAC_SKIPPED,
60+ NL80211_RADAR_STA_CAC_EXPIRED,
61 };
62
63 /**
64diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
developer83ad30d2023-09-12 17:28:06 +080065index 86f762d..df39a8b 100644
developer8a6d4bd2023-06-12 13:23:37 +080066--- a/net/mac80211/mlme.c
67+++ b/net/mac80211/mlme.c
developer83ad30d2023-09-12 17:28:06 +080068@@ -1981,6 +1981,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
developer8a6d4bd2023-06-12 13:23:37 +080069 IEEE80211_QUEUE_STOP_REASON_CSA);
70 mutex_unlock(&local->mtx);
71
72+ cfg80211_sta_update_dfs_state(&sdata->wdev,
73+ &sdata->vif.bss_conf.chandef,
74+ &link->csa_chandef,
75+ sdata->vif.cfg.assoc);
76+
developer83ad30d2023-09-12 17:28:06 +080077 cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef,
78 link->link_id, csa_ie.count,
79 csa_ie.mode, 0);
80@@ -3066,6 +3071,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
developer8a6d4bd2023-06-12 13:23:37 +080081 sizeof(sdata->vif.bss_conf.tx_pwr_env));
82
developer83ad30d2023-09-12 17:28:06 +080083 ieee80211_vif_set_links(sdata, 0, 0);
developer8a6d4bd2023-06-12 13:23:37 +080084+
85+ cfg80211_sta_update_dfs_state(&sdata->wdev,
86+ &sdata->vif.bss_conf.chandef,
87+ NULL, sdata->vif.cfg.assoc);
88 }
89
90 static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
developer83ad30d2023-09-12 17:28:06 +080091@@ -5445,6 +5454,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
developer8a6d4bd2023-06-12 13:23:37 +080092 event.u.mlme.status = MLME_SUCCESS;
93 drv_event_callback(sdata->local, sdata, &event);
94 sdata_info(sdata, "associated\n");
95+ cfg80211_sta_update_dfs_state(&sdata->wdev,
96+ &sdata->vif.bss_conf.chandef,
97+ NULL, sdata->vif.cfg.assoc);
98
99 info.success = 1;
100 }
101diff --git a/net/wireless/chan.c b/net/wireless/chan.c
developer83ad30d2023-09-12 17:28:06 +0800102index caa5acc..a7e597d 100644
developer8a6d4bd2023-06-12 13:23:37 +0800103--- a/net/wireless/chan.c
104+++ b/net/wireless/chan.c
105@@ -14,6 +14,7 @@
106 #include <net/cfg80211.h>
107 #include "core.h"
108 #include "rdev-ops.h"
109+#include "nl80211.h"
110
111 static bool cfg80211_valid_60g_freq(u32 freq)
112 {
developer83ad30d2023-09-12 17:28:06 +0800113@@ -1437,6 +1438,65 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
developer8a6d4bd2023-06-12 13:23:37 +0800114 }
115 EXPORT_SYMBOL(cfg80211_any_usable_channels);
116
117+static void cfg80211_sta_radar_notify(struct wiphy *wiphy,
118+ const struct cfg80211_chan_def *chandef,
119+ enum nl80211_radar_event event)
120+{
121+ struct wireless_dev *wdev;
122+
123+ list_for_each_entry(wdev, &wiphy->wdev_list, list) {
124+ if (cfg80211_chandef_dfs_required(wiphy, chandef, wdev->iftype) > 0) {
125+ nl80211_radar_notify(wiphy_to_rdev(wiphy), chandef,
126+ event, wdev->netdev, GFP_KERNEL);
127+ return;
128+ }
129+ }
130+}
131+
132+void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
133+ const struct cfg80211_chan_def *bss_chandef,
134+ const struct cfg80211_chan_def *csa_chandef,
135+ bool associated)
136+{
137+ bool csa_active = !!csa_chandef;
138+ enum nl80211_dfs_state dfs_state = NL80211_DFS_USABLE;
139+ enum nl80211_radar_event event = NL80211_RADAR_STA_CAC_EXPIRED;
140+
141+ if (!bss_chandef)
142+ return;
143+
144+ /* assume csa channel is cac completed */
145+ if (csa_active &&
146+ (cfg80211_chandef_dfs_usable(wdev->wiphy, csa_chandef) ||
147+ cfg80211_chandef_dfs_available(wdev->wiphy, csa_chandef))) {
148+ cfg80211_set_dfs_state(wdev->wiphy, csa_chandef, NL80211_DFS_AVAILABLE);
149+ cfg80211_sta_radar_notify(wdev->wiphy, csa_chandef,
150+ NL80211_RADAR_STA_CAC_SKIPPED);
151+ netdev_info(wdev->netdev, "Set CSA channel's DFS state to available\n");
152+ }
153+
154+ /* avoid updating the dfs state during nop */
155+ if (!cfg80211_chandef_dfs_usable(wdev->wiphy, bss_chandef) &&
156+ !cfg80211_chandef_dfs_available(wdev->wiphy, bss_chandef))
157+ return;
158+
159+ if (associated && !csa_active) {
160+ dfs_state = NL80211_DFS_AVAILABLE;
161+ event = NL80211_RADAR_STA_CAC_SKIPPED;
162+ }
163+
164+ cfg80211_set_dfs_state(wdev->wiphy, bss_chandef, dfs_state);
165+ cfg80211_sta_radar_notify(wdev->wiphy, bss_chandef, event);
166+
167+ if (csa_active)
168+ netdev_info(wdev->netdev, "Set origin channel's DFS state to usable\n");
169+ else
170+ netdev_info(wdev->netdev, "Set BSS channel's DFS state to %s due to %s\n",
171+ (dfs_state == NL80211_DFS_USABLE) ? "usable" : "available",
172+ associated ? "association" : "disassociation");
173+}
174+EXPORT_SYMBOL(cfg80211_sta_update_dfs_state);
175+
176 struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev,
177 unsigned int link_id)
178 {
179--
developer83ad30d2023-09-12 17:28:06 +08001802.39.2
developer8a6d4bd2023-06-12 13:23:37 +0800181