Kaynağa Gözat

msm: ipa3: adding new wwan extended_v2 ioctl

To support setting up ingress and egress ioctl parameters
from netmngr

Change-Id: Ib5aa503c951e6650e34dfa6ee501390a82967ab6
Signed-off-by: Michael Adisumarta <[email protected]>
Michael Adisumarta 4 yıl önce
ebeveyn
işleme
528d18939c

+ 39 - 15
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c

@@ -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;
@@ -2021,7 +2028,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;
 
@@ -2030,9 +2037,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;
 
@@ -2065,7 +2079,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();
@@ -2095,7 +2109,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;
@@ -3983,8 +3997,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;
@@ -4044,8 +4060,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;
@@ -4878,6 +4892,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,

+ 12 - 2
drivers/platform/msm/ipa/ipa_v3/ipa_i.h

@@ -1061,6 +1061,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
  */
@@ -1098,6 +1102,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;
@@ -3136,8 +3144,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);

+ 79 - 18
drivers/platform/msm/ipa/ipa_v3/rmnet_ctl_ipa.c

@@ -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 =

+ 608 - 4
drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c

@@ -180,6 +180,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
  *
@@ -1509,6 +1519,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");
 
@@ -1575,6 +1586,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;
@@ -1601,7 +1613,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;
@@ -1642,6 +1655,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);
 	/*
@@ -1711,6 +1725,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)) {
@@ -1727,7 +1742,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);
@@ -1760,6 +1776,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.
  *
@@ -1782,6 +2330,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;
@@ -2127,6 +2676,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);
@@ -2509,7 +3095,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;
 
@@ -2659,6 +3245,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:
@@ -2684,7 +3279,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);
@@ -2703,6 +3298,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());