From: Hari Chandrakanthan When any incumbent signal is detected by an AP/mesh interface operating in 6 GHz band, FCC mandates the AP/mesh to vacate the channels affected by it [1]. Add a new API cfg80211_incumbent_signal_detect_event() that can be used by mac80211 (or full mac drivers) to notify the higher layers about the signal interference event with the interference bitmap in which each bit denotes the affected 20 MHz in the operating channel. Add support for the new nl80211 event and nl80211 attribute as well to notify userspace on the details about the interference event. Userspace is expected to process it and take further action - vacate the channel, or reduce the bandwidth. [1] - https://apps.fcc.gov/kdb/GetAttachment.html?id=nXQiRC%2B4mfiA54Zha%2BrW4Q%3D%3D&desc=987594%20D02%20U-NII%206%20GHz%20EMC%20Measurement%20v03&tracking_number=277034 Signed-off-by: Hari Chandrakanthan Signed-off-by: Amith A --- include/net/cfg80211.h | 17 +++++++++++++++++ include/uapi/linux/nl80211.h | 16 ++++++++++++++++ net/wireless/mlme.c | 12 ++++++++++++ net/wireless/nl80211.c | 35 +++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 4 ++++ 5 files changed, 84 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 406626ff6cc8..8d51ff648c46 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -8984,6 +8984,23 @@ cfg80211_background_radar_event(struct wiphy *wiphy, __cfg80211_radar_event(wiphy, chandef, true, gfp); } +/** + * cfg80211_incumbent_signal_detect_event - Incumbent signal detection event + * @wiphy: the wiphy + * @chandef: chandef for the current channel + * @signal_interference_bitmap: Incumbent signal interference bitmap. + * See %NL80211_ATTR_INCUMBENT_SIGNAL_INTERFERENCE_BITMAP description for + * the usage. + * @gfp: context flags + * + * This function is called when any incumbent signal is detected on the + * current channel in the 6 GHz band. + */ +void cfg80211_incumbent_signal_detect_event(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef, + u32 signal_interference_bitmap, + gfp_t gfp); + /** * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event * @dev: network device diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index d1a14f2892d9..ec1220579e3d 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1344,6 +1344,12 @@ * control EPCS configuration. Used to notify userland on the current state * of EPCS. * + * @NL80211_CMD_INCUMBENT_SIGNAL_DETECT: Once any incumbent signal is detected + * on the operating channel in 6 GHz band, userspace is notified with the + * signal interference bitmap using + * %NL80211_ATTR_INCUMBENT_SIGNAL_INTERFERENCE_BITMAP. The current channel + * definition is also sent. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -1604,6 +1610,8 @@ enum nl80211_commands { NL80211_CMD_ASSOC_MLO_RECONF, NL80211_CMD_EPCS_CFG, + NL80211_CMD_INCUMBENT_SIGNAL_DETECT, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -2928,6 +2936,12 @@ enum nl80211_commands { * required alongside this attribute. Refer to * @enum nl80211_s1g_short_beacon_attrs for the attribute definitions. * + * @NL80211_ATTR_INCUMBENT_SIGNAL_INTERFERENCE_BITMAP: u32 attribute specifying + * the signal interference bitmap detected on the operating bandwidth for + * %NL80211_CMD_INCUMBENT_SIGNAL_DETECT. Each bit represents a 20 MHz + * segment, lowest bit corresponds to the lowest 20 MHz segment, in the + * operating bandwidth where the interference is detected. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3490,6 +3504,8 @@ enum nl80211_attrs { NL80211_ATTR_S1G_LONG_BEACON_PERIOD, NL80211_ATTR_S1G_SHORT_BEACON, + NL80211_ATTR_INCUMBENT_SIGNAL_INTERFERENCE_BITMAP, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 46394eb2086f..619d51a37b81 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -1127,6 +1127,18 @@ void __cfg80211_radar_event(struct wiphy *wiphy, } EXPORT_SYMBOL(__cfg80211_radar_event); +void cfg80211_incumbent_signal_detect_event(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef, + u32 signal_interference_bitmap, + gfp_t gfp) +{ + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + + nl80211_incumbent_signal_notify(rdev, chandef, + signal_interference_bitmap, gfp); +} +EXPORT_SYMBOL(cfg80211_incumbent_signal_detect_event); + void cfg80211_cac_event(struct net_device *netdev, const struct cfg80211_chan_def *chandef, enum nl80211_radar_event event, gfp_t gfp, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 89519aa52893..f26749c4499e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -20422,6 +20422,41 @@ void cfg80211_ch_switch_notify(struct net_device *dev, } EXPORT_SYMBOL(cfg80211_ch_switch_notify); +void nl80211_incumbent_signal_notify(struct cfg80211_registered_device *rdev, + struct cfg80211_chan_def *chandef, + u32 signal_interference_bitmap, gfp_t gfp) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_INCUMBENT_SIGNAL_DETECT); + if (!hdr) + goto nla_put_failure; + + if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) + goto nla_put_failure; + + if (nl80211_send_chandef(msg, chandef)) + goto nla_put_failure; + + if (nla_put_u32(msg, NL80211_ATTR_INCUMBENT_SIGNAL_INTERFERENCE_BITMAP, + signal_interference_bitmap)) + goto nla_put_failure; + + genlmsg_end(msg, hdr); + + genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, + NL80211_MCGRP_MLME, gfp); + return; + +nla_put_failure: + nlmsg_free(msg); +} + void cfg80211_ch_switch_started_notify(struct net_device *dev, struct cfg80211_chan_def *chandef, unsigned int link_id, u8 count, diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 5e25782af1e0..4a40eda33989 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -117,6 +117,10 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev, enum nl80211_radar_event event, struct net_device *netdev, gfp_t gfp); +void nl80211_incumbent_signal_notify(struct cfg80211_registered_device *rdev, + struct cfg80211_chan_def *chandef, + u32 signal_interference_bitmap, gfp_t gfp); + void nl80211_send_ap_stopped(struct wireless_dev *wdev, unsigned int link_id); void cfg80211_free_coalesce(struct cfg80211_coalesce *coalesce); -- 2.34.1