From 4e0c4422cfe94dc9fdf94ffe1f276f3cdcba67f5 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Tue, 6 Dec 2022 21:52:11 +0800 Subject: [PATCH] qcacmn: Enable static puncture Driver receive NL80211_CMD_START_AP to get fixed freq, width and apply puncture_bitmap from EHT ie, disable punctured 20 MHz sub channels in regulatory component, and send to F/W by vdev start, update eht op/he op/vht op in beacon template. When start ap, apply puncture to regulatory, set is_static_punctured flag for all 20 MHz sub channels of current bonded channel in master channel list of pdev, and disable 20 MHz sub channel in current channel list if is_static_punctured is set. When stop ap, remove puncture to regulatory, clear is_static_punctured flag for all 20 MHz sub channels in master channel list of pdev, and don't disable 20 MHz sub channel in current channel list if is_static_punctured is not set. change-Id: Ia97e7a4fa56a66f343bd648b62216347787ba6d0 CRs-Fixed: 3356755 --- .../regulatory/core/src/reg_build_chan_list.c | 27 +++++++ .../regulatory/core/src/reg_services_common.c | 80 +++++++++++++++++++ .../regulatory/core/src/reg_services_common.h | 36 +++++++++ .../inc/reg_services_public_struct.h | 4 + .../dispatcher/inc/wlan_reg_services_api.h | 68 ++++++++++++++++ .../dispatcher/src/wlan_reg_services_api.c | 17 ++++ 6 files changed, 232 insertions(+) diff --git a/umac/regulatory/core/src/reg_build_chan_list.c b/umac/regulatory/core/src/reg_build_chan_list.c index de6c5715bb..4729b8307b 100644 --- a/umac/regulatory/core/src/reg_build_chan_list.c +++ b/umac/regulatory/core/src/reg_build_chan_list.c @@ -857,6 +857,32 @@ static void reg_modify_chan_list_for_nol_list( } } +#ifdef CONFIG_REG_CLIENT +/** + * reg_modify_chan_list_for_static_puncture() - Disable the channel if + * static_puncture is set. + * @chan_list: Pointer to regulatory channel list. + */ +static void +reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list) +{ + enum channel_enum chan_enum; + + for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { + if (chan_list[chan_enum].is_static_punctured) { + chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; + chan_list[chan_enum].chan_flags |= + REGULATORY_CHAN_DISABLED; + } + } +} +#else +static void +reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list) +{ +} +#endif + /** * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums. * @chan_list: Pointer to regulatory channel list. @@ -2924,6 +2950,7 @@ void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj pdev_priv_obj->dfs_enabled); reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list); + reg_modify_chan_list_for_static_puncture(pdev_priv_obj->cur_chan_list); reg_modify_chan_list_for_indoor_channels(pdev_priv_obj); diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c index eb7687c3d3..34106be070 100644 --- a/umac/regulatory/core/src/reg_services_common.c +++ b/umac/regulatory/core/src/reg_services_common.c @@ -4833,6 +4833,86 @@ static void reg_update_5g_bonded_channel_state_punc_for_pwrmode( } } #endif + +#ifdef CONFIG_REG_CLIENT +QDF_STATUS reg_apply_puncture(struct wlan_objmgr_pdev *pdev, + uint16_t puncture_bitmap, + qdf_freq_t freq, + enum phy_ch_width bw, + qdf_freq_t cen320_freq) +{ + const struct bonded_channel_freq *bonded_chan; + qdf_freq_t chan_cfreq; + enum channel_enum chan_enum; + struct regulatory_channel *mas_chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + bool is_puncture; + uint16_t i = 0; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err_rl("pdev reg obj is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mas_chan_list = pdev_priv_obj->mas_chan_list; + if (!mas_chan_list) { + reg_err_rl("mas chan_list is NULL"); + return QDF_STATUS_E_FAILURE; + } + bonded_chan = reg_get_bonded_chan_entry(freq, bw, cen320_freq); + if (!bonded_chan) { + reg_err_rl("bonded chan fails, freq %d, bw %d, cen320_freq %d", + freq, bw, cen320_freq); + return QDF_STATUS_E_FAILURE; + } + + chan_cfreq = bonded_chan->start_freq; + while (chan_cfreq <= bonded_chan->end_freq) { + is_puncture = BIT(i) & puncture_bitmap; + if (is_puncture) { + chan_enum = reg_get_chan_enum_for_freq(chan_cfreq); + mas_chan_list[chan_enum].is_static_punctured = true; + } + i++; + chan_cfreq = chan_cfreq + BW_20_MHZ; + } + + reg_compute_pdev_current_chan_list(pdev_priv_obj); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS reg_remove_puncture(struct wlan_objmgr_pdev *pdev) +{ + enum channel_enum chan_enum; + struct regulatory_channel *mas_chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err_rl("pdev reg obj is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mas_chan_list = pdev_priv_obj->mas_chan_list; + if (!mas_chan_list) { + reg_err_rl("mas chan_list is NULL"); + return QDF_STATUS_E_FAILURE; + } + + for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) + if (mas_chan_list[chan_enum].is_static_punctured) + mas_chan_list[chan_enum].is_static_punctured = false; + + reg_compute_pdev_current_chan_list(pdev_priv_obj); + + return QDF_STATUS_SUCCESS; +} +#endif + #else static void reg_update_5g_bonded_channel_state_punc_for_freq( struct wlan_objmgr_pdev *pdev, diff --git a/umac/regulatory/core/src/reg_services_common.h b/umac/regulatory/core/src/reg_services_common.h index c12cfe1a02..c3f7f8acf7 100644 --- a/umac/regulatory/core/src/reg_services_common.h +++ b/umac/regulatory/core/src/reg_services_common.h @@ -1233,6 +1233,42 @@ QDF_STATUS reg_extract_puncture_by_bw(enum phy_ch_width ori_bw, */ void reg_set_create_punc_bitmap(struct ch_params *ch_params, bool is_create_punc_bitmap); + +#ifdef CONFIG_REG_CLIENT +/** + * reg_apply_puncture() - apply puncture to regulatory + * @pdev: pdev + * @puncture_bitmap: puncture bitmap + * @freq: sap operation freq + * @bw: band width + * @cen320_freq: 320 MHz center freq + * + * When start ap, apply puncture to regulatory, set static puncture flag + * for all 20 MHz sub channels of current bonded channel in master channel list + * of pdev, and disable 20 MHz sub channel in current channel list if static + * puncture flag is set. + * + * Return: QDF_STATUS + */ +QDF_STATUS reg_apply_puncture(struct wlan_objmgr_pdev *pdev, + uint16_t puncture_bitmap, + qdf_freq_t freq, + enum phy_ch_width bw, + qdf_freq_t cen320_freq); + +/** + * wlan_reg_remove_puncture() - Remove puncture from regulatory + * @pdev: pdev + * + * When stop ap, remove puncture from regulatory, clear static puncture flag + * for all 20 MHz sub channels in master channel list of pdev, and don't disable + * 20 MHz sub channel in current channel list if static puncture flag is not + * set. + * + * Return: QDF_STATUS + */ +QDF_STATUS reg_remove_puncture(struct wlan_objmgr_pdev *pdev); +#endif #else static inline QDF_STATUS reg_extract_puncture_by_bw(enum phy_ch_width ori_bw, diff --git a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h index 06f15d02f4..a7247e67bf 100644 --- a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h +++ b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h @@ -971,6 +971,7 @@ struct get_usable_chan_req_params { * intolerance. * @psd_flag: is PSD channel or not * @psd_eirp: PSD power level + * @is_static_punctured: is static punctured */ struct regulatory_channel { qdf_freq_t center_freq; @@ -991,6 +992,9 @@ struct regulatory_channel { bool psd_flag; uint16_t psd_eirp; #endif +#ifdef CONFIG_REG_CLIENT + uint8_t is_static_punctured; +#endif }; /** struct ap_cli_pwr_mode_info: AP and client power mode information diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index c9a961afc3..562828d2c8 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -1643,6 +1643,58 @@ QDF_STATUS wlan_reg_extract_puncture_by_bw(enum phy_ch_width ori_bw, */ void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params, bool is_create_punc_bitmap); + +#ifdef CONFIG_REG_CLIENT +/** + * wlan_reg_apply_puncture() - apply puncture to regulatory + * @pdev: pdev + * @puncture_bitmap: puncture bitmap + * @freq: sap operation freq + * @bw: band width + * @cen320_freq: 320 MHz center freq + * + * When start ap, apply puncture to regulatory, set static puncture flag + * for all 20 MHz sub channels of current bonded channel in master channel list + * of pdev, and disable 20 MHz sub channel in current channel list if static + * puncture flag is set. + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_reg_apply_puncture(struct wlan_objmgr_pdev *pdev, + uint16_t puncture_bitmap, + qdf_freq_t freq, + enum phy_ch_width bw, + qdf_freq_t cen320_freq); + +/** + * wlan_reg_remove_puncture() - Remove puncture from regulatory + * @pdev: pdev + * + * When stop ap, remove puncture from regulatory, clear static puncture flag + * for all 20 MHz sub channels in master channel list of pdev, and don't disable + * 20 MHz sub channel in current channel list if static puncture flag is not + * set. + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_reg_remove_puncture(struct wlan_objmgr_pdev *pdev); +#else +static inline +QDF_STATUS wlan_reg_apply_puncture(struct wlan_objmgr_pdev *pdev, + uint16_t puncture_bitmap, + qdf_freq_t freq, + enum phy_ch_width bw, + qdf_freq_t cen320_freq) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS wlan_reg_remove_puncture(struct wlan_objmgr_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} +#endif #ifdef CONFIG_REG_6G_PWRMODE /** * wlan_reg_fill_channel_list_for_pwrmode() - Fills the reg_channel_list @@ -1685,6 +1737,22 @@ static inline void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params, { } +static inline +QDF_STATUS wlan_reg_apply_puncture(struct wlan_objmgr_pdev *pdev, + uint16_t puncture_bitmap, + qdf_freq_t freq, + enum phy_ch_width bw, + qdf_freq_t cen320_freq) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS wlan_reg_remove_puncture(struct wlan_objmgr_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + static inline uint16_t wlan_reg_find_nearest_puncture_pattern(enum phy_ch_width bw, uint16_t proposed_bitmap) diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 59f1551476..2c2a88ba6e 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -1384,6 +1384,23 @@ void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params, { reg_set_create_punc_bitmap(ch_params, is_create_punc_bitmap); } + +#ifdef CONFIG_REG_CLIENT +QDF_STATUS wlan_reg_apply_puncture(struct wlan_objmgr_pdev *pdev, + uint16_t puncture_bitmap, + qdf_freq_t freq, + enum phy_ch_width bw, + qdf_freq_t cen320_freq) +{ + return reg_apply_puncture(pdev, puncture_bitmap, freq, bw, + cen320_freq); +} + +QDF_STATUS wlan_reg_remove_puncture(struct wlan_objmgr_pdev *pdev) +{ + return reg_remove_puncture(pdev); +} +#endif #endif /* WLAN_FEATURE_11BE */ #ifdef CONFIG_REG_6G_PWRMODE