diff --git a/target_if/core/inc/target_if.h b/target_if/core/inc/target_if.h index deec5bcf7fbd..35a2ad4091f5 100644 --- a/target_if/core/inc/target_if.h +++ b/target_if/core/inc/target_if.h @@ -54,6 +54,11 @@ typedef struct wlan_objmgr_psoc *(*get_psoc_handle_callback)( void *scn_handle); +typedef int (*wmi_legacy_service_ready_callback)(uint32_t event_id, + void *handle, + uint8_t *event_data, + uint32_t length); + /** * struct target_if_ctx - target_interface context * @magic: magic for target if ctx @@ -63,6 +68,7 @@ typedef struct wlan_objmgr_psoc *(*get_psoc_handle_callback)( struct target_if_ctx { uint32_t magic; get_psoc_handle_callback get_psoc_hdl_cb; + wmi_legacy_service_ready_callback service_ready_cb; qdf_spinlock_t lock; }; @@ -113,5 +119,28 @@ struct wlan_objmgr_psoc *target_if_get_psoc_from_scn_hdl(void *scn_handle); */ QDF_STATUS target_if_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); +/** + * target_if_get_psoc_from_scn_hdl() - get psoc from scn handle + * + * This API is generally used while processing wmi event. + * In wmi event SCN handle will be passed by wmi hence + * using this API we can get psoc from scn handle. + * + * Return: wmi_legacy_service_ready_callback + */ +wmi_legacy_service_ready_callback +target_if_get_psoc_legacy_service_ready_cb(void); + +/** + * target_if_register_legacy_service_ready_cb() - get legacy + * service ready handler from scn handle + * + * @service_ready_cb: funtion pointer to service ready callback + * + * Return: QDF Status + */ +QDF_STATUS target_if_register_legacy_service_ready_cb( + wmi_legacy_service_ready_callback service_ready_cb); + #endif diff --git a/target_if/core/src/target_if_main.c b/target_if/core/src/target_if_main.c index 48e3a16802d7..c2530e74a1e8 100644 --- a/target_if/core/src/target_if_main.c +++ b/target_if/core/src/target_if_main.c @@ -76,6 +76,7 @@ QDF_STATUS target_if_close(void) qdf_spin_lock_bh(&g_target_if_ctx->lock); g_target_if_ctx->magic = 0; g_target_if_ctx->get_psoc_hdl_cb = NULL; + g_target_if_ctx->service_ready_cb = NULL; qdf_spin_unlock_bh(&g_target_if_ctx->lock); qdf_spinlock_destroy(&g_target_if_ctx->lock); @@ -93,3 +94,30 @@ QDF_STATUS target_if_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) EXPORT_SYMBOL(target_if_register_tx_ops); +wmi_legacy_service_ready_callback +target_if_get_psoc_legacy_service_ready_cb(void) +{ + wmi_legacy_service_ready_callback service_ready_cb; + + qdf_spin_lock_bh(&g_target_if_ctx->lock); + if (g_target_if_ctx->service_ready_cb) + service_ready_cb = g_target_if_ctx->service_ready_cb; + else + service_ready_cb = NULL; + qdf_spin_unlock_bh(&g_target_if_ctx->lock); + + return service_ready_cb; +} +EXPORT_SYMBOL(target_if_get_psoc_legacy_service_ready_cb); + +QDF_STATUS target_if_register_legacy_service_ready_cb( + wmi_legacy_service_ready_callback service_ready_cb) +{ + qdf_spin_lock_bh(&g_target_if_ctx->lock); + g_target_if_ctx->service_ready_cb = service_ready_cb; + qdf_spin_unlock_bh(&g_target_if_ctx->lock); + + return QDF_STATUS_SUCCESS; +} +EXPORT_SYMBOL(target_if_register_legacy_service_ready_cb); + diff --git a/target_if/init_deinit/inc/service_ready_event_handler.h b/target_if/init_deinit/inc/service_ready_event_handler.h new file mode 100644 index 000000000000..34145ecf529f --- /dev/null +++ b/target_if/init_deinit/inc/service_ready_event_handler.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wmi_unified_event_handler.h + * + * Public API file for common WMI event handlers + */ +#ifndef _WMI_UNIFIED_EVENT_HANDLER_H_ +#define _WMI_UNIFIED_EVENT_HANDLER_H_ + +#include "athdefs.h" +#include "osapi_linux.h" +#include "a_types.h" +#include "a_debug.h" +#include "ol_if_athvar.h" +#include "ol_defines.h" +#include "qdf_types.h" +#include "qdf_util.h" +#include "wmi_unified_priv.h" +#include "wmi_unified_param.h" +#include "wlan_objmgr_psoc_obj.h" +#include "target_if.h" + +#define MAX_HW_MODE (2) +#define MAX_MAC_PHY_CAP (5) +#define MAX_PHY_REG_CAP (3) + +/** + * struct service_ready_param - service ready structure + * @wmi_service_bitmap: wmi service bitmap + * @target_caps: traget capability + * @hal_reg_cap: hal reg capability + */ +struct service_ready_param { + uint32_t wmi_service_bitmap[wmi_services_max]; + target_capability_info target_caps; + TARGET_HAL_REG_CAPABILITIES hal_reg_cap; +}; + +/** + * struct ext_service_ready_param - ext service ready structure + * @service_ext_param: service ext param + * @hw_mode_caps: hw mode caps + * @mac_phy_cap: mac phy cap + * @reg_cap: regulatory capability + */ +struct ext_service_ready_param { + struct wmi_host_service_ext_param service_ext_param; + struct wmi_host_hw_mode_caps hw_mode_caps[MAX_HW_MODE]; + struct wmi_host_mac_phy_caps mac_phy_cap[MAX_MAC_PHY_CAP]; + struct WMI_HOST_HAL_REG_CAPABILITIES_EXT reg_cap[MAX_PHY_REG_CAP]; +}; + +/** + * init_deinit_service_ready_event_handler() - service ready handler + * @handle: opaqueue pointer to scn + * @event: pointer to event buffer + * @event_len: event length + * + * WMI common event handler for WMI_SERVICE_READY_EVENTID + * + * Return: 0 for success, negative error code for failure + */ +int init_deinit_service_ready_event_handler(ol_scn_t handle, uint8_t *event, + uint32_t event_len); + +/** + * init_deinit_service_ext_ready_event_handler() - ext service ready handler + * @handle: opaqueue pointer to scn + * @event: pointer to event buffer + * @event_len: event length + * + * WMI common event handler for WMI_SERVICE_READY_EXT_EVENTID + * + * Return: 0 for success, negative error code for failure + */ +int init_deinit_service_ext_ready_event_handler(ol_scn_t handle, uint8_t *event, + uint32_t event_len); + +#endif /* _WMI_UNIFIED_EVENT_HANDLER_H_ */ diff --git a/target_if/init_deinit/src/service_ready_event_handler.c b/target_if/init_deinit/src/service_ready_event_handler.c new file mode 100644 index 000000000000..c46441d6cb62 --- /dev/null +++ b/target_if/init_deinit/src/service_ready_event_handler.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wmi_unified_event_handler.c + * + * WMI common event handler implementation source file + */ +#include "service_ready_event_handler.h" + +static int populate_service_bitmap(void *wmi_handle, uint8_t *event, + uint32_t *service_bitmap) +{ + QDF_STATUS status; + + status = wmi_save_service_bitmap(wmi_handle, event, service_bitmap); + if (QDF_IS_STATUS_ERROR(status)) { + WMI_LOGE("failed to parse service bitmap"); + return qdf_status_to_os_return(status); + } + + return 0; +} + +static int populate_target_cap(void *wmi_handle, uint8_t *event, + target_capability_info *cap) +{ + QDF_STATUS status; + + status = wmi_get_target_cap_from_service_ready(wmi_handle, event, cap); + if (QDF_IS_STATUS_ERROR(status)) { + WMI_LOGE("failed to parse target cap"); + return qdf_status_to_os_return(status); + } + + return 0; +} + +static int populate_hal_reg_cap(void *wmi_handle, uint8_t *event, + TARGET_HAL_REG_CAPABILITIES *cap) +{ + QDF_STATUS status; + + status = wmi_extract_hal_reg_cap(wmi_handle, event, cap); + if (QDF_IS_STATUS_ERROR(status)) { + WMI_LOGE("failed to parse hal reg cap"); + return qdf_status_to_os_return(status); + } + + return 0; +} + +int init_deinit_service_ready_event_handler(ol_scn_t scn_handle, + uint8_t *event, + uint32_t data_len) +{ + int err_code; + struct service_ready_param *service_param; + struct wlan_objmgr_psoc *psoc; + wmi_legacy_service_ready_callback legacy_callback; + void *wmi_handle; + + if (!scn_handle) { + WMI_LOGE("scn handle NULL in service ready handler"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn_handle); + if (!psoc) { + WMI_LOGE("psoc is null in service ready handler"); + return -EINVAL; + } + + wmi_handle = psoc->tgt_if_handle; + + service_param = qdf_mem_malloc(sizeof(struct service_ready_param)); + if (!service_param) { + WMI_LOGE("wmi_service_ready_param memory alloc failed"); + return -ENOMEM; + } + + err_code = populate_service_bitmap(wmi_handle, event, + service_param->wmi_service_bitmap); + if (err_code) + goto free_param_and_exit; + + err_code = populate_target_cap(wmi_handle, event, + &(service_param->target_caps)); + if (err_code) + goto free_param_and_exit; + + err_code = populate_hal_reg_cap(wmi_handle, event, + &(service_param->hal_reg_cap)); + if (err_code) + goto free_param_and_exit; + + /* populate wmi_service_ready_param in common psoc object using + * object manager api once its available + */ + legacy_callback = target_if_get_psoc_legacy_service_ready_cb(); + + err_code = legacy_callback(wmi_service_ready_event_id, + scn_handle, event, data_len); + +free_param_and_exit: + qdf_mem_free(service_param); + + return err_code; +} + +static int populate_service_ready_ext_param(void *handle, uint8_t *evt, + struct wmi_host_service_ext_param *param) +{ + QDF_STATUS status; + + status = wmi_extract_service_ready_ext(handle, evt, param); + if (QDF_IS_STATUS_ERROR(status)) { + WMI_LOGE("failed to parse wmi service ready ext param"); + return qdf_status_to_os_return(status); + } + + return 0; +} + +static int populate_mac_phy_capability(void *handle, uint8_t *evt, + struct wmi_host_hw_mode_caps *hw_cap, uint8_t *total_mac_phy, + struct ext_service_ready_param *service_param) +{ + QDF_STATUS status; + uint32_t hw_mode_id; + uint32_t phy_bit_map; + uint8_t mac_phy_id; + + hw_mode_id = hw_cap->hw_mode_id; + phy_bit_map = hw_cap->phy_id_map; + WMI_LOGE("hw_mode_id %d phy_bit_map 0x%x", hw_mode_id, phy_bit_map); + + mac_phy_id = 0; + while (phy_bit_map) { + status = wmi_extract_mac_phy_cap_service_ready_ext(handle, + evt, hw_mode_id, mac_phy_id, + &(service_param->mac_phy_cap[*total_mac_phy])); + if (QDF_IS_STATUS_ERROR(status)) { + WMI_LOGE("failed to parse mac phy capability"); + return qdf_status_to_os_return(status); + } + (*total_mac_phy)++; + if (*total_mac_phy > MAX_MAC_PHY_CAP) { + WMI_LOGE("total mac phy exceeds max limit %d", + *total_mac_phy); + return -EINVAL; + } + phy_bit_map &= (phy_bit_map - 1); + mac_phy_id++; + } + WMI_LOGE("total_mac_phy %d", *total_mac_phy); + + return 0; +} + +static int get_hw_mode(void *handle, uint8_t *evt, uint8_t i, + struct wmi_host_hw_mode_caps *cap) +{ + QDF_STATUS status; + + status = wmi_extract_hw_mode_cap_service_ready_ext(handle, evt, i, cap); + if (QDF_IS_STATUS_ERROR(status)) { + WMI_LOGE("failed to parse hw mode capability"); + return qdf_status_to_os_return(status); + } + + return 0; +} + +static int populate_hw_mode_capability(void *wmi_handle, + uint8_t *event, uint8_t *total_mac_phy, + struct ext_service_ready_param *service_param) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint8_t hw_idx; + uint32_t num_hw_modes; + + num_hw_modes = service_param->service_ext_param.num_hw_modes; + if (num_hw_modes > MAX_HW_MODE) { + WMI_LOGE("invalid num_hw_modes %d", num_hw_modes); + return -EINVAL; + } + WMI_LOGE("num_hw_modes %d", num_hw_modes); + + for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) { + status = get_hw_mode(wmi_handle, event, hw_idx, + &service_param->hw_mode_caps[hw_idx]); + if (status) + goto return_exit; + + status = populate_mac_phy_capability(wmi_handle, event, + &service_param->hw_mode_caps[hw_idx], + total_mac_phy, service_param); + if (status) + goto return_exit; + } + +return_exit: + return qdf_status_to_os_return(status); +} + +static int populate_phy_reg_capability(void *handle, uint8_t *event, + struct ext_service_ready_param *service_param) +{ + uint8_t reg_idx; + uint32_t num_phy_reg_cap; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + num_phy_reg_cap = service_param->service_ext_param.num_phy; + if (num_phy_reg_cap > MAX_PHY_REG_CAP) { + WMI_LOGE("Invalid num_phy_reg_cap %d", num_phy_reg_cap); + return -EINVAL; + } + WMI_LOGE("num_phy_reg_cap %d", num_phy_reg_cap); + + for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) { + status = wmi_extract_reg_cap_service_ready_ext(handle, event, + reg_idx, &(service_param->reg_cap[reg_idx])); + if (QDF_IS_STATUS_ERROR(status)) { + WMI_LOGE("failed to parse reg cap"); + return qdf_status_to_os_return(status); + } + } + + return 0; +} + +int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle, + uint8_t *event, + uint32_t data_len) +{ + int err_code; + struct ext_service_ready_param *service_param; + struct wlan_objmgr_psoc *psoc; + wmi_legacy_service_ready_callback legacy_callback; + void *wmi_handle; + + if (!scn_handle) { + WMI_LOGE("scn handle NULL in service ready handler"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn_handle); + if (!psoc) { + WMI_LOGE("psoc is null in service ready handler"); + return -EINVAL; + } + + wmi_handle = psoc->tgt_if_handle; + + service_param = + qdf_mem_malloc(sizeof(struct ext_service_ready_param)); + if (!service_param) { + WMI_LOGE("wmi_service_ready_param alloc failed"); + return QDF_STATUS_E_NOMEM; + } + + err_code = populate_service_ready_ext_param(wmi_handle, + event, &(service_param->service_ext_param)); + if (err_code) + goto free_param_and_exit; + + err_code = populate_hw_mode_capability(wmi_handle, + event, + &psoc->total_mac_phy, + service_param); + if (err_code) + goto free_param_and_exit; + + err_code = populate_phy_reg_capability(wmi_handle, + event, service_param); + if (err_code) + goto free_param_and_exit; + + /* populate wmi_ext_service_ready_param in common psoc object using + * object manager api once its available + */ + + legacy_callback = target_if_get_psoc_legacy_service_ready_cb(); + + err_code = legacy_callback(wmi_service_ready_ext_event_id, + scn_handle, event, data_len); + +free_param_and_exit: + qdf_mem_free(service_param); + + return err_code; +} diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h index 7dfcfa134c1d..2b753e65ae70 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h @@ -261,6 +261,7 @@ struct wlan_objmgr_psoc { QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS]; WLAN_OBJ_STATE obj_state; void *tgt_if_handle; + uint8_t total_mac_phy; qdf_spinlock_t psoc_lock; }; diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index f200390a2dea..eacaee60970d 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -1107,7 +1107,8 @@ QDF_STATUS wmi_unified_init_cmd_send(void *wmi_hdl, bool wmi_service_enabled(void *wmi_hdl, uint32_t service_id); -QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_buf); +QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_buf, + void *bitmap_buf); QDF_STATUS wmi_save_fw_version(void *wmi_hdl, void *evt_buf); diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 58d835e4b298..fa6e59676f30 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -904,7 +904,7 @@ QDF_STATUS (*send_lteu_config_cmd)(wmi_unified_t wmi_handle, QDF_STATUS (*send_set_ps_mode_cmd)(wmi_unified_t wmi_handle, struct set_ps_mode_params *param); void (*save_service_bitmap)(wmi_unified_t wmi_handle, - void *evt_buf); + void *evt_buf, void *bitmap_buf); bool (*is_service_enabled)(wmi_unified_t wmi_handle, uint32_t service_id); QDF_STATUS (*get_target_cap_from_service_ready)(wmi_unified_t wmi_handle, diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 278b7ae760b6..b07e15deef09 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -4604,12 +4604,14 @@ QDF_STATUS wmi_unified_init_cmd_send(void *wmi_hdl, * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_buf) +QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_buf, + void *bitmap_buf) { struct wmi_unified *wmi_handle = (struct wmi_unified *) wmi_hdl; if (wmi_handle->ops->save_service_bitmap) { - wmi_handle->ops->save_service_bitmap(wmi_handle, evt_buf); + wmi_handle->ops->save_service_bitmap(wmi_handle, evt_buf, + bitmap_buf); return 0; } return QDF_STATUS_E_FAILURE; diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c index 180957a25abb..9882400bf622 100644 --- a/wmi/src/wmi_unified_non_tlv.c +++ b/wmi/src/wmi_unified_non_tlv.c @@ -5405,10 +5405,12 @@ static QDF_STATUS send_ext_resource_config_non_tlv(wmi_unified_t wmi_handle, * save_service_bitmap_non_tlv() - save service bitmap * @wmi_handle: wmi handle * @param evt_buf: pointer to event buffer + * @param bitmap_buf: bitmap buffer for converged legacy support * * Return: None */ -static void save_service_bitmap_non_tlv(wmi_unified_t wmi_handle, void *evt_buf) +static void save_service_bitmap_non_tlv(wmi_unified_t wmi_handle, + void *evt_buf, void *bitmap_buf) { wmi_service_ready_event *ev; @@ -5416,6 +5418,10 @@ static void save_service_bitmap_non_tlv(wmi_unified_t wmi_handle, void *evt_buf) qdf_mem_copy(wmi_handle->wmi_service_bitmap, ev->wmi_service_bitmap, (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); + + if (bitmap_buf) + qdf_mem_copy(bitmap_buf, ev->wmi_service_bitmap, + (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); } /** diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 9fe47a88ceb0..8aa3a702c9ab 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -11920,12 +11920,14 @@ static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, * save_service_bitmap_tlv() - save service bitmap * @wmi_handle: wmi handle * @param evt_buf: pointer to event buffer + * @param bitmap_buf: bitmap buffer, for converged legacy support * * Return: None */ #ifndef CONFIG_MCL static -void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf) +void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, + void *bitmap_buf) { WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; @@ -11933,14 +11935,25 @@ void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf) qdf_mem_copy(wmi_handle->wmi_service_bitmap, param_buf->wmi_service_bitmap, (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); + + if (bitmap_buf) + qdf_mem_copy(bitmap_buf, + param_buf->wmi_service_bitmap, + (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); } #else static -void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf) +void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, + void *bitmap_buf) { - return; -} + WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; + param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; + if (bitmap_buf) + qdf_mem_copy(bitmap_buf, + param_buf->wmi_service_bitmap, + (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); +} #endif /**