Przeglądaj źródła

qcacld-3.0: Single link ML connection

Currently if link specific probe response generation fails
STA keeps sending probe requests until proper probe response
is received or join timeout failure. This results in ML
connection failure

Change is to continue with single link ML connection if probe
response generation for link/s by clearing partner link information.

Change-Id: Ia969501a3bdd1ac70e14f3a0eafd0752207b66da
CRs-Fixed: 3238861
Amruta Kulkarni 2 lat temu
rodzic
commit
7ad653825e

+ 3 - 6
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -1440,7 +1440,9 @@ static void cm_process_connect_complete(struct wlan_objmgr_psoc *psoc,
 	    QDF_HAS_PARAM(ucast_cipher, WLAN_CRYPTO_CIPHER_WEP_104) ||
 	    QDF_HAS_PARAM(ucast_cipher, WLAN_CRYPTO_CIPHER_WEP_104) ||
 	    QDF_HAS_PARAM(ucast_cipher, WLAN_CRYPTO_CIPHER_WEP))) {
 	    QDF_HAS_PARAM(ucast_cipher, WLAN_CRYPTO_CIPHER_WEP))) {
 		cm_csr_set_ss_none(vdev_id);
 		cm_csr_set_ss_none(vdev_id);
-		if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
+		if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+			mlo_enable_rso(pdev, vdev, rsp);
+		else if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
 			cm_roam_start_init_on_connect(pdev, vdev_id);
 			cm_roam_start_init_on_connect(pdev, vdev_id);
 	} else {
 	} else {
 		if (rsp->is_wps_connection)
 		if (rsp->is_wps_connection)
@@ -1462,7 +1464,6 @@ cm_connect_complete_ind(struct wlan_objmgr_vdev *vdev,
 	struct wlan_objmgr_pdev *pdev;
 	struct wlan_objmgr_pdev *pdev;
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_objmgr_psoc *psoc;
 	enum QDF_OPMODE op_mode;
 	enum QDF_OPMODE op_mode;
-	QDF_STATUS status;
 
 
 	if (!vdev || !rsp) {
 	if (!vdev || !rsp) {
 		mlme_err("vdev or rsp is NULL");
 		mlme_err("vdev or rsp is NULL");
@@ -1510,10 +1511,6 @@ cm_connect_complete_ind(struct wlan_objmgr_vdev *vdev,
 		wlan_cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_INIT,
 		wlan_cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_INIT,
 					  REASON_CONNECT);
 					  REASON_CONNECT);
 
 
-	status = mlo_enable_rso(pdev, vdev);
-	if (QDF_IS_STATUS_ERROR(status))
-		return status;
-
 	return QDF_STATUS_SUCCESS;
 	return QDF_STATUS_SUCCESS;
 }
 }
 
 

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

@@ -122,13 +122,15 @@ is_multi_link_roam(struct roam_offload_synch_ind *sync_ind);
  *
  *
  * @pdev: pdev pointer
  * @pdev: pdev pointer
  * @vdev: assoc vdev pointer
  * @vdev: assoc vdev pointer
+ * @rsp: cm connect rsp
  *
  *
  * This api will be called to enable RSO for MLO connection.
  * This api will be called to enable RSO for MLO connection.
  *
  *
  * Return: qdf_status success or fail
  * Return: qdf_status success or fail
  */
  */
 QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
 QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
-			  struct wlan_objmgr_vdev *vdev);
+			  struct wlan_objmgr_vdev *vdev,
+			  struct wlan_cm_connect_resp *rsp);
 
 
 /**
 /**
  * mlo_roam_copy_partner_info - copy partner link info to connect response
  * mlo_roam_copy_partner_info - copy partner link info to connect response
@@ -270,7 +272,8 @@ is_multi_link_roam(struct roam_offload_synch_ind *sync_ind)
 
 
 static inline
 static inline
 QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
 QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
-			  struct wlan_objmgr_vdev *vdev)
+			  struct wlan_objmgr_vdev *vdev,
+			  struct wlan_cm_connect_resp *rsp)
 {
 {
 	return QDF_STATUS_SUCCESS;
 	return QDF_STATUS_SUCCESS;
 }
 }

+ 14 - 3
components/umac/mlme/mlo_mgr/src/wlan_mlo_mgr_roam.c

@@ -373,17 +373,27 @@ bool is_multi_link_roam(struct roam_offload_synch_ind *sync_ind)
 }
 }
 
 
 QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
 QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
-			  struct wlan_objmgr_vdev *vdev)
+			  struct wlan_objmgr_vdev *vdev,
+			  struct wlan_cm_connect_resp *rsp)
 {
 {
 	struct wlan_objmgr_vdev *assoc_vdev;
 	struct wlan_objmgr_vdev *assoc_vdev;
+	uint8_t num_partner_links;
 
 
-	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) {
+	if (!rsp) {
+		mlo_err("Connect resp is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	num_partner_links = rsp->ml_parnter_info.num_partner_links;
+
+	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev) ||
+	    !num_partner_links ||
+	    num_partner_links == 1) {
 		assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev);
 		assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev);
 		if (!assoc_vdev) {
 		if (!assoc_vdev) {
 			mlo_err("Assoc vdev is null");
 			mlo_err("Assoc vdev is null");
 			return QDF_STATUS_E_NULL_VALUE;
 			return QDF_STATUS_E_NULL_VALUE;
 		}
 		}
-
 		cm_roam_start_init_on_connect(pdev,
 		cm_roam_start_init_on_connect(pdev,
 					      wlan_vdev_get_id(assoc_vdev));
 					      wlan_vdev_get_id(assoc_vdev));
 	}
 	}
@@ -410,6 +420,7 @@ mlo_roam_copy_partner_info(struct wlan_cm_connect_resp *connect_rsp,
 			&partner_info->partner_link_info[i].link_addr,
 			&partner_info->partner_link_info[i].link_addr,
 			&sync_ind->ml_link[i].link_addr);
 			&sync_ind->ml_link[i].link_addr);
 	}
 	}
+	partner_info->num_partner_links = sync_ind->num_setup_links;
 }
 }
 
 
 void
 void

+ 39 - 3
core/mac/src/pe/lim/lim_api.c

@@ -3536,6 +3536,7 @@ lim_add_bcn_probe(struct wlan_objmgr_vdev *vdev, uint8_t *bcn_probe,
 					    &rx_param, frm_type);
 					    &rx_param, frm_type);
 }
 }
 
 
+#ifdef WLAN_FEATURE_11BE_MLO
 static QDF_STATUS
 static QDF_STATUS
 lim_validate_probe_rsp_link_info(struct pe_session *session_entry,
 lim_validate_probe_rsp_link_info(struct pe_session *session_entry,
 				 uint8_t *probe_rsp,
 				 uint8_t *probe_rsp,
@@ -3577,6 +3578,35 @@ lim_validate_probe_rsp_link_info(struct pe_session *session_entry,
 	return status;
 	return status;
 }
 }
 
 
+static void
+lim_clear_ml_partner_info(struct pe_session *session_entry)
+{
+	uint8_t idx;
+	struct mlo_partner_info *partner_info = NULL;
+
+	if (!session_entry || !session_entry->lim_join_req)
+		return;
+
+	partner_info = &session_entry->lim_join_req->partner_info;
+	if (!partner_info) {
+		pe_err("Partner link info not present");
+		return;
+	}
+	pe_debug_rl("Clear Partner Link/s information");
+	for (idx = 0; idx < partner_info->num_partner_links; idx++) {
+		partner_info->partner_link_info[idx].link_id = 0;
+		qdf_zero_macaddr(
+			&partner_info->partner_link_info[idx].link_addr);
+	}
+	partner_info->num_partner_links = 0;
+}
+#else
+static inline void
+lim_clear_ml_partner_info(struct pe_session *session_entry)
+{
+}
+#endif
+
 QDF_STATUS lim_check_for_ml_probe_req(struct pe_session *session)
 QDF_STATUS lim_check_for_ml_probe_req(struct pe_session *session)
 {
 {
 	if (!session || !session->lim_join_req)
 	if (!session || !session->lim_join_req)
@@ -3620,12 +3650,16 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx,
 	if (session_entry->lim_join_req->is_ml_probe_req_sent &&
 	if (session_entry->lim_join_req->is_ml_probe_req_sent &&
 	    rcvd_probe_resp->mlo_ie.mlo_ie_present) {
 	    rcvd_probe_resp->mlo_ie.mlo_ie_present) {
 
 
+		session_entry->lim_join_req->is_ml_probe_req_sent = false;
+
 		status = lim_validate_probe_rsp_link_info(session_entry,
 		status = lim_validate_probe_rsp_link_info(session_entry,
 							  probe_rsp,
 							  probe_rsp,
 							  probe_rsp_len);
 							  probe_rsp_len);
 
 
-		if (QDF_IS_STATUS_ERROR(status))
-			return status;
+		if (QDF_IS_STATUS_ERROR(status)) {
+			lim_clear_ml_partner_info(session_entry);
+			goto end;
+		}
 
 
 		link_probe_rsp.ptr = qdf_mem_malloc(probe_rsp_len);
 		link_probe_rsp.ptr = qdf_mem_malloc(probe_rsp_len);
 		if (!link_probe_rsp.ptr)
 		if (!link_probe_rsp.ptr)
@@ -3644,6 +3678,7 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx,
 
 
 		if (QDF_IS_STATUS_ERROR(status)) {
 		if (QDF_IS_STATUS_ERROR(status)) {
 			pe_err("MLO: Link probe response generation failed %d", status);
 			pe_err("MLO: Link probe response generation failed %d", status);
+			lim_clear_ml_partner_info(session_entry);
 			status = QDF_STATUS_E_FAILURE;
 			status = QDF_STATUS_E_FAILURE;
 			goto end;
 			goto end;
 		}
 		}
@@ -3676,7 +3711,8 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx,
 		return status;
 		return status;
 	}
 	}
 end:
 end:
-	qdf_mem_free(link_probe_rsp.ptr);
+	if (link_probe_rsp.ptr)
+		qdf_mem_free(link_probe_rsp.ptr);
 	link_probe_rsp.len = 0;
 	link_probe_rsp.len = 0;
 	return status;
 	return status;
 }
 }

+ 5 - 12
core/mac/src/pe/lim/lim_process_probe_rsp_frame.c

@@ -110,7 +110,6 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info
 	uint8_t qos_enabled = false;
 	uint8_t qos_enabled = false;
 	uint8_t wme_enabled = false;
 	uint8_t wme_enabled = false;
 	uint32_t chan_freq = 0;
 	uint32_t chan_freq = 0;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 
 	if (!session_entry) {
 	if (!session_entry) {
 		pe_err("session_entry is NULL");
 		pe_err("session_entry is NULL");
@@ -158,16 +157,11 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info
 	qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, body,
 	qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, body,
 			   frame_len);
 			   frame_len);
 
 
-	status = lim_gen_link_specific_probe_rsp(mac_ctx, session_entry,
-						 probe_rsp,
-						 body,
-						 frame_len,
-						 mac_ctx->lim.bss_rssi);
-
-	if (QDF_IS_STATUS_ERROR(status)) {
-		pe_debug_rl("Link specific prb rsp generation failed");
-		goto end;
-	}
+	lim_gen_link_specific_probe_rsp(mac_ctx, session_entry,
+					probe_rsp,
+					body,
+					frame_len,
+					mac_ctx->lim.bss_rssi);
 
 
 	if (session_entry->limMlmState ==
 	if (session_entry->limMlmState ==
 			eLIM_MLM_WT_JOIN_BEACON_STATE) {
 			eLIM_MLM_WT_JOIN_BEACON_STATE) {
@@ -284,7 +278,6 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info
 				mac_ctx, probe_rsp, session_entry);
 				mac_ctx, probe_rsp, session_entry);
 		}
 		}
 	}
 	}
-end:
 	qdf_mem_free(probe_rsp);
 	qdf_mem_free(probe_rsp);
 
 
 	/* Ignore Probe Response frame in all other states */
 	/* Ignore Probe Response frame in all other states */