add offchannel radar chain support
Subsystems (2)
v2 cover add offchannel radar chain support
Introduce the capability to configure a dedicated chain available for radar detection on some hw (e.g. mt7915). This chain can't be used to transmit or receive frames and it is bounded to a running wdev.
Offchannel radar/CAC detection allows to avoid the CAC downtime switching to a different channel during CAC detection on the selected radar channel. hostapd will implement the logic to select and configure the monitored channel.
Changes since v1:
- introduce offchanel chain ownership through offchan_radar_wdev pointer
- spilt patch 1/5 in cfg80211 and mac80211 part
- move cac work from driver code to cfg80211
Changes since rfc:
- rely on NL80211_CMD_RADAR_DETECT netlink msg to configure offchannel radar chain
Lorenzo Bianconi (6):
cfg80211: introduce set_radar_offchan callback
mac80211: introduce set_radar_offchan callback
cfg80211: introduce the capability to configure offchannel CAC
detection
cfg80211: introduce cfg80211_cac_offchan_event routine
cfg80211: introduce offchannel cac delayed work
cfg80211: introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag
include/net/cfg80211.h | 24 +++++++ include/net/mac80211.h | 10 +++ include/uapi/linux/nl80211.h | 13 ++++ net/mac80211/cfg.c | 13 ++++ net/wireless/ap.c | 2 + net/wireless/core.c | 2 + net/wireless/core.h | 15 +++++ net/wireless/mlme.c | 117 +++++++++++++++++++++++++++++++++++ net/wireless/nl80211.c | 17 +++-- net/wireless/rdev-ops.h | 18 ++++++ net/wireless/trace.h | 19 ++++++ 11 files changed, 244 insertions(+), 6 deletions(-)
Signature · 1 line
2.31.1
PATCH v2 1/6 cfg80211: introduce set_radar_offchan callback
Introduce set_radar_offchan callback in cfg80211_ops in order to configure a dedicated offchannel chain available for radar/CAC detection on some hw. This chain can't be used to transmit or receive frames and it is bounded to a running wdev. Offchannel radar/CAC detection allows to avoid the CAC downtime switching on a different channel during CAC detection on the selected radar channel.
--- include/net/cfg80211.h | 11 +++++++++++ net/wireless/rdev-ops.h | 18 ++++++++++++++++++ net/wireless/trace.h | 19 +++++++++++++++++++ 3 files changed, 48 insertions(+)
include/net/cfg80211.h +11 -0
@@ -4072,6 +4072,15 @@ struct mgmt_frame_regs {* @set_fils_aad: Set FILS AAD data to the AP driver so that the driver can use * those to decrypt (Re)Association Request and encrypt (Re)Association * Response frame. +* +* @set_radar_offchan: Configure dedicated offchannel chain available for +* radar/CAC detection on some hw. This chain can't be used to transmit +* or receive frames and it is bounded to a running wdev. +* Offchannel radar/CAC detection allows to avoid the CAC downtime +* switching to a different channel during CAC detection on the selected +* radar channel. +* The caller is expected to set chandef pointer to NULL in order to +* disable offchannel CAC/radar detection. */ struct cfg80211_ops {int (*suspend)(struct wiphy *wiphy,struct cfg80211_wowlan *wow);
@@ -4404,6 +4413,8 @@ struct cfg80211_ops { struct cfg80211_color_change_settings *params);int (*set_fils_aad)(struct wiphy *wiphy,struct net_device *dev,struct cfg80211_fils_aad *fils_aad); +int (*set_radar_offchan)(struct wiphy *wiphy, +struct cfg80211_chan_def *chandef); };/*
net/wireless/rdev-ops.h +18 -0
@@ -1395,4 +1395,22 @@ rdev_set_fils_aad(struct cfg80211_registered_device *rdev, return ret; } +static inline int +rdev_set_radar_offchan (struct cfg80211_registered_device *rdev, +struct cfg80211_chan_def *chandef) +{ +struct wiphy *wiphy = &rdev->wiphy; +int ret; + +if (!rdev->ops->set_radar_offchan) +return -EOPNOTSUPP ; + +if (chandef) +trace_rdev_set_radar_offchan (wiphy, chandef); + ret = rdev->ops->set_radar_offchan (wiphy, chandef); +trace_rdev_return_int (wiphy, ret); + +return ret; +} +#endif /* __CFG80211_RDEV_OPS */
net/wireless/trace.h +19 -0
@@ -3674,6 +3674,25 @@ TRACE_EVENT(cfg80211_bss_color_notify, __entry->color_bitmap) ); +TRACE_EVENT (rdev_set_radar_offchan, + TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), + +TP_ARGS (wiphy, chandef), + +TP_STRUCT__entry ( + WIPHY_ENTRY +CHAN_DEF_ENTRY + ), + +TP_fast_assign ( + WIPHY_ASSIGN; +CHAN_DEF_ASSIGN (chandef) + ), + +TP_printk (WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT , +WIPHY_PR_ARG ,CHAN_DEF_PR_ARG ) +); +#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH
Signature · 1 line
2.31.1
PATCH v2 2/6 mac80211: introduce set_radar_offchan callback
In reply to Lorenzo BianconiSimilar to cfg80211, introduce set_radar_offchan callback in mac80211_ops in order to configure a dedicated offchannel chain available on some hw (e.g. mt7915) to perform offchannel CAC detection and avoid tx/rx downtime.
--- include/net/mac80211.h | 10 ++++++++++ net/mac80211/cfg.c | 13 +++++++++++++ 2 files changed, 23 insertions(+)
include/net/mac80211.h +10 -0
@@ -3944,6 +3944,14 @@ struct ieee80211_prep_tx_info {* twt structure. * @twt_teardown_request: Update the hw with TWT teardown request received * from the peer. +* @set_radar_offchan: Configure dedicated offchannel chain available for +* radar/CAC detection on some hw. This chain can't be used to transmit +* or receive frames and it is bounded to a running wdev. +* Offchannel radar/CAC detection allows to avoid the CAC downtime +* switching to a different channel during CAC detection on the selected +* radar channel. +* The caller is expected to set chandef pointer to NULL in order to +* disable offchannel CAC/radar detection. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw,
@@ -4272,6 +4280,8 @@ struct ieee80211_ops { struct ieee80211_twt_setup *twt);void (*twt_teardown_request)(struct ieee80211_hw *hw,struct ieee80211_sta *sta,u8 flowid); +int (*set_radar_offchan)(struct ieee80211_hw *hw, +struct cfg80211_chan_def *chandef); };/**
net/mac80211/cfg.c +13 -0
@@ -4379,6 +4379,18 @@ ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,return err; } +static int +ieee80211_set_radar_offchan (struct wiphy *wiphy, +struct cfg80211_chan_def *chandef) +{ +struct ieee80211_local *local =wiphy_priv (wiphy); + +if (!local->ops->set_radar_offchan) +return -EOPNOTSUPP ; + +return local->ops->set_radar_offchan (&local->hw, chandef); +} +const struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface,
@@ -4483,4 +4495,5 @@ const struct cfg80211_ops mac80211_config_ops = { .reset_tid_config = ieee80211_reset_tid_config, .set_sar_specs = ieee80211_set_sar_specs, .color_change = ieee80211_color_change, + .set_radar_offchan = ieee80211_set_radar_offchan, };
Signature · 1 line
2.31.1
PATCH v2 3/6 cfg80211: introduce the capability to configure offchannel CAC detection
In reply to Lorenzo BianconiIntroduce NL80211_ATTR_RADAR_OFFCHAN netlink attribute in order to configure a offchannel radar chain if supported by the underlay driver. Since the offchannel chain is commonly shared between multiple wireless devices, offchan_radar_wdev pointer refers to the current owner of the chain. Offchannel can't be used by multiple wdev at the same time.
--- include/uapi/linux/nl80211.h | 9 ++++++++ net/wireless/ap.c | 2 ++ net/wireless/core.c | 1 + net/wireless/core.h | 11 ++++++++++ net/wireless/mlme.c | 40 ++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.c | 17 +++++++++------ 6 files changed, 74 insertions(+), 6 deletions(-)
include/uapi/linux/nl80211.h +9 -0
@@ -2639,6 +2639,13 @@ enum nl80211_commands {* Mandatory parameter for the transmitting interface to enable MBSSID. * Optional for the non-transmitting interfaces. * +* @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated offchannel chain available for +* radar/CAC detection on some hw. This chain can't be used to transmit +* or receive frames and it is bounded to a running wdev. +* Offchannel radar/CAC detection allows to avoid the CAC downtime +* switching on a different channel during CAC detection on the selected +* radar channel. +* * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3145,6 +3152,8 @@ enum nl80211_attrs {NL80211_ATTR_MBSSID_CONFIG ,NL80211_ATTR_MBSSID_ELEMS , +NL80211_ATTR_RADAR_OFFCHAN , +/* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST,
net/wireless/ap.c +2 -0
@@ -25,6 +25,8 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,if (!wdev->beacon_interval)return -ENOENT ; +cfg80211_stop_offchan_radar_detection (rdev); + err =rdev_stop_ap (rdev, dev);if (!err) { wdev->conn_owner_nlportid =0 ;
net/wireless/core.c +1 -0
@@ -498,6 +498,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, }mutex_init (&rdev->wiphy.mtx); +mutex_init (&rdev->offchan_mutex);INIT_LIST_HEAD (&rdev->wiphy.wdev_list);INIT_LIST_HEAD (&rdev->beacon_registrations);spin_lock_init (&rdev->beacon_registrations_lock);
net/wireless/core.h +11 -0
@@ -84,6 +84,9 @@ struct cfg80211_registered_device {struct delayed_work dfs_update_channels_wk; +struct mutex offchan_mutex;/* protect offchan_radar_wdev */ +struct wireless_dev *offchan_radar_wdev; +/* netlink port which started critical protocol (0 means not started) */ u32 crit_proto_nlportid;
@@ -489,6 +492,14 @@ cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,void cfg80211_sched_dfs_chan_update (struct cfg80211_registered_device *rdev); +int +cfg80211_start_offchan_radar_detection (struct cfg80211_registered_device *rdev, +struct wireless_dev *wdev, +struct cfg80211_chan_def *chandef); + +int +cfg80211_stop_offchan_radar_detection (struct cfg80211_registered_device *rdev); +bool cfg80211_any_wiphy_oper_chan (struct wiphy *wiphy,struct ieee80211_channel *chan);
net/wireless/mlme.c +40 -0
@@ -968,3 +968,43 @@ void cfg80211_cac_event(struct net_device *netdev,nl80211_radar_notify (rdev, chandef, event, netdev, gfp); }EXPORT_SYMBOL (cfg80211_cac_event); + +int +cfg80211_start_offchan_radar_detection (struct cfg80211_registered_device *rdev, +struct wireless_dev *wdev, +struct cfg80211_chan_def *chandef) +{ +int err = -EBUSY ; + +mutex_lock (&rdev->offchan_mutex); +if (rdev->offchan_radar_wdev) + goto out; + + err =rdev_set_radar_offchan (rdev, chandef); +if (err) + goto out; + + rdev->offchan_radar_wdev = wdev; +out: +mutex_unlock (&rdev->offchan_mutex); +return err; +} + +int +cfg80211_stop_offchan_radar_detection (struct cfg80211_registered_device *rdev) +{ +int err =0 ; + +mutex_lock (&rdev->offchan_mutex); +if (!rdev->offchan_radar_wdev) + goto out; + + err =rdev_set_radar_offchan (rdev,NULL ); +if (err) + goto out; + + rdev->offchan_radar_wdev =NULL ; +out: +mutex_unlock (&rdev->offchan_mutex); +return err; +}
net/wireless/nl80211.c +11 -6
@@ -776,6 +776,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_MBSSID_CONFIG ] = NLA_POLICY_NESTED(nl80211_mbssid_config_policy), [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, + [NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG }, };/* policy for the key attributes */
@@ -9280,12 +9281,6 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,if (err)return err; -if (netif_carrier_ok (dev)) -return -EBUSY ; - -if (wdev->cac_started) -return -EBUSY ; - err =cfg80211_chandef_dfs_required (wiphy, &chandef, wdev->iftype);if (err <0 )return err;
@@ -9296,6 +9291,16 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,if (!cfg80211_chandef_dfs_usable (wiphy, &chandef))return -EINVAL ; +if (nla_get_flag (info->attrs[NL80211_ATTR_RADAR_OFFCHAN ])) +return cfg80211_start_offchan_radar_detection (rdev, wdev, + &chandef); + +if (netif_carrier_ok (dev)) +return -EBUSY ; + +if (wdev->cac_started) +return -EBUSY ; +/* CAC start is offloaded to HW and can't be started manually */ if (wiphy_ext_feature_isset (wiphy,NL80211_EXT_FEATURE_DFS_OFFLOAD ))return -EOPNOTSUPP ;
Signature · 1 line
2.31.1
PATCH v2 4/6 cfg80211: introduce cfg80211_cac_offchan_event routine
In reply to Lorenzo BianconiIntroduce cfg80211_cac_offchan_event routine in order to notify userland when a Channel Availability Check (CAC) is finished, started or aborted by a offchannel dedicated chain.
--- include/net/cfg80211.h | 13 ++++++++++ net/wireless/mlme.c | 57 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-)
include/net/cfg80211.h +13 -0
@@ -7646,6 +7646,19 @@ void cfg80211_cac_event(struct net_device *netdev,const struct cfg80211_chan_def *chandef, enum nl80211_radar_event event, gfp_t gfp); +/** +* cfg80211_offchan_cac_event - Channel Availability Check (CAC) offchan event +* @wiphy: the wiphy +* @chandef: chandef for the current channel +* @event: type of event +* @gfp: context flags +* +* This function is called when a Channel Availability Check (CAC) is finished, +* started or aborted by a offchannel dedicated chain. +*/ +void cfg80211_offchan_cac_event (struct wiphy *wiphy, +const struct cfg80211_chan_def *chandef, +enum nl80211_radar_event event,gfp_t gfp);/** * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying
net/wireless/mlme.c +55 -2
75 lines not on this page · raw message
Signature · 1 line
2.31.1
PATCH v2 5/6 cfg80211: introduce offchannel cac delayed work
In reply to Lorenzo BianconiIntroduce cac delayed work in order to report NL80211_RADAR_CAC_FINISHED to userspace.
--- net/wireless/core.c | 1 + net/wireless/core.h | 4 ++++ net/wireless/mlme.c | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+)
net/wireless/core.c +1 -0
@@ -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);
net/wireless/core.h +4 -0
@@ -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);
net/wireless/mlme.c +20 -0
@@ -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;
Signature · 1 line
2.31.1
PATCH v2 6/6 cfg80211: introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag
In reply to Lorenzo BianconiIntroduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag in order to notify userland the underlay hw supports offchannel radar/CAC detection.
--- include/uapi/linux/nl80211.h | 4 ++++ net/wireless/mlme.c | 4 ++++ 2 files changed, 8 insertions(+)
include/uapi/linux/nl80211.h +4 -0
@@ -6060,6 +6060,9 @@ enum nl80211_feature_flags {* frames. Userspace has to share FILS AAD details to the driver by using * @NL80211_CMD_SET_FILS_AAD. * +* @NL80211_EXT_FEATURE_RADAR_OFFCHAN: Device supports offchannel radar/CAC +* detection. +* * @NUM_NL80211_EXT_FEATURES: number of extended features. * @MAX_NL80211_EXT_FEATURES: highest extended feature index. */
@@ -6126,6 +6129,7 @@ enum nl80211_ext_feature_index {NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE ,NL80211_EXT_FEATURE_BSS_COLOR ,NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD , +NL80211_EXT_FEATURE_RADAR_OFFCHAN ,/* add new features before the definition below */ NUM_NL80211_EXT_FEATURES,
net/wireless/mlme.c +4 -0
@@ -1040,6 +1040,10 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,unsigned int cac_time_ms;int err = -EBUSY ; +if (!wiphy_ext_feature_isset (&rdev->wiphy, +NL80211_EXT_FEATURE_RADAR_OFFCHAN )) +return -EOPNOTSUPP ; +mutex_lock (&rdev->offchan_mutex);if (rdev->offchan_radar_wdev) goto out;
Signature · 1 line
2.31.1