summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlifeng <lifeng@codeaurora.org>2016-10-24 08:41:33 +0800
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-11-12 12:41:14 +0530
commit435c66836aecfacf21dba40d5d4ea9ff7198aaa5 (patch)
tree1e0fa549f85e04bd74e2de0e2d579601daa4f4e9
parent8f5edf28acedc1112168c82b763a9e94cc107b64 (diff)
qcacld-2.0: Add vendor attr to get rx aggregation statistics
By setting the corresponding parameters: reorder timeout and window size to FW, the host will deliver information about aggregation of the packets on RX to upper layer. Change-Id: I404d56d8d9ca3e90f8d1dee28abd80d784924901 CRs-fixed: 1078111
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h25
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c165
-rw-r--r--CORE/MAC/inc/sirApi.h36
-rw-r--r--CORE/MAC/inc/wniApi.h1
-rw-r--r--CORE/MAC/src/include/sirParams.h6
-rw-r--r--CORE/SERVICES/WMA/wma.c188
-rw-r--r--CORE/SME/inc/smeInternal.h11
-rw-r--r--CORE/SME/inc/sme_Api.h6
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c131
9 files changed, 568 insertions, 1 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 239d4286f84c..092043fd9191 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -443,6 +443,12 @@ enum qca_wlan_vendor_attr {
QCA_WLAN_VENDOR_ATTR_CHAIN_INDEX = 26,
QCA_WLAN_VENDOR_ATTR_CHAIN_RSSI = 27,
+ /* Used in QCA_NL80211_VENDOR_SUBCMD_STATS_EXT command
+ * to report frame aggregation statistics to userspace.
+ */
+ QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM = 34,
+ QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO = 35,
+
/* keep last */
QCA_WLAN_VENDOR_ATTR_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_MAX =
@@ -1637,6 +1643,18 @@ enum qca_access_policy {
* parameters
* @QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER: Unsigned 8bit length attribute to update
* power save config to turn off/on qpower
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE:
+ * 32-bit unsigned value to set reorder timeout for AC_VO
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO:
+ * 32-bit unsigned value to set reorder timeout for AC_VI
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT:
+ * 32-bit unsigned value to set reorder timeout for AC_BE
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND:
+ * 32-bit unsigned value to set reorder timeout for AC_BK
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC:
+ * 6-byte MAC address to point out the specific peer
+ * @QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT:
+ * 32-bit unsigned value to set window size for specific peer
* @QCA_WLAN_VENDOR_ATTR_CONFIG_LAST: last config
* @QCA_WLAN_VENDOR_ATTR_CONFIG_MAX: max config
*/
@@ -1709,6 +1727,13 @@ enum qca_wlan_vendor_config {
* the unit is micro-second */
QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL = 30,
+ QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE = 31,
+ QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO = 32,
+ QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT = 33,
+ QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND = 34,
+ QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC = 35,
+ QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT = 36,
+
/* keep last */
QCA_WLAN_VENDOR_ATTR_CONFIG_LAST,
QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index dad633c981ac..b58fd6d83c88 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -2286,11 +2286,75 @@ static void wlan_hdd_cfg80211_stats_ext_callback(void* ctx, tStatsExtEvent* msg)
}
+/**
+ * wlan_hdd_cfg80211_stats_ext2_callback - stats_ext2_callback
+ * @ctx: hdd context
+ * @pmsg: stats_ext2_event
+ *
+ * Return: void
+ */
+static void wlan_hdd_cfg80211_stats_ext2_callback(void *ctx,
+ struct stats_ext2_event *pmsg)
+{
+ hdd_context_t *hdd_ctx = (hdd_context_t *)ctx;
+ int status, data_size;
+ struct sk_buff *vendor_event;
+
+ status = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != status)
+ return;
+
+ if (NULL == pmsg) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "msg received here is null");
+ return;
+ }
+
+ data_size = sizeof(struct stats_ext2_event) +
+ (pmsg->hole_cnt)*sizeof(pmsg->hole_info_array[0]);
+
+ vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+ NULL,
+ data_size + NLMSG_HDRLEN + NLMSG_HDRLEN,
+ QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX,
+ GFP_KERNEL);
+
+ if (!vendor_event) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "vendor_event_alloc failed for STATS_EXT2");
+ return;
+ }
+
+ if (nla_put_u32(vendor_event,
+ QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM,
+ pmsg->hole_cnt)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s put fail",
+ "QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM");
+ kfree_skb(vendor_event);
+ return;
+ }
+
+ if (nla_put(vendor_event,
+ QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO,
+ (pmsg->hole_cnt)*sizeof(pmsg->hole_info_array[0]),
+ (void *)(pmsg->hole_info_array))) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s put fail",
+ "QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO");
+ kfree_skb(vendor_event);
+ return;
+ }
+
+ cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+}
void wlan_hdd_cfg80211_stats_ext_init(hdd_context_t *pHddCtx)
{
sme_StatsExtRegisterCallback(pHddCtx->hHal,
wlan_hdd_cfg80211_stats_ext_callback);
+ sme_register_stats_ext2_callback(pHddCtx->hHal,
+ wlan_hdd_cfg80211_stats_ext2_callback);
}
#endif
@@ -9623,6 +9687,18 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
[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 },
+ [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE] = {
+ .type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO] = {
+ .type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT] = {
+ .type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND] = {
+ .type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC] = {
+ .type = NLA_UNSPEC},
+ [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT] = {
+ .type = NLA_U32},
};
/**
@@ -9766,6 +9842,8 @@ static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
u32 ftm_capab;
eHalStatus status;
struct sir_set_tx_rx_aggregation_size request;
+ struct sir_set_rx_reorder_timeout_val reorder_timeout;
+ struct sir_peer_set_rx_blocksize rx_blocksize;
VOS_STATUS vos_status;
uint32_t tx_fail_count;
uint32_t antdiv_ena, antdiv_chain;
@@ -10115,6 +10193,93 @@ static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
}
}
+#define RX_TIMEOUT_VAL_MIN 10
+#define RX_TIMEOUT_VAL_MAX 1000
+ if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE] ||
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO] ||
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT] ||
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND]) {
+
+ /* if one is specified, all must be specified */
+ if (!tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE] ||
+ !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO] ||
+ !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT] ||
+ !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND]) {
+ hddLog(LOGE,
+ FL("four AC timeout val are required MAC"));
+ return -EINVAL;
+ }
+
+ reorder_timeout.rx_timeout_pri[0] = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE]);
+ reorder_timeout.rx_timeout_pri[1] = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO]);
+ reorder_timeout.rx_timeout_pri[2] = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT]);
+ reorder_timeout.rx_timeout_pri[3] = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND]);
+ /* timeout value is required to be in the rang 10 to 1000ms */
+ if (reorder_timeout.rx_timeout_pri[0] >= RX_TIMEOUT_VAL_MIN &&
+ reorder_timeout.rx_timeout_pri[0] <= RX_TIMEOUT_VAL_MAX &&
+ reorder_timeout.rx_timeout_pri[1] >= RX_TIMEOUT_VAL_MIN &&
+ reorder_timeout.rx_timeout_pri[1] <= RX_TIMEOUT_VAL_MAX &&
+ reorder_timeout.rx_timeout_pri[2] >= RX_TIMEOUT_VAL_MIN &&
+ reorder_timeout.rx_timeout_pri[2] <= RX_TIMEOUT_VAL_MAX &&
+ reorder_timeout.rx_timeout_pri[3] >= RX_TIMEOUT_VAL_MIN &&
+ reorder_timeout.rx_timeout_pri[3] <= RX_TIMEOUT_VAL_MAX) {
+ vos_status = sme_set_reorder_timeout(pHddCtx->hHal,
+ &reorder_timeout);
+ if (vos_status != VOS_STATUS_SUCCESS) {
+ hddLog(LOGE,
+ FL("failed to set reorder timeout err %d"),
+ vos_status);
+ ret_val = -EPERM;
+ }
+ } else {
+ hddLog(LOGE,
+ FL("one of the timeout value is not in range"));
+ ret_val = -EINVAL;
+ }
+ }
+
+#define WINDOW_SIZE_VAL_MIN 1
+#define WINDOW_SIZE_VAL_MAX 64
+ if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC] ||
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT]) {
+
+ /* if one is specified, both must be specified */
+ if (!tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC] ||
+ !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT]) {
+ hddLog(LOGE,
+ FL("Both Peer MAC and windows limit required"));
+ return -EINVAL;
+ }
+
+ memcpy(&rx_blocksize.peer_macaddr,
+ nla_data(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC]),
+ sizeof(rx_blocksize.peer_macaddr)),
+
+ rx_blocksize.vdev_id = pAdapter->sessionId;
+ set_value = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT]);
+ /* maximum window size is 64 */
+ if (set_value >= WINDOW_SIZE_VAL_MIN &&
+ set_value <= WINDOW_SIZE_VAL_MAX) {
+ rx_blocksize.rx_block_ack_win_limit = set_value;
+ vos_status = sme_set_rx_set_blocksize(pHddCtx->hHal,
+ &rx_blocksize);
+ if (vos_status != VOS_STATUS_SUCCESS) {
+ hddLog(LOGE,
+ FL("failed to set aggr sizes err %d"),
+ vos_status);
+ ret_val = -EPERM;
+ }
+ } else {
+ hddLog(LOGE, FL("window size val is not in range"));
+ ret_val = -EINVAL;
+ }
+ }
+
return ret_val;
}
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index b155f61e7eda..33c056874219 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -1820,6 +1820,17 @@ typedef struct sSirSmeNeighborBssInd
tSirBssDescription bssDescription[1];
} tSirSmeNeighborBssInd, *tpSirSmeNeighborBssInd;
+/**
+ * sir_sme_rx_aggr_hole_ind - sme rx aggr hole indication
+ * @hole_cnt: num of holes detected
+ * @hole_info_array: hole info
+ */
+struct sir_sme_rx_aggr_hole_ind
+{
+ uint32_t hole_cnt;
+ uint32_t hole_info_array[];
+};
+
/*
* Definition for MIC failure indication
* MAC --->
@@ -8176,4 +8187,29 @@ struct sme_sub20_chan_width {
uint8_t session_id;
uint8_t channelwidth;
};
+
+/**
+ * struct sir_set_rx_reorder_timeout_val - rx reorder timeout
+ * @rx_timeout_pri: reorder timeout for AC
+ * rx_timeout_pri[0] : AC_VO
+ * rx_timeout_pri[1] : AC_VI
+ * rx_timeout_pri[2] : AC_BE
+ * rx_timeout_pri[3] : AC_BK
+ */
+struct sir_set_rx_reorder_timeout_val {
+ uint32_t rx_timeout_pri[4];
+};
+
+/**
+ * struct sir_peer_set_rx_blocksize - set rx blocksize
+ * @vdev_id: vdev id
+ * @peer_macaddr: peer mac address
+ * @rx_block_ack_win_limit: windows size limitation
+ */
+struct sir_peer_set_rx_blocksize {
+ uint32_t vdev_id;
+ v_MACADDR_t peer_macaddr;
+ uint32_t rx_block_ack_win_limit;
+};
+
#endif /* __SIR_API_H */
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index f460621b980b..5cbd7933e1ed 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -419,6 +419,7 @@ enum eWniMsgTypes
eWNI_SME_NDP_END_IND,
eWNI_SME_REGISTER_P2P_ACK_CB,
eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE,
+ eWNI_SME_RX_AGGR_HOLE_IND,
/* Link layer statistics */
eWMI_SME_LL_STATS_IND,
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index a9ae1c34072a..8c3e15ecae7a 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -783,11 +783,15 @@ 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)
#endif
+
+#define SIR_HAL_SET_REORDER_TIMEOUT_CMDID (SIR_HAL_ITC_MSG_TYPES_BEGIN + 368)
+#define SIR_HAL_SET_RX_BLOCKSIZE_CMDID (SIR_HAL_ITC_MSG_TYPES_BEGIN + 369)
+#define SIR_HAL_GET_CHAIN_RSSI_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 370)
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
// CFG message types
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 2677b0a2761f..7af5917fe7da 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -7732,6 +7732,66 @@ static int wma_stats_ext_event_handler(void *handle, u_int8_t *event_buf,
WMA_LOGD("%s: stats ext event Posted to SME", __func__);
return 0;
}
+
+static int wma_rx_aggr_failure_event_handler(void *handle, u_int8_t *event_buf,
+ u_int32_t len)
+{
+ WMI_REPORT_RX_AGGR_FAILURE_EVENTID_param_tlvs *param_buf;
+ struct sir_sme_rx_aggr_hole_ind *rx_aggr_hole_event;
+ wmi_rx_aggr_failure_event_fixed_param *rx_aggr_failure_info;
+ wmi_rx_aggr_failure_info *hole_info;
+ u_int32_t i, alloc_len;
+ VOS_STATUS status;
+ vos_msg_t vos_msg;
+
+ WMA_LOGD("%s: Posting stats ext event to SME", __func__);
+
+ param_buf = (WMI_REPORT_RX_AGGR_FAILURE_EVENTID_param_tlvs *)event_buf;
+ if (!param_buf) {
+ WMA_LOGE("%s: Invalid stats ext event buf", __func__);
+ return -EINVAL;
+ }
+
+ rx_aggr_failure_info = param_buf->fixed_param;
+ hole_info = param_buf->failure_info;
+
+ alloc_len = sizeof(*rx_aggr_hole_event) +
+ (rx_aggr_failure_info->num_failure_info)*
+ sizeof(rx_aggr_hole_event->hole_info_array[0]);
+ rx_aggr_hole_event = vos_mem_malloc(alloc_len);
+ if (NULL == rx_aggr_hole_event) {
+ WMA_LOGE("%s: Memory allocation failure", __func__);
+ return -ENOMEM;
+ }
+
+ rx_aggr_hole_event->hole_cnt = rx_aggr_failure_info->num_failure_info;
+ WMA_LOGD("aggr holes_sum: %d\n",
+ rx_aggr_failure_info->num_failure_info);
+ for (i = 0; i < rx_aggr_hole_event->hole_cnt; i++) {
+ rx_aggr_hole_event->hole_info_array[i] =
+ hole_info->end_seq - hole_info->start_seq + 1;
+ WMA_LOGD("aggr_index: %d\tstart_seq: %d\tend_seq: %d\t"
+ "hole_info: %d mpdu lost",
+ i, hole_info->start_seq, hole_info->end_seq,
+ rx_aggr_hole_event->hole_info_array[i]);
+ hole_info++;
+ }
+
+ vos_msg.type = eWNI_SME_RX_AGGR_HOLE_IND;
+ vos_msg.bodyptr = rx_aggr_hole_event;
+ vos_msg.bodyval = 0;
+
+ status = vos_mq_post_message(VOS_MQ_ID_SME, &vos_msg);
+ if (status != VOS_STATUS_SUCCESS) {
+ WMA_LOGE("%s: Failed to post stats ext event to SME", __func__);
+ vos_mem_free(rx_aggr_hole_event);
+ return -EINVAL;
+ }
+
+ WMA_LOGD("%s: stats ext event Posted to SME", __func__);
+
+ return 0;
+}
#endif
/**
@@ -8496,6 +8556,9 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
wmi_unified_register_event_handler(wma_handle->wmi_handle,
WMI_STATS_EXT_EVENTID,
wma_stats_ext_event_handler);
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_REPORT_RX_AGGR_FAILURE_EVENTID,
+ wma_rx_aggr_failure_event_handler);
#endif
#ifdef FEATURE_WLAN_EXTSCAN
wma_register_extscan_event_handler(wma_handle);
@@ -31630,6 +31693,122 @@ static void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
return;
}
+/**
+ * wma_set_rx_reorder_timeout_val() - set rx recorder timeout value
+ * @wma_handle: pointer to wma handle
+ * @sir_set_rx_reorder_timeout_val: rx recorder timeout value
+ *
+ * Return: VOS_STATUS_SUCCESS for success or error code.
+ */
+static VOS_STATUS wma_set_rx_reorder_timeout_val(tp_wma_handle wma_handle,
+ struct sir_set_rx_reorder_timeout_val *reorder_timeout)
+{
+ wmi_pdev_set_reorder_timeout_val_cmd_fixed_param *cmd;
+ uint32_t len;
+ wmi_buf_t buf;
+ int ret;
+
+ if (!reorder_timeout) {
+ WMA_LOGE(FL("invalid pointer"));
+ return VOS_STATUS_E_INVAL;
+ }
+
+ if (!wma_handle) {
+ WMA_LOGE(FL("WMA context is invald!"));
+ return VOS_STATUS_E_INVAL;
+ }
+ len = sizeof(*cmd);
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+
+ if (!buf) {
+ WMA_LOGE(FL("Failed allocate wmi buffer"));
+ return VOS_STATUS_E_NOMEM;
+ }
+ cmd = (wmi_pdev_set_reorder_timeout_val_cmd_fixed_param *)
+ wmi_buf_data(buf);
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_pdev_set_reorder_timeout_val_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_reorder_timeout_val_cmd_fixed_param));
+
+ memcpy(cmd->rx_timeout_pri, reorder_timeout->rx_timeout_pri,
+ sizeof(reorder_timeout->rx_timeout_pri));
+
+ WMA_LOGD("rx aggr record timeout: VO: %d, VI: %d, BE: %d, BK: %d",
+ cmd->rx_timeout_pri[0], cmd->rx_timeout_pri[1],
+ cmd->rx_timeout_pri[2], cmd->rx_timeout_pri[3]);
+
+ ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_PDEV_SET_REORDER_TIMEOUT_VAL_CMDID);
+ if (ret) {
+ WMA_LOGE(FL("Failed to send aggregation timeout"));
+ wmi_buf_free(buf);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ return VOS_STATUS_SUCCESS;
+}
+
+/**
+ * wma_set_rx_blocksize() - set rx blocksize
+ * @wma_handle: pointer to wma handle
+ * @sir_peer_set_rx_blocksize: rx blocksize for peer mac
+ *
+ * Return: VOS_STATUS_SUCCESS for success or error code.
+ */
+static VOS_STATUS wma_set_rx_blocksize(tp_wma_handle wma_handle,
+ struct sir_peer_set_rx_blocksize *peer_rx_blocksize)
+{
+ wmi_peer_set_rx_blocksize_cmd_fixed_param *cmd;
+ int32_t len;
+ wmi_buf_t buf;
+ u_int8_t *buf_ptr;
+ int ret;
+
+ if (!peer_rx_blocksize) {
+ WMA_LOGE(FL("invalid pointer"));
+ return VOS_STATUS_E_INVAL;
+ }
+
+ if (!wma_handle) {
+ WMA_LOGE(FL(" WMA context is invald!"));
+ return VOS_STATUS_E_INVAL;
+ }
+
+ len = sizeof(*cmd);
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+
+ if (!buf) {
+ WMA_LOGE(FL("Failed allocate wmi buffer"));
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+ cmd = (wmi_peer_set_rx_blocksize_cmd_fixed_param *) buf_ptr;
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_peer_set_rx_blocksize_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_peer_set_rx_blocksize_cmd_fixed_param));
+
+ cmd->vdev_id = peer_rx_blocksize->vdev_id;
+ cmd->rx_block_ack_win_limit =
+ peer_rx_blocksize->rx_block_ack_win_limit;
+ WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_rx_blocksize->peer_macaddr.bytes,
+ &cmd->peer_macaddr);
+
+ WMA_LOGD("rx aggr blocksize: %d", cmd->rx_block_ack_win_limit);
+
+ ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_PEER_SET_RX_BLOCKSIZE_CMDID);
+ if (ret) {
+ WMA_LOGE(FL("Failed to send aggregation size command"));
+ wmi_buf_free(buf);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ return VOS_STATUS_SUCCESS;
+}
+
/*
* function : wma_mc_process_msg
* Description :
@@ -32540,6 +32719,15 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
wma_get_chain_rssi(wma_handle, msg->bodyptr);
vos_mem_free(msg->bodyptr);
break;
+ case SIR_HAL_SET_REORDER_TIMEOUT_CMDID:
+ wma_set_rx_reorder_timeout_val(wma_handle,
+ msg->bodyptr);
+ vos_mem_free(msg->bodyptr);
+ break;
+ case SIR_HAL_SET_RX_BLOCKSIZE_CMDID:
+ wma_set_rx_blocksize(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 03dd1baa1d7b..b21e58083e56 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -132,6 +132,16 @@ typedef struct sStatsExtEvent {
tANI_U8 event_data[];
} tStatsExtEvent, *tpStatsExtEvent;
+/**
+ * struct stats_ext2_event - stats ext2 event
+ * @hole_cnt: hole counter
+ * @hole_info_array: hole informaton
+ */
+struct stats_ext2_event {
+ uint32_t hole_cnt;
+ uint32_t hole_info_array[];
+};
+
#define MAX_ACTIVE_CMD_STATS 16
typedef struct sActiveCmdStats {
@@ -237,6 +247,7 @@ typedef struct tagSmeStruct
void (*pbpf_get_offload_cb)(void *context, struct sir_bpf_get_offload *);
void *mib_stats_context;
void (*csr_mib_stats_callback) (struct mib_stats_metrics*, void*);
+ void (*stats_ext2_cb)(void *, struct stats_ext2_event *);
} tSmeStruct, *tpSmeStruct;
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index f6b147146380..cf3acf035e43 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -4721,6 +4721,12 @@ void sme_set_chan_info_callback(tHalHandle hal_handle,
void sme_set_5g_band_pref(tHalHandle hal_handle,
struct sme_5g_band_pref_params *pref_params);
+eHalStatus sme_set_reorder_timeout(tHalHandle hal,
+ struct sir_set_rx_reorder_timeout_val *req);
+eHalStatus sme_set_rx_set_blocksize(tHalHandle hal,
+ struct sir_peer_set_rx_blocksize *req);
+eHalStatus sme_register_stats_ext2_callback(tHalHandle hHal,
+ void (*stats_ext2_cb)(void *, struct stats_ext2_event *));
#ifdef FEATURE_WLAN_SUB_20_MHZ
eHalStatus sme_update_sub20_channel_width(tHalHandle hal_handle,
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 58ee3f1d7cb3..bf02968f3d40 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -3421,6 +3421,13 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg)
pMac->sme.link_layer_stats_ext_cb(pMsg->bodyptr);
vos_mem_free(pMsg->bodyptr);
break;
+ case eWNI_SME_RX_AGGR_HOLE_IND:
+ if (pMac->sme.stats_ext2_cb)
+ pMac->sme.stats_ext2_cb(pMac->hHdd,
+ (struct stats_ext2_event *)pMsg->bodyptr);
+ vos_mem_free(pMsg->bodyptr);
+ break;
+
default:
if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN )
@@ -19881,7 +19888,131 @@ void sme_set_5g_band_pref(tHalHandle hal_handle,
else
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"Unable to acquire global sme lock");
+}
+
+/**
+ * sme_set_reorder_timeout() - set reorder timeout value
+ * including Voice,Video,Besteffort,Background parameters
+ * @hal: hal handle for getting global mac struct
+ * @reg: struct sir_set_rx_reorder_timeout_val
+ *
+ * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
+ */
+eHalStatus sme_set_reorder_timeout(tHalHandle hal,
+ struct sir_set_rx_reorder_timeout_val *req)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ vos_msg_t vos_msg;
+ struct sir_set_rx_reorder_timeout_val *reorder_timeout;
+
+ smsLog(mac_ctx, LOG1, FL("enter"));
+
+ reorder_timeout = vos_mem_malloc(sizeof(*reorder_timeout));
+ if (NULL == reorder_timeout) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("Failed to alloc txrate_update"));
+ return eHAL_STATUS_FAILED_ALLOC;
+ }
+
+ *reorder_timeout = *req;
+
+ status = sme_AcquireGlobalLock(&mac_ctx->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ /* Serialize the req through MC thread */
+ vos_msg.bodyptr = reorder_timeout;
+ vos_msg.type = SIR_HAL_SET_REORDER_TIMEOUT_CMDID;
+ vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);
+
+ if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("Post Update tx_rate msg fail"));
+ status = eHAL_STATUS_FAILURE;
+ vos_mem_free(reorder_timeout);
+ }
+ sme_ReleaseGlobalLock(&mac_ctx->sme);
+ } else {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("sme_AcquireGlobalLock failed"));
+ vos_mem_free(reorder_timeout);
+ }
+ smsLog(mac_ctx, LOG1, FL("exit"));
+ return status;
+}
+
+/**
+ * sme_set_rx_set_blocksize() - set blocksize value
+ * including mac_addr and win_limit parameters
+ * @hal: hal handle for getting global mac struct
+ * @reg: struct sir_peer_set_rx_blocksize
+ *
+ * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
+ */
+eHalStatus sme_set_rx_set_blocksize(tHalHandle hal,
+ struct sir_peer_set_rx_blocksize *req)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ vos_msg_t vos_msg;
+ struct sir_peer_set_rx_blocksize *rx_blocksize;
+
+ smsLog(mac_ctx, LOG1, FL("enter"));
+
+ rx_blocksize = vos_mem_malloc(sizeof(*rx_blocksize));
+ if (NULL == rx_blocksize) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("Failed to alloc rx_blocksize"));
+ return eHAL_STATUS_FAILED_ALLOC;
+ }
+ *rx_blocksize = *req;
+
+ status = sme_AcquireGlobalLock(&mac_ctx->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ /* Serialize the req through MC thread */
+ vos_msg.bodyptr = rx_blocksize;
+ vos_msg.type = SIR_HAL_SET_RX_BLOCKSIZE_CMDID;
+ vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);
+
+ if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("Post Update tx_rate msg fail"));
+ status = eHAL_STATUS_FAILURE;
+ vos_mem_free(rx_blocksize);
+ }
+ sme_ReleaseGlobalLock(&mac_ctx->sme);
+ } else {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("sme_AcquireGlobalLock failed"));
+ vos_mem_free(rx_blocksize);
+ }
+ smsLog(mac_ctx, LOG1, FL("exit"));
+ return status;
+}
+/**
+ * sme_register_stats_ext2_callback() - Register drone callback to SME
+ * @hal_handle: hal handle for getting global mac struct
+ * @stats_ext2_cb: callback to be registered
+ *
+ * This function will register a callback for frame aggregation failure
+ * indications processing.
+ *
+ * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
+ */
+eHalStatus sme_register_stats_ext2_callback(tHalHandle hal_handle,
+ void (*stats_ext2_cb)(void *, struct stats_ext2_event *))
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal pmac = PMAC_STRUCT(hal_handle);
+
+ status = sme_AcquireGlobalLock(&pmac->sme);
+ if (status == eHAL_STATUS_SUCCESS) {
+ pmac->sme.stats_ext2_cb = stats_ext2_cb;
+ sme_ReleaseGlobalLock(&pmac->sme);
+ }
+ return status;
}
#ifdef FEATURE_WLAN_SUB_20_MHZ