diff --git a/umac/regulatory/core/src/reg_opclass.c b/umac/regulatory/core/src/reg_opclass.c index c603dcbc5c6a..203a59f63d82 100644 --- a/umac/regulatory/core/src/reg_opclass.c +++ b/umac/regulatory/core/src/reg_opclass.c @@ -504,4 +504,48 @@ uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev, return 0; } +uint16_t reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup) +{ + const struct reg_dmn_op_class_map_t *op_class_tbl = NULL; + uint8_t i = 0; + + if (global_tbl_lookup) { + op_class_tbl = global_op_class; + } else { + if (channel_map == channel_map_global) { + op_class_tbl = global_op_class; + } else if (channel_map == channel_map_us) { + op_class_tbl = us_op_class; + } else if (channel_map == channel_map_eu) { + op_class_tbl = euro_op_class; + } else if (channel_map == channel_map_china) { + op_class_tbl = us_op_class; + } else if (channel_map == channel_map_jp) { + op_class_tbl = japan_op_class; + } else { + reg_err_rl("Invalid channel map"); + return 0; + } + } + + while (op_class_tbl->op_class) { + if (op_class_tbl->op_class == op_class) { + for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + op_class_tbl->channels[i]); i++) { + if (op_class_tbl->channels[i] == chan) { + chan = op_class_tbl->channels[i]; + return (op_class_tbl->start_freq + + (chan * FREQ_TO_CHAN_SCALE)); + } + } + reg_err_rl("Channel not found"); + return 0; + } + op_class_tbl++; + } + reg_err_rl("Invalid opclass given as input"); + return 0; +} #endif diff --git a/umac/regulatory/core/src/reg_opclass.h b/umac/regulatory/core/src/reg_opclass.h index fa3845248843..d72cd4cfa3ae 100644 --- a/umac/regulatory/core/src/reg_opclass.h +++ b/umac/regulatory/core/src/reg_opclass.h @@ -129,6 +129,17 @@ uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev, uint8_t op_class, bool global_tbl_lookup); +/** + * reg_chan_opclass_to_freq() - Convert channel number and opclass to frequency + * @chan: IEEE Channel Number. + * @op_class: Opclass. + * @global_tbl_lookup: Global table lookup. + * + * Return: Channel center frequency else return 0. + */ +uint16_t reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup); #else static inline uint16_t reg_dmn_get_chanwidth_from_opclass( @@ -192,5 +203,13 @@ uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev, return 0; } +static inline uint16_t +reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup) +{ + return 0; +} + #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 c8afba6891ee..e0130e2a36b4 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -1174,4 +1174,15 @@ bool wlan_reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev, */ bool wlan_reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev); +/** + * reg_chan_opclass_to_freq() - Convert channel number and opclass to frequency + * @chan: IEEE Channel Number. + * @op_class: Opclass. + * @global_tbl_lookup: Global table lookup. + * + * Return: Channel center frequency else return 0. + */ +uint16_t wlan_reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup); #endif diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 23f4b7009a29..3c1a1baa2fef 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -1023,3 +1023,13 @@ bool wlan_reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev) { return reg_is_6ghz_supported(pdev); } + +uint16_t wlan_reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup) +{ + if (!chan || !op_class) + return 0; + + return reg_chan_opclass_to_freq(chan, op_class, global_tbl_lookup); +}