Преглед на файлове

qcacld-3.0: Enable WLAN host data path support for IPA WDI3.0

Change to support WLAN Napier host autonomy data path architecture.

Change-Id: I80e8f609587d0df85d2da9fb0f41cb49e02a9d2f
CRs-Fixed: 2033368
Yun Park преди 8 години
родител
ревизия
b4f591d8aa
променени са 11 файла, в които са добавени 1398 реда и са изтрити 756 реда
  1. 11 0
      Kbuild
  2. 45 27
      core/dp/htt/htt_t2h.c
  3. 2 2
      core/dp/ol/inc/ol_cfg.h
  4. 1 2
      core/dp/txrx/ol_tx.c
  5. 17 154
      core/dp/txrx/ol_txrx.c
  6. 936 0
      core/dp/txrx/ol_txrx_ipa.c
  7. 132 0
      core/dp/txrx/ol_txrx_ipa.h
  8. 7 6
      core/dp/txrx/ol_txrx_types.h
  9. 1 1
      core/hdd/inc/wlan_hdd_ipa.h
  10. 125 514
      core/hdd/src/wlan_hdd_ipa.c
  11. 121 50
      core/wma/src/wma_main.c

+ 11 - 0
Kbuild

@@ -9,6 +9,7 @@ endif
 ifeq ($(CONFIG_CNSS_QCA6290), y)
 	CONFIG_LITHIUM := y
 	CONFIG_WLAN_FEATURE_11AX := y
+	CONFIG_IPA := n
 endif
 
 ifeq ($(CONFIG_CLD_HL_SDIO_CORE), y)
@@ -1061,6 +1062,10 @@ ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y)
 TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_flow_control.o
 endif
 
+ifeq ($(CONFIG_IPA_OFFLOAD), 1)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_ipa.o
+endif
+
 ifeq ($(CONFIG_LITHIUM), y)
 ############ DP 3.0 ############
 DP_INC := -I$(WLAN_COMMON_ROOT)/dp/inc \
@@ -1085,6 +1090,10 @@ DP_OBJS += $(DP_SRC)/dp_tx_flow_control.o
 endif
 endif
 
+ifeq ($(CONFIG_IPA_OFFLOAD), 1)
+DP_OBJS +=     $(DP_SRC)/dp_ipa.o
+endif
+
 ############ CFG ############
 WCFG_DIR := wlan_cfg
 WCFG_INC := -I$(WLAN_COMMON_INC)/$(WCFG_DIR)
@@ -1998,9 +2007,11 @@ CDEFINES += -DFEATURE_GREEN_AP
 endif
 
 #Stats & Quota Metering feature
+ifeq ($(CONFIG_IPA),y)
 ifeq ($(CONFIG_QCACLD_FEATURE_METERING),y)
 CDEFINES += -DFEATURE_METERING
 endif
+endif
 
 #Enable RX Full re-order OL feature only "LL and NON-MDM9630 platform"
 ifneq ($(CONFIG_ARCH_MDM9630), y)

+ 45 - 27
core/dp/htt/htt_t2h.c

@@ -151,6 +151,50 @@ static uint8_t *htt_t2h_mac_addr_deswizzle(uint8_t *tgt_mac_addr,
 #endif
 }
 
+/**
+ * htt_ipa_op_response() - invoke an event handler from FW
+ * @pdev: Handle (pointer) to HTT pdev.
+ * @msg_word: htt msg
+ *
+ * Return: None
+ */
+#ifdef IPA_OFFLOAD
+static void htt_ipa_op_response(struct htt_pdev_t *pdev, uint32_t *msg_word)
+{
+	uint8_t op_code;
+	uint16_t len;
+	uint8_t *op_msg_buffer;
+	uint8_t *msg_start_ptr;
+
+	htc_pm_runtime_put(pdev->htc_pdev);
+	msg_start_ptr = (uint8_t *) msg_word;
+	op_code =
+		HTT_WDI_IPA_OP_RESPONSE_OP_CODE_GET(*msg_word);
+	msg_word++;
+	len = HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_GET(*msg_word);
+
+	op_msg_buffer =
+		qdf_mem_malloc(sizeof
+				(struct htt_wdi_ipa_op_response_t) +
+				len);
+	if (!op_msg_buffer) {
+		qdf_print("OPCODE messsage buffer alloc fail");
+		return;
+	}
+	qdf_mem_copy(op_msg_buffer,
+			msg_start_ptr,
+			sizeof(struct htt_wdi_ipa_op_response_t) +
+			len);
+	cdp_ipa_op_response(cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_pdev *)pdev->txrx_pdev,
+			op_msg_buffer);
+}
+#else
+static void htt_ipa_op_response(struct htt_pdev_t *pdev, uint32_t *msg_word)
+{
+}
+#endif
+
 /* Target to host Msg/event  handler  for low priority messages*/
 static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg,
 				   bool free_msg_buf)
@@ -426,33 +470,7 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg,
 
 	case HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE:
 	{
-		uint8_t op_code;
-		uint16_t len;
-		uint8_t *op_msg_buffer;
-		uint8_t *msg_start_ptr;
-
-		htc_pm_runtime_put(pdev->htc_pdev);
-		msg_start_ptr = (uint8_t *) msg_word;
-		op_code =
-			HTT_WDI_IPA_OP_RESPONSE_OP_CODE_GET(*msg_word);
-		msg_word++;
-		len = HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_GET(*msg_word);
-
-		op_msg_buffer =
-			qdf_mem_malloc(sizeof
-				       (struct htt_wdi_ipa_op_response_t) +
-				       len);
-		if (!op_msg_buffer) {
-			qdf_print("OPCODE messsage buffer alloc fail");
-			break;
-		}
-		qdf_mem_copy(op_msg_buffer,
-			     msg_start_ptr,
-			     sizeof(struct htt_wdi_ipa_op_response_t) +
-			     len);
-		cdp_ipa_op_response(cds_get_context(QDF_MODULE_ID_SOC),
-				(struct cdp_pdev *)pdev->txrx_pdev,
-				op_msg_buffer);
+		htt_ipa_op_response(pdev, msg_word);
 		break;
 	}
 

+ 2 - 2
core/dp/ol/inc/ol_cfg.h

@@ -572,7 +572,7 @@ unsigned int ol_cfg_ipa_uc_rx_ind_ring_size(struct cdp_cfg *cfg_pdev);
  */
 unsigned int ol_cfg_ipa_uc_tx_partition_base(struct cdp_cfg *cfg_pdev);
 void ol_cfg_set_ipa_uc_tx_partition_base(struct cdp_cfg *cfg_pdev,
-					uint32_t value);
+					 uint32_t value);
 #else
 static inline unsigned int ol_cfg_ipa_uc_offload_enabled(
 	struct cdp_cfg *cfg_pdev)
@@ -605,7 +605,7 @@ static inline unsigned int ol_cfg_ipa_uc_tx_partition_base(
 }
 
 static inline void ol_cfg_set_ipa_uc_tx_partition_base(
-	struct cdp_cfg *cfg_pdev, uint32_t value)
+	void *cfg_pdev, uint32_t value)
 {
 }
 #endif /* IPA_OFFLOAD */

+ 1 - 2
core/dp/txrx/ol_tx.c

@@ -286,8 +286,7 @@ qdf_nbuf_t ol_tx_data(void *data_vdev, qdf_nbuf_t skb)
 }
 
 #ifdef IPA_OFFLOAD
-qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev,
-			qdf_nbuf_t skb)
+qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb)
 {
 	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
 	qdf_nbuf_t ret;

+ 17 - 154
core/dp/txrx/ol_txrx.c

@@ -86,6 +86,8 @@
 #include <a_types.h>
 #include <cdp_txrx_handle.h>
 #include <htt_internal.h>
+#include <ol_txrx_ipa.h>
+
 #ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID
 ol_txrx_peer_handle
 ol_txrx_peer_find_by_local_id(struct cdp_pdev *pdev,
@@ -4519,159 +4521,7 @@ ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth)
 }
 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 
-#ifdef IPA_OFFLOAD
-/**
- * ol_txrx_ipa_uc_get_resource() - Client request resource information
- * @pdev: handle to the HTT instance
- * @ce_sr_base_paddr: copy engine source ring base physical address
- * @ce_sr_ring_size: copy engine source ring size
- * @ce_reg_paddr: copy engine register physical address
- * @tx_comp_ring_base_paddr: tx comp ring base physical address
- * @tx_comp_ring_size: tx comp ring size
- * @tx_num_alloc_buffer: number of allocated tx buffer
- * @rx_rdy_ring_base_paddr: rx ready ring base physical address
- * @rx_rdy_ring_size: rx ready ring size
- * @rx_proc_done_idx_paddr: rx process done index physical address
- * @rx_proc_done_idx_vaddr: rx process done index virtual address
- * @rx2_rdy_ring_base_paddr: rx done ring base physical address
- * @rx2_rdy_ring_size: rx done ring size
- * @rx2_proc_done_idx_paddr: rx done index physical address
- * @rx2_proc_done_idx_vaddr: rx done index virtual address
- *
- *  OL client will reuqest IPA UC related resource information
- *  Resource information will be distributted to IPA module
- *  All of the required resources should be pre-allocated
- *
- * Return: none
- */
-static void
-ol_txrx_ipa_uc_get_resource(struct cdp_pdev *ppdev,
-		struct ol_txrx_ipa_resources *ipa_res)
-{
-	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
-
-	htt_ipa_uc_get_resource(pdev->htt_pdev,
-				&ipa_res->ce_sr_base_paddr,
-				&ipa_res->ce_sr_ring_size,
-				&ipa_res->ce_reg_paddr,
-				&ipa_res->tx_comp_ring_base_paddr,
-				&ipa_res->tx_comp_ring_size,
-				&ipa_res->tx_num_alloc_buffer,
-				&ipa_res->rx_rdy_ring_base_paddr,
-				&ipa_res->rx_rdy_ring_size,
-				&ipa_res->rx_proc_done_idx_paddr,
-				&ipa_res->rx_proc_done_idx_vaddr,
-				&ipa_res->rx2_rdy_ring_base_paddr,
-				&ipa_res->rx2_rdy_ring_size,
-				&ipa_res->rx2_proc_done_idx_paddr,
-				&ipa_res->rx2_proc_done_idx_vaddr);
-}
-
-/**
- * ol_txrx_ipa_uc_set_doorbell_paddr() - Client set IPA UC doorbell register
- * @pdev: handle to the HTT instance
- * @ipa_uc_tx_doorbell_paddr: tx comp doorbell physical address
- * @ipa_uc_rx_doorbell_paddr: rx ready doorbell physical address
- *
- *  IPA UC let know doorbell register physical address
- *  WLAN firmware will use this physical address to notify IPA UC
- *
- * Return: none
- */
-static void
-ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_pdev *ppdev,
-				  qdf_dma_addr_t ipa_tx_uc_doorbell_paddr,
-				  qdf_dma_addr_t ipa_rx_uc_doorbell_paddr)
-{
-	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
-	htt_ipa_uc_set_doorbell_paddr(pdev->htt_pdev,
-				      ipa_tx_uc_doorbell_paddr,
-				      ipa_rx_uc_doorbell_paddr);
-}
-
 /**
- * ol_txrx_ipa_uc_set_active() - Client notify IPA UC data path active or not
- * @pdev: handle to the HTT instance
- * @ipa_uc_tx_doorbell_paddr: tx comp doorbell physical address
- * @ipa_uc_rx_doorbell_paddr: rx ready doorbell physical address
- *
- *  IPA UC let know doorbell register physical address
- *  WLAN firmware will use this physical address to notify IPA UC
- *
- * Return: none
- */
-static void
-ol_txrx_ipa_uc_set_active(struct cdp_pdev *ppdev, bool uc_active, bool is_tx)
-{
-	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
-	htt_h2t_ipa_uc_set_active(pdev->htt_pdev, uc_active, is_tx);
-}
-
-/**
- * ol_txrx_ipa_uc_op_response() - Handle OP command response from firmware
- * @pdev: handle to the HTT instance
- * @op_msg: op response message from firmware
- *
- * Return: none
- */
-static void ol_txrx_ipa_uc_op_response(struct cdp_pdev *ppdev, uint8_t *op_msg)
-{
-	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
-	if (pdev->ipa_uc_op_cb) {
-		pdev->ipa_uc_op_cb(op_msg, pdev->osif_dev);
-	} else {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
-		    "%s: IPA callback function is not registered", __func__);
-		qdf_mem_free(op_msg);
-		return;
-	}
-}
-
-/**
- * ol_txrx_ipa_uc_register_op_cb() - Register OP handler function
- * @pdev: handle to the HTT instance
- * @op_cb: handler function pointer
- * @osif_dev: register client context
- *
- * Return: none
- */
-static void
-ol_txrx_ipa_uc_register_op_cb(struct cdp_pdev *ppdev,
-				   ipa_uc_op_cb_type op_cb, void *osif_dev)
-{
-	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
-	pdev->ipa_uc_op_cb = op_cb;
-	pdev->osif_dev = osif_dev;
-}
-
-/**
- * ol_txrx_ipa_uc_get_stat() - Get firmware wdi status
- * @pdev: handle to the HTT instance
- *
- * Return: none
- */
-static void ol_txrx_ipa_uc_get_stat(struct cdp_pdev *ppdev)
-{
-	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
-	htt_h2t_ipa_uc_get_stats(pdev->htt_pdev);
-}
-
-static void ol_txrx_ipa_uc_get_share_stats(struct cdp_pdev *ppdev,
-					   uint8_t reset_stats)
-{
-	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
-	htt_h2t_ipa_uc_get_share_stats(pdev->htt_pdev, reset_stats);
-}
-
-static void ol_txrx_ipa_uc_set_quota(struct cdp_pdev *ppdev,
-				     uint64_t quota_bytes)
-{
-	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
-	htt_h2t_ipa_uc_set_quota(pdev->htt_pdev, quota_bytes);
-}
-#endif /* IPA_UC_OFFLOAD */
-
-/*
  * ol_txrx_display_stats() - Display OL TXRX display stats
  * @value: Module id for which stats needs to be displayed
  *
@@ -5566,8 +5416,8 @@ static struct cdp_lflowctl_ops ol_ops_l_flowctl = {
 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 };
 
-static struct cdp_ipa_ops ol_ops_ipa = {
 #ifdef IPA_OFFLOAD
+static struct cdp_ipa_ops ol_ops_ipa = {
 	.ipa_get_resource = ol_txrx_ipa_uc_get_resource,
 	.ipa_set_doorbell_paddr = ol_txrx_ipa_uc_set_doorbell_paddr,
 	.ipa_set_active = ol_txrx_ipa_uc_set_active,
@@ -5576,10 +5426,21 @@ static struct cdp_ipa_ops ol_ops_ipa = {
 	.ipa_get_stat = ol_txrx_ipa_uc_get_stat,
 	.ipa_tx_data_frame = ol_tx_send_ipa_data_frame,
 	.ipa_set_uc_tx_partition_base = ol_cfg_set_ipa_uc_tx_partition_base,
+	.ipa_enable_autonomy = ol_txrx_ipa_enable_autonomy,
+	.ipa_disable_autonomy = ol_txrx_ipa_disable_autonomy,
+	.ipa_setup = ol_txrx_ipa_setup,
+	.ipa_cleanup = ol_txrx_ipa_cleanup,
+	.ipa_setup_iface = ol_txrx_ipa_setup_iface,
+	.ipa_cleanup_iface = ol_txrx_ipa_cleanup_iface,
+	.ipa_enable_pipes = ol_txrx_ipa_enable_pipes,
+	.ipa_disable_pipes = ol_txrx_ipa_disable_pipes,
+	.ipa_set_perf_level = ol_txrx_ipa_set_perf_level,
+#ifdef FEATURE_METERING
 	.ipa_uc_get_share_stats = ol_txrx_ipa_uc_get_share_stats,
 	.ipa_uc_set_quota = ol_txrx_ipa_uc_set_quota
-#endif /* IPA_OFFLOAD */
+#endif
 };
+#endif
 
 static struct cdp_bus_ops ol_ops_bus = {
 	.bus_suspend = ol_txrx_bus_suspend,
@@ -5696,7 +5557,9 @@ static struct cdp_ops ol_txrx_ops = {
 	.cfg_ops = &ol_ops_cfg,
 	.flowctl_ops = &ol_ops_flowctl,
 	.l_flowctl_ops = &ol_ops_l_flowctl,
+#ifdef IPA_OFFLOAD
 	.ipa_ops = &ol_ops_ipa,
+#endif
 	.bus_ops = &ol_ops_bus,
 	.ocb_ops = &ol_ops_ocb,
 	.peer_ops = &ol_ops_peer,

+ 936 - 0
core/dp/txrx/ol_txrx_ipa.c

@@ -0,0 +1,936 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*=== includes ===*/
+/* header files for OS primitives */
+#include <osdep.h>              /* uint32_t, etc. */
+#include <qdf_mem.h>         /* qdf_mem_malloc,free */
+#include <qdf_types.h>          /* qdf_device_t, qdf_print */
+#include <qdf_lock.h>           /* qdf_spinlock */
+#include <qdf_atomic.h>         /* qdf_atomic_read */
+
+#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB)
+/* Required for WLAN_FEATURE_FASTPATH */
+#include <ce_api.h>
+#endif
+/* header files for utilities */
+#include <cds_queue.h>          /* TAILQ */
+
+/* header files for configuration API */
+#include <ol_cfg.h>             /* ol_cfg_is_high_latency */
+#include <ol_if_athvar.h>
+
+/* header files for HTT API */
+#include <ol_htt_api.h>
+#include <ol_htt_tx_api.h>
+
+/* header files for our own APIs */
+#include <ol_txrx_api.h>
+#include <ol_txrx_dbg.h>
+#include <cdp_txrx_ocb.h>
+#include <ol_txrx_ctrl_api.h>
+#include <cdp_txrx_stats.h>
+#include <ol_txrx_osif_api.h>
+/* header files for our internal definitions */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT, etc. */
+#include <wdi_event.h>          /* WDI events */
+#include <ol_tx.h>              /* ol_tx_ll */
+#include <ol_rx.h>              /* ol_rx_deliver */
+#include <ol_txrx_peer_find.h>  /* ol_txrx_peer_find_attach, etc. */
+#include <ol_rx_pn.h>           /* ol_rx_pn_check, etc. */
+#include <ol_rx_fwd.h>          /* ol_rx_fwd_check, etc. */
+#include <ol_rx_reorder_timeout.h>      /* OL_RX_REORDER_TIMEOUT_INIT, etc. */
+#include <ol_rx_reorder.h>
+#include <ol_tx_send.h>         /* ol_tx_discard_target_frms */
+#include <ol_tx_desc.h>         /* ol_tx_desc_frame_free */
+#include <ol_tx_queue.h>
+#include <ol_tx_sched.h>           /* ol_tx_sched_attach, etc. */
+#include <ol_txrx.h>
+#include <ol_txrx_types.h>
+#include <cdp_txrx_flow_ctrl_legacy.h>
+#include <cdp_txrx_bus.h>
+#include <cdp_txrx_ipa.h>
+#include <cdp_txrx_pmf.h>
+#include "wma.h"
+#include "hif.h"
+#include <cdp_txrx_peer_ops.h>
+#ifndef REMOVE_PKT_LOG
+#include "pktlog_ac.h"
+#endif
+#include "epping_main.h"
+#include <a_types.h>
+
+#ifdef IPA_OFFLOAD
+#include <ol_txrx_ipa.h>
+
+/* For Tx pipes, use Ethernet-II Header format */
+struct ol_txrx_ipa_uc_tx_hdr ipa_uc_tx_hdr = {
+	{
+		0x0000,
+		0x00000000,
+		0x00000000
+	},
+	{
+		0x00000000
+	},
+	{
+		{0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc},
+		{0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff},
+		0x0008
+	}
+};
+
+/**
+ * ol_txrx_ipa_uc_get_resource() - Client request resource information
+ * @pdev: handle to the HTT instance
+ *
+ *  OL client will reuqest IPA UC related resource information
+ *  Resource information will be distributted to IPA module
+ *  All of the required resources should be pre-allocated
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+
+	htt_ipa_uc_get_resource(pdev->htt_pdev,
+				&ipa_res->ce_sr_base_paddr,
+				&ipa_res->ce_sr_ring_size,
+				&ipa_res->ce_reg_paddr,
+				&ipa_res->tx_comp_ring_base_paddr,
+				&ipa_res->tx_comp_ring_size,
+				&ipa_res->tx_num_alloc_buffer,
+				&ipa_res->rx_rdy_ring_base_paddr,
+				&ipa_res->rx_rdy_ring_size,
+				&ipa_res->rx_proc_done_idx_paddr,
+				&ipa_res->rx_proc_done_idx_vaddr,
+				&ipa_res->rx2_rdy_ring_base_paddr,
+				&ipa_res->rx2_rdy_ring_size,
+				&ipa_res->rx2_proc_done_idx_paddr,
+				&ipa_res->rx2_proc_done_idx_vaddr);
+
+	if ((0 == ipa_res->ce_sr_base_paddr) ||
+	    (0 == ipa_res->tx_comp_ring_base_paddr) ||
+	    (0 == ipa_res->rx_rdy_ring_base_paddr)
+#if defined(QCA_WIFI_3_0) && defined(CONFIG_IPA3)
+	    || (0 == ipa_res->rx2_rdy_ring_base_paddr)
+#endif
+	   )
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_set_doorbell_paddr() - Client set IPA UC doorbell register
+ * @pdev: handle to the HTT instance
+ *
+ *  IPA UC let know doorbell register physical address
+ *  WLAN firmware will use this physical address to notify IPA UC
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	int ret;
+
+	ret = htt_ipa_uc_set_doorbell_paddr(pdev->htt_pdev,
+				      ipa_res->tx_comp_doorbell_paddr,
+				      ipa_res->rx_ready_doorbell_paddr);
+
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "htt_ipa_uc_set_doorbell_paddr fail: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_set_active() - Client notify IPA UC data path active or not
+ * @pdev: handle to the HTT instance
+ * @uc_active: WDI UC path enable or not
+ * @is_tx: TX path or RX path
+ *
+ *  IPA UC let know doorbell register physical address
+ *  WLAN firmware will use this physical address to notify IPA UC
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_pdev *ppdev, bool uc_active,
+			       bool is_tx)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	int ret;
+
+	ret = htt_h2t_ipa_uc_set_active(pdev->htt_pdev, uc_active, is_tx);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "htt_h2t_ipa_uc_set_active fail: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_op_response() - Handle OP command response from firmware
+ * @pdev: handle to the device instance
+ * @op_msg: op response message from firmware
+ *
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_pdev *ppdev, uint8_t *op_msg)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+
+	if (pdev->ipa_uc_op_cb) {
+		pdev->ipa_uc_op_cb(op_msg, pdev->usr_ctxt);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "%s: IPA callback function is not registered", __func__);
+		qdf_mem_free(op_msg);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_register_op_cb() - Register OP handler function
+ * @pdev: handle to the device instance
+ * @op_cb: handler function pointer
+ *
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_pdev *ppdev,
+				   ipa_uc_op_cb_type op_cb, void *usr_ctxt)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+
+	pdev->ipa_uc_op_cb = op_cb;
+	pdev->usr_ctxt = usr_ctxt;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_get_stat() - Get firmware wdi status
+ * @pdev: handle to the HTT instance
+ *
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	int ret;
+
+	ret = htt_h2t_ipa_uc_get_stats(pdev->htt_pdev);
+
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "htt_h2t_ipa_uc_get_stats fail: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_enable_autonomy() - Enable autonomy RX path
+ * @pdev: handle to the device instance
+ *
+ * Set all RX packet route to IPA
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_pdev *ppdev)
+{
+	/* TBD */
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_disable_autonomy() - Disable autonomy RX path
+ * @pdev: handle to the device instance
+ *
+ * Disable RX packet route to host
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_pdev *ppdev)
+{
+	/* TBD */
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_setup() - Setup and connect IPA pipes
+ * @pdev: handle to the device instance
+ * @ipa_i2w_cb: IPA to WLAN callback
+ * @ipa_w2i_cb: WLAN to IPA callback
+ * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback
+ * @ipa_desc_size: IPA descriptor size
+ * @ipa_priv: handle to the HTT instance
+ * @is_rm_enabled: Is IPA RM enabled or not
+ * @p_tx_pipe_handle: pointer to Tx pipe handle
+ * @p_rx_pipe_handle: pointer to Rx pipe handle
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
+			     void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb,
+			     uint32_t ipa_desc_size, void *ipa_priv,
+			     bool is_rm_enabled, uint32_t *p_tx_pipe_handle,
+			     uint32_t *p_rx_pipe_handle)
+
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	struct ipa_wdi_in_params pipe_in;
+	struct ipa_wdi_out_params pipe_out;
+	int ret;
+
+	qdf_mem_zero(&pipe_in, sizeof(struct ipa_wdi_in_params));
+	qdf_mem_zero(&pipe_out, sizeof(struct ipa_wdi_out_params));
+
+	/* TX PIPE */
+	pipe_in.sys.ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
+	pipe_in.sys.ipa_ep_cfg.hdr.hdr_len = OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
+	pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1;
+	pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 0;
+	pipe_in.sys.ipa_ep_cfg.hdr.hdr_additional_const_len =
+		OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE;
+	pipe_in.sys.ipa_ep_cfg.mode.mode = IPA_BASIC;
+	pipe_in.sys.client = IPA_CLIENT_WLAN1_CONS;
+	pipe_in.sys.desc_fifo_sz = ipa_desc_size;
+	pipe_in.sys.priv = ipa_priv;
+	pipe_in.sys.ipa_ep_cfg.hdr_ext.hdr_little_endian = true;
+	pipe_in.sys.notify = ipa_i2w_cb;
+	if (!is_rm_enabled) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			    "%s: IPA RM DISABLED, IPA AWAKE", __func__);
+		pipe_in.sys.keep_ipa_awake = true;
+	}
+
+	pipe_in.u.dl.comp_ring_base_pa = ipa_res->tx_comp_ring_base_paddr;
+	pipe_in.u.dl.comp_ring_size = ipa_res->tx_comp_ring_size *
+				      sizeof(qdf_dma_addr_t);
+	pipe_in.u.dl.ce_ring_base_pa = ipa_res->ce_sr_base_paddr;
+	pipe_in.u.dl.ce_door_bell_pa = ipa_res->ce_reg_paddr;
+	pipe_in.u.dl.ce_ring_size = ipa_res->ce_sr_ring_size;
+	pipe_in.u.dl.num_tx_buffers = ipa_res->tx_num_alloc_buffer;
+
+	/* Connect WDI IPA PIPE */
+	ret = ipa_connect_wdi_pipe(&pipe_in, &pipe_out);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "ipa_connect_wdi_pipe: Tx pipe setup failed: ret=%d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Micro Controller Doorbell register */
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		"%s CONS DB pipe out 0x%x TX PIPE Handle 0x%x",
+		__func__, (unsigned int)pipe_out.uc_door_bell_pa,
+		pipe_out.clnt_hdl);
+	ipa_res->tx_comp_doorbell_paddr = pipe_out.uc_door_bell_pa;
+	/* WLAN TX PIPE Handle */
+	ipa_res->tx_pipe_handle = pipe_out.clnt_hdl;
+	*p_tx_pipe_handle = pipe_out.clnt_hdl;
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		"TX: %s 0x%x, %s %d, %s 0x%x, %s 0x%x, %s %d, %sNB %d, %s 0x%x",
+		"comp_ring_base_pa",
+		(unsigned int)pipe_in.u.dl.comp_ring_base_pa,
+		"comp_ring_size",
+		pipe_in.u.dl.comp_ring_size,
+		"ce_ring_base_pa",
+		(unsigned int)pipe_in.u.dl.ce_ring_base_pa,
+		"ce_door_bell_pa",
+		(unsigned int)pipe_in.u.dl.ce_door_bell_pa,
+		"ce_ring_size",
+		pipe_in.u.dl.ce_ring_size,
+		"num_tx_buffers",
+		pipe_in.u.dl.num_tx_buffers,
+		"tx_comp_doorbell_paddr",
+		(unsigned int)ipa_res->tx_comp_doorbell_paddr);
+
+	/* RX PIPE */
+	pipe_in.sys.ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
+	pipe_in.sys.ipa_ep_cfg.hdr.hdr_len = OL_TXRX_IPA_UC_WLAN_RX_HDR_LEN;
+	pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 0;
+	pipe_in.sys.ipa_ep_cfg.hdr.hdr_metadata_reg_valid = 1;
+	pipe_in.sys.ipa_ep_cfg.mode.mode = IPA_BASIC;
+	pipe_in.sys.client = IPA_CLIENT_WLAN1_PROD;
+	pipe_in.sys.desc_fifo_sz = ipa_desc_size + sizeof(struct sps_iovec);
+	pipe_in.sys.notify = ipa_w2i_cb;
+	if (!is_rm_enabled) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			    "%s: IPA RM DISABLED, IPA AWAKE", __func__);
+		pipe_in.sys.keep_ipa_awake = true;
+	}
+
+	pipe_in.u.ul.rdy_ring_base_pa = ipa_res->rx_rdy_ring_base_paddr;
+	pipe_in.u.ul.rdy_ring_size = ipa_res->rx_rdy_ring_size;
+	pipe_in.u.ul.rdy_ring_rp_pa = ipa_res->rx_proc_done_idx_paddr;
+	OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res);
+
+#ifdef FEATURE_METERING
+	pipe_in.wdi_notify = ipa_wdi_meter_notifier_cb;
+#endif
+
+	ret = ipa_connect_wdi_pipe(&pipe_in, &pipe_out);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "ipa_connect_wdi_pipe: Rx pipe setup failed: ret=%d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+	ipa_res->rx_ready_doorbell_paddr = pipe_out.uc_door_bell_pa;
+	ipa_res->rx_pipe_handle = pipe_out.clnt_hdl;
+	*p_rx_pipe_handle = pipe_out.clnt_hdl;
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "RX: %s 0x%x, %s %d, %s 0x%x, %s 0x%x",
+		  "rdy_ring_base_pa",
+		  (unsigned int)pipe_in.u.ul.rdy_ring_base_pa,
+		  "rdy_ring_size",
+		  pipe_in.u.ul.rdy_ring_size,
+		  "rdy_ring_rp_pa",
+		  (unsigned int)pipe_in.u.ul.rdy_ring_rp_pa,
+		  "rx_ready_doorbell_paddr",
+		  (unsigned int)ipa_res->rx_ready_doorbell_paddr);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_cleanup() - Disconnect IPA pipes
+ * @tx_pipe_handle: Tx pipe handle
+ * @rx_pipe_handle: Rx pipe handle
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_cleanup(uint32_t tx_pipe_handle, uint32_t rx_pipe_handle)
+{
+	int ret;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		    "%s: Disconnect TX PIPE tx_pipe_handle=0x%x",
+		    __func__, tx_pipe_handle);
+	ret = ipa_disconnect_wdi_pipe(tx_pipe_handle);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "ipa_disconnect_wdi_pipe: Tx pipe cleanup failed: ret=%d",
+		    ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		    "%s: Disconnect RX PIPE rx_pipe_handle=0x%x",
+		    __func__, rx_pipe_handle);
+	ret = ipa_disconnect_wdi_pipe(rx_pipe_handle);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "ipa_disconnect_wdi_pipe: Rx pipe cleanup failed: ret=%d",
+		    ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_remove_ipa_header() - Remove a specific header from IPA
+ * @name: Name of the header to be removed
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ol_txrx_ipa_remove_header(char *name)
+{
+	struct ipa_ioc_get_hdr hdrlookup;
+	int ret = 0, len;
+	struct ipa_ioc_del_hdr *ipa_hdr;
+
+	qdf_mem_zero(&hdrlookup, sizeof(hdrlookup));
+	strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name));
+	ret = ipa_get_hdr(&hdrlookup);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			  "Hdr deleted already %s, %d", name, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "hdl: 0x%x",
+		  hdrlookup.hdl);
+	len = sizeof(struct ipa_ioc_del_hdr) + sizeof(struct ipa_hdr_del) * 1;
+	ipa_hdr = (struct ipa_ioc_del_hdr *)qdf_mem_malloc(len);
+	if (ipa_hdr == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "ipa_hdr allocation failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ipa_hdr->num_hdls = 1;
+	ipa_hdr->commit = 0;
+	ipa_hdr->hdl[0].hdl = hdrlookup.hdl;
+	ipa_hdr->hdl[0].status = -1;
+	ret = ipa_del_hdr(ipa_hdr);
+	if (ret != 0) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Delete header failed: %d", ret);
+		qdf_mem_free(ipa_hdr);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_free(ipa_hdr);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_add_header_info() - Add IPA header for a given interface
+ * @ifname: Interface name
+ * @mac_addr: Interface MAC address
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: 0 on success, negativer errno value on error
+ */
+static int ol_txrx_ipa_add_header_info(char *ifname, uint8_t *mac_addr,
+				       uint8_t session_id, bool is_ipv6_enabled)
+{
+	struct ipa_ioc_add_hdr *ipa_hdr = NULL;
+	int ret = -EINVAL;
+	struct ol_txrx_ipa_uc_tx_hdr *uc_tx_hdr = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "Add Partial hdr: %s, %pM", ifname, mac_addr);
+
+	/* dynamically allocate the memory to add the hdrs */
+	ipa_hdr = qdf_mem_malloc(sizeof(struct ipa_ioc_add_hdr)
+				 + sizeof(struct ipa_hdr_add));
+	if (!ipa_hdr) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			    "%s: ipa_hdr allocation failed", ifname);
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	ipa_hdr->commit = 0;
+	ipa_hdr->num_hdrs = 1;
+
+	uc_tx_hdr = (struct ol_txrx_ipa_uc_tx_hdr *)ipa_hdr->hdr[0].hdr;
+	memcpy(uc_tx_hdr, &ipa_uc_tx_hdr, OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN);
+	memcpy(uc_tx_hdr->eth.h_source, mac_addr, ETH_ALEN);
+	uc_tx_hdr->ipa_hd.vdev_id = session_id;
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "ifname=%s, vdev_id=%d",
+		  ifname, uc_tx_hdr->ipa_hd.vdev_id);
+	snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+		 ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
+	ipa_hdr->hdr[0].hdr_len = OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
+	ipa_hdr->hdr[0].type = IPA_HDR_L2_ETHERNET_II;
+	ipa_hdr->hdr[0].is_partial = 1;
+	ipa_hdr->hdr[0].hdr_hdl = 0;
+	ipa_hdr->hdr[0].is_eth2_ofst_valid = 1;
+	ipa_hdr->hdr[0].eth2_ofst = OL_TXRX_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
+
+	ret = ipa_add_hdr(ipa_hdr);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s IPv4 add hdr failed: %d", ifname, ret);
+		goto end;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: IPv4 hdr_hdl: 0x%x",
+		  ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl);
+
+	if (is_ipv6_enabled) {
+		snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+			 ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
+
+		uc_tx_hdr = (struct ol_txrx_ipa_uc_tx_hdr *)ipa_hdr->hdr[0].hdr;
+		uc_tx_hdr->eth.h_proto = cpu_to_be16(ETH_P_IPV6);
+
+		ret = ipa_add_hdr(ipa_hdr);
+		if (ret) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				    "%s: IPv6 add hdr failed: %d", ifname, ret);
+			goto clean_ipv4_hdr;
+		}
+
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: IPv6 hdr_hdl: 0x%x",
+			  ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl);
+	}
+
+	qdf_mem_free(ipa_hdr);
+
+	return ret;
+
+clean_ipv4_hdr:
+	snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+		 ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
+	ol_txrx_ipa_remove_header(ipa_hdr->hdr[0].name);
+end:
+	if (ipa_hdr)
+		qdf_mem_free(ipa_hdr);
+
+	return ret;
+}
+
+/**
+ * ol_txrx_ipa_register_interface() - register IPA interface
+ * @ifname: Interface name
+ * @prod_client: IPA prod client type
+ * @cons_client: IPA cons client type
+ * @session_id: Session ID
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: 0 on success, negative errno on error
+ */
+static int ol_txrx_ipa_register_interface(char *ifname,
+					  enum ipa_client_type prod_client,
+					  enum ipa_client_type cons_client,
+					  uint8_t session_id,
+					  bool is_ipv6_enabled)
+{
+	struct ipa_tx_intf tx_intf;
+	struct ipa_rx_intf rx_intf;
+	struct ipa_ioc_tx_intf_prop *tx_prop = NULL;
+	struct ipa_ioc_rx_intf_prop *rx_prop = NULL;
+
+	char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX];
+	char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX];
+
+	int num_prop = 1;
+	int ret = 0;
+
+	if (is_ipv6_enabled)
+		num_prop++;
+
+	/* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */
+	tx_prop =
+		qdf_mem_malloc(sizeof(struct ipa_ioc_tx_intf_prop) * num_prop);
+	if (!tx_prop) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "tx_prop allocation failed");
+		goto register_interface_fail;
+	}
+
+	/* Allocate RX properties, 1 each for IPv4 & IPv6 */
+	rx_prop =
+		qdf_mem_malloc(sizeof(struct ipa_ioc_rx_intf_prop) * num_prop);
+	if (!rx_prop) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "rx_prop allocation failed");
+		goto register_interface_fail;
+	}
+
+	qdf_mem_zero(&tx_intf, sizeof(tx_intf));
+	qdf_mem_zero(&rx_intf, sizeof(rx_intf));
+
+	snprintf(ipv4_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
+		 ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
+	snprintf(ipv6_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
+		 ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
+
+	rx_prop[IPA_IP_v4].ip = IPA_IP_v4;
+	rx_prop[IPA_IP_v4].src_pipe = prod_client;
+	rx_prop[IPA_IP_v4].hdr_l2_type = IPA_HDR_L2_ETHERNET_II;
+	rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA;
+
+	/*
+	 * Interface ID is 3rd byte in the CLD header. Add the meta data and
+	 * mask to identify the interface in IPA hardware
+	 */
+	rx_prop[IPA_IP_v4].attrib.meta_data =
+		htonl(session_id << 16);
+	rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000);
+
+	rx_intf.num_props++;
+	if (is_ipv6_enabled) {
+		rx_prop[IPA_IP_v6].ip = IPA_IP_v6;
+		rx_prop[IPA_IP_v6].src_pipe = prod_client;
+		rx_prop[IPA_IP_v6].hdr_l2_type = IPA_HDR_L2_ETHERNET_II;
+		rx_prop[IPA_IP_v6].attrib.attrib_mask = IPA_FLT_META_DATA;
+		rx_prop[IPA_IP_v6].attrib.meta_data =
+			htonl(session_id << 16);
+		rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000);
+
+		rx_intf.num_props++;
+	}
+
+	tx_prop[IPA_IP_v4].ip = IPA_IP_v4;
+	tx_prop[IPA_IP_v4].hdr_l2_type = IPA_HDR_L2_ETHERNET_II;
+	tx_prop[IPA_IP_v4].dst_pipe = IPA_CLIENT_WLAN1_CONS;
+	tx_prop[IPA_IP_v4].alt_dst_pipe = cons_client;
+	strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name,
+			IPA_RESOURCE_NAME_MAX);
+	tx_intf.num_props++;
+
+	if (is_ipv6_enabled) {
+		tx_prop[IPA_IP_v6].ip = IPA_IP_v6;
+		tx_prop[IPA_IP_v6].hdr_l2_type = IPA_HDR_L2_ETHERNET_II;
+		tx_prop[IPA_IP_v6].dst_pipe = IPA_CLIENT_WLAN1_CONS;
+		tx_prop[IPA_IP_v6].alt_dst_pipe = cons_client;
+		strlcpy(tx_prop[IPA_IP_v6].hdr_name, ipv6_hdr_name,
+				IPA_RESOURCE_NAME_MAX);
+		tx_intf.num_props++;
+	}
+
+	tx_intf.prop = tx_prop;
+	rx_intf.prop = rx_prop;
+
+	/* Call the ipa api to register interface */
+	ret = ipa_register_intf(ifname, &tx_intf, &rx_intf);
+
+register_interface_fail:
+	qdf_mem_free(tx_prop);
+	qdf_mem_free(rx_prop);
+	return ret;
+}
+
+/**
+ * ol_txrx_ipa_setup_iface() - Setup IPA header and register interface
+ * @ifname: Interface name
+ * @mac_addr: Interface MAC address
+ * @prod_client: IPA prod client type
+ * @cons_client: IPA cons client type
+ * @session_id: Session ID
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
+				   enum ipa_client_type prod_client,
+				   enum ipa_client_type cons_client,
+				   uint8_t session_id, bool is_ipv6_enabled)
+{
+	int ret;
+
+	ret = ol_txrx_ipa_add_header_info(ifname, mac_addr, session_id,
+					  is_ipv6_enabled);
+	if (ret)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Configure the TX and RX pipes filter rules */
+	ret = ol_txrx_ipa_register_interface(ifname, prod_client, cons_client,
+					     session_id, is_ipv6_enabled);
+	if (ret)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_cleanup_iface() - Cleanup IPA header and deregister interface
+ * @ifname: Interface name
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled)
+{
+	char name_ipa[IPA_RESOURCE_NAME_MAX];
+	int ret;
+
+	/* Remove the headers */
+	snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
+			ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
+	ol_txrx_ipa_remove_header(name_ipa);
+
+	if (is_ipv6_enabled) {
+		snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
+				ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
+		ol_txrx_ipa_remove_header(name_ipa);
+	}
+	/* unregister the interface with IPA */
+	ret = ipa_deregister_intf(ifname);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+				"%s: ipa_deregister_intf fail: %d",
+				ifname, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+ /**
+ * ol_txrx_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes
+ * @pdev: handle to the device instance
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	int result;
+
+	/* ACTIVATE TX PIPE */
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Enable TX PIPE(tx_pipe_handle=%d)",
+			__func__, ipa_res->tx_pipe_handle);
+	result = ipa_enable_wdi_pipe(ipa_res->tx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Enable TX PIPE fail, code %d",
+				__func__, result);
+		return QDF_STATUS_E_FAILURE;
+	}
+	result = ipa_resume_wdi_pipe(ipa_res->tx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Resume TX PIPE fail, code %d",
+				__func__, result);
+		return QDF_STATUS_E_FAILURE;
+	}
+	ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, true);
+
+	/* ACTIVATE RX PIPE */
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Enable RX PIPE(rx_pipe_handle=%d)",
+			__func__, ipa_res->rx_pipe_handle);
+	result = ipa_enable_wdi_pipe(ipa_res->rx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Enable RX PIPE fail, code %d",
+				__func__, result);
+		return QDF_STATUS_E_FAILURE;
+	}
+	result = ipa_resume_wdi_pipe(ipa_res->rx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Resume RX PIPE fail, code %d",
+				__func__, result);
+		return QDF_STATUS_E_FAILURE;
+	}
+	ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, false);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_disable_pipes() – Suspend traffic and disable Tx/Rx pipes
+ * @pdev: handle to the device instance
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	int result;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Disable RX PIPE", __func__);
+	result = ipa_suspend_wdi_pipe(ipa_res->rx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Suspend RX PIPE fail, code %d",
+				__func__, result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	result = ipa_disable_wdi_pipe(ipa_res->rx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Disable RX PIPE fail, code %d",
+				__func__, result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Disable TX PIPE", __func__);
+	result = ipa_suspend_wdi_pipe(ipa_res->tx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Suspend TX PIPE fail, code %d",
+				__func__, result);
+		return QDF_STATUS_E_FAILURE;
+	}
+	result = ipa_disable_wdi_pipe(ipa_res->tx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Disable TX PIPE fail, code %d",
+				__func__, result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_set_perf_level() - Set IPA clock bandwidth based on data rates
+ * @client: Client type
+ * @max_supported_bw_mbps: Maximum bandwidth needed (in Mbps)
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_set_perf_level(int client,
+				      uint32_t max_supported_bw_mbps)
+{
+	struct ipa_rm_perf_profile profile;
+	int result;
+
+	profile.max_supported_bandwidth_mbps = max_supported_bw_mbps;
+	result = ipa_rm_set_perf_profile(client, &profile);
+
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"Set perf profile failed, code %d", result);
+
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_METERING
+QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_pdev *ppdev,
+					   uint8_t reset_stats)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	int result;
+
+	result = htt_h2t_ipa_uc_get_share_stats(pdev->htt_pdev, reset_stats);
+
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Get IPA sharing stats failed, code %d", result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_pdev *ppdev,
+				     uint64_t quota_bytes)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	int result;
+
+	result = htt_h2t_ipa_uc_set_quota(pdev->htt_pdev, quota_bytes);
+
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Set IPA quota failed, code %d", result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#endif /* IPA_UC_OFFLOAD */

+ 132 - 0
core/dp/txrx/ol_txrx_ipa.h

@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _OL_TXRX_IPA_H_
+#define _OL_TXRX_IPA_H_
+
+#ifdef IPA_OFFLOAD
+
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
+#include <ol_txrx_types.h>
+
+/**
+ * struct frag_header - fragment header type registered to IPA hardware
+ * @length:    fragment length
+ * @reserved1: Reserved not used
+ * @reserved2: Reserved not used
+ *
+ */
+struct frag_header {
+	uint16_t length;
+	uint32_t reserved1;
+	uint32_t reserved2;
+} __packed;
+
+/**
+ * struct ipa_header - ipa header type registered to IPA hardware
+ * @vdev_id:  vdev id
+ * @reserved: Reserved not used
+ *
+ */
+struct ipa_header {
+	uint32_t
+		vdev_id:8,      /* vdev_id field is LSB of IPA DESC */
+		reserved:24;
+} __packed;
+
+/**
+ * struct ol_txrx_ipa_uc_tx_hdr - full tx header registered to IPA hardware
+ * @frag_hd: fragment header
+ * @ipa_hd:  ipa header
+ * @eth:     ether II header
+ *
+ */
+struct ol_txrx_ipa_uc_tx_hdr {
+	struct frag_header frag_hd;
+	struct ipa_header ipa_hd;
+	struct ethhdr eth;
+} __packed;
+
+/**
+ * struct ol_txrx_ipa_uc_rx_hdr - full rx header registered to IPA hardware
+ * @eth:     ether II header
+ *
+ */
+struct ol_txrx_ipa_uc_rx_hdr {
+	struct ethhdr eth;
+} __packed;
+
+#define OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE      14
+
+#define OL_TXRX_IPA_IPV4_NAME_EXT              "_ipv4"
+#define OL_TXRX_IPA_IPV6_NAME_EXT              "_ipv6"
+
+#define OL_TXRX_IPA_WLAN_FRAG_HEADER        sizeof(struct frag_header)
+#define OL_TXRX_IPA_WLAN_IPA_HEADER         sizeof(struct ipa_header)
+#define OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN      sizeof(struct ol_txrx_ipa_uc_tx_hdr)
+#define OL_TXRX_IPA_UC_WLAN_RX_HDR_LEN      sizeof(struct ol_txrx_ipa_uc_rx_hdr)
+#define OL_TXRX_IPA_UC_WLAN_HDR_DES_MAC_OFFSET \
+	(OL_TXRX_IPA_WLAN_FRAG_HEADER + OL_TXRX_IPA_WLAN_IPA_HEADER)
+
+#if defined(QCA_WIFI_3_0) && defined(CONFIG_IPA3)
+#define OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res) \
+	do { \
+		pipe_in.u.ul.rdy_ring_rp_va = \
+		ipa_res->rx_proc_done_idx_vaddr; \
+		pipe_in.u.ul.rdy_comp_ring_base_pa = \
+		ipa_res->rx2_rdy_ring_base_paddr;\
+		pipe_in.u.ul.rdy_comp_ring_size = \
+		ipa_res->rx2_rdy_ring_size; \
+		pipe_in.u.ul.rdy_comp_ring_wp_pa = \
+		ipa_res->rx2_proc_done_idx_paddr; \
+		pipe_in.u.ul.rdy_comp_ring_wp_va = \
+		ipa_res->rx2_proc_done_idx_vaddr; \
+	} while (0)
+#else
+/* Do nothing */
+#define OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res)
+#endif /* IPA3 */
+
+QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_pdev *pdev, bool uc_active,
+		bool is_tx);
+QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_pdev *pdev, uint8_t *op_msg);
+QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_pdev *pdev,
+		ipa_uc_op_cb_type op_cb, void *usr_ctxt);
+QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *pdev, void *ipa_i2w_cb,
+		void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb,
+		uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled,
+		uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle);
+QDF_STATUS ol_txrx_ipa_cleanup(uint32_t tx_pipe_handle,
+		uint32_t rx_pipe_handle);
+QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
+		enum ipa_client_type prod_client,
+		enum ipa_client_type cons_client,
+		uint8_t session_id, bool is_ipv6_enabled);
+QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled);
+QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_set_perf_level(int client,
+		uint32_t max_supported_bw_mbps);
+#ifdef FEATURE_METERING
+QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_pdev *pdev,
+		uint8_t reset_stats);
+QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_pdev *pdev,
+		uint64_t quota_bytes);
+#endif
+#endif
+#endif /* _OL_TXRX_IPA_H_*/

+ 7 - 6
core/dp/txrx/ol_txrx_types.h

@@ -406,7 +406,7 @@ enum throttle_phase {
 
 #define THROTTLE_TX_THRESHOLD (100)
 
-typedef void (*ipa_uc_op_cb_type)(uint8_t *op_msg, void *osif_ctxt);
+typedef void (*ipa_uc_op_cb_type)(uint8_t *op_msg, void *usr_ctxt);
 
 struct ol_tx_queue_group_t {
 	qdf_atomic_t credit;
@@ -918,11 +918,6 @@ struct ol_txrx_pdev_t {
 		bool is_paused;
 	} tx_throttle;
 
-#ifdef IPA_OFFLOAD
-	ipa_uc_op_cb_type ipa_uc_op_cb;
-	void *osif_dev;
-#endif /* IPA_UC_OFFLOAD */
-
 #if defined(FEATURE_TSO)
 	struct {
 		uint16_t pool_size;
@@ -979,6 +974,12 @@ struct ol_txrx_pdev_t {
 	} lro_info;
 	struct ol_txrx_peer_t *self_peer;
 	qdf_work_t peer_unmap_timer_work;
+
+#ifdef IPA_OFFLOAD
+	ipa_uc_op_cb_type ipa_uc_op_cb;
+	void *usr_ctxt;
+	struct ol_txrx_ipa_resources ipa_resource;
+#endif /* IPA_UC_OFFLOAD */
 };
 
 struct ol_txrx_vdev_t {

+ 1 - 1
core/hdd/inc/wlan_hdd_ipa.h

@@ -269,7 +269,7 @@ static inline void hdd_ipa_set_tx_flow_info(void)
  *
  * Return: 0 on success, negativer errno on error
  */
-static int hdd_ipa_uc_ol_deinit(hdd_context_t *hdd_ctx)
+static inline int hdd_ipa_uc_ol_deinit(hdd_context_t *hdd_ctx)
 {
 	return 0;
 }

Файловите разлики са ограничени, защото са твърде много
+ 125 - 514
core/hdd/src/wlan_hdd_ipa.c


+ 121 - 50
core/wma/src/wma_main.c

@@ -605,6 +605,99 @@ int wma_cli_set_command(int vdev_id, int param_id, int sval, int vpdev)
 
 }
 
+/**
+ * wma_ipa_get_stat() - get IPA data path stats from FW
+ *
+ * Return: 0 on success, errno on failure
+ */
+#ifdef IPA_OFFLOAD
+static int wma_ipa_get_stat(void)
+{
+	struct cdp_pdev *pdev;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("pdev NULL for uc stat");
+		return -EINVAL;
+	}
+	cdp_ipa_get_stat(cds_get_context(QDF_MODULE_ID_SOC), pdev);
+
+	return 0;
+}
+#else
+static int wma_ipa_get_stat(void)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wma_ipa_uc_get_share_stats() - get Tx/Rx byte stats from FW
+ * @privcmd: private command
+ *
+ * Return: 0 on success, errno on failure
+ */
+#if defined(IPA_OFFLOAD) && defined(FEATURE_METERING)
+static int wma_ipa_uc_get_share_stats(wma_cli_set_cmd_t *privcmd)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct cdp_pdev *pdev;
+	uint8_t reset_stats = privcmd->param_value;
+
+	WMA_LOGD("%s: reset_stats=%d",
+			"WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID",
+			reset_stats);
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("pdev NULL for uc get share stats");
+		return -EINVAL;
+	}
+	cdp_ipa_uc_get_share_stats(soc, pdev, reset_stats);
+
+	return 0;
+}
+#else
+static int wma_ipa_uc_get_share_stats(wma_cli_set_cmd_t *privcmd)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wma_ipa_uc_set_quota() - set quota limit to FW
+ * @privcmd: private command
+ *
+ * Return: 0 on success, errno on failure
+ */
+#if defined(IPA_OFFLOAD) && defined(FEATURE_METERING)
+static int wma_ipa_uc_set_quota(wma_cli_set_cmd_t *privcmd)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct cdp_pdev *pdev;
+	uint64_t quota_bytes = privcmd->param_sec_value;
+
+	quota_bytes <<= 32;
+	quota_bytes |= privcmd->param_value;
+
+	WMA_LOGD("%s: quota_bytes=%llu",
+			"WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID",
+			quota_bytes);
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("pdev NULL for uc set quota");
+		return -EINVAL;
+	}
+	cdp_ipa_uc_set_quota(soc, pdev, quota_bytes);
+
+	return 0;
+}
+#else
+static int wma_ipa_uc_set_quota(wma_cli_set_cmd_t *privcmd)
+{
+	return 0;
+}
+#endif
+
 /**
  * wma_set_priv_cfg() - set private config parameters
  * @wma_handle: wma handle
@@ -751,54 +844,20 @@ static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle,
 
 	case WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID:
 	{
-		void *soc = cds_get_context(QDF_MODULE_ID_SOC);
-		struct cdp_pdev *pdev;
-
-		pdev = cds_get_context(QDF_MODULE_ID_TXRX);
-		if (!pdev) {
-			WMA_LOGE("pdev NULL for uc stat");
-			return -EINVAL;
-		}
-		cdp_ipa_get_stat(soc, pdev);
+		wma_ipa_get_stat();
 	}
 		break;
 
 	case WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID:
 	{
-		void *soc = cds_get_context(QDF_MODULE_ID_SOC);
-		struct cdp_pdev *pdev;
-		uint8_t reset_stats = privcmd->param_value;
-
-		WMA_LOGE("%s: reset_stats=%d",
-			 "WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID",
-			 reset_stats);
-		pdev = cds_get_context(QDF_MODULE_ID_TXRX);
-		if (!pdev) {
-			WMA_LOGE("pdev NULL for uc stat");
-			return -EINVAL;
-		}
-		cdp_ipa_uc_get_share_stats(soc, pdev, reset_stats);
+		wma_ipa_uc_get_share_stats(privcmd);
 	}
 		break;
 
 	case WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID:
 	{
-		void *soc = cds_get_context(QDF_MODULE_ID_SOC);
-		struct cdp_pdev *pdev;
-		uint64_t quota_bytes = privcmd->param_sec_value;
-
-		quota_bytes <<= 32;
-		quota_bytes |= privcmd->param_value;
-
-		WMA_LOGE("%s: quota_bytes=%llu",
-			 "WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID",
-			 quota_bytes);
-		pdev = cds_get_context(QDF_MODULE_ID_TXRX);
-		if (!pdev) {
-			WMA_LOGE("pdev NULL for uc stat");
-			return -EINVAL;
-		}
-		cdp_ipa_uc_set_quota(soc, pdev, quota_bytes);
+		wma_ipa_uc_set_quota(privcmd);
+
 	}
 		break;
 
@@ -3826,6 +3885,28 @@ static void wma_alloc_host_mem(tp_wma_handle wma_handle, uint32_t req_id,
 	wma_handle->num_mem_chunks = idx;
 }
 
+/**
+ * wma_set_tx_partition_base() - set TX MSDU ID partition base for IPA
+ * @value:  TX MSDU ID partition base
+ *
+ * Return: none
+ */
+#ifdef IPA_OFFLOAD
+static void wma_set_tx_partition_base(uint32_t value)
+{
+	cdp_ipa_set_uc_tx_partition_base(
+			cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG),
+			value);
+	WMA_LOGD("%s: TX_MSDU_ID_PARTITION=%d", __func__,
+			value);
+}
+#else
+static void wma_set_tx_partition_base(uint32_t value)
+{
+}
+#endif
+
 /**
  * wma_update_target_services() - update target services from wma handle
  * @wh: wma handle
@@ -3920,19 +4001,9 @@ static inline void wma_update_target_services(tp_wma_handle wh,
 
 	if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
 			WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT)) {
-		cdp_ipa_set_uc_tx_partition_base(
-			cds_get_context(QDF_MODULE_ID_SOC),
-			(struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG),
-			HTT_TX_IPA_NEW_MSDU_ID_SPACE_BEGIN);
-		WMA_LOGD("%s: TX_MSDU_ID_NEW_PARTITION=%d", __func__,
-				HTT_TX_IPA_NEW_MSDU_ID_SPACE_BEGIN);
+		wma_set_tx_partition_base(HTT_TX_IPA_NEW_MSDU_ID_SPACE_BEGIN);
 	} else {
-		cdp_ipa_set_uc_tx_partition_base(
-			cds_get_context(QDF_MODULE_ID_SOC),
-			(struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG),
-			HTT_TX_IPA_MSDU_ID_SPACE_BEGIN);
-		WMA_LOGD("%s: TX_MSDU_ID_OLD_PARTITION=%d", __func__,
-				HTT_TX_IPA_MSDU_ID_SPACE_BEGIN);
+		wma_set_tx_partition_base(HTT_TX_IPA_MSDU_ID_SPACE_BEGIN);
 	}
 
 	wma_he_update_tgt_services(wh, cfg);

Някои файлове не бяха показани, защото твърде много файлове са промени