qcacmn: MLO setup, teardown sequence changes

MLO setup, teardown sequence changes

Change-Id: I76d14cd66c373b3b734a17e44f3655ffd17893c5
CRs-Fixed: 3059859
This commit is contained in:
Kiran Venkatappa 2021-10-25 15:41:05 +05:30 committed by Madan Koyyalamudi
parent 31281aab2b
commit 3e3ed9ca89
7 changed files with 488 additions and 4 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -2764,6 +2765,27 @@ uint16_t target_if_pdev_get_hw_link_id
*/
void target_pdev_set_hw_link_id
(struct wlan_objmgr_pdev *pdev, uint16_t hw_link_id);
/**
* target_if_mlo_setup_req - API to trigger MLO setup sequence
* @pdev: Array of pointers to pdev object that are part of ML group
* @num_pdevs: Number of pdevs in above array
* @grp_id: ML Group ID
*
* Return: QDF_STATUS codes
*/
QDF_STATUS target_if_mlo_setup_req(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs, uint8_t grp_id);
/**
* target_if_mlo_ready - API to send MLO ready
* @pdev: Array of pointers to pdev object that are part of ML group
* @num_pdevs: Number of pdevs in above array
*
* Return: QDF_STATUS codes
*/
QDF_STATUS target_if_mlo_ready(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs);
#endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/
#endif

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -99,6 +100,8 @@
#include <target_if_mgmt_txrx.h>
#endif /* WLAN_MGMT_RX_REO_SUPPORT */
#include "wmi_unified_api.h"
static struct target_if_ctx *g_target_if_ctx;
struct target_if_ctx *target_if_get_ctx()
@ -915,4 +918,68 @@ void target_pdev_set_hw_link_id(struct wlan_objmgr_pdev *pdev,
tgt_pdev_info->hw_link_id = hw_link_id;
}
static QDF_STATUS target_if_mlo_setup_send(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_pdev **pdev_list,
uint8_t num_links, uint8_t grp_id)
{
wmi_unified_t wmi_handle;
struct wmi_mlo_setup_params params = {0};
uint8_t idx, num_valid_links = 0;
wmi_handle = lmac_get_pdev_wmi_handle(pdev);
if (!wmi_handle)
return QDF_STATUS_E_INVAL;
params.mld_grp_id = grp_id;
params.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
for (idx = 0; idx < num_links; idx++) {
if (pdev == pdev_list[idx])
continue;
params.partner_links[num_valid_links] =
target_if_pdev_get_hw_link_id(pdev_list[idx]);
num_valid_links++;
}
params.num_valid_hw_links = num_valid_links;
return wmi_mlo_setup_cmd_send(wmi_handle, &params);
}
QDF_STATUS target_if_mlo_setup_req(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs, uint8_t grp_id)
{
uint8_t idx;
for (idx = 0; idx < num_pdevs; idx++)
target_if_mlo_setup_send(pdev[idx], pdev, num_pdevs, grp_id);
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS target_if_mlo_ready_send(struct wlan_objmgr_pdev *pdev)
{
wmi_unified_t wmi_handle;
struct wmi_mlo_ready_params params = {0};
wmi_handle = lmac_get_pdev_wmi_handle(pdev);
if (!wmi_handle)
return QDF_STATUS_E_INVAL;
params.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
return wmi_mlo_ready_cmd_send(wmi_handle, &params);
}
QDF_STATUS target_if_mlo_ready(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs)
{
uint8_t idx;
for (idx = 0; idx < num_pdevs; idx++)
target_if_mlo_ready_send(pdev[idx]);
return QDF_STATUS_SUCCESS;
}
#endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/

View File

@ -34,6 +34,10 @@
#include <init_cmd_api.h>
#include <cdp_txrx_cmn.h>
#include <wlan_reg_ucfg_api.h>
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
#include <wlan_mlo_mgr_cmn.h>
#include <wlan_mlo_mgr_setup.h>
#endif
static void init_deinit_set_send_init_cmd(struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl)
@ -531,6 +535,38 @@ static int init_deinit_service_available_handler(ol_scn_t scn_handle,
return 0;
}
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
static void init_deinit_mlo_update_soc_ready(struct wlan_objmgr_psoc *psoc)
{
mlo_setup_update_soc_ready(wlan_psoc_get_id(psoc));
}
static void init_deinit_send_ml_link_ready(struct wlan_objmgr_psoc *psoc,
void *object, void *arg)
{
struct wlan_objmgr_pdev *pdev = object;
qdf_assert_always(psoc);
qdf_assert_always(pdev);
mlo_setup_link_ready(pdev);
}
static void init_deinit_mlo_update_pdev_ready(struct wlan_objmgr_psoc *psoc,
uint8_t num_radios)
{
wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
init_deinit_send_ml_link_ready,
NULL, 0, WLAN_INIT_DEINIT_ID);
}
#else
static void init_deinit_mlo_update_soc_ready(struct wlan_objmgr_psoc *psoc)
{}
static void init_deinit_mlo_update_pdev_ready(struct wlan_objmgr_psoc *psoc,
uint8_t num_radios)
{}
#endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/
/* MAC address fourth byte index */
#define MAC_BYTE_4 4
@ -609,6 +645,8 @@ static int init_deinit_ready_event_handler(ol_scn_t scn_handle,
goto exit;
}
init_deinit_mlo_update_soc_ready(psoc);
num_radios = target_psoc_get_num_radios(tgt_hdl);
if ((ready_ev.num_total_peer != 0) &&
@ -726,6 +764,7 @@ static int init_deinit_ready_event_handler(ol_scn_t scn_handle,
wlan_psoc_set_hw_macaddr(psoc, myaddr);
}
init_deinit_mlo_update_pdev_ready(psoc, num_radios);
out:
target_if_btcoex_cfg_enable(psoc, tgt_hdl, event);
tgt_hdl->info.wmi_ready = TRUE;
@ -735,6 +774,108 @@ exit:
return 0;
}
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
static int init_deinit_mlo_setup_comp_event_handler(ol_scn_t scn_handle,
uint8_t *event,
uint32_t data_len)
{
struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_pdev *pdev;
struct target_psoc_info *tgt_hdl;
struct wmi_unified *wmi_handle;
struct wmi_mlo_setup_complete_params params;
if (!scn_handle) {
target_if_err("scn handle NULL");
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
if (!psoc) {
target_if_err("psoc is null");
return -EINVAL;
}
tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return -EINVAL;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
if (wmi_extract_mlo_setup_cmpl_event(wmi_handle, event, &params) !=
QDF_STATUS_SUCCESS)
return -EINVAL;
pdev = wlan_objmgr_get_pdev_by_id(psoc, params.pdev_id,
WLAN_INIT_DEINIT_ID);
if (pdev) {
mlo_link_setup_complete(pdev);
wlan_objmgr_pdev_release_ref(pdev, WLAN_INIT_DEINIT_ID);
}
return 0;
}
static int init_deinit_mlo_teardown_comp_event_handler(ol_scn_t scn_handle,
uint8_t *event,
uint32_t data_len)
{
struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_pdev *pdev;
struct target_psoc_info *tgt_hdl;
struct wmi_unified *wmi_handle;
struct wmi_mlo_teardown_cmpl_params params;
if (!scn_handle) {
target_if_err("scn handle NULL");
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
if (!psoc) {
target_if_err("psoc is null");
return -EINVAL;
}
tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return -EINVAL;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
if (wmi_extract_mlo_teardown_cmpl_event(wmi_handle, event, &params) !=
QDF_STATUS_SUCCESS)
return -EINVAL;
pdev = wlan_objmgr_get_pdev_by_id(psoc, params.pdev_id,
WLAN_INIT_DEINIT_ID);
if (pdev) {
mlo_link_teardown_complete(pdev);
wlan_objmgr_pdev_release_ref(pdev, WLAN_INIT_DEINIT_ID);
}
return 0;
}
static QDF_STATUS init_deinit_register_mlo_ev_handlers(wmi_unified_t wmi_handle)
{
wmi_unified_register_event(wmi_handle,
wmi_mlo_setup_complete_event_id,
init_deinit_mlo_setup_comp_event_handler);
wmi_unified_register_event(wmi_handle,
wmi_mlo_teardown_complete_event_id,
init_deinit_mlo_teardown_comp_event_handler);
return QDF_STATUS_SUCCESS;
}
#else
static QDF_STATUS init_deinit_register_mlo_ev_handlers(wmi_unified_t wmi_handle)
{
return QDF_STATUS_SUCCESS;
}
#endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/
QDF_STATUS init_deinit_register_tgt_psoc_ev_handlers(
struct wlan_objmgr_psoc *psoc)
@ -777,6 +918,7 @@ QDF_STATUS init_deinit_register_tgt_psoc_ev_handlers(
wmi_service_ready_ext2_event_id,
init_deinit_service_ext2_ready_event_handler,
WMI_RX_WORK_CTX);
retval = init_deinit_register_mlo_ev_handlers(wmi_handle);
return retval;

View File

@ -484,6 +484,11 @@ struct wlan_lmac_if_mlme_tx_ops {
enum wlan_vdev_mgr_tgt_if_rsp_bit clear_bit);
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
uint16_t (*get_hw_link_id)(struct wlan_objmgr_pdev *pdev);
QDF_STATUS (*target_if_mlo_setup_req)(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs,
uint8_t grp_id);
QDF_STATUS (*target_if_mlo_ready)(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs);
#endif
};

View File

@ -59,13 +59,47 @@ struct vdev_mlme_obj;
#define STA_PROFILE_SUB_ELEM_ID 0
#define PER_STA_PROF_MAC_ADDR_START 4
#ifdef WLAN_MLO_MULTI_CHIP
/*
* struct mlo_setup_info
* To store the MLO setup related information
* enum MLO_LINK_STATE MLO link state enums
* @MLO_LINK_SETUP_INIT - MLO link SETUP exchange not yet done
* @MLO_LINK_SETUP_DONE - MLO link SETUP exchange started
* @MLO_LINK_READY - MLO link SETUP done and READY sent
* @MLO_LINK_TEARDOWN - MLO teardown done.
*/
struct mlo_setup_info {
enum MLO_LINK_STATE {
MLO_LINK_SETUP_INIT,
MLO_LINK_SETUP_DONE,
MLO_LINK_READY,
MLO_LINK_TEARDOWN
};
/**
* struct mlo_setup_info: MLO setup status per link
* @ml_grp_id: Unique id for ML grouping of Pdevs/links
* @tot_socs: Total number of soc participating in ML group
* @num_soc: Number of soc ready or probed
* @tot_links: Total links in ML group
* @num_links: Number of links probed in ML group
* @pdev_list[MAX_MLO_LINKS]: pdev pointers belonging to this group
* @state[MAX_MLO_LINKS]: MLO link state
* @state_lock: lock to protect access to link state
*/
#define MAX_MLO_LINKS 6
struct mlo_setup_info {
uint8_t ml_grp_id;
uint8_t tot_socs;
uint8_t num_soc;
uint8_t tot_links;
uint8_t num_links;
struct wlan_objmgr_pdev *pdev_list[MAX_MLO_LINKS];
enum MLO_LINK_STATE state[MAX_MLO_LINKS];
qdf_spinlock_t state_lock;
};
#define MAX_MLO_GROUP 1
#endif
/*
* struct mlo_mgr_context - MLO manager context
* @ml_dev_list_lock: ML DEV list lock
@ -94,7 +128,9 @@ struct mlo_mgr_context {
qdf_list_t ml_dev_list;
qdf_bitmap(mlo_peer_id_bmap, MAX_MLO_PEER_ID);
uint16_t max_mlo_peer_id;
struct mlo_setup_info info;
#ifdef WLAN_MLO_MULTI_CHIP
struct mlo_setup_info setup_info;
#endif
struct mlo_mlme_ext_ops *mlme_ops;
struct ctxt_switch_mgr *msgq_ctx;
bool mlo_is_force_primary_umac;
@ -344,4 +380,5 @@ struct mlo_mlme_ext_ops {
uint8_t link_ix);
void (*mlo_mlme_ext_deauth)(struct wlan_objmgr_peer *peer);
};
#endif

View File

@ -0,0 +1,69 @@
/* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* DOC: contains MLO manager public file containing setup/teardown functionality
*/
#ifdef WLAN_MLO_MULTI_CHIP
/**
* mlo_setup_update_total_socs() - API to update total socs for mlo
* @tot_socs: Total socs
*
* Return: None.
*/
void mlo_setup_update_total_socs(uint8_t tot_socs);
/**
* mlo_setup_update_num_links() - API to update num links in soc for mlo
* @soc_id: soc id of SoC corresponding to num_link
* @num_links: Number of links in that soc
*
* Return: None.
*/
void mlo_setup_update_num_links(uint8_t soc_id, uint8_t num_links);
/**
* mlo_setup_update_soc_ready() - API to notify when FW init done
* @soc_id: soc id of SoC ready
*
* Return: None.
*/
void mlo_setup_update_soc_ready(uint8_t soc_id);
/**
* mlo_setup_link_ready() - API to notify link ready
* @pdev: Pointer to pdev object
*
* Return: None.
*/
void mlo_setup_link_ready(struct wlan_objmgr_pdev *pdev);
/**
* mlo_link_setup_complete() - API to notify setup complete
* @pdev: Pointer to pdev object
*
* Return: None.
*/
void mlo_link_setup_complete(struct wlan_objmgr_pdev *pdev);
/**
* mlo_link_teardown_complete() - API to notify teardown complete
* @pdev: Pointer to pdev object
*
* Return: None.
*/
void mlo_link_teardown_complete(struct wlan_objmgr_pdev *pdev);
#endif

View File

@ -0,0 +1,142 @@
/* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* DOC: contains MLO manager ap related functionality
*/
#include "wlan_mlo_mgr_cmn.h"
#include "wlan_mlo_mgr_main.h"
#ifdef WLAN_MLO_MULTI_CHIP
#include "wlan_lmac_if_def.h"
#endif
#ifdef WLAN_MLO_MULTI_CHIP
void mlo_setup_update_total_socs(uint8_t tot_socs)
{
struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
if (!mlo_ctx)
return;
mlo_ctx->setup_info.tot_socs = tot_socs;
}
qdf_export_symbol(mlo_setup_update_total_socs);
void mlo_setup_update_num_links(uint8_t soc_id, uint8_t num_links)
{
struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
if (!mlo_ctx)
return;
mlo_ctx->setup_info.tot_links += num_links;
}
qdf_export_symbol(mlo_setup_update_num_links);
void mlo_setup_update_soc_ready(uint8_t soc_id)
{
struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
if (!mlo_ctx)
return;
mlo_ctx->setup_info.num_soc++;
}
qdf_export_symbol(mlo_setup_update_soc_ready);
void mlo_setup_link_ready(struct wlan_objmgr_pdev *pdev)
{
struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
uint8_t link_idx;
if (!mlo_ctx)
return;
link_idx = mlo_ctx->setup_info.num_links;
/* TODO: Get reference to PDEV */
mlo_ctx->setup_info.pdev_list[link_idx] = pdev;
mlo_ctx->setup_info.state[link_idx] = MLO_LINK_SETUP_INIT;
mlo_ctx->setup_info.num_links++;
if (mlo_ctx->setup_info.num_links == mlo_ctx->setup_info.tot_links &&
mlo_ctx->setup_info.num_soc == mlo_ctx->setup_info.tot_socs) {
struct wlan_objmgr_psoc *psoc;
struct wlan_lmac_if_tx_ops *tx_ops;
psoc = wlan_pdev_get_psoc(pdev);
tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
/* Trigger MLO setup */
if (tx_ops && tx_ops->mops.target_if_mlo_setup_req) {
tx_ops->mops.target_if_mlo_setup_req(
mlo_ctx->setup_info.pdev_list,
mlo_ctx->setup_info.num_links,
mlo_ctx->setup_info.ml_grp_id);
}
}
}
qdf_export_symbol(mlo_setup_link_ready);
void mlo_link_setup_complete(struct wlan_objmgr_pdev *pdev)
{
struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
uint8_t link_idx;
if (!mlo_ctx)
return;
for (link_idx = 0; link_idx < mlo_ctx->setup_info.tot_links; link_idx++)
if (mlo_ctx->setup_info.pdev_list[link_idx] == pdev) {
mlo_ctx->setup_info.state[link_idx] =
MLO_LINK_SETUP_DONE;
break;
}
for (link_idx = 0; link_idx < mlo_ctx->setup_info.tot_links; link_idx++)
if (mlo_ctx->setup_info.state[link_idx] == MLO_LINK_SETUP_DONE)
continue;
else
break;
if (link_idx == mlo_ctx->setup_info.tot_links) {
struct wlan_objmgr_psoc *psoc;
struct wlan_lmac_if_tx_ops *tx_ops;
psoc = wlan_pdev_get_psoc(pdev);
tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
/* Trigger MLO ready */
if (tx_ops && tx_ops->mops.target_if_mlo_ready) {
tx_ops->mops.target_if_mlo_ready(
mlo_ctx->setup_info.pdev_list,
mlo_ctx->setup_info.num_links);
}
}
}
qdf_export_symbol(mlo_link_setup_complete);
void mlo_link_teardown_complete(struct wlan_objmgr_pdev *pdev)
{
struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
if (!mlo_ctx)
return;
}
qdf_export_symbol(mlo_link_teardown_complete);
#endif /*WLAN_MLO_MULTI_CHIP*/