diff --git a/Kbuild b/Kbuild index 945fa0c5d160..fe0d494ee7a7 100644 --- a/Kbuild +++ b/Kbuild @@ -2615,7 +2615,6 @@ cppflags-$(CONFIG_THERMAL_STATS_SUPPORT) += -DTHERMAL_STATS_SUPPORT cppflags-$(CONFIG_PTT_SOCK_SVC_ENABLE) += -DPTT_SOCK_SVC_ENABLE cppflags-$(CONFIG_FEATURE_WLAN_WAPI) += -DFEATURE_WLAN_WAPI cppflags-$(CONFIG_FEATURE_WLAN_WAPI) += -DATH_SUPPORT_WAPI -cppflags-$(CONFIG_AGEIE_ON_SCAN_RESULTS) += -DWLAN_ENABLE_AGEIE_ON_SCAN_RESULTS cppflags-$(CONFIG_SOFTAP_CHANNEL_RANGE) += -DSOFTAP_CHANNEL_RANGE cppflags-$(CONFIG_FEATURE_WLAN_SCAN_PNO) += -DFEATURE_WLAN_SCAN_PNO cppflags-$(CONFIG_WLAN_FEATURE_PACKET_FILTERING) += -DWLAN_FEATURE_PACKET_FILTERING @@ -2853,6 +2852,7 @@ cppflags-y += -DCONN_MGR_ADV_FEATURE cppflags-$(CONFIG_QCACLD_WLAN_LFR3) += -DWLAN_FEATURE_ROAM_OFFLOAD cppflags-$(CONFIG_WLAN_FEATURE_MBSSID) += -DWLAN_FEATURE_MBSSID +cppflags-$(CONFIG_WLAN_FEATURE_P2P_P2P_STA) += -DWLAN_FEATURE_P2P_P2P_STA ifeq (y,$(findstring y, $(CONFIG_CNSS_GENL) $(CONFIG_CNSS_GENL_MODULE))) cppflags-y += -DCNSS_GENL @@ -3649,7 +3649,7 @@ ccflags-y += -DWLAN_PDEV_MAX_VDEVS=$(CONFIG_WLAN_PDEV_MAX_VDEVS) CONFIG_WLAN_PSOC_MAX_VDEVS ?= $(CONFIG_WLAN_MAX_VDEVS) ccflags-y += -DWLAN_PSOC_MAX_VDEVS=$(CONFIG_WLAN_PSOC_MAX_VDEVS) -CONFIG_MAX_SCAN_CACHE_SIZE ?= 300 +CONFIG_MAX_SCAN_CACHE_SIZE ?= 500 ccflags-y += -DMAX_SCAN_CACHE_SIZE=$(CONFIG_MAX_SCAN_CACHE_SIZE) CONFIG_SCAN_MAX_REST_TIME ?= 0 ccflags-y += -DSCAN_MAX_REST_TIME=$(CONFIG_SCAN_MAX_REST_TIME) diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 11add67ba3d7..429b34486e40 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -611,6 +611,125 @@ static inline void policy_mgr_change_sap_channel_with_csa( } #endif +#ifdef WLAN_FEATURE_P2P_P2P_STA +/** + * policy_mgr_is_p2p_p2p_conc_supported() - p2p concurrency support + * @psoc: pointer to psoc + * + * This API is used to check whether firmware supports p2p concurrency + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +bool +policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc); +#else +static inline bool +policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc) +{ + return false; +} +#endif + +#define GO_FORCE_SCC_DISABLE 0 +#define GO_FORCE_SCC_STRICT 1 +#define GO_FORCE_SCC_LIBERAL 2 +#ifdef WLAN_FEATURE_P2P_P2P_STA +/** + * Stay in MCC for 1 second, in case of first p2p go channel + * needs to be moved to curr go channel + */ +#define WAIT_BEFORE_GO_FORCESCC_RESTART (1000) + +/** + * policy_mgr_is_go_scc_strict() - Get GO force SCC enabled or not + * @psoc: psoc object + * + * This function checks if force SCC logic should be used on GO interface + * as a strict mode. + * + * Return: True if p2p needs o be start on provided channel only. + */ +bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_check_forcescc_for_other_go() - check if another p2pgo + * is present and find vdev id. + * + * @psoc: psoc object + * @vdev: vdev id + * @freq: frequency + * + * This function checks if another p2p go is there. + * + * Return: vdev_id + */ +uint8_t +policy_mgr_check_forcescc_for_other_go(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t curr_go_freq); + +/** + * policy_mgr_process_forcescc_for_go () - start work queue to move first p2p go + * to new p2p go's channel + * + * @psoc: PSOC object information + * @vdev_id: Vdev id + * @ch_freq: Channel frequency to change + * @ch_width: channel width to change + * + * starts delayed work queue of 1 second to move first p2p go to new + * p2p go's channel. + * + * Return: None + */ +void policy_mgr_process_forcescc_for_go( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + uint32_t ch_freq, uint32_t ch_width); + +/** + * policy_mgr_do_go_plus_go_force_scc() - First p2p go + * to new p2p go's channel + * + * @psoc: PSOC object information + * @vdev_id: Vdev id + * @ch_freq: Channel frequency to change + * @ch_width: channel width to change + * + * Move first p2p go to new + * p2p go's channel. + * + * Return: None + */ +void policy_mgr_do_go_plus_go_force_scc( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + uint32_t ch_freq, uint32_t ch_width); +#else +static inline +bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +static inline +uint8_t policy_mgr_check_forcescc_for_other_go(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint32_t curr_go_freq) +{ + return WLAN_UMAC_VDEV_ID_MAX; +} + +static inline +void policy_mgr_process_forcescc_for_go( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + uint32_t ch_freq, uint32_t ch_width) +{} + +static inline +void policy_mgr_do_go_plus_go_force_scc( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + uint32_t ch_freq, uint32_t ch_width) +{} +#endif + /** * policy_mgr_set_pcl_for_existing_combo() - SET PCL for existing combo * @psoc: PSOC object information @@ -3752,4 +3871,18 @@ QDF_STATUS policy_mgr_check_mon_concurrency(struct wlan_objmgr_psoc *psoc); bool policy_mgr_is_sta_chan_valid_for_connect_and_roam( struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); +/** + * policy_mgr_is_3rd_conn_on_same_band_allowed() - Check the third connection + * on same band allowed or not + * list for third connection + * @psoc: PSOC object information + * @mode: Device mode + * + * This function checks whether to allow third connection on same band or not + * based on pcl table + * + * Return: TRUE/FALSE + */ +bool policy_mgr_is_3rd_conn_on_same_band_allowed(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h index cf260ed21536..ddc65f739a14 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -548,12 +549,19 @@ CFG_INI_UINT("g_mark_sap_indoor_as_disable", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \ * * g_enable_go_force_scc - Enable/Disable force SCC on P2P GO * @Min: 0 - * @Max: 1 + * @Max: 2 * @Default: 0 * * This ini and along with "gWlanMccToSccSwitchMode" is used to enable * force SCC on P2P GO interface. * + * GO_FORCE_SCC_DISABLED (value 0): GO force scc disabled and GO can come up + * in MCC mode + * GO_FORCE_SCC_STRICT (value 1): New GO will be forced to form on existing + * GO/STA/GC channel in start bss itself. + * GO_FORCE_SCC_LIBERAL (value 2): After SET KEY is done, do force SCC for the + * first GO to move to new GO channel. + * * Supported Feature: P2P GO * * Usage: External @@ -562,7 +570,7 @@ CFG_INI_UINT("g_mark_sap_indoor_as_disable", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \ */ #define CFG_P2P_GO_ENABLE_FORCE_SCC \ -CFG_INI_UINT("g_enable_go_force_scc", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \ +CFG_INI_UINT("g_enable_go_force_scc", 0, 2, 0, CFG_VALUE_OR_DEFAULT, \ "Enable/Disable P2P GO force SCC") /** diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h index 9b807ad4d3d4..793bd23707a3 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -522,6 +523,21 @@ enum policy_mgr_one_connection_mode { * 2x2 * @PM_P2P_GO_SAP_SBS_5_1x1: P2P GO & SAP connection on 5G SBS * using 1x1 + * @PM_P2P_GO_P2P_GO_SCC_24_1x1: P2P GO & P2P GO SCC on 2.4G using 1x1 + * @PM_P2P_GO_P2P_GO_SCC_24_2x2: P2P GO & P2P GO SCC on 2.4G using 2x2 + * @PM_P2P_GO_P2P_GO_MCC_24_1x1: P2P GO & P2P GO MCC on 2.4G using 1x1 + * @PM_P2P_GO_P2P_GO_MCC_24_2x2: P2P GO & P2P GO MCC on 2.4G using 2x2 + * @PM_P2P_GO_P2P_GO_SCC_5_1x1: P2P GO & P2P GO SCC on 5G using 1x1 + * @PM_P2P_GO_P2P_GO_SCC_5_2x2: P2P GO & P2P GO SCC on 5G using 2x2 + * @PM_P2P_GO_P2P_GO_MCC_5_1x1: P2P GO & P2P GO MCC on 5G using 1x1 + * @PM_P2P_GO_P2P_GO_MCC_5_2x2: P2P GO & P2P GO MCC on 5G using 2x2 + * @PM_P2P_GO_P2P_GO_MCC_24_5_1x1: P2P GO 2.4G & P2P GO 5G dual band MCC + * using 1x1 + * @PM_P2P_GO_P2P_GO_MCC_24_5_2x2: P2P GO 2.4G & P2P GO 5G dual band MCC + * using 2x2 + * @PM_P2P_GO_P2P_GO_DBS_1x1: P2P GO & P2P GO on DBS using 1x1 + * @PM_P2P_GO_P2P_GO_DBS_2x2: P2P GO & P2P GO on DBS using 2x2 + * @PM_P2P_GO_P2P_GO_SBS_5_1x1: P2P GO & P2P GO on SBS using 1x1 * @PM_P2P_CLI_SAP_SCC_24_1x1: CLI & SAP connection on SCC using * 1x1@2.4 Ghz * @PM_P2P_CLI_SAP_SCC_24_2x2: CLI & SAP connection on SCC using @@ -547,6 +563,21 @@ enum policy_mgr_one_connection_mode { * 2x2 * @PM_P2P_CLI_SAP_SBS_5_1x1: P2P CLI & SAP connection on 5G SBS * using 1x1 + * @PM_P2P_CLI_P2P_CLI_SCC_24_1x1: P2P CLI & P2P CLI SCC on 2.4G using 1x1 + * @PM_P2P_CLI_P2P_CLI_SCC_24_2x2: P2P CLI & P2P CLI SCC on 2.4G using 2x2 + * @PM_P2P_CLI_P2P_CLI_MCC_24_1x1: P2P CLI & P2P CLI MCC on 2.4G using 1x1 + * @PM_P2P_CLI_P2P_CLI_MCC_24_2x2: P2P CLI & P2P CLI MCC on 2.4G using 2x2 + * @PM_P2P_CLI_P2P_CLI_SCC_5_1x1: P2P CLI & P2P CLI SCC on 5G using 1x1 + * @PM_P2P_CLI_P2P_CLI_SCC_5_2x2: P2P CLI & P2P CLI SCC on 5G using 2x2 + * @PM_P2P_CLI_P2P_CLI_MCC_5_1x1: P2P CLI & P2P CLI MCC on 5G using 1x1 + * @PM_P2P_CLI_P2P_CLI_MCC_5_2x2: P2P CLI & P2P CLI MCC on 5G using 2x2 + * @PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1: P2P CLI 2.4G & P2P CLI 5G dual band MCC + * using 1x1 + * @PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2: P2P CLI 2.4G & P2P CLI 5G dual band MCC + * using 2x2 + * @PM_P2P_CLI_P2P_CLI_DBS_1x1: P2P CLI & P2P CLI on DBS using 1x1 + * @PM_P2P_CLI_P2P_CLI_DBS_2x2: P2P CLI & P2P CLI on DBS using 2x2 + * @PM_P2P_CLI_P2P_CLI_SBS_5_1x1: P2P CLI & P2P CLI on SBS using 1x1 * @PM_SAP_SAP_SCC_24_1x1: SAP & SAP connection on * SCC using 1x1@2.4 Ghz * @PM_SAP_SAP_SCC_24_2x2: SAP & SAP connection on @@ -617,21 +648,6 @@ enum policy_mgr_one_connection_mode { * @PM_NAN_DISC_NDI_MCC_24_2x2: NAN & NDI connection on MCC using 2x2 on 2.4 GHz * @PM_NAN_DISC_NDI_DBS_1x1: NAN & NDI connection on DBS using 1x1 * @PM_NAN_DISC_NDI_DBS_2x2: NAN & NDI connection on DBS using 2x2 - * @PM_P2P_GO_P2P_GO_SCC_24_1x1: P2P GO & P2P GO SCC on 2.4G using 1x1 - * @PM_P2P_GO_P2P_GO_SCC_24_2x2: P2P GO & P2P GO SCC on 2.4G using 2x2 - * @PM_P2P_GO_P2P_GO_MCC_24_1x1: P2P GO & P2P GO MCC on 2.4G using 1x1 - * @PM_P2P_GO_P2P_GO_MCC_24_2x2: P2P GO & P2P GO MCC on 2.4G using 2x2 - * @PM_P2P_GO_P2P_GO_SCC_5_1x1: P2P GO & P2P GO SCC on 5G using 1x1 - * @PM_P2P_GO_P2P_GO_SCC_5_2x2: P2P GO & P2P GO SCC on 5G using 2x2 - * @PM_P2P_GO_P2P_GO_MCC_5_1x1: P2P GO & P2P GO MCC on 5G using 1x1 - * @PM_P2P_GO_P2P_GO_MCC_5_2x2: P2P GO & P2P GO MCC on 5G using 2x2 - * @PM_P2P_GO_P2P_GO_MCC_24_5_1x1: P2P GO 2.4G & P2P GO 5G dual band MCC - * using 1x1 - * @PM_P2P_GO_P2P_GO_MCC_24_5_2x2: P2P GO 2.4G & P2P GO 5G dual band MCC - * using 2x2 - * @PM_P2P_GO_P2P_GO_DBS_1x1: P2P GO & P2P GO on DBS using 1x1 - * @PM_P2P_GO_P2P_GO_DBS_2x2: P2P GO & P2P GO on DBS using 2x2 - * @PM_P2P_GO_P2P_GO_SBS_5_1x1: P2P GO & P2P GO on SBS using 1x1 * * These are generic IDs that identify the various roles in the * software system @@ -702,6 +718,21 @@ enum policy_mgr_two_connection_mode { PM_P2P_GO_SAP_DBS_1x1, PM_P2P_GO_SAP_DBS_2x2, PM_P2P_GO_SAP_SBS_5_1x1, + PM_P2P_GO_SAP_SBS_5_2x2 = PM_P2P_GO_SAP_SBS_5_1x1, + PM_P2P_GO_P2P_GO_SCC_24_1x1, + PM_P2P_GO_P2P_GO_SCC_24_2x2, + PM_P2P_GO_P2P_GO_MCC_24_1x1, + PM_P2P_GO_P2P_GO_MCC_24_2x2, + PM_P2P_GO_P2P_GO_SCC_5_1x1, + PM_P2P_GO_P2P_GO_SCC_5_2x2, + PM_P2P_GO_P2P_GO_MCC_5_1x1, + PM_P2P_GO_P2P_GO_MCC_5_2x2, + PM_P2P_GO_P2P_GO_MCC_24_5_1x1, + PM_P2P_GO_P2P_GO_MCC_24_5_2x2, + PM_P2P_GO_P2P_GO_DBS_1x1, + PM_P2P_GO_P2P_GO_DBS_2x2, + PM_P2P_GO_P2P_GO_SBS_5_1x1, + PM_P2P_GO_P2P_GO_SBS_5_2x2 = PM_P2P_GO_P2P_GO_SBS_5_1x1, PM_P2P_CLI_SAP_SCC_24_1x1, PM_P2P_CLI_SAP_SCC_24_2x2, PM_P2P_CLI_SAP_MCC_24_1x1, @@ -715,6 +746,21 @@ enum policy_mgr_two_connection_mode { PM_P2P_CLI_SAP_DBS_1x1, PM_P2P_CLI_SAP_DBS_2x2, PM_P2P_CLI_SAP_SBS_5_1x1, + PM_P2P_CLI_SAP_SBS_5_2x2 = PM_P2P_CLI_SAP_SBS_5_1x1, + PM_P2P_CLI_P2P_CLI_SCC_24_1x1, + PM_P2P_CLI_P2P_CLI_SCC_24_2x2, + PM_P2P_CLI_P2P_CLI_MCC_24_1x1, + PM_P2P_CLI_P2P_CLI_MCC_24_2x2, + PM_P2P_CLI_P2P_CLI_SCC_5_1x1, + PM_P2P_CLI_P2P_CLI_SCC_5_2x2, + PM_P2P_CLI_P2P_CLI_MCC_5_1x1, + PM_P2P_CLI_P2P_CLI_MCC_5_2x2, + PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1, + PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2, + PM_P2P_CLI_P2P_CLI_DBS_1x1, + PM_P2P_CLI_P2P_CLI_DBS_2x2, + PM_P2P_CLI_P2P_CLI_SBS_5_1x1, + PM_P2P_CLI_P2P_CLI_SBS_5_2x2 = PM_P2P_CLI_P2P_CLI_SBS_5_1x1, PM_SAP_SAP_SCC_24_1x1, PM_SAP_SAP_SCC_24_2x2, PM_SAP_SAP_MCC_24_1x1, @@ -759,19 +805,6 @@ enum policy_mgr_two_connection_mode { PM_NAN_DISC_NDI_MCC_24_2x2, PM_NAN_DISC_NDI_DBS_1x1, PM_NAN_DISC_NDI_DBS_2x2, - PM_P2P_GO_P2P_GO_SCC_24_1x1, - PM_P2P_GO_P2P_GO_SCC_24_2x2, - PM_P2P_GO_P2P_GO_MCC_24_1x1, - PM_P2P_GO_P2P_GO_MCC_24_2x2, - PM_P2P_GO_P2P_GO_SCC_5_1x1, - PM_P2P_GO_P2P_GO_SCC_5_2x2, - PM_P2P_GO_P2P_GO_MCC_5_1x1, - PM_P2P_GO_P2P_GO_MCC_5_2x2, - PM_P2P_GO_P2P_GO_MCC_24_5_1x1, - PM_P2P_GO_P2P_GO_MCC_24_5_2x2, - PM_P2P_GO_P2P_GO_DBS_1x1, - PM_P2P_GO_P2P_GO_DBS_2x2, - PM_P2P_GO_P2P_GO_SBS_5_1x1, PM_MAX_TWO_CONNECTION_MODE }; @@ -1284,12 +1317,30 @@ struct connection_info { uint32_t ch_freq; }; +/** + * struct go_plus_go_force_scc - structure to hold p2p go + * params for forcescc restart + * + * @vdev_id: vdev id of first p2p go which needs to do csa + * @ch_freq: ch freq of curr p2p go + * @ch_width: ch width of curr p2p go + */ +struct go_plus_go_force_scc { + uint8_t vdev_id; + uint32_t ch_freq; + uint32_t ch_width; +}; + /** * struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work * related info * @psoc: pointer to PSOC object information + * @go_plus_go_force_scc: structure to hold params of + * curr and first p2p go ctx */ struct sta_ap_intf_check_work_ctx { struct wlan_objmgr_psoc *psoc; + struct go_plus_go_force_scc go_plus_go_force_scc; }; + #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index d0db9e64a6fa..8bddabd08af7 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -1974,53 +1975,55 @@ end: pm_ctx->do_sap_unsafe_ch_check = false; } -static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) +static void __policy_mgr_check_sta_ap_concurrent_ch_intf( + struct policy_mgr_psoc_priv_obj *pm_ctx) { - struct wlan_objmgr_psoc *psoc; - struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; - struct sta_ap_intf_check_work_ctx *work_info = NULL; uint32_t mcc_to_scc_switch, cc_count = 0, i; QDF_STATUS status; uint32_t ch_freq; uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; - work_info = data; - if (!work_info) { - policy_mgr_err("Invalid work_info"); - return; - } - - psoc = work_info->psoc; - if (!psoc) { - policy_mgr_err("Invalid psoc"); - return; - } - - pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid context"); return; } + /* + * Check if force scc is required for GO + GO case. vdev id will be + * valid in case of GO+GO force scc only. So, for valid vdev id move + * first GO to newly formed GO channel. + */ + policy_mgr_debug("p2p go vdev id: %d", + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id); + if (pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id < + WLAN_UMAC_VDEV_ID_MAX) { + policy_mgr_do_go_plus_go_force_scc( + pm_ctx->psoc, pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id, + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.ch_freq, + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.ch_width); + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id = WLAN_UMAC_VDEV_ID_MAX; + return; + } mcc_to_scc_switch = - policy_mgr_get_mcc_to_scc_switch_mode(psoc); + policy_mgr_get_mcc_to_scc_switch_mode(pm_ctx->psoc); policy_mgr_debug("Concurrent open sessions running: %d", - policy_mgr_concurrent_open_sessions_running(psoc)); + policy_mgr_concurrent_open_sessions_running( + pm_ctx->psoc)); - if (!policy_mgr_is_sap_go_existed(psoc)) + if (!policy_mgr_is_sap_go_existed(pm_ctx->psoc)) goto end; cc_count = policy_mgr_get_mode_specific_conn_info( - psoc, &op_ch_freq_list[cc_count], + pm_ctx->psoc, &op_ch_freq_list[cc_count], &vdev_id[cc_count], PM_SAP_MODE); policy_mgr_debug("Number of concurrent SAP: %d", cc_count); if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) cc_count = cc_count + - policy_mgr_get_mode_specific_conn_info( - psoc, &op_ch_freq_list[cc_count], - &vdev_id[cc_count], PM_P2P_GO_MODE); + policy_mgr_get_mode_specific_conn_info( + pm_ctx->psoc, &op_ch_freq_list[cc_count], + &vdev_id[cc_count], PM_P2P_GO_MODE); policy_mgr_debug("Number of beaconing entities (SAP + GO):%d", cc_count); if (!cc_count) { @@ -2046,7 +2049,7 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) for (i = 0; i < cc_count; i++) { status = pm_ctx->hdd_cbacks. wlan_hdd_get_channel_for_sap_restart - (psoc, vdev_id[i], &ch_freq); + (pm_ctx->psoc, vdev_id[i], &ch_freq); if (status == QDF_STATUS_SUCCESS) { policy_mgr_debug("SAP vdev id %d restarts due to MCC->SCC switch, old ch freq :%d new ch freq: %d", vdev_id[i], @@ -2511,6 +2514,56 @@ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, } #endif +#ifdef WLAN_FEATURE_P2P_P2P_STA +void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t ch_freq, + uint32_t ch_width) +{ + uint8_t total_connection; + + total_connection = policy_mgr_mode_specific_connection_count( + psoc, PM_P2P_GO_MODE, NULL); + + policy_mgr_debug("Total p2p go connection %d", total_connection); + + /* If any p2p disconnected, don't do csa */ + if (total_connection > 1) { + policy_mgr_change_sap_channel_with_csa(psoc, vdev_id, + ch_freq, ch_width, true); + } +} + +void policy_mgr_process_forcescc_for_go(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t ch_freq, + uint32_t ch_width) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + if (!pm_ctx->sta_ap_intf_check_work_info) { + policy_mgr_err("invalid work info"); + return; + } + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id = + vdev_id; + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.ch_freq = + ch_freq; + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.ch_width = + ch_width; + + if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, + WAIT_BEFORE_GO_FORCESCC_RESTART)) { + policy_mgr_err("change interface request failure"); + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id = + WLAN_UMAC_VDEV_ID_MAX; + } +} +#endif + QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc) { QDF_STATUS status; diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index 332732690b14..654c4a41065e 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 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 @@ -1806,12 +1806,13 @@ enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw) /** * policy_mgr_get_sbs_channels() - provides the sbs channel(s) - * with respect to current connection(s) - * @channels: the channel(s) on which current connection(s) is - * @len: Number of channels - * @pcl_weight: Pointer to the weights of PCL - * @weight_len: Max length of the weight list - * @index: Index from which the weight list needs to be populated + * with respect to current connection(s) + * @psoc: psoc object + * @pcl_freqs: the channel(s) on which current connection(s) is + * @pcl_weights: Pointer to the weights of PCL + * @pcl_sz: Max length of the PCL list + * @index: Index from which the weight list needs to be populated, + * will increase accordingly if any channel is obtained * @group_id: Next available groups for weight assignment * @available_5g_channels: List of available 5g channels * @available_5g_channels_len: Length of the 5g channels list @@ -1823,25 +1824,34 @@ enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw) * Return: QDF_STATUS */ -static QDF_STATUS policy_mgr_get_sbs_channels( - uint32_t *ch_freq_list, - uint32_t *len, uint8_t *pcl_weight, uint32_t weight_len, - uint32_t *index, enum policy_mgr_pcl_group_id group_id, - uint32_t *available_5g_ch_freqs, - uint32_t available_5g_channels_len, - bool add_5g_channels) +static QDF_STATUS +policy_mgr_get_sbs_channels(struct wlan_objmgr_psoc *psoc, uint32_t *pcl_freqs, + uint8_t *pcl_weights, uint32_t pcl_sz, + uint32_t *index, + enum policy_mgr_pcl_group_id group_id, + uint32_t *available_5g_ch_freqs, + uint32_t available_5g_channels_len, + bool add_5g_channels) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t conn_index = 0, num_channels = 0; + uint32_t conn_index = 0; uint32_t num_5g_channels = 0, cur_5g_ch_freq = 0; uint32_t remaining_5g_ch_freqs[NUM_CHANNELS] = {}; uint32_t remaining_channel_index = 0; - uint32_t j = 0, i = 0, weight1, weight2; + uint32_t j = 0, i = 0, weight1, weight2, idx; + struct policy_mgr_psoc_priv_obj *pm_ctx; - if (!ch_freq_list || !len) { + if (!policy_mgr_is_hw_sbs_capable(psoc)) + return QDF_STATUS_E_NOSUPPORT; + + if (!pcl_freqs || !pcl_weights || !index || !pcl_sz) { policy_mgr_err("channels or len is NULL"); - status = QDF_STATUS_E_FAILURE; - return status; + return QDF_STATUS_E_INVAL; + } + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; } if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) { @@ -1855,9 +1865,11 @@ static QDF_STATUS policy_mgr_get_sbs_channels( weight2 = WEIGHT_OF_GROUP4_PCL_CHANNELS; } + idx = *index; policy_mgr_debug("weight1=%d weight2=%d index=%d ", - weight1, weight2, *index); + weight1, weight2, idx); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (WLAN_REG_IS_5GHZ_CH_FREQ( pm_conc_connection_list[conn_index].freq) && @@ -1872,13 +1884,14 @@ static QDF_STATUS policy_mgr_get_sbs_channels( conn_index = 0; if (num_5g_channels > 1) { /* This case we are already in SBS so return the channels */ - while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - ch_freq_list[num_channels++] = + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index) && + idx < pcl_sz) { + pcl_freqs[idx] = pm_conc_connection_list[conn_index++].freq; - if (*index < weight_len) - pcl_weight[(*index)++] = weight1; + pcl_weights[idx] = weight1; + idx++; } - *len = num_channels; + /* fix duplicate issue later */ if (add_5g_channels) for (j = 0; j < available_5g_channels_len; j++) @@ -1889,33 +1902,38 @@ static QDF_STATUS policy_mgr_get_sbs_channels( /* Get list of valid sbs channels for the current * connected channel */ - for (j = 0; j < available_5g_channels_len; j++) { + for (j = 0; (j < available_5g_channels_len) && + (j < NUM_CHANNELS) && idx < pcl_sz; j++) { if (WLAN_REG_IS_FREQUENCY_VALID_5G_SBS( cur_5g_ch_freq, available_5g_ch_freqs[j])) { - ch_freq_list[num_channels++] = - available_5g_ch_freqs[j]; + pcl_freqs[idx] = available_5g_ch_freqs[j]; + pcl_weights[idx] = weight1; + idx++; } else { remaining_5g_ch_freqs[ remaining_channel_index++] = available_5g_ch_freqs[j]; continue; } - if (*index < weight_len) - pcl_weight[(*index)++] = weight1; } - *len = num_channels; } if (add_5g_channels) { - qdf_mem_copy(ch_freq_list + num_channels, remaining_5g_ch_freqs, - remaining_channel_index * sizeof(*ch_freq_list)); - *len += remaining_channel_index; - for (i = 0; ((i < remaining_channel_index) - && (i < weight_len)); i++) - pcl_weight[i] = weight2; + remaining_channel_index = + QDF_MIN(idx + remaining_channel_index, pcl_sz) - idx; + qdf_mem_copy(&pcl_freqs[idx], remaining_5g_ch_freqs, + remaining_channel_index * sizeof(*pcl_freqs)); + + for (i = idx; i < idx + remaining_channel_index; i++) + pcl_weights[i] = weight2; + + idx += remaining_channel_index; } - return status; + *index = idx; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return QDF_STATUS_SUCCESS; } /** @@ -1923,36 +1941,37 @@ static QDF_STATUS policy_mgr_get_sbs_channels( * on which current connection(s) is * @psoc: psoc object * @mode: conn mode - * @ch_freq_list: the channel(s) on which current connection(s) is - * @len: Number of channels - * @order: no order OR 2.4 Ghz channel followed by 5 Ghz - * channel OR 5 Ghz channel followed by 2.4 Ghz channel + * @order: no order OR 2.4 Ghz channel followed by 5 Ghz channel OR + * 5 Ghz channel followed by 2.4 Ghz channel * @skip_dfs_channel: if this flag is true then skip the dfs channel - * @pcl_weight: Pointer to the weights of PCL - * @weight_len: Max length of the weight list - * @index: Index from which the weight list needs to be populated * @group_id: Next available groups for weight assignment - * + * @pcl_freqs: Pointer to the frequencies of PCL + * @pcl_weights: Pointer to the weights of PCL + * @pcl_sz: Max length of the PCL list + * @index: Index from which the PCL list needs to be populated, + * will increase accordingly if any channel is obtained * * This function provides the channel(s) on which current * connection(s) is/are * * Return: QDF_STATUS */ -static -QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - uint32_t *ch_freq_list, - uint32_t *len, enum policy_mgr_pcl_channel_order order, - bool skip_dfs_channel, - uint8_t *pcl_weight, uint32_t weight_len, - uint32_t *index, enum policy_mgr_pcl_group_id group_id) +static QDF_STATUS +policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + enum policy_mgr_pcl_channel_order order, + bool skip_dfs_channel, + enum policy_mgr_pcl_group_id group_id, + uint32_t *pcl_freqs, uint8_t *pcl_weights, + uint32_t pcl_sz, uint32_t *index) { QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t conn_index = 0, num_channels = 0; + uint32_t conn_index = 0; uint32_t weight1, weight2; struct policy_mgr_psoc_priv_obj *pm_ctx; + struct policy_mgr_conc_connection_info *cl; bool add_6ghz = true; + uint32_t idx; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1960,12 +1979,14 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, return status; } - if (!ch_freq_list || !len) { - policy_mgr_err("channels or len is NULL"); - status = QDF_STATUS_E_FAILURE; + if (!pcl_freqs || !pcl_weights || !index || !pcl_sz) { + policy_mgr_err("list or index is NULL"); + status = QDF_STATUS_E_INVAL; return status; } + idx = *index; + /* POLICY_MGR_PCL_GROUP_ID1_ID2 indicates that all three weights are * available for assignment. i.e., WEIGHT_OF_GROUP1_PCL_CHANNELS, * WEIGHT_OF_GROUP2_PCL_CHANNELS and WEIGHT_OF_GROUP3_PCL_CHANNELS @@ -1997,52 +2018,47 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, add_6ghz = false; qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + cl = pm_conc_connection_list; if (POLICY_MGR_PCL_ORDER_NONE == order) { while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ( - pm_conc_connection_list[conn_index].freq); + cl[conn_index].freq); if (skip_dfs_channel && wlan_reg_is_dfs_for_freq( - pm_ctx->pdev, - pm_conc_connection_list[conn_index].freq)) { + pm_ctx->pdev, cl[conn_index].freq)) { conn_index++; - } else if ((*index < weight_len) && + } else if ((idx < pcl_sz) && (!is_6ghz_ch || add_6ghz)) { - ch_freq_list[num_channels++] = - pm_conc_connection_list[ - conn_index++].freq; - pcl_weight[(*index)++] = weight1; + pcl_freqs[idx] = cl[conn_index++].freq; + pcl_weights[idx] = weight1; + idx++; } else { conn_index++; } } - *len = num_channels; } else if (POLICY_MGR_PCL_ORDER_24G_THEN_5G == order) { while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (WLAN_REG_IS_24GHZ_CH_FREQ( - pm_conc_connection_list[conn_index].freq) - && (*index < weight_len)) { - ch_freq_list[num_channels++] = - pm_conc_connection_list[ - conn_index++].freq; - pcl_weight[(*index)++] = weight1; + if (WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) && + idx < pcl_sz) { + pcl_freqs[idx] = cl[conn_index++].freq; + pcl_weights[idx] = weight1; + idx++; } else { conn_index++; } } + conn_index = 0; while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && - wlan_reg_is_dfs_for_freq( - pm_ctx->pdev, - pm_conc_connection_list[conn_index].freq)) { + wlan_reg_is_dfs_for_freq(pm_ctx->pdev, + cl[conn_index].freq)) { conn_index++; } else if (WLAN_REG_IS_5GHZ_CH_FREQ( - pm_conc_connection_list[conn_index].freq) && - (*index < weight_len)) { - ch_freq_list[num_channels++] = - pm_conc_connection_list[ - conn_index++].freq; - pcl_weight[(*index)++] = weight2; + cl[conn_index].freq) && + (idx < pcl_sz)) { + pcl_freqs[idx] = cl[conn_index++].freq; + pcl_weights[idx] = weight2; + idx++; } else { conn_index++; } @@ -2051,44 +2067,38 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, while (add_6ghz && PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ( - pm_conc_connection_list[conn_index].freq); - if (is_6ghz_ch && (*index < weight_len)) { - ch_freq_list[num_channels++] = - pm_conc_connection_list[ - conn_index++].freq; - pcl_weight[(*index)++] = weight2; + cl[conn_index].freq); + if (is_6ghz_ch && idx < pcl_sz) { + pcl_freqs[idx] = cl[conn_index++].freq; + pcl_weights[idx] = weight2; + idx++; } else { conn_index++; } } - *len = num_channels; } else if (POLICY_MGR_PCL_ORDER_5G_THEN_2G == order) { while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && wlan_reg_is_dfs_for_freq( - pm_ctx->pdev, - pm_conc_connection_list[conn_index].freq)) { + pm_ctx->pdev, cl[conn_index].freq)) { conn_index++; } else if (WLAN_REG_IS_5GHZ_CH_FREQ( - pm_conc_connection_list[conn_index].freq) && - (*index < weight_len)) { - ch_freq_list[num_channels++] = - pm_conc_connection_list[ - conn_index++].freq; - pcl_weight[(*index)++] = weight1; + cl[conn_index].freq) && + (idx < pcl_sz)) { + pcl_freqs[idx] = cl[conn_index++].freq; + pcl_weights[idx] = weight1; + idx++; } else { conn_index++; } } conn_index = 0; while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (WLAN_REG_IS_24GHZ_CH_FREQ( - pm_conc_connection_list[conn_index].freq) && - (*index < weight_len)) { - ch_freq_list[num_channels++] = - pm_conc_connection_list[ - conn_index++].freq; - pcl_weight[(*index)++] = weight2; + if (WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) && + idx < pcl_sz) { + pcl_freqs[idx] = cl[conn_index++].freq; + pcl_weights[idx] = weight2; + idx++; } else { conn_index++; @@ -2098,21 +2108,21 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, while (add_6ghz && PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ( - pm_conc_connection_list[conn_index].freq); - if (is_6ghz_ch && (*index < weight_len)) { - ch_freq_list[num_channels++] = - pm_conc_connection_list[ - conn_index++].freq; - pcl_weight[(*index)++] = weight2; + cl[conn_index].freq); + if (is_6ghz_ch && idx < pcl_sz) { + pcl_freqs[idx] = cl[conn_index++].freq; + pcl_weights[idx] = weight2; + idx++; } else { conn_index++; } } - *len = num_channels; } else { policy_mgr_err("unknown order %d", order); status = QDF_STATUS_E_FAILURE; } + + *index = idx; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return status; @@ -2181,22 +2191,51 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( return; } -static void policy_mgr_add_5g_to_pcl( - struct wlan_objmgr_psoc *psoc, - uint32_t *ch_freq_list, - uint32_t *len, - uint8_t *pcl_weight, uint32_t weight_len, - uint32_t *index, enum policy_mgr_pcl_group_id group_id, - const uint32_t *chlist_5g, uint8_t chlist_5g_len, - const uint32_t *chlist_6g, uint8_t chlist_6g_len) +static bool is_freq_present_in_pcl(uint32_t idx, uint32_t *pcl_freqs, + uint32_t chanlist_freq) +{ + uint32_t i; + + for (i = 0; i < idx; i++) { + if (pcl_freqs[i] == chanlist_freq) + return true; + } + + return false; +} + +/** + * policy_mgr_add_5g_to_pcl() - add the 5G/6G channels into PCL + * @psoc: psoc object + * @pcl_freqs: Pointer to the frequencies of PCL + * @pcl_weights: Pointer to the weights of PCL + * @pcl_sz: Max length of the PCL list + * @index: Index from which the PCL list needs to be populated, + * will increase accordingly if any channel is obtained + * @group_id: Next available groups for weight assignment + * @chlist_5g: Pointer to the 5G channel list + * @chlist_5g_len: Length of the 5G channel list + * @chlist_6g: Pointer to the 6G channel list + * @chlist_6g_len: Length of the 6G channel list + * + * Return: None + */ +static void +policy_mgr_add_5g_to_pcl(struct wlan_objmgr_psoc *psoc, uint32_t *pcl_freqs, + uint8_t *pcl_weights, uint32_t pcl_sz, uint32_t *index, + enum policy_mgr_pcl_group_id group_id, + const uint32_t *chlist_5g, uint8_t chlist_5g_len, + const uint32_t *chlist_6g, uint8_t chlist_6g_len) { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t weight1, weight2; const uint32_t *chlist1; uint8_t chlist1_len; + uint8_t list_len = 0; const uint32_t *chlist2; uint8_t chlist2_len; uint32_t i; + uint32_t len = 0, idx; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -2204,6 +2243,8 @@ static void policy_mgr_add_5g_to_pcl( return; } + idx = *index; + if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) { weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS; weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS; @@ -2225,42 +2266,84 @@ static void policy_mgr_add_5g_to_pcl( chlist2 = chlist_6g; chlist2_len = chlist_6g_len; } - if ((chlist1_len + *index) > weight_len) { + if ((chlist1_len + idx) > pcl_sz) { policy_mgr_err("no enough weight len %d chlist1_len %d %d", - weight_len, chlist1_len, *index); + pcl_sz, chlist1_len, idx); return; } - qdf_mem_copy(ch_freq_list, chlist1, chlist1_len * sizeof(*chlist1)); - for (i = 0; i < chlist1_len; i++) - pcl_weight[(*index)++] = weight1; + for (i = 0; i < chlist1_len; i++) { + if (is_freq_present_in_pcl(idx, pcl_freqs, chlist1[i])) + continue; + pcl_freqs[idx] = chlist1[i]; + pcl_weights[idx] = weight1; + idx++; + list_len++; + } - *len += chlist1_len; + len += list_len; - if ((chlist2_len + *index) > weight_len) { + if ((chlist2_len + idx) > pcl_sz) { policy_mgr_err("no enough weight len chlist2_len %d %d %d", - weight_len, chlist2_len, *index); + pcl_sz, chlist2_len, idx); return; } - qdf_mem_copy(&ch_freq_list[chlist1_len], chlist2, - chlist2_len * sizeof(*chlist2)); - for (i = 0; i < chlist2_len; i++) - pcl_weight[(*index)++] = weight2; - *len += chlist2_len; + list_len = 0; + for (i = 0; i < chlist2_len; i++) { + if (is_freq_present_in_pcl(idx, pcl_freqs, chlist2[i])) + continue; + pcl_freqs[idx] = chlist2[i]; + pcl_weights[idx] = weight2; + idx++; + list_len++; + } + len += list_len; + *index = idx; policy_mgr_debug("Add 5g chlist len %d 6g chlist len %d len %d index %d order %d", - chlist_5g_len, chlist_6g_len, *len, *index, + chlist_5g_len, chlist_6g_len, len, idx, pm_ctx->cfg.pcl_band_priority); } +/** + * policy_mgr_add_24g_to_pcl() - add the 2.4G channels into PCL + * @pcl_freqs: Pointer to the frequencies of PCL + * @pcl_weights: Pointer to the weights of PCL + * @pcl_sz: Max length of the PCL list + * @index: Index from which the PCL list needs to be populated, + * will increase accordingly if any channel is obtained + * @weight: group for weight assignment + * @chlist_24g: Pointer to the 2.4G channel list + * @chlist_24g_len: Length of the 2.4G channel list + * + * Return: None + */ +static void +policy_mgr_add_24g_to_pcl(uint32_t *pcl_freqs, uint8_t *pcl_weights, + uint32_t pcl_sz, uint32_t *index, uint32_t weight, + const uint32_t *chlist_24g, uint8_t chlist_24g_len) +{ + uint32_t num_to_add, i; + + num_to_add = QDF_MIN((*index + chlist_24g_len), pcl_sz) - *index; + qdf_mem_copy(&pcl_freqs[*index], chlist_24g, + num_to_add * sizeof(*chlist_24g)); + for (i = *index; i < *index + num_to_add; i++) + pcl_weights[i] = weight; + + *index = i; + policy_mgr_debug("Add 24g chlist len %d len %d index %d", + chlist_24g_len, num_to_add, *index); +} + /** * policy_mgr_get_channel_list() - provides the channel list * suggestion for new connection - * @pcl: The preferred channel list enum - * @pcl_channels: PCL channels - * @len: length of the PCL + * @pcl: The preferred channel list enum * @mode: concurrency mode for which channel list is requested + * @pcl_channels: PCL channels * @pcl_weights: Weights of the PCL - * @weight_len: Max length of the weight list + * @pcl_sz: Max length of the PCL list + * @len: length of the PCL obtained * * This function provides the actual channel list based on the * current regulatory domain derived using preferred channel @@ -2269,17 +2352,18 @@ static void policy_mgr_add_5g_to_pcl( * Return: Channel List */ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_pcl_type pcl, - uint32_t *pcl_channels, uint32_t *len, - enum policy_mgr_con_mode mode, - uint8_t *pcl_weights, uint32_t weight_len) + enum policy_mgr_pcl_type pcl, + enum policy_mgr_con_mode mode, + uint32_t *pcl_channels, + uint8_t *pcl_weights, + uint32_t pcl_sz, uint32_t *len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t num_channels = 0; uint32_t sbs_num_channels = 0; uint32_t chan_index_24 = 0, chan_index_5 = 0, chan_index_6 = 0; bool skip_dfs_channel = false; - uint32_t i = 0, j = 0; + uint32_t i = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t *channel_list, *channel_list_24, *channel_list_5, *sbs_channel_list, *channel_list_6; @@ -2389,323 +2473,236 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, */ switch (pcl) { case PM_24G: - chan_index_24 = QDF_MIN(chan_index_24, weight_len); - qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24 * sizeof(*pcl_channels)); - *len = chan_index_24; - for (i = 0; i < *len; i++) - pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz, + len, WEIGHT_OF_GROUP1_PCL_CHANNELS, + channel_list_24, chan_index_24); status = QDF_STATUS_SUCCESS; break; case PM_5G: - policy_mgr_add_5g_to_pcl( - psoc, pcl_channels, len, - pcl_weights, weight_len, - &i, - POLICY_MGR_PCL_GROUP_ID1_ID2, - channel_list_5, chan_index_5, - channel_list_6, chan_index_6); + policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights, + pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID1_ID2, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); status = QDF_STATUS_SUCCESS; break; case PM_SCC_CH: case PM_MCC_CH: - policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; + policy_mgr_get_connection_channels(psoc, mode, + POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, + pcl_sz, len); status = QDF_STATUS_SUCCESS; break; case PM_SCC_CH_24G: case PM_MCC_CH_24G: - policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; - chan_index_24 = QDF_MIN((num_channels + chan_index_24), - weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, - chan_index_24 * sizeof(*pcl_channels)); - *len += chan_index_24; - for (j = 0; j < chan_index_24; i++, j++) - pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; - + policy_mgr_get_connection_channels(psoc, mode, + POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, + pcl_sz, len); + policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz, + len, WEIGHT_OF_GROUP2_PCL_CHANNELS, + channel_list_24, chan_index_24); status = QDF_STATUS_SUCCESS; break; case PM_SCC_CH_5G: case PM_MCC_CH_5G: - policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; - policy_mgr_add_5g_to_pcl( - psoc, &pcl_channels[num_channels], len, - pcl_weights, weight_len, - &i, - POLICY_MGR_PCL_GROUP_ID2_ID3, - channel_list_5, chan_index_5, - channel_list_6, chan_index_6); + policy_mgr_get_connection_channels(psoc, mode, + POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, + pcl_sz, len); + policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights, + pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID2_ID3, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); status = QDF_STATUS_SUCCESS; break; case PM_24G_SCC_CH: case PM_24G_MCC_CH: - chan_index_24 = QDF_MIN(chan_index_24, weight_len); - qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24 * sizeof(*pcl_channels)); - *len = chan_index_24; - for (i = 0; i < chan_index_24; i++) - pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; - policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, - num_channels * sizeof(*pcl_channels)); - *len += num_channels; + policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz, + len, WEIGHT_OF_GROUP1_PCL_CHANNELS, + channel_list_24, chan_index_24); + policy_mgr_get_connection_channels(psoc, mode, + POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID2_ID3, + pcl_channels, pcl_weights, + pcl_sz, len); status = QDF_STATUS_SUCCESS; break; case PM_5G_SCC_CH: case PM_5G_MCC_CH: - policy_mgr_add_5g_to_pcl( - psoc, pcl_channels, len, - pcl_weights, weight_len, - &i, - POLICY_MGR_PCL_GROUP_ID1_ID2, - channel_list_5, chan_index_5, - channel_list_6, chan_index_6); - - policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID3_ID4); - qdf_mem_copy(&pcl_channels[*len], channel_list, - num_channels * sizeof(*pcl_channels)); - *len += num_channels; + policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights, + pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID1_ID2, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); + policy_mgr_get_connection_channels(psoc, mode, + POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID3_ID4, + pcl_channels, pcl_weights, + pcl_sz, len); status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_24_SCC_ON_5: policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, - POLICY_MGR_PCL_ORDER_24G_THEN_5G, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; + psoc, mode, + POLICY_MGR_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, pcl_sz, len); status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_5_SCC_ON_24: policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, - POLICY_MGR_PCL_ORDER_5G_THEN_2G, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; + psoc, mode, + POLICY_MGR_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, pcl_sz, len); status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_24_SCC_ON_5_24G: policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, - POLICY_MGR_PCL_ORDER_24G_THEN_5G, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; - chan_index_24 = QDF_MIN((num_channels + chan_index_24), - weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, - chan_index_24 * sizeof(*pcl_channels)); - *len += chan_index_24; - for (j = 0; j < chan_index_24; i++, j++) - pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + psoc, mode, + POLICY_MGR_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, pcl_sz, len); + policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz, + len, WEIGHT_OF_GROUP3_PCL_CHANNELS, + channel_list_24, chan_index_24); status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_24_SCC_ON_5_5G: policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, - POLICY_MGR_PCL_ORDER_24G_THEN_5G, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; - policy_mgr_add_5g_to_pcl( - psoc, &pcl_channels[num_channels], len, - pcl_weights, weight_len, - &i, - POLICY_MGR_PCL_GROUP_ID3_ID4, - channel_list_5, chan_index_5, - channel_list_6, chan_index_6); + psoc, mode, + POLICY_MGR_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, pcl_sz, len); + policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights, + pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_5_SCC_ON_24_24G: policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, - POLICY_MGR_PCL_ORDER_5G_THEN_2G, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; - chan_index_24 = QDF_MIN((num_channels + chan_index_24), - weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, - chan_index_24 * sizeof(*pcl_channels)); - *len += chan_index_24; - for (j = 0; j < chan_index_24; i++, j++) - pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + psoc, mode, + POLICY_MGR_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, pcl_sz, len); + policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz, + len, WEIGHT_OF_GROUP3_PCL_CHANNELS, + channel_list_24, chan_index_24); status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_5_SCC_ON_24_5G: policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, - POLICY_MGR_PCL_ORDER_5G_THEN_2G, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, - num_channels * sizeof(*pcl_channels)); - *len = num_channels; - policy_mgr_add_5g_to_pcl( - psoc, &pcl_channels[num_channels], len, - pcl_weights, weight_len, - &i, - POLICY_MGR_PCL_GROUP_ID3_ID4, - channel_list_5, chan_index_5, - channel_list_6, chan_index_6); + psoc, mode, + POLICY_MGR_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID1_ID2, + pcl_channels, pcl_weights, pcl_sz, len); + policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights, + pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); status = QDF_STATUS_SUCCESS; break; case PM_24G_SCC_CH_SBS_CH: - qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24 * sizeof(*pcl_channels)); - *len = chan_index_24; - for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) - pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; - policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, - num_channels * sizeof(*pcl_channels)); - *len += num_channels; - if (policy_mgr_is_hw_sbs_capable(psoc)) { - policy_mgr_get_sbs_channels( - sbs_channel_list, &sbs_num_channels, pcl_weights, - weight_len, &i, POLICY_MGR_PCL_GROUP_ID3_ID4, - channel_list_5, chan_index_5, false); - qdf_mem_copy( - &pcl_channels[chan_index_24 + num_channels], - sbs_channel_list, - sbs_num_channels * sizeof(*pcl_channels)); - *len += sbs_num_channels; - } + policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz, + len, WEIGHT_OF_GROUP1_PCL_CHANNELS, + channel_list_24, chan_index_24); + + policy_mgr_get_connection_channels(psoc, mode, + POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID2_ID3, + pcl_channels, pcl_weights, + pcl_sz, len); + + policy_mgr_get_sbs_channels(psoc, pcl_channels, pcl_weights, + pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, + false); status = QDF_STATUS_SUCCESS; break; case PM_24G_SCC_CH_SBS_CH_5G: - qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24 * sizeof(*pcl_channels)); - *len = chan_index_24; - for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) - pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz, + len, WEIGHT_OF_GROUP1_PCL_CHANNELS, + channel_list_24, chan_index_24); policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, - num_channels * sizeof(*pcl_channels)); - *len += num_channels; + psoc, mode, + POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID2_ID3, + pcl_channels, pcl_weights, + pcl_sz, len); if (policy_mgr_is_hw_sbs_capable(psoc)) { policy_mgr_get_sbs_channels( - sbs_channel_list, &sbs_num_channels, pcl_weights, - weight_len, &i, POLICY_MGR_PCL_GROUP_ID3_ID4, - channel_list_5, chan_index_5, true); - qdf_mem_copy( - &pcl_channels[chan_index_24 + num_channels], - sbs_channel_list, - sbs_num_channels * sizeof(*pcl_channels)); - *len += sbs_num_channels; + psoc, pcl_channels, + pcl_weights, pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, + true); } else { - policy_mgr_add_5g_to_pcl( - psoc, - &pcl_channels[chan_index_24 + num_channels], - len, - pcl_weights, weight_len, - &i, - POLICY_MGR_PCL_GROUP_ID3_ID4, - channel_list_5, chan_index_5, - channel_list_6, chan_index_6); + policy_mgr_add_5g_to_pcl(psoc, pcl_channels, + pcl_weights, pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); } status = QDF_STATUS_SUCCESS; break; case PM_24G_SBS_CH_MCC_CH: - qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24 * sizeof(*pcl_channels)); - *len = chan_index_24; - for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) - pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz, + len, WEIGHT_OF_GROUP1_PCL_CHANNELS, + channel_list_24, chan_index_24); if (policy_mgr_is_hw_sbs_capable(psoc)) { policy_mgr_get_sbs_channels( - sbs_channel_list, &sbs_num_channels, pcl_weights, - weight_len, &i, POLICY_MGR_PCL_GROUP_ID2_ID3, - channel_list_5, chan_index_5, false); - qdf_mem_copy(&pcl_channels[num_channels], - sbs_channel_list, - sbs_num_channels * sizeof(*pcl_channels)); - *len += sbs_num_channels; + psoc, pcl_channels, + pcl_weights, + pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID2_ID3, + channel_list_5, chan_index_5, + false); } policy_mgr_get_connection_channels( - psoc, mode, - channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, - skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, - num_channels * sizeof(*pcl_channels)); - *len += num_channels; + psoc, mode, + POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, + POLICY_MGR_PCL_GROUP_ID2_ID3, + pcl_channels, pcl_weights, + pcl_sz, len); status = QDF_STATUS_SUCCESS; break; case PM_SBS_CH_5G: if (policy_mgr_is_hw_sbs_capable(psoc)) { policy_mgr_get_sbs_channels( - sbs_channel_list, &sbs_num_channels, pcl_weights, - weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2, - channel_list_5, chan_index_5, true); - qdf_mem_copy(&pcl_channels[num_channels], - sbs_channel_list, - sbs_num_channels * sizeof(*pcl_channels)); - *len += sbs_num_channels; - } else { - policy_mgr_add_5g_to_pcl( - psoc, - pcl_channels, - len, - pcl_weights, weight_len, - &i, + psoc, pcl_channels, + pcl_weights, pcl_sz, len, POLICY_MGR_PCL_GROUP_ID1_ID2, - channel_list_5, chan_index_5, - channel_list_6, chan_index_6); + channel_list_5, chan_index_5, true); + } else { + policy_mgr_add_5g_to_pcl(psoc, pcl_channels, + pcl_weights, pcl_sz, len, + POLICY_MGR_PCL_GROUP_ID1_ID2, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); } status = QDF_STATUS_SUCCESS; break; @@ -2722,10 +2719,10 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, if ((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, len, pcl_weights, - weight_len); + pcl_sz); policy_mgr_set_weight_of_dfs_passive_channels_to_zero(psoc, - pcl_channels, len, pcl_weights, weight_len); + pcl_channels, len, pcl_weights, pcl_sz); end: qdf_mem_free(channel_list); qdf_mem_free(channel_list_24); @@ -2770,35 +2767,37 @@ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, } /** - * policy_mgr_is_multi_ap_plus_sta_3vif_conc() - Check multiple AP plus STA - * concurrency - * @mode1: policy_mgr_con_mode of connection 1 - * @mode2: policy_mgr_con_mode of connection 2 - * @mode2: policy_mgr_con_mode of connection 3 + * policy_mgr_is_3rd_conn_on_same_band() - Check whether 3rd connection is on + * same band or not + * @ch_freq: channel frequency * - * Check the 3vif concurrency is SAP(GO)+SAP(GO)+STA or not based on - * connection mode. + * Check the existing two connection are in same band or not. If it is in + * same band then check the 3rd connection is also in same band or not * * Return: True/False */ -static bool policy_mgr_is_multi_ap_plus_sta_3vif_conc( - enum policy_mgr_con_mode mode1, enum policy_mgr_con_mode mode2, - enum policy_mgr_con_mode mode3) +static bool policy_mgr_is_3rd_conn_on_same_band(uint32_t ch_freq) { - if (mode1 == PM_STA_MODE && - (mode2 == PM_SAP_MODE || mode2 == PM_P2P_GO_MODE) && - (mode3 == PM_SAP_MODE || mode3 == PM_P2P_GO_MODE)) - return true; - if (mode2 == PM_STA_MODE && - (mode1 == PM_SAP_MODE || mode1 == PM_P2P_GO_MODE) && - (mode3 == PM_SAP_MODE || mode3 == PM_P2P_GO_MODE)) - return true; - if (mode3 == PM_STA_MODE && - (mode1 == PM_SAP_MODE || mode1 == PM_P2P_GO_MODE) && - (mode2 == PM_SAP_MODE || mode2 == PM_P2P_GO_MODE)) - return true; + bool ret = false; - return false; + if (((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) && + (WLAN_REG_IS_24GHZ_CH_FREQ + (pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_24GHZ_CH_FREQ + (pm_conc_connection_list[1].freq))) || + (((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) || + (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq))) && + ((WLAN_REG_IS_5GHZ_CH_FREQ + (pm_conc_connection_list[0].freq)) || + (WLAN_REG_IS_6GHZ_CHAN_FREQ + (pm_conc_connection_list[0].freq))) && + ((WLAN_REG_IS_5GHZ_CH_FREQ + (pm_conc_connection_list[1].freq)) || + (WLAN_REG_IS_6GHZ_CHAN_FREQ + (pm_conc_connection_list[1].freq))))) { + ret = true; + } + return ret; } /** @@ -2874,16 +2873,8 @@ bool policy_mgr_allow_new_home_channel( policy_mgr_rl_debug("don't allow 3rd home channel on same MAC"); status = false; } - } else if (((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) && - (WLAN_REG_IS_24GHZ_CH_FREQ - (pm_conc_connection_list[0].freq)) && - (WLAN_REG_IS_24GHZ_CH_FREQ - (pm_conc_connection_list[1].freq))) || - ((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) && - (WLAN_REG_IS_5GHZ_CH_FREQ - (pm_conc_connection_list[0].freq)) && - (WLAN_REG_IS_5GHZ_CH_FREQ - (pm_conc_connection_list[1].freq)))) { + } else if (policy_mgr_is_3rd_conn_on_same_band( + ch_freq)) { policy_mgr_rl_debug("don't allow 3rd home channel on same MAC"); status = false; } @@ -2909,12 +2900,10 @@ bool policy_mgr_allow_new_home_channel( * and therefore a 3rd connection with the * same MAC is possible. */ - } else if (wlan_reg_is_same_band_freqs(ch_freq, - pm_conc_connection_list[0].freq) && - policy_mgr_is_multi_ap_plus_sta_3vif_conc( - pm_conc_connection_list[0].mode, - pm_conc_connection_list[1].mode, - mode)) { + } else if (policy_mgr_is_3rd_conn_on_same_band( + ch_freq) && + !(policy_mgr_is_3rd_conn_on_same_band_allowed( + psoc, mode))) { policy_mgr_rl_debug("don't allow 3rd home channel on same MAC - sta existing"); status = false; } diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index e54d98c61b7a..5661c5a03491 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -2616,6 +2616,13 @@ static bool policy_mgr_is_6g_channel_allowed( return true; } +#ifdef WLAN_FEATURE_P2P_P2P_STA +bool policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc) +{ + return wlan_mlme_get_p2p_p2p_conc_support(psoc); +} +#endif + bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t ch_freq, @@ -2641,15 +2648,14 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (num_connections && policy_mgr_is_sub_20_mhz_enabled(psoc)) { policy_mgr_rl_debug("dont allow concurrency if Sub 20 MHz is enabled"); - status = false; - goto done; + return status; } if (policy_mgr_max_concurrent_connections_reached(psoc)) { policy_mgr_rl_debug("Reached max concurrent connections: %d", pm_ctx->cfg.max_conc_cxns); policy_mgr_validate_conn_info(psoc); - goto done; + return status; } if (ch_freq) { @@ -2668,7 +2674,7 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (!policy_mgr_allow_new_home_channel(psoc, mode, ch_freq, num_connections, is_dfs_ch)) - goto done; + return status; /* * 1) DFS MCC is not yet supported @@ -2685,13 +2691,13 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, */ if (!policy_mgr_is_5g_channel_allowed(psoc, ch_freq, list, PM_P2P_GO_MODE)) - goto done; + return status; if (!policy_mgr_is_5g_channel_allowed(psoc, ch_freq, list, PM_SAP_MODE)) - goto done; + return status; if (!policy_mgr_is_6g_channel_allowed(psoc, mode, ch_freq)) - goto done; + return status; sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); @@ -2706,14 +2712,14 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, } if (true == match) { policy_mgr_rl_debug("No MCC, SAP/GO about to come up on DFS channel"); - goto done; + return status; } if ((policy_mgr_is_hw_dbs_capable(psoc) != true) && num_connections) { if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { if (policy_mgr_is_sap_p2pgo_on_dfs(psoc)) { policy_mgr_rl_debug("MCC not allowed: SAP/P2PGO on DFS"); - goto done; + return status; } } } @@ -2725,21 +2731,26 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (mode == PM_STA_MODE && count) { if (count >= 2) { policy_mgr_rl_debug("3rd STA isn't permitted"); - goto done; + return status; } sta_freq = pm_conc_connection_list[list[0]].freq; if (!policy_mgr_allow_multiple_sta_connections(psoc, ch_freq, sta_freq)) - goto done; + return status; } if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, ch_freq, WLAN_INVALID_VDEV_ID)) { policy_mgr_rl_debug("This concurrency combination is not allowed"); - goto done; + return status; } - /* don't allow two P2P GO on same band */ - if (ch_freq && mode == PM_P2P_GO_MODE && num_connections) { + + /* + * don't allow two P2P GO on same band, if fw doesn't + * support p2p +p2p concurrency + */ + if (ch_freq && mode == PM_P2P_GO_MODE && num_connections && + !policy_mgr_is_p2p_p2p_conc_supported(psoc)) { index = 0; count = policy_mgr_mode_specific_connection_count( psoc, PM_P2P_GO_MODE, list); @@ -2750,7 +2761,7 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, pm_conc_connection_list[list[index]].freq)) { policy_mgr_rl_debug("Don't allow P2P GO on same band"); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - goto done; + return status; } index++; } @@ -2759,12 +2770,11 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (!policy_mgr_allow_wapi_concurrency(pm_ctx)) { policy_mgr_rl_debug("Don't allow new conn when wapi security conn existing"); - goto done; + return status; } status = true; -done: return status; } @@ -4307,8 +4317,6 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, if (mode != PM_SAP_MODE && mode != PM_P2P_GO_MODE) return true; - if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc)) - return true; dbs = policy_mgr_is_hw_dbs_capable(psoc); for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) { if (!pm_conc_connection_list[id].in_use) @@ -4320,6 +4328,18 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, if (con_mode != PM_SAP_MODE && con_mode != PM_P2P_GO_MODE) continue; con_freq = pm_conc_connection_list[id].freq; + + if (policy_mgr_is_p2p_p2p_conc_supported(psoc) && + (mode == PM_P2P_GO_MODE) && (con_mode == PM_P2P_GO_MODE)) { + policy_mgr_debug("GO+GO scc is allowed freq = %d ", + ch_freq); + return true; + } + + if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc) && + (mode == PM_SAP_MODE) && (con_mode == PM_SAP_MODE)) + return true; + if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc) && (ch_freq == con_freq)) { policy_mgr_debug("SCC enabled, 2 AP on same channel, allow 2nd AP"); @@ -4608,6 +4628,63 @@ bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc) return false; } +#ifdef WLAN_FEATURE_P2P_P2P_STA +uint8_t +policy_mgr_check_forcescc_for_other_go(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t freq) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t conn_index; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return WLAN_UMAC_VDEV_ID_MAX; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (pm_conc_connection_list[conn_index].mode == + PM_P2P_GO_MODE && + pm_conc_connection_list[conn_index].in_use && + wlan_reg_is_same_band_freqs( + freq, + pm_conc_connection_list[conn_index].freq) && + freq != pm_conc_connection_list[conn_index].freq && + vdev_id != pm_conc_connection_list[conn_index].vdev_id) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug( + "Existing p2p go vdev_id is %d", + pm_conc_connection_list[conn_index].vdev_id); + return pm_conc_connection_list[conn_index].vdev_id; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return WLAN_UMAC_VDEV_ID_MAX; +} + +bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + bool ret = false; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + ret = false; + goto return_val; + } + if (pm_ctx->cfg.go_force_scc & GO_FORCE_SCC_STRICT) { + ret = true; + goto return_val; + } + ret = false; +return_val: + policy_mgr_debug("ret val is %d", ret); + return ret; +} +#endif + QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc, uint8_t nan_vdev_id, uint8_t mac_id) diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index e70b599e774b..4caca995244f 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -571,11 +571,32 @@ void pm_dbs_opportunistic_timer_handler(void *data); enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type, uint8_t subtype); +/** + * policy_mgr_get_bw() - Convert phy_ch_width to hw_mode_bandwidth. + * @chan_width: phy_ch_width + * + * Return: hw_mode_bandwidth + */ +enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width); + +/** + * policy_mgr_get_channel_list() - Get channel list based on PCL and mode + * @psoc: psoc object + * @pcl: pcl type + * @mode: interface mode + * @pcl_channels: pcl channel list buffer + * @pcl_weights: pcl weight buffer + * @pcl_sz: pcl channel list buffer size + * @len: pcl channel number returned from API + * + * Return: QDF_STATUS + */ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_pcl_type pcl, - uint32_t *pcl_channels, uint32_t *len, - enum policy_mgr_con_mode mode, - uint8_t *pcl_weights, uint32_t weight_len); + enum policy_mgr_pcl_type pcl, + enum policy_mgr_con_mode mode, + uint32_t *pcl_channels, + uint8_t *pcl_weights, + uint32_t pcl_sz, uint32_t *len); /** * policy_mgr_allow_new_home_channel() - Check for allowed number of diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c index 3a5c07f982fe..eda6605cf014 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 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 @@ -339,6 +339,8 @@ QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_E_FAILURE; } pm_ctx->sta_ap_intf_check_work_info->psoc = psoc; + pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id = + WLAN_UMAC_VDEV_ID_MAX; if (QDF_IS_STATUS_ERROR(qdf_delayed_work_create( &pm_ctx->sta_ap_intf_check_work, policy_mgr_check_sta_ap_concurrent_ch_intf, diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c index 9c940ef8d8f1..f2569eb908cc 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 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 @@ -1022,8 +1022,8 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, /* once the PCL enum is obtained find out the exact channel list with * help from sme_get_cfg_valid_channels */ - status = policy_mgr_get_channel_list(psoc, pcl, pcl_channels, len, mode, - pcl_weight, weight_len); + status = policy_mgr_get_channel_list(psoc, pcl, mode, pcl_channels, + pcl_weight, weight_len, len); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("failed to get channel list:%d", status); return status; @@ -1729,58 +1729,128 @@ static enum policy_mgr_two_connection_mode return index; } +/* + * policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc() - + * This function checks connection mode is in scc or not and returns + * index value based on mode and prvided index inputs. + * + * @scc_2g_1x1: index of scc_2g_1x1 for provided concurrency + * @scc_2g_2x2: index of scc_2g_2x2 for provided concurrency + * @scc_5g_1x1: index of scc_5g_1x1 for provided concurrency + * @scc_5g_2x2: index of scc_5g_2x2 for provided concurrency + * + * Return: policy_mgr_two_connection_mode index + */ static enum policy_mgr_two_connection_mode - policy_mgr_get_third_connection_pcl_table_index_go_go(void) +policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( + enum policy_mgr_two_connection_mode scc_2g_1x1, + enum policy_mgr_two_connection_mode scc_2g_2x2, + enum policy_mgr_two_connection_mode scc_5g_1x1, + enum policy_mgr_two_connection_mode scc_5g_2x2) { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; - /* SCC */ + if (pm_conc_connection_list[0].freq == - pm_conc_connection_list[1].freq) { + pm_conc_connection_list[1].freq) { if (WLAN_REG_IS_24GHZ_CH_FREQ( - pm_conc_connection_list[0].freq)) { + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_P2P_GO_SCC_24_1x1; + pm_conc_connection_list[0].chain_mask) + index = scc_2g_1x1; else - index = PM_P2P_GO_P2P_GO_SCC_24_2x2; + index = scc_2g_2x2; } else { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_P2P_GO_SCC_5_1x1; + index = scc_5g_1x1; else - index = PM_P2P_GO_P2P_GO_SCC_5_2x2; + index = scc_5g_2x2; } - /* MCC */ - } else if (pm_conc_connection_list[0].mac == - pm_conc_connection_list[1].mac) { + } + return index; +} + +/* + * policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc() - + * This function checks connection mode is in mcc or not and returns + * index value based on mode and prvided index inputs. + * + * @mcc_2g_1x1: index of mcc_2g_1x1 for provided concurrency + * @mcc_2g_2x2: index of mcc_2g_2x2 for provided concurrency + * @mcc_5g_1x1: index of mcc_5g_1x1 for provided concurrency + * @mcc_5g_2x2: index of mcc_5g_2x2 for provided concurrency + * @mcc_24_5_1x1: index of mcc_24_5_1x1 for provided concurrency + * @mcc_24_5_2x2: index of mcc_24_5_2x2 for provided concurrency + * + * Return: policy_mgr_two_connection_mode index + */ +static enum policy_mgr_two_connection_mode +policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc( + enum policy_mgr_two_connection_mode mcc_2g_1x1, + enum policy_mgr_two_connection_mode mcc_2g_2x2, + enum policy_mgr_two_connection_mode mcc_5g_1x1, + enum policy_mgr_two_connection_mode mcc_5g_2x2, + enum policy_mgr_two_connection_mode mcc_24_5_1x1, + enum policy_mgr_two_connection_mode mcc_24_5_2x2) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + + if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { if ((WLAN_REG_IS_24GHZ_CH_FREQ( - pm_conc_connection_list[0].freq)) && - (WLAN_REG_IS_24GHZ_CH_FREQ( - pm_conc_connection_list[1].freq))) { + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_P2P_GO_MCC_24_1x1; + pm_conc_connection_list[0].chain_mask) + index = mcc_2g_1x1; else - index = PM_P2P_GO_P2P_GO_MCC_24_2x2; + index = mcc_2g_2x2; } else if ((WLAN_REG_IS_5GHZ_CH_FREQ( pm_conc_connection_list[0].freq)) && (WLAN_REG_IS_5GHZ_CH_FREQ( pm_conc_connection_list[1].freq))) { + } else if (!(WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + !(WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_P2P_GO_MCC_5_1x1; + pm_conc_connection_list[0].chain_mask) + index = mcc_5g_1x1; else - index = PM_P2P_GO_P2P_GO_MCC_5_2x2; + index = mcc_5g_2x2; } else { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_P2P_GO_MCC_24_5_1x1; + index = mcc_24_5_1x1; else - index = PM_P2P_GO_P2P_GO_MCC_24_5_2x2; + index = mcc_24_5_2x2; } - /* SBS or DBS */ - } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { + } + return index; +} + +/* + * policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs() - + * This function checks connection mode is in dbs or sbs and returns index + * value based on mode and prvided index inputs. + * + * @sbs_5g_1x1: index of sbs_5g_1x1 for provided concurrency + * @sbs_5g_2x2: index of sbs_5g_2x2 for provided concurrency + * @dbs_1x1: index of dbs_1x1 for provided concurrency + * @dbs_2x2: index of dbs_2x2 for provided concurrency + * + * Return: policy_mgr_two_connection_mode index + */ +static enum policy_mgr_two_connection_mode +policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs( + enum policy_mgr_two_connection_mode sbs_5g_1x1, + enum policy_mgr_two_connection_mode sbs_5g_2x2, + enum policy_mgr_two_connection_mode dbs_1x1, + enum policy_mgr_two_connection_mode dbs_2x2) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + + if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ if ((WLAN_REG_IS_5GHZ_CH_FREQ( pm_conc_connection_list[0].freq)) && @@ -1788,16 +1858,89 @@ static enum policy_mgr_two_connection_mode pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_P2P_GO_SBS_5_1x1; + index = sbs_5g_1x1; + else + index = sbs_5g_2x2; } else { /* DBS */ if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_P2P_GO_DBS_1x1; + index = dbs_1x1; else - index = PM_P2P_GO_P2P_GO_DBS_2x2; + index = dbs_2x2; } } + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_cli_cli(void) +{ + enum policy_mgr_two_connection_mode index; + + index = + policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( + PM_P2P_CLI_P2P_CLI_SCC_24_1x1, + PM_P2P_CLI_P2P_CLI_SCC_24_2x2, + PM_P2P_CLI_P2P_CLI_SCC_5_1x1, + PM_P2P_CLI_P2P_CLI_SCC_5_2x2); + if (index != PM_MAX_TWO_CONNECTION_MODE) + return index; + + index = + policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc( + PM_P2P_CLI_P2P_CLI_MCC_24_1x1, + PM_P2P_CLI_P2P_CLI_MCC_24_2x2, + PM_P2P_CLI_P2P_CLI_MCC_5_1x1, + PM_P2P_CLI_P2P_CLI_MCC_5_2x2, + PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1, + PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2); + + if (index != PM_MAX_TWO_CONNECTION_MODE) + return index; + + index = + policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs( + PM_P2P_CLI_P2P_CLI_SBS_5_1x1, + PM_P2P_CLI_P2P_CLI_SBS_5_2x2, + PM_P2P_CLI_P2P_CLI_DBS_1x1, + PM_P2P_CLI_P2P_CLI_DBS_2x2); + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_go_go(void) +{ + enum policy_mgr_two_connection_mode index; + + index = + policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( + PM_P2P_GO_P2P_GO_SCC_24_1x1, + PM_P2P_GO_P2P_GO_SCC_24_2x2, + PM_P2P_GO_P2P_GO_SCC_5_1x1, + PM_P2P_GO_P2P_GO_SCC_5_2x2); + if (index != PM_MAX_TWO_CONNECTION_MODE) + return index; + + index = + policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc( + PM_P2P_GO_P2P_GO_MCC_24_1x1, + PM_P2P_GO_P2P_GO_MCC_24_2x2, + PM_P2P_GO_P2P_GO_MCC_5_1x1, + PM_P2P_GO_P2P_GO_MCC_5_2x2, + PM_P2P_GO_P2P_GO_MCC_24_5_1x1, + PM_P2P_GO_P2P_GO_MCC_24_5_2x2); + if (index != PM_MAX_TWO_CONNECTION_MODE) + return index; + + index = + policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs( + PM_P2P_GO_P2P_GO_SBS_5_1x1, + PM_P2P_GO_P2P_GO_SBS_5_2x2, + PM_P2P_GO_P2P_GO_DBS_1x1, + PM_P2P_GO_P2P_GO_DBS_2x2); return index; } @@ -1977,6 +2120,11 @@ enum policy_mgr_two_connection_mode index = policy_mgr_get_third_connection_pcl_table_index_go_go(); + else if ((pm_conc_connection_list[0].mode == PM_P2P_CLIENT_MODE) && + (pm_conc_connection_list[1].mode == PM_P2P_CLIENT_MODE)) + index = + policy_mgr_get_third_connection_pcl_table_index_cli_cli(); + policy_mgr_debug("mode0:%d mode1:%d freq0:%d freq1:%d chain:%d index:%d", pm_conc_connection_list[0].mode, pm_conc_connection_list[1].mode, @@ -2547,7 +2695,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, if ((mode == PM_P2P_GO_MODE || mode == PM_P2P_CLIENT_MODE) || (mode == PM_STA_MODE && policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, - NULL) > 0)) { + NULL))) { /* * Store the STA mode's parameter and temporarily delete it * from the concurrency table. This way the allow concurrency @@ -2566,10 +2714,22 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, for (i = 0; i < weight->saved_num_chan; i++) { if (policy_mgr_is_concurrency_allowed (psoc, mode, weight->saved_chan_list[i], - HW_MODE_20_MHZ)) { + HW_MODE_20_MHZ) && + (policy_mgr_mode_specific_connection_count + (psoc, PM_P2P_GO_MODE, NULL) || + policy_mgr_mode_specific_connection_count + (psoc, PM_P2P_CLIENT_MODE, NULL)) && + policy_mgr_go_scc_enforced(psoc)) + /* + * For two port/three port connection where if one p2p + * connection is already present and force scc is enabled + * then enforce Go negotiation channels to be strictly + * based on PCL list. + */ + weight->weighed_valid_list[i] = 0; + else weight->weighed_valid_list[i] = - WEIGHT_OF_NON_PCL_CHANNELS; - } + WEIGHT_OF_NON_PCL_CHANNELS; } /* Restore the connection info */ if (mode == PM_STA_MODE) @@ -2787,3 +2947,82 @@ bool policy_mgr_is_sta_chan_valid_for_connect_and_roam( return true; } + +bool policy_mgr_is_3rd_conn_on_same_band_allowed(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode) +{ + enum policy_mgr_pcl_type pcl = PM_NONE; + enum policy_mgr_conc_priority_mode conc_system_pref = 0; + enum policy_mgr_two_connection_mode third_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + bool ret = false; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("context is NULL"); + return false; + } + + policy_mgr_debug("pref:%d requested mode:%d", + pm_ctx->cur_conc_system_pref, mode); + + switch (pm_ctx->cur_conc_system_pref) { + case 0: + conc_system_pref = PM_THROUGHPUT; + break; + case 1: + conc_system_pref = PM_POWERSAVE; + break; + case 2: + conc_system_pref = PM_LATENCY; + break; + default: + policy_mgr_err("unknown cur_conc_system_pref value %d", + pm_ctx->cur_conc_system_pref); + break; + } + + third_index = policy_mgr_get_third_connection_pcl_table_index(psoc); + if (PM_MAX_TWO_CONNECTION_MODE == third_index) { + policy_mgr_err( + "couldn't find index for 3rd connection pcl table"); + return false; + } + if (policy_mgr_is_hw_dbs_capable(psoc) == true) { + pcl = (*third_connection_pcl_dbs_table) + [third_index][mode][conc_system_pref]; + } else { + pcl = (*third_connection_pcl_non_dbs_table) + [third_index][mode][conc_system_pref]; + } + + policy_mgr_debug("pcl for third connection is %d", pcl); + switch (pcl) { + case PM_SCC_CH: + case PM_SCC_CH_24G: + case PM_SCC_CH_5G: + case PM_24G_SCC_CH: + case PM_5G_SCC_CH: + case PM_SCC_ON_5_SCC_ON_24_24G: + case PM_SCC_ON_5_SCC_ON_24_5G: + case PM_SCC_ON_24_SCC_ON_5_24G: + case PM_SCC_ON_24_SCC_ON_5_5G: + case PM_SCC_ON_5_SCC_ON_24: + case PM_SCC_ON_24_SCC_ON_5: + case PM_24G_SCC_CH_SBS_CH: + case PM_24G_SCC_CH_SBS_CH_5G: + case PM_MCC_CH: + case PM_MCC_CH_24G: + case PM_MCC_CH_5G: + case PM_24G_MCC_CH: + case PM_5G_MCC_CH: + case PM_24G_SBS_CH_MCC_CH: + ret = true; + break; + default: + policy_mgr_debug("Not in SCC case"); + ret = false; + break; + } + return ret; +} diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h index 4d1d964696e6..fe458df7fd2d 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -570,8 +571,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_P2P_GO_SCC_24_2x2] = { [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -590,8 +590,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_P2P_GO_MCC_24_2x2] = { [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -616,8 +615,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_SAP_MODE] = { PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -640,8 +638,7 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -690,8 +687,8 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, @@ -1150,6 +1147,182 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + [PM_P2P_CLI_P2P_CLI_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_DBS_1x1] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_DBS_2x2] = { + [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_P2P_CLI_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + [PM_STA_P2P_CLI_SCC_24_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -1166,10 +1339,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -1190,10 +1361,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -1214,10 +1383,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -1238,10 +1405,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -1288,10 +1453,10 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_NAN_DISC_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -1322,8 +1487,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = { - [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { @@ -1349,7 +1513,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_5G, PM_5G, PM_5G}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { @@ -1374,8 +1538,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = { - [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { @@ -1401,7 +1564,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_24G, PM_24G, PM_24G}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { @@ -1452,8 +1615,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_DBS_2x2] = { - [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_STA_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 020a96b617cf..1bf5978842d5 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 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 @@ -3242,4 +3242,22 @@ QDF_STATUS wlan_mlme_get_channel_bonding_5ghz(struct wlan_objmgr_psoc *psoc, uint32_t *value); +#ifdef WLAN_FEATURE_P2P_P2P_STA +/** + * wlan_mlme_get_p2p_p2p_conc_support() - Get p2p+p2p conc support + * + * @psoc: pointer to psoc object + * @val : value + * + * Return: Success/failure + */ +bool +wlan_mlme_get_p2p_p2p_conc_support(struct wlan_objmgr_psoc *psoc); +#else +static inline bool +wlan_mlme_get_p2p_p2p_conc_support(struct wlan_objmgr_psoc *psoc) +{ + return false; +} +#endif #endif /* _WLAN_MLME_API_H_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index ee1347cda4d7..2dc3b418de18 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 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 @@ -5020,3 +5020,12 @@ wlan_mlme_get_channel_bonding_5ghz(struct wlan_objmgr_psoc *psoc, *value = mlme_obj->cfg.feature_flags.channel_bonding_mode_5ghz; return QDF_STATUS_SUCCESS; } + +#ifdef WLAN_FEATURE_P2P_P2P_STA +bool +wlan_mlme_get_p2p_p2p_conc_support(struct wlan_objmgr_psoc *psoc) +{ + return wlan_psoc_nif_fw_ext_cap_get(psoc, + WLAN_SOC_EXT_P2P_P2P_CONC_SUPPORT); +} +#endif diff --git a/components/p2p/core/src/wlan_p2p_roc.c b/components/p2p/core/src/wlan_p2p_roc.c index 7fa8a6c5b6ff..7146367eae62 100644 --- a/components/p2p/core/src/wlan_p2p_roc.c +++ b/components/p2p/core/src/wlan_p2p_roc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -136,11 +137,30 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) is_dbs = policy_mgr_is_hw_dbs_capable(p2p_soc_obj->soc); if (go_num) - req->scan_req.dwell_time_passive *= + /* Add fixed 300ms extra ROC time instead of multiplying the + * ROC duration by const value as this causes the ROC to be + * upto 1.5 secs if GO is present. Firmware will advertize NOA + * of 1.5 secs and if supplicant cancels ROC after 200 or 300ms + * then firmware cannot cancel NOA. So when supplicant sends + * next ROC it will be delayed as firmware already is running + * previous NOA. This causes p2p find issues if GO is present. + * So add fixed duration of 300ms and also cap max ROC to 600ms + * when GO is present + */ + req->scan_req.dwell_time_passive += P2P_ROC_DURATION_MULTI_GO_PRESENT; else req->scan_req.dwell_time_passive *= P2P_ROC_DURATION_MULTI_GO_ABSENT; + if (go_num && req->scan_req.dwell_time_passive > + P2P_MAX_ROC_DURATION_GO_PRESENT) { + req->scan_req.dwell_time_passive = + P2P_MAX_ROC_DURATION_GO_PRESENT; + } else if (req->scan_req.dwell_time_passive > + P2P_MAX_ROC_DURATION) { + req->scan_req.dwell_time_passive = P2P_MAX_ROC_DURATION; + } + /* this is to protect too huge value if some customers * give a higher value from supplicant */ @@ -162,9 +182,6 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) P2P_MAX_ROC_DURATION_NON_DBS_NAN_PRESENT) req->scan_req.dwell_time_passive = P2P_MAX_ROC_DURATION_NON_DBS_NAN_PRESENT; - } else if (req->scan_req.dwell_time_passive > - P2P_MAX_ROC_DURATION) { - req->scan_req.dwell_time_passive = P2P_MAX_ROC_DURATION; } } p2p_debug("FW requested roc duration is:%d", diff --git a/components/p2p/core/src/wlan_p2p_roc.h b/components/p2p/core/src/wlan_p2p_roc.h index cfcb586d89c3..143e01726a8f 100644 --- a/components/p2p/core/src/wlan_p2p_roc.h +++ b/components/p2p/core/src/wlan_p2p_roc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -35,8 +36,9 @@ #define P2P_MAX_ROC_DURATION_NON_DBS_NDP_PRESENT 250 #define P2P_MAX_ROC_DURATION_DBS_NAN_PRESENT 450 #define P2P_MAX_ROC_DURATION_NON_DBS_NAN_PRESENT 300 +#define P2P_MAX_ROC_DURATION_GO_PRESENT 600 -#define P2P_ROC_DURATION_MULTI_GO_PRESENT 6 +#define P2P_ROC_DURATION_MULTI_GO_PRESENT 300 #define P2P_ROC_DURATION_MULTI_GO_ABSENT 10 #define P2P_ACTION_FRAME_DEFAULT_WAIT 200 #define P2P_ROC_DEFAULT_DURATION 200 diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_main.c b/components/pkt_capture/core/src/wlan_pkt_capture_main.c index 72b08322e3fc..27081aa1c9a6 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_main.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_main.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 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 @@ -125,8 +125,8 @@ static void pkt_capture_wdi_event_unsubscribe(struct wlan_objmgr_psoc *psoc) WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA); /* unsubscribe for rx data no peer packets */ - cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER, - WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER); + cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER, + WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER); /* unsubscribing for rx data packets */ cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_RX_SUBSCRIBER, diff --git a/configs/default_defconfig b/configs/default_defconfig index 024743284a2d..1a3b0a244cdf 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -199,6 +199,7 @@ ifeq ($(CONFIG_ARCH_QCS40X), y) CONFIG_WLAN_CLD_PM_QOS := y endif CONFIG_WLAN_FEATURE_MBSSID := y +CONFIG_WLAN_FEATURE_P2P_P2P_STA := y #Flag to enable Legacy Fast Roaming3(LFR3) ifeq (y,$(findstring y,$(CONFIG_HELIUMPLUS) $(CONFIG_LITHIUM))) @@ -973,8 +974,6 @@ CONFIG_FEATURE_INTEROP_ISSUES_AP := y CONFIG_FEATURE_WLAN_WAPI := y -CONFIG_AGEIE_ON_SCAN_RESULTS := y - #Flag to enable FW log parsing support feature CONFIG_FEATURE_FW_LOG_PARSING := y diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 67f3e1f93559..7fd32192150a 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 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 @@ -165,7 +165,7 @@ u8 ccp_rsn_oui_13[HDD_RSN_OUI_SIZE] = {0x50, 0x6F, 0x9A, 0x01}; #define HDD_PEER_AUTHORIZE_WAIT 10 -/** +/* * beacon_filter_table - table of IEs used for beacon filtering */ static const int beacon_filter_table[] = { @@ -434,18 +434,6 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress( hdd_adapter_dev_put_debug(next_adapter, dbgid); return adapter; - } else if ((eConnectionState_Associated == - hdd_sta_ctx->conn_info.conn_state) && - sme_is_sta_key_exchange_in_progress( - hdd_ctx->mac_handle, - adapter->vdev_id)) { - hdd_debug("vdev_id %d: Key exchange is in progress", - adapter->vdev_id); - hdd_adapter_dev_put_debug(adapter, dbgid); - if (next_adapter) - hdd_adapter_dev_put_debug(next_adapter, - dbgid); - return adapter; } } hdd_adapter_dev_put_debug(adapter, dbgid); diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index bc93b02a6359..1bc03e75936e 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 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 @@ -7237,6 +7237,8 @@ const struct nla_policy wlan_hdd_wifi_config_policy[ [QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS] = {.type = NLA_U8 }, [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS] = {.type = NLA_U8 }, [QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE] = { + .type = NLA_U8 }, }; static const struct nla_policy @@ -9017,6 +9019,38 @@ static int hdd_set_nss(struct hdd_adapter *adapter, return ret; } +/** + * hdd_set_wfc_state() - Set wfc state + * @adapter: hdd adapter + * @attr: pointer to nla attr + * + * Return: 0 on success, negative on failure + */ +static int hdd_set_wfc_state(struct hdd_adapter *adapter, + const struct nlattr *attr) +{ + uint8_t cfg_val; + enum pld_wfc_mode set_val; + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + int errno; + + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; + + cfg_val = nla_get_u8(attr); + + hdd_debug_rl("set wfc state %d", cfg_val); + if (cfg_val == 0) + set_val = PLD_WFC_MODE_OFF; + else if (cfg_val == 1) + set_val = PLD_WFC_MODE_ON; + else + return -EINVAL; + + return pld_set_wfc_mode(hdd_ctx->parent_dev, set_val); +} + /** * typedef independent_setter_fn - independent attribute handler * @adapter: The adapter being configured @@ -9129,6 +9163,8 @@ static const struct independent_setters independent_setters[] = { hdd_config_udp_qos_upgrade_threshold}, {QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS, hdd_set_ft_over_ds}, + {QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE, + hdd_set_wfc_state}, }; #ifdef WLAN_FEATURE_ELNA @@ -19714,7 +19750,8 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, const u8 *ssid, size_t ssid_len, const u8 *bssid, const u8 *bssid_hint, uint32_t oper_freq, - enum nl80211_chan_width ch_width) + enum nl80211_chan_width ch_width, + uint32_t ch_freq_hint) { int status = 0; QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; @@ -19907,6 +19944,8 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, roam_profile->ChannelInfo.numOfChannels = 0; } + roam_profile->freq_hint = ch_freq_hint; + if (wlan_hdd_cfg80211_check_pmf_valid(roam_profile)) { status = -EINVAL; goto conn_failure; @@ -21723,6 +21762,7 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, #endif struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); struct hdd_context *hdd_ctx; + uint32_t ch_freq_hint = 0; hdd_enter(); @@ -21838,11 +21878,15 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, else ch_freq = 0; + if (req->channel_hint) + ch_freq_hint = req->channel_hint->center_freq; + wlan_hdd_check_ht20_ht40_ind(hdd_ctx, adapter, req); status = wlan_hdd_cfg80211_connect_start(adapter, req->ssid, req->ssid_len, req->bssid, - bssid_hint, ch_freq, 0); + bssid_hint, ch_freq, 0, + ch_freq_hint); if (status) { wlan_hdd_cfg80211_clear_privacy(adapter); hdd_err("connect failed"); diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index f5edc1c9c586..d1d8318f2802 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5273,24 +5273,6 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, return -EINVAL; } } - /* - * For STA+SAP concurrency support from GUI, first STA connection gets - * triggered and while it is in progress, SAP start also comes up. - * Once STA association is successful, STA connect event is sent to - * kernel which gets queued in kernel workqueue and supplicant won't - * process M1 received from AP and send M2 until this NL80211_CONNECT - * event is received. Workqueue is not scheduled as RTNL lock is already - * taken by hostapd thread which has issued start_bss command to driver. - * Driver cannot complete start_bss as the pending command at the head - * of the SME command pending list is hw_mode_update for STA session - * which cannot be processed as SME is in WAITforKey state for STA - * interface. The start_bss command for SAP interface is queued behind - * the hw_mode_update command and so it cannot be processed until - * hw_mode_update command is processed. This is causing a deadlock so - * disconnect the STA interface first if connection or key exchange is - * in progress and then start SAP interface. - */ - hdd_abort_ongoing_sta_connection(hdd_ctx); mac_handle = hdd_ctx->mac_handle; @@ -6070,13 +6052,6 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, hdd_debug("Device_mode %s(%d)", qdf_opmode_str(adapter->device_mode), adapter->device_mode); - /* - * If a STA connection is in progress in another adapter, disconnect - * the STA and complete the SAP operation. STA will reconnect - * after SAP stop is done. - */ - hdd_abort_ongoing_sta_connection(hdd_ctx); - if (adapter->device_mode == QDF_SAP_MODE) { wlan_hdd_del_station(adapter); mac_handle = hdd_ctx->mac_handle; @@ -6361,6 +6336,9 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter, return false; } + if (adapter->device_mode == QDF_P2P_GO_MODE && + policy_mgr_is_p2p_p2p_conc_supported(hdd_ctx->psoc)) + return false; if (!policy_mgr_concurrent_beaconing_sessions_running(hdd_ctx->psoc)) return false; if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(hdd_ctx->psoc)) diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index 1030046ff134..6bfdee44a536 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 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 @@ -6507,12 +6507,15 @@ static int drv_cmd_set_channel_switch(struct hdd_adapter *adapter, return status; } - if ((chan_bw != 20) && (chan_bw != 40) && (chan_bw != 80)) { + if ((chan_bw != 20) && (chan_bw != 40) && (chan_bw != 80) && + (chan_bw != 160)) { hdd_err("BW %d is not allowed for CHANNEL_SWITCH", chan_bw); return -EINVAL; } - if (chan_bw == 80) + if (chan_bw == 160) + width = CH_WIDTH_160MHZ; + else if (chan_bw == 80) width = CH_WIDTH_80MHZ; else if (chan_bw == 40) width = CH_WIDTH_40MHZ; diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index 16cc1e458c3d..d947d31a71d0 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 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 @@ -803,7 +803,10 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, name_assign_type, true); } else { uint8_t *device_address; - + if (strnstr(name, "p2p", 3) && mode == QDF_STA_MODE) { + hdd_debug("change mode to p2p device"); + mode = QDF_P2P_DEVICE_MODE; + } device_address = wlan_hdd_get_intf_addr(hdd_ctx, mode); if (!device_address) return ERR_PTR(-EINVAL); diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index cddc1e33bd58..aea31a5f4d54 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -32,9 +32,9 @@ #define QWLAN_VERSION_MAJOR 2 #define QWLAN_VERSION_MINOR 0 #define QWLAN_VERSION_PATCH 8 -#define QWLAN_VERSION_EXTRA "E" +#define QWLAN_VERSION_EXTRA "R" #define QWLAN_VERSION_BUILD 32 -#define QWLAN_VERSIONSTR "2.0.8.32E" +#define QWLAN_VERSIONSTR "2.0.8.32R" #endif /* QWLAN_VERSION_H */ diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h index 772007805899..27b6447cea4e 100644 --- a/core/pld/inc/pld_common.h +++ b/core/pld/inc/pld_common.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 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 @@ -133,6 +133,16 @@ enum pld_platform_cap_flag { PLD_HAS_DRV_SUPPORT = 0x04, }; +/** + * enum pld_wfc_mode - WFC Mode + * @PLD_WFC_MODE_OFF: WFC Inactive + * @PLD_WFC_MODE_ON: WFC Active + */ +enum pld_wfc_mode { + PLD_WFC_MODE_OFF, + PLD_WFC_MODE_ON, +}; + /** * struct pld_platform_cap - platform capabilities * @cap_flag: capabilities flag @@ -946,6 +956,15 @@ int pld_thermal_register(struct device *dev, unsigned long state, int mon_id); */ void pld_thermal_unregister(struct device *dev, int mon_id); +/** + * pld_set_wfc_mode() - Sent WFC mode to FW via platform driver + * @dev: The device structure + * @wfc_mode: WFC Modes (0 => Inactive, 1 => Active) + * + * Return: Error code on error + */ +int pld_set_wfc_mode(struct device *dev, enum pld_wfc_mode wfc_mode); + /** * pld_bus_width_type_to_str() - Helper function to convert PLD bandwidth level * to string diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c index b756a115bb98..a75c8c20adad 100644 --- a/core/pld/src/pld_common.c +++ b/core/pld/src/pld_common.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 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 @@ -3154,6 +3154,32 @@ void pld_thermal_unregister(struct device *dev, int mon_id) } } +int pld_set_wfc_mode(struct device *dev, enum pld_wfc_mode wfc_mode) +{ + int errno = -ENOTSUPP; + enum pld_bus_type type; + + type = pld_get_bus_type(dev); + switch (type) { + case PLD_BUS_TYPE_SDIO: + case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI_FW_SIM: + case PLD_BUS_TYPE_SNOC_FW_SIM: + case PLD_BUS_TYPE_IPCI: + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE: + errno = pld_pcie_set_wfc_mode(dev, wfc_mode); + break; + default: + pr_err("Invalid device type %d\n", type); + break; + } + + return errno; +} + const char *pld_bus_width_type_to_str(enum pld_bus_width_type level) { switch (level) { diff --git a/core/pld/src/pld_pcie.c b/core/pld/src/pld_pcie.c index 8132f4f42069..e04f9a904397 100644 --- a/core/pld/src/pld_pcie.c +++ b/core/pld/src/pld_pcie.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -940,5 +941,30 @@ void pld_pcie_device_self_recovery(struct device *dev, } cnss_self_recovery(dev, cnss_reason); } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +int pld_pcie_set_wfc_mode(struct device *dev, + enum pld_wfc_mode wfc_mode) +{ + struct cnss_wfc_cfg cfg; + int ret; + + switch (wfc_mode) { + case PLD_WFC_MODE_OFF: + cfg.mode = CNSS_WFC_MODE_OFF; + break; + case PLD_WFC_MODE_ON: + cfg.mode = CNSS_WFC_MODE_ON; + break; + default: + ret = -EINVAL; + goto out; + } + + ret = cnss_set_wfc_mode(dev, cfg); +out: + return ret; +} +#endif #endif #endif diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h index 07ed2933cf7b..607367c0c887 100644 --- a/core/pld/src/pld_pcie.h +++ b/core/pld/src/pld_pcie.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -404,7 +405,24 @@ static inline bool pld_pcie_platform_driver_support(void) { return false; } + +static inline int pld_pcie_set_wfc_mode(struct device *dev, + enum pld_wfc_mode wfc_mode) +{ + return 0; +} #else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +int pld_pcie_set_wfc_mode(struct device *dev, + enum pld_wfc_mode wfc_mode); +#else +static inline int pld_pcie_set_wfc_mode(struct device *dev, + enum pld_wfc_mode wfc_mode) +{ + return 0; +} +#endif + int pld_pcie_get_fw_files_for_target(struct device *dev, struct pld_fw_files *pfw_files, u32 target_type, u32 target_version); diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c index 8bf3e659ad17..2e3860804dc9 100644 --- a/core/sap/src/sap_api_link_cntl.c +++ b/core/sap/src/sap_api_link_cntl.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -829,6 +830,51 @@ static void wlansap_update_vendor_acs_chan(struct mac_context *mac_ctx, } } +#ifdef WLAN_FEATURE_P2P_P2P_STA +/** + * sap_check_and_process_forcescc_for_other_go() - find if other p2p go is there + * and needs to be moved to current p2p go's channel. + * + * @cur_sap_ctx: current sap context + * + * Return: None + */ +static void +sap_check_and_process_forcescc_for_other_go(struct sap_context *cur_sap_ctx) +{ + struct sap_context *sap_ctx; + struct mac_context *mac_ctx; + uint8_t i; + + mac_ctx = sap_get_mac_context(); + if (!mac_ctx) { + sap_err("Invalid MAC context"); + return; + } + + for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { + sap_ctx = mac_ctx->sap.sapCtxList[i].sap_context; + if (sap_ctx && + QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[i].sapPersona && + sap_ctx->is_forcescc_restart_required) { + sap_debug("sessionId %d chan_freq %d chan_width %d", + sap_ctx->sessionId, cur_sap_ctx->chan_freq, + cur_sap_ctx->ch_params.ch_width); + policy_mgr_process_forcescc_for_go( + mac_ctx->psoc, sap_ctx->sessionId, + cur_sap_ctx->chan_freq, + cur_sap_ctx->ch_params.ch_width); + sap_ctx->is_forcescc_restart_required = false; + break; + } + } +} +#else +static void +sap_check_and_process_forcescc_for_other_go(struct sap_context *cur_sap_ctx) +{} +#endif + QDF_STATUS wlansap_roam_callback(void *ctx, struct csr_roam_info *csr_roam_info, uint32_t roam_id, @@ -1157,10 +1203,25 @@ QDF_STATUS wlansap_roam_callback(void *ctx, * disassoc event * Fill in the event structure */ - if (roam_status == eCSR_ROAM_SET_KEY_COMPLETE) + if (roam_status == eCSR_ROAM_SET_KEY_COMPLETE) { sap_signal_hdd_event(sap_ctx, csr_roam_info, eSAP_STA_SET_KEY_EVENT, (void *) eSAP_STATUS_SUCCESS); + + /* + * After set key if this is the first peer connecting to new GO + * then check for peer count (which is self peer + peer count) + * and take decision for GO+GO force SCC + */ + if (sap_ctx->vdev->vdev_mlme.vdev_opmode == + QDF_P2P_GO_MODE && + wlan_vdev_get_peer_count(sap_ctx->vdev) == 2 && + policy_mgr_mode_specific_connection_count( + mac_ctx->psoc, PM_P2P_GO_MODE, + NULL) > 1) + sap_check_and_process_forcescc_for_other_go( + sap_ctx); + } break; case eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED: /* Fill in the event structure */ diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 681e70398140..81ab4af7735a 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 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 @@ -784,6 +784,41 @@ static bool is_mcc_preferred(struct sap_context *sap_context, return false; } +#ifdef WLAN_FEATURE_P2P_P2P_STA +/** + * sap_set_forcescc_required - set force scc flag for provided p2p go vdev + * + * vdev_id - vdev_id for which flag needs to be set + * + * Return: None + */ +static void sap_set_forcescc_required(uint8_t vdev_id) +{ + struct mac_context *mac_ctx; + struct sap_context *sap_ctx; + uint8_t i = 0; + + mac_ctx = sap_get_mac_context(); + if (!mac_ctx) { + sap_err("Invalid MAC context"); + return; + } + + for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { + sap_ctx = mac_ctx->sap.sapCtxList[i].sap_context; + if (QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[i].sapPersona && + sap_ctx->sessionId == vdev_id) { + sap_debug("update forcescc restart for vdev %d", + vdev_id); + sap_ctx->is_forcescc_restart_required = true; + } + } +} +#else +static void sap_set_forcescc_required(uint8_t vdev_id) +{} +#endif + QDF_STATUS sap_validate_chan(struct sap_context *sap_context, bool pre_start_bss, @@ -799,6 +834,8 @@ sap_validate_chan(struct sap_context *sap_context, uint32_t concurrent_state; bool go_force_scc; struct ch_params ch_params = {0}; + bool is_go_scc_strict = false; + uint8_t first_p2p_go_vdev_id = WLAN_UMAC_VDEV_ID_MAX; mac_handle = cds_get_context(QDF_MODULE_ID_SME); mac_ctx = MAC_CONTEXT(mac_handle); @@ -812,10 +849,45 @@ sap_validate_chan(struct sap_context *sap_context, sap_err("Invalid channel"); return QDF_STATUS_E_FAILURE; } - go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc); - if (sap_context->vdev && !go_force_scc && - (wlan_vdev_mlme_get_opmode(sap_context->vdev) == QDF_P2P_GO_MODE)) - goto validation_done; + + if (sap_context->vdev && + sap_context->vdev->vdev_mlme.vdev_opmode == QDF_P2P_GO_MODE) { + /* + * check whether go_force_scc is enabled or not. + * If it not enabled then don't any force scc on existing and new + * p2p go vdevs. + * Otherwise, if it is enabled then check whether it's in strict + * mode or liberal mode. + * For strict mode, do force scc on newly p2p go to existing p2p + * go channel. + * For liberal mode, first form new p2p go on requested channel. + * Once set key is done, do force scc on existing p2p go to new + * p2p go channel. + */ + go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc); + sap_debug("go force scc value %d", go_force_scc); + if (go_force_scc) { + is_go_scc_strict = + policy_mgr_is_go_scc_strict(mac_ctx->psoc); + if (!is_go_scc_strict) { + sap_debug("liberal mode is enabled"); + first_p2p_go_vdev_id = + policy_mgr_check_forcescc_for_other_go( + mac_ctx->psoc, + sap_context->sessionId, + sap_context->chan_freq); + + if (first_p2p_go_vdev_id < + WLAN_UMAC_VDEV_ID_MAX) { + sap_set_forcescc_required( + first_p2p_go_vdev_id); + goto validation_done; + } + } + } else { + goto validation_done; + } + } concurrent_state = policy_mgr_get_concurrency_mode(mac_ctx->psoc); if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) || diff --git a/core/sap/src/sap_internal.h b/core/sap/src/sap_internal.h index bfad11f685b5..b13ee52c0f58 100644 --- a/core/sap/src/sap_internal.h +++ b/core/sap/src/sap_internal.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -230,6 +231,13 @@ struct sap_context { bool is_chan_change_inprogress; qdf_list_t owe_pending_assoc_ind_list; uint32_t freq_before_ch_switch; +#ifdef WLAN_FEATURE_P2P_P2P_STA +/* + *This param is used for GO+GO force scc logic where after + *setkey first GO will move to latest GO's channel + */ + bool is_forcescc_restart_required; +#endif }; /*---------------------------------------------------------------------------- diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 133896da4386..d2b522974b6b 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -662,6 +663,7 @@ struct csr_roam_profile { tCsrKeys Keys; tCsrChannelInfo ChannelInfo; uint32_t op_freq; + uint32_t freq_hint; struct ch_params ch_params; /* If this is 0, SME will fill in for caller. */ uint16_t beaconInterval; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 854b6c35a72e..0b75b2e3a1e8 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 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 @@ -8711,35 +8711,60 @@ bool is_disconnect_pending(struct mac_context *pmac, uint8_t vdev_id) return disconnect_cmd_exist; } -bool is_disconnect_pending_on_other_vdev(struct mac_context *pmac, - uint8_t vdev_id) +bool is_any_other_vdev_connecting_disconnecting(struct mac_context *pmac, + uint8_t vdev_id) { tListElem *entry = NULL; tListElem *next_entry = NULL; tSmeCmd *command = NULL; - bool disconnect_cmd_exist = false; + bool is_pending_cmd = false; + enum QDF_OPMODE opmode; entry = csr_nonscan_pending_ll_peek_head(pmac, LL_ACCESS_NOLOCK); while (entry) { next_entry = csr_nonscan_pending_ll_next(pmac, entry, LL_ACCESS_NOLOCK); command = GET_BASE_ADDR(entry, tSmeCmd, Link); - /* - * check if any other vdev NB disconnect or SB disconnect - * (eSmeCommandWmStatusChange) is pending - */ - if (command && (CSR_IS_DISCONNECT_COMMAND(command) || - command->command == eSmeCommandWmStatusChange) && - command->vdev_id != vdev_id) { - sme_debug("disconnect is pending on vdev:%d, cmd:%d", - command->vdev_id, command->command); - disconnect_cmd_exist = true; - break; + if (!command) { + entry = next_entry; + continue; } + + opmode = wlan_get_opmode_from_vdev_id(pmac->pdev, + command->vdev_id); + + if (opmode == QDF_STA_MODE || opmode == QDF_P2P_CLIENT_MODE) { + /* + * check if any other vdev NB disconnect or SB + * disconnect (eSmeCommandWmStatusChange) is pending + */ + if ((CSR_IS_DISCONNECT_COMMAND(command) || + command->command == eSmeCommandWmStatusChange) && + command->vdev_id != vdev_id) { + sme_debug("disconnect is pending on vdev:%d, cmd:%d", + command->vdev_id, command->command); + is_pending_cmd = true; + break; + } + } + + if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) { + /* Check if START/STOP AP OP is in progress */ + if ((command->command == eSmeCommandRoam && + (command->u.roamCmd.roamReason == eCsrStopBss || + command->u.roamCmd.roamReason == eCsrHddIssued))) { + sme_debug("vdev ops pending on vdev_id:%d, cmd:%d, reason:%d", + command->vdev_id, command->command, + command->u.roamCmd.roamReason); + is_pending_cmd = true; + break; + } + } + entry = next_entry; } - return disconnect_cmd_exist; + return is_pending_cmd; } #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) @@ -8861,7 +8886,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, struct csr_roam_connectedinfo *prev_connect_info; struct wlan_crypto_pmksa *pmksa; uint32_t len = 0, roamId = 0, reason_code = 0; - bool is_dis_pending, is_dis_pending_on_other_vdev; + bool is_dis_pending, is_vdev_ops_pending_on_other_vdev; bool use_same_bss = false; uint8_t max_retry_count = 1; bool retry_same_bss = false; @@ -8965,8 +8990,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, reason_code); is_dis_pending = is_disconnect_pending(mac, session_ptr->sessionId); - is_dis_pending_on_other_vdev = - is_disconnect_pending_on_other_vdev(mac, + is_vdev_ops_pending_on_other_vdev = + is_any_other_vdev_connecting_disconnecting(mac, session_ptr->sessionId); is_time_allowed = csr_is_time_allowed_for_connect_attempt(pCommand, @@ -8976,7 +9001,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, * if userspace has issued disconnection or we have reached mac tries or * max time, driver should not continue for next connection. */ - if (is_dis_pending || is_dis_pending_on_other_vdev || !is_time_allowed || + if (is_dis_pending || is_vdev_ops_pending_on_other_vdev || !is_time_allowed || session_ptr->join_bssid_count >= CSR_MAX_BSSID_COUNT) attempt_next_bss = false; @@ -9092,8 +9117,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, if (is_dis_pending) sme_err("disconnect is pending, complete roam"); - if (is_dis_pending_on_other_vdev) - sme_err("disconnect is pending on other vdev, complete roam"); + if (is_vdev_ops_pending_on_other_vdev) + sme_err("vdev ops is pending on other vdev, complete roam"); if (!is_time_allowed) sme_err("time can exceed the active timeout for connection attempt"); diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 2a499ca3dcaf..e98e39512c71 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 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 @@ -1395,6 +1395,15 @@ QDF_STATUS csr_scan_for_ssid(struct mac_context *mac_ctx, uint32_t session_id, req->scan_req.chan_list.num_chan = num_chan; } + /* Add freq hint for scan for ssid */ + if (!num_chan && profile->freq_hint && + csr_roam_is_valid_channel(mac_ctx, profile->freq_hint)) { + sme_debug("add freq hint %d", profile->freq_hint); + req->scan_req.chan_list.chan[0].freq = + profile->freq_hint; + req->scan_req.chan_list.num_chan = 1; + } + /* Extend it for multiple SSID */ if (profile->SSIDs.numOfSSIDs) { if (profile->SSIDs.SSIDList[0].SSID.length > WLAN_SSID_MAX_LEN) { diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index b873e2aa8692..d9f9d701cc4c 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 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 @@ -984,15 +985,15 @@ bool is_disconnect_pending(struct mac_context *mac_ctx, uint8_t sessionid); /** - * is_disconnect_pending_on_other_vdev() - To check whether a disconnect req - * is pending on any other vdev or not + * is_any_other_vdev_connecting_disconnecting() - To check whether any other + * vdev is in waiting for vdev operations (connect/disconnect or start/stop AP) * @mac_tx: mac context * @sessionid: session id * * Return true if disconnect is pending on any other vdev */ -bool is_disconnect_pending_on_other_vdev(struct mac_context *mac_ctx, - uint8_t sessionid); +bool is_any_other_vdev_connecting_disconnecting(struct mac_context *mac_ctx, + uint8_t sessionid); QDF_STATUS csr_roam_prepare_bss_config_from_profile(struct mac_context *mac_ctx,