mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 12:25:00 -04:00
msm: ipa: create ipa framework
IPA driver is moving to teckpack. create a thin kernel framework for IPA driver that will allow dependent drivers to dispatch IPA APIs from teckpack. Disable IPA and GSI kernel drivers compilation. This change comes in parallel to IPA and GSI drivers enablement in teckpack. Change-Id: I35f2918b935423637e21d6f871a113dc0224f878 Signed-off-by: Amir Levy <alevy@codeaurora.org>
This commit is contained in:
parent
b7a4d9d478
commit
26fe8fee6f
8 changed files with 423 additions and 157 deletions
5
arch/arm64/configs/vendor/lahaina_GKI.config
vendored
5
arch/arm64/configs/vendor/lahaina_GKI.config
vendored
|
|
@ -105,14 +105,9 @@ CONFIG_MSM_BT_POWER=m
|
|||
CONFIG_ARM_SMMU=m
|
||||
CONFIG_MSM_CLK_AOP_QMP=m
|
||||
CONFIG_MSM_SPSS_UTILS=m
|
||||
CONFIG_GSI=m
|
||||
CONFIG_GSI_REGISTER_VERSION_2=y
|
||||
CONFIG_QCOM_MINIDUMP=m
|
||||
CONFIG_IPA3=m
|
||||
CONFIG_IPA_USB=m
|
||||
CONFIG_IPA_WDI_UNIFIED_API=y
|
||||
CONFIG_RMNET_IPA3=y
|
||||
CONFIG_RNDIS_IPA=m
|
||||
CONFIG_CNSS2=m
|
||||
CONFIG_CNSS2_QMI=y
|
||||
CONFIG_CNSS_ASYNC=y
|
||||
|
|
|
|||
|
|
@ -42,31 +42,11 @@ config SPS_SUPPORT_NDP_BAM
|
|||
to do the actual data transfer themselves, instead of the
|
||||
BAM.
|
||||
|
||||
config GSI
|
||||
tristate "GSI support"
|
||||
help
|
||||
This driver provides the transport needed to talk to the
|
||||
IPA core. It replaces the BAM transport used previously.
|
||||
|
||||
The GSI connects to a peripheral component via uniform TLV
|
||||
interface, and allows it to interface with other peripherals
|
||||
and CPUs over various types of interfaces such as MHI, xDCI,
|
||||
xHCI, GPI, WDI, Ethernet, etc.
|
||||
|
||||
config GSI_REGISTER_VERSION_2
|
||||
bool "GSI core Version 2 Registers SWI Support"
|
||||
depends on GSI
|
||||
help
|
||||
GSI core registers Software interface version 2 has updated
|
||||
registers interface to communicate with GSI. This includes
|
||||
new registers offsets, new registers fields structure and
|
||||
new registers.
|
||||
|
||||
config IPA3
|
||||
tristate "IPA3 support"
|
||||
depends on NET && GSI
|
||||
depends on NET
|
||||
help
|
||||
This driver supports the Internet Packet Accelerator (IPA3) core.
|
||||
This framework supports the Internet Packet Accelerator (IPA3) core.
|
||||
IPA is a programmable protocol processor HW block.
|
||||
It is designed to support generic HW processing of UL/DL IP packets
|
||||
for various use cases independent of radio technology.
|
||||
|
|
@ -75,24 +55,6 @@ config IPA3
|
|||
Kernel and user-space processes can call the IPA driver
|
||||
to configure IPA core.
|
||||
|
||||
config IPA_USB
|
||||
tristate "IPA USB offload support"
|
||||
depends on IPA3 && ARCH_QCOM
|
||||
help
|
||||
This driver supports control of USB data traffic offload via IPA.
|
||||
Using xDCI GSI protocol, IPA USB enables USB to configure IPA to
|
||||
offload traffic with different USB functions. The supported functions
|
||||
are RNDIS, ECM, MBIM, RMNET as well as DPL (data packet logging).
|
||||
|
||||
config IPA_DEBUG
|
||||
bool "IPA DEBUG for non-perf build"
|
||||
depends on IPA3
|
||||
help
|
||||
This driver support more debug info for non-perf build.
|
||||
If you use the non-perf build and want to have more debug
|
||||
info enabled, then this flag can be enabled.
|
||||
It is not suggested to enable this flag for perf build.
|
||||
|
||||
config IPA_WDI_UNIFIED_API
|
||||
bool "IPA WDI unified API support"
|
||||
depends on IPA3
|
||||
|
|
@ -103,73 +65,6 @@ config IPA_WDI_UNIFIED_API
|
|||
The IPA WDI unified API supports all WDI versions through a unified
|
||||
interface.
|
||||
|
||||
config RMNET_IPA3
|
||||
bool "IPA3 RMNET WWAN Network Device"
|
||||
depends on IPA3 && ARCH_QCOM
|
||||
select QCOM_QMI_HELPERS
|
||||
help
|
||||
This WWAN Network Driver implements network stack class device.
|
||||
It supports Embedded data transfer from A7 to Q6. Configures IPA HW
|
||||
for RmNet Data Driver and also exchange of QMI messages between
|
||||
A7 and Q6 IPA-driver.
|
||||
|
||||
config ECM_IPA
|
||||
tristate "STD ECM LAN Driver support"
|
||||
depends on IPA_USB
|
||||
help
|
||||
Enables LAN between applications processor and a tethered
|
||||
host using the STD ECM protocol.
|
||||
This Network interface is aimed to allow data path go through
|
||||
IPA core while using STD ECM protocol.
|
||||
|
||||
config RNDIS_IPA
|
||||
tristate "RNDIS_IPA Network Interface Driver support"
|
||||
depends on IPA_USB
|
||||
help
|
||||
Enables LAN between applications processor and a tethered
|
||||
host using the RNDIS protocol.
|
||||
This Network interface is aimed to allow data path go through
|
||||
IPA core while using RNDIS protocol.
|
||||
|
||||
config IPA3_MHI_PROXY
|
||||
bool "IPA3 MHI proxy driver"
|
||||
depends on RMNET_IPA3
|
||||
help
|
||||
This driver is used as a proxy between modem and MHI host driver.
|
||||
Its main functionality is to setup MHI Satellite channels on behalf of
|
||||
modem and provide the ability of modem to MHI device communication.
|
||||
Once the configuration is done modem will communicate directly with
|
||||
the MHI device without AP involvement, with the exception of
|
||||
power management.
|
||||
|
||||
config IPA3_MHI_PRIME_MANAGER
|
||||
tristate "IPA3_MHI Prime Manager driver"
|
||||
depends on RMNET_IPA3
|
||||
help
|
||||
This driver functionality is to setup MHI Prime channels between Host and
|
||||
modem and enable the ability for MHI Prime communication.
|
||||
Once the configuration is done modem will communicate directly with
|
||||
the Host without AP involvement for tethering data offload.
|
||||
|
||||
config IPA_UT
|
||||
bool "IPA Unit-Test Framework and Test Suites"
|
||||
depends on IPA3 && DEBUG_FS
|
||||
help
|
||||
This Module implements IPA in-kernel test framework.
|
||||
The framework supports defining and running tests, grouped
|
||||
into suites according to the sub-unit of the IPA being tested.
|
||||
The user interface to run and control the tests is debugfs file
|
||||
system.
|
||||
|
||||
config IPA_EMULATION
|
||||
bool "IPA on X86 Linux (IPA emulation support)"
|
||||
depends on X86 && IPA3
|
||||
help
|
||||
This options is used only when building the X86 version of
|
||||
the IPA/GSI driver. On this mode, IPA driver will be probed
|
||||
as PCIE device (and not platform device) where IPA emulation
|
||||
shall be connected via PCIE to X86 machine.
|
||||
|
||||
config USB_BAM
|
||||
tristate "USB BAM Driver"
|
||||
depends on SPS && USB_GADGET
|
||||
|
|
@ -187,44 +82,6 @@ config MSM_GENI_SE
|
|||
module is used to configure and read the configuration from the
|
||||
Serial Engines.
|
||||
|
||||
config IPA3_REGDUMP
|
||||
bool "Dump or collect IPA/GSI register values on Linux crash"
|
||||
depends on IPA3
|
||||
help
|
||||
This option is to be used when the saving of IPA register state is
|
||||
desired upon a fatal system exception. When an exception occurs,
|
||||
an IPA register collection algorithm will be run in the context of
|
||||
the exception handler. A predefined set of registers will be read
|
||||
and their values will be placed into a static hierarchical data
|
||||
structure that can be perused post crash.
|
||||
|
||||
choice
|
||||
prompt "Platform whose registers are to be dumped/collected"
|
||||
depends on IPA3_REGDUMP
|
||||
help
|
||||
The choices within represent the possible platforms this build is
|
||||
intended for. The choices are mutually exclusive. By selecting
|
||||
one, you effect the inclusion path used, such that the relevant
|
||||
register definitions will be found. Each platform has unique
|
||||
register definitions.
|
||||
|
||||
config IPA3_REGDUMP_IPA_4_5
|
||||
bool "The 4.5 IPA"
|
||||
depends on IPA3_REGDUMP
|
||||
depends on ARCH_KONA
|
||||
help
|
||||
Set this to enable the 4.5 IPA's registers to be dumped/collected.
|
||||
|
||||
endchoice
|
||||
|
||||
config IPA3_REGDUMP_NUM_EXTRA_ENDP_REGS
|
||||
int "The number of extra endp registers for remaining pipes"
|
||||
depends on IPA3_REGDUMP
|
||||
default 0
|
||||
help
|
||||
If the platform has extra endpoint registers for remaining
|
||||
pipes, please express how many here.
|
||||
|
||||
config QPNP_REVID
|
||||
tristate "QPNP Revision ID Peripheral"
|
||||
depends on SPMI
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
#
|
||||
|
||||
obj-$(CONFIG_MSM_EXT_DISPLAY) += msm_ext_display.o
|
||||
obj-$(CONFIG_GSI) += gsi/
|
||||
obj-$(CONFIG_IPA3) += ipa/
|
||||
obj-$(CONFIG_IPA3) += ipa_fmwk/
|
||||
obj-$(CONFIG_MSM_GENI_SE) += msm-geni-se.o
|
||||
obj-$(CONFIG_USB_BAM) += usb_bam.o
|
||||
obj-$(CONFIG_QPNP_REVID) += qpnp-revid.o
|
||||
|
|
|
|||
5
drivers/platform/msm/ipa_fmwk/Makefile
Normal file
5
drivers/platform/msm/ipa_fmwk/Makefile
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
ipa_fwmk-y += ipa_fmwk.o
|
||||
|
||||
obj-$(CONFIG_IPA3) += ipa_fmwk.o
|
||||
322
drivers/platform/msm/ipa_fmwk/ipa_fmwk.c
Normal file
322
drivers/platform/msm/ipa_fmwk/ipa_fmwk.c
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/ipa.h>
|
||||
#include <linux/ipa_uc_offload.h>
|
||||
#include <linux/ipa_mhi.h>
|
||||
#include <linux/ipa_wigig.h>
|
||||
#include <linux/ipa_wdi3.h>
|
||||
#include <linux/ipa_usb.h>
|
||||
#include <linux/ipa_odu_bridge.h>
|
||||
#include <linux/ipa_fmwk.h>
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#define IPA_FMWK_DISPATCH_RETURN(api, p...) \
|
||||
do { \
|
||||
if (!ipa_fmwk_ctx) { \
|
||||
pr_err("%s:%d IPA framework was not inited\n", \
|
||||
__func__, __LINE__); \
|
||||
ret = -EPERM; \
|
||||
} \
|
||||
else { \
|
||||
if (ipa_fmwk_ctx->api) { \
|
||||
ret = ipa_fmwk_ctx->api(p); \
|
||||
} else { \
|
||||
WARN(1, \
|
||||
"%s was not registered on ipa_fmwk\n", \
|
||||
__func__); \
|
||||
ret = -EPERM; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* struct ipa_ready_cb_info - A list of all the registrations
|
||||
* for an indication of IPA driver readiness
|
||||
*
|
||||
* @link: linked list link
|
||||
* @ready_cb: callback
|
||||
* @user_data: User data
|
||||
*
|
||||
*/
|
||||
struct ipa_ready_cb_info {
|
||||
struct list_head link;
|
||||
ipa_ready_cb ready_cb;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
struct ipa_fmwk_contex {
|
||||
bool ipa_ready;
|
||||
struct list_head ipa_ready_cb_list;
|
||||
struct mutex lock;
|
||||
|
||||
/* ipa core driver APIs */
|
||||
int (*ipa_tx_dp)(enum ipa_client_type dst, struct sk_buff *skb,
|
||||
struct ipa_tx_meta *metadata);
|
||||
|
||||
/* ipa_usb APIs */
|
||||
int (*ipa_usb_init_teth_prot)(enum ipa_usb_teth_prot teth_prot,
|
||||
struct ipa_usb_teth_params *teth_params,
|
||||
int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event,
|
||||
void *),
|
||||
void *user_data);
|
||||
|
||||
int (*ipa_usb_xdci_connect)(
|
||||
struct ipa_usb_xdci_chan_params *ul_chan_params,
|
||||
struct ipa_usb_xdci_chan_params *dl_chan_params,
|
||||
struct ipa_req_chan_out_params *ul_out_params,
|
||||
struct ipa_req_chan_out_params *dl_out_params,
|
||||
struct ipa_usb_xdci_connect_params *connect_params);
|
||||
|
||||
int (*ipa_usb_xdci_disconnect)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot);
|
||||
|
||||
int (*ipa_usb_deinit_teth_prot)(enum ipa_usb_teth_prot teth_prot);
|
||||
|
||||
int (*ipa_usb_xdci_suspend)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot,
|
||||
bool with_remote_wakeup);
|
||||
|
||||
int (*ipa_usb_xdci_resume)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot);
|
||||
};
|
||||
|
||||
static struct ipa_fmwk_contex *ipa_fmwk_ctx;
|
||||
|
||||
static inline void ipa_trigger_ipa_ready_cbs(void)
|
||||
{
|
||||
struct ipa_ready_cb_info *info;
|
||||
struct ipa_ready_cb_info *next;
|
||||
|
||||
/* Call all the CBs */
|
||||
list_for_each_entry_safe(info, next,
|
||||
&ipa_fmwk_ctx->ipa_ready_cb_list, link) {
|
||||
if (info->ready_cb)
|
||||
info->ready_cb(info->user_data);
|
||||
|
||||
list_del(&info->link);
|
||||
kfree(info);
|
||||
}
|
||||
}
|
||||
|
||||
/* registration API for IPA core module */
|
||||
int ipa_fmwk_register_ipa(const struct ipa_core_data *in)
|
||||
{
|
||||
if (!ipa_fmwk_ctx) {
|
||||
pr_err("ipa framework hasn't been initialized yet\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
mutex_lock(&ipa_fmwk_ctx->lock);
|
||||
if (ipa_fmwk_ctx->ipa_ready) {
|
||||
pr_err("ipa core driver API were already registered\n");
|
||||
mutex_unlock(&ipa_fmwk_ctx->lock);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
ipa_fmwk_ctx->ipa_tx_dp = in->ipa_tx_dp;
|
||||
|
||||
ipa_fmwk_ctx->ipa_ready = true;
|
||||
ipa_trigger_ipa_ready_cbs();
|
||||
mutex_unlock(&ipa_fmwk_ctx->lock);
|
||||
|
||||
pr_info("IPA driver is now in ready state\n");
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_fmwk_register_ipa);
|
||||
|
||||
int ipa_register_ipa_ready_cb(void(*ipa_ready_cb)(void *user_data),
|
||||
void *user_data)
|
||||
{
|
||||
struct ipa_ready_cb_info *cb_info = NULL;
|
||||
|
||||
if (!ipa_fmwk_ctx) {
|
||||
pr_err("ipa framework hasn't been initialized yet\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
mutex_lock(&ipa_fmwk_ctx->lock);
|
||||
if (ipa_fmwk_ctx->ipa_ready) {
|
||||
pr_debug("IPA driver finished initialization already\n");
|
||||
mutex_unlock(&ipa_fmwk_ctx->lock);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
cb_info = kmalloc(sizeof(struct ipa_ready_cb_info), GFP_KERNEL);
|
||||
if (!cb_info) {
|
||||
mutex_unlock(&ipa_fmwk_ctx->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cb_info->ready_cb = ipa_ready_cb;
|
||||
cb_info->user_data = user_data;
|
||||
|
||||
list_add_tail(&cb_info->link, &ipa_fmwk_ctx->ipa_ready_cb_list);
|
||||
mutex_unlock(&ipa_fmwk_ctx->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_register_ipa_ready_cb);
|
||||
|
||||
/* ipa core driver API wrappers*/
|
||||
|
||||
int ipa_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
|
||||
struct ipa_tx_meta *metadata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
IPA_FMWK_DISPATCH_RETURN(ipa_tx_dp,
|
||||
dst, skb, metadata);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_tx_dp);
|
||||
|
||||
/* registration API for IPA usb module */
|
||||
int ipa_fmwk_register_ipa_usb(const struct ipa_usb_data *in)
|
||||
{
|
||||
if (!ipa_fmwk_ctx) {
|
||||
pr_err("ipa framework hasn't been initialized yet\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (ipa_fmwk_ctx->ipa_usb_init_teth_prot ||
|
||||
ipa_fmwk_ctx->ipa_usb_xdci_connect ||
|
||||
ipa_fmwk_ctx->ipa_usb_xdci_disconnect ||
|
||||
ipa_fmwk_ctx->ipa_usb_deinit_teth_prot ||
|
||||
ipa_fmwk_ctx->ipa_usb_xdci_suspend ||
|
||||
ipa_fmwk_ctx->ipa_usb_xdci_resume) {
|
||||
pr_err("ipa_usb APIs were already initialized\n");
|
||||
return -EPERM;
|
||||
}
|
||||
ipa_fmwk_ctx->ipa_usb_init_teth_prot = in->ipa_usb_init_teth_prot;
|
||||
ipa_fmwk_ctx->ipa_usb_xdci_connect = in->ipa_usb_xdci_connect;
|
||||
ipa_fmwk_ctx->ipa_usb_xdci_disconnect = in->ipa_usb_xdci_disconnect;
|
||||
ipa_fmwk_ctx->ipa_usb_deinit_teth_prot = in->ipa_usb_deinit_teth_prot;
|
||||
ipa_fmwk_ctx->ipa_usb_xdci_suspend = in->ipa_usb_xdci_suspend;
|
||||
ipa_fmwk_ctx->ipa_usb_xdci_resume = in->ipa_usb_xdci_resume;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_fmwk_register_ipa_usb);
|
||||
|
||||
/* ipa_usb API wrappers*/
|
||||
int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot,
|
||||
struct ipa_usb_teth_params *teth_params,
|
||||
int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event,
|
||||
void *),
|
||||
void *user_data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
IPA_FMWK_DISPATCH_RETURN(ipa_usb_init_teth_prot,
|
||||
teth_prot, teth_params, ipa_usb_notify_cb, user_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_usb_init_teth_prot);
|
||||
|
||||
int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params,
|
||||
struct ipa_usb_xdci_chan_params *dl_chan_params,
|
||||
struct ipa_req_chan_out_params *ul_out_params,
|
||||
struct ipa_req_chan_out_params *dl_out_params,
|
||||
struct ipa_usb_xdci_connect_params *connect_params)
|
||||
{
|
||||
int ret;
|
||||
|
||||
IPA_FMWK_DISPATCH_RETURN(ipa_usb_xdci_connect,
|
||||
ul_chan_params, dl_chan_params, ul_out_params,
|
||||
dl_out_params, connect_params);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_usb_xdci_connect);
|
||||
|
||||
int ipa_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot)
|
||||
{
|
||||
int ret;
|
||||
|
||||
IPA_FMWK_DISPATCH_RETURN(ipa_usb_xdci_disconnect,
|
||||
ul_clnt_hdl, dl_clnt_hdl, teth_prot);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_usb_xdci_disconnect);
|
||||
|
||||
int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot)
|
||||
{
|
||||
int ret;
|
||||
|
||||
IPA_FMWK_DISPATCH_RETURN(ipa_usb_deinit_teth_prot,
|
||||
teth_prot);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_usb_deinit_teth_prot);
|
||||
|
||||
int ipa_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot,
|
||||
bool with_remote_wakeup)
|
||||
{
|
||||
int ret;
|
||||
|
||||
IPA_FMWK_DISPATCH_RETURN(ipa_usb_xdci_suspend,
|
||||
ul_clnt_hdl, dl_clnt_hdl, teth_prot, with_remote_wakeup);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_usb_xdci_suspend);
|
||||
|
||||
int ipa_usb_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot)
|
||||
{
|
||||
int ret;
|
||||
|
||||
IPA_FMWK_DISPATCH_RETURN(ipa_usb_xdci_resume,
|
||||
ul_clnt_hdl, dl_clnt_hdl, teth_prot);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_usb_xdci_resume);
|
||||
|
||||
static int __init ipa_fmwk_init(void)
|
||||
{
|
||||
pr_info("IPA framework init\n");
|
||||
|
||||
ipa_fmwk_ctx = kzalloc(sizeof(struct ipa_fmwk_contex), GFP_KERNEL);
|
||||
if (ipa_fmwk_ctx == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&ipa_fmwk_ctx->ipa_ready_cb_list);
|
||||
mutex_init(&ipa_fmwk_ctx->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(ipa_fmwk_init);
|
||||
|
||||
static void __exit ipa_fmwk_exit(void)
|
||||
{
|
||||
struct ipa_ready_cb_info *info;
|
||||
struct ipa_ready_cb_info *next;
|
||||
|
||||
pr_debug("IPA framework exit\n");
|
||||
list_for_each_entry_safe(info, next,
|
||||
&ipa_fmwk_ctx->ipa_ready_cb_list, link) {
|
||||
list_del(&info->link);
|
||||
kfree(info);
|
||||
}
|
||||
kfree(ipa_fmwk_ctx);
|
||||
ipa_fmwk_ctx = NULL;
|
||||
}
|
||||
module_exit(ipa_fmwk_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("IPA HW framework");
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _IPA_H_
|
||||
|
|
@ -1477,6 +1477,34 @@ int ipa_set_single_ndp_per_mbim(bool enable);
|
|||
/*
|
||||
* Data path
|
||||
*/
|
||||
|
||||
/**
|
||||
* ipa_tx_dp() - Data-path tx handler
|
||||
* @dst: [in] which IPA destination to route tx packets to
|
||||
* @skb: [in] the packet to send
|
||||
* @metadata: [in] TX packet meta-data
|
||||
*
|
||||
* Data-path tx handler, this is used for both SW data-path which by-passes most
|
||||
* IPA HW blocks AND the regular HW data-path for WLAN AMPDU traffic only. If
|
||||
* dst is a "valid" CONS type, then SW data-path is used. If dst is the
|
||||
* WLAN_AMPDU PROD type, then HW data-path for WLAN AMPDU is used. Anything else
|
||||
* is an error. For errors, client needs to free the skb as needed. For success,
|
||||
* IPA driver will later invoke client callback if one was supplied. That
|
||||
* callback should free the skb. If no callback supplied, IPA driver will free
|
||||
* the skb internally
|
||||
*
|
||||
* The function will use two descriptors for this send command
|
||||
* (for A5_WLAN_AMPDU_PROD only one desciprtor will be sent),
|
||||
* the first descriptor will be used to inform the IPA hardware that
|
||||
* apps need to push data into the IPA (IP_PACKET_INIT immediate command).
|
||||
* Once this send was done from SPS point-of-view the IPA driver will
|
||||
* get notified by the supplied callback - ipa_sps_irq_tx_comp()
|
||||
*
|
||||
* ipa_sps_irq_tx_comp will call to the user supplied
|
||||
* callback (from ipa_connect)
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*/
|
||||
int ipa_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
|
||||
struct ipa_tx_meta *metadata);
|
||||
|
||||
|
|
|
|||
60
include/linux/ipa_fmwk.h
Normal file
60
include/linux/ipa_fmwk.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018 - 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _IPA_FMWK_H_
|
||||
#define _IPA_FMWK_H_
|
||||
|
||||
struct ipa_core_data {
|
||||
int (*ipa_tx_dp)(enum ipa_client_type dst, struct sk_buff *skb,
|
||||
struct ipa_tx_meta *metadata);
|
||||
};
|
||||
|
||||
struct ipa_usb_data {
|
||||
int (*ipa_usb_init_teth_prot)(enum ipa_usb_teth_prot teth_prot,
|
||||
struct ipa_usb_teth_params *teth_params,
|
||||
int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event,
|
||||
void *),
|
||||
void *user_data);
|
||||
|
||||
int (*ipa_usb_xdci_connect)(
|
||||
struct ipa_usb_xdci_chan_params *ul_chan_params,
|
||||
struct ipa_usb_xdci_chan_params *dl_chan_params,
|
||||
struct ipa_req_chan_out_params *ul_out_params,
|
||||
struct ipa_req_chan_out_params *dl_out_params,
|
||||
struct ipa_usb_xdci_connect_params *connect_params);
|
||||
|
||||
int (*ipa_usb_xdci_disconnect)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot);
|
||||
|
||||
int (*ipa_usb_deinit_teth_prot)(enum ipa_usb_teth_prot teth_prot);
|
||||
|
||||
int (*ipa_usb_xdci_suspend)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot,
|
||||
bool with_remote_wakeup);
|
||||
|
||||
int (*ipa_usb_xdci_resume)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot);
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPA3)
|
||||
|
||||
int ipa_fmwk_register_ipa(const struct ipa_core_data *in);
|
||||
|
||||
int ipa_fmwk_register_ipa_usb(const struct ipa_usb_data *in);
|
||||
|
||||
#else /* IS_ENABLED(CONFIG_IPA3) */
|
||||
|
||||
int ipa_fmwk_register_ipa(const struct ipa_core_data *in)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
int ipa_fmwk_register_ipa_usb(const struct ipa_usb_data *in)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_IPA3) */
|
||||
|
||||
#endif /* _IPA_FMWK_H_ */
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _IPA_USB_H_
|
||||
|
|
@ -169,7 +169,7 @@ struct ipa_req_chan_out_params {
|
|||
u32 db_reg_phs_addr_msb;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPA_USB)
|
||||
#if IS_ENABLED(CONFIG_IPA3)
|
||||
|
||||
/**
|
||||
* ipa_usb_init_teth_prot - Peripheral should call this function to initialize
|
||||
|
|
@ -284,7 +284,7 @@ int ipa_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
|||
int ipa_usb_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
||||
enum ipa_usb_teth_prot teth_prot);
|
||||
|
||||
#else /* IS_ENABLED(CONFIG_IPA_USB) */
|
||||
#else /* IS_ENABLED(CONFIG_IPA3) */
|
||||
|
||||
static inline int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot,
|
||||
struct ipa_usb_teth_params *teth_params,
|
||||
|
|
@ -330,6 +330,6 @@ static inline int ipa_usb_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
|
|||
}
|
||||
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_IPA_USB) */
|
||||
#endif /* IS_ENABLED(CONFIG_IPA3) */
|
||||
|
||||
#endif /* _IPA_USB_H_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue