qcacld-3.0: Add api's to handle MLO Roaming
- New api's added to handle mlo roaming scenarios. - Read and store link addr from wmi. Change-Id: I6a18802d27f72235dc69d2eedb05f3e563d1b0f4 CRs-Fixed: 2997105
This commit is contained in:

committed by
Madan Koyyalamudi

parent
5017adcd22
commit
24f04ca536
@@ -37,6 +37,7 @@
|
||||
#include "connection_mgr/core/src/wlan_cm_sm.h"
|
||||
#include "connection_mgr/core/src/wlan_cm_main_api.h"
|
||||
#include "wlan_roam_debug.h"
|
||||
#include "wlan_mlo_mgr_roam.h"
|
||||
|
||||
#define FW_ROAM_SYNC_TIMEOUT 7000
|
||||
|
||||
@@ -353,7 +354,7 @@ cm_roam_sync_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t len,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
return cm_fw_roam_sync_req(psoc, sync_ind->roamed_vdev_id,
|
||||
return mlo_fw_roam_sync_req(psoc, sync_ind->roamed_vdev_id,
|
||||
sync_ind, sizeof(sync_ind));
|
||||
}
|
||||
|
||||
|
@@ -1558,4 +1558,16 @@ wlan_cm_sta_mlme_vdev_roam_notify(struct vdev_mlme_obj *vdev_mlme,
|
||||
*/
|
||||
bool wlan_cm_same_band_sta_allowed(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* cm_cleanup_mlo_link() - Cleanup the MLO link
|
||||
*
|
||||
* @vdev: MLO link vdev
|
||||
*
|
||||
* This posts the event WLAN_CM_SM_EV_ROAM_LINK_DOWN to CM to cleanup the
|
||||
* resources allocated for MLO link e.g. vdev, pe_session, etc..
|
||||
* This gets called when MLO to non-MLO roaming happens
|
||||
*
|
||||
* Return: qdf_status
|
||||
*/
|
||||
QDF_STATUS cm_cleanup_mlo_link(struct wlan_objmgr_vdev *vdev);
|
||||
#endif /* WLAN_CM_ROAM_API_H__ */
|
||||
|
@@ -2358,12 +2358,14 @@ struct cm_hw_mode_trans_ind {
|
||||
* @link_id: link id of the link
|
||||
* @channel: wmi channel
|
||||
* @flags: link flags
|
||||
* @link_addr: link mac addr
|
||||
*/
|
||||
struct ml_setup_link_param {
|
||||
uint32_t vdev_id;
|
||||
uint32_t link_id;
|
||||
wmi_channel channel;
|
||||
uint32_t flags;
|
||||
struct qdf_mac_addr link_addr;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -3272,3 +3272,9 @@ rel_ref:
|
||||
return status;
|
||||
}
|
||||
#endif /* WLAN_FEATURE_FIPS */
|
||||
|
||||
QDF_STATUS
|
||||
cm_cleanup_mlo_link(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <wlan_mlo_mgr_cmn.h>
|
||||
#include <wlan_mlo_mgr_public_structs.h>
|
||||
#include <wlan_cm_roam_public_struct.h>
|
||||
#include <../../core/src/wlan_cm_roam_i.h>
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
/**
|
||||
@@ -76,6 +77,34 @@ mlo_get_sta_link_mac_addr(uint8_t vdev_id,
|
||||
struct roam_offload_synch_ind *sync_ind,
|
||||
struct qdf_mac_addr *link_mac_addr);
|
||||
|
||||
/**
|
||||
* mlo_roam_get_chan_freq - get channel frequency
|
||||
*
|
||||
* @vdev_id: vdev id
|
||||
* @sync_ind: roam sync ind pointer
|
||||
*
|
||||
* This api will be called to get the link channel frequency.
|
||||
*
|
||||
* Return: channel frequency
|
||||
*/
|
||||
uint32_t
|
||||
mlo_roam_get_chan_freq(uint8_t vdev_id,
|
||||
struct roam_offload_synch_ind *sync_ind);
|
||||
|
||||
/**
|
||||
* mlo_roam_get_link_id - get link id
|
||||
*
|
||||
* @vdev_id: vdev id
|
||||
* @sync_ind: roam sync ind pointer
|
||||
*
|
||||
* This api will be called to get the link id information.
|
||||
*
|
||||
* Return: link id
|
||||
*/
|
||||
uint32_t
|
||||
mlo_roam_get_link_id(uint8_t vdev_id,
|
||||
struct roam_offload_synch_ind *sync_ind);
|
||||
|
||||
/**
|
||||
* is_multi_link_roam - check if MLO roaming
|
||||
*
|
||||
@@ -101,7 +130,46 @@ is_multi_link_roam(struct roam_offload_synch_ind *sync_ind);
|
||||
QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
|
||||
struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
#else
|
||||
/**
|
||||
* mlo_roam_copy_partner_info - copy partner link info to connect response
|
||||
*
|
||||
* @sync_ind: roam sync ind pointer
|
||||
* @connect_rsp: connect resp structure pointer
|
||||
*
|
||||
* This api will be called to copy partner link info to connect response.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void mlo_roam_copy_partner_info(struct wlan_cm_connect_resp *connect_rsp,
|
||||
struct roam_offload_synch_ind *sync_ind);
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
|
||||
/**
|
||||
* mlo_cm_roam_sync_cb - Callback function from CM to MLO mgr
|
||||
*
|
||||
* @vdev: vdev pointer
|
||||
* @event: event ptr
|
||||
* @event_data_len: event data len
|
||||
*
|
||||
* This api will be called from connection manger to mlo
|
||||
* manager to start roam sync request on link vdev's.
|
||||
*
|
||||
* Return: qdf status
|
||||
*/
|
||||
void mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
|
||||
void *event, uint32_t event_data_len);
|
||||
#endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
|
||||
|
||||
#else /* WLAN_FEATURE_11BE_MLO */
|
||||
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
||||
static inline
|
||||
QDF_STATUS mlo_fw_roam_sync_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id, void *event,
|
||||
uint32_t event_data_len)
|
||||
{
|
||||
return cm_fw_roam_sync_req(psoc, vdev_id, event, event_data_len);
|
||||
}
|
||||
#endif
|
||||
static inline QDF_STATUS
|
||||
mlo_get_sta_link_mac_addr(uint8_t vdev_id,
|
||||
struct roam_offload_synch_ind *sync_ind,
|
||||
@@ -110,6 +178,25 @@ mlo_get_sta_link_mac_addr(uint8_t vdev_id,
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
mlo_roam_get_chan_freq(uint8_t vdev_id,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
mlo_roam_get_link_id(uint8_t vdev_id,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
|
||||
void *event, uint32_t event_data_len)
|
||||
{}
|
||||
|
||||
static inline bool
|
||||
is_multi_link_roam(struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
@@ -122,5 +209,10 @@ QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlo_roam_copy_partner_info(struct wlan_cm_connect_resp *connect_rsp,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{}
|
||||
#endif /* WLAN_FEATURE_11BE_MLO */
|
||||
#endif
|
||||
|
@@ -28,22 +28,225 @@
|
||||
#include <../../core/src/wlan_cm_roam_i.h>
|
||||
#include "wlan_cm_roam_api.h"
|
||||
|
||||
static bool
|
||||
mlo_check_connect_req_bmap(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
|
||||
struct wlan_mlo_sta *sta_ctx;
|
||||
uint8_t i = 0;
|
||||
|
||||
if (!mlo_dev_ctx)
|
||||
return false;
|
||||
|
||||
sta_ctx = mlo_dev_ctx->sta_ctx;
|
||||
|
||||
for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
||||
if (!mlo_dev_ctx->wlan_vdev_list[i])
|
||||
continue;
|
||||
|
||||
if (vdev == mlo_dev_ctx->wlan_vdev_list[i])
|
||||
return qdf_test_bit(i, sta_ctx->wlan_connect_req_links);
|
||||
}
|
||||
|
||||
mlo_err("vdev not found in ml dev ctx list");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
mlo_update_for_multi_link_roam(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t ml_link_vdev_id)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
|
||||
ml_link_vdev_id,
|
||||
WLAN_MLME_SB_ID);
|
||||
if (!vdev) {
|
||||
mlo_err("VDEV is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (vdev_id == ml_link_vdev_id) {
|
||||
wlan_vdev_mlme_feat_ext2_cap_set(vdev,
|
||||
WLAN_VDEV_FEXT2_MLO);
|
||||
goto end;
|
||||
}
|
||||
|
||||
wlan_vdev_mlme_feat_ext2_cap_set(vdev,
|
||||
WLAN_VDEV_FEXT2_MLO);
|
||||
wlan_vdev_mlme_feat_ext2_cap_set(vdev,
|
||||
WLAN_VDEV_FEXT2_MLO_STA_LINK);
|
||||
|
||||
mlo_update_connect_req_links(vdev, true);
|
||||
|
||||
end:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
|
||||
}
|
||||
|
||||
static void
|
||||
mlo_cleanup_link(struct wlan_objmgr_vdev *tmp_vdev,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
wlan_vdev_mlme_feat_ext2_cap_clear(vdev,
|
||||
WLAN_VDEV_FEXT2_MLO);
|
||||
|
||||
if (wlan_vdev_mlme_is_mlo_link_vdev(tmp_vdev)) {
|
||||
//cm_cleanup_mlo_link(tmp_vdev);
|
||||
wlan_vdev_mlme_feat_ext2_cap_clear(tmp_vdev,
|
||||
WLAN_VDEV_FEXT2_MLO_STA_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mlo_update_for_legacy_roam(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
struct wlan_mlo_dev_context *mlo_dev_ctx;
|
||||
uint8_t i;
|
||||
struct wlan_objmgr_vdev *vdev, *tmp_vdev;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
|
||||
vdev_id,
|
||||
WLAN_MLME_SB_ID);
|
||||
if (!vdev) {
|
||||
mlo_err("VDEV is null");
|
||||
return;
|
||||
}
|
||||
|
||||
mlo_dev_ctx = vdev->mlo_dev_ctx;
|
||||
for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
||||
if (!mlo_dev_ctx->wlan_vdev_list[i])
|
||||
continue;
|
||||
|
||||
tmp_vdev = mlo_dev_ctx->wlan_vdev_list[i];
|
||||
mlo_cleanup_link(tmp_vdev, vdev);
|
||||
}
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
|
||||
}
|
||||
|
||||
static void
|
||||
mlo_clear_link_bmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
|
||||
vdev_id,
|
||||
WLAN_MLME_SB_ID);
|
||||
if (!vdev) {
|
||||
mlo_err("VDEV is null");
|
||||
return;
|
||||
}
|
||||
|
||||
mlo_clear_connect_req_links_bmap(vdev);
|
||||
wlan_vdev_mlme_feat_ext2_cap_clear(vdev,
|
||||
WLAN_VDEV_FEXT2_MLO);
|
||||
if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
|
||||
wlan_vdev_mlme_feat_ext2_cap_clear(vdev,
|
||||
WLAN_VDEV_FEXT2_MLO_STA_LINK);
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
|
||||
}
|
||||
|
||||
QDF_STATUS mlo_fw_roam_sync_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
||||
void *event, uint32_t event_data_len)
|
||||
{
|
||||
struct roam_offload_synch_ind *sync_ind;
|
||||
QDF_STATUS status;
|
||||
uint8_t i;
|
||||
|
||||
sync_ind = (struct roam_offload_synch_ind *)event;
|
||||
if (!sync_ind)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
for (i = 0; i < sync_ind->num_setup_links; i++)
|
||||
mlo_update_for_multi_link_roam(psoc, vdev_id,
|
||||
sync_ind->ml_link[i].vdev_id);
|
||||
|
||||
if (!sync_ind->num_setup_links)
|
||||
mlo_debug("MLO_ROAM: Roamed to Legacy");
|
||||
else
|
||||
mlo_debug("MLO_ROAM: Roamed to MLO");
|
||||
|
||||
status = cm_fw_roam_sync_req(psoc, vdev_id, event, event_data_len);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
mlo_clear_link_bmap(psoc, vdev_id);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
|
||||
void mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
|
||||
void *event, uint32_t event_data_len)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct roam_offload_synch_ind *sync_ind;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wlan_objmgr_vdev *link_vdev;
|
||||
uint8_t i;
|
||||
uint8_t vdev_id;
|
||||
|
||||
sync_ind = (struct roam_offload_synch_ind *)event;
|
||||
vdev_id = wlan_vdev_get_id(vdev);
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
|
||||
if (!sync_ind->num_setup_links)
|
||||
mlo_update_for_legacy_roam(psoc, vdev_id);
|
||||
|
||||
for (i = 0; i < sync_ind->num_setup_links; i++) {
|
||||
if (vdev_id == sync_ind->ml_link[i].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 (mlo_check_connect_req_bmap(link_vdev)) {
|
||||
mlo_update_connect_req_links(link_vdev, false);
|
||||
|
||||
status = cm_fw_roam_sync_req(psoc,
|
||||
sync_ind->ml_link[i].vdev_id,
|
||||
event, event_data_len);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
mlo_clear_connect_req_links_bmap(link_vdev);
|
||||
wlan_objmgr_vdev_release_ref(link_vdev,
|
||||
WLAN_MLME_SB_ID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
wlan_objmgr_vdev_release_ref(link_vdev,
|
||||
WLAN_MLME_SB_ID);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
mlo_fw_ho_fail_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id, struct qdf_mac_addr bssid)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct wlan_mlo_dev_context *mlo_dev_ctx;
|
||||
uint8_t i;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
|
||||
vdev_id,
|
||||
WLAN_MLME_SB_ID);
|
||||
mlo_dev_ctx = vdev->mlo_dev_ctx;
|
||||
|
||||
for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
||||
if (!mlo_dev_ctx->wlan_vdev_list[i] ||
|
||||
mlo_dev_ctx->wlan_vdev_list[i] == vdev)
|
||||
continue;
|
||||
cm_fw_ho_fail_req(psoc,
|
||||
wlan_vdev_get_id(mlo_dev_ctx->wlan_vdev_list[i]),
|
||||
bssid);
|
||||
}
|
||||
|
||||
cm_fw_ho_fail_req(psoc, vdev_id, bssid);
|
||||
wlan_objmgr_vdev_release_ref(vdev,
|
||||
WLAN_MLME_SB_ID);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
@@ -52,13 +255,61 @@ mlo_get_sta_link_mac_addr(uint8_t vdev_id,
|
||||
struct qdf_mac_addr *link_mac_addr)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
uint8_t i;
|
||||
|
||||
if (!sync_ind || !sync_ind->num_setup_links)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
for (i = 0; i < sync_ind->num_setup_links; i++) {
|
||||
if (sync_ind->ml_link[i].vdev_id == vdev_id) {
|
||||
qdf_copy_macaddr(link_mac_addr,
|
||||
&sync_ind->ml_link[i].link_addr);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == sync_ind->num_setup_links) {
|
||||
mlo_err("Link mac addr not found");
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
mlo_roam_get_chan_freq(uint8_t vdev_id,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (!sync_ind || !sync_ind->num_setup_links)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < sync_ind->num_setup_links; i++) {
|
||||
if (sync_ind->ml_link[i].vdev_id == vdev_id)
|
||||
return sync_ind->ml_link[i].channel.mhz;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
mlo_roam_get_link_id(uint8_t vdev_id,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (!sync_ind || !sync_ind->num_setup_links)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < sync_ind->num_setup_links; i++) {
|
||||
if (sync_ind->ml_link[i].vdev_id == vdev_id)
|
||||
return sync_ind->ml_link[i].link_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_multi_link_roam(struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
if (!sync_ind)
|
||||
@@ -89,3 +340,24 @@ QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
mlo_roam_copy_partner_info(struct wlan_cm_connect_resp *connect_rsp,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
uint8_t i;
|
||||
struct mlo_partner_info *partner_info;
|
||||
|
||||
if (!sync_ind)
|
||||
return;
|
||||
|
||||
partner_info = &connect_rsp->ml_parnter_info;
|
||||
|
||||
for (i = 0; i < sync_ind->num_setup_links; i++) {
|
||||
partner_info->partner_link_info[i].link_id =
|
||||
sync_ind->ml_link[i].link_id;
|
||||
qdf_copy_macaddr(
|
||||
&partner_info->partner_link_info[i].link_addr,
|
||||
&sync_ind->ml_link[i].link_addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user