From c682062e13aa6f79d134c39ea4ce0b1c89ef2070 Mon Sep 17 00:00:00 2001 From: Vinod Kumar Pirla Date: Fri, 14 Oct 2022 02:57:28 -0700 Subject: [PATCH] qcacld-3.0: Associate in 11ax mode on non MLO vdev In 11be capable configuration, for connection attempt to MLO AP from non-MLO type vdev, downgrade to 11ax mode association for that vdev. User can still connect in ML mode from MLO type vdev. Change-Id: I1e7cf940a778a20f2f4d5d24283ffb6aae52781b CRs-Fixed: 3312163 --- .../interface_mgr/src/wlan_if_mgr_roam.c | 10 ++++ components/mlme/core/inc/wlan_mlme_main.h | 16 +++++++ components/mlme/core/src/wlan_mlme_main.c | 46 +++++++++++++++++++ .../dispatcher/inc/wlan_mlme_public_struct.h | 15 ------ core/hdd/src/wlan_hdd_cm_connect.c | 19 ++++++++ .../src/pe/lim/lim_process_sme_req_messages.c | 40 ++++++++++------ core/mac/src/pe/lim/lim_utils.c | 12 +++-- core/sme/inc/csr_internal.h | 4 +- core/sme/src/common/sme_api.c | 5 +- core/sme/src/csr/csr_util.c | 42 +++++------------ 10 files changed, 142 insertions(+), 67 deletions(-) diff --git a/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c b/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c index cc645bc3a4..00edc88894 100644 --- a/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c +++ b/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c @@ -736,6 +736,16 @@ static inline uint32_t if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, struct validate_bss_data *candidate_info) { + struct qdf_mac_addr *mld_addr; + + /* If connection is happening on non-ML VDEV + * force the ML AP candidate as non-MLO to + * downgrade connection to 11ax. + */ + mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev); + if (qdf_is_macaddr_zero(mld_addr)) + return policy_mgr_get_conc_ext_flags(vdev, false); + return policy_mgr_get_conc_ext_flags(vdev, candidate_info->is_mlo); } diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index 8fccdc2de3..39f63799a0 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -851,6 +851,22 @@ qdf_freq_t wlan_get_operation_chan_freq_vdev_id(struct wlan_objmgr_pdev *pdev, enum QDF_OPMODE wlan_get_opmode_vdev_id(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id); +/** + * wlan_vdev_set_dot11mode - Set the dot11mode of the vdev + * @mac_mlme_cfg: MAC's MLME config pointer + * @device_mode: OPMODE of the vdev + * @vdev_mlme: MLME component of the vdev + * + * Use this API to set the dot11mode of the vdev. + * For non-ML type vdev, this API restricts the connection + * of vdev to 11ax on 11be capable operation. + * + * Return: void + */ +void wlan_vdev_set_dot11mode(struct wlan_mlme_cfg *mac_mlme_cfg, + enum QDF_OPMODE device_mode, + struct vdev_mlme_obj *vdev_mlme); + /** * wlan_is_open_wep_cipher() - check if cipher is open or WEP * @pdev: Pointer to pdev diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 5b36040837..84d90d29eb 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -3449,6 +3449,52 @@ enum QDF_OPMODE wlan_get_opmode_vdev_id(struct wlan_objmgr_pdev *pdev, return opmode; } +void wlan_vdev_set_dot11mode(struct wlan_mlme_cfg *mac_mlme_cfg, + enum QDF_OPMODE device_mode, + struct vdev_mlme_obj *vdev_mlme) +{ + uint8_t dot11_mode_indx; + uint8_t *mld_addr; + enum mlme_vdev_dot11_mode vdev_dot11_mode; + uint32_t mac_dot11_mode = + mac_mlme_cfg->dot11_mode.vdev_type_dot11_mode; + + switch (device_mode) { + default: + case QDF_STA_MODE: + dot11_mode_indx = STA_DOT11_MODE_INDX; + break; + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_DEVICE_MODE: + dot11_mode_indx = P2P_DEV_DOT11_MODE_INDX; + break; + case QDF_TDLS_MODE: + dot11_mode_indx = TDLS_DOT11_MODE_INDX; + break; + case QDF_NAN_DISC_MODE: + dot11_mode_indx = NAN_DISC_DOT11_MODE_INDX; + break; + case QDF_NDI_MODE: + dot11_mode_indx = NDI_DOT11_MODE_INDX; + break; + case QDF_OCB_MODE: + dot11_mode_indx = OCB_DOT11_MODE_INDX; + break; + } + + vdev_dot11_mode = QDF_GET_BITS(mac_dot11_mode, dot11_mode_indx, 4); + if (vdev_dot11_mode == MLME_VDEV_DOT11_MODE_AUTO || + vdev_dot11_mode == MLME_VDEV_DOT11_MODE_11BE) { + mld_addr = wlan_vdev_mlme_get_mldaddr(vdev_mlme->vdev); + if (qdf_is_macaddr_zero((struct qdf_mac_addr *)mld_addr)) { + vdev_dot11_mode = MLME_VDEV_DOT11_MODE_11AX; + vdev_mlme->proto.vdev_dot11_mode = vdev_dot11_mode; + } + } + mlme_debug("vdev%d: dot11_mode %d", wlan_vdev_get_id(vdev_mlme->vdev), + vdev_dot11_mode); +} + bool wlan_is_open_wep_cipher(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id) { struct wlan_objmgr_vdev *vdev; diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 139f09536e..8f8d28725c 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -251,21 +251,6 @@ enum mlme_dot11_mode { MLME_DOT11_MODE_11BE_ONLY }; -/** - * enum mlme_vdev_dot11_mode - Dot11 mode of the vdev - * MLME_VDEV_DOT11_MODE_AUTO: vdev uses mlme_dot11_mode - * MLME_VDEV_DOT11_MODE_11N: vdev supports 11N mode - * MLME_VDEV_DOT11_MODE_11AC: vdev supports 11AC mode - * MLME_VDEV_DOT11_MODE_11AX: vdev supports 11AX mode - */ -enum mlme_vdev_dot11_mode { - MLME_VDEV_DOT11_MODE_AUTO, - MLME_VDEV_DOT11_MODE_11N, - MLME_VDEV_DOT11_MODE_11AC, - MLME_VDEV_DOT11_MODE_11AX, - MLME_VDEV_DOT11_MODE_11BE, -}; - /** * struct wlan_mlme_dot11_mode - dot11 mode * diff --git a/core/hdd/src/wlan_hdd_cm_connect.c b/core/hdd/src/wlan_hdd_cm_connect.c index 71f3f40dd9..ef69dcc0d1 100644 --- a/core/hdd/src/wlan_hdd_cm_connect.c +++ b/core/hdd/src/wlan_hdd_cm_connect.c @@ -437,6 +437,23 @@ hdd_update_action_oui_for_connect(struct hdd_context *hdd_ctx, } #endif +#ifdef WLAN_FEATURE_11BE +static inline bool +hdd_config_is_dot11mode_11be_only(struct hdd_config *config) +{ + if (config->dot11Mode == eHDD_DOT11_MODE_11be_ONLY) + return true; + else + return false; +} +#else +static inline bool +hdd_config_is_dot11mode_11be_only(struct hdd_config *config) +{ + return false; +} +#endif + /** * hdd_get_dot11mode_filter() - Get dot11 mode filter * @hdd_ctx: HDD context @@ -457,6 +474,8 @@ hdd_get_dot11mode_filter(struct hdd_context *hdd_ctx) return ALLOW_11AC_ONLY; else if (config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) return ALLOW_11AX_ONLY; + else if (hdd_config_is_dot11mode_11be_only(config)) + return ALLOW_11BE_ONLY; else return ALLOW_ALL; } diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index b821919c48..49e417e676 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -1931,28 +1931,31 @@ static void lim_check_oui_and_update_session(struct mac_context *mac_ctx, } static enum mlme_dot11_mode -lim_get_self_dot11_mode(struct mac_context *mac_ctx, enum QDF_OPMODE opmode) +lim_get_self_dot11_mode(struct mac_context *mac_ctx, enum QDF_OPMODE opmode, + uint8_t vdev_id) { + struct wlan_objmgr_vdev *vdev; + struct vdev_mlme_obj *vdev_mlme; + enum mlme_vdev_dot11_mode vdev_dot11_mode; enum mlme_dot11_mode self_dot11_mode = mac_ctx->mlme_cfg->dot11_mode.dot11_mode; - enum mlme_vdev_dot11_mode vdev_dot11_mode; - uint8_t dot11_mode_indx; - uint32_t vdev_type_dot11_mode = - mac_ctx->mlme_cfg->dot11_mode.vdev_type_dot11_mode; switch (opmode) { case QDF_STA_MODE: - dot11_mode_indx = STA_DOT11_MODE_INDX; - break; case QDF_P2P_CLIENT_MODE: - dot11_mode_indx = P2P_DEV_DOT11_MODE_INDX; break; default: return self_dot11_mode; } - vdev_dot11_mode = QDF_GET_BITS(vdev_type_dot11_mode, dot11_mode_indx, - 4); + vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, vdev_id, + WLAN_MLME_OBJMGR_ID); + if (!vdev) + return self_dot11_mode; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + vdev_dot11_mode = vdev_mlme->proto.vdev_dot11_mode; + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); pe_debug("self_dot11_mode %d, vdev_dot11 %d, dev_mode %d", self_dot11_mode, vdev_dot11_mode, opmode); @@ -1972,6 +1975,10 @@ lim_get_self_dot11_mode(struct mac_context *mac_ctx, enum QDF_OPMODE opmode) vdev_dot11_mode == MLME_VDEV_DOT11_MODE_11AX) return MLME_DOT11_MODE_11AX; + if (IS_DOT11_MODE_EHT(self_dot11_mode) && + vdev_dot11_mode == MLME_VDEV_DOT11_MODE_11BE) + return MLME_DOT11_MODE_11BE; + return self_dot11_mode; } @@ -2613,7 +2620,8 @@ lim_fill_dot11_mode(struct mac_context *mac_ctx, struct pe_session *session, enum mlme_dot11_mode bss_dot11_mode; enum mlme_dot11_mode intersected_mode; - self_dot11_mode = lim_get_self_dot11_mode(mac_ctx, session->opmode); + self_dot11_mode = lim_get_self_dot11_mode(mac_ctx, session->opmode, + session->vdev_id); bss_dot11_mode = lim_get_bss_dot11_mode(mac_ctx, bss_desc, ie_struct); pe_debug("vdev id %d opmode %d self dot11mode %d bss_dot11 mode %d", @@ -5012,7 +5020,8 @@ QDF_STATUS cm_process_reassoc_req(struct scheduler_msg *msg) static QDF_STATUS lim_fill_preauth_req_dot11_mode(struct mac_context *mac_ctx, - tpSirFTPreAuthReq req) + tpSirFTPreAuthReq req, + uint8_t vdev_id) { QDF_STATUS status; tDot11fBeaconIEs *ie_struct; @@ -5028,7 +5037,8 @@ lim_fill_preauth_req_dot11_mode(struct mac_context *mac_ctx, return QDF_STATUS_E_FAILURE; } - self_dot11_mode = lim_get_self_dot11_mode(mac_ctx, QDF_STA_MODE); + self_dot11_mode = lim_get_self_dot11_mode(mac_ctx, QDF_STA_MODE, + vdev_id); bss_dot11_mode = lim_get_bss_dot11_mode(mac_ctx, bss_desc, ie_struct); status = lim_get_intersected_dot11_mode_sta_ap(mac_ctx, self_dot11_mode, @@ -5090,14 +5100,14 @@ static QDF_STATUS lim_cm_handle_preauth_req(struct wlan_preauth_req *req) goto end; } + vdev_id = req->vdev_id; preauth_req->pbssDescription = bss_desc; - status = lim_fill_preauth_req_dot11_mode(mac_ctx, preauth_req); + status = lim_fill_preauth_req_dot11_mode(mac_ctx, preauth_req, vdev_id); if (QDF_IS_STATUS_ERROR(status)) { pe_err("dot11mode doesn't get proper filling"); goto end; } - vdev_id = req->vdev_id; vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, vdev_id, WLAN_MLME_CM_ID); if (!vdev) { diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 824855373c..9cf7bbdb18 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -5749,7 +5749,9 @@ static bool is_dot11mode_support_ht_cap(enum csr_cfgdot11mode dot11mode) (dot11mode == eCSR_CFG_DOT11_MODE_11N_ONLY) || (dot11mode == eCSR_CFG_DOT11_MODE_11AC_ONLY) || (dot11mode == eCSR_CFG_DOT11_MODE_11AX) || - (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY)) { + (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY) || + (dot11mode == eCSR_CFG_DOT11_MODE_11BE) || + (dot11mode == eCSR_CFG_DOT11_MODE_11BE_ONLY)) { return true; } @@ -5770,7 +5772,9 @@ static bool is_dot11mode_support_vht_cap(enum csr_cfgdot11mode dot11mode) (dot11mode == eCSR_CFG_DOT11_MODE_11AC) || (dot11mode == eCSR_CFG_DOT11_MODE_11AC_ONLY) || (dot11mode == eCSR_CFG_DOT11_MODE_11AX) || - (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY)) { + (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY) || + (dot11mode == eCSR_CFG_DOT11_MODE_11BE) || + (dot11mode == eCSR_CFG_DOT11_MODE_11BE_ONLY)) { return true; } @@ -5789,7 +5793,9 @@ static bool is_dot11mode_support_he_cap(enum csr_cfgdot11mode dot11mode) { if ((dot11mode == eCSR_CFG_DOT11_MODE_AUTO) || (dot11mode == eCSR_CFG_DOT11_MODE_11AX) || - (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY)) { + (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY) || + (dot11mode == eCSR_CFG_DOT11_MODE_11BE) || + (dot11mode == eCSR_CFG_DOT11_MODE_11BE_ONLY)) { return true; } diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index 2cfe56c910..6bf2a26577 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -407,7 +407,7 @@ struct csr_roamstruct { /** * csr_get_vdev_dot11_mode() - get the supported dot11mode by vdev * @mac_ctx: pointer to global mac structure - * @device_mode: vdev mode + * @vdev_id: vdev id * @curr_dot11_mode: Current dot11 mode * * The function return the min of supported dot11 mode and vdev type dot11mode @@ -417,7 +417,7 @@ struct csr_roamstruct { */ enum csr_cfgdot11mode csr_get_vdev_dot11_mode(struct mac_context *mac, - enum QDF_OPMODE device_mode, + uint8_t vdev_id, enum csr_cfgdot11mode curr_dot11_mode); QDF_STATUS csr_get_channel_and_power_list(struct mac_context *mac); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index d1d93981c0..9777f50219 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -4767,6 +4767,9 @@ QDF_STATUS sme_vdev_post_vdev_create_setup(mac_handle_t mac_handle, goto cleanup_wma; } + wlan_vdev_set_dot11mode(mac_ctx->mlme_cfg, vdev->vdev_mlme.vdev_opmode, + vdev_mlme); + status = mlme_vdev_self_peer_create(vdev); if (QDF_IS_STATUS_ERROR(status)) { sme_err("Failed to create vdev selfpeer for vdev:%d", vdev_id); @@ -12612,7 +12615,7 @@ void sme_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id, p_msg->vdev_id = vdev_id; p_msg->device_mode = device_mode; - p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, device_mode, + p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, vdev_id, curr_dot11_mode); p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND; p_msg->len = sizeof(*p_msg); diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index f90e64fac9..0807ee161a 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -305,43 +305,23 @@ bool csr_is_conn_state_wds(struct mac_context *mac, uint32_t sessionId) enum csr_cfgdot11mode csr_get_vdev_dot11_mode(struct mac_context *mac, - enum QDF_OPMODE device_mode, + uint8_t vdev_id, enum csr_cfgdot11mode curr_dot11_mode) { + struct wlan_objmgr_vdev *vdev; + struct vdev_mlme_obj *vdev_mlme; enum mlme_vdev_dot11_mode vdev_dot11_mode; - uint8_t dot11_mode_indx; enum csr_cfgdot11mode dot11_mode = curr_dot11_mode; - uint32_t vdev_type_dot11_mode = - mac->mlme_cfg->dot11_mode.vdev_type_dot11_mode; - sme_debug("curr_dot11_mode %d, vdev_dot11 %08X, dev_mode %d", - curr_dot11_mode, vdev_type_dot11_mode, device_mode); + vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id, + WLAN_MLME_OBJMGR_ID); + if (!vdev) + return curr_dot11_mode; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + vdev_dot11_mode = vdev_mlme->proto.vdev_dot11_mode; + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); - switch (device_mode) { - case QDF_STA_MODE: - dot11_mode_indx = STA_DOT11_MODE_INDX; - break; - case QDF_P2P_CLIENT_MODE: - case QDF_P2P_DEVICE_MODE: - dot11_mode_indx = P2P_DEV_DOT11_MODE_INDX; - break; - case QDF_TDLS_MODE: - dot11_mode_indx = TDLS_DOT11_MODE_INDX; - break; - case QDF_NAN_DISC_MODE: - dot11_mode_indx = NAN_DISC_DOT11_MODE_INDX; - break; - case QDF_NDI_MODE: - dot11_mode_indx = NDI_DOT11_MODE_INDX; - break; - case QDF_OCB_MODE: - dot11_mode_indx = OCB_DOT11_MODE_INDX; - break; - default: - return dot11_mode; - } - vdev_dot11_mode = QDF_GET_BITS(vdev_type_dot11_mode, - dot11_mode_indx, 4); if (vdev_dot11_mode == MLME_VDEV_DOT11_MODE_AUTO) dot11_mode = curr_dot11_mode;