qcacmn: Code change in IPA component for 2x_pdev

2x_pdev changes are included mainly related to IPA
init for second pdev/radio and pipe enablement for
second pdev/radio, code changes can support n number
of radio for IPA, add support for new IPA API's.

Change-Id: Iac67e05e0f0098bdc24626fdbe59b89d768154cd
This commit is contained in:
Devender Kumar 2022-01-12 15:18:41 +05:30 committed by Madan Koyyalamudi
parent e0934446af
commit 3d525ae1ce
9 changed files with 243 additions and 75 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-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
@ -770,7 +770,8 @@ static inline void wlan_ipa_mcc_work_handler(void *data)
QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
uint8_t session_id,
enum wlan_ipa_wlan_event ipa_event_type,
uint8_t *mac_addr, bool is_2g_iface);
uint8_t *mac_addr, bool is_2g_iface,
struct wlan_ipa_priv *ipa_obj);
/**
* wlan_ipa_uc_smmu_map() - Map / Unmap DMA buffer to IPA UC

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018-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
@ -31,6 +31,9 @@
#include <wlan_ipa_public_struct.h>
#include <wlan_ipa_priv.h>
/* Declare a variable for IPA instancess added based on pdev */
extern uint8_t g_instances_added;
#define IPA_INVALID_HDL 0xFF
#define ipa_fatal(params...) \
QDF_TRACE_FATAL(QDF_MODULE_ID_IPA, params)
#define ipa_err(params...) \

View File

@ -516,11 +516,13 @@ struct uc_rm_work_struct {
* @work: uC OP work
* @msg: OP message
* @osdev: poiner to qdf net device, used by osif_psoc_sync_trans_start_wait
* @ipa_priv_bp: back pointer to ipa_obj
*/
struct uc_op_work_struct {
qdf_work_t work;
struct op_msg_type *msg;
qdf_device_t osdev;
struct wlan_ipa_priv *ipa_priv_bp;
};
/**
@ -734,6 +736,9 @@ struct wlan_ipa_priv {
qdf_atomic_t stats_quota;
uint8_t curr_bw_level;
qdf_atomic_t deinit_in_prog;
uint8_t instance_id;
bool handle_initialized;
qdf_ipa_wdi_hdl_t hdl;
};
#define WLAN_IPA_WLAN_FRAG_HEADER sizeof(struct frag_header)

View File

@ -37,6 +37,8 @@
#include <qal_vbus_dev.h>
#define IPA_SPS_DESC_SIZE 8
#define IPA_DEFAULT_HDL 0
static struct wlan_ipa_priv *gp_ipa;
static void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
static void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
@ -542,7 +544,7 @@ wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx,
&ipa_ctx->tx_pipe_handle,
&ipa_ctx->rx_pipe_handle,
wlan_ipa_wdi_is_smmu_enabled(ipa_ctx, osdev),
sys_in, ipa_ctx->over_gsi);
sys_in, ipa_ctx->over_gsi, ipa_ctx->hdl);
qdf_mem_free(sys_in);
@ -590,6 +592,7 @@ static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
QDF_IPA_WDI_INIT_IN_PARAMS_WDI_VERSION(&in) = ipa_ctx->wdi_version;
QDF_IPA_WDI_INIT_IN_PARAMS_NOTIFY(&in) = wlan_ipa_uc_loaded_uc_cb;
QDF_IPA_WDI_INIT_IN_PARAMS_PRIV(&in) = ipa_ctx;
QDF_IPA_WDI_INIT_IN_PARAMS_INSTANCE_ID(&in) = ipa_ctx->instance_id;
wlan_ipa_wdi_init_metering(ipa_ctx, &in);
ret = qdf_ipa_wdi_init(&in, &out);
@ -602,8 +605,10 @@ static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
QDF_IPA_WDI_INIT_OUT_PARAMS_IS_OVER_GSI(&out);
ipa_ctx->is_smmu_enabled =
QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out);
ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d",
ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled);
ipa_ctx->hdl = QDF_IPA_WDI_INIT_OUT_PARAMS_HANDLE(&out);
ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d, handle: %d",
ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled, ipa_ctx->hdl);
if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) {
ipa_debug("IPA uC READY");
@ -616,11 +621,11 @@ static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
return QDF_STATUS_SUCCESS;
}
static inline int wlan_ipa_wdi_cleanup(void)
static inline int wlan_ipa_wdi_cleanup(qdf_ipa_wdi_hdl_t hdl)
{
int ret;
ret = qdf_ipa_wdi_cleanup();
ret = qdf_ipa_wdi_cleanup(hdl);
if (ret)
ipa_info("ipa_wdi_cleanup failed ret=%d", ret);
return ret;
@ -697,11 +702,18 @@ int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
ipa_info("No buffers to map/unmap");
return 0;
}
/**
* This API will compile for prelithium chipset
* where we have only one soc so passing default
* handle to IPA which is 0.
*/
if (map)
return qdf_ipa_wdi_create_smmu_mapping(num_buf, buf_arr);
return qdf_ipa_wdi_create_smmu_mapping(IPA_DEFAULT_HDL,
num_buf, buf_arr);
else
return qdf_ipa_wdi_release_smmu_mapping(num_buf, buf_arr);
return qdf_ipa_wdi_release_smmu_mapping(IPA_DEFAULT_HDL,
num_buf, buf_arr);
return 0;
}
#ifdef MDM_PLATFORM
@ -945,9 +957,12 @@ int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
}
if (map)
return qdf_ipa_wdi_create_smmu_mapping(num_buf, buf_arr);
return qdf_ipa_wdi_create_smmu_mapping(IPA_DEFAULT_HDL,
num_buf, buf_arr);
else
return qdf_ipa_wdi_release_smmu_mapping(num_buf, buf_arr);
return qdf_ipa_wdi_release_smmu_mapping(IPA_DEFAULT_HDL,
num_buf, buf_arr);
return 0;
}
static enum wlan_ipa_forward_type
@ -976,10 +991,14 @@ wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx,
static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb,
struct wlan_objmgr_pdev *pdev)
{
struct wlan_ipa_priv *ipa_ctx = gp_ipa;
struct wlan_ipa_priv *ipa_ctx;
struct ethhdr *eh;
struct wlan_objmgr_vdev *vdev = NULL;
ipa_ctx = ipa_pdev_get_priv_obj(pdev);
if (!ipa_ctx)
return -EINVAL;
eh = (struct ethhdr *)qdf_nbuf_data(skb);
vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(
pdev, eh->h_dest, WLAN_IPA_ID);
@ -1019,7 +1038,9 @@ static void
wlan_ipa_send_skb_to_network(qdf_nbuf_t skb,
struct wlan_ipa_iface_context *iface_ctx)
{
struct wlan_ipa_priv *ipa_ctx = gp_ipa;
struct wlan_ipa_priv *ipa_ctx;
ipa_ctx = iface_ctx->ipa_ctx;
if (!iface_ctx->dev) {
ipa_debug_rl("Invalid interface");
@ -1513,7 +1534,8 @@ QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx)
if (qdf_atomic_read(&ipa_ctx->pipes_disabled)) {
result = cdp_ipa_enable_pipes(ipa_ctx->dp_soc,
ipa_ctx->dp_pdev_id);
ipa_ctx->dp_pdev_id,
ipa_ctx->hdl);
if (result) {
ipa_err("Enable IPA WDI PIPE failed: ret=%d", result);
qdf_status = QDF_STATUS_E_FAILURE;
@ -1573,7 +1595,8 @@ wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx, bool force_disable)
wlan_ipa_set_pending_tx_timer(ipa_ctx);
} else {
qdf_status = cdp_ipa_disable_pipes(ipa_ctx->dp_soc,
ipa_ctx->dp_pdev_id);
ipa_ctx->dp_pdev_id,
ipa_ctx->hdl);
if (QDF_IS_STATUS_ERROR(qdf_status)) {
ipa_err("Disable IPA WDI PIPE failed: ret=%u",
qdf_status);
@ -1715,7 +1738,8 @@ static void wlan_ipa_cleanup_iface(struct wlan_ipa_iface_context *iface_context,
if (cdp_ipa_cleanup_iface(ipa_ctx->dp_soc,
iface_context->dev->name,
wlan_ipa_is_ipv6_enabled(ipa_ctx->config))) {
wlan_ipa_is_ipv6_enabled(ipa_ctx->config),
ipa_ctx->hdl)) {
ipa_err("ipa_cleanup_iface failed");
}
@ -1944,7 +1968,8 @@ static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx,
iface_context->cons_client,
wlan_ipa_set_session_id(session_id,
is_2g_iface),
wlan_ipa_is_ipv6_enabled(ipa_ctx->config));
wlan_ipa_is_ipv6_enabled(ipa_ctx->config),
ipa_ctx->hdl);
if (status != QDF_STATUS_SUCCESS)
goto end;
@ -2450,9 +2475,10 @@ wlan_ipa_save_bssid_iface_ctx(struct wlan_ipa_priv *ipa_ctx, uint8_t iface_id,
static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
uint8_t session_id,
qdf_ipa_wlan_event type,
uint8_t *mac_addr, bool is_2g_iface)
uint8_t *mac_addr, bool is_2g_iface,
struct wlan_ipa_priv *ipa_obj)
{
struct wlan_ipa_priv *ipa_ctx = gp_ipa;
struct wlan_ipa_priv *ipa_ctx;
struct wlan_ipa_iface_context *iface_ctx = NULL;
qdf_ipa_msg_meta_t meta;
qdf_ipa_wlan_msg_t *msg;
@ -2470,6 +2496,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
if (type >= QDF_IPA_WLAN_EVENT_MAX)
return QDF_STATUS_E_INVAL;
ipa_ctx = ipa_obj;
if (wlan_ipa_uc_is_enabled(ipa_ctx->config) &&
!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
(device_mode != QDF_SAP_MODE)) {
@ -3174,7 +3201,8 @@ static uint8_t wlan_ipa_device_mode_switch(uint8_t device_mode)
QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
uint8_t session_id,
enum wlan_ipa_wlan_event ipa_event_type,
uint8_t *mac_addr, bool is_2g_iface)
uint8_t *mac_addr, bool is_2g_iface,
struct wlan_ipa_priv *ipa_obj)
{
qdf_ipa_wlan_event type = wlan_host_to_ipa_wlan_event(ipa_event_type);
QDF_STATUS status = QDF_STATUS_SUCCESS;
@ -3186,7 +3214,7 @@ QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
(device_mode == QDF_SAP_MODE))
status = __wlan_ipa_wlan_evt(net_dev, device_mode,
session_id, type, mac_addr,
is_2g_iface);
is_2g_iface, ipa_obj);
return status;
}
@ -3226,7 +3254,7 @@ wlan_ipa_uc_proc_pending_event(struct wlan_ipa_priv *ipa_ctx, bool is_loading)
pending_event->session_id,
pending_event->type,
pending_event->mac_addr,
pending_event->is_2g_iface);
pending_event->is_2g_iface, ipa_ctx);
}
if (vdev)
@ -3427,7 +3455,8 @@ static inline uint8_t wlan_ipa_get_rx_ipa_client(struct wlan_ipa_priv *ipa_ctx)
*
* Return: QDF_STATUS
*/
static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(bool ctrl)
static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(struct wlan_ipa_priv *ipa_ctx,
bool ctrl)
{
return QDF_STATUS_SUCCESS;
}
@ -3438,9 +3467,10 @@ static inline uint8_t wlan_ipa_get_rx_ipa_client(struct wlan_ipa_priv *ipa_ctx)
return IPA_CLIENT_WLAN1_PROD;
}
static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(bool ctrl)
static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(struct wlan_ipa_priv *ipa_ctx,
bool ctrl)
{
struct wlan_ipa_priv *ipa_ctx = gp_ipa;
struct wlan_ipa_priv *ipa_obj = ipa_ctx;
qdf_ipa_msg_meta_t meta;
qdf_ipa_wlan_msg_t *ipa_msg;
int ret = 0;
@ -3453,10 +3483,10 @@ static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(bool ctrl)
if (ctrl) {
QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_ENABLE);
ipa_ctx->stats.event[QDF_WDI_ENABLE]++;
ipa_obj->stats.event[QDF_WDI_ENABLE]++;
} else {
QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_DISABLE);
ipa_ctx->stats.event[QDF_WDI_DISABLE]++;
ipa_obj->stats.event[QDF_WDI_DISABLE]++;
}
ipa_debug("ipa_send_msg(Evt:%d)", QDF_IPA_MSG_META_MSG_TYPE(&meta));
@ -3729,7 +3759,7 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx,
ipa_ctx);
}
} else if (status == QDF_STATUS_E_BUSY) {
ret = wlan_ipa_uc_send_wdi_control_msg(false);
ret = wlan_ipa_uc_send_wdi_control_msg(ipa_ctx, false);
if (ret) {
ipa_err("IPA WDI msg send failed: ret=%d", ret);
goto ipa_wdi_destroy;
@ -3835,7 +3865,7 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx)
}
if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
wlan_ipa_wdi_cleanup();
wlan_ipa_wdi_cleanup(ipa_ctx->hdl);
qdf_mutex_destroy(&ipa_ctx->event_lock);
qdf_mutex_destroy(&ipa_ctx->ipa_lock);
qdf_list_destroy(&ipa_ctx->pending_event);
@ -3844,6 +3874,15 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx)
gp_ipa = NULL;
/* Acquire lock */
ipa_init_deinit_lock();
if (g_instances_added)
g_instances_added--;
/* Unlock */
ipa_init_deinit_unlock();
ipa_ctx->handle_initialized = false;
return QDF_STATUS_SUCCESS;
}
@ -3969,7 +4008,7 @@ static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx)
return;
smmu_map_fail:
qdf_ipa_wdi_disconn_pipes();
qdf_ipa_wdi_disconn_pipes(ipa_ctx->hdl);
connect_pipe_fail:
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
@ -4014,7 +4053,7 @@ static void wlan_ipa_uc_op_cb(struct op_msg_type *op_msg,
qdf_event_set(&ipa_ctx->ipa_resource_comp);
if (ipa_ctx->wdi_enabled == false) {
ipa_ctx->wdi_enabled = true;
if (wlan_ipa_uc_send_wdi_control_msg(true) == 0)
if (wlan_ipa_uc_send_wdi_control_msg(ipa_ctx, true) == 0)
wlan_ipa_send_mcc_scc_msg(ipa_ctx,
ipa_ctx->mcc_mode);
}
@ -4103,7 +4142,7 @@ static void __wlan_ipa_uc_fw_op_event_handler(void *data)
struct op_msg_type *msg;
struct uc_op_work_struct *uc_op_work =
(struct uc_op_work_struct *)data;
struct wlan_ipa_priv *ipa_ctx = gp_ipa;
struct wlan_ipa_priv *ipa_ctx = uc_op_work->ipa_priv_bp;
msg = uc_op_work->msg;
uc_op_work->msg = NULL;
@ -4198,6 +4237,7 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx,
for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) {
ipa_ctx->uc_op_work[i].osdev = osdev;
ipa_ctx->uc_op_work[i].msg = NULL;
ipa_ctx->uc_op_work[i].ipa_priv_bp = ipa_ctx;
qdf_create_work(0, &ipa_ctx->uc_op_work[i].work,
wlan_ipa_uc_fw_op_event_handler,
&ipa_ctx->uc_op_work[i]);
@ -4288,7 +4328,7 @@ QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx)
status = cdp_ipa_cleanup(ipa_ctx->dp_soc,
ipa_ctx->dp_pdev_id,
ipa_ctx->tx_pipe_handle,
ipa_ctx->rx_pipe_handle);
ipa_ctx->rx_pipe_handle, ipa_ctx->hdl);
if (status)
ipa_err("Failure to cleanup IPA pipes (status=%d)",
status);
@ -4314,12 +4354,18 @@ QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx)
*/
static QDF_STATUS wlan_ipa_uc_send_evt(qdf_netdev_t net_dev,
qdf_ipa_wlan_event type,
uint8_t *mac_addr)
uint8_t *mac_addr,
struct wlan_ipa_priv *ipa_priv)
{
struct wlan_ipa_priv *ipa_ctx = gp_ipa;
struct wlan_ipa_priv *ipa_ctx;
qdf_ipa_msg_meta_t meta;
qdf_ipa_wlan_msg_t *msg;
if (!ipa_priv)
return QDF_STATUS_E_INVAL;
ipa_ctx = ipa_priv;
QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t);
msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
if (!msg)
@ -4357,7 +4403,7 @@ void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx,
if (iface_ctx && iface_ctx->device_mode == QDF_STA_MODE &&
iface_ctx->dev && iface_ctx->dev == net_dev) {
wlan_ipa_uc_send_evt(net_dev, QDF_IPA_STA_DISCONNECT,
net_dev->dev_addr);
net_dev->dev_addr, ipa_ctx);
wlan_ipa_cleanup_iface(iface_ctx, NULL);
}
}
@ -4376,7 +4422,7 @@ QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx,
iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_SAP_MODE);
if (iface_ctx)
status = wlan_ipa_uc_send_evt(net_dev, QDF_IPA_AP_DISCONNECT,
net_dev->dev_addr);
net_dev->dev_addr, ipa_ctx);
else
return QDF_STATUS_E_INVAL;
@ -4413,11 +4459,13 @@ void wlan_ipa_uc_ssr_cleanup(struct wlan_ipa_priv *ipa_ctx)
if (iface->device_mode == QDF_SAP_MODE)
wlan_ipa_uc_send_evt(iface->dev,
QDF_IPA_AP_DISCONNECT,
iface->dev->dev_addr);
iface->dev->dev_addr,
ipa_ctx);
else if (iface->device_mode == QDF_STA_MODE)
wlan_ipa_uc_send_evt(iface->dev,
QDF_IPA_STA_DISCONNECT,
iface->dev->dev_addr);
iface->dev->dev_addr,
ipa_ctx);
wlan_ipa_cleanup_iface(iface, NULL);
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018-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
@ -621,7 +621,8 @@ QDF_STATUS ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
status = wlan_ipa_uc_ol_deinit(ipa_obj);
ipa_obj_cleanup(ipa_obj);
ipa_disable_register_cb();
if (!g_instances_added)
ipa_disable_register_cb();
out:
ipa_init_deinit_unlock();
@ -667,7 +668,8 @@ QDF_STATUS ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev,
}
return wlan_ipa_wlan_evt(net_dev, device_mode, session_id,
ipa_event_type, mac_addr, is_2g_iface);
ipa_event_type, mac_addr, is_2g_iface,
ipa_obj);
}
int ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 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
@ -47,7 +48,7 @@ QDF_STATUS wlan_ipa_set_perf_level(struct wlan_ipa_priv *ipa_ctx,
ipa_ctx->curr_cons_bw, next_bw);
ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
QDF_IPA_CLIENT_WLAN1_CONS,
next_bw);
next_bw, ipa_ctx->hdl);
if (ret) {
ipa_err("RM CONS set perf profile failed: %d", ret);
@ -55,7 +56,7 @@ QDF_STATUS wlan_ipa_set_perf_level(struct wlan_ipa_priv *ipa_ctx,
}
ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
QDF_IPA_CLIENT_WLAN1_PROD,
next_bw);
next_bw, ipa_ctx->hdl);
if (ret) {
ipa_err("RM PROD set perf profile failed: %d", ret);
return QDF_STATUS_E_FAILURE;
@ -80,7 +81,7 @@ QDF_STATUS wlan_ipa_init_perf_level(struct wlan_ipa_priv *ipa_ctx)
ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
QDF_IPA_CLIENT_WLAN1_CONS,
WLAN_IPA_MAX_BANDWIDTH);
WLAN_IPA_MAX_BANDWIDTH, ipa_ctx->hdl);
if (ret) {
ipa_err("CONS set perf profile failed: %d", ret);
return QDF_STATUS_E_FAILURE;
@ -88,7 +89,7 @@ QDF_STATUS wlan_ipa_init_perf_level(struct wlan_ipa_priv *ipa_ctx)
ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
QDF_IPA_CLIENT_WLAN1_PROD,
WLAN_IPA_MAX_BANDWIDTH);
WLAN_IPA_MAX_BANDWIDTH, ipa_ctx->hdl);
if (ret) {
ipa_err("PROD set perf profile failed: %d", ret);
return QDF_STATUS_E_FAILURE;

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 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
@ -127,6 +128,10 @@ static void wlan_ipa_uc_rt_debug_handler(void *ctext)
void wlan_ipa_uc_rt_debug_destructor(qdf_nbuf_t nbuff)
{
/* Make change to get the ipa_ctx on per pdev basis
* Currently storing the debug count only in global ipa_ctx
* or to the last enumerated radio ipa_ctx
*/
struct wlan_ipa_priv *ipa_ctx = wlan_ipa_get_obj_context();
if (!ipa_ctx) {

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, 2020-2021 The Linux Foundation. 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
@ -69,6 +70,15 @@ static inline bool wlan_ipa_config_is_enabled(void)
return ipa_config_is_enabled();
}
/**
* wlan_ipa_get_hdl() - Get ipa hdl set by IPA driver
* @psoc: void psoc object
* @pdev_id: pdev id
*
* Return: IPA handle
*/
qdf_ipa_wdi_hdl_t wlan_ipa_get_hdl(void *soc, uint8_t pdev_id);
#else
static inline QDF_STATUS ipa_init(void)
@ -95,7 +105,6 @@ static inline bool wlan_ipa_config_is_enabled(void)
{
return false;
}
#endif /* IPA_OFFLOAD */
#endif /* _WLAN_IPA_OBJ_MGMT_H_ */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018, 2020-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
@ -23,13 +23,19 @@
#include "wlan_ipa_obj_mgmt_api.h"
#include "wlan_ipa_main.h"
#include "wlan_objmgr_global_obj.h"
#include <wlan_objmgr_global_obj_i.h>
#include "target_if_ipa.h"
#include "wlan_ipa_ucfg_api.h"
#include "qdf_platform.h"
#include "qdf_module.h"
/* This is as per IPA capbility */
#define MAX_INSTANCES_SUPPORTED 2
uint8_t g_instances_added;
static bool g_ipa_is_ready;
static qdf_mutex_t g_init_deinit_lock;
qdf_mutex_t g_init_deinit_lock;
bool ipa_cb_is_ready(void)
{
return g_ipa_is_ready;
@ -136,17 +142,24 @@ ipa_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
static void ipa_register_ready_cb(void *user_data)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)user_data;
struct wlan_ipa_priv *ipa_obj;
struct wlan_objmgr_pdev *pdev;
struct wlan_objmgr_psoc *psoc;
qdf_device_t qdf_dev;
qdf_ipa_wdi_capabilities_out_params_t out_param;
uint8_t obj_id;
uint8_t pdev_id;
uint8_t pdev_count;
uint8_t instances_supported = 0;
uint8_t instances_processed = 0;
if (!ipa_config_is_enabled()) {
ipa_info("IPA config is disabled");
return;
}
if (!ipa_obj) {
ipa_err("IPA object is NULL");
if (!user_data) {
ipa_err("User_data object is NULL");
return;
}
@ -166,31 +179,77 @@ static void ipa_register_ready_cb(void *user_data)
ipa_err("Driver modules stop in-progress/done, releasing lock");
goto out;
}
pdev = ipa_priv_obj_get_pdev(ipa_obj);
psoc = wlan_pdev_get_psoc(pdev);
qdf_dev = wlan_psoc_get_qdf_dev(psoc);
if (!qdf_dev) {
ipa_err("QDF device context is NULL");
goto out;
}
g_ipa_is_ready = true;
ipa_info("IPA ready callback invoked: ipa_register_ready_cb");
status = ipa_obj_setup(ipa_obj);
if (QDF_IS_STATUS_ERROR(status)) {
ipa_err("Failed to setup ipa component");
wlan_objmgr_pdev_component_obj_detach(pdev,
WLAN_UMAC_COMP_IPA,
ipa_obj);
qdf_mem_free(ipa_obj);
ipa_disable_register_cb();
goto out;
}
if (ucfg_ipa_uc_ol_init(pdev, qdf_dev)) {
ipa_err("IPA ucfg_ipa_uc_ol_init failed");
goto out;
}
/* Make call to get num_instances supported by IPA */
qdf_ipa_wdi_get_capabilities(&out_param);
instances_supported =
QDF_IPA_WDI_CAPABILITIES_OUT_PARAMS_NUM_INSTANCES(&out_param);
ipa_info("Max instances supported by IPA is %d", instances_supported);
for (obj_id = 0; obj_id < WLAN_OBJMGR_MAX_DEVICES; obj_id++) {
/* Get Psoc from global umac obj */
psoc = g_umac_glb_obj->psoc[obj_id];
if (!psoc)
continue;
pdev_count = psoc->soc_objmgr.wlan_pdev_count;
for (pdev_id = 0; pdev_id < pdev_count &&
instances_processed < instances_supported &&
instances_processed < g_instances_added;
pdev_id++, instances_processed++) {
pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id,
WLAN_IPA_ID);
if (!pdev) {
qdf_err("Pdev is NULL for pdev_id[%d]", pdev_id);
continue;
}
/* Get IPA obj from pdev obj */
ipa_obj = ipa_pdev_get_priv_obj(pdev);
if (!ipa_obj) {
ipa_err("ipa_obj is NULL for pdev_id[%d]",
pdev_id);
wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
continue;
}
if (ipa_obj->handle_initialized) {
ipa_info("ipa_obj hdl is true for pdev_id %d", pdev_id);
wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
continue;
}
/* Update instace_id for current pdev */
ipa_obj->instance_id = instances_processed;
qdf_dev = wlan_psoc_get_qdf_dev(psoc);
if (!qdf_dev) {
ipa_err("QDF device context is NULL");
wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
continue;
}
status = ipa_obj_setup(ipa_obj);
if (QDF_IS_STATUS_ERROR(status)) {
ipa_err("Failed to setup ipa component");
wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_IPA,
ipa_obj);
qdf_mem_free(ipa_obj);
wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
continue;
}
if (ucfg_ipa_uc_ol_init(pdev, qdf_dev)) {
ipa_err("IPA ucfg_ipa_uc_ol_init failed");
wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
continue;
}
ipa_obj->handle_initialized = true;
wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
}
}
out:
ipa_init_deinit_unlock();
}
@ -211,6 +270,13 @@ QDF_STATUS ipa_register_is_ipa_ready(struct wlan_objmgr_pdev *pdev)
return QDF_STATUS_E_FAILURE;
}
/* Acquire lock */
ipa_init_deinit_lock();
g_instances_added++;
ipa_info("No. of instances added for IPA is %d", g_instances_added);
/* Unlock */
ipa_init_deinit_unlock();
ret = qdf_ipa_register_ipa_ready_cb(ipa_register_ready_cb,
(void *)ipa_obj);
if (ret == -EEXIST) {
@ -294,3 +360,31 @@ QDF_STATUS ipa_deinit(void)
return status;
}
qdf_ipa_wdi_hdl_t wlan_ipa_get_hdl(void *soc, uint8_t pdev_id)
{
struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)soc;
struct wlan_objmgr_pdev *pdev;
struct wlan_ipa_priv *ipa_obj;
qdf_ipa_wdi_hdl_t hdl;
pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_IPA_ID);
if (!pdev) {
ipa_err("Failed to get pdev handle");
return IPA_INVALID_HDL;
}
ipa_obj = ipa_pdev_get_priv_obj(pdev);
if (!ipa_obj) {
ipa_err("IPA object is NULL for pdev_id[%d]", pdev_id);
wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
return IPA_INVALID_HDL;
}
hdl = ipa_obj->hdl;
wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
return hdl;
}
qdf_export_symbol(wlan_ipa_get_hdl);