Bläddra i källkod

Merge 6b9996a66cd167725a1e69e50c034bada3b0a713 on remote branch

Change-Id: I2f03775ca4cd1a9c391dedbbcd6a1a0352f19c27
Linux Build Service Account 1 år sedan
förälder
incheckning
0e18112920
91 ändrade filer med 3450 tillägg och 635 borttagningar
  1. 2 1
      Android.mk
  2. 5 1
      Kbuild
  3. 3 0
      components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c
  4. 2 4
      components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ll_sap.h
  5. 8 2
      components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h
  6. 64 48
      components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c
  7. 27 3
      components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c
  8. 5 14
      components/cmn_services/policy_mgr/src/wlan_policy_mgr_ll_sap.c
  9. 6 1
      components/coex/dispatcher/src/wlan_coex_ucfg_api.c
  10. 2 0
      components/dp/core/src/wlan_dp_main.c
  11. 4 1
      components/dp/core/src/wlan_dp_txrx.c
  12. 2 0
      components/mlme/core/inc/wlan_mlme_main.h
  13. 38 7
      components/mlme/core/src/wlan_mlme_main.c
  14. 10 12
      components/mlme/dispatcher/inc/wlan_mlme_api.h
  15. 5 4
      components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
  16. 45 0
      components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
  17. 14 0
      components/mlme/dispatcher/src/wlan_mlme_api.c
  18. 15 1
      components/pkt_capture/core/inc/wlan_pkt_capture_main.h
  19. 45 15
      components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c
  20. 5 18
      components/pkt_capture/core/src/wlan_pkt_capture_main.c
  21. 0 4
      components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c
  22. 5 3
      components/tdls/core/src/wlan_tdls_cmds_process.c
  23. 43 21
      components/tdls/core/src/wlan_tdls_main.c
  24. 21 2
      components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c
  25. 24 1
      components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c
  26. 21 0
      components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c
  27. 1 1
      components/umac/mlme/mlo_mgr/src/wlan_epcs_api.c
  28. 22 0
      components/umac/mlme/mlo_mgr/src/wlan_t2lm_api.c
  29. 966 8
      components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.c
  30. 132 37
      components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.h
  31. 42 6
      components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_main.c
  32. 21 0
      components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_main.h
  33. 13 16
      components/umac/mlme/sap/ll_sap/core/src/wlan_ll_sap_main.c
  34. 19 6
      components/umac/mlme/sap/ll_sap/core/src/wlan_ll_sap_main.h
  35. 72 4
      components/umac/mlme/sap/ll_sap/dispatcher/inc/wlan_ll_sap_api.h
  36. 91 25
      components/umac/mlme/sap/ll_sap/dispatcher/inc/wlan_ll_sap_public_structs.h
  37. 53 3
      components/umac/mlme/sap/ll_sap/dispatcher/inc/wlan_ll_sap_ucfg_api.h
  38. 133 2
      components/umac/mlme/sap/ll_sap/dispatcher/src/wlan_ll_sap_api.c
  39. 22 3
      components/umac/mlme/sap/ll_sap/dispatcher/src/wlan_ll_sap_ucfg_api.c
  40. 4 0
      configs/config_to_feature.h
  41. 4 0
      configs/peach_defconfig
  42. 1 0
      configs/sun_consolidate_kiwi-v2_defconfig
  43. 9 1
      configs/sun_gki_kiwi-v2_defconfig
  44. 10 1
      configs/sun_gki_peach_defconfig
  45. 2 2
      core/hdd/inc/wlan_hdd_cfg.h
  46. 6 0
      core/hdd/inc/wlan_hdd_driver_ops.h
  47. 0 12
      core/hdd/inc/wlan_hdd_ll_lt_sap.h
  48. 13 0
      core/hdd/inc/wlan_hdd_power.h
  49. 22 29
      core/hdd/src/wlan_hdd_cfg.c
  50. 88 12
      core/hdd/src/wlan_hdd_cfg80211.c
  51. 3 4
      core/hdd/src/wlan_hdd_cfg80211.h
  52. 35 5
      core/hdd/src/wlan_hdd_cm_disconnect.c
  53. 26 6
      core/hdd/src/wlan_hdd_driver_ops.c
  54. 42 67
      core/hdd/src/wlan_hdd_ll_lt_sap.c
  55. 43 5
      core/hdd/src/wlan_hdd_main.c
  56. 20 11
      core/hdd/src/wlan_hdd_power.c
  57. 3 0
      core/hdd/src/wlan_hdd_scan.c
  58. 2 2
      core/hdd/src/wlan_hdd_son.c
  59. 5 1
      core/hdd/src/wlan_hdd_stats.c
  60. 3 3
      core/mac/inc/qwlan_version.h
  61. 9 0
      core/mac/src/pe/lim/lim_mlo.c
  62. 7 3
      core/mac/src/pe/lim/lim_process_action_frame.c
  63. 10 0
      core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
  64. 5 0
      core/mac/src/pe/lim/lim_process_beacon_frame.c
  65. 15 13
      core/mac/src/pe/lim/lim_process_sme_req_messages.c
  66. 9 15
      core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
  67. 44 47
      core/mac/src/pe/lim/lim_utils.c
  68. 13 30
      core/mac/src/pe/lim/lim_utils.h
  69. 19 1
      core/mac/src/pe/sch/sch_beacon_gen.c
  70. 2 0
      core/mac/src/pe/sch/sch_beacon_process.c
  71. 2 2
      core/mac/src/sys/legacy/src/system/src/mac_init_api.c
  72. 391 13
      core/mac/src/sys/legacy/src/utils/src/parser_api.c
  73. 1 0
      core/sap/inc/sap_api.h
  74. 4 1
      core/sap/src/sap_api_link_cntl.c
  75. 23 0
      core/sap/src/sap_fsm.c
  76. 10 1
      core/sap/src/sap_module.c
  77. 11 0
      core/sme/inc/csr_internal.h
  78. 9 0
      core/sme/inc/sme_api.h
  79. 34 22
      core/sme/src/common/sme_api.c
  80. 53 9
      core/sme/src/csr/csr_api_roam.c
  81. 21 0
      core/wma/inc/wma.h
  82. 10 10
      core/wma/src/wma_dev_if.c
  83. 13 0
      core/wma/src/wma_eht.c
  84. 8 0
      core/wma/src/wma_eht.h
  85. 25 21
      core/wma/src/wma_main.c
  86. 6 6
      core/wma/src/wma_scan_roam.c
  87. 25 5
      core/wma/src/wma_utils.c
  88. 96 0
      os_if/mlme/sap/ll_sap/inc/os_if_ll_sap.h
  89. 214 0
      os_if/mlme/sap/ll_sap/src/os_if_ll_sap.c
  90. 1 1
      os_if/pkt_capture/src/os_if_pkt_capture.c
  91. 11 0
      wlan_qcacld3_modules.bzl

+ 2 - 1
Android.mk

@@ -32,6 +32,7 @@ endif
 
 LOCAL_PATH := $(call my-dir)
 $(call wlog,LOCAL_PATH=$(LOCAL_PATH))
+BOARD_OPENSOURCE_DIR ?= vendor/qcom/opensource
 
 ENABLE_QCACLD := true
 ifeq ($(TARGET_USES_QMAA), true)
@@ -66,7 +67,7 @@ ifneq ($(WLAN_CHIPSET),)
 ifneq ($(findstring vendor,$(LOCAL_PATH)),)
 
 ifneq ($(findstring opensource,$(LOCAL_PATH)),)
-	WLAN_BLD_DIR := vendor/qcom/opensource/wlan
+	WLAN_BLD_DIR := $(BOARD_OPENSOURCE_DIR)/wlan
 endif # opensource
 
 # Multi-ko check

+ 5 - 1
Kbuild

@@ -1636,8 +1636,10 @@ MLME_OBJS += $(WFA_TGT_IF_DIR)/src/target_if_wfa_testcmd.o \
 
 ####### LL_SAP #######
 LL_SAP_DIR := components/umac/mlme/sap/ll_sap
+LL_SAP_OS_IF_DIR := os_if/mlme/sap/ll_sap
 
 LL_SAP_INC := -I$(WLAN_ROOT)/$(LL_SAP_DIR)/dispatcher/inc \
+		-I$(WLAN_ROOT)/$(LL_SAP_OS_IF_DIR)/inc
 
 MLME_INC += $(LL_SAP_INC)
 
@@ -1646,7 +1648,8 @@ MLME_OBJS += $(LL_SAP_DIR)/dispatcher/src/wlan_ll_sap_ucfg_api.o \
 		$(LL_SAP_DIR)/dispatcher/src/wlan_ll_sap_api.o \
 		$(LL_SAP_DIR)/core/src/wlan_ll_sap_main.o \
 		$(LL_SAP_DIR)/core/src/wlan_ll_lt_sap_main.o \
-		$(LL_SAP_DIR)/core/src/wlan_ll_lt_sap_bearer_switch.o
+		$(LL_SAP_DIR)/core/src/wlan_ll_lt_sap_bearer_switch.o \
+		$(LL_SAP_OS_IF_DIR)/src/os_if_ll_sap.o
 endif
 
 $(call add-wlan-objs,mlme,$(MLME_OBJS))
@@ -4204,6 +4207,7 @@ ccflags-$(CONFIG_DP_RX_UDP_OVER_PEER_ROAM) += -DDP_RX_UDP_OVER_PEER_ROAM
 cppflags-$(CONFIG_WLAN_BOOST_CPU_FREQ_IN_ROAM) += -DWLAN_BOOST_CPU_FREQ_IN_ROAM
 
 ccflags-$(CONFIG_QCA_WIFI_EMULATION) += -DQCA_WIFI_EMULATION
+ccflags-$(CONFIG_SAP_MULTI_LINK_EMULATION) += -DSAP_MULTI_LINK_EMULATION
 ccflags-$(CONFIG_SHADOW_V2) += -DCONFIG_SHADOW_V2
 ccflags-$(CONFIG_SHADOW_V3) += -DCONFIG_SHADOW_V3
 ccflags-$(CONFIG_QCA6290_HEADERS_DEF) += -DQCA6290_HEADERS_DEF

+ 3 - 0
components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c

@@ -39,6 +39,7 @@
 #include "wlan_vdev_mgr_utils_api.h"
 #include "wlan_tdls_api.h"
 #include "wlan_mlo_mgr_link_switch.h"
+#include "wlan_ll_sap_api.h"
 
 QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev,
 				struct if_mgr_event_data *event_data)
@@ -189,6 +190,8 @@ QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev,
 		policy_mgr_check_concurrent_intf_and_restart_sap(psoc,
 				wlan_util_vdev_mgr_get_acs_mode_for_vdev(vdev));
 
+	wlan_ll_sap_switch_bearer_on_sta_connect_complete(psoc, vdev_id);
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 2 - 4
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ll_sap.h

@@ -30,8 +30,6 @@
  * caller has to invoke the wlan_objmgr_vdev_release_ref() to decrement
  * ref count
  *
- * Return: vdev pointer
- *         NULL on FAILURE
+ * Return: vdev id
  */
-struct wlan_objmgr_vdev *
-wlan_policy_mgr_get_ll_lt_sap_vdev(struct wlan_objmgr_psoc *psoc);
+uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev(struct wlan_objmgr_psoc *psoc);

+ 8 - 2
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h

@@ -1213,6 +1213,8 @@ enum policy_mgr_band {
 
 /**
  * enum policy_mgr_conn_update_reason: Reason for conc connection update
+ * @POLICY_MGR_UPDATE_REASON_TIMER_START: This is to decide whether to start the
+ *                                        timer or not
  * @POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN: Set probable operating channel
  * @POLICY_MGR_UPDATE_REASON_START_AP: Start AP
  * @POLICY_MGR_UPDATE_REASON_NORMAL_STA: Connection to Normal STA
@@ -1231,8 +1233,11 @@ enum policy_mgr_band {
  * @POLICY_MGR_UPDATE_REASON_LFR2_ROAM: LFR2 Roaming
  * @POLICY_MGR_UPDATE_REASON_STA_CONNECT: STA/CLI connection to peer
  * @POLICY_MGR_UPDATE_REASON_LFR3_ROAM: LFR3 Roaming
+ * @POLICY_MGR_UPDATE_REASON_MAX: Reason code to indicate that it's not a
+ * valid operation, should always be maintained at the end of enum.
  */
 enum policy_mgr_conn_update_reason {
+	POLICY_MGR_UPDATE_REASON_TIMER_START,
 	POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN,
 	POLICY_MGR_UPDATE_REASON_START_AP,
 	POLICY_MGR_UPDATE_REASON_NORMAL_STA,
@@ -1248,6 +1253,7 @@ enum policy_mgr_conn_update_reason {
 	POLICY_MGR_UPDATE_REASON_LFR2_ROAM,
 	POLICY_MGR_UPDATE_REASON_STA_CONNECT,
 	POLICY_MGR_UPDATE_REASON_LFR3_ROAM,
+	POLICY_MGR_UPDATE_REASON_MAX,
 };
 
 /**
@@ -1566,8 +1572,8 @@ struct policy_mgr_freq_range {
  * @MODE_SBS_UPPER_SHARE:   Higher 5Ghz shared with 2.4Ghz
  * @MODE_SBS_LOWER_SHARE:   LOWER 5Ghz shared with 2.4Ghz
  * @MODE_EMLSR:             eMLSR mode
- * @MODE_EMLSR_SINGLE:	    eMLSR split mode
- * @MODE_EMLSR_SPLIT:	    eMLSR split mode
+ * @MODE_EMLSR_SINGLE:      eMLSR single mode
+ * @MODE_EMLSR_SPLIT:       eMLSR split mode
  * @MODE_HW_MAX: MAX
  */
 enum policy_mgr_mode {

+ 64 - 48
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -140,13 +140,15 @@ QDF_STATUS policy_mgr_check_n_start_opportunistic_timer(
 {
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	enum policy_mgr_conn_update_reason reason =
+				POLICY_MGR_UPDATE_REASON_TIMER_START;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
 		policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start");
 		return QDF_STATUS_E_FAILURE;
 	}
-	if (policy_mgr_need_opportunistic_upgrade(psoc, NULL)) {
+	if (policy_mgr_need_opportunistic_upgrade(psoc, &reason)) {
 	/* let's start the timer */
 	qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
 	status = qdf_mc_timer_start(
@@ -243,11 +245,47 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * policy_mgr_get_sap_bw() - get current SAP bandwidth
+ * @psoc: Pointer to psoc
+ * @bw: Buffer to update the bandwidth
+ *
+ * Get the current SAP bandwidth. This API supports only single SAP
+ * concurrencies and doesn't cover multi SAP(e.g. SAP+SAP).
+ *
+ * return : QDF_STATUS
+ */
+static QDF_STATUS
+policy_mgr_get_sap_bw(struct wlan_objmgr_psoc *psoc, enum phy_ch_width *bw)
+{
+	uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
+	struct wlan_objmgr_vdev *vdev;
+
+	if (policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0],
+						   &vdev_id_list[0],
+						   PM_SAP_MODE) != 1)
+		return QDF_STATUS_E_NOSUPPORT;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id_list[0],
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d is NULL", vdev_id_list[0]);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*bw = wlan_mlme_get_ap_oper_ch_width(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * policy_mgr_get_sap_ch_width_update_action() - get SAP ch_width update action
  * @psoc: Pointer to psoc
  * @ch_freq: channel frequency of new connection
  * @next_action: next action to happen in order to update bandwidth
+ * @reason: Bandwidth upgrade/downgrade reason
  *
  * Check if current operating SAP needs a downgrade to 160MHz or an upgrade
  * to 320MHz based on the new connection.
@@ -257,9 +295,9 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
 static void
 policy_mgr_get_sap_ch_width_update_action(struct wlan_objmgr_psoc *psoc,
 				uint32_t ch_freq,
-				enum policy_mgr_conc_next_action *next_action)
+				enum policy_mgr_conc_next_action *next_action,
+				enum policy_mgr_conn_update_reason *reason)
 {
-	struct wlan_objmgr_vdev *vdev;
 	enum phy_ch_width cur_bw;
 	uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
@@ -268,36 +306,21 @@ policy_mgr_get_sap_ch_width_update_action(struct wlan_objmgr_psoc *psoc,
 	if (QDF_IS_STATUS_ERROR(wlan_psoc_mlme_get_11be_capab(psoc,
 							      &eht_capab)) ||
 	    !eht_capab ||
-	    policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0],
-						   &vdev_id_list[0],
-						   PM_SAP_MODE) != 1)
-		return;
-
-	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id_list[0],
-						    WLAN_POLICY_MGR_ID);
-	if (!vdev) {
-		policy_mgr_err("vdev %d is NULL", vdev_id_list[0]);
-		return;
-	}
-
-	cur_bw = wlan_mlme_get_ap_oper_ch_width(vdev);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
-
-	if (cur_bw < CH_WIDTH_160MHZ)
+	    QDF_IS_STATUS_ERROR(policy_mgr_get_sap_bw(psoc, &cur_bw)) ||
+	    cur_bw < CH_WIDTH_160MHZ)
 		return;
 
-	if (!ch_freq) {
-		if (policy_mgr_get_connection_count(psoc) == 1 ||
-		    (!policy_mgr_is_current_hwmode_dbs(psoc) &&
-		     !policy_mgr_is_current_hwmode_sbs(psoc)))
-			*next_action = PM_UPGRADE_BW;
-		return;
-	}
-
+	policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0],
+					       &vdev_id_list[0], PM_SAP_MODE);
 	if (cur_bw == CH_WIDTH_320MHZ &&
-	    policy_mgr_is_conn_lead_to_dbs_sbs(psoc, ch_freq))
+	    ch_freq && policy_mgr_is_conn_lead_to_dbs_sbs(psoc, ch_freq))
 		*next_action = PM_DOWNGRADE_BW;
-	else
+	else if (cur_bw == CH_WIDTH_160MHZ &&
+		 !ch_freq &&
+		 !policy_mgr_is_conn_lead_to_dbs_sbs(psoc, freq_list[0]) &&
+		 (reason &&
+		  (*reason == POLICY_MGR_UPDATE_REASON_TIMER_START ||
+		   *reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC)))
 		*next_action = PM_UPGRADE_BW;
 }
 
@@ -314,7 +337,8 @@ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 
 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
-		policy_mgr_get_sap_ch_width_update_action(psoc, 0, &upgrade);
+		policy_mgr_get_sap_ch_width_update_action(psoc, 0, &upgrade,
+							  reason);
 		return upgrade;
 	}
 
@@ -929,10 +953,6 @@ policy_mgr_is_conn_lead_to_dbs_sbs(struct wlan_objmgr_psoc *psoc,
 	struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
 	uint32_t connection_count, i;
 
-	if (policy_mgr_is_current_hwmode_dbs(psoc) ||
-	    policy_mgr_is_current_hwmode_sbs(psoc))
-		return true;
-
 	connection_count = policy_mgr_get_connection_info(psoc, info);
 
 	for (i = 0; i < connection_count; i++)
@@ -967,7 +987,7 @@ policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc,
 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
 		*next_action = PM_NOP;
 		policy_mgr_get_sap_ch_width_update_action(psoc, ch_freq,
-							  next_action);
+							  next_action, &reason);
 		return QDF_STATUS_SUCCESS;
 	}
 
@@ -1107,13 +1127,14 @@ policy_mgr_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
 	uint32_t ch_freq = 0;
 	struct scan_cache_entry *entry;
 	bool eht_capab =  false, check_sap_bw_downgrade = false;
+	enum phy_ch_width cur_bw = CH_WIDTH_INVALID;
 
 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
 		wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab);
 		if (eht_capab &&
-		    policy_mgr_mode_specific_connection_count(psoc,
-							      PM_SAP_MODE,
-							      NULL) == 1)
+		    QDF_IS_STATUS_SUCCESS(policy_mgr_get_sap_bw(psoc,
+								&cur_bw)) &&
+						cur_bw == CH_WIDTH_320MHZ)
 			check_sap_bw_downgrade = true;
 		else
 			goto end;
@@ -1160,8 +1181,8 @@ ch_width_update:
 							  vdev_id) ||
 		    policy_mgr_is_ch_width_downgrade_required(psoc, entry,
 							      scan_list)) {
-			policy_mgr_debug("Scan list has BSS of freq %d hw mode/ch_width update required",
-					 ch_freq);
+			policy_mgr_debug("Scan list has BSS of freq %d hw mode/SAP ch_width:%d update required",
+					 ch_freq, cur_bw);
 			break;
 		}
 
@@ -1575,16 +1596,10 @@ QDF_STATUS policy_mgr_next_actions(
 					session_id, request_id);
 		break;
 	case PM_DOWNGRADE_BW:
+	case PM_UPGRADE_BW:
 		policy_mgr_sap_ch_width_update(psoc, action, reason,
 					       session_id, request_id);
 		break;
-	case PM_UPGRADE_BW:
-		if (reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC)
-			policy_mgr_sap_ch_width_update(psoc, action, reason,
-						       session_id, request_id);
-		else
-			policy_mgr_restart_opportunistic_timer(psoc, false);
-		break;
 	default:
 		policy_mgr_err("unexpected action value %d", action);
 		status = QDF_STATUS_E_FAILURE;
@@ -3991,7 +4006,8 @@ void policy_mgr_check_and_stop_opportunistic_timer(
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 	enum policy_mgr_conc_next_action action = PM_NOP;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
-	enum policy_mgr_conn_update_reason reason;
+	enum policy_mgr_conn_update_reason reason =
+					POLICY_MGR_UPDATE_REASON_MAX;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {

+ 27 - 3
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -1045,7 +1045,6 @@ policy_mgr_update_5Ghz_freq_info(struct policy_mgr_freq_range *mac_range,
 				    QDF_MIN(mac_cap->reg_cap_ext.high_5ghz_chan,
 					    max_5g_freq) :
 				    max_5g_freq;
-
 }
 
 static void
@@ -1370,9 +1369,19 @@ policy_mgr_update_mac_freq_info(struct wlan_objmgr_psoc *psoc,
 
 		break;
 	case WMI_HW_MODE_EMLSR:
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR,
+					    phy_id);
+		break;
 	case WMI_HW_MODE_AUX_EMLSR_SINGLE:
+		if (phy_id) {
+			policy_mgr_debug("MAC Phy 1 is not supported");
+			break;
+		}
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR_SINGLE,
+					    phy_id);
+		break;
 	case WMI_HW_MODE_AUX_EMLSR_SPLIT:
-		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR,
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR_SPLIT,
 					    phy_id);
 		break;
 	default:
@@ -1410,6 +1419,8 @@ static const char *policy_mgr_hw_mode_to_str(enum policy_mgr_mode hw_mode)
 	CASE_RETURN_STRING(MODE_SBS_UPPER_SHARE);
 	CASE_RETURN_STRING(MODE_SBS_LOWER_SHARE);
 	CASE_RETURN_STRING(MODE_EMLSR);
+	CASE_RETURN_STRING(MODE_EMLSR_SINGLE);
+	CASE_RETURN_STRING(MODE_EMLSR_SPLIT);
 	default:
 		return "Unknown";
 	}
@@ -1560,6 +1571,12 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc,
 		if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
 		    WMI_HW_MODE_EMLSR)
 			hw_config_type = WMI_HW_MODE_EMLSR;
+		else if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
+			 WMI_HW_MODE_AUX_EMLSR_SINGLE)
+			hw_config_type = WMI_HW_MODE_AUX_EMLSR_SINGLE;
+		else if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
+			 WMI_HW_MODE_AUX_EMLSR_SPLIT)
+			hw_config_type = WMI_HW_MODE_AUX_EMLSR_SPLIT;
 
 		policy_mgr_update_mac_freq_info(psoc, pm_ctx,
 						hw_config_type,
@@ -1584,7 +1601,8 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc,
 			    (hw_config_type == WMI_HW_MODE_SBS) ||
 			    (hw_config_type == WMI_HW_MODE_DBS_OR_SBS)))
 				sbs_mode = HW_MODE_SBS;
-		} else if (hw_config_type == WMI_HW_MODE_EMLSR) {
+		} else if (hw_config_type == WMI_HW_MODE_EMLSR ||
+			hw_config_type == WMI_HW_MODE_AUX_EMLSR_SPLIT) {
 			/* eMLSR mode */
 			tmp = &info->mac_phy_cap[j++];
 			cap = &info->mac_phy_caps_ext2[i];
@@ -1594,6 +1612,12 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc,
 							hw_config_type,
 							tmp->phy_id, tmp);
 			emlsr_mode = HW_MODE_EMLSR;
+		} else if (hw_config_type == WMI_HW_MODE_AUX_EMLSR_SINGLE) {
+			/* eMLSR mode */
+			cap = &info->mac_phy_caps_ext2[i];
+			wlan_mlme_set_eml_params(psoc, cap);
+			policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
+			emlsr_mode = HW_MODE_EMLSR;
 		}
 
 		/* Updating HW mode list */

+ 5 - 14
components/cmn_services/policy_mgr/src/wlan_policy_mgr_ll_sap.c

@@ -24,27 +24,18 @@
 #include "wlan_policy_mgr_i.h"
 #include "wlan_cmn.h"
 
-struct wlan_objmgr_vdev *
-wlan_policy_mgr_get_ll_lt_sap_vdev(struct wlan_objmgr_psoc *psoc)
+uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev(struct wlan_objmgr_psoc *psoc)
 {
 	uint8_t ll_lt_sap_cnt;
 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
-	struct wlan_objmgr_vdev *vdev;
 
-	ll_lt_sap_cnt = policy_mgr_get_mode_specific_conn_info(
-							psoc, NULL,
+	ll_lt_sap_cnt = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
 							vdev_id_list,
 							PM_LL_LT_SAP_MODE);
 
 	/* Currently only 1 ll_lt_sap is supported */
-	if (ll_lt_sap_cnt != 1) {
-		policy_mgr_err("invalid number of ll_lt_sap %d", ll_lt_sap_cnt);
-		return NULL;
-	}
+	if (!ll_lt_sap_cnt)
+		return WLAN_INVALID_VDEV_ID;
 
-	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id_list[0],
-						    WLAN_LL_SAP_ID);
-	if (!vdev)
-		policy_mgr_err("vdev is NULL");
-	return vdev;
+	return vdev_id_list[0];
 }

+ 6 - 1
components/coex/dispatcher/src/wlan_coex_ucfg_api.c

@@ -128,13 +128,18 @@ ucfg_coex_send_logging_config(struct wlan_objmgr_psoc *psoc,
 	QDF_STATUS status;
 
 	if (apps_args[0] != COEX_CONFIG_ENABLE_CONT_INFO) {
-		coex_err("invalid cmd %d", apps_args);
+		coex_err("invalid cmd %d", apps_args[0]);
 		return QDF_STATUS_E_FAILURE;
 	}
 
 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_STA_MODE,
 							WLAN_COEX_ID);
 
+	if (!vdev) {
+		coex_err("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
 	param.vdev_id = wlan_vdev_get_id(vdev);
 	param.config_type = WMI_COEX_CONFIG_ENABLE_CONT_INFO;
 	param.config_arg1 = apps_args[1];

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

@@ -2651,9 +2651,11 @@ void wlan_dp_soc_cfg_sync_profile(struct cdp_soc_t *cdp_soc)
 				}
 				dp_info("current RXDMA refill ring size:%u synced with profile:%u", cur_val, profile_ctx->size);
 			}
+			break;
 		case DP_RX_REFILL_POOL_NUM_CFG:
 			wlan_dp_rx_refill_pool_cfg_sync_profile(cdp_soc,
 								profile_ctx);
+			break;
 		default:
 			dp_debug("Unknown profile param type:%u", profile_ctx->param_type);
 			break;

+ 4 - 1
components/dp/core/src/wlan_dp_txrx.c

@@ -834,6 +834,7 @@ QDF_STATUS dp_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf)
 	qdf_nbuf_t nbuf_next;
 	unsigned int cpu_index;
 	struct dp_tx_rx_stats *stats;
+	enum dp_nbuf_push_type type;
 
 	/* Sanity check on inputs */
 	if ((!context) || (!rxbuf)) {
@@ -879,8 +880,10 @@ QDF_STATUS dp_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf)
 			 * This is the last packet on the chain
 			 * Scheduling rx sirq
 			 */
+			type = qdf_in_atomic() ? DP_NBUF_PUSH_NAPI :
+						 DP_NBUF_PUSH_BH_DISABLE;
 			status = dp_intf->dp_ctx->dp_ops.dp_nbuf_push_pkt(nbuf,
-							DP_NBUF_PUSH_NAPI);
+							type);
 		}
 
 		if (QDF_IS_STATUS_SUCCESS(status))

+ 2 - 0
components/mlme/core/inc/wlan_mlme_main.h

@@ -400,10 +400,12 @@ struct ft_context {
  * struct assoc_channel_info - store channel info at the time of association
  * @assoc_ch_width: channel width at the time of initial connection
  * @sec_2g_freq: secondary 2 GHz freq
+ * @cen320_freq: 320 MHz center freq
  */
 struct assoc_channel_info {
 	enum phy_ch_width assoc_ch_width;
 	qdf_freq_t sec_2g_freq;
+	qdf_freq_t cen320_freq;
 };
 
 /**

+ 38 - 7
components/mlme/core/src/wlan_mlme_main.c

@@ -401,9 +401,14 @@ mlme_update_freq_in_scan_start_req(struct wlan_objmgr_vdev *vdev,
 	enum scan_phy_mode phymode = SCAN_PHY_MODE_UNKNOWN;
 	uint8_t vdev_id;
 	struct wlan_channel *des_chan;
+	struct mlme_legacy_priv *mlme_priv;
 
 	vdev_id = vdev->vdev_objmgr.vdev_id;
 
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv)
+		return QDF_STATUS_E_FAILURE;
+
 	if (scan_freq != INVALID_CHANNEL) {
 		op_freq = scan_freq;
 	} else {
@@ -414,7 +419,7 @@ mlme_update_freq_in_scan_start_req(struct wlan_objmgr_vdev *vdev,
 		}
 		op_freq = des_chan->ch_freq;
 		/* Set center_freq1 to center frequency of complete 320MHz */
-		cen320_freq = des_chan->ch_cfreq2;
+		cen320_freq = mlme_priv->connect_info.assoc_chan_info.cen320_freq;
 	}
 
 	mlme_debug("vdev %d :op_freq:%d, cen320_freq:%d, scan_ch_width: %d",
@@ -827,6 +832,7 @@ QDF_STATUS mlme_init_connect_chan_info_config(struct vdev_mlme_obj *vdev_mlme)
 	mlme_priv->connect_info.assoc_chan_info.assoc_ch_width =
 							CH_WIDTH_INVALID;
 	mlme_priv->connect_info.assoc_chan_info.sec_2g_freq = 0;
+	mlme_priv->connect_info.assoc_chan_info.cen320_freq = 0;
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -2950,6 +2956,33 @@ void mlme_reinit_control_config_lfr_params(struct wlan_objmgr_psoc *psoc,
 	lfr->wes_mode_enabled = cfg_get(psoc, CFG_LFR_ENABLE_WES_MODE);
 }
 
+#ifdef CONNECTION_ROAMING_CFG
+/**
+ * mlme_init_bmiss_timeout() - Init bmiss timeout
+ * @psoc: Pointer to psoc
+ * @lfr: Pointer to lfr config
+ *
+ * Return: None
+ */
+static void mlme_init_bmiss_timeout(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_mlme_lfr_cfg *lfr)
+{
+	lfr->beaconloss_timeout_onwakeup =
+		cfg_get(psoc, CFG_LFR_BEACONLOSS_TIMEOUT_ON_WAKEUP) / 2;
+	lfr->beaconloss_timeout_onsleep =
+		cfg_get(psoc, CFG_LFR_BEACONLOSS_TIMEOUT_ON_SLEEP) / 2;
+}
+#else
+static void mlme_init_bmiss_timeout(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_mlme_lfr_cfg *lfr)
+{
+	lfr->beaconloss_timeout_onwakeup =
+		cfg_get(psoc, CFG_LFR_BEACONLOSS_TIMEOUT_ON_WAKEUP);
+	lfr->beaconloss_timeout_onsleep =
+		cfg_get(psoc, CFG_LFR_BEACONLOSS_TIMEOUT_ON_SLEEP);
+}
+#endif
+
 static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc,
 			      struct wlan_mlme_lfr_cfg *lfr)
 {
@@ -3141,10 +3174,7 @@ static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc,
 	mlme_init_adaptive_11r_cfg(psoc, lfr);
 	mlme_init_subnet_detection(psoc, lfr);
 	lfr->rso_user_config.cat_rssi_offset = DEFAULT_RSSI_DB_GAP;
-	lfr->beaconloss_timeout_onwakeup =
-		cfg_get(psoc, CFG_LFR_BEACONLOSS_TIMEOUT_ON_WAKEUP);
-	lfr->beaconloss_timeout_onsleep =
-		cfg_get(psoc, CFG_LFR_BEACONLOSS_TIMEOUT_ON_SLEEP);
+	mlme_init_bmiss_timeout(psoc, lfr);
 }
 
 static void mlme_init_power_cfg(struct wlan_objmgr_psoc *psoc,
@@ -4418,8 +4448,9 @@ void wlan_vdev_set_dot11mode(struct wlan_mlme_cfg *mac_mlme_cfg,
 	}
 
 	vdev_dot11_mode = QDF_GET_BITS(mac_dot11_mode, dot11_mode_indx, 4);
-	if (vdev_dot11_mode == MLME_VDEV_DOT11_MODE_AUTO ||
-	    vdev_dot11_mode == MLME_VDEV_DOT11_MODE_11BE) {
+	if ((device_mode != QDF_NAN_DISC_MODE && device_mode != QDF_NDI_MODE) &&
+	    (vdev_dot11_mode == MLME_VDEV_DOT11_MODE_AUTO ||
+	     vdev_dot11_mode == MLME_VDEV_DOT11_MODE_11BE)) {
 		mld_addr = wlan_vdev_mlme_get_mldaddr(vdev_mlme->vdev);
 		if (qdf_is_macaddr_zero((struct qdf_mac_addr *)mld_addr)) {
 			vdev_dot11_mode = MLME_VDEV_DOT11_MODE_11AX;

+ 10 - 12
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -2941,18 +2941,6 @@ wlan_mlme_set_t2lm_negotiation_supported(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_E_NOSUPPORT;
 }
 
-static inline uint8_t
-wlan_mlme_get_eht_mld_id(struct wlan_objmgr_psoc *psoc)
-{
-	return 0;
-}
-
-static inline QDF_STATUS
-wlan_mlme_set_eht_mld_id(struct wlan_objmgr_psoc *psoc, uint8_t value)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
 static inline void
 wlan_mlme_get_mlo_prefer_percentage(
 				struct wlan_objmgr_psoc *psoc,
@@ -4185,6 +4173,16 @@ bool wlan_mlme_skip_tpe(struct wlan_objmgr_psoc *psoc);
 bool
 wlan_mlme_is_data_stall_recovery_fw_supported(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * mlme_cfg_get_orig_eht_caps() - Get the original EHT capability info
+ * @psoc: pointer to psoc object
+ * @eht_cap: Caps that needs to be filled.
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS mlme_cfg_get_orig_eht_caps(struct wlan_objmgr_psoc *psoc,
+				      tDot11fIEeht_cap *eht_cap);
+
 /**
  * mlme_cfg_get_eht_caps() - Get the EHT capability info
  * @psoc: pointer to psoc object

+ 5 - 4
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -1388,10 +1388,11 @@ enum wlan_mlme_hw_mode_config_type {
 };
 
 /**
- * wlan_mlme_aux_caps_bit - Bit mapping for aux capability
- * WLAN_MLME_AUX_MODE_SCAN_BIT: if set, aux scan is supported
- * WLAN_MLME_AUX_MODE_LISTEN_BIT: if set, aux listen is supported
- * WLAN_MLME_AUX_MODE_EMLSR_BIT: if set, aux emlsr is supported
+ * enum wlan_mlme_aux_caps_bit - Bit mapping for aux capability
+ *
+ * @WLAN_MLME_AUX_MODE_SCAN_BIT: if set, aux scan is supported
+ * @WLAN_MLME_AUX_MODE_LISTEN_BIT: if set, aux listen is supported
+ * @WLAN_MLME_AUX_MODE_EMLSR_BIT: if set, aux emlsr is supported
  */
 enum wlan_mlme_aux_caps_bit {
 	WLAN_MLME_AUX_MODE_SCAN_BIT = 0,

+ 45 - 0
components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h

@@ -3905,6 +3905,51 @@ void ucfg_mlme_set_usr_disable_sta_eht(struct wlan_objmgr_psoc *psoc,
 }
 #endif
 
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * ucfg_mlme_get_eht_mld_id() - Get the MLD ID of the requested BSS
+ * @psoc: pointer to psoc object
+ *
+ * This API gives the MLD ID of the requested BSS
+ *
+ * Return: MLD ID of the requested BSS
+ */
+static inline uint8_t
+ucfg_mlme_get_eht_mld_id(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_mlme_get_eht_mld_id(psoc);
+}
+
+/**
+ * ucfg_mlme_set_eht_mld_id() - Set MLD ID of the requested BSS information
+ * @psoc: pointer to psoc object
+ * @value: set MLD ID
+ *
+ * This API sets the MLD ID of the requested BSS information within the ML
+ * probe request.
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+ucfg_mlme_set_eht_mld_id(struct wlan_objmgr_psoc *psoc,
+			 uint8_t value)
+{
+	return wlan_mlme_set_eht_mld_id(psoc, value);
+}
+#else
+static inline uint8_t
+ucfg_mlme_get_eht_mld_id(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_eht_mld_id(struct wlan_objmgr_psoc *psoc, uint8_t value)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif /* WLAN_FEATURE_11BE_MLO */
+
 /**
  * ucfg_mlme_get_80211e_is_enabled() - Enable 802.11e feature
  * @psoc: pointer to psoc object

+ 14 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -6514,6 +6514,20 @@ bool wlan_mlme_skip_tpe(struct wlan_objmgr_psoc *psoc)
 }
 
 #ifdef WLAN_FEATURE_11BE
+QDF_STATUS mlme_cfg_get_orig_eht_caps(struct wlan_objmgr_psoc *psoc,
+				      tDot11fIEeht_cap *eht_cap)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_FAILURE;
+
+	*eht_cap = mlme_obj->cfg.eht_caps.eht_cap_orig;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS mlme_cfg_get_eht_caps(struct wlan_objmgr_psoc *psoc,
 				 tDot11fIEeht_cap *eht_cap)
 {

+ 15 - 1
components/pkt_capture/core/inc/wlan_pkt_capture_main.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -239,6 +239,20 @@ QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
  */
 bool pkt_capture_is_tx_mgmt_enable(struct wlan_objmgr_pdev *pdev);
 
+/**
+ * pkt_capture_is_frame_filter_set - Check if filter type set by user and packet
+ * type matches
+ * @buf: netbuf
+ * @frame_filter: filter set by user via vendor command
+ * @direction: Tx or Rx
+ *
+ * Return: bool
+ */
+bool
+pkt_capture_is_frame_filter_set(qdf_nbuf_t buf,
+				struct pkt_capture_frame_filter *frame_filter,
+				bool direction);
+
 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
 /**
  * pkt_capture_get_pktcap_mode_v2 - Get packet capture mode

+ 45 - 15
components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c

@@ -1639,9 +1639,51 @@ void pkt_capture_offload_deliver_indication_handler(
 	struct pkt_capture_tx_hdr_elem_t *ptr_pktcapture_hdr;
 	struct pkt_capture_tx_hdr_elem_t pktcapture_hdr = {0};
 	uint32_t txcap_hdr_size = sizeof(struct pkt_capture_tx_hdr_elem_t);
+	struct wlan_objmgr_vdev *vdev;
+	struct pkt_capture_vdev_priv *vdev_priv;
+	struct pkt_capture_frame_filter *frame_filter;
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
 
 	offload_deliver_msg = (struct htt_tx_offload_deliver_ind_hdr_t *)msg;
 
+	vdev = pkt_capture_get_vdev();
+	ret = pkt_capture_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(ret))
+		return;
+
+	vdev_priv = pkt_capture_vdev_get_priv(vdev);
+	if (!vdev_priv) {
+		pkt_capture_err("vdev priv is NULL");
+		pkt_capture_vdev_put_ref(vdev);
+		return;
+	}
+
+	frame_filter = &vdev_priv->frame_filter;
+
+	nbuf_len = offload_deliver_msg->tx_mpdu_bytes;
+	netbuf = qdf_nbuf_alloc(NULL,
+				roundup(nbuf_len + RESERVE_BYTES, 4),
+				RESERVE_BYTES, 4, false);
+	if (!netbuf) {
+		pkt_capture_vdev_put_ref(vdev);
+		return;
+	}
+
+	qdf_nbuf_put_tail(netbuf, nbuf_len);
+
+	qdf_mem_copy(qdf_nbuf_data(netbuf),
+		     buf + sizeof(struct htt_tx_offload_deliver_ind_hdr_t),
+		     nbuf_len);
+
+	if (!(frame_filter->data_tx_frame_filter &
+	    PKT_CAPTURE_DATA_FRAME_TYPE_ALL) &&
+	    !pkt_capture_is_frame_filter_set(
+	    netbuf, frame_filter, IEEE80211_FC1_DIR_TODS)) {
+		qdf_nbuf_free(netbuf);
+		pkt_capture_vdev_put_ref(vdev);
+		return;
+	}
+
 	pktcapture_hdr.timestamp = offload_deliver_msg->phy_timestamp_l32;
 	pktcapture_hdr.preamble = offload_deliver_msg->preamble;
 	pktcapture_hdr.mcs = offload_deliver_msg->mcs;
@@ -1661,25 +1703,11 @@ void pkt_capture_offload_deliver_indication_handler(
 	status = offload_deliver_msg->status;
 	pkt_format = offload_deliver_msg->format;
 
-	nbuf_len = offload_deliver_msg->tx_mpdu_bytes;
-
-	netbuf = qdf_nbuf_alloc(NULL,
-				roundup(nbuf_len + RESERVE_BYTES, 4),
-				RESERVE_BYTES, 4, false);
-
-	if (!netbuf)
-		return;
-
-	qdf_nbuf_put_tail(netbuf, nbuf_len);
-
-	qdf_mem_copy(qdf_nbuf_data(netbuf),
-		     buf + sizeof(struct htt_tx_offload_deliver_ind_hdr_t),
-		     nbuf_len);
-
 	qdf_nbuf_push_head(netbuf, txcap_hdr_size);
 
 	ptr_pktcapture_hdr =
 	(struct pkt_capture_tx_hdr_elem_t *)qdf_nbuf_data(netbuf);
+
 	qdf_mem_copy(ptr_pktcapture_hdr, &pktcapture_hdr, txcap_hdr_size);
 
 	pkt_capture_datapkt_process(
@@ -1687,5 +1715,7 @@ void pkt_capture_offload_deliver_indication_handler(
 			netbuf, TXRX_PROCESS_TYPE_DATA_TX,
 			tid, status, pkt_format, bssid, soc,
 			offload_deliver_msg->tx_retry_cnt);
+
+	pkt_capture_vdev_put_ref(vdev);
 }
 #endif

+ 5 - 18
components/pkt_capture/core/src/wlan_pkt_capture_main.c

@@ -406,7 +406,7 @@ pkt_capture_process_tx_data(void *soc, void *log_data, u_int16_t vdev_id,
  * Return: true, if filter bit is set
  *         false, if filter bit is not set
  */
-static bool
+bool
 pkt_capture_is_frame_filter_set(qdf_nbuf_t buf,
 				struct pkt_capture_frame_filter *frame_filter,
 				bool direction)
@@ -594,8 +594,6 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data,
 		struct htt_tx_offload_deliver_ind_hdr_t *offload_deliver_msg;
 		bool is_pkt_during_roam = false;
 		uint32_t freq = 0;
-		qdf_nbuf_t buf = log_data +
-				sizeof(struct htt_tx_offload_deliver_ind_hdr_t);
 
 		if (!frame_filter->data_tx_frame_filter) {
 			pkt_capture_vdev_put_ref(vdev);
@@ -615,17 +613,9 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data,
 			vdev_id = offload_deliver_msg->vdev_id;
 		}
 
-		if (frame_filter->data_tx_frame_filter &
-		    PKT_CAPTURE_DATA_FRAME_TYPE_ALL) {
-			pkt_capture_offload_deliver_indication_handler(
-							log_data,
-							vdev_id, bssid, soc);
-		} else if (pkt_capture_is_frame_filter_set(
-			   buf, frame_filter, IEEE80211_FC1_DIR_TODS)) {
-			pkt_capture_offload_deliver_indication_handler(
+		pkt_capture_offload_deliver_indication_handler(
 							log_data,
 							vdev_id, bssid, soc);
-		}
 		break;
 	}
 
@@ -1256,7 +1246,7 @@ QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
 	ol_txrx_soc_handle soc;
 	QDF_STATUS status;
 	enum pkt_capture_config config = 0;
-	bool check_enable_beacon = 0, send_bcn = 0;
+	bool send_bcn = 0;
 	struct vdev_mlme_obj *vdev_mlme;
 	uint32_t bcn_interval, nth_beacon_value;
 
@@ -1341,16 +1331,13 @@ QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
 		    PKT_CAPTURE_MGMT_CONNECT_NO_BEACON) {
 			mode |= PACKET_CAPTURE_MODE_MGMT_ONLY;
 			config |= PACKET_CAPTURE_CONFIG_NO_BEACON_ENABLE;
-		} else {
-			check_enable_beacon = 1;
 		}
-	}
 
-	if (check_enable_beacon) {
 		if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
-		    PKT_CAPTURE_MGMT_CONNECT_BEACON)
+		    PKT_CAPTURE_MGMT_CONNECT_BEACON) {
 			if (!send_bcn)
 				config |= PACKET_CAPTURE_CONFIG_BEACON_ENABLE;
+		}
 
 		if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
 		    PKT_CAPTURE_MGMT_CONNECT_SCAN_BEACON)

+ 0 - 4
components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c

@@ -594,10 +594,6 @@ pkt_capture_is_beacon_forward_enable(struct wlan_objmgr_vdev *vdev,
 		return false;
 	}
 
-	if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
-	    PKT_CAPTURE_MGMT_CONNECT_NO_BEACON)
-		return false;
-
 	mac_hdr = (tpSirMacMgmtHdr)(qdf_nbuf_data(wbuf));
 	wlan_vdev_get_bss_peer_mac(vdev, &connected_bssid);
 

+ 5 - 3
components/tdls/core/src/wlan_tdls_cmds_process.c

@@ -2058,8 +2058,6 @@ QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req)
 	uint32_t pref_width;
 	struct wlan_objmgr_pdev *pdev;
 
-	tdls_debug("Configure external TDLS peer " QDF_MAC_ADDR_FMT,
-		   QDF_MAC_ADDR_REF(req->peer_addr));
 
 	/* reference cnt is acquired in ucfg_tdls_oper */
 	vdev = req->vdev;
@@ -2070,11 +2068,15 @@ QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req)
 	}
 
 	if (!tdls_check_is_tdls_allowed(vdev)) {
-		tdls_err("TDLS not allowed, Reject setup peer");
+		tdls_err("TDLS not allowed on vdev:%d, Reject setup peer",
+			 wlan_vdev_get_id(vdev));
 		status = QDF_STATUS_E_INVAL;
 		goto error;
 	}
 
+	tdls_debug("vdev:%d Configure external TDLS peer " QDF_MAC_ADDR_FMT,
+		   wlan_vdev_get_id(vdev),
+		   QDF_MAC_ADDR_REF(req->peer_addr));
 	qdf_mem_zero(&peer_req, sizeof(peer_req));
 	peer_req.vdev = vdev;
 	qdf_mem_copy(peer_req.peer_addr, req->peer_addr, QDF_MAC_ADDR_SIZE);

+ 43 - 21
components/tdls/core/src/wlan_tdls_main.c

@@ -997,7 +997,16 @@ bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev)
 	     tdls_is_concurrency_allowed(tdls_soc_obj->soc))) {
 		state = true;
 	} else {
-		tdls_warn("Concurrent sessions exist disable TDLS");
+		tdls_warn("vdev:%d Concurrent sessions exist disable TDLS",
+			  wlan_vdev_get_id(vdev));
+		state = false;
+		goto exit;
+	}
+
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE && sta_count) {
+		tdls_warn("vdev:%d Concurrent STA exists. TDLS not allowed for P2P vdev",
+			  wlan_vdev_get_id(vdev));
+		state = false;
 		goto exit;
 	}
 
@@ -1507,7 +1516,8 @@ void tdls_process_enable_for_vdev(struct wlan_objmgr_vdev *vdev)
 							      NULL);
 	opmode = wlan_vdev_mlme_get_opmode(vdev);
 	if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
-		tdls_debug("STA + P2P concurrency. Don't allow TDLS on P2P vdev");
+		tdls_debug("STA + P2P concurrency. Don't allow TDLS on P2P vdev:%d",
+			   wlan_vdev_get_id(vdev));
 		return;
 	}
 
@@ -1827,18 +1837,17 @@ static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev,
 				  enum tdls_feature_mode tdls_mode,
 				  enum tdls_disable_sources source)
 {
-	if (!tdls_vdev)
-		return;
-	tdls_debug("enter tdls mode is %d", tdls_mode);
+	tdls_debug("set tdls mode: %d source:%d", tdls_mode,
+		   source);
 
-	if (TDLS_SUPPORT_IMP_MODE == tdls_mode ||
-	    TDLS_SUPPORT_EXT_CONTROL == tdls_mode) {
-		clear_bit((unsigned long)source,
-			  &tdls_soc->tdls_source_bitmap);
+	switch (tdls_mode) {
+	case TDLS_SUPPORT_IMP_MODE:
+		fallthrough;
+	case TDLS_SUPPORT_EXT_CONTROL:
+		clear_bit((unsigned long)source, &tdls_soc->tdls_source_bitmap);
 		/*
 		 * Check if any TDLS source bit is set and if
-		 * bitmap is not zero then we should not
-		 * enable TDLS
+		 * bitmap is not zero then we should not enable TDLS
 		 */
 		if (tdls_soc->tdls_source_bitmap) {
 			tdls_notice("Don't enable TDLS, source bitmap: %lu",
@@ -1846,12 +1855,15 @@ static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev,
 			return;
 		}
 		tdls_implicit_enable(tdls_vdev);
-		/* tdls implicit mode is enabled, so
-		 * enable the connection tracker
+		/*
+		 * tdls implicit mode is enabled, so enable the connection
+		 * tracker
 		 */
-		tdls_soc->enable_tdls_connection_tracker =
-			true;
-	} else if (TDLS_SUPPORT_DISABLED == tdls_mode) {
+		tdls_soc->enable_tdls_connection_tracker = true;
+
+		return;
+
+	case TDLS_SUPPORT_DISABLED:
 		set_bit((unsigned long)source,
 			&tdls_soc->tdls_source_bitmap);
 		tdls_implicit_disable(tdls_vdev);
@@ -1859,7 +1871,10 @@ static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev,
 		 * stop the connection tracker.
 		 */
 		tdls_soc->enable_tdls_connection_tracker = false;
-	} else if (TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_mode) {
+
+		return;
+
+	case TDLS_SUPPORT_EXP_TRIG_ONLY:
 		clear_bit((unsigned long)source,
 			  &tdls_soc->tdls_source_bitmap);
 		tdls_implicit_disable(tdls_vdev);
@@ -1875,8 +1890,11 @@ static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev,
 		 */
 		if (tdls_soc->tdls_source_bitmap)
 			return;
+
+		return;
+	default:
+		return;
 	}
-	tdls_debug("exit ");
 }
 
 /**
@@ -1932,12 +1950,15 @@ static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc,
 							QDF_STA_MODE,
 							WLAN_TDLS_NB_ID);
 	if (vdev) {
-		tdls_debug("set mode in tdls vdev ");
+		tdls_debug("set mode in tdls STA vdev:%d",
+			   wlan_vdev_get_id(vdev));
 		tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
 		if (tdls_vdev)
 			tdls_set_mode_in_vdev(tdls_vdev, tdls_soc,
 					      tdls_mode, source);
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
+
+		goto exit;
 	}
 
 	/* get p2p client vdev */
@@ -1945,7 +1966,8 @@ static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc,
 							QDF_P2P_CLIENT_MODE,
 							WLAN_TDLS_NB_ID);
 	if (vdev) {
-		tdls_debug("set mode in tdls vdev ");
+		tdls_debug("set mode in tdls P2P cli vdev:%d",
+			   wlan_vdev_get_id(vdev));
 		tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
 		if (tdls_vdev)
 			tdls_set_mode_in_vdev(tdls_vdev, tdls_soc,
@@ -1953,11 +1975,11 @@ static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc,
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
 	}
 
+exit:
 	if (!update_last)
 		tdls_soc->tdls_last_mode = tdls_soc->tdls_current_mode;
 
 	tdls_soc->tdls_current_mode = tdls_mode;
-
 }
 
 QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode)

+ 21 - 2
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -6890,6 +6890,22 @@ cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data,
 	return status;
 }
 
+static enum wlan_diag_wifi_band
+wlan_convert_bitmap_to_band(uint8_t bitmap)
+{
+	uint8_t i;
+	enum wlan_diag_wifi_band band = WLAN_INVALID_BAND;
+
+	for (i = WLAN_24GHZ_BAND; i <= WLAN_6GHZ_BAND; i++) {
+		if (qdf_test_bit(i, (unsigned long *)&bitmap)) {
+			band = i;
+			break;
+		}
+	}
+
+	return band;
+}
+
 QDF_STATUS
 cm_roam_mgmt_frame_event(struct wlan_objmgr_vdev *vdev,
 			 struct roam_frame_info *frame_data,
@@ -6938,18 +6954,21 @@ cm_roam_mgmt_frame_event(struct wlan_objmgr_vdev *vdev,
 		}
 	}
 
-	wlan_diag_event.supported_links = frame_data->band;
-
 	if (frame_data->type == ROAM_FRAME_INFO_FRAME_TYPE_EXT) {
 		wlan_diag_event.subtype =
 			(uint8_t)cm_roam_get_eapol_tag(frame_data->subtype);
 		diag_event = EVENT_WLAN_CONN_DP;
+		wlan_diag_event.supported_links =
+			wlan_convert_bitmap_to_band(frame_data->band);
+
 	} else {
 		wlan_diag_event.subtype =
 		(uint8_t)cm_roam_get_tag(frame_data->subtype,
 					 !frame_data->is_rsp);
 		diag_event = EVENT_WLAN_MGMT;
 
+		wlan_diag_event.supported_links = frame_data->band;
+
 		status =
 			wlan_populate_mlo_mgmt_event_param(vdev,
 							   &wlan_diag_event,

+ 24 - 1
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -1139,8 +1139,29 @@ QDF_STATUS cm_flush_join_req(struct scheduler_msg *msg)
 
 	return QDF_STATUS_SUCCESS;
 }
-
 #ifdef WLAN_FEATURE_11BE_MLO
+#if defined (SAP_MULTI_LINK_EMULATION)
+static void
+set_partner_info_for_2link_sap(struct scan_cache_entry *scan_entry,
+			       struct mlo_partner_info *partner_info)
+{
+	partner_info->partner_link_info[0].link_addr =
+		scan_entry->ml_info.link_info[0].link_addr;
+	partner_info->partner_link_info[0].link_id =
+		scan_entry->ml_info.link_info[0].link_id;
+	partner_info->partner_link_info[0].chan_freq =
+		scan_entry->ml_info.link_info[0].freq;
+	partner_info->num_partner_links = 1;
+
+}
+#else
+static void
+set_partner_info_for_2link_sap(struct scan_cache_entry *scan_entry,
+			       struct mlo_partner_info *partner_info)
+{
+}
+#endif
+
 QDF_STATUS
 cm_get_ml_partner_info(struct wlan_objmgr_pdev *pdev,
 		       struct scan_cache_entry *scan_entry,
@@ -1201,6 +1222,8 @@ cm_get_ml_partner_info(struct wlan_objmgr_pdev *pdev,
 	partner_info->num_partner_links = j;
 	mlme_debug("sta and ap intersect num of partner link: %d", j);
 
+	set_partner_info_for_2link_sap(scan_entry, partner_info);
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 21 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -139,8 +139,16 @@ cm_update_associated_ch_info(struct wlan_objmgr_vdev *vdev, bool is_update)
 	struct mlme_legacy_priv *mlme_priv;
 	struct wlan_channel *des_chan;
 	struct assoc_channel_info *assoc_chan_info;
+	struct wlan_objmgr_pdev *pdev;
 	enum phy_ch_width ch_width;
 	QDF_STATUS status;
+	uint8_t band_mask;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		mlme_err("invalid pdev");
+		return;
+	}
 
 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
 	if (!mlme_priv)
@@ -177,6 +185,19 @@ cm_update_associated_ch_info(struct wlan_objmgr_vdev *vdev, bool is_update)
 		if (des_chan->ch_cfreq1 == des_chan->ch_freq - BW_10_MHZ)
 			assoc_chan_info->sec_2g_freq =
 					des_chan->ch_freq - BW_20_MHZ;
+	} else if (des_chan->ch_width == CH_WIDTH_320MHZ) {
+		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(des_chan->ch_freq))
+			band_mask = BIT(REG_BAND_6G);
+		else
+			band_mask = BIT(REG_BAND_5G);
+		assoc_chan_info->cen320_freq =
+			wlan_reg_chan_band_to_freq(pdev,
+						   des_chan->ch_freq_seg2,
+						   band_mask);
+
+		mlme_debug("ch_freq_seg2: %d, cen320_freq: %d",
+			   des_chan->ch_freq_seg2,
+			   assoc_chan_info->cen320_freq);
 	}
 
 	mlme_debug("ch width :%d, ch_freq:%d, ch_cfreq1:%d, sec_2g_freq:%d",

+ 1 - 1
components/umac/mlme/mlo_mgr/src/wlan_epcs_api.c

@@ -670,7 +670,7 @@ QDF_STATUS wlan_epcs_set_config(struct wlan_objmgr_vdev *vdev, uint8_t flag)
 	else
 		wlan_mlme_set_epcs_capability(wlan_vdev_get_psoc(vdev), false);
 
-	return lim_send_eht_caps_ie(mac_ctx, NULL, QDF_STA_MODE,
+	return lim_send_eht_caps_ie(mac_ctx, QDF_STA_MODE,
 				    wlan_vdev_get_id(vdev));
 }
 

+ 22 - 0
components/umac/mlme/mlo_mgr/src/wlan_t2lm_api.c

@@ -146,6 +146,19 @@ QDF_STATUS t2lm_handle_rx_req(struct wlan_objmgr_vdev *vdev,
 	bool valid_map = false;
 	QDF_STATUS status;
 	struct wlan_mlo_peer_context *ml_peer;
+	struct wlan_objmgr_psoc *psoc;
+
+	if (!vdev)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	if (!wlan_mlme_get_t2lm_negotiation_supported(psoc)) {
+		mlme_rl_debug("T2LM negotiation not supported");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
 
 	ml_peer = peer->mlo_peer_ctx;
 	if (!ml_peer)
@@ -449,11 +462,20 @@ wlan_t2lm_validate_candidate(struct cnx_mgr *cm_ctx,
 	uint16_t tid_map_link_id;
 	uint16_t established_tid_mapped_link_id = 0;
 	uint16_t upcoming_tid_mapped_link_id = 0;
+	struct wlan_objmgr_psoc *psoc;
 
 	if (!scan_entry || !cm_ctx || !cm_ctx->vdev)
 		return QDF_STATUS_E_NULL_VALUE;
 
 	vdev = cm_ctx->vdev;
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	if (!wlan_mlme_get_t2lm_negotiation_supported(psoc)) {
+		mlme_rl_debug("T2LM negotiation not supported");
+		return QDF_STATUS_SUCCESS;
+	}
 
 	/*
 	 * Skip T2LM validation for following cases:

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 966 - 8
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.c


+ 132 - 37
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.h

@@ -26,20 +26,7 @@
 #include <qdf_atomic.h>
 #include "wlan_cmn.h"
 #include "wlan_ll_sap_main.h"
-
-/**
- * enum bearer_switch_status: Bearer switch request status
- * @XPAN_BLE_SWITCH_INIT: Init status
- * @XPAN_BLE_SWITCH_SUCCESS: Bearer switch success
- * @XPAN_BLE_SWITCH_REJECTED: Bearer switch is rejected
- * @XPAN_BLE_SWITCH_TIMEOUT: Bearer switch request timed out
- */
-enum bearer_switch_status {
-	XPAN_BLE_SWITCH_INIT,
-	XPAN_BLE_SWITCH_SUCCESS,
-	XPAN_BLE_SWITCH_REJECTED,
-	XPAN_BLE_SWITCH_TIMEOUT,
-};
+#include "wlan_sm_engine.h"
 
 /**
  * enum wlan_bearer_switch_sm_state - Bearer switch states
@@ -98,23 +85,6 @@ struct bs_state_sm {
 	enum wlan_bearer_switch_sm_state bs_state;
 };
 
-/**
- * struct bearer_switch_request - Data structure to store the bearer switch
- * request
- * @requester_cb: Callback which needs to be invoked to indicate the status of
- * the request to the requester, this callback will be passed by the requester
- * when requester will send the request.
- * @arg: Argument passed by requester, this will be returned back in the
- * callback
- * @request_id: Unique value to identify the request
- */
-
-struct bearer_switch_request {
-	requester_callback requester_cb;
-	void *arg;
-	uint32_t request_id;
-};
-
 /**
  * struct bearer_switch_info - Data structure to store the bearer switch
  * requests and related information
@@ -122,25 +92,31 @@ struct bearer_switch_request {
  * @request_id: Last allocated request id
  * @sm: state machine context
  * @ref_count: Reference count corresponding to each vdev and requester
- * @last_status: last status of the bearer switch request
+ * @fw_ref_count: Reference counts for the firmware requests
+ * @total_ref_count: Total reference counts
+ * @last_status:status of the last bearer switch request
  * @requests: Array of bearer_switch_requests to cache the request information
+ * @bs_request_timer: Bearer switch request timer
  */
 struct bearer_switch_info {
 	struct wlan_objmgr_vdev *vdev;
 	qdf_atomic_t request_id;
 	struct bs_state_sm sm;
-	uint8_t ref_count[WLAN_UMAC_PSOC_MAX_VDEVS][XPAN_BLE_SWITCH_REQUESTER_MAX];
-	enum bearer_switch_status last_status;
-	struct bearer_switch_request requests[MAX_BEARER_SWITCH_REQUESTERS];
+	qdf_atomic_t ref_count[WLAN_UMAC_PSOC_MAX_VDEVS][BEARER_SWITCH_REQ_MAX];
+	qdf_atomic_t fw_ref_count;
+	qdf_atomic_t total_ref_count;
+	QDF_STATUS last_status;
+	struct wlan_bearer_switch_request requests[MAX_BEARER_SWITCH_REQUESTERS];
+	qdf_mc_timer_t bs_request_timer;
 };
 
 /**
  * ll_lt_sap_bearer_switch_get_id() - Get the request id for bearer switch
  * request
- * @vdev: Pointer to vdev
+ * @psoc: Pointer to psoc
  * Return: Bearer switch request id
  */
-uint32_t ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_vdev *vdev);
+wlan_bs_req_id ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_psoc *psoc);
 
 /**
  * bs_sm_create() - Invoke SM creation for bearer switch
@@ -211,4 +187,123 @@ static inline void bs_lock_release(struct bearer_switch_info *bs_ctx)
 {
 	qdf_mutex_release(&bs_ctx->sm.bs_sm_lock);
 }
+
+/**
+ * bs_sm_transition_to() - invokes state transition
+ * @bs_ctx:  Bearer switch ctx
+ * @state: new cm state
+ *
+ * API to invoke SM API to move to new state
+ *
+ * Return: void
+ */
+static inline void bs_sm_transition_to(struct bearer_switch_info *bs_ctx,
+				       enum wlan_bearer_switch_sm_state state)
+{
+	wlan_sm_transition_to(bs_ctx->sm.sm_hdl, state);
+}
+
+/**
+ * bs_sm_deliver_event() - Delivers event to Bearer switch SM
+ * @psoc: Pointer to psoc
+ * @event: BS event
+ * @data_len: data size
+ * @data: event data
+ *
+ * API to dispatch event to Bearer switch state machine. To be used while
+ * posting events from API called from public API.
+ *
+ * Return: SUCCESS: on handling event
+ *         FAILURE: If event not handled
+ */
+QDF_STATUS bs_sm_deliver_event(struct wlan_objmgr_psoc *psoc,
+			       enum wlan_bearer_switch_sm_evt event,
+			       uint16_t data_len, void *data);
+
+/**
+ * bs_req_timer_init() - Initialize Bearer switch request timer
+ * @bs_ctx: Bearer switch context
+ *
+ * Return: None
+ */
+void bs_req_timer_init(struct bearer_switch_info *bs_ctx);
+
+/**
+ * bs_req_timer_deinit() - De-initialize Bearer switch request timer
+ * @bs_ctx: Bearer switch context
+ *
+ * Return: None
+ */
+void bs_req_timer_deinit(struct bearer_switch_info *bs_ctx);
+
+/**
+ * ll_lt_sap_is_bs_ctx_valid() - Check if bearer switch context is valid or not
+ * @bs_ctx: Bearer switch context
+ *
+ * Return: True if bearer switch context is valid else return false
+ */
+#define ll_lt_sap_is_bs_ctx_valid(bs_ctx) \
+	__ll_lt_sap_is_bs_ctx_valid(bs_ctx, __func__)
+
+bool __ll_lt_sap_is_bs_ctx_valid(struct bearer_switch_info *bs_ctx,
+				 const char *func);
+
+/**
+ * ll_lt_sap_is_bs_req_valid() - Check if bearer switch request is valid or not
+ * @bs_req: Bearer switch request
+ *
+ * Return: True if bearer switch request is valid else return false
+ */
+#define ll_lt_sap_is_bs_req_valid(bs_req) \
+	__ll_lt_sap_is_bs_req_valid(bs_req, __func__)
+
+bool __ll_lt_sap_is_bs_req_valid(struct wlan_bearer_switch_request *bs_req,
+				 const char *func);
+
+/**
+ * ll_lt_sap_switch_bearer_to_ble() - Switch audio transport to BLE
+ * @psoc: Pointer to psoc
+ * @bs_request: Pointer to bearer switch request
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch else failure
+ */
+QDF_STATUS
+ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
+			       struct wlan_bearer_switch_request *bs_request);
+
+/**
+ * ll_lt_sap_switch_bearer_to_wlan() - Switch audio transport to BLE
+ * @psoc: Pointer to psoc
+ * @bs_request: Pointer to bearer switch request
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch else failure
+ */
+QDF_STATUS
+ll_lt_sap_switch_bearer_to_wlan(struct wlan_objmgr_psoc *psoc,
+				struct wlan_bearer_switch_request *bs_request);
+
+/**
+ * ll_lt_sap_request_for_audio_transport_switch() - Handls audio transport
+ * switch request from userspace
+ * @vdev: Vdev on which the request is received
+ * @req_type: requested transport switch type
+ *
+ * Return: True/False
+ */
+QDF_STATUS
+ll_lt_sap_request_for_audio_transport_switch(struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type);
+
+/**
+ * ll_lt_sap_deliver_audio_transport_switch_resp() - Deliver audio
+ * transport switch response
+ * @vdev: Vdev on which the request is received
+ * @req_type: Transport switch type for which the response is received
+ * @status: Status of the response
+ *
+ * Return: None
+ */
+void
+ll_lt_sap_deliver_audio_transport_switch_resp(struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type,
+					enum bearer_switch_status status);
+
 #endif /* _WLAN_LL_LT_SAP_BEARER_SWITCH_H_ */

+ 42 - 6
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_main.c

@@ -76,6 +76,8 @@ QDF_STATUS ll_lt_sap_init(struct wlan_objmgr_vdev *vdev)
 {
 	struct ll_sap_vdev_priv_obj *ll_sap_obj;
 	QDF_STATUS status;
+	uint8_t i, j;
+	struct bearer_switch_info *bs_ctx;
 
 	ll_sap_obj = ll_sap_get_vdev_priv_obj(vdev);
 
@@ -85,16 +87,24 @@ QDF_STATUS ll_lt_sap_init(struct wlan_objmgr_vdev *vdev)
 		return QDF_STATUS_E_INVAL;
 	}
 
-	ll_sap_obj->bearer_switch_ctx =
-			qdf_mem_malloc(sizeof(struct bearer_switch_info));
-	if (!ll_sap_obj->bearer_switch_ctx)
+	bs_ctx = ll_sap_obj->bearer_switch_ctx;
+
+	bs_ctx = qdf_mem_malloc(sizeof(struct bearer_switch_info));
+	if (!bs_ctx)
 		return QDF_STATUS_E_NOMEM;
 
-	qdf_atomic_init(&ll_sap_obj->bearer_switch_ctx->request_id);
+	qdf_atomic_init(&bs_ctx->request_id);
+
+	for (i = 0; i < WLAN_UMAC_PSOC_MAX_VDEVS; i++)
+		for (j = 0; j < BEARER_SWITCH_REQ_MAX; j++)
+			qdf_atomic_init(&bs_ctx->ref_count[i][j]);
 
-	ll_sap_obj->bearer_switch_ctx->vdev = vdev;
+	qdf_atomic_init(&bs_ctx->fw_ref_count);
+	qdf_atomic_init(&bs_ctx->total_ref_count);
 
-	status = bs_sm_create(ll_sap_obj->bearer_switch_ctx);
+	bs_ctx->vdev = vdev;
+
+	status = bs_sm_create(bs_ctx);
 
 	if (QDF_IS_STATUS_ERROR(status))
 		goto bs_sm_failed;
@@ -105,6 +115,7 @@ QDF_STATUS ll_lt_sap_init(struct wlan_objmgr_vdev *vdev)
 
 bs_sm_failed:
 	qdf_mem_free(ll_sap_obj->bearer_switch_ctx);
+	ll_sap_obj->bearer_switch_ctx = NULL;
 	return status;
 }
 
@@ -134,3 +145,28 @@ QDF_STATUS ll_lt_sap_deinit(struct wlan_objmgr_vdev *vdev)
 
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
+				struct wlan_bearer_switch_request *bs_request)
+{
+	return bs_sm_deliver_event(psoc, WLAN_BS_SM_EV_SWITCH_TO_NON_WLAN,
+				   sizeof(*bs_request), bs_request);
+}
+
+QDF_STATUS ll_lt_sap_request_for_audio_transport_switch(
+					enum bearer_switch_req_type req_type)
+{
+	/*
+	 * return status as QDF_STATUS_SUCCESS or failure based on the current
+	 * pending requests of the transport switch
+	 */
+	if (req_type == WLAN_BS_REQ_TO_NON_WLAN) {
+		ll_sap_debug("request SWITCH_TYPE_NON_WLAN accepted");
+		return QDF_STATUS_SUCCESS;
+	} else if (req_type == WLAN_BS_REQ_TO_WLAN) {
+		ll_sap_debug("request SWITCH_TYPE_WLAN accepted");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return QDF_STATUS_E_RESOURCES;
+}

+ 21 - 0
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_main.h

@@ -26,6 +26,7 @@
 #include <i_qdf_types.h>
 #include <qdf_types.h>
 #include "wlan_ll_sap_main.h"
+#include "wlan_ll_sap_public_structs.h"
 
 /**
  * ll_lt_sap_is_supported() - Check if ll_lt_sap is supported or not
@@ -64,4 +65,24 @@ QDF_STATUS ll_lt_sap_init(struct wlan_objmgr_vdev *vdev);
  * else error code
  */
 QDF_STATUS ll_lt_sap_deinit(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ll_lt_sap_switch_bearer_to_ble() - Switch audio transport to BLE
+ * @psoc: Pointer to psoc
+ * @bs_request: Pointer to bearer switch request
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch else failure
+ */
+QDF_STATUS
+ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
+			       struct wlan_bearer_switch_request *bs_request);
+
+/**
+ * ll_lt_sap_request_for_audio_transport_switch() - Handls audio transport
+ * switch request from userspace
+ * @req_type: requested transport switch type
+ *
+ * Return: True/False
+ */
+QDF_STATUS ll_lt_sap_request_for_audio_transport_switch(
+					enum bearer_switch_req_type req_type);
 #endif /* _WLAN_LL_SAP_MAIN_H_ */

+ 13 - 16
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_sap_main.c

@@ -19,6 +19,8 @@
 #include "qca_vendor.h"
 #include "wlan_ll_lt_sap_main.h"
 
+struct ll_sap_ops *global_ll_sap_ops;
+
 static QDF_STATUS ll_sap_psoc_obj_created_notification(struct wlan_objmgr_psoc *psoc, void *arg_list)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -222,22 +224,17 @@ QDF_STATUS ll_sap_deinit(void)
 	return ret;
 }
 
-QDF_STATUS ll_lt_sap_request_for_audio_transport_switch(
-						uint8_t transport_switch_type)
+void ll_sap_register_os_if_cb(struct ll_sap_ops *ll_sap_global_ops)
 {
-	/*
-	 * return status as QDF_STATUS_SUCCESS or failure based on the current
-	 * pending requests of the transport switch
-	 */
-	if (transport_switch_type ==
-		QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_NON_WLAN) {
-		ll_sap_debug("request SWITCH_TYPE_NON_WLAN accepted");
-		return QDF_STATUS_SUCCESS;
-	} else if (transport_switch_type ==
-				QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_WLAN) {
-		ll_sap_debug("request SWITCH_TYPE_WLAN accepted");
-		return QDF_STATUS_SUCCESS;
-	}
+	global_ll_sap_ops = ll_sap_global_ops;
+}
 
-	return QDF_STATUS_E_RESOURCES;
+void ll_sap_unregister_os_if_cb(void)
+{
+	global_ll_sap_ops = NULL;
+}
+
+struct ll_sap_ops *ll_sap_get_osif_cbk(void)
+{
+	return global_ll_sap_ops;
 }

+ 19 - 6
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_sap_main.h

@@ -23,6 +23,7 @@
 
 #include "wlan_objmgr_psoc_obj.h"
 #include "wlan_objmgr_vdev_obj.h"
+#include "wlan_ll_sap_public_structs.h"
 
 #define ll_sap_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_LL_SAP, params)
 #define ll_sap_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_LL_SAP, params)
@@ -80,13 +81,25 @@ QDF_STATUS ll_sap_init(void);
 QDF_STATUS ll_sap_deinit(void);
 
 /**
- * ll_lt_sap_request_for_audio_transport_switch() - Check if audio transport
- * switch request can be supported or not
- * @transport_switch_type: requested transport switch type
+ * ll_sap_register_os_if_cb() - Register ll_sap osif callbacks
+ * @ll_sap_global_ops: Ops which needs to be registered
  *
- * Return: True/False
+ * Return: None
  */
-QDF_STATUS ll_lt_sap_request_for_audio_transport_switch(
-						uint8_t transport_switch_type);
+void ll_sap_register_os_if_cb(struct ll_sap_ops *ll_sap_global_ops);
+
+/**
+ * ll_sap_unregister_os_if_cb() - Un-register ll_sap osif callbacks
+ *
+ * Return: None
+ */
+void ll_sap_unregister_os_if_cb(void);
+
+/**
+ * ll_sap_get_osif_cbk() - API to get ll_sap osif callbacks
+ *
+ * Return: global ll_sap osif callback
+ */
+struct ll_sap_ops *ll_sap_get_osif_cbk(void);
 
 #endif /* _WLAN_LL_SAP_MAIN_H_ */

+ 72 - 4
components/umac/mlme/sap/ll_sap/dispatcher/inc/wlan_ll_sap_api.h

@@ -24,22 +24,90 @@
 
 #include <wlan_cmn.h>
 #include <wlan_objmgr_vdev_obj.h>
+#include "wlan_ll_sap_public_structs.h"
+#include "wlan_cm_public_struct.h"
 
 #ifdef WLAN_FEATURE_LL_LT_SAP
-
 /**
  * wlan_ll_lt_sap_bearer_switch_get_id() - Get the request id for bearer switch
  * request
- * @vdev: Pointer to vdev
+ * @psoc: Pointer to psoc
  * Return: Bearer switch request id
  */
-uint32_t wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_vdev *vdev);
+wlan_bs_req_id
+wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_ll_lt_sap_switch_bearer_to_ble() - Switch audio transport to BLE
+ * @psoc: Pointer to psoc
+ * @bs_request: Pointer to bearer switch request
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch else failure
+ */
+QDF_STATUS wlan_ll_lt_sap_switch_bearer_to_ble(
+				struct wlan_objmgr_psoc *psoc,
+				struct wlan_bearer_switch_request *bs_request);
+
+/**
+ * wlan_ll_sap_switch_bearer_on_sta_connect_start() - Switch bearer during
+ * station connection start
+ * @psoc: Pointer to psoc
+ * @scan_list: Pointer to the candidate list
+ * @vdev_id: Vdev id of the requesting vdev
+ * @cm_id: connection manager id of the current connect request
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch
+ *         QDF_STATUS_E_ALREADY, if bearer switch is not required
+ *         else failure
+ */
+QDF_STATUS wlan_ll_sap_switch_bearer_on_sta_connect_start(
+						struct wlan_objmgr_psoc *psoc,
+						qdf_list_t *scan_list,
+						uint8_t vdev_id,
+						wlan_cm_id cm_id);
+
+/**
+ * wlan_ll_sap_switch_bearer_on_sta_connect_complete() - Switch bearer during
+ * station connection complete
+ * @psoc: Pointer to psoc
+ * @vdev_id: Vdev id of the requesting vdev
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch
+ *         QDF_STATUS_E_ALREADY, if bearer switch is not required
+ *         else failure
+ */
+QDF_STATUS wlan_ll_sap_switch_bearer_on_sta_connect_complete(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+
 #else
 
-static inline uint32_t
+static inline wlan_bs_req_id
 wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_vdev *vdev)
 {
 	return 0;
 }
+
+static inline QDF_STATUS
+wlan_ll_lt_sap_switch_bearer_to_ble(
+				struct wlan_objmgr_psoc *psoc,
+				struct wlan_bearer_switch_request *bs_request)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+wlan_ll_sap_switch_bearer_on_sta_connect_start(struct wlan_objmgr_psoc *psoc,
+					       qdf_list_t *scan_list,
+					       uint8_t vdev_id,
+					       wlan_cm_id cm_id)
+
+{
+	return QDF_STATUS_E_ALREADY;
+}
+
+static inline QDF_STATUS
+wlan_ll_sap_switch_bearer_on_sta_connect_complete(struct wlan_objmgr_psoc *psoc,
+						  uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif /* WLAN_FEATURE_LL_LT_SAP */
 #endif /* _WLAN_LL_LT_SAP_API_H_ */

+ 91 - 25
components/umac/mlme/sap/ll_sap/dispatcher/inc/wlan_ll_sap_public_structs.h

@@ -27,35 +27,101 @@
 
 /* Indicates MAX bearer switch requesters at a time */
 #define MAX_BEARER_SWITCH_REQUESTERS 5
+#define BS_REQ_ID_INVALID 0xFFFFFFFF
+typedef uint32_t wlan_bs_req_id;
 
 /**
- * enum bearer_switch_requester_source: Bearer switch requester source
- * @XPAN_BLE_SWITCH_REQUESTER_CONNECT: Bearer switch requester is connect
- * @XPAN_BLE_SWITCH_REQUESTER_CSA: Bearer switch requester is CSA
- * @XPAN_BLE_SWITCH_REQUESTER_FW: Bearer switch requester is FW
- * @XPAN_BLE_SWITCH_REQUESTER_MAX: Indicates MAX bearer switch requester
- */
-enum bearer_switch_requester_source {
-	XPAN_BLE_SWITCH_REQUESTER_CONNECT,
-	XPAN_BLE_SWITCH_REQUESTER_CSA,
-	XPAN_BLE_SWITCH_REQUESTER_FW,
-	XPAN_BLE_SWITCH_REQUESTER_MAX,
+ * enum bearer_switch_req_type: Bearer switch request type
+ * @WLAN_BS_REQ_TO_NON_WLAN: Bearer switch request to non-wlan
+ * @WLAN_BS_REQ_TO_WLAN: Bearer switch request to wlan
+ * @WLAN_BS_REQ_INVALID: Invalid bearer switch request
+ */
+enum bearer_switch_req_type {
+	WLAN_BS_REQ_TO_NON_WLAN = 0,
+	WLAN_BS_REQ_TO_WLAN = 1,
+	WLAN_BS_REQ_INVALID,
+};
+
+/**
+ * enum bearer_switch_status: Bearer switch status
+ * @WLAN_BS_STATUS_REJECTED: Bearer switch request rejected
+ * @WLAN_BS_STATUS_COMPLETED: Bearer switch request completed
+ * @WLAN_BS_STATUS_INVALID: Invalid bearer switch request
+ */
+enum bearer_switch_status {
+	WLAN_BS_STATUS_REJECTED = 0,
+	WLAN_BS_STATUS_COMPLETED = 1,
+	WLAN_BS_STATUS_INVALID,
+};
+
+/**
+ * enum bearer_switch_req_source: Bearer switch requester source
+ * @BEARER_SWITCH_REQ_CONNECT: Bearer switch requester is connect
+ * @BEARER_SWITCH_REQ_CSA: Bearer switch requester is CSA
+ * @BEARER_SWITCH_REQ_FW: Bearer switch requester is FW
+ * @BEARER_SWITCH_REQ_MAX: Indicates MAX bearer switch requester
+ */
+enum bearer_switch_req_source {
+	BEARER_SWITCH_REQ_CONNECT,
+	BEARER_SWITCH_REQ_CSA,
+	BEARER_SWITCH_REQ_FW,
+	BEARER_SWITCH_REQ_MAX,
 };
 
  /**
-  * typedef requester_callback() - Callback function, which will be invoked with
-  * the bearer switch request status.
-  * @psoc: Psoc pointer
-  * @request_id: Request ID
-  * @status: Status of the bearer switch request
-  * @request_params: Request params for the bearer switch request
-  *
-  * Return: None
-  */
-
-typedef void (*requester_callback)(struct wlan_objmgr_psoc *psoc,
-				    uint8_t vdev_id, uint32_t request_id,
-				    QDF_STATUS status,
-				    void *request_params);
+ * typedef bearer_switch_requester_cb() - Callback function, which will
+ * be invoked with the bearer switch request status.
+ * @psoc: Psoc pointer
+ * @vdev_id: vdev id of the requester
+ * @request_id: Request ID
+ * @status: Status of the bearer switch request
+ * @req_value: Request value for the bearer switch request
+ * @request_params: Request params for the bearer switch request
+ *
+ * Return: None
+ */
+typedef void (*bearer_switch_requester_cb)(struct wlan_objmgr_psoc *psoc,
+					   uint8_t vdev_id,
+					   wlan_bs_req_id request_id,
+					   QDF_STATUS status,
+					   uint32_t req_value,
+					   void *request_params);
+
+/**
+ * struct wlan_bearer_switch_request - Data structure to store the bearer switch
+ * request
+ * @vdev_id: Vdev id of the requester
+ * @request_id: Unique value to identify the request
+ * @req_type: Type of the request,  bearer switch to wlan or bearer switch
+ * to non-wlan
+ * @source: Bearer switch request source
+ * @requester_cb: Callback which needs to be invoked to indicate the status of
+ * the request to the requester, this callback will be passed by the requester
+ * when requester will send the request.
+ * @arg_value: argument value passed by requester, this will be returned back
+ * in the callback
+ * @arg: Argument passed by requester, this will be returned back in the
+ * callback
+ */
+struct wlan_bearer_switch_request {
+	uint8_t vdev_id;
+	wlan_bs_req_id request_id;
+	enum bearer_switch_req_type req_type;
+	enum bearer_switch_req_source source;
+	bearer_switch_requester_cb requester_cb;
+	uint32_t arg_value;
+	void *arg;
+};
+
+/**
+ * struct ll_sap_ops - ll_sap osif callbacks
+ * @ll_sap_send_audio_transport_switch_req_cb: Send audio transport request to
+ * userspace
+ */
+struct ll_sap_ops {
+		void (*ll_sap_send_audio_transport_switch_req_cb)(
+					struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type);
+};
 
 #endif /* _WLAN_LL_LT_SAP_BEARER_SWITCH_PUBLIC_STRUCTS_H_ */

+ 53 - 3
components/umac/mlme/sap/ll_sap/dispatcher/inc/wlan_ll_sap_ucfg_api.h

@@ -22,6 +22,7 @@
 
 #ifndef _WLAN_LL_SAP_UCFG_API_H_
 #define _WLAN_LL_SAP_UCFG_API_H_
+#include "wlan_ll_sap_public_structs.h"
 
 #ifdef WLAN_FEATURE_LL_LT_SAP
 
@@ -49,12 +50,43 @@ bool ucfg_is_ll_lt_sap_supported(void);
 /**
  * ucfg_ll_lt_sap_request_for_audio_transport_switch() - Request to switch the
  * audio transport medium
- * @transport_switch_type: Requested transport switch type
+ * @vdev: Vdev on which the request is received
+ * @req_type: Requested transport switch type
  *
  * Return: Accepted/Rejected
  */
 QDF_STATUS ucfg_ll_lt_sap_request_for_audio_transport_switch(
-						uint8_t transport_switch_type);
+					struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type);
+
+/**
+ * ucfg_ll_lt_sap_deliver_audio_transport_switch_resp() - Deliver audio
+ * transport switch response
+ * @vdev: Vdev on which the request is received
+ * @req_type: Transport switch type for which the response is received
+ * @status: Status of the response
+ *
+ * Return: None
+ */
+void ucfg_ll_lt_sap_deliver_audio_transport_switch_resp(
+					struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type,
+					enum bearer_switch_status status);
+
+/**
+ * ucfg_ll_sap_register_cb() - Register ll_sap osif callbacks
+ * @ll_sap_global_ops: Ops which needs to be registered
+ *
+ * Return: None
+ */
+void ucfg_ll_sap_register_cb(struct ll_sap_ops *ll_sap_global_ops);
+
+/**
+ * ucfg_ll_sap_unregister_cb() - Un-register ll_sap osif callbacks
+ *
+ * Return: None
+ */
+void ucfg_ll_sap_unregister_cb(void);
 
 #else
 static inline QDF_STATUS ucfg_ll_sap_init(void)
@@ -73,11 +105,29 @@ static inline bool ucfg_is_ll_lt_sap_supported(void)
 }
 
 static inline QDF_STATUS
-ucfg_ll_lt_sap_request_for_audio_transport_switch(uint8_t transport_switch_type)
+ucfg_ll_lt_sap_request_for_audio_transport_switch(
+					struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type)
 {
 	return QDF_STATUS_E_INVAL;
 }
 
+static inline void
+ucfg_ll_lt_sap_deliver_audio_transport_switch_resp(
+					struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type,
+					enum bearer_switch_status status)
+{
+}
+
+static inline void ucfg_ll_sap_register_cb(struct ll_sap_ops *ll_sap_global_ops)
+{
+}
+
+static inline void ucfg_ll_sap_unregister_cb(void)
+{
+}
+
 #endif /* WLAN_FEATURE_LL_LT_SAP */
 #endif /* _WLAN_LL_SAP_UCFG_API_H_ */
 

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

@@ -17,8 +17,139 @@
 #include "wlan_ll_sap_api.h"
 #include <../../core/src/wlan_ll_lt_sap_bearer_switch.h>
 #include <../../core/src/wlan_ll_lt_sap_main.h>
+#include "wlan_cm_api.h"
+#include "wlan_policy_mgr_ll_sap.h"
+#include "wlan_policy_mgr_api.h"
 
-uint32_t wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_vdev *vdev)
+wlan_bs_req_id
+wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_psoc *psoc)
 {
-	return ll_lt_sap_bearer_switch_get_id(vdev);
+	return ll_lt_sap_bearer_switch_get_id(psoc);
+}
+
+QDF_STATUS
+wlan_ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
+				struct wlan_bearer_switch_request *bs_request)
+{
+	return ll_lt_sap_switch_bearer_to_ble(psoc, bs_request);
+}
+
+static void
+connect_start_bearer_switch_requester_cb(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id,
+					 wlan_bs_req_id request_id,
+					 QDF_STATUS status, uint32_t req_value,
+					 void *request_params)
+{
+	wlan_cm_id cm_id = req_value;
+
+	wlan_cm_bearer_switch_resp(psoc, vdev_id, cm_id, status);
+}
+
+QDF_STATUS
+wlan_ll_sap_switch_bearer_on_sta_connect_start(struct wlan_objmgr_psoc *psoc,
+					       qdf_list_t *scan_list,
+					       uint8_t vdev_id,
+					       wlan_cm_id cm_id)
+{
+	struct scan_cache_node *scan_node = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	uint32_t ch_freq = 0;
+	struct scan_cache_entry *entry;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_bearer_switch_request bs_request = {0};
+	qdf_freq_t ll_lt_sap_freq;
+	bool is_bearer_switch_required = false;
+	QDF_STATUS status = QDF_STATUS_E_ALREADY;
+	uint8_t vdev_id;
+
+	vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev(psoc);
+	/* LL_LT SAP is not present, bearer switch is not required */
+	if (vdev_id == WLAN_INVALID_VDEV_ID)
+		return status;
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_LL_SAP_ID);
+	if (!vdev)
+		return status;
+
+	if (!scan_list || !qdf_list_size(scan_list))
+		goto rel_ref;
+
+	ll_lt_sap_freq = policy_mgr_get_lt_ll_sap_freq(psoc);
+	qdf_list_peek_front(scan_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(scan_list, cur_node, &next_node);
+
+		scan_node = qdf_container_of(cur_node, struct scan_cache_node,
+					     node);
+		entry = scan_node->entry;
+		ch_freq = entry->channel.chan_freq;
+
+		/*
+		 * Switch the bearer in case of SCC/MCC for LL_LT SAP
+		 */
+		if (policy_mgr_2_freq_always_on_same_mac(psoc, ch_freq,
+							 ll_lt_sap_freq)) {
+			ll_sap_debug("Scan list has BSS of freq %d on same mac with ll_lt sap %d",
+				     ch_freq, ll_lt_sap_freq);
+			is_bearer_switch_required = true;
+			break;
+		}
+
+		ch_freq = 0;
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	if (!is_bearer_switch_required)
+		goto rel_ref;
+
+	bs_request.vdev_id = vdev_id;
+	bs_request.request_id = ll_lt_sap_bearer_switch_get_id(psoc);
+	bs_request.req_type = WLAN_BS_REQ_TO_NON_WLAN;
+	bs_request.source = BEARER_SWITCH_REQ_CONNECT;
+	bs_request.requester_cb = connect_start_bearer_switch_requester_cb;
+	bs_request.arg_value = cm_id;
+
+	status = ll_lt_sap_switch_bearer_to_ble(psoc, &bs_request);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		status = QDF_STATUS_E_ALREADY;
+rel_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LL_SAP_ID);
+
+	return status;
+}
+
+static void connect_complete_bearer_switch_requester_cb(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id,
+						wlan_bs_req_id request_id,
+						QDF_STATUS status,
+						uint32_t req_value,
+						void *request_params)
+{
+	/* Drop this response as no action is required */
+}
+
+QDF_STATUS wlan_ll_sap_switch_bearer_on_sta_connect_complete(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id)
+{
+	struct wlan_bearer_switch_request bs_request = {0};
+	QDF_STATUS status;
+
+	bs_request.vdev_id = vdev_id;
+	bs_request.request_id = ll_lt_sap_bearer_switch_get_id(psoc);
+	bs_request.req_type = WLAN_BS_REQ_TO_WLAN;
+	bs_request.source = BEARER_SWITCH_REQ_CONNECT;
+	bs_request.requester_cb = connect_complete_bearer_switch_requester_cb;
+
+	status = ll_lt_sap_switch_bearer_to_wlan(psoc, &bs_request);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_ALREADY;
+
+	return QDF_STATUS_SUCCESS;
 }

+ 22 - 3
components/umac/mlme/sap/ll_sap/dispatcher/src/wlan_ll_sap_ucfg_api.c

@@ -21,6 +21,7 @@
  */
 #include "../../core/src/wlan_ll_sap_main.h"
 #include "../../core/src/wlan_ll_lt_sap_main.h"
+#include "../../core/src/wlan_ll_lt_sap_bearer_switch.h"
 #include <wlan_ll_sap_ucfg_api.h>
 
 QDF_STATUS ucfg_ll_sap_init(void)
@@ -39,9 +40,27 @@ bool ucfg_is_ll_lt_sap_supported(void)
 }
 
 QDF_STATUS ucfg_ll_lt_sap_request_for_audio_transport_switch(
-						uint8_t transport_switch_type)
+					struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type)
 {
-	return ll_lt_sap_request_for_audio_transport_switch(
-							transport_switch_type);
+	return ll_lt_sap_request_for_audio_transport_switch(vdev, req_type);
 }
 
+void ucfg_ll_lt_sap_deliver_audio_transport_switch_resp(
+					struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type,
+					enum bearer_switch_status status)
+{
+	ll_lt_sap_deliver_audio_transport_switch_resp(vdev, req_type,
+						      status);
+}
+
+void ucfg_ll_sap_register_cb(struct ll_sap_ops *ll_sap_global_ops)
+{
+	ll_sap_register_os_if_cb(ll_sap_global_ops);
+}
+
+void ucfg_ll_sap_unregister_cb(void)
+{
+	ll_sap_unregister_os_if_cb();
+}

+ 4 - 0
configs/config_to_feature.h

@@ -1460,6 +1460,10 @@
 #define QCA_WIFI_EMULATION (1)
 #endif
 
+#ifdef CONFIG_SAP_MULTI_LINK_EMULATION
+#define SAP_MULTI_LINK_EMULATION (1)
+#endif
+
 #ifdef CONFIG_QCA6290_HEADERS_DEF
 #define QCA6290_HEADERS_DEF (1)
 #endif

+ 4 - 0
configs/peach_defconfig

@@ -51,6 +51,7 @@ CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y
 #Enable KIWI based Configs
 ifeq ($(CONFIG_CNSS_EMULATION), y)
 	CONFIG_QCA_WIFI_EMULATION := y
+	CONFIG_SAP_MULTI_LINK_EMULATION := y
 endif
 CONFIG_EMULATION_2_0 := y
 CONFIG_DIRECT_BUF_RX_ENABLE := y
@@ -686,6 +687,9 @@ CONFIG_WIFI_POS_LEGACY := y
 endif
 
 CONFIG_CP_STATS := y
+
+CONFIG_QCA_TARGET_IF_MLME := y
+
 CONFIG_FEATURE_INTEROP_ISSUES_AP := y
 
 CONFIG_FEATURE_WLAN_WAPI := y

+ 1 - 0
configs/sun_consolidate_kiwi-v2_defconfig

@@ -31,3 +31,4 @@ CONFIG_WLAN_RECORD_RX_PADDR=y
 CONFIG_QDF_TEST=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_FEATURE_WLM_STATS=y
+CONFIG_WLAN_TRACE_HIDE_MAC_ADDRESS_DISABLE=y

+ 9 - 1
configs/sun_gki_kiwi-v2_defconfig

@@ -46,6 +46,8 @@ CONFIG_DP_PKT_ADD_TIMESTAMP=y
 CONFIG_DP_PKT_STATS_PER_LMAC=y
 CONFIG_DP_RX_BUFFER_POOL_ALLOC_THRES=5
 CONFIG_DP_RX_BUFFER_POOL_SIZE=128
+CONFIG_DP_RX_REFILL_BUFF_POOL_SIZE=2048
+CONFIG_DP_RX_REFILL_THRD_THRESHOLD=512
 CONFIG_DP_RX_DROP_RAW_FRM=y
 CONFIG_DP_RX_PKT_NO_PEER_DELIVER=y
 CONFIG_DP_RX_SPECIAL_FRAME_NEED=y
@@ -118,6 +120,7 @@ CONFIG_HIF_PCI=y
 CONFIG_HIF_REG_WINDOW_SUPPORT=y
 CONFIG_HOST_OPCLASS=y
 CONFIG_HTT_PADDR64=y
+CONFIG_IPA_OFFLOAD=y
 CONFIG_IPA_OPT_WIFI_DP=y
 CONFIG_IPA_SET_RESET_TX_DB_PA=y
 CONFIG_KIWI_HEADERS_DEF=y
@@ -222,7 +225,6 @@ CONFIG_WLAN_DEBUGFS=y
 CONFIG_WLAN_DFS_MASTER_ENABLE=y
 CONFIG_WLAN_DFS_STATIC_MEM_ALLOC=y
 CONFIG_WLAN_DIAG_VERSION=y
-CONFIG_WLAN_DISABLE_EXPORT_SYMBOL=y
 CONFIG_WLAN_DL_MODES=y
 CONFIG_WLAN_DP_DISABLE_TCL_CMD_CRED_SRNG=y
 CONFIG_WLAN_DP_DISABLE_TCL_STATUS_SRNG=y
@@ -328,10 +330,14 @@ CONFIG_WLAN_SYSFS_TDLS_PEERS=y
 CONFIG_WLAN_SYSFS_TEMPERATURE=y
 CONFIG_WLAN_SYSFS_TX_STBC=y
 CONFIG_WLAN_SYSFS_WLAN_DBG=y
+CONFIG_WLAN_SYSFS_BITRATES=y
+CONFIG_WLAN_SYSFS_RF_TEST_MODE=y
 CONFIG_WLAN_THERMAL_CFG=y
 CONFIG_WLAN_THERMAL_MULTI_CLIENT_SUPPORT=y
 CONFIG_WLAN_TRACEPOINTS=y
+CONFIG_WLAN_TSF_AUTO_REPORT=y
 CONFIG_WLAN_TSF_UPLINK_DELAY=y
+CONFIG_WLAN_TX_LATENCY_STATS=y
 CONFIG_WLAN_TWT_CONVERGED=y
 CONFIG_WLAN_TWT_SAP_PDEV_COUNT=y
 CONFIG_WLAN_TWT_SAP_STA_COUNT=y
@@ -372,6 +378,7 @@ CONFIG_CFG80211_MLD_AP_STA_CONNECT_UPSTREAM_SUPPORT=y
 CONFIG_DP_MULTIPASS_SUPPORT=y
 CONFIG_WLAN_DP_VDEV_NO_SELF_PEER=y
 CONFIG_WLAN_FEATURE_AFFINITY_MGR=y
+CONFIG_WALT_GET_CPU_TAKEN_SUPPORT=y
 CONFIG_DP_MLO_LINK_STATS_SUPPORT=y
 CONFIG_HIF_DEBUG=y
 CONFIG_WLAN_OBJMGR_DEBUG=y
@@ -385,3 +392,4 @@ CONFIG_BUS_AUTO_SUSPEND=y
 CONFIG_CNSS_OUT_OF_TREE=y
 CONFIG_SMP=y
 CONFIG_RPS=y
+CONFIG_BCN_RATECODE_ENABLE=y

+ 10 - 1
configs/sun_gki_peach_defconfig

@@ -47,6 +47,8 @@ CONFIG_DP_PKT_ADD_TIMESTAMP=y
 CONFIG_DP_PKT_STATS_PER_LMAC=y
 CONFIG_DP_RX_BUFFER_POOL_ALLOC_THRES=5
 CONFIG_DP_RX_BUFFER_POOL_SIZE=128
+CONFIG_DP_RX_REFILL_BUFF_POOL_SIZE=2048
+CONFIG_DP_RX_REFILL_THRD_THRESHOLD=512
 CONFIG_DP_RX_DROP_RAW_FRM=y
 CONFIG_DP_RX_PKT_NO_PEER_DELIVER=y
 CONFIG_DP_RX_SPECIAL_FRAME_NEED=y
@@ -119,6 +121,7 @@ CONFIG_HIF_PCI=y
 CONFIG_HIF_REG_WINDOW_SUPPORT=y
 CONFIG_HOST_OPCLASS=y
 CONFIG_HTT_PADDR64=y
+CONFIG_IPA_OFFLOAD=y
 CONFIG_IPA_OPT_WIFI_DP=y
 CONFIG_IPA_SET_RESET_TX_DB_PA=y
 CONFIG_KIWI_HEADERS_DEF=y
@@ -223,7 +226,6 @@ CONFIG_WLAN_DEBUGFS=y
 CONFIG_WLAN_DFS_MASTER_ENABLE=y
 CONFIG_WLAN_DFS_STATIC_MEM_ALLOC=y
 CONFIG_WLAN_DIAG_VERSION=y
-CONFIG_WLAN_DISABLE_EXPORT_SYMBOL=y
 CONFIG_WLAN_DL_MODES=y
 CONFIG_WLAN_DP_DISABLE_TCL_CMD_CRED_SRNG=y
 CONFIG_WLAN_DP_DISABLE_TCL_STATUS_SRNG=y
@@ -329,10 +331,14 @@ CONFIG_WLAN_SYSFS_TDLS_PEERS=y
 CONFIG_WLAN_SYSFS_TEMPERATURE=y
 CONFIG_WLAN_SYSFS_TX_STBC=y
 CONFIG_WLAN_SYSFS_WLAN_DBG=y
+CONFIG_WLAN_SYSFS_BITRATES=y
+CONFIG_WLAN_SYSFS_RF_TEST_MODE=y
 CONFIG_WLAN_THERMAL_CFG=y
 CONFIG_WLAN_THERMAL_MULTI_CLIENT_SUPPORT=y
 CONFIG_WLAN_TRACEPOINTS=y
+CONFIG_WLAN_TSF_AUTO_REPORT=y
 CONFIG_WLAN_TSF_UPLINK_DELAY=y
+CONFIG_WLAN_TX_LATENCY_STATS=y
 CONFIG_WLAN_TWT_CONVERGED=y
 CONFIG_WLAN_TWT_SAP_PDEV_COUNT=y
 CONFIG_WLAN_TWT_SAP_STA_COUNT=y
@@ -370,6 +376,7 @@ CONFIG_CFG80211_MLD_AP_STA_CONNECT_UPSTREAM_SUPPORT=y
 CONFIG_DP_MULTIPASS_SUPPORT=y
 CONFIG_WLAN_DP_VDEV_NO_SELF_PEER=y
 CONFIG_WLAN_FEATURE_AFFINITY_MGR=y
+CONFIG_WALT_GET_CPU_TAKEN_SUPPORT=y
 CONFIG_DP_MLO_LINK_STATS_SUPPORT=y
 CONFIG_HIF_DEBUG=y
 CONFIG_WLAN_OBJMGR_DEBUG=y
@@ -383,3 +390,5 @@ CONFIG_BUS_AUTO_SUSPEND=y
 CONFIG_CNSS_OUT_OF_TREE=y
 CONFIG_SMP=y
 CONFIG_RPS=y
+CONFIG_BCN_RATECODE_ENABLE=y
+CONFIG_4_BYTES_TLV_TAG=y

+ 2 - 2
core/hdd/inc/wlan_hdd_cfg.h

@@ -490,7 +490,7 @@ int hdd_set_rx_stbc(struct wlan_hdd_link_info *link_info, int value);
 
 /**
  * hdd_update_channel_width() - Update adapter channel width settings
- * @adapter: adapter being modified
+ * @link_info: Link info in HDD adapter
  * @chwidth: new channel width of enum eSirMacHTChannelWidth
  * @bonding_mode: channel bonding mode of the new channel width
  * @link_id: mlo link id
@@ -498,7 +498,7 @@ int hdd_set_rx_stbc(struct wlan_hdd_link_info *link_info, int value);
  *
  * Return: 0 on success, negative errno on failure
  */
-int hdd_update_channel_width(struct hdd_adapter *adapter,
+int hdd_update_channel_width(struct wlan_hdd_link_info *link_info,
 			     enum eSirMacHTChannelWidth chwidth,
 			     uint32_t bonding_mode, uint8_t link_id,
 			     bool is_restore);

+ 6 - 0
core/hdd/inc/wlan_hdd_driver_ops.h

@@ -22,9 +22,15 @@
 #define __WLAN_HDD_DRIVER_OPS_H__
 
 #include "hif.h"
+#include <qdf_types.h>
 
 struct hdd_context;
 
+#define wlan_hdd_trigger_cds_recovery(reason) \
+	__wlan_hdd_trigger_cds_recovery(reason, __func__, __LINE__)
+
+void __wlan_hdd_trigger_cds_recovery(enum qdf_hang_reason reason,
+				     const char *func, const uint32_t line);
 /**
  * DOC: wlan_hdd_driver_ops.h
  *

+ 0 - 12
core/hdd/inc/wlan_hdd_ll_lt_sap.h

@@ -57,16 +57,4 @@ int wlan_hdd_cfg80211_ll_lt_sap_transport_switch(struct wiphy *wiphy,
 						 const void *data,
 						 int data_len);
 
-/**
- * wlan_hdd_send_audio_transport_switch_req_event() - Audio transport switch
- * event
- * @adapter:              pointer to adapter structure.
- * @audio_switch_mode:    audio switch mode.
- *
- * Return:   Return the Success or Failure code.
- */
-int wlan_hdd_send_audio_transport_switch_req_event(struct hdd_adapter *adapter,
-						   uint8_t audio_switch_mode);
-
-
 #endif /* __WLAN_HDD_LL_LT_SAP_H */

+ 13 - 0
core/hdd/inc/wlan_hdd_power.h

@@ -683,4 +683,17 @@ void hdd_enable_icmp_offload(struct hdd_adapter *adapter,
 {}
 #endif /* FEATURE_ICMP_OFFLOAD */
 
+#if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
+int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
+			bool allow_power_save, int timeout,
+			int link_id);
+#else
+static inline
+int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
+			bool allow_power_save, int timeout,
+			int link_id)
+{
+        return 0;
+}
+#endif
 #endif /* __WLAN_HDD_POWER_H */

+ 22 - 29
core/hdd/src/wlan_hdd_cfg.c

@@ -2412,36 +2412,32 @@ hdd_convert_chwidth_to_phy_chwidth(enum eSirMacHTChannelWidth chwidth)
 
 /**
  * hdd_update_bss_rate_flags() - update bss rate flag as per new channel width
- * @adapter: adapter being modified
+ * @link_info: Link info in HDD adapter
  * @psoc: psoc common object
  * @cw: channel width for which bss rate flag being updated
  *
  * Return: QDF_STATUS
  */
-static QDF_STATUS hdd_update_bss_rate_flags(struct hdd_adapter *adapter,
-					    struct wlan_objmgr_psoc *psoc,
-					    enum phy_ch_width cw)
+static QDF_STATUS
+hdd_update_bss_rate_flags(struct wlan_hdd_link_info *link_info,
+			  struct wlan_objmgr_psoc *psoc, enum phy_ch_width cw)
 {
 	struct hdd_station_ctx *hdd_sta_ctx;
 	uint8_t eht_present, he_present, vht_present, ht_present;
 
-	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
-	if (!hdd_sta_ctx) {
-		hdd_err("hdd_sta_ctx is null");
-		return QDF_STATUS_E_INVAL;
-	}
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
 
 	eht_present = hdd_sta_ctx->conn_info.conn_flag.eht_present;
 	he_present = hdd_sta_ctx->conn_info.conn_flag.he_present;
 	vht_present = hdd_sta_ctx->conn_info.conn_flag.vht_present;
 	ht_present = hdd_sta_ctx->conn_info.conn_flag.ht_present;
 
-	return ucfg_mlme_update_bss_rate_flags(psoc, adapter->deflink->vdev_id,
+	return ucfg_mlme_update_bss_rate_flags(psoc, link_info->vdev_id,
 					       cw, eht_present, he_present,
 					       vht_present, ht_present);
 }
 
-int hdd_update_channel_width(struct hdd_adapter *adapter,
+int hdd_update_channel_width(struct wlan_hdd_link_info *link_info,
 			     enum eSirMacHTChannelWidth chwidth,
 			     uint32_t bonding_mode, uint8_t link_id,
 			     bool is_restore)
@@ -2451,25 +2447,26 @@ int hdd_update_channel_width(struct hdd_adapter *adapter,
 	int ret;
 	enum phy_ch_width ch_width = CH_WIDTH_INVALID;
 	QDF_STATUS status;
+	uint8_t vdev_id = link_info->vdev_id;
 
-	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
 	if (!hdd_ctx) {
 		hdd_err("hdd_ctx failure");
 		return -EINVAL;
 	}
 
 	if (ucfg_mlme_is_chwidth_with_notify_supported(hdd_ctx->psoc) &&
-	    hdd_cm_is_vdev_connected(adapter->deflink)) {
+	    hdd_cm_is_vdev_connected(link_info)) {
 		ch_width = hdd_convert_chwidth_to_phy_chwidth(chwidth);
 		hdd_debug("vdev %d : process update ch width request to %d",
-			  adapter->deflink->vdev_id, ch_width);
-		status =
-		    ucfg_mlme_send_ch_width_update_with_notify(hdd_ctx->psoc,
-					adapter->deflink->vdev_id, ch_width,
-					link_id);
+			  vdev_id, ch_width);
+		status = ucfg_mlme_send_ch_width_update_with_notify(hdd_ctx->psoc,
+								    vdev_id,
+								    ch_width,
+								    link_id);
 		if (QDF_IS_STATUS_ERROR(status))
 			return -EIO;
-		status = hdd_update_bss_rate_flags(adapter, hdd_ctx->psoc,
+		status = hdd_update_bss_rate_flags(link_info, hdd_ctx->psoc,
 						   ch_width);
 		if (QDF_IS_STATUS_ERROR(status))
 			return -EIO;
@@ -2479,28 +2476,24 @@ int hdd_update_channel_width(struct hdd_adapter *adapter,
 	if (!sme_config)
 		return -ENOMEM;
 
-	ret = wma_cli_set_command(adapter->deflink->vdev_id,
-				  wmi_vdev_param_chwidth, chwidth, VDEV_CMD);
+	ret = wma_cli_set_command(vdev_id, wmi_vdev_param_chwidth,
+				  chwidth, VDEV_CMD);
 	if (ret)
 		goto free_config;
 
 	sme_get_config_param(hdd_ctx->mac_handle, sme_config);
 	if (is_restore) {
 		sme_config->csr_config.channelBondingMode5GHz =
-			cfg_get(adapter->hdd_ctx->psoc,
-				CFG_CHANNEL_BONDING_MODE_5GHZ);
+			cfg_get(hdd_ctx->psoc, CFG_CHANNEL_BONDING_MODE_5GHZ);
 		sme_config->csr_config.channelBondingMode24GHz =
-			cfg_get(adapter->hdd_ctx->psoc,
-				CFG_CHANNEL_BONDING_MODE_24GHZ);
+			cfg_get(hdd_ctx->psoc, CFG_CHANNEL_BONDING_MODE_24GHZ);
 	} else {
 		sme_config->csr_config.channelBondingMode5GHz = bonding_mode;
 		sme_config->csr_config.channelBondingMode24GHz = bonding_mode;
 	}
 	sme_update_config(hdd_ctx->mac_handle, sme_config);
-	sme_set_he_bw_cap(hdd_ctx->mac_handle,
-			  adapter->deflink->vdev_id, chwidth);
-	sme_set_eht_bw_cap(hdd_ctx->mac_handle,
-			   adapter->deflink->vdev_id, chwidth);
+	sme_set_he_bw_cap(hdd_ctx->mac_handle, vdev_id, chwidth);
+	sme_set_eht_bw_cap(hdd_ctx->mac_handle, vdev_id, chwidth);
 free_config:
 	qdf_mem_free(sme_config);
 	return ret;

+ 88 - 12
core/hdd/src/wlan_hdd_cfg80211.c

@@ -284,6 +284,11 @@
 #define WLAN_CIPHER_SUITE_GCMP_256 0x000FAC09
 #endif
 
+/* Default number of Simultaneous Transmit */
+#define DEFAULT_MAX_STR_LINK_COUNT 1
+/* Maximum number of Simultaneous Transmit */
+#define MAX_STR_LINK_COUNT 2
+
 static const u32 hdd_gcmp_cipher_suits[] = {
 	WLAN_CIPHER_SUITE_GCMP,
 	WLAN_CIPHER_SUITE_GCMP_256,
@@ -5093,6 +5098,8 @@ __wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
 	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
 	QDF_STATUS status;
 	int ret_val;
+	uint8_t max_assoc_cnt = 0;
+	uint8_t max_str_link_count = 0;
 
 	uint8_t feature_flags[(NUM_QCA_WLAN_VENDOR_FEATURES + 7) / 8] = {0};
 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
@@ -5235,7 +5242,28 @@ __wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
 			MAX_CONCURRENT_CHAN_ON_5G))
 		goto nla_put_failure;
 
-	hdd_debug("feature flags:");
+	max_assoc_cnt = wlan_mlme_get_sta_mlo_conn_max_num(hdd_ctx->psoc);
+	if (max_assoc_cnt) {
+		if (nla_put_u8(
+			skb,
+			QCA_WLAN_VENDOR_ATTR_MLO_CAPABILITY_MAX_ASSOCIATION_COUNT,
+			max_assoc_cnt))
+			goto nla_put_failure;
+
+		max_str_link_count = DEFAULT_MAX_STR_LINK_COUNT;
+
+		if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) ||
+		    policy_mgr_is_hw_sbs_capable(hdd_ctx->psoc))
+			max_str_link_count = MAX_STR_LINK_COUNT;
+
+		if (nla_put_u8(skb,
+			       QCA_WLAN_VENDOR_ATTR_MLO_CAPABILITY_MAX_STR_LINK_COUNT,
+			       max_str_link_count))
+			goto nla_put_failure;
+	}
+
+	hdd_debug("max_assoc_cnt %d max_str_link_count %d",
+		  max_assoc_cnt, max_str_link_count);
 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
 			   feature_flags, sizeof(feature_flags));
 
@@ -8660,6 +8688,8 @@ wlan_hdd_wifi_test_config_policy[
 			.type = NLA_U8},
 		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_EHT_MLO_STR_TX] = {
 			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_EHT_MLO_LINK_POWER_SAVE] = {
+			.type = NLA_NESTED},
 		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MLD_ID_ML_PROBE_REQ] = {
 			.type = NLA_U8},
 };
@@ -10986,16 +11016,15 @@ static uint32_t hdd_mac_chwidth_to_bonding_mode(
 	return bonding_mode;
 }
 
-int hdd_set_mac_chan_width(struct hdd_adapter *adapter,
+int hdd_set_mac_chan_width(struct wlan_hdd_link_info *link_info,
 			   enum eSirMacHTChannelWidth chwidth,
-			   uint8_t link_id,
-			   bool is_restore)
+			   uint8_t link_id, bool is_restore)
 {
 	uint32_t bonding_mode;
 
 	bonding_mode = hdd_mac_chwidth_to_bonding_mode(chwidth);
 
-	return hdd_update_channel_width(adapter, chwidth,
+	return hdd_update_channel_width(link_info, chwidth,
 					bonding_mode, link_id, is_restore);
 }
 
@@ -11070,8 +11099,7 @@ skip_mlo:
 		return -EINVAL;
 	}
 set_chan_width:
-	return hdd_set_mac_chan_width(link_info->adapter,
-				      chwidth, link_id, false);
+	return hdd_set_mac_chan_width(link_info, chwidth, link_id, false);
 }
 
 /**
@@ -13312,6 +13340,31 @@ static int hdd_test_config_6ghz_security_test_mode(struct hdd_context *hdd_ctx,
 	return 0;
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static void wlan_hdd_set_listen_interval(struct hdd_context *hdd_ctx,
+					 struct hdd_adapter *adapter)
+{
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	enum wlan_eht_mode eht_mode;
+	uint16_t max_simult_link_num;
+
+	ucfg_mlme_get_eht_mode(psoc, &eht_mode);
+	max_simult_link_num = wlan_mlme_get_sta_mlo_simultaneous_links(psoc);
+
+	if (eht_mode == WLAN_EHT_MODE_MLSR && max_simult_link_num == 0)
+		sme_set_listen_interval(hdd_ctx->mac_handle,
+					adapter->deflink->vdev_id);
+
+	hdd_debug("EHT mode: %d, max simultaneous link num: %d",
+		  eht_mode, max_simult_link_num);
+}
+#else
+static inline void wlan_hdd_set_listen_interval(struct hdd_context *hdd_ctx,
+					        struct hdd_adapter *adapter)
+{
+}
+#endif
+
 /**
  * __wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration
  * vendor command
@@ -13351,7 +13404,7 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
 	uint8_t link_id = 0xFF;
 	struct keep_alive_req keep_alive_req = {0};
 	struct set_wfatest_params wfa_param = {0};
-	struct wlan_hdd_link_info *link_info = adapter->link_info;
+	struct wlan_hdd_link_info *link_info = adapter->deflink;
 	struct hdd_station_ctx *hdd_sta_ctx =
 			WLAN_HDD_GET_STATION_CTX_PTR(link_info);
 	uint8_t op_mode;
@@ -14065,7 +14118,7 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
 		sme_set_ru_242_tone_tx_cfg(hdd_ctx->mac_handle, cfg_val);
 		if (cfg_val)
 			hdd_update_channel_width(
-					adapter, eHT_CHANNEL_WIDTH_20MHZ,
+					link_info, eHT_CHANNEL_WIDTH_20MHZ,
 					WNI_CFG_CHANNEL_BONDING_MODE_DISABLE,
 					link_id, false);
 	}
@@ -14076,7 +14129,7 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
 		hdd_debug("EU SU PPDU type Tx enable: %d", cfg_val);
 		if (cfg_val) {
 			hdd_update_channel_width(
-					adapter, eHT_CHANNEL_WIDTH_20MHZ,
+					link_info, eHT_CHANNEL_WIDTH_20MHZ,
 					WNI_CFG_CHANNEL_BONDING_MODE_DISABLE,
 					link_id, false);
 			hdd_set_tx_stbc(link_info, 0);
@@ -14097,7 +14150,7 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
 					status);
 		} else {
 			hdd_update_channel_width(
-					adapter, eHT_CHANNEL_WIDTH_160MHZ,
+					link_info, eHT_CHANNEL_WIDTH_160MHZ,
 					link_id,
 					WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
 					false);
@@ -14471,11 +14524,34 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
 			hdd_err("Failed to send STR TX indication");
 	}
 
+	cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_EHT_MLO_LINK_POWER_SAVE;
+	if (tb[cmd_id]) {
+		struct nlattr *curr_attr;
+		int len;
+		uint8_t link_id, timeout = 0, num_links = 0;
+		bool allow_ps = true;
+
+		nla_for_each_nested(curr_attr, tb[cmd_id], len) {
+			if (nla_len(curr_attr) != sizeof(uint8_t)) {
+				hdd_err("len is not correct for idx %d",
+					num_links);
+				goto send_err;
+			}
+			link_id = nla_get_u8(curr_attr);
+			hdd_debug("link id[%d]: %d", num_links, link_id);
+			wlan_hdd_set_mlo_ps(adapter, allow_ps, timeout,
+					    link_id);
+			num_links++;
+		}
+
+		wlan_hdd_set_listen_interval(hdd_ctx, adapter);
+	}
+
 	cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MLD_ID_ML_PROBE_REQ;
 	if (tb[cmd_id]) {
 		cfg_val = nla_get_u8(tb[cmd_id]);
 		hdd_debug("MLD ID in ML probe request: %d", cfg_val);
-		ret_val = wlan_mlme_set_eht_mld_id(hdd_ctx->psoc, cfg_val);
+		ret_val = ucfg_mlme_set_eht_mld_id(hdd_ctx->psoc, cfg_val);
 		if (ret_val)
 			hdd_err("Failed to set MLD ID");
 	}

+ 3 - 4
core/hdd/src/wlan_hdd_cfg80211.h

@@ -975,17 +975,16 @@ int hdd_set_phy_mode(struct hdd_adapter *adapter,
 
 /**
  * hdd_set_mac_chan_width() - set channel width
- * @adapter: Handle to hdd_adapter
+ * @link_info: Link info in HDD adapter
  * @chwidth: given channel width
  * @link_id: mlo link id
  * @is_restore: is restore
  *
  * Return: 0 on success, negative errno on failure
  */
-int hdd_set_mac_chan_width(struct hdd_adapter *adapter,
+int hdd_set_mac_chan_width(struct wlan_hdd_link_info *link_info,
 			   enum eSirMacHTChannelWidth chwidth,
-			   uint8_t link_id,
-			   bool is_restore);
+			   uint8_t link_id, bool is_restore);
 
 /**
  * hdd_is_legacy_connection() - Is adapter connection is legacy

+ 35 - 5
core/hdd/src/wlan_hdd_cm_disconnect.c

@@ -482,7 +482,7 @@ static void hdd_cm_reset_udp_qos_upgrade_config(struct hdd_adapter *adapter)
 #ifdef WLAN_FEATURE_11BE
 static inline enum eSirMacHTChannelWidth get_max_bw(void)
 {
-	uint32_t max_bw = wma_get_eht_ch_width();
+	uint32_t max_bw = wma_get_orig_eht_ch_width();
 
 	if (max_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ)
 		return eHT_CHANNEL_WIDTH_320MHZ;
@@ -495,6 +495,27 @@ static inline enum eSirMacHTChannelWidth get_max_bw(void)
 	else
 		return eHT_CHANNEL_WIDTH_40MHZ;
 }
+
+static
+void wlan_hdd_re_enable_320mhz_6g_conection(struct hdd_context *hdd_ctx,
+					    enum phy_ch_width assoc_ch_width)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(hdd_ctx->psoc);
+	if (!mlme_obj)
+		return;
+	/*
+	 * Initial connection was in 320 MHz and if via SET_MAX_BANDWIDTH
+	 * command, current channel BW (des_chan->ch_width) gets modified
+	 * to less than 320MHz, driver disables 6 GHz connection by disabling
+	 * support_320mhz_6ghz EHT capability. So, in order to allow
+	 * re-connection (after disconnection) in 320 MHz, also re-enable
+	 * support_320mhz_6ghz EHT capability before disconnect complete.
+	 */
+	if (assoc_ch_width == CH_WIDTH_320MHZ)
+		mlme_obj->cfg.eht_caps.dot11_eht_cap.support_320mhz_6ghz = 1;
+}
 #else
 static inline enum eSirMacHTChannelWidth get_max_bw(void)
 {
@@ -509,12 +530,18 @@ static inline enum eSirMacHTChannelWidth get_max_bw(void)
 	else
 		return eHT_CHANNEL_WIDTH_40MHZ;
 }
+
+static
+void wlan_hdd_re_enable_320mhz_6g_conection(struct hdd_context *hdd_ctx,
+					    enum phy_ch_width assoc_ch_width)
+{
+}
 #endif
 
 static void hdd_cm_restore_ch_width(struct wlan_objmgr_vdev *vdev,
-				    struct hdd_adapter *adapter)
+				    struct wlan_hdd_link_info *link_info)
 {
-	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
 	struct mlme_legacy_priv *mlme_priv;
 	enum eSirMacHTChannelWidth max_bw;
 	struct wlan_channel *des_chan;
@@ -538,8 +565,11 @@ static void hdd_cm_restore_ch_width(struct wlan_objmgr_vdev *vdev,
 
 	cm_update_associated_ch_info(vdev, false);
 
+	if (des_chan->ch_width != assoc_ch_width)
+		wlan_hdd_re_enable_320mhz_6g_conection(hdd_ctx, assoc_ch_width);
+
 	max_bw = get_max_bw();
-	ret = hdd_set_mac_chan_width(adapter, max_bw, link_id, true);
+	ret = hdd_set_mac_chan_width(link_info, max_bw, link_id, true);
 	if (ret) {
 		hdd_err("vdev %d : fail to set max ch width", vdev_id);
 		return;
@@ -581,7 +611,7 @@ hdd_cm_disconnect_complete_post_user_update(struct wlan_objmgr_vdev *vdev,
 	 * bandwidth on disconnection so that post disconnection DUT can
 	 * connect in max BW.
 	 */
-	hdd_cm_restore_ch_width(vdev, adapter);
+	hdd_cm_restore_ch_width(vdev, link_info);
 	hdd_cm_set_default_wlm_mode(adapter);
 	__hdd_cm_disconnect_handler_post_user_update(link_info, vdev,
 						     rsp->req.req.source);

+ 26 - 6
core/hdd/src/wlan_hdd_driver_ops.c

@@ -1278,6 +1278,12 @@ hdd_to_pmo_wow_enable_params(struct wow_enable_params *in_params,
 	return 0;
 }
 
+void __wlan_hdd_trigger_cds_recovery(enum qdf_hang_reason reason,
+				     const char *func, const uint32_t line)
+{
+	__cds_trigger_recovery(reason, func, line);
+}
+
 /**
  * __wlan_hdd_bus_suspend() - handles platform suspend
  * @wow_params: collection of wow enable override parameters
@@ -1406,26 +1412,40 @@ static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params,
 
 resume_txrx:
 	status = ucfg_pmo_core_txrx_resume(hdd_ctx->psoc);
-	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_hdd_trigger_cds_recovery(QDF_RESUME_TIMEOUT);
+		return qdf_status_to_os_return(status);
+	}
 
 resume_hif:
 	status = hif_bus_resume(hif_ctx);
-	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_hdd_trigger_cds_recovery(QDF_RESUME_TIMEOUT);
+		return qdf_status_to_os_return(status);
+	}
 
 resume_pmo:
 	status = ucfg_pmo_psoc_bus_resume_req(hdd_ctx->psoc,
 					      type);
-	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_hdd_trigger_cds_recovery(QDF_RESUME_TIMEOUT);
+		return qdf_status_to_os_return(status);
+	}
 
 late_hif_resume:
 	status = hif_bus_late_resume(hif_ctx);
-	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_hdd_trigger_cds_recovery(QDF_RESUME_TIMEOUT);
+		return qdf_status_to_os_return(status);
+	}
 
 resume_dp:
 	status = ucfg_dp_bus_resume(dp_soc, OL_TXRX_PDEV_ID);
-	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_hdd_trigger_cds_recovery(QDF_RESUME_TIMEOUT);
+		return qdf_status_to_os_return(status);
+	}
 	hif_system_pm_set_state_on(hif_ctx);
-
 	return err;
 }
 

+ 42 - 67
core/hdd/src/wlan_hdd_ll_lt_sap.c

@@ -24,6 +24,7 @@
 #include "wlan_ll_sap_ucfg_api.h"
 #include "osif_sync.h"
 #include "wlan_hdd_cfg80211.h"
+#include "os_if_ll_sap.h"
 
 const struct nla_policy
 	wlan_hdd_ll_lt_sap_transport_switch_policy
@@ -53,9 +54,10 @@ __wlan_hdd_cfg80211_ll_lt_sap_transport_switch(struct wiphy *wiphy,
 	struct net_device *dev = wdev->netdev;
 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct wlan_objmgr_vdev *vdev;
 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_MAX + 1];
-	uint8_t transport_switch_type;
-	uint8_t transport_switch_status;
+	enum qca_wlan_audio_transport_switch_type transport_switch_type;
+	enum qca_wlan_audio_transport_switch_status transport_switch_status;
 	QDF_STATUS status;
 
 	hdd_enter_dev(dev);
@@ -65,97 +67,70 @@ __wlan_hdd_cfg80211_ll_lt_sap_transport_switch(struct wiphy *wiphy,
 		return -EPERM;
 	}
 
-	if (0 != wlan_hdd_validate_context(hdd_ctx))
+	if (wlan_hdd_validate_context(hdd_ctx))
 		return -EINVAL;
 
-	if (!adapter)
+	if (hdd_validate_adapter(adapter))
 		return -EINVAL;
 
+	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
+		return -EINVAL;
+
+	if (!policy_mgr_is_vdev_ll_lt_sap(hdd_ctx->psoc,
+					  adapter->deflink->vdev_id)) {
+		hdd_err("Command not allowed on vdev %d",
+			adapter->deflink->vdev_id);
+		return -EINVAL;
+	}
+
 	if (wlan_cfg80211_nla_parse(
 			tb, QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_MAX,
 			data, data_len,
 			wlan_hdd_ll_lt_sap_transport_switch_policy)) {
-		hdd_err("Invalid attribute");
+		hdd_err("vdev %d Invalid attribute", adapter->deflink->vdev_id);
 		return -EINVAL;
 	}
 
 	if (!tb[QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_TYPE]) {
-		hdd_err("attr transport switch type failed");
+		hdd_err("Vdev %d attr transport switch type failed",
+			adapter->deflink->vdev_id);
+		return -EINVAL;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc,
+						    adapter->deflink->vdev_id,
+						    WLAN_LL_SAP_ID);
+	if (!vdev) {
+		hdd_err("vdev %d not found", adapter->deflink->vdev_id);
 		return -EINVAL;
 	}
+
 	transport_switch_type = nla_get_u8(
 			tb[QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_TYPE]);
 
 	if (!tb[QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_STATUS]) {
-		status = ucfg_ll_lt_sap_request_for_audio_transport_switch(
-							transport_switch_type);
-		hdd_debug("Transport switch request type %d status %d",
-			  transport_switch_type, status);
+		status = osif_ll_lt_sap_request_for_audio_transport_switch(
+						vdev,
+						transport_switch_type);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LL_SAP_ID);
+		hdd_debug("Transport switch request type %d status %d vdev %d",
+			  transport_switch_type, status,
+			  adapter->deflink->vdev_id);
 		return qdf_status_to_os_return(status);
 	}
 
 	transport_switch_status = nla_get_u8(
 			tb[QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_STATUS]);
 
-	if (transport_switch_status ==
-		QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_COMPLETED) {
-		hdd_debug("Transport switch request completed");
-		return 0;
-	} else if (transport_switch_status ==
-		QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_REJECTED) {
-		hdd_debug("Transport switch request rejected");
-		return 0;
-	}
-
-	hdd_err("Invalid transport switch status");
-	return -EINVAL;
-}
-
-int wlan_hdd_send_audio_transport_switch_req_event(struct hdd_adapter *adapter,
-						   uint8_t audio_switch_mode)
-{
-	struct sk_buff *vendor_event;
-	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
-	uint32_t len;
-
-	hdd_enter();
-
-	if (wlan_hdd_validate_context(hdd_ctx)) {
-		hdd_err("Invalid context");
-		return -EINVAL;
-	}
-	if (hdd_validate_adapter(adapter)) {
-		hdd_err("Invalid adapter");
-		return -EINVAL;
-	}
-
-	len = nla_total_size(sizeof(uint8_t)) + NLMSG_HDRLEN;
-
-	vendor_event = wlan_cfg80211_vendor_event_alloc(
-			hdd_ctx->wiphy,
-			&adapter->wdev,
-			len,
-			QCA_NL80211_VENDOR_SUBCMD_AUDIO_TRANSPORT_SWITCH_INDEX,
-			GFP_KERNEL);
-
-	if (!vendor_event) {
-		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
-		return -ENOMEM;
-	}
-
-	if (nla_put_u8(vendor_event,
-		       QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_TYPE,
-		       audio_switch_mode)) {
-		hdd_err("VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_TYPE put fail");
-		wlan_cfg80211_vendor_free_skb(vendor_event);
-		return -EINVAL;
-	}
+	/* Deliver the switch response */
+	status = osif_ll_lt_sap_deliver_audio_transport_switch_resp(
+						vdev,
+						transport_switch_type,
+						transport_switch_status);
 
-	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LL_SAP_ID);
 
-	hdd_debug("transport switch request sent on %s interface",
-		   netdev_name(adapter->dev));
-	return 0;
+	return qdf_status_to_os_return(status);
 }
 
 int wlan_hdd_cfg80211_ll_lt_sap_transport_switch(struct wiphy *wiphy,

+ 43 - 5
core/hdd/src/wlan_hdd_main.c

@@ -248,6 +248,7 @@
 #include "os_if_dp_local_pkt_capture.h"
 #include <wlan_mlo_mgr_link_switch.h>
 #include "cdp_txrx_mon.h"
+#include "os_if_ll_sap.h"
 
 #ifdef MULTI_CLIENT_LL_SUPPORT
 #define WLAM_WLM_HOST_DRIVER_PORT_ID 0xFFFFFF
@@ -18821,6 +18822,18 @@ const struct file_operations wlan_hdd_state_fops = {
 	.release = wlan_hdd_state_ctrl_param_release,
 };
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0))
+static struct class *wlan_hdd_class_create(const char *name)
+{
+	return class_create(THIS_MODULE, name);
+}
+#else
+static struct class *wlan_hdd_class_create(const char *name)
+{
+	return class_create(name);
+}
+#endif
+
 static int  wlan_hdd_state_ctrl_param_create(void)
 {
 	unsigned int wlan_hdd_state_major = 0;
@@ -18838,8 +18851,7 @@ static int  wlan_hdd_state_ctrl_param_create(void)
 		goto dev_alloc_err;
 	}
 	wlan_hdd_state_major = MAJOR(device);
-
-	class = class_create(THIS_MODULE, WLAN_CTRL_NAME);
+	class = wlan_hdd_class_create(WLAN_CTRL_NAME);
 	if (IS_ERR(class)) {
 		pr_err("wlan_hdd_state class_create error");
 		goto class_err;
@@ -18982,6 +18994,26 @@ static void hdd_vdev_mgr_unregister_cb(void)
 	osif_vdev_mgr_reset_legacy_cb();
 }
 
+/**
+ * hdd_ll_sap_register_cb() - Register ll_sap osif callbacks
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS hdd_ll_sap_register_cb(void)
+{
+	return osif_ll_sap_register_cb();
+}
+
+/**
+ * hdd_ll_sap_unregister_cb() - Un-register ll_sap osif callbacks
+ *
+ * Return: void
+ */
+static void hdd_ll_sap_unregister_cb(void)
+{
+	osif_ll_sap_unregister_cb();
+}
+
 /**
  * hdd_component_cb_init() - Initialize component callbacks
  *
@@ -19011,8 +19043,14 @@ static QDF_STATUS hdd_component_cb_init(void)
 	if (QDF_IS_STATUS_ERROR(status))
 		goto hdd_vdev_mgr_unregister_cb;
 
+	status = hdd_ll_sap_register_cb();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto pre_cac_unregister_cb;
+
 	return QDF_STATUS_SUCCESS;
 
+pre_cac_unregister_cb:
+	hdd_pre_cac_unregister_cb();
 hdd_vdev_mgr_unregister_cb:
 	hdd_vdev_mgr_unregister_cb();
 cm_unregister_cb:
@@ -19030,6 +19068,7 @@ cm_unregister_cb:
  */
 static void hdd_component_cb_deinit(void)
 {
+	hdd_ll_sap_unregister_cb();
 	hdd_pre_cac_unregister_cb();
 	hdd_vdev_mgr_unregister_cb();
 	hdd_cm_unregister_cb();
@@ -21619,10 +21658,9 @@ int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width)
 		    chwidth_info[i].sir_chwidth != ch_width)
 			continue;
 
-		return hdd_update_channel_width(link_info->adapter, ch_width,
+		return hdd_update_channel_width(link_info, ch_width,
 						chwidth_info[i].bonding_mode,
-						link_id,
-						false);
+						link_id, false);
 	}
 
 	hdd_err("Invalid ch_width %d", ch_width);

+ 20 - 11
core/hdd/src/wlan_hdd_power.c

@@ -2872,13 +2872,18 @@ static int wlan_hdd_set_ps(struct wlan_hdd_link_info *link_info,
 
 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
-static int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
-			       bool allow_power_save, int timeout)
+int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
+			bool allow_power_save, int timeout,
+			int link_id)
 {
 	struct wlan_hdd_link_info *link_info;
 	int status = -EINVAL;
 
 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
+		if (link_id >= 0 &&
+		    wlan_vdev_get_link_id(link_info->vdev) != link_id)
+			continue;
+
 		status = wlan_hdd_set_ps(link_info,
 					 link_info->link_addr.bytes,
 					 allow_power_save, timeout);
@@ -2889,8 +2894,9 @@ static int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
 	return status;
 }
 #else
-static int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
-			       bool allow_power_save, int timeout)
+int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
+			bool allow_power_save, int timeout,
+			int link_id)
 {
 	struct hdd_adapter *link_adapter;
 	struct hdd_mlo_adapter_info *mlo_adapter_info;
@@ -2901,6 +2907,12 @@ static int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
 		link_adapter = mlo_adapter_info->link_adapter[i];
 		if (!link_adapter)
 			continue;
+
+		if (link_id >= 0 &&
+		    wlan_vdev_get_link_id(link_adapter->deflink->vdev) !=
+		    link_id)
+			continue;
+
 		status = wlan_hdd_set_ps(link_adapter->deflink,
 					 link_adapter->mac_addr.bytes,
 					 allow_power_save, timeout);
@@ -2908,15 +2920,12 @@ static int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
 			break;
 	}
 
+	if (i == WLAN_MAX_MLD && link_id >= 0)
+		hdd_err("No link adapter found for link id: %d", link_id);
+
 	return status;
 }
 #endif
-#else
-static int wlan_hdd_set_mlo_ps(struct hdd_adapter *adapter,
-			       bool allow_power_save, int timeout)
-{
-	return 0;
-}
 #endif
 
 /**
@@ -2978,7 +2987,7 @@ static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
 
 	if (hdd_adapter_is_ml_adapter(adapter)) {
 		status = wlan_hdd_set_mlo_ps(adapter, allow_power_save,
-					     timeout);
+					     timeout, -1);
 		goto exit;
 	}
 

+ 3 - 0
core/hdd/src/wlan_hdd_scan.c

@@ -673,6 +673,9 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
 	if (QDF_IS_STATUS_ERROR(status))
 		hdd_err("Failed to get unicast probe req ra cfg");
 
+	params.mld_id = ucfg_mlme_get_eht_mld_id(hdd_ctx->psoc);
+	hdd_debug("MLD ID: %d", params.mld_id);
+
 	status = wlan_cfg80211_scan(vdev, request, &params);
 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
 error:

+ 2 - 2
core/hdd/src/wlan_hdd_son.c

@@ -154,13 +154,13 @@ static int hdd_son_set_chwidth(struct wlan_objmgr_vdev *vdev,
 
 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
 	if (!link_info) {
-		hdd_err("null adapter");
+		hdd_err("null adapter for %d", wlan_vdev_get_id(vdev));
 		return -EINVAL;
 	}
 
 	chwidth = hdd_son_chan_width_to_chan_width(son_chwidth);
 
-	return hdd_set_mac_chan_width(link_info->adapter, chwidth, link_id, false);
+	return hdd_set_mac_chan_width(link_info, chwidth, link_id, false);
 }
 
 /**

+ 5 - 1
core/hdd/src/wlan_hdd_stats.c

@@ -1484,7 +1484,11 @@ wlan_hdd_copy_mlo_peer_stats(struct hdd_adapter *adapter,
 		qdf_mem_copy(&link_info->mlo_peer_info.peer_mac,
 			     &sta_ctx->conn_info.bssid, QDF_MAC_ADDR_SIZE);
 		link_info->mlo_peer_info.type = peer_info->type;
-		hdd_debug("For peer " QDF_MAC_ADDR_FMT "filling default values",
+		link_info->mlo_peer_info.num_rate = HDD_MAX_PER_PEER_RATES;
+		for (j = 0; j < HDD_MAX_PER_PEER_RATES; j++)
+			qdf_mem_zero(&link_info->mlo_peer_info.rate_stats[j],
+				     sizeof(struct wifi_rate_stat));
+		hdd_debug("Default values for standby link " QDF_MAC_ADDR_FMT,
 			  QDF_MAC_ADDR_REF(sta_ctx->conn_info.bssid.bytes));
 	}
 

+ 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            81
+#define QWLAN_VERSION_EXTRA            "C"
+#define QWLAN_VERSION_BUILD            82
 
-#define QWLAN_VERSIONSTR               "5.2.1.81K"
+#define QWLAN_VERSIONSTR               "5.2.1.82C"
 
 #endif /* QWLAN_VERSION_H */

+ 9 - 0
core/mac/src/pe/lim/lim_mlo.c

@@ -903,6 +903,14 @@ void lim_mlo_delete_link_peer(struct pe_session *pe_session,
 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
 }
 
+#if defined(SAP_MULTI_LINK_EMULATION)
+QDF_STATUS lim_mlo_assoc_ind_upper_layer(struct mac_context *mac,
+					 struct pe_session *pe_session,
+					 struct mlo_partner_info *mlo_info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#else
 QDF_STATUS lim_mlo_assoc_ind_upper_layer(struct mac_context *mac,
 					 struct pe_session *pe_session,
 					 struct mlo_partner_info *mlo_info)
@@ -1007,6 +1015,7 @@ QDF_STATUS lim_mlo_assoc_ind_upper_layer(struct mac_context *mac,
 
 	return status;
 }
+#endif
 
 void lim_mlo_save_mlo_info(tpDphHashNode sta_ds,
 			   struct mlo_partner_info *mlo_info)

+ 7 - 3
core/mac/src/pe/lim/lim_process_action_frame.c

@@ -1727,6 +1727,7 @@ void lim_process_action_frame(struct mac_context *mac_ctx,
 	enum wlan_t2lm_resp_frm_type status_code;
 	uint8_t token = 0;
 	struct wlan_objmgr_peer *peer = NULL;
+	QDF_STATUS status;
 
 	if (frame_len < sizeof(*action_hdr)) {
 		pe_debug("frame_len %d less than Action Frame Hdr size",
@@ -2184,17 +2185,20 @@ void lim_process_action_frame(struct mac_context *mac_ctx,
 		}
 		switch (action_hdr->actionID) {
 		case EHT_T2LM_REQUEST:
-			if (wlan_t2lm_deliver_event(
+			status = wlan_t2lm_deliver_event(
 				session->vdev, peer,
 				WLAN_T2LM_EV_ACTION_FRAME_RX_REQ,
 				(void *)body_ptr, frame_len,
-				&token) == QDF_STATUS_SUCCESS)
+				&token);
+			if (QDF_IS_STATUS_SUCCESS(status))
 				status_code = WLAN_T2LM_RESP_TYPE_SUCCESS;
 			else
 				status_code =
 				WLAN_T2LM_RESP_TYPE_DENIED_TID_TO_LINK_MAPPING;
 
-			if (lim_send_t2lm_action_rsp_frame(
+			if (status == QDF_STATUS_E_NOSUPPORT)
+				pe_err("STA does not support T2LM drop frame");
+			else if (lim_send_t2lm_action_rsp_frame(
 					mac_ctx, mac_hdr->sa, session, token,
 					status_code) != QDF_STATUS_SUCCESS) {
 				pe_err("T2LM action response frame not sent");

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

@@ -940,6 +940,7 @@ lim_process_assoc_rsp_t2lm(struct pe_session *session,
 	struct wlan_objmgr_vdev *vdev;
 	struct wlan_t2lm_context *t2lm_ctx;
 	struct wlan_mlo_dev_context *mlo_dev_ctx;
+	struct wlan_objmgr_psoc *psoc;
 
 	if (!session || !assoc_rsp) {
 		pe_err("invalid input parameters");
@@ -950,6 +951,15 @@ lim_process_assoc_rsp_t2lm(struct pe_session *session,
 	if (!vdev || !wlan_vdev_mlme_is_mlo_vdev(vdev))
 		return;
 
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return;
+
+	if (!wlan_mlme_get_t2lm_negotiation_supported(psoc)) {
+		pe_err_rl("T2LM negotiation not supported");
+		return;
+	}
+
 	mlo_dev_ctx = wlan_vdev_get_mlo_dev_ctx(vdev);
 	if (!mlo_dev_ctx) {
 		pe_err("ml dev ctx is null");

+ 5 - 0
core/mac/src/pe/lim/lim_process_beacon_frame.c

@@ -68,6 +68,11 @@ void lim_process_bcn_prb_rsp_t2lm(struct mac_context *mac_ctx,
 		return;
 	}
 
+	if (!wlan_mlme_get_t2lm_negotiation_supported(mac_ctx->psoc)) {
+		pe_err_rl("T2LM negotiation not supported");
+		return;
+	}
+
 	vdev = session->vdev;
 	if (!vdev || !wlan_vdev_mlme_is_mlo_vdev(vdev))
 		return;

+ 15 - 13
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -3228,10 +3228,14 @@ lim_fill_pe_session(struct mac_context *mac_ctx, struct pe_session *session,
 	/*
 	 * Join timeout: if we find a BeaconInterval in the BssDescription,
 	 * then set the Join Timeout to be 10 x the BeaconInterval.
+	 *
+	 * 10 * BeaconInterval should be greater than the minimum join
+	 * timeout and lesser than the configured timeout.
 	 */
 	timeout = mac_ctx->mlme_cfg->timeouts.join_failure_timeout_ori;
 	if (bss_desc->beaconInterval)
-		timeout = QDF_MAX(10 * bss_desc->beaconInterval, timeout);
+		timeout = QDF_MAX(10 * bss_desc->beaconInterval,
+				  cfg_min(CFG_JOIN_FAILURE_TIMEOUT));
 
 	mac_ctx->mlme_cfg->timeouts.join_failure_timeout =
 		QDF_MIN(timeout,
@@ -8286,7 +8290,7 @@ static void lim_set_pdev_ht_ie(struct mac_context *mac_ctx, uint8_t pdev_id,
 		}
 		*ie_params->ie_ptr = WLAN_ELEMID_HTCAP_ANA;
 		*(ie_params->ie_ptr + 1) = ie_params->ie_len - 2;
-		lim_set_ht_caps(mac_ctx, NULL, ie_params->ie_ptr,
+		lim_set_ht_caps(mac_ctx, ie_params->ie_ptr,
 				ie_params->ie_len);
 
 		if (NSS_1x1_MODE == i) {
@@ -8356,8 +8360,7 @@ static void lim_set_pdev_vht_ie(struct mac_context *mac_ctx, uint8_t pdev_id,
 		}
 		*ie_params->ie_ptr = WLAN_ELEMID_VHTCAP;
 		*(ie_params->ie_ptr + 1) = ie_params->ie_len - 2;
-		lim_set_vht_caps(mac_ctx, NULL, ie_params->ie_ptr,
-				ie_params->ie_len);
+		lim_set_vht_caps(mac_ctx, ie_params->ie_ptr, ie_params->ie_len);
 
 		if (NSS_1x1_MODE == i) {
 			p_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_VHTCAPS,
@@ -8417,8 +8420,8 @@ static void lim_process_set_vdev_ies_per_band(struct mac_context *mac_ctx,
 
 	pe_debug("rcvd set vdev ie per band req vdev_id = %d",
 		p_msg->vdev_id);
-	/* intentionally using NULL here so that self capability are sent */
-	if (lim_send_ies_per_band(mac_ctx, NULL, p_msg->vdev_id,
+
+	if (lim_send_ies_per_band(mac_ctx, p_msg->vdev_id,
 				  p_msg->dot11_mode, p_msg->device_mode) !=
 	    QDF_STATUS_SUCCESS)
 		pe_err("Unable to send HT/VHT Cap to FW");
@@ -8815,14 +8818,13 @@ lim_process_sap_ch_width_update(struct mac_context *mac_ctx,
 	return;
 
 fail:
-	param = qdf_mem_malloc(sizeof(*param));
-	if (!param)
-		return;
-
 	pe_err("vdev %d: send bandwidth update fail", vdev_id);
-	param->status = QDF_STATUS_E_FAILURE;
-	param->vdev_id = INVALID_VDEV_ID;
-	param->reason = REASON_CH_WIDTH_UPDATE;
+	param = qdf_mem_malloc(sizeof(*param));
+	if (param) {
+		param->status = QDF_STATUS_E_FAILURE;
+		param->vdev_id = INVALID_VDEV_ID;
+		param->reason = REASON_CH_WIDTH_UPDATE;
+	}
 	msg_return.type = eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP;
 	msg_return.bodyptr = param;
 	msg_return.bodyval = 0;

+ 9 - 15
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -2058,13 +2058,8 @@ void lim_handle_sta_csa_param(struct mac_context *mac_ctx,
 	chnl_switch_info =
 		&session_entry->gLimWiderBWChannelSwitch;
 
-	if (WLAN_REG_IS_24GHZ_CH_FREQ(csa_params->csa_chan_freq)) {
-		channel_bonding_mode =
-			mac_ctx->roam.configParam.channelBondingMode24GHz;
-	} else {
-		channel_bonding_mode =
-			mac_ctx->roam.configParam.channelBondingMode5GHz;
-	}
+	channel_bonding_mode = lim_get_cb_mode_for_freq(mac_ctx, session_entry,
+						   csa_params->csa_chan_freq);
 
 	pe_debug("Session %d vdev %d: vht: %d ht: %d he %d cbmode %d",
 		 session_entry->peSessionId, session_entry->vdev_id,
@@ -2773,16 +2768,15 @@ void lim_nss_or_ch_width_update_rsp(struct mac_context *mac_ctx,
 	QDF_STATUS qdf_status = QDF_STATUS_E_INVAL;
 
 	rsp = qdf_mem_malloc(sizeof(*rsp));
-	if (!rsp)
-		return;
-
-	rsp->vdev_id = vdev_id;
-	rsp->status = status;
-	rsp->reason = reason;
+	if (rsp) {
+		rsp->vdev_id = vdev_id;
+		rsp->status = status;
+		rsp->reason = reason;
+	}
 
-	if (rsp->reason == REASON_NSS_UPDATE)
+	if (reason == REASON_NSS_UPDATE)
 		msg.type = eWNI_SME_NSS_UPDATE_RSP;
-	else if (rsp->reason == REASON_CH_WIDTH_UPDATE)
+	else if (reason == REASON_CH_WIDTH_UPDATE)
 		msg.type = eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP;
 	else
 		goto done;

+ 44 - 47
core/mac/src/pe/lim/lim_utils.c

@@ -3834,6 +3834,20 @@ uint8_t lim_get_cb_mode_for_freq(struct mac_context *mac,
 	return cb_mode;
 }
 
+static
+uint8_t lim_get_sta_cb_mode_for_24ghz(struct mac_context *mac,
+				      uint8_t vdev_id)
+{
+	struct pe_session *session;
+	uint8_t cb_mode = mac->roam.configParam.channelBondingMode24GHz;
+
+	session = pe_find_session_by_vdev_id(mac, vdev_id);
+	if (!session || !session->force_24ghz_in_ht20)
+		return cb_mode;
+
+	return WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+}
+
 void lim_update_sta_run_time_ht_switch_chnl_params(struct mac_context *mac,
 						   tDot11fIEHTInfo *pHTInfo,
 						   struct pe_session *pe_session)
@@ -5099,13 +5113,13 @@ lim_set_protected_bit(struct mac_context *mac,
 	}
 } /*** end lim_set_protected_bit() ***/
 
-void lim_set_ht_caps(struct mac_context *p_mac, struct pe_session *p_session_entry,
-		uint8_t *p_ie_start, uint32_t num_bytes)
+void lim_set_ht_caps(struct mac_context *p_mac, uint8_t *p_ie_start,
+		     uint32_t num_bytes)
 {
 	const uint8_t *p_ie = NULL;
 	tDot11fIEHTCaps dot11_ht_cap = {0,};
 
-	populate_dot11f_ht_caps(p_mac, p_session_entry, &dot11_ht_cap);
+	populate_dot11f_ht_caps(p_mac, NULL, &dot11_ht_cap);
 	p_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_HTCAPS,
 					p_ie_start, num_bytes);
 	pe_debug("p_ie: %pK dot11_ht_cap.supportedMCSSet[0]: 0x%x",
@@ -5174,13 +5188,13 @@ void lim_set_ht_caps(struct mac_context *p_mac, struct pe_session *p_session_ent
 	}
 }
 
-void lim_set_vht_caps(struct mac_context *p_mac, struct pe_session *p_session_entry,
+void lim_set_vht_caps(struct mac_context *p_mac,
 		      uint8_t *p_ie_start, uint32_t num_bytes)
 {
 	const uint8_t       *p_ie = NULL;
 	tDot11fIEVHTCaps     dot11_vht_cap;
 
-	populate_dot11f_vht_caps(p_mac, p_session_entry, &dot11_vht_cap);
+	populate_dot11f_vht_caps(p_mac, NULL, &dot11_vht_cap);
 	p_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_VHTCAPS, p_ie_start,
 					num_bytes);
 	if (p_ie) {
@@ -5851,7 +5865,6 @@ static bool is_dot11mode_support_eht_cap(enum csr_cfgdot11mode dot11mode)
 /**
  * lim_send_ht_caps_ie() - gets HT capability and send to firmware via wma
  * @mac_ctx: global mac context
- * @session: pe session. This can be NULL. In that case self cap will be sent
  * @device_mode: VDEV op mode
  * @vdev_id: vdev for which IE is targeted
  *
@@ -5860,7 +5873,6 @@ static bool is_dot11mode_support_eht_cap(enum csr_cfgdot11mode dot11mode)
  * Return: QDF_STATUS
  */
 static QDF_STATUS lim_send_ht_caps_ie(struct mac_context *mac_ctx,
-				      struct pe_session *session,
 				      enum QDF_OPMODE device_mode,
 				      uint8_t vdev_id)
 {
@@ -5871,13 +5883,13 @@ static QDF_STATUS lim_send_ht_caps_ie(struct mac_context *mac_ctx,
 
 	ht_caps[0] = DOT11F_EID_HTCAPS;
 	ht_caps[1] = DOT11F_IE_HTCAPS_MIN_LEN;
-	lim_set_ht_caps(mac_ctx, session, ht_caps,
+	lim_set_ht_caps(mac_ctx, ht_caps,
 			DOT11F_IE_HTCAPS_MIN_LEN + 2);
 	/* Get LDPC and over write for 2G */
 	p_ht_cap->advCodingCap = lim_get_rx_ldpc(mac_ctx,
 						 CHAN_ENUM_2437);
 	/* Get self cap for HT40 support in 2G */
-	if (mac_ctx->roam.configParam.channelBondingMode24GHz) {
+	if (lim_get_sta_cb_mode_for_24ghz(mac_ctx, vdev_id)) {
 		p_ht_cap->supportedChannelWidthSet = 1;
 		p_ht_cap->shortGI40MHz = 1;
 	} else {
@@ -5928,7 +5940,6 @@ static QDF_STATUS lim_send_ht_caps_ie(struct mac_context *mac_ctx,
 /**
  * lim_send_vht_caps_ie() - gets VHT capability and send to firmware via wma
  * @mac_ctx: global mac context
- * @session: pe session. This can be NULL. In that case self cap will be sent
  * @device_mode: VDEV op mode
  * @vdev_id: vdev for which IE is targeted
  *
@@ -5937,7 +5948,6 @@ static QDF_STATUS lim_send_ht_caps_ie(struct mac_context *mac_ctx,
  * Return: QDF_STATUS
  */
 static QDF_STATUS lim_send_vht_caps_ie(struct mac_context *mac_ctx,
-				       struct pe_session *session,
 				       enum QDF_OPMODE device_mode,
 				       uint8_t vdev_id)
 {
@@ -5949,8 +5959,7 @@ static QDF_STATUS lim_send_vht_caps_ie(struct mac_context *mac_ctx,
 
 	vht_caps[0] = DOT11F_EID_VHTCAPS;
 	vht_caps[1] = DOT11F_IE_VHTCAPS_MAX_LEN;
-	lim_set_vht_caps(mac_ctx, session, vht_caps,
-			DOT11F_IE_VHTCAPS_MIN_LEN + 2);
+	lim_set_vht_caps(mac_ctx, vht_caps, DOT11F_IE_VHTCAPS_MIN_LEN + 2);
 	/*
 	 * Get LDPC and over write for 5G - using channel 64 because it
 	 * is available in all reg domains.
@@ -6000,8 +6009,7 @@ static QDF_STATUS lim_send_vht_caps_ie(struct mac_context *mac_ctx,
 	return QDF_STATUS_E_FAILURE;
 }
 
-QDF_STATUS lim_send_ies_per_band(struct mac_context *mac_ctx,
-				 struct pe_session *session, uint8_t vdev_id,
+QDF_STATUS lim_send_ies_per_band(struct mac_context *mac_ctx, uint8_t vdev_id,
 				 enum csr_cfgdot11mode dot11_mode,
 				 enum QDF_OPMODE device_mode)
 {
@@ -6015,27 +6023,21 @@ QDF_STATUS lim_send_ies_per_band(struct mac_context *mac_ctx,
 	 * to send IE to wma.
 	 */
 	if (is_dot11mode_support_ht_cap(dot11_mode))
-		status_ht = lim_send_ht_caps_ie(mac_ctx, session,
-						device_mode, vdev_id);
+		status_ht = lim_send_ht_caps_ie(mac_ctx, device_mode, vdev_id);
 
 	if (is_dot11mode_support_vht_cap(dot11_mode))
-		status_vht = lim_send_vht_caps_ie(mac_ctx, session,
-						  device_mode, vdev_id);
+		status_vht = lim_send_vht_caps_ie(mac_ctx, device_mode, vdev_id);
 
 	if (is_dot11mode_support_he_cap(dot11_mode)) {
-		status_he = lim_send_he_caps_ie(mac_ctx, session,
-						device_mode, vdev_id);
+		status_he = lim_send_he_caps_ie(mac_ctx, device_mode, vdev_id);
 
 		if (QDF_IS_STATUS_SUCCESS(status_he))
 			status_he = lim_send_he_6g_band_caps_ie(mac_ctx,
-								session,
 								vdev_id);
 	}
 
-	if (is_dot11mode_support_eht_cap(dot11_mode)) {
-		status_he = lim_send_eht_caps_ie(mac_ctx, session,
-						 device_mode, vdev_id);
-	}
+	if (is_dot11mode_support_eht_cap(dot11_mode))
+		status_he = lim_send_eht_caps_ie(mac_ctx, device_mode, vdev_id);
 
 	if (QDF_IS_STATUS_SUCCESS(status_ht) &&
 	    QDF_IS_STATUS_SUCCESS(status_vht) &&
@@ -7768,8 +7770,8 @@ void lim_update_session_he_capable_chan_switch(struct mac_context *mac,
 		 mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band);
 }
 
-void lim_set_he_caps(struct mac_context *mac, struct pe_session *session,
-		     uint8_t *ie_start, uint32_t num_bytes, uint8_t band)
+void lim_set_he_caps(struct mac_context *mac, uint8_t *ie_start,
+		     uint32_t num_bytes, uint8_t band)
 {
 	const uint8_t *ie = NULL;
 	tDot11fIEhe_cap dot11_cap;
@@ -7780,7 +7782,7 @@ void lim_set_he_caps(struct mac_context *mac, struct pe_session *session,
 		is_band_2g = true;
 
 	populate_dot11f_he_caps_by_band(mac, is_band_2g, &dot11_cap,
-					session);
+					NULL);
 	lim_log_he_cap(mac, &dot11_cap);
 	ie = wlan_get_ext_ie_ptr_from_ext_id(HE_CAP_OUI_TYPE,
 			HE_CAP_OUI_SIZE, ie_start, num_bytes);
@@ -7916,19 +7918,17 @@ void lim_set_he_caps(struct mac_context *mac, struct pe_session *session,
 }
 
 static void lim_intersect_he_ch_width_2g(struct mac_context *mac,
-					 struct he_capability_info *he_cap)
+					 struct he_capability_info *he_cap,
+					 uint8_t vdev_id)
 {
 	struct wlan_objmgr_psoc *psoc;
 	uint32_t cbm_24ghz;
-	QDF_STATUS ret;
 
 	psoc = mac->psoc;
 	if (!psoc)
 		return;
 
-	ret = ucfg_mlme_get_channel_bonding_24ghz(psoc, &cbm_24ghz);
-	if (QDF_IS_STATUS_ERROR(ret))
-		return;
+	cbm_24ghz = lim_get_sta_cb_mode_for_24ghz(mac, vdev_id);
 
 	pe_debug("channel bonding mode 2.4GHz %d", cbm_24ghz);
 
@@ -7967,7 +7967,6 @@ static uint8_t lim_set_he_caps_ppet(struct mac_context *mac, uint8_t *ie,
 }
 
 QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx,
-			       struct pe_session *session,
 			       enum QDF_OPMODE device_mode,
 			       uint8_t vdev_id)
 {
@@ -7988,7 +7987,7 @@ QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx,
 	he_caps[0] = DOT11F_EID_HE_CAP;
 	he_caps[1] = SIR_MAC_HE_CAP_MIN_LEN;
 	qdf_mem_copy(&he_caps[2], HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE);
-	lim_set_he_caps(mac_ctx, session, he_caps, he_cap_total_len,
+	lim_set_he_caps(mac_ctx, he_caps, he_cap_total_len,
 			CDS_BAND_5GHZ);
 	he_cap = (struct he_capability_info *) (&he_caps[2 + HE_CAP_OUI_SIZE]);
 
@@ -8054,7 +8053,7 @@ QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx,
 	he_caps[0] = DOT11F_EID_HE_CAP;
 	he_caps[1] = SIR_MAC_HE_CAP_MIN_LEN;
 	qdf_mem_copy(&he_caps[2], HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE);
-	lim_set_he_caps(mac_ctx, session, he_caps, he_cap_total_len,
+	lim_set_he_caps(mac_ctx, he_caps, he_cap_total_len,
 			CDS_BAND_2GHZ);
 	he_cap = (struct he_capability_info *)(&he_caps[2 + HE_CAP_OUI_SIZE]);
 
@@ -8071,7 +8070,7 @@ QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx,
 		pe_debug("he_cap_2g: bfee_sts_gt_80 %d num_sounding_gt_80 %d",
 			 he_cap->bfee_sts_gt_80, he_cap->num_sounding_gt_80);
 	}
-	lim_intersect_he_ch_width_2g(mac_ctx, he_cap);
+	lim_intersect_he_ch_width_2g(mac_ctx, he_cap, vdev_id);
 
 	if (he_cap->ppet_present)
 		num_ppe_th = lim_set_he_caps_ppet(mac_ctx, he_caps,
@@ -8975,7 +8974,7 @@ void lim_log_eht_op(struct mac_context *mac, tDot11fIEeht_op *eht_ops,
 			   eht_ops, sizeof(tDot11fIEeht_op));
 }
 
-void lim_set_eht_caps(struct mac_context *mac, struct pe_session *session,
+void lim_set_eht_caps(struct mac_context *mac,
 		      uint8_t *ie_start, uint32_t num_bytes, uint8_t band,
 		      uint8_t vdev_id)
 {
@@ -8993,13 +8992,13 @@ void lim_set_eht_caps(struct mac_context *mac, struct pe_session *session,
 	if (band == CDS_BAND_2GHZ)
 		is_band_2g = true;
 
-	populate_dot11f_eht_caps_by_band(mac, is_band_2g, &dot11_cap, session);
+	populate_dot11f_eht_caps_by_band(mac, is_band_2g, &dot11_cap, NULL);
 	populate_dot11f_he_caps_by_band(mac, is_band_2g, &dot11_he_cap,
-					session);
+					NULL);
 	lim_log_eht_cap(mac, &dot11_cap);
 
 	if (is_band_2g) {
-		ucfg_mlme_get_channel_bonding_24ghz(mac->psoc, &cbm_24ghz);
+		cbm_24ghz = lim_get_sta_cb_mode_for_24ghz(mac, vdev_id);
 		if (!cbm_24ghz) {
 			/* B0: 40Mhz channel width in the 2.4GHz band */
 			dot11_he_cap.chan_width_0 = 0;
@@ -9221,7 +9220,6 @@ void lim_set_eht_caps(struct mac_context *mac, struct pe_session *session,
 }
 
 QDF_STATUS lim_send_eht_caps_ie(struct mac_context *mac_ctx,
-				struct pe_session *session,
 				enum QDF_OPMODE device_mode,
 				uint8_t vdev_id)
 {
@@ -9248,7 +9246,7 @@ QDF_STATUS lim_send_eht_caps_ie(struct mac_context *mac_ctx,
 
 	qdf_mem_copy(&eht_caps_2g[2], EHT_CAP_OUI_TYPE, EHT_CAP_OUI_SIZE);
 
-	lim_set_eht_caps(mac_ctx, session, eht_caps_2g, eht_cap_total_len,
+	lim_set_eht_caps(mac_ctx,  eht_caps_2g, eht_cap_total_len,
 			 CDS_BAND_2GHZ, vdev_id);
 	status_2g = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_EHT_CAP,
 				CDS_BAND_2GHZ, &eht_caps_2g[2],
@@ -9259,7 +9257,7 @@ QDF_STATUS lim_send_eht_caps_ie(struct mac_context *mac_ctx,
 
 	qdf_mem_copy(&eht_caps_5g[2], EHT_CAP_OUI_TYPE, EHT_CAP_OUI_SIZE);
 
-	lim_set_eht_caps(mac_ctx, session, eht_caps_5g, eht_cap_total_len,
+	lim_set_eht_caps(mac_ctx, eht_caps_5g, eht_cap_total_len,
 			 CDS_BAND_5GHZ, vdev_id);
 	status_5g = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_EHT_CAP,
 				CDS_BAND_5GHZ, &eht_caps_5g[2],
@@ -9534,7 +9532,6 @@ void lim_extract_msd_caps(struct mac_context *mac_ctx,
 
 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)
 QDF_STATUS lim_send_he_6g_band_caps_ie(struct mac_context *mac_ctx,
-				       struct pe_session *session,
 				       uint8_t vdev_id)
 {
 	uint8_t he_6g_band_caps_ie[DOT11F_IE_HE_6GHZ_BAND_CAP_MIN_LEN + 3];
@@ -9544,7 +9541,7 @@ QDF_STATUS lim_send_he_6g_band_caps_ie(struct mac_context *mac_ctx,
 	uint32_t result;
 
 	qdf_mem_zero(&he_6g_band_cap, sizeof(he_6g_band_cap));
-	populate_dot11f_he_6ghz_cap(mac_ctx, session, &he_6g_band_cap);
+	populate_dot11f_he_6ghz_cap(mac_ctx, NULL, &he_6g_band_cap);
 	if (!he_6g_band_cap.present) {
 		pe_debug("no HE 6g band cap for vdev %d", vdev_id);
 		return QDF_STATUS_SUCCESS;

+ 13 - 30
core/mac/src/pe/lim/lim_utils.h

@@ -1011,15 +1011,11 @@ void lim_set_protected_bit(struct mac_context *mac,
 	struct pe_session *pe_session,
 	tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr);
 
-void lim_set_ht_caps(struct mac_context *p_mac,
-		struct pe_session *p_session_ntry,
-		uint8_t *p_ie_start,
-		uint32_t num_bytes);
-
-void lim_set_vht_caps(struct mac_context *p_mac,
-		struct pe_session *p_session_entry,
-		uint8_t *p_ie_start,
-		uint32_t num_bytes);
+void lim_set_ht_caps(struct mac_context *p_mac, uint8_t *p_ie_start,
+		     uint32_t num_bytes);
+
+void lim_set_vht_caps(struct mac_context *p_mac, uint8_t *p_ie_start,
+		      uint32_t num_bytes);
 bool lim_validate_received_frame_a1_addr(struct mac_context *mac_ctx,
 		tSirMacAddr a1, struct pe_session *session);
 void lim_set_stads_rtt_cap(tpDphHashNode sta_ds, struct s_ext_cap *ext_cap,
@@ -1034,7 +1030,6 @@ QDF_STATUS lim_send_ext_cap_ie(struct mac_context *mac_ctx, uint32_t session_id,
  * lim_send_ies_per_band() - gets ht and vht capability and send to firmware via
  * wma
  * @mac_ctx: global mac context
- * @session: pe session. This can be NULL. In that case self cap will be sent
  * @vdev_id: vdev for which IE is targeted
  * @dot11_mode: vdev dot11 mode
  * @device_mode: device mode
@@ -1044,7 +1039,7 @@ QDF_STATUS lim_send_ext_cap_ie(struct mac_context *mac_ctx, uint32_t session_id,
  * Return: status of operation
  */
 QDF_STATUS lim_send_ies_per_band(struct mac_context *mac_ctx,
-				 struct pe_session *session, uint8_t vdev_id,
+				 uint8_t vdev_id,
 				 enum csr_cfgdot11mode dot11_mode,
 				 enum QDF_OPMODE device_mode);
 
@@ -1524,20 +1519,18 @@ void lim_update_session_he_capable_chan_switch(struct mac_context *mac,
 /**
  * lim_set_he_caps() - update HE caps to be sent to FW as part of scan IE
  * @mac: pointer to MAC
- * @session: pointer to PE session
  * @ie_start: pointer to start of IE buffer
  * @num_bytes: length of IE buffer
  * @band: 2g or 5g band
  *
  * Return: None
  */
-void lim_set_he_caps(struct mac_context *mac, struct pe_session *session,
-		     uint8_t *ie_start, uint32_t num_bytes, uint8_t band);
+void lim_set_he_caps(struct mac_context *mac, uint8_t *ie_start,
+		     uint32_t num_bytes, uint8_t band);
 
 /**
  * lim_send_he_caps_ie() - gets HE capability and send to firmware via wma
  * @mac_ctx: global mac context
- * @session: pe session. This can be NULL. In that case self cap will be sent
  * @device_mode: VDEV op mode
  * @vdev_id: vdev for which IE is targeted
  *
@@ -1546,7 +1539,6 @@ void lim_set_he_caps(struct mac_context *mac, struct pe_session *session,
  * Return: QDF_STATUS
  */
 QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx,
-			       struct pe_session *session,
 			       enum QDF_OPMODE device_mode,
 			       uint8_t vdev_id);
 
@@ -1772,7 +1764,6 @@ static inline void lim_set_he_caps(struct mac_context *mac, struct pe_session *s
 }
 
 static inline QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx,
-					     struct pe_session *session,
 					     enum QDF_OPMODE device_mode,
 					     uint8_t vdev_id)
 {
@@ -2063,7 +2054,6 @@ void lim_log_eht_cap(struct mac_context *mac, tDot11fIEeht_cap *eht_cap);
 /**
  * lim_set_eht_caps() - update EHT caps to be sent to FW as part of scan IE
  * @mac: pointer to MAC
- * @session: pointer to PE session
  * @ie_start: pointer to start of IE buffer
  * @num_bytes: length of IE buffer
  * @band: 2g or 5g band
@@ -2071,14 +2061,12 @@ void lim_log_eht_cap(struct mac_context *mac, tDot11fIEeht_cap *eht_cap);
  *
  * Return: None
  */
-void lim_set_eht_caps(struct mac_context *mac, struct pe_session *session,
-		      uint8_t *ie_start, uint32_t num_bytes, uint8_t band,
-		      uint8_t vdev_id);
+void lim_set_eht_caps(struct mac_context *mac, uint8_t *ie_start,
+		      uint32_t num_bytes, uint8_t band, uint8_t vdev_id);
 
 /**
  * lim_send_eht_caps_ie() - gets EHT capability and send to firmware via wma
  * @mac_ctx: global mac context
- * @session: pe session. This can be NULL. In that case self cap will be sent
  * @device_mode: VDEV op mode
  * @vdev_id: vdev for which IE is targeted
  *
@@ -2087,7 +2075,6 @@ void lim_set_eht_caps(struct mac_context *mac, struct pe_session *session,
  * Return: QDF_STATUS
  */
 QDF_STATUS lim_send_eht_caps_ie(struct mac_context *mac_ctx,
-				struct pe_session *session,
 				enum QDF_OPMODE device_mode,
 				uint8_t vdev_id);
 /**
@@ -2299,14 +2286,13 @@ lim_log_eht_cap(struct mac_context *mac, tDot11fIEeht_cap *eht_cap)
 }
 
 static inline void
-lim_set_eht_caps(struct mac_context *mac, struct pe_session *session,
-		 uint8_t *ie_start, uint32_t num_bytes, uint8_t band,
-		 uint8_t vdev_id)
+lim_set_eht_caps(struct mac_context *mac, uint8_t *ie_start,
+		 uint32_t num_bytes, uint8_t band, uint8_t vdev_id)
 {
 }
 
 static inline QDF_STATUS
-lim_send_eht_caps_ie(struct mac_context *mac_ctx, struct pe_session *session,
+lim_send_eht_caps_ie(struct mac_context *mac_ctx,
 		     enum QDF_OPMODE device_mode, uint8_t vdev_id)
 {
 	return QDF_STATUS_SUCCESS;
@@ -2433,7 +2419,6 @@ lim_extract_msd_caps(struct mac_context *mac_ctx,
 /**
  * lim_send_he_6g_band_caps_ie() - Send HE 6ghz band caps to FW
  * @mac_ctx: Global MAC context
- * @session: session ptr
  * @vdev_id: vdev id
  *
  * Send HE 6ghz band capabilities IE to firmware
@@ -2441,12 +2426,10 @@ lim_extract_msd_caps(struct mac_context *mac_ctx,
  * Return: QDF_STATUS_SUCCESS on success
  */
 QDF_STATUS lim_send_he_6g_band_caps_ie(struct mac_context *mac_ctx,
-				       struct pe_session *session,
 				       uint8_t vdev_id);
 #else
 static inline
 QDF_STATUS lim_send_he_6g_band_caps_ie(struct mac_context *mac_ctx,
-				       struct pe_session *session,
 				       uint8_t vdev_id)
 {
 	return QDF_STATUS_SUCCESS;

+ 19 - 1
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -521,6 +521,22 @@ static uint16_t sch_get_tim_size(uint32_t max_aid)
 	return tim_size;
 }
 
+#ifdef SAP_MULTI_LINK_EMULATION
+static void omit_caps_for_2link_sap(tDot11fBeacon2 *bcn_2)
+{
+	qdf_mem_zero(&bcn_2->HTCaps, sizeof(bcn_2->HTCaps));
+	qdf_mem_zero(&bcn_2->EDCAParamSet, sizeof(bcn_2->EDCAParamSet));
+	qdf_mem_zero(&bcn_2->PowerConstraints, sizeof(bcn_2->PowerConstraints));
+	qdf_mem_zero(&bcn_2->TPCReport, sizeof(bcn_2->TPCReport));
+
+	pe_debug("Removed caps from beacon/probe rsp");
+}
+#else
+static inline void omit_caps_for_2link_sap(tDot11fBeacon2 *bcn_2)
+{
+}
+#endif
+
 /**
  * sch_set_fixed_beacon_fields() - sets the fixed params in beacon frame
  * @mac_ctx:       mac global context
@@ -912,7 +928,7 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 		}
 	}
 
-	if (session->vhtCapability && session->gLimOperatingMode.present) {
+	if (session->vhtCapability || session->gLimOperatingMode.present) {
 		populate_dot11f_operating_mode(mac_ctx, &bcn_2->OperatingMode,
 					       session);
 		lim_strip_ie(mac_ctx, addn_ie, &addn_ielen,
@@ -920,6 +936,8 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 			     NULL, SIR_MAC_VHT_OPMODE_SIZE - 2);
 	}
 
+	omit_caps_for_2link_sap(bcn_2);
+
 	n_status = dot11f_pack_beacon2(mac_ctx, bcn_2,
 				       session->pSchBeaconFrameEnd,
 				       SIR_MAX_BEACON_SIZE, &n_bytes);

+ 2 - 0
core/mac/src/pe/sch/sch_beacon_process.c

@@ -1039,6 +1039,8 @@ sch_beacon_process(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 		return;
 	}
 
+	session->dtimPeriod = bcn.tim.dtimPeriod;
+
 	sch_send_beacon_report(mac_ctx, &bcn, session);
 	__sch_beacon_process_for_session(mac_ctx, &bcn, rx_pkt_info, session);
 }

+ 2 - 2
core/mac/src/sys/legacy/src/system/src/mac_init_api.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -150,7 +150,7 @@ QDF_STATUS mac_open(struct wlan_objmgr_psoc *psoc, mac_handle_t *mac_handle,
 
 	status = pe_open(mac, cds_cfg);
 	if (QDF_IS_STATUS_ERROR(status)) {
-		pe_err("failed to open PE; status:%u", status);
+		QDF_DEBUG_PANIC("failed to open PE; status: %u", status);
 		goto release_psoc_ref;
 	}
 

+ 391 - 13
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -9873,6 +9873,343 @@ no_sta_prof:
 	return QDF_STATUS_SUCCESS;
 }
 
+#if defined(SAP_MULTI_LINK_EMULATION)
+QDF_STATUS populate_dot11f_assoc_rsp_mlo_ie(struct mac_context *mac_ctx,
+					    struct pe_session *session,
+					    tpDphHashNode sta,
+					    tDot11fAssocResponse *frm)
+{
+	struct wlan_mlo_ie *mlo_ie;
+	struct wlan_mlo_sta_profile *sta_pro;
+	tpSirAssocReq assoc_req;
+	uint8_t *sta_data;
+	uint32_t sta_len_left;
+	uint8_t common_info_len = 0;
+	uint8_t *p_ml_ie;
+	uint16_t len_remaining;
+	uint16_t presence_bitmap = 0;
+	uint16_t sta_prof_len;
+	uint8_t sta_prof_[] = {0x00, 0xff, 0xf1, 0x01, 0x13, 0x02, 0x03, 0x7f, 0x95, 0xaf, 0x62, 0x64, 0x00, 0x54, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31, 0x04, 0x00, 0x00, 0x01, 0x08, 0x8c, 0x12, 0x98, 0x24, 0xb0,
+		0x48, 0x60, 0x6c, 0x07, 0x0a, 0x55, 0x53, 0x04, 0xc9, 0x83, 0x00, 0x01, 0x3b, 0x00, 0x00, 0x20,
+		0x01, 0x00, 0x23, 0x02, 0x0a, 0x00, 0x32, 0x01, 0xfb, 0x7f, 0x0b, 0x04, 0x00, 0x4f, 0x02, 0x00,
+		0x00, 0x00, 0x40, 0x00, 0x40, 0x19, 0xc3, 0x02, 0x58, 0x0a, 0xc3, 0x02, 0x18, 0xfe, 0xff, 0x23,
+		0x23, 0x0d, 0x01, 0x08, 0x1a, 0x40, 0x10, 0x00, 0x63, 0x40, 0x88, 0x1f, 0x43, 0x81, 0x1c, 0x11,
+		0x08, 0x00, 0xaa, 0xff, 0xaa, 0xff, 0x7b, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71,
+		0x1c, 0xc7, 0x71, 0xff, 0x0c, 0x24, 0xf4, 0x3f, 0x02, 0x28, 0xfc, 0xff, 0x25, 0x00, 0x25, 0x00,
+		0x01, 0xff, 0x0e, 0x26, 0x00, 0x03, 0xa4, 0xff, 0x27, 0xa4, 0xff, 0x42, 0x43, 0xff, 0x62, 0x32,
+		0xff, 0xff, 0x03, 0x3b, 0xb8, 0x36, 0xff, 0x0f, 0x6c, 0x17, 0x00, 0xe0, 0x03, 0x03, 0x00, 0x18,
+		0x76, 0xd8, 0x12, 0x00, 0x44, 0x44, 0x44, 0xff, 0x06, 0x6a, 0x04, 0x11, 0x00, 0x00, 0x00};
+	QDF_STATUS status;
+
+	if (!mac_ctx || !session || !frm)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	mlo_ie = &session->mlo_ie;
+
+	p_ml_ie = mlo_ie->data;
+	len_remaining = sizeof(mlo_ie->data);
+
+	*p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
+	len_remaining--;
+	/* set length later */
+	*p_ml_ie++ = 0;
+	len_remaining--;
+	*p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
+	len_remaining--;
+
+	mlo_ie->type = 0;
+	/* Common Info Length*/
+	common_info_len += WLAN_ML_BV_CINFO_LENGTH_SIZE;
+	qdf_mem_copy(mlo_ie->mld_mac_addr,
+		     session->vdev->mlo_dev_ctx->mld_addr.bytes,
+		     sizeof(mlo_ie->mld_mac_addr));
+	common_info_len += QDF_MAC_ADDR_SIZE;
+
+	mlo_ie->link_id_info_present = 1;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P;
+	mlo_ie->link_id = wlan_vdev_get_link_id(session->vdev);
+	common_info_len += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
+
+	mlo_ie->bss_param_change_cnt_present = 1;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P;
+	mlo_ie->bss_param_change_count =
+			session->mlo_link_info.link_ie.bss_param_change_cnt;
+	common_info_len += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
+
+	mlo_ie->mld_capab_and_op_present = 1;
+	mlo_ie->mld_id_present = 1;
+	mlo_ie->ext_mld_capab_and_op_present = 1;
+	common_info_len += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MLDCAPANDOP_P;
+
+	common_info_len += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_EMLCAP_P;
+
+	common_info_len += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P;
+
+	mlo_ie->common_info_length = common_info_len;
+
+	QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
+		     WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
+	QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
+		     WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
+	p_ml_ie += WLAN_ML_CTRL_SIZE;
+	len_remaining -= WLAN_ML_CTRL_SIZE;
+
+	*p_ml_ie++ = common_info_len;
+	len_remaining--;
+
+	qdf_mem_copy(p_ml_ie, mlo_ie->mld_mac_addr, QDF_MAC_ADDR_SIZE);
+	p_ml_ie += QDF_MAC_ADDR_SIZE;
+	len_remaining -= QDF_MAC_ADDR_SIZE;
+
+	QDF_SET_BITS(*p_ml_ie, WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_IDX,
+		     WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_BITS, mlo_ie->link_id);
+	p_ml_ie++;
+	len_remaining--;
+
+	*p_ml_ie++ = mlo_ie->bss_param_change_count;
+	len_remaining--;
+
+	p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+
+	if (mlo_ie->mld_capab_and_op_present) {
+		QDF_SET_BITS(*(uint16_t *)p_ml_ie,
+		     WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_IDX,
+		     WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_BITS,
+		     mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num);
+		QDF_SET_BITS(*(uint16_t *)p_ml_ie,
+		     WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_IDX,
+		     WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_BITS,
+		     mlo_ie->mld_capab_and_op_info.tid_link_map_supported);
+		p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+		len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	}
+
+	mlo_ie->num_data = p_ml_ie - mlo_ie->data;
+
+	sta_prof_[5] = session->self_mac_addr[0];
+	sta_prof_[6] = session->self_mac_addr[1];
+	sta_prof_[7] = session->self_mac_addr[2];
+	sta_prof_[8] = session->self_mac_addr[3];
+
+	sta_prof_[9] = 0xaf;
+	sta_prof_[10] = 0x62;
+
+	sta_pro = &mlo_ie->sta_profile[0];
+	sta_data = sta_pro->data;
+	sta_len_left = sizeof(sta_pro->data);
+
+	sta_prof_len = ARRAY_SIZE(sta_prof_);
+	qdf_mem_copy(sta_data, sta_prof_, sta_prof_len);
+	sta_data += sta_prof_len;
+	sta_len_left -= sta_prof_len;
+
+	sta_pro->num_data = sta_data - sta_pro->data;
+	pe_debug("num data: %d, sta_prof_len: %d, sta_data len: %d",
+		 sta_pro->num_data, sta_prof_len, sizeof(sta_pro->data));
+	sta_pro->data[TAG_LEN_POS] = sta_pro->num_data - MIN_IE_LEN;
+
+	mlo_ie->num_sta_profile = 1;
+	mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num = 1;
+
+		if (sta_pro->num_data > WLAN_MAX_IE_LEN + MIN_IE_LEN) {
+			sta_pro->data[TAG_LEN_POS] = WLAN_MAX_IE_LEN;
+			status =
+			    lim_add_frag_ie_for_sta_profile(sta_pro->data,
+							    &sta_pro->num_data);
+			if (status != QDF_STATUS_SUCCESS) {
+				pe_debug("add frg ie for sta profile error.");
+				sta_pro->num_data =
+					WLAN_MAX_IE_LEN + MIN_IE_LEN;
+			}
+		} else {
+			sta_pro->data[TAG_LEN_POS] =
+					sta_pro->num_data - MIN_IE_LEN;
+		}
+	assoc_req = session->parsedAssocReq[sta->assocId];
+
+	pe_debug("num partner links: %d", assoc_req->mlo_info.num_partner_links);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS populate_dot11f_bcn_mlo_ie(struct mac_context *mac_ctx,
+				      struct pe_session *session)
+{
+	struct wlan_mlo_ie *mlo_ie;
+	struct wlan_mlo_sta_profile *sta_pro;
+	uint16_t vdev_count;
+	struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
+	uint16_t tmp_offset = 0;
+	struct ml_sch_partner_info *tmp_info;
+	struct mlo_sch_partner_links *sch_info;
+	uint8_t *sta_data;
+	uint8_t common_info_length = 0;
+	uint8_t *p_ml_ie;
+	uint16_t len_remaining;
+	uint16_t presence_bitmap = 0;
+	uint32_t sta_len_left;
+	QDF_STATUS status;
+	uint16_t sta_prof_len;
+	uint8_t sta_prof_[] = {0x00, 0xff, 0xf1, 0x01, 0x13, 0x02, 0x03, 0x7f, 0x95, 0xaf, 0x62, 0x64, 0x00, 0x54, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x05, 0x01, 0x08, 0x8c, 0x12, 0x98, 0x24, 0xb0,
+		0x48, 0x60, 0x6c, 0x07, 0x0a, 0x55, 0x53, 0x04, 0xc9, 0x83, 0x00, 0x01, 0x3b, 0x00, 0x00, 0x20,
+		0x01, 0x00, 0x23, 0x02, 0x0a, 0x00, 0x32, 0x01, 0xfb, 0x7f, 0x0b, 0x04, 0x00, 0x4f, 0x02, 0x00,
+		0x00, 0x00, 0x40, 0x00, 0x40, 0x19, 0xc3, 0x02, 0x58, 0x0a, 0xc3, 0x02, 0x18, 0xfe, 0xff, 0x23,
+		0x23, 0x0d, 0x01, 0x08, 0x1a, 0x40, 0x10, 0x00, 0x63, 0x40, 0x88, 0x1f, 0x43, 0x81, 0x1c, 0x11,
+		0x08, 0x00, 0xaa, 0xff, 0xaa, 0xff, 0x7b, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71,
+		0x1c, 0xc7, 0x71, 0xff, 0x0c, 0x24, 0xf4, 0x3f, 0x02, 0x28, 0xfc, 0xff, 0x25, 0x00, 0x25, 0x00,
+		0x01, 0xff, 0x0e, 0x26, 0x00, 0x03, 0xa4, 0xff, 0x27, 0xa4, 0xff, 0x42, 0x43, 0xff, 0x62, 0x32,
+		0xff, 0xff, 0x03, 0x3b, 0xb8, 0x36, 0xff, 0x0f, 0x6c, 0x17, 0x00, 0xe0, 0x03, 0x03, 0x00, 0x18,
+		0x76, 0xd8, 0x12, 0x00, 0x44, 0x44, 0x44, 0xff, 0x06, 0x6a, 0x04, 0x11, 0x00, 0x00, 0x00};
+	if (!mac_ctx || !session)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	mlo_ie = &session->mlo_ie;
+
+	/* Common Info Length */
+	common_info_length += WLAN_ML_BV_CINFO_LENGTH_SIZE;
+	qdf_mem_zero(&mac_ctx->sch.sch_mlo_partner,
+		     sizeof(mac_ctx->sch.sch_mlo_partner));
+	sch_info = &mac_ctx->sch.sch_mlo_partner;
+	mlo_ie->type = 0;
+	tmp_offset += 1; /* Element ID */
+	tmp_offset += 1; /* length */
+	tmp_offset += 1; /* Element ID extension */
+	tmp_offset += 2; /* Multi-link control */
+	qdf_mem_copy(mlo_ie->mld_mac_addr,
+		     session->vdev->mlo_dev_ctx->mld_addr.bytes,
+		     sizeof(mlo_ie->mld_mac_addr));
+	tmp_offset += 1; /* Common Info Length */
+	tmp_offset += 6; /* mld mac addr */
+	common_info_length += QDF_MAC_ADDR_SIZE;
+	mlo_ie->link_id_info_present = 1;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P;
+	mlo_ie->link_id = wlan_vdev_get_link_id(session->vdev);
+	tmp_offset += 1; /* link id */
+	common_info_length += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
+	mlo_ie->bss_param_change_cnt_present = 1;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P;
+	mlo_ie->bss_param_change_count =
+			session->mlo_link_info.link_ie.bss_param_change_cnt;
+	tmp_offset += 1; /* bss parameters change count */
+	common_info_length += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
+
+	tmp_offset += 2;/* MLD Parameters */
+	mlo_ie->mld_capab_and_op_present = 1;
+	mlo_ie->mld_id_present = 1;
+	mlo_ie->ext_mld_capab_and_op_present = 1;
+	sch_info->num_links = 1;
+	common_info_length += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MLDCAPANDOP_P;
+
+	tmp_offset += 2;
+	common_info_length += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_EMLCAP_P;
+
+	tmp_offset += 2;
+	common_info_length += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P;
+
+	lim_get_mlo_vdev_list(session, &vdev_count, wlan_vdev_list);
+	mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num =
+							vdev_count;
+
+	mlo_ie->mld_capab_and_op_info.tid_link_map_supported = 1;
+
+	mlo_ie->common_info_length = common_info_length;
+	sch_info->mlo_ie_link_info_ofst = tmp_offset;
+
+	p_ml_ie = mlo_ie->data;
+	len_remaining = sizeof(mlo_ie->data);
+
+	*p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
+	len_remaining--;
+	*p_ml_ie++ = 0;
+	len_remaining--;
+	*p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
+	len_remaining--;
+
+	QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
+		     WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
+	QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
+		     WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
+	p_ml_ie += WLAN_ML_CTRL_SIZE;
+	len_remaining -= WLAN_ML_CTRL_SIZE;
+
+	*p_ml_ie++ = common_info_length;
+	len_remaining--;
+
+	qdf_mem_copy(p_ml_ie, mlo_ie->mld_mac_addr, QDF_MAC_ADDR_SIZE);
+	p_ml_ie += QDF_MAC_ADDR_SIZE;
+	len_remaining -= QDF_MAC_ADDR_SIZE;
+
+	QDF_SET_BITS(*p_ml_ie, WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_IDX,
+		     WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_BITS,
+		     mlo_ie->link_id);
+	p_ml_ie++;
+	len_remaining--;
+
+	*p_ml_ie++ = mlo_ie->bss_param_change_count;
+	len_remaining--;
+
+	p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+
+	if (mlo_ie->mld_capab_and_op_present) {
+		QDF_SET_BITS(*(uint16_t *)p_ml_ie,
+		     WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_IDX,
+		     WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_BITS,
+		     mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num);
+		QDF_SET_BITS(*(uint16_t *)p_ml_ie,
+		     WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_IDX,
+		     WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_BITS,
+		     mlo_ie->mld_capab_and_op_info.tid_link_map_supported);
+		p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+		len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
+	}
+
+	mlo_ie->num_data = p_ml_ie - mlo_ie->data;
+
+	sta_prof_[5] = session->self_mac_addr[0];
+	sta_prof_[6] = session->self_mac_addr[1];
+	sta_prof_[7] = session->self_mac_addr[2];
+	sta_prof_[8] = session->self_mac_addr[3];
+
+	sta_prof_[9] = 0xaf;
+	sta_prof_[10] = 0x62;
+
+	sta_pro = &mlo_ie->sta_profile[0];
+	sta_data = sta_pro->data;
+	sta_len_left = sizeof(sta_pro->data);
+
+	sta_prof_len = ARRAY_SIZE(sta_prof_);
+	qdf_mem_copy(sta_data, sta_prof_, sta_prof_len);
+	sta_data += sta_prof_len;
+	sta_len_left -= sta_prof_len;
+	sch_info->num_links = 1;
+	mlo_ie->num_sta_profile = 1;
+
+	sta_pro->num_data = sta_data - sta_pro->data;
+	pe_debug("num data: %d, sta_prof_len: %d, sta_data len: %d",
+		 sta_pro->num_data, sta_prof_len, sizeof(sta_pro->data));
+	sta_pro->data[TAG_LEN_POS] =	sta_pro->num_data - MIN_IE_LEN;
+	tmp_info = &sch_info->partner_info[0];
+	tmp_info->link_info_sta_prof_ofst = sta_prof_len;
+
+	mlo_ie->num_sta_profile = 1;
+	status = QDF_STATUS_SUCCESS;
+
+	return status;
+}
+#else
 QDF_STATUS populate_dot11f_assoc_rsp_mlo_ie(struct mac_context *mac_ctx,
 					    struct pe_session *session,
 					    tpDphHashNode sta,
@@ -10727,6 +11064,7 @@ QDF_STATUS populate_dot11f_bcn_mlo_ie(struct mac_context *mac_ctx,
 
 	return QDF_STATUS_SUCCESS;
 }
+#endif
 
 QDF_STATUS populate_dot11f_tdls_mgmt_mlo_ie(struct mac_context *mac_ctx,
 					    struct pe_session *session)
@@ -10779,6 +11117,46 @@ QDF_STATUS populate_dot11f_tdls_mgmt_mlo_ie(struct mac_context *mac_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 
+#if defined (SAP_MULTI_LINK_EMULATION)
+static void populate_2link_rnr_info(struct pe_session *session,
+				    tDot11fIEreduced_neighbor_report *dot11f)
+{
+	tSirMacAddr fake_mac_addr;
+
+	qdf_mem_copy(fake_mac_addr, session->self_mac_addr, sizeof(tSirMacAddr));
+
+	pe_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(fake_mac_addr));
+
+	dot11f->present = 1;
+	dot11f->op_class = 131;
+	dot11f->channel_num = 37;
+
+	dot11f->tbtt_info_count = 0;
+	dot11f->tbtt_info_len = 16;
+
+	fake_mac_addr[4] = 0xaf;
+	fake_mac_addr[5] = 0x62;
+	qdf_mem_copy(dot11f->tbtt_info.tbtt_info_16.bssid,
+		     fake_mac_addr, sizeof(tSirMacAddr));
+	dot11f->tbtt_info.tbtt_info_16.mld_id = 0;
+	dot11f->tbtt_info.tbtt_info_16.link_id = 1;
+
+	dot11f->tbtt_info.tbtt_info_16.bss_params = 0x4e;
+	dot11f->tbtt_info.tbtt_info_16.short_ssid = 0x558df58e;
+	dot11f->tbtt_info.tbtt_info_16.psd_20mhz = 0xfe;
+
+	dot11f->tbtt_info.tbtt_info_16.bss_param_change_cnt =
+		session->mlo_link_info.link_ie.bss_param_change_cnt;
+
+	pe_debug("Populated rnr IE...");
+}
+#else
+static inline void populate_2link_rnr_info(struct pe_session *session,
+					   tDot11fIEreduced_neighbor_report *dot11f)
+{
+}
+#endif
+
 void populate_dot11f_mlo_rnr(struct mac_context *mac_ctx,
 			     struct pe_session *session,
 			     tDot11fIEreduced_neighbor_report *dot11f)
@@ -10821,6 +11199,9 @@ void populate_dot11f_mlo_rnr(struct mac_context *mac_ctx,
 		}
 		lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
 	}
+
+	populate_2link_rnr_info(session, dot11f);
+
 }
 
 void populate_dot11f_rnr_tbtt_info_16(struct mac_context *mac_ctx,
@@ -11952,7 +12333,7 @@ QDF_STATUS populate_dot11f_assoc_req_mlo_ie(struct mac_context *mac_ctx,
 	uint16_t presence_bitmap = 0;
 	bool is_2g;
 	uint32_t value = 0;
-	uint8_t *ppet;
+	uint8_t *ppet, cb_mode;
 	uint8_t *eht_cap_ie = NULL;
 	bool sta_prof_he_ie = false;
 
@@ -12258,19 +12639,16 @@ QDF_STATUS populate_dot11f_assoc_req_mlo_ie(struct mac_context *mac_ctx,
 		}
 
 		if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq)) {
+			cb_mode = lim_get_cb_mode_for_freq(mac_ctx, pe_session,
+							   chan_freq);
 			populate_dot11f_ht_caps(mac_ctx, NULL, &ht_caps);
-			ht_caps.supportedChannelWidthSet = 0;
-			ht_caps.shortGI40MHz = 0;
-		}
-		if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) &&
-		    mac_ctx->roam.configParam.channelBondingMode5GHz) {
-			ht_caps.supportedChannelWidthSet = 1;
-			ht_caps.shortGI40MHz = 1;
-		}
-		if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq) &&
-		    mac_ctx->roam.configParam.channelBondingMode24GHz) {
-			ht_caps.supportedChannelWidthSet = 1;
-			ht_caps.shortGI40MHz = 1;
+			if (!cb_mode) {
+				ht_caps.supportedChannelWidthSet = 0;
+				ht_caps.shortGI40MHz = 0;
+			} else {
+				ht_caps.supportedChannelWidthSet = 1;
+				ht_caps.shortGI40MHz = 1;
+			}
 		}
 
 		if ((ht_caps.present && frm->HTCaps.present &&

+ 1 - 0
core/sap/inc/sap_api.h

@@ -661,6 +661,7 @@ typedef struct sSapDfsInfo {
 	uint8_t sap_ch_switch_beacon_cnt;
 	uint8_t sap_ch_switch_mode;
 	uint16_t reduced_beacon_interval;
+	uint8_t vdev_id;
 } tSapDfsInfo;
 
 /* MAX number of CAC channels to be recorded */

+ 4 - 1
core/sap/src/sap_api_link_cntl.c

@@ -741,6 +741,7 @@ wlansap_roam_process_dfs_radar_found(struct mac_context *mac_ctx,
 			sap_err("sapdfs: sap_radar_found_status is false");
 			return;
 		}
+
 		sap_debug("sapdfs:Posting event eSAP_DFS_CHANNEL_CAC_RADAR_FOUND");
 		/*
 		 * If Radar is found, while in DFS CAC WAIT State then post stop
@@ -754,6 +755,7 @@ wlansap_roam_process_dfs_radar_found(struct mac_context *mac_ctx,
 					sap.SapDfsInfo.sap_dfs_cac_timer);
 		}
 		mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
+		mac_ctx->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
 
 		/*
 		 * User space is already indicated the CAC start and if
@@ -1038,8 +1040,9 @@ static void wlan_sap_pre_cac_radar_ind(struct sap_context *sap_ctx,
 		qdf_mc_timer_stop(dfs_timer);
 		qdf_mc_timer_destroy(dfs_timer);
 	}
-
 	mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
+	mac_ctx->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
+
 	wlan_pre_cac_handle_radar_ind(sap_ctx->vdev);
 }
 #else

+ 23 - 0
core/sap/src/sap_fsm.c

@@ -4709,6 +4709,12 @@ void sap_dfs_cac_timer_callback(void *data)
 		return;
 	}
 
+	if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) {
+		sap_err("vdev mismatch sap_ctx->vdev_id %d mac->sap.SapDfsInfo.vdev_id %d",
+			sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id);
+		return;
+	}
+
 	/*
 	 * SAP may not be in CAC wait state, when the timer runs out.
 	 * if following flag is set, then timer is in initialized state,
@@ -4719,6 +4725,7 @@ void sap_dfs_cac_timer_callback(void *data)
 			qdf_mc_timer_destroy(
 				&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
+		mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
 	}
 
 	/*
@@ -4751,8 +4758,15 @@ static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx)
 		return 0;
 	}
 
+	if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) {
+		sap_err("Invalid vdev Id sap_ctx_vdev_id %d mac_ctx vdev id %d",
+			sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id);
+		return 0;
+	}
+
 	if (sap_ctx->dfs_cac_offload) {
 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+		mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
 		return 0;
 	}
 
@@ -4764,6 +4778,7 @@ static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx)
 
 	qdf_mc_timer_stop(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+	mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
 	qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
 
 	return 0;
@@ -4790,10 +4805,16 @@ static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx)
 		sap_err("Invalid MAC context");
 		return 0;
 	}
+	/* start time only when is_dfs_cac_timer_running is not running */
+	if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+		sap_err("Invalid state is_dfs_cac_timer_running");
+		return 0;
+	}
 
 	if (sap_ctx->dfs_cac_offload) {
 		sap_debug("cac timer offloaded to firmware");
 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
+		mac->sap.SapDfsInfo.vdev_id = sap_ctx->vdev_id;
 		return 1;
 	}
 
@@ -4821,11 +4842,13 @@ static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx)
 	}
 
 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
+	mac->sap.SapDfsInfo.vdev_id = sap_ctx->vdev_id;
 
 	return 0;
 
 destroy_timer:
 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
+	mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
 	qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
 
 	return 1;

+ 10 - 1
core/sap/src/sap_module.c

@@ -3012,15 +3012,24 @@ void wlansap_cleanup_cac_timer(struct sap_context *sap_ctx)
 		return;
 	}
 
+	if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) {
+		sap_err("sapdfs, force cleanup vdev mismatch sap vdev id %d mac_ctx vdev id %d",
+			sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id);
+		return;
+	}
+
 	if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+		mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
+
 		if (!sap_ctx->dfs_cac_offload) {
 			qdf_mc_timer_stop(
 				&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
 			qdf_mc_timer_destroy(
 				&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
+			sap_debug("sapdfs, force cleanup running dfs cac timer vdev id %d",
+				  sap_ctx->vdev_id);
 		}
-		sap_err("sapdfs, force cleanup running dfs cac timer");
 	}
 }
 

+ 11 - 0
core/sme/inc/csr_internal.h

@@ -630,4 +630,15 @@ csr_roam_auth_offload_callback(struct mac_context *mac_ctx,
 QDF_STATUS csr_invoke_neighbor_report_request(uint8_t session_id,
 				struct sRrmNeighborReq *neighbor_report_req,
 				bool send_resp_to_host);
+
+/**
+ * csr_set_vdev_ies_per_band() - sends the per band IEs to vdev
+ * @mac_handle: Opaque handle to the global MAC context
+ * @vdev_id: vdev_id for which IE is targeted
+ * @device_mode: vdev mode
+ *
+ * Return: None
+ */
+void csr_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id,
+			       enum QDF_OPMODE device_mode);
 #endif

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

@@ -957,6 +957,15 @@ QDF_STATUS sme_set_custom_mac_addr(tSirMacAddr customMacAddr);
 QDF_STATUS sme_hide_ssid(mac_handle_t mac_handle, uint8_t sessionId,
 		uint8_t ssidHidden);
 
+/**
+ * sme_set_listen_interval() - Set the listen interval
+ * @mac_handle: The handle returned by mac_open
+ * @vdev_id: vdev identifier
+ *
+ * Return: None
+ */
+void sme_set_listen_interval(mac_handle_t mac_handle, uint8_t vdev_id);
+
 /**
  * sme_update_roam_scan_n_probes() - Update no.of roam scan probes
  * @mac_handle: The handle returned by mac_open

+ 34 - 22
core/sme/src/common/sme_api.c

@@ -85,6 +85,7 @@
 #include "wlan_cp_stats_mc_ucfg_api.h"
 #include "wlan_psoc_mlme_ucfg_api.h"
 #include <wlan_mlo_link_force.h>
+#include "wma_eht.h"
 
 static QDF_STATUS init_sme_cmd_list(struct mac_context *mac);
 
@@ -2679,6 +2680,7 @@ sme_process_sap_ch_width_update_rsp(struct mac_context *mac, uint8_t *msg)
 	enum policy_mgr_conn_update_reason reason;
 	uint32_t request_id;
 	uint8_t vdev_id;
+	QDF_STATUS status = QDF_STATUS_E_NOMEM;
 
 	param = (struct sir_bcn_update_rsp *)msg;
 	if (!param)
@@ -2710,8 +2712,10 @@ sme_process_sap_ch_width_update_rsp(struct mac_context *mac, uint8_t *msg)
 	reason = command->u.bw_update_cmd.reason;
 	request_id = command->u.bw_update_cmd.request_id;
 	vdev_id = command->u.bw_update_cmd.conc_vdev_id;
+	if (param)
+		status = param->status;
 	sme_debug("vdev %d reason %d status %d cm_id 0x%x",
-		  vdev_id, reason, param->status, request_id);
+		  vdev_id, reason, status, request_id);
 
 	if (reason == POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA) {
 		sme_debug("Continue channel switch for STA on vdev %d",
@@ -2719,9 +2723,9 @@ sme_process_sap_ch_width_update_rsp(struct mac_context *mac, uint8_t *msg)
 		csr_sta_continue_csa(mac, vdev_id);
 	} else if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT) {
 		sme_debug("Continue connect/reassoc on vdev %d reason %d status %d cm_id 0x%x",
-			  vdev_id, reason, param->status, request_id);
+			  vdev_id, reason, status, request_id);
 		wlan_cm_handle_hw_mode_change_resp(mac->pdev, vdev_id,
-						   request_id, param->status);
+						   request_id, status);
 	}
 
 	policy_mgr_set_connection_update(mac->psoc);
@@ -6009,6 +6013,23 @@ QDF_STATUS sme_set_max_tx_power(mac_handle_t mac_handle,
 	return QDF_STATUS_SUCCESS;
 }
 
+void sme_set_listen_interval(mac_handle_t mac_handle, uint8_t vdev_id)
+{
+	struct mac_context *mac = MAC_CONTEXT(mac_handle);
+	struct pe_session *session = NULL;
+	uint8_t val = 0;
+
+	session = pe_find_session_by_vdev_id(mac, vdev_id);
+	if (!session) {
+		sme_err("Session lookup fails for vdev %d", vdev_id);
+		return;
+	}
+
+	val = session->dtimPeriod;
+	pe_debug("Listen interval: %d vdev id: %d", val, vdev_id);
+	wma_vdev_set_listen_interval(vdev_id, val);
+}
+
 /*
  * sme_set_custom_mac_addr() -
  * Set the customer Mac Address.
@@ -12673,28 +12694,15 @@ void sme_set_cal_failure_event_cb(
 void sme_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id,
 			       enum QDF_OPMODE device_mode)
 {
-	struct sir_set_vdev_ies_per_band *p_msg;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
-	enum csr_cfgdot11mode curr_dot11_mode =
-				mac_ctx->roam.configParam.uCfgDot11Mode;
 
-	p_msg = qdf_mem_malloc(sizeof(*p_msg));
-	if (!p_msg)
-		return;
-
-
-	p_msg->vdev_id = vdev_id;
-	p_msg->device_mode = device_mode;
-	p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, vdev_id,
-						    curr_dot11_mode);
-	p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND;
-	p_msg->len = sizeof(*p_msg);
-	sme_debug("SET_VDEV_IES_PER_BAND: vdev_id %d dot11mode %d dev_mode %d",
-		  vdev_id, p_msg->dot11_mode, device_mode);
-	status = umac_send_mb_message_to_mac(p_msg);
-	if (QDF_STATUS_SUCCESS != status)
-		sme_err("Send eWNI_SME_SET_VDEV_IES_PER_BAND fail");
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_set_vdev_ies_per_band(mac_handle, vdev_id,
+					  device_mode);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
 }
 
 /**
@@ -15165,6 +15173,10 @@ void sme_reset_he_caps(mac_handle_t mac_handle, uint8_t vdev_id)
 	if (mac_ctx->usr_cfg_disable_rsp_tx)
 		sme_set_cfg_disable_tx(mac_handle, vdev_id, 0);
 	mac_ctx->is_usr_cfg_amsdu_enabled = true;
+	status = wlan_scan_cfg_set_scan_mode_6g(mac_ctx->psoc,
+						SCAN_MODE_6G_ALL_CHANNEL);
+	if (QDF_IS_STATUS_ERROR(status))
+		sme_err("Failed to set scan mode for 6 GHz, %d", status);
 }
 #endif
 

+ 53 - 9
core/sme/src/csr/csr_api_roam.c

@@ -5690,6 +5690,7 @@ QDF_STATUS
 cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 			struct wlan_cm_connect_resp *rsp)
 {
+	mac_handle_t mac_handle;
 	struct mac_context *mac_ctx;
 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
 	int32_t count;
@@ -5705,7 +5706,9 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 	 * CSR is cleaned up fully. No new params should be added to CSR, use
 	 * vdev/pdev/psoc instead
 	 */
-	mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
+	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
+
+	mac_ctx = MAC_CONTEXT(mac_handle);
 	if (!mac_ctx)
 		return QDF_STATUS_E_INVAL;
 
@@ -5812,6 +5815,12 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 				vdev_id);
 	}
 
+	/*
+	 * Update the IEs after connection to reconfigure
+	 * any capability that changed during connection.
+	 */
+	sme_set_vdev_ies_per_band(mac_handle, vdev_id,
+				  wlan_vdev_mlme_get_opmode(vdev));
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -5871,6 +5880,7 @@ QDF_STATUS
 cm_csr_diconnect_done_ind(struct wlan_objmgr_vdev *vdev,
 			  struct wlan_cm_discon_rsp *rsp)
 {
+	mac_handle_t mac_handle;
 	struct mac_context *mac_ctx;
 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
 
@@ -5879,7 +5889,9 @@ cm_csr_diconnect_done_ind(struct wlan_objmgr_vdev *vdev,
 	 * CSR is cleaned up fully. No new params should be added to CSR, use
 	 * vdev/pdev/psoc instead
 	 */
-	mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
+	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
+
+	mac_ctx = MAC_CONTEXT(mac_handle);
 	if (!mac_ctx)
 		return QDF_STATUS_E_INVAL;
 
@@ -5888,6 +5900,13 @@ cm_csr_diconnect_done_ind(struct wlan_objmgr_vdev *vdev,
 		sme_qos_update_hand_off(vdev_id, false);
 	csr_set_default_dot11_mode(mac_ctx);
 
+	/*
+	 * Update the IEs after disconnection to remove
+	 * any connection specific capability change and
+	 * to reset back to self cap
+	 */
+	sme_set_vdev_ies_per_band(mac_handle, vdev_id,
+				  wlan_vdev_mlme_get_opmode(vdev));
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -7719,14 +7738,13 @@ void csr_process_sap_ch_width_update(struct mac_context *mac, tSmeCmd *command)
 
 	sme_err("Posting to PE failed");
 fail:
-	param = qdf_mem_malloc(sizeof(*param));
-	if (!param)
-		return;
-
 	sme_err("Sending ch_width update fail response to SME");
-	param->status = QDF_STATUS_E_FAILURE;
-	param->vdev_id = command->u.bw_update_cmd.vdev_id;
-	param->reason = REASON_CH_WIDTH_UPDATE;
+	param = qdf_mem_malloc(sizeof(*param));
+	if (param) {
+		param->status = QDF_STATUS_E_FAILURE;
+		param->vdev_id = command->u.bw_update_cmd.vdev_id;
+		param->reason = REASON_CH_WIDTH_UPDATE;
+	}
 	msg_return.type = eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP;
 	msg_return.bodyptr = param;
 	msg_return.bodyval = 0;
@@ -8163,3 +8181,29 @@ void csr_process_sap_response(struct mac_context *mac_ctx,
 	wlan_vdev_mlme_ser_remove_request(vdev, cmd_id, cmd_type);
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
 }
+
+void csr_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id,
+			       enum QDF_OPMODE device_mode)
+{
+	struct sir_set_vdev_ies_per_band *p_msg;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
+	enum csr_cfgdot11mode curr_dot11_mode =
+			mac_ctx->roam.configParam.uCfgDot11Mode;
+
+	p_msg = qdf_mem_malloc(sizeof(*p_msg));
+	if (!p_msg)
+		return;
+
+	p_msg->vdev_id = vdev_id;
+	p_msg->device_mode = device_mode;
+	p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, vdev_id,
+						    curr_dot11_mode);
+	p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND;
+	p_msg->len = sizeof(*p_msg);
+	sme_debug("SET_VDEV_IES_PER_BAND: vdev_id %d dot11mode %d dev_mode %d",
+		  vdev_id, p_msg->dot11_mode, device_mode);
+	status = umac_send_mb_message_to_mac(p_msg);
+	if (QDF_STATUS_SUCCESS != status)
+		sme_err("Send eWNI_SME_SET_VDEV_IES_PER_BAND fail");
+}

+ 21 - 0
core/wma/inc/wma.h

@@ -1478,8 +1478,29 @@ int wma_mgmt_tx_bundle_completion_handler(void *handle,
 uint32_t wma_get_vht_ch_width(void);
 
 #ifdef WLAN_FEATURE_11BE
+/**
+ * wma_get_orig_eht_ch_width() - Get original EHT channel width supported
+ *
+ * API to get original EHT channel width
+ *
+ * Return: void
+ */
+uint32_t wma_get_orig_eht_ch_width(void);
+
+/**
+ * wma_get_orig_eht_ch_width() - Get current EHT channel width supported
+ *
+ * API to get current EHT channel width
+ *
+ * Return: void
+ */
 uint32_t wma_get_eht_ch_width(void);
 #else
+static inline uint32_t wma_get_orig_eht_ch_width(void)
+{
+	return 0;
+}
+
 static inline uint32_t wma_get_eht_ch_width(void)
 {
 	return 0;

+ 10 - 10
core/wma/src/wma_dev_if.c

@@ -481,7 +481,7 @@ wma_release_vdev_ref(struct wma_txrx_node *iface)
 
 /**
  * wma_handle_monitor_mode_vdev_detach() - Stop and down monitor mode vdev
- * @wma_handle: wma handle
+ * @wma: wma handle
  * @vdev_id: used to get wma interface txrx node
  *
  * Monitor mode is unconneted mode, so do explicit vdev stop and down
@@ -539,9 +539,8 @@ rel_ref:
 
 /**
  * wma_self_peer_remove() - Self peer remove handler
- * @wma: wma handle
- * @del_vdev_req_param: vdev id
- * @generate_vdev_rsp: request type
+ * @wma_handle: wma handle
+ * @del_vdev_req: vdev id
  *
  * Return: success if peer delete command sent to firmware, else failure.
  */
@@ -768,8 +767,8 @@ send_fail_rsp:
 /**
  * wma_send_start_resp() - send vdev start response to upper layer
  * @wma: wma handle
- * @add_bss: add bss params
- * @resp_event: response params
+ * @add_bss_rsp: add bss params
+ * @rsp: response params
  *
  * Return: none
  */
@@ -814,7 +813,7 @@ static void wma_send_start_resp(tp_wma_handle wma,
  * wma_vdev_start_rsp() - send vdev start response to upper layer
  * @wma: wma handle
  * @vdev: vdev
- * @resp_event: response params
+ * @rsp: response params
  *
  * Return: none
  */
@@ -1517,7 +1516,7 @@ QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
 
 /**
  * wma_peer_unmap_conf_send - send peer unmap conf cmnd to fw
- * @wma_ctx: wma handle
+ * @wma: wma handle
  * @msg: peer unmap conf params
  *
  * Return: QDF_STATUS
@@ -1762,7 +1761,7 @@ peer_detach:
 }
 
 /**
- * wma_get_peer_type() - Determine the type of peer(eg. STA/AP) and return it
+ * wma_get_obj_mgr_peer_type() - Determine the type of peer(eg. STA/AP)
  * @wma: wma handle
  * @vdev_id: vdev id
  * @peer_addr: peer mac address
@@ -2289,6 +2288,7 @@ end:
  * @wma: pointer to WMA handle
  * @vdev_id: vdev id on which delete BSS request was received
  * @vdev_stop_resp: pointer to Delete BSS response
+ * @type: request type
  *
  * This function is called on receiving vdev stop response from FW or
  * vdev stop response timeout. In case of NDI, use vdev's self MAC
@@ -6064,7 +6064,7 @@ out:
 }
 
 /**
- * wma_find_ibss_vdev() - This function finds vdev_id based on input type
+ * wma_find_vdev_by_type() - This function finds vdev_id based on input type
  * @wma: wma handle
  * @type: vdev type
  *

+ 13 - 0
core/wma/src/wma_eht.c

@@ -1102,3 +1102,16 @@ wma_set_eht_txbf_vdev_params(struct mac_context *mac, uint32_t *mode)
 	return QDF_STATUS_SUCCESS;
 }
 #endif
+
+#ifdef WLAN_FEATURE_11BE_MLO
+void wma_vdev_set_listen_interval(uint8_t vdev_id, uint8_t val)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	QDF_STATUS status;
+
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+				    wmi_vdev_param_listen_interval, val);
+	if (QDF_IS_STATUS_ERROR(status))
+		wma_err("failed to set Listen interval for vdev: %d", vdev_id);
+}
+#endif

+ 8 - 0
core/wma/src/wma_eht.h

@@ -366,4 +366,12 @@ QDF_STATUS wma_set_eht_txbf_vdev_params(struct mac_context *mac, uint32_t *mode)
 	return QDF_STATUS_E_NOSUPPORT;
 }
 #endif
+
+#ifdef WLAN_FEATURE_11BE_MLO
+void wma_vdev_set_listen_interval(uint8_t vdev_id, uint8_t val);
+#else
+static inline
+void wma_vdev_set_listen_interval(uint8_t vdev_id, uint8_t val)
+{}
+#endif
 #endif

+ 25 - 21
core/wma/src/wma_main.c

@@ -219,6 +219,7 @@ static uint8_t wma_get_number_of_peers_supported(tp_wma_handle wma)
 /**
  * wma_get_number_of_tids_supported - API to query for number of tids supported
  * @no_of_peers_supported: Number of peer supported
+ * @no_vdevs: Number of vdevs
  *
  * Return: Max number of tids supported
  */
@@ -576,6 +577,7 @@ static bool wma_is_feature_set_supported(tp_wma_handle wma_handle)
  * wma_set_default_tgt_config() - set default tgt config
  * @wma_handle: wma handle
  * @tgt_cfg: Resource config given to target
+ * @cds_cfg: cds configuration
  *
  * Return: none
  */
@@ -2199,7 +2201,7 @@ struct wma_version_info g_wmi_version_info;
 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
 /**
  * wma_state_info_dump() - prints state information of wma layer
- * @buf: buffer pointer
+ * @buf_ptr: buffer pointer
  * @size: size of buffer to be filled
  *
  * This function is used to dump state information of wma layer
@@ -2603,11 +2605,11 @@ static int wma_flush_complete_evt_handler(void *handle,
 /**
  * wma_extract_single_phyerr_spectral() - extract single phy error from event
  * @handle: wma handle
- * @param evt_buf: pointer to event buffer
- * @param datalen: data length of event buffer
- * @param buf_offset: Pointer to hold value of current event buffer offset
+ * @evt_buf: pointer to event buffer
+ * @datalen: data length of event buffer
+ * @buf_offset: Pointer to hold value of current event buffer offset
  * post extraction
- * @param phyerr: Pointer to hold phyerr
+ * @phyerr: Pointer to hold phyerr
  *
  * Return: QDF_STATUS
  */
@@ -3426,10 +3428,10 @@ wma_set_exclude_selftx_from_cca_busy_time(bool exclude_selftx_from_cca_busy,
 
 /**
  * wma_open() - Allocate wma context and initialize it.
- * @cds_context:  cds context
- * @wma_tgt_cfg_cb: tgt config callback fun
- * @radar_ind_cb: dfs radar indication callback
+ * @psoc: psoc object
+ * @tgt_cfg_cb: tgt config callback fun
  * @cds_cfg:  mac parameters
+ * @target_type: target type
  *
  * Return: 0 on success, errno on failure
  */
@@ -4283,8 +4285,8 @@ fail:
  *
  * @handle: WMA handle
  * @fixed_param: Event fixed parameters
- * @vdev_mac_entry - vdev mac entry
- * @hw_mode_trans_ind - Buffer to store parsed information
+ * @vdev_mac_entry: vdev mac entry
+ * @hw_mode_trans_ind: Buffer to store parsed information
  *
  * Parses fixed_param, vdev_mac_entry and fills in the information into
  * hw_mode_trans_ind and wma
@@ -5593,9 +5595,9 @@ static QDF_STATUS wma_update_supported_bands(
 /**
  * wma_derive_ext_ht_cap() - Derive HT caps based on given value
  * @ht_cap: given pointer to HT caps which needs to be updated
+ * @value: new HT cap info provided in form of bitmask
  * @tx_chain: given tx chainmask value
  * @rx_chain: given rx chainmask value
- * @value: new HT cap info provided in form of bitmask
  *
  * This function takes the value provided in form of bitmask and decodes
  * it. After decoding, what ever value it gets, it takes the union(max) or
@@ -5647,7 +5649,7 @@ static void wma_derive_ext_ht_cap(
 
 /**
  * wma_update_target_ext_ht_cap() - Update HT caps with given extended cap
- * @tgt_hdl - target psoc information
+ * @tgt_hdl: target psoc information
  * @ht_cap: HT cap structure to be filled
  *
  * This function loop through each hardware mode and for each hardware mode
@@ -5821,7 +5823,7 @@ static void wma_derive_ext_vht_cap(
 
 /**
  * wma_update_target_ext_vht_cap() - Update VHT caps with given extended cap
- * @tgt_hdl - target psoc information
+ * @tgt_hdl: target psoc information
  * @vht_cap: VHT cap structure to be filled
  *
  * This function loop through each hardware mode and for each hardware mode
@@ -6639,6 +6641,7 @@ static QDF_STATUS wma_register_gtk_offload_event(tp_wma_handle wma_handle)
  *                                wmi rx service ready event.
  * @handle: wma handle
  * @cmd_param_info: command params info
+ * @length: param length
  *
  * Return: none
  */
@@ -7185,7 +7188,7 @@ static void wma_print_mac_phy_capabilities(struct wlan_psoc_host_mac_phy_caps
 
 /**
  * wma_print_populate_soc_caps() - Prints all the caps populated per hw mode
- * @tgt_info: target related info
+ * @tgt_hdl: target related info
  *
  * This function prints all the caps populater per hw mode and per PHY
  *
@@ -7226,7 +7229,7 @@ static void wma_print_populate_soc_caps(struct target_psoc_info *tgt_hdl)
 /**
  * wma_update_hw_mode_list() - updates hw_mode_list
  * @wma_handle: pointer to wma global structure
- * @tgt_hdl - target psoc information
+ * @tgt_hdl: target psoc information
  *
  * This function updates hw_mode_list with tx_streams, rx_streams,
  * bandwidth, dbs and agile dfs for each hw_mode.
@@ -7371,6 +7374,7 @@ static inline void wma_init_dbr_params(t_wma_handle *wma_handle)
 /**
  * wma_set_coex_res_cfg() - Set target COEX resource configuration.
  * @wma_handle: pointer to wma global structure
+ * @wmi_handle: pointer to wmi handle
  * @wlan_res_cfg: Pointer to target resource configuration
  *
  * Return: none
@@ -8058,7 +8062,7 @@ void wma_send_flush_logs_to_fw(tp_wma_handle wma_handle)
 
 /**
  * wma_update_tx_fail_cnt_th() - Set threshold for TX pkt fail
- * @wma_handle: WMA handle
+ * @wma: WMA handle
  * @tx_fail_cnt_th: sme_tx_fail_cnt_threshold parameter
  *
  * This function is used to set Tx pkt fail count threshold,
@@ -8100,7 +8104,7 @@ static QDF_STATUS wma_update_tx_fail_cnt_th(tp_wma_handle wma,
 
 /**
  * wma_update_short_retry_limit() - Set retry limit for short frames
- * @wma_handle: WMA handle
+ * @wma: WMA handle
  * @short_retry_limit_th: retry limir count for Short frames.
  *
  * This function is used to configure the transmission retry limit at which
@@ -8141,7 +8145,7 @@ static QDF_STATUS wma_update_short_retry_limit(tp_wma_handle wma,
 
 /**
  * wma_update_long_retry_limit() - Set retry limit for long frames
- * @wma_handle: WMA handle
+ * @wma: WMA handle
  * @long_retry_limit_th: retry limir count for long frames
  *
  * This function is used to configure the transmission retry limit at which
@@ -8282,7 +8286,7 @@ WMITLV_TAG_STRUC_wmi_wow_hostwakeup_gpio_pin_pattern_config_cmd_fixed_param
  * wma_send_wow_pulse_cmd() - send wmi cmd of wow pulse cmd
  * information to fw.
  * @wma_handle: wma handler
- * @udp_response: wow_pulse_mode pointer
+ * @wow_pulse_cmd: wow_pulse_mode pointer
  *
  * Return: Return QDF_STATUS
  */
@@ -8436,7 +8440,7 @@ static QDF_STATUS wma_process_beacon_debug_stats_req(tp_wma_handle wma_handle,
 
 /**
  * wma_set_arp_req_stats() - process set arp stats request command to fw
- * @wma_handle: WMA handle
+ * @handle: WMA handle
  * @req_buf: set srp stats request buffer
  *
  * Return: None
@@ -8739,7 +8743,7 @@ static QDF_STATUS wma_roam_scan_send_hlp(tp_wma_handle wma_handle,
 #endif
 
 /**
- * wma_process_set_limit_off_chan() - set limit off channel parameters
+ * wma_process_limit_off_chan() - set limit off channel parameters
  * @wma_handle: pointer to wma handle
  * @param: pointer to sir_limit_off_chan
  *

+ 6 - 6
core/wma/src/wma_scan_roam.c

@@ -754,12 +754,6 @@ wma_roam_update_vdev(tp_wma_handle wma,
 		return;
 	}
 
-	if (wlan_vdev_mlme_get_opmode(wma->interfaces[vdev_id].vdev) ==
-								QDF_STA_MODE)
-		wlan_cdp_set_peer_freq(wma->psoc, bssid,
-				       wma->interfaces[vdev_id].ch_freq,
-				       vdev_id);
-
 	is_assoc_peer = wlan_vdev_mlme_get_is_mlo_vdev(wma->psoc, vdev_id);
 	if (is_multi_link_roam(roam_synch_ind_ptr)) {
 		wma_create_peer(wma, mac_addr.bytes,
@@ -780,6 +774,12 @@ wma_roam_update_vdev(tp_wma_handle wma,
 					 vdev_id,
 					 mac_addr.bytes);
 
+	if (wlan_vdev_mlme_get_opmode(wma->interfaces[vdev_id].vdev) ==
+								QDF_STA_MODE)
+		wlan_cdp_set_peer_freq(wma->psoc, mac_addr.bytes,
+				       wma->interfaces[vdev_id].ch_freq,
+				       vdev_id);
+
 	/* Update new peer's uc cipher */
 	uc_cipher = wlan_crypto_get_param(wma->interfaces[vdev_id].vdev,
 					   WLAN_CRYPTO_PARAM_UCAST_CIPHER);

+ 25 - 5
core/wma/src/wma_utils.c

@@ -5169,12 +5169,32 @@ int wma_oem_event_handler(void *wma_ctx, uint8_t *event_buff, uint32_t len)
 }
 #endif
 
-/**
- * wma_get_eht_ch_width - return eht channel width
- *
- * Return: return eht channel width
- */
 #ifdef WLAN_FEATURE_11BE
+uint32_t wma_get_orig_eht_ch_width(void)
+{
+	tDot11fIEeht_cap eht_cap;
+	tp_wma_handle wma;
+	QDF_STATUS status;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (qdf_unlikely(!wma)) {
+		wma_err_rl("wma handle is NULL");
+		goto vht_ch_width;
+	}
+
+	status = mlme_cfg_get_orig_eht_caps(wma->psoc, &eht_cap);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wma_err_rl("Failed to get eht caps");
+		goto vht_ch_width;
+	}
+
+	if (eht_cap.support_320mhz_6ghz)
+		return WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ;
+
+vht_ch_width:
+	return wma_get_vht_ch_width();
+}
+
 uint32_t wma_get_eht_ch_width(void)
 {
 	tDot11fIEeht_cap eht_cap;

+ 96 - 0
os_if/mlme/sap/ll_sap/inc/os_if_ll_sap.h

@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains ll_sap definitions specific to the ll_sap module
+ */
+
+#ifndef __OS_IF_LL_SAP_H__
+#define __OS_IF_LL_SAP_H__
+
+#include "qdf_types.h"
+#include "qca_vendor.h"
+#include "wlan_objmgr_vdev_obj.h"
+
+#ifdef WLAN_FEATURE_LL_LT_SAP
+
+/**
+ * osif_ll_sap_register_cb() - Register ll_sap osif callbacks
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS osif_ll_sap_register_cb(void);
+
+/**
+ * osif_ll_sap_unregister_cb() - un-register ll_sap osif callbacks
+ *
+ * Return: QDF_STATUS
+ */
+void osif_ll_sap_unregister_cb(void);
+
+/**
+ * osif_ll_lt_sap_request_for_audio_transport_switch() - Userspace request for
+ * the audio transport switch
+ * @vdev: Vdev on which the request is received
+ * @req_type: Type of the request
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS osif_ll_lt_sap_request_for_audio_transport_switch(
+			struct wlan_objmgr_vdev *vdev,
+			enum qca_wlan_audio_transport_switch_type req_type);
+
+/**
+ * osif_ll_lt_sap_deliver_audio_transport_switch_resp() - Deliver userspace
+ * response for the audio transport switch request to BS_SM
+ * @vdev: Vdev on which the response is received
+ * @req_type: Type of the request
+ * @status: status of the response
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS osif_ll_lt_sap_deliver_audio_transport_switch_resp(
+			struct wlan_objmgr_vdev *vdev,
+			enum qca_wlan_audio_transport_switch_type req_type,
+			enum qca_wlan_audio_transport_switch_status status);
+
+#else
+static inline QDF_STATUS osif_ll_sap_register_cb(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void osif_ll_sap_unregister_cb(void) {}
+
+static inline QDF_STATUS
+osif_ll_lt_sap_request_for_audio_transport_switch(
+			struct wlan_objmgr_vdev *vdev,
+			enum qca_wlan_audio_transport_switch_type req_type)
+{
+	return QDF_STATUS_E_INVAL;
+}
+
+static inline QDF_STATUS
+osif_ll_lt_sap_deliver_audio_transport_switch_resp(
+			struct wlan_objmgr_vdev *vdev,
+			enum qca_wlan_audio_transport_switch_type req_type,
+			enum qca_wlan_audio_transport_switch_status status)
+{
+	return QDF_STATUS_E_INVAL;
+}
+
+#endif /* WLAN_FEATURE_LL_LT_SAP */
+#endif /* __OS_IF_LL_SAP_H__*/

+ 214 - 0
os_if/mlme/sap/ll_sap/src/os_if_ll_sap.c

@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains ll_sap definitions specific to the ll_lt_sap module
+ */
+
+#include "os_if_ll_sap.h"
+#include "wlan_ll_sap_public_structs.h"
+#include "wlan_ll_sap_ucfg_api.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_cfg80211.h"
+#include "wlan_osif_priv.h"
+
+#define WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_INVALID 0xFFFF
+
+/**
+ * osif_convert_audio_transport_switch_req_type_to_qca_type() - Convert
+ * audio transport switch request type to qca audio transport switch req type
+ * @req_type: Request type
+ *
+ * Return:   enum qca_wlan_audio_transport_switch_type
+ */
+static enum qca_wlan_audio_transport_switch_type
+osif_convert_audio_transport_switch_req_type_to_qca_type
+					(enum bearer_switch_req_type req_type)
+{
+	switch (req_type) {
+	case WLAN_BS_REQ_TO_NON_WLAN:
+		return QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_NON_WLAN;
+	case WLAN_BS_REQ_TO_WLAN:
+		return QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_WLAN;
+	default:
+		osif_err("Invalid audio transport switch type");
+		return WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_INVALID;
+	}
+}
+
+/**
+ * osif_convert_audio_transport_switch_req_type_from_qca_type() - Convert
+ * audio transport switch request type from qca audio transport switch req type
+ * @req_type: Request type.
+ *
+ * Return:   enum bearer_switch_req_type
+ */
+static enum bearer_switch_req_type
+osif_convert_audio_transport_switch_req_type_from_qca_type
+			(enum qca_wlan_audio_transport_switch_type req_type)
+{
+	switch (req_type) {
+	case  QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_NON_WLAN:
+		return WLAN_BS_REQ_TO_NON_WLAN;
+	case QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_WLAN:
+		return WLAN_BS_REQ_TO_WLAN;
+	default:
+		osif_err("Invalid %d req type", req_type);
+		return WLAN_BS_REQ_INVALID;
+	}
+}
+
+/**
+ * osif_convert_audio_transport_switch_status_type_from_qca_type() - Convert
+ * audio transport switch status from qca audio transport switch status type
+ * @status:    audio transport switch status.
+ *
+ * Return:   enum bearer_switch_status
+ */
+static enum bearer_switch_status
+osif_convert_audio_transport_switch_status_type_from_qca_type
+			(enum qca_wlan_audio_transport_switch_status status)
+{
+	switch (status) {
+	case  QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_REJECTED:
+		return WLAN_BS_STATUS_REJECTED;
+	case QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_COMPLETED:
+		return WLAN_BS_STATUS_COMPLETED;
+	default:
+		return WLAN_BS_STATUS_INVALID;
+	}
+}
+
+/**
+ * wlan_osif_send_audio_transport_switch_req_event() - Send audio transport
+ * switch event
+ * @vdev: pointer to vdev structure.
+ * @req_type: Request type.
+ *
+ * Return: None.
+ */
+static void wlan_osif_send_audio_transport_switch_req_event(
+					struct wlan_objmgr_vdev *vdev,
+					enum bearer_switch_req_type req_type)
+{
+	struct sk_buff *vendor_event;
+	struct wireless_dev *wdev;
+	struct vdev_osif_priv *osif_priv;
+	uint32_t len;
+	enum qca_wlan_audio_transport_switch_type switch_type;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+
+	osif_priv = wlan_vdev_get_ospriv(vdev);
+	if (!osif_priv) {
+		osif_err("Vdev %d osif_priv is null", vdev_id);
+		return;
+	}
+
+	wdev = osif_priv->wdev;
+	if (!wdev) {
+		osif_err("vdev %d wireless dev is null", vdev_id);
+		return;
+	}
+
+	switch_type =
+		osif_convert_audio_transport_switch_req_type_to_qca_type(
+								req_type);
+	len = nla_total_size(sizeof(uint8_t)) + NLMSG_HDRLEN;
+
+	vendor_event = wlan_cfg80211_vendor_event_alloc(
+			wdev->wiphy, wdev, len,
+			QCA_NL80211_VENDOR_SUBCMD_AUDIO_TRANSPORT_SWITCH_INDEX,
+			GFP_KERNEL);
+
+	if (!vendor_event) {
+		osif_err("vdev %d wlan_cfg80211_vendor_event_alloc failed",
+			 vdev_id);
+		return;
+	}
+
+	if (nla_put_u8(vendor_event,
+		       QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_TYPE,
+		       switch_type)) {
+		osif_err("Vdev %d VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_TYPE put fail",
+			 vdev_id);
+		wlan_cfg80211_vendor_free_skb(vendor_event);
+		return;
+	}
+
+	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+	osif_nofl_debug("Vdev %d Audio Transport switch request %d sent",
+			vdev_id, switch_type);
+}
+
+QDF_STATUS osif_ll_lt_sap_request_for_audio_transport_switch(
+			struct wlan_objmgr_vdev *vdev,
+			enum qca_wlan_audio_transport_switch_type req_type)
+{
+	return ucfg_ll_lt_sap_request_for_audio_transport_switch(
+		vdev,
+		osif_convert_audio_transport_switch_req_type_from_qca_type(
+								req_type));
+}
+
+QDF_STATUS osif_ll_lt_sap_deliver_audio_transport_switch_resp(
+			struct wlan_objmgr_vdev *vdev,
+			enum qca_wlan_audio_transport_switch_type req_type,
+			enum qca_wlan_audio_transport_switch_status status)
+{
+	static enum bearer_switch_status bs_status;
+	enum bearer_switch_req_type bs_req_type;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+
+	if (status == QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_COMPLETED) {
+		osif_nofl_debug("vdev %d Transport switch request %d completed",
+				vdev_id, req_type);
+	} else if (status == QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_REJECTED) {
+		osif_nofl_debug("vdev %d Transport switch request %d rejected",
+				vdev_id, req_type);
+	} else {
+		osif_err("vdev %d Invalid transport switch status %d", vdev_id,
+			 status);
+		return QDF_STATUS_E_INVAL;
+	}
+	bs_status =
+		osif_convert_audio_transport_switch_status_type_from_qca_type(
+									status);
+	bs_req_type =
+		osif_convert_audio_transport_switch_req_type_from_qca_type(
+								req_type);
+
+	ucfg_ll_lt_sap_deliver_audio_transport_switch_resp(vdev, bs_req_type,
+							   bs_status);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static struct ll_sap_ops ll_sap_global_ops = {
+	.ll_sap_send_audio_transport_switch_req_cb =
+		wlan_osif_send_audio_transport_switch_req_event,
+};
+
+QDF_STATUS osif_ll_sap_register_cb(void)
+{
+	ucfg_ll_sap_register_cb(&ll_sap_global_ops);
+	return QDF_STATUS_SUCCESS;
+}
+
+void osif_ll_sap_unregister_cb(void)
+{
+	ucfg_ll_sap_unregister_cb();
+}

+ 1 - 1
os_if/pkt_capture/src/os_if_pkt_capture.c

@@ -152,7 +152,7 @@ QDF_STATUS os_if_monitor_mode_configure(struct hdd_adapter *adapter,
 			BIT(SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL);
 	}
 
-	osif_debug("Monitor mode config %s data tx %d data rx %d mgmt tx %d mgmt rx %d ctrl tx %d ctrl rx %d bi %d\n",
+	osif_debug("Monitor mode config data tx %d data rx %d mgmt tx %d mgmt rx %d ctrl tx %d ctrl rx %d bi %d\n",
 		   frame_filter.data_tx_frame_filter,
 		   frame_filter.data_rx_frame_filter,
 		   frame_filter.mgmt_tx_frame_filter,

+ 11 - 0
wlan_qcacld3_modules.bzl

@@ -289,6 +289,7 @@ _fixed_ipaths = [
     "os_if/dp/inc",
     "os_if/fw_offload/inc",
     "os_if/interop_issues_ap/inc",
+    "os_if/mlme/sap/ll_sap/inc",
     "os_if/nan/inc",
     "os_if/p2p/inc",
     "os_if/pkt_capture/inc",
@@ -2097,6 +2098,7 @@ _conditional_srcs = {
             "components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_main.c",
             "components/umac/mlme/sap/ll_sap/core/src/wlan_ll_sap_main.c",
             "components/cmn_services/policy_mgr/src/wlan_policy_mgr_ll_sap.c",
+            "os_if/mlme/sap/ll_sap/src/os_if_ll_sap.c",
         ],
     },
 }
@@ -2198,6 +2200,15 @@ def _define_module_for_target_variant_chipset(target, variant, chipset):
         ],
         cmd = "cat $(SRCS) > $@",
     )
+    native.genrule(
+        name = "configs/{}_defconfig_generate_perf".format(tvc),
+        outs = ["configs/{}_defconfig.generated_perf".format(tvc)],
+        srcs = [
+            "configs/{}_gki_{}_defconfig".format(target, chipset),
+        ],
+        cmd = "cat $(SRCS) > $@",
+    )
+
 
     srcs = native.glob(iglobs) + _fixed_srcs
 

Vissa filer visades inte eftersom för många filer har ändrats