]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mac80211: use wiphy_hrtimer_work for CAC timeout
authorAmith A <amith.a@oss.qualcomm.com>
Fri, 30 Jan 2026 03:55:11 +0000 (09:25 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 2 Feb 2026 09:06:14 +0000 (10:06 +0100)
Prior initiating communication in a DFS channel, there should be a
monitoring of RADAR in that channel for a minimum of 600 seconds if it
is a Weather RADAR channel and 60 seconds for other DFS channels. This
Channel Availability Check(CAC) is currently implemented by scheduling
a work item for execution with a delay equal to an appropriate timeout.
But this work item is observed to take more delay than specified
(4-5 seconds in regular DFS channels and 25-30 seconds in Weather RADAR
channels). Even though this delay is expected in case of delayed work
queue as there is no guarantee that the work will be scheduled exactly
after the specified delay, a delay of more than 20 seconds is too much
for the AP to be in non-operational state.

Recently commit 7ceba45a6658 ("wifi: cfg80211: add an hrtimer based
delayed work item") added an infrastructure to overcome this issue by
supporting high resolution timers for mac80211 delayed work, which do not
have this timeout latency. Switch the CAC timeout to use this
infrastructure, so the CAC completion handling is triggered with tighter
timing and reduced latency.

Signed-off-by: Amith A <amith.a@oss.qualcomm.com>
Link: https://patch.msgid.link/20260130035511.2328713-1-amith.a@oss.qualcomm.com
[fix delay handling]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/link.c
net/mac80211/util.c

index 964f440e31cdb2517f3daba5f003c6115316c227..3551049d64b33a52677b4efe2aa3f20d6236e8ef 100644 (file)
@@ -1916,7 +1916,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
 
        if (sdata->wdev.links[link_id].cac_started) {
                chandef = link_conf->chanreq.oper;
-               wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
+               wiphy_hrtimer_work_cancel(wiphy, &link->dfs_cac_timer_work);
                cfg80211_cac_event(sdata->dev, &chandef,
                                   NL80211_RADAR_CAC_ABORTED,
                                   GFP_KERNEL, link_id);
@@ -3874,8 +3874,8 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
        if (err)
                return err;
 
-       wiphy_delayed_work_queue(wiphy, &link_data->dfs_cac_timer_work,
-                                msecs_to_jiffies(cac_time_ms));
+       wiphy_hrtimer_work_queue(wiphy, &link_data->dfs_cac_timer_work,
+                                ms_to_ktime(cac_time_ms));
 
        return 0;
 }
@@ -3894,7 +3894,7 @@ static void ieee80211_end_cac(struct wiphy *wiphy,
                if (!link_data)
                        continue;
 
-               wiphy_delayed_work_cancel(wiphy,
+               wiphy_hrtimer_work_cancel(wiphy,
                                          &link_data->dfs_cac_timer_work);
 
                if (sdata->wdev.links[link_id].cac_started) {
index ea4c9293d2993187bddca9b97716133bbe1f2844..e9e3b7f60ff5328ec1c48b6b11070ba84a785eb5 100644 (file)
@@ -1099,7 +1099,7 @@ struct ieee80211_link_data {
        int ap_power_level; /* in dBm */
 
        bool radar_required;
-       struct wiphy_delayed_work dfs_cac_timer_work;
+       struct wiphy_hrtimer_work dfs_cac_timer_work;
 
        union {
                struct ieee80211_link_data_managed mgd;
index 463b78093d3ef1fbaaffedf56785c5a2a0fb6e67..5dfe605b37d4532df5b2a182627a5e1d152d1a14 100644 (file)
@@ -565,7 +565,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
        wiphy_work_cancel(local->hw.wiphy, &sdata->deflink.csa.finalize_work);
        wiphy_work_cancel(local->hw.wiphy,
                          &sdata->deflink.color_change_finalize_work);
-       wiphy_delayed_work_cancel(local->hw.wiphy,
+       wiphy_hrtimer_work_cancel(local->hw.wiphy,
                                  &sdata->deflink.dfs_cac_timer_work);
 
        if (sdata->wdev.links[0].cac_started) {
index 1e05845872afc86f3188336c178f5b7c3b3fec52..17bf55dabd31eed342247afed03326ae13ad44e9 100644 (file)
@@ -116,7 +116,7 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
                        ieee80211_color_change_finalize_work);
        wiphy_delayed_work_init(&link->color_collision_detect_work,
                                ieee80211_color_collision_detection_work);
-       wiphy_delayed_work_init(&link->dfs_cac_timer_work,
+       wiphy_hrtimer_work_init(&link->dfs_cac_timer_work,
                                ieee80211_dfs_cac_timer_work);
 
        if (!deflink) {
@@ -155,7 +155,7 @@ void ieee80211_link_stop(struct ieee80211_link_data *link)
                          &link->csa.finalize_work);
 
        if (link->sdata->wdev.links[link->link_id].cac_started) {
-               wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
+               wiphy_hrtimer_work_cancel(link->sdata->local->hw.wiphy,
                                          &link->dfs_cac_timer_work);
                cfg80211_cac_event(link->sdata->dev,
                                   &link->conf->chanreq.oper,
index 4d5680da7aa0f60555feb3d3d5f9f06aee2867ee..260893b83df1696daf66bdbed33267884d0e3952 100644 (file)
@@ -3597,7 +3597,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local,
                        if (ctx && &ctx->conf != chanctx_conf)
                                continue;
 
-                       wiphy_delayed_work_cancel(local->hw.wiphy,
+                       wiphy_hrtimer_work_cancel(local->hw.wiphy,
                                                  &link->dfs_cac_timer_work);
 
                        if (!sdata->wdev.links[link_id].cac_started)