summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornakul kachhwaha <nkachh@codeaurora.org>2017-01-18 16:00:41 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-04-26 05:51:16 -0700
commit344e641707dac46705eb7026d01e900615d1a033 (patch)
treedc0473e65db05a9778f4c25364896c24c0035ffe
parent1eeddf8238b3f025b492dd414e23424e1e4cdcf0 (diff)
qcacld-2.0: Requirement to add iwpriv command to get antenna isolation
Added the code to fetch the isolation value from HW using iwpriv Change-Id: I0892b6dbbb78104172a3e95e9c862e05bd7dd037 CRs-Fixed: 1112419
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h1
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c172
-rw-r--r--CORE/MAC/inc/sirApi.h7
-rw-r--r--CORE/MAC/src/include/sirParams.h2
-rw-r--r--CORE/SERVICES/WMA/wma.c87
-rw-r--r--CORE/SME/inc/smeInternal.h3
-rw-r--r--CORE/SME/inc/sme_Api.h5
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c39
-rw-r--r--CORE/SYS/legacy/src/utils/src/macTrace.c1
-rw-r--r--CORE/WDA/inc/wlan_qct_wda.h2
10 files changed, 316 insertions, 3 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 0425476ac21e..cfce715f53a5 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -367,6 +367,7 @@ extern spinlock_t hdd_context_lock;
#define POWER_STATS_MAGIC 0x14111990
#define BPF_CONTEXT_MAGIC 0x4575354 /* BPF */
#define ACTION_FRAME_RANDOM_CONTEXT_MAGIC 0x87878787
+#define ISOLATION_CONTEXT_MAGIC 0x48575354 //Antenna Isolation
#ifdef QCA_LL_TX_FLOW_CT
/* MAX OS Q block time value in msec
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 094c2619b479..974dc8bc7ed0 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -414,7 +414,8 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WE_GET_TSF 1
/* (SIOCIWFIRSTPRIV + 17) is currently unused */
-/* (SIOCIWFIRSTPRIV + 19) is currently unused */
+
+#define WLAN_GET_ISOLATION (SIOCIWFIRSTPRIV + 19)
#ifdef WLAN_FEATURE_VOWIFI_11R
#define WLAN_PRIV_SET_FTIES (SIOCIWFIRSTPRIV + 20)
@@ -4089,6 +4090,167 @@ static int iw_get_linkspeed_priv(struct net_device *dev,
return ret;
}
+void hdd_get_isolation_cb(struct sir_isolation_resp *isolation,
+ void *context)
+{
+ struct statsContext *isolation_context;
+ int buf = 0;
+ int length = 0;
+ char *isolation_output;
+ union iwreq_data *wrqu;
+
+ if ((NULL == isolation) || (NULL == context)) {
+
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: Bad param, %s",
+ __func__,
+ isolation ? "context is NULL" : "isolation is NULL");
+ return;
+ }
+
+ spin_lock(&hdd_context_lock);
+
+ isolation_context = context;
+ if (ISOLATION_CONTEXT_MAGIC !=
+ isolation_context->magic) {
+
+ /*
+ * the caller presumably timed out so there is nothing
+ * we can do
+ */
+ spin_unlock(&hdd_context_lock);
+ hddLog(VOS_TRACE_LEVEL_WARN,
+ "%s: Invalid context, magic [%08x]",
+ __func__,
+ isolation_context->magic);
+ return;
+ }
+
+ isolation_output = isolation_context->extra;
+ wrqu = isolation_context->wrqu;
+ isolation_context->magic = 0;
+
+ hddLog(LOG1, "%s: chain1 %d chain2 %d chain3 %d chain4 %d", __func__,
+ isolation->isolation_chain0, isolation->isolation_chain1,
+ isolation->isolation_chain2, isolation->isolation_chain3);
+
+ length = scnprintf((isolation_output), WE_MAX_STR_LEN, "\n");
+ buf = scnprintf
+ (
+ (isolation_output + length), WE_MAX_STR_LEN - length,
+ "isolation chain 0 : %d\n",
+ isolation->isolation_chain0
+ );
+ length += buf;
+ buf = scnprintf
+ (
+ (isolation_output + length), WE_MAX_STR_LEN - length,
+ "isolation chain 1 : %d\n",
+ isolation->isolation_chain1
+ );
+ length += buf;
+ buf = scnprintf
+ (
+ (isolation_output + length), WE_MAX_STR_LEN - length,
+ "isolation chain 2 : %d\n",
+ isolation->isolation_chain2
+ );
+ length += buf;
+ buf = scnprintf
+ (
+ (isolation_output + length), WE_MAX_STR_LEN - length,
+ "isolation chain 3 : %d\n",
+ isolation->isolation_chain3
+ );
+ length += buf;
+
+ wrqu->data.length = length + 1;
+
+ /* notify the caller */
+ complete(&isolation_context->completion);
+
+ /* serialization is complete */
+ spin_unlock(&hdd_context_lock);
+}
+
+static int wlan_hdd_get_isolation(hdd_adapter_t *adapter,
+ union iwreq_data *wrqu, char *extra)
+{
+ eHalStatus hstatus;
+ int ret;
+ struct statsContext context;
+
+ if (NULL == adapter) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL",
+ __func__);
+ return -EINVAL;
+ }
+
+ init_completion(&context.completion);
+ context.magic = ISOLATION_CONTEXT_MAGIC;
+ context.extra = extra;
+ context.wrqu = wrqu;
+
+ hstatus = sme_get_isolation(WLAN_HDD_GET_HAL_CTX(adapter),
+ &context,
+ hdd_get_isolation_cb);
+ if (eHAL_STATUS_SUCCESS != hstatus) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: Unable to retrieve isolation",
+ __func__);
+ ret = -EFAULT;
+ } else {
+ if (!wait_for_completion_timeout(&context.completion,
+ msecs_to_jiffies(8000))) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: SME timed out while retrieving isolation",
+ __func__);
+ ret = -ETIMEDOUT;
+ } else
+ ret = 0;
+ }
+
+ spin_lock(&hdd_context_lock);
+ context.magic = 0;
+ spin_unlock(&hdd_context_lock);
+ return ret;
+}
+
+static int __iw_get_isolation(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *hdd_ctx;
+ int ret;
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret)
+ return ret;
+
+ ret = wlan_hdd_get_isolation(adapter, wrqu, extra);
+
+ if (ret < 0)
+ return ret;
+
+ /* a value is being successfully returned */
+ return 0;
+}
+
+static int iw_get_isolation(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __iw_get_isolation(dev, info, wrqu, extra);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+
VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode)
{
struct statsContext context;
@@ -11326,6 +11488,7 @@ static const iw_handler we_private[] = {
[WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed_priv,
[WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_two_ints_getnone,
[WLAN_SET_DOT11P_CHANNEL_SCHED - SIOCIWFIRSTPRIV] = iw_set_dot11p_channel_sched,
+ [WLAN_GET_ISOLATION - SIOCIWFIRSTPRIV] = iw_get_isolation,
};
/*Maximum command length can be only 15 */
@@ -12389,7 +12552,12 @@ static const struct iw_priv_args we_private_args[] = {
WLAN_GET_LINK_SPEED,
IW_PRIV_TYPE_CHAR | 18,
IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
-
+ {
+ WLAN_GET_ISOLATION,
+ 0,
+ IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+ "get_isolation"
+ },
/* handlers for main ioctl */
{ WLAN_PRIV_SET_TWO_INT_GET_NONE,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index ae379bb50707..87c457fefc04 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -4903,6 +4903,13 @@ struct sir_peer_info_ext_resp {
struct sir_peer_info_ext info[0];
};
+struct sir_isolation_resp {
+ uint32_t isolation_chain0:8, //[7:0], isolation value for chain 0
+ isolation_chain1:8, //[15:8], isolation value for chain 1
+ isolation_chain2:8, //[23:16], isolation value for chain 2
+ isolation_chain3:8; //[31:24], isolation value for chain 3
+};
+
typedef struct sSirAddPeriodicTxPtrn
{
/* MAC Address for the adapter */
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index b8e957f689a8..a664520a1236 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -539,7 +539,7 @@ typedef struct sSirMbMsgP2p
#define SIR_HAL_SMPS_FORCE_MODE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 220)
-/* 221 unused */
+#define SIR_HAL_GET_ISOLATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 221)
#define SIR_HAL_START_ROAM_CANDIDATE_LOOKUP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 222)
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index aaa20d729ded..a83ff41c214f 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -8497,6 +8497,46 @@ wma_register_extscan_event_handler(tp_wma_handle wma_handle)
}
+static int wma_antenna_isolation_event_handler(void *handle,
+ u_int8_t *param, u_int32_t len)
+{
+ tp_wma_handle wma = (tp_wma_handle)handle;
+ wmi_coex_report_isolation_event_fixed_param *event;
+ WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID_param_tlvs *param_buf;
+ struct sir_isolation_resp isolation;
+ tpAniSirGlobal mac = NULL;
+ WMA_LOGE("%s: handle %p param %p len %d", __func__, handle, param, len);
+
+ if(wma != NULL && wma->vos_context != NULL) {
+ mac = (tpAniSirGlobal)vos_get_context(
+ VOS_MODULE_ID_PE, wma->vos_context);
+ }
+ if (!mac) {
+ WMA_LOGE("%s: Invalid mac context", __func__);
+ return -EINVAL;
+ }
+
+ 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;
+ isolation.isolation_chain0 = event->isolation_chain0;
+ isolation.isolation_chain1 = event->isolation_chain1;
+ isolation.isolation_chain2 = event->isolation_chain2;
+ isolation.isolation_chain3 = event->isolation_chain3;
+
+ printk("\n*********************ANTENNA ISOLATION********************\n");
+
+ WMA_LOGD("%s: chain1 %d chain2 %d chain3 %d chain4 %d", __func__,
+ isolation.isolation_chain0, isolation.isolation_chain1,
+ isolation.isolation_chain2, isolation.isolation_chain3);
+ mac->sme.get_isolation(&isolation, mac->sme.get_isolation_cb_context);
+ return 0;
+}
+
void wma_wow_tx_complete(void *wma)
{
tp_wma_handle wma_handle = (tp_wma_handle)wma;
@@ -9212,6 +9252,10 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID,
wma_chip_power_save_failure_detected_handler);
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID,
+ wma_antenna_isolation_event_handler);
+
wma_register_debug_callback();
wma_ndp_register_all_event_handlers(wma_handle);
@@ -32832,6 +32876,46 @@ wma_process_action_frame_random_mac(tp_wma_handle wma_handle,
return VOS_STATUS_SUCCESS;
}
+static VOS_STATUS wma_get_isolation(tp_wma_handle wma)
+{
+ tp_wma_handle wma_handle = (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_LOGE("%s: get isolation",
+ __func__);
+
+ if (!wma_handle || !wma_handle->wmi_handle) {
+ WMA_LOGE("%s: WMA is closed, can not issue get isolation",
+ __func__);
+ return VOS_STATUS_E_INVAL;
+ }
+
+ len = sizeof(wmi_coex_get_antenna_isolation_cmd_fixed_param);
+ wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+ if (!wmi_buf) {
+ WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
+ return VOS_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_handle->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 VOS_STATUS_E_FAILURE;
+ }
+
+ return VOS_STATUS_SUCCESS;
+}
+
/*
* function : wma_mc_process_msg
* Description :
@@ -33762,6 +33846,9 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
(struct action_frame_random_filter *)msg->bodyptr);
vos_mem_free(msg->bodyptr);
break;
+ case WDA_GET_ISOLATION:
+ wma_get_isolation(wma_handle);
+ break;
default:
WMA_LOGD("unknow msg type %x", msg->type);
/* Do Nothing? MSG Body should be freed at here */
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index 8317e739606f..df1f14eb7773 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -214,6 +214,9 @@ typedef struct tagSmeStruct
void (*pget_peer_info_ext_ind_cb) (struct sir_peer_info_ext_resp *param,
void *pcontext);
void *pget_peer_info_ext_cb_context;
+ /* get isolation callback */
+ void (*get_isolation) (struct sir_isolation_resp *param, void *context);
+ void *get_isolation_cb_context;
#ifdef FEATURE_WLAN_EXTSCAN
void (*pExtScanIndCb) (void *, const tANI_U16, void *);
#endif /* FEATURE_WLAN_EXTSCAN */
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 686243ca9472..310b9b1ac6f9 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3840,6 +3840,11 @@ eHalStatus sme_get_peer_info(tHalHandle hal, struct sir_peer_info_req req,
void (*callbackfn)(struct sir_peer_info_resp *param,
void *pcontext));
+eHalStatus sme_get_isolation(tHalHandle hal,
+ void *context,
+ void (*callbackfn)(struct sir_isolation_resp *param,
+ void *pcontext));
+
/*----------------------------------------------------------------------------
\fn sme_get_peer_info_ext
\brief This function sends msg to get info for remote peer
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 4dd595d91f97..6f6aa0442e5e 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -12667,6 +12667,45 @@ eHalStatus sme_get_peer_info_ext(tHalHandle hal,
return status;
}
+eHalStatus sme_get_isolation(tHalHandle hal,
+ void *context,
+ void (*callbackfn)(struct sir_isolation_resp *param,
+ void *pcontext))
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ VOS_STATUS vosstatus = VOS_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ vos_msg_t vosmessage;
+
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: get isolation", __func__);
+
+ status = sme_AcquireGlobalLock(&mac->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ if (NULL == callbackfn) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Indication Call back is NULL",
+ __func__);
+ sme_ReleaseGlobalLock(&mac->sme);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ mac->sme.get_isolation = callbackfn;
+ mac->sme.get_isolation_cb_context = context;
+
+ vosmessage.bodyptr = NULL;
+ vosmessage.type = WDA_GET_ISOLATION;
+ vosstatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosmessage);
+ if (!VOS_IS_STATUS_SUCCESS(vosstatus)) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Post get isolation msg fail", __func__);
+ status = eHAL_STATUS_FAILURE;
+ }
+ sme_ReleaseGlobalLock(&mac->sme);
+ }
+ return status;
+}
+
/* ---------------------------------------------------------------------------
\fn sme_IsPmcBmps
\API to Check if PMC state is BMPS.
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index 21e0ad168e25..cd9fb719d67b 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -1001,6 +1001,7 @@ tANI_U8* macTraceGetWdaMsgString(tANI_U16 wdaMsg)
CASE_RETURN_STRING(WDA_SET_MIB_STATS_DISABLE);
CASE_RETURN_STRING(SIR_HAL_POWER_DEBUG_STATS_REQ);
CASE_RETURN_STRING(WDA_ACTION_FRAME_RANDOM_MAC);
+ CASE_RETURN_STRING(SIR_HAL_GET_ISOLATION);
default:
return((tANI_U8*) "UNKNOWN");
break;
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index e831bfabc3e5..456c11a90e4a 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -975,6 +975,8 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#define WDA_GET_PEER_INFO_EXT SIR_HAL_GET_PEER_INFO_EXT
#define WDA_GET_PEER_INFO_EXT_IND SIR_HAL_GET_PEER_INFO_EXT_IND
+#define WDA_GET_ISOLATION SIR_HAL_GET_ISOLATION
+
#define WDA_MODEM_POWER_STATE_IND SIR_HAL_MODEM_POWER_STATE_IND
#define WDA_VDEV_STOP_IND SIR_HAL_VDEV_STOP_IND