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) {