diff --git a/components/action_oui/core/inc/wlan_action_oui_main.h b/components/action_oui/core/inc/wlan_action_oui_main.h index c306bc743e..61609e1767 100644 --- a/components/action_oui/core/inc/wlan_action_oui_main.h +++ b/components/action_oui/core/inc/wlan_action_oui_main.h @@ -93,6 +93,18 @@ action_oui_psoc_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg); bool wlan_action_oui_search(struct wlan_objmgr_psoc *psoc, struct action_oui_search_attr *attr, enum action_oui_id action_id); + +/** + * wlan_action_oui_is_empty() - Check action oui present or not + * @psoc: psoc object + * @action_id: action oui id + * + * This function will check action oui present or not for specific action type. + * + * Return: True if no action oui for the action type. + */ +bool wlan_action_oui_is_empty(struct wlan_objmgr_psoc *psoc, + enum action_oui_id action_id); #else static inline bool wlan_action_oui_search(struct wlan_objmgr_psoc *psoc, @@ -101,5 +113,12 @@ bool wlan_action_oui_search(struct wlan_objmgr_psoc *psoc, { return false; } + +static inline +bool wlan_action_oui_is_empty(struct wlan_objmgr_psoc *psoc, + enum action_oui_id action_id) +{ + return true; +} #endif #endif /* end of _WLAN_ACTION_OUI_MAIN_H_ */ diff --git a/components/action_oui/core/inc/wlan_action_oui_priv.h b/components/action_oui/core/inc/wlan_action_oui_priv.h index 2b325b4ae8..c150809b62 100644 --- a/components/action_oui/core/inc/wlan_action_oui_priv.h +++ b/components/action_oui/core/inc/wlan_action_oui_priv.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -144,4 +145,16 @@ action_oui_search(struct action_oui_psoc_priv *psoc_priv, struct action_oui_search_attr *attr, enum action_oui_id action_id); +/** + * action_oui_is_empty() - Check action oui present or not + * @psoc_priv: action psoc private object + * @action_id: action oui id + * + * This function will check action oui present or not for specific action type. + * + * Return: True if no action oui for the action type. + */ +bool +action_oui_is_empty(struct action_oui_psoc_priv *psoc_priv, + enum action_oui_id action_id); #endif /* End of _WLAN_ACTION_OUI_PRIV_STRUCT_H_ */ diff --git a/components/action_oui/core/src/wlan_action_oui_main.c b/components/action_oui/core/src/wlan_action_oui_main.c index 7818670388..935de6c197 100644 --- a/components/action_oui/core/src/wlan_action_oui_main.c +++ b/components/action_oui/core/src/wlan_action_oui_main.c @@ -228,3 +228,31 @@ exit: return found; } +bool wlan_action_oui_is_empty(struct wlan_objmgr_psoc *psoc, + enum action_oui_id action_id) +{ + struct action_oui_psoc_priv *psoc_priv; + bool empty = true; + + if (!psoc) { + action_oui_err("Invalid psoc"); + goto exit; + } + + if (action_id >= ACTION_OUI_MAXIMUM_ID) { + action_oui_err("Invalid action_oui id: %u", action_id); + goto exit; + } + + psoc_priv = action_oui_psoc_get_priv(psoc); + if (!psoc_priv) { + action_oui_err("psoc priv is NULL"); + goto exit; + } + + empty = action_oui_is_empty(psoc_priv, action_id); + +exit: + return empty; +} + diff --git a/components/action_oui/core/src/wlan_action_oui_parse.c b/components/action_oui/core/src/wlan_action_oui_parse.c index 82868ae322..5d122ed2d3 100644 --- a/components/action_oui/core/src/wlan_action_oui_parse.c +++ b/components/action_oui/core/src/wlan_action_oui_parse.c @@ -868,6 +868,33 @@ action_oui_get_oui_ptr(struct action_oui_extension *extension, attr->ie_length); } +bool +action_oui_is_empty(struct action_oui_psoc_priv *psoc_priv, + enum action_oui_id action_id) +{ + struct action_oui_priv *oui_priv; + qdf_list_t *extension_list; + + oui_priv = psoc_priv->oui_priv[action_id]; + if (!oui_priv) { + action_oui_debug("action oui for id %d is empty", + action_id); + return true; + } + + extension_list = &oui_priv->extension_list; + qdf_mutex_acquire(&oui_priv->extension_lock); + if (qdf_list_empty(extension_list)) { + qdf_mutex_release(&oui_priv->extension_lock); + action_oui_debug("action oui for id %d list is empty", + action_id); + return true; + } + qdf_mutex_release(&oui_priv->extension_lock); + + return false; +} + bool action_oui_search(struct action_oui_psoc_priv *psoc_priv, struct action_oui_search_attr *attr, diff --git a/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h b/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h index a659b0a3dc..4a60fbe5f7 100644 --- a/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h +++ b/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h @@ -94,6 +94,8 @@ * @ACTION_OUI_DISABLE_TWT: disable TWT with the ap * @ACTION_OUI_EXTEND_WOW_ITO: extend ITO under WOW mode if vendor OUI is * received in beacon. + * @ACTION_OUI_11BE_OUI_ALLOW: ap oui for which station can connect with + * 11be mode * @ACTION_OUI_HOST_ONLY: host only action id start - placeholder. * New Firmware related "ACTION" needs to be added before this placeholder. * @ACTION_OUI_HOST_RECONN: reconnect to the same BSSID when wait for @@ -113,6 +115,7 @@ enum action_oui_id { ACTION_OUI_DISABLE_AGGRESSIVE_EDCA = 8, ACTION_OUI_DISABLE_TWT = 9, ACTION_OUI_EXTEND_WOW_ITO = 10, + ACTION_OUI_11BE_OUI_ALLOW = 11, ACTION_OUI_HOST_ONLY, ACTION_OUI_HOST_RECONN = ACTION_OUI_HOST_ONLY, ACTION_OUI_TAKE_ALL_BAND_INFO, 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 976bc87e0a..55cacaecda 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 @@ -738,6 +738,26 @@ if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, { return policy_mgr_get_conc_ext_flags(vdev, candidate_info->is_mlo); } + +static void if_mgr_update_candidate(struct wlan_objmgr_psoc *psoc, + struct validate_bss_data *candidate_info) +{ + struct scan_cache_entry *scan_entry = candidate_info->scan_entry; + + if (!(scan_entry->ie_list.multi_link || scan_entry->ie_list.ehtcap || + scan_entry->ie_list.ehtop)) + return; + + if (mlme_get_bss_11be_allowed(psoc, &candidate_info->peer_addr, + util_scan_entry_ie_data(scan_entry), + util_scan_entry_ie_len(scan_entry))) + return; + scan_entry->ie_list.multi_link = NULL; + scan_entry->ie_list.ehtcap = NULL; + scan_entry->ie_list.ehtop = NULL; + qdf_mem_zero(&scan_entry->ml_info, sizeof(scan_entry->ml_info)); + candidate_info->is_mlo = false; +} #else static inline uint32_t if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, @@ -745,6 +765,11 @@ if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, { return 0; } + +static void if_mgr_update_candidate(struct wlan_objmgr_psoc *psoc, + struct validate_bss_data *candidate_info) +{ +} #endif QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev, @@ -770,6 +795,7 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev, if (!psoc) return QDF_STATUS_E_FAILURE; + if_mgr_update_candidate(psoc, candidate_info); /* * Do not allow STA to connect on 6Ghz or indoor channel for non dbs * hardware if SAP and skip_6g_and_indoor_freq_scan ini are present diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 58e4c887a8..477d7e9ad0 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -2224,6 +2224,31 @@ mlme_update_vht_cap(struct wlan_objmgr_psoc *psoc, struct wma_tgt_vht_cap *cfg); */ QDF_STATUS mlme_update_nss_vht_cap(struct wlan_objmgr_psoc *psoc); +#ifdef WLAN_FEATURE_11BE +/** + * mlme_get_bss_11be_allowed() - Check BSS allowed in 11be mode + * @psoc: psoc context + * @bssid: bssid + * @ie_date: ie data + * @ie_length: ie data length + * + * Return: true if AP in 11be oui allow list + */ +bool mlme_get_bss_11be_allowed(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *bssid, + uint8_t *ie_data, + uint32_t ie_length); +#else +static inline +bool mlme_get_bss_11be_allowed(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *bssid, + uint8_t *ie_data, + uint32_t ie_length) +{ + return false; +} +#endif + /** * wlan_mlme_is_sap_uapsd_enabled() - Get if SAP UAPSD is enabled/disabled * @psoc: psoc context diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 28f9cb3b63..d3fb6e0d6e 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -33,6 +33,7 @@ #include "wlan_vdev_mgr_utils_api.h" #include <../../core/src/wlan_cm_vdev_api.h> #include "wlan_psoc_mlme_api.h" +#include "wlan_action_oui_main.h" /* quota in milliseconds */ #define MCC_DUTY_CYCLE 70 @@ -3975,6 +3976,31 @@ QDF_STATUS mlme_update_nss_vht_cap(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +#ifdef WLAN_FEATURE_11BE +bool mlme_get_bss_11be_allowed(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *bssid, + uint8_t *ie_data, + uint32_t ie_length) +{ + struct action_oui_search_attr search_attr; + + if (wlan_action_oui_is_empty(psoc, ACTION_OUI_11BE_OUI_ALLOW)) + return true; + + qdf_mem_zero(&search_attr, sizeof(search_attr)); + search_attr.ie_data = ie_data; + search_attr.ie_length = ie_length; + if (wlan_action_oui_search(psoc, &search_attr, + ACTION_OUI_11BE_OUI_ALLOW)) + return true; + + mlme_legacy_debug("AP not in 11be oui allow list "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(bssid->bytes)); + + return false; +} +#endif + QDF_STATUS wlan_mlme_is_sap_uapsd_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { diff --git a/core/hdd/inc/hdd_config.h b/core/hdd/inc/hdd_config.h index 3aa77b4ee5..516ef04bb9 100644 --- a/core/hdd/inc/hdd_config.h +++ b/core/hdd/inc/hdd_config.h @@ -1515,6 +1515,32 @@ struct dhcp_server { "0017f2 01 0a 80 01", \ "Used to specify action OUIs to control country ie") +/* + * + * g11be_oui_allow_list - Used to specify 802.11be allowed ap oui list + * + * This ini is used to specify AP OUIs for which station can connect + * in 802.11be mode with the 802.11be AP. + * If no OUI set, then allow STA to connect to All 802.11be AP in 802.11be + * mode. + * If INI is set to "ffffff 00 01", then STA is not allowed to connect to + * any AP in 802.11be mode. + * + * Related: None + * + * Supported Feature: Action OUIs + * + * Usage: External + * + * + */ +#define CFG_ACTION_11BE_OUI_ALLOW_LIST CFG_INI_STRING( \ + "g11be_oui_allow_list", \ + 0, \ + ACTION_OUI_MAX_STR_LEN, \ + "", \ + "Used to specify 11be allowed ap oui list") + /* End of action oui inis */ #ifdef ENABLE_MTRACE_LOG @@ -1938,6 +1964,7 @@ enum host_log_level { CFG(CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT) \ CFG(CFG_ACTION_OUI_DISABLE_TWT) \ CFG(CFG_ACTION_OUI_TAKE_ALL_BAND_INFO) \ + CFG(CFG_ACTION_11BE_OUI_ALLOW_LIST) \ CFG(CFG_ADVERTISE_CONCURRENT_OPERATION) \ CFG(CFG_BUG_ON_REINIT_FAILURE) \ CFG(CFG_DBS_SCAN_SELECTION) \ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index afc2d21fb5..2e39750535 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -12654,6 +12654,9 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) qdf_str_lcopy(config->action_oui_str[ACTION_OUI_TAKE_ALL_BAND_INFO], cfg_get(psoc, CFG_ACTION_OUI_TAKE_ALL_BAND_INFO), ACTION_OUI_MAX_STR_LEN); + qdf_str_lcopy(config->action_oui_str[ACTION_OUI_11BE_OUI_ALLOW], + cfg_get(psoc, CFG_ACTION_11BE_OUI_ALLOW_LIST), + ACTION_OUI_MAX_STR_LEN); config->is_unit_test_framework_enabled = cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK); 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 82018026b8..d3c5e7af29 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 @@ -1506,7 +1506,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, if (lim_process_srp_ie(assoc_rsp, sta_ds) == QDF_STATUS_SUCCESS) lim_update_vdev_sr_elements(session_entry, sta_ds); - lim_process_eht_info(beacon, sta_ds); + if (lim_is_session_eht_capable(session_entry)) + lim_process_eht_info(beacon, sta_ds); if (mac_ctx->lim.gLimProtectionControl != MLME_FORCE_POLICY_PROTECTION_DISABLE) 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 31331b7c83..fc04a51857 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 @@ -1975,8 +1975,24 @@ lim_get_self_dot11_mode(struct mac_context *mac_ctx, enum QDF_OPMODE opmode) return self_dot11_mode; } +static bool +lim_get_bss_11be_mode_allowed(struct mac_context *mac_ctx, + struct bss_description *bss_desc, + tDot11fBeaconIEs *ie_struct) +{ + if (!ie_struct->eht_cap.present) + return false; + + return mlme_get_bss_11be_allowed( + mac_ctx->psoc, + (struct qdf_mac_addr *)&bss_desc->bssId, + (uint8_t *)&bss_desc->ieFields[0], + wlan_get_ielen_from_bss_description(bss_desc)); +} + static enum mlme_dot11_mode -lim_get_bss_dot11_mode(struct bss_description *bss_desc, +lim_get_bss_dot11_mode(struct mac_context *mac_ctx, + struct bss_description *bss_desc, tDot11fBeaconIEs *ie_struct) { enum mlme_dot11_mode bss_dot11_mode; @@ -2007,7 +2023,8 @@ lim_get_bss_dot11_mode(struct bss_description *bss_desc, if (ie_struct->he_cap.present) bss_dot11_mode = MLME_DOT11_MODE_11AX; - if (ie_struct->eht_cap.present) + if (ie_struct->eht_cap.present && + lim_get_bss_11be_mode_allowed(mac_ctx, bss_desc, ie_struct)) bss_dot11_mode = MLME_DOT11_MODE_11BE; pe_debug("bss HT %d VHT %d HE %d EHT %d nw_type %d bss dot11_mode %d", @@ -2597,7 +2614,7 @@ lim_fill_dot11_mode(struct mac_context *mac_ctx, struct pe_session *session, enum mlme_dot11_mode intersected_mode; self_dot11_mode = lim_get_self_dot11_mode(mac_ctx, session->opmode); - bss_dot11_mode = lim_get_bss_dot11_mode(bss_desc, ie_struct); + 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", session->vdev_id, session->opmode, self_dot11_mode, @@ -5007,7 +5024,7 @@ lim_fill_preauth_req_dot11_mode(struct mac_context *mac_ctx, } self_dot11_mode = lim_get_self_dot11_mode(mac_ctx, QDF_STA_MODE); - bss_dot11_mode = lim_get_bss_dot11_mode(bss_desc, ie_struct); + 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, bss_dot11_mode, diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 951f7d3730..2063b9d819 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -8236,6 +8236,10 @@ QDF_STATUS lim_populate_eht_mcs_set(struct mac_context *mac_ctx, pe_debug("peer not eht capable or eht_caps NULL"); return QDF_STATUS_SUCCESS; } + if (lim_is_session_eht_capable(session_entry)) { + pe_debug("session not eht capable"); + return QDF_STATUS_SUCCESS; + } switch (session_entry->ch_width) { case CH_WIDTH_320MHZ: