ソースを参照

qcacmn: IPA changes to support SDX+Pine

IPA changes to support SDX+Pine.

Change-Id: I66ad2a2c3e2f142c54df3e35c867ee827ac1d687
CRs-Fixed: 3079952
Himanshu Batra 3 年 前
コミット
78fb9d70d7

+ 17 - 1
ipa/core/inc/wlan_ipa_core.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -541,6 +542,21 @@ void wlan_ipa_reg_sap_xmit_cb(struct wlan_ipa_priv *ipa_ctx,
 	ipa_ctx->softap_xmit = cb;
 }
 
+/**
+ * wlan_ipa_reg_is_driver_unloading_cb() - Register cb to check if driver
+ * is unloading
+ * @ipa_ctx: IPA context
+ * @cb: callback
+ *
+ * Return: None
+ */
+static inline
+void wlan_ipa_reg_is_driver_unloading_cb(struct wlan_ipa_priv *ipa_ctx,
+					 wlan_ipa_driver_unloading cb)
+{
+	ipa_ctx->driver_is_unloading = cb;
+}
+
 /**
  * wlan_ipa_reg_send_to_nw_cb() - Register cb to send IPA Rx packet to network
  * @ipa_ctx: IPA context
@@ -717,7 +733,7 @@ QDF_STATUS wlan_ipa_suspend(struct wlan_ipa_priv *ipa_ctx);
  */
 QDF_STATUS wlan_ipa_resume(struct wlan_ipa_priv *ipa_ctx);
 
-#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+#if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
 /**
  * wlan_ipa_send_mcc_scc_msg() - Send IPA WLAN_SWITCH_TO_MCC/SCC message
  * @ipa_ctx: IPA context

+ 12 - 0
ipa/core/inc/wlan_ipa_main.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -291,6 +292,16 @@ void ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev,
 			   wlan_ipa_rps_enable cb);
 #endif
 
+/**
+ * ipa_reg_is_driver_unloading_cb() - Register cb to check if driver is
+ *                                    unloading
+ * @pdev: pdev obj
+ * @cb: callback
+ *
+ * Return: None
+ */
+void ipa_reg_is_driver_unloading_cb(struct wlan_objmgr_pdev *pdev,
+				    wlan_ipa_driver_unloading cb);
 /**
  * ipa_set_mcc_mode() - Set MCC mode
  * @pdev: pdev obj
@@ -543,6 +554,7 @@ void ipa_init_deinit_unlock(void);
 typedef QDF_STATUS (*wlan_ipa_softap_xmit)(qdf_nbuf_t nbuf, qdf_netdev_t dev);
 typedef void (*wlan_ipa_send_to_nw)(qdf_nbuf_t nbuf, qdf_netdev_t dev);
 typedef void (*wlan_ipa_rps_enable)(uint8_t vdev_id, bool enable);
+typedef bool (*wlan_ipa_driver_unloading)(void);
 
 #endif /* IPA_OFFLOAD */
 #endif /* end  of _WLAN_IPA_MAIN_H_ */

+ 5 - 5
ipa/core/inc/wlan_ipa_priv.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -196,7 +197,7 @@ struct wlan_ipa_tx_hdr {
  */
 #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
     defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) || \
-    defined(QCA_WIFI_WCN7850)
+    defined(QCA_WIFI_WCN7850) || defined(QCA_WIFI_QCN9000)
 struct frag_header {
 	uint8_t reserved[0];
 };
@@ -223,7 +224,7 @@ struct frag_header {
 
 #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
     defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) || \
-    defined(QCA_WIFI_WCN7850)
+    defined(QCA_WIFI_WCN7850) || defined(QCA_WIFI_QCN9000)
 struct ipa_header {
 	uint8_t reserved[0];
 };
@@ -598,6 +599,7 @@ struct wlan_ipa_tx_desc {
 
 typedef QDF_STATUS (*wlan_ipa_softap_xmit)(qdf_nbuf_t nbuf, qdf_netdev_t dev);
 typedef void (*wlan_ipa_send_to_nw)(qdf_nbuf_t nbuf, qdf_netdev_t dev);
+typedef bool (*wlan_ipa_driver_unloading)(void);
 
 /**
  * typedef wlan_ipa_rps_enable - Enable/disable RPS for adapter using vdev id
@@ -711,14 +713,12 @@ struct wlan_ipa_priv {
 
 	wlan_ipa_softap_xmit softap_xmit;
 	wlan_ipa_send_to_nw send_to_nw;
-	ipa_uc_offload_control_req ipa_tx_op;
-	ipa_intrabss_control_req ipa_intrabss_op;
 
 #ifdef QCA_CONFIG_RPS
 	/*Callback to enable RPS for STA in STA+SAP scenario*/
 	wlan_ipa_rps_enable rps_enable;
 #endif
-
+	wlan_ipa_driver_unloading driver_is_unloading;
 	qdf_event_t ipa_resource_comp;
 
 	uint32_t wdi_version;

+ 95 - 51
ipa/core/src/wlan_ipa_core.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -19,20 +20,33 @@
 /* Include Files */
 #include "wlan_ipa_core.h"
 #include "wlan_ipa_main.h"
-#include "wlan_hdd_main.h"
-#include <ol_txrx.h>
 #include "cdp_txrx_ipa.h"
+#include "cdp_txrx_ctrl.h"
 #include "wal_rx_desc.h"
 #include "qdf_str.h"
-#include "sir_api.h"
 #include "host_diag_core_event.h"
 #include "wlan_objmgr_vdev_obj.h"
 #include "qdf_platform.h"
+#include <wmi_unified_param.h>
+#include <wlan_osif_priv.h>
+#include <net/cfg80211.h>
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+#include <cdp_txrx_flow_ctrl_v2.h>
+#include <cdp_txrx_peer_ops.h>
+#endif
 
+#define IPA_SPS_DESC_SIZE 8
 static struct wlan_ipa_priv *gp_ipa;
 static void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
 static void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
 
+static inline
+bool wlan_ipa_is_driver_unloading(struct wlan_ipa_priv *ipa_ctx)
+{
+	if (ipa_ctx->driver_is_unloading)
+		return ipa_ctx->driver_is_unloading();
+	return false;
+}
 
 static struct wlan_ipa_iface_2_client {
 	qdf_ipa_client_type_t cons_client;
@@ -289,7 +303,7 @@ static void wlan_ipa_send_pkt_to_tl(
 		ipa_ctx->stats.num_tx_desc_q_cnt++;
 		qdf_spin_unlock_bh(&ipa_ctx->q_lock);
 		/* Store Tx Desc index into SKB CB */
-		QDF_NBUF_CB_TX_IPA_PRIV(skb) = tx_desc->id;
+		qdf_nbuf_ipa_priv_set(skb, tx_desc->id);
 	} else {
 		ipa_ctx->stats.num_tx_desc_error++;
 		qdf_spin_unlock_bh(&ipa_ctx->q_lock);
@@ -306,7 +320,7 @@ static void wlan_ipa_send_pkt_to_tl(
 		return;
 	}
 
-	skb = cdp_ipa_tx_send_data_frame(cds_get_context(QDF_MODULE_ID_SOC),
+	skb = cdp_ipa_tx_send_data_frame(ipa_ctx->dp_soc,
 					 iface_context->session_id,
 					 QDF_IPA_RX_DATA_SKB(ipa_tx_desc));
 	if (skb) {
@@ -386,6 +400,38 @@ static void wlan_ipa_forward(struct wlan_ipa_priv *ipa_ctx,
  *
  */
 
+#ifndef QCA_IPA_LL_TX_FLOW_CONTROL
+static inline
+bool wlan_ipa_tx_desc_thresh_reached(struct cdp_soc_t *soc, uint8_t vdev_id)
+{
+	return cdp_tx_desc_thresh_reached(soc, vdev_id);
+}
+
+static inline
+bool wlan_ipa_get_peer_state(struct cdp_soc_t *soc, uint8_t vdev_id,
+			     uint8_t *peer_mac)
+{
+	if (cdp_peer_state_get(soc, vdev_id, peer_mac) ==
+	    OL_TXRX_PEER_STATE_AUTH)
+		return true;
+
+	return false;
+}
+#else
+static inline
+bool wlan_ipa_tx_desc_thresh_reached(struct cdp_soc_t *soc, uint8_t vdev_id)
+{
+	return false;
+}
+
+static inline
+bool wlan_ipa_get_peer_state(struct cdp_soc_t *soc, uint8_t vdev_id,
+			     uint8_t *peer_mac)
+{
+	return cdp_peer_get_authorize(soc, vdev_id, peer_mac);
+}
+#endif
+
 static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward(
 		struct wlan_ipa_priv *ipa_ctx,
 		struct wlan_ipa_iface_context *iface_ctx,
@@ -393,10 +439,11 @@ static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward(
 		qdf_nbuf_t skb)
 {
 	int ret = WLAN_IPA_FORWARD_PKT_NONE;
-	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *soc = ipa_ctx->dp_soc;
 
 	if ((desc & FW_RX_DESC_FORWARD_M)) {
-		if (cdp_tx_desc_thresh_reached(soc, iface_ctx->session_id)) {
+		if (wlan_ipa_tx_desc_thresh_reached(soc,
+						    iface_ctx->session_id)) {
 			/* Drop the packet*/
 			ipa_ctx->stats.num_tx_fwd_err++;
 			goto drop_pkt;
@@ -436,7 +483,7 @@ drop_pkt:
  */
 #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
     defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) || \
-    defined(QCA_WIFI_WCN7850)
+    defined(QCA_WIFI_WCN7850) || defined(QCA_WIFI_QCN9000)
 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
 {
 	ipa_ctx->wdi_version = IPA_WDI_3;
@@ -916,38 +963,35 @@ wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx,
  *
  * Return: 0 on success, err_code for failure.
  */
-static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb)
+static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb,
+					 struct wlan_objmgr_pdev *pdev)
 {
 	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
-	struct hdd_context *hdd_ctx;
-	struct hdd_adapter *adapter;
 	struct ethhdr *eh;
-
-	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
-	if (!hdd_ctx) {
-		ipa_err_rl("Invalid hdd_context");
-		return -EINVAL;
-	}
+	struct wlan_objmgr_vdev *vdev = NULL;
 
 	eh = (struct ethhdr *)qdf_nbuf_data(skb);
-	adapter = hdd_get_adapter_by_macaddr(hdd_ctx, eh->h_dest);
-	if (hdd_validate_adapter(adapter)) {
-		ipa_err_rl("Invalid adapter");
+	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(
+				pdev, eh->h_dest, WLAN_IPA_ID);
+	if (!vdev) {
+		ipa_err_rl("Invalid vdev");
 		return -EINVAL;
 	}
-	if (adapter->device_mode != QDF_STA_MODE) {
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) {
 		ipa_err_rl("device_mode is not STA");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID);
 		return -EINVAL;
 	}
 
 	skb->destructor = wlan_ipa_uc_rt_debug_destructor;
 
 	if (ipa_ctx->send_to_nw)
-		ipa_ctx->send_to_nw(skb, adapter->dev);
+		ipa_ctx->send_to_nw(skb, vdev->vdev_nif.osdev->wdev->netdev);
 
 	ipa_ctx->ipa_rx_net_send_count++;
 	ipa_ctx->stats.num_rx_no_iface_eapol++;
-
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID);
 	return 0;
 }
 
@@ -1058,7 +1102,8 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
 
 			if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) {
 				ipa_err_rl("EAPOL pkt. Sending to NW!");
-				if (!wlan_ipa_send_sta_eapol_to_nw(skb))
+				if (!wlan_ipa_send_sta_eapol_to_nw(
+						skb, ipa_ctx->pdev))
 					break;
 			}
 			ipa_err_rl("Pkt Dropped!");
@@ -1106,10 +1151,10 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
 		 * non-EAPOL/WAPI frames to be intrabss forwarded
 		 * or submitted to stack.
 		 */
-		if (cdp_peer_state_get(ipa_ctx->dp_soc,
-				       iface_context->session_id,
-				       &peer_mac_addr.bytes[0]) !=
-		    OL_TXRX_PEER_STATE_AUTH && !is_eapol_wapi) {
+		if (!wlan_ipa_get_peer_state(ipa_ctx->dp_soc,
+					     iface_context->session_id,
+					     &peer_mac_addr.bytes[0]) &&
+		    !is_eapol_wapi) {
 			ipa_err_rl("Non EAPOL/WAPI packet received when peer " QDF_MAC_ADDR_FMT " is unauthorized",
 				   QDF_MAC_ADDR_REF(peer_mac_addr.bytes));
 			ipa_ctx->ipa_rx_internal_drop_count++;
@@ -1189,7 +1234,7 @@ static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
 }
 #endif /* MDM_PLATFORM */
 
-#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+#if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
 
 /**
  * __wlan_ipa_i2w_cb() - IPA to WLAN callback
@@ -1600,7 +1645,7 @@ static void wlan_ipa_cleanup_iface(struct wlan_ipa_iface_context *iface_context,
 	ipa_debug("exit: num_iface=%d", iface_context->ipa_ctx->num_iface);
 }
 
-#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+#if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
 
 /**
  * wlan_ipa_nbuf_cb() - IPA TX complete callback
@@ -1643,7 +1688,7 @@ static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb)
 	}
 
 	/* Get Tx desc pointer from SKB CB */
-	id = QDF_NBUF_CB_TX_IPA_PRIV(skb);
+	id = qdf_nbuf_ipa_priv_get(skb);
 	tx_desc = &ipa_ctx->tx_desc_pool[id];
 	ipa_tx_desc = tx_desc->ipa_tx_desc_ptr;
 
@@ -1822,7 +1867,7 @@ end:
 
 #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
     defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) || \
-    defined(QCA_WIFI_WCN7850)
+    defined(QCA_WIFI_WCN7850) || defined(QCA_WIFI_QCN9000)
 
 #ifdef QCA_CONFIG_RPS
 void ipa_set_rps(struct wlan_ipa_priv *ipa_ctx, enum QDF_OPMODE mode,
@@ -2252,7 +2297,7 @@ void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx,
 
 			if (iface_ctx->device_mode == QDF_SAP_MODE) {
 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-							SIR_AP_RX_DATA_OFFLOAD,
+							WMI_AP_RX_DATA_OFFLOAD,
 							iface_ctx->session_id,
 							true);
 				break;
@@ -2266,7 +2311,7 @@ void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx,
 
 			if (iface_ctx->device_mode == QDF_SAP_MODE) {
 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-							SIR_AP_RX_DATA_OFFLOAD,
+							WMI_AP_RX_DATA_OFFLOAD,
 							iface_ctx->session_id,
 							false);
 			}
@@ -2375,7 +2420,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 
 			if (type == QDF_IPA_AP_DISCONNECT) {
 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-						SIR_AP_RX_DATA_OFFLOAD,
+						WMI_AP_RX_DATA_OFFLOAD,
 						session_id, false);
 			} else if (type == QDF_IPA_CLIENT_CONNECT_EX &&
 				   wlan_sap_no_client_connected(ipa_ctx)) {
@@ -2386,7 +2431,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 				    !wlan_ipa_is_sta_only_offload_enabled()) {
 					wlan_ipa_uc_offload_enable_disable(
 							ipa_ctx,
-							SIR_STA_RX_DATA_OFFLOAD,
+							WMI_STA_RX_DATA_OFFLOAD,
 							sta_session_id, true);
 				}
 			}
@@ -2505,7 +2550,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 		    !ipa_ctx->sta_connected) {
 			qdf_mutex_release(&ipa_ctx->event_lock);
 			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-				SIR_STA_RX_DATA_OFFLOAD, session_id,
+				WMI_STA_RX_DATA_OFFLOAD, session_id,
 				true);
 			qdf_mutex_acquire(&ipa_ctx->event_lock);
 			qdf_atomic_set(&ipa_ctx->stats_quota, 1);
@@ -2522,7 +2567,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 				ipa_info("handle 1st conn failed %d", status);
 				wlan_ipa_uc_offload_enable_disable(
 						ipa_ctx,
-						SIR_STA_RX_DATA_OFFLOAD,
+						WMI_STA_RX_DATA_OFFLOAD,
 						session_id,
 						false);
 				ipa_ctx->vdev_to_iface[session_id] =
@@ -2576,7 +2621,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 				wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type);
 			} else {
 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-							SIR_AP_RX_DATA_OFFLOAD,
+							WMI_AP_RX_DATA_OFFLOAD,
 							session_id, true);
 			}
 			qdf_mutex_acquire(&ipa_ctx->event_lock);
@@ -2628,7 +2673,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 			    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
 			    !ipa_ctx->ipa_pipes_down &&
 			    (ipa_ctx->resource_unloading == false)) {
-				if (cds_is_driver_unloading()) {
+				if (wlan_ipa_is_driver_unloading(ipa_ctx)) {
 					/*
 					 * We disable WDI pipes directly here
 					 * since IPA_OPCODE_TX/RX_SUSPEND
@@ -2650,7 +2695,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 			qdf_atomic_set(&ipa_ctx->stats_quota, 0);
 			qdf_mutex_release(&ipa_ctx->event_lock);
 			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-				SIR_STA_RX_DATA_OFFLOAD, session_id, false);
+				WMI_STA_RX_DATA_OFFLOAD, session_id, false);
 			qdf_mutex_acquire(&ipa_ctx->event_lock);
 		}
 
@@ -2679,7 +2724,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 		    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
 		    !ipa_ctx->ipa_pipes_down &&
 		    (ipa_ctx->resource_unloading == false)) {
-			if (cds_is_driver_unloading()) {
+			if (wlan_ipa_is_driver_unloading(ipa_ctx)) {
 				/*
 				 * We disable WDI pipes directly here since
 				 * IPA_OPCODE_TX/RX_SUSPEND message will not be
@@ -2701,7 +2746,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
 			qdf_mutex_release(&ipa_ctx->event_lock);
 			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-				SIR_AP_RX_DATA_OFFLOAD, session_id, false);
+				WMI_AP_RX_DATA_OFFLOAD, session_id, false);
 			qdf_mutex_acquire(&ipa_ctx->event_lock);
 			ipa_ctx->vdev_to_iface[session_id] =
 				WLAN_IPA_MAX_SESSION;
@@ -2751,7 +2796,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 			    !wlan_ipa_is_sta_only_offload_enabled()) {
 				qdf_mutex_release(&ipa_ctx->event_lock);
 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-							SIR_STA_RX_DATA_OFFLOAD,
+							WMI_STA_RX_DATA_OFFLOAD,
 							sta_session_id, true);
 				qdf_mutex_acquire(&ipa_ctx->event_lock);
 				qdf_atomic_set(&ipa_ctx->stats_quota, 1);
@@ -2777,7 +2822,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 					qdf_mutex_release(&ipa_ctx->event_lock);
 					wlan_ipa_uc_offload_enable_disable(
 							ipa_ctx,
-							SIR_STA_RX_DATA_OFFLOAD,
+							WMI_STA_RX_DATA_OFFLOAD,
 							sta_session_id, false);
 				} else {
 					qdf_mutex_release(&ipa_ctx->event_lock);
@@ -2867,7 +2912,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 			if ((false == ipa_ctx->resource_unloading) &&
 			    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
 			    !ipa_ctx->ipa_pipes_down) {
-				if (cds_is_driver_unloading()) {
+				if (wlan_ipa_is_driver_unloading(ipa_ctx)) {
 					/*
 					 * We disable WDI pipes directly here
 					 * since IPA_OPCODE_TX/RX_SUSPEND
@@ -2897,7 +2942,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 				qdf_atomic_set(&ipa_ctx->stats_quota, 0);
 				qdf_mutex_release(&ipa_ctx->event_lock);
 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
-							SIR_STA_RX_DATA_OFFLOAD,
+							WMI_STA_RX_DATA_OFFLOAD,
 							sta_session_id, false);
 			} else {
 				qdf_mutex_release(&ipa_ctx->event_lock);
@@ -3090,7 +3135,7 @@ wlan_ipa_uc_proc_pending_event(struct wlan_ipa_priv *ipa_ctx, bool is_loading)
 	}
 }
 
-#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+#if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
 
 /**
  * wlan_ipa_free_tx_desc_list() - Free IPA Tx desc list
@@ -3412,8 +3457,7 @@ static int wlan_ipa_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
 	 * Because of above requirement, one extra descriptor will be added to
 	 * make sure hardware always has one descriptor.
 	 */
-	desc_fifo_sz = ipa_ctx->config->desc_size
-		       + SPS_DESC_SIZE;
+	desc_fifo_sz = ipa_ctx->config->desc_size + IPA_SPS_DESC_SIZE;
 
 	ret = wlan_ipa_setup_tx_sys_pipe(ipa_ctx, desc_fifo_sz);
 	if (ret) {
@@ -3442,7 +3486,7 @@ setup_sys_pipe_fail:
 	return ret;
 }
 
-#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+#if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
 QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
 				     bool mcc_mode)
 {

+ 23 - 0
ipa/core/src/wlan_ipa_main.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -378,6 +379,28 @@ void ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev,
 }
 #endif
 
+void ipa_reg_is_driver_unloading_cb(struct wlan_objmgr_pdev *pdev,
+				    wlan_ipa_driver_unloading cb)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	if (!ipa_cb_is_ready())
+		return;
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_reg_is_driver_unloading_cb(ipa_obj, cb);
+}
+
 void ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode)
 {
 	struct wlan_ipa_priv *ipa_obj;

+ 1 - 8
ipa/dispatcher/inc/wlan_ipa_public_struct.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -96,12 +97,4 @@ struct ipa_intrabss_control_params {
 	uint32_t vdev_id;
 	uint32_t enable;
 };
-
-/* fp to send IPA UC offload cmd */
-typedef QDF_STATUS (*ipa_uc_offload_control_req)(struct wlan_objmgr_psoc *psoc,
-				struct ipa_uc_offload_control_params *req);
-/* fp to send IPA intrabss cmd */
-typedef QDF_STATUS (*ipa_intrabss_control_req)(struct wlan_objmgr_psoc *psoc,
-				struct ipa_intrabss_control_params *req);
-
 #endif /* end  of _WLAN_IPA_PUBLIC_STRUCT_H_ */

+ 18 - 0
ipa/dispatcher/inc/wlan_ipa_ucfg_api.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -194,6 +195,17 @@ void ucfg_ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev,
 }
 #endif
 
+/**
+ * ucfg_ipa_reg_is_driver_unloading_cb() - Register cb to check if driver
+ * is unloading
+ * @pdev: pdev obj
+ * @cb: callback
+ *
+ * Return: None
+ */
+void ucfg_ipa_reg_is_driver_unloading_cb(struct wlan_objmgr_pdev *pdev,
+					 wlan_ipa_driver_unloading cb);
+
 /**
  * ucfg_ipa_set_mcc_mode() - Set MCC mode
  * @pdev: pdev obj
@@ -519,6 +531,12 @@ void ucfg_ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev,
 {
 }
 
+static inline
+void ucfg_ipa_reg_is_driver_unloading_cb(struct wlan_objmgr_pdev *pdev,
+					 wlan_ipa_driver_unloading cb)
+{
+}
+
 static inline
 void ucfg_ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode)
 {

+ 6 - 2
ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018, 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -25,6 +26,7 @@
 #include "target_if_ipa.h"
 #include "wlan_ipa_ucfg_api.h"
 #include "qdf_platform.h"
+#include "qdf_module.h"
 
 static bool g_ipa_is_ready;
 static qdf_mutex_t g_init_deinit_lock;
@@ -39,6 +41,8 @@ void ipa_disable_register_cb(void)
 	g_ipa_is_ready = false;
 }
 
+qdf_export_symbol(ipa_disable_register_cb);
+
 void ipa_init_deinit_lock(void)
 {
 	qdf_mutex_acquire(&g_init_deinit_lock);
@@ -124,8 +128,6 @@ ipa_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
 	}
 
 	ipa_obj->pdev = pdev;
-	target_if_ipa_register_tx_ops(&ipa_obj->ipa_tx_op);
-	target_if_ipa_register_intrabss_ops(&ipa_obj->ipa_intrabss_op);
 
 	ipa_debug("ipa pdev attached");
 
@@ -222,6 +224,8 @@ QDF_STATUS ipa_register_is_ipa_ready(struct wlan_objmgr_pdev *pdev)
 	return QDF_STATUS_SUCCESS;
 }
 
+qdf_export_symbol(ipa_register_is_ipa_ready);
+
 QDF_STATUS ipa_init(void)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;

+ 22 - 16
ipa/dispatcher/src/wlan_ipa_tgt_api.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018, 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -24,26 +25,29 @@
 #include "wlan_ipa_public_struct.h"
 #include <wlan_objmgr_global_obj.h>
 #include <wlan_objmgr_pdev_obj.h>
+#include <wlan_lmac_if_def.h>
 
 QDF_STATUS tgt_ipa_uc_offload_enable_disable(struct wlan_objmgr_pdev *pdev,
 				struct ipa_uc_offload_control_params *req)
 {
-	struct wlan_ipa_priv *ipa_obj;
 	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_tx_ops *tx_ops;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 
 	IPA_ENTER();
 
-	ipa_obj = ipa_pdev_get_priv_obj(pdev);
-	if (!ipa_obj) {
-		ipa_err("IPA object is NULL");
-		return QDF_STATUS_E_INVAL;
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		ipa_err("NULL psoc");
+		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	psoc = wlan_pdev_get_psoc(pdev);
+	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
+	if (!tx_ops)
+		return QDF_STATUS_E_NULL_VALUE;
 
-	if (ipa_obj->ipa_tx_op)
-		status = ipa_obj->ipa_tx_op(psoc, req);
+	if (tx_ops->ipa_ops.ipa_uc_offload_control_req)
+		status = tx_ops->ipa_ops.ipa_uc_offload_control_req(psoc, req);
 
 	IPA_EXIT();
 	return status;
@@ -53,22 +57,24 @@ QDF_STATUS
 tgt_ipa_intrabss_enable_disable(struct wlan_objmgr_pdev *pdev,
 				struct ipa_intrabss_control_params *req)
 {
-	struct wlan_ipa_priv *ipa_obj;
 	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_tx_ops *tx_ops;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 
 	IPA_ENTER();
 
-	ipa_obj = ipa_pdev_get_priv_obj(pdev);
-	if (!ipa_obj) {
-		ipa_err("IPA object is NULL");
-		return QDF_STATUS_E_INVAL;
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		ipa_err("NULL psoc");
+		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	psoc = wlan_pdev_get_psoc(pdev);
+	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
+	if (!tx_ops)
+		return QDF_STATUS_E_NULL_VALUE;
 
-	if (ipa_obj->ipa_intrabss_op)
-		status = ipa_obj->ipa_intrabss_op(psoc, req);
+	if (tx_ops->ipa_ops.ipa_intrabss_control_req)
+		status = tx_ops->ipa_ops.ipa_intrabss_control_req(psoc, req);
 
 	IPA_EXIT();
 	return status;

+ 88 - 1
ipa/dispatcher/src/wlan_ipa_ucfg_api.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -22,156 +23,216 @@
 #include "wlan_ipa_ucfg_api.h"
 #include "wlan_ipa_main.h"
 #include "cfg_ucfg_api.h"
-
+#include "qdf_module.h"
 
 bool ucfg_ipa_is_present(void)
 {
 	return ipa_is_hw_support();
 }
 
+qdf_export_symbol(ucfg_ipa_is_present);
+
 bool ucfg_ipa_is_ready(void)
 {
 	return ipa_cb_is_ready();
 }
 
+qdf_export_symbol(ucfg_ipa_is_ready);
+
 bool ucfg_ipa_is_enabled(void)
 {
 	return ipa_config_is_enabled();
 }
 
+qdf_export_symbol(ucfg_ipa_is_enabled);
+
 bool ucfg_ipa_uc_is_enabled(void)
 {
 	return ipa_config_is_uc_enabled();
 }
 
+qdf_export_symbol(ucfg_ipa_uc_is_enabled);
+
 void ucfg_ipa_set_pdev_id(struct wlan_objmgr_psoc *psoc,
 			  uint8_t pdev_id)
 {
 	return ipa_set_pdev_id(psoc, pdev_id);
 }
 
+qdf_export_symbol(ucfg_ipa_set_pdev_id);
+
 void ucfg_ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc,
 				     void *dp_soc)
 {
 	return ipa_set_dp_handle(psoc, dp_soc);
 }
 
+qdf_export_symbol(ucfg_ipa_set_dp_handle);
+
 QDF_STATUS ucfg_ipa_set_perf_level(struct wlan_objmgr_pdev *pdev,
 				   uint64_t tx_packets, uint64_t rx_packets)
 {
 	return ipa_rm_set_perf_level(pdev, tx_packets, rx_packets);
 }
 
+qdf_export_symbol(ucfg_ipa_set_perf_level);
+
 void ucfg_ipa_uc_info(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_uc_info(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_info);
+
 void ucfg_ipa_uc_stat(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_uc_stat(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_stat);
+
 void ucfg_ipa_uc_rt_debug_host_dump(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_uc_rt_debug_host_dump(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_rt_debug_host_dump);
+
 void ucfg_ipa_dump_info(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_dump_info(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_dump_info);
+
 void ucfg_ipa_uc_stat_request(struct wlan_objmgr_pdev *pdev,
 			      uint8_t reason)
 {
 	return ipa_uc_stat_request(pdev, reason);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_stat_request);
+
 void ucfg_ipa_uc_stat_query(struct wlan_objmgr_pdev *pdev,
 			    uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff)
 {
 	return ipa_uc_stat_query(pdev, ipa_tx_diff, ipa_rx_diff);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_stat_query);
+
 void ucfg_ipa_reg_sap_xmit_cb(struct wlan_objmgr_pdev *pdev,
 			      wlan_ipa_softap_xmit cb)
 {
 	return ipa_reg_sap_xmit_cb(pdev, cb);
 }
 
+qdf_export_symbol(ucfg_ipa_reg_sap_xmit_cb);
+
 void ucfg_ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev,
 				wlan_ipa_send_to_nw cb)
 {
 	return ipa_reg_send_to_nw_cb(pdev, cb);
 }
 
+qdf_export_symbol(ucfg_ipa_reg_send_to_nw_cb);
+
 #ifdef QCA_CONFIG_RPS
 void ucfg_ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev,
 				wlan_ipa_rps_enable cb)
 {
 	return ipa_reg_rps_enable_cb(pdev, cb);
 }
+
+qdf_export_symbol(ucfg_ipa_reg_rps_enable_cb);
 #endif
 
+void ucfg_ipa_reg_is_driver_unloading_cb(struct wlan_objmgr_pdev *pdev,
+					 wlan_ipa_driver_unloading cb)
+{
+	return ipa_reg_is_driver_unloading_cb(pdev, cb);
+}
+
 void ucfg_ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode)
 {
 	return ipa_set_mcc_mode(pdev, mcc_mode);
 }
 
+qdf_export_symbol(ucfg_ipa_set_mcc_mode);
+
 void ucfg_ipa_set_dfs_cac_tx(struct wlan_objmgr_pdev *pdev, bool tx_block)
 {
 	return ipa_set_dfs_cac_tx(pdev, tx_block);
 }
 
+qdf_export_symbol(ucfg_ipa_set_dfs_cac_tx);
+
 void ucfg_ipa_set_ap_ibss_fwd(struct wlan_objmgr_pdev *pdev, uint8_t session_id,
 			      bool intra_bss)
 {
 	return ipa_set_ap_ibss_fwd(pdev, session_id, intra_bss);
 }
 
+qdf_export_symbol(ucfg_ipa_set_ap_ibss_fwd);
+
 void ucfg_ipa_uc_force_pipe_shutdown(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_uc_force_pipe_shutdown(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_force_pipe_shutdown);
+
 void ucfg_ipa_flush(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_flush(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_flush);
+
 QDF_STATUS ucfg_ipa_suspend(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_suspend(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_suspend);
+
 QDF_STATUS ucfg_ipa_resume(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_resume(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_resume);
+
 QDF_STATUS ucfg_ipa_uc_ol_init(struct wlan_objmgr_pdev *pdev,
 			       qdf_device_t osdev)
 {
 	return ipa_uc_ol_init(pdev, osdev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_ol_init);
+
 QDF_STATUS ucfg_ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_uc_ol_deinit(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_ol_deinit);
+
 bool ucfg_ipa_is_tx_pending(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_is_tx_pending(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_is_tx_pending);
+
 QDF_STATUS ucfg_ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev,
 				     bool mcc_mode)
 {
 	return ipa_send_mcc_scc_msg(pdev, mcc_mode);
 }
 
+qdf_export_symbol(ucfg_ipa_send_mcc_scc_msg);
+
 QDF_STATUS ucfg_ipa_wlan_evt(struct wlan_objmgr_pdev *pdev,
 			     qdf_netdev_t net_dev, uint8_t device_mode,
 			     uint8_t session_id,
@@ -182,67 +243,93 @@ QDF_STATUS ucfg_ipa_wlan_evt(struct wlan_objmgr_pdev *pdev,
 			    ipa_event_type, mac_addr, is_2g_iface);
 }
 
+qdf_export_symbol(ucfg_ipa_wlan_evt);
+
 int ucfg_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
 {
 	return ipa_uc_smmu_map(map, num_buf, buf_arr);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_smmu_map);
+
 bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_is_fw_wdi_activated(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_is_fw_wdi_activated);
+
 void ucfg_ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
 			     qdf_netdev_t net_dev)
 {
 	return ipa_uc_cleanup_sta(pdev, net_dev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_cleanup_sta);
+
 QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
 				     qdf_netdev_t net_dev)
 {
 	return ipa_uc_disconnect_ap(pdev, net_dev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_disconnect_ap);
+
 void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
 				qdf_netdev_t net_dev)
 {
 	return ipa_cleanup_dev_iface(pdev, net_dev);
 }
 
+qdf_export_symbol(ucfg_ipa_cleanup_dev_iface);
+
 void ucfg_ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_uc_ssr_cleanup(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_uc_ssr_cleanup);
+
 void ucfg_ipa_fw_rejuvenate_send_msg(struct wlan_objmgr_pdev *pdev)
 {
 	return ipa_fw_rejuvenate_send_msg(pdev);
 }
 
+qdf_export_symbol(ucfg_ipa_fw_rejuvenate_send_msg);
+
 void ucfg_ipa_component_config_update(struct wlan_objmgr_psoc *psoc)
 {
 	ipa_component_config_update(psoc);
 }
 
+qdf_export_symbol(ucfg_ipa_component_config_update);
+
 void ucfg_ipa_component_config_free(void)
 {
 	ipa_component_config_free();
 }
 
+qdf_export_symbol(ucfg_ipa_component_config_free);
+
 uint32_t ucfg_ipa_get_tx_buf_count(void)
 {
 	return ipa_get_tx_buf_count();
 }
 
+qdf_export_symbol(ucfg_ipa_get_tx_buf_count);
+
 void ucfg_ipa_update_tx_stats(struct wlan_objmgr_pdev *pdev, uint64_t sta_tx,
 			      uint64_t ap_tx)
 {
 	ipa_update_tx_stats(pdev, sta_tx, ap_tx);
 }
 
+qdf_export_symbol(ucfg_ipa_update_tx_stats);
+
 void ucfg_ipa_flush_pending_vdev_events(struct wlan_objmgr_pdev *pdev,
 					uint8_t vdev_id)
 {
 	ipa_flush_pending_vdev_events(pdev, vdev_id);
 }
+
+qdf_export_symbol(ucfg_ipa_flush_pending_vdev_events);

+ 14 - 0
target_if/core/src/target_if_main.c

@@ -95,6 +95,9 @@
 #endif
 
 #include <target_if_gpio.h>
+#ifdef IPA_OFFLOAD
+#include <target_if_ipa.h>
+#endif
 
 #ifdef WLAN_MGMT_RX_REO_SUPPORT
 #include <target_if_mgmt_txrx.h>
@@ -516,6 +519,16 @@ target_if_mlo_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
 }
 #endif
 
+#ifdef IPA_OFFLOAD
+static void target_if_ipa_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
+{
+	target_if_ipa_register_tx_ops(tx_ops);
+}
+#else
+static void target_if_ipa_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
+{ }
+#endif
+
 static
 QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 {
@@ -568,6 +581,7 @@ QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 
 	target_if_mlo_tx_ops_register(tx_ops);
 
+	target_if_ipa_tx_ops_register(tx_ops);
 	/* Converged UMAC components to register their TX-ops here */
 	return QDF_STATUS_SUCCESS;
 }

+ 5 - 14
target_if/ipa/inc/target_if_ipa.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -27,24 +28,14 @@
 #ifdef IPA_OFFLOAD
 
 #include "wlan_ipa_public_struct.h"
-
 /**
  * target_if_ipa_register_tx_ops() - Register IPA component TX OPS
- * @ipa_tx_op: IPA if transmit op
- *
- * Return: None
- */
-void target_if_ipa_register_tx_ops(ipa_uc_offload_control_req *ipa_tx_op);
-
-/**
- * target_if_ipa_register_intrabss_ops() - Register IPA component INTRABSS OPS
- * @ipa_intrabss_op: IPA if intrabss transmit op
+ * @tx_ops: pointer to tx_ops structure
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-void
-target_if_ipa_register_intrabss_ops(ipa_intrabss_control_req *ipa_intrabss_op);
-
+QDF_STATUS
+target_if_ipa_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
 #endif /* IPA_OFFLOAD */
 #endif /* _TARGET_IF_IPA_H_ */
 

+ 18 - 11
target_if/ipa/src/target_if_ipa.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -44,14 +45,7 @@ target_if_ipa_uc_offload_control_req(struct wlan_objmgr_psoc *psoc,
 			get_wmi_unified_hdl_from_psoc(psoc), req);
 }
 
-void target_if_ipa_register_tx_ops(ipa_uc_offload_control_req *ipa_tx_op)
-{
-	*ipa_tx_op = target_if_ipa_uc_offload_control_req;
-}
-
 /**
- * target_if_ipa_intrabss_control_req() - send IPA intrabss control to FW
- * @psoc: pointer to PSOC object
  * @req: IPA intra bss enable/disable control param
  *
  * Return: QDF_STATUS_SUCCESS on success
@@ -69,14 +63,27 @@ target_if_ipa_intrabss_control_req(struct wlan_objmgr_psoc *psoc,
 		return QDF_STATUS_E_FAILURE;
 
 	param.vdev_id = req->vdev_id;
-	param.param_id = WMI_VDEV_PARAM_INTRA_BSS_FWD;
+	param.param_id = wmi_vdev_param_intra_bss_fwd;
 	param.param_value = req->enable;
 
 	return wmi_unified_vdev_set_param_send(wmi_handle, &param);
 }
 
-void
-target_if_ipa_register_intrabss_ops(ipa_intrabss_control_req *ipa_intrabss_op)
+QDF_STATUS
+target_if_ipa_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 {
-	*ipa_intrabss_op = target_if_ipa_intrabss_control_req;
+	struct wlan_lmac_if_ipa_tx_ops *ipa_ops;
+
+	if (!tx_ops) {
+		target_if_err("tx ops is NULL!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ipa_ops = &tx_ops->ipa_ops;
+
+	ipa_ops->ipa_uc_offload_control_req =
+			target_if_ipa_uc_offload_control_req;
+	ipa_ops->ipa_intrabss_control_req = target_if_ipa_intrabss_control_req;
+
+	return QDF_STATUS_SUCCESS;
 }

+ 18 - 0
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -54,6 +54,10 @@
 #endif
 #include <wlan_mgmt_txrx_rx_reo_public_structs.h>
 
+#ifdef IPA_OFFLOAD
+#include <wlan_ipa_public_struct.h>
+#endif
+
 /* Number of dev type: Direct attach and Offload */
 #define MAX_DEV_TYPE 2
 
@@ -1212,6 +1216,16 @@ struct wlan_lmac_if_gpio_tx_ops {
 };
 #endif
 
+#ifdef IPA_OFFLOAD
+struct wlan_lmac_if_ipa_tx_ops {
+	QDF_STATUS (*ipa_uc_offload_control_req)(
+				struct wlan_objmgr_psoc *psoc,
+				struct ipa_uc_offload_control_params *req);
+	QDF_STATUS (*ipa_intrabss_control_req)(
+				struct wlan_objmgr_psoc *psoc,
+				struct ipa_intrabss_control_params *req);
+};
+#endif
 /**
  * wlan_lmac_if_son_tx_ops: son tx operations
  * son_send_null: send null packet
@@ -1385,6 +1399,10 @@ struct wlan_lmac_if_tx_ops {
 #ifdef WLAN_FEATURE_11BE_MLO
 	struct wlan_lmac_if_mlo_tx_ops mlo_ops;
 #endif
+
+#ifdef IPA_OFFLOAD
+	struct wlan_lmac_if_ipa_tx_ops ipa_ops;
+#endif
 };
 
 /**