Explorar o código

Merge 02daca55fefe243c63d63ffce04599f2126339d3 on remote branch

Change-Id: If69f5286667b06b940c5dd0a02b83e7b91fdc479
Linux Build Service Account hai 8 meses
pai
achega
9f51b9542a

+ 12 - 0
components/cmn_services/logging/src/wlan_connectivity_logging.c

@@ -1036,6 +1036,8 @@ wlan_connectivity_connecting_event(struct wlan_objmgr_vdev *vdev,
 	/* for candidate not found case*/
 	if (con_req) {
 		req = *con_req;
+		qdf_mem_zero(&req.scan_ie, sizeof(struct element_info));
+		qdf_mem_zero(&req.assoc_ie, sizeof(struct element_info));
 	} else {
 		status = wlan_cm_get_active_connect_req_param(vdev, &req);
 		if (QDF_IS_STATUS_ERROR(status)) {
@@ -1076,6 +1078,16 @@ wlan_connectivity_connecting_event(struct wlan_objmgr_vdev *vdev,
 	wlan_diag_event.akm = req.crypto.user_akm_suite;
 	wlan_diag_event.auth_algo = req.crypto.user_auth_type;
 
+	if (req.scan_ie.len) {
+		qdf_mem_free(req.scan_ie.ptr);
+		qdf_mem_zero(&req.scan_ie, sizeof(struct element_info));
+	}
+
+	if (req.assoc_ie.len) {
+		qdf_mem_free(req.assoc_ie.ptr);
+		qdf_mem_zero(&req.assoc_ie, sizeof(struct element_info));
+	}
+
 	wlan_diag_event.bt_coex =
 		wlan_mlme_get_bt_profile_con(wlan_vdev_get_psoc(vdev));
 

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

@@ -2587,6 +2587,8 @@ static void mlme_init_sta_mlo_cfg(struct wlan_objmgr_psoc *psoc,
 		cfg_default(CFG_MLO_SAME_LINK_MLD_ADDR);
 	sta->mlo_5gl_5gh_mlsr =
 		cfg_get(psoc, CFG_MLO_MLO_5GL_5GH_MLSR);
+	sta->epcs_capability =
+		cfg_get(psoc, CFG_MLO_EPCS_SUPPORT_ENABLE);
 
 	mlme_debug("mlo_support_link_num: %d, mlo_support_link_band: 0x%x",
 		   sta->mlo_support_link_num, sta->mlo_support_link_band);
@@ -2804,7 +2806,8 @@ static void mlme_init_sta_cfg(struct wlan_objmgr_psoc *psoc,
 		cfg_get(psoc, CFG_MAX_LI_MODULATED_DTIM_MS);
 
 	mlme_init_sta_mlo_cfg(psoc, sta);
-	wlan_mlme_set_epcs_capability(psoc, false);
+	wlan_mlme_set_epcs_capability(psoc,
+				      wlan_mlme_get_epcs_capability(psoc));
 	wlan_mlme_set_usr_disable_sta_eht(psoc, false);
 	wlan_mlme_set_eht_disable_punct_in_us_lpi(psoc,
 						  cfg_default(CFG_EHT_DISABLE_PUNCT_IN_US_LPI));

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

@@ -767,8 +767,33 @@
 		"enable 5GL+5GH MLSR")
 
 #define CFG_MLO_MLO_5GL_5GH_MLSR_CFG CFG(CFG_MLO_MLO_5GL_5GH_MLSR)
+
+/*
+ * <ini>
+ * epcs_support_enable - enable/disable epcs
+ * @Min: false
+ * @Max: true
+ * @Default: false
+ *
+ * Related: None
+ *
+ * Supported Feature: emergency preparedness communications service (EPCS)
+ * priority access
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_MLO_EPCS_SUPPORT_ENABLE CFG_INI_BOOL( \
+		"epcs_support_enable",\
+		0, \
+		"enable epcs support")
+
+#define CFG_MLO_EPCS_SUPPORT_ENABLE_CFG CFG(CFG_MLO_EPCS_SUPPORT_ENABLE)
 #else
 #define CFG_MLO_MLO_5GL_5GH_MLSR_CFG
+#define CFG_MLO_EPCS_SUPPORT_ENABLE_CFG
 #endif
 
 #define CFG_STA_ALL \
@@ -798,5 +823,6 @@
 	CFG_MLO_PREFER_PERCENTAGE_CFG \
 	CFG_MLO_SAME_LINK_MLD_ADDR_CFG \
 	CFG_EHT_DISABLE_PUNCT_IN_US_LPI_CFG \
-	CFG_MLO_MLO_5GL_5GH_MLSR_CFG
+	CFG_MLO_MLO_5GL_5GH_MLSR_CFG \
+	CFG_MLO_EPCS_SUPPORT_ENABLE_CFG
 #endif /* CFG_MLME_STA_H__ */

+ 6 - 0
components/pmo/core/src/wlan_pmo_suspend_resume.c

@@ -1394,6 +1394,12 @@ QDF_STATUS pmo_core_psoc_send_host_wakeup_ind_to_fw(
 
 	hif_ctx = pmo_core_psoc_get_hif_handle(psoc);
 
+	if (!hif_ctx) {
+		pmo_err("hif_ctx is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
 	hif_set_ep_intermediate_vote_access(hif_ctx);
 
 	qdf_event_reset(&psoc_ctx->wow.target_resume);

+ 8 - 2
components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -66,6 +66,8 @@
 #define PMO_MAC_ACTION_FST            18
 #define PMO_MAC_ACTION_RVS            19
 #define PMO_MAC_ACTION_VHT            21
+#define PMO_MAC_ACTION_EHT            36
+#define PMO_MAC_ACTION_PROT_EHT       37
 #define PMO_VENDOR_PROTECTED          126
 #define PMO_MAC_ACTION_MAX            256
 
@@ -98,6 +100,8 @@
  * PMO_ACTION_FST             18      1
  * PMO_ACTION_RVS             19      1
  * PMO_ACTION_VHT             21      1
+ * PMO_MAC_ACTION_EHT         36      1
+ * PMO_MAC_ACTION_PROT_EHT    37      1
  * PMO_VENDOR_PROTECTED       126     1
  * ----------------------------+------+-------+
  */
@@ -113,7 +117,9 @@
 			 (1 << PMO_MAC_ACTION_RVS) | \
 			 (1 << PMO_MAC_ACTION_VHT))
 
-#define ALLOWED_ACTION_FRAMES_BITMAP1   0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP1 \
+			 ((1 << (PMO_MAC_ACTION_EHT % 32)) |\
+			 (1 << (PMO_MAC_ACTION_PROT_EHT % 32)))
 #define ALLOWED_ACTION_FRAMES_BITMAP2   0x0
 #define ALLOWED_ACTION_FRAMES_BITMAP3 \
 		(1 << (PMO_VENDOR_PROTECTED % 32))

+ 4 - 1
components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -739,6 +739,9 @@ ucfg_pmo_get_runtime_pm_delay(struct wlan_objmgr_psoc *psoc)
 {
 	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
 
+	if (!pmo_psoc_ctx)
+		return 0;
+
 	return pmo_psoc_ctx->psoc_cfg.runtime_pm_delay;
 }
 #endif /* FEATURE_RUNTIME_PM */

+ 17 - 4
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -4598,6 +4598,7 @@ cm_roam_switch_to_roam_sync(struct wlan_objmgr_pdev *pdev,
 {
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 	enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id);
+	QDF_STATUS status;
 
 	switch (cur_state) {
 	case WLAN_ROAM_RSO_ENABLED:
@@ -4626,11 +4627,23 @@ cm_roam_switch_to_roam_sync(struct wlan_objmgr_pdev *pdev,
 					    WLAN_ROAM_SYNCH_IN_PROG);
 			break;
 		}
+
+		mlme_debug("ROAM: ROAM_SYNCH received in state: %d", cur_state);
 		/*
-		 * transition to WLAN_ROAM_SYNCH_IN_PROG not allowed otherwise
-		 * if we're already RSO stopped, fall through to return failure
-		 */
-		fallthrough;
+		* If ROAM SYNC come to host in below scenario:
+		* 1. HOST sends RSO stop command with scan mode 4, in order
+		*    to process supplicant disabled roaming request
+		* 2. FW already queued the roam sync event before RSO STOP
+		*    command receive from host
+		* In this case host should send RSO STOP with scan mode = 0
+		* to allow FW to move into RSO STOP state
+		*/
+		status = cm_roam_stop_req(psoc, vdev_id, REASON_ROAM_ABORT,
+					  NULL, false);
+		if (QDF_IS_STATUS_ERROR(status))
+			mlme_err("ROAM: Unable to process RSO STOP req");
+
+		return QDF_STATUS_E_FAILURE;
 	case WLAN_ROAM_INIT:
 	case WLAN_ROAM_DEINIT:
 	case WLAN_ROAM_SYNCH_IN_PROG:

+ 2 - 0
configs/pineapple_gki_qca6750_defconfig

@@ -326,4 +326,6 @@ CONFIG_MULTI_IF_NAME="qca6750"
 CONFIG_CNSS_QCA6750=y
 CONFIG_BUILD_TAG=y
 CONFIG_DP_RX_DESC_COOKIE_INVALIDATE=y
+CONFIG_FEATURE_COEX=y
+CONFIG_WLAN_FEATURE_COEX_DBAM=y
 CONFIG_CFG80211_MLD_AP_STA_CONNECT_UPSTREAM_SUPPORT=y

+ 5 - 0
core/hdd/src/wlan_hdd_hostapd.c

@@ -7217,6 +7217,11 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 	if (ret)
 		goto exit;
 
+	if (hdd_ctx->is_wiphy_suspended) {
+		hdd_debug("wiphy is suspended");
+		return -EINVAL;
+	}
+
 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		goto exit;

+ 4 - 0
core/hdd/src/wlan_hdd_regulatory.c

@@ -1909,6 +1909,10 @@ static void hdd_handle_country_change_work_error(struct hdd_context *hdd_ctx,
 		qdf_sched_work(0, &hdd_ctx->country_change_work);
 	} else {
 		hdd_err("can not handle country change %d", errno);
+		qdf_event_set_all(&hdd_ctx->regulatory_update_event);
+		qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
+		hdd_ctx->is_regulatory_update_in_progress = false;
+		qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
 	}
 }
 

+ 2 - 2
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            "G"
+#define QWLAN_VERSION_EXTRA            "N"
 #define QWLAN_VERSION_BUILD            91
 
-#define QWLAN_VERSIONSTR               "5.2.1.91G"
+#define QWLAN_VERSIONSTR               "5.2.1.91N"
 
 #endif /* QWLAN_VERSION_H */

+ 35 - 10
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -667,6 +667,9 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx,
 	tDot11fIEExtCap extracted_ext_cap = {0};
 	bool extracted_ext_cap_flag = false;
 	uint16_t mlo_ie_len = 0;
+	uint16_t tpe_ie_len = 0;
+	tDot11fIEtransmit_power_env *transmit_power_env = NULL;
+	uint16_t num_transmit_power_env = 0;
 
 	/* We don't answer requests in this case*/
 	if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG)
@@ -770,11 +773,6 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx,
 		populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
 		populate_dot11f_vht_operation(mac_ctx, pe_session,
 			&frm->VHTOperation);
-		populate_dot11f_tx_power_env(mac_ctx,
-					     &frm->transmit_power_env[0],
-					     pe_session->ch_width,
-					     pe_session->curr_op_freq,
-					     &frm->num_transmit_power_env, false);
 		/*
 		 * we do not support multi users yet.
 		 * populate_dot11f_vht_ext_bss_load( mac_ctx,
@@ -783,13 +781,23 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx,
 		is_vht_enabled = true;
 	}
 
-	if (wlan_reg_is_6ghz_chan_freq(pe_session->curr_op_freq)) {
+	if (pe_session->vhtCapability ||
+	    wlan_reg_is_6ghz_chan_freq(pe_session->curr_op_freq)) {
+		transmit_power_env = qdf_mem_malloc(
+					WLAN_MAX_NUM_TPE_IE *
+					sizeof(tDot11fIEtransmit_power_env));
+		if (!transmit_power_env)
+			goto err_ret;
+
 		populate_dot11f_tx_power_env(mac_ctx,
-					     &frm->transmit_power_env[0],
+					     transmit_power_env,
 					     pe_session->ch_width,
 					     pe_session->curr_op_freq,
-					     &frm->num_transmit_power_env,
+					     &num_transmit_power_env,
 					     false);
+		tpe_ie_len = lim_get_tpe_ie_length(pe_session->ch_width,
+						   transmit_power_env,
+						   num_transmit_power_env);
 	}
 
 	if (lim_is_session_he_capable(pe_session)) {
@@ -920,7 +928,7 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx,
 			status);
 	}
 
-	bytes += payload + sizeof(tSirMacMgmtHdr) + mlo_ie_len;
+	bytes += payload + sizeof(tSirMacMgmtHdr) + mlo_ie_len + tpe_ie_len;
 
 	qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
 				      (void **)&packet);
@@ -953,6 +961,19 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx,
 		pe_warn("Probe Response pack warning (0x%08x)", status);
 	}
 
+	if (tpe_ie_len) {
+		qdf_status = lim_fill_complete_tpe_ie(
+					pe_session->ch_width, tpe_ie_len,
+					transmit_power_env,
+					num_transmit_power_env, frame +
+					sizeof(tSirMacMgmtHdr) + payload);
+		if (QDF_IS_STATUS_ERROR(qdf_status)) {
+			pe_debug("assemble tpe ie error");
+			tpe_ie_len = 0;
+		}
+		payload += tpe_ie_len;
+	}
+
 	if (mlo_ie_len) {
 		qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len,
 				    frame + sizeof(tSirMacMgmtHdr) + payload);
@@ -989,8 +1010,9 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx,
 
 	if (add_ie)
 		qdf_mem_free(add_ie);
-
+	qdf_mem_free(transmit_power_env);
 	qdf_mem_free(frm);
+
 	return;
 
 err_ret:
@@ -1000,6 +1022,9 @@ err_ret:
 		qdf_mem_free(frm);
 	if (packet)
 		cds_packet_free((void *)packet);
+	if (transmit_power_env)
+		qdf_mem_free(transmit_power_env);
+
 	return;
 
 } /* End lim_send_probe_rsp_mgmt_frame. */

+ 137 - 0
core/mac/src/pe/lim/lim_utils.c

@@ -12232,3 +12232,140 @@ void lim_cp_stats_cstats_log_csa_evt(struct pe_session *pe_session,
 	wlan_cstats_host_stats(sizeof(struct cstats_csa_evt), &stat);
 }
 #endif /* WLAN_CHIPSET_STATS */
+
+uint16_t lim_get_tpe_ie_length(enum phy_ch_width chan_width,
+			       tDot11fIEtransmit_power_env *tpe_ie,
+			       uint16_t num_tpe)
+{
+	uint16_t total_ie_len = 0;
+	uint16_t idx = 0;
+
+	for (idx = 0; idx < num_tpe; idx++) {
+		if (!tpe_ie[idx].present)
+			return total_ie_len;
+
+		/* +2 for including element id and length */
+		total_ie_len += 2;
+		/* +1 for including tx power info */
+		total_ie_len += 1;
+		total_ie_len += tpe_ie[idx].num_tx_power;
+
+		if (!(chan_width == CH_WIDTH_320MHZ &&
+		      tpe_ie[idx].max_tx_pwr_interpret))
+			continue;
+
+		if (tpe_ie[idx].max_tx_pwr_interpret == LOCAL_EIRP ||
+		    tpe_ie[idx].max_tx_pwr_interpret == REGULATORY_CLIENT_EIRP) {
+			/* Maximum Transmit Power For 320 MHz */
+			total_ie_len += 1;
+		} else if (tpe_ie[idx].max_tx_pwr_interpret == LOCAL_EIRP_PSD ||
+			   tpe_ie[idx].max_tx_pwr_interpret == REGULATORY_CLIENT_EIRP_PSD) {
+			/* Extension Transmit PSD Information */
+			total_ie_len += 1;
+			/* Maximum Transmit PSD power */
+			total_ie_len += MAX_TX_PSD_POWER;
+		}
+	}
+
+	return total_ie_len;
+}
+
+QDF_STATUS lim_fill_complete_tpe_ie(enum phy_ch_width chan_width,
+				    uint16_t tpe_ie_len,
+				    tDot11fIEtransmit_power_env *tpe_ptr,
+				    uint16_t num_tpe, uint8_t *target)
+{
+	uint8_t *ie_len = NULL;
+	uint32_t consumed = 0;
+	uint32_t total_consumed = 0;
+	uint8_t tx_pwr_info = 0U;
+	uint8_t local_psd = 0U;
+	uint8_t reg_psd = 0U;
+	uint8_t *on_entry_target = target;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint16_t idx = 0;
+
+	for (idx = 0; idx < num_tpe; idx++) {
+		if (!tpe_ptr[idx].present)
+			return QDF_STATUS_E_INVAL;
+
+		consumed = 0;
+		*target = WLAN_ELEMID_VHT_TX_PWR_ENVLP;
+		++target;
+		++consumed;
+
+		ie_len = target;
+		++target;
+		++consumed;
+
+		tx_pwr_info = 0U;
+		tx_pwr_info |= (tpe_ptr[idx].max_tx_pwr_count << 0);
+		tx_pwr_info |= (tpe_ptr[idx].max_tx_pwr_interpret << 3);
+		tx_pwr_info |= (tpe_ptr[idx].max_tx_pwr_category << 6);
+		*target = tx_pwr_info;
+		++consumed;
+		++target;
+
+		qdf_mem_copy(target, &tpe_ptr[idx].tx_power, tpe_ptr[idx].num_tx_power);
+		consumed += tpe_ptr[idx].num_tx_power;
+		target += tpe_ptr[idx].num_tx_power;
+
+		if (!(chan_width == CH_WIDTH_320MHZ &&
+		      tpe_ptr[idx].max_tx_pwr_interpret))
+			goto end;
+
+		switch (tpe_ptr[idx].max_tx_pwr_interpret) {
+		case LOCAL_EIRP:
+			/* Maximum Local EIRP Transmit Power For 320 MHz */
+			*target = tpe_ptr[idx].ext_max_tx_power.ext_max_tx_power_local_eirp.max_tx_power_for_320;
+			target += 1;
+			consumed += 1;
+			break;
+		case LOCAL_EIRP_PSD:
+			local_psd = 0U;
+			local_psd |= (tpe_ptr[idx].ext_max_tx_power.ext_max_tx_power_local_psd.ext_count << 0);
+			local_psd |= (tpe_ptr[idx].ext_max_tx_power.ext_max_tx_power_local_psd.reserved << 4);
+			/* Extension Transmit Local PSD Information */
+			*target = local_psd;
+			target += 1;
+			consumed += 1;
+			/* Maximum Transmit Local PSD power */
+			qdf_mem_copy(target, tpe_ptr[idx].ext_max_tx_power.ext_max_tx_power_local_psd.max_tx_psd_power, MAX_TX_PSD_POWER);
+			target += MAX_TX_PSD_POWER;
+			consumed += MAX_TX_PSD_POWER;
+			break;
+		case REGULATORY_CLIENT_EIRP:
+			/* Maximum Regulatory EIRP Transmit Power For 320 MHz */
+			*target = tpe_ptr[idx].ext_max_tx_power.ext_max_tx_power_reg_eirp.max_tx_power_for_320;
+			target += 1;
+			consumed += 1;
+			break;
+		case REGULATORY_CLIENT_EIRP_PSD:
+			reg_psd = 0U;
+			reg_psd |= (tpe_ptr[idx].ext_max_tx_power.ext_max_tx_power_reg_psd.ext_count << 0);
+			reg_psd |= (tpe_ptr[idx].ext_max_tx_power.ext_max_tx_power_reg_psd.reserved << 4);
+			/* Extension Transmit Regulatory PSD Information */
+			*target = reg_psd;
+			consumed += 1;
+			target += 1;
+			/* Maximum Transmit Regulatory PSD power */
+			qdf_mem_copy(target, tpe_ptr[idx].ext_max_tx_power.ext_max_tx_power_reg_psd.max_tx_psd_power, MAX_TX_PSD_POWER);
+			target += MAX_TX_PSD_POWER;
+			consumed += MAX_TX_PSD_POWER;
+			break;
+		}
+end:
+		if (ie_len && consumed >= 2) {
+			total_consumed += consumed;
+			/* -2 for element id and length */
+			*ie_len = consumed - 2;
+		}
+	}
+
+	pe_debug("pack tpe ie %d bytes, expected to copy %d bytes",
+		 total_consumed, tpe_ie_len);
+	qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   on_entry_target, total_consumed);
+
+	return status;
+}

+ 29 - 0
core/mac/src/pe/lim/lim_utils.h

@@ -3658,4 +3658,33 @@ lim_cp_stats_cstats_log_csa_evt(struct pe_session *pe_session,
 {
 }
 #endif /* WLAN_CHIPSET_STATS */
+
+#define MAX_TX_PSD_POWER 15
+
+/**
+ * lim_get_tpe_ie_length() : Get the tpe ie length
+ * @ch_width: phy channel width
+ * @tpe_ie: pointer to dot11f TPE IE structure
+ * @num_tpe: number of TPE IE
+ *
+ * Return: tpe ie length
+ */
+uint16_t lim_get_tpe_ie_length(enum phy_ch_width ch_width,
+			       tDot11fIEtransmit_power_env *tpe_ie,
+			       uint16_t num_tpe);
+
+/**
+ * lim_fill_complete_tpe_ie() : fill tpe ie to target buffer
+ * @ch_width: phy channel width
+ * @tpe_ie_len: the total bytes to fill target buffer
+ * @tpe_ptr: pointer to dot11f TPE IE structure
+ * @num_tpe: number of TPE IE
+ * @target: the buffer to fill data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_fill_complete_tpe_ie(enum phy_ch_width ch_width,
+				    uint16_t tpe_ie_len,
+				    tDot11fIEtransmit_power_env *tpe_ptr,
+				    uint16_t num_tpe, uint8_t *target);
 #endif /* __LIM_UTILS_H */

+ 35 - 14
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -571,6 +571,9 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 	uint16_t mlo_ie_len = 0;
 	uint16_t tim_size;
 	uint8_t reg_cc[REG_ALPHA2_LEN + 1];
+	uint16_t tpe_ie_len = 0;
+	tDot11fIEtransmit_power_env *transmit_power_env = NULL;
+	uint16_t num_transmit_power_env = 0;
 
 	tim_size = sch_get_tim_size(HAL_NUM_STA);
 
@@ -743,21 +746,26 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 		/*
 		populate_dot11f_vht_ext_bss_load( mac_ctx, &bcn2.VHTExtBssLoad);
 		*/
-		populate_dot11f_tx_power_env(mac_ctx,
-					     &bcn_2->transmit_power_env[0],
-					     session->ch_width,
-					     session->curr_op_freq,
-					     &bcn_2->num_transmit_power_env,
-					     false);
 	}
 
-	if (wlan_reg_is_6ghz_chan_freq(session->curr_op_freq)) {
+	if (session->vhtCapability ||
+	    wlan_reg_is_6ghz_chan_freq(session->curr_op_freq)) {
+		transmit_power_env = qdf_mem_malloc(
+					WLAN_MAX_NUM_TPE_IE *
+					sizeof(tDot11fIEtransmit_power_env));
+		if (!transmit_power_env) {
+			status = QDF_STATUS_E_NOMEM;
+			goto free_and_exit;
+		}
 		populate_dot11f_tx_power_env(mac_ctx,
-					     &bcn_2->transmit_power_env[0],
+					     transmit_power_env,
 					     session->ch_width,
 					     session->curr_op_freq,
-					     &bcn_2->num_transmit_power_env,
+					     &num_transmit_power_env,
 					     false);
+		tpe_ie_len = lim_get_tpe_ie_length(session->ch_width,
+						   transmit_power_env,
+						   num_transmit_power_env);
 	}
 
 	if (lim_is_session_he_capable(session)) {
@@ -883,10 +891,8 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 		addn_ielen = session->add_ie_params.probeRespBCNDataLen;
 		addn_ie = qdf_mem_malloc(addn_ielen);
 		if (!addn_ie) {
-			qdf_mem_free(bcn_1);
-			qdf_mem_free(bcn_2);
-			qdf_mem_free(wsc_prb_res);
-			return QDF_STATUS_E_NOMEM;
+			status = QDF_STATUS_E_NOMEM;
+			goto free_and_exit;
 		}
 		qdf_mem_copy(addn_ie,
 			session->add_ie_params.probeRespBCNData_buff,
@@ -998,6 +1004,19 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 		n_bytes = ie_buf_size + eht_cap_ie_len;
 	}
 
+	if (tpe_ie_len) {
+		status = lim_fill_complete_tpe_ie(
+					session->ch_width, tpe_ie_len,
+					transmit_power_env,
+					num_transmit_power_env,
+					session->pSchBeaconFrameEnd + n_bytes);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_debug("assemble tpe ie error");
+			tpe_ie_len = 0;
+		}
+		n_bytes += tpe_ie_len;
+	}
+
 	if (mlo_ie_len) {
 		status = lim_fill_complete_mlo_ie(session, mlo_ie_len,
 					 session->pSchBeaconFrameEnd + n_bytes);
@@ -1088,6 +1107,8 @@ free_and_exit:
 	qdf_mem_free(bcn_2);
 	qdf_mem_free(wsc_prb_res);
 	qdf_mem_free(addn_ie);
+	qdf_mem_free(transmit_power_env);
+
 	return status;
 }
 

+ 4 - 0
os_if/sync/src/osif_psoc_sync.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, 2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -25,6 +26,7 @@
 #include "qdf_types.h"
 #include "wlan_dsc_psoc.h"
 #include "wlan_dsc_vdev.h"
+#include "__wlan_dsc.h"
 
 /**
  * struct osif_psoc_sync - a psoc synchronization context
@@ -312,6 +314,8 @@ int __osif_psoc_sync_op_start(struct device *dev,
 	errno = __osif_psoc_sync_start_callback(dev, out_psoc_sync, func,
 						_dsc_psoc_op_start);
 	osif_psoc_sync_unlock();
+	if (errno)
+		dsc_exit_status(errno);
 
 	return errno;
 }