summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlifeng <lifeng@codeaurora.org>2016-09-06 13:13:41 +0800
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-11-11 19:51:32 +0530
commit6f6eca768048c4aa930e4608c23d14397773f2d3 (patch)
treee13e824b5cfcc4d4ef2285b0e863d60879e12c20
parentfbef740168f0907ee0c069bb87d0610fb6a1e080 (diff)
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
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h20
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h16
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c234
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c4
-rw-r--r--CORE/MAC/inc/sirApi.h18
-rw-r--r--CORE/MAC/src/include/sirParams.h1
-rw-r--r--CORE/SERVICES/WMA/wma.c109
-rw-r--r--CORE/SME/inc/smeInternal.h1
-rw-r--r--CORE/SME/inc/sme_Api.h20
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c63
10 files changed, 486 insertions, 0 deletions
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;
@@ -8408,6 +8455,10 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
#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
@@ -16018,6 +16018,48 @@ eHalStatus sme_getCachedResults (tHalHandle hHal,
}
/**
+ * 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
* @input: request message
@@ -16237,6 +16279,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
* @cb: callback function pointer