Merge "msm: ipa3: adding new wwan extended_v2 ioctl"
Este commit está contenido en:

cometido por
Gerrit - the friendly Code Review server

commit
b9d424a20e
@@ -1,7 +1,7 @@
|
||||
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/msm_gsi.h>
|
||||
#include <net/sock.h>
|
||||
#include <asm/page.h>
|
||||
#include "gsi.h"
|
||||
#include "ipa_i.h"
|
||||
#include "ipa_trace.h"
|
||||
@@ -98,7 +99,7 @@ static void ipa3_replenish_rx_page_cache(struct ipa3_sys_context *sys);
|
||||
static void ipa3_wq_page_repl(struct work_struct *work);
|
||||
static void ipa3_replenish_rx_page_recycle(struct ipa3_sys_context *sys);
|
||||
static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page(gfp_t flag,
|
||||
bool is_tmp_alloc);
|
||||
bool is_tmp_alloc, struct ipa3_sys_context *sys);
|
||||
static void ipa3_wq_handle_rx(struct work_struct *work);
|
||||
static void ipa3_wq_rx_common(struct ipa3_sys_context *sys,
|
||||
struct gsi_chan_xfer_notify *notify);
|
||||
@@ -1209,6 +1210,10 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
|
||||
ep->client = sys_in->client;
|
||||
ep->client_notify = sys_in->notify;
|
||||
ep->sys->napi_obj = sys_in->napi_obj;
|
||||
ep->sys->ext_ioctl_v2 = sys_in->ext_ioctl_v2;
|
||||
ep->sys->int_modt = sys_in->int_modt;
|
||||
ep->sys->int_modc = sys_in->int_modc;
|
||||
ep->sys->buff_size = sys_in->buff_size;
|
||||
ep->priv = sys_in->priv;
|
||||
ep->keep_ipa_awake = sys_in->keep_ipa_awake;
|
||||
atomic_set(&ep->avail_fifo_desc,
|
||||
@@ -1355,9 +1360,11 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
|
||||
qmap_cfg.mux_id_byte_sel = IPA_QMAP_ID_BYTE;
|
||||
ipahal_write_reg_fields(IPA_COAL_QMAP_CFG, &qmap_cfg);
|
||||
|
||||
sys_in->client = IPA_CLIENT_APPS_WAN_CONS;
|
||||
sys_in->ipa_ep_cfg = ep_cfg_copy;
|
||||
result = ipa3_setup_sys_pipe(sys_in, &wan_handle);
|
||||
if (!sys_in->ext_ioctl_v2) {
|
||||
sys_in->client = IPA_CLIENT_APPS_WAN_CONS;
|
||||
sys_in->ipa_ep_cfg = ep_cfg_copy;
|
||||
result = ipa3_setup_sys_pipe(sys_in, &wan_handle);
|
||||
}
|
||||
if (result) {
|
||||
IPAERR("failed to setup default coalescing pipe\n");
|
||||
goto fail_repl;
|
||||
@@ -2029,7 +2036,7 @@ fail_kmem_cache_alloc:
|
||||
}
|
||||
|
||||
static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page(
|
||||
gfp_t flag, bool is_tmp_alloc)
|
||||
gfp_t flag, bool is_tmp_alloc, struct ipa3_sys_context *sys)
|
||||
{
|
||||
struct ipa3_rx_pkt_wrapper *rx_pkt;
|
||||
|
||||
@@ -2038,9 +2045,16 @@ static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page(
|
||||
flag);
|
||||
if (unlikely(!rx_pkt))
|
||||
return NULL;
|
||||
rx_pkt->len = PAGE_SIZE << IPA_WAN_PAGE_ORDER;
|
||||
rx_pkt->page_data.page = __dev_alloc_pages(flag,
|
||||
IPA_WAN_PAGE_ORDER);
|
||||
if (sys->ext_ioctl_v2) {
|
||||
rx_pkt->len = sys->buff_size;
|
||||
rx_pkt->page_data.page = __dev_alloc_pages(flag,
|
||||
get_order(sys->buff_size));
|
||||
} else {
|
||||
rx_pkt->len = PAGE_SIZE << IPA_WAN_PAGE_ORDER;
|
||||
rx_pkt->page_data.page = __dev_alloc_pages(flag,
|
||||
IPA_WAN_PAGE_ORDER);
|
||||
}
|
||||
|
||||
if (unlikely(!rx_pkt->page_data.page))
|
||||
goto fail_page_alloc;
|
||||
|
||||
@@ -2073,7 +2087,7 @@ static void ipa3_replenish_rx_page_cache(struct ipa3_sys_context *sys)
|
||||
u32 curr;
|
||||
|
||||
for (curr = 0; curr < sys->page_recycle_repl->capacity; curr++) {
|
||||
rx_pkt = ipa3_alloc_rx_pkt_page(GFP_KERNEL, false);
|
||||
rx_pkt = ipa3_alloc_rx_pkt_page(GFP_KERNEL, false, sys);
|
||||
if (!rx_pkt) {
|
||||
IPAERR("ipa3_alloc_rx_pkt_page fails\n");
|
||||
ipa_assert();
|
||||
@@ -2103,7 +2117,7 @@ begin:
|
||||
next = (curr + 1) % sys->repl->capacity;
|
||||
if (unlikely(next == atomic_read(&sys->repl->head_idx)))
|
||||
goto fail_kmem_cache_alloc;
|
||||
rx_pkt = ipa3_alloc_rx_pkt_page(GFP_KERNEL, true);
|
||||
rx_pkt = ipa3_alloc_rx_pkt_page(GFP_KERNEL, true, sys);
|
||||
if (unlikely(!rx_pkt)) {
|
||||
IPAERR("ipa3_alloc_rx_pkt_page fails\n");
|
||||
break;
|
||||
@@ -3991,8 +4005,10 @@ static int ipa3_assign_policy(struct ipa_sys_connect_params *in,
|
||||
in->ipa_ep_cfg.aggr.aggr = IPA_COALESCE;
|
||||
else
|
||||
in->ipa_ep_cfg.aggr.aggr = IPA_GENERIC;
|
||||
in->ipa_ep_cfg.aggr.aggr_time_limit =
|
||||
IPA_GENERIC_AGGR_TIME_LIMIT;
|
||||
if (in->client == IPA_CLIENT_APPS_LAN_CONS ||
|
||||
!in->ext_ioctl_v2)
|
||||
in->ipa_ep_cfg.aggr.aggr_time_limit =
|
||||
IPA_GENERIC_AGGR_TIME_LIMIT;
|
||||
if (in->client == IPA_CLIENT_APPS_LAN_CONS) {
|
||||
INIT_WORK(&sys->repl_work, ipa3_wq_repl_rx);
|
||||
sys->pyld_hdlr = ipa3_lan_rx_pyld_hdlr;
|
||||
@@ -4052,8 +4068,6 @@ static int ipa3_assign_policy(struct ipa_sys_connect_params *in,
|
||||
IPA_CLIENT_APPS_WAN_LOW_LAT_CONS) {
|
||||
INIT_WORK(&sys->repl_work, ipa3_wq_repl_rx);
|
||||
sys->ep->status.status_en = false;
|
||||
in->ipa_ep_cfg.aggr.aggr_en = IPA_BYPASS_AGGR;
|
||||
in->ipa_ep_cfg.aggr.aggr_time_limit = 0;
|
||||
sys->rx_buff_sz = IPA_GENERIC_RX_BUFF_SZ(
|
||||
IPA_QMAP_RX_BUFF_BASE_SZ);
|
||||
sys->pyld_hdlr = ipa3_low_lat_rx_pyld_hdlr;
|
||||
@@ -4895,6 +4909,16 @@ static int ipa_gsi_setup_event_ring(struct ipa3_ep_context *ep,
|
||||
gsi_evt_ring_props.int_modc = 1;
|
||||
}
|
||||
|
||||
if (ep->sys->ext_ioctl_v2 &&
|
||||
((ep->client == IPA_CLIENT_APPS_WAN_PROD) ||
|
||||
(ep->client == IPA_CLIENT_APPS_WAN_CONS) ||
|
||||
(ep->client == IPA_CLIENT_APPS_WAN_COAL_CONS) ||
|
||||
(ep->client == IPA_CLIENT_APPS_WAN_LOW_LAT_PROD) ||
|
||||
(ep->client == IPA_CLIENT_APPS_WAN_LOW_LAT_CONS))) {
|
||||
gsi_evt_ring_props.int_modt = ep->sys->int_modt;
|
||||
gsi_evt_ring_props.int_modc = ep->sys->int_modc;
|
||||
}
|
||||
|
||||
IPADBG("client=%d moderation threshold cycles=%u cnt=%u\n",
|
||||
ep->client,
|
||||
gsi_evt_ring_props.int_modt,
|
||||
|
@@ -1062,6 +1062,10 @@ struct ipa3_repl_ctx {
|
||||
* @napi_tx: napi for eot write done handle (tx_complete) - to replace tasklet
|
||||
* @in_napi_context: an atomic variable used for non-blocking locking,
|
||||
* preventing from multiple napi_sched to be called.
|
||||
* @int_modt: GSI event ring interrupt moderation timer
|
||||
* @int_modc: GSI event ring interrupt moderation counter
|
||||
* @buff_size: rx packet length
|
||||
* @ext_ioctl_v2: specifies if it's new version of ingress/egress ioctl
|
||||
*
|
||||
* IPA context specific to the GPI pipes a.k.a LAN IN/OUT and WAN
|
||||
*/
|
||||
@@ -1099,6 +1103,10 @@ struct ipa3_sys_context {
|
||||
u32 eob_drop_cnt;
|
||||
struct napi_struct napi_tx;
|
||||
atomic_t in_napi_context;
|
||||
u32 int_modt;
|
||||
u32 int_modc;
|
||||
u32 buff_size;
|
||||
bool ext_ioctl_v2;
|
||||
|
||||
/* ordering is important - mutable fields go above */
|
||||
struct ipa3_ep_context *ep;
|
||||
@@ -3147,8 +3155,10 @@ int ipa3_register_rmnet_ctl_cb(
|
||||
void *user_data3);
|
||||
int ipa3_unregister_rmnet_ctl_cb(void);
|
||||
int ipa3_rmnet_ctl_xmit(struct sk_buff *skb);
|
||||
int ipa3_setup_apps_low_lat_prod_pipe(void);
|
||||
int ipa3_setup_apps_low_lat_cons_pipe(void);
|
||||
int ipa3_setup_apps_low_lat_prod_pipe(bool rmnet_config,
|
||||
struct rmnet_egress_param *egress_param);
|
||||
int ipa3_setup_apps_low_lat_cons_pipe(bool rmnet_config,
|
||||
struct rmnet_ingress_param *ingress_param);
|
||||
int ipa3_teardown_apps_low_lat_pipes(void);
|
||||
const char *ipa_hw_error_str(enum ipa3_hw_errors err_type);
|
||||
int ipa_gsi_ch20_wa(void);
|
||||
|
@@ -210,7 +210,8 @@ int ipa3_unregister_rmnet_ctl_cb(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipa3_setup_apps_low_lat_cons_pipe(void)
|
||||
int ipa3_setup_apps_low_lat_cons_pipe(bool rmnet_config,
|
||||
struct rmnet_ingress_param *ingress_param)
|
||||
{
|
||||
struct ipa_sys_connect_params *ipa_low_lat_ep_cfg;
|
||||
int ret = 0;
|
||||
@@ -234,12 +235,40 @@ int ipa3_setup_apps_low_lat_cons_pipe(void)
|
||||
}
|
||||
ipa_low_lat_ep_cfg =
|
||||
&rmnet_ctl_ipa3_ctx->ipa_to_apps_low_lat_ep_cfg;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_ENABLE_CS_DL_QMAP;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_byte_limit =
|
||||
0;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_pkt_limit =
|
||||
0;
|
||||
/*
|
||||
* Removing bypass aggr from assign_policy
|
||||
* and placing it here for future enablement
|
||||
*/
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_en = IPA_BYPASS_AGGR;
|
||||
if (rmnet_config && ingress_param) {
|
||||
/* Open for future cs offload disablement on low lat pipe */
|
||||
if (ingress_param->cs_offload_en) {
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_ENABLE_CS_DL_QMAP;
|
||||
} else {
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_DISABLE_CS_OFFLOAD;
|
||||
}
|
||||
ipa_low_lat_ep_cfg->ext_ioctl_v2 = true;
|
||||
ipa_low_lat_ep_cfg->int_modt = ingress_param->int_modt;
|
||||
ipa_low_lat_ep_cfg->int_modc = ingress_param->int_modc;
|
||||
ipa_low_lat_ep_cfg->buff_size = ingress_param->buff_size;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_byte_limit =
|
||||
ingress_param->agg_byte_limit;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_pkt_limit =
|
||||
ingress_param->agg_pkt_limit;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_time_limit =
|
||||
ingress_param->agg_time_limit;
|
||||
} else {
|
||||
ipa_low_lat_ep_cfg->ext_ioctl_v2 = false;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_ENABLE_CS_DL_QMAP;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_byte_limit =
|
||||
0;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_pkt_limit =
|
||||
0;
|
||||
}
|
||||
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 8;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid
|
||||
= 1;
|
||||
@@ -295,7 +324,8 @@ int ipa3_setup_apps_low_lat_cons_pipe(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipa3_setup_apps_low_lat_prod_pipe(void)
|
||||
int ipa3_setup_apps_low_lat_prod_pipe(bool rmnet_config,
|
||||
struct rmnet_egress_param *egress_param)
|
||||
{
|
||||
struct ipa_sys_connect_params *ipa_low_lat_ep_cfg;
|
||||
int ret = 0;
|
||||
@@ -313,16 +343,47 @@ int ipa3_setup_apps_low_lat_prod_pipe(void)
|
||||
}
|
||||
ipa_low_lat_ep_cfg =
|
||||
&rmnet_ctl_ipa3_ctx->apps_to_ipa_low_lat_ep_cfg;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 8;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_ENABLE_CS_OFFLOAD_UL;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_metadata_hdr_offset
|
||||
= 1;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_en =
|
||||
IPA_BYPASS_AGGR;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1;
|
||||
/* modem want offset at 0! */
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata = 0;
|
||||
if (rmnet_config && egress_param) {
|
||||
/* Open for future cs offload disablement on low lat pipe */
|
||||
IPAERR("Configuring low lat prod with rmnet config\n");
|
||||
ipa_low_lat_ep_cfg->ext_ioctl_v2 = true;
|
||||
ipa_low_lat_ep_cfg->int_modt = egress_param->int_modt;
|
||||
ipa_low_lat_ep_cfg->int_modc = egress_param->int_modc;
|
||||
if (egress_param->cs_offload_en) {
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 8;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_ENABLE_CS_OFFLOAD_UL;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_metadata_hdr_offset
|
||||
= 1;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid
|
||||
= 1;
|
||||
/* modem want offset at 0! */
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata = 0;
|
||||
} else {
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_DISABLE_CS_OFFLOAD;
|
||||
}
|
||||
|
||||
/* Open for future deaggr enablement on low lat pipe */
|
||||
if (!egress_param->aggr_en) {
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_en =
|
||||
IPA_BYPASS_AGGR;
|
||||
}
|
||||
} else {
|
||||
IPAERR("Configuring low lat prod without rmnet config\n");
|
||||
ipa_low_lat_ep_cfg->ext_ioctl_v2 = false;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 8;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_ENABLE_CS_OFFLOAD_UL;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.aggr.aggr_en =
|
||||
IPA_BYPASS_AGGR;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.cfg.cs_metadata_hdr_offset
|
||||
= 1;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid
|
||||
= 1;
|
||||
/* modem want offset at 0! */
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata = 0;
|
||||
}
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.mode.dst =
|
||||
IPA_CLIENT_Q6_WAN_CONS;
|
||||
ipa_low_lat_ep_cfg->ipa_ep_cfg.mode.mode =
|
||||
|
@@ -182,6 +182,16 @@ static struct rmnet_ipa3_context *rmnet_ipa3_ctx;
|
||||
static struct ipa3_rmnet_plat_drv_res ipa3_rmnet_res;
|
||||
bool ipa_net_initialized = false;
|
||||
|
||||
struct rmnet_ipa_pipe_setup_status {
|
||||
int ep_type;
|
||||
int status;
|
||||
};
|
||||
|
||||
static struct rmnet_ipa_pipe_setup_status egress_pipe_status[
|
||||
RMNET_EGRESS_MAX];
|
||||
static struct rmnet_ipa_pipe_setup_status ingress_pipe_status[
|
||||
RMNET_INGRESS_MAX];
|
||||
|
||||
/**
|
||||
* ipa3_setup_a7_qmap_hdr() - Setup default a7 qmap hdr
|
||||
*
|
||||
@@ -1511,6 +1521,7 @@ static int handle3_ingress_format(struct net_device *dev,
|
||||
struct ipa_sys_connect_params *ipa_wan_ep_cfg;
|
||||
int ep_idx;
|
||||
int ingress_eps_mask = IPA_AP_INGRESS_NONE;
|
||||
bool rmnet_config;
|
||||
|
||||
IPAWANDBG("Get RMNET_IOCTL_SET_INGRESS_DATA_FORMAT\n");
|
||||
|
||||
@@ -1577,6 +1588,7 @@ static int handle3_ingress_format(struct net_device *dev,
|
||||
ipa_wan_ep_cfg->client = IPA_CLIENT_APPS_WAN_COAL_CONS;
|
||||
ingress_eps_mask |= IPA_AP_INGRESS_EP_COALS;
|
||||
}
|
||||
ipa_wan_ep_cfg->ext_ioctl_v2 = false;
|
||||
|
||||
ipa_wan_ep_cfg->notify = apps_ipa_packet_receive_notify;
|
||||
ipa_wan_ep_cfg->priv = dev;
|
||||
@@ -1603,7 +1615,8 @@ static int handle3_ingress_format(struct net_device *dev,
|
||||
IPAWANDBG("ingress WAN pipe setup successfully\n");
|
||||
|
||||
if (ipa3_ctx->rmnet_ctl_enable) {
|
||||
ret = ipa3_setup_apps_low_lat_cons_pipe();
|
||||
rmnet_config = false;
|
||||
ret = ipa3_setup_apps_low_lat_cons_pipe(rmnet_config, NULL);
|
||||
if (ret)
|
||||
goto low_lat_fail;
|
||||
ingress_eps_mask |= IPA_AP_INGRESS_EP_LOW_LAT;
|
||||
@@ -1644,6 +1657,7 @@ static int handle3_egress_format(struct net_device *dev,
|
||||
int rc;
|
||||
struct ipa_sys_connect_params *ipa_wan_ep_cfg;
|
||||
int ep_idx;
|
||||
bool rmnet_config;
|
||||
|
||||
IPAWANDBG("get RMNET_IOCTL_SET_EGRESS_DATA_FORMAT %x\n", e->u.data);
|
||||
/*
|
||||
@@ -1713,6 +1727,7 @@ static int handle3_egress_format(struct net_device *dev,
|
||||
ipa_wan_ep_cfg->notify = apps_ipa_tx_complete_notify;
|
||||
ipa_wan_ep_cfg->desc_fifo_sz = IPA_SYS_TX_DATA_DESC_FIFO_SZ;
|
||||
ipa_wan_ep_cfg->priv = dev;
|
||||
ipa_wan_ep_cfg->ext_ioctl_v2 = false;
|
||||
|
||||
mutex_lock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
|
||||
@@ -1729,7 +1744,8 @@ static int handle3_egress_format(struct net_device *dev,
|
||||
}
|
||||
IPAWANDBG("engress WAN pipe setup successfully\n");
|
||||
if (ipa3_ctx->rmnet_ctl_enable) {
|
||||
rc = ipa3_setup_apps_low_lat_prod_pipe();
|
||||
rmnet_config = false;
|
||||
rc = ipa3_setup_apps_low_lat_prod_pipe(rmnet_config, NULL);
|
||||
if (rc) {
|
||||
IPAWANERR("failed to setup egress low lat endpoint\n");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
@@ -1762,6 +1778,538 @@ low_lat_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa3_setup_apps_wan_cons_pipes() - wan/coal pipe config
|
||||
*
|
||||
* Setup IPA Ingress wan pipes and Configure them:
|
||||
*/
|
||||
static int ipa3_setup_apps_wan_cons_pipes(
|
||||
struct rmnet_ingress_param *ingress_param,
|
||||
struct rmnet_ipa_pipe_setup_status *pipe_status,
|
||||
int *ingress_eps_mask,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct ipa_sys_connect_params *ipa_wan_ep_cfg;
|
||||
int ep_idx, coal_ep_idx;
|
||||
int rc = 0;
|
||||
|
||||
if (ingress_param->pipe_setup_status == IPA_PIPE_SETUP_EXISTS)
|
||||
return rc;
|
||||
|
||||
coal_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS);
|
||||
ep_idx = ipa_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS);
|
||||
if (ep_idx == IPA_EP_NOT_ALLOCATED) {
|
||||
IPAWANERR("Embedded datapath not supported\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
ipa_wan_ep_cfg = &rmnet_ipa3_ctx->ipa_to_apps_ep_cfg;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
|
||||
IPA_ENABLE_CS_DL_QMAP;
|
||||
|
||||
if (!ipa3_disable_apps_wan_cons_deaggr(
|
||||
ingress_param->agg_byte_limit,
|
||||
ingress_param->agg_pkt_limit)) {
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_byte_limit =
|
||||
ingress_param->agg_byte_limit;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_pkt_limit =
|
||||
ingress_param->agg_pkt_limit;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_time_limit =
|
||||
ingress_param->agg_time_limit;
|
||||
}
|
||||
|
||||
if (ingress_param->cs_offload_en) {
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 8;
|
||||
rmnet_ipa3_ctx->dl_csum_offload_enabled = true;
|
||||
} else {
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 4;
|
||||
rmnet_ipa3_ctx->dl_csum_offload_enabled = false;
|
||||
}
|
||||
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata = 1;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 2;
|
||||
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad_valid
|
||||
= true;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad
|
||||
= 0;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_payload_len_inc_padding
|
||||
= true;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad_offset
|
||||
= 0;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_little_endian
|
||||
= 0;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.metadata_mask.metadata_mask
|
||||
= 0xFF000000;
|
||||
|
||||
if (ingress_param->ingress_ep_type == RMNET_INGRESS_DEFAULT) {
|
||||
/* Reject the whole ioctl if coal pipe is not setup first */
|
||||
if (dev->features & NETIF_F_GRO_HW) {
|
||||
if (coal_ep_idx == IPA_EP_NOT_ALLOCATED) {
|
||||
IPAWANERR("Trying to setup def WAN before coals");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
return -EFAULT;
|
||||
}
|
||||
else if (!ipa3_ctx->ep[coal_ep_idx].valid) {
|
||||
IPAWANERR("Trying to setup def WAN before coals.");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup default pipe */
|
||||
IPAWANDBG("Setting up default pipe\n");
|
||||
ipa_wan_ep_cfg->client = IPA_CLIENT_APPS_WAN_CONS;
|
||||
pipe_status->ep_type = RMNET_INGRESS_DEFAULT;
|
||||
*ingress_eps_mask |= IPA_AP_INGRESS_EP_DEFAULT;
|
||||
} else if (ingress_param->ingress_ep_type ==
|
||||
RMNET_INGRESS_COALS && (dev->features & NETIF_F_GRO_HW)) {
|
||||
/* Setup coalescing pipes */
|
||||
IPAWANDBG("Setting up coalescing pipe\n");
|
||||
ipa_wan_ep_cfg->client = IPA_CLIENT_APPS_WAN_COAL_CONS;
|
||||
pipe_status->ep_type = RMNET_INGRESS_COALS;
|
||||
*ingress_eps_mask |= IPA_AP_INGRESS_EP_COALS;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
|
||||
ipa_wan_ep_cfg->notify = apps_ipa_packet_receive_notify;
|
||||
ipa_wan_ep_cfg->priv = dev;
|
||||
|
||||
if (ipa3_rmnet_res.ipa_napi_enable)
|
||||
ipa_wan_ep_cfg->napi_obj = &(rmnet_ipa3_ctx->wwan_priv->napi);
|
||||
ipa_wan_ep_cfg->desc_fifo_sz =
|
||||
ipa3_rmnet_res.wan_rx_desc_size * IPA_FIFO_ELEMENT_SIZE;
|
||||
|
||||
if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
|
||||
IPAWANERR("In SSR sequence/recovery\n");
|
||||
return rc;
|
||||
}
|
||||
ipa_wan_ep_cfg->ext_ioctl_v2 = true;
|
||||
ipa_wan_ep_cfg->int_modt = ingress_param->int_modt;
|
||||
ipa_wan_ep_cfg->int_modc = ingress_param->int_modc;
|
||||
ipa_wan_ep_cfg->buff_size = ingress_param->buff_size;
|
||||
|
||||
rc = ipa_setup_sys_pipe(&rmnet_ipa3_ctx->ipa_to_apps_ep_cfg,
|
||||
&rmnet_ipa3_ctx->ipa3_to_apps_hdl);
|
||||
|
||||
if (rc) {
|
||||
pipe_status->status = IPA_PIPE_SETUP_FAILURE;
|
||||
IPAWANERR("failed to setup default/coal pipe rc = %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
IPAWANDBG("Ingress default/coal pipe setup successfully\n");
|
||||
|
||||
ingress_param->pipe_setup_status = IPA_PIPE_SETUP_SUCCESS;
|
||||
/* caching the success status of the pipe */
|
||||
pipe_status->status = IPA_PIPE_SETUP_EXISTS;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle3_ingress_format_v2() - Ingress data format configuration
|
||||
*
|
||||
* Setup IPA Ingress system pipes and Configure them:
|
||||
*
|
||||
* @dev: network device
|
||||
* @ioctl_ptr: Pointer to ingress pipes' config info
|
||||
*/
|
||||
static int handle3_ingress_format_v2(struct net_device *dev,
|
||||
__u64 ioctl_ptr)
|
||||
{
|
||||
struct ingress_format_v2 ingress_ioctl_v2_data;
|
||||
struct rmnet_ingress_param ingress_param[RMNET_INGRESS_MAX];
|
||||
int ingress_eps_mask = IPA_AP_INGRESS_NONE;
|
||||
int i, j;
|
||||
bool rmnet_config;
|
||||
int rc = 0;
|
||||
|
||||
if(copy_from_user(&ingress_ioctl_v2_data, u64_to_user_ptr(ioctl_ptr),
|
||||
sizeof(struct ingress_format_v2))) {
|
||||
IPAWANERR("failed to copy ingress extended ioctl v2 data\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if(ingress_ioctl_v2_data.number_of_eps >
|
||||
RMNET_INGRESS_MAX) {
|
||||
IPAWANERR("Ingress pipe count mismatch\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if(ingress_ioctl_v2_data.ingress_param_size !=
|
||||
sizeof(struct rmnet_ingress_param)) {
|
||||
IPAWANERR("Ingress pipe param size mismatch\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if(copy_from_user(&ingress_param, u64_to_user_ptr(
|
||||
ingress_ioctl_v2_data.ingress_param_ptr),
|
||||
sizeof(struct rmnet_ingress_param) *
|
||||
ingress_ioctl_v2_data.number_of_eps)) {
|
||||
IPAWANERR("Failed to copy all ingress pipes' params\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
IPAWANDBG("ingress_ioctl_v2_data.number_of_eps = %d\n",
|
||||
ingress_ioctl_v2_data.number_of_eps);
|
||||
|
||||
mutex_lock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
|
||||
for (i = 0; i < ingress_ioctl_v2_data.number_of_eps; i++) {
|
||||
ingress_param[i].pipe_setup_status = IPA_PIPE_SETUP_FAILURE;
|
||||
IPAWANDBG("pipe ep_type = %d cs_offload_en = %d buff_size =%d\n",
|
||||
ingress_param[i].ingress_ep_type,
|
||||
ingress_param[i].cs_offload_en,
|
||||
ingress_param[i].buff_size);
|
||||
IPAWANDBG("agg_limit byte =%d time =%d pkt =%d\n",
|
||||
ingress_param[i].agg_byte_limit,
|
||||
ingress_param[i].agg_time_limit,
|
||||
ingress_param[i].agg_pkt_limit);
|
||||
IPAWANDBG("int_modt = %d int_modc = %d\n",
|
||||
ingress_param[i].int_modt, ingress_param[i].int_modc);
|
||||
if (ingress_param[i].ingress_ep_type == RMNET_INGRESS_DEFAULT ||
|
||||
ingress_param[i].ingress_ep_type == RMNET_INGRESS_COALS) {
|
||||
|
||||
memset(&rmnet_ipa3_ctx->ipa_to_apps_ep_cfg, 0,
|
||||
sizeof(struct ipa_sys_connect_params));
|
||||
|
||||
/* Searching through the static table, if pipe exists already */
|
||||
for (j = 0; j < RMNET_INGRESS_MAX; j++) {
|
||||
if (ingress_param[i].ingress_ep_type ==
|
||||
RMNET_INGRESS_DEFAULT &&
|
||||
ingress_pipe_status[j].ep_type ==
|
||||
RMNET_INGRESS_DEFAULT &&
|
||||
ingress_pipe_status[j].status == IPA_PIPE_SETUP_EXISTS) {
|
||||
ingress_param[i].pipe_setup_status =
|
||||
IPA_PIPE_SETUP_EXISTS;
|
||||
IPAWANERR("Receiving ingress wan default ioctl again\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Searching through the static table, if pipe exists already */
|
||||
for (j = 0; j < RMNET_INGRESS_MAX; j++) {
|
||||
if (ingress_param[i].ingress_ep_type == RMNET_INGRESS_COALS &&
|
||||
ingress_pipe_status[j].ep_type == RMNET_INGRESS_COALS &&
|
||||
ingress_pipe_status[j].status == IPA_PIPE_SETUP_EXISTS) {
|
||||
ingress_param[i].pipe_setup_status =
|
||||
IPA_PIPE_SETUP_EXISTS;
|
||||
IPAWANERR("Receiving ingress coal ioctl again\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ipa3_setup_apps_wan_cons_pipes(&ingress_param[i],
|
||||
&ingress_pipe_status[i],
|
||||
&ingress_eps_mask,
|
||||
dev);
|
||||
|
||||
if (rc == -EFAULT) {
|
||||
IPAWANERR("Failed to setup wan/coal cons pipes\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
} else if (ingress_param[i].ingress_ep_type ==
|
||||
RMNET_INGRESS_LOW_LAT_CTRL) {
|
||||
/* Searching through the static table, if pipe exists already */
|
||||
for (j = 0; j < RMNET_INGRESS_MAX; j++) {
|
||||
if (ingress_pipe_status[j].ep_type ==
|
||||
RMNET_INGRESS_LOW_LAT_CTRL &&
|
||||
ingress_pipe_status[j].status == IPA_PIPE_SETUP_EXISTS) {
|
||||
ingress_param[i].pipe_setup_status
|
||||
= IPA_PIPE_SETUP_EXISTS;
|
||||
IPAWANERR("Receiving ingress low lat ctrl ioctl again");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ipa3_ctx->rmnet_ctl_enable &&
|
||||
(ingress_param[i].pipe_setup_status == IPA_PIPE_SETUP_EXISTS))
|
||||
continue;
|
||||
|
||||
ingress_pipe_status[i].ep_type = RMNET_INGRESS_LOW_LAT_CTRL;
|
||||
rmnet_config = true;
|
||||
rc = ipa3_setup_apps_low_lat_cons_pipe(rmnet_config,
|
||||
&ingress_param[i]);
|
||||
if (rc) {
|
||||
IPAWANERR("failed to setup ingress low lat endpoint\n");
|
||||
ingress_pipe_status[i].status = IPA_PIPE_SETUP_FAILURE;
|
||||
continue;
|
||||
}
|
||||
ingress_eps_mask |= IPA_AP_INGRESS_EP_LOW_LAT;
|
||||
IPAWANDBG("Ingress LOW LAT CTRL pipe setup successfully\n");
|
||||
ingress_param[i].pipe_setup_status = IPA_PIPE_SETUP_SUCCESS;
|
||||
/* caching the success status of the pipe */
|
||||
ingress_pipe_status[i].status = IPA_PIPE_SETUP_EXISTS;
|
||||
|
||||
} else if (ingress_param[i].ingress_ep_type ==
|
||||
RMNET_INGRESS_LOW_LAT_DATA) {
|
||||
IPAWANERR("Ingress Low lat data pipe is not defined\n");
|
||||
continue;
|
||||
} else {
|
||||
IPAWANERR("Ingress ep_type not defined\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(copy_to_user(u64_to_user_ptr(ingress_ioctl_v2_data.ingress_param_ptr),
|
||||
&ingress_param,
|
||||
sizeof(struct rmnet_ingress_param) *
|
||||
ingress_ioctl_v2_data.number_of_eps)) {
|
||||
IPAWANERR("Ingress copy to user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
|
||||
/* construct default WAN RT tbl for IPACM */
|
||||
rc = ipa3_setup_a7_qmap_hdr();
|
||||
if (rc) {
|
||||
IPAWANERR("A7 QMAP header setup failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
rc = ipa3_setup_dflt_wan_rt_tables();
|
||||
if (rc)
|
||||
ipa3_del_a7_qmap_hdr();
|
||||
|
||||
/* Sending QMI indication message share RSC/QMAP pipe details*/
|
||||
ipa_send_wan_pipe_ind_to_modem(ingress_eps_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa3_setup_apps_wan_prod_pipes() - wan prod pipe config
|
||||
*
|
||||
* Setup IPA egress wan pipes and Configure them:
|
||||
*/
|
||||
static int ipa3_setup_apps_wan_prod_pipes(
|
||||
struct rmnet_egress_param *egress_param,
|
||||
struct rmnet_ipa_pipe_setup_status *pipe_status,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct ipa_sys_connect_params *ipa_wan_ep_cfg;
|
||||
int ep_idx;
|
||||
int rc = 0;
|
||||
|
||||
if(egress_param->pipe_setup_status == IPA_PIPE_SETUP_EXISTS)
|
||||
return rc;
|
||||
|
||||
ep_idx = ipa_get_ep_mapping(IPA_CLIENT_APPS_WAN_PROD);
|
||||
if (ep_idx == IPA_EP_NOT_ALLOCATED) {
|
||||
IPAWANERR("Embedded datapath not supported\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
ipa_wan_ep_cfg = &rmnet_ipa3_ctx->apps_to_ipa_ep_cfg;
|
||||
if (egress_param->cs_offload_en) {
|
||||
IPAWANDBG("UL Chksum set\n");
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 8;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en
|
||||
= IPA_ENABLE_CS_OFFLOAD_UL;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.cfg.cs_metadata_hdr_offset
|
||||
= 1;
|
||||
} else {
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 4;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en
|
||||
= IPA_DISABLE_CS_OFFLOAD;
|
||||
}
|
||||
|
||||
if (egress_param->aggr_en) {
|
||||
IPAWANDBG("WAN UL Aggr enabled\n");
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_en = IPA_ENABLE_DEAGGR;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr = IPA_QCMAP;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.deaggr.packet_offset_valid = false;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 2;
|
||||
ipa_wan_ep_cfg->
|
||||
ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad_valid = true;
|
||||
ipa_wan_ep_cfg->
|
||||
ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad = IPA_HDR_PAD;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_pad_to_alignment = 2;
|
||||
ipa_wan_ep_cfg->
|
||||
ipa_ep_cfg.hdr_ext.hdr_payload_len_inc_padding = true;
|
||||
ipa_wan_ep_cfg->
|
||||
ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad_offset = 0;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_little_endian = false;
|
||||
} else {
|
||||
IPAWANERR("WAN UL Aggregation disabled\n");
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_en = IPA_BYPASS_AGGR;
|
||||
}
|
||||
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1;
|
||||
/* modem want offset at 0! */
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata = 0;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.mode.dst = IPA_CLIENT_APPS_WAN_PROD;
|
||||
ipa_wan_ep_cfg->ipa_ep_cfg.mode.mode = IPA_BASIC;
|
||||
ipa_wan_ep_cfg->client = IPA_CLIENT_APPS_WAN_PROD;
|
||||
ipa_wan_ep_cfg->notify = apps_ipa_tx_complete_notify;
|
||||
ipa_wan_ep_cfg->desc_fifo_sz = IPA_SYS_TX_DATA_DESC_FIFO_SZ;
|
||||
ipa_wan_ep_cfg->priv = dev;
|
||||
|
||||
ipa_wan_ep_cfg->ext_ioctl_v2 = true;
|
||||
ipa_wan_ep_cfg->int_modt = egress_param->int_modt;
|
||||
ipa_wan_ep_cfg->int_modc = egress_param->int_modc;
|
||||
if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
|
||||
IPAWANERR("In SSR sequence/recovery\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
pipe_status->ep_type = RMNET_EGRESS_DEFAULT;
|
||||
|
||||
rc = ipa_setup_sys_pipe(
|
||||
ipa_wan_ep_cfg, &rmnet_ipa3_ctx->apps_to_ipa3_hdl);
|
||||
|
||||
if (rc) {
|
||||
IPAWANERR("failed to setup egress default pipe\n");
|
||||
pipe_status->status = IPA_PIPE_SETUP_FAILURE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
IPAWANDBG("Egress WAN pipe setup successful\n");
|
||||
egress_param->pipe_setup_status = IPA_PIPE_SETUP_SUCCESS;
|
||||
/* caching the success status of the pipe */
|
||||
pipe_status->status = IPA_PIPE_SETUP_EXISTS;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle3_egress_format_v2() - Egress data format configuration
|
||||
*
|
||||
* Setup IPA egress system pipes and Configure them:
|
||||
*
|
||||
* @dev: network device
|
||||
* @ioctl_ptr: Pointer to egress pipes' config info
|
||||
*/
|
||||
static int handle3_egress_format_v2(struct net_device *dev,
|
||||
__u64 ioctl_ptr)
|
||||
{
|
||||
struct egress_format_v2 egress_ioctl_v2_data;
|
||||
struct rmnet_egress_param egress_param[RMNET_EGRESS_MAX];
|
||||
int i, j;
|
||||
int rc = 0;
|
||||
bool rmnet_config;
|
||||
|
||||
if(copy_from_user(&egress_ioctl_v2_data, u64_to_user_ptr(ioctl_ptr),
|
||||
sizeof(struct egress_format_v2))) {
|
||||
IPAWANERR("failed to copy egress extended ioctl v2 data\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if(egress_ioctl_v2_data.number_of_eps >
|
||||
RMNET_EGRESS_MAX) {
|
||||
IPAWANERR("Egress pipe count mismatch = %d\n",
|
||||
egress_ioctl_v2_data.number_of_eps);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if(egress_ioctl_v2_data.egress_param_size !=
|
||||
sizeof(struct rmnet_egress_param)) {
|
||||
IPAWANERR("Egress pipe param size mismatch\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if(copy_from_user(&egress_param, u64_to_user_ptr(
|
||||
egress_ioctl_v2_data.egress_param_ptr),
|
||||
sizeof(struct rmnet_egress_param) *
|
||||
egress_ioctl_v2_data.number_of_eps)) {
|
||||
IPAWANERR("Failed to copy all egress pipes' params\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
IPAWANDBG("egress_ioctl_v2_data.number_of_eps = %d\n",
|
||||
egress_ioctl_v2_data.number_of_eps);
|
||||
|
||||
mutex_lock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
|
||||
for (i = 0; i < egress_ioctl_v2_data.number_of_eps; i++) {
|
||||
egress_param[i].pipe_setup_status = IPA_PIPE_SETUP_FAILURE;
|
||||
IPAWANDBG("cs_offload_en = %d, aggr_en = %d, ulso_en = %d\n",
|
||||
egress_param[i].cs_offload_en,
|
||||
egress_param[i].aggr_en,
|
||||
egress_param[i].ulso_en);
|
||||
IPAWANDBG("ipid_min_max_idx = %d, int_modt = %d, int_modc = %d\n",
|
||||
egress_param[i].ipid_min_max_idx,
|
||||
egress_param[i].int_modt,
|
||||
egress_param[i].int_modc);
|
||||
if (egress_param[i].egress_ep_type == RMNET_EGRESS_DEFAULT) {
|
||||
/* Searching through the static table, if pipe exists already */
|
||||
for (j = 0; j < RMNET_EGRESS_MAX; j++) {
|
||||
if (egress_pipe_status[j].ep_type == RMNET_EGRESS_DEFAULT &&
|
||||
egress_pipe_status[j].status == IPA_PIPE_SETUP_EXISTS) {
|
||||
IPAWANERR("Receiving egress default ioctl again");
|
||||
egress_param[i].pipe_setup_status = IPA_PIPE_SETUP_EXISTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ipa3_setup_apps_wan_prod_pipes(&egress_param[i],
|
||||
&egress_pipe_status[i],
|
||||
dev);
|
||||
|
||||
if (rc == -EFAULT) {
|
||||
IPAWANERR("Failed to setup wan prod pipes\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
} else if (egress_param[i].egress_ep_type ==
|
||||
RMNET_EGRESS_LOW_LAT_CTRL) {
|
||||
/* Searching through the static table, if pipe exists already */
|
||||
for (j = 0; j < RMNET_EGRESS_MAX; j++) {
|
||||
if (egress_pipe_status[j].ep_type ==
|
||||
RMNET_EGRESS_LOW_LAT_CTRL &&
|
||||
egress_pipe_status[j].status == IPA_PIPE_SETUP_EXISTS) {
|
||||
egress_param[i].pipe_setup_status = IPA_PIPE_SETUP_EXISTS;
|
||||
IPAWANERR("Receiving egress low lat ioctl again");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ipa3_ctx->rmnet_ctl_enable &&
|
||||
(egress_param[i].pipe_setup_status == IPA_PIPE_SETUP_EXISTS))
|
||||
continue;
|
||||
|
||||
egress_pipe_status[i].ep_type = RMNET_EGRESS_LOW_LAT_CTRL;
|
||||
|
||||
rmnet_config = true;
|
||||
rc = ipa3_setup_apps_low_lat_prod_pipe(
|
||||
rmnet_config, &egress_param[i]);
|
||||
if (rc) {
|
||||
IPAWANERR("failed to setup egress low lat endpoint\n");
|
||||
egress_pipe_status[i].status = IPA_PIPE_SETUP_FAILURE;
|
||||
continue;
|
||||
}
|
||||
IPAWANDBG("Egress LOW LAT CTRL pipe setup successfully\n");
|
||||
egress_param[i].pipe_setup_status = IPA_PIPE_SETUP_SUCCESS;
|
||||
/* caching the success status of the pipe */
|
||||
egress_pipe_status[i].status = IPA_PIPE_SETUP_EXISTS;
|
||||
|
||||
} else if (egress_param[i].egress_ep_type ==
|
||||
RMNET_EGRESS_LOW_LAT_DATA) {
|
||||
IPAWANERR("Egress Low lat data pipe is not defined yet\n");
|
||||
continue;
|
||||
} else {
|
||||
IPAWANERR("Egress ep type not defined");
|
||||
}
|
||||
}
|
||||
|
||||
if(copy_to_user(u64_to_user_ptr(egress_ioctl_v2_data.egress_param_ptr),
|
||||
&egress_param,
|
||||
sizeof(struct rmnet_egress_param) * egress_ioctl_v2_data.number_of_eps)) {
|
||||
IPAWANERR("Egress copy to user failed\n");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
return -EFAULT;
|
||||
}
|
||||
mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
rmnet_ipa3_ctx->egress_set = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa3_wwan_ioctl() - I/O control for wwan network driver.
|
||||
*
|
||||
@@ -1784,6 +2332,7 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
struct ipa_msg_meta msg_meta;
|
||||
struct ipa_wan_msg *wan_msg = NULL;
|
||||
struct rmnet_ioctl_extended_s ext_ioctl_data;
|
||||
struct rmnet_ioctl_extended_s_v2 ext_ioctl_v2_data;
|
||||
struct rmnet_ioctl_data_s ioctl_data;
|
||||
struct ipa3_rmnet_mux_val *mux_channel;
|
||||
int rmnet_index;
|
||||
@@ -2129,6 +2678,43 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
rc = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case RMNET_IOCTL_EXTENDED_V2:
|
||||
IPAWANDBG("RMNET_IOCTL_EXTENDED_V2 received\n");
|
||||
if (copy_from_user(&ext_ioctl_v2_data,
|
||||
(u8 *)ifr->ifr_ifru.ifru_data,
|
||||
sizeof(struct rmnet_ioctl_extended_s_v2))) {
|
||||
IPAWANERR("failed to copy extended ioctl data\n");
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
switch (ext_ioctl_v2_data.extended_v2_ioctl_type) {
|
||||
case RMNET_IOCTL_SET_EGRESS_DATA_FORMAT_V2:
|
||||
if (ext_ioctl_v2_data.ioctl_data_size !=
|
||||
sizeof(struct egress_format_v2)) {
|
||||
IPAWANERR("Egress ioctl v2 format size mismatch\n");
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
rc = handle3_egress_format_v2(dev,
|
||||
ext_ioctl_v2_data.ioctl_ptr);
|
||||
break;
|
||||
case RMNET_IOCTL_SET_INGRESS_DATA_FORMAT_V2:
|
||||
if (ext_ioctl_v2_data.ioctl_data_size !=
|
||||
sizeof(struct ingress_format_v2)) {
|
||||
IPAWANERR("ingress ioctl v2 format size mismatch\n");
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
rc = handle3_ingress_format_v2(dev,
|
||||
ext_ioctl_v2_data.ioctl_ptr);
|
||||
break;
|
||||
default:
|
||||
IPAWANERR("%d is Unsupported extended ioctl v2\n",
|
||||
ext_ioctl_v2_data.extended_v2_ioctl_type);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
IPAWANERR("[%s] unsupported cmd[%d]",
|
||||
dev->name, cmd);
|
||||
@@ -2511,7 +3097,7 @@ static void ipa3_wwan_deregister_netdev_pm_client(void)
|
||||
*/
|
||||
static int ipa3_wwan_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret, i;
|
||||
int ret, i, j;
|
||||
struct net_device *dev;
|
||||
int wan_cons_ep;
|
||||
|
||||
@@ -2661,6 +3247,15 @@ static int ipa3_wwan_probe(struct platform_device *pdev)
|
||||
atomic_set(&rmnet_ipa3_ctx->ap_suspend, 0);
|
||||
ipa3_update_ssr_state(false);
|
||||
|
||||
for (j = 0; j < RMNET_INGRESS_MAX; j++) {
|
||||
ingress_pipe_status[j].ep_type = 0;
|
||||
ingress_pipe_status[j].status = 0;
|
||||
}
|
||||
for (j = 0; j < RMNET_EGRESS_MAX; j++) {
|
||||
egress_pipe_status[j].ep_type = 0;
|
||||
egress_pipe_status[j].status = 0;
|
||||
}
|
||||
|
||||
IPAWANERR("rmnet_ipa completed initialization\n");
|
||||
return 0;
|
||||
config_err:
|
||||
@@ -2686,7 +3281,7 @@ wan_ioctl_init_err:
|
||||
|
||||
static int ipa3_wwan_remove(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
int ret, j;
|
||||
|
||||
IPAWANINFO("rmnet_ipa started deinitialization\n");
|
||||
mutex_lock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
@@ -2705,6 +3300,15 @@ static int ipa3_wwan_remove(struct platform_device *pdev)
|
||||
IPAWANERR("Failed to teardown APPS->IPA pipe\n");
|
||||
else
|
||||
rmnet_ipa3_ctx->apps_to_ipa3_hdl = -1;
|
||||
/* Clear pipe setup info */
|
||||
for (j = 0; j < RMNET_INGRESS_MAX; j++) {
|
||||
ingress_pipe_status[j].ep_type = 0;
|
||||
ingress_pipe_status[j].status = 0;
|
||||
}
|
||||
for (j = 0; j < RMNET_EGRESS_MAX; j++) {
|
||||
egress_pipe_status[j].ep_type = 0;
|
||||
egress_pipe_status[j].status = 0;
|
||||
}
|
||||
mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
IPAWANINFO("rmnet_ipa unregister_netdev\n");
|
||||
unregister_netdev(IPA_NETDEV());
|
||||
|
Referencia en una nueva incidencia
Block a user