qcacmn: MLO Teardown sequence

Trigger MLO teardown and wait for response before proceeding with soc
power down.

Change-Id: Ie1d00408862459b0e5240ef3151a0d969ab65e80
CRs-Fixed: 3102143
Цей коміт міститься в:
Kiran Venkatappa
2021-11-30 14:16:56 +05:30
зафіксовано Madan Koyyalamudi
джерело 8f62ddf128
коміт 9d402b668b
6 змінених файлів з 156 додано та 4 видалено

Переглянути файл

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 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
@@ -2789,6 +2789,17 @@ QDF_STATUS target_if_mlo_setup_req(struct wlan_objmgr_pdev **pdev,
*/
QDF_STATUS target_if_mlo_ready(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs);
/**
* target_if_mlo_teardown_req - API to trigger MLO teardown sequence
* @pdev: Array of pointers to pdev object that are part of ML group
* @num_pdevs: Number of pdevs in above array
* @reason: Reason for triggering teardown
*
* Return: QDF_STATUS codes
*/
QDF_STATUS target_if_mlo_teardown_req(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs, uint32_t reason);
#endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/
#endif

Переглянути файл

@@ -1016,4 +1016,33 @@ QDF_STATUS target_if_mlo_ready(struct wlan_objmgr_pdev **pdev,
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS
target_if_mlo_teardown_send(struct wlan_objmgr_pdev *pdev,
enum wmi_mlo_teardown_reason reason)
{
wmi_unified_t wmi_handle;
struct wmi_mlo_teardown_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);
params.reason = reason;
return wmi_mlo_teardown_cmd_send(wmi_handle, &params);
}
QDF_STATUS target_if_mlo_teardown_req(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs,
enum wmi_mlo_teardown_reason reason)
{
uint8_t idx;
for (idx = 0; idx < num_pdevs; idx++)
target_if_mlo_teardown_send(pdev[idx], reason);
return QDF_STATUS_SUCCESS;
}
#endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/

Переглянути файл

@@ -498,6 +498,9 @@ struct wlan_lmac_if_mlme_tx_ops {
uint8_t grp_id);
QDF_STATUS (*target_if_mlo_ready)(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs);
QDF_STATUS (*target_if_mlo_teardown_req)(struct wlan_objmgr_pdev **pdev,
uint8_t num_pdevs,
uint32_t grp_id);
#endif
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
QDF_STATUS (*vdev_send_set_mac_addr)(struct qdf_mac_addr mac_addr,

Переглянути файл

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 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
@@ -28,6 +28,9 @@
#include <wlan_cmn_ieee80211.h>
#include <wlan_cmn.h>
#include <wlan_objmgr_global_obj.h>
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
#include <qdf_event.h>
#endif
/* MAX MLO dev support */
#define WLAN_UMAC_MLO_MAX_VDEVS 2
@@ -85,6 +88,7 @@ enum MLO_LINK_STATE {
* @soc_list[MAX_MLO_CHIPS]: psoc pointers belonging to this group
* @state[MAX_MLO_LINKS]: MLO link state
* @state_lock: lock to protect access to link state
* @qdf_event_t: event for tearodwn completion
*/
#define MAX_MLO_LINKS 6
#define MAX_MLO_CHIPS 3
@@ -98,6 +102,7 @@ struct mlo_setup_info {
struct wlan_objmgr_psoc *soc_list[MAX_MLO_CHIPS];
enum MLO_LINK_STATE state[MAX_MLO_LINKS];
qdf_spinlock_t state_lock;
qdf_event_t event;
};
#define MAX_MLO_GROUP 1

Переглянути файл

@@ -1,4 +1,4 @@
/* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
/* Copyright (c) 2021-2022 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
@@ -67,4 +67,14 @@ void mlo_link_setup_complete(struct wlan_objmgr_pdev *pdev);
* Return: None.
*/
void mlo_link_teardown_complete(struct wlan_objmgr_pdev *pdev);
/**
* mlo_link_teardown_link() - API to trigger teardown
* @psoc: Pointer to psoc object
* @reason: Reason code for MLO tear down
*
* Return: QDF_STATUS - success / failure.
*/
QDF_STATUS mlo_link_teardown_link(struct wlan_objmgr_psoc *psoc,
uint32_t reason);
#endif

Переглянути файл

@@ -1,4 +1,4 @@
/* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
/* Copyright (c) 2021-2022 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
@@ -152,13 +152,107 @@ void mlo_link_setup_complete(struct wlan_objmgr_pdev *pdev)
qdf_export_symbol(mlo_link_setup_complete);
static QDF_STATUS mlo_find_pdev_idx(struct wlan_objmgr_pdev *pdev,
uint8_t *link_idx)
{
struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
uint8_t idx;
if (!mlo_ctx)
return QDF_STATUS_E_FAILURE;
if (!link_idx)
return QDF_STATUS_E_FAILURE;
for (idx = 0; idx < mlo_ctx->setup_info.tot_links; idx++) {
if (mlo_ctx->setup_info.pdev_list[idx] == pdev) {
*link_idx = idx;
return QDF_STATUS_SUCCESS;
}
}
return QDF_STATUS_E_FAILURE;
}
void mlo_link_teardown_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;
if (!mlo_ctx->setup_info.num_links) {
qdf_err("Delayed response ignore");
return;
}
if (mlo_find_pdev_idx(pdev, &link_idx) != QDF_STATUS_SUCCESS) {
qdf_info("Failed to find pdev");
return;
}
qdf_debug("link idx = %d", link_idx);
mlo_ctx->setup_info.pdev_list[link_idx] = NULL;
mlo_ctx->setup_info.state[link_idx] = MLO_LINK_TEARDOWN;
mlo_ctx->setup_info.num_links--;
if (!mlo_ctx->setup_info.num_links) {
qdf_info("Teardown complete");
qdf_event_set(&mlo_ctx->setup_info.event);
}
}
qdf_export_symbol(mlo_link_teardown_complete);
#define MLO_MGR_TEARDOWN_TIMEOUT 3000
QDF_STATUS mlo_link_teardown_link(struct wlan_objmgr_psoc *psoc,
uint32_t reason)
{
struct wlan_lmac_if_tx_ops *tx_ops;
QDF_STATUS status;
struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
qdf_debug(" %d %d ",
mlo_ctx->setup_info.num_soc,
mlo_ctx->setup_info.num_links);
if (!mlo_ctx)
return QDF_STATUS_E_FAILURE;
if (!mlo_ctx->setup_info.num_soc)
return QDF_STATUS_SUCCESS;
if (!mlo_ctx->setup_info.num_links) {
mlo_ctx->setup_info.num_soc--;
return QDF_STATUS_SUCCESS;
}
if (qdf_event_create(&mlo_ctx->setup_info.event) != QDF_STATUS_SUCCESS)
return QDF_STATUS_E_FAULT;
tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
/* Trigger MLO teardown */
if (tx_ops && tx_ops->mops.target_if_mlo_teardown_req) {
tx_ops->mops.target_if_mlo_teardown_req(
mlo_ctx->setup_info.pdev_list,
mlo_ctx->setup_info.num_links,
reason);
}
status = qdf_wait_for_event_completion(&mlo_ctx->setup_info.event,
MLO_MGR_TEARDOWN_TIMEOUT);
if (status != QDF_STATUS_SUCCESS) {
qdf_info("Teardown timeout");
mlo_ctx->setup_info.num_links = 0;
}
qdf_event_destroy(&mlo_ctx->setup_info.event);
mlo_ctx->setup_info.num_soc--;
return status;
}
qdf_export_symbol(mlo_link_teardown_link);
#endif /*WLAN_MLO_MULTI_CHIP*/