Эх сурвалжийг харах

qcacmn: Add bearer switch request in connect path

If LL_LT_SAP is already present and if STA tries to
come up on same mac, then it may result in data loss
on LL_LT_SAP as STA will need ROC on the connection
channel for some time, to avoid these data loss during
STA connection, add logic to switch the bearer for LL_LT_SAP
data to non-wlan and once connection completes, switch back
the bearer to wlan.

Change-Id: Ic44cd77b9b5e569350d697c33260cf5cec3652e0
CRs-Fixed: 3627643
Ashish Kumar Dhanotiya 1 жил өмнө
parent
commit
9a73106903

+ 83 - 37
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -44,6 +44,9 @@
 #include <wlan_objmgr_vdev_obj.h>
 #include "wlan_psoc_mlme_api.h"
 #include "wlan_scan_public_structs.h"
+#ifdef WLAN_FEATURE_LL_LT_SAP
+#include "wlan_ll_sap_api.h"
+#endif
 
 void
 cm_fill_failure_resp_from_cm_id(struct cnx_mgr *cm_ctx,
@@ -313,9 +316,41 @@ cm_send_connect_start_fail(struct cnx_mgr *cm_ctx,
 }
 
 #ifdef WLAN_POLICY_MGR_ENABLE
+static void
+cm_cont_connect_for_event(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			  wlan_cm_id cm_id, enum wlan_cm_sm_evt event)
+{
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+	struct cnx_mgr *cm_ctx;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev)
+		return;
+
+	cm_ctx = cm_get_cm_ctx(vdev);
+	if (!cm_ctx) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+		return;
+	}
+
+	status = cm_sm_deliver_event(vdev, event, sizeof(wlan_cm_id), &cm_id);
+
+	/*
+	 * Handle failure if posting fails, i.e. the SM state has
+	 * changed or head cm_id doesn't match the active cm_id. If
+	 * new command has been received connect should be
+	 * aborted from here with req cleanup.
+	 */
+	if (QDF_IS_STATUS_ERROR(status))
+		cm_connect_handle_event_post_fail(cm_ctx, cm_id);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+}
 
-QDF_STATUS cm_handle_hw_mode_change(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
-				    enum wlan_cm_sm_evt event)
+QDF_STATUS
+cm_ser_connect_after_mode_change_resp(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
+				      enum wlan_cm_sm_evt event)
 {
 	struct cm_req *cm_req;
 	enum wlan_cm_connect_fail_reason reason = CM_GENERIC_FAILURE;
@@ -337,18 +372,22 @@ QDF_STATUS cm_handle_hw_mode_change(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
 		goto send_failure;
 	}
 
-	if (event == WLAN_CM_SM_EV_HW_MODE_SUCCESS) {
+	switch (event) {
+	case WLAN_CM_SM_EV_HW_MODE_SUCCESS:
+	case WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE:
 		status = cm_ser_connect_req(pdev, cm_ctx, &cm_req->connect_req);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			reason = CM_SER_FAILURE;
-			goto send_failure;
+			break;
 		}
 		return status;
+	case WLAN_CM_SM_EV_HW_MODE_FAILURE:
+		reason = CM_HW_MODE_FAILURE;
+		break;
+	default:
+		break;
 	}
 
-	/* Set reason HW mode fail for event WLAN_CM_SM_EV_HW_MODE_FAILURE */
-	reason = CM_HW_MODE_FAILURE;
-
 send_failure:
 	return cm_send_connect_start_fail(cm_ctx, &cm_req->connect_req, reason);
 }
@@ -356,40 +395,16 @@ send_failure:
 void cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 			    wlan_cm_id cm_id, QDF_STATUS status)
 {
-	struct wlan_objmgr_vdev *vdev;
-	QDF_STATUS qdf_status;
 	enum wlan_cm_sm_evt event = WLAN_CM_SM_EV_HW_MODE_SUCCESS;
-	struct cnx_mgr *cm_ctx;
 
 	mlme_debug(CM_PREFIX_FMT "Continue connect after HW mode change, status %d",
 		   CM_PREFIX_REF(vdev_id, cm_id), status);
 
-	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
-						    WLAN_MLME_CM_ID);
-	if (!vdev)
-		return;
-
-	cm_ctx = cm_get_cm_ctx(vdev);
-	if (!cm_ctx) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
-		return;
-	}
-
 	if (QDF_IS_STATUS_ERROR(status))
 		event = WLAN_CM_SM_EV_HW_MODE_FAILURE;
-	qdf_status = cm_sm_deliver_event(vdev, event, sizeof(wlan_cm_id),
-					 &cm_id);
 
-	/*
-	 * Handle failure if posting fails, i.e. the SM state has
-	 * changed or head cm_id doesn't match the active cm_id.
-	 * hw mode change resp should be handled only in JOIN_PENDING. If
-	 * new command has been received connect should be
-	 * aborted from here with connect req cleanup.
-	 */
-	if (QDF_IS_STATUS_ERROR(status))
-		cm_connect_handle_event_post_fail(cm_ctx, cm_id);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+	cm_cont_connect_for_event(wlan_pdev_get_psoc(pdev), vdev_id, cm_id,
+				  event);
 }
 
 static QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
@@ -400,10 +415,7 @@ static QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
 	return policy_mgr_change_hw_mode_sta_connect(psoc, scan_list, vdev_id,
 						     connect_id);
 }
-
-
 #else
-
 static inline
 QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
 				       qdf_list_t *scan_list, uint8_t vdev_id,
@@ -411,9 +423,35 @@ QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
 {
 	return QDF_STATUS_E_ALREADY;
 }
-
 #endif /* WLAN_POLICY_MGR_ENABLE */
 
+#ifdef WLAN_FEATURE_LL_LT_SAP
+void cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			   wlan_cm_id cm_id, QDF_STATUS status)
+{
+	mlme_debug(CM_PREFIX_FMT "Continue connect after bearer switch %d",
+		   CM_PREFIX_REF(vdev_id, cm_id), status);
+
+	cm_cont_connect_for_event(psoc, vdev_id, cm_id,
+				  WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE);
+}
+
+static QDF_STATUS
+cm_check_for_bearer_switch(struct wlan_objmgr_psoc *psoc, qdf_list_t *scan_list,
+			   uint8_t vdev_id, wlan_cm_id cm_id)
+{
+	return wlan_ll_sap_switch_bearer_on_sta_connect_start(psoc, scan_list,
+							      vdev_id, cm_id);
+}
+#else
+static inline QDF_STATUS
+cm_check_for_bearer_switch(struct wlan_objmgr_psoc *psoc, qdf_list_t *scan_list,
+			   uint8_t vdev_id, wlan_cm_id cm_id)
+{
+	return QDF_STATUS_E_ALREADY;
+}
+#endif /* WLAN_FEATURE_LL_LT_SAP  */
+
 static inline void cm_delete_pmksa_for_bssid(struct cnx_mgr *cm_ctx,
 					     struct qdf_mac_addr *bssid)
 {
@@ -1889,6 +1927,14 @@ QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx,
 		goto connect_err;
 	}
 
+	status = cm_check_for_bearer_switch(psoc, cm_req->candidate_list,
+					    vdev_id, cm_req->cm_id);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mlme_debug(CM_PREFIX_FMT "Connect will continue after bearer switch",
+			   CM_PREFIX_REF(vdev_id, cm_req->cm_id));
+		return QDF_STATUS_SUCCESS;
+	}
+
 	status = cm_check_for_hw_mode_change(psoc, cm_req->candidate_list,
 					     vdev_id, cm_req->cm_id);
 	if (QDF_IS_STATUS_ERROR(status) && status != QDF_STATUS_E_ALREADY) {

+ 1 - 1
umac/mlme/connection_mgr/core/src/wlan_cm_host_roam.c

@@ -752,7 +752,7 @@ void cm_reassoc_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev,
 	 * new command has been received reassoc should be
 	 * aborted from here with reassoc req cleanup.
 	 */
-	if (QDF_IS_STATUS_ERROR(status))
+	if (QDF_IS_STATUS_ERROR(qdf_status))
 		cm_reassoc_handle_event_post_fail(cm_ctx, cm_id);
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
 }

+ 24 - 6
umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h

@@ -332,19 +332,22 @@ void cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 			    wlan_cm_id cm_id, QDF_STATUS status);
 
 /**
- * cm_handle_hw_mode_change() - SM handling of hw mode change resp
+ * cm_ser_connect_after_mode_change_resp() - SM handling of
+ * hw mode change/bearer switch resp
  * @cm_ctx: connection manager context
  * @cm_id: Connection mgr ID assigned to this connect request.
- * @event: HW mode success or failure event
+ * @event: success or failure event
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS cm_handle_hw_mode_change(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
-				    enum wlan_cm_sm_evt event);
+QDF_STATUS cm_ser_connect_after_mode_change_resp(struct cnx_mgr *cm_ctx,
+						wlan_cm_id *cm_id,
+						enum wlan_cm_sm_evt event);
 #else
 static inline
-QDF_STATUS cm_handle_hw_mode_change(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
-				    enum wlan_cm_sm_evt event)
+QDF_STATUS cm_ser_connect_after_mode_change_resp(struct cnx_mgr *cm_ctx,
+						wlan_cm_id *cm_id,
+						enum wlan_cm_sm_evt event)
 {
 	return QDF_STATUS_SUCCESS;
 }
@@ -1591,4 +1594,19 @@ cm_bss_mlo_type(struct wlan_objmgr_psoc *psoc,
 	return SLO;
 }
 #endif
+
+#ifdef WLAN_FEATURE_LL_LT_SAP
+/**
+ * cm_bearer_switch_resp() - Bearer switch response
+ * @psoc: Psoc pointer
+ * @vdev_id: vdev id
+ * @cm_id: connection ID which gave the hw mode change request
+ * @status: status of the bearer switch
+ *
+ * Return: void
+ */
+void cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			   wlan_cm_id cm_id, QDF_STATUS status);
+#endif
+
 #endif /* __WLAN_CM_MAIN_API_H__ */

+ 3 - 1
umac/mlme/connection_mgr/core/src/wlan_cm_sm.c

@@ -618,12 +618,13 @@ static bool cm_subst_join_pending_event(void *ctx, uint16_t event,
 		break;
 	case WLAN_CM_SM_EV_HW_MODE_SUCCESS:
 	case WLAN_CM_SM_EV_HW_MODE_FAILURE:
+	case WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE:
 		/* check if cm id is valid for the current req */
 		if (!cm_check_cmid_match_list_head(cm_ctx, data)) {
 			event_handled = false;
 			break;
 		}
-		cm_handle_hw_mode_change(cm_ctx, data, event);
+		cm_ser_connect_after_mode_change_resp(cm_ctx, data, event);
 		break;
 	case WLAN_CM_SM_EV_SCAN:
 		cm_sm_transition_to(cm_ctx, WLAN_CM_SS_SCAN);
@@ -1279,6 +1280,7 @@ static const char *cm_sm_event_names[] = {
 	"EV_REASSOC_TIMER",
 	"EV_HO_ROAM_DISCONNECT_DONE",
 	"EV_RSO_STOP_RSP",
+	"EV_BEARER_SWITCH_COMPLETE",
 };
 
 enum wlan_cm_sm_state cm_get_state(struct cnx_mgr *cm_ctx)

+ 3 - 0
umac/mlme/connection_mgr/core/src/wlan_cm_sm.h

@@ -70,6 +70,8 @@
  * @WLAN_CM_SM_EV_HO_ROAM_DISCONNECT_DONE: Disconnect done for hands off/roaming
  * @WLAN_CM_SM_EV_RSO_STOP_RSP:           Event to continue disconnect after
  *                                        RSO stop response is received
+ * @WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE: Event to continue connect after bearer
+ *                                       switch complete
  * @WLAN_CM_SM_EV_MAX:                    Max event
  */
 enum wlan_cm_sm_evt {
@@ -111,6 +113,7 @@ enum wlan_cm_sm_evt {
 	WLAN_CM_SM_EV_REASSOC_TIMER = 35,
 	WLAN_CM_SM_EV_HO_ROAM_DISCONNECT_DONE = 36,
 	WLAN_CM_SM_EV_RSO_STOP_RSP = 37,
+	WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE = 38,
 	WLAN_CM_SM_EV_MAX,
 };
 

+ 14 - 0
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h

@@ -662,4 +662,18 @@ enum MLO_TYPE
 wlan_cm_bss_mlo_type(struct wlan_objmgr_psoc *psoc,
 		     struct scan_cache_entry *entry,
 		     qdf_list_t *scan_list);
+
+#ifdef WLAN_FEATURE_LL_LT_SAP
+/**
+ * wlan_cm_bearer_switch_resp() - Bearer switch response
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @cm_id: connection ID which gave the hw mode change request
+ * @status: status of the Bearer switch
+ *
+ * Return: void
+ */
+void wlan_cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+				wlan_cm_id cm_id, QDF_STATUS status);
+#endif /* WLAN_FEATURE_LL_LT_SAP */
 #endif /* __WLAN_CM_UCFG_API_H */

+ 8 - 0
umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c

@@ -361,6 +361,14 @@ void wlan_cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 }
 #endif /* ifdef POLICY_MGR_ENABLE */
 
+#ifdef WLAN_FEATURE_LL_LT_SAP
+void wlan_cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+				wlan_cm_id cm_id, QDF_STATUS status)
+{
+	cm_bearer_switch_resp(psoc, vdev_id, cm_id, status);
+}
+#endif
+
 #ifdef SM_ENG_HIST_ENABLE
 void wlan_cm_sm_history_print(struct wlan_objmgr_vdev *vdev)
 {