From: Hari Chandrakanthan Add a new API ieee80211_incumbent_signal_detected() that can be used by wireless drivers to notify the higher layers about the interference of incumbent signals in 6 GHz band with the operating channel (mandatory to pass during MLO) and the interference bitmap in which each bit denotes the affected 20 MHz in the operating channel. Signed-off-by: Hari Chandrakanthan Co-developed-by: Aditya Kumar Singh Signed-off-by: Aditya Kumar Singh Signed-off-by: Amith A --- include/net/mac80211.h | 18 ++++++++++++++++++ net/mac80211/ieee80211_i.h | 5 +++++ net/mac80211/main.c | 3 +++ net/mac80211/trace.h | 26 +++++++++++++++++++++++++ net/mac80211/util.c | 39 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index a45e4bee65d4..678e58609280 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -257,6 +257,8 @@ struct ieee80211_chan_req { * after RTS/CTS handshake to receive SMPS MIMO transmissions; * this will always be >= @rx_chains_static. * @radar_enabled: whether radar detection is enabled on this channel. + * @incumbt_sig_intf_bmap: Bitmap indicating the sub-channels where an + * incumbent signal's interference was detected. * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *), size is determined in hw information. */ @@ -270,6 +272,8 @@ struct ieee80211_chanctx_conf { bool radar_enabled; + u32 incumbt_sig_intf_bmap; + u8 drv_priv[] __aligned(sizeof(void *)); }; @@ -7834,4 +7838,18 @@ int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw, int n_vifs, enum ieee80211_chanctx_switch_mode mode); +/** + * ieee80211_incumbent_signal_detected - inform that an incumbent signal + * interference was detected + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @chanctx_conf: Channel context on which the signal interference was detected. + * Mandatory to pass a valid pointer for MLO. For non-MLO %NULL can be + * passed + * @incumbt_sig_intf_bmap: Bitmap indicating where the incumbent signal was + * detected. + */ +void ieee80211_incumbent_signal_detected(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *chanctx_conf, + u32 incumbt_sig_intf_bmap); + #endif /* MAC80211_H */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8afa2404eaa8..d25930f6f122 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1675,6 +1675,8 @@ struct ieee80211_local { u8 ext_capa[8]; bool wbrf_supported; + + struct wiphy_work incumbent_signal_detected_work; }; static inline struct ieee80211_sub_if_data * @@ -2884,4 +2886,7 @@ ieee80211_determine_chan_mode(struct ieee80211_sub_if_data *sdata, #define VISIBLE_IF_MAC80211_KUNIT static #endif +void ieee80211_incumbent_signal_detected_work(struct wiphy *wiphy, + struct wiphy_work *work); + #endif /* IEEE80211_I_H */ diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 9c8f18b258a6..1495d2a16517 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -994,6 +994,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, wiphy_work_init(&local->radar_detected_work, ieee80211_dfs_radar_detected_work); + wiphy_work_init(&local->incumbent_signal_detected_work, + ieee80211_incumbent_signal_detected_work); wiphy_work_init(&local->reconfig_filter, ieee80211_reconfig_filter); @@ -1670,6 +1672,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) wiphy_work_cancel(local->hw.wiphy, &local->reconfig_filter); wiphy_work_cancel(local->hw.wiphy, &local->sched_scan_stopped_work); wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work); + wiphy_work_cancel(local->hw.wiphy, &local->incumbent_signal_detected_work); wiphy_unlock(local->hw.wiphy); rtnl_unlock(); diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 0bfbce157486..ce97faab1765 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -3136,6 +3136,32 @@ TRACE_EVENT(api_radar_detected, ) ); +TRACE_EVENT(api_incumbent_signal_detected, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_chanctx_conf *chanctx_conf), + + TP_ARGS(local, chanctx_conf), + + TP_STRUCT__entry( + LOCAL_ENTRY + CHANDEF_ENTRY + __field(u32, bitmap) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + CHANDEF_ASSIGN(&chanctx_conf->def) + __entry->bitmap = + chanctx_conf ? chanctx_conf->incumbt_sig_intf_bmap : 0; + ), + + TP_printk( + LOCAL_PR_FMT " Incumbent signal detected." + CHANDEF_PR_FMT " Bitmap: 0x%x ", + LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->bitmap + ) +); + TRACE_EVENT(api_request_smps, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 32f1bc5908c5..82e3ef4165aa 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3533,6 +3533,32 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local, } } +void ieee80211_incumbent_signal_detected_work(struct wiphy *wiphy, + struct wiphy_work *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, + incumbent_signal_detected_work); + struct ieee80211_chanctx_conf *conf; + struct ieee80211_chanctx *ctx; + + lockdep_assert_wiphy(local->hw.wiphy); + + list_for_each_entry(ctx, &local->chanctx_list, list) { + if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) + continue; + + if (!ctx->conf.incumbt_sig_intf_bmap) + continue; + + conf = &ctx->conf; + cfg80211_incumbent_signal_detect_event(local->hw.wiphy, + &conf->def, + conf->incumbt_sig_intf_bmap, + GFP_KERNEL); + } +} + void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy, struct wiphy_work *work) { @@ -3591,6 +3617,19 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ieee80211_radar_detected); +void ieee80211_incumbent_signal_detected(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *chanctx_conf, + u32 incumbt_sig_intf_bmap) +{ + struct ieee80211_local *local = hw_to_local(hw); + + chanctx_conf->incumbt_sig_intf_bmap = incumbt_sig_intf_bmap; + + trace_api_incumbent_signal_detected(local, chanctx_conf); + wiphy_work_queue(hw->wiphy, &local->incumbent_signal_detected_work); +} +EXPORT_SYMBOL(ieee80211_incumbent_signal_detected); + void ieee80211_chandef_downgrade(struct cfg80211_chan_def *c, struct ieee80211_conn_settings *conn) { -- 2.34.1