diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c index c10a431f28ae..8cf19a04226f 100644 --- a/umac/regulatory/core/src/reg_services_common.c +++ b/umac/regulatory/core/src/reg_services_common.c @@ -2023,3 +2023,87 @@ bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev) return reg_en302_502_regdmn(cur_reg_dmn.regdmn_pair_id); } + +QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; + struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap_ptr; + uint32_t cnt; + uint32_t pdev_id; + enum direction dir; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + reg_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc_priv_obj = reg_get_psoc_obj(psoc); + if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { + reg_err("psoc reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + + reg_cap_ptr = psoc_priv_obj->reg_cap; + + for (cnt = 0; cnt < PSOC_MAX_PHY_REG_CAP; cnt++) { + if (!reg_cap_ptr) { + qdf_mem_free(pdev_priv_obj); + reg_err("reg cap ptr is NULL"); + return QDF_STATUS_E_FAULT; + } + + if (reg_cap_ptr->phy_id == pdev_id) + break; + reg_cap_ptr++; + } + + if (cnt == PSOC_MAX_PHY_REG_CAP) { + qdf_mem_free(pdev_priv_obj); + reg_err("extended capabilities not found for pdev"); + return QDF_STATUS_E_FAULT; + } + + if (psoc_priv_obj->offload_enabled) { + dir = NORTHBOUND; + } else { + dir = SOUTHBOUND; + } + + pdev_priv_obj->range_2g_low = reg_cap_ptr->low_2ghz_chan; + pdev_priv_obj->range_2g_high = reg_cap_ptr->high_2ghz_chan; + pdev_priv_obj->range_5g_low = reg_cap_ptr->low_5ghz_chan; + pdev_priv_obj->range_5g_high = reg_cap_ptr->high_5ghz_chan; + pdev_priv_obj->wireless_modes = reg_cap_ptr->wireless_modes; + + reg_compute_pdev_current_chan_list(pdev_priv_obj); + + reg_tx_ops = reg_get_psoc_tx_ops(psoc); + + /* Fill the ic channel list with the updated current channel + * chan list. + */ + if (reg_tx_ops->fill_umac_legacy_chanlist) { + reg_tx_ops->fill_umac_legacy_chanlist(pdev, + pdev_priv_obj->cur_chan_list); + + } else { + if (dir == NORTHBOUND) + status = reg_send_scheduler_msg_nb(psoc, pdev); + else + status = reg_send_scheduler_msg_sb(psoc, pdev); + } + + return status; +} diff --git a/umac/regulatory/core/src/reg_services_common.h b/umac/regulatory/core/src/reg_services_common.h index d2ed228f755e..52df9be9558e 100644 --- a/umac/regulatory/core/src/reg_services_common.h +++ b/umac/regulatory/core/src/reg_services_common.h @@ -514,4 +514,13 @@ QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev, bool enable); * Return: True if en302_502 is applicable, else false. */ bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev); + +/** + * reg_modify_pdev_chan_range() - Compute current channel list + * in accordance with the modified reg caps. + * @pdev: The physical dev for which channel list must be built. + * + * Return: QDF_STATUS + */ +QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev); #endif diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index f7da9e3d51d8..b3a7d3290867 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -703,4 +703,13 @@ void wlan_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, * False: otherwise. */ bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_reg_modify_pdev_chan_range() - Compute current channel list for the + * modified channel range in the regcap. + * @pdev: pointer to wlan_objmgr_pdev. + * + * Return : QDF_STATUS + */ +QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev); #endif diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 67e5d745e955..5b9172521267 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -713,3 +713,14 @@ bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev) { return reg_is_regdmn_en302502_applicable(pdev); } + +/** + * wlan_reg_modify_pdev_chan_range() - Compute current channel list for the + * modified regcap. + * @pdev: pointer to struct wlan_objmgr_pdev + * + */ +QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev) +{ + return reg_modify_pdev_chan_range(pdev); +}