|
|
@@ -0,0 +1,118 @@
|
|
|
+From dc0c18ed229cdcca283dd78fefa38273ec37a42c Mon Sep 17 00:00:00 2001
|
|
|
+From: Aaron Komisar <[email protected]>
|
|
|
+Date: Wed, 2 Oct 2019 13:59:07 +0000
|
|
|
+Subject: mac80211: fix scan when operating on DFS channels in ETSI domains
|
|
|
+
|
|
|
+In non-ETSI regulatory domains scan is blocked when operating channel
|
|
|
+is a DFS channel. For ETSI, however, once DFS channel is marked as
|
|
|
+available after the CAC, this channel will remain available (for some
|
|
|
+time) even after leaving this channel.
|
|
|
+
|
|
|
+Therefore a scan can be done without any impact on the availability
|
|
|
+of the DFS channel as no new CAC is required after the scan.
|
|
|
+
|
|
|
+Enable scan in mac80211 in these cases.
|
|
|
+
|
|
|
+Signed-off-by: Aaron Komisar <[email protected]>
|
|
|
+Link: https://lore.kernel.org/r/[email protected]
|
|
|
+Signed-off-by: Johannes Berg <[email protected]>
|
|
|
+---
|
|
|
+ include/net/cfg80211.h | 8 ++++++++
|
|
|
+ net/mac80211/scan.c | 30 ++++++++++++++++++++++++++++--
|
|
|
+ net/wireless/reg.c | 1 +
|
|
|
+ net/wireless/reg.h | 8 --------
|
|
|
+ 4 files changed, 37 insertions(+), 10 deletions(-)
|
|
|
+
|
|
|
+--- a/include/net/cfg80211.h
|
|
|
++++ b/include/net/cfg80211.h
|
|
|
+@@ -5451,6 +5451,14 @@ const struct ieee80211_reg_rule *freq_re
|
|
|
+ const char *reg_initiator_name(enum nl80211_reg_initiator initiator);
|
|
|
+
|
|
|
+ /**
|
|
|
++ * regulatory_pre_cac_allowed - check if pre-CAC allowed in the current regdom
|
|
|
++ * @wiphy: wiphy for which pre-CAC capability is checked.
|
|
|
++ *
|
|
|
++ * Pre-CAC is allowed only in some regdomains (notable ETSI).
|
|
|
++ */
|
|
|
++bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
|
|
|
++
|
|
|
++/**
|
|
|
+ * DOC: Internal regulatory db functions
|
|
|
+ *
|
|
|
+ */
|
|
|
+--- a/net/mac80211/scan.c
|
|
|
++++ b/net/mac80211/scan.c
|
|
|
+@@ -520,10 +520,33 @@ static int ieee80211_start_sw_scan(struc
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
++static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata)
|
|
|
++{
|
|
|
++ struct ieee80211_local *local = sdata->local;
|
|
|
++ struct ieee80211_sub_if_data *sdata_iter;
|
|
|
++
|
|
|
++ if (!ieee80211_is_radar_required(local))
|
|
|
++ return true;
|
|
|
++
|
|
|
++ if (!regulatory_pre_cac_allowed(local->hw.wiphy))
|
|
|
++ return false;
|
|
|
++
|
|
|
++ mutex_lock(&local->iflist_mtx);
|
|
|
++ list_for_each_entry(sdata_iter, &local->interfaces, list) {
|
|
|
++ if (sdata_iter->wdev.cac_started) {
|
|
|
++ mutex_unlock(&local->iflist_mtx);
|
|
|
++ return false;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ mutex_unlock(&local->iflist_mtx);
|
|
|
++
|
|
|
++ return true;
|
|
|
++}
|
|
|
++
|
|
|
+ static bool ieee80211_can_scan(struct ieee80211_local *local,
|
|
|
+ struct ieee80211_sub_if_data *sdata)
|
|
|
+ {
|
|
|
+- if (ieee80211_is_radar_required(local))
|
|
|
++ if (!__ieee80211_can_leave_ch(sdata))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (!list_empty(&local->roc_list))
|
|
|
+@@ -630,7 +653,10 @@ static int __ieee80211_start_scan(struct
|
|
|
+
|
|
|
+ lockdep_assert_held(&local->mtx);
|
|
|
+
|
|
|
+- if (local->scan_req || ieee80211_is_radar_required(local))
|
|
|
++ if (local->scan_req)
|
|
|
++ return -EBUSY;
|
|
|
++
|
|
|
++ if (!__ieee80211_can_leave_ch(sdata))
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
+ if (!ieee80211_can_scan(local, sdata)) {
|
|
|
+--- a/net/wireless/reg.c
|
|
|
++++ b/net/wireless/reg.c
|
|
|
+@@ -3866,6 +3866,7 @@ bool regulatory_pre_cac_allowed(struct w
|
|
|
+
|
|
|
+ return pre_cac_allowed;
|
|
|
+ }
|
|
|
++EXPORT_SYMBOL(regulatory_pre_cac_allowed);
|
|
|
+
|
|
|
+ void regulatory_propagate_dfs_state(struct wiphy *wiphy,
|
|
|
+ struct cfg80211_chan_def *chandef,
|
|
|
+--- a/net/wireless/reg.h
|
|
|
++++ b/net/wireless/reg.h
|
|
|
+@@ -156,14 +156,6 @@ bool regulatory_indoor_allowed(void);
|
|
|
+ #define REG_PRE_CAC_EXPIRY_GRACE_MS 2000
|
|
|
+
|
|
|
+ /**
|
|
|
+- * regulatory_pre_cac_allowed - if pre-CAC allowed in the current dfs domain
|
|
|
+- * @wiphy: wiphy for which pre-CAC capability is checked.
|
|
|
+-
|
|
|
+- * Pre-CAC is allowed only in ETSI domain.
|
|
|
+- */
|
|
|
+-bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
|
|
|
+-
|
|
|
+-/**
|
|
|
+ * regulatory_propagate_dfs_state - Propagate DFS channel state to other wiphys
|
|
|
+ * @wiphy - wiphy on which radar is detected and the event will be propagated
|
|
|
+ * to other available wiphys having the same DFS domain
|