diff --git a/umac/regulatory/core/src/reg_build_chan_list.c b/umac/regulatory/core/src/reg_build_chan_list.c index 519ac3f71a..68bc2d4c59 100644 --- a/umac/regulatory/core/src/reg_build_chan_list.c +++ b/umac/regulatory/core/src/reg_build_chan_list.c @@ -42,6 +42,38 @@ #define MAX_PWR_FCC_CHAN_13 2 #define CHAN_144_CENT_FREQ 5720 +/** + * reg_init_chan() - Initialize the channel list from the channel_map global + * list + * @dst_list: list to initialize + * @beg_enum: starting point in list(inclusive) + * @end_enum: ending point in list(inclusive) + * @dst_idx_adj: offset between channel_map and dst_list + * @soc_reg: soc private object for regulatory + * + * Return: none + */ +static void reg_init_chan(struct regulatory_channel *dst_list, + enum channel_enum beg_enum, + enum channel_enum end_enum, uint8_t dst_idx_adj, + struct wlan_regulatory_psoc_priv_obj *soc_reg) +{ + enum channel_enum chan_enum; + uint8_t dst_idx; + + for (chan_enum = beg_enum; chan_enum <= end_enum; chan_enum++) { + dst_idx = chan_enum - dst_idx_adj; + + dst_list[dst_idx].chan_num = channel_map[chan_enum].chan_num; + dst_list[dst_idx].center_freq = + channel_map[chan_enum].center_freq; + dst_list[dst_idx].chan_flags = REGULATORY_CHAN_DISABLED; + dst_list[dst_idx].state = CHANNEL_STATE_DISABLE; + if (!soc_reg->retain_nol_across_regdmn_update) + dst_list[dst_idx].nol_chan = false; + } +} + static inline bool reg_nol_and_history_not_set(struct regulatory_channel *chan) { @@ -63,12 +95,33 @@ static void reg_fill_psd_info(enum channel_enum chan_enum, master_list[chan_enum].psd_eirp = reg_rule->psd_eirp; } + +/** + * reg_init_6ghz_master_chan() - Init 6 GHz channel list + * @dst_list: pointer to 6 GHz channel list + * @soc_reg: pointer to regulatory psoc private object. + * + * Return: None + */ +static void +reg_init_6ghz_master_chan(struct regulatory_channel *dst_list, + struct wlan_regulatory_psoc_priv_obj *soc_reg) +{ + reg_init_chan(dst_list, MIN_6GHZ_CHANNEL, MAX_6GHZ_CHANNEL, + MIN_6GHZ_CHANNEL, soc_reg); +} #else static inline void reg_fill_psd_info(enum channel_enum chan_enum, struct cur_reg_rule *reg_rule, struct regulatory_channel *master_list) { } + +static inline void +reg_init_6ghz_master_chan(struct regulatory_channel *dst_list, + struct wlan_regulatory_psoc_priv_obj *soc_reg) +{ +} #endif /** @@ -1527,12 +1580,120 @@ reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj } } +/** + * reg_dump_valid_6ghz_channel_list() - Function to print valid 6 GHz channel + * list state and attribute. + * @chan: Pointer to array of 6 GHz channel list + * + * Return: None + */ +static void +reg_dump_valid_6ghz_channel_list(struct regulatory_channel *chan) +{ +#define MAX_CHAN_LOG_ONE_LINE 18 + uint32_t buf_size = MAX_CHAN_LOG_ONE_LINE * 24 + 1; + uint8_t *buf; + uint32_t i, len = 0, count = 0; + + buf = qdf_mem_malloc(buf_size); + if (!buf) + return; + + for (i = MIN_6GHZ_CHANNEL; i <= MAX_6GHZ_CHANNEL; i++, chan++) { + if (chan->state == CHANNEL_STATE_DISABLE) + continue; + len += qdf_scnprintf(buf + len, buf_size - len, + "%d:%d:%d:%d:%d:%x ", + chan->center_freq, chan->state, + chan->psd_flag, chan->tx_power, + (int16_t)chan->psd_eirp, + chan->chan_flags); + count++; + if (count >= MAX_CHAN_LOG_ONE_LINE) { + reg_nofl_debug("%s", buf); + count = 0; + len = 0; + } + } + + if (len) + reg_nofl_debug("%s", buf); + + qdf_mem_free(buf); +} + +/** + * reg_dump_valid_6ghz_cur_chan_list() - API to dump pdev current/secondary + * channel list state + * @pdev_priv_obj: pointer to pdev private object + * + * Return: None + */ +static void +reg_dump_valid_6ghz_cur_chan_list(struct wlan_regulatory_pdev_priv_obj + *pdev_priv_obj) +{ + reg_debug("sta freq:state:ispsd:pwr:psd:flags(hex):"); + reg_dump_valid_6ghz_channel_list( + &pdev_priv_obj->cur_chan_list[MIN_6GHZ_CHANNEL]); + reg_debug("sap freq:state:ispsd:pwr:psd:flags(hex):"); + reg_dump_valid_6ghz_channel_list( + &pdev_priv_obj->secondary_cur_chan_list[MIN_6GHZ_CHANNEL]); +} + +#ifdef CONFIG_AFC_SUPPORT +/** + * reg_populate_afc_secondary_cur_chan_list() - Function to populate AFC + * channel list to secondary current channel list + * @pdev_priv_obj: Pointer to pdev regulatory private object + * @chan_list: Pointer to array of 6 GHz channel list + * + * Return: None + */ +static void reg_populate_afc_secondary_cur_chan_list( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, + struct regulatory_channel *chan_list) +{ + uint32_t i; + struct regulatory_channel *afc_chan_list; + struct regulatory_channel *sp_chan_list; + + if (!pdev_priv_obj->is_6g_afc_power_event_received) + return; + + afc_chan_list = pdev_priv_obj->afc_chan_list; + sp_chan_list = pdev_priv_obj-> + mas_chan_list_6g_ap[REG_STANDARD_POWER_AP]; + for (i = 0; i < NUM_6GHZ_CHANNELS; i++) { + if (afc_chan_list[i].state == CHANNEL_STATE_DISABLE && + sp_chan_list[i].state == CHANNEL_STATE_ENABLE) { + chan_list[i].state = CHANNEL_STATE_DISABLE; + chan_list[i].chan_flags |= REGULATORY_CHAN_DISABLED; + } else if (afc_chan_list[i].state == CHANNEL_STATE_ENABLE) { + qdf_mem_copy(&chan_list[i], + &afc_chan_list[i], + sizeof(chan_list[i])); + chan_list[i].chan_flags |= REGULATORY_CHAN_AFC; + } + } +} +#else +static inline void reg_populate_afc_secondary_cur_chan_list( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, + struct regulatory_channel *chan_list) +{ +} +#endif + static void reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) { struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; + struct wlan_regulatory_psoc_priv_obj *soc_reg; + struct regulatory_channel *chan_list; + uint32_t len_6ghz; psoc = wlan_pdev_get_psoc(pdev_priv_obj->pdev_ptr); if (!psoc) { @@ -1540,29 +1701,59 @@ reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj return; } + soc_reg = reg_get_psoc_obj(psoc); + if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) { + reg_err("psoc reg component is NULL"); + return; + } + reg_tx_ops = reg_get_psoc_tx_ops(psoc); if (!reg_tx_ops) { reg_err("reg_tx_ops null"); return; } - if (reg_tx_ops->register_master_ext_handler && - wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_EXT_EVENT_SUPPORTED)) { - qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list, - pdev_priv_obj->cur_chan_list, - (NUM_CHANNELS - NUM_6GHZ_CHANNELS) * - sizeof(struct regulatory_channel)); - qdf_mem_copy(&pdev_priv_obj-> - secondary_cur_chan_list[MIN_6GHZ_CHANNEL], - pdev_priv_obj->mas_chan_list_6g_ap - [pdev_priv_obj->reg_cur_6g_ap_pwr_type], - NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); - } else { + if (!reg_tx_ops->register_master_ext_handler || + !wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_EXT_EVENT_SUPPORTED)) { qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list, pdev_priv_obj->cur_chan_list, (NUM_CHANNELS) * sizeof(struct regulatory_channel)); + return; } + + len_6ghz = NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel); + chan_list = qdf_mem_malloc(len_6ghz); + if (!chan_list) + return; + + if (pdev_priv_obj->indoor_chan_enabled && + pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP]) { + qdf_mem_copy(chan_list, + pdev_priv_obj->mas_chan_list_6g_ap[REG_INDOOR_AP], + len_6ghz); + /* has flag REGULATORY_CHAN_INDOOR_ONLY */ + } else if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules + [REG_VERY_LOW_POWER_AP]) { + qdf_mem_copy(chan_list, + pdev_priv_obj->mas_chan_list_6g_ap + [REG_VERY_LOW_POWER_AP], + len_6ghz); + } else { + reg_init_6ghz_master_chan(chan_list, soc_reg); + } + + reg_populate_afc_secondary_cur_chan_list(pdev_priv_obj, chan_list); + + qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list, + pdev_priv_obj->cur_chan_list, + (NUM_CHANNELS - NUM_6GHZ_CHANNELS) * + sizeof(struct regulatory_channel)); + qdf_mem_copy(&pdev_priv_obj->secondary_cur_chan_list[MIN_6GHZ_CHANNEL], + chan_list, + len_6ghz); + qdf_mem_free(chan_list); + reg_dump_valid_6ghz_cur_chan_list(pdev_priv_obj); } #else /* CONFIG_REG_CLIENT */ @@ -3267,38 +3458,6 @@ reg_soc_vars_reset_on_failure(enum cc_setting_code status_code, return QDF_STATUS_SUCCESS; } -/** - * reg_init_chan() - Initialize the channel list from the channel_map global - * list - * @dst_list: list to initialize - * @beg_enum: starting point in list(inclusive) - * @end_enum: ending point in list(inclusive) - * @dst_idx_adj: offset between channel_map and dst_list - * @soc_reg: soc private object for regulatory - * - * Return: none - */ -static void reg_init_chan(struct regulatory_channel *dst_list, - enum channel_enum beg_enum, - enum channel_enum end_enum, uint8_t dst_idx_adj, - struct wlan_regulatory_psoc_priv_obj *soc_reg) -{ - enum channel_enum chan_enum; - uint8_t dst_idx; - - for (chan_enum = beg_enum; chan_enum <= end_enum; chan_enum++) { - dst_idx = chan_enum - dst_idx_adj; - - dst_list[dst_idx].chan_num = channel_map[chan_enum].chan_num; - dst_list[dst_idx].center_freq = - channel_map[chan_enum].center_freq; - dst_list[dst_idx].chan_flags = REGULATORY_CHAN_DISABLED; - dst_list[dst_idx].state = CHANNEL_STATE_DISABLE; - if (!soc_reg->retain_nol_across_regdmn_update) - dst_list[dst_idx].nol_chan = false; - } -} - static void reg_init_legacy_master_chan(struct regulatory_channel *dst_list, struct wlan_regulatory_psoc_priv_obj *soc_reg) { @@ -3346,13 +3505,6 @@ static void reg_init_2g_5g_master_chan(struct regulatory_channel *dst_list, reg_init_chan(dst_list, 0, MAX_5GHZ_CHANNEL, 0, soc_reg); } -static void reg_init_6g_master_chan(struct regulatory_channel *dst_list, - struct wlan_regulatory_psoc_priv_obj *soc_reg) -{ - reg_init_chan(dst_list, MIN_6GHZ_CHANNEL, MAX_6GHZ_CHANNEL, - MIN_6GHZ_CHANNEL, soc_reg); -} - /** * reg_store_regulatory_ext_info_to_socpriv() - Copy ext info from regulatory * to regulatory PSOC private obj @@ -3875,10 +4027,10 @@ QDF_STATUS reg_process_master_chan_list_ext( reg_init_2g_5g_master_chan(mas_chan_list_2g_5g, soc_reg); for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { - reg_init_6g_master_chan(mas_chan_list_6g_ap[i], soc_reg); + reg_init_6ghz_master_chan(mas_chan_list_6g_ap[i], soc_reg); for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) - reg_init_6g_master_chan(mas_chan_list_6g_client[i][j], - soc_reg); + reg_init_6ghz_master_chan(mas_chan_list_6g_client[i][j], + soc_reg); } reg_store_regulatory_ext_info_to_socpriv(soc_reg, regulat_info, phy_id); @@ -4038,6 +4190,37 @@ reg_disable_sp_channels_in_super_chan_list( } } +#if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_REG_CLIENT) +/** + * reg_client_afc_populate_channels() - Function to populate channels and + * invoke callbacks to notify the channel list change. + * @psoc: Pointer to PSOC object + * @pdev: Pointer to PDEV object + * + * Return: None + */ +static void +reg_client_afc_populate_channels(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + 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_alert("pdev reg component is NULL"); + return; + } + reg_compute_pdev_current_chan_list(pdev_priv_obj); + reg_send_scheduler_msg_nb(psoc, pdev); +} +#else +static inline void +reg_client_afc_populate_channels(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ +} +#endif + /** * reg_process_afc_expiry_event() - Process the afc expiry event and get the * afc request id @@ -4108,6 +4291,7 @@ reg_process_afc_expiry_event(struct afc_regulatory_info *afc_info) pdev_priv_obj->is_6g_afc_power_event_received = false; reg_disable_afc_mas_chan_list_channels(pdev_priv_obj); reg_disable_sp_channels_in_super_chan_list(pdev_priv_obj); + reg_client_afc_populate_channels(psoc, pdev); if (tx_ops->trigger_acs_for_afc) tx_ops->trigger_acs_for_afc(pdev); break; @@ -4564,7 +4748,7 @@ reg_process_afc_power_event(struct afc_regulatory_info *afc_info) afc_mas_chan_list = this_mchan_params->mas_chan_list_6g_afc; qdf_mem_zero(afc_mas_chan_list, NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel)); - reg_init_6g_master_chan(afc_mas_chan_list, soc_reg); + reg_init_6ghz_master_chan(afc_mas_chan_list, soc_reg); soc_reg->mas_chan_params[phy_id].is_6g_afc_power_event_received = true; pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); @@ -4582,7 +4766,7 @@ reg_process_afc_power_event(struct afc_regulatory_info *afc_info) } reg_init_pdev_super_chan_list(pdev_priv_obj); - reg_init_6g_master_chan(pdev_priv_obj->afc_chan_list, soc_reg); + reg_init_6ghz_master_chan(pdev_priv_obj->afc_chan_list, soc_reg); /* Free the old power_info event if it was allocated */ if (pdev_priv_obj->power_info) reg_free_afc_pwr_info(pdev_priv_obj); @@ -4607,6 +4791,7 @@ reg_process_afc_power_event(struct afc_regulatory_info *afc_info) reg_modify_6g_afc_chan_list(pdev_priv_obj); reg_compute_super_chan_list(pdev_priv_obj); + reg_client_afc_populate_channels(psoc, pdev); if (tx_ops->trigger_acs_for_afc && !wlan_reg_is_noaction_on_afc_pwr_evt(pdev) && diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c index 4bc07864c0..da8f0a854f 100644 --- a/umac/regulatory/core/src/reg_services_common.c +++ b/umac/regulatory/core/src/reg_services_common.c @@ -4347,6 +4347,167 @@ static uint32_t reg_get_channel_flags_from_secondary_list_for_freq( return pdev_priv_obj->secondary_cur_chan_list[chan_enum].chan_flags; } + +#ifdef CONFIG_BAND_6GHZ +/** + * reg_get_psd_power() - Function to get PSD power for 6 GHz channel + * @chan: Pointer to channel object + * @is_psd: Pointer to whether it is PSD power + * + * Return: Channel PSD power value if it is PSD type. + */ +static uint16_t reg_get_psd_power(struct regulatory_channel *chan, bool *is_psd) +{ + if (is_psd) + *is_psd = chan->psd_flag; + return chan->psd_eirp; +} +#else +static uint16_t reg_get_psd_power(struct regulatory_channel *chan, bool *is_psd) +{ + if (is_psd) + *is_psd = false; + return 0; +} +#endif + +QDF_STATUS +reg_get_channel_power_attr_from_secondary_list_for_freq( + struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, bool *is_psd, + uint16_t *tx_power, uint16_t *psd_eirp, uint32_t *flags) +{ + enum channel_enum chan_enum; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct regulatory_channel *chan; + + if (!is_psd && !tx_power && !psd_eirp && !flags) { + reg_err("all pointers null"); + return QDF_STATUS_E_FAILURE; + } + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!pdev_priv_obj) { + reg_err("pdev priv obj is NULL"); + return QDF_STATUS_E_FAILURE; + } + + chan_enum = reg_get_chan_enum_for_freq(freq); + if (chan_enum == INVALID_CHANNEL) { + reg_err_rl("chan freq %u is not valid", freq); + return QDF_STATUS_E_FAILURE; + } + + chan = &pdev_priv_obj->secondary_cur_chan_list[chan_enum]; + + if (chan->state == CHANNEL_STATE_DISABLE || + chan->state == CHANNEL_STATE_INVALID) { + reg_err_rl("invalid channel state %d", chan->state); + return QDF_STATUS_E_FAILURE; + } + + if (tx_power) + *tx_power = chan->tx_power; + if (psd_eirp) + *psd_eirp = reg_get_psd_power(chan, is_psd); + if (flags) + *flags = chan->chan_flags; + + return QDF_STATUS_SUCCESS; +} + +#ifdef CONFIG_BAND_6GHZ +QDF_STATUS +reg_decide_6ghz_power_within_bw_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, enum phy_ch_width bw, + bool *is_psd, uint16_t *min_tx_power, + int16_t *min_psd_eirp, + enum reg_6g_ap_type *power_type) +{ + const struct bonded_channel_freq *bonded_chan_ptr = NULL; + enum channel_state state; + qdf_freq_t start_freq; + uint16_t tx_power, psd_eirp; + uint32_t chan_flags, min_chan_flags = 0; + bool first_time = true; + + if (!reg_is_6ghz_chan_freq(freq)) + return QDF_STATUS_E_INVAL; + + if (!is_psd) { + reg_err("is_psd pointer null"); + return QDF_STATUS_E_INVAL; + } + if (!min_tx_power) { + reg_err("min_tx_power pointer null"); + return QDF_STATUS_E_INVAL; + } + if (!min_psd_eirp) { + reg_err("min_psd_eirp pointer null"); + return QDF_STATUS_E_INVAL; + } + if (!power_type) { + reg_err("power_type pointer null"); + return QDF_STATUS_E_INVAL; + } + + state = reg_get_5g_bonded_channel_for_freq(pdev, + freq, + bw, + &bonded_chan_ptr); + if (state != CHANNEL_STATE_ENABLE && + state != CHANNEL_STATE_DFS) { + reg_err("invalid channel state %d", state); + return QDF_STATUS_E_INVAL; + } + + if (bw <= CH_WIDTH_20MHZ) { + if (reg_get_channel_power_attr_from_secondary_list_for_freq( + pdev, freq, is_psd, &tx_power, + &psd_eirp, &chan_flags) != QDF_STATUS_SUCCESS) + return QDF_STATUS_E_INVAL; + *min_psd_eirp = (int16_t)psd_eirp; + *min_tx_power = tx_power; + min_chan_flags = chan_flags; + goto decide_power_type; + } + + start_freq = bonded_chan_ptr->start_freq; + while (start_freq <= bonded_chan_ptr->end_freq) { + if (reg_get_channel_power_attr_from_secondary_list_for_freq( + pdev, start_freq, is_psd, &tx_power, + &psd_eirp, &chan_flags) != QDF_STATUS_SUCCESS) + return QDF_STATUS_E_INVAL; + + if (first_time) { + *min_psd_eirp = (int16_t)psd_eirp; + *min_tx_power = tx_power; + min_chan_flags = chan_flags; + first_time = false; + } + if ((int16_t)psd_eirp < *min_psd_eirp) + *min_psd_eirp = (int16_t)psd_eirp; + if (tx_power < *min_tx_power) + *min_tx_power = tx_power; + min_chan_flags |= (chan_flags & REGULATORY_CHAN_AFC); + min_chan_flags |= (chan_flags & REGULATORY_CHAN_INDOOR_ONLY); + start_freq += 20; + } + +decide_power_type: + if ((min_chan_flags & REGULATORY_CHAN_AFC) && + (min_chan_flags & REGULATORY_CHAN_INDOOR_ONLY)) + *power_type = REG_INDOOR_AP; + else if (min_chan_flags & REGULATORY_CHAN_AFC) + *power_type = REG_STANDARD_POWER_AP; + else if (min_chan_flags & REGULATORY_CHAN_INDOOR_ONLY) + *power_type = REG_INDOOR_AP; + else + *power_type = REG_VERY_LOW_POWER_AP; + + return QDF_STATUS_SUCCESS; +} +#endif #endif /** diff --git a/umac/regulatory/core/src/reg_services_common.h b/umac/regulatory/core/src/reg_services_common.h index bdfb77c80d..bb3c53fde2 100644 --- a/umac/regulatory/core/src/reg_services_common.h +++ b/umac/regulatory/core/src/reg_services_common.h @@ -1293,6 +1293,57 @@ bool reg_is_dfs_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); */ bool reg_is_dfs_in_secondary_list_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); + +/** + * reg_get_channel_power_attr_from_secondary_list_for_freq() - get channel + * power attributions from secondary channel list. + * @pdev: pdev pointer + * @freq: channel frequency + * @is_psd: pointer to retrieve value whether channel power is psd + * @tx_power: pointer to retrieve value of channel eirp tx power + * @psd_eirp: pointer to retrieve value of channel psd eirp power + * @flags: pointer to retrieve value of channel flags + * + * Return: QDF STATUS + */ +QDF_STATUS +reg_get_channel_power_attr_from_secondary_list_for_freq( + struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, bool *is_psd, + uint16_t *tx_power, uint16_t *psd_eirp, + uint32_t *flags); + +#ifdef CONFIG_BAND_6GHZ +/** + * reg_decide_6ghz_power_within_bw_for_freq() - decide tx power and 6 GHz power + * type given channel frequency and bandwidth. + * @pdev: pdev pointer + * @freq: channel frequency + * @bw: channel bandwidth + * @is_psd: pointer to retrieve value whether channel power is psd + * @min_tx_power: pointer to retrieve value of minimum eirp tx power in bw + * @min_psd_eirp: pointer to retrieve value of minimum psd eirp power in bw + * @power_type: pointer to retrieve value of 6 GHz power type + * + * Return: QDF STATUS + */ +QDF_STATUS +reg_decide_6ghz_power_within_bw_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, enum phy_ch_width bw, + bool *is_psd, uint16_t *min_tx_power, + int16_t *min_psd_eirp, + enum reg_6g_ap_type *power_type); +#else +static inline QDF_STATUS +reg_decide_6ghz_power_within_bw_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, enum phy_ch_width bw, + bool *is_psd, uint16_t *min_tx_power, + int16_t *min_psd_eirp, + enum reg_6g_ap_type *power_type) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif #endif /** diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index 365f26bd7b..8c1be1c544 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -1832,6 +1832,46 @@ bool wlan_reg_is_enable_in_secondary_list_for_freq( */ bool wlan_reg_is_dfs_in_secondary_list_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); + +/** + * wlan_reg_get_chan_pwr_attr_from_secondary_list_for_freq() - get channel + * power attributions from secondary channel list + * @pdev: pdev ptr + * @freq: channel center frequency + * @is_psd: pointer to retrieve value whether channel power is psd + * @tx_power: pointer to retrieve value of channel eirp tx power + * @psd_eirp: pointer to retrieve value of channel psd eirp power + * @flags: pointer to retrieve value of channel flags + * + * Return: QDF STATUS + */ +QDF_STATUS +wlan_reg_get_chan_pwr_attr_from_secondary_list_for_freq( + struct wlan_objmgr_pdev *pdev, qdf_freq_t freq, + bool *is_psd, uint16_t *tx_power, + uint16_t *psd_eirp, uint32_t *flags); + +/** + * wlan_reg_decide_6ghz_power_within_bw_for_freq() - decide minimum tx power in + * bandwidth and 6 GHz power type + * @pdev: pdev ptr + * @freq: channel center frequency + * @bw: channel bandwidth + * @is_psd: pointer to retrieve value whether channel power is psd + * @min_tx_power: pointer to retrieve minimum tx power in bandwidth + * @min_psd_eirp: pointer to retrieve minimum psd eirp in bandwidth + * @power_type: pointer to retrieve 6 GHz power type + * + * Return: QDF STATUS + */ +QDF_STATUS +wlan_reg_decide_6ghz_power_within_bw_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + enum phy_ch_width bw, + bool *is_psd, + uint16_t *min_tx_power, + int16_t *min_psd_eirp, + enum reg_6g_ap_type *power_type); #endif /** diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index cf54f7f34e..28d2aa2e35 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -1151,6 +1151,34 @@ bool wlan_reg_is_dfs_in_secondary_list_for_freq(struct wlan_objmgr_pdev *pdev, { return reg_is_dfs_in_secondary_list_for_freq(pdev, freq); } + +QDF_STATUS +wlan_reg_get_chan_pwr_attr_from_secondary_list_for_freq( + struct wlan_objmgr_pdev *pdev, qdf_freq_t freq, + bool *is_psd, uint16_t *tx_power, + uint16_t *psd_eirp, uint32_t *flags) +{ + return reg_get_channel_power_attr_from_secondary_list_for_freq( + pdev, freq, is_psd, tx_power, psd_eirp, flags); +} + +QDF_STATUS +wlan_reg_decide_6ghz_power_within_bw_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + enum phy_ch_width bw, + bool *is_psd, + uint16_t *min_tx_power, + int16_t *min_psd_eirp, + enum reg_6g_ap_type *power_type) +{ + return reg_decide_6ghz_power_within_bw_for_freq(pdev, + freq, + bw, + is_psd, + min_tx_power, + min_psd_eirp, + power_type); +} #endif bool wlan_reg_is_passive_for_freq(struct wlan_objmgr_pdev *pdev,