浏览代码

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
guangde 5 年之前
父节点
当前提交
4853c40d31

+ 7 - 0
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

+ 5 - 0
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

+ 1 - 0
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

+ 2 - 0
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
 

+ 2 - 0
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)

+ 212 - 0
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(&params);
+	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;
+}

+ 58 - 0
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 <net/cfg80211.h>
+
+/**
+ * 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 */

+ 14 - 0
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;

+ 2 - 1
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 {

+ 2 - 0
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 */

+ 1 - 0
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;

+ 14 - 0
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

+ 11 - 0
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 */

+ 41 - 0
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)
 {

+ 10 - 0
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

+ 2 - 0
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

+ 40 - 0
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

+ 72 - 0
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);