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 bb354d1e6631..11add67ba3d7 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 @@ -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 @@ -884,6 +884,7 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, * @psoc: PSOC object information * @mode: connection mode * @ch_freq: target channel frequency to switch + * @bw: target channel bandwidth * @vdev_id: vdev id of channel switch interface * @forced: forced to chan switch. * @reason: request reason of CSA @@ -903,8 +904,17 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint32_t ch_freq, uint32_t vdev_id, - bool forced, enum sap_csa_reason_code reason); + uint32_t ch_freq, enum hw_mode_bandwidth bw, + uint32_t vdev_id, bool forced, + enum sap_csa_reason_code reason); + +/** + * 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_first_connection_pcl_table_index() - provides the 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 4785a580def7..e54d98c61b7a 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 @@ -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 @@ -2653,11 +2653,14 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, } if (ch_freq) { - chan_state = wlan_reg_get_5g_bonded_channel_state_for_freq( + if (wlan_reg_is_5ghz_ch_freq(ch_freq)) { + chan_state = + wlan_reg_get_5g_bonded_channel_state_for_freq( pm_ctx->pdev, ch_freq, policy_mgr_get_ch_width(bw)); - if (chan_state == CHANNEL_STATE_DFS) - is_dfs_ch = true; + if (chan_state == CHANNEL_STATE_DFS) + is_dfs_ch = true; + } /* don't allow 3rd home channel on same MAC * also check for single mac target which doesn't * support interbad MCC as well @@ -2693,8 +2696,10 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); go_force_scc = policy_mgr_go_scc_enforced(psoc); - if ((!sta_sap_scc_on_dfs_chan && mode == PM_SAP_MODE) || - (!go_force_scc && mode == PM_P2P_GO_MODE)) { + if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) && + (!sta_sap_scc_on_dfs_chan || + !policy_mgr_is_sta_sap_scc(psoc, ch_freq) || + (!go_force_scc && mode == PM_P2P_GO_MODE))) { if (is_dfs_ch) match = policy_mgr_disallow_mcc(psoc, ch_freq); @@ -2796,8 +2801,9 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint32_t ch_freq, uint32_t vdev_id, - bool forced, enum sap_csa_reason_code reason) + uint32_t ch_freq, enum hw_mode_bandwidth bw, + uint32_t vdev_id, bool forced, + enum sap_csa_reason_code reason) { bool allow = false; struct policy_mgr_conc_connection_info @@ -2812,8 +2818,8 @@ policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, policy_mgr_err("Invalid Context"); return allow; } - policy_mgr_debug("check concurrency_csa vdev:%d ch %d, forced %d, reason %d", - vdev_id, ch_freq, forced, reason); + policy_mgr_debug("check concurrency_csa vdev:%d ch %d bw %d, forced %d, reason %d", + vdev_id, ch_freq, bw, forced, reason); status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &old_ch_freq); @@ -2851,8 +2857,7 @@ policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, policy_mgr_store_and_del_conn_info_by_vdev_id( psoc, vdev_id, info, &num_cxn_del); - allow = policy_mgr_allow_concurrency(psoc, mode, ch_freq, - HW_MODE_20_MHZ); + allow = policy_mgr_allow_concurrency(psoc, mode, ch_freq, bw); /* Restore the connection entry */ if (num_cxn_del > 0) policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); 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 fd6922e77d94..e70b599e774b 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. 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 @@ -570,14 +571,6 @@ 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); - 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, diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 929a936c5d14..a283dfd3c622 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -1822,6 +1822,7 @@ static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc, lfr->roam_preauth_retry_count = cfg_get(psoc, CFG_LFR3_ROAM_PREAUTH_RETRY_COUNT); lfr->roam_rssi_diff = cfg_get(psoc, CFG_LFR_ROAM_RSSI_DIFF); + lfr->roam_rssi_diff_6ghz = cfg_get(psoc, CFG_LFR_ROAM_RSSI_DIFF_6GHZ); lfr->bg_rssi_threshold = cfg_get(psoc, CFG_LFR_ROAM_BG_RSSI_TH); lfr->roam_scan_offload_enabled = cfg_get(psoc, CFG_LFR_ROAM_SCAN_OFFLOAD_ENABLED); diff --git a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h index 87eed6987544..6ad5d7011e58 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1250,6 +1251,35 @@ CFG_VALUE_OR_DEFAULT, \ "Enable roam based on rssi") +/* + * + * RoamRssiDiff6GHz - Enable roam to 6 GHz AP based on rssi + * @Min: 0 + * @Max: 100 + * @Default: 5 + * + * This INI is used to decide whether to roam to 6 GHz AP or not based on RSSI. + * AP1 is the currently associated AP(2.4 GHz / 5 GHz) and AP2(6 GHz) is chosen + * for roaming. The Roaming will happen only if AP2 has better Signal Quality + * and it has a RSSI better than AP1. RoamRssiDiff6GHz is the number of units + * (typically measured in dB) AP2 is better than AP1. + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: External + * + * + */ +#define CFG_LFR_ROAM_RSSI_DIFF_6GHZ CFG_INI_UINT( \ + "RoamRssiDiff6GHz", \ + 0, \ + 100, \ + 5, \ + CFG_VALUE_OR_DEFAULT, \ + "Enable 6 GHz roam based on rssi") + /* * * bg_rssi_threshold - To set RSSI Threshold for BG scan roaming @@ -2899,6 +2929,7 @@ CFG(CFG_LFR_MAWC_FEATURE_ENABLED) \ CFG(CFG_LFR_FAST_TRANSITION_ENABLED) \ CFG(CFG_LFR_ROAM_RSSI_DIFF) \ + CFG(CFG_LFR_ROAM_RSSI_DIFF_6GHZ) \ CFG(CFG_LFR_ROAM_BG_RSSI_TH) \ CFG(CFG_LFR_ENABLE_WES_MODE) \ CFG(CFG_LFR_ROAM_SCAN_OFFLOAD_ENABLED) \ diff --git a/components/mlme/dispatcher/inc/cfg_mlme_sap.h b/components/mlme/dispatcher/inc/cfg_mlme_sap.h index 894b6e9edf13..146ebb5b4cd0 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_sap.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_sap.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -261,7 +262,7 @@ * gSoftApMaxPeers - Set Max peers connected for SAP * @Min: 1 * @Max: 64 - * @Default: 32 + * @Default: 10 * * This ini is used to set Max peers connected for SAP * @@ -277,7 +278,7 @@ "gSoftApMaxPeers", \ 1, \ 64, \ - 32, \ + 10, \ CFG_VALUE_OR_DEFAULT, \ "max no of peers") diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 328d3edf40f4..19ce7447dad7 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1673,6 +1673,7 @@ struct fw_scan_channels { * @roam_preauth_retry_count: Configure the max number of preauth retry * @roam_preauth_no_ack_timeout: Configure the no ack timeout period * @roam_rssi_diff: Enable roam based on rssi + * @roam_rssi_diff_6ghz: RSSI diff value to be used for roaming to 6 GHz AP. * @roam_scan_offload_enabled: Enable Roam Scan Offload * @neighbor_scan_timer_period: Neighbor scan timer period * @neighbor_scan_min_timer_period: Min neighbor scan timer period @@ -1722,6 +1723,11 @@ struct fw_scan_channels { * @sae_single_pmk_feature_enabled: Contains value of ini * sae_single_pmk_feature_enabled * @enable_ft_over_ds: Flag to enable/disable FT-over-DS + * @roam_ho_delay_config: Roam HO delay value + * @exclude_rm_partial_scan_freq: Exclude the channels in roam full scan that + * are already scanned as part of partial scan. + * @roam_full_scan_6ghz_on_disc: Include the 6 GHz channels in roam full scan + * only on prior discovery of any 6 GHz support in the environment. */ struct wlan_mlme_lfr_cfg { bool mawc_roam_enabled; @@ -1790,6 +1796,7 @@ struct wlan_mlme_lfr_cfg { uint32_t roam_preauth_retry_count; uint32_t roam_preauth_no_ack_timeout; uint8_t roam_rssi_diff; + uint8_t roam_rssi_diff_6ghz; uint8_t bg_rssi_threshold; bool roam_scan_offload_enabled; uint32_t neighbor_scan_timer_period; @@ -1840,6 +1847,9 @@ struct wlan_mlme_lfr_cfg { bool sae_single_pmk_feature_enabled; #endif bool enable_ft_over_ds; + uint16_t roam_ho_delay_config; + uint8_t exclude_rm_partial_scan_freq; + uint8_t roam_full_scan_6ghz_on_disc; }; /** diff --git a/components/p2p/core/src/wlan_p2p_off_chan_tx.c b/components/p2p/core/src/wlan_p2p_off_chan_tx.c index 38fb76a21546..1478df85dce7 100644 --- a/components/p2p/core/src/wlan_p2p_off_chan_tx.c +++ b/components/p2p/core/src/wlan_p2p_off_chan_tx.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1545,38 +1546,6 @@ static QDF_STATUS p2p_disable_tx_timer(struct tx_action_context *tx_ctx) return status; } -/** - * is_rmf_mgmt_action_frame() - check RMF action frame by category - * @action_category: action frame actegory - * - * This function check the frame is robust mgmt action frame or not - * - * Return: true - if category is robust mgmt type - */ -static bool is_rmf_mgmt_action_frame(uint8_t action_category) -{ - switch (action_category) { - case ACTION_CATEGORY_SPECTRUM_MGMT: - case ACTION_CATEGORY_QOS: - case ACTION_CATEGORY_DLS: - case ACTION_CATEGORY_BACK: - case ACTION_CATEGORY_RRM: - case ACTION_FAST_BSS_TRNST: - case ACTION_CATEGORY_SA_QUERY: - case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION: - case ACTION_CATEGORY_WNM: - case ACTION_CATEGORY_MESH_ACTION: - case ACTION_CATEGORY_MULTIHOP_ACTION: - case ACTION_CATEGORY_DMG: - case ACTION_CATEGORY_FST: - case ACTION_CATEGORY_VENDOR_SPECIFIC_PROTECTED: - return true; - default: - break; - } - return false; -} - /** * p2p_populate_rmf_field() - populate unicast rmf frame * @tx_ctx: tx_action_context @@ -1620,7 +1589,7 @@ static QDF_STATUS p2p_populate_rmf_field(struct tx_action_context *tx_ctx, * to get the actual action category we need to ignore the MSB. */ action_category = action_hdr->action_category & 0x7f; - if (!is_rmf_mgmt_action_frame(action_category)) { + if (!wlan_mgmt_is_rmf_mgmt_action_frame(action_category)) { p2p_debug("non rmf act frame 0x%x category %x", tx_ctx->frame_info.sub_type, action_hdr->action_category); diff --git a/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h index 88b23b07ac3f..a38e36c8e84b 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -65,6 +66,7 @@ #define PMO_MAC_ACTION_FST 18 #define PMO_MAC_ACTION_RVS 19 #define PMO_MAC_ACTION_VHT 21 +#define PMO_VENDOR_PROTECTED 126 #define PMO_MAC_ACTION_MAX 256 /* @@ -96,6 +98,7 @@ * PMO_ACTION_FST 18 1 * PMO_ACTION_RVS 19 1 * PMO_ACTION_VHT 21 1 + * PMO_VENDOR_PROTECTED 126 1 * ----------------------------+------+-------+ */ #define SYSTEM_SUSPEND_ALLOWED_ACTION_FRAMES_BITMAP0 \ @@ -112,7 +115,9 @@ #define ALLOWED_ACTION_FRAMES_BITMAP1 0x0 #define ALLOWED_ACTION_FRAMES_BITMAP2 0x0 -#define ALLOWED_ACTION_FRAMES_BITMAP3 0x0 +#define ALLOWED_ACTION_FRAMES_BITMAP3 \ + (1 << (PMO_VENDOR_PROTECTED % 32)) + #define ALLOWED_ACTION_FRAMES_BITMAP4 0x0 #define ALLOWED_ACTION_FRAMES_BITMAP5 0x0 #define ALLOWED_ACTION_FRAMES_BITMAP6 0x0 diff --git a/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c b/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c index f2f046b22c48..7ad9b0a04ffc 100644 --- a/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c +++ b/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -130,11 +131,149 @@ target_if_cm_roam_rt_stats_config(struct wlan_objmgr_vdev *vdev, return status; } +/** + * target_if_cm_roam_ho_delay_config() - Send roam HO delay value to wmi + * @vdev: vdev object + * @vdev_id: vdev id + * @roam_ho_delay: roam hand-off delay value + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_cm_roam_ho_delay_config(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, uint16_t roam_ho_delay) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + wmi_unified_t wmi_handle; + + wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev); + if (!wmi_handle) + return status; + + status = target_if_roam_set_param( + wmi_handle, + vdev_id, + WMI_ROAM_PARAM_ROAM_HO_DELAY_RUNTIME_CONFIG, + roam_ho_delay); + + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("Failed to set " + "WMI_ROAM_PARAM_ROAM_HO_DELAY_RUNTIME_CONFIG"); + + return status; +} + +/** + * target_if_cm_exclude_rm_partial_scan_freq() - Indicate to FW whether to + * exclude the channels in roam full scan that are already scanned as part of + * partial scan or not. + * @vdev: vdev object + * @exclude_rm_partial_scan_freq: Include/exclude the channels in roam full scan + * that are already scanned as part of partial scan. + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_vdev *vdev, + uint8_t exclude_rm_partial_scan_freq) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint8_t vdev_id; + wmi_unified_t wmi_handle; + + wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev); + if (!wmi_handle) + return status; + + vdev_id = wlan_vdev_get_id(vdev); + status = target_if_roam_set_param( + wmi_handle, vdev_id, + WMI_ROAM_PARAM_ROAM_CONTROL_FULL_SCAN_CHANNEL_OPTIMIZATION, + exclude_rm_partial_scan_freq); + + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("Failed to set WMI_ROAM_PARAM_ROAM_CONTROL_FULL_SCAN_CHANNEL_OPTIMIZATION"); + + return status; +} + +/** + * target_if_cm_roam_full_scan_6ghz_on_disc() - Indicate to FW whether to + * include the 6 GHz channels in roam full scan only on prior discovery of any + * 6 GHz support in the environment or by default. + * @vdev: vdev object + * @roam_full_scan_6ghz_on_disc: Include the 6 GHz channels in roam full scan: + * 1 - Include only on prior discovery of any 6 GHz support in the environment + * 0 - Include all the supported 6 GHz channels by default + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_vdev *vdev, + uint8_t roam_full_scan_6ghz_on_disc) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint8_t vdev_id; + wmi_unified_t wmi_handle; + + wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev); + if (!wmi_handle) + return status; + + vdev_id = wlan_vdev_get_id(vdev); + status = target_if_roam_set_param(wmi_handle, vdev_id, + WMI_ROAM_PARAM_ROAM_CONTROL_FULL_SCAN_6GHZ_PSC_ONLY_WITH_RNR, + roam_full_scan_6ghz_on_disc); + + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("Failed to set WMI_ROAM_PARAM_ROAM_CONTROL_FULL_SCAN_6GHZ_PSC_ONLY_WITH_RNR"); + + return status; +} + +/** + * target_if_cm_roam_rssi_diff_6ghz() - Send the roam RSSI diff value to FW + * which is used to decide how better the RSSI of the new/roamable 6GHz AP + * should be for roaming. + * @vdev: vdev object + * @roam_rssi_diff_6ghz: RSSI diff value to be used for roaming to 6 GHz AP + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_cm_roam_rssi_diff_6ghz(struct wlan_objmgr_vdev *vdev, + uint8_t roam_rssi_diff_6ghz) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint8_t vdev_id; + wmi_unified_t wmi_handle; + + wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev); + if (!wmi_handle) + return status; + + vdev_id = wlan_vdev_get_id(vdev); + status = target_if_roam_set_param( + wmi_handle, vdev_id, + WMI_ROAM_PARAM_ROAM_RSSI_BOOST_FOR_6GHZ_CAND_AP, + roam_rssi_diff_6ghz); + + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("Failed to set WMI_ROAM_PARAM_ROAM_RSSI_BOOST_FOR_6GHZ_CAND_AP"); + + return status; +} + static void target_if_cm_roam_register_lfr3_ops(struct wlan_cm_roam_tx_ops *tx_ops) { tx_ops->send_vdev_set_pcl_cmd = target_if_cm_roam_send_vdev_set_pcl_cmd; tx_ops->send_roam_rt_stats_config = target_if_cm_roam_rt_stats_config; + tx_ops->send_roam_ho_delay_config = target_if_cm_roam_ho_delay_config; + tx_ops->send_exclude_rm_partial_scan_freq = + target_if_cm_exclude_rm_partial_scan_freq; + tx_ops->send_roam_full_scan_6ghz_on_disc = + target_if_cm_roam_full_scan_6ghz_on_disc; } #else static inline void @@ -147,6 +286,34 @@ target_if_cm_roam_rt_stats_config(struct wlan_objmgr_vdev *vdev, { return QDF_STATUS_E_NOSUPPORT; } + +static QDF_STATUS +target_if_cm_roam_ho_delay_config(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, uint16_t roam_ho_delay) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static QDF_STATUS +target_if_cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_vdev *vdev, + uint8_t exclude_rm_partial_scan_freq) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static QDF_STATUS +target_if_cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_vdev *vdev, + uint8_t roam_full_scan_6ghz_on_disc) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static QDF_STATUS +target_if_cm_roam_rssi_diff_6ghz(struct wlan_objmgr_vdev *vdev, + uint8_t roam_rssi_diff_6ghz) +{ + return QDF_STATUS_E_NOSUPPORT; +} #endif /** @@ -1032,6 +1199,23 @@ target_if_cm_roam_send_start(struct wlan_objmgr_vdev *vdev, if (req->wlan_roam_rt_stats_config) target_if_cm_roam_rt_stats_config(vdev, vdev_id, req->wlan_roam_rt_stats_config); + + if (req->wlan_roam_ho_delay_config) + target_if_cm_roam_ho_delay_config( + vdev, vdev_id, req->wlan_roam_ho_delay_config); + + if (req->wlan_exclude_rm_partial_scan_freq) + target_if_cm_exclude_rm_partial_scan_freq( + vdev, req->wlan_exclude_rm_partial_scan_freq); + + if (req->wlan_roam_full_scan_6ghz_on_disc) + target_if_cm_roam_full_scan_6ghz_on_disc( + vdev, req->wlan_roam_full_scan_6ghz_on_disc); + + if (req->wlan_roam_rssi_diff_6ghz) + target_if_cm_roam_rssi_diff_6ghz(vdev, + req->wlan_roam_rssi_diff_6ghz); + /* add other wmi commands */ end: return status; @@ -1254,6 +1438,23 @@ target_if_cm_roam_send_update_config(struct wlan_objmgr_vdev *vdev, target_if_cm_roam_rt_stats_config( vdev, vdev_id, req->wlan_roam_rt_stats_config); + + if (req->wlan_roam_ho_delay_config) + target_if_cm_roam_ho_delay_config( + vdev, vdev_id, + req->wlan_roam_ho_delay_config); + + if (req->wlan_exclude_rm_partial_scan_freq) + target_if_cm_exclude_rm_partial_scan_freq( + vdev, req->wlan_exclude_rm_partial_scan_freq); + + if (req->wlan_roam_full_scan_6ghz_on_disc) + target_if_cm_roam_full_scan_6ghz_on_disc( + vdev, req->wlan_roam_full_scan_6ghz_on_disc); + + if (req->wlan_roam_rssi_diff_6ghz) + target_if_cm_roam_rssi_diff_6ghz( + vdev, req->wlan_roam_rssi_diff_6ghz); } end: return status; diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c index d1618afbcce8..9883bfc6a980 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c @@ -272,6 +272,51 @@ cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, return status; } + +QDF_STATUS +cm_roam_send_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t param_value) +{ + QDF_STATUS status; + + wlan_cm_roam_set_ho_delay_config(psoc, param_value); + status = wlan_cm_tgt_send_roam_ho_delay_config(psoc, + vdev_id, param_value); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("fail to send roam HO delay config"); + + return status; +} + +QDF_STATUS +cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t param_value) +{ + QDF_STATUS status; + + wlan_cm_set_exclude_rm_partial_scan_freq(psoc, param_value); + status = wlan_cm_tgt_exclude_rm_partial_scan_freq(psoc, vdev_id, + param_value); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("fail to exclude roam partial scan channels"); + + return status; +} + +QDF_STATUS cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint8_t param_value) +{ + QDF_STATUS status; + + wlan_cm_roam_set_full_scan_6ghz_on_disc(psoc, param_value); + status = wlan_cm_tgt_send_roam_full_scan_6ghz_on_disc(psoc, vdev_id, + param_value); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("fail to send 6 GHz channels inclusion in full scan"); + + return status; +} #else static inline void cm_roam_reason_vsie(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, @@ -503,6 +548,7 @@ cm_roam_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, { struct wlan_roam_start_config *start_req; QDF_STATUS status; + struct cm_roam_values_copy temp; start_req = qdf_mem_malloc(sizeof(*start_req)); if (!start_req) @@ -526,6 +572,18 @@ cm_roam_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, start_req->wlan_roam_rt_stats_config = wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE); + start_req->wlan_roam_ho_delay_config = + wlan_cm_roam_get_ho_delay_config(psoc); + + start_req->wlan_exclude_rm_partial_scan_freq = + wlan_cm_get_exclude_rm_partial_scan_freq(psoc); + + start_req->wlan_roam_full_scan_6ghz_on_disc = + wlan_cm_roam_get_full_scan_6ghz_on_disc(psoc); + + wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_RSSI_DIFF_6GHZ, &temp); + start_req->wlan_roam_rssi_diff_6ghz = temp.uint_value; + status = wlan_cm_tgt_send_roam_start_req(psoc, vdev_id, start_req); if (QDF_IS_STATUS_ERROR(status)) mlme_debug("fail to send roam start"); @@ -549,6 +607,7 @@ cm_roam_update_config_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, { struct wlan_roam_update_config *update_req; QDF_STATUS status; + struct cm_roam_values_copy temp; cm_roam_set_roam_reason_better_ap(psoc, vdev_id, false); @@ -575,6 +634,18 @@ cm_roam_update_config_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, update_req->wlan_roam_rt_stats_config = wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE); + update_req->wlan_roam_ho_delay_config = + wlan_cm_roam_get_ho_delay_config(psoc); + + update_req->wlan_exclude_rm_partial_scan_freq = + wlan_cm_get_exclude_rm_partial_scan_freq(psoc); + + update_req->wlan_roam_full_scan_6ghz_on_disc = + wlan_cm_roam_get_full_scan_6ghz_on_disc(psoc); + + wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_RSSI_DIFF_6GHZ, &temp); + update_req->wlan_roam_rssi_diff_6ghz = temp.uint_value; + status = wlan_cm_tgt_send_roam_update_req(psoc, vdev_id, update_req); if (QDF_IS_STATUS_ERROR(status)) mlme_debug("fail to send update config"); diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h index e05eb0b8d1de..5ae40f27e891 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -114,6 +115,47 @@ cm_roam_fill_rssi_change_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, QDF_STATUS cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t param_value); + +/** + * cm_roam_send_ho_delay_config() - Send HO delay value to FW to delay + * hand-off (in msec) by the specified duration to receive pending rx frames + * from current BSS. + * @psoc: PSOC pointer + * @vdev_id: vdev id + * @param_value: HO delay value + * + * Return: QDF_STATUS + */ +QDF_STATUS +cm_roam_send_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t param_value); + +/** + * cm_exclude_rm_partial_scan_freq() - Exclude the channels in roam full scan + * that are already scanned as part of partial scan. + * @psoc: PSOC pointer + * @vdev_id: vdev id + * @param_value: include/exclude the partial scan channels in roam full scan + * + * Return: QDF_STATUS + */ +QDF_STATUS +cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t param_value); + +/** + * cm_roam_full_scan_6ghz_on_disc() - Include the 6 GHz channels in roam full + * scan only on prior discovery of any 6 GHz support in the environment + * @psoc: PSOC pointer + * @vdev_id: vdev id + * @param_value: Include the 6 GHz channels in roam full scan: + * 1 - Include only on prior discovery of any 6 GHz support in the environment + * 0 - Include all the supported 6 GHz channels by default + * + * Return: QDF_STATUS + */ +QDF_STATUS cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t param_value); #else static inline QDF_STATUS cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, @@ -121,6 +163,27 @@ cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, { return QDF_STATUS_E_NOSUPPORT; } + +static inline QDF_STATUS +cm_roam_send_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t param_value) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t param_value) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline +QDF_STATUS cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t param_value) +{ + return QDF_STATUS_E_NOSUPPORT; +} #endif /** diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h index 478d6a477160..6cdd5965714b 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -159,6 +160,56 @@ wlan_cm_roam_neighbor_proceed_with_handoff_req(uint8_t vdev_id); */ bool wlan_cm_is_sta_connected(uint8_t vdev_id); +/** + * wlan_cm_set_exclude_rm_partial_scan_freq() - set value to include/exclude + * the partial scan channels in roam full scan. + * @psoc: PSOC pointer + * @exclude_rm_partial_scan_freq: Include/exclude the channels in roam full scan + * that are already scanned as part of partial scan. + * + * Return: none + */ +void +wlan_cm_set_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, + uint8_t exclude_rm_partial_scan_freq); + +/** + * wlan_cm_get_exclude_rm_partial_scan_freq() - Get value to include/exclude + * the partial scan channels in roam full scan. + * @psoc: PSOC pointer + * + * Return: value to include/exclude the partial scan channels in roam full scan + */ +uint8_t +wlan_cm_get_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_cm_roam_set_full_scan_6ghz_on_disc() - set value to include the 6 GHz + * channels in roam full scan only on prior discovery of any 6 GHz support in + * the environment. + * @psoc: PSOC pointer + * @roam_full_scan_6ghz_on_disc: Include the 6 GHz channels in roam full scan: + * 1 - Include only on prior discovery of any 6 GHz support in the environment + * 0 - Include all the supported 6 GHz channels by default + * + * Return: none + */ +void +wlan_cm_roam_set_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc, + uint8_t roam_full_scan_6ghz_on_disc); + +/** + * wlan_cm_roam_get_full_scan_6ghz_on_disc() - Get value to include the 6 GHz + * channels in roam full scan only on prior discovery of any 6 GHz support in + * the environment. + * @psoc: PSOC pointer + * + * Return: + * 1 - Include only on prior discovery of any 6 GHz support in the environment + * 0 - Include all the supported 6 GHz channels by default + */ +uint8_t wlan_cm_roam_get_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc); + #else static inline QDF_STATUS wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev, @@ -621,6 +672,26 @@ wlan_cm_update_roam_rt_stats(struct wlan_objmgr_psoc *psoc, uint8_t wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, enum roam_rt_stats_params stats); + +/** + * wlan_cm_roam_set_ho_delay_config() - Set roam hand-off delay + * @psoc: PSOC pointer + * @roam_ho_delay: vendor configured roam HO delay value + * + * Return: none + */ +void +wlan_cm_roam_set_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint16_t roam_ho_delay); + +/** + * wlan_cm_roam_get_ho_delay_config() - Get roam hand-off delay + * @psoc: PSOC pointer + * + * Return: Roam HO delay value + */ +uint16_t +wlan_cm_roam_get_ho_delay_config(struct wlan_objmgr_psoc *psoc); #else static inline void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc, @@ -737,5 +808,23 @@ wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, { return 0; } + +static inline uint16_t +wlan_cm_roam_get_ho_delay_config(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} + +static inline uint8_t +wlan_cm_get_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} + +static inline uint8_t +wlan_cm_roam_get_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} #endif /* FEATURE_ROAM_OFFLOAD */ #endif /* WLAN_CM_ROAM_API_H__ */ diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h index 058b92f4f5db..6118e79b7484 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h @@ -119,11 +119,13 @@ * @RSSI_CHANGE_THRESHOLD: Rssi change threshold * @BEACON_RSSI_WEIGHT: Beacon Rssi weight parameter * @HI_RSSI_DELAY_BTW_SCANS: High Rssi delay between scans + * @ROAM_RSSI_DIFF_6GHZ: roam rssi diff for 6 GHz AP */ enum roam_cfg_param { RSSI_CHANGE_THRESHOLD, BEACON_RSSI_WEIGHT, HI_RSSI_DELAY_BTW_SCANS, + ROAM_RSSI_DIFF_6GHZ, }; /** @@ -1168,6 +1170,13 @@ enum roam_rt_stats_params { * @disconnect_params: disconnect params * @idle_params: idle params * @wlan_roam_rt_stats_config: roam events stats config + * @wlan_roam_ho_delay_config: roam HO delay value + * @wlan_exclude_rm_partial_scan_freq: Include/exclude the channels in roam full + * scan that are already scanned as part of partial scan. + * @wlan_roam_full_scan_6ghz_on_disc: Include the 6 GHz channels in roam full + * scan only on prior discovery of any 6 GHz support in the environment. + * @wlan_roam_rssi_diff_6ghz: This value is used as to how better the RSSI of + * the new/roamable 6GHz AP should be for roaming. */ struct wlan_roam_start_config { struct wlan_roam_offload_scan_rssi_params rssi_params; @@ -1187,6 +1196,10 @@ struct wlan_roam_start_config { struct wlan_roam_disconnect_params disconnect_params; struct wlan_roam_idle_params idle_params; uint8_t wlan_roam_rt_stats_config; + uint16_t wlan_roam_ho_delay_config; + uint8_t wlan_exclude_rm_partial_scan_freq; + uint8_t wlan_roam_full_scan_6ghz_on_disc; + uint8_t wlan_roam_rssi_diff_6ghz; /* other wmi cmd structures */ }; @@ -1232,6 +1245,13 @@ struct wlan_roam_stop_config { * @idle_params: idle params * @roam_triggers: roam triggers parameters * @wlan_roam_rt_stats_config: roam events stats config + * @wlan_roam_ho_delay_config: roam HO delay value + * @wlan_exclude_rm_partial_scan_freq: Include/exclude the channels in roam full + * scan that are already scanned as part of partial scan. + * @wlan_roam_full_scan_6ghz_on_disc: Include the 6 GHz channels in roam full + * scan only on prior discovery of any 6 GHz support in the environment. + * @wlan_roam_rssi_diff_6ghz: This value is used as to how better the RSSI of + * the new/roamable 6GHz AP should be for roaming. */ struct wlan_roam_update_config { struct wlan_roam_beacon_miss_cnt beacon_miss_cnt; @@ -1246,6 +1266,10 @@ struct wlan_roam_update_config { struct wlan_roam_idle_params idle_params; struct wlan_roam_triggers roam_triggers; uint8_t wlan_roam_rt_stats_config; + uint16_t wlan_roam_ho_delay_config; + uint8_t wlan_exclude_rm_partial_scan_freq; + uint8_t wlan_roam_full_scan_6ghz_on_disc; + uint8_t wlan_roam_rssi_diff_6ghz; }; #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) @@ -1371,6 +1395,11 @@ struct set_pcl_req { * @send_roam_abort: send roam abort * @send_roam_disable_config: send roam disable config * @send_roam_rt_stats_config: Send roam events vendor command param value to FW + * @send_roam_ho_delay_config: Send roam Hand-off delay value to FW + * @send_exclude_rm_partial_scan_freq: Include/exclude the channels in roam full + * scan that are already scanned as part of partial scan. + * @send_roam_full_scan_6ghz_on_disc: Include the 6 GHz channels in roam full + * scan only on prior discovery of any 6 GHz support in the environment. */ struct wlan_cm_roam_tx_ops { QDF_STATUS (*send_vdev_set_pcl_cmd)(struct wlan_objmgr_vdev *vdev, @@ -1398,6 +1427,15 @@ struct wlan_cm_roam_tx_ops { #ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS (*send_roam_rt_stats_config)(struct wlan_objmgr_vdev *vdev, uint8_t vdev_id, uint8_t value); + QDF_STATUS (*send_roam_ho_delay_config)(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, + uint16_t value); + QDF_STATUS (*send_exclude_rm_partial_scan_freq)( + struct wlan_objmgr_vdev *vdev, + uint8_t value); + QDF_STATUS (*send_roam_full_scan_6ghz_on_disc)( + struct wlan_objmgr_vdev *vdev, + uint8_t value); #endif }; @@ -1449,6 +1487,7 @@ enum roam_fail_params { * @roam_trigger_reason: Roam trigger reason(enum WMI_ROAM_TRIGGER_REASON_ID) * @roam_invoke_fail_reason: One of reason id from enum * wmi_roam_invoke_status_error in case of forced roam + * @roam_rssi_diff_6ghz: roam rssi diff for 6 GHz AP */ struct wlan_cm_rso_configs { uint8_t rescan_rssi_delta; @@ -1458,6 +1497,7 @@ struct wlan_cm_rso_configs { uint32_t roam_fail_reason; uint32_t roam_trigger_reason; uint32_t roam_invoke_fail_reason; + uint8_t roam_rssi_diff_6ghz; }; /** diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h index 6272fb622c2f..b4ec5f2543dd 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -184,6 +185,48 @@ ucfg_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, uint8_t param_value); + +/** + * ucfg_cm_roam_send_ho_delay_config() - Send the HO delay value to Firmware + * @pdev: Pointer to pdev + * @vdev_id: vdev id + * @param_value: Value will be from range 20 to 1000 in msec. + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_cm_roam_send_ho_delay_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint16_t param_value); + +/** + * ucfg_cm_exclude_rm_partial_scan_freq() - Exclude the channels in roam full + * scan that are already scanned as part of partial scan. + * @pdev: Pointer to pdev + * @vdev_id: vdev id + * @param_value: Include/exclude the partial scan channel in roam full scan + * 1 - Exclude + * 0 - Include + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint8_t param_value); + +/** + * ucfg_cm_roam_full_scan_6ghz_on_disc() - Include the 6 GHz channels in roam + * full scan only on prior discovery of any 6 GHz support in the environment. + * @pdev: Pointer to pdev + * @vdev_id: vdev id + * @param_value: Include the 6 GHz channels in roam full scan: + * 1 - Include only on prior discovery of any 6 GHz support in the environment + * 0 - Include all the supported 6 GHz channels by default + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, + uint8_t param_value); #else static inline QDF_STATUS ucfg_cm_update_roam_scan_scheme_bitmap(struct wlan_objmgr_psoc *psoc, @@ -213,4 +256,25 @@ ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, { return QDF_STATUS_SUCCESS; } + +static inline QDF_STATUS +ucfg_cm_roam_send_ho_delay_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint16_t param_value) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +ucfg_cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint8_t param_value) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +ucfg_cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint8_t param_value) +{ + return QDF_STATUS_SUCCESS; +} #endif diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h index f814c4f6b626..05486e85645a 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -47,6 +48,51 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, struct roam_disable_cfg *req); + +/** + * wlan_cm_tgt_send_roam_ho_delay_config() - Send roam HO delay config command + * to FW + * @psoc: psoc pointer + * @vdev_id: vdev id + * @roam_ho_delay: roam hand-off delay value + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cm_tgt_send_roam_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint16_t roam_ho_delay); + +/** + * wlan_cm_tgt_exclude_rm_partial_scan_freq() - Exclude the channels in roam + * full scan that are already scanned as part of partial scan. + * @psoc: psoc pointer + * @vdev_id: vdev id + * @exclude_rm_partial_scan_freq: Exclude the channels in roam full scan that + * are already scanned as part of partial scan. + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_cm_tgt_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint8_t exclude_rm_partial_scan_freq); + +/** + * wlan_cm_tgt_send_roam_full_scan_6ghz_on_disc() - Include the 6 GHz channels + * in roam full scan only on prior discovery of any 6 GHz support in the + * environment. + * @psoc: PSOC pointer + * @roam_inc_6ghz_if_disc: Include the 6 GHz channels in roam full scan: + * 1 - Include only on prior discovery of any 6 GHz support in the environment + * 0 - Include all the supported 6 GHz channels by default + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_cm_tgt_send_roam_full_scan_6ghz_on_disc( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint8_t roam_full_scan_6ghz_on_disc); #else static inline QDF_STATUS wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, @@ -61,6 +107,30 @@ wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, { return QDF_STATUS_E_FAILURE; } + +static inline QDF_STATUS +wlan_cm_tgt_send_roam_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t roam_ho_delay) +{ + return QDF_STATUS_E_FAILURE; +} + +static inline QDF_STATUS +wlan_cm_tgt_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint8_t exclude_rm_partial_scan_freq) +{ + return QDF_STATUS_E_FAILURE; +} + +static inline QDF_STATUS +wlan_cm_tgt_send_roam_full_scan_6ghz_on_disc( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint8_t roam_full_scan_6ghz_on_disc) +{ + return QDF_STATUS_E_FAILURE; +} #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c index b29f3b28854e..578cb0e3ddaf 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c +++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -189,21 +190,12 @@ QDF_STATUS wlan_cm_abort_rso(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id) bool wlan_cm_roaming_in_progress(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id) { struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); - QDF_STATUS status; - - status = cm_roam_acquire_lock(); - if (QDF_IS_STATUS_ERROR(status)) - return false; if (MLME_IS_ROAM_SYNCH_IN_PROGRESS(psoc, vdev_id) || MLME_IS_ROAMING_IN_PROG(psoc, vdev_id) || mlme_is_roam_invoke_in_progress(psoc, vdev_id) || - wlan_cm_neighbor_roam_in_progress(psoc, vdev_id)) { - cm_roam_release_lock(); + wlan_cm_neighbor_roam_in_progress(psoc, vdev_id)) return true; - } - - cm_roam_release_lock(); return false; } @@ -524,6 +516,9 @@ QDF_STATUS wlan_cm_roam_cfg_get_value(struct wlan_objmgr_psoc *psoc, case HI_RSSI_DELAY_BTW_SCANS: dst_config->uint_value = src_config->hi_rssi_scan_delay; break; + case ROAM_RSSI_DIFF_6GHZ: + dst_config->uint_value = src_config->roam_rssi_diff_6ghz; + break; default: mlme_err("Invalid roam config requested:%d", roam_cfg_type); status = QDF_STATUS_E_FAILURE; @@ -570,6 +565,9 @@ wlan_cm_roam_cfg_set_value(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, case HI_RSSI_DELAY_BTW_SCANS: dst_config->hi_rssi_scan_delay = src_config->uint_value; break; + case ROAM_RSSI_DIFF_6GHZ: + dst_config->roam_rssi_diff_6ghz = src_config->uint_value; + break; default: mlme_err("Invalid roam config requested:%d", roam_cfg_type); status = QDF_STATUS_E_FAILURE; @@ -897,4 +895,86 @@ uint8_t wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, return rstats_value; } + +void +wlan_cm_roam_set_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint16_t roam_ho_delay) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return; + + mlme_obj->cfg.lfr.roam_ho_delay_config = roam_ho_delay; +} + +uint16_t +wlan_cm_roam_get_ho_delay_config(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + mlme_legacy_err("Failed to get MLME Obj"); + return 0; + } + + return mlme_obj->cfg.lfr.roam_ho_delay_config; +} + +void +wlan_cm_set_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, + uint8_t exclude_rm_partial_scan_freq) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return; + + mlme_obj->cfg.lfr.exclude_rm_partial_scan_freq = + exclude_rm_partial_scan_freq; +} + +uint8_t +wlan_cm_get_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + mlme_legacy_err("Failed to get MLME Obj"); + return 0; + } + + return mlme_obj->cfg.lfr.exclude_rm_partial_scan_freq; +} + +void +wlan_cm_roam_set_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc, + uint8_t roam_full_scan_6ghz_on_disc) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return; + + mlme_obj->cfg.lfr.roam_full_scan_6ghz_on_disc = + roam_full_scan_6ghz_on_disc; +} + +uint8_t wlan_cm_roam_get_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + mlme_legacy_err("Failed to get MLME Obj"); + return 0; + } + + return mlme_obj->cfg.lfr.roam_full_scan_6ghz_on_disc; +} #endif diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c index 630deff30cf4..bfbd2e756301 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c +++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -137,4 +138,31 @@ ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, return cm_roam_send_rt_stats_config(psoc, vdev_id, param_value); } + +QDF_STATUS +ucfg_cm_roam_send_ho_delay_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint16_t param_value) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + return cm_roam_send_ho_delay_config(psoc, vdev_id, param_value); +} + +QDF_STATUS +ucfg_cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint8_t param_value) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + return cm_exclude_rm_partial_scan_freq(psoc, vdev_id, param_value); +} + +QDF_STATUS ucfg_cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, + uint8_t param_value) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + return cm_roam_full_scan_6ghz_on_disc(psoc, vdev_id, param_value); +} #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c index 7b556f9b0d9c..f69e416f59a0 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c +++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c @@ -202,6 +202,103 @@ QDF_STATUS wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, return status; } + +QDF_STATUS wlan_cm_tgt_send_roam_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint16_t roam_ho_delay) +{ + QDF_STATUS status; + struct wlan_cm_roam_tx_ops *roam_tx_ops; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) + return QDF_STATUS_E_INVAL; + + roam_tx_ops = wlan_cm_roam_get_tx_ops_from_vdev(vdev); + if (!roam_tx_ops || !roam_tx_ops->send_roam_ho_delay_config) { + mlme_err("vdev %d send_roam_ho_delay_config is NULL", vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_INVAL; + } + + status = roam_tx_ops->send_roam_ho_delay_config(vdev, vdev_id, + roam_ho_delay); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("vdev %d fail to send roam HO delay config", + vdev_id); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + + return status; +} + +QDF_STATUS +wlan_cm_tgt_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint8_t exclude_rm_partial_scan_freq) +{ + QDF_STATUS status; + struct wlan_cm_roam_tx_ops *roam_tx_ops; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) + return QDF_STATUS_E_INVAL; + + roam_tx_ops = wlan_cm_roam_get_tx_ops_from_vdev(vdev); + if (!roam_tx_ops || !roam_tx_ops->send_exclude_rm_partial_scan_freq) { + mlme_err("vdev %d send_exclude_rm_partial_scan_freq is NULL", + vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_INVAL; + } + + status = roam_tx_ops->send_exclude_rm_partial_scan_freq( + vdev, exclude_rm_partial_scan_freq); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("vdev %d fail to exclude roam partial scan freq", + vdev_id); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + + return status; +} + +QDF_STATUS wlan_cm_tgt_send_roam_full_scan_6ghz_on_disc( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint8_t roam_full_scan_6ghz_on_disc) +{ + QDF_STATUS status; + struct wlan_cm_roam_tx_ops *roam_tx_ops; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) + return QDF_STATUS_E_INVAL; + + roam_tx_ops = wlan_cm_roam_get_tx_ops_from_vdev(vdev); + if (!roam_tx_ops || !roam_tx_ops->send_roam_full_scan_6ghz_on_disc) { + mlme_err("vdev %d send_roam_full_scan_6ghz_on_disc is NULL", + vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_INVAL; + } + + status = roam_tx_ops->send_roam_full_scan_6ghz_on_disc( + vdev, roam_full_scan_6ghz_on_disc); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("vdev %d fail to send inclusion of 6 GHz channels", + vdev_id); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + + return status; +} #endif #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 08b6ed22fc77..bc93b02a6359 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -4645,6 +4645,11 @@ roam_control_policy[QCA_ATTR_ROAM_CONTROL_MAX + 1] = { .type = NLA_U32}, [QCA_ATTR_ROAM_CONTROL_USER_REASON] = {.type = NLA_U32}, [QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS] = {.type = NLA_U32}, + [QCA_ATTR_ROAM_CONTROL_HO_DELAY_FOR_RX] = {.type = NLA_U16}, + [QCA_ATTR_ROAM_CONTROL_FULL_SCAN_NO_REUSE_PARTIAL_SCAN_FREQ] = { + .type = NLA_U8}, + [QCA_ATTR_ROAM_CONTROL_FULL_SCAN_6GHZ_ONLY_ON_PRIOR_DISCOVERY] = { + .type = NLA_U8}, }; /** @@ -5036,6 +5041,19 @@ hdd_send_roam_scan_period_to_sme(struct hdd_context *hdd_ctx, return status; } +/* Roam Hand-off delay range is 20 to 1000 msec */ +#define MIN_ROAM_HO_DELAY 20 +#define MAX_ROAM_HO_DELAY 1000 + +/* Include/Exclude roam partial scan channels in full scan */ +#define INCLUDE_ROAM_PARTIAL_SCAN_FREQ 0 +#define EXCLUDE_ROAM_PARTIAL_SCAN_FREQ 1 + +/* Include the supported 6 GHz PSC channels in full scan by default */ +#define INCLUDE_6GHZ_IN_FULL_SCAN_BY_DEF 0 +/* Include the 6 GHz channels in roam full scan only on prior discovery */ +#define INCLUDE_6GHZ_IN_FULL_SCAN_IF_DISC 1 + /** * hdd_set_roam_with_control_config() - Set roam control configuration * @hdd_ctx: HDD context @@ -5229,6 +5247,60 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx, sme_send_vendor_btm_params(hdd_ctx->mac_handle, vdev_id); } + attr = tb2[QCA_ATTR_ROAM_CONTROL_HO_DELAY_FOR_RX]; + if (attr) { + value = nla_get_u16(attr); + if (value < MIN_ROAM_HO_DELAY || value > MAX_ROAM_HO_DELAY) { + hdd_err("Invalid roam HO delay value: %d", value); + return -EINVAL; + } + + hdd_debug("Received roam HO delay value: %d", value); + + status = ucfg_cm_roam_send_ho_delay_config(hdd_ctx->pdev, + vdev_id, value); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("failed to set hand-off delay"); + } + + attr = tb2[QCA_ATTR_ROAM_CONTROL_FULL_SCAN_NO_REUSE_PARTIAL_SCAN_FREQ]; + if (attr) { + value = nla_get_u8(attr); + if (value < INCLUDE_ROAM_PARTIAL_SCAN_FREQ || + value > EXCLUDE_ROAM_PARTIAL_SCAN_FREQ) { + hdd_err("Invalid value %d to exclude partial scan freq", + value); + return -EINVAL; + } + + hdd_debug("%s partial scan channels in roam full scan", + value ? "Exclude" : "Include"); + + status = ucfg_cm_exclude_rm_partial_scan_freq(hdd_ctx->pdev, + vdev_id, value); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("Fail to exclude roam partial scan channels"); + } + + attr = tb2[QCA_ATTR_ROAM_CONTROL_FULL_SCAN_6GHZ_ONLY_ON_PRIOR_DISCOVERY]; + if (attr) { + value = nla_get_u8(attr); + if (value < INCLUDE_6GHZ_IN_FULL_SCAN_BY_DEF || + value > INCLUDE_6GHZ_IN_FULL_SCAN_IF_DISC) { + hdd_err("Invalid value %d to decide inclusion of 6 GHz channels", + value); + return -EINVAL; + } + + hdd_debug("Include 6 GHz channels in roam full scan by %s", + value ? "prior discovery" : "default"); + + status = ucfg_cm_roam_full_scan_6ghz_on_disc(hdd_ctx->pdev, + vdev_id, value); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("Fail to decide inclusion of 6 GHz channels"); + } + return qdf_status_to_os_return(status); } diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 9025e939a06c..f5edc1c9c586 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. 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 @@ -1347,6 +1348,10 @@ static int calcuate_max_phy_rate(int mode, int nss, int ch_width, if (mode == SIR_SME_PHY_MODE_HT) { /* check for HT Mode */ maxidx = ht_mcs_idx; + if (maxidx > 7) { + hdd_err("ht_mcs_idx %d is incorrect", ht_mcs_idx); + return maxrate; + } if (nss == 1) { supported_mcs_rate = supported_mcs_rate_nss1; } else if (nss == 2) { @@ -2961,6 +2966,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq, struct wlan_objmgr_vdev *vdev; bool strict; uint32_t sta_cnt = 0; + struct ch_params ch_params = {0}; hdd_ctx = WLAN_HDD_GET_CTX(adapter); ret = wlan_hdd_validate_context(hdd_ctx); @@ -3041,7 +3047,10 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq, hdd_err("Channel switch in progress!!"); return -EBUSY; } - + ch_params.ch_width = target_bw; + target_bw = wlansap_get_csa_chanwidth_from_phymode(sap_ctx, + target_chan_freq, + &ch_params); /* * Do SAP concurrency check to cover channel switch case as following: * There is already existing SAP+GO combination but due to upper layer @@ -3058,7 +3067,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq, hdd_ctx->psoc, policy_mgr_convert_device_mode_to_qdf_type( adapter->device_mode), - target_chan_freq, + target_chan_freq, policy_mgr_get_bw(target_bw), adapter->vdev_id, forced, sap_ctx->csa_reason)) { diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 2a1b2efd5349..1c010f73e6df 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -10552,6 +10552,13 @@ void hdd_send_mscs_action_frame(struct hdd_context *hdd_ctx, uint64_t mscs_vo_pkt_delta; unsigned long tx_vo_pkts; + /* + * To disable MSCS feature in driver set mscs_pkt_threshold = 0 + * in ini file. + */ + if (!hdd_ctx->config->mscs_pkt_threshold) + return; + tx_vo_pkts = adapter->hdd_stats.tx_rx_stats.tx_classified_ac[SME_AC_VO]; if (!adapter->mscs_counter) @@ -18083,6 +18090,11 @@ static int con_mode_handler_ftm(const char *kmessage, ret = param_set_int(kmessage, kp); + if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) { + pr_err("Driver already loaded or load/unload in progress"); + return -ENOTSUPP; + } + if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) { pr_err("Only FTM mode supported!"); return -ENOTSUPP; diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index 9bfee6b526e4..cddc1e33bd58 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 "N" -#define QWLAN_VERSION_BUILD 31 +#define QWLAN_VERSION_EXTRA "E" +#define QWLAN_VERSION_BUILD 32 -#define QWLAN_VERSIONSTR "2.0.8.31N" +#define QWLAN_VERSIONSTR "2.0.8.32E" #endif /* QWLAN_VERSION_H */ diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index a3f9e9f778ff..8927b19557e7 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -134,6 +135,7 @@ /* block acknowledgment action frame types */ #define SIR_MAC_ACTION_VENDOR_SPECIFIC 9 #define SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7F +#define SIR_MAC_PROT_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7E #define SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP 2 /* Public Action for 20/40 BSS Coexistence */ @@ -345,9 +347,11 @@ #define SIR_MAC_BAD_HTC_HE_VENDOR_OUI2 "\x00\x50\xF2\x12" #define SIR_MAC_BAD_HTC_HE_VENDOR_OUI_LEN 4 -/* Maximum allowable size of a beacon and probe rsp frame */ -#define SIR_MAX_BEACON_SIZE 512 +/* Maximum allowable size of a beacon,probe rsp and fils discovery frame */ +#define SIR_MAX_BEACON_SIZE 512 #define SIR_MAX_PROBE_RESP_SIZE 512 +#define SIR_MAX_FD_TMPL_SIZE 512 + /* / Frame control field format (2 bytes) */ typedef struct sSirMacFrameCtl { diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c index a66585ca24a2..0017167ac437 100644 --- a/core/mac/src/pe/lim/lim_ft.c +++ b/core/mac/src/pe/lim/lim_ft.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -735,10 +736,8 @@ void lim_fill_ft_session(struct mac_context *mac, #ifdef WLAN_FEATURE_11W ft_session->limRmfEnabled = pe_session->limRmfEnabled; #endif - if ((ft_session->limRFBand == REG_BAND_2G) && - (ft_session->htSupportedChannelWidthSet == - eHT_CHANNEL_WIDTH_40MHZ)) - lim_init_obss_params(mac, ft_session); + /* Load default OBSS parameters to session entry */ + lim_init_obss_params(mac, ft_session); ft_session->enableHtSmps = pe_session->enableHtSmps; ft_session->htSmpsvalue = pe_session->htSmpsvalue; diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c index 1a683db31d7d..09e65cfb444b 100644 --- a/core/mac/src/pe/lim/lim_process_action_frame.c +++ b/core/mac/src/pe/lim/lim_process_action_frame.c @@ -1606,7 +1606,6 @@ void lim_process_action_frame(struct mac_context *mac_ctx, int8_t rssi; uint32_t frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info); tpSirMacVendorSpecificFrameHdr vendor_specific; - uint8_t oui[] = { 0x00, 0x00, 0xf0 }; uint8_t dpp_oui[] = { 0x50, 0x6F, 0x9A, 0x1A }; tpSirMacVendorSpecificPublicActionFrameHdr pub_action; @@ -1617,8 +1616,8 @@ void lim_process_action_frame(struct mac_context *mac_ctx, } #ifdef WLAN_FEATURE_11W - if (lim_is_robust_mgmt_action_frame(action_hdr->category) && - lim_drop_unprotected_action_frame(mac_ctx, session, + if (wlan_mgmt_is_rmf_mgmt_action_frame(action_hdr->category) && + lim_drop_unprotected_action_frame(mac_ctx, session, mac_hdr_11w, action_hdr->category)) return; #endif @@ -1818,6 +1817,7 @@ void lim_process_action_frame(struct mac_context *mac_ctx, break; case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY: + case SIR_MAC_PROT_ACTION_VENDOR_SPECIFIC_CATEGORY: vendor_specific = (tpSirMacVendorSpecificFrameHdr) action_hdr; mac_hdr = NULL; @@ -1829,12 +1829,9 @@ void lim_process_action_frame(struct mac_context *mac_ctx, return; } - /* Check if it is a vendor specific action frame. */ - if (LIM_IS_STA_ROLE(session) && - (!qdf_mem_cmp(session->self_mac_addr, - &mac_hdr->da[0], sizeof(tSirMacAddr))) - && IS_WES_MODE_ENABLED(mac_ctx) - && !qdf_mem_cmp(vendor_specific->Oui, oui, 3)) { + /* Forward all vendor specific action frames. */ + if (!qdf_mem_cmp(session->self_mac_addr, + &mac_hdr->da[0], sizeof(tSirMacAddr))) { pe_debug("Rcvd Vendor specific frame OUI: %x %x %x", vendor_specific->Oui[0], vendor_specific->Oui[1], @@ -1854,16 +1851,8 @@ void lim_process_action_frame(struct mac_context *mac_ctx, WMA_GET_RX_RSSI_NORMALIZED( rx_pkt_info), RXMGMT_FLAG_NONE); } else { - pe_debug("Dropping the vendor specific action frame" - "beacause of (WES Mode not enabled " - "(WESMODE: %d) or OUI mismatch " - "(%02x %02x %02x) or not received with" - "SelfSta address) system role: %d", - IS_WES_MODE_ENABLED(mac_ctx), - vendor_specific->Oui[0], - vendor_specific->Oui[1], - vendor_specific->Oui[2], - GET_LIM_SYSTEM_ROLE(session)); + pe_debug("Dropping the vendor specific action frame SelfSta address system role: %d", + GET_LIM_SYSTEM_ROLE(session)); } break; case ACTION_CATEGORY_PUBLIC: @@ -1896,11 +1885,15 @@ void lim_process_action_frame(struct mac_context *mac_ctx, /* send the frame to supplicant */ /* fallthrough */ case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY: + case SIR_MAC_PROT_ACTION_VENDOR_SPECIFIC_CATEGORY: case SIR_MAC_ACTION_2040_BSS_COEXISTENCE: case SIR_MAC_ACTION_GAS_INITIAL_REQUEST: case SIR_MAC_ACTION_GAS_INITIAL_RESPONSE: case SIR_MAC_ACTION_GAS_COMEBACK_REQUEST: case SIR_MAC_ACTION_GAS_COMEBACK_RESPONSE: + default: + pe_debug("Public action frame: %d", + action_hdr->actionID); /* * Forward to the SME to HDD to wpa_supplicant * type is ACTION @@ -1914,10 +1907,6 @@ void lim_process_action_frame(struct mac_context *mac_ctx, WMA_GET_RX_RSSI_NORMALIZED( rx_pkt_info), RXMGMT_FLAG_NONE); break; - default: - pe_debug("Unhandled public action frame: %d", - action_hdr->actionID); - break; } break; diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index dc64531f28ca..1fec33b2ddbd 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2020 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 @@ -2138,7 +2138,9 @@ void lim_calculate_tpc(struct mac_context *mac, if (mlme_obj->reg_tpc_obj.ap_constraint_power) { local_constraint = mlme_obj->reg_tpc_obj.ap_constraint_power; - reg_max = mlme_obj->reg_tpc_obj.reg_max[i]; + pe_debug("local constraint: %d" + "power constraint absolute: %d", + local_constraint, is_pwr_constraint_absolute); if (is_pwr_constraint_absolute) max_tx_power = QDF_MIN(reg_max, local_constraint); @@ -2178,8 +2180,9 @@ void lim_calculate_tpc(struct mac_context *mac, mlme_obj->reg_tpc_obj.eirp_power = reg_max; mlme_obj->reg_tpc_obj.power_type_6g = ap_power_type_6g; - pe_debug("num_pwr_levels: %d, is_psd_power: %d, total eirp_power: %d, ap_pwr_type: %d", - num_pwr_levels, is_psd_power, reg_max, ap_power_type_6g); + pe_debug("num_pwr_levels: %d, is_psd_power: %d, total eirp_power: %d, ap_pwr_type: %d tx_pwrlimit: %d", + num_pwr_levels, is_psd_power, reg_max, ap_power_type_6g, + mlme_obj->mgmt.generic.tx_pwrlimit); } /** diff --git a/core/mac/src/pe/lim/lim_timer_utils.c b/core/mac/src/pe/lim/lim_timer_utils.c index a43ba3293280..2e3892e5293c 100644 --- a/core/mac/src/pe/lim/lim_timer_utils.c +++ b/core/mac/src/pe/lim/lim_timer_utils.c @@ -751,11 +751,16 @@ lim_deactivate_and_change_per_sta_id_timer(struct mac_context *mac, uint32_t tim switch (timerId) { case eLIM_CNF_WAIT_TIMER: - if (tx_timer_deactivate - (&mac->lim.lim_timers.gpLimCnfWaitTimer[staId]) - != TX_SUCCESS) { + if (staId >= (mac->lim.maxStation + 1)) { + pe_err("Invalid staId = %d ", staId); + return; + } + + if (tx_timer_deactivate(&mac->lim.lim_timers.gpLimCnfWaitTimer[staId]) + != TX_SUCCESS) { pe_err("unable to deactivate CNF wait timer"); } + /* Change timer to reactivate it in future */ val = mac->mlme_cfg->sta.wait_cnf_timeout; val = SYS_MS_TO_TICKS(val); diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index d456c3f29f4c..6e85825a8c3f 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -6652,46 +6652,6 @@ void lim_update_obss_scanparams(struct pe_session *session, return; } -/** - * lim_is_robust_mgmt_action_frame() - Check if action category is - * robust action frame - * @action_category: Action frame category. - * - * This function is used to check if given action category is robust - * action frame. - * - * Return: bool - */ -bool lim_is_robust_mgmt_action_frame(uint8_t action_category) -{ - switch (action_category) { - /* - * NOTE: This function doesn't take care of the DMG - * (Directional Multi-Gigatbit) BSS case as 8011ad - * support is not yet added. In future, if the support - * is required then this function need few more arguments - * and little change in logic. - */ - case ACTION_CATEGORY_SPECTRUM_MGMT: - case ACTION_CATEGORY_QOS: - case ACTION_CATEGORY_DLS: - case ACTION_CATEGORY_BACK: - case ACTION_CATEGORY_RRM: - case ACTION_FAST_BSS_TRNST: - case ACTION_CATEGORY_SA_QUERY: - case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION: - case ACTION_CATEGORY_WNM: - case ACTION_CATEGORY_MESH_ACTION: - case ACTION_CATEGORY_MULTIHOP_ACTION: - case ACTION_CATEGORY_FST: - return true; - default: - pe_debug("non-PMF action category: %d", action_category); - break; - } - return false; -} - /** * lim_compute_ext_cap_ie_length - compute the length of ext cap ie * based on the bits set diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 6126ac888c27..6b2e0103741b 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -1081,7 +1081,6 @@ static inline void lim_deactivate_and_change_timer_host_roam( {} #endif -bool lim_is_robust_mgmt_action_frame(uint8_t action_category); uint8_t lim_compute_ext_cap_ie_length(tDot11fIEExtCap *ext_cap); void lim_update_caps_info_for_bss(struct mac_context *mac_ctx, diff --git a/core/mac/src/pe/sch/sch_api.c b/core/mac/src/pe/sch/sch_api.c index 7b51fae0dcca..104855636a9b 100644 --- a/core/mac/src/pe/sch/sch_api.c +++ b/core/mac/src/pe/sch/sch_api.c @@ -47,6 +47,398 @@ #include "wma_types.h" +#include +#include +#include + +/* Fils Dicovery Frame */ +/** + * struct fd_action_header - FILS Discovery Action frame header + * @action_header: WLAN Action frame header + * @fd_frame_cntl: FILS Disovery Frame Control + * @timestamp: Time stamp + * @bcn_interval: Beacon Interval + * @elem: variable len sub element fields + */ +struct fd_action_header { + struct action_frm_hdr action_header; + uint16_t fd_frame_cntl; + uint8_t timestamp[WLAN_TIMESTAMP_LEN]; + uint16_t bcn_interval; + uint8_t elem[]; +} qdf_packed; + +/** + * struct tpe_ie - Transmit Power Enevolpe IE + * @tpe_header: WLAN IE Header + * @max_tx_pwr_count: Maximum Transmit Power Count + * @max_tx_pwr_interpret: Maximum Transmit Power Interpretation + * @max_tx_pwr_category: Maximum Transmit Power category + * @tx_pwr_info: Transmit power Information + * @elem: variable len sub element fields + */ +struct tpe_ie { + struct ie_header tpe_header; + union { + struct { + uint8_t max_tx_pwr_count:3; + uint8_t max_tx_pwr_interpret:3; + uint8_t max_tx_pwr_category:2; + }; + uint8_t tx_pwr_info; + }; + uint8_t elem[]; +} qdf_packed; + +/** + * lim_populate_fd_capability() - populate the capability field in the + * fils discovery template + * @pe_session: pointer to pe session + * @cur_phymode: current phymode + * @fd_cap: pointer to fils discovery capability array + * + * Return: void + */ +static void lim_populate_fd_capability(struct pe_session *pe_session, + enum wlan_phymode cur_phymode, + uint8_t *fd_cap) +{ + /* Setting ESS and Privacy bits */ + fd_cap[0] |= ((!WLAN_FD_CAP_ESS_ENABLE << WLAN_FD_CAP_ESS_S) | + ((pe_session->privacy) << WLAN_FD_CAP_PRIVACY_S)); + + /* Channel Width Selection */ + switch (pe_session->ch_width) { + case CH_WIDTH_20MHZ: + fd_cap[0] |= (WLAN_FD_CHWIDTH_20 << WLAN_FD_CAP_BSS_CHWIDTH_S); + break; + case CH_WIDTH_40MHZ: + fd_cap[0] |= (WLAN_FD_CHWIDTH_40 << WLAN_FD_CAP_BSS_CHWIDTH_S); + break; + case CH_WIDTH_80MHZ: + fd_cap[0] |= (WLAN_FD_CHWIDTH_80 << WLAN_FD_CAP_BSS_CHWIDTH_S); + break; + case CH_WIDTH_160MHZ: + case CH_WIDTH_80P80MHZ: + fd_cap[0] |= (WLAN_FD_CHWIDTH_160_80_80 << + WLAN_FD_CAP_BSS_CHWIDTH_S); + break; + default: + pe_err("channel width : %d is not supported", pe_session->ch_width); + break; + } + + /* Max Num of Spatial Steam */ + switch (pe_session->nss) { + case WLAN_FD_CAP_NSS_MODE_1: + case WLAN_FD_CAP_NSS_MODE_2: + fd_cap[0] |= ((pe_session->nss - 1) << WLAN_FD_CAP_NSS_S); + break; + case WLAN_FD_CAP_NSS_MODE_3: + case WLAN_FD_CAP_NSS_MODE_4: + case WLAN_FD_CAP_NSS_MODE_5: + case WLAN_FD_CAP_NSS_MODE_6: + case WLAN_FD_CAP_NSS_MODE_7: + case WLAN_FD_CAP_NSS_MODE_8: + fd_cap[0] |= (WLAN_FD_CAP_NSS_GTE_5 << WLAN_FD_CAP_NSS_S); + break; + default: + pe_err("NSS value: %d is not supported", pe_session->nss); + break; + } + + /* Set PHY index */ + switch (cur_phymode) { + case WLAN_PHYMODE_11AXA_HE20: + case WLAN_PHYMODE_11AXG_HE20: + case WLAN_PHYMODE_11AXA_HE40: + case WLAN_PHYMODE_11AXG_HE40: + case WLAN_PHYMODE_11AXG_HE40PLUS: + case WLAN_PHYMODE_11AXG_HE40MINUS: + case WLAN_PHYMODE_11AXA_HE80: + case WLAN_PHYMODE_11AXA_HE160: + case WLAN_PHYMODE_11AXA_HE80_80: + fd_cap[1] |= (WLAN_FD_CAP_PHY_INDEX_HE << + WLAN_FD_CAP_PHY_INDEX_S); + break; + case WLAN_PHYMODE_11AC_VHT20: + case WLAN_PHYMODE_11AC_VHT40: + case WLAN_PHYMODE_11AC_VHT80: + case WLAN_PHYMODE_11AC_VHT160: + case WLAN_PHYMODE_11AC_VHT80_80: + fd_cap[1] |= (WLAN_FD_CAP_PHY_INDEX_VHT << + WLAN_FD_CAP_PHY_INDEX_S); + break; + case WLAN_PHYMODE_11NA_HT20: + case WLAN_PHYMODE_11NG_HT20: + case WLAN_PHYMODE_11NG_HT40PLUS: + case WLAN_PHYMODE_11NG_HT40MINUS: + case WLAN_PHYMODE_11NG_HT40: + case WLAN_PHYMODE_11NA_HT40: + fd_cap[1] |= (WLAN_FD_CAP_PHY_INDEX_HT << + WLAN_FD_CAP_PHY_INDEX_S); + break; + default: + pe_err("Phymode : %d is not supported", cur_phymode); + break; + } + + /* FILS Min Rate */ + fd_cap[1] |= (WLAN_FD_CAP_MIN_RATE << WLAN_FD_CAP_MIN_RATE_S); +} + +/** + * lim_populate_fd_tmpl_frame() - populate the fils discovery frame + * @mac: pointer to mac structure + * @frm: pointer to fils discovery frame + * @pe_session:pointer to pe session + * @frame_size: pointer to fils discovery frame size + * + * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE + */ +static QDF_STATUS lim_populate_fd_tmpl_frame(struct mac_context *mac, + struct pe_session *pe_session, + uint8_t *frm, uint32_t *frame_size) +{ + uint16_t fd_cntl_subfield = 0; + struct fd_action_header *fd_header; + struct wlan_objmgr_vdev *vdev; + uint8_t fd_cap[WLAN_FD_CAP_LEN] = {0}; + uint8_t length = 0; + uint8_t ssid_len = 0, ssid[WLAN_SSID_MAX_LEN + 1] = {0}; + uint32_t shortssid; + uint16_t chwidth = pe_session->ch_width; + qdf_freq_t cur_chan_freq = pe_session->curr_op_freq; + struct wlan_channel *des_chan; + enum wlan_phymode cur_phymode; + uint16_t tpe_num = 0; + tDot11fIEtransmit_power_env tpe[WLAN_MAX_NUM_TPE_IE]; + struct tpe_ie *tpe_ie; + uint8_t i, idx; + tSirMacMgmtHdr *mac_hdr; + struct qdf_mac_addr broadcast_mac_addr = QDF_MAC_ADDR_BCAST_INIT; + + pe_debug("FD TMPL freq: %d chWidth: %d", cur_chan_freq, chwidth); + + vdev = pe_session->vdev; + if (!vdev) { + pe_err("VDEV is NULL"); + return QDF_STATUS_E_FAILURE; + } + + des_chan = wlan_vdev_mlme_get_des_chan(vdev); + if (!des_chan) { + pe_err("des_chan is NULL"); + return QDF_STATUS_E_FAILURE; + } + + cur_phymode = des_chan->ch_phymode; + + lim_populate_mac_header(mac, frm, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, broadcast_mac_addr.bytes, + pe_session->self_mac_addr); + mac_hdr = (tpSirMacMgmtHdr)frm; + sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId); + frm += sizeof(*mac_hdr); + *frame_size = sizeof(*mac_hdr); + + /* filling fd header */ + fd_header = (struct fd_action_header *)frm; + fd_header->action_header.action_category = ACTION_CATEGORY_PUBLIC; + fd_header->action_header.action_code = WLAN_ACTION_FILS_DISCOVERY; + + /* + * FILS DIscovery Frame Control Subfield - 2 byte + * Enable Short SSID + * When the Short SSID Indicator subfield is equal to 1, + * the SSID Length subfield is equal to 3 + */ + fd_cntl_subfield = WLAN_FD_SSID_LEN_PRES(WLAN_FD_FRAMECNTL_SHORTSSID_LEN); + fd_cntl_subfield |= WLAN_FD_FRAMECNTL_SHORTSSID; + + if (wlan_reg_is_6ghz_chan_freq(cur_chan_freq)) { + fd_cntl_subfield |= WLAN_FD_FRAMECNTL_CAP; + pe_debug("FD Capability Present"); + length = WLAN_FD_CAP_LEN; + } + + /* For 80+80 set Channel center freq segment 1 */ + if (IS_WLAN_PHYMODE_160MHZ(cur_phymode)) { + fd_cntl_subfield |= WLAN_FD_FRAMECNTL_CH_CENTERFREQ; + pe_debug("Center frequenceny Present"); + length += 1; + } + + /* Update the length field */ + /*Indicates length from FD cap to Mobility Domain */ + if (length) + fd_cntl_subfield |= WLAN_FD_FRAMECNTL_LEN_PRES; + + /* FD Control - 2 bytes */ + fd_header->fd_frame_cntl = qdf_cpu_to_le16(fd_cntl_subfield); + + /* Timestamp - 8 bytes */ + qdf_mem_zero(fd_header->timestamp, sizeof(fd_header->timestamp)); + + /* Beacon Interval - 2 bytes */ + fd_header->bcn_interval = + qdf_cpu_to_le16(pe_session->beaconParams.beaconInterval); + + *frame_size += sizeof(*fd_header); + + /* Variable length data */ + frm = &fd_header->elem[0]; + + /* Short SSID - 4 bytes */ + wlan_vdev_mlme_get_ssid(vdev, ssid, &ssid_len); + shortssid = wlan_construct_shortssid(ssid, ssid_len); + *(uint32_t *)frm = qdf_cpu_to_le32(shortssid); + frm += 4; + *frame_size += 4; + pe_debug("Category:%02x Action:%02x fd_cntl:%02x bcn_intvl:%02x short ssid:%02x frame_size:%02x", + fd_header->action_header.action_category, + fd_header->action_header.action_code, fd_cntl_subfield, + fd_header->bcn_interval, shortssid, *frame_size); + + /* Length - 1 byte */ + if (length) { + *frm = length; + pe_debug("length: %d", length); + frm++; + *frame_size += length + 1; + } + + /* FD Capabilities - 2 bytes */ + if (WLAN_FD_IS_CAP_PRESENT(fd_cntl_subfield)) { + lim_populate_fd_capability(pe_session, cur_phymode, &fd_cap[0]); + qdf_mem_copy(frm, fd_cap, WLAN_FD_CAP_LEN); + frm += WLAN_FD_CAP_LEN; + pe_debug("fd_cap: %02x %02x", fd_cap[0], fd_cap[1]); + } + + /* Channel Center Freq Segment 1 - 1 byte */ + if (WLAN_FD_IS_FRAMECNTL_CH_CENTERFREQ(fd_cntl_subfield)) { + /* spec has seg0 and seg1 naming while we use seg1 and seg2 */ + *frm = des_chan->ch_freq_seg1; + frm++; + pe_debug("ch_center_freq: %02x", des_chan->ch_freq_seg1); + } + + /* Add TPE IE */ + if ((wlan_reg_is_6ghz_chan_freq(cur_chan_freq)) || + (pe_session->vhtCapability)) { + populate_dot11f_tx_power_env(mac, &tpe[0], chwidth, + cur_chan_freq, &tpe_num, false); + pe_debug("tpe_num: %02x", tpe_num); + if (tpe_num > WLAN_MAX_NUM_TPE_IE) { + pe_err("tpe_num %d greater than max size", tpe_num); + return QDF_STATUS_E_FAILURE; + } + + for (idx = 0; idx < tpe_num; idx++) { + /* filling tpe_header header */ + tpe_ie = (struct tpe_ie *)frm; + tpe_ie->tpe_header.ie_id = WLAN_ELEMID_VHT_TX_PWR_ENVLP; + + if (tpe[idx].num_tx_power > WLAN_MAX_NUM_TPE_IE) { + pe_err("num_tx_power %d greater than max num", + tpe[idx].num_tx_power); + return QDF_STATUS_E_FAILURE; + } + + /* +1 for including tx power info */ + tpe_ie->tpe_header.ie_len = tpe[idx].num_tx_power + 1; + + if (tpe_ie->tpe_header.ie_len < WLAN_TPE_IE_MIN_LEN || + tpe_ie->tpe_header.ie_len > WLAN_TPE_IE_MAX_LEN) { + pe_err("tpe length %d less than min len or greater than max len", + tpe_ie->tpe_header.ie_len); + return QDF_STATUS_E_FAILURE; + } + + tpe_ie->max_tx_pwr_count = tpe[idx].max_tx_pwr_count; + tpe_ie->max_tx_pwr_interpret = + tpe[idx].max_tx_pwr_interpret; + tpe_ie->max_tx_pwr_category = + tpe[idx].max_tx_pwr_category; + pe_debug("tx_pwr_info: %02x", tpe_ie->tx_pwr_info); + frm = &tpe_ie->elem[0]; + + for (i = 0; i < tpe[idx].num_tx_power; i++) { + *frm = tpe[idx].tx_power[i]; + pe_debug("tx_pwr[%d]: %02x", i, *frm); + frm++; + } + + /* +2 for including element id and length */ + *frame_size += tpe_ie->tpe_header.ie_len + 2; + } + } + + return QDF_STATUS_SUCCESS; +} + +/** + * lim_send_fils_discovery_template() - send fils discovery template to + * target_if + * @mac: pointer to mac structure + * @pe_session:pe session + * + * return: status + */ +static QDF_STATUS lim_send_fils_discovery_template(struct mac_context *mac, + struct pe_session *pe_session) +{ + struct fils_discovery_tmpl_params *fd_params; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t n_bytes = sizeof(*fd_params); + + fd_params = qdf_mem_malloc(n_bytes); + + if (!fd_params) + return QDF_STATUS_E_NOMEM; + + fd_params->vdev_id = pe_session->vdev_id; + + fd_params->frm = qdf_mem_malloc(SIR_MAX_FD_TMPL_SIZE); + if (!(fd_params->frm)) { + qdf_mem_free(fd_params); + return QDF_STATUS_E_NOMEM; + } + + status = lim_populate_fd_tmpl_frame(mac, pe_session, fd_params->frm, + &n_bytes); + + if (QDF_IS_STATUS_ERROR(status)) { + pe_err("FAIL bytes %d retcode[%X]", n_bytes, status); + goto memfree; + } + + pe_debug("Fils Discovery template created successfully %d", n_bytes); + + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, + fd_params->frm, n_bytes); + + fd_params->tmpl_len = n_bytes; + fd_params->tmpl_len_aligned = roundup(fd_params->tmpl_len, + sizeof(uint32_t)); + + /* Sending data to wmi layer via target_if */ + status = target_if_vdev_mgr_send_fd_tmpl(pe_session->vdev, + fd_params); + if (QDF_IS_STATUS_ERROR(status)) { + pe_err("FAIL bytes %d retcode[%X]", n_bytes, status); + } else { + pe_debug("Fils Discovery tmpl msg posted to HAL of bytes %d", + n_bytes); + } + +memfree: + qdf_mem_free(fd_params->frm); + qdf_mem_free(fd_params); + return status; +} + QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload, uint16_t size, struct pe_session *pe_session, enum sir_bcn_update_reason reason) @@ -66,6 +458,11 @@ QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload, if (QDF_STATUS_SUCCESS != retCode) pe_err("FAILED to send probe response template with retCode %d", retCode); + /*Fils Discovery Template */ + retCode = lim_send_fils_discovery_template(mac, pe_session); + if (QDF_STATUS_SUCCESS != retCode) + pe_err("FAILED to send fils discovery template retCode %d", + retCode); } beaconParams = qdf_mem_malloc(sizeof(tSendbeaconParams)); diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c index 1a3e40532eb0..df8c0cfabee5 100644 --- a/core/sme/src/csr/csr_neighbor_roam.c +++ b/core/sme/src/csr/csr_neighbor_roam.c @@ -844,6 +844,10 @@ static void csr_neighbor_roam_info_ctx_init(struct mac_context *mac, wlan_cm_update_roam_scan_scheme_bitmap(mac->psoc, session_id, DEFAULT_ROAM_SCAN_SCHEME_BITMAP); + src_cfg.uint_value = mac->mlme_cfg->lfr.roam_rssi_diff_6ghz; + wlan_cm_roam_cfg_set_value(mac->psoc, session_id, + ROAM_RSSI_DIFF_6GHZ, &src_cfg); + /* * Now we can clear the preauthDone that * was saved as we are connected afresh diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 507fd43a2967..f0f92e08802a 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1249,6 +1249,8 @@ QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_E_INVAL; mlme_obj->mgmt.generic.tx_pwrlimit = rsp->max_allowed_tx_power; + wma_debug("Max allowed tx power: %d", rsp->max_allowed_tx_power); + if (iface->type == WMI_VDEV_TYPE_STA) assoc_type = mlme_get_assoc_type(vdev_mlme->vdev); diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 19dc459dbe44..409c88336202 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-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 @@ -3564,7 +3564,7 @@ int wma_extscan_hotlist_match_event_handler(void *handle, return -ENOMEM; dest_ap = &dest_hotlist->ap[0]; - dest_hotlist->numOfAps = event->total_entries; + dest_hotlist->numOfAps = numap; dest_hotlist->requestId = event->config_request_id; if (event->first_entry_index + @@ -3730,6 +3730,7 @@ static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info, struct extscan_cached_scan_results *t_cached_result; struct extscan_cached_scan_result *t_scan_id_grp; int i, j; + uint32_t total_scan_num_results = 0; tSirWifiScanResult *ap; param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *) @@ -3740,16 +3741,19 @@ static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info, t_cached_result = cached_result; t_scan_id_grp = &t_cached_result->result[0]; - if ((t_cached_result->num_scan_ids * - QDF_MIN(t_scan_id_grp->num_results, - param_buf->num_bssid_list)) > param_buf->num_bssid_list) { - wma_err("num_scan_ids %d, num_results %d num_bssid_list %d", - t_cached_result->num_scan_ids, - t_scan_id_grp->num_results, - param_buf->num_bssid_list); + for (i = 0; i < t_cached_result->num_scan_ids; i++) { + total_scan_num_results += t_scan_id_grp->num_results; + t_scan_id_grp++; + } + + if (total_scan_num_results > param_buf->num_bssid_list) { + wma_err("total_scan_num_results %d, num_bssid_list %d", + total_scan_num_results, + param_buf->num_bssid_list); return -EINVAL; } + t_scan_id_grp = &t_cached_result->result[0]; wma_debug("num_scan_ids:%d", t_cached_result->num_scan_ids); for (i = 0; i < t_cached_result->num_scan_ids; i++) { @@ -3760,8 +3764,7 @@ static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info, return -ENOMEM; ap = &t_scan_id_grp->ap[0]; - for (j = 0; j < QDF_MIN(t_scan_id_grp->num_results, - param_buf->num_bssid_list); j++) { + for (j = 0; j < t_scan_id_grp->num_results; j++) { ap->channel = src_hotlist->channel; ap->ts = WMA_MSEC_TO_USEC(src_rssi->tstamp); ap->rtt = src_hotlist->rtt; diff --git a/os_if/pkt_capture/src/os_if_pkt_capture.c b/os_if/pkt_capture/src/os_if_pkt_capture.c index 43633ab18f5d..c1e836a57ffc 100644 --- a/os_if/pkt_capture/src/os_if_pkt_capture.c +++ b/os_if/pkt_capture/src/os_if_pkt_capture.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -74,10 +75,6 @@ QDF_STATUS os_if_monitor_mode_configure(struct hdd_adapter *adapter, QDF_STATUS status; os_if_pkt_enter(); - - if (tb[SET_MONITOR_MODE_INVALID]) - return QDF_STATUS_E_FAILURE; - vdev = hdd_objmgr_get_vdev(adapter); if (!vdev) return QDF_STATUS_E_INVAL; @@ -89,6 +86,9 @@ QDF_STATUS os_if_monitor_mode_configure(struct hdd_adapter *adapter, return QDF_STATUS_E_INVAL; } + if (tb[SET_MONITOR_MODE_INVALID]) + return QDF_STATUS_E_FAILURE; + if (tb[SET_MONITOR_MODE_DATA_TX_FRAME_TYPE] && nla_get_u32(tb[SET_MONITOR_MODE_DATA_TX_FRAME_TYPE]) < PACKET_CAPTURE_DATA_MAX_FILTER) {