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
This commit is contained in:
Ashish Kumar Dhanotiya
2023-09-28 01:00:51 +05:30
committed by Rahul Choudhary
parent b74949ee0f
commit 0afa4fa7e5
6 changed files with 227 additions and 38 deletions

View File

@@ -39,6 +39,7 @@
#include "wlan_vdev_mgr_utils_api.h" #include "wlan_vdev_mgr_utils_api.h"
#include "wlan_tdls_api.h" #include "wlan_tdls_api.h"
#include "wlan_mlo_mgr_link_switch.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, QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev,
struct if_mgr_event_data *event_data) 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, policy_mgr_check_concurrent_intf_and_restart_sap(psoc,
wlan_util_vdev_mgr_get_acs_mode_for_vdev(vdev)); 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; return QDF_STATUS_SUCCESS;
} }

View File

@@ -202,7 +202,7 @@ ll_lt_sap_invoke_req_callback_f(struct bearer_switch_info *bs_ctx,
QDF_STATUS status, const char *func) QDF_STATUS status, const char *func)
{ {
if (!bs_req->requester_cb) { 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, func, wlan_vdev_get_id(bs_ctx->vdev), bs_req->vdev_id,
bs_req->source, bs_req->request_id, bs_req->source, bs_req->request_id,
bs_req->arg_value); bs_req->arg_value);
@@ -443,8 +443,8 @@ ll_lt_sap_send_bs_req_to_userspace(struct wlan_objmgr_vdev *vdev,
* *
* Return: None * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_wlan_in_non_wlan_state( static void
struct bearer_switch_info *bs_ctx, ll_lt_sap_handle_bs_to_wlan_in_non_wlan_state(struct bearer_switch_info *bs_ctx,
struct wlan_bearer_switch_request *bs_req) struct wlan_bearer_switch_request *bs_req)
{ {
QDF_STATUS status; QDF_STATUS status;
@@ -550,7 +550,7 @@ ll_lt_sap_handle_bs_to_wlan_in_non_wlan_requested_state(
return; return;
if (!bs_req->requester_cb) { 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), wlan_vdev_get_id(bs_ctx->vdev),
bs_req->vdev_id, bs_req->source, bs_req->vdev_id, bs_req->source,
bs_req->request_id, bs_req->arg_value); 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 * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_non_wlan_timeout( static void
struct bearer_switch_info *bs_ctx, 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 *bs_req)
{ {
struct wlan_bearer_switch_request *first_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 * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_non_wlan_completed( static void
struct bearer_switch_info *bs_ctx, 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 *bs_req)
{ {
struct wlan_bearer_switch_request *first_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 * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_non_wlan_failure( static void
struct bearer_switch_info *bs_ctx, 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 *bs_req)
{ {
struct wlan_bearer_switch_request *first_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 * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_wlan_in_wlan_state( static void
struct bearer_switch_info *bs_ctx, ll_lt_sap_handle_bs_to_wlan_in_wlan_state(struct bearer_switch_info *bs_ctx,
struct wlan_bearer_switch_request *bs_req) struct wlan_bearer_switch_request *bs_req)
{ {
ll_lt_sap_invoke_req_callback(bs_ctx, bs_req, QDF_STATUS_E_ALREADY); 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 * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_non_wlan_in_wlan_state( static void
struct bearer_switch_info *bs_ctx, ll_lt_sap_handle_bs_to_non_wlan_in_wlan_state(struct bearer_switch_info *bs_ctx,
struct wlan_bearer_switch_request *bs_req) struct wlan_bearer_switch_request *bs_req)
{ {
QDF_STATUS status; QDF_STATUS status;
@@ -915,8 +915,8 @@ ll_lt_sap_switch_to_non_wlan_from_wlan(struct bearer_switch_info *bs_ctx)
* *
* Return: None * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_wlan_timeout( static void
struct bearer_switch_info *bs_ctx, ll_lt_sap_handle_bs_to_wlan_timeout(struct bearer_switch_info *bs_ctx,
struct wlan_bearer_switch_request *bs_req) struct wlan_bearer_switch_request *bs_req)
{ {
bs_sm_transition_to(bs_ctx, BEARER_WLAN); bs_sm_transition_to(bs_ctx, BEARER_WLAN);
@@ -940,8 +940,8 @@ static void ll_lt_sap_handle_bs_to_wlan_timeout(
* *
* Return: None * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_wlan_completed( static void
struct bearer_switch_info *bs_ctx, ll_lt_sap_handle_bs_to_wlan_completed(struct bearer_switch_info *bs_ctx,
struct wlan_bearer_switch_request *bs_req) struct wlan_bearer_switch_request *bs_req)
{ {
ll_lt_sap_stop_bs_timer(bs_ctx); ll_lt_sap_stop_bs_timer(bs_ctx);
@@ -969,8 +969,8 @@ static void ll_lt_sap_handle_bs_to_wlan_completed(
* *
* Return: None * Return: None
*/ */
static void ll_lt_sap_handle_bs_to_wlan_failure( static void
struct bearer_switch_info *bs_ctx, ll_lt_sap_handle_bs_to_wlan_failure(struct bearer_switch_info *bs_ctx,
struct wlan_bearer_switch_request *bs_req) struct wlan_bearer_switch_request *bs_req)
{ {
ll_lt_sap_stop_bs_timer(bs_ctx); ll_lt_sap_stop_bs_timer(bs_ctx);
@@ -1484,16 +1484,24 @@ rel_ref:
return status; return status;
} }
QDF_STATUS ll_lt_sap_switch_bearer_to_ble( QDF_STATUS
struct wlan_objmgr_psoc *psoc, ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
struct wlan_bearer_switch_request *bs_request) struct wlan_bearer_switch_request *bs_request)
{ {
return bs_sm_deliver_event(psoc, WLAN_BS_SM_EV_SWITCH_TO_NON_WLAN, return bs_sm_deliver_event(psoc, WLAN_BS_SM_EV_SWITCH_TO_NON_WLAN,
sizeof(*bs_request), bs_request); sizeof(*bs_request), bs_request);
} }
QDF_STATUS ll_lt_sap_request_for_audio_transport_switch( QDF_STATUS
struct wlan_objmgr_vdev *vdev, 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) enum bearer_switch_req_type req_type)
{ {
struct ll_sap_vdev_priv_obj *ll_sap_obj; 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)); wlan_vdev_get_id(vdev));
return QDF_STATUS_E_FAILURE; 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; 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); bs_sm_state_update(bs_ctx, BEARER_NON_WLAN);
} }
void ll_lt_sap_deliver_audio_transport_switch_resp( void
struct wlan_objmgr_vdev *vdev, ll_lt_sap_deliver_audio_transport_switch_resp(struct wlan_objmgr_vdev *vdev,
enum bearer_switch_req_type req_type, enum bearer_switch_req_type req_type,
enum bearer_switch_status status) enum bearer_switch_status status)
{ {
if (req_type == WLAN_BS_REQ_TO_NON_WLAN) if (req_type == WLAN_BS_REQ_TO_NON_WLAN)
ll_lt_sap_deliver_non_wlan_audio_transport_switch_resp( ll_lt_sap_deliver_non_wlan_audio_transport_switch_resp(

View File

@@ -270,6 +270,16 @@ QDF_STATUS
ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc, ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
struct wlan_bearer_switch_request *bs_request); 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 * ll_lt_sap_request_for_audio_transport_switch() - Handls audio transport
* switch request from userspace * switch request from userspace
@@ -291,8 +301,8 @@ ll_lt_sap_request_for_audio_transport_switch(struct wlan_objmgr_vdev *vdev,
* *
* Return: None * Return: None
*/ */
void ll_lt_sap_deliver_audio_transport_switch_resp( void
struct wlan_objmgr_vdev *vdev, ll_lt_sap_deliver_audio_transport_switch_resp(struct wlan_objmgr_vdev *vdev,
enum bearer_switch_req_type req_type, enum bearer_switch_req_type req_type,
enum bearer_switch_status status); enum bearer_switch_status status);

View File

@@ -25,9 +25,9 @@
#include <wlan_cmn.h> #include <wlan_cmn.h>
#include <wlan_objmgr_vdev_obj.h> #include <wlan_objmgr_vdev_obj.h>
#include "wlan_ll_sap_public_structs.h" #include "wlan_ll_sap_public_structs.h"
#include "wlan_cm_public_struct.h"
#ifdef WLAN_FEATURE_LL_LT_SAP #ifdef WLAN_FEATURE_LL_LT_SAP
/** /**
* wlan_ll_lt_sap_bearer_switch_get_id() - Get the request id for bearer switch * wlan_ll_lt_sap_bearer_switch_get_id() - Get the request id for bearer switch
* request * 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( QDF_STATUS wlan_ll_lt_sap_switch_bearer_to_ble(
struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_psoc *psoc,
struct wlan_bearer_switch_request *bs_request); 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 #else
static inline wlan_bs_req_id 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; 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_objmgr_psoc *psoc,
struct wlan_bearer_switch_request *bs_request) struct wlan_bearer_switch_request *bs_request)
{ {
return QDF_STATUS_E_FAILURE; 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_FEATURE_LL_LT_SAP */
#endif /* _WLAN_LL_LT_SAP_API_H_ */ #endif /* _WLAN_LL_LT_SAP_API_H_ */

View File

@@ -17,6 +17,9 @@
#include "wlan_ll_sap_api.h" #include "wlan_ll_sap_api.h"
#include <../../core/src/wlan_ll_lt_sap_bearer_switch.h> #include <../../core/src/wlan_ll_lt_sap_bearer_switch.h>
#include <../../core/src/wlan_ll_lt_sap_main.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_bs_req_id
wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_psoc *psoc) 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); 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;
}

View File

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