diff --git a/target_if/regulatory/src/target_if_reg.c b/target_if/regulatory/src/target_if_reg.c index 6920ed465b..9ea65cc613 100644 --- a/target_if/regulatory/src/target_if_reg.c +++ b/target_if/regulatory/src/target_if_reg.c @@ -1456,5 +1456,7 @@ QDF_STATUS target_if_register_regulatory_tx_ops( reg_ops->is_80p80_supported = NULL; + reg_ops->is_freq_80p80_supported = NULL; + return QDF_STATUS_SUCCESS; } diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index fa05ee38ed..a7b7f29bf9 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -1135,6 +1135,8 @@ struct wlan_lmac_if_ftm_rx_ops { * response from fw. * @is_80p80_supported: Callback function to check if the device supports a * 6GHz 80p80 channel. + * @is_freq_80p80_supported: Callback function to check if the given primary + * frequency supports 80P80 mode of operation. */ struct wlan_lmac_if_reg_tx_ops { QDF_STATUS (*register_master_handler)(struct wlan_objmgr_psoc *psoc, @@ -1207,6 +1209,8 @@ struct wlan_lmac_if_reg_tx_ops { struct wlan_objmgr_psoc *psoc, uint32_t pdev_id); bool (*is_80p80_supported)(struct wlan_objmgr_pdev *pdev); + bool (*is_freq_80p80_supported)(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); }; /** diff --git a/umac/regulatory/core/src/reg_opclass.c b/umac/regulatory/core/src/reg_opclass.c index 497cac4694..18818b19fb 100644 --- a/umac/regulatory/core/src/reg_opclass.c +++ b/umac/regulatory/core/src/reg_opclass.c @@ -1772,6 +1772,18 @@ static bool reg_is_cfi_supported(struct wlan_objmgr_pdev *pdev, return is_cfi_supported; } +/** + * reg_is_opclass_entry_80p80() - Return true if the opclass entry is + * 80P80 false otherwise. + * @op_class_tbl: Pointer to struct reg_dmn_op_class_map_t + */ +static bool +reg_is_opclass_entry_80p80(const struct reg_dmn_op_class_map_t *op_class_tbl) +{ + return (op_class_tbl->chan_spacing == BW_80_MHZ && + op_class_tbl->behav_limit == BIT(BEHAV_BW80_PLUS)); +} + /** * reg_get_cfis_from_opclassmap_for_6g()- Get channels from the opclass map * for 6GHz @@ -1805,11 +1817,15 @@ static void reg_get_cfis_from_opclassmap_for_6g( bool is_cfi_supported; cfi_freq = start_freq + FREQ_TO_CHAN_SCALE * cfi; - is_cfi_supported = reg_is_cfi_supported(pdev, - cfi_freq, - bw, - op_class_tbl->op_class, - in_6g_pwr_mode); + /* 6 Ghz band does not support 80P80 mode of operation.*/ + if (reg_is_opclass_entry_80p80(op_class_tbl)) + is_cfi_supported = false; + else + is_cfi_supported = reg_is_cfi_supported(pdev, + cfi_freq, + bw, + op_class_tbl->op_class, + in_6g_pwr_mode); if (is_cfi_supported && (in_opclass_conf == OPCLASSES_SUPPORTED_BY_CUR_HWMODE || in_opclass_conf == OPCLASSES_SUPPORTED_BY_DOMAIN)) { @@ -1828,6 +1844,37 @@ static uint16_t reg_find_nearest_ieee_bw(uint16_t spacing) return (spacing / SMALLEST_BW) * SMALLEST_BW; } +/** + * reg_is_freq_80p80_supported() - Return true if the given input frequency + * supports 80P80, false otherwise. + * @pdev: Pointer to struct wlan_objmgr_pdev + * @primary_freq: Primary frequency in MHz + * + * Return: True if the frequency supports 80P80 mode of operation, false + * otherwise. + */ +static bool +reg_is_freq_80p80_supported(struct wlan_objmgr_pdev *pdev, + qdf_freq_t primary_freq) +{ + struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) + return false; + + reg_tx_ops = reg_get_psoc_tx_ops(psoc); + if (!reg_tx_ops) + return false; + + if (reg_tx_ops->is_freq_80p80_supported && + reg_tx_ops->is_freq_80p80_supported(pdev, primary_freq)) + return true; + + return false; +} + /** * reg_get_cfis_from_opclassmap_for_non6g()- Get channels from the opclass map * for non-6GHz @@ -1868,12 +1915,15 @@ static void reg_get_cfis_from_opclassmap_for_non6g( pri_freq = reg_get_nearest_primary_freq(opcls_bw, pri_freq, op_class_tbl->op_class); - is_supported = reg_is_chan_supported(pdev, - pri_freq, - 0, - ch_width, - in_6g_pwr_mode); + if (reg_is_opclass_entry_80p80(op_class_tbl)) + is_supported = reg_is_freq_80p80_supported(pdev, pri_freq); + else + is_supported = reg_is_chan_supported(pdev, + pri_freq, + 0, + ch_width, + in_6g_pwr_mode); if (is_supported && (in_opclass_conf == OPCLASSES_SUPPORTED_BY_CUR_HWMODE || in_opclass_conf == OPCLASSES_SUPPORTED_BY_DOMAIN)) {