Forráskód Böngészése

qcacld-3.0: 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: I7ace6c6f4f41548ec112882dc81be6c6b5a4eae0
CRs-Fixed: 3627656
Ashish Kumar Dhanotiya 1 éve
szülő
commit
0afa4fa7e5

+ 3 - 0
components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c

@@ -39,6 +39,7 @@
 #include "wlan_vdev_mgr_utils_api.h"
 #include "wlan_tdls_api.h"
 #include "wlan_mlo_mgr_link_switch.h"
+#include "wlan_ll_sap_api.h"
 
 QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev,
 				struct if_mgr_event_data *event_data)
@@ -189,6 +190,8 @@ QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev,
 		policy_mgr_check_concurrent_intf_and_restart_sap(psoc,
 				wlan_util_vdev_mgr_get_acs_mode_for_vdev(vdev));
 
+	wlan_ll_sap_switch_bearer_on_sta_connect_complete(psoc, vdev_id);
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 38 - 33
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.c

@@ -202,7 +202,7 @@ ll_lt_sap_invoke_req_callback_f(struct bearer_switch_info *bs_ctx,
 				QDF_STATUS status, const char *func)
 {
 	if (!bs_req->requester_cb) {
-		ll_sap_err("%s BS_SM vdev %d NULL cbk req_vdev %d src %d req %d arg val %d",
+		ll_sap_err("%s BS_SM vdev %d NULL cbk, req_vdev %d src %d req %d arg val %d",
 			   func, wlan_vdev_get_id(bs_ctx->vdev), bs_req->vdev_id,
 			   bs_req->source, bs_req->request_id,
 			   bs_req->arg_value);
@@ -443,8 +443,8 @@ ll_lt_sap_send_bs_req_to_userspace(struct wlan_objmgr_vdev *vdev,
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_wlan_in_non_wlan_state(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_wlan_in_non_wlan_state(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	QDF_STATUS status;
@@ -550,7 +550,7 @@ ll_lt_sap_handle_bs_to_wlan_in_non_wlan_requested_state(
 		return;
 
 	if (!bs_req->requester_cb) {
-		ll_sap_err("BS_SM vdev %d NULL cbk req_vdev %d src %d req %d arg val %d",
+		ll_sap_err("BS_SM vdev %d NULL cbk, req_vdev %d src %d req %d arg val %d",
 			   wlan_vdev_get_id(bs_ctx->vdev),
 			   bs_req->vdev_id, bs_req->source,
 			   bs_req->request_id, bs_req->arg_value);
@@ -609,8 +609,8 @@ ll_lt_sap_handle_bs_to_non_wlan_in_non_wlan_requested_state(
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_non_wlan_timeout(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_non_wlan_timeout(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	struct wlan_bearer_switch_request *first_bs_req;
@@ -659,8 +659,8 @@ static void ll_lt_sap_handle_bs_to_non_wlan_timeout(
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_non_wlan_completed(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_non_wlan_completed(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	struct wlan_bearer_switch_request *first_bs_req;
@@ -717,8 +717,8 @@ static void ll_lt_sap_handle_bs_to_non_wlan_completed(
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_non_wlan_failure(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_non_wlan_failure(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	struct wlan_bearer_switch_request *first_bs_req;
@@ -763,8 +763,8 @@ static void ll_lt_sap_handle_bs_to_non_wlan_failure(
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_wlan_in_wlan_state(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_wlan_in_wlan_state(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	ll_lt_sap_invoke_req_callback(bs_ctx, bs_req, QDF_STATUS_E_ALREADY);
@@ -781,8 +781,8 @@ static void ll_lt_sap_handle_bs_to_wlan_in_wlan_state(
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_non_wlan_in_wlan_state(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_non_wlan_in_wlan_state(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	QDF_STATUS status;
@@ -915,8 +915,8 @@ ll_lt_sap_switch_to_non_wlan_from_wlan(struct bearer_switch_info *bs_ctx)
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_wlan_timeout(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_wlan_timeout(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	bs_sm_transition_to(bs_ctx, BEARER_WLAN);
@@ -940,8 +940,8 @@ static void ll_lt_sap_handle_bs_to_wlan_timeout(
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_wlan_completed(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_wlan_completed(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	ll_lt_sap_stop_bs_timer(bs_ctx);
@@ -969,8 +969,8 @@ static void ll_lt_sap_handle_bs_to_wlan_completed(
  *
  * Return: None
  */
-static void ll_lt_sap_handle_bs_to_wlan_failure(
-				struct bearer_switch_info *bs_ctx,
+static void
+ll_lt_sap_handle_bs_to_wlan_failure(struct bearer_switch_info *bs_ctx,
 				struct wlan_bearer_switch_request *bs_req)
 {
 	ll_lt_sap_stop_bs_timer(bs_ctx);
@@ -1484,16 +1484,24 @@ rel_ref:
 	return status;
 }
 
-QDF_STATUS ll_lt_sap_switch_bearer_to_ble(
-				struct wlan_objmgr_psoc *psoc,
-				struct wlan_bearer_switch_request *bs_request)
+QDF_STATUS
+ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
+			       struct wlan_bearer_switch_request *bs_request)
 {
 	return bs_sm_deliver_event(psoc, WLAN_BS_SM_EV_SWITCH_TO_NON_WLAN,
 				   sizeof(*bs_request), bs_request);
 }
 
-QDF_STATUS ll_lt_sap_request_for_audio_transport_switch(
-					struct wlan_objmgr_vdev *vdev,
+QDF_STATUS
+ll_lt_sap_switch_bearer_to_wlan(struct wlan_objmgr_psoc *psoc,
+				struct wlan_bearer_switch_request *bs_request)
+{
+	return bs_sm_deliver_event(psoc, WLAN_BS_SM_EV_SWITCH_TO_WLAN,
+				   sizeof(*bs_request), bs_request);
+}
+
+QDF_STATUS
+ll_lt_sap_request_for_audio_transport_switch(struct wlan_objmgr_vdev *vdev,
 					enum bearer_switch_req_type req_type)
 {
 	struct ll_sap_vdev_priv_obj *ll_sap_obj;
@@ -1532,11 +1540,8 @@ QDF_STATUS ll_lt_sap_request_for_audio_transport_switch(
 			     wlan_vdev_get_id(vdev));
 
 		return QDF_STATUS_E_FAILURE;
-		}
-	} else {
-		ll_sap_err("BS_SM vdev %d Invalid audio transport type %d",
-			   req_type);
 	}
+	ll_sap_err("BS_SM vdev %d Invalid audio transport type %d", req_type);
 
 	return QDF_STATUS_E_INVAL;
 }
@@ -1663,10 +1668,10 @@ static void ll_lt_sap_deliver_non_wlan_audio_transport_switch_resp(
 	bs_sm_state_update(bs_ctx, BEARER_NON_WLAN);
 }
 
-void ll_lt_sap_deliver_audio_transport_switch_resp(
-			struct wlan_objmgr_vdev *vdev,
-			enum bearer_switch_req_type req_type,
-			enum bearer_switch_status status)
+void
+ll_lt_sap_deliver_audio_transport_switch_resp(struct wlan_objmgr_vdev *vdev,
+				enum bearer_switch_req_type req_type,
+				enum bearer_switch_status status)
 {
 	if (req_type == WLAN_BS_REQ_TO_NON_WLAN)
 		ll_lt_sap_deliver_non_wlan_audio_transport_switch_resp(

+ 12 - 2
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.h

@@ -270,6 +270,16 @@ QDF_STATUS
 ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
 			       struct wlan_bearer_switch_request *bs_request);
 
+/**
+ * ll_lt_sap_switch_bearer_to_wlan() - Switch audio transport to BLE
+ * @psoc: Pointer to psoc
+ * @bs_request: Pointer to bearer switch request
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch else failure
+ */
+QDF_STATUS
+ll_lt_sap_switch_bearer_to_wlan(struct wlan_objmgr_psoc *psoc,
+				struct wlan_bearer_switch_request *bs_request);
+
 /**
  * ll_lt_sap_request_for_audio_transport_switch() - Handls audio transport
  * switch request from userspace
@@ -291,8 +301,8 @@ ll_lt_sap_request_for_audio_transport_switch(struct wlan_objmgr_vdev *vdev,
  *
  * Return: None
  */
-void ll_lt_sap_deliver_audio_transport_switch_resp(
-					struct wlan_objmgr_vdev *vdev,
+void
+ll_lt_sap_deliver_audio_transport_switch_resp(struct wlan_objmgr_vdev *vdev,
 					enum bearer_switch_req_type req_type,
 					enum bearer_switch_status status);
 

+ 51 - 2
components/umac/mlme/sap/ll_sap/dispatcher/inc/wlan_ll_sap_api.h

@@ -25,9 +25,9 @@
 #include <wlan_cmn.h>
 #include <wlan_objmgr_vdev_obj.h>
 #include "wlan_ll_sap_public_structs.h"
+#include "wlan_cm_public_struct.h"
 
 #ifdef WLAN_FEATURE_LL_LT_SAP
-
 /**
  * wlan_ll_lt_sap_bearer_switch_get_id() - Get the request id for bearer switch
  * request
@@ -46,6 +46,37 @@ wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_psoc *psoc);
 QDF_STATUS wlan_ll_lt_sap_switch_bearer_to_ble(
 				struct wlan_objmgr_psoc *psoc,
 				struct wlan_bearer_switch_request *bs_request);
+
+/**
+ * wlan_ll_sap_switch_bearer_on_sta_connect_start() - Switch bearer during
+ * station connection start
+ * @psoc: Pointer to psoc
+ * @scan_list: Pointer to the candidate list
+ * @vdev_id: Vdev id of the requesting vdev
+ * @cm_id: connection manager id of the current connect request
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch
+ *         QDF_STATUS_E_ALREADY, if bearer switch is not required
+ *         else failure
+ */
+QDF_STATUS wlan_ll_sap_switch_bearer_on_sta_connect_start(
+						struct wlan_objmgr_psoc *psoc,
+						qdf_list_t *scan_list,
+						uint8_t vdev_id,
+						wlan_cm_id cm_id);
+
+/**
+ * wlan_ll_sap_switch_bearer_on_sta_connect_complete() - Switch bearer during
+ * station connection complete
+ * @psoc: Pointer to psoc
+ * @vdev_id: Vdev id of the requesting vdev
+ * Return: QDF_STATUS_SUCCESS on successful bearer switch
+ *         QDF_STATUS_E_ALREADY, if bearer switch is not required
+ *         else failure
+ */
+QDF_STATUS wlan_ll_sap_switch_bearer_on_sta_connect_complete(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+
 #else
 
 static inline wlan_bs_req_id
@@ -54,11 +85,29 @@ wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_vdev *vdev)
 	return 0;
 }
 
-QDF_STATUS wlan_ll_lt_sap_switch_bearer_to_ble(
+static inline QDF_STATUS
+wlan_ll_lt_sap_switch_bearer_to_ble(
 				struct wlan_objmgr_psoc *psoc,
 				struct wlan_bearer_switch_request *bs_request)
 {
 	return QDF_STATUS_E_FAILURE;
 }
+
+static inline QDF_STATUS
+wlan_ll_sap_switch_bearer_on_sta_connect_start(struct wlan_objmgr_psoc *psoc,
+					       qdf_list_t *scan_list,
+					       uint8_t vdev_id,
+					       wlan_cm_id cm_id)
+
+{
+	return QDF_STATUS_E_ALREADY;
+}
+
+static inline QDF_STATUS
+wlan_ll_sap_switch_bearer_on_sta_connect_complete(struct wlan_objmgr_psoc *psoc,
+						  uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif /* WLAN_FEATURE_LL_LT_SAP */
 #endif /* _WLAN_LL_LT_SAP_API_H_ */

+ 122 - 0
components/umac/mlme/sap/ll_sap/dispatcher/src/wlan_ll_sap_api.c

@@ -17,6 +17,9 @@
 #include "wlan_ll_sap_api.h"
 #include <../../core/src/wlan_ll_lt_sap_bearer_switch.h>
 #include <../../core/src/wlan_ll_lt_sap_main.h>
+#include "wlan_cm_api.h"
+#include "wlan_policy_mgr_ll_sap.h"
+#include "wlan_policy_mgr_api.h"
 
 wlan_bs_req_id
 wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_psoc *psoc)
@@ -31,3 +34,122 @@ wlan_ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
 	return ll_lt_sap_switch_bearer_to_ble(psoc, bs_request);
 }
 
+static void
+connect_start_bearer_switch_requester_cb(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id,
+					 wlan_bs_req_id request_id,
+					 QDF_STATUS status, uint32_t req_value,
+					 void *request_params)
+{
+	wlan_cm_id cm_id = req_value;
+
+	wlan_cm_bearer_switch_resp(psoc, vdev_id, cm_id, status);
+}
+
+QDF_STATUS
+wlan_ll_sap_switch_bearer_on_sta_connect_start(struct wlan_objmgr_psoc *psoc,
+					       qdf_list_t *scan_list,
+					       uint8_t vdev_id,
+					       wlan_cm_id cm_id)
+{
+	struct scan_cache_node *scan_node = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	uint32_t ch_freq = 0;
+	struct scan_cache_entry *entry;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_bearer_switch_request bs_request = {0};
+	qdf_freq_t ll_lt_sap_freq;
+	bool is_bearer_switch_required = false;
+	QDF_STATUS status = QDF_STATUS_E_ALREADY;
+	uint8_t vdev_id;
+
+	vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev(psoc);
+	/* LL_LT SAP is not present, bearer switch is not required */
+	if (vdev_id == WLAN_INVALID_VDEV_ID)
+		return status;
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_LL_SAP_ID);
+	if (!vdev)
+		return status;
+
+	if (!scan_list || !qdf_list_size(scan_list))
+		goto rel_ref;
+
+	ll_lt_sap_freq = policy_mgr_get_lt_ll_sap_freq(psoc);
+	qdf_list_peek_front(scan_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(scan_list, cur_node, &next_node);
+
+		scan_node = qdf_container_of(cur_node, struct scan_cache_node,
+					     node);
+		entry = scan_node->entry;
+		ch_freq = entry->channel.chan_freq;
+
+		/*
+		 * Switch the bearer in case of SCC/MCC for LL_LT SAP
+		 */
+		if (policy_mgr_2_freq_always_on_same_mac(psoc, ch_freq,
+							 ll_lt_sap_freq)) {
+			ll_sap_debug("Scan list has BSS of freq %d on same mac with ll_lt sap %d",
+				     ch_freq, ll_lt_sap_freq);
+			is_bearer_switch_required = true;
+			break;
+		}
+
+		ch_freq = 0;
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	if (!is_bearer_switch_required)
+		goto rel_ref;
+
+	bs_request.vdev_id = vdev_id;
+	bs_request.request_id = ll_lt_sap_bearer_switch_get_id(psoc);
+	bs_request.req_type = WLAN_BS_REQ_TO_NON_WLAN;
+	bs_request.source = BEARER_SWITCH_REQ_CONNECT;
+	bs_request.requester_cb = connect_start_bearer_switch_requester_cb;
+	bs_request.arg_value = cm_id;
+
+	status = ll_lt_sap_switch_bearer_to_ble(psoc, &bs_request);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		status = QDF_STATUS_E_ALREADY;
+rel_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LL_SAP_ID);
+
+	return status;
+}
+
+static void connect_complete_bearer_switch_requester_cb(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id,
+						wlan_bs_req_id request_id,
+						QDF_STATUS status,
+						uint32_t req_value,
+						void *request_params)
+{
+	/* Drop this response as no action is required */
+}
+
+QDF_STATUS wlan_ll_sap_switch_bearer_on_sta_connect_complete(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id)
+{
+	struct wlan_bearer_switch_request bs_request = {0};
+	QDF_STATUS status;
+
+	bs_request.vdev_id = vdev_id;
+	bs_request.request_id = ll_lt_sap_bearer_switch_get_id(psoc);
+	bs_request.req_type = WLAN_BS_REQ_TO_WLAN;
+	bs_request.source = BEARER_SWITCH_REQ_CONNECT;
+	bs_request.requester_cb = connect_complete_bearer_switch_requester_cb;
+
+	status = ll_lt_sap_switch_bearer_to_wlan(psoc, &bs_request);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_ALREADY;
+
+	return QDF_STATUS_SUCCESS;
+}

+ 1 - 1
os_if/mlme/sap/ll_sap/src/os_if_ll_sap.c

@@ -88,7 +88,7 @@ osif_convert_audio_transport_switch_status_type_from_qca_type
 	case QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_COMPLETED:
 		return WLAN_BS_STATUS_COMPLETED;
 	default:
-		return WLAN_BS_REQ_INVALID;
+		return WLAN_BS_STATUS_INVALID;
 	}
 }