diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 26e5f48c1d..49b2e9ee07 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -1150,9 +1150,26 @@ QDF_STATUS wmi_unified_init_cmd_send(void *wmi_hdl, bool wmi_service_enabled(void *wmi_hdl, uint32_t service_id); +/** + * wmi_save_service_bitmap() - save service bitmap + * @wmi_handle: wmi handle + * @param evt_buf: pointer to event buffer + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS failure code + */ QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_buf, void *bitmap_buf); +/** + * wmi_save_ext_service_bitmap() - save extended service bitmap + * @wmi_handle: wmi handle + * @param evt_buf: pointer to event buffer + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS failure code + */ +QDF_STATUS wmi_save_ext_service_bitmap(void *wmi_hdl, void *evt_buf, + void *bitmap_buf); + QDF_STATUS wmi_save_fw_version(void *wmi_hdl, void *evt_buf); QDF_STATUS wmi_get_target_cap_from_service_ready(void *wmi_hdl, diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index bcd0acca2a..20d8025ca1 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -5157,6 +5157,7 @@ typedef enum { wmi_ext_tbttoffset_update_event_id, wmi_11d_new_country_event_id, wmi_get_arp_stats_req_id, + wmi_service_available_event_id, wmi_events_max, } wmi_conv_event_id; diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 372b328716..130c5673c3 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -955,7 +955,9 @@ 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, +QDF_STATUS (*save_service_bitmap)(wmi_unified_t wmi_handle, + void *evt_buf, void *bitmap_buf); +QDF_STATUS (*save_ext_service_bitmap)(wmi_unified_t wmi_handle, void *evt_buf, void *bitmap_buf); bool (*is_service_enabled)(wmi_unified_t wmi_handle, uint32_t service_id); @@ -1452,8 +1454,6 @@ struct wmi_unified { bool wmi_stopinprogress; uint32_t *wmi_events; #ifndef CONFIG_MCL - /* WMI service bitmap recieved from target */ - uint32_t *wmi_service_bitmap; uint32_t *pdev_param; uint32_t *vdev_param; uint32_t *services; @@ -1478,9 +1478,10 @@ struct wmi_soc { uint16_t max_msg_len[WMI_MAX_RADIOS]; struct wmi_ops *ops; uint32_t wmi_events[wmi_events_max]; -#ifndef CONFIG_MCL /* WMI service bitmap recieved from target */ - uint32_t wmi_service_bitmap[wmi_services_max]; + uint32_t *wmi_service_bitmap; + uint32_t *wmi_ext_service_bitmap; +#ifndef CONFIG_MCL uint32_t pdev_param[wmi_pdev_param_max]; uint32_t vdev_param[wmi_vdev_param_max]; uint32_t services[wmi_services_max]; diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c index 8c6386e05f..f9d9bb6b9d 100644 --- a/wmi/src/wmi_unified.c +++ b/wmi/src/wmi_unified.c @@ -2573,8 +2573,6 @@ void wmi_interface_logging_init(struct wmi_unified *wmi_handle) static inline void wmi_target_params_init(struct wmi_soc *soc, struct wmi_unified *wmi_handle) { - /* WMI service bitmap recieved from target */ - wmi_handle->wmi_service_bitmap = soc->wmi_service_bitmap; wmi_handle->pdev_param = soc->pdev_param; wmi_handle->vdev_param = soc->vdev_param; wmi_handle->services = soc->services; @@ -2783,6 +2781,17 @@ void wmi_unified_detach(struct wmi_unified *wmi_handle) } } qdf_spinlock_destroy(&soc->ctx_lock); + + if (soc->wmi_service_bitmap) { + qdf_mem_free(soc->wmi_service_bitmap); + soc->wmi_service_bitmap = NULL; + } + + if (soc->wmi_ext_service_bitmap) { + qdf_mem_free(soc->wmi_ext_service_bitmap); + soc->wmi_ext_service_bitmap = NULL; + } + /* Decrease the ref count once refcount infra is present */ soc->wmi_psoc = NULL; qdf_mem_free(soc); diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 3a644478eb..e2401f5b24 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -4447,9 +4447,27 @@ QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_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, + return wmi_handle->ops->save_service_bitmap(wmi_handle, evt_buf, bitmap_buf); - return 0; + } + return QDF_STATUS_E_FAILURE; +} + +/** + * wmi_save_ext_service_bitmap() - save extended service bitmap + * @wmi_handle: wmi handle + * @param evt_buf: pointer to event buffer + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_save_ext_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_ext_service_bitmap) { + return wmi_handle->ops->save_ext_service_bitmap(wmi_handle, + evt_buf, bitmap_buf); } return QDF_STATUS_E_FAILURE; } diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c index 2850f860eb..7ae0283227 100644 --- a/wmi/src/wmi_unified_non_tlv.c +++ b/wmi/src/wmi_unified_non_tlv.c @@ -5458,21 +5458,36 @@ static QDF_STATUS send_ext_resource_config_non_tlv(wmi_unified_t wmi_handle, * @param evt_buf: pointer to event buffer * @param bitmap_buf: bitmap buffer for converged legacy support * - * Return: None + * Return: QDF_STATUS */ -static void save_service_bitmap_non_tlv(wmi_unified_t wmi_handle, +static QDF_STATUS save_service_bitmap_non_tlv(wmi_unified_t wmi_handle, void *evt_buf, void *bitmap_buf) { wmi_service_ready_event *ev; + struct wmi_soc *soc = wmi_handle->soc; ev = (wmi_service_ready_event *) evt_buf; - qdf_mem_copy(wmi_handle->wmi_service_bitmap, ev->wmi_service_bitmap, + /* If it is already allocated, use that buffer. This can happen + * during target stop/start scenarios where host allocation is skipped. + */ + if (!soc->wmi_service_bitmap) { + soc->wmi_service_bitmap = + qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); + if (!soc->wmi_service_bitmap) { + WMI_LOGE("Failed memory alloc for service bitmap\n"); + return QDF_STATUS_E_NOMEM; + } + } + + qdf_mem_copy(soc->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))); + + return QDF_STATUS_SUCCESS; } /** @@ -5485,7 +5500,14 @@ static void save_service_bitmap_non_tlv(wmi_unified_t wmi_handle, static bool is_service_enabled_non_tlv(wmi_unified_t wmi_handle, uint32_t service_id) { - return WMI_SERVICE_IS_ENABLED(wmi_handle->wmi_service_bitmap, + struct wmi_soc *soc = wmi_handle->soc; + + if (!soc->wmi_service_bitmap) { + WMI_LOGE("WMI service bit map is not saved yet\n"); + return false; + } + + return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, service_id); } diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 52e4b8317e..f320a5d6ad 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -15862,17 +15862,30 @@ static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, * @param evt_buf: pointer to event buffer * @param bitmap_buf: bitmap buffer, for converged legacy support * - * Return: None + * Return: QDF_STATUS */ -#ifndef CONFIG_MCL static -void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, +QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, void *bitmap_buf) { WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; + struct wmi_soc *soc = wmi_handle->soc; + param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; - qdf_mem_copy(wmi_handle->wmi_service_bitmap, + /* If it is already allocated, use that buffer. This can happen + * during target stop/start scenarios where host allocation is skipped. + */ + if (!soc->wmi_service_bitmap) { + soc->wmi_service_bitmap = + qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); + if (!soc->wmi_service_bitmap) { + WMI_LOGE("Failed memory allocation for service bitmap"); + return QDF_STATUS_E_NOMEM; + } + } + + qdf_mem_copy(soc->wmi_service_bitmap, param_buf->wmi_service_bitmap, (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); @@ -15880,22 +15893,53 @@ void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, qdf_mem_copy(bitmap_buf, param_buf->wmi_service_bitmap, (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); + + return QDF_STATUS_SUCCESS; } -#else + +/** + * save_ext_service_bitmap_tlv() - save extendend service bitmap + * @wmi_handle: wmi handle + * @param evt_buf: pointer to event buffer + * @param bitmap_buf: bitmap buffer, for converged legacy support + * + * Return: QDF_STATUS + */ static -void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, +QDF_STATUS save_ext_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; + WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; + wmi_service_available_event_fixed_param *ev; + struct wmi_soc *soc = wmi_handle->soc; + + param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; + + ev = param_buf->fixed_param; + + /* If it is already allocated, use that buffer. This can happen + * during target stop/start scenarios where host allocation is skipped. + */ + if (!soc->wmi_ext_service_bitmap) { + soc->wmi_ext_service_bitmap = qdf_mem_malloc( + WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); + if (!soc->wmi_ext_service_bitmap) { + WMI_LOGE("Failed memory allocation for service bitmap"); + return QDF_STATUS_E_NOMEM; + } + } + + qdf_mem_copy(soc->wmi_ext_service_bitmap, + ev->wmi_service_segment_bitmap, + (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); if (bitmap_buf) qdf_mem_copy(bitmap_buf, - param_buf->wmi_service_bitmap, - (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); -} -#endif + soc->wmi_ext_service_bitmap, + (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); + return QDF_STATUS_SUCCESS; +} /** * is_service_enabled_tlv() - Check if service enabled * @param wmi_handle: wmi handle @@ -15907,8 +15951,23 @@ void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, uint32_t service_id) { - return WMI_SERVICE_IS_ENABLED(wmi_handle->wmi_service_bitmap, - service_id); + struct wmi_soc *soc = wmi_handle->soc; + + if (!soc->wmi_service_bitmap) { + WMI_LOGE("WMI service bit map is not saved yet\n"); + return false; + } + + /* if WMI_EXTENDED_SERVICE_AVAILABLE was received with extended bitmap, + * use WMI_SERVICE_EXT_ENABLE to check the services. + */ + if (soc->wmi_ext_service_bitmap) + return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, + soc->wmi_ext_service_bitmap, + service_id); + + return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, + service_id); } #else static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, @@ -19257,6 +19316,7 @@ struct wmi_ops tlv_ops = { .extract_hal_reg_cap = extract_hal_reg_cap_tlv, .extract_host_mem_req = extract_host_mem_req_tlv, .save_service_bitmap = save_service_bitmap_tlv, + .save_ext_service_bitmap = save_ext_service_bitmap_tlv, .is_service_enabled = is_service_enabled_tlv, .save_fw_version = save_fw_version_in_service_ready_tlv, .ready_extract_init_status = ready_extract_init_status_tlv, @@ -19596,6 +19656,8 @@ static void populate_tlv_events_id(uint32_t *event_ids) event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; + event_ids[wmi_service_available_event_id] = + WMI_SERVICE_AVAILABLE_EVENTID; } #ifndef CONFIG_MCL