diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 63ec8699d1..fa939ef59c 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -1528,6 +1528,16 @@ QDF_STATUS wlan_mlme_cfg_set_vht_max_mpdu_len(struct wlan_objmgr_psoc *psoc, uint8_t value); +/** + * wlan_mlme_cfg_get_ht_smps() - gets HT SM Power Save mode from cfg item + * @psoc: psoc context + * @value: data to be set + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlme_cfg_get_ht_smps(struct wlan_objmgr_psoc *psoc, + uint8_t *value); + /** * wlan_mlme_cfg_get_vht_chan_width() - gets vht supported channel width from * cfg item diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 619f420d81..ceb24744ab 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -4235,4 +4235,25 @@ QDF_STATUS ucfg_mlme_cfg_get_eht_caps(struct wlan_objmgr_psoc *psoc, { return mlme_cfg_get_eht_caps(psoc, eht_cap); } + +static inline QDF_STATUS +ucfg_mlme_cfg_get_vht_ampdu_len_exp(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + return wlan_mlme_cfg_get_vht_ampdu_len_exp(psoc, value); +} + +static inline QDF_STATUS +ucfg_mlme_cfg_get_vht_max_mpdu_len(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + return wlan_mlme_cfg_get_vht_max_mpdu_len(psoc, value); +} + +static inline QDF_STATUS +ucfg_mlme_cfg_get_ht_smps(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + return wlan_mlme_cfg_get_ht_smps(psoc, value); +} #endif /* _WLAN_MLME_UCFG_API_H_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index ba08902349..8ef3cc6354 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -1359,6 +1359,48 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_vo_sus_intv(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS wlan_mlme_cfg_get_vht_ampdu_len_exp(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *value = mlme_obj->cfg.vht_caps.vht_cap_info.ampdu_len_exponent; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_mlme_cfg_get_vht_max_mpdu_len(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *value = mlme_obj->cfg.vht_caps.vht_cap_info.ampdu_len; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_mlme_cfg_get_ht_smps(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *value = mlme_obj->cfg.ht_caps.smps; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_get_wmm_dir_ac_vi(struct wlan_objmgr_psoc *psoc, uint8_t *value) { diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index dbeb98ea6e..4239c20212 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2236,6 +2236,42 @@ static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx) #if defined(WLAN_FEATURE_11AX) && \ (defined(CFG80211_SBAND_IFTYPE_DATA_BACKPORT) || \ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))) + +#if defined(CONFIG_BAND_6GHZ) && (KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE) +static void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) +{ + uint16_t he_6ghz_capa = 0; + uint8_t min_mpdu_start_spacing; + uint8_t max_ampdu_len_exp; + uint8_t max_mpdu_len; + uint8_t sm_pow_save; + + ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &min_mpdu_start_spacing); + he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START, + min_mpdu_start_spacing); + + ucfg_mlme_cfg_get_vht_ampdu_len_exp(hdd_ctx->psoc, &max_ampdu_len_exp); + he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, + max_ampdu_len_exp); + + ucfg_mlme_cfg_get_vht_max_mpdu_len(hdd_ctx->psoc, &max_mpdu_len); + he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, + max_mpdu_len); + + ucfg_mlme_cfg_get_ht_smps(hdd_ctx->psoc, &sm_pow_save); + he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, sm_pow_save); + + he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS; + he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS; + + hdd_ctx->iftype_data_6g->he_6ghz_capa.capa = he_6ghz_capa; +} +#else +static inline void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) +{ +} +#endif + #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) static void @@ -2267,6 +2303,8 @@ hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx) phy_info[0] |= IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; + hdd_update_wiphy_he_6ghz_capa(hdd_ctx); + band_6g->iftype_data = hdd_ctx->iftype_data_6g; } #else