From bc87bec984a4d972a2acd0921041b5a0e7fb0b76 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Tue, 27 Feb 2018 20:06:42 -0800 Subject: [PATCH] qcacld-3.0: Add support to send ADDBA with user config Add support to send ADDBA request with user configured buffer size and tid and ADDBA response with user configured buffer size. Change-Id: I2a1dfedadeb68a1cfca9a6eba8e7775d0bb51d1a CRs-Fixed: 2193872 --- core/hdd/src/wlan_hdd_cfg80211.c | 67 ++++++++++++++++-- core/mac/inc/ani_global.h | 1 + core/mac/inc/sir_api.h | 5 ++ core/mac/src/include/sir_params.h | 2 + .../src/pe/lim/lim_send_management_frames.c | 6 +- core/sme/inc/sme_api.h | 23 +++++++ core/sme/src/common/sme_api.c | 68 +++++++++++++++++++ core/wma/inc/wma_types.h | 1 + core/wma/src/wma_main.c | 30 ++++++++ 9 files changed, 194 insertions(+), 9 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 5fd2d595789a..73c63117ca12 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -6294,6 +6294,12 @@ wlan_hdd_wifi_test_config_policy[ .type = NLA_U8}, [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE] = { .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION] = { + .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID] = { + .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE] = { + .type = NLA_U8}, }; /** @@ -7274,6 +7280,8 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, uint8_t set_val = 0; tSmeConfigParams *sme_config; bool update_sme_cfg = false; + uint8_t tid = 0; + uint16_t buff_size = 0; ENTER_DEV(dev); @@ -7284,26 +7292,28 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, } sme_get_config_param(hdd_ctx->hHal, sme_config); - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { hdd_err("Command not allowed in FTM mode"); - return -EPERM; + ret_val = -EPERM; + goto send_err; } ret_val = wlan_hdd_validate_context(hdd_ctx); if (ret_val) - return ret_val; + goto send_err; if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { hdd_err("Driver Modules are closed, can not start logger"); - return -EINVAL; + ret_val = -EINVAL; + goto send_err; } if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX, data, data_len, wlan_hdd_wifi_test_config_policy)) { hdd_err("invalid attr"); - return -EINVAL; + ret_val = -EINVAL; + goto send_err; } if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ]) { @@ -7314,7 +7324,7 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, ret_val = sme_set_addba_accept(hdd_ctx->hHal, adapter->session_id, cfg_val); if (ret_val) - return ret_val; + goto send_err; } if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS]) { @@ -7324,7 +7334,7 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, ret_val = sme_update_he_mcs(hdd_ctx->hHal, adapter->session_id, cfg_val); if (ret_val) - return ret_val; + goto send_err; } if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE]) { @@ -7382,9 +7392,52 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, update_sme_cfg = true; } + if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION]) { + if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID]) { + tid = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID]); + } else { + hdd_err("TID is not set for ADD/DEL BA cfg"); + ret_val = -EINVAL; + goto send_err; + } + cfg_val = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION]); + if (cfg_val == QCA_WLAN_ADD_BA) { + if (tb[ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]) + buff_size = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]); + ret_val = sme_send_addba_req(hdd_ctx->hHal, + adapter->session_id, tid, buff_size); + } else if (cfg_val == QCA_WLAN_DELETE_BA) { + } else { + hdd_err("Invalid BA session cfg"); + ret_val = -EINVAL; + goto send_err; + } + } else if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]) { + buff_size = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]); + hdd_debug("set buff size to %d for all tids", buff_size); + ret_val = sme_set_ba_buff_size(hdd_ctx->hHal, + adapter->session_id, buff_size); + if (ret_val) + goto send_err; + if (buff_size > 64) + /* Configure ADDBA req buffer size to 256 */ + set_val = 3; + else + /* Configure ADDBA req buffer size to 64 */ + set_val = 2; + ret_val = wma_cli_set_command(adapter->session_id, + WMI_VDEV_PARAM_BA_MODE, set_val, VDEV_CMD); + } + if (update_sme_cfg) sme_update_config(hdd_ctx->hHal, sme_config); +send_err: qdf_mem_free(sme_config); return ret_val; diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index c90b6fd50e84..9be4dc39c389 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -955,6 +955,7 @@ typedef struct sAniSirGlobal { /* 11k Offload Support */ bool is_11k_offload_supported; uint8_t reject_addba_req; + uint16_t usr_cfg_ba_buff_size; } tAniSirGlobal; diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 1ca7f8cbd697..338d1f470e2d 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -3969,6 +3969,11 @@ typedef struct sSirModifyIE { } tSirModifyIE, *tpSirModifyIE; +struct send_add_ba_req { + uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; + struct addba_send_params param; +}; + /* Message format for Update IE message sent to PE */ typedef struct sSirModifyIEsInd { uint16_t msgType; diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index ad84a0fc2f94..1c2667a6aeb8 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -696,6 +696,8 @@ struct sir_mgmt_msg { #define SIR_HAL_INVOKE_NEIGHBOR_REPORT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 395) #define SIR_HAL_OBSS_COLOR_COLLISION_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 396) #define SIR_HAL_OBSS_COLOR_COLLISION_INFO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 397) + +#define SIR_HAL_SEND_ADDBA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 398) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) /* CFG message types */ diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 325753fdd728..ba518f1d71ff 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -4749,8 +4749,10 @@ QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx, } frm.addba_param_set.tid = tid; frm.addba_param_set.buff_size = buff_size; - frm.addba_param_set.amsdu_supp = SIR_MAC_BA_POLICY_IMMEDIATE; - frm.addba_param_set.policy = SIR_MAC_BA_AMSDU_SUPPORTED; + if (mac_ctx->usr_cfg_ba_buff_size) + frm.addba_param_set.buff_size = mac_ctx->usr_cfg_ba_buff_size; + frm.addba_param_set.amsdu_supp = SIR_MAC_BA_AMSDU_SUPPORTED; + frm.addba_param_set.policy = SIR_MAC_BA_POLICY_IMMEDIATE; frm.ba_timeout.timeout = batimeout; if (addba_extn_present) { frm.addba_extn_element.present = 1; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index d57a11489c42..7b5158c4578a 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -2118,6 +2118,29 @@ static inline QDF_STATUS sme_handle_sae_msg(tHalHandle hal, uint8_t session_id, } #endif +/** + * sme_set_ba_buff_size() - sets BA buffer size + * @hal: Pointer to HAL + * @session_id: SME session id + * @buff_size: BA buffer size + * + * Return: 0 on success else err code + */ +int sme_set_ba_buff_size(tHalHandle hal, uint8_t session_id, + uint16_t buff_size); + +/** + * sme_send_addba_req() - send ADDBA request with user config + * @hal: Pointer to HAL + * @session_id: SME session id + * @tid: tid val for BA session + * @buff_size: BA buffer size + * + * Return: 0 on success else err code + */ +int sme_send_addba_req(tHalHandle hal, uint8_t session_id, uint8_t tid, + uint16_t buff_size); + #ifdef WLAN_FEATURE_11AX /** * sme_update_he_cap_nss() - sets the nss based on user request diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 2bd7b4d4917b..73108627a999 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -10089,6 +10089,74 @@ int sme_set_addba_accept(tHalHandle hal, uint8_t session_id, int value) } return 0; } + +int sme_set_ba_buff_size(tHalHandle hal, uint8_t session_id, + uint16_t buff_size) +{ + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + if (!buff_size) { + sme_err("invalid buff size %d", buff_size); + return -EINVAL; + } + mac_ctx->usr_cfg_ba_buff_size = buff_size; + sme_debug("addba buff size is set to %d", + mac_ctx->usr_cfg_ba_buff_size); + + return 0; +} + +#define DEFAULT_BA_BUFF_SIZE 64 +int sme_send_addba_req(tHalHandle hal, uint8_t session_id, uint8_t tid, + uint16_t buff_size) +{ + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + uint16_t ba_buff = 0; + QDF_STATUS status; + struct scheduler_msg msg = {0}; + struct send_add_ba_req *send_ba_req; + struct csr_roam_session *csr_session = NULL; + + if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) { + sme_err("STA not infra/connected state session_id: %d", + session_id); + return -EINVAL; + } + csr_session = CSR_GET_SESSION(mac_ctx, session_id); + if (!csr_session) { + sme_err("CSR session is NULL"); + return -EINVAL; + } + send_ba_req = qdf_mem_malloc(sizeof(*send_ba_req)); + if (!send_ba_req) { + sme_err("mem alloc failed"); + return -EIO; + } + qdf_mem_copy(send_ba_req->mac_addr, + csr_session->connectedProfile.bssid.bytes, + QDF_MAC_ADDR_SIZE); + ba_buff = buff_size; + if (!buff_size) { + if (mac_ctx->usr_cfg_ba_buff_size) + ba_buff = mac_ctx->usr_cfg_ba_buff_size; + else + ba_buff = DEFAULT_BA_BUFF_SIZE; + } + send_ba_req->param.vdev_id = session_id; + send_ba_req->param.tidno = tid; + send_ba_req->param.buffersize = ba_buff; + msg.type = WMA_SEND_ADDBA_REQ; + msg.bodyptr = send_ba_req; + status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg); + if (QDF_STATUS_SUCCESS != status) { + sme_err("Failed to post WMA_SEND_ADDBA_REQ"); + qdf_mem_free(send_ba_req); + return -EIO; + } + sme_debug("ADDBA_REQ sent to FW: tid %d buff_size %d", tid, ba_buff); + + return 0; +} + #define HT20_SHORT_GI_MCS7_RATE 722 /* * sme_send_rate_update_ind() - diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index 58aed37f97a6..5eb615f85ce8 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -344,6 +344,7 @@ #define WMA_RATE_UPDATE_IND SIR_HAL_RATE_UPDATE_IND +#define WMA_SEND_ADDBA_REQ SIR_HAL_SEND_ADDBA_REQ #define WMA_INIT_THERMAL_INFO_CMD SIR_HAL_INIT_THERMAL_INFO_CMD #define WMA_SET_THERMAL_LEVEL SIR_HAL_SET_THERMAL_LEVEL #define WMA_RMC_ENABLE_IND SIR_HAL_RMC_ENABLE_IND diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 5b0a7a080d4a..c05f8b3f8eb4 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -660,6 +660,31 @@ QDF_STATUS wma_form_unit_test_cmd_and_send(uint32_t vdev_id, return status; } +static void wma_process_send_addba_req(tp_wma_handle wma_handle, + struct send_add_ba_req *send_addba) +{ + QDF_STATUS status; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE(FL("Invalid WMA/WMI handle")); + qdf_mem_free(send_addba); + return; + } + + status = wmi_unified_addba_send_cmd_send(wma_handle->wmi_handle, + send_addba->mac_addr, + &send_addba->param); + if (QDF_STATUS_SUCCESS != status) { + WMA_LOGE(FL("Failed to process WMA_SEND_ADDBA_REQ")); + } + WMA_LOGD(FL("sent ADDBA req to" MAC_ADDRESS_STR "tid %d buff_size %d"), + MAC_ADDR_ARRAY(send_addba->mac_addr), + send_addba->param.tidno, + send_addba->param.buffersize); + + qdf_mem_free(send_addba); +} + /** * wma_ipa_get_stat() - get IPA data path stats from FW * @@ -7745,6 +7770,11 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) (tSirTxPowerLimit *) msg->bodyptr); qdf_mem_free(msg->bodyptr); break; + case WMA_SEND_ADDBA_REQ: + wma_process_send_addba_req(wma_handle, + (struct send_add_ba_req *)msg->bodyptr); + break; + #ifdef FEATURE_WLAN_CH_AVOID case WMA_CH_AVOID_UPDATE_REQ: wma_process_ch_avoid_update_req(wma_handle,