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) 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * 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, QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
uint8_t session_id, uint8_t session_id,
enum wlan_ipa_wlan_event ipa_event_type, 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 * 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) 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * 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_public_struct.h>
#include <wlan_ipa_priv.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...) \ #define ipa_fatal(params...) \
QDF_TRACE_FATAL(QDF_MODULE_ID_IPA, params) QDF_TRACE_FATAL(QDF_MODULE_ID_IPA, params)
#define ipa_err(params...) \ #define ipa_err(params...) \

View File

@ -516,11 +516,13 @@ struct uc_rm_work_struct {
* @work: uC OP work * @work: uC OP work
* @msg: OP message * @msg: OP message
* @osdev: poiner to qdf net device, used by osif_psoc_sync_trans_start_wait * @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 { struct uc_op_work_struct {
qdf_work_t work; qdf_work_t work;
struct op_msg_type *msg; struct op_msg_type *msg;
qdf_device_t osdev; qdf_device_t osdev;
struct wlan_ipa_priv *ipa_priv_bp;
}; };
/** /**
@ -734,6 +736,9 @@ struct wlan_ipa_priv {
qdf_atomic_t stats_quota; qdf_atomic_t stats_quota;
uint8_t curr_bw_level; uint8_t curr_bw_level;
qdf_atomic_t deinit_in_prog; 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) #define WLAN_IPA_WLAN_FRAG_HEADER sizeof(struct frag_header)

View File

@ -37,6 +37,8 @@
#include <qal_vbus_dev.h> #include <qal_vbus_dev.h>
#define IPA_SPS_DESC_SIZE 8 #define IPA_SPS_DESC_SIZE 8
#define IPA_DEFAULT_HDL 0
static struct wlan_ipa_priv *gp_ipa; 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_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
static void wlan_ipa_reset_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->tx_pipe_handle,
&ipa_ctx->rx_pipe_handle, &ipa_ctx->rx_pipe_handle,
wlan_ipa_wdi_is_smmu_enabled(ipa_ctx, osdev), 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); 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_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_NOTIFY(&in) = wlan_ipa_uc_loaded_uc_cb;
QDF_IPA_WDI_INIT_IN_PARAMS_PRIV(&in) = ipa_ctx; 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); wlan_ipa_wdi_init_metering(ipa_ctx, &in);
ret = qdf_ipa_wdi_init(&in, &out); 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); QDF_IPA_WDI_INIT_OUT_PARAMS_IS_OVER_GSI(&out);
ipa_ctx->is_smmu_enabled = ipa_ctx->is_smmu_enabled =
QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out); QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out);
ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d", ipa_ctx->hdl = QDF_IPA_WDI_INIT_OUT_PARAMS_HANDLE(&out);
ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled);
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)) { if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) {
ipa_debug("IPA uC READY"); 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; 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; int ret;
ret = qdf_ipa_wdi_cleanup(); ret = qdf_ipa_wdi_cleanup(hdl);
if (ret) if (ret)
ipa_info("ipa_wdi_cleanup failed ret=%d", ret); ipa_info("ipa_wdi_cleanup failed ret=%d", ret);
return 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"); ipa_info("No buffers to map/unmap");
return 0; 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) 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 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 #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) 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 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 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, static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb,
struct wlan_objmgr_pdev *pdev) struct wlan_objmgr_pdev *pdev)
{ {
struct wlan_ipa_priv *ipa_ctx = gp_ipa; struct wlan_ipa_priv *ipa_ctx;
struct ethhdr *eh; struct ethhdr *eh;
struct wlan_objmgr_vdev *vdev = NULL; 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); eh = (struct ethhdr *)qdf_nbuf_data(skb);
vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev( vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(
pdev, eh->h_dest, WLAN_IPA_ID); pdev, eh->h_dest, WLAN_IPA_ID);
@ -1019,7 +1038,9 @@ static void
wlan_ipa_send_skb_to_network(qdf_nbuf_t skb, wlan_ipa_send_skb_to_network(qdf_nbuf_t skb,
struct wlan_ipa_iface_context *iface_ctx) 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) { if (!iface_ctx->dev) {
ipa_debug_rl("Invalid interface"); 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)) { if (qdf_atomic_read(&ipa_ctx->pipes_disabled)) {
result = cdp_ipa_enable_pipes(ipa_ctx->dp_soc, result = cdp_ipa_enable_pipes(ipa_ctx->dp_soc,
ipa_ctx->dp_pdev_id); ipa_ctx->dp_pdev_id,
ipa_ctx->hdl);
if (result) { if (result) {
ipa_err("Enable IPA WDI PIPE failed: ret=%d", result); ipa_err("Enable IPA WDI PIPE failed: ret=%d", result);
qdf_status = QDF_STATUS_E_FAILURE; 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); wlan_ipa_set_pending_tx_timer(ipa_ctx);
} else { } else {
qdf_status = cdp_ipa_disable_pipes(ipa_ctx->dp_soc, 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)) { if (QDF_IS_STATUS_ERROR(qdf_status)) {
ipa_err("Disable IPA WDI PIPE failed: ret=%u", ipa_err("Disable IPA WDI PIPE failed: ret=%u",
qdf_status); 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, if (cdp_ipa_cleanup_iface(ipa_ctx->dp_soc,
iface_context->dev->name, 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"); 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, iface_context->cons_client,
wlan_ipa_set_session_id(session_id, wlan_ipa_set_session_id(session_id,
is_2g_iface), 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) if (status != QDF_STATUS_SUCCESS)
goto end; 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, static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
uint8_t session_id, uint8_t session_id,
qdf_ipa_wlan_event type, 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; struct wlan_ipa_iface_context *iface_ctx = NULL;
qdf_ipa_msg_meta_t meta; qdf_ipa_msg_meta_t meta;
qdf_ipa_wlan_msg_t *msg; 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) if (type >= QDF_IPA_WLAN_EVENT_MAX)
return QDF_STATUS_E_INVAL; return QDF_STATUS_E_INVAL;
ipa_ctx = ipa_obj;
if (wlan_ipa_uc_is_enabled(ipa_ctx->config) && if (wlan_ipa_uc_is_enabled(ipa_ctx->config) &&
!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && !wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
(device_mode != QDF_SAP_MODE)) { (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, QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
uint8_t session_id, uint8_t session_id,
enum wlan_ipa_wlan_event ipa_event_type, 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_ipa_wlan_event type = wlan_host_to_ipa_wlan_event(ipa_event_type);
QDF_STATUS status = QDF_STATUS_SUCCESS; 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)) (device_mode == QDF_SAP_MODE))
status = __wlan_ipa_wlan_evt(net_dev, device_mode, status = __wlan_ipa_wlan_evt(net_dev, device_mode,
session_id, type, mac_addr, session_id, type, mac_addr,
is_2g_iface); is_2g_iface, ipa_obj);
return status; 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->session_id,
pending_event->type, pending_event->type,
pending_event->mac_addr, pending_event->mac_addr,
pending_event->is_2g_iface); pending_event->is_2g_iface, ipa_ctx);
} }
if (vdev) 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 * 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; 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; 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_msg_meta_t meta;
qdf_ipa_wlan_msg_t *ipa_msg; qdf_ipa_wlan_msg_t *ipa_msg;
int ret = 0; int ret = 0;
@ -3453,10 +3483,10 @@ static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(bool ctrl)
if (ctrl) { if (ctrl) {
QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_ENABLE); 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 { } else {
QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_DISABLE); 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)); 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); ipa_ctx);
} }
} else if (status == QDF_STATUS_E_BUSY) { } 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) { if (ret) {
ipa_err("IPA WDI msg send failed: ret=%d", ret); ipa_err("IPA WDI msg send failed: ret=%d", ret);
goto ipa_wdi_destroy; 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)) { 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->event_lock);
qdf_mutex_destroy(&ipa_ctx->ipa_lock); qdf_mutex_destroy(&ipa_ctx->ipa_lock);
qdf_list_destroy(&ipa_ctx->pending_event); 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; 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; return QDF_STATUS_SUCCESS;
} }
@ -3969,7 +4008,7 @@ static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx)
return; return;
smmu_map_fail: smmu_map_fail:
qdf_ipa_wdi_disconn_pipes(); qdf_ipa_wdi_disconn_pipes(ipa_ctx->hdl);
connect_pipe_fail: connect_pipe_fail:
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { 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); qdf_event_set(&ipa_ctx->ipa_resource_comp);
if (ipa_ctx->wdi_enabled == false) { if (ipa_ctx->wdi_enabled == false) {
ipa_ctx->wdi_enabled = true; 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, wlan_ipa_send_mcc_scc_msg(ipa_ctx,
ipa_ctx->mcc_mode); 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 op_msg_type *msg;
struct uc_op_work_struct *uc_op_work = struct uc_op_work_struct *uc_op_work =
(struct uc_op_work_struct *)data; (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; msg = uc_op_work->msg;
uc_op_work->msg = NULL; 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++) { for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) {
ipa_ctx->uc_op_work[i].osdev = osdev; ipa_ctx->uc_op_work[i].osdev = osdev;
ipa_ctx->uc_op_work[i].msg = NULL; 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, qdf_create_work(0, &ipa_ctx->uc_op_work[i].work,
wlan_ipa_uc_fw_op_event_handler, wlan_ipa_uc_fw_op_event_handler,
&ipa_ctx->uc_op_work[i]); &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, status = cdp_ipa_cleanup(ipa_ctx->dp_soc,
ipa_ctx->dp_pdev_id, ipa_ctx->dp_pdev_id,
ipa_ctx->tx_pipe_handle, ipa_ctx->tx_pipe_handle,
ipa_ctx->rx_pipe_handle); ipa_ctx->rx_pipe_handle, ipa_ctx->hdl);
if (status) if (status)
ipa_err("Failure to cleanup IPA pipes (status=%d)", ipa_err("Failure to cleanup IPA pipes (status=%d)",
status); 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, static QDF_STATUS wlan_ipa_uc_send_evt(qdf_netdev_t net_dev,
qdf_ipa_wlan_event type, 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_msg_meta_t meta;
qdf_ipa_wlan_msg_t *msg; 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); QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t);
msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
if (!msg) 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 && if (iface_ctx && iface_ctx->device_mode == QDF_STA_MODE &&
iface_ctx->dev && iface_ctx->dev == net_dev) { iface_ctx->dev && iface_ctx->dev == net_dev) {
wlan_ipa_uc_send_evt(net_dev, QDF_IPA_STA_DISCONNECT, 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); 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); iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_SAP_MODE);
if (iface_ctx) if (iface_ctx)
status = wlan_ipa_uc_send_evt(net_dev, QDF_IPA_AP_DISCONNECT, status = wlan_ipa_uc_send_evt(net_dev, QDF_IPA_AP_DISCONNECT,
net_dev->dev_addr); net_dev->dev_addr, ipa_ctx);
else else
return QDF_STATUS_E_INVAL; 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) if (iface->device_mode == QDF_SAP_MODE)
wlan_ipa_uc_send_evt(iface->dev, wlan_ipa_uc_send_evt(iface->dev,
QDF_IPA_AP_DISCONNECT, QDF_IPA_AP_DISCONNECT,
iface->dev->dev_addr); iface->dev->dev_addr,
ipa_ctx);
else if (iface->device_mode == QDF_STA_MODE) else if (iface->device_mode == QDF_STA_MODE)
wlan_ipa_uc_send_evt(iface->dev, wlan_ipa_uc_send_evt(iface->dev,
QDF_IPA_STA_DISCONNECT, QDF_IPA_STA_DISCONNECT,
iface->dev->dev_addr); iface->dev->dev_addr,
ipa_ctx);
wlan_ipa_cleanup_iface(iface, NULL); wlan_ipa_cleanup_iface(iface, NULL);
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. * 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * 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); status = wlan_ipa_uc_ol_deinit(ipa_obj);
ipa_obj_cleanup(ipa_obj); ipa_obj_cleanup(ipa_obj);
ipa_disable_register_cb(); if (!g_instances_added)
ipa_disable_register_cb();
out: out:
ipa_init_deinit_unlock(); 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, 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) 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) 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * 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); ipa_ctx->curr_cons_bw, next_bw);
ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc, ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
QDF_IPA_CLIENT_WLAN1_CONS, QDF_IPA_CLIENT_WLAN1_CONS,
next_bw); next_bw, ipa_ctx->hdl);
if (ret) { if (ret) {
ipa_err("RM CONS set perf profile failed: %d", 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, ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
QDF_IPA_CLIENT_WLAN1_PROD, QDF_IPA_CLIENT_WLAN1_PROD,
next_bw); next_bw, ipa_ctx->hdl);
if (ret) { if (ret) {
ipa_err("RM PROD set perf profile failed: %d", ret); ipa_err("RM PROD set perf profile failed: %d", ret);
return QDF_STATUS_E_FAILURE; 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, ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
QDF_IPA_CLIENT_WLAN1_CONS, QDF_IPA_CLIENT_WLAN1_CONS,
WLAN_IPA_MAX_BANDWIDTH); WLAN_IPA_MAX_BANDWIDTH, ipa_ctx->hdl);
if (ret) { if (ret) {
ipa_err("CONS set perf profile failed: %d", ret); ipa_err("CONS set perf profile failed: %d", ret);
return QDF_STATUS_E_FAILURE; 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, ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
QDF_IPA_CLIENT_WLAN1_PROD, QDF_IPA_CLIENT_WLAN1_PROD,
WLAN_IPA_MAX_BANDWIDTH); WLAN_IPA_MAX_BANDWIDTH, ipa_ctx->hdl);
if (ret) { if (ret) {
ipa_err("PROD set perf profile failed: %d", ret); ipa_err("PROD set perf profile failed: %d", ret);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * 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) 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(); struct wlan_ipa_priv *ipa_ctx = wlan_ipa_get_obj_context();
if (!ipa_ctx) { if (!ipa_ctx) {

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018, 2020-2021 The Linux Foundation. All rights reserved. * 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * 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(); 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 #else
static inline QDF_STATUS ipa_init(void) static inline QDF_STATUS ipa_init(void)
@ -95,7 +105,6 @@ static inline bool wlan_ipa_config_is_enabled(void)
{ {
return false; return false;
} }
#endif /* IPA_OFFLOAD */ #endif /* IPA_OFFLOAD */
#endif /* _WLAN_IPA_OBJ_MGMT_H_ */ #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) 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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * 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_obj_mgmt_api.h"
#include "wlan_ipa_main.h" #include "wlan_ipa_main.h"
#include "wlan_objmgr_global_obj.h" #include "wlan_objmgr_global_obj.h"
#include <wlan_objmgr_global_obj_i.h>
#include "target_if_ipa.h" #include "target_if_ipa.h"
#include "wlan_ipa_ucfg_api.h" #include "wlan_ipa_ucfg_api.h"
#include "qdf_platform.h" #include "qdf_platform.h"
#include "qdf_module.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 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) bool ipa_cb_is_ready(void)
{ {
return g_ipa_is_ready; 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) static void ipa_register_ready_cb(void *user_data)
{ {
QDF_STATUS status = QDF_STATUS_SUCCESS; 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_pdev *pdev;
struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_psoc *psoc;
qdf_device_t qdf_dev; 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()) { if (!ipa_config_is_enabled()) {
ipa_info("IPA config is disabled"); ipa_info("IPA config is disabled");
return; return;
} }
if (!ipa_obj) {
ipa_err("IPA object is NULL"); if (!user_data) {
ipa_err("User_data object is NULL");
return; return;
} }
@ -166,31 +179,77 @@ static void ipa_register_ready_cb(void *user_data)
ipa_err("Driver modules stop in-progress/done, releasing lock"); ipa_err("Driver modules stop in-progress/done, releasing lock");
goto out; 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; g_ipa_is_ready = true;
ipa_info("IPA ready callback invoked: ipa_register_ready_cb"); 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: out:
ipa_init_deinit_unlock(); 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; 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, ret = qdf_ipa_register_ipa_ready_cb(ipa_register_ready_cb,
(void *)ipa_obj); (void *)ipa_obj);
if (ret == -EEXIST) { if (ret == -EEXIST) {
@ -294,3 +360,31 @@ QDF_STATUS ipa_deinit(void)
return status; 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);