From 6f6eca768048c4aa930e4608c23d14397773f2d3 Mon Sep 17 00:00:00 2001 From: lifeng Date: Tue, 6 Sep 2016 13:13:41 +0800 Subject: qcacld-2.0: Add vendor cmd to support antenna diversity Add qca_wlan_vendor_config attr to config antenna diversity. Add vendor subcmd QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI to get chain rssi value. Change-Id: I75c4c8016b15772b0c52be91e446f69580475496 CRs-fixed: 1071075 --- CORE/HDD/inc/wlan_hdd_cfg80211.h | 20 ++++ CORE/HDD/inc/wlan_hdd_main.h | 16 +++ CORE/HDD/src/wlan_hdd_cfg80211.c | 234 ++++++++++++++++++++++++++++++++++++++ CORE/HDD/src/wlan_hdd_main.c | 4 + CORE/MAC/inc/sirApi.h | 18 +++ CORE/MAC/src/include/sirParams.h | 1 + CORE/SERVICES/WMA/wma.c | 109 ++++++++++++++++++ CORE/SME/inc/smeInternal.h | 1 + CORE/SME/inc/sme_Api.h | 20 ++++ CORE/SME/src/sme_common/sme_Api.c | 63 ++++++++++ 10 files changed, 486 insertions(+) diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h index 00736acb8dbd..3f48cd0e9608 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg80211.h +++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h @@ -272,6 +272,8 @@ enum qca_nl80211_vendor_subcmds { /* subcommand for link layer statistics extension */ QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT = 127, + /* subcommand to get chain rssi value */ + QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI = 138, }; enum qca_nl80211_vendor_subcmds_index { @@ -437,6 +439,10 @@ enum qca_wlan_vendor_attr { /* Unsigned 32-bit value from enum qca_set_band */ QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE = 12, + /* used by QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI */ + QCA_WLAN_VENDOR_ATTR_CHAIN_INDEX = 26, + QCA_WLAN_VENDOR_ATTR_CHAIN_RSSI = 27, + /* keep last */ QCA_WLAN_VENDOR_ATTR_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_MAX = @@ -1691,6 +1697,18 @@ enum qca_wlan_vendor_config { /* Unsigned 8-bit, for setting qpower dynamically */ QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER, + /* 32-bit unsigned value to trigger antenna diversity features: + * 1-Enable, 0-Disable */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA = 27, + /* 32-bit unsigned value to configure specific chain antenna */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN = 28, + /* 32-bit unsigned value to trigger cycle selftest + * 1-Enable, 0-Disable */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST = 29, + /* 32-bit unsigned to configure the cycle time of selftest + * the unit is micro-second */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL = 30, + /* keep last */ QCA_WLAN_VENDOR_ATTR_CONFIG_LAST, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX = @@ -2203,6 +2221,8 @@ void wlan_hdd_cfg80211_extscan_callback(void *ctx, void *pMsg); #endif /* FEATURE_WLAN_EXTSCAN */ +void wlan_hdd_cfg80211_chainrssi_callback(void *ctx, void *pmsg); + void hdd_rssi_threshold_breached(void *hddctx, struct rssi_breach_event *data); diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 065a8685ab8e..8a70ab5d417d 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -149,6 +149,8 @@ #define WLAN_WAIT_TIME_BPF 1000 +#define WLAN_WAIT_TIME_CHAIN_RSSI 1000 + #define MAX_NUMBER_OF_ADAPTERS 4 #define MAX_CFG_STRING_LEN 255 @@ -1432,6 +1434,18 @@ struct hdd_ll_stats_context { }; #endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */ +/** + * struct hdd_chain_rssi_context - hdd chain rssi context + * @response_event: chain rssi request wait event + * @ignore_result: Flag to ignore the result or not + * @chain_rssi: chain rssi array + */ +struct hdd_chain_rssi_context { + struct completion response_event; + bool ignore_result; + struct chain_rssi_result result; +}; + #ifdef WLAN_FEATURE_OFFLOAD_PACKETS /** * struct hdd_offloaded_packets - request id to pattern id mapping @@ -1813,6 +1827,8 @@ struct hdd_context_s struct hdd_ll_stats_context ll_stats_context; #endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */ + struct hdd_chain_rssi_context chain_rssi_context; + #ifdef WLAN_FEATURE_MEMDUMP uint8_t *fw_dump_loc; uint32_t dump_loc_paddr; diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index ea7c4dc74ece..152a230fcb77 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -8620,6 +8620,10 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX [QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY] = {.type = NLA_U8}, [QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY] = {.type = NLA_U8}, [QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL] = {.type = NLA_U32 }, }; /** @@ -8765,6 +8769,8 @@ static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, struct sir_set_tx_rx_aggregation_size request; VOS_STATUS vos_status; uint32_t tx_fail_count; + uint32_t antdiv_ena, antdiv_chain; + uint32_t antdiv_selftest, antdiv_selftest_intvl; int attr_len; int access_policy = 0; char vendor_ie[SIR_MAC_MAX_IE_LENGTH + 2]; @@ -9057,6 +9063,59 @@ static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, } } + if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA]) { + antdiv_ena = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA]); + hddLog(LOG1, FL("antdiv_ena: %d"), antdiv_ena); + ret_val = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ENA_ANT_DIV, + antdiv_ena, PDEV_CMD); + if (ret_val) { + hddLog(LOG1, FL("Failed to set antdiv_ena")); + return ret_val; + } + } + + if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN]) { + antdiv_chain = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN]); + hddLog(LOG1, FL("antdiv_chain: %d"), antdiv_chain); + ret_val = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_FORCE_CHAIN_ANT, + antdiv_chain, PDEV_CMD); + if (ret_val) { + hddLog(LOG1, FL("Failed to set antdiv_chain")); + return ret_val; + } + } + + if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST]) { + antdiv_selftest = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST]); + hddLog(LOG1, FL("antdiv_selftest: %d"), antdiv_selftest); + ret_val = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANT_DIV_SELFTEST, + antdiv_selftest, PDEV_CMD); + if (ret_val) { + hddLog(LOG1, FL("Failed to set antdiv_selftest")); + return ret_val; + } + } + + if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL]) { + antdiv_selftest_intvl = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL]); + hddLog(LOG1, FL("antdiv_selftest_intvl: %d"), + antdiv_selftest_intvl); + ret_val = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANT_DIV_SELFTEST_INTVL, + antdiv_selftest_intvl, PDEV_CMD); + if (ret_val) { + hddLog(LOG1, FL("Failed to set antdiv_selftest_intvl")); + return ret_val; + } + } + return ret_val; } @@ -11808,6 +11867,135 @@ static int wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy, return ret; } +/** + * hdd_post_get_chain_rssi_rsp - send rsp to user space + * @hdd_ctx: Pointer to hdd context + * + * Return: 0 for success, non-zero for failure + */ +static int hdd_post_get_chain_rssi_rsp(hdd_context_t *hdd_ctx) +{ + struct sk_buff *skb = NULL; + int data_len = sizeof(hdd_ctx->chain_rssi_context.result); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, + data_len+NLMSG_HDRLEN); + + if (!skb) { + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); + return -ENOMEM; + } + + if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_CHAIN_RSSI, data_len, + &hdd_ctx->chain_rssi_context.result)) { + hddLog(LOGE, FL("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_chain_rssi() - get chain rssi + * @wiphy: wiphy pointer + * @wdev: pointer to struct wireless_dev + * @data: pointer to incoming NL vendor data + * @data_len: length of @data + * + * Return: 0 on success; error number otherwise. + */ +static int __wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct get_chain_rssi_req_params req_msg; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct hdd_chain_rssi_context *context; + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1]; + eHalStatus status; + int retval = 0; + unsigned long rc; + + ENTER(); + + retval = wlan_hdd_validate_context(hdd_ctx); + if (0 != retval) + return retval; + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len, NULL)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) { + hddLog(LOGE, FL("attr mac addr failed")); + return -EINVAL; + } + + memcpy(&req_msg.peer_macaddr, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]), + sizeof(req_msg.peer_macaddr)); + + spin_lock(&hdd_context_lock); + context = &hdd_ctx->chain_rssi_context; + INIT_COMPLETION(context->response_event); + context->ignore_result = false; + spin_unlock(&hdd_context_lock); + + status = sme_get_chain_rssi(hdd_ctx->hHal, &req_msg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(LOGE, + FL("sme_get_chain_rssi failed(err=%d)"), status); + return -EINVAL; + } + + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_CHAIN_RSSI)); + if (!rc) { + hddLog(LOGE, FL("Target response timed out")); + spin_lock(&hdd_context_lock); + context->ignore_result = true; + spin_unlock(&hdd_context_lock); + return -ETIMEDOUT; + } + + retval = hdd_post_get_chain_rssi_rsp(hdd_ctx); + if (retval) + hddLog(LOGE, + FL("Failed to send chain rssi to user space")); + + EXIT(); + return retval; +} + +/** + * wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi + * @wiphy: wiphy pointer + * @wdev: pointer to struct wireless_dev + * @data: pointer to incoming NL vendor data + * @data_len: length of @data + * + * Return: 0 on success; error number otherwise. + */ +static int wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_chain_rssi(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { { @@ -12339,6 +12527,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = wlan_hdd_cfg80211_txpower_scale_decr_db }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_get_chain_rssi + }, }; @@ -26556,6 +26752,44 @@ void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType, #endif /* FEATURE_WLAN_EXTSCAN */ +/** + * wlan_hdd_cfg80211_chainrssi_callback - chainrssi callback + * @ctx: hdd context + * @pmsg: pmsg + * + * Return: void + */ +void wlan_hdd_cfg80211_chainrssi_callback(void *ctx, void *pmsg) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *)ctx; + struct chain_rssi_result *data = (struct chain_rssi_result *)pmsg; + struct hdd_chain_rssi_context *context; + bool ignore_result; + + ENTER(); + + if (wlan_hdd_validate_context(hdd_ctx)) + return; + + spin_lock(&hdd_context_lock); + context = &hdd_ctx->chain_rssi_context; + ignore_result = context->ignore_result; + + if (ignore_result) { + hddLog(LOGE, FL("Ignore the result received after timeout")); + spin_unlock(&hdd_context_lock); + return; + } + + memcpy(&context->result, data->chain_rssi, + sizeof(data->chain_rssi)); + + complete(&context->response_event); + spin_unlock(&hdd_context_lock); + + return; +} + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \ defined(CFG80211_ABORT_SCAN) /** diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index cbcb5126d7b5..1658d3993216 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -14879,6 +14879,8 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) hdd_init_ll_stats_ctx(pHddCtx); + init_completion(&pHddCtx->chain_rssi_context.response_event); + spin_lock_init(&pHddCtx->schedScan_lock); hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS ); @@ -15734,6 +15736,8 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) sme_ExtScanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_extscan_callback); #endif /* FEATURE_WLAN_EXTSCAN */ + sme_chain_rssi_register_callback(pHddCtx->hHal, + wlan_hdd_cfg80211_chainrssi_callback); sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached); #ifdef WLAN_FEATURE_LINK_LAYER_STATS wlan_hdd_cfg80211_link_layer_stats_init(pHddCtx); diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 0017b1532391..d9cf4d6e9d37 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -5394,6 +5394,15 @@ struct extscan_cached_scan_results struct extscan_cached_scan_result *result; }; +/** + * struct chain_rssi_result - chain rssi result + * @chain_rssi: chain rssi result + */ +struct chain_rssi_result +{ + #define CHAIN_RSSI_NUM 8 + uint32_t chain_rssi[CHAIN_RSSI_NUM]; +}; /** * struct tSirWifiFullScanResultEvent - extscan full scan event @@ -8078,4 +8087,13 @@ struct scan_chan_info { uint32_t tx_frame_count; uint32_t clock_freq; }; + +/** + * struct get_chain_rssi_req_params - get chain rssi req params + * @peer_macaddr: specific peer mac address + */ +struct get_chain_rssi_req_params +{ + v_MACADDR_t peer_macaddr; +}; #endif /* __SIR_API_H */ diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 620a55c380ac..a9ae1c34072a 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -783,6 +783,7 @@ typedef struct sSirMbMsgP2p #define SIR_HAL_LONG_RETRY_LIMIT_CNT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 364) #define SIR_HAL_STA_INACTIVITY_TIMEOUT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 365) #define SIR_HAL_RX_CHN_STATUS_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 366) +#define SIR_HAL_GET_CHAIN_RSSI_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 369) #ifdef WLAN_FEATURE_LINK_LAYER_STATS #define SIR_HAL_LL_STATS_EXT_SET_THRESHOLD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 367) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index d08abccda068..fc7eaca537d2 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -5804,6 +5804,53 @@ static int wma_fw_mem_dump_event_handler(void *handle, u_int8_t *cmd_param_info, } #endif /* WLAN_FEATURE_MEMDUMP */ +static int wma_peer_ant_info_evt_handler(void *handle, u_int8_t *event, + u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + wmi_peer_antdiv_info *peer_ant_info; + WMI_PEER_ANTDIV_INFO_EVENTID_param_tlvs *param_buf; + wmi_peer_antdiv_info_event_fixed_param *fix_param; + struct chain_rssi_result chain_rssi_result; + u_int32_t chain_index; + + tpAniSirGlobal pmac = (tpAniSirGlobal)vos_get_context( + VOS_MODULE_ID_PE, wma->vos_context); + if (!pmac) { + WMA_LOGE("%s: Invalid pmac", __func__); + return -EINVAL; + } + + param_buf = (WMI_PEER_ANTDIV_INFO_EVENTID_param_tlvs *) event; + if (!param_buf) { + WMA_LOGE("Invalid peer_ant_info event buffer"); + return -EINVAL; + } + fix_param = param_buf->fixed_param; + peer_ant_info = param_buf->peer_info; + + WMA_LOGD(FL("num_peers=%d\tvdev_id=%d\n"), + fix_param->num_peers, fix_param->vdev_id); + WMA_LOGD(FL("peer_ant_info: %p\n"), peer_ant_info); + + if (!peer_ant_info) { + WMA_LOGE("Invalid peer_ant_info ptr\n"); + return -EINVAL; + } + + for (chain_index = 0; chain_index < CHAIN_RSSI_NUM; chain_index++) + WMA_LOGD(FL("chain%d rssi: %x\n"), chain_index, + peer_ant_info->chain_rssi[chain_index]); + + vos_mem_copy(chain_rssi_result.chain_rssi, + peer_ant_info->chain_rssi, + sizeof(peer_ant_info->chain_rssi)); + + pmac->sme.pchain_rssi_ind_cb(pmac->hHdd, &chain_rssi_result); + + return 0; +} + u_int8_t *wma_add_p2p_ie(u_int8_t *frm) { u_int8_t wfa_oui[3] = WMA_P2P_WFA_OUI; @@ -8407,6 +8454,10 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, wma_register_extscan_event_handler(wma_handle); #endif + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PEER_ANTDIV_INFO_EVENTID, + wma_peer_ant_info_evt_handler); + wmi_unified_register_event_handler(wma_handle->wmi_handle, WMI_BPF_CAPABILIY_INFO_EVENTID, wma_get_bpf_caps_event_handler); @@ -15830,6 +15881,11 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, else WMA_LOGE("Current band is not 5G"); break; + case WMI_PDEV_PARAM_ENA_ANT_DIV: + case WMI_PDEV_PARAM_FORCE_CHAIN_ANT: + case WMI_PDEV_PARAM_ANT_DIV_SELFTEST: + case WMI_PDEV_PARAM_ANT_DIV_SELFTEST_INTVL: + break; default: WMA_LOGE("Invalid wda_cli_set pdev command/Not" " yet implemented 0x%x", privcmd->param_id); @@ -31130,6 +31186,55 @@ void wma_process_set_allowed_action_frames_ind(tp_wma_handle wma_handle, return; } +static VOS_STATUS wma_get_chain_rssi(tp_wma_handle wma_handle, + struct get_chain_rssi_req_params *req_params) +{ + wmi_peer_antdiv_info_req_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len = sizeof(wmi_peer_antdiv_info_req_cmd_fixed_param); + u_int8_t *buf_ptr; + int32_t vdev_id; + + if (!wma_handle) { + WMA_LOGE(FL("WMA is closed, can not issue cmd")); + return VOS_STATUS_E_INVAL; + } + + if (VOS_STA_MODE == vos_get_conparam()) { + vdev_id = wma_find_vdev_by_type(wma_handle, WMI_VDEV_TYPE_STA); + } else if (VOS_STA_SAP_MODE == vos_get_conparam()) { + vdev_id = wma_find_vdev_by_type(wma_handle, WMI_VDEV_TYPE_AP); + } else { + WMA_LOGE("vdev does not exist could not get peer info"); + return VOS_STATUS_E_FAILURE; + } + + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE(FL("wmi_buf_alloc failed")); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); + + cmd = (wmi_peer_antdiv_info_req_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_antdiv_info_req_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_peer_antdiv_info_req_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(req_params->peer_macaddr.bytes, + &cmd->peer_mac_address); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_PEER_ANTDIV_INFO_REQ_CMDID)) { + WMA_LOGE(FL("failed to send get chain rssi command")); + wmi_buf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + /** * wma_update_tx_fail_cnt_th() - Set threshold for TX pkt fail * @wma_handle: WMA handle @@ -32207,6 +32312,10 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) msg->bodyptr); vos_mem_free(msg->bodyptr); break; + case SIR_HAL_GET_CHAIN_RSSI_REQ: + wma_get_chain_rssi(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + 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 98a68639b5f6..03dd1baa1d7b 100644 --- a/CORE/SME/inc/smeInternal.h +++ b/CORE/SME/inc/smeInternal.h @@ -195,6 +195,7 @@ typedef struct tagSmeStruct #ifdef FEATURE_WLAN_EXTSCAN void (*pExtScanIndCb) (void *, const tANI_U16, void *); #endif /* FEATURE_WLAN_EXTSCAN */ + void (*pchain_rssi_ind_cb)(void *, void *); #ifdef WLAN_FEATURE_NAN void (*nanCallback) (void*, tSirNanEvent*); #endif diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index c3e0b8eebeab..0c9576dce46c 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -4146,6 +4146,16 @@ eHalStatus sme_ResetSignificantChange (tHalHandle hHal, eHalStatus sme_getCachedResults (tHalHandle hHal, tSirExtScanGetCachedResultsReqParams *pCachedResultsReq); +/** + * sme_get_chain_rssi - sme api to get chain rssi + * @hHal: global hal handle + * @input: get chain rssi req params + * + * Return: eHalStatus enumeration. + */ +eHalStatus sme_get_chain_rssi(tHalHandle phal, + struct get_chain_rssi_req_params *input); + eHalStatus sme_set_epno_list(tHalHandle hal, struct wifi_epno_params *req_msg); eHalStatus sme_set_passpoint_list(tHalHandle hal, @@ -4164,6 +4174,16 @@ eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal, #endif /* FEATURE_WLAN_EXTSCAN */ +/** + * sme_chain_rssi_register_callback - chain rssi callback + * @hal: global hal handle + * @pchain_rssi_ind_cb: callback function pointer + * + * Return: eHalStatus enumeration. + */ +eHalStatus sme_chain_rssi_register_callback(tHalHandle phal, + void (*pchain_rssi_ind_cb)(void *, void *)); + eHalStatus sme_bpf_offload_register_callback(tHalHandle hal, void (*pbpf_get_offload_cb)(void *, struct sir_bpf_get_offload *)); diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 1b3a7e931341..339c2f8f7cef 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -16017,6 +16017,48 @@ eHalStatus sme_getCachedResults (tHalHandle hHal, return status; } +/** + * sme_get_chain_rssi - sme api to get chain rssi + * @hHal: global hal handle + * @input: get chain rssi req params + * + * Return: eHalStatus enumeration. + */ +eHalStatus sme_get_chain_rssi(tHalHandle phal, + struct get_chain_rssi_req_params *input) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pmac = PMAC_STRUCT(phal); + vos_msg_t vos_message; + struct get_chain_rssi_req_params *req_msg; + + req_msg = vos_mem_malloc(sizeof(*req_msg)); + if (!req_msg) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + *req_msg = *input; + + status = sme_AcquireGlobalLock(&pmac->sme); + if (eHAL_STATUS_SUCCESS == status) { + /* serialize the req through MC thread */ + vos_message.bodyptr = req_msg; + vos_message.type = SIR_HAL_GET_CHAIN_RSSI_REQ; + vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Post Get Chain Rssi msg fail")); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pmac->sme); + } + + return status; +} + /** * sme_set_epno_list() - set epno network list * @hHal: global hal handle @@ -16236,6 +16278,27 @@ eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal, #endif /* FEATURE_WLAN_EXTSCAN */ +/** + * sme_chain_rssi_register_callback - chain rssi callback + * @hal: global hal handle + * @pchain_rssi_ind_cb: callback function pointer + * + * Return: eHalStatus enumeration. + */ +eHalStatus sme_chain_rssi_register_callback(tHalHandle phal, + void (*pchain_rssi_ind_cb)(void *, void *)) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pmac = PMAC_STRUCT(phal); + + status = sme_AcquireGlobalLock(&pmac->sme); + if (eHAL_STATUS_SUCCESS == status) { + pmac->sme.pchain_rssi_ind_cb = pchain_rssi_ind_cb; + sme_ReleaseGlobalLock(&pmac->sme); + } + return status; +} + /** * sme_set_rssi_threshold_breached_cb() - set rssi threshold breached callback * @hal: global hal handle -- cgit v1.2.3