dataipa: adding new xr wlan filter reserve/install API's
changes to enable xr-wdi-opt-dpath and handle wlan filter reserve/install/remove API's and it cb's accordingly. Change-Id: I1c11e15d3b2af89318bc29d6afebdf6797cdd039 Signed-off-by: Prasad Arepalli <quic_parepall@quicinc.com>
This commit is contained in:

committed by
Jagadeesh Ponduru

parent
90e8adec6c
commit
554231f83f
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 - 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _IPA_WDI3_H_
|
||||
@@ -447,6 +447,43 @@ int ipa_wdi_opt_dpath_remove_all_filter_req(
|
||||
struct ipa_wlan_opt_dp_remove_all_filter_req_msg_v01 *req,
|
||||
struct ipa_wlan_opt_dp_remove_all_filter_resp_msg_v01 *resp);
|
||||
|
||||
/**
|
||||
* ipa_xr_wdi_opt_dpath_rsrv_filter_req - Client should call this function to
|
||||
* send filter reservation request to wlan
|
||||
*
|
||||
*
|
||||
* @Return 0 on success, negative on failure
|
||||
*/
|
||||
int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void);
|
||||
|
||||
/**
|
||||
* ipa_xr_wdi_opt_dpath_add_filter_req - Client should call this function to
|
||||
* send filter add request to wlan
|
||||
*
|
||||
*
|
||||
* @Return 0 on success, negative on failure
|
||||
*/
|
||||
int ipa_xr_wdi_opt_dpath_add_filter_req(struct ipa_wdi_opt_dpath_flt_add_cb_params *req,
|
||||
u32 stream_id);
|
||||
|
||||
/**
|
||||
* ipa_xr_wdi_opt_dpath_remove_filter_req - Client should call this function to
|
||||
* send filter remove request to wlan
|
||||
*
|
||||
*
|
||||
* @Return 0 on success, negative on failure
|
||||
*/
|
||||
int ipa_xr_wdi_opt_dpath_remove_filter_req(u32 stream_id);
|
||||
|
||||
/**
|
||||
* ipa_xr_wdi_opt_dpath_remove_all_filter_req - Client should call this function to
|
||||
* send release reservation request to wlan
|
||||
*
|
||||
*
|
||||
* @Return 0 on success, negative on failure
|
||||
*/
|
||||
int ipa_xr_wdi_opt_dpath_remove_all_filter_req(void);
|
||||
|
||||
/** ipa_get_wdi_version - return wdi version
|
||||
*
|
||||
* @Return void
|
||||
@@ -941,6 +978,27 @@ static int ipa_wdi_opt_dpath_remove_all_filter_req(
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int ipa_xr_wdi_opt_dpath_add_filter_req(struct ipa_wdi_opt_dpath_flt_add_cb_params *req,
|
||||
u32 stream_id)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int ipa_xr_wdi_opt_dpath_remove_filter_req(u32 stream_id)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int ipa_xr_wdi_opt_dpath_remove_all_filter_req(void)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_IPA3) */
|
||||
|
||||
#endif /* _IPA_WDI3_H_ */
|
||||
|
@@ -2,12 +2,14 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "ipa_wdi3.h"
|
||||
#include <linux/msm_ipa.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/sched.h>
|
||||
#include "ipa_common_i.h"
|
||||
#include "ipa_pm.h"
|
||||
#include "ipa_i.h"
|
||||
@@ -48,6 +50,20 @@
|
||||
#define DEFAULT_INSTANCE_ID (-1)
|
||||
#define INVALID_INSTANCE_ID (-2)
|
||||
|
||||
/**
|
||||
* Time delay value for delayed queue.
|
||||
*/
|
||||
#define QUEUE_DELAY_TIME 100
|
||||
|
||||
/**
|
||||
* No. of filters reserving at wlan for IPA-XR usecase.
|
||||
*/
|
||||
#define NO_OF_FILTERS 4
|
||||
|
||||
static void ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler(struct work_struct *work);
|
||||
static struct workqueue_struct *wlan_flt_rsrv_wq = NULL;
|
||||
static DECLARE_DELAYED_WORK(wlan_flt_rsrv_handle, ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler);
|
||||
|
||||
struct ipa_wdi_intf_info {
|
||||
char netdev_name[IPA_RESOURCE_NAME_MAX];
|
||||
u8 hdr_len;
|
||||
@@ -63,6 +79,7 @@ struct ipa_wdi_opt_dpath_info {
|
||||
u32 hdr_len;
|
||||
atomic_t rsrv_req;
|
||||
atomic_t is_opt_dp_cb_registered;
|
||||
atomic_t is_xr_opt_dp_cb_registered;
|
||||
void *priv;
|
||||
int ipa_ep_idx_tx, ipa_ep_idx_rx;
|
||||
u32 ipa_pm_hdl;
|
||||
@@ -85,6 +102,13 @@ struct ipa_wdi_context {
|
||||
ipa_wdi_meter_notifier_cb wdi_notify;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ipa_wdi_opt_dpath_add_flt_handle {
|
||||
uint64_t filter_handle;
|
||||
};
|
||||
|
||||
struct ipa_wdi_opt_dpath_add_flt_handle add_flt_hndl[4];
|
||||
|
||||
/**
|
||||
* opt_dpath_info contains fn callbacks which are set by WLAN context and
|
||||
* accessed by QMI context. To avoid race condition between these 2,
|
||||
@@ -850,6 +874,23 @@ int ipa_wdi_enable_pipes_per_inst(ipa_wdi_hdl_t hdl)
|
||||
}
|
||||
}
|
||||
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) {
|
||||
if (wlan_flt_rsrv_wq == NULL) {
|
||||
wlan_flt_rsrv_wq = create_singlethread_workqueue("wlan_flt_rsrv_wq");
|
||||
if (wlan_flt_rsrv_wq) {
|
||||
IPA_WDI_ERR("failed to create wq\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = queue_delayed_work(wlan_flt_rsrv_wq, &wlan_flt_rsrv_handle,
|
||||
msecs_to_jiffies(QUEUE_DELAY_TIME));
|
||||
if (ret) {
|
||||
IPA_WDI_ERR("failed to queue delayed wq\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_wdi_enable_pipes_per_inst);
|
||||
@@ -1056,6 +1097,12 @@ int ipa_wdi_opt_dpath_register_flt_cb_per_inst(
|
||||
opt_dpath_info[hdl].flt_add_cb = flt_add_cb;
|
||||
opt_dpath_info[hdl].flt_rem_cb = flt_rem_cb;
|
||||
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) {
|
||||
IPADBG("wdi_xr_opt_dpath_register_flt_cb: callbacks registered.\n");
|
||||
atomic_set(&opt_dpath_info[hdl].is_xr_opt_dp_cb_registered, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
atomic_set(&opt_dpath_info[hdl].is_opt_dp_cb_registered, 1);
|
||||
|
||||
IPADBG("wdi_opt_dpath_register_flt_cb: callbacks registered.\n");
|
||||
@@ -1096,6 +1143,11 @@ int ipa_wdi_opt_dpath_notify_flt_rsvd_per_inst
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) {
|
||||
ipa3_ctx->ipa_xr_wdi_flt_rsv_status = is_success;
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(&ind, 0, sizeof(ind));
|
||||
ind.rsrv_filter_status.result = (is_success == true) ? IPA_QMI_RESULT_SUCCESS_V01:IPA_QMI_RESULT_FAILURE_V01;
|
||||
ind.rsrv_filter_status.error = IPA_QMI_ERR_NONE_V01;
|
||||
@@ -1130,6 +1182,8 @@ int ipa_wdi_opt_dpath_notify_flt_rlsd_per_inst
|
||||
}
|
||||
|
||||
ret = ipa_pm_deferred_deactivate(ipa_wdi_ctx_list[0]->ipa_pm_hdl);
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR)
|
||||
return ret;
|
||||
|
||||
memset(&ind, 0, sizeof(ind));
|
||||
ind.filter_removal_all_status.result =
|
||||
@@ -1411,6 +1465,157 @@ int ipa_wdi_opt_dpath_remove_all_filter_req(
|
||||
EXPORT_SYMBOL(ipa_wdi_opt_dpath_remove_all_filter_req);
|
||||
|
||||
|
||||
/**
|
||||
* ipa_xr_wdi_opt_dpath_rsrv_filter_req() - Sends WLAN DP filter reservation
|
||||
* from IPA Driver to WLAN
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
*/
|
||||
int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ipa_wdi_opt_dpath_flt_rsrv_cb_params rsrv_filter_req;
|
||||
|
||||
memset(&rsrv_filter_req, 0, sizeof(struct ipa_wdi_opt_dpath_flt_rsrv_cb_params));
|
||||
if (!atomic_read(&opt_dpath_info[0].is_xr_opt_dp_cb_registered)) {
|
||||
IPAERR("filter reserve cb not registered");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (opt_dpath_info[0].ipa_ep_idx_tx <= 0 || opt_dpath_info[0].ipa_ep_idx_rx <= 0) {
|
||||
IPA_WDI_ERR("Either TX/RX ep is not configured.\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
ret = ipa_pm_activate_sync(opt_dpath_info[0].ipa_pm_hdl);
|
||||
if (ret) {
|
||||
IPA_WDI_DBG("fail to activate ipa pm\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
rsrv_filter_req.num_filters = NO_OF_FILTERS;
|
||||
ret = opt_dpath_info[0].flt_rsrv_cb(
|
||||
opt_dpath_info[0].priv, &rsrv_filter_req);
|
||||
if (!ret) {
|
||||
atomic_set(&opt_dpath_info[0].rsrv_req, 1);
|
||||
} else {
|
||||
if (ipa_pm_deferred_deactivate(opt_dpath_info[0].ipa_pm_hdl))
|
||||
IPA_WDI_DBG("fail to deactivate ipa pm\n");
|
||||
}
|
||||
|
||||
IPA_WDI_DBG("reserved filter callbacks called.\n");
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_rsrv_filter_req);
|
||||
|
||||
/**
|
||||
* ipa_xr_wdi_opt_dpath_add_filter_req() - Sends WLAN DP filter info
|
||||
* from IPA Driver to WLAN
|
||||
* @req: [in] filter add parameters from IPA Driver
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
int ipa_xr_wdi_opt_dpath_add_filter_req(struct ipa_wdi_opt_dpath_flt_add_cb_params *req,
|
||||
u32 stream_id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!atomic_read(&opt_dpath_info[0].is_xr_opt_dp_cb_registered)) {
|
||||
IPAERR("filter add cb not registered");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
ret =
|
||||
opt_dpath_info[0].flt_add_cb
|
||||
(opt_dpath_info[0].priv, req);
|
||||
add_flt_hndl[stream_id].filter_handle = req->flt_info[0].out_hdl;
|
||||
IPA_WDI_DBG("add filter callbacks called, stream id %d\n", stream_id);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_add_filter_req);
|
||||
|
||||
/**
|
||||
* ipa_xr_wdi_opt_dpath_remove_filter_req() - Sends WLAN DP filter info
|
||||
* from IPA Driver to WLAN
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
int ipa_xr_wdi_opt_dpath_remove_filter_req(u32 stream_id)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ipa_wdi_opt_dpath_flt_rem_cb_params flt_rem_req;
|
||||
|
||||
memset(&flt_rem_req, 0, sizeof(struct ipa_wdi_opt_dpath_flt_rem_cb_params));
|
||||
if (!atomic_read(&opt_dpath_info[0].is_xr_opt_dp_cb_registered)) {
|
||||
IPAERR("filter remove cb not registered");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
flt_rem_req.num_tuples = 1;
|
||||
flt_rem_req.hdl_info[0] = add_flt_hndl[stream_id].filter_handle;
|
||||
|
||||
ret = opt_dpath_info[0].flt_rem_cb
|
||||
(opt_dpath_info[0].priv, &flt_rem_req);
|
||||
IPA_WDI_DBG("remove filter callbacks called, stream id %d\n", stream_id);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_remove_filter_req);
|
||||
|
||||
/**
|
||||
* ipa_xr_wdi_opt_dpath_remove_all_filter_req() - Sends WLAN DP filter info
|
||||
* from IPAs to WLAN
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
int ipa_xr_wdi_opt_dpath_remove_all_filter_req(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!atomic_read(&opt_dpath_info[0].is_xr_opt_dp_cb_registered)) {
|
||||
IPAERR("filter release cb not registered");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (!atomic_read(&opt_dpath_info[0].rsrv_req)) {
|
||||
IPAERR("Reservation request not sent. IGNORE");
|
||||
return 0;
|
||||
}
|
||||
|
||||
atomic_set(&opt_dpath_info[0].rsrv_req, 0);
|
||||
|
||||
ret = opt_dpath_info[0].flt_rsrv_rel_cb(
|
||||
opt_dpath_info[0].priv);
|
||||
|
||||
if (opt_dpath_info[0].ipa_ep_idx_rx <= 0 || opt_dpath_info[0].ipa_ep_idx_tx <= 0) {
|
||||
IPA_WDI_ERR("Either RX ep or TX ep is not configured.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IPA_WDI_DBG("remove all filter callbacks called.\n");
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_remove_all_filter_req);
|
||||
|
||||
|
||||
static void ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler(struct work_struct *work)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
res = ipa_xr_wdi_opt_dpath_rsrv_filter_req();
|
||||
if (!res)
|
||||
IPAERR("Failed to reserve the filters in wlan\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up WDI IPA offload data path
|
||||
*
|
||||
@@ -1450,6 +1655,7 @@ int ipa_wdi_cleanup_per_inst(ipa_wdi_hdl_t hdl)
|
||||
}
|
||||
mutex_destroy(&ipa_wdi_ctx_list[hdl]->lock);
|
||||
kfree(ipa_wdi_ctx_list[hdl]);
|
||||
atomic_set(&opt_dpath_info[hdl].is_xr_opt_dp_cb_registered, 0);
|
||||
atomic_set(&opt_dpath_info[hdl].is_opt_dp_cb_registered, 0);
|
||||
opt_dpath_info[0].ipa_ep_idx_rx = 0;
|
||||
opt_dpath_info[0].ipa_ep_idx_tx = 0;
|
||||
@@ -1567,6 +1773,10 @@ int ipa_wdi_disconn_pipes_per_inst(ipa_wdi_hdl_t hdl)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (wlan_flt_rsrv_wq) {
|
||||
destroy_workqueue(wlan_flt_rsrv_wq);
|
||||
wlan_flt_rsrv_wq = NULL;
|
||||
}
|
||||
|
||||
if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_1 &&
|
||||
ipa_wdi_ctx_list[hdl]->wdi_version < IPA_WDI_3 &&
|
||||
|
@@ -1568,6 +1568,7 @@ enum ipa3_platform_type {
|
||||
IPA_PLAT_TYPE_MDM = 0,
|
||||
IPA_PLAT_TYPE_MSM = 1,
|
||||
IPA_PLAT_TYPE_APQ = 2,
|
||||
IPA_PLAT_TYPE_XR = 3,
|
||||
};
|
||||
|
||||
enum ipa3_config_this_ep {
|
||||
@@ -2426,6 +2427,7 @@ struct ipa3_context {
|
||||
bool ipa_wdi2_over_gsi;
|
||||
bool ipa_wdi3_over_gsi;
|
||||
bool ipa_wdi_opt_dpath;
|
||||
bool ipa_xr_wdi_flt_rsv_status;
|
||||
u8 rtp_stream_id_cnt;
|
||||
bool ipa_endp_delay_wa;
|
||||
bool lan_coal_enable;
|
||||
|
Reference in New Issue
Block a user