Jelajahi Sumber

Merge 31038a49b000fa192bb81fecd5db87b0da74fcaf on remote branch

Change-Id: Idc528ceed50f64ed54b7c5d54ca6de0f4070df17
Linux Build Service Account 11 bulan lalu
induk
melakukan
79c1de95c4
65 mengubah file dengan 815 tambahan dan 679 penghapusan
  1. 3 2
      components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c
  2. 2 2
      components/cmn_services/logging/src/wlan_connectivity_logging.c
  3. 19 2
      components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h
  4. 32 10
      components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c
  5. 2 3
      components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c
  6. 40 20
      components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c
  7. 4 0
      components/dp/core/inc/wlan_dp_priv.h
  8. 40 4
      components/dp/core/src/wlan_dp_bus_bandwidth.c
  9. 24 2
      components/dp/core/src/wlan_dp_main.c
  10. 48 5
      components/dp/dispatcher/src/wlan_dp_ucfg_api.c
  11. 1 0
      components/mlme/core/src/wlan_mlme_main.c
  12. 32 5
      components/mlme/dispatcher/inc/cfg_mlme_reg.h
  13. 1 1
      components/mlme/dispatcher/inc/cfg_mlme_sta.h
  14. 20 2
      components/mlme/dispatcher/inc/wlan_mlme_api.h
  15. 1 1
      components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
  16. 11 1
      components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
  17. 16 1
      components/mlme/dispatcher/src/wlan_mlme_api.c
  18. 8 2
      components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c
  19. 1 6
      components/pmo/core/src/wlan_pmo_mc_addr_filtering.c
  20. 6 1
      components/target_if/cp_stats/src/target_if_mc_cp_stats.c
  21. 25 16
      components/tdls/core/src/wlan_tdls_ct.c
  22. 2 12
      components/tdls/core/src/wlan_tdls_main.c
  23. 15 2
      components/tdls/core/src/wlan_tdls_mgmt.c
  24. 3 3
      components/tdls/dispatcher/src/wlan_tdls_api.c
  25. 5 0
      components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c
  26. 13 7
      components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c
  27. 6 3
      components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h
  28. 2 1
      components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload_event.c
  29. 0 41
      components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c
  30. 3 3
      components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h
  31. 22 11
      components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c
  32. 8 1
      components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.c
  33. 5 2
      components/umac/mlme/sap/ll_sap/dispatcher/src/wlan_ll_sap_api.c
  34. 10 0
      core/hdd/inc/wlan_hdd_cfg.h
  35. 43 1
      core/hdd/src/wlan_hdd_cfg.c
  36. 71 15
      core/hdd/src/wlan_hdd_cfg80211.c
  37. 26 14
      core/hdd/src/wlan_hdd_hostapd.c
  38. 1 24
      core/hdd/src/wlan_hdd_ioctl.c
  39. 13 2
      core/hdd/src/wlan_hdd_main.c
  40. 0 8
      core/hdd/src/wlan_hdd_power.c
  41. 10 2
      core/hdd/src/wlan_hdd_regulatory.c
  42. 3 3
      core/hdd/src/wlan_hdd_station_info.c
  43. 6 3
      core/hdd/src/wlan_hdd_stats.c
  44. 3 3
      core/mac/inc/qwlan_version.h
  45. 20 90
      core/mac/src/pe/lim/lim_api.c
  46. 6 8
      core/mac/src/pe/lim/lim_ft.c
  47. 9 8
      core/mac/src/pe/lim/lim_link_monitoring_algo.c
  48. 8 2
      core/mac/src/pe/lim/lim_process_action_frame.c
  49. 0 150
      core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
  50. 10 5
      core/mac/src/pe/lim/lim_process_deauth_frame.c
  51. 6 5
      core/mac/src/pe/lim/lim_process_disassoc_frame.c
  52. 6 4
      core/mac/src/pe/lim/lim_process_sme_req_messages.c
  53. 35 35
      core/mac/src/pe/lim/lim_process_tdls.c
  54. 6 3
      core/sap/src/sap_api_link_cntl.c
  55. 3 2
      core/sap/src/sap_ch_select.c
  56. 10 5
      core/sap/src/sap_fsm.c
  57. 2 1
      core/sap/src/sap_internal.h
  58. 44 43
      core/sap/src/sap_module.c
  59. 0 16
      core/sme/inc/sme_api.h
  60. 4 41
      core/sme/src/common/sme_api.c
  61. 2 2
      core/wma/inc/wma_if.h
  62. 3 1
      core/wma/inc/wma_tgt_cfg.h
  63. 1 4
      core/wma/src/wma_features.c
  64. 10 4
      core/wma/src/wma_main.c
  65. 24 3
      core/wma/src/wma_scan_roam.c

+ 3 - 2
components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -814,7 +814,8 @@ static void if_mgr_update_candidate(struct wlan_objmgr_psoc *psoc,
 
 	if (!mlme_get_bss_11be_allowed(psoc, &candidate_info->peer_addr,
 				       attr.ie_data, attr.ie_length) ||
-	    wlan_vdev_mlme_get_user_dis_eht_flag(vdev)) {
+	    wlan_vdev_mlme_get_user_dis_eht_flag(vdev) ||
+	    !wlan_reg_phybitmap_support_11be(wlan_vdev_get_pdev(vdev))) {
 		scan_entry->ie_list.multi_link_bv = NULL;
 		scan_entry->ie_list.ehtcap = NULL;
 		scan_entry->ie_list.ehtop = NULL;

+ 2 - 2
components/cmn_services/logging/src/wlan_connectivity_logging.c

@@ -988,8 +988,8 @@ wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
 	wlan_diag_event.auth_seq_num = auth_seq;
 	wlan_diag_event.assoc_id = aid;
 
-	if (tag == WLAN_DEAUTH_TX || tag == WLAN_DISASSOC_TX)
-		wlan_populate_vsie(vdev, &wlan_diag_event, true);
+	if (tag == WLAN_DEAUTH_RX || tag == WLAN_DISASSOC_RX)
+		wlan_populate_vsie(vdev, &wlan_diag_event, false);
 
 	if (wlan_diag_event.subtype > WLAN_CONN_DIAG_REASSOC_RESP_EVENT &&
 	    wlan_diag_event.subtype < WLAN_CONN_DIAG_BMISS_EVENT)

+ 19 - 2
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -4052,6 +4052,7 @@ policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc *psoc)
 /**
  * policy_mgr_is_sap_freq_allowed - Check if the channel is allowed for sap
  * @psoc: PSOC object information
+ * @opmode: Current op_mode, helps to check whether it's P2P_GO/SAP
  * @sap_freq: channel frequency to be checked
  *
  * Check the factors as below to decide whether the channel is allowed or not:
@@ -4062,6 +4063,7 @@ policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc *psoc)
  * Return: true for allowed, else false
  */
 bool policy_mgr_is_sap_freq_allowed(struct wlan_objmgr_psoc *psoc,
+				    enum QDF_OPMODE opmode,
 				    uint32_t sap_freq);
 
 /**
@@ -4827,7 +4829,7 @@ bool policy_mgr_is_mlo_sta_disconnected(struct wlan_objmgr_psoc *psoc,
 					uint8_t vdev_id);
 
 #ifdef WLAN_FEATURE_11BE_MLO
-/*
+/**
  * policy_mgr_is_ml_sta_links_in_mcc() - Check ML links are in MCC or not
  * @psoc: psoc ctx
  * @ml_freq_lst: ML STA freq list
@@ -4847,6 +4849,21 @@ policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc *psoc,
 				  uint8_t num_ml_sta,
 				  uint32_t *affected_linkid_bitmap);
 
+/**
+ * policy_mgr_is_ml_links_in_mcc_allowed() - Check ML links are in MCC or not
+ * @psoc: psoc ctx
+ * @vdev: Pointer to vdev object
+ * @ml_sta_vdev_lst: ML STA vdev id list
+ * @num_ml_sta: Number of total ML STA links
+ *
+ * Return: QDF_STATUS_SUCCESS if ML link in MCC is allowed
+ */
+QDF_STATUS
+policy_mgr_is_ml_links_in_mcc_allowed(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      uint8_t *ml_sta_vdev_lst,
+				      uint8_t *num_ml_sta);
+
 /**
  * policy_mgr_is_vdev_high_tput_or_low_latency() - Check vdev has
  * high througput or low latency flag

+ 32 - 10
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -1760,7 +1760,8 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
 	for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
 		if ((ch_freq == pm_ctx->unsafe_channel_list[j]) &&
 		    (qdf_test_bit(QDF_SAP_MODE, &restriction_mask) ||
-		     !wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(psoc))) {
+		     !wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
+								     psoc))) {
 			is_safe = false;
 			policy_mgr_warn("Freq %d is not safe, restriction mask %lu", ch_freq, restriction_mask);
 			break;
@@ -1815,11 +1816,18 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
 #endif
 
 bool policy_mgr_is_sap_freq_allowed(struct wlan_objmgr_psoc *psoc,
+				    enum QDF_OPMODE opmode,
 				    uint32_t sap_freq)
 {
 	uint32_t nan_2g_freq, nan_5g_freq;
 
-	if (policy_mgr_is_safe_channel(psoc, sap_freq))
+	/*
+	 * Ignore safe channel validation when the mode is P2P_GO and user
+	 * configures the corresponding bit in ini coex_unsafe_chan_nb_user_prefer.
+	 */
+	if ((opmode == QDF_P2P_GO_MODE &&
+	     wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_p2p_go(psoc)) ||
+	    policy_mgr_is_safe_channel(psoc, sap_freq))
 		return true;
 
 	/*
@@ -3176,14 +3184,14 @@ void policy_mgr_check_concurrent_intf_and_restart_sap(
 	}
 
 	/*
+	 * This is to check the cases where STA got disconnected or
+	 * sta is present on some valid channel where SAP evaluation/restart
+	 * might be needed.
 	 * force SCC with STA+STA+SAP will need some additional logic
 	 */
 	cc_count = policy_mgr_get_mode_specific_conn_info(
 				psoc, &op_ch_freq_list[cc_count],
 				&vdev_id[cc_count], PM_STA_MODE);
-	if (!cc_count) {
-		policy_mgr_debug("Could not get STA operating channel&vdevid");
-	}
 
 	sta_check = !cc_count ||
 		    policy_mgr_valid_sta_channel_check(psoc, op_ch_freq_list[0]);
@@ -3192,16 +3200,30 @@ void policy_mgr_check_concurrent_intf_and_restart_sap(
 	cc_count = policy_mgr_get_mode_specific_conn_info(
 				psoc, &op_ch_freq_list[cc_count],
 				&vdev_id[cc_count], PM_P2P_CLIENT_MODE);
-	if (!cc_count)
-		policy_mgr_debug("Could not get GC operating channel&vdevid");
 
 	gc_check = !!cc_count;
-	policy_mgr_debug("gc_check: %d", gc_check);
 
 	mcc_to_scc_switch =
 		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
-	policy_mgr_debug("MCC to SCC switch: %d chan: %d",
-			 mcc_to_scc_switch, op_ch_freq_list[0]);
+	policy_mgr_debug("MCC to SCC switch: %d chan: %d sta_check: %d, gc_check: %d",
+			 mcc_to_scc_switch, op_ch_freq_list[0],
+			 sta_check, gc_check);
+
+	cc_count = 0;
+	cc_count = policy_mgr_get_mode_specific_conn_info(
+				psoc, &op_ch_freq_list[cc_count],
+				&vdev_id[cc_count], PM_SAP_MODE);
+
+	/* SAP + SAP case needs additional handling */
+	if (cc_count == 1 && !is_acs_mode &&
+	    target_psoc_get_sap_coex_fixed_chan_cap(
+			wlan_psoc_get_tgt_if_handle(psoc)) &&
+	    !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[0])) {
+		policy_mgr_debug("Avoid channel switch as it's allowed to operate on unsafe channel: %d",
+				 op_ch_freq_list[0]);
+		return;
+	}
+
 sap_restart:
 	/*
 	 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not

+ 2 - 3
components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -4568,8 +4568,7 @@ void policy_mgr_check_scc_channel(struct wlan_objmgr_psoc *psoc,
 	}
 
 	/* Always do force SCC on non-DBS platforms */
-	if (!policy_mgr_is_hw_dbs_capable(psoc) &&
-	    cc_mode !=  QDF_MCC_TO_SCC_WITH_PREFERRED_BAND)
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
 		return;
 
 	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,

+ 40 - 20
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -7752,37 +7752,26 @@ policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc *psoc,
 	return false;
 }
 
-/*
- * policy_mgr_handle_mcc_ml_sta() - disables one ML STA link if causing MCC
- * DBS - if ML STA links on 5 GHz + 6 GHz
- * SBS - if both ML STA links on 5 GHz high/5 GHz low
- * non-SBS - any combo (5/6 GHz + 5/6 GHz OR 2 GHz + 5/6 GHz)
- * @psoc: psoc ctx
- *
- * Return: Success if MCC link is disabled else failure
- */
-static QDF_STATUS
-policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
-			     struct wlan_objmgr_vdev *vdev)
+QDF_STATUS
+policy_mgr_is_ml_links_in_mcc_allowed(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      uint8_t *ml_sta_vdev_lst,
+				      uint8_t *num_ml_sta)
 {
-	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
-	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t num_disabled_ml_sta = 0;
 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 
-	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE))
-		return QDF_STATUS_E_FAILURE;
-
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
 		policy_mgr_err("Invalid Context");
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+	policy_mgr_get_ml_sta_info(pm_ctx, num_ml_sta, &num_disabled_ml_sta,
 				   ml_sta_vdev_lst, ml_freq_lst,
 				   NULL, NULL, NULL);
-	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	if (*num_ml_sta < 2 || *num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
 	    num_disabled_ml_sta) {
 		policy_mgr_debug("num_ml_sta invalid %d or link already disabled%d",
 				 num_ml_sta, num_disabled_ml_sta);
@@ -7791,7 +7780,7 @@ policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
 
 	if (!policy_mgr_is_ml_sta_links_in_mcc(psoc, ml_freq_lst,
 					       ml_sta_vdev_lst, NULL,
-					       num_ml_sta,
+					       *num_ml_sta,
 					       NULL))
 		return QDF_STATUS_E_FAILURE;
 
@@ -7804,9 +7793,40 @@ policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_handle_mcc_ml_sta() - disables one ML STA link if causing MCC
+ * DBS - if ML STA links on 5 GHz + 6 GHz
+ * SBS - if both ML STA links on 5 GHz high/5 GHz low
+ * non-SBS - any combo (5/6 GHz + 5/6 GHz OR 2 GHz + 5/6 GHz)
+ * @psoc: psoc ctx
+ * @vdev: Pointer to vdev object
+ *
+ * Return: Success if MCC link is disabled else failure
+ */
+static QDF_STATUS
+policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t num_ml_sta = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	QDF_STATUS status;
+
+	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE))
+		return QDF_STATUS_E_FAILURE;
+
+	status = policy_mgr_is_ml_links_in_mcc_allowed(psoc, vdev,
+						       ml_sta_vdev_lst,
+						       &num_ml_sta);
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_FAILURE;
+
 	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
 				    MLO_LINK_FORCE_MODE_ACTIVE_NUM,
 				    num_ml_sta, ml_sta_vdev_lst);
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 4 - 0
components/dp/core/inc/wlan_dp_priv.h

@@ -694,9 +694,12 @@ struct wlan_dp_intf {
 	qdf_list_t dp_link_list;
 };
 
+#define WLAN_DP_LINK_MAGIC 0x5F44505F4C494E4B	/* "_DP_LINK" in ASCII */
+
 /**
  * struct wlan_dp_link - DP link (corresponds to objmgr vdev)
  * @node: list node for membership in the DP links list
+ * @magic: magic number to identify validity of dp_link
  * @link_id: ID for this DP link (Same as vdev_id)
  * @mac_addr: mac address of this link
  * @dp_intf: Parent DP interface for this DP link
@@ -711,6 +714,7 @@ struct wlan_dp_intf {
  */
 struct wlan_dp_link {
 	qdf_list_node_t node;
+	uint64_t magic;
 	uint8_t link_id;
 	struct qdf_mac_addr mac_addr;
 	struct wlan_dp_intf *dp_intf;

+ 40 - 4
components/dp/core/src/wlan_dp_bus_bandwidth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -653,6 +653,11 @@ void dp_reset_tcp_delack(struct wlan_objmgr_psoc *psoc)
 	enum wlan_tp_level next_level = WLAN_SVC_TP_LOW;
 	struct wlan_rx_tp_data rx_tp_data = {0};
 
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
 	if (!dp_ctx->en_tcp_delack_no_lro)
 		return;
 
@@ -2063,6 +2068,11 @@ static void dp_bus_bw_work_handler(void *context)
 	struct wlan_dp_psoc_context *dp_ctx = context;
 	struct qdf_op_sync *op_sync;
 
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
 	if (qdf_op_protect(&op_sync))
 		return;
 
@@ -2099,7 +2109,14 @@ int dp_bus_bandwidth_init(struct wlan_objmgr_psoc *psoc)
 void dp_bus_bandwidth_deinit(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
-	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+	hdd_cb_handle ctx;
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	ctx = dp_ctx->dp_ops.callback_ctx;
 
 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
 		return;
@@ -2129,6 +2146,11 @@ static void __dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
 
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
 		return;
 
@@ -2149,10 +2171,17 @@ void dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc *psoc)
 void dp_bus_bw_compute_timer_try_start(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
-	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+	hdd_cb_handle ctx;
 
 	dp_enter();
 
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	ctx = dp_ctx->dp_ops.callback_ctx;
+
 	if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx))
 		__dp_bus_bw_compute_timer_start(psoc);
 
@@ -2230,10 +2259,17 @@ void dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc *psoc)
 void dp_bus_bw_compute_timer_try_stop(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
-	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+	hdd_cb_handle ctx;
 
 	dp_enter();
 
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	ctx = dp_ctx->dp_ops.callback_ctx;
+
 	if (!dp_ctx->dp_ops.dp_any_adapter_connected(ctx))
 		__dp_bus_bw_compute_timer_stop(psoc);
 

+ 24 - 2
components/dp/core/src/wlan_dp_main.c

@@ -79,6 +79,7 @@ QDF_STATUS dp_allocate_ctx(void)
 	}
 
 	qdf_spinlock_create(&dp_ctx->intf_list_lock);
+	qdf_spinlock_create(&dp_ctx->dp_link_del_lock);
 	qdf_list_create(&dp_ctx->intf_list, 0);
 	TAILQ_INIT(&dp_ctx->inactive_dp_link_list);
 
@@ -230,6 +231,11 @@ bool is_dp_link_valid(struct wlan_dp_link *dp_link)
 		return false;
 	}
 
+	if (dp_link->magic != WLAN_DP_LINK_MAGIC) {
+		dp_err("dp_link %pK bad magic %llx", dp_link, dp_link->magic);
+		return false;
+	}
+
 	dp_intf = dp_link->dp_intf;
 	ret = is_dp_intf_valid(dp_intf);
 	if (ret)
@@ -1195,6 +1201,7 @@ dp_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, void *arg)
 	}
 
 	/* Update Parent interface details */
+	dp_link->magic = WLAN_DP_LINK_MAGIC;
 	dp_link->dp_intf = dp_intf;
 	qdf_spin_lock_bh(&dp_intf->dp_link_list_lock);
 	qdf_list_insert_front(&dp_intf->dp_link_list, &dp_link->node);
@@ -1258,12 +1265,20 @@ static void dp_link_handle_cdp_vdev_delete(struct wlan_dp_psoc_context *dp_ctx,
 
 	if (!dp_link->cdp_vdev_registered || dp_link->cdp_vdev_deleted) {
 		/* CDP vdev is not created/registered or already deleted */
+		dp_info("Free dp_link %pK id %d (" QDF_MAC_ADDR_FMT ")",
+			dp_link, dp_link->link_id,
+			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
+		dp_link->magic = 0;
 		qdf_mem_free(dp_link);
 	} else {
 		/*
 		 * Add it to inactive dp_link list, and it will be freed when
 		 * the CDP vdev gets deleted
 		 */
+		dp_info("Add to inactive list dp_link %pK id %d ("
+			QDF_MAC_ADDR_FMT ")",
+			dp_link, dp_link->link_id,
+			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
 		TAILQ_INSERT_TAIL(&dp_ctx->inactive_dp_link_list, dp_link,
 				  inactive_list_elem);
 		dp_link->destroyed = 1;
@@ -2015,12 +2030,11 @@ void wlan_dp_link_cdp_vdev_delete_notification(void *context)
 	struct wlan_dp_psoc_context *dp_ctx = NULL;
 	uint8_t found = 0;
 
-	/* TODO - What will happen if cdp vdev was never created ? */
-
 	/* dp_link will not be freed before this point. */
 	if (!dp_link)
 		return;
 
+	dp_info("dp_link %pK id %d", dp_link, dp_link->link_id);
 	dp_intf = dp_link->dp_intf;
 	dp_ctx = dp_intf->dp_ctx;
 
@@ -2045,9 +2059,17 @@ void wlan_dp_link_cdp_vdev_delete_notification(void *context)
 		else
 			qdf_assert_always(0);
 
+		dp_info("Free dp_link %pK id %d (" QDF_MAC_ADDR_FMT ")",
+			dp_link, dp_link->link_id,
+			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
+		dp_link->magic = 0;
 		qdf_mem_free(dp_link);
 	} else {
 		/* dp_link not yet destroyed */
+		dp_info("CDP vdev delete for dp_link %pK id %d ("
+			QDF_MAC_ADDR_FMT ")",
+			dp_link, dp_link->link_id,
+			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
 		dp_link->cdp_vdev_deleted = 1;
 	}
 

+ 48 - 5
components/dp/dispatcher/src/wlan_dp_ucfg_api.c

@@ -300,6 +300,11 @@ void ucfg_dp_set_cmn_dp_handle(struct wlan_objmgr_psoc *psoc,
 
 	dp_ctx = dp_psoc_get_priv(psoc);
 
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
 	dp_ctx->cdp_soc = soc;
 
 	soc_param.hal_soc_hdl = NULL;
@@ -319,6 +324,10 @@ void ucfg_dp_set_hif_handle(struct wlan_objmgr_psoc *psoc,
 	struct wlan_dp_psoc_context *dp_ctx;
 
 	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
 
 	dp_ctx->hif_handle = hif_handle;
 }
@@ -1057,6 +1066,10 @@ ucfg_dp_update_config(struct wlan_objmgr_psoc *psoc,
 	void *soc;
 
 	dp_ctx =  dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return QDF_STATUS_E_INVAL;
+	}
 
 	dp_ctx->arp_connectivity_map = req->arp_connectivity_map;
 	soc = cds_get_context(QDF_MODULE_ID_SOC);
@@ -1097,7 +1110,13 @@ ucfg_dp_update_config(struct wlan_objmgr_psoc *psoc,
 uint64_t
 ucfg_dp_get_rx_softirq_yield_duration(struct wlan_objmgr_psoc *psoc)
 {
-	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+	struct wlan_dp_psoc_context *dp_ctx;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return 0;
+	}
 
 	return dp_ctx->dp_cfg.rx_softirq_max_yield_duration_ns;
 }
@@ -1537,8 +1556,20 @@ void ucfg_dp_register_rx_mic_error_ind_handler(void *soc)
 bool
 ucfg_dp_is_roam_after_nud_enabled(struct wlan_objmgr_psoc *psoc)
 {
-	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
-	struct wlan_dp_psoc_cfg *dp_cfg = &dp_ctx->dp_cfg;
+	struct wlan_dp_psoc_context *dp_ctx;
+	struct wlan_dp_psoc_cfg *dp_cfg;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return false;
+	}
+
+	dp_cfg = &dp_ctx->dp_cfg;
+	if (!dp_cfg) {
+		dp_err("Unable to get DP config");
+		return false;
+	}
 
 	if (dp_cfg->enable_nud_tracking == DP_ROAM_AFTER_NUD_FAIL ||
 	    dp_cfg->enable_nud_tracking == DP_DISCONNECT_AFTER_ROAM_FAIL)
@@ -1550,8 +1581,20 @@ ucfg_dp_is_roam_after_nud_enabled(struct wlan_objmgr_psoc *psoc)
 bool
 ucfg_dp_is_disconect_after_roam_fail(struct wlan_objmgr_psoc *psoc)
 {
-	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
-	struct wlan_dp_psoc_cfg *dp_cfg = &dp_ctx->dp_cfg;
+	struct wlan_dp_psoc_context *dp_ctx;
+	struct wlan_dp_psoc_cfg *dp_cfg;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return false;
+	}
+
+	dp_cfg = &dp_ctx->dp_cfg;
+	if (!dp_cfg) {
+		dp_err("Unable to get DP config");
+		return false;
+	}
 
 	if (dp_cfg->enable_nud_tracking == DP_DISCONNECT_AFTER_ROAM_FAIL)
 		return true;

+ 1 - 0
components/mlme/core/src/wlan_mlme_main.c

@@ -1712,6 +1712,7 @@ static void mlme_init_ht_cap_in_cfg(struct wlan_objmgr_psoc *psoc,
 				cfg_get(psoc, CFG_SHORT_GI_20MHZ);
 	u1.ht_cap_info.short_gi_40_mhz =
 				cfg_get(psoc, CFG_SHORT_GI_40MHZ);
+	u1.ht_cap_info.mimo_power_save = cfg_get(psoc, CFG_HT_SMPS_MODE);
 	ht_caps->ht_cap_info = u1.ht_cap_info;
 
 	/* HT Capapabilties - AMPDU Params */

+ 32 - 5
components/mlme/dispatcher/inc/cfg_mlme_reg.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -413,23 +413,50 @@
 		"Retain NOL even if the regdomain changes")
 
 #ifdef FEATURE_WLAN_CH_AVOID_EXT
+
+/**
+ * enum ignore_fw_coex_info_modes - Represents modes
+ * @IGNORE_FW_COEX_INFO_ON_SAP_MODE: Set this bit to ignore fw coex info on
+ *                                   SAP mode
+ * @IGNORE_FW_COEX_INFO_ON_P2P_GO_MODE: Set this bit to ignore fw coex info
+ *                                   on P2P-GO mode
+ */
+enum ignore_fw_coex_info_modes {
+	IGNORE_FW_COEX_INFO_ON_SAP_MODE = 1 << 0,
+	IGNORE_FW_COEX_INFO_ON_P2P_GO_MODE = 1 << 1
+};
+
 /*
  * <ini>
  * coex_unsafe_chan_nb_user_prefer- Used to handle coex unsafe freq
  * event
  *
- * @Min: 0 (Honor Firmware event)
- * @Max: 1 (Don't honor Firmware event)
- * Default: 0
+ * @Min: 0
+ * @Max: 0xFF
+ * @Default: 0
+ *
+ * Bit map of the modes to consider/ignore firmware provided coex/unsafe
+ * channels.
+ * Firmware provided coex/unsafe channel info is ignored if the corresponding
+ * bit is set to 1.
+ * Firmware provided coex/unsafe channel info is honored if the corresponding
+ * bit is set to 0.
+ *
+ * BIT 0: Don't honor firmware coex info for SAP mode
+ * BIT 1: Don't honor firmware coex info for P2P-GO mode
+ * Rest of the bits are currently reserved
  *
  * This ini is used to handle coex unsafe freq event
  * Usage: External
  *
  * </ini>
  */
-#define CFG_COEX_UNSAFE_CHAN_NB_USER_PREFER CFG_INI_BOOL( \
+#define CFG_COEX_UNSAFE_CHAN_NB_USER_PREFER CFG_INI_UINT( \
 		"coex_unsafe_chan_nb_user_prefer", \
 		0, \
+		0xff, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
 		"Honor coex unsafe freq event from firmware")
 /*
  * <ini>

+ 1 - 1
components/mlme/dispatcher/inc/cfg_mlme_sta.h

@@ -763,7 +763,7 @@
 
 #define CFG_MLO_MLO_5GL_5GH_MLSR CFG_INI_BOOL( \
 		"mlo_5gl_5gh_mlsr",\
-		0, \
+		1, \
 		"enable 5GL+5GH MLSR")
 
 #define CFG_MLO_MLO_5GL_5GH_MLSR_CFG CFG(CFG_MLO_MLO_5GL_5GH_MLSR)

+ 20 - 2
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -355,11 +355,29 @@ wlan_mlme_get_wlm_multi_client_ll_caps(struct wlan_objmgr_psoc *psoc)
  *
  * Return: coex_unsafe_chan_nb_user_prefer
  */
-bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(
+uint32_t wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(
+		struct wlan_objmgr_psoc *psoc);
+bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_p2p_go(
+		struct wlan_objmgr_psoc *psoc);
+bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
 		struct wlan_objmgr_psoc *psoc);
 #else
 static inline
-bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(
+uint32_t wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline
+bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline
+bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_p2p_go(
 		struct wlan_objmgr_psoc *psoc)
 {
 	return false;

+ 1 - 1
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -2768,7 +2768,7 @@ struct wlan_mlme_reg {
 	bool is_afc_reg_noaction;
 #endif
 #ifdef FEATURE_WLAN_CH_AVOID_EXT
-	bool coex_unsafe_chan_nb_user_prefer;
+	uint32_t coex_unsafe_chan_nb_user_prefer;
 	bool coex_unsafe_chan_reg_disable;
 #endif
 };

+ 11 - 1
components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -5076,6 +5076,9 @@ ucfg_mlme_cfg_get_ht_smps(struct wlan_objmgr_psoc *psoc,
 bool ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(
 		struct wlan_objmgr_psoc *psoc);
 
+bool ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
+		struct wlan_objmgr_psoc *psoc);
+
 /**
  * ucfg_mlme_get_coex_unsafe_chan_reg_disable() - get reg disable cap for
  * coex unsafe channels support
@@ -5093,6 +5096,13 @@ bool ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(
 	return false;
 }
 
+static inline
+bool ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
 static inline
 bool ucfg_mlme_get_coex_unsafe_chan_reg_disable(
 		struct wlan_objmgr_psoc *psoc)

+ 16 - 1
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -223,7 +223,7 @@ bool wlan_mlme_get_wlm_multi_client_ll_caps(struct wlan_objmgr_psoc *psoc)
 #endif
 
 #ifdef FEATURE_WLAN_CH_AVOID_EXT
-bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(
+uint32_t wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(
 		struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
@@ -233,8 +233,23 @@ bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(
 		mlme_legacy_err("Failed to get MLME Obj");
 		return cfg_default(CFG_COEX_UNSAFE_CHAN_NB_USER_PREFER);
 	}
+
 	return mlme_obj->cfg.reg.coex_unsafe_chan_nb_user_prefer;
 }
+
+bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return !!(wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(psoc) &
+					IGNORE_FW_COEX_INFO_ON_SAP_MODE);
+}
+
+bool wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_p2p_go(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return !!(wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(psoc) &
+					IGNORE_FW_COEX_INFO_ON_P2P_GO_MODE);
+}
 #endif
 
 QDF_STATUS wlan_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc,

+ 8 - 2
components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -1959,7 +1959,13 @@ bool ucfg_mlme_validate_scan_period(struct wlan_objmgr_psoc *psoc,
 bool ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(
 		struct wlan_objmgr_psoc *psoc)
 {
-	return wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(psoc);
+	return wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(psoc);
+}
+
+bool ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(psoc);
 }
 
 bool ucfg_mlme_get_coex_unsafe_chan_reg_disable(

+ 1 - 6
components/pmo/core/src/wlan_pmo_mc_addr_filtering.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 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
@@ -558,11 +558,6 @@ QDF_STATUS pmo_core_disable_mc_addr_filtering_in_fwr(
 	if (status != QDF_STATUS_SUCCESS)
 		goto put_ref;
 
-	if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) {
-		status = QDF_STATUS_E_INVAL;
-		goto put_ref;
-	}
-
 	pmo_debug("disable mclist trigger: %d", trigger);
 
 	status = pmo_core_handle_disable_mc_list_trigger(vdev, trigger);

+ 6 - 1
components/target_if/cp_stats/src/target_if_mc_cp_stats.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -1691,6 +1691,11 @@ target_if_set_pdev_stats_update_period(struct wlan_objmgr_psoc *psoc,
 
 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
 
+	if (!wmi_handle) {
+		cp_stats_err("wmi_handle is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
 	pdev_param.param_id = wmi_pdev_param_pdev_stats_update_period;
 	pdev_param.param_value = val;
 	return wmi_unified_pdev_param_send(wmi_handle,

+ 25 - 16
components/tdls/core/src/wlan_tdls_ct.c

@@ -165,7 +165,7 @@ void tdls_discovery_timeout_peer_cb(void *user_data)
 			peer = qdf_container_of(p_node, struct tdls_peer,
 						node);
 
-			tdls_debug("Peer: " QDF_MAC_ADDR_FMT "link status %d, vdev id %d",
+			tdls_debug("Peer: " QDF_MAC_ADDR_FMT " link status %d, vdev id %d",
 				   QDF_MAC_ADDR_REF(peer->peer_mac.bytes),
 				   peer->link_status, wlan_vdev_get_id(vdev));
 
@@ -474,8 +474,8 @@ void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
 	return;
 }
 
-void tdls_implicit_send_discovery_request(
-				struct tdls_vdev_priv_obj *tdls_vdev_obj)
+void
+tdls_implicit_send_discovery_request(struct tdls_vdev_priv_obj *tdls_vdev_obj)
 {
 	struct tdls_peer *curr_peer;
 	struct tdls_peer *temp_peer;
@@ -574,12 +574,16 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev,
 			qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer);
 	}
 
-	tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDR_FMT
-		   " link_status %d", tdls_vdev->discovery_sent_cnt,
+	tdls_debug("[TDLS] vdev:%d action:%d (%s) sent_count:%u from peer " QDF_MAC_ADDR_FMT
+		   " link_status %d", wlan_vdev_get_id(tdls_vdev->vdev),
+		   TDLS_DISCOVERY_RESPONSE,
+		   "TDLS_DISCOVERY_RESPONSE",
+		   tdls_vdev->discovery_sent_cnt,
 		   QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes),
 		   curr_peer->link_status);
 
-	/* Since peer link status bases on vdev and stream goes through
+	/*
+	 * Since peer link status bases on vdev and stream goes through
 	 * vdev0 (assoc link) at start, rx/tx pkt count on vdev0, but
 	 * it choices vdev1 as tdls link, the peer status does not change on
 	 * vdev1 though it has been changed for vdev0 per the rx/tx pkt count.
@@ -901,9 +905,10 @@ static void tdls_ct_process_connected_link(
  *
  * Return: None
  */
-static void tdls_ct_process_cap_supported(struct tdls_peer *curr_peer,
-					struct tdls_vdev_priv_obj *tdls_vdev,
-					struct tdls_soc_priv_obj *tdls_soc_obj)
+static void
+tdls_ct_process_cap_supported(struct tdls_peer *curr_peer,
+			      struct tdls_vdev_priv_obj *tdls_vdev,
+			      struct tdls_soc_priv_obj *tdls_soc_obj)
 {
 	if (curr_peer->rx_pkt || curr_peer->tx_pkt)
 		tdls_debug(QDF_MAC_ADDR_FMT "link_status %d tdls_support %d tx %d rx %d rssi %d vdev %d",
@@ -915,10 +920,11 @@ static void tdls_ct_process_cap_supported(struct tdls_peer *curr_peer,
 	switch (curr_peer->link_status) {
 	case TDLS_LINK_IDLE:
 	case TDLS_LINK_DISCOVERING:
-		if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(
-			tdls_soc_obj->tdls_configs.tdls_feature_flags) &&
-			(!curr_peer->is_forced_peer))
+		if (!curr_peer->is_forced_peer &&
+		    TDLS_IS_EXTERNAL_CONTROL_ENABLED(
+			tdls_soc_obj->tdls_configs.tdls_feature_flags))
 			break;
+
 		tdls_ct_process_idle_and_discovery(curr_peer, tdls_vdev,
 						   tdls_soc_obj);
 		break;
@@ -951,7 +957,7 @@ static void tdls_ct_process_cap_unknown(struct tdls_peer *curr_peer,
 		return;
 
 	if (curr_peer->rx_pkt || curr_peer->tx_pkt)
-		tdls_debug(QDF_MAC_ADDR_FMT "link_status %d tdls_support %d tx %d rx %d vdev %d",
+		tdls_debug(QDF_MAC_ADDR_FMT " link_status %d tdls_support %d tx %d rx %d vdev %d",
 			   QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes),
 			   curr_peer->link_status, curr_peer->tdls_support,
 			   curr_peer->tx_pkt, curr_peer->rx_pkt,
@@ -971,7 +977,10 @@ static void tdls_ct_process_cap_unknown(struct tdls_peer *curr_peer,
 		if (curr_peer->is_forced_peer ||
 		    curr_peer->discovery_attempt <
 		    tdls_vdev->threshold_config.discovery_tries_n) {
-			tdls_debug("TDLS UNKNOWN discover ");
+			tdls_debug("TDLS UNKNOWN discover num_attempts:%d num_left:%d forced_peer:%d",
+				   curr_peer->discovery_attempt,
+				   tdls_vdev->threshold_config.discovery_tries_n,
+				   curr_peer->is_forced_peer);
 			tdls_vdev->curr_candidate = curr_peer;
 			tdls_implicit_send_discovery_request(tdls_vdev);
 
@@ -1027,8 +1036,8 @@ static void tdls_ct_process_handler(struct wlan_objmgr_vdev *vdev)
 	struct tdls_vdev_priv_obj *tdls_vdev_obj;
 	struct tdls_soc_priv_obj *tdls_soc_obj;
 
-	if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj,
-						   &tdls_soc_obj))
+	status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
+	if (QDF_IS_STATUS_ERROR(status))
 		return;
 
 	/* If any concurrency is detected */

+ 2 - 12
components/tdls/core/src/wlan_tdls_main.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -709,8 +709,7 @@ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg)
 	}
 	event = &notify->event;
 
-	tdls_debug("evt type: %s(%d)",
-		   tdls_get_event_type_str(event->message_type),
+	tdls_debug(" %s(%d)", tdls_get_event_type_str(event->message_type),
 		   event->message_type);
 
 	switch (event->message_type) {
@@ -1606,15 +1605,6 @@ tdls_update_discovery_tries(struct wlan_objmgr_vdev *vdev)
 
 	vdev_config->discovery_tries_n =
 			tdls_config->tdls_max_discovery_attempt;
-
-	/*
-	 * For MLO peer discovery will happen on 2 links and the best link
-	 * will be chosen based on score for TDLS. So factor that into the
-	 * number of discovery attempts to increase the discoverability
-	 * window for the peer.
-	 */
-	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
-		vdev_config->discovery_tries_n *= 2;
 }
 
 QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify)

+ 15 - 2
components/tdls/core/src/wlan_tdls_mgmt.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 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
@@ -896,6 +896,8 @@ QDF_STATUS tdls_set_link_mode(struct tdls_action_frame_request *req)
 	bool is_mlo_vdev;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct ml_nlink_change_event data;
+	uint8_t num_ml_sta = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
 
 	is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(req->vdev);
 	if (!is_mlo_vdev)
@@ -907,12 +909,22 @@ QDF_STATUS tdls_set_link_mode(struct tdls_action_frame_request *req)
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
+
 	if (req->tdls_mgmt.frame_type == TDLS_DISCOVERY_RESPONSE ||
 	    req->tdls_mgmt.frame_type == TDLS_DISCOVERY_REQUEST) {
 		mlo_tdls_vdev = wlan_mlo_get_tdls_link_vdev(req->vdev);
 		if (mlo_tdls_vdev)
 			return status;
 
+		status = policy_mgr_is_ml_links_in_mcc_allowed(
+						psoc, req->vdev,
+						ml_sta_vdev_lst,
+						&num_ml_sta);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			tdls_err("ML STA Links in MCC, so don't send the TDLS frames");
+			return QDF_STATUS_E_FAILURE;
+		}
+
 		qdf_mem_zero(&data, sizeof(data));
 		data.evt.tdls.link_bitmap =
 				1 << wlan_vdev_get_link_id(req->vdev);
@@ -971,7 +983,8 @@ QDF_STATUS tdls_process_mgmt_req(
 
 	status = tdls_set_link_mode(tdls_mgmt_req);
 	if (status != QDF_STATUS_SUCCESS) {
-		tdls_err("failed to set link active");
+		tdls_err("failed to set link:%d active",
+			 wlan_vdev_get_link_id(tdls_mgmt_req->vdev));
 		status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
 							 status);
 		goto error_mgmt;

+ 3 - 3
components/tdls/dispatcher/src/wlan_tdls_api.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -502,8 +502,8 @@ void wlan_tdls_increment_discovery_attempts(struct wlan_objmgr_psoc *psoc,
 	}
 
 	peer->discovery_attempt++;
-	tdls_debug("vdev:%d peer discovery attempts:%d", vdev_id,
-		   peer->discovery_attempt);
+	tdls_debug("vdev:%d peer: " QDF_MAC_ADDR_FMT " discovery attempts:%d ", vdev_id,
+		   QDF_MAC_ADDR_REF(peer_addr), peer->discovery_attempt);
 
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
 }

+ 5 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c

@@ -70,6 +70,11 @@ cm_is_peer_preset_on_other_sta(struct wlan_objmgr_psoc *psoc,
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
 	uint8_t peer_vdev_id;
 
+	if (!wma) {
+		wma_err("wma_handle is NULL");
+		return false;
+	}
+
 	sync_ind = (struct roam_offload_synch_ind *)event;
 
 	if (wma_objmgr_peer_exist(wma, sync_ind->bssid.bytes, &peer_vdev_id)) {

+ 13 - 7
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -4958,7 +4958,8 @@ cm_roam_state_change(struct wlan_objmgr_pdev *pdev,
 		is_up = QDF_IS_STATUS_SUCCESS(wlan_vdev_is_up(vdev));
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
 
-	if (requested_state != WLAN_ROAM_DEINIT && !is_up) {
+	if ((requested_state != WLAN_ROAM_DEINIT &&
+	     requested_state != WLAN_ROAM_RSO_STOPPED) && !is_up) {
 		mlme_debug("ROAM: roam state(%d) change requested in non-connected state",
 			   requested_state);
 		goto end;
@@ -6954,7 +6955,7 @@ cm_roam_btm_query_event(struct wmi_neighbor_report_data *btm_data,
 	qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event));
 
 	populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id,
-			  (uint64_t)btm_data->timestamp, NULL);
+			  (uint64_t)btm_data->req_time, NULL);
 
 	wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_QUERY_EVENT;
 	wlan_diag_event.version = DIAG_BTM_VERSION_2;
@@ -7075,7 +7076,7 @@ cm_roam_btm_resp_event(struct wmi_roam_trigger_info *trigger_info,
 	qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event));
 
 	populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id,
-			  (uint64_t)trigger_info->timestamp,
+			  (uint64_t)btm_data->timestamp,
 			  &btm_data->target_bssid);
 
 	wlan_diag_event.version = DIAG_BTM_VERSION_2;
@@ -7123,7 +7124,8 @@ cm_roam_btm_candidate_event(struct wmi_btm_req_candidate_info *btm_data,
 }
 
 QDF_STATUS
-cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data,
+cm_roam_btm_req_event(struct wmi_neighbor_report_data *neigh_rpt,
+		      struct wmi_roam_btm_trigger_data *btm_data,
 		      struct wmi_roam_trigger_info *trigger_info,
 		      uint8_t vdev_id, bool is_wtc)
 {
@@ -7144,9 +7146,13 @@ cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data,
 	    btm_data->disassoc_timer)
 		return status;
 
-	populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id,
-			  (uint64_t)btm_data->timestamp,
-			  NULL);
+	if (neigh_rpt->resp_time)
+		populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id,
+				  (uint64_t)neigh_rpt->resp_time, NULL);
+	else
+		populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id,
+				  (uint64_t)trigger_info->timestamp, NULL);
+
 
 	wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_REQ_EVENT;
 	wlan_diag_event.version = DIAG_BTM_VERSION_2;

+ 6 - 3
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h

@@ -603,15 +603,17 @@ cm_roam_mgmt_frame_event(struct wlan_objmgr_vdev *vdev,
 
 /**
  * cm_roam_btm_req_event  - Send BTM request related logging event
- * @vdev_id: Vdev id
+ * @neigh_rpt: Neighbor report/BTM request related data
  * @btm_data: BTM trigger related data
  * @trigger_info: Roam trigger related info
+ * @vdev_id: vdev id
  * @is_wtc: Is WTC or BTM response
  *
  * Return: QDF_STATUS
  */
 QDF_STATUS
-cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data,
+cm_roam_btm_req_event(struct wmi_neighbor_report_data *neigh_rpt,
+		      struct wmi_roam_btm_trigger_data *btm_data,
 		      struct wmi_roam_trigger_info *trigger_info,
 		      uint8_t vdev_id, bool is_wtc);
 
@@ -696,7 +698,8 @@ cm_roam_mgmt_frame_event(struct wlan_objmgr_vdev *vdev,
 }
 
 static inline QDF_STATUS
-cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data,
+cm_roam_btm_req_event(struct wmi_neighbor_report_data *neigh_rpt,
+		      struct wmi_roam_btm_trigger_data *btm_data,
 		      struct wmi_roam_trigger_info *trigger_info,
 		      uint8_t vdev_id, bool is_wtc)
 {

+ 2 - 1
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload_event.c

@@ -624,7 +624,8 @@ QDF_STATUS cm_roam_sync_event_handler_cb(struct wlan_objmgr_vdev *vdev,
 		goto err;
 	}
 
-	cm_roam_update_vdev(sync_ind, vdev_id);
+	cm_roam_update_vdev(vdev, sync_ind);
+
 	/*
 	 * update phy_mode in wma to avoid mismatch in phymode between host and
 	 * firmware. The phymode stored in peer->peer_mlme.phymode is

+ 0 - 41
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -1161,46 +1161,6 @@ set_partner_info_for_2link_sap(struct scan_cache_entry *scan_entry,
 }
 #endif
 
-static void
-cm_check_ml_missing_partner_entries(struct cm_connect_req *conn_req)
-{
-	uint8_t idx;
-	struct scan_cache_entry *entry, *partner_entry;
-	qdf_list_t *candidate_list = conn_req->candidate_list;
-	struct qdf_mac_addr *mld_addr;
-	struct partner_link_info *partner_info;
-
-	entry = conn_req->cur_candidate->entry;
-	mld_addr = util_scan_entry_mldaddr(entry);
-
-	/*
-	 * If the entry is not one of following, return gracefully:
-	 *   -AP is not ML type
-	 *   -AP is SLO
-	 */
-	if (!mld_addr || !entry->ml_info.num_links)
-		return;
-
-	for (idx = 0; idx < entry->ml_info.num_links; idx++) {
-		if (!entry->ml_info.link_info[idx].is_valid_link)
-			continue;
-
-		partner_info = &entry->ml_info.link_info[idx];
-		partner_entry = cm_get_entry(candidate_list,
-					     &partner_info->link_addr);
-		/*
-		 * If partner entry is not found in candidate list or if
-		 * the MLD address of the entry is not equal to current
-		 * candidate MLD address, treat it as entry not found.
-		 */
-		if (!partner_entry ||
-		    !qdf_is_macaddr_equal(mld_addr,
-					  &partner_entry->ml_info.mld_mac_addr)) {
-			partner_info->is_scan_entry_not_found = true;
-		}
-	}
-}
-
 QDF_STATUS
 cm_get_ml_partner_info(struct wlan_objmgr_pdev *pdev,
 		       struct cm_connect_req *conn_req)
@@ -1264,7 +1224,6 @@ cm_get_ml_partner_info(struct wlan_objmgr_pdev *pdev,
 	mlme_debug("sta and ap intersect num of partner link: %d", j);
 
 	set_partner_info_for_2link_sap(scan_entry, partner_info);
-	cm_check_ml_missing_partner_entries(conn_req);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 3 - 3
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -1966,8 +1966,8 @@ cm_roam_vendor_handoff_event_handler(struct wlan_objmgr_psoc *psoc,
 
 /**
  * cm_roam_update_vdev() - Update the STA and BSS
+ * @vdev: Pointer to the vdev object
  * @sync_ind: Information needed for roam sync propagation
- * @vdev_id: vdev id
  *
  * This function will perform all the vdev related operations with
  * respect to the self sta and the peer after roaming and completes
@@ -1975,8 +1975,8 @@ cm_roam_vendor_handoff_event_handler(struct wlan_objmgr_psoc *psoc,
  *
  * Return: None
  */
-void cm_roam_update_vdev(struct roam_offload_synch_ind *sync_ind,
-			 uint8_t vdev_id);
+void cm_roam_update_vdev(struct wlan_objmgr_vdev *vdev,
+			 struct roam_offload_synch_ind *sync_ind);
 
 /**
  * cm_roam_pe_sync_callback() - Callback registered at pe, gets invoked when

+ 22 - 11
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -2899,6 +2899,7 @@ cm_roam_scan_ch_list_event_handler(struct cm_roam_scan_ch_resp *data)
 /**
  * cm_roam_stats_get_trigger_detail_str - Return roam trigger string from the
  * enum roam_trigger_reason
+ * @neigh_rpt: Neighbor report/BTM request related data
  * @ptr: Pointer to the roam trigger info
  * @buf: Destination buffer to write the reason string
  * @is_full_scan: Is roam scan partial scan or all channels scan
@@ -2907,7 +2908,8 @@ cm_roam_scan_ch_list_event_handler(struct cm_roam_scan_ch_resp *data)
  * Return: None
  */
 static void
-cm_roam_stats_get_trigger_detail_str(struct wmi_roam_trigger_info *ptr,
+cm_roam_stats_get_trigger_detail_str(struct wmi_neighbor_report_data *neigh_rpt,
+				     struct wmi_roam_trigger_info *ptr,
 				     char *buf, bool is_full_scan,
 				     uint8_t vdev_id)
 {
@@ -2938,7 +2940,8 @@ cm_roam_stats_get_trigger_detail_str(struct wmi_roam_trigger_info *ptr,
 	case ROAM_TRIGGER_REASON_UNIT_TEST:
 		break;
 	case ROAM_TRIGGER_REASON_BTM:
-		cm_roam_btm_req_event(&ptr->btm_trig_data, ptr, vdev_id, false);
+		cm_roam_btm_req_event(neigh_rpt, &ptr->btm_trig_data, ptr,
+				      vdev_id, false);
 		buf_cons = qdf_snprint(
 				temp, buf_left,
 				"Req_mode: %d Disassoc_timer: %d",
@@ -3030,6 +3033,7 @@ cm_roam_stats_get_trigger_detail_str(struct wmi_roam_trigger_info *ptr,
 /**
  * cm_roam_stats_print_trigger_info  - Roam trigger related details
  * @psoc:  Pointer to PSOC object
+ * @neigh_rpt: Neighbor report/BTM request related data
  * @data:  Pointer to the roam trigger data
  * @scan_data: Roam scan data pointer
  * @vdev_id: Vdev ID
@@ -3042,6 +3046,7 @@ cm_roam_stats_get_trigger_detail_str(struct wmi_roam_trigger_info *ptr,
  */
 static void
 cm_roam_stats_print_trigger_info(struct wlan_objmgr_psoc *psoc,
+				 struct wmi_neighbor_report_data *neigh_rpt,
 				 struct wmi_roam_trigger_info *data,
 				 struct wmi_roam_scan_data *scan_data,
 				 uint8_t vdev_id, bool is_full_scan)
@@ -3054,7 +3059,8 @@ cm_roam_stats_print_trigger_info(struct wlan_objmgr_psoc *psoc,
 	if (!buf)
 		return;
 
-	cm_roam_stats_get_trigger_detail_str(data, buf, is_full_scan, vdev_id);
+	cm_roam_stats_get_trigger_detail_str(neigh_rpt, data, buf,
+					     is_full_scan, vdev_id);
 	mlme_get_converted_timestamp(data->timestamp, time);
 
 	/* Update roam trigger info to userspace */
@@ -3604,7 +3610,8 @@ cm_roam_handle_btm_stats(struct wlan_objmgr_psoc *psoc,
 	 */
 	if (stats_info->scan[i].present &&
 	    stats_info->scan[i].type == ROAM_STATS_SCAN_TYPE_NO_SCAN) {
-		cm_roam_btm_req_event(&stats_info->trigger[i].btm_trig_data,
+		cm_roam_btm_req_event(&stats_info->data_11kv[i],
+				      &stats_info->trigger[i].btm_trig_data,
 				      &stats_info->trigger[i],
 				      stats_info->vdev_id, false);
 		log_btm_frames_only = true;
@@ -3616,7 +3623,9 @@ cm_roam_handle_btm_stats(struct wlan_objmgr_psoc *psoc,
 				    stats_info->scan[i].type;
 
 		/* BTM request diag log event will be sent from inside below */
-		cm_roam_stats_print_trigger_info(psoc, &stats_info->trigger[i],
+		cm_roam_stats_print_trigger_info(psoc,
+						 &stats_info->data_11kv[i],
+						 &stats_info->trigger[i],
 						 &stats_info->scan[i],
 						 stats_info->vdev_id,
 						 is_full_scan);
@@ -4384,7 +4393,8 @@ cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
 			}
 
 			cm_roam_stats_print_trigger_info(
-					psoc, &stats_info->trigger[i],
+					psoc, &stats_info->data_11kv[i],
+					&stats_info->trigger[i],
 					&stats_info->scan[i],
 					stats_info->vdev_id, is_full_scan);
 
@@ -4469,9 +4479,10 @@ cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
 			    ROAM_TRIGGER_REASON_WTC_BTM)
 				is_wtc = true;
 
-			cm_roam_btm_req_event(&stats_info->trigger[0].btm_trig_data,
-					      &stats_info->trigger[0],
-					      stats_info->vdev_id, is_wtc);
+			cm_roam_btm_req_event(&stats_info->data_11kv[0],
+					&stats_info->trigger[0].btm_trig_data,
+					&stats_info->trigger[0],
+					stats_info->vdev_id, is_wtc);
 		}
 
 		if (stats_info->scan[0].present &&
@@ -5001,8 +5012,8 @@ wlan_cm_set_force_20mhz_in_24ghz(struct wlan_objmgr_vdev *vdev,
 		return;
 
 	/*
-	 * Force 20 MHz in 2.4 GHz only if "override_ht20_40_24g" ini
-	 * is set and userspace connect req doesn't have 40 MHz HT caps
+	 * Force the connection to 20 MHz in 2.4 GHz if the userspace
+	 * connect req doesn't support 40 MHz in HT caps.
 	 */
 	if (mlme_priv->connect_info.force_20mhz_in_24ghz != !is_40mhz_cap)
 		send_ie_to_fw = true;

+ 8 - 1
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 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
@@ -78,6 +78,13 @@ bool __ll_lt_sap_is_bs_req_valid(struct wlan_bearer_switch_request *bs_req,
 		ll_sap_nofl_err("BS_SM request is null (via %s)", func);
 		return false;
 	}
+
+	if (bs_req->vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
+		ll_sap_nofl_err("Invalid vdev id %d in BS_SM request",
+				bs_req->vdev_id);
+		return false;
+	}
+
 	return true;
 }
 

+ 5 - 2
components/umac/mlme/sap/ll_sap/dispatcher/src/wlan_ll_sap_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 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
@@ -22,6 +22,7 @@
 #include "wlan_policy_mgr_api.h"
 #include "wlan_reg_services_api.h"
 #include "wlan_dfs_utils_api.h"
+#include "wlan_mlme_main.h"
 
 #ifdef WLAN_FEATURE_BEARER_SWITCH
 wlan_bs_req_id
@@ -205,7 +206,9 @@ qdf_freq_t wlan_get_ll_lt_sap_restart_freq(struct wlan_objmgr_pdev *pdev,
 	} else if (wlan_reg_is_passive_for_freq(pdev, chan_freq))  {
 		*csa_reason = CSA_REASON_CHAN_PASSIVE;
 		goto get_new_ll_lt_sap_freq;
-	} else if (!policy_mgr_is_sap_freq_allowed(psoc, chan_freq)) {
+	} else if (!policy_mgr_is_sap_freq_allowed(psoc,
+				wlan_get_opmode_from_vdev_id(pdev, vdev_id),
+				chan_freq)) {
 		*csa_reason = CSA_REASON_UNSAFE_CHANNEL;
 		goto get_new_ll_lt_sap_freq;
 	} else if (policy_mgr_is_ll_lt_sap_restart_required(psoc)) {

+ 10 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -387,6 +387,16 @@ void hdd_override_all_ps(struct hdd_context *hdd_ctx);
 int hdd_vendor_mode_to_phymode(enum qca_wlan_vendor_phy_mode vendor_phy_mode,
 			       eCsrPhyMode *csr_phy_mode);
 
+/**
+ * hdd_phymode_to_vendor_mode() - Get vendor phy mode according to CSR phy mode.
+ * @csr_phy_mode: phy mode of eCsrPhyMode
+ * @vendor_phy_mode: vendor phy mode
+ *
+ * Return: 0 on success, negative error value on failure
+ */
+int hdd_phymode_to_vendor_mode(eCsrPhyMode csr_phy_mode,
+			       enum qca_wlan_vendor_phy_mode *vendor_phy_mode);
+
 /**
  * hdd_vendor_mode_to_band() - Get band_info according to vendor phy mode
  * @vendor_phy_mode: vendor phy mode

+ 43 - 1
core/hdd/src/wlan_hdd_cfg.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -1863,6 +1863,47 @@ QDF_STATUS hdd_get_rx_nss(struct wlan_hdd_link_info *link_info, uint8_t *rx_nss)
 	return status;
 }
 
+int hdd_phymode_to_vendor_mode(eCsrPhyMode csr_phy_mode,
+			       enum qca_wlan_vendor_phy_mode *vendor_phy_mode)
+{
+	switch (csr_phy_mode) {
+	case eCSR_DOT11_MODE_AUTO:
+	case eCSR_DOT11_MODE_11be:
+	case eCSR_DOT11_MODE_11be_ONLY:
+		*vendor_phy_mode = QCA_WLAN_VENDOR_PHY_MODE_AUTO;
+		break;
+	case eCSR_DOT11_MODE_11a:
+		*vendor_phy_mode = QCA_WLAN_VENDOR_PHY_MODE_11A;
+		break;
+	case eCSR_DOT11_MODE_11b:
+	case eCSR_DOT11_MODE_11b_ONLY:
+		*vendor_phy_mode = QCA_WLAN_VENDOR_PHY_MODE_11B;
+		break;
+	case eCSR_DOT11_MODE_11g:
+	case eCSR_DOT11_MODE_11g_ONLY:
+		*vendor_phy_mode = QCA_WLAN_VENDOR_PHY_MODE_11G;
+		break;
+	case eCSR_DOT11_MODE_11n:
+	case eCSR_DOT11_MODE_11n_ONLY:
+		*vendor_phy_mode = QCA_WLAN_VENDOR_PHY_MODE_11AGN;
+		break;
+	case eCSR_DOT11_MODE_11ac:
+	case eCSR_DOT11_MODE_11ac_ONLY:
+		*vendor_phy_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160;
+		break;
+	case eCSR_DOT11_MODE_11ax:
+	case eCSR_DOT11_MODE_11ax_ONLY:
+		*vendor_phy_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160;
+		break;
+	case eCSR_DOT11_MODE_abg:
+	default:
+		hdd_err("Not supported mode %d", csr_phy_mode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 int hdd_vendor_mode_to_phymode(enum qca_wlan_vendor_phy_mode vendor_phy_mode,
 			       eCsrPhyMode *csr_phy_mode)
 {
@@ -2027,6 +2068,7 @@ int hdd_phymode_to_dot11_mode(eCsrPhyMode phymode,
 {
 	switch (phymode) {
 	case eCSR_DOT11_MODE_AUTO:
+	case eCSR_DOT11_MODE_11be:
 		*dot11_mode = eHDD_DOT11_MODE_AUTO;
 		break;
 	case eCSR_DOT11_MODE_11a:

+ 71 - 15
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1339,7 +1339,7 @@ static int __wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy,
 						       NLMSG_HDRLEN);
 	if (!skb) {
 		hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
-		goto fail;
+		return -EINVAL;
 	}
 
 	if ((cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support) ==
@@ -9056,7 +9056,9 @@ int hdd_set_vdev_phy_mode(struct hdd_adapter *adapter,
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
 	struct wlan_hdd_link_info *link_info = adapter->deflink;
-	eCsrPhyMode phymode;
+	eCsrPhyMode csr_req_phymode, csr_max_phymode;
+	enum reg_phymode reg_req_phymode, reg_max_phymode;
+	enum qca_wlan_vendor_phy_mode max_vendor_phy_mode;
 	WMI_HOST_WIFI_STANDARD std;
 	enum hdd_dot11_mode dot11_mode;
 	uint8_t supported_band;
@@ -9066,24 +9068,41 @@ int hdd_set_vdev_phy_mode(struct hdd_adapter *adapter,
 		hdd_err("Station is connected, command is not supported");
 		return -EINVAL;
 	}
+	ret = hdd_vendor_mode_to_phymode(vendor_phy_mode, &csr_req_phymode);
+	if (ret < 0)
+		return ret;
 
-	adapter->user_phy_mode = vendor_phy_mode;
+	reg_req_phymode = csr_convert_to_reg_phy_mode(csr_req_phymode, 0);
+	reg_max_phymode = wlan_reg_get_max_phymode(hdd_ctx->pdev,
+						   reg_req_phymode, 0);
+	if (reg_req_phymode != reg_max_phymode) {
+		hdd_debug("reg_max_phymode %d, req_req_phymode %d",
+			  reg_max_phymode, reg_req_phymode);
+		csr_max_phymode =
+			csr_convert_from_reg_phy_mode(reg_max_phymode);
+		ret = hdd_phymode_to_vendor_mode(csr_max_phymode,
+						 &max_vendor_phy_mode);
+		if (ret)
+			return ret;
+	} else {
+		csr_max_phymode = csr_req_phymode;
+		max_vendor_phy_mode = vendor_phy_mode;
+	}
 
-	ret = hdd_vendor_mode_to_phymode(vendor_phy_mode, &phymode);
-	if (ret)
-		return ret;
+	adapter->user_phy_mode = max_vendor_phy_mode;
 
-	ret = hdd_phymode_to_dot11_mode(phymode, &dot11_mode);
+	ret = hdd_phymode_to_dot11_mode(csr_max_phymode, &dot11_mode);
 	if (ret)
 		return ret;
 
-	ret = hdd_vendor_mode_to_band(vendor_phy_mode, &supported_band,
+	ret = hdd_vendor_mode_to_band(max_vendor_phy_mode, &supported_band,
 				      wlan_reg_is_6ghz_supported(psoc));
 	if (ret)
 		return ret;
 
 	std = hdd_get_wifi_standard(hdd_ctx, dot11_mode, supported_band);
-	hdd_debug("wifi_standard %d, vendor_phy_mode %d", std, vendor_phy_mode);
+	hdd_debug("wifi_standard %d, vendor_phy_mode %d",
+		  std, max_vendor_phy_mode);
 
 	ret = sme_cli_set_command(link_info->vdev_id,
 				  wmi_vdev_param_wifi_standard_version,
@@ -9103,31 +9122,68 @@ int hdd_set_phy_mode(struct hdd_adapter *adapter,
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
-	eCsrPhyMode phymode;
+	eCsrPhyMode csr_req_phymode, csr_max_phymode;
+	enum reg_phymode reg_req_phymode, reg_max_phymode;
+	enum qca_wlan_vendor_phy_mode max_vendor_phy_mode = vendor_phy_mode;
 	uint8_t supported_band;
 	uint32_t bonding_mode;
 	int ret = 0;
+	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV;
+	struct hdd_adapter *curr_adapter, *next_adapter;
 
 	if (!psoc) {
 		hdd_err("psoc is NULL");
 		return -EINVAL;
 	}
 
-	ret = hdd_vendor_mode_to_phymode(vendor_phy_mode, &phymode);
+	ret = hdd_vendor_mode_to_phymode(vendor_phy_mode, &csr_req_phymode);
 	if (ret < 0)
 		return ret;
 
-	ret = hdd_vendor_mode_to_band(vendor_phy_mode, &supported_band,
+	reg_req_phymode = csr_convert_to_reg_phy_mode(csr_req_phymode, 0);
+	reg_max_phymode = wlan_reg_get_max_phymode(hdd_ctx->pdev,
+						   reg_req_phymode, 0);
+
+	if (reg_req_phymode != reg_max_phymode) {
+		hdd_debug("reg_max_phymode %d, req_req_phymode %d",
+			  reg_max_phymode, reg_req_phymode);
+		csr_max_phymode =
+			csr_convert_from_reg_phy_mode(reg_max_phymode);
+		ret = hdd_phymode_to_vendor_mode(csr_max_phymode,
+						 &max_vendor_phy_mode);
+		if (ret)
+			return ret;
+	} else {
+		csr_max_phymode = csr_req_phymode;
+		max_vendor_phy_mode = vendor_phy_mode;
+	}
+
+	ret = hdd_vendor_mode_to_band(max_vendor_phy_mode, &supported_band,
 				      wlan_reg_is_6ghz_supported(psoc));
 	if (ret < 0)
 		return ret;
 
-	ret = hdd_vendor_mode_to_bonding_mode(vendor_phy_mode, &bonding_mode);
+	ret = hdd_vendor_mode_to_bonding_mode(max_vendor_phy_mode,
+					      &bonding_mode);
 	if (ret < 0)
 		return ret;
 
-	return hdd_update_phymode(adapter, phymode, supported_band,
-				  bonding_mode);
+	ret = hdd_update_phymode(adapter, csr_max_phymode, supported_band,
+				 bonding_mode);
+	if (ret)
+		return ret;
+
+	hdd_for_each_adapter_dev_held_safe(hdd_ctx, curr_adapter, next_adapter,
+					   dbgid) {
+		if (curr_adapter->device_mode == QDF_STA_MODE &&
+		    !hdd_cm_is_vdev_connected(curr_adapter->deflink)) {
+			hdd_set_vdev_phy_mode(curr_adapter,
+					      max_vendor_phy_mode);
+		}
+		hdd_adapter_dev_put_debug(curr_adapter, dbgid);
+	}
+
+	return 0;
 }
 
 /**

+ 26 - 14
core/hdd/src/wlan_hdd_hostapd.c

@@ -364,18 +364,21 @@ hdd_hostapd_deinit_sap_session(struct wlan_hdd_link_info *link_info)
  * Called when, 1. bss stopped, 2. channel switch
  *
  * @adapter: pointer to hdd adapter
- * @chan_freq: current channel frequency
+ * @chan_freq: channel frequency
+ * @ch_params: channel params
  *
  * Return: None
  */
 static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter,
-					      uint32_t chan_freq)
+					      uint32_t chan_freq,
+					      struct ch_params *ch_params)
 {
 
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	struct hdd_hostapd_state *hostapd_state =
 		WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter->deflink);
 	struct sap_context *sap_ctx;
+	bool is_dfs;
 
 	hdd_debug("bss_state: %d, chan_freq: %d, dfs_ref_cnt: %d",
 		  hostapd_state->bss_state, chan_freq,
@@ -391,9 +394,10 @@ static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter,
 		return;
 	}
 
-	if (!sap_chan_bond_dfs_sub_chan(sap_ctx,
-					chan_freq,
-					PHY_CHANNEL_BONDING_STATE_MAX))
+	is_dfs = wlan_mlme_check_chan_param_has_dfs(hdd_ctx->pdev,
+						    ch_params,
+						    chan_freq);
+	if (!is_dfs)
 		return;
 
 	/* Release wakelock when no more DFS channels are used */
@@ -411,17 +415,20 @@ static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter,
  * Called when, 1. bss started, 2. channel switch
  *
  * @adapter: pointer to hdd adapter
- * @chan_freq: current channel frequency
+ * @chan_freq: channel frequency
+ * @ch_params: channel params
  *
  * Return - None
  */
 static void hdd_hostapd_channel_prevent_suspend(struct hdd_adapter *adapter,
-						uint32_t chan_freq)
+						uint32_t chan_freq,
+						struct ch_params *ch_params)
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	struct hdd_hostapd_state *hostapd_state =
 		WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter->deflink);
 	struct sap_context *sap_ctx;
+	bool is_dfs;
 
 	hdd_debug("bss_state: %d, chan_freq: %d, dfs_ref_cnt: %d",
 		  hostapd_state->bss_state, chan_freq,
@@ -437,9 +444,10 @@ static void hdd_hostapd_channel_prevent_suspend(struct hdd_adapter *adapter,
 		return;
 	}
 
-	if (!sap_chan_bond_dfs_sub_chan(sap_ctx,
-					chan_freq,
-					PHY_CHANNEL_BONDING_STATE_MAX))
+	is_dfs = wlan_mlme_check_chan_param_has_dfs(hdd_ctx->pdev,
+						    &sap_ctx->ch_params,
+						    chan_freq);
+	if (!is_dfs)
 		return;
 
 	/* Acquire wakelock if we have at least one DFS channel in use */
@@ -2353,7 +2361,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
 		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
 #endif
 		hdd_hostapd_channel_prevent_suspend(adapter,
-			ap_ctx->operating_chan_freq);
+			ap_ctx->operating_chan_freq,
+			&sap_config->ch_params);
 
 		hostapd_state->bss_state = BSS_START;
 		vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID);
@@ -2428,7 +2437,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
 		       status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
 
 		hdd_hostapd_channel_allow_suspend(adapter,
-						  ap_ctx->operating_chan_freq);
+						  ap_ctx->operating_chan_freq,
+						  &ap_ctx->sap_context->ch_params);
 
 		/* Invalidate the channel info. */
 		ap_ctx->operating_chan_freq = 0;
@@ -3017,10 +3027,12 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
 		if (hostapd_state->bss_state != BSS_STOP) {
 			/* Allow suspend for old channel */
 			hdd_hostapd_channel_allow_suspend(adapter,
-				ap_ctx->sap_context->freq_before_ch_switch);
+				ap_ctx->sap_context->freq_before_ch_switch,
+				&ap_ctx->sap_context->ch_params_before_ch_switch);
 			/* Prevent suspend for new channel */
 			hdd_hostapd_channel_prevent_suspend(adapter,
-				sap_event->sapevt.sap_ch_selected.pri_ch_freq);
+				sap_event->sapevt.sap_ch_selected.pri_ch_freq,
+				&ap_ctx->sap_context->ch_params);
 		}
 		/* SME/PE is already updated for new operation
 		 * channel. So update HDD layer also here. This

+ 1 - 24
core/hdd/src/wlan_hdd_ioctl.c

@@ -6004,30 +6004,7 @@ static bool hdd_is_supported_chain_mask_1x1(struct hdd_context *hdd_ctx)
 
 QDF_STATUS hdd_update_smps_antenna_mode(struct hdd_context *hdd_ctx, int mode)
 {
-	QDF_STATUS status;
-	uint8_t smps_mode;
-	uint8_t smps_enable;
-	mac_handle_t mac_handle;
-
-	/* Update SME SMPS config */
-	if (HDD_ANTENNA_MODE_1X1 == mode) {
-		smps_enable = true;
-		smps_mode = HDD_SMPS_MODE_STATIC;
-	} else {
-		smps_enable = false;
-		smps_mode = HDD_SMPS_MODE_DISABLED;
-	}
-
-	hdd_debug("Update SME SMPS enable: %d mode: %d",
-		 smps_enable, smps_mode);
-	mac_handle = hdd_ctx->mac_handle;
-	status = sme_update_mimo_power_save(mac_handle, smps_enable,
-					    smps_mode, false);
-	if (QDF_STATUS_SUCCESS != status) {
-		hdd_err("Update SMPS config failed enable: %d mode: %d status: %d",
-			smps_enable, smps_mode, status);
-		return QDF_STATUS_E_FAILURE;
-	}
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
 
 	hdd_ctx->current_antenna_mode = mode;
 	/*

+ 13 - 2
core/hdd/src/wlan_hdd_main.c

@@ -1941,9 +1941,11 @@ static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
 	if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
 	     config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
 		config->dot11Mode = eHDD_DOT11_MODE_AUTO;
+
 	/* 11BE mode support */
-	if (!hdd_dot11Mode_support_11be(config->dot11Mode) &&
-	    cfg->en_11be) {
+	if (cfg->en_11be &&
+	    (!hdd_dot11Mode_support_11be(config->dot11Mode) ||
+	     !wlan_reg_phybitmap_support_11be(hdd_ctx->pdev))) {
 		hdd_debug("dot11Mode %d override target en_11be to false",
 			  config->dot11Mode);
 		cfg->en_11be = false;
@@ -2186,6 +2188,15 @@ static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
 	if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
 		ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
 
+	hdd_debug("gHtSMPS ini: %d, dynamic_smps fw cap: %d",
+		  ht_cap_info.mimo_power_save, cfg->dynamic_smps);
+	if (ht_cap_info.mimo_power_save == HDD_SMPS_MODE_DYNAMIC) {
+		if (cfg->dynamic_smps)
+			ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DYNAMIC;
+		else
+			ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DISABLED;
+	}
+
 	hdd_ctx->num_rf_chains = cfg->num_rf_chains;
 	hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
 

+ 0 - 8
core/hdd/src/wlan_hdd_power.c

@@ -1542,9 +1542,6 @@ void hdd_disable_mc_addr_filtering(struct hdd_adapter *adapter,
 	if (wlan_hdd_validate_context(hdd_ctx))
 		return;
 
-	if (!hdd_cm_is_vdev_associated(adapter->deflink))
-		return;
-
 	status = ucfg_pmo_disable_mc_addr_filtering_in_fwr(
 						hdd_ctx->psoc,
 						adapter->deflink->vdev_id,
@@ -1568,9 +1565,6 @@ void hdd_disable_and_flush_mc_addr_list(struct hdd_adapter *adapter,
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	QDF_STATUS status;
 
-	if (!hdd_cm_is_vdev_associated(adapter->deflink))
-		goto flush_mc_list;
-
 	/* disable mc list first because the mc list is cached in PMO */
 	status = ucfg_pmo_disable_mc_addr_filtering_in_fwr(
 						hdd_ctx->psoc,
@@ -1579,12 +1573,10 @@ void hdd_disable_and_flush_mc_addr_list(struct hdd_adapter *adapter,
 	if (QDF_IS_STATUS_ERROR(status))
 		hdd_debug("failed to disable mc list; status:%d", status);
 
-flush_mc_list:
 	status = ucfg_pmo_flush_mc_addr_list(hdd_ctx->psoc,
 					     adapter->deflink->vdev_id);
 	if (QDF_IS_STATUS_ERROR(status))
 		hdd_debug("failed to flush mc list; status:%d", status);
-
 }
 
 /**

+ 10 - 2
core/hdd/src/wlan_hdd_regulatory.c

@@ -1656,6 +1656,8 @@ static void hdd_country_change_update_sta(struct hdd_context *hdd_ctx)
 	eCsrPhyMode csr_phy_mode;
 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA;
 	struct wlan_hdd_link_info *link_info;
+	enum qca_wlan_vendor_phy_mode vendor_phy_mode =
+						QCA_WLAN_VENDOR_PHY_MODE_AUTO;
 
 	pdev = hdd_ctx->pdev;
 
@@ -1692,8 +1694,11 @@ static void hdd_country_change_update_sta(struct hdd_context *hdd_ctx)
 					hdd_country_change_bw_check(link_info,
 								    oper_freq);
 
-				if (!hdd_is_vdev_in_conn_state(link_info))
+				if (!hdd_is_vdev_in_conn_state(link_info)) {
+					hdd_set_vdev_phy_mode(adapter,
+							      vendor_phy_mode);
 					continue;
+				}
 
 				if (phy_changed || freq_changed ||
 				    width_changed) {
@@ -1704,6 +1709,8 @@ static void hdd_country_change_update_sta(struct hdd_context *hdd_ctx)
 							link_info,
 							REASON_UNSPEC_FAILURE,
 							false);
+					hdd_set_vdev_phy_mode(adapter,
+							      vendor_phy_mode);
 					sta_ctx->reg_phymode = csr_phy_mode;
 				} else {
 					hdd_debug("Remain on current channel but update tx power");
@@ -1954,7 +1961,8 @@ static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc,
 	wiphy = pdev_priv->wiphy;
 	hdd_ctx = wiphy_priv(wiphy);
 
-	nb_flag = ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc);
+	nb_flag = ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
+								hdd_ctx->psoc);
 	reg_flag = ucfg_mlme_get_coex_unsafe_chan_reg_disable(hdd_ctx->psoc);
 
 	if (avoid_freq_ind && nb_flag && reg_flag)

+ 3 - 3
core/hdd/src/wlan_hdd_station_info.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -1588,7 +1588,7 @@ static int hdd_get_connected_station_info(struct wlan_hdd_link_info *link_info,
 						       nl_buf_len);
 	if (!skb) {
 		hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
-		goto fail;
+		return -ENOMEM;
 	}
 
 	hdd_info("stainfo");
@@ -2350,7 +2350,7 @@ static int hdd_get_connected_station_info_ex(struct hdd_context *hdd_ctx,
 						       nl_buf_len);
 	if (!skb) {
 		hdd_err_rl("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
-		goto fail;
+		return -ENOMEM;
 	}
 
 	if (qdf_is_macaddr_zero(&stainfo->mld_addr))

+ 6 - 3
core/hdd/src/wlan_hdd_stats.c

@@ -2384,7 +2384,7 @@ static void hdd_llstats_post_radio_stats(struct hdd_adapter *adapter,
 	if (!vendor_event) {
 		hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
 		hdd_llstats_free_radio_stats(radiostat);
-		goto failure;
+		return;
 	}
 
 	if (nla_put_u32(vendor_event,
@@ -3325,16 +3325,19 @@ static QDF_STATUS wlan_hdd_stats_request_needed(struct hdd_adapter *adapter)
 		hdd_err("Invalid hdd config");
 		return QDF_STATUS_E_INVAL;
 	}
+
 	if (adapter->hdd_ctx->is_get_station_clubbed_in_ll_stats_req) {
 		uint32_t stats_cached_duration;
 
 		stats_cached_duration =
 				qdf_system_ticks_to_msecs(qdf_system_ticks()) -
 				adapter->sta_stats_cached_timestamp;
-		if (stats_cached_duration <=
-			adapter->hdd_ctx->config->sta_stats_cache_expiry_time)
+		if (qdf_atomic_read(&adapter->is_ll_stats_req_pending) ||
+		    (stats_cached_duration <=
+			adapter->hdd_ctx->config->sta_stats_cache_expiry_time))
 			return QDF_STATUS_E_ALREADY;
 	}
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 3 - 3
core/mac/inc/qwlan_version.h

@@ -32,9 +32,9 @@
 #define QWLAN_VERSION_MAJOR            5
 #define QWLAN_VERSION_MINOR            2
 #define QWLAN_VERSION_PATCH            1
-#define QWLAN_VERSION_EXTRA            "K"
-#define QWLAN_VERSION_BUILD            88
+#define QWLAN_VERSION_EXTRA            "N"
+#define QWLAN_VERSION_BUILD            89
 
-#define QWLAN_VERSIONSTR               "5.2.1.88K"
+#define QWLAN_VERSIONSTR               "5.2.1.89N"
 
 #endif /* QWLAN_VERSION_H */

+ 20 - 90
core/mac/src/pe/lim/lim_api.c

@@ -2880,9 +2880,7 @@ pe_roam_synch_callback(struct mac_context *mac_ctx,
 		pe_err("LFR3:roam_sync_ind_ptr is NULL");
 		return status;
 	}
-	session_ptr = pe_find_session_by_vdev_id(mac_ctx,
-				vdev_id);
-
+	session_ptr = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
 	if (!session_ptr) {
 		pe_err("LFR3:Unable to find session");
 		return status;
@@ -3154,6 +3152,7 @@ pe_roam_synch_callback(struct mac_context *mac_ctx,
 	}
 
 	pe_delete_session(mac_ctx, session_ptr);
+
 	return QDF_STATUS_SUCCESS;
 
 roam_sync_fail:
@@ -3924,7 +3923,7 @@ lim_validate_probe_rsp_link_info(struct pe_session *session_entry,
 		if (!lim_match_link_info(ml_partner_info.partner_link_info[i].link_id,
 					 &ml_partner_info.partner_link_info[i].link_addr,
 					 &partner_info)) {
-			pe_err("Prb req link info does not match prb resp link info");
+			pe_err("Atleast one Per-STA profile is missing in the ML-probe response");
 			return QDF_STATUS_E_PROTO;
 		}
 	}
@@ -3958,61 +3957,16 @@ lim_clear_ml_partner_info(struct pe_session *session_entry)
 	partner_info->num_partner_links = 0;
 }
 
-static QDF_STATUS
-lim_compare_scan_entry_partner_info_with_join_req(struct mlo_partner_info
-						  *partner_info,
-						  struct partner_link_info
-						  *partner_link)
-{
-	int i;
-	int j;
-	struct mlo_link_info *partner_link_info;
-	struct partner_link_info *scan_info;
-	int num_matching_links = 0;
-	QDF_STATUS status = QDF_STATUS_E_FAILURE;
-
-	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
-		partner_link_info = &partner_info->partner_link_info[i];
-		for (j = 0; j < MLD_MAX_LINKS - 1; j++) {
-			scan_info = &partner_link[j];
-			if (!scan_info)
-				continue;
-			/*
-			 * do not compare if both have freq as zero
-			 */
-			if (scan_info->freq == 0)
-				continue;
-
-			if (scan_info->freq == partner_link_info->chan_freq) {
-				qdf_mem_cmp(partner_link_info->link_addr.bytes,
-					    scan_info->link_addr.bytes,
-					    QDF_MAC_ADDR_SIZE);
-				num_matching_links += 1;
-			}
-		}
-	}
-
-	if (partner_info->num_partner_links == num_matching_links) {
-		pe_debug("num of matching partner links %d",
-			 num_matching_links);
-		status = QDF_STATUS_SUCCESS;
-	}
-
-	return status;
-}
-
 static QDF_STATUS
 lim_check_scan_db_for_join_req_partner_info(struct pe_session *session_entry,
 					    struct mac_context *mac_ctx)
 {
 	struct join_req *lim_join_req;
 	struct wlan_objmgr_pdev *pdev;
-	struct partner_link_info *partner_link = NULL;
-	struct qdf_mac_addr qdf_bssid;
-	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	struct mlo_partner_info *partner_info;
-	uint16_t join_req_freq = 0;
-	struct scan_cache_entry *cache_entry;
+	struct mlo_link_info *link_info;
+	struct scan_cache_entry *partner_entry;
+	uint8_t i;
 
 	if (!session_entry) {
 		pe_err("session entry is NULL");
@@ -4036,47 +3990,23 @@ lim_check_scan_db_for_join_req_partner_info(struct pe_session *session_entry,
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	partner_link = qdf_mem_malloc(sizeof(struct partner_link_info) *
-			(MLD_MAX_LINKS - 1));
-
-	if (!partner_link)
-		return QDF_STATUS_E_FAILURE;
-
-	qdf_mem_copy(&qdf_bssid,
-		     &(lim_join_req->bssDescription.bssId),
-		     QDF_MAC_ADDR_SIZE);
-
-	join_req_freq = lim_join_req->bssDescription.chan_freq;
-
-	cache_entry = wlan_scan_get_scan_entry_by_mac_freq(pdev,
-							   &qdf_bssid,
-							   join_req_freq);
-
-	if (!cache_entry) {
-		pe_err("failed to get partner link info by mac addr");
-		status = QDF_STATUS_E_FAILURE;
-		goto free_mem;
-	}
-
-	qdf_mem_copy(partner_link, cache_entry->ml_info.link_info,
-		     sizeof(struct partner_link_info) * (MLD_MAX_LINKS - 1));
-
-	util_scan_free_cache_entry(cache_entry);
-
 	partner_info = &lim_join_req->partner_info;
-
-	status = lim_compare_scan_entry_partner_info_with_join_req(
-			partner_info, partner_link);
-
-	if (!QDF_IS_STATUS_SUCCESS(status)) {
-		pe_err("failed to match num of partner links in scan entry");
-		status = QDF_STATUS_E_FAILURE;
-		goto free_mem;
+	for (i = 0; i < partner_info->num_partner_links; i++) {
+		link_info = &partner_info->partner_link_info[i];
+		partner_entry =
+			wlan_scan_get_entry_by_bssid(pdev,
+						     &link_info->link_addr);
+		if (!partner_entry) {
+			pe_err("Scan entry is not found for partner link %d "
+			       QDF_MAC_ADDR_FMT,
+			       link_info->link_id,
+			       QDF_MAC_ADDR_REF(link_info->link_addr.bytes));
+			return QDF_STATUS_E_FAILURE;
+		}
+		util_scan_free_cache_entry(partner_entry);
 	}
 
-free_mem:
-	qdf_mem_free(partner_link);
-	return status;
+	return QDF_STATUS_SUCCESS;
 }
 
 QDF_STATUS lim_update_mlo_mgr_info(struct mac_context *mac_ctx,

+ 6 - 8
core/mac/src/pe/lim/lim_ft.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -620,7 +620,7 @@ lim_fill_ft_session(struct mac_context *mac,
 {
 	uint8_t bss_chan_id;
 	tSchBeaconStruct *pBeaconStruct;
-	ePhyChanBondState cbEnabledMode;
+	uint8_t cb_mode;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct));
@@ -702,14 +702,12 @@ lim_fill_ft_session(struct mac_context *mac,
 
 	ft_session->nss = ft_session ->vdev_nss;
 
-	if (ft_session->limRFBand == REG_BAND_2G) {
-		cbEnabledMode = mac->roam.configParam.channelBondingMode24GHz;
-	} else {
-		cbEnabledMode = mac->roam.configParam.channelBondingMode5GHz;
-	}
+	cb_mode = lim_get_cb_mode_for_freq(mac, ft_session,
+					   ft_session->curr_op_freq);
+
 	ft_session->htSupportedChannelWidthSet =
 	    (pBeaconStruct->HTInfo.present) ?
-	    (cbEnabledMode && pBeaconStruct->HTInfo.recommendedTxWidthSet &&
+	    (cb_mode && pBeaconStruct->HTInfo.recommendedTxWidthSet &&
 	     pBeaconStruct->HTCaps.supportedChannelWidthSet) : 0;
 	ft_session->htRecommendedTxWidthSet =
 		ft_session->htSupportedChannelWidthSet;

+ 9 - 8
core/mac/src/pe/lim/lim_link_monitoring_algo.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -403,14 +403,20 @@ lim_tear_down_link_with_ap(struct mac_context *mac, uint8_t sessionId,
 	 */
 	pe_session->pmmOffloadInfo.bcnmiss = false;
 
+	/* Delete all TDLS peers connected before leaving BSS */
+	lim_delete_tdls_peers(mac, pe_session);
+
 	/* Announce loss of link to Roaming algorithm */
 	/* and cleanup by sending SME_DISASSOC_REQ to SME */
 
 	sta = dph_get_hash_entry(mac, DPH_STA_HASH_INDEX_PEER,
 				 &pe_session->dph.dphHashTable);
-
-	if (!sta)
+	if (!sta) {
+		pe_debug("vdev:%d no sta hash entry for peer:" QDF_MAC_ADDR_FMT,
+			 pe_session->vdev_id,
+			 QDF_MAC_ADDR_REF(pe_session->bssId));
 		return;
+	}
 
 	if ((sta->mlmStaContext.disassocReason ==
 	    REASON_DEAUTH_NETWORK_LEAVING) ||
@@ -420,11 +426,6 @@ lim_tear_down_link_with_ap(struct mac_context *mac, uint8_t sessionId,
 		return;
 	}
 
-#ifdef FEATURE_WLAN_TDLS
-	/* Delete all TDLS peers connected before leaving BSS */
-	lim_delete_tdls_peers(mac, pe_session);
-#endif
-
 	sta->mlmStaContext.disassocReason = reasonCode;
 	sta->mlmStaContext.cleanupTrigger = trigger;
 	/* / Issue Deauth Indication to SME. */

+ 8 - 2
core/mac/src/pe/lim/lim_process_action_frame.c

@@ -1589,10 +1589,16 @@ static void lim_process_addba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_i
 
 	sta_ds = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
 				       &session->dph.dphHashTable);
-	if (sta_ds && lim_is_session_he_capable(session))
+	if (sta_ds &&
+	    (lim_is_session_he_capable(session) ||
+	     sta_ds->staType == STA_ENTRY_TDLS_PEER))
 		he_cap = lim_is_sta_he_capable(sta_ds);
-	if (sta_ds && lim_is_session_eht_capable(session))
+
+	if (sta_ds &&
+	    (lim_is_session_eht_capable(session) ||
+	     sta_ds->staType == STA_ENTRY_TDLS_PEER))
 		eht_cap = lim_is_sta_eht_capable(sta_ds);
+
 	if (sta_ds && sta_ds->staType == STA_ENTRY_NDI_PEER)
 		he_cap = lim_is_session_he_capable(session);
 

+ 0 - 150
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -47,8 +47,6 @@
 #include "wlan_mlme_ucfg_api.h"
 #include "wlan_connectivity_logging.h"
 #include <lim_mlo.h>
-#include <utils_mlo.h>
-#include <wlan_cm_roam_api.h>
 #include "parser_api.h"
 #include "wlan_twt_cfg_ext_api.h"
 #include "wlan_mlo_mgr_roam.h"
@@ -1096,133 +1094,6 @@ void lim_send_join_fail_on_vdev(struct mac_context *mac_ctx,
 			session_entry);
 }
 
-#ifdef WLAN_FEATURE_11BE_MLO
-static QDF_STATUS
-lim_gen_link_specific_probe_resp_from_assoc_resp(struct mac_context *mac_ctx,
-						 uint8_t *rx_pkt_info,
-						 uint32_t frame_len,
-						 struct pe_session *session)
-{
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	struct bss_description *bss;
-	struct scan_cache_entry *scan_entry;
-	struct mlo_partner_info *lim_partner_info;
-	struct partner_link_info *scan_partner_info;
-	struct mlo_link_info *link_info;
-	uint8_t link_id, idx, idx2;
-	struct qdf_mac_addr link_addr;
-	struct element_info link_probe_rsp, probe_rsp;
-	uint8_t *frame = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
-	int8_t rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
-
-	if (!session->lim_join_req) {
-		pe_debug("Session join req invalid");
-		return QDF_STATUS_E_INVAL;
-	}
-
-	bss = &session->lim_join_req->bssDescription;
-	lim_partner_info = &session->lim_join_req->partner_info;
-
-	/*
-	 * For link VDEV no need to generate again, as during assoc VDEv
-	 * it is already generated.
-	 */
-	if (!bss->mbssid_info.profile_num ||
-	    !lim_partner_info->num_partner_links ||
-	    wlan_vdev_mlme_is_mlo_link_vdev(session->vdev)) {
-		return QDF_STATUS_SUCCESS;
-	}
-
-	link_probe_rsp.ptr = qdf_mem_malloc(MAX_MGMT_MPDU_LEN);
-	if (!link_probe_rsp.ptr) {
-		pe_err("mallloc failed for %u bytes", MAX_MGMT_MPDU_LEN);
-		return QDF_STATUS_E_NOMEM;
-	}
-
-	scan_entry = wlan_cm_get_curr_candidate_entry(session->vdev,
-						      session->cm_id);
-	if (!scan_entry) {
-		pe_err("Curr scan entry NULL");
-		qdf_mem_free(link_probe_rsp.ptr);
-		return QDF_STATUS_E_INVAL;
-	}
-
-	probe_rsp.ptr =
-		util_scan_entry_frame_ptr(scan_entry) + WLAN_MAC_HDR_LEN_3A;
-	probe_rsp.len =
-		util_scan_entry_frame_len(scan_entry) - WLAN_MAC_HDR_LEN_3A;
-
-	qdf_mem_copy(&link_addr, session->self_mac_addr, QDF_MAC_ADDR_SIZE);
-
-	/*
-	 * For each partner entry, check if the corresponding partner link
-	 * is found or not to generate probe resp for the missing link.
-	 */
-	for (idx2 = 0; idx2 < lim_partner_info->num_partner_links; idx2++) {
-		link_info = &lim_partner_info->partner_link_info[idx2];
-		for (idx = 0; idx < scan_entry->ml_info.num_links; idx++) {
-			scan_partner_info = &scan_entry->ml_info.link_info[idx];
-			if (!scan_partner_info->is_scan_entry_not_found)
-				continue;
-
-			if (link_info->link_id != scan_partner_info->link_id)
-				continue;
-
-			link_id = link_info->link_id;
-			link_probe_rsp.len = 0;
-			status = util_gen_link_probe_rsp_from_assoc_rsp(frame,
-									frame_len,
-									link_id,
-									link_addr,
-									link_probe_rsp.ptr,
-									(qdf_size_t)MAX_MGMT_MPDU_LEN,
-									(qdf_size_t *)&link_probe_rsp.len,
-									probe_rsp.ptr,
-									probe_rsp.len);
-
-			if (QDF_IS_STATUS_ERROR(status))
-				goto mem_free;
-
-			status = lim_add_bcn_probe(session->vdev,
-						   link_probe_rsp.ptr,
-						   link_probe_rsp.len,
-						   link_info->chan_freq, rssi);
-			if (QDF_IS_STATUS_ERROR(status)) {
-				pe_debug("Scan entry add failed for %d",
-					 link_id);
-				goto mem_free;
-			}
-		}
-
-		status = lim_update_mlo_mgr_info(mac_ctx,
-						 session->vdev,
-						 &link_info->link_addr,
-						 link_info->link_id,
-						 link_info->chan_freq);
-		if (QDF_IS_STATUS_ERROR(status)) {
-			pe_debug("failed to update mlo_mgr %d for link_id: %d",
-				 status, link_info->link_id);
-			goto mem_free;
-		}
-	}
-
-mem_free:
-	qdf_mem_free(link_probe_rsp.ptr);
-	util_scan_free_cache_entry(scan_entry);
-
-	return status;
-}
-#else /* WLAN_FEATURE_11BE_MLO */
-static inline QDF_STATUS
-lim_gen_link_specific_probe_resp_from_assoc_resp(struct mac_context *mac_ctx,
-						 uint8_t *rx_pkt_info,
-						 uint32_t frame_len,
-						 struct pe_session *session)
-{
-	return QDF_STATUS_SUCCESS;
-}
-#endif /* WLAN_FEATURE_11BE_MLO */
-
 /**
  * lim_process_assoc_rsp_frame() - Processes assoc response
  * @mac_ctx: Pointer to Global MAC structure
@@ -1880,27 +1751,6 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 #endif
 	lim_update_stads_ext_cap(mac_ctx, session_entry, assoc_rsp, sta_ds);
 
-	/* Try to generate link probe resp from assoc resp for MBSSID AP
-	 * as ML probe is not sent for MBSSID AP.
-	 *
-	 * Any failure during partner link probe resp generation, treat
-	 * it as connect failure and send deauth to AP.
-	 */
-	status = lim_gen_link_specific_probe_resp_from_assoc_resp(mac_ctx,
-								  rx_pkt_info,
-								  frame_body_len,
-								  session_entry);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
-		assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
-		/* Send advisory Disassociation frame to AP */
-		lim_send_disassoc_mgmt_frame(mac_ctx,
-					     REASON_UNSPEC_FAILURE,
-					     hdr->sa, session_entry,
-					     false);
-		goto assocReject;
-	}
-
 	/* Update the BSS Entry, this entry was added during preassoc. */
 	if (QDF_STATUS_SUCCESS ==
 	    lim_sta_send_add_bss(mac_ctx, assoc_rsp, beacon,

+ 10 - 5
core/mac/src/pe/lim/lim_process_deauth_frame.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -162,10 +162,6 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
 			pe_session->limSmeState,
 			GET_LIM_SYSTEM_ROLE(pe_session));
 
-	wlan_connectivity_mgmt_event(mac->psoc, (struct wlan_frame_hdr *)pHdr,
-				     pe_session->vdev_id, reasonCode,
-				     0, frame_rssi, 0, 0, 0, 0,
-				     WLAN_DEAUTH_RX);
 	lim_diag_event_report(mac, WLAN_PE_DIAG_DEAUTH_FRAME_EVENT,
 		pe_session, 0, reasonCode);
 
@@ -173,6 +169,10 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
 		pe_debug("Ignore the Deauth received, while waiting for ack of "
 			"disassoc/deauth");
 		lim_clean_up_disassoc_deauth_req(mac, (uint8_t *) pHdr->sa, 1);
+		wlan_connectivity_mgmt_event(mac->psoc, (struct wlan_frame_hdr *)pHdr,
+					     pe_session->vdev_id, reasonCode,
+					     0, frame_rssi, 0, 0, 0, 0,
+					     WLAN_DEAUTH_RX);
 		return;
 	}
 
@@ -314,6 +314,11 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
 
 	lim_extract_ies_from_deauth_disassoc(pe_session, (uint8_t *)pHdr,
 					WMA_GET_RX_MPDU_LEN(pRxPacketInfo));
+	wlan_connectivity_mgmt_event(mac->psoc, (struct wlan_frame_hdr *)pHdr,
+				     pe_session->vdev_id, reasonCode,
+				     0, frame_rssi, 0, 0, 0, 0,
+				     WLAN_DEAUTH_RX);
+
 	lim_perform_deauth(mac, pe_session, reasonCode, pHdr->sa,
 			   frame_rssi);
 

+ 6 - 5
core/mac/src/pe/lim/lim_process_disassoc_frame.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -159,10 +159,6 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
 			reasonCode, pe_session->limMlmState,
 			pe_session->limSmeState,
 			GET_LIM_SYSTEM_ROLE(pe_session));
-	wlan_connectivity_mgmt_event(mac->psoc, (struct wlan_frame_hdr *)pHdr,
-				     pe_session->vdev_id, reasonCode,
-				     0, frame_rssi, 0, 0, 0, 0,
-				     WLAN_DISASSOC_RX);
 	lim_diag_event_report(mac, WLAN_PE_DIAG_DISASSOC_FRAME_EVENT,
 		pe_session, 0, reasonCode);
 
@@ -328,6 +324,11 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
 	}
 	lim_extract_ies_from_deauth_disassoc(pe_session, (uint8_t *)pHdr,
 					WMA_GET_RX_MPDU_LEN(pRxPacketInfo));
+	wlan_connectivity_mgmt_event(mac->psoc, (struct wlan_frame_hdr *)pHdr,
+				     pe_session->vdev_id, reasonCode,
+				     0, frame_rssi, 0, 0, 0, 0,
+				     WLAN_DISASSOC_RX);
+
 	lim_perform_disassoc(mac, frame_rssi, reasonCode,
 			     pe_session, pHdr->sa);
 

+ 6 - 4
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -5690,7 +5690,11 @@ lim_update_ext_tpe_power(struct mac_context *mac, struct pe_session *session,
 		}
 
 		total_psd_power = existing_pwr_count + ext_psd_count;
-
+		if (total_psd_power > MAX_NUM_PWR_LEVEL) {
+			pe_debug("total powers greater than max %d",
+				 MAX_NUM_PWR_LEVEL);
+			return existing_pwr_count;
+		}
 		i = existing_pwr_count;
 		for (j = 0; j < ext_psd_count && i < total_psd_power; j++)
 		{
@@ -6327,11 +6331,9 @@ void lim_calculate_tpc(struct mac_context *mac,
 			} else {
 				max_tx_power = QDF_MIN(reg_max,
 						       local_constraint);
-				if (!max_tx_power)
-					max_tx_power = reg_max;
 			}
 		} else {
-			max_tx_power = QDF_MIN(reg_max, local_constraint);
+			max_tx_power = reg_max - local_constraint;
 			if (!max_tx_power)
 				max_tx_power = reg_max;
 		}

+ 35 - 35
core/mac/src/pe/lim/lim_process_tdls.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -552,6 +552,7 @@ static uint32_t lim_prepare_tdls_frame_header(struct mac_context *mac, uint8_t *
 	/* add payload type as TDLS */
 	*(pFrame + header_offset) = PAYLOAD_TYPE_TDLS;
 	header_offset += PAYLOAD_TYPE_TDLS_SIZE;
+
 	return header_offset;
 }
 
@@ -572,10 +573,8 @@ static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context, qdf_nbuf_t buf,
 	struct mac_context *mac_ctx = (struct mac_context *)context;
 	struct tdls_ethernet_hdr *ethernet_hdr;
 	tpSirMacActionFrameHdr action_hdr;
-	bool is_tdls_discvory_frm;
+	bool is_tdls_discvory_frm = false;
 
-	pe_debug("tdls_frm_session_id: %x tx_complete: %x",
-		 mac_ctx->lim.tdls_frm_session_id, tx_complete);
 
 	if (NO_SESSION != mac_ctx->lim.tdls_frm_session_id) {
 		if (buf &&
@@ -591,8 +590,6 @@ static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context, qdf_nbuf_t buf,
 				eth_890d_tdls_discvory_frm_hdr,
 				sizeof(eth_890d_tdls_discvory_frm_hdr));
 
-			pe_debug("is_tdls_discvory_frm: %d",
-				 is_tdls_discvory_frm);
 			if (is_tdls_discvory_frm &&
 			    tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK)
 				wlan_tdls_increment_discovery_attempts(
@@ -607,6 +604,10 @@ static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context, qdf_nbuf_t buf,
 		mac_ctx->lim.tdls_frm_session_id = NO_SESSION;
 	}
 
+	pe_debug("tdls_frm_session_id: %x tx_complete: %x is_discovery:%d",
+		 mac_ctx->lim.tdls_frm_session_id, tx_complete,
+		 is_tdls_discvory_frm);
+
 	if (buf)
 		qdf_nbuf_free(buf);
 
@@ -2393,15 +2394,20 @@ QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac,
 					&pe_session->dph.dphHashTable);
 	if (sta_ds)
 		qos_mode = sta_ds->qosMode;
-	tdls_link_type = (reason == REASON_TDLS_PEER_UNREACHABLE)
-				? TDLS_LINK_AP : TDLS_LINK_DIRECT;
-	nbytes = payload + (((IS_QOS_ENABLED(pe_session) &&
-			     (tdls_link_type == TDLS_LINK_AP)) ||
-			     ((tdls_link_type == TDLS_LINK_DIRECT) && qos_mode))
-			     ? sizeof(tSirMacDataHdr3a) :
-			     sizeof(tSirMacMgmtHdr))
-		 + sizeof(eth_890d_header)
-		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+	if (reason == REASON_TDLS_PEER_UNREACHABLE)
+		tdls_link_type = TDLS_LINK_AP;
+	else
+		tdls_link_type = TDLS_LINK_DIRECT;
+
+	nbytes = payload + sizeof(eth_890d_header) + PAYLOAD_TYPE_TDLS_SIZE;
+	nbytes += addIeLen;
+
+	if ((IS_QOS_ENABLED(pe_session) && tdls_link_type == TDLS_LINK_AP) ||
+	    (tdls_link_type == TDLS_LINK_DIRECT && qos_mode))
+		nbytes += sizeof(tSirMacDataHdr3a);
+	else
+		nbytes += sizeof(tSirMacMgmtHdr);
 
 #ifndef NO_PAD_TDLS_MIN_8023_SIZE
 	/* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
@@ -2493,12 +2499,11 @@ QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac,
 				    padlen - MIN_VENDOR_SPECIFIC_IE_SIZE);
 	}
 #endif
-	pe_debug("[TDLS] action: %d (%s) -%s-> OTA peer="QDF_MAC_ADDR_FMT,
-		TDLS_TEARDOWN,
-		lim_trace_tdls_action_string(TDLS_TEARDOWN),
-		((reason == REASON_TDLS_PEER_UNREACHABLE) ? "AP" :
-		    "DIRECT"),
-		QDF_MAC_ADDR_REF(peer_mac.bytes));
+	pe_debug("[TDLS] vdev:%d action: %d (%s) -%s-> OTA peer="QDF_MAC_ADDR_FMT,
+		 pe_session->vdev_id, TDLS_TEARDOWN,
+		 lim_trace_tdls_action_string(TDLS_TEARDOWN),
+		 ((reason == REASON_TDLS_PEER_UNREACHABLE) ? "AP" : "DIRECT"),
+		 QDF_MAC_ADDR_REF(peer_mac.bytes));
 
 	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
 
@@ -2510,9 +2515,7 @@ QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac,
 
 	qdf_status = wma_tx_frame_with_tx_complete_send(mac, packet,
 					(uint16_t)nbytes,
-					TID_AC_VI,
-					frame,
-					vdev_id,
+					TID_AC_VI, frame, vdev_id,
 					(reason == REASON_TDLS_PEER_UNREACHABLE)
 					? true : false);
 
@@ -2535,8 +2538,7 @@ lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
 			      uint8_t dialog,
 			      struct pe_session *pe_session,
 			      etdlsLinkSetupStatus setupStatus,
-			      uint8_t *addIe,
-			      uint16_t addIeLen,
+			      uint8_t *addIe, uint16_t addIeLen,
 			      enum wifi_traffic_ac ac)
 {
 	tDot11fTDLSSetupRsp *setup_rsp;
@@ -2758,10 +2760,9 @@ lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
 			pe_session);
 
 	pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x",
-		setup_rsp->VHTCaps.supportedChannelWidthSet,
-		setup_rsp->VHTCaps.rxMCSMap,
-		setup_rsp->VHTCaps.txMCSMap,
-		setup_rsp->VHTCaps.txSupDataRate);
+		 setup_rsp->VHTCaps.supportedChannelWidthSet,
+		 setup_rsp->VHTCaps.rxMCSMap, setup_rsp->VHTCaps.txMCSMap,
+		 setup_rsp->VHTCaps.txSupDataRate);
 	status = dot11f_pack_tdls_setup_rsp(mac, setup_rsp,
 					    pFrame + header_offset,
 					    nPayload, &nPayload);
@@ -2803,7 +2804,6 @@ lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
 		qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len,
 						      pFrame + header_offset +
 						      nPayload);
-
 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
 			pe_debug("assemble ml ie error");
 			mlo_ie_len = 0;
@@ -2812,10 +2812,10 @@ lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
 		nPayload += mlo_ie_len;
 	}
 
-	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT,
-		TDLS_SETUP_RESPONSE,
-		lim_trace_tdls_action_string(TDLS_SETUP_RESPONSE),
-		QDF_MAC_ADDR_REF(peer_mac.bytes));
+	pe_debug("[TDLS] vdev:%d action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT,
+		 pe_session->vdev_id, TDLS_SETUP_RESPONSE,
+		 lim_trace_tdls_action_string(TDLS_SETUP_RESPONSE),
+		 QDF_MAC_ADDR_REF(peer_mac.bytes));
 
 	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
 	vdev_id = lim_get_assoc_link_vdev_id(pe_session);

+ 6 - 3
core/sap/src/sap_api_link_cntl.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -308,7 +308,9 @@ wlansap_filter_unsafe_ch(struct wlan_objmgr_psoc *psoc,
 	 */
 	for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
 		freq = sap_ctx->acs_cfg->freq_list[i];
-		if (!policy_mgr_is_sap_freq_allowed(psoc, freq)) {
+		if (!policy_mgr_is_sap_freq_allowed(psoc,
+				wlan_vdev_mlme_get_opmode(sap_ctx->vdev),
+				freq)) {
 			sap_debug("remove freq %d from acs list", freq);
 			continue;
 		}
@@ -1714,7 +1716,8 @@ void wlansap_process_chan_info_event(struct sap_context *sap_ctx,
 		goto exit;
 
 	if (!policy_mgr_is_sap_freq_allowed(mac->psoc,
-					    roam_info->chan_info_freq))
+				wlan_vdev_mlme_get_opmode(sap_ctx->vdev),
+				roam_info->chan_info_freq))
 		goto exit;
 	if (sap_ctx->acs_cfg->ch_width > CH_WIDTH_20MHZ) {
 		sap_mark_freq_as_clean(sap_ctx->clean_channel_array,

+ 3 - 2
core/sap/src/sap_ch_select.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -488,7 +488,8 @@ static bool sap_chan_sel_init(struct mac_context *mac,
 			}
 		}
 
-		if (!policy_mgr_is_sap_freq_allowed(mac->psoc, *ch_list)) {
+		if (!policy_mgr_is_sap_freq_allowed(mac->psoc,
+			wlan_vdev_mlme_get_opmode(sap_ctx->vdev), *ch_list)) {
 			if (sap_acs_is_puncture_applicable(sap_ctx->acs_cfg)) {
 				sap_info("freq %d is not allowed, can be punctured",
 					 *ch_list);

+ 10 - 5
core/sap/src/sap_fsm.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -1143,6 +1143,7 @@ sap_validate_chan(struct sap_context *sap_context,
 	struct ch_params ch_params = {0};
 	bool is_go_scc_strict = false;
 	bool start_sap_on_provided_freq = false;
+	enum QDF_OPMODE opmode = QDF_SAP_MODE;
 
 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
 	mac_ctx = MAC_CONTEXT(mac_handle);
@@ -1165,8 +1166,10 @@ sap_validate_chan(struct sap_context *sap_context,
 		return QDF_STATUS_SUCCESS;
 	}
 
-	if (sap_context->vdev &&
-	    sap_context->vdev->vdev_mlme.vdev_opmode == QDF_P2P_GO_MODE) {
+	if (sap_context->vdev)
+		opmode = wlan_vdev_mlme_get_opmode(sap_context->vdev);
+
+	if (opmode == QDF_P2P_GO_MODE) {
 	       /*
 		* check whether go_force_scc is enabled or not.
 		* If it not enabled then don't any force scc on existing go and
@@ -1293,7 +1296,7 @@ validation_done:
 
 	if ((sap_context->acs_cfg->acs_mode ||
 	     policy_mgr_restrict_sap_on_unsafe_chan(mac_ctx->psoc)) &&
-	    !policy_mgr_is_sap_freq_allowed(mac_ctx->psoc,
+	    !policy_mgr_is_sap_freq_allowed(mac_ctx->psoc, opmode,
 					    sap_context->chan_freq)) {
 		sap_warn("Abort SAP start due to unsafe channel");
 		return QDF_STATUS_E_ABORTED;
@@ -3730,7 +3733,9 @@ bool wlansap_validate_channel_post_csa(mac_handle_t mac_handle,
 	     (!policy_mgr_restrict_sap_on_unsafe_chan(mac_ctx->psoc) ||
 	      target_psoc_get_sap_coex_fixed_chan_cap(
 		      wlan_psoc_get_tgt_if_handle(mac_ctx->psoc)))) ||
-	    (policy_mgr_is_sap_freq_allowed(mac_ctx->psoc, sap_ctx->chan_freq) &&
+	    (policy_mgr_is_sap_freq_allowed(mac_ctx->psoc,
+				wlan_vdev_mlme_get_opmode(sap_ctx->vdev),
+				sap_ctx->chan_freq) &&
 	     !wlan_reg_is_disable_for_pwrmode(mac_ctx->pdev, sap_ctx->chan_freq,
 					      REG_CURRENT_PWR_MODE)))
 		return true;

+ 2 - 1
core/sap/src/sap_internal.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -235,6 +235,7 @@ struct sap_context {
 	qdf_list_t ft_pending_assoc_ind_list;
 	qdf_event_t ft_pending_event;
 	uint32_t freq_before_ch_switch;
+	struct ch_params ch_params_before_ch_switch;
 #ifdef WLAN_FEATURE_P2P_P2P_STA
 /*
  *This param is used for GO+GO force scc logic where after

+ 44 - 43
core/sap/src/sap_module.c

@@ -655,9 +655,6 @@ enum phy_ch_width wlan_sap_get_concurrent_bw(struct wlan_objmgr_pdev *pdev,
 		  sta_sap_scc_on_dfs_chnl,
 		  is_hw_dbs_capable, sta_count, scc_sta_present);
 
-	if (!is_hw_dbs_capable)
-		goto dfs_master_mode_check;
-
 	/*
 	 * In indoor concurrency cases, limit the channel width with the STA
 	 * interface bandwidth. Since, only the bonded channels are active
@@ -667,12 +664,8 @@ enum phy_ch_width wlan_sap_get_concurrent_bw(struct wlan_objmgr_pdev *pdev,
 		channel_width = QDF_MIN(sta_chan_width, channel_width);
 		sap_debug("STA + SAP on indoor channels");
 		return channel_width;
-	} else if (is_con_chan_dfs) {
-		channel_width = QDF_MIN(sta_chan_width, channel_width);
-		sap_debug("STA + SAP on dfs channels");
-		goto dfs_master_mode_check;
-	} else {
-		/* Handle "DBS + active channel" concurrency/standalone SAP */
+	} else if (!is_con_chan_dfs) {
+		/* Handle "Active channel" concurrency/standalone SAP */
 		sap_debug("STA + SAP/GO or standalone SAP on active channel");
 		if (scc_sta_present)
 			return  QDF_MAX(sta_chan_width, CH_WIDTH_80MHZ);
@@ -681,39 +674,43 @@ enum phy_ch_width wlan_sap_get_concurrent_bw(struct wlan_objmgr_pdev *pdev,
 		return channel_width;
 	}
 
-dfs_master_mode_check:
 	/* Handle "DBS/non-DBS + dfs channels" concurrency */
-	if (sta_sap_scc_on_dfs_chnl == PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX) {
-		if (scc_sta_present) {
-			sap_debug("STA+SAP/GO: limit the SAP channel width");
-			return QDF_MIN(sta_chan_width, channel_width);
-		}
+	if (is_con_chan_dfs) {
+		switch (sta_sap_scc_on_dfs_chnl) {
+		case PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX:
+			if (scc_sta_present) {
+				sap_debug("STA+SAP/GO: limit the SAP channel width");
+				return QDF_MIN(sta_chan_width, channel_width);
+			}
 
-		sap_debug("Standalone SAP/GO: set BW coming in start req");
-		return channel_width;
-	} else if (sta_sap_scc_on_dfs_chnl ==
-		   PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED) {
-		if (scc_sta_present) {
-			sap_debug("STA present: Limit the SAP channel width");
-			channel_width = QDF_MIN(sta_chan_width, channel_width);
+			sap_debug("Standalone SAP/GO: set BW coming in start req");
 			return channel_width;
+		case PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED:
+			if (scc_sta_present) {
+				sap_debug("STA present: Limit the SAP channel width");
+				channel_width = QDF_MIN(sta_chan_width,
+							channel_width);
+				return channel_width;
+			}
+			/*
+			 * sta_sap_scc_on_dfs_chnl = 1, DFS master is disabled.
+			 * If STA not present (SAP single), the SAP (160Mhz) is
+			 * not allowed on DFS, so limit SAP to 80Mhz.
+			 */
+			sap_debug("Limit Standalone SAP/GO to 80Mhz");
+			return QDF_MIN(channel_width, CH_WIDTH_80MHZ);
+		case PM_STA_SAP_ON_DFS_DEFAULT:
+		default:
+			/*
+			 * sta_sap_scc_on_dfs_chnl = 0, not allow STA+SAP SCC on DFS.
+			 * Limit SAP to 80Mhz if STA present.
+			 */
+			if (sta_count) {
+				sap_debug("STA present, Limit SAP/GO to 80Mhz");
+				return QDF_MIN(channel_width, CH_WIDTH_80MHZ);
+			}
+			break;
 		}
-		/*
-		 * sta_sap_scc_on_dfs_chnl = 1, DFS master is disabled.
-		 * If STA not present (SAP single), the SAP (160Mhz) is
-		 * not allowed on DFS, so limit SAP to 80Mhz.
-		 */
-		sap_debug("Limit Standalone SAP/GO to 80Mhz");
-		return QDF_MIN(channel_width, CH_WIDTH_80MHZ);
-	}
-
-	/*
-	 * sta_sap_scc_on_dfs_chnl = 0, not allow STA+SAP SCC on DFS.
-	 * Limit SAP to 80Mhz if STA present.
-	 */
-	if (sta_count) {
-		sap_debug("STA present, Limit SAP/GO to 80Mhz");
-		return QDF_MIN(channel_width, CH_WIDTH_80MHZ);
 	}
 
 	sap_debug("Single SAP/GO: set BW coming in SAP/GO start req");
@@ -1634,7 +1631,9 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx,
 	if (((sap_ctx->acs_cfg && sap_ctx->acs_cfg->acs_mode) ||
 	     policy_mgr_restrict_sap_on_unsafe_chan(mac->psoc) ||
 	     sap_ctx->csa_reason != CSA_REASON_USER_INITIATED) &&
-	    !policy_mgr_is_sap_freq_allowed(mac->psoc, target_chan_freq)) {
+	    !policy_mgr_is_sap_freq_allowed(mac->psoc,
+			wlan_vdev_mlme_get_opmode(sap_ctx->vdev),
+			target_chan_freq)) {
 		sap_err("%u is unsafe channel freq", target_chan_freq);
 		return QDF_STATUS_E_FAULT;
 	}
@@ -2026,11 +2025,12 @@ QDF_STATUS wlansap_channel_change_request(struct sap_context *sap_ctx,
 	wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, target_chan_freq,
 						0, ch_params,
 						REG_CURRENT_PWR_MODE);
-	sap_ctx->ch_params = *ch_params;
+	sap_ctx->ch_params_before_ch_switch = sap_ctx->ch_params;
 	sap_ctx->freq_before_ch_switch = sap_ctx->chan_freq;
 	/* Update the channel as this will be used to
 	 * send event to supplicant
 	 */
+	sap_ctx->ch_params = *ch_params;
 	sap_ctx->chan_freq = target_chan_freq;
 	wlansap_get_sec_channel(ch_params->sec_ch_offset, sap_ctx->chan_freq,
 				&sap_ctx->sec_ch_freq);
@@ -3348,7 +3348,7 @@ wlansap_select_chan_with_best_bandwidth(struct sap_context *sap_ctx,
 	enum phy_ch_width ch_width;
 	uint32_t center_freq, bw_val, bw_start, bw_end;
 	uint16_t i, j;
-	uint16_t  unsafe_chan[NUM_CHANNELS];
+	uint16_t  unsafe_chan[NUM_CHANNELS] = {0};
 	uint16_t  unsafe_chan_cnt = 0;
 	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
 
@@ -4079,7 +4079,8 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 		*csa_reason = CSA_REASON_CHAN_PASSIVE;
 		return wlansap_get_safe_channel_from_pcl_for_sap(sap_ctx);
 	} else if (!policy_mgr_is_sap_freq_allowed(mac->psoc,
-						   sap_ctx->chan_freq)) {
+			wlan_vdev_mlme_get_opmode(sap_ctx->vdev),
+			sap_ctx->chan_freq)) {
 		sap_debug("channel is unsafe");
 		*csa_reason = CSA_REASON_UNSAFE_CHANNEL;
 		return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx,
@@ -4434,7 +4435,7 @@ void wlansap_get_user_config_acs_ch_list(uint8_t vdev_id,
 		return;
 	}
 
-	if (vdev_id >= WLAN_UMAC_VDEV_ID_MAX)
+	if (vdev_id >= SAP_MAX_NUM_SESSION)
 		return;
 
 	sap_ctx = mac_ctx->sap.sapCtxList[vdev_id].sap_context;

+ 0 - 16
core/sme/inc/sme_api.h

@@ -1957,10 +1957,6 @@ QDF_STATUS sme_reset_tsfcb(mac_handle_t mac_handle);
 QDF_STATUS sme_set_tsf_gpio(mac_handle_t mac_handle, uint32_t pinvalue);
 #endif
 
-QDF_STATUS sme_update_mimo_power_save(mac_handle_t mac_handle,
-				      uint8_t is_ht_smps_enabled,
-				      uint8_t ht_smps_mode,
-				      bool send_smps_action);
 #ifdef WLAN_BCN_RECV_FEATURE
 /**
  * sme_handle_bcn_recv_start() - Enable fw to start sending
@@ -4672,23 +4668,11 @@ enum csr_cfgdot11mode sme_phy_mode_to_dot11mode(enum wlan_phymode phy_mode);
  * Return: Max EHT channel width supported by FW (eg. 80, 160, 320)
  */
 uint32_t sme_get_eht_ch_width(void);
-
-/**
- * sme_is_11be_capable() - Check if 11 be is supported or not
- *
- * Return: True if 11be is supported
- */
-bool sme_is_11be_capable(void);
 #else /* !WLAN_FEATURE_11BE */
 static inline uint32_t sme_get_eht_ch_width(void)
 {
 	return 0;
 }
-
-static inline bool sme_is_11be_capable(void)
-{
-	return false;
-}
 #endif /* WLAN_FEATURE_11BE */
 
 /**

+ 4 - 41
core/sme/src/common/sme_api.c

@@ -12279,37 +12279,6 @@ QDF_STATUS sme_ht40_stop_obss_scan(mac_handle_t mac_handle, uint32_t vdev_id)
 	return QDF_STATUS_SUCCESS;
 }
 
-/**
- * sme_update_mimo_power_save() - Update MIMO power save
- * configuration
- * @mac_handle: The handle returned by macOpen
- * @is_ht_smps_enabled: enable/disable ht smps
- * @ht_smps_mode: smps mode disabled/static/dynamic
- * @send_smps_action: flag to send smps force mode command
- * to FW
- *
- * Return: QDF_STATUS if SME update mimo power save
- * configuration success else failure status
- */
-QDF_STATUS sme_update_mimo_power_save(mac_handle_t mac_handle,
-				      uint8_t is_ht_smps_enabled,
-				      uint8_t ht_smps_mode,
-				      bool send_smps_action)
-{
-	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
-
-	sme_debug("SMPS enable: %d mode: %d send action: %d",
-		is_ht_smps_enabled, ht_smps_mode,
-		send_smps_action);
-	mac_ctx->mlme_cfg->ht_caps.enable_smps =
-		is_ht_smps_enabled;
-	mac_ctx->mlme_cfg->ht_caps.smps = ht_smps_mode;
-	mac_ctx->roam.configParam.send_smps_action =
-		send_smps_action;
-
-	return QDF_STATUS_SUCCESS;
-}
-
 #ifdef WLAN_BCN_RECV_FEATURE
 QDF_STATUS sme_handle_bcn_recv_start(mac_handle_t mac_handle,
 				     uint32_t vdev_id, uint32_t nth_value,
@@ -16752,14 +16721,6 @@ QDF_STATUS sme_switch_channel(mac_handle_t mac_handle,
 }
 
 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
-
-#ifdef WLAN_FEATURE_11BE
-bool sme_is_11be_capable(void)
-{
-	return sme_is_feature_supported_by_fw(DOT11BE);
-}
-#endif
-
 QDF_STATUS sme_send_set_mac_addr(struct qdf_mac_addr mac_addr,
 				 struct qdf_mac_addr mld_addr,
 				 struct wlan_objmgr_vdev *vdev)
@@ -16819,6 +16780,7 @@ QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_vdev *vdev,
 	struct wlan_objmgr_peer *peer;
 	struct vdev_mlme_obj *vdev_mlme;
 	struct wlan_objmgr_psoc *psoc;
+	bool eht_enab = false;
 
 	psoc = wlan_vdev_get_psoc(vdev);
 
@@ -16827,8 +16789,9 @@ QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_vdev *vdev,
 	if (req_status)
 		goto p2p_self_peer_create;
 
+	ucfg_psoc_mlme_get_11be_capab(psoc, &eht_enab);
 	if (vdev_opmode == QDF_STA_MODE && update_sta_self_peer) {
-		if (sme_is_11be_capable() && update_mld_addr) {
+		if (eht_enab && update_mld_addr) {
 			old_macaddr = wlan_vdev_mlme_get_mldaddr(vdev);
 			new_macaddr = mld_addr.bytes;
 		} else {
@@ -16857,7 +16820,7 @@ QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_vdev *vdev,
 	}
 
 	/* Update VDEV MAC address */
-	if (sme_is_11be_capable() && update_mld_addr) {
+	if (eht_enab && update_mld_addr) {
 		if (update_sta_self_peer || vdev_opmode == QDF_SAP_MODE) {
 			qdf_ret_status = wlan_mlo_mgr_update_mld_addr(
 					    (struct qdf_mac_addr *)

+ 2 - 2
core/wma/inc/wma_if.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -57,8 +57,8 @@
 /* Special station id for transmitting broadcast frames. */
 #define STA_ENTRY_BCAST             3
 #define STA_ENTRY_PEER              STA_ENTRY_OTHER
-#ifdef FEATURE_WLAN_TDLS
 #define STA_ENTRY_TDLS_PEER         4
+#ifdef FEATURE_WLAN_TDLS
 #define IS_TDLS_PEER(type) ((type) == STA_ENTRY_TDLS_PEER)
 #else /* !FEATURE_WLAN_TDLS */
 #define IS_TDLS_PEER(type) false

+ 3 - 1
core/wma/inc/wma_tgt_cfg.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -131,6 +131,7 @@ struct wma_tgt_services {
  * @ht_sgi_20: ht sgi 20
  * @ht_sgi_40: ht sgi 40
  * @num_rf_chains: num of rf chains
+ * @dynamic_smps: Dynamic MIMO powersave
  */
 struct wma_tgt_ht_cap {
 	uint32_t mpdu_density;
@@ -140,6 +141,7 @@ struct wma_tgt_ht_cap {
 	bool ht_sgi_20;
 	bool ht_sgi_40;
 	uint32_t num_rf_chains;
+	bool dynamic_smps;
 };
 
 /**

+ 1 - 4
core/wma/src/wma_features.c

@@ -89,7 +89,6 @@
  * MCL platform.
  */
 #define WMA_SET_VDEV_IE_SOURCE_HOST 0x0
-#define CH_WR_IE_MAX_LEN 29
 
 /*
  * Max AMPDU Tx Aggr supported size
@@ -1222,9 +1221,7 @@ wma_parse_ch_switch_wrapper_ie(uint8_t *ch_wr_ie, uint8_t sub_ele_id,
 	struct extn_ie_header *extn_ie;
 
 	ele = (struct ie_header *)ch_wr_ie;
-	if (ele->ie_id != WLAN_ELEMID_CHAN_SWITCH_WRAP ||
-	    ele->ie_len == 0 || ele->ie_len > (CH_WR_IE_MAX_LEN -
-					       sizeof(struct ie_header))) {
+	if (ele->ie_id != WLAN_ELEMID_CHAN_SWITCH_WRAP || ele->ie_len == 0) {
 		wma_debug("Invalid len: %d", ele->ie_len);
 		return NULL;
 	}

+ 10 - 4
core/wma/src/wma_main.c

@@ -5550,16 +5550,18 @@ wma_update_target_ht_cap(struct target_psoc_info *tgt_hdl,
 
 	cfg->ht_sgi_40 = !!(ht_cap_info & WMI_HT_CAP_HT40_SGI);
 
+	cfg->dynamic_smps = !!(ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS);
+
 	/* RF chains */
 	cfg->num_rf_chains = target_if_get_num_rf_chains(tgt_hdl);
 
 	wma_nofl_debug("ht_cap_info - %x ht_rx_stbc - %d, ht_tx_stbc - %d\n"
 		 "mpdu_density - %d ht_rx_ldpc - %d ht_sgi_20 - %d\n"
-		 "ht_sgi_40 - %d num_rf_chains - %d",
+		 "ht_sgi_40 - %d num_rf_chains - %d dynamic_smps - %d",
 		 ht_cap_info,
 		 cfg->ht_rx_stbc, cfg->ht_tx_stbc, cfg->mpdu_density,
 		 cfg->ht_rx_ldpc, cfg->ht_sgi_20, cfg->ht_sgi_40,
-		 cfg->num_rf_chains);
+		 cfg->num_rf_chains, cfg->dynamic_smps);
 
 }
 
@@ -5694,6 +5696,7 @@ static void wma_derive_ext_ht_cap(
 		ht_cap->ht_rx_ldpc = (!!(value & WMI_HT_CAP_RX_LDPC));
 		ht_cap->ht_sgi_20 = (!!(value & WMI_HT_CAP_HT20_SGI));
 		ht_cap->ht_sgi_40 = (!!(value & WMI_HT_CAP_HT40_SGI));
+		ht_cap->dynamic_smps = (!!(value & WMI_HT_CAP_DYNAMIC_SMPS));
 		ht_cap->num_rf_chains =
 			QDF_MAX(wma_get_num_of_setbits_from_bitmask(tx_chain),
 				wma_get_num_of_setbits_from_bitmask(rx_chain));
@@ -5710,6 +5713,9 @@ static void wma_derive_ext_ht_cap(
 					(!!(value & WMI_HT_CAP_HT20_SGI)));
 		ht_cap->ht_sgi_40 = QDF_MIN(ht_cap->ht_sgi_40,
 					(!!(value & WMI_HT_CAP_HT40_SGI)));
+		ht_cap->dynamic_smps = QDF_MIN(ht_cap->dynamic_smps,
+					(!!(value & WMI_HT_CAP_DYNAMIC_SMPS)));
+
 		ht_cap->num_rf_chains =
 			QDF_MAX(ht_cap->num_rf_chains,
 				QDF_MAX(wma_get_num_of_setbits_from_bitmask(
@@ -5781,11 +5787,11 @@ static void wma_update_target_ext_ht_cap(struct target_psoc_info *tgt_hdl,
 
 	wma_nofl_debug("[ext ht cap] ht_rx_stbc - %d, ht_tx_stbc - %d\n"
 			"mpdu_density - %d ht_rx_ldpc - %d ht_sgi_20 - %d\n"
-			"ht_sgi_40 - %d num_rf_chains - %d",
+			"ht_sgi_40 - %d num_rf_chains - %d dynamic_smps - %d",
 			ht_cap->ht_rx_stbc, ht_cap->ht_tx_stbc,
 			ht_cap->mpdu_density, ht_cap->ht_rx_ldpc,
 			ht_cap->ht_sgi_20, ht_cap->ht_sgi_40,
-			ht_cap->num_rf_chains);
+			ht_cap->num_rf_chains, ht_cap->dynamic_smps);
 }
 
 /**

+ 24 - 3
core/wma/src/wma_scan_roam.c

@@ -1,6 +1,6 @@
  /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 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
@@ -91,6 +91,7 @@
 #include "wlan_cm_roam_api.h"
 #include "wlan_mlo_mgr_roam.h"
 #include "lim_mlo.h"
+#include "wlan_dp_api.h"
 #ifdef FEATURE_WLAN_EXTSCAN
 #define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION WAKELOCK_DURATION_RECOMMENDED
 
@@ -3147,15 +3148,35 @@ QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma,
 }
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-void cm_roam_update_vdev(struct roam_offload_synch_ind *sync_ind,
-			 uint8_t vdev_id)
+void cm_roam_update_vdev(struct wlan_objmgr_vdev *vdev,
+			 struct roam_offload_synch_ind *sync_ind)
 {
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct qdf_mac_addr *self_mac_addr;
+	uint8_t vdev_id;
 
 	if (!wma)
 		return;
 
+	vdev_id = wlan_vdev_get_id(vdev);
+
 	wma_roam_update_vdev(wma, sync_ind, vdev_id);
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		self_mac_addr =
+			(struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev);
+		goto update_deflink;
+	}
+
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
+	    wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+		return;
+
+	self_mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
+
+update_deflink:
+	/* Set the assoc vdev as DP deflink after roaming */
+	wlan_dp_update_def_link(wma->psoc, self_mac_addr, vdev);
 }
 
 QDF_STATUS