diff --git a/Kbuild b/Kbuild index 2cf557b10354..906c3bfbb447 100644 --- a/Kbuild +++ b/Kbuild @@ -86,6 +86,9 @@ HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_csr.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_connect.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_offload.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_roam.o +ifeq ($(CONFIG_WLAN_MWS_INFO_DEBUGFS), y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_coex.o +endif endif ifeq ($(CONFIG_WLAN_CONV_SPECTRAL_ENABLE),y) @@ -1669,6 +1672,9 @@ endif ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y) WMA_OBJS += $(WMA_SRC_DIR)/wma_fw_state.o endif +ifeq ($(CONFIG_WLAN_MWS_INFO_DEBUGFS), y) +WMA_OBJS += $(WMA_SRC_DIR)/wma_coex.o +endif ############## PLD ########## PLD_DIR := core/pld PLD_INC_DIR := $(PLD_DIR)/inc @@ -2074,6 +2080,8 @@ cppflags-$(CONFIG_FEATURE_ROAM_DEBUG) += -DFEATURE_ROAM_DEBUG cppflags-$(CONFIG_WLAN_POWER_DEBUGFS) += -DWLAN_POWER_DEBUGFS +cppflags-$(CONFIG_WLAN_MWS_INFO_DEBUGFS) += -DWLAN_MWS_INFO_DEBUGFS + # Enable object manager reference count debug infrastructure cppflags-$(CONFIG_WLAN_OBJMGR_DEBUG) += -DWLAN_OBJMGR_DEBUG cppflags-$(CONFIG_WLAN_OBJMGR_DEBUG) += -DWLAN_OBJMGR_REF_ID_DEBUG diff --git a/configs/default_defconfig b/configs/default_defconfig index 6331b6714900..38c5e21eb97c 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -373,6 +373,8 @@ ifeq ($(CONFIG_DEBUG_FS), y) CONFIG_WLAN_DEBUGFS := y CONFIG_WLAN_POWER_DEBUGFS := y + + CONFIG_WLAN_MWS_INFO_DEBUGFS := y endif # Feature flags which are not (currently) configurable via Kconfig diff --git a/core/hdd/inc/wlan_hdd_debugfs_coex.h b/core/hdd/inc/wlan_hdd_debugfs_coex.h new file mode 100644 index 000000000000..5a6bfed8829d --- /dev/null +++ b/core/hdd/inc/wlan_hdd_debugfs_coex.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef _WLAN_HDD_DEBUGFS_COEX_H +#define _WLAN_HDD_DEBUGFS_COEX_H + +#ifdef WLAN_MWS_INFO_DEBUGFS +/** + * hdd_debugfs_mws_coex_info_init() - MWS coex initialization + * @hdd_ctx: Pointer to the hdd_ctx + * + * This function is called to initialize the coex debugfs. + * Return: None + */ +void hdd_debugfs_mws_coex_info_init(struct hdd_context *hdd_ctx); + +/** + * hdd_debugfs_mws_coex_info_deinit() - MWS coex deintialization + * @hdd_ctx: Pointer to the hdd_ctx + * + * This function is called to deinitialize the coex debugfs. + * Return: None + */ +void hdd_debugfs_mws_coex_info_deinit(struct hdd_context *hdd_ctx); +#else +static inline void hdd_debugfs_mws_coex_info_init(struct hdd_context *hdd_ctx) +{ +} + +static inline void hdd_debugfs_mws_coex_info_deinit(struct hdd_context *hdd_ctx) +{ +} +#endif +#endif diff --git a/core/hdd/src/wlan_hdd_debugfs_coex.c b/core/hdd/src/wlan_hdd_debugfs_coex.c new file mode 100644 index 000000000000..9f245c7774db --- /dev/null +++ b/core/hdd/src/wlan_hdd_debugfs_coex.c @@ -0,0 +1,668 @@ +/* + * Copyright (c) 2019 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: wlan_hdd_debugfs_coex.c + * + * This file currently supports the following debugfs: + * Get the following information coex information + * COEX STATE + * COEX DPWB STATE + * COEX TDM STATE + * COEX IDRX STATE + * COEX ANTENNA SHARING STATE + * + * Example to read the COEX STATE logging: + * sm6150:/ # cat /sys/kernel/debug/wlan/mws_coex_state + */ + +#include +#include +#include +#include "wmi_unified.h" +#include "wmi_unified_param.h" +#include "osif_sync.h" + +#define MWS_DEBUGFS_PERMS (QDF_FILE_USR_READ | \ + QDF_FILE_GRP_READ | \ + QDF_FILE_OTH_READ) + +/* wait time for mws coex info in milliseconds */ +#define WLAN_WAIT_TIME_MWS_COEX_INFO 800 + +struct mws_coex_state_priv { + struct mws_coex_state coex_state; +}; + +struct mws_coex_dpwb_state_priv { + struct mws_coex_dpwb_state dpwb_state; +}; + +struct mws_coex_tdm_state_priv { + struct mws_coex_tdm_state tdm_state; +}; + +struct mws_coex_idrx_state_priv { + struct mws_coex_idrx_state idrx_state; +}; + +struct mws_antenna_sharing_info_priv { + struct mws_antenna_sharing_info antenna_sharing; +}; + +static void hdd_debugfs_mws_coex_info_cb(void *coex_info_data, void *context, + wmi_mws_coex_cmd_id cmd_id) +{ + struct osif_request *request = NULL; + struct mws_coex_state_priv *coex_priv; + struct mws_coex_dpwb_state_priv *dpwb_priv; + struct mws_coex_tdm_state_priv *tdm_priv; + struct mws_coex_idrx_state_priv *idrx_priv; + struct mws_antenna_sharing_info_priv *antenna_priv; + + if (!coex_info_data) { + hdd_err("data is null"); + return; + } + + request = osif_request_get(context); + if (!request) { + hdd_err("obselete request"); + return; + } + + switch (cmd_id) { + case WMI_MWS_COEX_STATE: + coex_priv = osif_request_priv(request); + qdf_mem_copy(&coex_priv->coex_state, coex_info_data, + sizeof(struct mws_coex_state)); + break; + case WMI_MWS_COEX_DPWB_STATE: + dpwb_priv = osif_request_priv(request); + qdf_mem_copy(&dpwb_priv->dpwb_state, coex_info_data, + sizeof(struct mws_coex_dpwb_state)); + break; + case WMI_MWS_COEX_TDM_STATE: + tdm_priv = osif_request_priv(request); + qdf_mem_copy(&tdm_priv->tdm_state, coex_info_data, + sizeof(struct mws_coex_tdm_state)); + break; + case WMI_MWS_COEX_IDRX_STATE: + idrx_priv = osif_request_priv(request); + qdf_mem_copy(&idrx_priv->idrx_state, coex_info_data, + sizeof(struct mws_coex_idrx_state)); + break; + case WMI_MWS_COEX_ANTENNA_SHARING_STATE: + antenna_priv = osif_request_priv(request); + qdf_mem_copy(&antenna_priv->antenna_sharing, coex_info_data, + sizeof(struct mws_antenna_sharing_info)); + break; + } + + osif_request_complete(request); + osif_request_put(request); +} + +static QDF_STATUS __hdd_debugfs_mws_coex_state_read(struct hdd_context *hdd_ctx, + qdf_debugfs_file_t file) +{ + struct hdd_adapter *adapter; + QDF_STATUS status; + int rc; + struct osif_request *request; + struct mws_coex_state *coex_state; + struct mws_coex_state_priv *priv; + static const struct osif_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO, + }; + void *cookie; + + adapter = hdd_get_first_valid_adapter(hdd_ctx); + if (!adapter) { + hdd_err("Failed to get adapter"); + return QDF_STATUS_E_INVAL; + } + + if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { + hdd_err("Interface is not enabled"); + return QDF_STATUS_E_INVAL; + } + + if (file->index > 0) + return QDF_STATUS_SUCCESS; + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_NOMEM; + } + + cookie = osif_request_cookie(request); + + status = sme_get_mws_coex_info(hdd_ctx->mac_handle, + adapter->vdev_id, WMI_MWS_COEX_STATE, + hdd_debugfs_mws_coex_info_cb, cookie); + + if (QDF_IS_STATUS_ERROR(status)) { + rc = qdf_status_to_os_return(status); + goto exit; + } + + rc = osif_request_wait_for_response(request); + if (rc) { + qdf_debugfs_printf(file, "Timedout while retrieving MWS coex state"); + rc = -ETIMEDOUT; + goto exit; + } + + priv = osif_request_priv(request); + coex_state = &priv->coex_state; + + qdf_debugfs_printf(file, "vdev_id = %u\n" + "coex_scheme_bitmap = %u\n" + "active_conflict_count = %u\n" + "potential_conflict_count = %u\n" + "chavd_group0_bitmap = %u\n" + "chavd_group1_bitmap = %u\n" + "chavd_group2_bitmap = %u\n" + "chavd_group3_bitmap = %u\n", + coex_state->vdev_id, + coex_state->coex_scheme_bitmap, + coex_state->active_conflict_count, + coex_state->potential_conflict_count, + coex_state->chavd_group0_bitmap, + coex_state->chavd_group1_bitmap, + coex_state->chavd_group2_bitmap, + coex_state->chavd_group3_bitmap); + +exit: + osif_request_put(request); + return qdf_status_from_os_return(rc); + } + +static QDF_STATUS hdd_debugfs_mws_coex_state_read(qdf_debugfs_file_t file, + void *arg) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = arg; + int ret; + QDF_STATUS status; + + ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); + if (ret) + return qdf_status_from_os_return(ret); + + status = __hdd_debugfs_mws_coex_state_read(hdd_ctx, file); + + osif_psoc_sync_op_stop(psoc_sync); + return qdf_status_from_os_return(ret); +} + +static QDF_STATUS __hdd_debugfs_mws_coex_dpwb_read(struct hdd_context *hdd_ctx, + qdf_debugfs_file_t file) + { + struct hdd_adapter *adapter; + QDF_STATUS status; + int rc; + struct osif_request *request; + struct mws_coex_dpwb_state *dpwb_state; + struct mws_coex_dpwb_state_priv *dpwb_priv; + static const struct osif_request_params params = { + .priv_size = sizeof(*dpwb_priv), + .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO, + }; + void *cookie; + + adapter = hdd_get_first_valid_adapter(hdd_ctx); + if (!adapter) { + hdd_err("Failed to get adapter"); + return QDF_STATUS_E_INVAL; + } + + if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { + hdd_err("Interface is not enabled"); + return QDF_STATUS_E_INVAL; + } + + if (file->index > 0) + return QDF_STATUS_SUCCESS; + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_NOMEM; + } + + cookie = osif_request_cookie(request); + + status = sme_get_mws_coex_info(hdd_ctx->mac_handle, + adapter->vdev_id, + WMI_MWS_COEX_DPWB_STATE, + hdd_debugfs_mws_coex_info_cb, cookie); + + if (QDF_IS_STATUS_ERROR(status)) { + rc = qdf_status_to_os_return(status); + goto exit; + } + + rc = osif_request_wait_for_response(request); + if (rc) { + qdf_debugfs_printf(file, "Timedout while retrieving MWS coex dpwb state"); + rc = -ETIMEDOUT; + goto exit; + } + + dpwb_priv = osif_request_priv(request); + dpwb_state = &dpwb_priv->dpwb_state; + qdf_debugfs_printf(file, "vdev_id = %u\n" + "current_dpwb_state = %d\n" + "pnp1_value = %d\n" + "lte_dutycycle = %d\n" + "sinr_wlan_on = %d\n" + "bler_count = %u\n" + "block_count = %u\n" + "wlan_rssi_level = %u\n" + "wlan_rssi = %d\n" + "is_tdm_running = %u\n", + dpwb_state->vdev_id, + dpwb_state->current_dpwb_state, + dpwb_state->pnp1_value, + dpwb_state->lte_dutycycle, + dpwb_state->sinr_wlan_on, + dpwb_state->sinr_wlan_off, + dpwb_state->bler_count, + dpwb_state->block_count, + dpwb_state->wlan_rssi_level, + dpwb_state->wlan_rssi, + dpwb_state->is_tdm_running); + +exit: + osif_request_put(request); + return qdf_status_from_os_return(rc); +} + +static QDF_STATUS hdd_debugfs_mws_coex_dpwb_read(qdf_debugfs_file_t file, + void *arg) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = arg; + int ret; + QDF_STATUS status; + + ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); + if (ret) + return qdf_status_from_os_return(ret); + + status = __hdd_debugfs_mws_coex_dpwb_read(hdd_ctx, file); + + osif_psoc_sync_op_stop(psoc_sync); + return qdf_status_from_os_return(ret); +} + +static QDF_STATUS __hdd_debugfs_mws_tdm_state_read(struct hdd_context *hdd_ctx, + qdf_debugfs_file_t file) +{ + struct hdd_adapter *adapter; + QDF_STATUS status; + int rc; + struct mws_coex_tdm_state *tdm_state; + struct mws_coex_tdm_state_priv *tdm_priv; + struct osif_request *request; + static const struct osif_request_params params = { + .priv_size = sizeof(*tdm_priv), + .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO, + }; + void *cookie; + + adapter = hdd_get_first_valid_adapter(hdd_ctx); + if (!adapter) { + hdd_err("Failed to get adapter"); + return QDF_STATUS_E_INVAL; + } + + if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { + hdd_err("Interface is not enabled"); + return QDF_STATUS_E_INVAL; + } + + if (file->index > 0) + return QDF_STATUS_SUCCESS; + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_NOMEM; + } + + cookie = osif_request_cookie(request); + + status = sme_get_mws_coex_info(hdd_ctx->mac_handle, + adapter->vdev_id, WMI_MWS_COEX_TDM_STATE, + hdd_debugfs_mws_coex_info_cb, cookie); + + if (QDF_IS_STATUS_ERROR(status)) { + rc = qdf_status_to_os_return(status); + goto exit; + } + + rc = osif_request_wait_for_response(request); + if (rc) { + qdf_debugfs_printf(file, "Timedout while retrieving MWS coex tdm state"); + rc = -ETIMEDOUT; + goto exit; + } + + tdm_priv = osif_request_priv(request); + tdm_state = &tdm_priv->tdm_state; + + qdf_debugfs_printf(file, "vdev_id = %u\n" + "tdm_policy_bitmap = %u\n" + "tdm_sf_bitmap = %u\n", + tdm_state->vdev_id, + tdm_state->tdm_policy_bitmap, + tdm_state->tdm_sf_bitmap); + +exit: + osif_request_put(request); + return qdf_status_from_os_return(rc); +} + +static QDF_STATUS hdd_debugfs_mws_tdm_state_read(qdf_debugfs_file_t file, + void *arg) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = arg; + int ret; + QDF_STATUS status; + + ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); + if (ret) + return qdf_status_from_os_return(ret); + + status = __hdd_debugfs_mws_tdm_state_read(hdd_ctx, file); + + osif_psoc_sync_op_stop(psoc_sync); + return qdf_status_from_os_return(ret); +} + +static QDF_STATUS __hdd_debugfs_mws_coex_idrx_read(struct hdd_context *hdd_ctx, + qdf_debugfs_file_t file) +{ + struct hdd_adapter *adapter; + QDF_STATUS status; + int rc; + struct osif_request *request; + struct mws_coex_idrx_state_priv *idrx_priv; + struct mws_coex_idrx_state *idrx_state; + static const struct osif_request_params params = { + .priv_size = sizeof(*idrx_priv), + .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO, + }; + void *cookie; + + adapter = hdd_get_first_valid_adapter(hdd_ctx); + if (!adapter) { + hdd_err("Failed to get adapter"); + return QDF_STATUS_E_INVAL; + } + + if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { + hdd_err("Interface is not enabled"); + return QDF_STATUS_E_INVAL; + } + + if (file->index > 0) + return QDF_STATUS_SUCCESS; + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_NOMEM; + } + + cookie = osif_request_cookie(request); + + status = sme_get_mws_coex_info(hdd_ctx->mac_handle, + adapter->vdev_id, + WMI_MWS_COEX_IDRX_STATE, + hdd_debugfs_mws_coex_info_cb, cookie); + + if (QDF_IS_STATUS_ERROR(status)) { + rc = qdf_status_to_os_return(status); + goto exit; + } + + rc = osif_request_wait_for_response(request); + if (rc) { + qdf_debugfs_printf(file, "Timedout while retrieving MWS coex idrx state"); + rc = -ETIMEDOUT; + goto exit; + } + + idrx_priv = osif_request_priv(request); + idrx_state = &idrx_priv->idrx_state; + qdf_debugfs_printf(file, "vdev_id = %u\n" + "sub0_techid = %u\n" + "sub0_policy = %u\n" + "sub0_is_link_critical = %u\n" + "sub0_static_power = %u\n" + "sub0_rssi = %d\n" + "sub0_techid = %d\n" + "sub0_policy = %d\n" + "sub0_is_link_critical = %d\n" + "sub0_static_power = %u\n" + "sub0_rssi = %d\n", + idrx_state->vdev_id, + idrx_state->sub0_techid, + idrx_state->sub0_policy, + idrx_state->sub0_is_link_critical, + idrx_state->sub0_static_power, + idrx_state->sub0_rssi, + idrx_state->sub1_techid, + idrx_state->sub1_policy, + idrx_state->sub1_is_link_critical, + idrx_state->sub1_static_power, + idrx_state->sub1_rssi); + +exit: + osif_request_put(request); + return qdf_status_from_os_return(rc); +} + +static QDF_STATUS hdd_debugfs_mws_coex_idrx_read(qdf_debugfs_file_t file, + void *arg) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = arg; + int ret; + QDF_STATUS status; + + ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); + if (ret) + return qdf_status_from_os_return(ret); + + status = __hdd_debugfs_mws_coex_idrx_read(hdd_ctx, file); + + osif_psoc_sync_op_stop(psoc_sync); + return qdf_status_from_os_return(ret); +} + +static QDF_STATUS __hdd_debugfs_mws_antenna_sharing_read(struct hdd_context + *hdd_ctx, + qdf_debugfs_file_t + file) +{ + struct hdd_adapter *adapter; + QDF_STATUS status; + int rc; + struct mws_antenna_sharing_info *antenna_sharing; + struct mws_antenna_sharing_info_priv *antenna_priv; + struct osif_request *request; + static const struct osif_request_params params = { + .priv_size = sizeof(*antenna_priv), + .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO, + }; + void *cookie; + + adapter = hdd_get_first_valid_adapter(hdd_ctx); + if (!adapter) { + hdd_err("Failed to get adapter"); + return QDF_STATUS_E_INVAL; + } + + if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { + hdd_err("Interface is not enabled"); + return QDF_STATUS_E_INVAL; + } + + if (file->index > 0) + return QDF_STATUS_SUCCESS; + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_NOMEM; + } + + cookie = osif_request_cookie(request); + + status = sme_get_mws_coex_info(hdd_ctx->mac_handle, + adapter->vdev_id, + WMI_MWS_COEX_ANTENNA_SHARING_STATE, + hdd_debugfs_mws_coex_info_cb, cookie); + + if (QDF_IS_STATUS_ERROR(status)) { + rc = qdf_status_to_os_return(status); + goto exit; + } + + rc = osif_request_wait_for_response(request); + if (rc) { + qdf_debugfs_printf(file, "Timedout while retrieving MWS coex antenna sharing state"); + rc = -ETIMEDOUT; + goto exit; + } + + antenna_priv = osif_request_priv(request); + antenna_sharing = &antenna_priv->antenna_sharing; + qdf_debugfs_printf(file, "vdev_id = %u\n" + "coex_flags = %u\n" + "coex_config = %u\n" + "tx_chain_mask = %u\n" + "rx_chain_mask = %u\n" + "rx_nss = %u\n" + "force_mrc = %u\n" + "rssi_type = %u\n" + "chain0_rssi = %d\n" + "chain1_rssi = %d\n" + "combined_rssi = %d\n" + "imbalance = %u\n" + "mrc_threshold = %d\n" + "grant_duration = %u\n", + antenna_sharing->vdev_id, + antenna_sharing->coex_flags, + antenna_sharing->coex_config, + antenna_sharing->tx_chain_mask, + antenna_sharing->rx_chain_mask, + antenna_sharing->rx_nss, + antenna_sharing->force_mrc, + antenna_sharing->rssi_type, + antenna_sharing->chain0_rssi, + antenna_sharing->chain1_rssi, + antenna_sharing->combined_rssi, + antenna_sharing->imbalance, + antenna_sharing->mrc_threshold, + antenna_sharing->grant_duration); + +exit: + osif_request_put(request); + return qdf_status_from_os_return(rc); +} + +static QDF_STATUS hdd_debugfs_mws_antenna_sharing_read(qdf_debugfs_file_t file, + void *arg) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = arg; + int ret; + QDF_STATUS status; + + ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); + if (ret) + return qdf_status_from_os_return(ret); + + status = __hdd_debugfs_mws_antenna_sharing_read(hdd_ctx, file); + + osif_psoc_sync_op_stop(psoc_sync); + return qdf_status_from_os_return(ret); +} + +static struct qdf_debugfs_fops hdd_mws_debugfs_coex_state_fops = { + .show = hdd_debugfs_mws_coex_state_read, +}; + +static struct qdf_debugfs_fops hdd_mws_debugfs_fops_coex_dpwb_fops = { + .show = hdd_debugfs_mws_coex_dpwb_read, +}; + +static struct qdf_debugfs_fops hdd_mws_debugfs_tdm_state_fpos = { + .show = hdd_debugfs_mws_tdm_state_read, +}; + +static struct qdf_debugfs_fops hdd_mws_debugfs_idrx_state_fpos = { + .show = hdd_debugfs_mws_coex_idrx_read, +}; + +static struct qdf_debugfs_fops hdd_mws_debugfs_antenna_sharing_fpos = { + .show = hdd_debugfs_mws_antenna_sharing_read, +}; + +void hdd_debugfs_mws_coex_info_init(struct hdd_context *hdd_ctx) +{ + hdd_mws_debugfs_coex_state_fops.priv = hdd_ctx; + hdd_mws_debugfs_fops_coex_dpwb_fops.priv = hdd_ctx; + hdd_mws_debugfs_tdm_state_fpos.priv = hdd_ctx; + hdd_mws_debugfs_idrx_state_fpos.priv = hdd_ctx; + hdd_mws_debugfs_antenna_sharing_fpos.priv = hdd_ctx; + if (!qdf_debugfs_create_file("mws_coex_state", MWS_DEBUGFS_PERMS, + NULL, &hdd_mws_debugfs_coex_state_fops)) + hdd_err("Failed to create the mws coex state file"); + if (!qdf_debugfs_create_file("mws_coex_dpwb_state", MWS_DEBUGFS_PERMS, + NULL, + &hdd_mws_debugfs_fops_coex_dpwb_fops)) + hdd_err("Failed to create the mws coex dpwb file"); + if (!qdf_debugfs_create_file("mws_coex_tdm_state", MWS_DEBUGFS_PERMS, + NULL, &hdd_mws_debugfs_tdm_state_fpos)) + hdd_err("Failed to create the mws coex tdm file"); + if (!qdf_debugfs_create_file("mws_coex_idrx", MWS_DEBUGFS_PERMS, + NULL, &hdd_mws_debugfs_idrx_state_fpos)) + hdd_err("Failed to create the mws coex idrx file"); + if (!qdf_debugfs_create_file("mws_coex_antenna_sharing", + MWS_DEBUGFS_PERMS, + NULL, + &hdd_mws_debugfs_antenna_sharing_fpos)) + hdd_err("Failed to create the mws coex antenna sharing file"); +} + +void hdd_debugfs_mws_coex_info_deinit(struct hdd_context *hdd_ctx) +{ + /** + * Coex info dosent have a directory it is removed as part of qdf remove + */ +} diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index ffc25ace7fb2..0f4a68d39958 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -161,6 +161,7 @@ #include "wlan_green_ap_ucfg_api.h" #include #include +#include #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) @@ -7286,6 +7287,7 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx) hdd_enter(); + hdd_debugfs_mws_coex_info_deinit(hdd_ctx); hdd_psoc_idle_timer_stop(hdd_ctx); hdd_unregister_notifiers(hdd_ctx); @@ -11889,6 +11891,7 @@ int hdd_wlan_startup(struct hdd_context *hdd_ctx) ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); + hdd_debugfs_mws_coex_info_init(hdd_ctx); hdd_exit(); diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index e5aab0475444..9e0c74b534f4 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -5886,4 +5886,16 @@ struct sir_md_evt { uint32_t status; }; #endif /* WLAN_FEATURE_MOTION_DETECTION */ + +#ifdef WLAN_MWS_INFO_DEBUGFS +/** + * struct sir_get_mws_coex_info - Get MWS coex info + * @vdev_id: vdev id + * @cmd_id: wmi mws-coex command IDs + */ +struct sir_get_mws_coex_info { + uint32_t vdev_id; + uint32_t cmd_id; +}; +#endif /* WLAN_MWS_INFO_DEBUGFS */ #endif /* __SIR_API_H */ diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 1ca682da7afa..07569e8c90c3 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -405,7 +405,9 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_PDEV_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) -/* 162 unused */ +#ifdef WLAN_MWS_INFO_DEBUGFS +#define SIR_HAL_GET_MWS_COEX_INFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 162) +#endif /* WLAN_MWS_INFO_DEBUGFS */ #define SIR_HAL_CLI_SET_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 163) #ifndef REMOVE_PKT_LOG diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index a0295c69fa35..479d49b33c53 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -43,6 +43,7 @@ #include "scheduler_api.h" #include "wlan_serialization_legacy_api.h" #include +#include "wmi_unified.h" /*-------------------------------------------------------------------------- Preprocessor definitions and constants @@ -3426,4 +3427,25 @@ QDF_STATUS sme_update_hidden_ssid_status_cb(mac_handle_t mac_handle, */ QDF_STATUS sme_update_owe_info(struct mac_context *mac, struct assoc_ind *assoc_ind); + +#ifdef WLAN_MWS_INFO_DEBUGFS +/** + * sme_get_mws_coex_info() - SME API to get the coex information + * @mac_handle: mac handler + * @vdev_id: Vdev_id + * @cmd_id: enum mws_coex_cmdid which information is needed. + * @callback_fn: Callback function + * @context: callback context + * + * Return: QDF_STATUS + */ +QDF_STATUS +sme_get_mws_coex_info(mac_handle_t mac_handle, uint32_t vdev_id, + uint32_t cmd_id, void (*callback_fn)(void *coex_info_data, + void *context, + wmi_mws_coex_cmd_id + cmd_id), + void *context); +#endif /* WLAN_MWS_INFO_DEBUGFS */ + #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index ea99c72ab4d9..e6ca7224e26c 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -36,6 +36,7 @@ #include "host_diag_core_event.h" #include "csr_link_list.h" #include "sme_power_save.h" +#include "wmi_unified.h" struct wmi_twt_enable_complete_event_param; /*-------------------------------------------------------------------------- @@ -356,6 +357,12 @@ struct sme_context { #endif /* WLAN_FEATURE_MOTION_DETECTION */ /* hidden ssid rsp callback */ hidden_ssid_cb hidden_ssid_cb; +#ifdef WLAN_MWS_INFO_DEBUGFS + void *mws_coex_info_ctx; + void (*mws_coex_info_state_resp_callback)(void *coex_info_data, + void *context, + wmi_mws_coex_cmd_id cmd_id); +#endif /* WLAN_MWS_INFO_DEBUGFS */ }; diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 743493fe32ac..d7515344f116 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -15351,3 +15351,50 @@ QDF_STATUS sme_update_owe_info(struct mac_context *mac, return status; } + +#ifdef WLAN_MWS_INFO_DEBUGFS +QDF_STATUS +sme_get_mws_coex_info(mac_handle_t mac_handle, uint32_t vdev_id, + uint32_t cmd_id, void (*callback_fn)(void *coex_info_data, + void *context, + wmi_mws_coex_cmd_id + cmd_id), + void *context) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + struct scheduler_msg msg = {0}; + struct sir_get_mws_coex_info *req; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + sme_err("Failed allocate memory for MWS coex info req"); + return QDF_STATUS_E_NOMEM; + } + + req->vdev_id = vdev_id; + req->cmd_id = cmd_id; + mac->sme.mws_coex_info_state_resp_callback = callback_fn; + mac->sme.mws_coex_info_ctx = context; + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + msg.bodyptr = req; + msg.type = WMA_GET_MWS_COEX_INFO_REQ; + status = scheduler_post_message(QDF_MODULE_ID_SME, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, + &msg); + sme_release_global_lock(&mac->sme); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_err("post MWS coex info req failed"); + status = QDF_STATUS_E_FAILURE; + qdf_mem_free(req); + } + } else { + sme_err("sme_acquire_global_lock failed"); + qdf_mem_free(req); + } + + return status; +} +#endif /* WLAN_MWS_INFO_DEBUGFS */ diff --git a/core/wma/inc/wma_coex.h b/core/wma/inc/wma_coex.h new file mode 100644 index 000000000000..33ff1fd4d531 --- /dev/null +++ b/core/wma/inc/wma_coex.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef _WLAN_HDD_DEBUGFS_COEX_H +#define _WLAN_HDD_DEBUGFS_COEX_H + +#include +#include "sme_api.h" + +#ifdef WLAN_MWS_INFO_DEBUGFS +void wma_get_mws_coex_info_req(tp_wma_handle wma_handle, + struct sir_get_mws_coex_info *req); +void wma_register_mws_coex_events(tp_wma_handle wma_handle); +#else +static void wma_register_mws_coex_events(tp_wma_handle wma_handle) +{ +} +#endif +#endif diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index ba8e44dea6fe..077a2d42d756 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -456,6 +456,10 @@ #define WMA_SET_THERMAL_MGMT SIR_HAL_SET_THERMAL_MGMT #endif /* FW_THERMAL_THROTTLE_SUPPORT */ +#ifdef WLAN_MWS_INFO_DEBUGFS +#define WMA_GET_MWS_COEX_INFO_REQ SIR_HAL_GET_MWS_COEX_INFO_REQ +#endif + /* Bit 6 will be used to control BD rate for Management frames */ #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 diff --git a/core/wma/src/wma_coex.c b/core/wma/src/wma_coex.c new file mode 100644 index 000000000000..732692f19794 --- /dev/null +++ b/core/wma/src/wma_coex.c @@ -0,0 +1,377 @@ + +/* + * Copyright (c) 2019 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. + */ + +#include +#include +#include "wmi_unified.h" + +/** + * wma_mws_coex_state_host_event_handler - Coex state Event Handler + * @handle: pointer to scn handle + * @event: Coex state event + * @len: Length of cmd + * + * Return: 0 on success, else error on failure + */ +static int wma_mws_coex_state_host_event_handler(void *handle, uint8_t *event, + uint32_t len) +{ + WMI_VDEV_GET_MWS_COEX_STATE_EVENTID_param_tlvs *param_tlvs; + wmi_vdev_get_mws_coex_state_fixed_param *param_buf; + struct mws_coex_state coex_state; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + + wma_debug("Enter"); + param_tlvs = + (WMI_VDEV_GET_MWS_COEX_STATE_EVENTID_param_tlvs *)event; + if (!param_tlvs) { + wma_err("Invalid stats event"); + return -EINVAL; + } + + param_buf = param_tlvs->fixed_param; + if (!param_buf || !mac || !mac->sme.mws_coex_info_state_resp_callback) { + wma_debug("NULL mac ptr or HDD callback is null"); + return -EINVAL; + } + + if (!param_buf) { + wma_debug("NULL mws coes state event fixed param"); + return -EINVAL; + } + + coex_state.vdev_id = param_buf->vdev_id; + coex_state.coex_scheme_bitmap = param_buf->coex_scheme_bitmap; + coex_state.active_conflict_count = param_buf->active_conflict_count; + coex_state.potential_conflict_count = + param_buf->potential_conflict_count; + coex_state.chavd_group0_bitmap = param_buf->chavd_group0_bitmap; + coex_state.chavd_group1_bitmap = param_buf->chavd_group1_bitmap; + coex_state.chavd_group2_bitmap = param_buf->chavd_group2_bitmap; + coex_state.chavd_group3_bitmap = param_buf->chavd_group3_bitmap; + mac->sme.mws_coex_info_state_resp_callback(&coex_state, + mac->sme.mws_coex_info_ctx, + WMI_MWS_COEX_STATE); + wma_debug("vdev_id = %u coex_scheme_bitmap = %u active_conflict_count = %u potential_conflict_count = %u chavd_group0_bitmap = %u chavd_group1_bitmap = %u chavd_group2_bitmap = %u chavd_group3_bitmap = %u", + param_buf->vdev_id, param_buf->coex_scheme_bitmap, + param_buf->active_conflict_count, + param_buf->potential_conflict_count, + param_buf->chavd_group0_bitmap, + param_buf->chavd_group1_bitmap, + param_buf->chavd_group2_bitmap, + param_buf->chavd_group3_bitmap); + + wma_debug("Exit"); + return 0; +} + +/** + * wma_mws_coex_state_dpwb_event_handler - DPWB state Event Handler + * @handle: handle to scn + * @event: DPWB state event + * @len: Length of cmd + * + * Return: 0 on success, else error on failure + */ +static int wma_mws_coex_state_dpwb_event_handler(void *handle, uint8_t *event, + uint32_t len) +{ + WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID_param_tlvs *param_tlvs; + wmi_vdev_get_mws_coex_dpwb_state_fixed_param *param_buf; + struct mws_coex_dpwb_state coex_dpwb; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + + wma_debug("Enter"); + param_tlvs = + (WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID_param_tlvs *)event; + if (!param_tlvs) { + wma_err("Invalid coex mws event"); + return -EINVAL; + } + + param_buf = param_tlvs->fixed_param; + if (!param_buf || !mac || !mac->sme.mws_coex_info_state_resp_callback) { + wma_debug("NULL mac ptr or HDD callback is null"); + return -EINVAL; + } + + if (!param_buf) { + wma_err("NULL mws dpwb info event fixed param"); + return -EINVAL; + } + + coex_dpwb.vdev_id = param_buf->vdev_id; + coex_dpwb.current_dpwb_state = param_buf->current_dpwb_state; + coex_dpwb.pnp1_value = param_buf->pnp1_value; + coex_dpwb.lte_dutycycle = param_buf->lte_dutycycle; + coex_dpwb.sinr_wlan_on = param_buf->sinr_wlan_on; + coex_dpwb.sinr_wlan_off = param_buf->sinr_wlan_off; + coex_dpwb.bler_count = param_buf->bler_count; + coex_dpwb.block_count = param_buf->block_count; + coex_dpwb.wlan_rssi_level = param_buf->wlan_rssi_level; + coex_dpwb.wlan_rssi = param_buf->wlan_rssi; + coex_dpwb.is_tdm_running = param_buf->is_tdm_running; + mac->sme.mws_coex_info_state_resp_callback(&coex_dpwb, + mac->sme.mws_coex_info_ctx, + WMI_MWS_COEX_DPWB_STATE); + wma_debug("vdev_id = %u current_dpwb_state = %d pnp1_value = %d lte_dutycycle = %d sinr_wlan_on = %d sinr_wlan_off = %d bler_count = %u block_count = %u wlan_rssi_level = %u wlan_rssi = %d is_tdm_running = %u", + param_buf->vdev_id, param_buf->current_dpwb_state, + param_buf->pnp1_value, + param_buf->lte_dutycycle, param_buf->sinr_wlan_on, + param_buf->sinr_wlan_off, param_buf->bler_count, + param_buf->block_count, param_buf->wlan_rssi_level, + param_buf->wlan_rssi, param_buf->is_tdm_running); + + wma_debug("Exit"); + return 0; +} + +/** + * wma_mws_coex_tdm_event_handler - TDM state Event Handler + * @handle: handle to scn + * @event: TDM state event + * @len: Length of cmd + * + * Return: 0 on success, else error on failure + */ +static int wma_mws_coex_tdm_event_handler(void *handle, uint8_t *event, + uint32_t len) +{ + WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID_param_tlvs *param_tlvs; + wmi_vdev_get_mws_coex_tdm_state_fixed_param *param_buf; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + struct mws_coex_tdm_state coex_tdm; + + wma_debug("Enter"); + param_tlvs = + (WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID_param_tlvs *)event; + if (!param_tlvs) { + wma_err("Invalid MWS coex event"); + return -EINVAL; + } + + param_buf = param_tlvs->fixed_param; + if (!param_buf || !mac || !mac->sme.mws_coex_info_state_resp_callback) { + wma_debug("NULL mac ptr or HDD callback is null"); + return -EINVAL; + } + + if (!param_buf) { + wma_debug("NULL mws tdm info event fixed param"); + return -EINVAL; + } + + coex_tdm.vdev_id = param_buf->vdev_id; + coex_tdm.tdm_policy_bitmap = param_buf->tdm_policy_bitmap; + coex_tdm.tdm_sf_bitmap = param_buf->tdm_sf_bitmap; + + mac->sme.mws_coex_info_state_resp_callback(&coex_tdm, + mac->sme.mws_coex_info_ctx, + WMI_MWS_COEX_TDM_STATE); + wma_debug("vdev_id = %u tdm_policy_bitmap = %u tdm_sf_bitmap = %u", + param_buf->vdev_id, param_buf->tdm_policy_bitmap, + param_buf->tdm_sf_bitmap); + + wma_debug("Exit"); + return 0; +} + +/** + * wma_mws_coex_idrx_event_handler - IDRX state Event Handler + * @handle: handle to scn + * @event: IDRX state event + * @len: Length of cmd + * + * Return: 0 on success, else error on failure + */ +static int wma_mws_coex_idrx_event_handler(void *handle, uint8_t *event, + uint32_t len) +{ + WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID_param_tlvs *param_tlvs; + wmi_vdev_get_mws_coex_idrx_state_fixed_param *param_buf; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + struct mws_coex_idrx_state coex_idrx; + + wma_debug("Enter"); + param_tlvs = + (WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID_param_tlvs *)event; + if (!param_tlvs) { + wma_err("Invalid stats event"); + return -EINVAL; + } + + param_buf = param_tlvs->fixed_param; + if (!param_buf || !mac || !mac->sme.mws_coex_info_state_resp_callback) { + wma_debug("NULL mac ptr or HDD callback is null"); + return -EINVAL; + } + + if (!param_buf) { + wma_debug("NULL MWS Coex event fixed param"); + return -EINVAL; + } + + coex_idrx.vdev_id = param_buf->vdev_id; + coex_idrx.sub0_techid = param_buf->sub0_techid; + coex_idrx.sub0_policy = param_buf->sub0_policy; + coex_idrx.sub0_is_link_critical = param_buf->sub0_is_link_critical; + coex_idrx.sub0_static_power = param_buf->sub0_static_power; + coex_idrx.sub0_rssi = param_buf->sub0_rssi; + coex_idrx.sub1_techid = param_buf->sub1_techid; + coex_idrx.sub1_policy = param_buf->sub1_policy; + coex_idrx.sub1_is_link_critical = param_buf->sub1_is_link_critical; + coex_idrx.sub1_static_power = param_buf->sub1_static_power; + coex_idrx.sub1_rssi = param_buf->sub1_rssi; + mac->sme.mws_coex_info_state_resp_callback(&coex_idrx, + mac->sme.mws_coex_info_ctx, + WMI_MWS_COEX_IDRX_STATE); + + wma_debug("vdev_id = %u sub0_techid = %u sub0_policy = %u sub0_is_link_critical = %u sub0_static_power = %u sub0_rssi = %d sub1_techid = %d sub1_policy = %d sub1_is_link_critical = %d sub1_static_power = %u sub1_rssi= %d", + param_buf->vdev_id, param_buf->sub0_techid, + param_buf->sub0_policy, param_buf->sub0_is_link_critical, + param_buf->sub0_static_power, param_buf->sub0_rssi, + param_buf->sub1_techid, param_buf->sub1_policy, + param_buf->sub1_is_link_critical, + param_buf->sub1_static_power, param_buf->sub1_rssi); + + wma_debug("EXIT"); + return 0; +} + +/** + * wma_mws_coex_antenna_sharing_event_handler - Antenna sharing Event Handler + * @handle: handle to scn + * @event: Antenna sharing state event + * @len: Length of cmd + * + * Return: 0 on success, else error on failure + */ +static int wma_mws_coex_antenna_sharing_event_handler(void *handle, + uint8_t *event, + uint32_t len) +{ + WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID_param_tlvs + *param_tlvs = + (WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID_param_tlvs *)event; + wmi_vdev_get_mws_coex_antenna_sharing_state_fixed_param *param_buf; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + struct mws_antenna_sharing_info *antenna_sharing; + + wma_debug("Enter"); + if (!param_tlvs) { + wma_err("Invalid stats event"); + return -EINVAL; + } + + param_buf = param_tlvs->fixed_param; + if (!param_buf || !mac || !mac->sme.mws_coex_info_state_resp_callback) { + wma_debug("NULL mac ptr or HDD callback is null"); + return -EINVAL; + } + + if (!param_buf) { + wma_debug("NULL MWS event fixed param"); + return -EINVAL; + } + + antenna_sharing = qdf_mem_malloc(sizeof(*antenna_sharing)); + if (!antenna_sharing) + return -ENOMEM; + + antenna_sharing->vdev_id = param_buf->vdev_id; + antenna_sharing->coex_flags = param_buf->coex_flags; + antenna_sharing->coex_config = param_buf->coex_config; + antenna_sharing->tx_chain_mask = param_buf->tx_chain_mask; + antenna_sharing->rx_chain_mask = param_buf->rx_chain_mask; + antenna_sharing->rx_nss = param_buf->rx_nss; + antenna_sharing->force_mrc = param_buf->force_mrc; + antenna_sharing->rssi_type = param_buf->rssi_type; + antenna_sharing->chain0_rssi = param_buf->chain0_rssi; + antenna_sharing->chain1_rssi = param_buf->chain1_rssi; + antenna_sharing->combined_rssi = param_buf->combined_rssi; + antenna_sharing->imbalance = param_buf->imbalance; + antenna_sharing->mrc_threshold = param_buf->mrc_threshold; + antenna_sharing->grant_duration = param_buf->grant_duration; + + mac->sme.mws_coex_info_state_resp_callback(antenna_sharing, + mac->sme.mws_coex_info_ctx, + WMI_MWS_COEX_ANTENNA_SHARING_STATE); + wma_debug("vdev_id = %u coex_flags = %u coex_config = %u tx_chain_mask = %u rx_chain_mask = %u rx_nss = %u force_mrc = %u rssi_type = %u chain0_rssi = %d chain1_rssi = %d chain0_rssi = %d imbalance = %u mrc_threshold = %d grant_duration = %u", + param_buf->vdev_id, param_buf->coex_flags, + param_buf->coex_config, param_buf->tx_chain_mask, + param_buf->rx_chain_mask, + param_buf->rx_nss, param_buf->force_mrc, + param_buf->rssi_type, param_buf->chain0_rssi, + param_buf->chain1_rssi, param_buf->combined_rssi, + param_buf->imbalance, param_buf->mrc_threshold, + param_buf->grant_duration); + + qdf_mem_free(antenna_sharing); + wma_debug("EXIT"); + return 0; +} + +void wma_get_mws_coex_info_req(tp_wma_handle wma_handle, + struct sir_get_mws_coex_info *req) +{ + QDF_STATUS status; + + status = wmi_unified_send_mws_coex_req_cmd(wma_handle->wmi_handle, + req->vdev_id, req->cmd_id); + + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("Failed to send mws coex info"); +} + +void wma_register_mws_coex_events(tp_wma_handle wma_handle) +{ + if (!wma_handle) { + wma_err("wma_handle is NULL"); + return; + } + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + wmi_vdev_get_mws_coex_state_eventid, + wma_mws_coex_state_host_event_handler, + WMA_RX_SERIALIZER_CTX); + + wmi_unified_register_event_handler( + wma_handle->wmi_handle, + wmi_vdev_get_mws_coex_dpwb_state_eventid, + wma_mws_coex_state_dpwb_event_handler, + WMA_RX_SERIALIZER_CTX); + + wmi_unified_register_event_handler( + wma_handle->wmi_handle, + wmi_vdev_get_mws_coex_tdm_state_eventid, + wma_mws_coex_tdm_event_handler, + WMA_RX_SERIALIZER_CTX); + + wmi_unified_register_event_handler( + wma_handle->wmi_handle, + wmi_vdev_get_mws_coex_idrx_state_eventid, + wma_mws_coex_idrx_event_handler, + WMA_RX_SERIALIZER_CTX); + + wmi_unified_register_event_handler( + wma_handle->wmi_handle, + wmi_vdev_get_mws_coex_antenna_sharing_state_eventid, + wma_mws_coex_antenna_sharing_event_handler, + WMA_RX_SERIALIZER_CTX); +} diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 6b5e9a9fbf6f..4710127d4fc2 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -96,6 +96,7 @@ #include "cfg_ucfg_api.h" #include "init_cmd_api.h" #include "nan_ucfg_api.h" +#include "wma_coex.h" #define WMA_LOG_COMPLETION_TIMER 3000 /* 3 seconds */ #define WMI_TLV_HEADROOM 128 @@ -3719,7 +3720,7 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_register_apf_events(wma_handle); wma_register_md_events(wma_handle); wma_register_wlm_stats_events(wma_handle); - + wma_register_mws_coex_events(wma_handle); return QDF_STATUS_SUCCESS; err_dbglog_init: @@ -9031,6 +9032,12 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) qdf_mem_free(msg->bodyptr); break; #endif /* FW_THERMAL_THROTTLE_SUPPORT */ +#ifdef WLAN_MWS_INFO_DEBUGFS + case WMA_GET_MWS_COEX_INFO_REQ: + wma_get_mws_coex_info_req(wma_handle, msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; +#endif default: WMA_LOGD("Unhandled WMA message of type %d", msg->type); if (msg->bodyptr)