浏览代码

qcacld-3.0: mlo sap bss start

mlo sap bss start implementation

Change-Id: I662c0b469dc5e4430ec7a819ec4ba954bccf5a25
CRs-Fixed: 2974664
bings 4 年之前
父节点
当前提交
ec8096ea07

+ 4 - 0
Kbuild

@@ -625,6 +625,10 @@ ifeq ($(CONFIG_QCACLD_WLAN_LFR2), y)
 		$(MAC_SRC_DIR)/pe/lim/lim_reassoc_utils.o
 endif
 
+ifeq ($(CONFIG_WLAN_FEATURE_11BE_MLO), y)
+	MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_mlo.o
+endif
+
 MAC_SCH_OBJS := $(MAC_SRC_DIR)/pe/sch/sch_api.o \
 		$(MAC_SRC_DIR)/pe/sch/sch_beacon_gen.o \
 		$(MAC_SRC_DIR)/pe/sch/sch_beacon_process.o \

+ 2 - 0
core/mac/inc/sir_api.h

@@ -3855,6 +3855,7 @@ struct sir_nss_update_request {
  * @REASON_SET_HT2040: HT2040 update
  * @REASON_COLOR_CHANGE: Color change
  * @REASON_CHANNEL_SWITCH: channel switch
+ * @REASON_MLO_IE_UPDATE: mlo ie update
  */
 enum sir_bcn_update_reason {
 	REASON_DEFAULT = 0,
@@ -3863,6 +3864,7 @@ enum sir_bcn_update_reason {
 	REASON_SET_HT2040 = 3,
 	REASON_COLOR_CHANGE = 4,
 	REASON_CHANNEL_SWITCH = 5,
+	REASON_MLO_IE_UPDATE = 6,
 };
 
 /**

+ 71 - 0
core/mac/src/pe/include/lim_session.h

@@ -124,6 +124,74 @@ struct obss_detection_cfg {
 #define ADAPTIVE_11R_DATA_LEN      0x04
 #define ADAPTIVE_11R_OUI_DATA     "\x00\x00\x00\x01"
 
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * struct mlo_link_ie - IE per link to populate mlo ie
+ * @link_ds: DS IE
+ * @link_edca: ecsa IE
+ * @link_wmm_params: wmm params IE
+ * @link_wmm_caps: wmm caps IE
+ * @link_csa: csa IE
+ * @link_ecsa:ecsa IE
+ * @link_swt_time: switch time IE
+ * @link_quiet: quiet IE
+ * @link_ht_cap: ht cap IE
+ * @link_ht_info: ht info IE
+ * @link_cap: link caps IE
+ * @link_ext_cap: link extend cap IE
+ * @link_vht_cap: vht cap IE
+ * @link_vht_op: vht op IE
+ * @link_qcn_ie: qcn IE
+ * @link_he_cap: he cap IE
+ * @link_he_op: he op IE
+ * @link_he_6ghz_band_cap: 6G band cap IE
+ * @link_eht_cap: eht cap IE
+ * @link_eht_op: eht op IE
+ * @max_chan_swt_time: MLOTD
+ * @bss_param_change_cnt: bss param change count
+ */
+struct mlo_link_ie {
+	tDot11fIEDSParams                    link_ds;
+	tDot11fIEEDCAParamSet                link_edca;
+	tDot11fIEWMMParams                   link_wmm_params;
+	tDot11fIEWMMCaps                     link_wmm_caps;
+	tDot11fIEChanSwitchAnn               link_csa;
+	tDot11fIEext_chan_switch_ann         link_ecsa;
+	tDot11fIEmax_chan_switch_time        link_swt_time;
+	tDot11fIEQuiet                       link_quiet;
+	tDot11fIEHTCaps                      link_ht_cap;
+	tDot11fIEHTInfo                      link_ht_info;
+	tDot11fFfCapabilities                link_cap;
+	tDot11fIEExtCap                      link_ext_cap;
+	tDot11fIEVHTCaps                     link_vht_cap;
+	tDot11fIEVHTOperation                link_vht_op;
+	tDot11fIEqcn_ie                      link_qcn_ie;
+	tDot11fIEhe_cap                      link_he_cap;
+	tDot11fIEhe_op                       link_he_op;
+	tDot11fIEhe_6ghz_band_cap            link_he_6ghz_band_cap;
+	tDot11fIEeht_cap                     link_eht_cap;
+	tDot11fIEeht_op                      link_eht_op;
+	uint32_t                             max_chan_swt_time;
+	uint8_t                              bss_param_change_cnt;
+};
+
+/**
+ * struct mlo_link_ie_info - information per link to populate mlo ie
+ * @upt_bcn_mlo_ie: notify partner links to update their mlo ie of bcn temp
+ * @mlo_rnr_updated: link already notified partner link to update rnr
+ * @bss_param_change: bss param changed
+ * @bcn_tmpl_exist: bcn template is generated or not
+ * @link_ie: IEs which will be used for generating partner mlo IE
+ */
+struct mlo_link_ie_info {
+	bool upt_bcn_mlo_ie;
+	bool mlo_rnr_updated;
+	bool bss_param_change;
+	bool bcn_tmpl_exist;
+	struct mlo_link_ie link_ie;
+};
+#endif
+
 /**
  * struct pe_session - per-vdev PE context
  * @available: true if the entry is available, false if it is in use
@@ -583,6 +651,9 @@ struct pe_session {
 	bool eht_capable;
 	tDot11fIEeht_cap eht_config;
 	tDot11fIEeht_op eht_op;
+#ifdef WLAN_FEATURE_11BE_MLO
+	struct mlo_link_ie_info mlo_link_info;
+#endif
 #endif /* WLAN_FEATURE_11BE */
 };
 

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

@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2021, The Linux Foundation. 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 : lim_mlo.c
+ *
+ * WLAN Host Device Driver file for 802.11be (Extremely High Throughput)
+ * support.
+ *
+ */
+
+#include "lim_mlo.h"
+#include "sch_api.h"
+#include "lim_types.h"
+#include "wlan_mlo_mgr_ap.h"
+
+/**
+ * lim_send_mlo_ie_update - mlo ie is changed, populate new beacon template
+ * @session: pe session
+ *
+ * Return: void
+ */
+static void lim_send_mlo_ie_update(struct mac_context *mac_ctx,
+				   struct pe_session *session)
+{
+	if (QDF_IS_STATUS_ERROR(
+		sch_set_fixed_beacon_fields(mac_ctx, session))) {
+		pe_err("Unable to update mlo IE in beacon");
+		return;
+	}
+
+	lim_send_beacon_ind(mac_ctx, session, REASON_MLO_IE_UPDATE);
+}
+
+QDF_STATUS lim_partner_link_info_change(struct wlan_objmgr_vdev *vdev)
+{
+	struct pe_session *session;
+	struct mac_context *mac;
+
+	mac = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac) {
+		pe_err("mac ctx is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!vdev) {
+		pe_err("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	session = pe_find_session_by_vdev_id(
+			mac, vdev->vdev_objmgr.vdev_id);
+	if (!session) {
+		pe_err("session is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (session->mlo_link_info.bcn_tmpl_exist)
+		lim_send_mlo_ie_update(mac, session);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint8_t lim_get_max_simultaneous_link_num(struct pe_session *session)
+{
+	struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
+	uint16_t vdev_count = 0;
+
+	mlo_ap_get_vdev_list(session->vdev, &vdev_count,
+			     wlan_vdev_list);
+
+	return vdev_count;
+}
+
+void lim_mlo_release_vdev_ref(struct wlan_objmgr_vdev *vdev)
+{
+	mlo_release_vdev_ref(vdev);
+}
+
+struct pe_session *pe_find_partner_session_by_link_id(
+			struct pe_session *session, uint8_t link_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mac_context *mac;
+
+	mac = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac) {
+		pe_err("mac ctx is null");
+		return NULL;
+	}
+
+	if (!session) {
+		pe_err("session is null");
+		return NULL;
+	}
+
+	vdev = mlo_get_partner_vdev_by_link_id(session->vdev, link_id);
+
+	if (!vdev) {
+		pe_err("vdev is null");
+		return NULL;
+	}
+
+	return pe_find_session_by_vdev_id(
+			mac, vdev->vdev_objmgr.vdev_id);
+}
+
+void lim_get_mlo_vdev_list(struct pe_session *session, uint16_t *vdev_count,
+			   struct wlan_objmgr_vdev **wlan_vdev_list)
+{
+	mlo_ap_get_vdev_list(session->vdev, vdev_count,
+			     wlan_vdev_list);
+}

+ 82 - 0
core/mac/src/pe/lim/lim_mlo.h

@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021, The Linux Foundation. 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 : lim_mlo.h
+ *
+ * WLAN Host Device Driver file for 802.11be (Extremely High Throughput)
+ * support.
+ *
+ */
+
+#if !defined(LIM_MLO_H)
+#define LIM_MLO_H
+
+#include "ani_global.h"
+#include "lim_session.h"
+
+#ifdef WLAN_FEATURE_11BE_MLO
+
+/**
+ * lim_update_partner_link_info - Update partner link information
+ *
+ * This function is triggered from mlo mgr
+ *
+ * @vdev: vdev pointer
+ *
+ * Return: QDF_STATUS_SUCCESS on successful update link info else failure.
+ */
+QDF_STATUS lim_partner_link_info_change(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * lim_get_max_simultaneous_link_num() - Get max simultaneous link num
+ *                                       It is max vdev number for sap
+ * @session: pe session
+ *
+ * Return: max simultaneous link num
+ */
+uint8_t lim_get_max_simultaneous_link_num(struct pe_session *session);
+
+/**
+ * lim_mlo_free_vdev_ref() - release vdev reference
+ * @vdev: vdev obj
+ *
+ * Return: void
+ */
+void lim_mlo_release_vdev_ref(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pe_find_partner_session_by_link_id() - Get partner session by link id
+ * @session: pe session
+ * @link_id: link id
+ *
+ * Return: partner session
+ */
+struct pe_session *pe_find_partner_session_by_link_id(
+		struct pe_session *session, uint8_t link_id);
+
+/**
+ * lim_get_mlo_vdev_list() - Get mlo vdev list
+ * @session: pe session
+ * @vdev_count: vdev count
+ * @wlan_vdev_list: vdev list
+ *
+ * Return: void
+ */
+void lim_get_mlo_vdev_list(struct pe_session *session, uint16_t *vdev_count,
+			   struct wlan_objmgr_vdev **wlan_vdev_list);
+#endif
+#endif

+ 47 - 1
core/mac/src/pe/sch/sch_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2021 The Linux Foundation. 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
@@ -46,6 +46,47 @@
 
 #include "wma_types.h"
 
+#ifdef WLAN_FEATURE_11BE_MLO
+#include "lim_mlo.h"
+#endif
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * lim_notify_link_info() - notify partner link to update beacon template
+ * @pe_session: pointer to pe session
+ *
+ * Return: void
+ */
+static void lim_notify_link_info(struct pe_session *pe_session)
+{
+	struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
+	uint16_t vdev_count = 0;
+	int link;
+
+	if (!pe_session->mlo_link_info.upt_bcn_mlo_ie &&
+	    pe_session->mlo_link_info.mlo_rnr_updated)
+		return;
+	pe_session->mlo_link_info.mlo_rnr_updated = true;
+	pe_debug("mlo notify beacon change info to partner link");
+	lim_get_mlo_vdev_list(pe_session, &vdev_count,
+			      wlan_vdev_list);
+	for (link = 0; link < vdev_count; link++) {
+		if (!wlan_vdev_list[link])
+			continue;
+		if (wlan_vdev_list[link] == session->vdev) {
+			lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
+			continue;
+		}
+		lim_partner_link_info_change(wlan_vdev_list[link]);
+		lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
+	}
+}
+#else
+static void lim_notify_link_info(struct pe_session *pe_session)
+{
+}
+#endif
+
 QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload,
 			       uint16_t size, struct pe_session *pe_session,
 			       enum sir_bcn_update_reason reason)
@@ -121,6 +162,11 @@ QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload,
 		pe_err("Posting SEND_BEACON_REQ to HAL failed, reason=%X",
 			retCode);
 
+	if (QDF_IS_STATUS_SUCCESS(retCode)) {
+		if (wlan_vdev_mlme_is_mlo_ap(pe_session->vdev))
+			lim_notify_link_info(pe_session);
+	}
+
 	return retCode;
 }
 

+ 185 - 0
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -48,6 +48,163 @@
 
 const uint8_t p2p_oui[] = { 0x50, 0x6F, 0x9A, 0x9 };
 
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * lim_update_link_info() - update mlo_link_info
+ * @mac_ctx: mac context
+ * @session: pe session
+ * @bcn_1: pointer to tDot11fBeacon1
+ * @bcn_2: pointer to tDot11fBeacon2
+ *
+ * Return: void
+ */
+static void lim_update_link_info(struct mac_context *mac_ctx,
+				 struct pe_session *session,
+				 tDot11fBeacon1 *bcn_1,
+				 tDot11fBeacon2 *bcn_2)
+{
+	struct mlo_link_ie *link_ie = &session->mlo_link_info.link_ie;
+	uint16_t offset;
+	uint8_t *ptr;
+	uint32_t n_bytes;
+
+	session->mlo_link_info.upt_bcn_mlo_ie = false;
+	session->mlo_link_info.bss_param_change = false;
+
+	if (qdf_mem_cmp(&link_ie->link_ds, &bcn_1->DSParams,
+			sizeof(bcn_1->DSParams))) {
+		qdf_mem_copy(&link_ie->link_ds, &bcn_1->DSParams,
+			     sizeof(bcn_1->DSParams));
+		session->mlo_link_info.bss_param_change = true;
+	}
+
+	qdf_mem_copy(&link_ie->link_wmm_params, &bcn_2->WMMParams,
+		     sizeof(bcn_2->WMMParams));
+
+	qdf_mem_copy(&link_ie->link_wmm_caps, &bcn_2->WMMCaps,
+		     sizeof(bcn_2->WMMCaps));
+
+	if (qdf_mem_cmp(&link_ie->link_edca, &bcn_2->EDCAParamSet,
+			sizeof(bcn_2->EDCAParamSet))) {
+		qdf_mem_copy(&link_ie->link_edca, &bcn_2->EDCAParamSet,
+			     sizeof(bcn_2->EDCAParamSet));
+		session->mlo_link_info.bss_param_change = true;
+	}
+
+	if (qdf_mem_cmp(&link_ie->link_csa, &bcn_2->ChanSwitchAnn,
+			sizeof(bcn_2->ChanSwitchAnn))) {
+		session->mlo_link_info.upt_bcn_mlo_ie = true;
+		qdf_mem_copy(&link_ie->link_csa, &bcn_2->ChanSwitchAnn,
+			     sizeof(bcn_2->ChanSwitchAnn));
+	}
+
+	if (qdf_mem_cmp(&link_ie->link_ecsa, &bcn_2->ext_chan_switch_ann,
+			sizeof(bcn_2->ext_chan_switch_ann))) {
+		session->mlo_link_info.upt_bcn_mlo_ie = true;
+		qdf_mem_copy(&link_ie->link_ecsa, &bcn_2->ext_chan_switch_ann,
+			     sizeof(bcn_2->ext_chan_switch_ann));
+	}
+
+	if (qdf_mem_cmp(&link_ie->link_swt_time, &bcn_2->max_chan_switch_time,
+			sizeof(bcn_2->max_chan_switch_time))) {
+		session->mlo_link_info.upt_bcn_mlo_ie = true;
+		qdf_mem_copy(&link_ie->link_swt_time,
+			     &bcn_2->max_chan_switch_time,
+			     sizeof(bcn_2->max_chan_switch_time));
+	}
+
+	if (qdf_mem_cmp(&link_ie->link_quiet, &bcn_2->Quiet,
+			sizeof(bcn_2->Quiet))) {
+		session->mlo_link_info.upt_bcn_mlo_ie = true;
+		qdf_mem_copy(&link_ie->link_quiet, &bcn_2->Quiet,
+			     sizeof(bcn_2->Quiet));
+	}
+
+	if (qdf_mem_cmp(&link_ie->link_ht_info, &bcn_2->HTInfo,
+			sizeof(bcn_2->HTInfo))) {
+		qdf_mem_copy(&link_ie->link_ht_info, &bcn_2->HTInfo,
+			     sizeof(bcn_2->HTInfo));
+		session->mlo_link_info.bss_param_change = true;
+	}
+
+	if (qdf_mem_cmp(&link_ie->link_vht_op, &bcn_2->VHTOperation,
+			sizeof(bcn_2->VHTOperation))) {
+		qdf_mem_copy(&link_ie->link_vht_op, &bcn_2->VHTOperation,
+			     sizeof(bcn_2->VHTOperation));
+		session->mlo_link_info.bss_param_change = true;
+	}
+
+	if (qdf_mem_cmp(&link_ie->link_he_op, &bcn_2->he_op,
+			sizeof(bcn_2->he_op))) {
+		qdf_mem_copy(&link_ie->link_he_op, &bcn_2->he_op,
+			     sizeof(bcn_2->he_op));
+		session->mlo_link_info.bss_param_change = true;
+	}
+
+	if (qdf_mem_cmp(&link_ie->link_eht_op, &bcn_2->eht_op,
+			sizeof(bcn_2->eht_op))) {
+		qdf_mem_copy(&link_ie->link_eht_op, &bcn_2->eht_op,
+			     sizeof(bcn_2->eht_op));
+		session->mlo_link_info.bss_param_change = true;
+	}
+
+	/*
+	 * MLOTD
+	 * If max channel switch time is not exist, calculate one for partner
+	 * link, if current link enters CAC
+	 */
+
+	if (session->mlo_link_info.bcn_tmpl_exist) {
+		if (bcn_2->ChanSwitchAnn.present ||
+		    bcn_2->ext_chan_switch_ann.present ||
+		    bcn_2->Quiet.present ||
+		    bcn_2->WiderBWChanSwitchAnn.present ||
+		    bcn_2->ChannelSwitchWrapper.present ||
+		    bcn_2->OperatingMode.present ||
+		    bcn_2->bss_color_change.present)
+			session->mlo_link_info.bss_param_change = true;
+		if (session->mlo_link_info.bss_param_change) {
+			link_ie->bss_param_change_cnt++;
+			offset = sizeof(tAniBeaconStruct);
+			bcn_1->Capabilities.criticalUpdateFlag = 1;
+			ptr = session->pSchBeaconFrameBegin + offset;
+			dot11f_pack_beacon1(mac_ctx, bcn_1, ptr,
+					    SIR_MAX_BEACON_SIZE - offset,
+					    &n_bytes);
+			bcn_1->Capabilities.criticalUpdateFlag = 0;
+		}
+	} else {
+		//save one time
+		session->mlo_link_info.bcn_tmpl_exist = true;
+		session->mlo_link_info.link_ie.bss_param_change_cnt = 0;
+		qdf_mem_copy(&link_ie->link_cap, &bcn_1->Capabilities,
+			     sizeof(bcn_1->Capabilities));
+		qdf_mem_copy(&link_ie->link_qcn_ie, &bcn_2->qcn_ie,
+			     sizeof(bcn_2->qcn_ie));
+		qdf_mem_copy(&link_ie->link_ht_cap, &bcn_2->HTCaps,
+			     sizeof(bcn_2->HTCaps));
+		qdf_mem_copy(&link_ie->link_ext_cap, &bcn_2->ExtCap,
+			     sizeof(bcn_2->ExtCap));
+		qdf_mem_copy(&link_ie->link_vht_cap, &bcn_2->VHTCaps,
+			     sizeof(bcn_2->VHTCaps));
+		qdf_mem_copy(&link_ie->link_he_cap, &bcn_2->he_cap,
+			     sizeof(bcn_2->he_cap));
+		qdf_mem_copy(&link_ie->link_he_6ghz_band_cap,
+			     &bcn_2->he_6ghz_band_cap,
+			     sizeof(bcn_2->he_6ghz_band_cap));
+		qdf_mem_copy(&link_ie->link_eht_cap, &bcn_2->eht_cap,
+			     sizeof(bcn_2->eht_cap));
+	}
+}
+#else
+static void lim_update_link_info(struct mac_context *mac_ctx,
+				 struct pe_session *session,
+				 tDot11fBeacon1 *bcn_1,
+				 tDot11fBeacon2 *bcn_2)
+{
+}
+#endif
+
 static QDF_STATUS sch_get_p2p_ie_offset(uint8_t *pextra_ie,
 					uint32_t extra_ie_len,
 					uint16_t *pie_offset)
@@ -437,6 +594,11 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 			}
 		}
 	}
+
+	if (bcn_2->ext_chan_switch_ann.present || bcn_2->ChanSwitchAnn.present)
+		populate_dot11f_max_chan_switch_time(
+			mac_ctx, &bcn_2->max_chan_switch_time, session);
+
 	if (mac_ctx->rrm.rrmConfig.sap_rrm_enabled)
 		populate_dot11f_rrm_ie(mac_ctx, &bcn_2->RRMEnabledCap,
 			session);
@@ -548,6 +710,14 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 	}
 
 	if (LIM_IS_AP_ROLE(session)) {
+		if (wlan_vdev_mlme_is_mlo_ap(session->vdev)) {
+			lim_update_link_info(mac_ctx, session, bcn_1, bcn_2);
+			populate_dot11f_bcn_mlo_ie(mac_ctx, session,
+						   &bcn_2->mlo_ie);
+			populate_dot11f_mlo_rnr(
+				mac_ctx, session,
+				&bcn_2->reduced_neighbor_report);
+		}
 		/*
 		 * Can be efficiently updated whenever new IE added  in Probe
 		 * response in future
@@ -959,6 +1129,21 @@ void lim_update_probe_rsp_template_ie_bitmap_beacon2(struct mac_context *mac,
 			     sizeof(beacon2->eht_op));
 	}
 
+	if (beacon2->mlo_ie.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					DOT11F_EID_MLO_IE);
+		qdf_mem_copy((void *)&prb_rsp->mlo_ie,
+			     (void *)&beacon2->mlo_ie,
+			     sizeof(beacon2->mlo_ie));
+	}
+
+	if (beacon2->reduced_neighbor_report.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					DOT11F_EID_REDUCED_NEIGHBOR_REPORT);
+		qdf_mem_copy((void *)&prb_rsp->reduced_neighbor_report,
+			     (void *)&beacon2->reduced_neighbor_report,
+			     sizeof(beacon2->reduced_neighbor_report));
+	}
 }
 
 void set_probe_rsp_ie_bitmap(uint32_t *IeBitmap, uint32_t pos)