Browse Source

qcacld-3.0: Allow 3 link roam sync based on fw capability

Currently while processing roam synch indication event, the
setup links info is filled for WLAN_UMAC_MLO_MAX_VDEVS(2). But
with 3 Link MLO support, it will reject the roam synch
indication event.
So allow 3 Link roam synch based on fw capability and ini
intersection for number of links supported. Use
wlan_mlme_get_sta_mlo_conn_max_num() API to get max allowed
links for connection.

Also replace array length declaration for setup_links having
WLAN_UMAC_MLO_MAX_VDEVS and use WLAN_MAX_ML_BSS_LINKS instead.

Change-Id: I1982e50f5036ba4eacbab50044444a7238cd1073
CRs-Fixed: 3573066
Pragaspathi Thilagaraj 1 year ago
parent
commit
e25cd1cafb

+ 34 - 2
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c

@@ -427,6 +427,30 @@ cm_fils_update_erp_seq_num(struct wlan_objmgr_vdev *vdev,
 #endif
 
 #ifdef WLAN_FEATURE_11BE_MLO
+static void
+cm_roam_update_mlo_mgr_info(struct wlan_objmgr_vdev *vdev,
+			    struct roam_offload_synch_ind *roam_synch_data)
+{
+	struct wlan_channel channel = {0};
+	struct ml_setup_link_param *ml_link;
+	uint8_t i;
+
+	if (!is_multi_link_roam(roam_synch_data))
+		return;
+
+	for (i = 0; i < roam_synch_data->num_setup_links; i++) {
+		ml_link = &roam_synch_data->ml_link[i];
+
+		channel.ch_freq = ml_link->channel.mhz;
+		channel.ch_cfreq1 = ml_link->channel.band_center_freq1;
+		channel.ch_cfreq1 = ml_link->channel.band_center_freq2;
+
+		mlo_mgr_roam_update_ap_link_info(vdev, ml_link->link_id,
+						 ml_link->link_addr.bytes,
+						 channel);
+	}
+}
+
 static QDF_STATUS
 cm_fill_bssid_freq_info(uint8_t vdev_id,
 			struct roam_offload_synch_ind *roam_synch_data,
@@ -468,9 +492,14 @@ cm_mlo_roam_copy_partner_info(struct wlan_cm_connect_resp *connect_rsp,
 			      struct roam_offload_synch_ind *roam_synch_data)
 {
 	mlo_roam_copy_partner_info(&connect_rsp->ml_parnter_info,
-				   roam_synch_data, WLAN_INVALID_VDEV_ID);
+				   roam_synch_data, WLAN_INVALID_VDEV_ID,
+				   true);
 }
 #else
+static inline void
+cm_roam_update_mlo_mgr_info(struct wlan_objmgr_vdev *vdev,
+			    struct roam_offload_synch_ind *roam_synch_data)
+{}
 static QDF_STATUS
 cm_fill_bssid_freq_info(uint8_t vdev_id,
 			struct roam_offload_synch_ind *roam_synch_data,
@@ -536,7 +565,8 @@ cm_fill_roam_info(struct wlan_objmgr_vdev *vdev,
 
 	rsp->connect_rsp.roaming_info = qdf_mem_malloc(sizeof(*roaming_info));
 	if (!rsp->connect_rsp.roaming_info)
-			return QDF_STATUS_E_NOMEM;
+		return QDF_STATUS_E_NOMEM;
+
 	rsp->connect_rsp.vdev_id = wlan_vdev_get_id(vdev);
 	status = cm_fill_bssid_freq_info(wlan_vdev_get_id(vdev),
 					 roam_synch_data, rsp);
@@ -963,6 +993,8 @@ cm_fw_roam_sync_propagation(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 	wlan_rec_conn_info(vdev_id, DEBUG_CONN_ROAMING,
 			   roam_synch_data->bssid.bytes, 0, 0);
 
+	cm_roam_update_mlo_mgr_info(vdev, roam_synch_data);
+
 	cm_id = roam_req->cm_id;
 	rsp = qdf_mem_malloc(sizeof(struct cm_vdev_join_rsp));
 	if (!rsp) {

+ 2 - 2
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -2853,9 +2853,9 @@ struct roam_offload_synch_ind {
 	uint8_t is_link_beacon;
 #ifdef WLAN_FEATURE_11BE_MLO
 	uint8_t num_setup_links;
-	struct ml_setup_link_param ml_link[WLAN_UMAC_MLO_MAX_VDEVS];
+	struct ml_setup_link_param ml_link[WLAN_MAX_ML_BSS_LINKS];
 	uint8_t num_ml_key_material;
-	struct ml_key_material_param ml_key[WLAN_UMAC_MLO_MAX_VDEVS];
+	struct ml_key_material_param ml_key[WLAN_MAX_ML_BSS_LINKS];
 #endif
 };
 

+ 3 - 2
components/umac/mlme/mlo_mgr/inc/wlan_mlo_mgr_roam.h

@@ -176,6 +176,7 @@ QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
  * @partner_info: Destination buffer to fill partner info from roam sync ind
  * @sync_ind: roam sync ind pointer
  * @skip_vdev_id: Skip to copy the link info corresponds to this vdev_id
+ * @fill_all_links: Fill all the links for connect response to userspace
  *
  * This api will be called to copy partner link info to connect response.
  *
@@ -183,7 +184,7 @@ QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
  */
 void mlo_roam_copy_partner_info(struct mlo_partner_info *partner_info,
 				struct roam_offload_synch_ind *sync_ind,
-				uint8_t skip_vdev_id);
+				uint8_t skip_vdev_id, bool fill_all_links);
 
 /**
  * mlo_roam_init_cu_bpcc() - init cu bpcc per roam sync data
@@ -513,7 +514,7 @@ QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
 static inline void
 mlo_roam_copy_partner_info(struct mlo_partner_info *partner_info,
 			   struct roam_offload_synch_ind *sync_ind,
-			   uint8_t skip_vdev_id)
+			   uint8_t skip_vdev_id, bool fill_all_links)
 {}
 
 static inline

+ 18 - 8
components/umac/mlme/mlo_mgr/src/wlan_mlo_mgr_roam.c

@@ -55,7 +55,8 @@ mlo_check_connect_req_bmap(struct wlan_objmgr_vdev *vdev)
 			return qdf_test_bit(i, sta_ctx->wlan_connect_req_links);
 	}
 
-	mlo_err("vdev not found in ml dev ctx list");
+	mlo_err("vdev:%d not found in ml dev ctx list", wlan_vdev_get_id(vdev));
+
 	return false;
 }
 
@@ -122,7 +123,7 @@ mlo_update_vdev_after_roam(struct wlan_objmgr_psoc *psoc,
 						    vdev_id,
 						    WLAN_MLME_SB_ID);
 	if (!vdev) {
-		mlo_err("VDEV is null");
+		mlo_err("VDEV:%d is null", vdev_id);
 		return;
 	}
 
@@ -265,7 +266,8 @@ QDF_STATUS mlo_fw_roam_sync_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 		mlo_debug("MLO_ROAM: Roamed to single link MLO");
 		mlo_set_single_link_ml_roaming(psoc, vdev_id, true);
 	} else {
-		mlo_debug("MLO_ROAM: Roamed to MLO");
+		mlo_debug("MLO_ROAM: Roamed to MLO with %d links",
+			  sync_ind->num_setup_links);
 		mlo_set_single_link_ml_roaming(psoc, vdev_id, false);
 	}
 
@@ -319,12 +321,16 @@ QDF_STATUS mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
 		if (vdev_id == sync_ind->ml_link[i].vdev_id)
 			continue;
 
+		/* Standby Link */
+		if (sync_ind->ml_link[i].vdev_id == WLAN_INVALID_VDEV_ID)
+			continue;
+
 		link_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
 								 sync_ind->ml_link[i].vdev_id,
 								 WLAN_MLME_SB_ID);
-
 		if (!link_vdev) {
-			mlo_err("Link vdev is null");
+			mlo_err("Link vdev:%d is null",
+				sync_ind->ml_link[i].vdev_id);
 			return QDF_STATUS_E_FAILURE;
 		}
 
@@ -553,7 +559,7 @@ QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
 void
 mlo_roam_copy_partner_info(struct mlo_partner_info *partner_info,
 			   struct roam_offload_synch_ind *sync_ind,
-			   uint8_t skip_vdev_id)
+			   uint8_t skip_vdev_id, bool fill_all_links)
 {
 	uint8_t i, j;
 	struct mlo_link_info *link;
@@ -562,8 +568,10 @@ mlo_roam_copy_partner_info(struct mlo_partner_info *partner_info,
 		return;
 
 	for (i = 0, j = 0; i < sync_ind->num_setup_links; i++) {
-		if (sync_ind->ml_link[i].vdev_id == skip_vdev_id)
+		if (!fill_all_links &&
+		    sync_ind->ml_link[i].vdev_id == skip_vdev_id)
 			continue;
+
 		link = &partner_info->partner_link_info[j];
 		link->link_id = sync_ind->ml_link[i].link_id;
 		link->vdev_id = sync_ind->ml_link[i].vdev_id;
@@ -577,7 +585,9 @@ mlo_roam_copy_partner_info(struct mlo_partner_info *partner_info,
 		j++;
 	}
 	partner_info->num_partner_links = j;
-	mlo_debug("num_setup_links %d", partner_info->num_partner_links);
+	mlo_debug("vdev_to_skip:%d num_setup_links %d fill_all_links:%d",
+		  skip_vdev_id, partner_info->num_partner_links,
+		  fill_all_links);
 }
 
 void mlo_roam_init_cu_bpcc(struct wlan_objmgr_vdev *vdev,

+ 41 - 25
components/wmi/src/wmi_unified_roam_tlv.c

@@ -2227,33 +2227,44 @@ wmi_fill_data_synch_event(struct roam_offload_synch_ind *roam_sync_ind,
 }
 
 #ifdef WLAN_FEATURE_11BE_MLO
+#define STANDBY_VDEV_ID (0xFFFFFFFF)
 static QDF_STATUS
 wmi_fill_roam_mlo_info(wmi_unified_t wmi_handle,
 		       WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
 		       struct roam_offload_synch_ind *roam_sync_ind)
 {
-	uint8_t i;
+	uint8_t i, mlo_max_allowed_links;
 	wmi_roam_ml_setup_links_param *setup_links;
 	wmi_roam_ml_key_material_param *ml_key_param;
 	struct ml_setup_link_param *link;
 	struct ml_key_material_param *key;
 
+	mlo_max_allowed_links =
+		wlan_mlme_get_sta_mlo_conn_max_num(wmi_handle->soc->wmi_psoc);
 	if (param_buf->num_setup_links_param) {
-		if (param_buf->num_setup_links_param >
-		    WLAN_UMAC_MLO_MAX_VDEVS) {
-			wmi_err("Number of umac mlo vdev entries %d exceeded max vdev supported %d",
+		if (param_buf->num_setup_links_param > mlo_max_allowed_links ||
+		    param_buf->num_setup_links_param > WLAN_MAX_ML_BSS_LINKS) {
+			wmi_err("Number of links %d exceeded max vdev supported %d",
 				param_buf->num_setup_links_param,
-				WLAN_UMAC_MLO_MAX_VDEVS);
+				mlo_max_allowed_links);
 			return QDF_STATUS_E_INVAL;
 		}
+
 		roam_sync_ind->num_setup_links =
-			param_buf->num_setup_links_param;
+				param_buf->num_setup_links_param;
 		setup_links = param_buf->setup_links_param;
 
 		for (i = 0; i < roam_sync_ind->num_setup_links; i++) {
 			link = &roam_sync_ind->ml_link[i];
 			link->link_id = setup_links->link_id;
-			link->vdev_id = setup_links->vdev_id;
+
+			/*
+			 * setup_links->vdev_id == UINT32_MAX for standby link
+			 */
+			link->vdev_id = WLAN_INVALID_VDEV_ID;
+			if (setup_links->vdev_id != STANDBY_VDEV_ID)
+				link->vdev_id = setup_links->vdev_id;
+
 			link->channel = setup_links->channel;
 			link->flags = setup_links->flags;
 
@@ -2270,25 +2281,30 @@ wmi_fill_roam_mlo_info(wmi_unified_t wmi_handle,
 			setup_links++;
 		}
 	}
-	if (param_buf->num_ml_key_material) {
-		roam_sync_ind->num_ml_key_material =
-			param_buf->num_ml_key_material;
-		ml_key_param = param_buf->ml_key_material;
-
-		for (i = 0; i < roam_sync_ind->num_ml_key_material; i++) {
-			key = &roam_sync_ind->ml_key[i];
-			key->link_id = ml_key_param->link_id;
-			key->key_idx = ml_key_param->key_ix;
-			key->key_cipher = ml_key_param->key_cipher;
-			qdf_mem_copy(key->pn, ml_key_param->pn,
-				     WMI_MAX_PN_LEN);
-			qdf_mem_copy(key->key_buff, ml_key_param->key_buff,
-				     WMI_MAX_KEY_LEN);
-			wmi_debug("link_id: %u key_idx: %u key_cipher: %u",
-				  key->link_id, key->key_idx, key->key_cipher);
-			ml_key_param++;
-		}
+
+	if (!param_buf->num_ml_key_material)
+		return QDF_STATUS_SUCCESS;
+
+	if (param_buf->num_ml_key_material > WLAN_MAX_ML_BSS_LINKS)
+		param_buf->num_ml_key_material = WLAN_MAX_ML_BSS_LINKS;
+
+	roam_sync_ind->num_ml_key_material = param_buf->num_ml_key_material;
+	ml_key_param = param_buf->ml_key_material;
+
+	for (i = 0; i < roam_sync_ind->num_ml_key_material; i++) {
+		key = &roam_sync_ind->ml_key[i];
+		key->link_id = ml_key_param->link_id;
+		key->key_idx = ml_key_param->key_ix;
+		key->key_cipher = ml_key_param->key_cipher;
+		qdf_mem_copy(key->pn, ml_key_param->pn,
+			     WMI_MAX_PN_LEN);
+		qdf_mem_copy(key->key_buff, ml_key_param->key_buff,
+			     WMI_MAX_KEY_LEN);
+		wmi_debug("link_id: %u key_idx: %u key_cipher: %u",
+			  key->link_id, key->key_idx, key->key_cipher);
+		ml_key_param++;
 	}
+
 	return QDF_STATUS_SUCCESS;
 }
 #else

+ 1 - 1
core/mac/src/pe/lim/lim_api.c

@@ -2654,7 +2654,7 @@ lim_mlo_roam_copy_partner_info_to_session(struct pe_session *session,
 					  struct roam_offload_synch_ind *sync_ind)
 {
 	mlo_roam_copy_partner_info(&session->ml_partner_info,
-				   sync_ind, sync_ind->roamed_vdev_id);
+				   sync_ind, sync_ind->roamed_vdev_id, false);
 }
 
 static QDF_STATUS