From 4853c40d313e987bfa1576962e6fd3a73b529723 Mon Sep 17 00:00:00 2001 From: guangde Date: Mon, 6 May 2019 15:54:04 +0800 Subject: [PATCH] qcacld-3.0: Add get antenna isolation command Propagation from qcacld2.0 to qcacld3.0. The WMI CMD and EVENT of "get antenna isolation" are already defined, but not used before in qcacld3.0. Now, The host driver uses vendor command to get this information instead of iwpriv command in qcacld-2.0. The attribution of this feature is already defined in file "qca_vendor.h". The name is "QCA_WLAN_VENDOR_ATTR_ANTENNA_ISOLATION". So host driver will use vendor command "QCA_NL80211_VENDOR_SUBCMD_GET_HW_CAPABILITY" to get the information from lower layer. Change-Id: I915768f622ddc9a70a95ce4fe952f19917a8f901 CRs-Fixed: 2447360 --- Kbuild | 7 + configs/default_defconfig | 5 + configs/qcs40x.snoc.perf_defconfig | 1 + core/hdd/inc/wlan_hdd_main.h | 2 + core/hdd/src/wlan_hdd_cfg80211.c | 2 + core/hdd/src/wlan_hdd_hw_capability.c | 212 ++++++++++++++++++ core/hdd/src/wlan_hdd_hw_capability.h | 58 +++++ core/mac/inc/sir_api.h | 14 ++ core/mac/inc/wni_api.h | 3 +- core/mac/src/include/sir_params.h | 2 + .../src/sys/legacy/src/utils/src/mac_trace.c | 1 + core/sme/inc/sme_api.h | 14 ++ core/sme/inc/sme_internal.h | 11 + core/sme/src/common/sme_api.c | 41 ++++ core/wma/inc/wma_internal.h | 10 + core/wma/inc/wma_types.h | 2 + core/wma/src/wma_features.c | 40 ++++ core/wma/src/wma_main.c | 72 ++++++ 18 files changed, 496 insertions(+), 1 deletion(-) create mode 100644 core/hdd/src/wlan_hdd_hw_capability.c create mode 100644 core/hdd/src/wlan_hdd_hw_capability.h diff --git a/Kbuild b/Kbuild index ef00a964398e..f292fa7a4c69 100644 --- a/Kbuild +++ b/Kbuild @@ -245,6 +245,10 @@ ifeq ($(CONFIG_WLAN_BCN_RECV_FEATURE), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_bcn_recv.o endif +ifeq ($(CONFIG_QCACLD_FEATURE_HW_CAPABILITY), y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_hw_capability.o +endif + ###### OSIF_SYNC ######## SYNC_DIR := os_if/sync SYNC_INC_DIR := $(SYNC_DIR)/inc @@ -2607,6 +2611,9 @@ cppflags-$(CONFIG_QCACLD_FEATURE_COEX_CONFIG) += -DFEATURE_COEX_CONFIG #Flag to enable MPTA helper feature cppflags-$(CONFIG_QCACLD_FEATURE_MPTA_HELPER) += -DFEATURE_MPTA_HELPER +#Flag to enable get hw capability +cppflags-$(CONFIG_QCACLD_FEATURE_HW_CAPABILITY) += -DFEATURE_HW_CAPABILITY + cppflags-$(CONFIG_DATA_CE_SW_INDEX_NO_INLINE_UPDATE) += -DDATA_CE_SW_INDEX_NO_INLINE_UPDATE #Flag to enable Multi page memory allocation for RX descriptor pool diff --git a/configs/default_defconfig b/configs/default_defconfig index 36b847b99859..a8cf80820011 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -129,6 +129,11 @@ CONFIG_QCACLD_FEATURE_FW_STATE := y #Flag to enable set coex configuration CONFIG_QCACLD_FEATURE_COEX_CONFIG := n +#Flag to enable get hw capability +ifeq ($(CONFIG_ARCH_QCS405), y) +CONFIG_QCACLD_FEATURE_HW_CAPABILITY := y +endif + ifeq ($(CONFIG_ARCH_MSM8998), y) CONFIG_QCACLD_FEATURE_METERING := y endif diff --git a/configs/qcs40x.snoc.perf_defconfig b/configs/qcs40x.snoc.perf_defconfig index d03795e28f35..82b50fdf917b 100644 --- a/configs/qcs40x.snoc.perf_defconfig +++ b/configs/qcs40x.snoc.perf_defconfig @@ -102,6 +102,7 @@ CONFIG_PTT_SOCK_SVC_ENABLE := y CONFIG_WMI_INTERFACE_EVENT_LOGGING := y CONFIG_WLAN_FEATURE_LINK_LAYER_STATS := y CONFIG_DP_TRACE := n +CONFIG_QCACLD_FEATURE_HW_CAPABILITY := y CONFIG_WLAN_LOG_FATAL := y CONFIG_WLAN_LOG_ERROR := y diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index b42417feff90..244721793769 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -237,6 +237,8 @@ enum hdd_driver_flags { #define WLAN_WAIT_TIME_FW_ROAM_STATS 1000 +#define WLAN_WAIT_TIME_ANTENNA_ISOLATION 8000 + /* Maximum time(ms) to wait for RSO CMD status event */ #define WAIT_TIME_RSO_CMD_STATUS 2000 diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 1258b3a46fa7..7c7bcbbca323 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -142,6 +142,7 @@ #include "wlan_hdd_coex_config.h" #include "wlan_hdd_bcn_recv.h" #include "wlan_blm_ucfg_api.h" +#include "wlan_hdd_hw_capability.h" #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -13139,6 +13140,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { FEATURE_FW_STATE_COMMANDS FEATURE_COEX_CONFIG_COMMANDS FEATURE_MPTA_HELPER_COMMANDS + FEATURE_HW_CAPABILITY_COMMANDS }; struct hdd_context *hdd_cfg80211_wiphy_alloc(void) diff --git a/core/hdd/src/wlan_hdd_hw_capability.c b/core/hdd/src/wlan_hdd_hw_capability.c new file mode 100644 index 000000000000..9898c6a6e491 --- /dev/null +++ b/core/hdd/src/wlan_hdd_hw_capability.c @@ -0,0 +1,212 @@ +/* + * 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_hw_capability.c + * + * The implementation of get hw capability + * + */ + +#include "wlan_hdd_main.h" +#include "wmi_unified_param.h" +#include "wlan_hdd_hw_capability.h" +#include "qca_vendor.h" +#include "wlan_osif_request_manager.h" +#include "osif_sync.h" + +/** + * hdd_get_isolation_cb - Callback function to get isolation information + * @context: opaque context originally passed to SME. HDD always passes + * a cookie for the request context + * @isolation: pointer of isolation information + * + * This function will fill isolation information to isolation priv adapter + * + * Return: None + */ +static void hdd_get_isolation_cb(struct sir_isolation_resp *isolation, + void *context) +{ + struct osif_request *request; + struct sir_isolation_resp *priv; + + if (!isolation) { + hdd_err("Bad param"); + return; + } + + request = osif_request_get(context); + if (!request) { + hdd_err("Obsolete request"); + return; + } + + priv = osif_request_priv(request); + priv->isolation_chain0 = isolation->isolation_chain0; + priv->isolation_chain1 = isolation->isolation_chain1; + priv->isolation_chain2 = isolation->isolation_chain2; + priv->isolation_chain3 = isolation->isolation_chain3; + + osif_request_complete(request); + osif_request_put(request); +} + +/** + * hdd_post_isolation - send rsp to user space + * @hdd_ctx: pointer to hdd context + * @isolation: antenna isolation information + * + * Return: 0 for success, non-zero for failure + */ +static int hdd_post_isolation(struct hdd_context *hdd_ctx, + struct sir_isolation_resp *isolation) +{ + struct sk_buff *skb; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, + (sizeof(u8) + NLA_HDRLEN) + + (sizeof(u8) + NLA_HDRLEN) + + (sizeof(u8) + NLA_HDRLEN) + + (sizeof(u8) + NLA_HDRLEN) + + NLMSG_HDRLEN); + + if (!skb) { + hdd_err("cfg80211_vendor_event_alloc failed"); + return -ENOMEM; + } + + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_ISOLATION, + isolation->isolation_chain0)) { + hdd_err("put fail"); + goto nla_put_failure; + } + + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_ISOLATION, + isolation->isolation_chain1)) { + hdd_err("put fail"); + goto nla_put_failure; + } + + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_ISOLATION, + isolation->isolation_chain2)) { + hdd_err("put fail"); + goto nla_put_failure; + } + + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_ISOLATION, + isolation->isolation_chain3)) { + hdd_err("put fail"); + goto nla_put_failure; + } + + cfg80211_vendor_cmd_reply(skb); + return 0; + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +/** + * __wlan_hdd_cfg80211_get_hw_capability() - get hw capability + * @wiphy: wiphy device pointer + * @wdev: wireless device pointer + * @data: Vendor command data buffer + * @data_len: Buffer length + * + * Return: 0 on success; error number otherwise. + * + */ +static int __wlan_hdd_cfg80211_get_hw_capability(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct osif_request *request; + struct sir_isolation_resp *priv; + mac_handle_t mac_handle; + void *cookie; + QDF_STATUS status; + int ret; + static const struct osif_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_ANTENNA_ISOLATION, + }; + + hdd_enter(); + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + if (wlan_hdd_validate_context(hdd_ctx)) + return -EINVAL; + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return -ENOMEM; + } + + cookie = osif_request_cookie(request); + + mac_handle = hdd_ctx->mac_handle; + status = sme_get_isolation(mac_handle, + cookie, + hdd_get_isolation_cb); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Unable to retrieve isolation"); + ret = -EFAULT; + } else { + ret = osif_request_wait_for_response(request); + if (ret) { + hdd_err("SME timed out while retrieving isolation"); + ret = -ETIMEDOUT; + } else { + priv = osif_request_priv(request); + hdd_post_isolation(hdd_ctx, priv); + ret = 0; + } + } + osif_request_put(request); + + return ret; +} + +int wlan_hdd_cfg80211_get_hw_capability(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_get_hw_capability(wiphy, wdev, + data, data_len); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} diff --git a/core/hdd/src/wlan_hdd_hw_capability.h b/core/hdd/src/wlan_hdd_hw_capability.h new file mode 100644 index 000000000000..0cbdc071a54a --- /dev/null +++ b/core/hdd/src/wlan_hdd_hw_capability.h @@ -0,0 +1,58 @@ +/* + * 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_hw_capability.h + * + * Add Vendor subcommand QCA_NL80211_VENDOR_SUBCMD_GET_HW_CAPABILITY + */ + +#ifndef __WLAN_HDD_HW_CAPABILITY_H +#define __WLAN_HDD_HW_CAPABILITY_H + +#ifdef FEATURE_HW_CAPABILITY +#include + +/** + * wlan_hdd_cfg80211_get_hw_capability() - get hardware capability + * @wiphy: wiphy device pointer + * @wdev: wireless device pointer + * @data: Vendor command data buffer + * @data_len: Buffer length + * + * Return: 0 on success; error number otherwise. + */ +int wlan_hdd_cfg80211_get_hw_capability(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + +#define FEATURE_HW_CAPABILITY_COMMANDS \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_HW_CAPABILITY,\ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_NETDEV | \ + WIPHY_VENDOR_CMD_NEED_RUNNING, \ + .doit = wlan_hdd_cfg80211_get_hw_capability \ +}, +#else /* FEATURE_HW_CAPABILITY */ +#define FEATURE_HW_CAPABILITY_COMMANDS +#endif /* FEATURE_HW_CAPABILITY */ + +#endif /* __WLAN_HDD_HW_CAPABILITY_H */ diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 34fc7e46cc53..970440e0a7e7 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -2712,6 +2712,20 @@ struct sir_peer_sta_ext_info { struct sir_peer_info_ext info[MAX_PEER_STA]; }; +/** + * struct sir_isolation_resp - isolation info related structure + * @isolation_chain0: isolation value for chain 0 + * @isolation_chain1: isolation value for chain 1 + * @isolation_chain2: isolation value for chain 2 + * @isolation_chain3: isolation value for chain 3 + */ +struct sir_isolation_resp { + uint32_t isolation_chain0:8, + isolation_chain1:8, + isolation_chain2:8, + isolation_chain3:8; +}; + typedef struct sSirAddPeriodicTxPtrn { /* MAC Address for the adapter */ struct qdf_mac_addr mac_address; diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index a31ae81fc496..2789f493edb0 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -238,7 +238,8 @@ enum eWniMsgTypes { eWNI_SME_FW_STATUS_IND = SIR_SME_MSG_TYPES_BEGIN + 152, eWNI_SME_STA_CSA_CONTINUE_REQ = SIR_SME_MSG_TYPES_BEGIN + 153, WNI_SME_REGISTER_BCN_REPORT_SEND_CB = SIR_SME_MSG_TYPES_BEGIN + 154, - eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 155 + eWNI_SME_ANTENNA_ISOLATION_RSP = SIR_SME_MSG_TYPES_BEGIN + 155, + eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 156 }; typedef struct sAniCfgTxRateCtrs { diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 07569e8c90c3..d5bdd1fcf93a 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -663,6 +663,8 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_SEND_PEER_UNMAP_CONF (SIR_HAL_ITC_MSG_TYPES_BEGIN + 411) +#define SIR_HAL_GET_ISOLATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 412) + #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) /* LIM message types */ diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 71fe945836ca..43b56d29c6f6 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -370,6 +370,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END); CASE_RETURN_STRING(eWNI_SME_HIDDEN_SSID_RESTART_RSP); CASE_RETURN_STRING(eWNI_SME_STA_CSA_CONTINUE_REQ); + CASE_RETURN_STRING(eWNI_SME_ANTENNA_ISOLATION_RSP); default: return (uint8_t *) "UNKNOWN"; break; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 8e2d860550dd..25cade9ae04f 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -2271,6 +2271,20 @@ QDF_STATUS sme_get_chain_rssi(mac_handle_t mac_handle, get_chain_rssi_callback callback, void *context); +/** + * sme_get_isolation() - sme api to get antenna isolation + * @mac_handle: hal handle for getting global mac struct + * @context: context of callback function + * @callbackfn: hdd callback function when receive response + * + * This function will send WMA_GET_ISOLATION to WMA + * + * Return: QDF_STATUS_SUCCESS or non-zero on failure + */ +QDF_STATUS sme_get_isolation(mac_handle_t mac_handle, + void *context, + sme_get_isolation_cb callbackfn); + #ifdef FEATURE_FW_STATE /** * sme_get_fw_state() - Get fw state diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 59fbb1c055a2..7f8f150af9df 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -277,6 +277,15 @@ typedef void (*beacon_pause_cb)(hdd_handle_t hdd_handle, enum scan_event_type type, bool is_disconnected); +/** + * typedef sme_get_isolation_cb - get isolation callback fun + * @param: isolation result reported by firmware + * @pcontext: Opaque context that the client can use to associate the + * callback with the request + */ +typedef void (*sme_get_isolation_cb)(struct sir_isolation_resp *param, + void *pcontext); + #ifdef WLAN_FEATURE_MOTION_DETECTION typedef QDF_STATUS (*md_host_evt_cb)(void *hdd_ctx, struct sir_md_evt *event); #endif /* WLAN_FEATURE_MOTION_DETECTION */ @@ -325,6 +334,8 @@ struct sme_context { void (*pget_peer_info_ext_ind_cb)(struct sir_peer_info_ext_resp *param, void *pcontext); void *pget_peer_info_ext_cb_context; + sme_get_isolation_cb get_isolation_cb; + void *get_isolation_cb_context; #ifdef FEATURE_WLAN_EXTSCAN ext_scan_ind_cb ext_scan_ind_cb; #endif /* FEATURE_WLAN_EXTSCAN */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 8392012c8bf7..8613c9ff5c16 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2264,6 +2264,17 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) else sme_err("callback is NULL"); break; + case eWNI_SME_ANTENNA_ISOLATION_RSP: + if (pMsg->bodyptr) { + if (mac->sme.get_isolation_cb) + mac->sme.get_isolation_cb( + (struct sir_isolation_resp *)pMsg->bodyptr, + mac->sme.get_isolation_cb_context); + qdf_mem_free(pMsg->bodyptr); + } else { + sme_err("Empty message for: %d", pMsg->type); + } + break; default: if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN) @@ -7567,6 +7578,36 @@ QDF_STATUS sme_get_peer_info_ext(mac_handle_t mac_handle, return status; } +QDF_STATUS sme_get_isolation(mac_handle_t mac_handle, void *context, + sme_get_isolation_cb callbackfn) +{ + QDF_STATUS status; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + struct scheduler_msg message = {0}; + + if (!callbackfn) { + sme_err("Indication Call back is NULL"); + return QDF_STATUS_E_FAILURE; + } + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(status)) + return status; + mac->sme.get_isolation_cb = callbackfn; + mac->sme.get_isolation_cb_context = context; + message.bodyptr = NULL; + message.type = WMA_GET_ISOLATION; + status = scheduler_post_message(QDF_MODULE_ID_SME, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, + &message); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_err("failed to post WMA_GET_ISOLATION"); + status = QDF_STATUS_E_FAILURE; + } + sme_release_global_lock(&mac->sme); + return status; +} + /*convert the ini value to the ENUM used in csr and MAC for CB state*/ ePhyChanBondState sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value) { diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 0e37064f5346..bad0b9577444 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1060,6 +1060,16 @@ QDF_STATUS wma_get_peer_info(WMA_HANDLE handle, QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle, struct sir_peer_info_ext_req *peer_info_req); +/** + * wma_get_isolation() - get antenna isolation + * @handle: wma interface + * + * This function will send WMI_COEX_GET_ANTENNA_ISOLATION_CMDID to FW + * + * Return: 0 on success, otherwise error value + */ +QDF_STATUS wma_get_isolation(tp_wma_handle wma); + /** * wma_peer_info_event_handler() - Handler for WMI_PEER_STATS_INFO_EVENTID * @handle: WMA global handle diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index c8fc52e3215d..7a620ddc09cc 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -336,6 +336,8 @@ #define WMA_GET_PEER_INFO SIR_HAL_GET_PEER_INFO #define WMA_GET_PEER_INFO_EXT SIR_HAL_GET_PEER_INFO_EXT +#define WMA_GET_ISOLATION SIR_HAL_GET_ISOLATION + #define WMA_MODEM_POWER_STATE_IND SIR_HAL_MODEM_POWER_STATE_IND #ifdef WLAN_FEATURE_STATS_EXT diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index ad0e6d6b4ff2..79b45f6d52c0 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -901,6 +901,46 @@ QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle, return QDF_STATUS_SUCCESS; } +QDF_STATUS wma_get_isolation(tp_wma_handle wma) +{ + wmi_coex_get_antenna_isolation_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len; + uint8_t *buf_ptr; + + WMA_LOGD("%s: get isolation", __func__); + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue get isolation", + __func__); + return QDF_STATUS_E_INVAL; + } + + len = sizeof(wmi_coex_get_antenna_isolation_cmd_fixed_param); + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return QDF_STATUS_E_NOMEM; + } + buf_ptr = (uint8_t *)wmi_buf_data(wmi_buf); + + cmd = (wmi_coex_get_antenna_isolation_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR( + &cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_coex_get_antenna_isolation_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_coex_get_antenna_isolation_cmd_fixed_param)); + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_COEX_GET_ANTENNA_ISOLATION_CMDID)) { + WMA_LOGE("Failed to get isolation request from fw"); + wmi_buf_free(wmi_buf); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + /** * wma_add_beacon_filter() - Issue WMI command to set beacon filter * @wma: wma handler diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 295a9946d346..82a0bbb3b691 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -1818,6 +1818,69 @@ int wma_process_fw_event_handler(ol_scn_t scn_handle, void *evt_buf, return err; } +/** + * wma_antenna_isolation_event_handler() - antenna isolation event handler + * @handle: wma handle + * @param: event data + * @len: length + * + * Return: 0 for success or error code + */ +static int wma_antenna_isolation_event_handler(void *handle, + u8 *param, + u32 len) +{ + struct scheduler_msg cds_msg = {0}; + wmi_coex_report_isolation_event_fixed_param *event; + WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID_param_tlvs *param_buf; + struct sir_isolation_resp *pisolation; + struct mac_context *mac = NULL; + + WMA_LOGD("%s: handle %pK param %pK len %d", __func__, + handle, param, len); + + mac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE); + if (!mac) { + WMA_LOGE("%s: Invalid mac context", __func__); + return -EINVAL; + } + + pisolation = qdf_mem_malloc(sizeof(*pisolation)); + if (!pisolation) + return 0; + + param_buf = + (WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID_param_tlvs *)param; + if (!param_buf) { + WMA_LOGE("%s: Invalid isolation event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + pisolation->isolation_chain0 = event->isolation_chain0; + pisolation->isolation_chain1 = event->isolation_chain1; + pisolation->isolation_chain2 = event->isolation_chain2; + pisolation->isolation_chain3 = event->isolation_chain3; + + WMA_LOGD("%s: chain1 %d chain2 %d chain3 %d chain4 %d", __func__, + pisolation->isolation_chain0, pisolation->isolation_chain1, + pisolation->isolation_chain2, pisolation->isolation_chain3); + + cds_msg.type = eWNI_SME_ANTENNA_ISOLATION_RSP; + cds_msg.bodyptr = pisolation; + cds_msg.bodyval = 0; + if (QDF_STATUS_SUCCESS != + scheduler_post_message(QDF_MODULE_ID_WMA, + QDF_MODULE_ID_SME, + QDF_MODULE_ID_SME, &cds_msg)) { + WMA_LOGE("%s: could not post peer info rsp msg to SME", + __func__); + /* free the mem and return */ + qdf_mem_free(pisolation); + } + + return 0; +} + /** * wma_init_max_no_of_peers - API to initialize wma configuration params * @wma_handle: WMA Handle @@ -3632,6 +3695,12 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_rx_aggr_failure_event_handler, WMA_RX_SERIALIZER_CTX); + wmi_unified_register_event_handler( + wma_handle->wmi_handle, + wmi_coex_report_antenna_isolation_event_id, + wma_antenna_isolation_event_handler, + WMA_RX_SERIALIZER_CTX); + wma_handle->ito_repeat_count = cds_cfg->ito_repeat_count; wma_handle->bandcapability = cds_cfg->bandcapability; @@ -8726,6 +8795,9 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) wma_get_peer_info_ext(wma_handle, msg->bodyptr); qdf_mem_free(msg->bodyptr); break; + case WMA_GET_ISOLATION: + wma_get_isolation(wma_handle); + break; case WMA_MODEM_POWER_STATE_IND: wma_notify_modem_power_state(wma_handle, (tSirModemPowerStateInd *) msg->bodyptr);