mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 04:12:04 -04:00
Merge "msm: ipa: create ipa framework"
This commit is contained in:
commit
b1a5bd0150
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
|
|
@ -106,14 +106,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