瀏覽代碼

qcacmn: AST entry create and update support for IPA

To support WDS feature in IPA driver, WLAN needs
to update the ast entry for any new rx packet, and for
end-nodes connected via repeater to root.

CRs-Fixed: 3226348
Change-Id: I7383b12f18e7c70ec06499d66130667eca033131
Devender Kumar 3 年之前
父節點
當前提交
277054124d

+ 33 - 3
dp/inc/cdp_txrx_ipa.h

@@ -406,6 +406,7 @@ cdp_ipa_disable_autonomy(ol_txrx_soc_handle soc, uint8_t pdev_id)
  * @over_gsi: Is IPA using GSI
  * @hdl: IPA handle
  * @id: IPA instance id
+ * @ipa_ast_notify_cb: IPA to WLAN callback for ast create
  *
  * Return: QDF_STATUS
  */
@@ -415,7 +416,8 @@ cdp_ipa_setup(ol_txrx_soc_handle soc, uint8_t pdev_id, void *ipa_i2w_cb,
 	      uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled,
 	      uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle,
 	      bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in,
-	      bool over_gsi, qdf_ipa_wdi_hdl_t hdl, qdf_ipa_wdi_hdl_t id)
+	      bool over_gsi, qdf_ipa_wdi_hdl_t hdl, qdf_ipa_wdi_hdl_t id,
+	      void *ipa_ast_notify_cb)
 {
 	if (!soc || !soc->ops || !soc->ops->ipa_ops) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
@@ -432,7 +434,8 @@ cdp_ipa_setup(ol_txrx_soc_handle soc, uint8_t pdev_id, void *ipa_i2w_cb,
 						    tx_pipe_handle,
 						    rx_pipe_handle,
 						    is_smmu_enabled,
-						    sys_in, over_gsi, hdl, id);
+						    sys_in, over_gsi, hdl, id,
+						    ipa_ast_notify_cb);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -726,7 +729,34 @@ cdp_ipa_tx_buf_smmu_unmapping(ol_txrx_soc_handle soc, uint8_t pdev_id)
 
 	return QDF_STATUS_SUCCESS;
 }
+
+#ifdef IPA_WDS_EASYMESH_FEATURE
+/**
+ * cdp_ipa_ast_create() - Create/update AST entry in AST table
+ *			  for learning/roaming packets from IPA
+ * @soc: data path soc handle
+ * @data: Structure used for updating the AST table
+ *
+ * Create/update AST entry in AST table for learning/roaming packets from IPA
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+cdp_ipa_ast_create(ol_txrx_soc_handle soc, qdf_ipa_ast_info_type_t *data)
+{
+	if (!soc || !soc->ops || !soc->ops->ipa_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (soc->ops->ipa_ops->ipa_ast_create)
+		return soc->ops->ipa_ops->ipa_ast_create(soc, data);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 #endif /* IPA_OFFLOAD */
 
 #endif /* _CDP_TXRX_IPA_H_ */
-

+ 13 - 2
dp/inc/cdp_txrx_ops.h

@@ -1333,10 +1333,15 @@ struct ol_if_ops {
 			       uint8_t vdev_id, uint8_t *peer_mac_addr,
 			       enum cdp_txrx_ast_entry_type peer_type,
 			       uint32_t tx_ast_hashidx);
+#ifdef IPA_OFFLOAD
+	int (*peer_unmap_event)(struct cdp_ctrl_objmgr_psoc *psoc,
+				uint16_t peer_id,
+				uint8_t vdev_id, uint8_t *mac_addr);
+#else
 	int (*peer_unmap_event)(struct cdp_ctrl_objmgr_psoc *psoc,
 				uint16_t peer_id,
 				uint8_t vdev_id);
-
+#endif
 	int (*get_dp_cfg_param)(struct cdp_ctrl_objmgr_psoc *psoc,
 				enum cdp_cfg_param_type param_num);
 
@@ -1870,6 +1875,7 @@ struct cdp_throttle_ops {
  * @ipa_tx_buf_smmu_mapping: Create SMMU mappings for Tx
  * @ipa_tx_buf_smmu_unmapping: Release SMMU mappings for Tx
  * buffers to IPA
+ * @ipa_ast_create: Create/Update ast entry
  */
 struct cdp_ipa_ops {
 	QDF_STATUS (*ipa_get_resource)(struct cdp_soc_t *soc_hdl,
@@ -1916,7 +1922,8 @@ struct cdp_ipa_ops {
 				uint32_t *rx_pipe_handle, bool is_smmu_enabled,
 				qdf_ipa_sys_connect_params_t *sys_in,
 				bool over_gsi, qdf_ipa_wdi_hdl_t hdl,
-				qdf_ipa_wdi_hdl_t id);
+				qdf_ipa_wdi_hdl_t id,
+				void *ipa_ast_notify_cb);
 #else /* CONFIG_IPA_WDI_UNIFIED_API */
 	QDF_STATUS (*ipa_setup)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 				void *ipa_i2w_cb, void *ipa_w2i_cb,
@@ -1949,6 +1956,10 @@ struct cdp_ipa_ops {
 					      uint8_t pdev_id);
 	QDF_STATUS (*ipa_tx_buf_smmu_unmapping)(struct cdp_soc_t *soc_hdl,
 						uint8_t pdev_id);
+#ifdef IPA_WDS_EASYMESH_FEATURE
+	QDF_STATUS (*ipa_ast_create)(struct cdp_soc_t *soc_hdl,
+				     qdf_ipa_ast_info_type_t *data);
+#endif
 };
 #endif
 

+ 76 - 4
dp/wifi3.0/dp_ipa.c

@@ -17,6 +17,7 @@
 
 #ifdef IPA_OFFLOAD
 
+#include <wlan_ipa_ucfg_api.h>
 #include <qdf_ipa_wdi3.h>
 #include <qdf_types.h>
 #include <qdf_lock.h>
@@ -36,6 +37,9 @@
 #ifdef WIFI_MONITOR_SUPPORT
 #include "dp_mon.h"
 #endif
+#ifdef FEATURE_WDS
+#include "dp_txrx_wds.h"
+#endif
 
 /* Ring index for WBM2SW2 release ring */
 #define IPA_TX_COMP_RING_IDX HAL_IPA_TX_COMP_RING_IDX
@@ -64,6 +68,14 @@ struct dp_ipa_reo_remap_record {
 	uint32_t ix3_reg;
 };
 
+#ifdef IPA_WDS_EASYMESH_FEATURE
+#define WLAN_IPA_META_DATA_MASK htonl(0x000000FF)
+#define WLAN_IPA_HDR_L2_ETHERNET IPA_HDR_L2_ETHERNET_II_AST
+#else
+#define WLAN_IPA_META_DATA_MASK htonl(0x00FF0000)
+#define WLAN_IPA_HDR_L2_ETHERNET IPA_HDR_L2_ETHERNET_II
+#endif
+
 #define REO_REMAP_HISTORY_SIZE 32
 
 struct dp_ipa_reo_remap_record dp_ipa_reo_remap_history[REO_REMAP_HISTORY_SIZE];
@@ -1028,11 +1040,29 @@ static void dp_ipa_set_pipe_db(struct dp_ipa_resources *res,
 		QDF_IPA_WDI_CONN_OUT_PARAMS_RX_UC_DB_PA(out);
 }
 
+#ifdef IPA_WDS_EASYMESH_FEATURE
+/**
+ * dp_ipa_setup_iface_session_id - Pass vdev id to IPA
+ * @in: ipa in params
+ * @session_id: vdev id
+ *
+ * Pass Vdev id to IPA, IPA metadata order is changed and vdev id
+ * is stored at higher nibble so, no shift is required.
+ *
+ * Return: none
+ */
+static void dp_ipa_setup_iface_session_id(qdf_ipa_wdi_reg_intf_in_params_t *in,
+					  uint8_t session_id)
+{
+	QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA(in) = htonl(session_id);
+}
+#else
 static void dp_ipa_setup_iface_session_id(qdf_ipa_wdi_reg_intf_in_params_t *in,
 					  uint8_t session_id)
 {
 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA(in) = htonl(session_id << 16);
 }
+#endif
 
 static inline void dp_ipa_tx_comp_ring_init_hp(struct dp_soc *soc,
 					       struct dp_ipa_resources *res)
@@ -2040,7 +2070,8 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 			bool is_rm_enabled, uint32_t *tx_pipe_handle,
 			uint32_t *rx_pipe_handle, bool is_smmu_enabled,
 			qdf_ipa_sys_connect_params_t *sys_in, bool over_gsi,
-			qdf_ipa_wdi_hdl_t hdl, qdf_ipa_wdi_hdl_t id)
+			qdf_ipa_wdi_hdl_t hdl, qdf_ipa_wdi_hdl_t id,
+			void *ipa_ast_notify_cb)
 {
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
 	struct dp_pdev *pdev =
@@ -2118,7 +2149,11 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 	}
 
 	QDF_IPA_EP_CFG_NAT_EN(rx_cfg) = IPA_BYPASS_NAT;
-	QDF_IPA_EP_CFG_HDR_LEN(rx_cfg) = DP_IPA_UC_WLAN_RX_HDR_LEN;
+	if (ucfg_ipa_is_wds_enabled())
+		QDF_IPA_EP_CFG_HDR_LEN(rx_cfg) = DP_IPA_UC_WLAN_RX_HDR_LEN_AST;
+	else
+		QDF_IPA_EP_CFG_HDR_LEN(rx_cfg) = DP_IPA_UC_WLAN_RX_HDR_LEN;
+
 	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE_VALID(rx_cfg) = 1;
 	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE(rx_cfg) = 0;
 	QDF_IPA_EP_CFG_HDR_ADDITIONAL_CONST_LEN(rx_cfg) = 0;
@@ -2141,6 +2176,7 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 	QDF_IPA_WDI_CONN_IN_PARAMS_NOTIFY(pipe_in) = ipa_w2i_cb;
 	QDF_IPA_WDI_CONN_IN_PARAMS_PRIV(pipe_in) = ipa_priv;
 	QDF_IPA_WDI_CONN_IN_PARAMS_HANDLE(pipe_in) = hdl;
+	dp_ipa_ast_notify_cb(pipe_in, ipa_ast_notify_cb);
 
 	/* Connect WDI IPA PIPEs */
 	ret = qdf_ipa_wdi_conn_pipes(pipe_in, &pipe_out);
@@ -2208,7 +2244,8 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
 
 	QDF_IPA_WDI_HDR_INFO_HDR(&hdr_info) = (uint8_t *)&uc_tx_hdr;
 	QDF_IPA_WDI_HDR_INFO_HDR_LEN(&hdr_info) = DP_IPA_UC_WLAN_TX_HDR_LEN;
-	QDF_IPA_WDI_HDR_INFO_HDR_TYPE(&hdr_info) = IPA_HDR_L2_ETHERNET_II;
+	QDF_IPA_WDI_HDR_INFO_HDR_TYPE(&hdr_info) = WLAN_IPA_HDR_L2_ETHERNET;
+
 	QDF_IPA_WDI_HDR_INFO_DST_MAC_ADDR_OFFSET(&hdr_info) =
 		DP_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
 
@@ -2217,7 +2254,7 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
 		     &hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t));
 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_ALT_DST_PIPE(&in) = cons_client;
 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_IS_META_DATA_VALID(&in) = 1;
-	QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA_MASK(&in) = htonl(0x00FF0000);
+	QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA_MASK(&in) = WLAN_IPA_META_DATA_MASK;
 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_HANDLE(&in) = hdl;
 	dp_ipa_setup_iface_session_id(&in, session_id);
 
@@ -2965,4 +3002,39 @@ QDF_STATUS dp_ipa_tx_buf_smmu_unmapping(
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef IPA_WDS_EASYMESH_FEATURE
+QDF_STATUS dp_ipa_ast_create(struct cdp_soc_t *soc_hdl,
+			     qdf_ipa_ast_info_type_t *data)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	uint8_t *rx_tlv_hdr;
+	struct dp_peer *peer;
+	struct hal_rx_msdu_metadata msdu_metadata;
+	qdf_ipa_ast_info_type_t *ast_info;
+
+	if (!data) {
+		dp_err("Data is NULL !!!");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ast_info = data;
+
+	rx_tlv_hdr = qdf_nbuf_data(ast_info->skb);
+	peer = dp_peer_get_ref_by_id(soc, ast_info->ta_peer_id,
+				     DP_MOD_ID_IPA);
+	if (!peer) {
+		dp_err("Peer is NULL !!!!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hal_rx_msdu_metadata_get(soc->hal_soc, rx_tlv_hdr, &msdu_metadata);
+
+	dp_rx_ipa_wds_srcport_learn(soc, peer, ast_info->skb, msdu_metadata,
+				    ast_info->mac_addr_ad4_valid,
+				    ast_info->first_msdu_in_mpdu_flag);
+
+	dp_peer_unref_delete(peer, DP_MOD_ID_IPA);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #endif

+ 50 - 2
dp/wifi3.0/dp_ipa.h

@@ -59,6 +59,10 @@ struct dp_ipa_uc_rx_hdr {
 
 #define DP_IPA_UC_WLAN_TX_HDR_LEN      sizeof(struct dp_ipa_uc_tx_hdr)
 #define DP_IPA_UC_WLAN_RX_HDR_LEN      sizeof(struct dp_ipa_uc_rx_hdr)
+/* 28 <bytes of rx_msdu_end_tlv> + 16 <bytes of attn tlv> +
+ * 52 <bytes of rx_mpdu_start_tlv> + <L2 Header>
+ */
+#define DP_IPA_UC_WLAN_RX_HDR_LEN_AST  110
 #define DP_IPA_UC_WLAN_HDR_DES_MAC_OFFSET	0
 
 #define DP_IPA_HDL_INVALID	0xFF
@@ -205,6 +209,7 @@ QDF_STATUS dp_ipa_disable_autonomy(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
  * @sys_in: parameters to setup sys pipe in mcc mode
  * @hdl: IPA handle
  * @id: IPA instance id
+ * @ipa_ast_notify_cb: IPA to WLAN callback for ast create and update
  *
  * Return: QDF_STATUS
  */
@@ -216,8 +221,8 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 			uint32_t *rx_pipe_handle,
 			bool is_smmu_enabled,
 			qdf_ipa_sys_connect_params_t *sys_in, bool over_gsi,
-			qdf_ipa_wdi_hdl_t hdl,
-			qdf_ipa_wdi_hdl_t id);
+			qdf_ipa_wdi_hdl_t hdl, qdf_ipa_wdi_hdl_t id,
+			void *ipa_ast_notify_cb);
 #else /* CONFIG_IPA_WDI_UNIFIED_API */
 /**
  * dp_ipa_setup() - Setup and connect IPA pipes
@@ -392,6 +397,41 @@ dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc,
 }
 #endif
 
+#ifdef IPA_WDS_EASYMESH_FEATURE
+/**
+ * dp_ipa_ast_create() - Create/update AST entry in AST table
+ *			 for learning/roaming packets from IPA
+ * @soc: data path soc handle
+ * @data: Structure used for updating the AST table
+ *
+ * Create/update AST entry in AST table for learning/roaming packets from IPA
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS dp_ipa_ast_create(struct cdp_soc_t *soc_hdl,
+			     qdf_ipa_ast_info_type_t *data);
+
+/**
+ * dp_ipa_ast_notify_cb() - Provide ast notify cb to IPA
+ * @pipe_in: WDI conn pipe in params
+ * @ipa_ast_notify_cb: ipa ast notify cb
+ *
+ * Return: None
+ */
+static inline void
+dp_ipa_ast_notify_cb(qdf_ipa_wdi_conn_in_params_t *pipe_in,
+		     void *ipa_ast_notify_cb)
+{
+	QDF_IPA_WDI_CONN_IN_PARAMS_AST_NOTIFY(pipe_in) = ipa_ast_notify_cb;
+}
+#else
+static inline void
+dp_ipa_ast_notify_cb(qdf_ipa_wdi_conn_in_params_t *pipe_in,
+		     void *ipa_ast_notify_cb)
+{
+}
+#endif
+
 #else
 static inline int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
 {
@@ -457,5 +497,13 @@ static inline QDF_STATUS dp_ipa_tx_buf_smmu_unmapping(struct cdp_soc_t *soc_hdl,
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef IPA_WDS_EASYMESH_FEATURE
+static inline QDF_STATUS dp_ipa_ast_create(struct cdp_soc_t *soc_hdl,
+					   qdf_ipa_ast_info_type_t *data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 #endif
 #endif /* _DP_IPA_H_ */

+ 4 - 1
dp/wifi3.0/dp_main.c

@@ -13671,7 +13671,10 @@ static struct cdp_ipa_ops dp_ops_ipa = {
 	.ipa_set_perf_level = dp_ipa_set_perf_level,
 	.ipa_rx_intrabss_fwd = dp_ipa_rx_intrabss_fwd,
 	.ipa_tx_buf_smmu_mapping = dp_ipa_tx_buf_smmu_mapping,
-	.ipa_tx_buf_smmu_unmapping = dp_ipa_tx_buf_smmu_unmapping
+	.ipa_tx_buf_smmu_unmapping = dp_ipa_tx_buf_smmu_unmapping,
+#ifdef IPA_WDS_EASYMESH_FEATURE
+	.ipa_ast_create = dp_ipa_ast_create,
+#endif
 };
 #endif
 

+ 31 - 6
dp/wifi3.0/dp_peer.c

@@ -2109,7 +2109,6 @@ void dp_peer_ast_set_type(struct dp_soc *soc,
 {
 	ast_entry->type = type;
 }
-
 #else
 QDF_STATUS dp_peer_add_ast(struct dp_soc *soc,
 			   struct dp_peer *peer,
@@ -2186,7 +2185,6 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer,
 {
 	return 1;
 }
-
 #endif
 
 void dp_peer_ast_send_wds_del(struct dp_soc *soc,
@@ -2954,6 +2952,36 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
 	return err;
 }
 
+#ifdef IPA_OFFLOAD
+/**
+ * dp_rx_peer_unmap_event() - Peer unmap event
+ * @soc_handle - genereic soc handle
+ * @peer_id - peer_id from firmware
+ * @vdev_id - vdev ID
+ * @mac_addr - mac address of the peer or wds entry
+ *
+ * Return: none
+ */
+static inline void
+dp_rx_peer_unmap_event(struct dp_soc *soc, uint16_t peer_id,
+		       uint8_t vdev_id, uint8_t *mac_addr)
+{
+	if (soc->cdp_soc.ol_ops->peer_unmap_event) {
+		soc->cdp_soc.ol_ops->peer_unmap_event(soc->ctrl_psoc,
+				peer_id, vdev_id, mac_addr);
+	}
+}
+#else
+static inline void
+dp_rx_peer_unmap_event(struct dp_soc *soc, uint16_t peer_id,
+		       uint8_t vdev_id, uint8_t *mac_addr)
+{
+	if (soc->cdp_soc.ol_ops->peer_unmap_event) {
+		soc->cdp_soc.ol_ops->peer_unmap_event(soc->ctrl_psoc,
+				peer_id, vdev_id);
+	}
+}
+#endif
 /**
  * dp_rx_peer_unmap_handler() - handle peer unmap event from firmware
  * @soc_handle - genereic soc handle
@@ -3032,10 +3060,7 @@ dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id,
 	if (!soc->ast_offload_support)
 		dp_peer_reset_flowq_map(peer);
 
-	if (soc->cdp_soc.ol_ops->peer_unmap_event) {
-		soc->cdp_soc.ol_ops->peer_unmap_event(soc->ctrl_psoc,
-				peer_id, vdev_id);
-	}
+	dp_rx_peer_unmap_event(soc, peer_id, vdev_id, peer->mac_addr.raw);
 
 	vdev = peer->vdev;
 	dp_update_vdev_stats_on_peer_unmap(vdev, peer);

+ 8 - 0
dp/wifi3.0/dp_rx.h

@@ -1286,6 +1286,14 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
 			struct hal_rx_msdu_metadata msdu_metadata)
 {
 }
+
+static inline void
+dp_rx_ipa_wds_srcport_learn(struct dp_soc *soc,
+			    struct dp_peer *ta_peer, qdf_nbuf_t nbuf,
+			    struct hal_rx_msdu_metadata msdu_end_info,
+			    bool ad4_valid, bool chfrag_start)
+{
+}
 #endif
 
 /*

+ 10 - 0
dp/wifi3.0/dp_txrx_wds.c

@@ -295,6 +295,7 @@ static void dp_ast_aging_timer_fn(void *soc_hdl)
 }
 #endif /* WLAN_FEATURE_MULTI_AST_DEL */
 
+#ifndef IPA_WDS_EASYMESH_FEATURE
 /*
  * dp_soc_wds_attach() - Setup WDS timer and AST table
  * @soc:		Datapath SOC handle
@@ -326,6 +327,15 @@ void dp_soc_wds_detach(struct dp_soc *soc)
 	qdf_timer_stop(&soc->ast_aging_timer);
 	qdf_timer_free(&soc->ast_aging_timer);
 }
+#else
+void dp_soc_wds_attach(struct dp_soc *soc)
+{
+}
+
+void dp_soc_wds_detach(struct dp_soc *soc)
+{
+}
+#endif
 
 /**
  * dp_tx_mec_handler() - Tx  MEC Notify Handler

+ 38 - 0
dp/wifi3.0/dp_txrx_wds.h

@@ -386,6 +386,44 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
 				    msdu_end_info.sa_idx, msdu_end_info.sa_sw_peer_id);
 }
 
+#ifdef IPA_WDS_EASYMESH_FEATURE
+/**
+ * dp_rx_ipa_wds_srcport_learn() - Add or update the STA PEER which
+ *				is behind the WDS repeater.
+ *
+ * @soc: core txrx main context
+ * @ta_peer: WDS repeater peer
+ * @nbuf: rx pkt
+ * @msdu_end_info: msdu end info
+ * @ad4_valid: address4 valid bit
+ * @chfrag_start: Msdu start bit
+ *
+ * Return: void
+ */
+static inline void
+dp_rx_ipa_wds_srcport_learn(struct dp_soc *soc,
+			    struct dp_peer *ta_peer, qdf_nbuf_t nbuf,
+			    struct hal_rx_msdu_metadata msdu_end_info,
+			    bool ad4_valid, bool chfrag_start)
+{
+	uint8_t sa_is_valid = qdf_nbuf_is_sa_valid(nbuf);
+	uint8_t is_chfrag_start = (uint8_t)chfrag_start;
+	uint8_t is_ad4_valid = (uint8_t)ad4_valid;
+	struct dp_txrx_peer *peer = (struct dp_txrx_peer *)ta_peer;
+
+	if (qdf_unlikely(!ta_peer))
+		return;
+
+	/*
+	 * Get the AST entry from HW SA index and mark it as active
+	 */
+	dp_rx_wds_add_or_update_ast(soc, peer, nbuf, is_ad4_valid,
+				    sa_is_valid, is_chfrag_start,
+				    msdu_end_info.sa_idx,
+				    msdu_end_info.sa_sw_peer_id);
+}
+#endif
+
 /*
  * dp_rx_ast_set_active() - set the active flag of the astentry
  *				    corresponding to a hw index.

+ 15 - 0
hal/wifi3.0/li/hal_li_rx.h

@@ -271,6 +271,20 @@ struct rx_pkt_hdr_tlv {
  */
 #define RX_PADDING0_BYTES	4
 #define RX_PADDING1_BYTES	16
+#if defined(IPA_OFFLOAD) && defined(IPA_WDS_EASYMESH_FEATURE)
+struct rx_pkt_tlvs {
+	struct rx_msdu_end_tlv   msdu_end_tlv;	/*  72 bytes */
+	struct rx_attention_tlv  attn_tlv;	/*  16 bytes */
+	struct rx_mpdu_start_tlv mpdu_start_tlv;/*  96 bytes */
+	struct rx_msdu_start_tlv msdu_start_tlv;/*  40 bytes */
+	uint8_t rx_padding0[RX_PADDING0_BYTES];	/*   4 bytes */
+	struct rx_mpdu_end_tlv   mpdu_end_tlv;	/*  12 bytes */
+	uint8_t rx_padding1[RX_PADDING1_BYTES];	/*  16 bytes */
+#ifndef NO_RX_PKT_HDR_TLV
+	struct rx_pkt_hdr_tlv	 pkt_hdr_tlv;	/* 128 bytes */
+#endif
+};
+#else
 struct rx_pkt_tlvs {
 	struct rx_msdu_end_tlv   msdu_end_tlv;	/*  72 bytes */
 	struct rx_attention_tlv  attn_tlv;	/*  16 bytes */
@@ -283,6 +297,7 @@ struct rx_pkt_tlvs {
 	struct rx_pkt_hdr_tlv	 pkt_hdr_tlv;	/* 128 bytes */
 #endif
 };
+#endif
 #else /* RXDMA_OPTIMIZATION */
 struct rx_pkt_tlvs {
 	struct rx_attention_tlv  attn_tlv;