aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Komisar <aaron.komisar@tandemg.com>2019-10-02 09:59:07 -0400
committerJohannes Berg <johannes.berg@intel.com>2019-10-07 16:10:50 -0400
commitdc0c18ed229cdcca283dd78fefa38273ec37a42c (patch)
tree986840000f070e524e4c802074e1cea589c05c9c
parent95697f9907bfe3eab0ef20265a766b22e27dde64 (diff)
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 <aaron.komisar@tandemg.com> Link: https://lore.kernel.org/r/1570024728-17284-1-git-send-email-aaron.komisar@tandemg.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h8
-rw-r--r--net/mac80211/scan.c30
-rw-r--r--net/wireless/reg.c1
-rw-r--r--net/wireless/reg.h8
4 files changed, 37 insertions, 10 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ff45c3e1abff..4ab2c49423dc 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5550,6 +5550,14 @@ const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy,
5550const char *reg_initiator_name(enum nl80211_reg_initiator initiator); 5550const char *reg_initiator_name(enum nl80211_reg_initiator initiator);
5551 5551
5552/** 5552/**
5553 * regulatory_pre_cac_allowed - check if pre-CAC allowed in the current regdom
5554 * @wiphy: wiphy for which pre-CAC capability is checked.
5555 *
5556 * Pre-CAC is allowed only in some regdomains (notable ETSI).
5557 */
5558bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
5559
5560/**
5553 * DOC: Internal regulatory db functions 5561 * DOC: Internal regulatory db functions
5554 * 5562 *
5555 */ 5563 */
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index adf94ba1ed77..4d31d9688dc2 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -520,10 +520,33 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local,
520 return 0; 520 return 0;
521} 521}
522 522
523static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata)
524{
525 struct ieee80211_local *local = sdata->local;
526 struct ieee80211_sub_if_data *sdata_iter;
527
528 if (!ieee80211_is_radar_required(local))
529 return true;
530
531 if (!regulatory_pre_cac_allowed(local->hw.wiphy))
532 return false;
533
534 mutex_lock(&local->iflist_mtx);
535 list_for_each_entry(sdata_iter, &local->interfaces, list) {
536 if (sdata_iter->wdev.cac_started) {
537 mutex_unlock(&local->iflist_mtx);
538 return false;
539 }
540 }
541 mutex_unlock(&local->iflist_mtx);
542
543 return true;
544}
545
523static bool ieee80211_can_scan(struct ieee80211_local *local, 546static bool ieee80211_can_scan(struct ieee80211_local *local,
524 struct ieee80211_sub_if_data *sdata) 547 struct ieee80211_sub_if_data *sdata)
525{ 548{
526 if (ieee80211_is_radar_required(local)) 549 if (!__ieee80211_can_leave_ch(sdata))
527 return false; 550 return false;
528 551
529 if (!list_empty(&local->roc_list)) 552 if (!list_empty(&local->roc_list))
@@ -630,7 +653,10 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
630 653
631 lockdep_assert_held(&local->mtx); 654 lockdep_assert_held(&local->mtx);
632 655
633 if (local->scan_req || ieee80211_is_radar_required(local)) 656 if (local->scan_req)
657 return -EBUSY;
658
659 if (!__ieee80211_can_leave_ch(sdata))
634 return -EBUSY; 660 return -EBUSY;
635 661
636 if (!ieee80211_can_scan(local, sdata)) { 662 if (!ieee80211_can_scan(local, sdata)) {
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 420c4207ab59..446c76d44e65 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3883,6 +3883,7 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy)
3883 3883
3884 return pre_cac_allowed; 3884 return pre_cac_allowed;
3885} 3885}
3886EXPORT_SYMBOL(regulatory_pre_cac_allowed);
3886 3887
3887void regulatory_propagate_dfs_state(struct wiphy *wiphy, 3888void regulatory_propagate_dfs_state(struct wiphy *wiphy,
3888 struct cfg80211_chan_def *chandef, 3889 struct cfg80211_chan_def *chandef,
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 504133d76de4..dc8f689bd469 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -156,14 +156,6 @@ bool regulatory_indoor_allowed(void);
156#define REG_PRE_CAC_EXPIRY_GRACE_MS 2000 156#define REG_PRE_CAC_EXPIRY_GRACE_MS 2000
157 157
158/** 158/**
159 * regulatory_pre_cac_allowed - if pre-CAC allowed in the current dfs domain
160 * @wiphy: wiphy for which pre-CAC capability is checked.
161
162 * Pre-CAC is allowed only in ETSI domain.
163 */
164bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
165
166/**
167 * regulatory_propagate_dfs_state - Propagate DFS channel state to other wiphys 159 * regulatory_propagate_dfs_state - Propagate DFS channel state to other wiphys
168 * @wiphy - wiphy on which radar is detected and the event will be propagated 160 * @wiphy - wiphy on which radar is detected and the event will be propagated
169 * to other available wiphys having the same DFS domain 161 * to other available wiphys having the same DFS domain