diff options
| author | nakul kachhwaha <nkachh@codeaurora.org> | 2017-01-18 16:00:41 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-04-26 05:51:16 -0700 |
| commit | 344e641707dac46705eb7026d01e900615d1a033 (patch) | |
| tree | dc0473e65db05a9778f4c25364896c24c0035ffe | |
| parent | 1eeddf8238b3f025b492dd414e23424e1e4cdcf0 (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.h | 1 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wext.c | 172 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 7 | ||||
| -rw-r--r-- | CORE/MAC/src/include/sirParams.h | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 87 | ||||
| -rw-r--r-- | CORE/SME/inc/smeInternal.h | 3 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_Api.h | 5 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 39 | ||||
| -rw-r--r-- | CORE/SYS/legacy/src/utils/src/macTrace.c | 1 | ||||
| -rw-r--r-- | CORE/WDA/inc/wlan_qct_wda.h | 2 |
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 |
