diff --git a/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch b/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch new file mode 100644 index 0000000000..7bba7176cb --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch @@ -0,0 +1,118 @@ +From dc0c18ed229cdcca283dd78fefa38273ec37a42c Mon Sep 17 00:00:00 2001 +From: Aaron Komisar +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 +Link: https://lore.kernel.org/r/1570024728-17284-1-git-send-email-aaron.komisar@tandemg.com +Signed-off-by: Johannes Berg +--- + 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