qcacmn: Add a Regulatory API to compute channel list after HW Mode Switch
Add regulatory API and a dispatcher function to compute current channel
list after dynamic HW Mode Switch. range_5g_low, range_5g_high and wireless
modes are extracted from wlan_psoc_host_mac_phy_caps based on the new
HW mode configured and are used to derive the current channel list.
Change-Id: I799712da8992ede0b5896dd2eb438cffea5fe048
CRs-Fixed: 2481535
diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c
index c10a431..8cf19a0 100644
--- a/umac/regulatory/core/src/reg_services_common.c
+++ b/umac/regulatory/core/src/reg_services_common.c
@@ -2023,3 +2023,87 @@
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 d2ed228..52df9be 100644
--- a/umac/regulatory/core/src/reg_services_common.h
+++ b/umac/regulatory/core/src/reg_services_common.h
@@ -514,4 +514,13 @@
* 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 f7da9e3..b3a7d32 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 @@
* 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 67e5d74..5b91725 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 @@
{
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);
+}