|
@@ -928,6 +928,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|
|
/* TODO: make hostapd tell us what it wants */
|
|
|
sdata->smps_mode = IEEE80211_SMPS_OFF;
|
|
|
sdata->needed_rx_chains = sdata->local->rx_chains;
|
|
|
+ sdata->radar_required = params->radar_required;
|
|
|
|
|
|
err = ieee80211_vif_use_channel(sdata, ¶ms->chandef,
|
|
|
IEEE80211_CHANCTX_SHARED);
|
|
@@ -2395,7 +2396,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
|
|
INIT_LIST_HEAD(&roc->dependents);
|
|
|
|
|
|
/* if there's one pending or we're scanning, queue this one */
|
|
|
- if (!list_empty(&local->roc_list) || local->scanning)
|
|
|
+ if (!list_empty(&local->roc_list) ||
|
|
|
+ local->scanning || local->radar_detect_enabled)
|
|
|
goto out_check_combine;
|
|
|
|
|
|
/* if not HW assist, just queue & schedule work */
|
|
@@ -2645,6 +2647,37 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
|
|
|
return ieee80211_cancel_roc(local, cookie, false);
|
|
|
}
|
|
|
|
|
|
+static int ieee80211_start_radar_detection(struct wiphy *wiphy,
|
|
|
+ struct net_device *dev,
|
|
|
+ struct cfg80211_chan_def *chandef)
|
|
|
+{
|
|
|
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
|
+ struct ieee80211_local *local = sdata->local;
|
|
|
+ unsigned long timeout;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ if (!list_empty(&local->roc_list) || local->scanning)
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
+ /* whatever, but channel contexts should not complain about that one */
|
|
|
+ sdata->smps_mode = IEEE80211_SMPS_OFF;
|
|
|
+ sdata->needed_rx_chains = local->rx_chains;
|
|
|
+ sdata->radar_required = true;
|
|
|
+
|
|
|
+ mutex_lock(&local->iflist_mtx);
|
|
|
+ err = ieee80211_vif_use_channel(sdata, chandef,
|
|
|
+ IEEE80211_CHANCTX_SHARED);
|
|
|
+ mutex_unlock(&local->iflist_mtx);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
|
|
|
+ ieee80211_queue_delayed_work(&sdata->local->hw,
|
|
|
+ &sdata->dfs_cac_timer_work, timeout);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|
|
struct ieee80211_channel *chan, bool offchan,
|
|
|
unsigned int wait, const u8 *buf, size_t len,
|
|
@@ -3350,4 +3383,5 @@ struct cfg80211_ops mac80211_config_ops = {
|
|
|
.get_et_stats = ieee80211_get_et_stats,
|
|
|
.get_et_strings = ieee80211_get_et_strings,
|
|
|
.get_channel = ieee80211_cfg_get_channel,
|
|
|
+ .start_radar_detection = ieee80211_start_radar_detection,
|
|
|
};
|