瀏覽代碼

qcacmn: Add optional wifi datapath feature ipa layer

This change adds the optional wifi datapath feature
to transfer data to and from modem via WLAN.
By using the existing path between WLAN and IPA, this
change registers new interfaces between IPA and WLAN
to reserve, add, delete and release rx filters,
which are required for setting up CCE filter rules.
These filters help to determine which packets need
to be routed to IPA specific REO rings.

Change-Id: I17c2ab77ae343f15d6b79fa02bb70ed62294089c
CRs-Fixed: 3403314
Namita Nair 2 年之前
父節點
當前提交
aab63b2b96

+ 62 - 2
dp/wifi3.0/dp_htt.c

@@ -32,7 +32,9 @@
 #endif
 #endif
 #include "qdf_mem.h"   /* qdf_mem_malloc,free */
 #include "qdf_mem.h"   /* qdf_mem_malloc,free */
 #include "cdp_txrx_cmn_struct.h"
 #include "cdp_txrx_cmn_struct.h"
-
+#ifdef IPA_OPT_WIFI_DP
+#include "cdp_txrx_ipa.h"
+#endif
 #ifdef FEATURE_PERPKT_INFO
 #ifdef FEATURE_PERPKT_INFO
 #include "dp_ratetable.h"
 #include "dp_ratetable.h"
 #endif
 #endif
@@ -776,6 +778,15 @@ fail0:
 qdf_export_symbol(htt_srng_setup);
 qdf_export_symbol(htt_srng_setup);
 
 
 #ifdef QCA_SUPPORT_FULL_MON
 #ifdef QCA_SUPPORT_FULL_MON
+/**
+ * htt_h2t_full_mon_cfg() - Send full monitor configuration msg to FW
+ *
+ * @htt_soc: HTT Soc handle
+ * @pdev_id: Radio id
+ * @config: enabled/disable configuration
+ *
+ * Return: Success when HTT message is sent, error on failure
+ */
 int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
 int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
 			 uint8_t pdev_id,
 			 uint8_t pdev_id,
 			 enum dp_full_mon_config config)
 			 enum dp_full_mon_config config)
@@ -1863,7 +1874,7 @@ dp_htt_set_pdev_obss_stats(struct dp_pdev *pdev, uint32_t tag_type,
 /**
 /**
  * dp_process_htt_stat_msg(): Process the list of buffers of HTT EXT stats
  * dp_process_htt_stat_msg(): Process the list of buffers of HTT EXT stats
  * @htt_stats: htt stats info
  * @htt_stats: htt stats info
- * @soc: DP soc
+ * @soc: dp_soc
  *
  *
  * The FW sends the HTT EXT STATS as a stream of T2H messages. Each T2H message
  * The FW sends the HTT EXT STATS as a stream of T2H messages. Each T2H message
  * contains sub messages which are identified by a TLV header.
  * contains sub messages which are identified by a TLV header.
@@ -2567,6 +2578,10 @@ static void dp_htt_alert_print(enum htt_t2h_msg_type msg_type,
  * @srng: DP_SRNG handle
  * @srng: DP_SRNG handle
  * @ring_type: srng src/dst ring
  * @ring_type: srng src/dst ring
  * @state: ring state
  * @state: ring state
+ * @pdev: pdev
+ * @srng: DP_SRNG handle
+ * @ring_type: srng src/dst ring
+ * @state: ring_state
  *
  *
  * Return: void
  * Return: void
  */
  */
@@ -2679,6 +2694,7 @@ dp_get_tcl_status_ring_state_from_hal(struct dp_pdev *pdev,
 
 
 /**
 /**
  * dp_queue_ring_stats() - Print pdev hal level ring stats
  * dp_queue_ring_stats() - Print pdev hal level ring stats
+ * dp_queue_ring_stats(): Print pdev hal level ring stats
  * @pdev: DP_pdev handle
  * @pdev: DP_pdev handle
  *
  *
  * Return: void
  * Return: void
@@ -3865,6 +3881,20 @@ void htt_soc_detach(struct htt_soc *htt_hdl)
 
 
 }
 }
 
 
+/**
+ * dp_h2t_ext_stats_msg_send(): function to construct HTT message to pass to FW
+ * @pdev: DP PDEV handle
+ * @stats_type_upload_mask: stats type requested by user
+ * @config_param_0: extra configuration parameters
+ * @config_param_1: extra configuration parameters
+ * @config_param_2: extra configuration parameters
+ * @config_param_3: extra configuration parameters
+ * @cookie_val: cookie value
+ * @cookie_msb: msb of debug status cookie
+ * @mac_id: mac number
+ *
+ * return: QDF STATUS
+ */
 QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev,
 QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev,
 		uint32_t stats_type_upload_mask, uint32_t config_param_0,
 		uint32_t stats_type_upload_mask, uint32_t config_param_0,
 		uint32_t config_param_1, uint32_t config_param_2,
 		uint32_t config_param_1, uint32_t config_param_2,
@@ -4108,6 +4138,22 @@ QDF_STATUS dp_h2t_hw_vdev_stats_config_send(struct dp_soc *dpsoc,
 }
 }
 #endif
 #endif
 
 
+/**
+ * dp_h2t_3tuple_config_send(): function to construct 3 tuple configuration
+ * HTT message to pass to FW
+ * @pdev: DP PDEV handle
+ * @tuple_mask: tuple configuration to report 3 tuple hash value in either
+ * toeplitz_2_or_4 or flow_id_toeplitz in MSDU START TLV.
+ * @mac_id: mac id
+ *
+ * tuple_mask[1:0]:
+ *   00 - Do not report 3 tuple hash value
+ *   10 - Report 3 tuple hash value in toeplitz_2_or_4
+ *   01 - Report 3 tuple hash value in flow_id_toeplitz
+ *   11 - Report 3 tuple hash value in both toeplitz_2_or_4 & flow_id_toeplitz
+ *
+ * return: QDF STATUS
+ */
 QDF_STATUS dp_h2t_3tuple_config_send(struct dp_pdev *pdev,
 QDF_STATUS dp_h2t_3tuple_config_send(struct dp_pdev *pdev,
 				     uint32_t tuple_mask, uint8_t mac_id)
 				     uint32_t tuple_mask, uint8_t mac_id)
 {
 {
@@ -4585,6 +4631,13 @@ dp_htt_rx_flow_fse_operation(struct dp_pdev *pdev,
 	return status;
 	return status;
 }
 }
 
 
+/**
+ * dp_htt_rx_fisa_config(): Send HTT msg to configure FISA
+ * @pdev: DP pdev handle
+ * @fisa_config: Fisa config struct
+ *
+ * Return: Success when HTT message is sent, error on failure
+ */
 QDF_STATUS
 QDF_STATUS
 dp_htt_rx_fisa_config(struct dp_pdev *pdev,
 dp_htt_rx_fisa_config(struct dp_pdev *pdev,
 		      struct dp_htt_rx_fisa_cfg *fisa_config)
 		      struct dp_htt_rx_fisa_cfg *fisa_config)
@@ -4679,6 +4732,13 @@ dp_htt_rx_fisa_config(struct dp_pdev *pdev,
 }
 }
 
 
 #ifdef WLAN_SUPPORT_PPEDS
 #ifdef WLAN_SUPPORT_PPEDS
+/**
+ * dp_htt_rxdma_rxole_ppe_cfg_set() - Send RxOLE and RxDMA PPE config
+ * @soc: Data path SoC handle
+ * @cfg: RxDMA and RxOLE PPE config
+ *
+ * Return: Success when HTT message is sent, error on failure
+ */
 QDF_STATUS
 QDF_STATUS
 dp_htt_rxdma_rxole_ppe_cfg_set(struct dp_soc *soc,
 dp_htt_rxdma_rxole_ppe_cfg_set(struct dp_soc *soc,
 			       struct dp_htt_rxdma_rxole_ppe_config *cfg)
 			       struct dp_htt_rxdma_rxole_ppe_config *cfg)

+ 7 - 2
dp/wifi3.0/dp_internal.h

@@ -2783,14 +2783,19 @@ void dp_peer_update_tid_stats_from_reo(struct dp_soc *soc, void *cb_ctxt,
 
 
 int dp_peer_get_rxtid_stats_ipa(struct dp_peer *peer,
 int dp_peer_get_rxtid_stats_ipa(struct dp_peer *peer,
 				dp_rxtid_stats_cmd_cb dp_stats_cmd_cb);
 				dp_rxtid_stats_cmd_cb dp_stats_cmd_cb);
-
+#ifdef IPA_OPT_WIFI_DP
+void dp_ipa_wdi_opt_dpath_notify_flt_rlsd(int flt0_rslt,
+					  int flt1_rslt);
+void dp_ipa_wdi_opt_dpath_notify_flt_add_rem_cb(int flt0_rslt, int flt1_rslt);
+void dp_ipa_wdi_opt_dpath_notify_flt_rsvd(bool is_success);
+#endif
+#ifdef QCA_ENHANCED_STATS_SUPPORT
 /**
 /**
  * dp_peer_aggregate_tid_stats - aggregate rx tid stats
  * dp_peer_aggregate_tid_stats - aggregate rx tid stats
  * @peer: Data Path peer
  * @peer: Data Path peer
  *
  *
  * Return: void
  * Return: void
  */
  */
-#ifdef QCA_ENHANCED_STATS_SUPPORT
 void dp_peer_aggregate_tid_stats(struct dp_peer *peer);
 void dp_peer_aggregate_tid_stats(struct dp_peer *peer);
 #endif
 #endif
 #else
 #else

+ 78 - 0
dp/wifi3.0/dp_ipa.c

@@ -18,6 +18,7 @@
 #ifdef IPA_OFFLOAD
 #ifdef IPA_OFFLOAD
 
 
 #include <wlan_ipa_ucfg_api.h>
 #include <wlan_ipa_ucfg_api.h>
+#include <wlan_ipa_core.h>
 #include <qdf_ipa_wdi3.h>
 #include <qdf_ipa_wdi3.h>
 #include <qdf_types.h>
 #include <qdf_types.h>
 #include <qdf_lock.h>
 #include <qdf_lock.h>
@@ -3364,6 +3365,83 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev,
 	return NULL;
 	return NULL;
 }
 }
 
 
+#ifdef IPA_OPT_WIFI_DP
+/**
+ * dp_ipa_rx_super_rule_setup()- pass cce super rule params to fw from ipa
+ *
+ * @soc_hdl: cdp soc
+ * @flt_params: filter tuple
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS dp_ipa_rx_super_rule_setup(struct cdp_soc_t *soc_hdl,
+				      void *flt_params)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+
+	return htt_h2t_rx_cce_super_rule_setup(soc->htt_handle, flt_params);
+}
+
+/**
+ * dp_ipa_wdi_opt_dpath_notify_flt_add_rem_cb()- send cce super rule filter
+ * add/remove result to ipa
+ *
+ * @flt0_rslt : result for filter0 add/remove
+ * @flt1_rslt : result for filter1 add/remove
+ *
+ * Return: void
+ */
+void dp_ipa_wdi_opt_dpath_notify_flt_add_rem_cb(int flt0_rslt, int flt1_rslt)
+{
+	wlan_ipa_wdi_opt_dpath_notify_flt_add_rem_cb(flt0_rslt, flt1_rslt);
+}
+
+int dp_ipa_pcie_link_up(struct cdp_soc_t *soc_hdl)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	struct hal_soc *hal_soc = (struct hal_soc *)soc->hal_soc;
+	int response = 0;
+
+	response = hif_prevent_l1((hal_soc->hif_handle));
+	return response;
+}
+
+void dp_ipa_pcie_link_down(struct cdp_soc_t *soc_hdl)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	struct hal_soc *hal_soc = (struct hal_soc *)soc->hal_soc;
+
+	hif_allow_l1(hal_soc->hif_handle);
+}
+
+/**
+ * dp_ipa_wdi_opt_dpath_notify_flt_rlsd()- send cce super rule release
+ * notification to ipa
+ *
+ * @flt0_rslt : result for filter0 release
+ * @flt1_rslt : result for filter1 release
+ *
+ *Return: void
+ */
+void dp_ipa_wdi_opt_dpath_notify_flt_rlsd(int flt0_rslt, int flt1_rslt)
+{
+	wlan_ipa_wdi_opt_dpath_notify_flt_rlsd(flt0_rslt, flt1_rslt);
+}
+
+/**
+ * dp_ipa_wdi_opt_dpath_notify_flt_rsvd()- send cce super rule reserve
+ * notification to ipa
+ *
+ *@is_success : result of filter reservatiom
+ *
+ *Return: void
+ */
+void dp_ipa_wdi_opt_dpath_notify_flt_rsvd(bool is_success)
+{
+	wlan_ipa_wdi_opt_dpath_notify_flt_rsvd(is_success);
+}
+#endif
+
 #ifdef IPA_WDS_EASYMESH_FEATURE
 #ifdef IPA_WDS_EASYMESH_FEATURE
 /**
 /**
  * dp_ipa_peer_check() - Check for peer for given mac
  * dp_ipa_peer_check() - Check for peer for given mac

+ 6 - 0
dp/wifi3.0/dp_ipa.h

@@ -351,6 +351,12 @@ QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
  */
  */
 QDF_STATUS dp_ipa_set_perf_level(int client, uint32_t max_supported_bw_mbps,
 QDF_STATUS dp_ipa_set_perf_level(int client, uint32_t max_supported_bw_mbps,
 				 qdf_ipa_wdi_hdl_t hdl);
 				 qdf_ipa_wdi_hdl_t hdl);
+#ifdef IPA_OPT_WIFI_DP
+QDF_STATUS dp_ipa_rx_super_rule_setup(struct cdp_soc_t *soc_hdl,
+				      void *flt_params);
+int dp_ipa_pcie_link_up(struct cdp_soc_t *soc_hdl);
+void dp_ipa_pcie_link_down(struct cdp_soc_t *soc_hdl);
+#endif
 
 
 /**
 /**
  * dp_ipa_rx_intrabss_fwd() - Perform intra-bss fwd for IPA RX path
  * dp_ipa_rx_intrabss_fwd() - Perform intra-bss fwd for IPA RX path

+ 8 - 0
dp/wifi3.0/dp_main.c

@@ -8423,6 +8423,9 @@ static void dp_peer_setup_get_reo_hash(struct dp_vdev *vdev,
 		} else if (vdev->opmode == wlan_op_mode_sta &&
 		} else if (vdev->opmode == wlan_op_mode_sta &&
 			   dp_ipa_is_mdm_platform()) {
 			   dp_ipa_is_mdm_platform()) {
 			*reo_dest = IPA_REO_DEST_RING_IDX + 1;
 			*reo_dest = IPA_REO_DEST_RING_IDX + 1;
+		} else if (vdev->opmode == wlan_op_mode_sta &&
+			   (!dp_ipa_is_mdm_platform())) {
+			dp_debug("opt_dp: default reo ring is set");
 		}
 		}
 	}
 	}
 }
 }
@@ -15150,6 +15153,11 @@ static struct cdp_ipa_ops dp_ops_ipa = {
 #ifdef QCA_ENHANCED_STATS_SUPPORT
 #ifdef QCA_ENHANCED_STATS_SUPPORT
 	.ipa_update_peer_rx_stats = dp_ipa_update_peer_rx_stats,
 	.ipa_update_peer_rx_stats = dp_ipa_update_peer_rx_stats,
 #endif
 #endif
+#ifdef IPA_OPT_WIFI_DP
+	.ipa_rx_super_rule_setup = dp_ipa_rx_super_rule_setup,
+	.ipa_pcie_link_up = dp_ipa_pcie_link,
+	.ipa_pcie_link_down = dp_ipa_pcie_link_down,
+#endif
 #ifdef IPA_WDS_EASYMESH_FEATURE
 #ifdef IPA_WDS_EASYMESH_FEATURE
 	.ipa_ast_create = dp_ipa_ast_create,
 	.ipa_ast_create = dp_ipa_ast_create,
 #endif
 #endif

+ 95 - 2
ipa/core/inc/wlan_ipa_core.h

@@ -1,6 +1,6 @@
 /*
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -432,7 +432,22 @@ static inline void wlan_ipa_update_tx_stats(struct wlan_ipa_priv *ipa_ctx,
 }
 }
 #endif /* FEATURE_METERING */
 #endif /* FEATURE_METERING */
 
 
-/**
+#ifdef IPA_OPT_WIFI_DP
+/*
+ * wlan_ipa_add_rem_flt_cb_event() - Set event to get notified when cce
+ * super rule filter is added/removed
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+void wlan_ipa_add_rem_flt_cb_event(struct wlan_ipa_priv *ipa_ctx);
+#else
+static inline void wlan_ipa_add_rem_flt_cb_event(struct wlan_ipa_priv *ipa_ctx)
+{
+}
+#endif /* IPA_OPT_WIFI_DP */
+
+/*
  * wlan_ipa_uc_stat() - Print IPA uC stats
  * wlan_ipa_uc_stat() - Print IPA uC stats
  * @ipa_ctx: IPA context
  * @ipa_ctx: IPA context
  *
  *
@@ -856,5 +871,83 @@ void wlan_ipa_fw_rejuvenate_send_msg(struct wlan_ipa_priv *ipa_ctx);
  */
  */
 void wlan_ipa_flush_pending_vdev_events(struct wlan_ipa_priv *ipa_ctx,
 void wlan_ipa_flush_pending_vdev_events(struct wlan_ipa_priv *ipa_ctx,
 					uint8_t vdev_id);
 					uint8_t vdev_id);
+
+#ifdef IPA_OPT_WIFI_DP
+/**
+ * wlan_ipa_wdi_opt_dpath_flt_rsrv_cb() - reserve cce super rules for Rx filter
+ * @ipa_ctx - ipa_context
+ * out_params - filter reservation params
+ *
+ * Return:int 0 on success, negative on failure
+ *
+ */
+int wlan_ipa_wdi_opt_dpath_flt_rsrv_cb(
+		       void *ipa_ctx,
+		       struct ipa_wdi_opt_dpath_flt_rsrv_cb_params *out_params);
+
+/**
+ * wlan_ipa_wdi_opt_dpath_notify_flt_rsvd() - notify filter reservation
+ * response to IPA
+ *
+ * @is_success : result of filter reservation
+ *
+ * @Return 0 on success, negative on failure
+ */
+int wlan_ipa_wdi_opt_dpath_notify_flt_rsvd(bool is_success);
+
+/**
+ * wlan_ipa_wdi_opt_dpath_flt_add_cb - Add rx filter tuple to cce filter
+ * @ipa_ctx: IPA context
+ * in_out - filter tuple info
+ *
+ * Return: 0 on success, negative on failure
+ */
+int wlan_ipa_wdi_opt_dpath_flt_add_cb(
+			    void *ipa_ctx,
+			    struct ipa_wdi_opt_dpath_flt_add_cb_params *in_out);
+
+/**
+ * wlan_ipa_wdi_opt_dpath_flt_rem_cb() - Remove rx filter tuple from cce filter
+ * @ipa_ctx: IPA context
+ * in - filter tuple info
+ *
+ * Return: 0 on success, negative on failure
+ */
+int wlan_ipa_wdi_opt_dpath_flt_rem_cb(
+			      void *ipa_ctx,
+			      struct ipa_wdi_opt_dpath_flt_rem_cb_params *in);
+
+/**
+ * wlan_ipa_wdi_opt_dpath_notify_flt_add_rem_cb() - notify filter add/remove
+ * result to IPA
+ *
+ * @result0 : result of add/remove filter0
+ * @result1 : result of add/remove filter1
+ *
+ * Return: void
+ */
+void wlan_ipa_wdi_opt_dpath_notify_flt_add_rem_cb(int result0, int result1);
+
+/**
+ * wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb() - cb to release cce super rules
+ * @ipa_ctx: IPA context
+ *
+ * Return: 0 on success, negative on failure
+ *
+ */
+int wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb(void *ipa_ctx);
+
+/**
+ * wlan_ipa_wdi_opt_dpath_notify_flt_rlsd() - notify filter release
+ * response to IPA
+ *
+ * @result0 : result of filter0 release
+ * @result1 : result of filter1 release
+ *
+ * @Return: 0 on success, negative on failure
+ */
+int wlan_ipa_wdi_opt_dpath_notify_flt_rlsd(int result0, int result1);
+
+#endif /* IPA_OPT_WIFI_DP */
 #endif /* IPA_OFFLOAD */
 #endif /* IPA_OFFLOAD */
 #endif /* _WLAN_IPA_CORE_H_ */
 #endif /* _WLAN_IPA_CORE_H_ */

+ 10 - 1
ipa/core/inc/wlan_ipa_priv.h

@@ -1,6 +1,6 @@
 /*
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -44,6 +44,9 @@
 #include "qdf_delayed_work.h"
 #include "qdf_delayed_work.h"
 #include <qdf_event.h>
 #include <qdf_event.h>
 #include "wlan_ipa_public_struct.h"
 #include "wlan_ipa_public_struct.h"
+#ifdef IPA_OPT_WIFI_DP
+#include "cdp_txrx_ipa.h"
+#endif
 
 
 #define WLAN_IPA_RX_INACTIVITY_MSEC_DELAY   1000
 #define WLAN_IPA_RX_INACTIVITY_MSEC_DELAY   1000
 #define WLAN_IPA_UC_WLAN_8023_HDR_SIZE      14
 #define WLAN_IPA_UC_WLAN_8023_HDR_SIZE      14
@@ -742,12 +745,18 @@ struct wlan_ipa_priv {
 
 
 	uint32_t wdi_version;
 	uint32_t wdi_version;
 	bool is_smmu_enabled;	/* IPA caps returned from ipa_wdi_init */
 	bool is_smmu_enabled;	/* IPA caps returned from ipa_wdi_init */
+	/* Flag to notify whether optional wifi dp feature is enabled or not */
+	bool opt_wifi_datapath;
 	qdf_atomic_t stats_quota;
 	qdf_atomic_t stats_quota;
 	uint8_t curr_bw_level;
 	uint8_t curr_bw_level;
 	qdf_atomic_t deinit_in_prog;
 	qdf_atomic_t deinit_in_prog;
 	uint8_t instance_id;
 	uint8_t instance_id;
 	bool handle_initialized;
 	bool handle_initialized;
 	qdf_ipa_wdi_hdl_t hdl;
 	qdf_ipa_wdi_hdl_t hdl;
+#ifdef IPA_OPT_WIFI_DP
+	struct wifi_dp_flt_setup dp_cce_super_rule_flt_param;
+	qdf_event_t ipa_flt_evnt;
+#endif
 };
 };
 
 
 #define WLAN_IPA_WLAN_FRAG_HEADER        sizeof(struct frag_header)
 #define WLAN_IPA_WLAN_FRAG_HEADER        sizeof(struct frag_header)

+ 436 - 6
ipa/core/src/wlan_ipa_core.c

@@ -30,6 +30,9 @@
 #include <wmi_unified_param.h>
 #include <wmi_unified_param.h>
 #include <wlan_osif_priv.h>
 #include <wlan_osif_priv.h>
 #include <net/cfg80211.h>
 #include <net/cfg80211.h>
+#ifdef IPA_OPT_WIFI_DP
+#include "init_deinit_lmac.h"
+#endif
 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
 #include <cdp_txrx_flow_ctrl_v2.h>
 #include <cdp_txrx_flow_ctrl_v2.h>
 #include <cdp_txrx_peer_ops.h>
 #include <cdp_txrx_peer_ops.h>
@@ -41,6 +44,15 @@
 #ifdef IPA_WDS_EASYMESH_FEATURE
 #ifdef IPA_WDS_EASYMESH_FEATURE
 #define IPA_TA_PEER_ID_ATTRI 2
 #define IPA_TA_PEER_ID_ATTRI 2
 #endif
 #endif
+#ifdef IPA_OPT_WIFI_DP
+#define IPA_WDI_MAX_FILTER 2
+#define IPV6BYTES 16 /* IPV6 addr: 128bits/8 = 16bytes */
+#define IPV4BYTES 4 /* IPV4 addr: 32bits/8 = 4bytes */
+#define DP_MAX_SLEEP_TIME 100
+#define IPV4 0x0008
+#define IPV6 0xdd86
+#define IPV6ARRAY 4
+#endif
 
 
 static struct wlan_ipa_priv *gp_ipa;
 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_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
@@ -141,11 +153,18 @@ static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
 	return true;
 	return true;
 }
 }
 #else
 #else
+#ifdef IPA_OPT_WIFI_DP
+static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
+{
+	return true;
+}
+#else
 static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
 static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
 {
 {
 	return false;
 	return false;
 }
 }
-#endif
+#endif /* IPA_OPT_WIFI_DP */
+#endif /* MDM_PLATFORM */
 
 
 /**
 /**
  * wlan_ipa_msg_free_fn() - Free an IPA message
  * wlan_ipa_msg_free_fn() - Free an IPA message
@@ -620,6 +639,29 @@ static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt,
 }
 }
 #endif
 #endif
 
 
+#ifdef IPA_OPT_WIFI_DP
+/**
+ * wlan_ipa_wdi_init_set_opt_wifi_dp - set if optional wifi dp feature enabled_
+ * @ipa_ctxt: IPA context
+ * @out: IPA WDI out param
+ *
+ * Return: void
+ */
+static inline void wlan_ipa_wdi_init_set_opt_wifi_dp(
+					     struct wlan_ipa_priv *ipa_ctxt,
+					     qdf_ipa_wdi_init_out_params_t out)
+{
+	ipa_ctx->opt_wifi_datapath =
+				QDF_IPA_WDI_INIT_OUT_PARAMS_OPT_WIFI_DP(&out);
+}
+#else
+static inline void wlan_ipa_wdi_init_set_opt_wifi_dp(
+					     struct wlan_ipa_priv *ipa_ctxt,
+					     qdf_ipa_wdi_init_out_params_t out)
+{
+}
+#endif
+
 #ifdef IPA_WDS_EASYMESH_FEATURE
 #ifdef IPA_WDS_EASYMESH_FEATURE
 /**
 /**
  * wlan_ipa_update_wds_params() - IPA update WDS parameters
  * wlan_ipa_update_wds_params() - IPA update WDS parameters
@@ -696,9 +738,12 @@ static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
 	ipa_ctx->is_smmu_enabled =
 	ipa_ctx->is_smmu_enabled =
 		QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out);
 		QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out);
 	ipa_ctx->hdl = QDF_IPA_WDI_INIT_OUT_PARAMS_HANDLE(&out);
 	ipa_ctx->hdl = QDF_IPA_WDI_INIT_OUT_PARAMS_HANDLE(&out);
+	wlan_ipa_wdi_init_set_opt_wifi_dp(ipa_ctx, &out);
 
 
 	ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d, handle: %d",
 	ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d, handle: %d",
 		 ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled, ipa_ctx->hdl);
 		 ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled, ipa_ctx->hdl);
+	ipa_info("opt_dp: enabled from IPA : %d",
+		 ipa_ctx->opt_wifi_datapath);
 
 
 	if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) {
 	if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) {
 		ipa_debug("IPA uC READY");
 		ipa_debug("IPA uC READY");
@@ -1683,9 +1728,14 @@ QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx)
 	qdf_event_reset(&ipa_ctx->ipa_resource_comp);
 	qdf_event_reset(&ipa_ctx->ipa_resource_comp);
 
 
 	if (qdf_atomic_read(&ipa_ctx->autonomy_disabled)) {
 	if (qdf_atomic_read(&ipa_ctx->autonomy_disabled)) {
-		cdp_ipa_enable_autonomy(ipa_ctx->dp_soc,
-					ipa_ctx->dp_pdev_id);
-		qdf_atomic_set(&ipa_ctx->autonomy_disabled, 0);
+		if (ipa_ctx->opt_wifi_datapath) {
+			/* Default packet routing is to HOST REO rings */
+			ipa_info("opt_dp: enable pipes. Do not enable autonomy");
+		} else {
+			cdp_ipa_enable_autonomy(ipa_ctx->dp_soc,
+						ipa_ctx->dp_pdev_id);
+			qdf_atomic_set(&ipa_ctx->autonomy_disabled, 0);
+		}
 	}
 	}
 end:
 end:
 	qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock);
 	qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock);
@@ -3903,6 +3953,59 @@ static void wlan_ipa_mcc_work_handler(void *data)
 }
 }
 #endif
 #endif
 
 
+#ifdef IPA_OPT_WIFI_DP
+/**
+ * wlan_ipa_reg_flt_cbs() - register filter cbs with IPA to set up Rx CCE filter
+ * rules for optional wifi datapath
+ * @ipa_ctx: IPA context
+ *
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static inline QDF_STATUS wlan_ipa_reg_flt_cbs(struct wlan_ipa_priv *ipa_ctx)
+{
+	QDF_STATUS status;
+
+	ipa_wdi_opt_dpath_flt_rsrv_cb flt_rsrv_cb =
+					    &wlan_ipa_wdi_opt_dpath_flt_rsrv_cb;
+	ipa_wdi_opt_dpath_flt_rsrv_rel_cb
+		flt_rsrv_rel_cb = &wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb;
+	ipa_wdi_opt_dpath_flt_rem_cb flt_rem_cb =
+					     &wlan_ipa_wdi_opt_dpath_flt_rem_cb;
+	ipa_wdi_opt_dpath_flt_add_cb flt_add_cb =
+					     &wlan_ipa_wdi_opt_dpath_flt_add_cb;
+
+	ipa_info("opt_dp: ipa_reg_flt_cb");
+	status = qdf_ipa_wdi_register_flt_cb(ipa_ctx->hdl, flt_rsrv_cb,
+					     flt_rsrv_rel_cb,
+					     flt_add_cb,
+					     flt_rem_cb);
+	return status;
+}
+
+/**
+ * wlan_ipa_destroy_opt_wifi_flt_cb_event - destroy filter cb event
+ * @ipa_ctx: IPA context
+ *
+ *Return: void
+ */
+static inline void wlan_ipa_destroy_opt_wifi_flt_cb_event(
+						  struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_event_destroy(&ipa_ctx->ipa_flt_evnt);
+}
+#else
+static inline QDF_STATUS wlan_ipa_reg_flt_cbs(struct wlan_ipa_priv *ipa_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void wlan_ipa_destroy_opt_wifi_flt_cb_event(
+						  struct wlan_ipa_priv *ipa_ctx)
+{
+}
+#endif
+
 /**
 /**
  * wlan_ipa_setup() - IPA initialization function
  * wlan_ipa_setup() - IPA initialization function
  * @ipa_ctx: IPA context
  * @ipa_ctx: IPA context
@@ -3982,6 +4085,13 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx,
 		ipa_ctx->wdi_enabled = false;
 		ipa_ctx->wdi_enabled = false;
 
 
 		status = wlan_ipa_wdi_init(ipa_ctx);
 		status = wlan_ipa_wdi_init(ipa_ctx);
+
+		/* Register call backs for opt wifi dp */
+		if (ipa_ctx->opt_wifi_datapath) {
+			status = wlan_ipa_reg_flt_cbs(ipa_ctx);
+			ipa_info("opt_dp: Register cb status %d", status);
+		}
+
 		if (status == QDF_STATUS_SUCCESS) {
 		if (status == QDF_STATUS_SUCCESS) {
 			/* Setup IPA system pipes */
 			/* Setup IPA system pipes */
 			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
 			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
@@ -4076,6 +4186,8 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx)
 	if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
 	if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
 
 
+	wlan_ipa_destroy_opt_wifi_flt_cb_event(ipa_ctx);
+
 	/* Teardown IPA sys_pipe for MCC */
 	/* Teardown IPA sys_pipe for MCC */
 	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
 	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
@@ -4222,7 +4334,7 @@ static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx)
 	ipa_info("TX buffers mapped to IPA");
 	ipa_info("TX buffers mapped to IPA");
 	cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id);
 	cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id);
 	wlan_ipa_init_metering(ipa_ctx);
 	wlan_ipa_init_metering(ipa_ctx);
-
+	wlan_ipa_add_rem_flt_cb_event(ipa_ctx);
 	if (QDF_IS_STATUS_ERROR(wlan_ipa_init_perf_level(ipa_ctx)))
 	if (QDF_IS_STATUS_ERROR(wlan_ipa_init_perf_level(ipa_ctx)))
 		ipa_err("Failed to init perf level");
 		ipa_err("Failed to init perf level");
 
 
@@ -4506,7 +4618,7 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx,
 		cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc,
 		cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc,
 					   ipa_ctx->dp_pdev_id);
 					   ipa_ctx->dp_pdev_id);
 		wlan_ipa_init_metering(ipa_ctx);
 		wlan_ipa_init_metering(ipa_ctx);
-
+		wlan_ipa_add_rem_flt_cb_event(ipa_ctx);
 		if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS)
 		if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS)
 			ipa_err("Failed to init perf level");
 			ipa_err("Failed to init perf level");
 	}
 	}
@@ -4752,3 +4864,321 @@ void wlan_ipa_flush_pending_vdev_events(struct wlan_ipa_priv *ipa_ctx,
 
 
 	qdf_mutex_release(&ipa_ctx->ipa_lock);
 	qdf_mutex_release(&ipa_ctx->ipa_lock);
 }
 }
+
+#ifdef IPA_OPT_WIFI_DP
+int wlan_ipa_wdi_opt_dpath_notify_flt_rsvd(bool response)
+{
+	ipa_info("opt_dp: IPA notify filter resrv response: %d", response);
+	return qdf_ipa_wdi_opt_dpath_notify_flt_rsvd_per_inst(gp_ipa->hdl,
+							      response);
+}
+
+int wlan_ipa_wdi_opt_dpath_flt_rsrv_cb(
+			void *ipa_ctx,
+			struct ipa_wdi_opt_dpath_flt_rsrv_cb_params *out_params)
+{
+	struct wifi_dp_flt_setup *dp_flt_params = NULL;
+	struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
+	int i;
+
+	ipa_info("opt_dp: Send filter reserve req");
+	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
+	dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_SETUP_REQUEST;
+	dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
+	for (i = 0; i < IPA_WDI_MAX_FILTER; i++) {
+		dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required = 0;
+		dp_flt_params->flt_addr_params[i].ipa_flt_in_use = false;
+	}
+	return cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
+}
+
+int wlan_ipa_wdi_opt_dpath_flt_add_cb(
+			     void *ipa_ctx,
+			     struct ipa_wdi_opt_dpath_flt_add_cb_params *in_out)
+{
+	struct ipa_wdi_opt_dpath_flt_add_cb_params *ipa_flt =
+			 (struct ipa_wdi_opt_dpath_flt_add_cb_params *)(in_out);
+	struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
+	int i, param_val, pdev_id;
+	uint8_t num_flts;
+	uint32_t src_ip_addr, dst_ip_addr;
+	uint32_t *host_ipv6;
+	int response = 0;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	struct wifi_dp_flt_setup *dp_flt_param = NULL;
+	void *htc_handle;
+
+	pdev = ipa_obj->pdev;
+	psoc = wlan_pdev_get_psoc(pdev);
+	pdev_id = ipa_obj->dp_pdev_id;
+	num_flts = ipa_flt->num_tuples;
+
+	htc_handle = lmac_get_htc_hdl(psoc);
+	if (!htc_handle) {
+		ipa_err("HTC Handle is null");
+		return QDF_STATUS_FILT_REQ_ERROR;
+	}
+
+	dp_flt_param = &(ipa_obj->dp_cce_super_rule_flt_param);
+
+	if (num_flts > IPA_WDI_MAX_FILTER) {
+		ipa_err("Wrong IPA flt count %d", num_flts);
+		return QDF_STATUS_FILT_REQ_ERROR;
+	}
+
+	/* Disable Low power features before filter addition */
+	ipa_info("opt_dp: Disable low power features to add filter param");
+	param_val = 0;
+	response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
+								param_val);
+	if (response) {
+		ipa_err("Low power feature disable failed. status %d",
+			response);
+		return QDF_STATUS_FILT_REQ_ERROR;
+	}
+	response = cdp_ipa_pcie_link_up(ipa_obj->dp_soc);
+	ipa_info("opt_dp: Pcie link up status %d", response);
+
+	/* set filter tuple params for rx filter */
+	for (i = 0; i < num_flts; i++) {
+		ipa_flt->flt_info[i].out_hdl = (WLAN_HDL_FILTER1 + i);
+		dp_flt_param->flt_addr_params[i].valid = 1;
+		dp_flt_param->flt_addr_params[i].flt_hdl =
+						ipa_flt->flt_info[i].out_hdl;
+		dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required = 1;
+		dp_flt_param->flt_addr_params[i].ipa_flt_in_use = true;
+
+		if (ipa_flt->flt_info[i].version == 0) {
+			dp_flt_param->flt_addr_params[i].l3_type = IPV4;
+		} else if (ipa_flt->flt_info[i].version == 1) {
+			dp_flt_param->flt_addr_params[i].l3_type = IPV6;
+		} else {
+			ipa_err("Wrong IPA version %d",
+				ipa_flt->flt_info[i].version);
+			return QDF_STATUS_FILT_REQ_ERROR;
+		}
+
+		if (dp_flt_param->flt_addr_params[i].l3_type == IPV4) {
+			src_ip_addr = qdf_ntohl(ipa_flt->flt_info[i].
+						ipv4_addr.ipv4_saddr);
+			dst_ip_addr = qdf_ntohl(ipa_flt->flt_info[i].
+						ipv4_addr.ipv4_daddr);
+			qdf_mem_copy(
+				dp_flt_param->flt_addr_params[i].src_ipv4_addr,
+				(&src_ip_addr),
+				IPV4BYTES);
+			qdf_mem_copy(
+				dp_flt_param->flt_addr_params[i].dst_ipv4_addr,
+				(&dst_ip_addr),
+				IPV4BYTES);
+			ipa_info("ipv4 src addr rxed from ipa 0x%x",
+				 ipa_flt->flt_info[i].ipv4_addr.ipv4_saddr);
+			ipa_info("ipv4 sent to FW 0x%x", src_ip_addr);
+		} else if (dp_flt_param->flt_addr_params[i].l3_type == IPV6) {
+			host_ipv6 = (uint32_t *)dp_flt_param->flt_addr_params[i].
+				    src_ipv6_addr;
+
+			for (j = 0; j < IPV6ARRAY; j++) {
+				src_ip_addr = qdf_ntohl(ipa_flt->flt_info[i].
+							ipv6_addr.ipv6_saddr[j]);
+				qdf_mem_copy(host_ipv6,
+					     &src_ip_addr,
+					     IPV6ARRAY);
+				host_ipv6++;
+			}
+			for (j = 0; j < IPV6ARRAY; j++) {
+				ipa_info("ipv6 src addr rxed from ipa 0x%x",
+					 ipa_flt->flt_info[i].ipv6_addr.
+					 ipv6_saddr[j]);
+			}
+			for (j = 0; j < IPV6ARRAY; j++)
+				ipa_info("ipv6 sent to FW 0x%x",
+					 *((uint32_t *)dp_flt_param->flt_addr_params[i].
+					 src_ipv6_addr + j));
+			/* Dest addr is currently not used in filter */
+		}
+	}
+
+	dp_flt_param->op = HTT_RX_CCE_SUPER_RULE_INSTALL;
+	dp_flt_param->pdev_id = ipa_obj->dp_pdev_id;
+	dp_flt_param->num_filters = num_flts;
+	qdf_event_reset(&ipa_obj->ipa_flt_evnt);
+
+	ipa_info("opt_dp: op %d, pdev_id %d. num_flts %d,",
+		 dp_flt_param->op, dp_flt_param->pdev_id, num_flts);
+	for (i = 0; i < num_flts; i++)
+		ipa_info("version %d, valid %d, src addr_ %08lx, evnt reqd %d",
+			 dp_flt_param->flt_addr_params[i].l3_type,
+			 dp_flt_param->flt_addr_params[i].valid,
+			 dp_flt_param->flt_addr_params[i].src_ipv4_addr,
+			 dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required);
+
+	cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_param);
+
+	qdf_wait_single_event(&ipa_obj->ipa_flt_evnt,
+			      DP_MAX_SLEEP_TIME);
+
+	for (i = 0; i < num_flts; i++)
+		dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required = 0;
+
+	response = dp_flt_param->ipa_flt_evnt_response;
+	if (response != QDF_STATUS_SUCCESS) {
+		if (response == QDF_STATUS_E_TIMEOUT)
+			qdf_err("TIMEOUT_OCCURS");
+		else
+			qdf_err("Error on event wait for filter add cb");
+	}
+	return response;
+}
+
+int wlan_ipa_wdi_opt_dpath_flt_rem_cb(
+				void *ipa_ctx,
+				struct ipa_wdi_opt_dpath_flt_rem_cb_params *in)
+{
+	struct ipa_wdi_opt_dpath_flt_rem_cb_params *rem_flt =
+			 (struct ipa_wdi_opt_dpath_flt_rem_cb_params *)(in);
+	struct wifi_dp_flt_setup *dp_flt_params = NULL;
+	struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	int pdev_id;
+	uint8_t num_flts;
+	uint32_t i, j, response = 0, param_val = 0;
+	void *htc_handle;
+
+	pdev = ipa_obj->pdev;
+	psoc = wlan_pdev_get_psoc(pdev);
+	pdev_id = ipa_obj->dp_pdev_id;
+	num_flts = rem_flt->num_tuples;
+
+	htc_handle = lmac_get_htc_hdl(psoc);
+	if (!htc_handle) {
+		ipa_err("HTC Handle is null");
+		return QDF_STATUS_FILT_REQ_ERROR;
+	}
+	/* Enable Low power features before filter deletion */
+	ipa_info("opt_dp: Enable low power features to delete filter param");
+	param_val = 1;
+	response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
+								param_val);
+	if (response) {
+		ipa_err("Low power feature enable failed. status %d", response);
+		return QDF_STATUS_FILT_REQ_ERROR;
+	}
+
+	response = cdp_ipa_pcie_link_up(ipa_obj->dp_soc);
+	ipa_info("opt_dp: Vote for PCIe link up");
+
+	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
+	for (i = 0; i < num_flts; i++) {
+		for (j = 0; j < IPA_WDI_MAX_FILTER; j++) {
+			if (rem_flt->hdl_info[i] ==
+				 dp_flt_params->flt_addr_params[j].flt_hdl) {
+				dp_flt_params->flt_addr_params[i].valid = 0;
+				qdf_mem_zero(dp_flt_params->flt_addr_params[i].
+					     src_ipv4_addr,
+					     IPV4BYTES);
+				qdf_mem_zero(dp_flt_params->flt_addr_params[i].
+					     src_ipv6_addr,
+					     IPV6BYTES);
+				dp_flt_params->flt_addr_params[i].
+						      ipa_flt_evnt_required = 1;
+				dp_flt_params->flt_addr_params[i].ipa_flt_in_use
+									= false;
+			}
+		}
+	}
+	dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_INSTALL;
+	dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
+	dp_flt_params->num_filters = IPA_WDI_MAX_FILTER;
+	qdf_event_reset(&ipa_obj->ipa_flt_evnt);
+
+	ipa_info("opt_dp: op %d, pdev_id %d. num_flts %d,",
+		 dp_flt_params->op, dp_flt_params->pdev_id, num_flts);
+	for (i = 0; i < num_flts; i++)
+		ipa_info("version %d, valid %d, src addr_ %08lx, evnt_reqd %d",
+			 dp_flt_params->flt_addr_params[i].l3_type,
+			 dp_flt_params->flt_addr_params[i].valid,
+			 dp_flt_params->flt_addr_params[i].src_ipv4_addr,
+			 dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required);
+
+	cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
+
+	qdf_wait_single_event(&ipa_obj->ipa_flt_evnt,
+			      DP_MAX_SLEEP_TIME);
+
+	for (i = 0; i < num_flts; i++)
+		dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required = 0;
+
+	response = dp_flt_params->ipa_flt_evnt_response;
+	if (response != QDF_STATUS_SUCCESS) {
+		if (response == QDF_STATUS_E_TIMEOUT)
+			qdf_err("TIMEOUT_OCCURS");
+		else
+			qdf_err("Error on event wait for filter rem cb");
+	}
+	return response;
+}
+
+int wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb(void *ipa_ctx)
+{
+	struct wifi_dp_flt_setup *dp_flt_params = NULL;
+	struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
+	int i;
+
+	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
+	for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
+		 dp_flt_params->flt_addr_params[i].valid = 0;
+	dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_RELEASE;
+	dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
+	dp_flt_params->num_filters = IPA_WDI_MAX_FILTER;
+	return cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
+}
+
+int wlan_ipa_wdi_opt_dpath_notify_flt_rlsd(int flt0_rslt,
+					   int flt1_rslt)
+{
+	struct wifi_dp_flt_setup *dp_flt_params = NULL;
+	struct wlan_ipa_priv *ipa_obj = gp_ipa;
+	bool result = false;
+
+	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
+
+	if ((dp_flt_params->flt_addr_params[0].ipa_flt_in_use == true &&
+	     flt0_rslt == 0) ||
+	    (dp_flt_params->flt_addr_params[1].ipa_flt_in_use == true &&
+	     flt1_rslt == 0))
+		result = false;
+	else {
+		dp_flt_params->flt_addr_params[0].ipa_flt_in_use = false;
+		dp_flt_params->flt_addr_params[1].ipa_flt_in_use = false;
+		result = true;
+	}
+
+	ipa_info("opt_dp: ipa_flt_event_release is_success: %d", result);
+	return qdf_ipa_wdi_opt_dpath_notify_flt_rlsd_per_inst(ipa_obj->hdl,
+								result);
+}
+
+void wlan_ipa_wdi_opt_dpath_notify_flt_add_rem_cb(int flt0_rslt, int flt1_rslt)
+{
+	struct wifi_dp_flt_setup *dp_flt_params = NULL;
+	struct wlan_ipa_priv *ipa_obj = gp_ipa;
+
+	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
+
+	if ((dp_flt_params->flt_addr_params[0].ipa_flt_evnt_required == 1 &&
+	     flt0_rslt == 0) ||
+	    (dp_flt_params->flt_addr_params[1].ipa_flt_evnt_required == 1 &&
+	     flt1_rslt == 0))
+			dp_flt_params->ipa_flt_evnt_response =
+						      QDF_STATUS_FILT_REQ_ERROR;
+	else
+			dp_flt_params->ipa_flt_evnt_response =
+							     QDF_STATUS_SUCCESS;
+	ipa_info("opt_dp: ipa_flt_event_response set status: %d",
+		 dp_flt_params->ipa_flt_evnt_response);
+	qdf_event_set(&ipa_obj->ipa_flt_evnt);
+}
+#endif /* IPA_OPT_WIFI_DP */

+ 8 - 1
ipa/core/src/wlan_ipa_rm.c

@@ -1,6 +1,6 @@
 /*
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -134,6 +134,13 @@ void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx)
 }
 }
 #endif
 #endif
 
 
+#ifdef IPA_OPT_WIFI_DP
+void wlan_ipa_add_rem_flt_cb_event(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_event_create(&ipa_ctx->ipa_flt_evnt);
+}
+#endif
+
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) && \
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) && \
 	!defined(CONFIG_IPA_WDI_UNIFIED_API)
 	!defined(CONFIG_IPA_WDI_UNIFIED_API)
 /**
 /**

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

@@ -1,6 +1,6 @@
 /*
 /*
  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -80,6 +80,20 @@ enum wlan_ipa_wlan_event {
 	WLAN_IPA_WLAN_EVENT_MAX
 	WLAN_IPA_WLAN_EVENT_MAX
 };
 };
 
 
+#ifdef IPA_OPT_WIFI_DP
+/**
+ * enum wlan_ipa_cce_super_rule_flt_hdl - Filter hdl values for cce super rules
+ * @WLAN_HDL_FILTER1 : Handle for filter1
+ * @WLAN_HDL_FILTER2 : Handle for filter 2
+ * @WLAN_HDL_MAX_FILTER : Max value for filter handle
+ */
+enum wlan_ipa_cce_super_rule_flt_hdl {
+	WLAN_HDL_FILTER1 = 0xC,
+	WLAN_HDL_FILTER2 = 0xD,
+	WLAN_HDL_MAX_FILTER
+};
+#endif
+
 /**
 /**
  * struct ipa_uc_offload_control_params - ipa offload control params
  * struct ipa_uc_offload_control_params - ipa offload control params
  * @offload_type: ipa offload type
  * @offload_type: ipa offload type