diff options
| author | lifeng <lifeng@codeaurora.org> | 2016-10-24 08:41:33 +0800 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-11-12 12:41:14 +0530 |
| commit | 435c66836aecfacf21dba40d5d4ea9ff7198aaa5 (patch) | |
| tree | 1e0fa549f85e04bd74e2de0e2d579601daa4f4e9 | |
| parent | 8f5edf28acedc1112168c82b763a9e94cc107b64 (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.h | 25 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 165 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 36 | ||||
| -rw-r--r-- | CORE/MAC/inc/wniApi.h | 1 | ||||
| -rw-r--r-- | CORE/MAC/src/include/sirParams.h | 6 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 188 | ||||
| -rw-r--r-- | CORE/SME/inc/smeInternal.h | 11 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_Api.h | 6 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 131 |
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 |
