Commit dc0c18ed authored by Aaron Komisar's avatar Aaron Komisar Committed by Johannes Berg

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: default avatarAaron Komisar <aaron.komisar@tandemg.com>
Link: https://lore.kernel.org/r/1570024728-17284-1-git-send-email-aaron.komisar@tandemg.comSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 95697f99
...@@ -5549,6 +5549,14 @@ const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, ...@@ -5549,6 +5549,14 @@ const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy,
*/ */
const char *reg_initiator_name(enum nl80211_reg_initiator initiator); 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 * DOC: Internal regulatory db functions
* *
......
...@@ -520,10 +520,33 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local, ...@@ -520,10 +520,33 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local,
return 0; 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, static bool ieee80211_can_scan(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata) struct ieee80211_sub_if_data *sdata)
{ {
if (ieee80211_is_radar_required(local)) if (!__ieee80211_can_leave_ch(sdata))
return false; return false;
if (!list_empty(&local->roc_list)) if (!list_empty(&local->roc_list))
...@@ -630,7 +653,10 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, ...@@ -630,7 +653,10 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
lockdep_assert_held(&local->mtx); 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; return -EBUSY;
if (!ieee80211_can_scan(local, sdata)) { if (!ieee80211_can_scan(local, sdata)) {
......
...@@ -3883,6 +3883,7 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy) ...@@ -3883,6 +3883,7 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy)
return pre_cac_allowed; return pre_cac_allowed;
} }
EXPORT_SYMBOL(regulatory_pre_cac_allowed);
void regulatory_propagate_dfs_state(struct wiphy *wiphy, void regulatory_propagate_dfs_state(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef, struct cfg80211_chan_def *chandef,
......
...@@ -155,14 +155,6 @@ bool regulatory_indoor_allowed(void); ...@@ -155,14 +155,6 @@ bool regulatory_indoor_allowed(void);
*/ */
#define REG_PRE_CAC_EXPIRY_GRACE_MS 2000 #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 * regulatory_propagate_dfs_state - Propagate DFS channel state to other wiphys
* @wiphy - wiphy on which radar is detected and the event will be propagated * @wiphy - wiphy on which radar is detected and the event will be propagated
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment