@@ -545,6 +545,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work);
INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
INIT_WORK(&rdev->event_work, cfg80211_event_work);
+ INIT_DELAYED_WORK(&rdev->offchan_cac_work, cfg80211_offchan_cac_work);
init_waitqueue_head(&rdev->dev_wait);
@@ -86,6 +86,8 @@ struct cfg80211_registered_device {
struct mutex offchan_mutex; /* protect offchan_radar_wdev */
struct wireless_dev *offchan_radar_wdev;
+ struct cfg80211_chan_def offchan_radar_chandef;
+ struct delayed_work offchan_cac_work;
/* netlink port which started critical protocol (0 means not started) */
u32 crit_proto_nlportid;
@@ -500,6 +502,8 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
int
cfg80211_stop_offchan_radar_detection(struct cfg80211_registered_device *rdev);
+void cfg80211_offchan_cac_work(struct work_struct *work);
+
bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
struct ieee80211_channel *chan);
@@ -969,6 +969,17 @@ void cfg80211_cac_event(struct net_device *netdev,
}
EXPORT_SYMBOL(cfg80211_cac_event);
+void cfg80211_offchan_cac_work(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct cfg80211_registered_device *rdev;
+
+ rdev = container_of(delayed_work, struct cfg80211_registered_device,
+ offchan_cac_work);
+ cfg80211_offchan_cac_event(&rdev->wiphy, &rdev->offchan_radar_chandef,
+ NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
+}
+
static void
__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
@@ -993,6 +1004,7 @@ __cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev,
rdev->offchan_radar_wdev = NULL;
break;
case NL80211_RADAR_CAC_ABORTED:
+ cancel_delayed_work(&rdev->offchan_cac_work);
wdev = rdev->offchan_radar_wdev;
rdev->offchan_radar_wdev = NULL;
break;
@@ -1025,6 +1037,7 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
struct cfg80211_chan_def *chandef)
{
+ unsigned int cac_time_ms;
int err = -EBUSY;
mutex_lock(&rdev->offchan_mutex);
@@ -1035,8 +1048,15 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
if (err)
goto out;
+ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, chandef);
+ if (!cac_time_ms)
+ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
+
+ rdev->offchan_radar_chandef = *chandef;
__cfg80211_offchan_cac_event(rdev, wdev, chandef,
NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
+ queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_work,
+ msecs_to_jiffies(cac_time_ms));
out:
mutex_unlock(&rdev->offchan_mutex);
return err;
Introduce cac delayed work in order to report NL80211_RADAR_CAC_FINISHED to userspace. Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> --- net/wireless/core.c | 1 + net/wireless/core.h | 4 ++++ net/wireless/mlme.c | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+)