diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index 7748b0d150..17b870077a 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -393,6 +393,7 @@ struct wait_for_key_timer { * @hb_failure_rssi: heartbeat failure AP RSSI * @opr_rate_set: operational rates set * @ext_opr_rate_set: extended operational rates set + * @mcs_rate_set: MCS Based rates set * @mscs_req_info: Information related to mscs request * @he_config: he config * @he_sta_obsspd: he_sta_obsspd @@ -429,6 +430,7 @@ struct mlme_legacy_priv { uint32_t hb_failure_rssi; struct mlme_cfg_str opr_rate_set; struct mlme_cfg_str ext_opr_rate_set; + struct mlme_cfg_str mcs_rate_set; bool twt_wait_for_notify; #ifdef WLAN_FEATURE_MSCS struct mscs_req_info mscs_req_info; diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 9eb742b791..2e97b9638a 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -114,10 +114,16 @@ QDF_STATUS mlme_init_rate_config(struct vdev_mlme_obj *vdev_mlme) return QDF_STATUS_E_FAILURE; } - mlme_priv->opr_rate_set.max_len = CFG_OPERATIONAL_RATE_SET_LEN; + mlme_priv->opr_rate_set.max_len = + QDF_MIN(CFG_OPERATIONAL_RATE_SET_LEN, CFG_STR_DATA_LEN); mlme_priv->opr_rate_set.len = 0; - mlme_priv->ext_opr_rate_set.max_len = CFG_OPERATIONAL_RATE_SET_LEN; + mlme_priv->ext_opr_rate_set.max_len = + QDF_MIN(CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN, + CFG_STR_DATA_LEN); mlme_priv->ext_opr_rate_set.len = 0; + mlme_priv->mcs_rate_set.max_len = + QDF_MIN(CFG_SUPPORTED_MCS_SET_LEN, CFG_STR_DATA_LEN); + mlme_priv->mcs_rate_set.len = 0; return QDF_STATUS_SUCCESS; } diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index ac00c7755f..3e7f6944ca 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -3154,13 +3154,13 @@ wlan_mlme_get_usr_disabled_roaming(struct wlan_objmgr_psoc *psoc, bool *val); /** * mlme_get_opr_rate() - get operational rate * @vdev: vdev pointer - * @dst: pointer to get operational rate - * @len: length of operational rate + * @dst: buffer to get rates set + * @len: length of the buffer * - * Return: QDF_SUCCESS if success + * Return: length of the rates set */ -QDF_STATUS mlme_get_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, - qdf_size_t *len); +qdf_size_t mlme_get_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, + qdf_size_t len); /** * mlme_set_opr_rate() - set operational rate @@ -3176,13 +3176,13 @@ QDF_STATUS mlme_set_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src, /** * mlme_get_ext_opr_rate() - get extended operational rate * @vdev: vdev pointer - * @dst: pointer to get extended operational rate - * @len: length of extended operational rate + * @dst: buffer to get rates set + * @len: length of the buffer * - * Return: QDF_SUCCESS if success + * Return: length of the rates set */ -QDF_STATUS mlme_get_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, - qdf_size_t *len); +qdf_size_t mlme_get_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, + qdf_size_t len); /** * mlme_set_ext_opr_rate() - set extended operational rate @@ -3195,6 +3195,28 @@ QDF_STATUS mlme_get_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, QDF_STATUS mlme_set_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src, qdf_size_t len); +/** + * mlme_get_mcs_rate() - get MCS based rate + * @vdev: vdev pointer + * @dst: buffer to get rates set + * @len: length of the buffer + * + * Return: length of the rates set + */ +qdf_size_t mlme_get_mcs_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, + qdf_size_t len); + +/** + * mlme_set_mcs_rate() - set MCS based rate + * @vdev: vdev pointer + * @src: pointer to set MCS based rate + * @len: length of MCS based rate + * + * Return: QDF_SUCCESS if success + */ +QDF_STATUS mlme_set_mcs_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src, + qdf_size_t len); + /** * wlan_mlme_is_sta_mon_conc_supported() - Check if STA + Monitor mode * concurrency is supported diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 49bd58f731..c551c0d834 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -2764,11 +2764,12 @@ ucfg_mlme_set_rf_test_mode_enabled(struct wlan_objmgr_psoc *psoc, bool value) * @psoc: pointer to vdev object * @buf: buffer to get rates set * @len: length of the buffer - * Return: QDF Status + * + * Return: length of the rates set */ -static inline QDF_STATUS +static inline qdf_size_t ucfg_mlme_get_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *buf, - qdf_size_t *len) + qdf_size_t len) { return mlme_get_opr_rate(vdev, buf, len); } @@ -2778,15 +2779,31 @@ ucfg_mlme_get_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *buf, * @psoc: pointer to vdev object * @buf: buffer to get rates set * @len: length of the buffer - * Return: QDF Status + * + * Return: length of the rates set */ -static inline QDF_STATUS +static inline qdf_size_t ucfg_mlme_get_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *buf, - qdf_size_t *len) + qdf_size_t len) { return mlme_get_ext_opr_rate(vdev, buf, len); } +/** + * ucfg_mlme_get_mcs_rate() - Get MCS based rate set + * @psoc: pointer to vdev object + * @buf: buffer to get rates set + * @len: length of the buffer + * + * Return: length of the rates set + */ +static inline qdf_size_t +ucfg_mlme_get_mcs_rate(struct wlan_objmgr_vdev *vdev, uint8_t *buf, + qdf_size_t len) +{ + return mlme_get_mcs_rate(vdev, buf, len); +} + /** * ucfg_mlme_get_supported_mcs_set() - Get Supported MCS set * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 9ba3efef12..625f641855 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -4897,26 +4897,32 @@ wlan_mlme_get_usr_disabled_roaming(struct wlan_objmgr_psoc *psoc, bool *val) return QDF_STATUS_SUCCESS; } -QDF_STATUS mlme_get_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, - qdf_size_t *len) +qdf_size_t mlme_get_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, + qdf_size_t len) { struct mlme_legacy_priv *mlme_priv; if (!vdev || !dst || !len) { mlme_legacy_err("invalid params"); - return QDF_STATUS_E_INVAL; + return 0; } mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - return QDF_STATUS_E_FAILURE; + return 0; } - *len = mlme_priv->opr_rate_set.len; - qdf_mem_copy(dst, mlme_priv->opr_rate_set.data, *len); + if (len < mlme_priv->opr_rate_set.len) { + mlme_legacy_err("Invalid length %zd (<%zd)", len, + mlme_priv->opr_rate_set.len); + return 0; + } - return QDF_STATUS_SUCCESS; + qdf_mem_copy(dst, mlme_priv->opr_rate_set.data, + mlme_priv->opr_rate_set.len); + + return mlme_priv->opr_rate_set.len; } QDF_STATUS mlme_set_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src, @@ -4947,26 +4953,32 @@ QDF_STATUS mlme_set_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src, return QDF_STATUS_SUCCESS; } -QDF_STATUS mlme_get_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, - qdf_size_t *len) +qdf_size_t mlme_get_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, + qdf_size_t len) { struct mlme_legacy_priv *mlme_priv; if (!vdev || !dst || !len) { mlme_legacy_err("invalid params"); - return QDF_STATUS_E_INVAL; + return 0; } mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - return QDF_STATUS_E_FAILURE; + return 0; } - *len = mlme_priv->ext_opr_rate_set.len; - qdf_mem_copy(dst, mlme_priv->ext_opr_rate_set.data, *len); + if (len < mlme_priv->ext_opr_rate_set.len) { + mlme_legacy_err("Invalid length %zd (<%zd)", len, + mlme_priv->ext_opr_rate_set.len); + return 0; + } - return QDF_STATUS_SUCCESS; + qdf_mem_copy(dst, mlme_priv->ext_opr_rate_set.data, + mlme_priv->ext_opr_rate_set.len); + + return mlme_priv->ext_opr_rate_set.len; } QDF_STATUS mlme_set_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src, @@ -4997,6 +5009,62 @@ QDF_STATUS mlme_set_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src, return QDF_STATUS_SUCCESS; } +qdf_size_t mlme_get_mcs_rate(struct wlan_objmgr_vdev *vdev, uint8_t *dst, + qdf_size_t len) +{ + struct mlme_legacy_priv *mlme_priv; + + if (!vdev || !dst || !len) { + mlme_legacy_err("invalid params"); + return 0; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return 0; + } + + if (len < mlme_priv->mcs_rate_set.len) { + mlme_legacy_err("Invalid length %zd (<%zd)", len, + mlme_priv->mcs_rate_set.len); + return 0; + } + + qdf_mem_copy(dst, mlme_priv->mcs_rate_set.data, + mlme_priv->mcs_rate_set.len); + + return mlme_priv->mcs_rate_set.len; +} + +QDF_STATUS mlme_set_mcs_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src, + qdf_size_t len) +{ + struct mlme_legacy_priv *mlme_priv; + + if (!vdev || !src) { + mlme_legacy_err("invalid params"); + return QDF_STATUS_E_INVAL; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + if (len > mlme_priv->mcs_rate_set.max_len) { + mlme_legacy_err("Invalid len %zd (>%zd)", len, + mlme_priv->mcs_rate_set.max_len); + return QDF_STATUS_E_INVAL; + } + + mlme_priv->mcs_rate_set.len = len; + qdf_mem_copy(mlme_priv->mcs_rate_set.data, src, len); + + return QDF_STATUS_SUCCESS; +} + static enum monitor_mode_concurrency wlan_mlme_get_monitor_mode_concurrency(struct wlan_objmgr_psoc *psoc) { diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 87d9e14450..cfc7b3e126 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -4980,50 +4980,6 @@ static void wlan_hdd_fill_os_rate_info(enum tx_rate_info rate_flags, os_rate->flags |= RATE_INFO_FLAGS_SHORT_GI; } -/** - * hdd_get_current_mcs_set() - Get current MCS rate set from connection info - * @adapter: Pointer to STA adapter - * @buf: pointer to buffer for holding the output mcs rate set - * @len: length of the buffer - * - * Return: number of elements in mcs rate set, 0 for failure. - */ -static qdf_size_t -hdd_get_current_mcs_set(struct hdd_adapter *adapter, uint8_t *buf, - qdf_size_t len) -{ - struct hdd_station_ctx *hdd_sta_ctx; - qdf_size_t ret = 0; - int i; - uint32_t *mcs_set; - uint8_t *dst_rate = buf; - - if (!adapter || !buf || !len) - return 0; - - hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - if (!hdd_sta_ctx) { - hdd_err("Invalid sta ctx"); - return 0; - } - - if (!hdd_sta_ctx->conn_info.conn_flag.ht_present) { - hdd_err("No HT cap"); - return 0; - } - - mcs_set = (uint32_t *)hdd_sta_ctx->conn_info.ht_caps.mcs.rx_mask; - for (i = 0; i < VALID_MAX_MCS_INDEX && ret < len; i++) { - if (!QDF_GET_BITS(*mcs_set, i, 1)) - continue; - - *dst_rate++ = i; - ret++; - } - - return ret; -} - bool hdd_report_max_rate(struct hdd_adapter *adapter, mac_handle_t mac_handle, struct rate_info *rate, @@ -5038,10 +4994,10 @@ bool hdd_report_max_rate(struct hdd_adapter *adapter, bool is_vht20_mcs9 = false; uint16_t he_mcs_12_13_map = 0; uint16_t current_rate = 0; - qdf_size_t or_leng = CSR_DOT11_SUPPORTED_RATES_MAX; + qdf_size_t or_leng; uint8_t operational_rates[CSR_DOT11_SUPPORTED_RATES_MAX]; uint8_t extended_rates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX]; - qdf_size_t er_leng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX; + qdf_size_t er_leng; uint8_t mcs_rates[SIZE_OF_BASIC_MCS_SET]; qdf_size_t mcs_len; struct index_data_rate_type *supported_mcs_rate; @@ -5091,14 +5047,8 @@ bool hdd_report_max_rate(struct hdd_adapter *adapter, } /* Get Basic Rate Set */ - if (0 != ucfg_mlme_get_opr_rate(vdev, operational_rates, - &or_leng)) { - hdd_err("cfg get returned failure"); - hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_STATS_ID); - /*To keep GUI happy */ - return false; - } - + or_leng = ucfg_mlme_get_opr_rate(vdev, operational_rates, + sizeof(operational_rates)); for (i = 0; i < or_leng; i++) { for (j = 0; j < ARRAY_SIZE(supported_data_rate); j++) { @@ -5116,14 +5066,8 @@ bool hdd_report_max_rate(struct hdd_adapter *adapter, } /* Get Extended Rate Set */ - if (0 != ucfg_mlme_get_ext_opr_rate(vdev, extended_rates, - &er_leng)) { - hdd_err("cfg get returned failure"); - hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_STATS_ID); - /*To keep GUI happy */ - return false; - } - + er_leng = ucfg_mlme_get_ext_opr_rate(vdev, extended_rates, + sizeof(extended_rates)); he_mcs_12_13_map = wlan_vdev_mlme_get_he_mcs_12_13_map(vdev); hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_STATS_ID); @@ -5208,9 +5152,9 @@ bool hdd_report_max_rate(struct hdd_adapter *adapter, max_mcs_idx = (max_mcs_idx > mcs_index) ? max_mcs_idx : mcs_index; } else { - mcs_len = - hdd_get_current_mcs_set(adapter, mcs_rates, - SIZE_OF_BASIC_MCS_SET); + mcs_len = ucfg_mlme_get_mcs_rate(adapter->vdev, + mcs_rates, + sizeof(mcs_rates)); if (!mcs_len) { hdd_err("Failed to get current mcs rate set"); /*To keep GUI happy */ diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 2448762c42..3232c6ba4e 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c @@ -772,6 +772,69 @@ static void lim_update_ml_partner_info(struct pe_session *session_entry, } #endif +/** + * hdd_cm_update_mcs_rate_set() - Update MCS rate set from HT capability + * @vdev: Pointer to vdev boject + * @ht_cap: pointer to parsed HT capablity + * + * Return: None. + */ +static inline void +lim_update_mcs_rate_set(struct wlan_objmgr_vdev *vdev, tDot11fIEHTCaps *ht_cap) +{ + qdf_size_t len = 0; + int i; + uint32_t *mcs_set; + uint8_t dst_rate[VALID_MAX_MCS_INDEX] = {0}; + + mcs_set = (uint32_t *)ht_cap->supportedMCSSet; + for (i = 0; i < VALID_MAX_MCS_INDEX; i++) { + if (!QDF_GET_BITS(*mcs_set, i, 1)) + continue; + + dst_rate[len++] = i; + } + + mlme_set_mcs_rate(vdev, dst_rate, len); +} + +/** + * hdd_cm_update_rate_set() - Update rate set according to assoc resp + * @psoc: Pointer to psoc object + * @vdev_id: vdev id + * @assoc_resp: pointer to parsed associate response + * + * Return: None. + */ +static void +lim_update_vdev_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + tpSirAssocRsp assoc_resp) +{ + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_LEGACY_MAC_ID); + if (!vdev) { + pe_err("vdev not found for id: %d", vdev_id); + return; + } + + if (assoc_resp->suppRatesPresent && assoc_resp->supportedRates.numRates) + mlme_set_opr_rate(vdev, assoc_resp->supportedRates.rate, + assoc_resp->supportedRates.numRates); + + if (assoc_resp->extendedRatesPresent && + assoc_resp->extendedRates.numRates) + mlme_set_ext_opr_rate(vdev, + assoc_resp->extendedRates.rate, + assoc_resp->extendedRates.numRates); + + if (assoc_resp->HTCaps.present) + lim_update_mcs_rate_set(vdev, &assoc_resp->HTCaps); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); +} + /** * lim_process_assoc_rsp_frame() - Processes assoc response * @mac_ctx: Pointer to Global MAC structure @@ -1136,6 +1199,9 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, lim_objmgr_update_vdev_nss(mac_ctx->psoc, session_entry->smeSessionId, session_entry->nss); + lim_update_vdev_rate_set(mac_ctx->psoc, + session_entry->smeSessionId, + assoc_rsp); if ((session_entry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE) || @@ -1233,6 +1299,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, lim_objmgr_update_vdev_nss(mac_ctx->psoc, session_entry->smeSessionId, session_entry->nss); + lim_update_vdev_rate_set(mac_ctx->psoc, session_entry->smeSessionId, + assoc_rsp); /* * Extract the AP capabilities from the beacon that diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index b9a439974e..f8e3027ee0 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -853,7 +853,6 @@ populate_dot11f_ext_supp_rates(struct mac_context *mac, uint8_t nChannelNum, tDot11fIEExtSuppRates *pDot11f, struct pe_session *pe_session) { - QDF_STATUS nsir_status; qdf_size_t n_rates = 0; uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES]; @@ -874,15 +873,9 @@ populate_dot11f_ext_supp_rates(struct mac_context *mac, uint8_t nChannelNum, pe_err("null pe_session"); return QDF_STATUS_E_INVAL; } - n_rates = SIR_MAC_MAX_NUMBER_OF_RATES; - nsir_status = mlme_get_ext_opr_rate(pe_session->vdev, rates, - &n_rates); - if (QDF_IS_STATUS_ERROR(nsir_status)) { - n_rates = 0; - pe_err("Failed to retrieve nItem from CFG status: %d", - (nsir_status)); - return nsir_status; - } + + n_rates = mlme_get_ext_opr_rate(pe_session->vdev, rates, + sizeof(rates)); } if (0 != n_rates) {