]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211_hwsim: background CAC support
authorJanusz Dziedzic <janusz.dziedzic@gmail.com>
Fri, 6 Feb 2026 17:15:51 +0000 (18:15 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 2 Mar 2026 08:10:28 +0000 (09:10 +0100)
Report background CAC support and add allow
to cancel background CAC and simulate radar.

echo cancel > /sys/kernel/debug/ieee80211/phy2/hwsim/dfs_background_cac
echo radar > /sys/kernel/debug/ieee80211/phy2/hwsim/dfs_background_cac

Signed-off-by: Janusz Dziedzic <janusz.dziedzic@gmail.com>
Link: https://patch.msgid.link/20260206171830.553879-5-janusz.dziedzic@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/virtual/mac80211_hwsim.c
drivers/net/wireless/virtual/mac80211_hwsim.h

index e89173f9163774f7825e2f938c79781a8d249c9b..d2a43eec4641ee830e924791ed01ffe4bf7afd60 100644 (file)
@@ -715,6 +715,7 @@ struct mac80211_hwsim_data {
        } ps;
        bool ps_poll_pending;
        struct dentry *debugfs;
+       struct cfg80211_chan_def radar_background_chandef;
 
        atomic_t pending_cookie;
        struct sk_buff_head pending;    /* packets pending */
@@ -936,6 +937,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
        [HWSIM_ATTR_PMSR_RESULT] = NLA_POLICY_NESTED(hwsim_pmsr_peers_result_policy),
        [HWSIM_ATTR_MULTI_RADIO] = { .type = NLA_FLAG },
        [HWSIM_ATTR_SUPPORT_NAN_DEVICE] = { .type = NLA_FLAG },
+       [HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR] = { .type = NLA_FLAG },
 };
 
 #if IS_REACHABLE(CONFIG_VIRTIO)
@@ -1164,6 +1166,41 @@ static int hwsim_write_simulate_radar(void *dat, u64 val)
 DEFINE_DEBUGFS_ATTRIBUTE(hwsim_simulate_radar, NULL,
                         hwsim_write_simulate_radar, "%llu\n");
 
+static ssize_t hwsim_background_cac_write(struct file *file,
+                                         const char __user *user_buf,
+                                         size_t count, loff_t *ppos)
+{
+       struct mac80211_hwsim_data *data = file->private_data;
+       char buf[8] = {};
+
+       if (count >= sizeof(buf))
+               return -EINVAL;
+
+       if (copy_from_user(buf, user_buf, count))
+               return -EFAULT;
+
+       /* Check if background radar channel is configured */
+       if (!data->radar_background_chandef.chan)
+               return -ENOENT;
+
+       if (sysfs_streq(buf, "radar"))
+               cfg80211_background_radar_event(data->hw->wiphy,
+                                               &data->radar_background_chandef,
+                                               GFP_KERNEL);
+       else if (sysfs_streq(buf, "cancel"))
+               cfg80211_background_cac_abort(data->hw->wiphy);
+       else
+               return -EINVAL;
+
+       return count;
+}
+
+static const struct file_operations hwsim_background_cac_ops = {
+       .write = hwsim_background_cac_write,
+       .open = simple_open,
+       .llseek = default_llseek,
+};
+
 static int hwsim_fops_group_read(void *dat, u64 *val)
 {
        struct mac80211_hwsim_data *data = dat;
@@ -4154,6 +4191,24 @@ static int mac80211_hwsim_change_nan_config(struct ieee80211_hw *hw,
        return 0;
 }
 
+static int mac80211_hwsim_set_radar_background(struct ieee80211_hw *hw,
+                                              struct cfg80211_chan_def *chan)
+{
+       struct mac80211_hwsim_data *data = hw->priv;
+
+       if (!wiphy_ext_feature_isset(hw->wiphy,
+                                    NL80211_EXT_FEATURE_RADAR_BACKGROUND))
+               return -EOPNOTSUPP;
+
+       if (chan)
+               data->radar_background_chandef = *chan;
+       else
+               memset(&data->radar_background_chandef, 0,
+                      sizeof(data->radar_background_chandef));
+
+       return 0;
+}
+
 #ifdef CONFIG_MAC80211_DEBUGFS
 #define HWSIM_DEBUGFS_OPS                                      \
        .link_add_debugfs = mac80211_hwsim_link_add_debugfs,
@@ -4189,6 +4244,7 @@ static int mac80211_hwsim_change_nan_config(struct ieee80211_hw *hw,
        .start_nan = mac80211_hwsim_start_nan,                  \
        .stop_nan = mac80211_hwsim_stop_nan,                    \
        .nan_change_conf = mac80211_hwsim_change_nan_config,    \
+       .set_radar_background = mac80211_hwsim_set_radar_background, \
        HWSIM_DEBUGFS_OPS
 
 #define HWSIM_NON_MLO_OPS                                      \
@@ -4255,6 +4311,7 @@ struct hwsim_new_radio_params {
        bool mlo;
        const struct cfg80211_pmsr_capabilities *pmsr_capa;
        bool nan_device;
+       bool background_radar;
 };
 
 static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
@@ -4340,6 +4397,12 @@ static int append_radio_msg(struct sk_buff *skb, int id,
                if (ret < 0)
                        return ret;
        }
+
+       if (param->background_radar) {
+               ret = nla_put_flag(skb, HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR);
+               if (ret < 0)
+                       return ret;
+       }
        return 0;
 }
 
@@ -5794,6 +5857,9 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 
        wiphy_ext_feature_set(hw->wiphy,
                              NL80211_EXT_FEATURE_DFS_CONCURRENT);
+       if (param->background_radar)
+               wiphy_ext_feature_set(hw->wiphy,
+                                     NL80211_EXT_FEATURE_RADAR_BACKGROUND);
 
        if (param->no_vif)
                ieee80211_hw_set(hw, NO_AUTO_VIF);
@@ -5832,6 +5898,10 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
                debugfs_create_file("dfs_simulate_radar", 0222,
                                    data->debugfs,
                                    data, &hwsim_simulate_radar);
+       if (param->background_radar)
+               debugfs_create_file("dfs_background_cac", 0200,
+                                   data->debugfs,
+                                   data, &hwsim_background_cac_ops);
 
        if (param->pmsr_capa) {
                data->pmsr_capa = *param->pmsr_capa;
@@ -5950,6 +6020,9 @@ static int mac80211_hwsim_get_radio(struct sk_buff *skb,
        param.channels = data->channels;
        param.hwname = wiphy_name(data->hw->wiphy);
        param.pmsr_capa = &data->pmsr_capa;
+       param.background_radar =
+               wiphy_ext_feature_isset(data->hw->wiphy,
+                                       NL80211_EXT_FEATURE_RADAR_BACKGROUND);
 
        res = append_radio_msg(skb, data->idx, &param);
        if (res < 0)
@@ -6387,6 +6460,9 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
        if (info->attrs[HWSIM_ATTR_MULTI_RADIO])
                param.multi_radio = true;
 
+       if (info->attrs[HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR])
+               param.background_radar = true;
+
        if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2])
                param.reg_alpha2 =
                        nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]);
@@ -7165,6 +7241,7 @@ static int __init init_mac80211_hwsim(void)
                param.p2p_device = support_p2p_device;
                param.mlo = mlo;
                param.multi_radio = multi_radio;
+               param.background_radar = true;
                param.use_chanctx = channels > 1 || mlo || multi_radio;
                param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
                if (param.p2p_device)
index c2d06cf852a56d0b3c5abb7ed25f5e1d00d23604..a022cd5c0f1c7386f22d33a9b06350e420a5f278 100644 (file)
@@ -161,6 +161,7 @@ enum hwsim_commands {
  *     Adds one radio for each band. Number of supported channels will be set for
  *     each radio instead of for the wiphy.
  * @HWSIM_ATTR_SUPPORT_NAN_DEVICE: support NAN Device virtual interface (flag)
+ * @HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR: background radar/CAC support (flag)
  * @__HWSIM_ATTR_MAX: enum limit
  */
 enum hwsim_attrs {
@@ -195,6 +196,7 @@ enum hwsim_attrs {
        HWSIM_ATTR_PMSR_RESULT,
        HWSIM_ATTR_MULTI_RADIO,
        HWSIM_ATTR_SUPPORT_NAN_DEVICE,
+       HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR,
        __HWSIM_ATTR_MAX,
 };
 #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)