Эх сурвалжийг харах

qcacmn: Add PPE Tx/RX changes

Add support for:-
   1. PPE VP entry attach and detach.
   2. Per VAP PRI2TID Support
   3. Dump the PPE VP HW entries.
   4. Add tx completion handling for ppeds descriptors

Change-Id: I2a6d0be5bb556663a39a24d17b703877f3b5ad00
CRs-Fixed: 3276981
Neelansh Mittal 3 жил өмнө
parent
commit
83990186aa

+ 4 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -1284,6 +1284,7 @@ enum cdp_pdev_param_type {
  *
  * @cdp_psoc_param_en_rate_stats: set rate stats enable/disable
  * @cdp_psoc_param_en_nss_cfg: set nss cfg
+ * @cdp_psoc_param_ppeds_enabled: PPE-DS feature enable
  * @cdp_ipa_enabled : set ipa mode
  * @cdp_psoc_param_vdev_stats_hw_offload: Configure HW vdev stats offload
  * @cdp_pdev_param_undecoded_metadata_enable: Undecoded metadata capture enable
@@ -1367,6 +1368,7 @@ typedef union cdp_config_param_t {
 	int cdp_psoc_param_en_nss_cfg;
 	int cdp_psoc_param_preferred_hw_mode;
 	bool cdp_psoc_param_pext_stats;
+	bool cdp_psoc_param_ppeds_enabled;
 
 	bool cdp_skip_bar_update;
 	bool cdp_ipa_enabled;
@@ -1513,6 +1515,7 @@ enum cdp_vdev_param_type {
  * @CDP_IPA_ENABLE : set IPA enable mode.
  * @CDP_CFG_VDEV_STATS_HW_OFFLOAD: HW Vdev stats config
  * @CDP_UMAC_RST_SKEL_ENABLE: Enable Umac reset skeleton code for debug
+ * @CDP_CDP_PPEDS_ENABLE: PPEDS is enabled or not
  */
 enum cdp_psoc_param_type {
 	CDP_ENABLE_RATE_STATS,
@@ -1523,6 +1526,7 @@ enum cdp_psoc_param_type {
 	CDP_CFG_VDEV_STATS_HW_OFFLOAD,
 	CDP_SAWF_ENABLE,
 	CDP_UMAC_RST_SKEL_ENABLE,
+	CDP_PPEDS_ENABLE,
 };
 
 #define TXRX_FW_STATS_TXSTATS                     1

+ 22 - 0
dp/inc/cdp_txrx_ops.h

@@ -2156,6 +2156,25 @@ struct cdp_sawf_ops {
 };
 #endif
 
+#ifdef WLAN_SUPPORT_PPEDS
+struct cdp_ppe_txrx_ops {
+	QDF_STATUS
+	(*ppeds_entry_attach)(struct cdp_soc_t *soc,
+			      uint8_t vdev_id, void *vpai,
+			      int32_t *ppe_vp_num);
+	QDF_STATUS
+	(*ppeds_enable_pri2tid)(struct cdp_soc_t *soc,
+				uint8_t vdev_id, bool val);
+	void (*ppeds_entry_detach)(struct cdp_soc_t *soc,
+				   uint8_t vdev_id);
+	void (*ppeds_set_int_pri2tid)(struct cdp_soc_t *soc,
+				      uint8_t *pri2tid);
+	void (*ppeds_update_int_pri2tid)(struct cdp_soc_t *soc,
+					 uint8_t pri, uint8_t tid);
+	void (*ppeds_entry_dump)(struct cdp_soc_t *soc);
+};
+#endif /* WLAN_SUPPORT_PPEDS */
+
 struct cdp_ops {
 	struct cdp_cmn_ops          *cmn_drv_ops;
 	struct cdp_ctrl_ops         *ctrl_ops;
@@ -2206,5 +2225,8 @@ struct cdp_ops {
 #ifdef WLAN_SUPPORT_SCS
 	struct cdp_scs_ops   *scs_ops;
 #endif
+#ifdef WLAN_SUPPORT_PPEDS
+	struct cdp_ppe_txrx_ops *ppe_ops;
+#endif
 };
 #endif

+ 159 - 0
dp/inc/cdp_txrx_ppe.h

@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2022 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 above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _CDP_TXRX_PPE_H_
+#define _CDP_TXRX_PPE_H_
+
+/**
+ * cdp_ppesds_entry_attach() - attach the ppe vp interface.
+ * @soc: data path soc handle
+ * @vdev_id: vdev id
+ * @vpai: PPE VP opaque
+ * @ppe_vp_num: Allocated VP Port number
+ *
+ * return: qdf_status where vp entry got allocated or not.
+ */
+static inline
+QDF_STATUS cdp_ppesds_entry_attach(struct cdp_soc_t *soc, uint8_t vdev_id,
+				   void *vpai, int32_t *ppe_vp_num)
+{
+	if (!soc || !soc->ops || !soc->ops->ppe_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (soc->ops->ppe_ops->ppeds_entry_attach) {
+		return soc->ops->ppe_ops->ppeds_entry_attach(soc, vdev_id,
+				vpai, ppe_vp_num);
+	}
+
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+/**
+ * cdp_ppesds_entry_detach() - Detach the PPE VP interface.
+ * @soc: data path soc handle
+ * @vdev_id: vdev ID
+ *
+ * return: void
+ */
+static inline
+void cdp_ppesds_entry_detach(struct cdp_soc_t *soc, uint8_t vdev_id)
+{
+	if (!soc || !soc->ops || !soc->ops->ppe_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return;
+	}
+
+	if (soc->ops->ppe_ops->ppeds_entry_detach) {
+		return soc->ops->ppe_ops->ppeds_entry_detach
+			(soc, vdev_id);
+	}
+}
+
+/**
+ * cdp_ppesds_set_int_pri2tid() - Set the INT_PRI to TID
+ * @soc: data path soc handle
+ * @pri2tid: PRI2TID table
+ *
+ * return: void
+ */
+static inline
+void cdp_ppesds_set_int_pri2tid(struct cdp_soc_t *soc,
+				uint8_t *pri2tid)
+{
+	if (!soc || !soc->ops || !soc->ops->ppe_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return;
+	}
+
+	if (soc->ops->ppe_ops->ppeds_set_int_pri2tid) {
+		return soc->ops->ppe_ops->ppeds_set_int_pri2tid
+			(soc, pri2tid);
+	}
+}
+
+/**
+ * cdp_ppesds_update_int_pri2tid() - Update the INT_PRI to TID
+ * @soc: data path soc handle
+ * @pri: Priority index
+ * @tid: TID mapped to the input priority
+ *
+ * return: void
+ */
+static inline
+void cdp_ppesds_update_int_pri2tid(struct cdp_soc_t *soc,
+				   uint8_t pri, uint8_t tid)
+{
+	if (!soc || !soc->ops || !soc->ops->ppe_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+	}
+
+	if (soc->ops->ppe_ops->ppeds_update_int_pri2tid) {
+		return soc->ops->ppe_ops->ppeds_update_int_pri2tid
+		       (soc, pri, tid);
+	}
+}
+
+/**
+ * cdp_ppesds_entry_dump() - Dump the PPE VP entries
+ * @soc: data path soc handle
+ *
+ * return: void
+ */
+static inline
+void cdp_ppesds_entry_dump(struct cdp_soc_t *soc)
+{
+	if (!soc || !soc->ops || !soc->ops->ppe_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return;
+	}
+
+	if (soc->ops->ppe_ops->ppeds_entry_dump)
+		soc->ops->ppe_ops->ppeds_entry_dump(soc);
+}
+
+/**
+ * cdp_ppesds_enable_pri2tid() - Enable PPE VP PRI2TID table
+ * @soc: data path soc handle
+ * @vdev_id: vdev id
+ * @val: Boolean value to enable/disable
+ *
+ * return: QDF_STATUS
+ */
+static inline
+QDF_STATUS cdp_ppesds_enable_pri2tid(struct cdp_soc_t *soc,
+				     uint8_t vdev_id, bool val)
+{
+	if (!soc || !soc->ops || !soc->ops->ppe_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (soc->ops->ppe_ops->ppeds_enable_pri2tid) {
+		return soc->ops->ppe_ops->ppeds_enable_pri2tid(soc,
+				vdev_id, val);
+	}
+
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif /* _CDP_TXRX_PPE_H_ */

+ 73 - 0
dp/wifi3.0/be/dp_be.c

@@ -30,6 +30,9 @@
 #include "dp_mon.h"
 #endif
 #include <hal_be_api.h>
+#ifdef WLAN_SUPPORT_PPEDS
+#include "be/dp_ppeds.h"
+#endif
 
 /* Generic AST entry aging timer value */
 #define DP_AST_AGING_TIMER_DEFAULT_MS	5000
@@ -62,6 +65,15 @@ static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RIN
 #endif
 
 #ifdef WLAN_SUPPORT_PPEDS
+static struct cdp_ppe_txrx_ops dp_ops_ppe_be = {
+	.ppeds_entry_attach = dp_ppeds_attach_vdev_be,
+	.ppeds_entry_detach = dp_ppeds_detach_vdev_be,
+	.ppeds_set_int_pri2tid = dp_ppeds_set_int_pri2tid_be,
+	.ppeds_update_int_pri2tid = dp_ppeds_update_int_pri2tid_be,
+	.ppeds_entry_dump = dp_ppeds_dump_ppe_vp_tbl_be,
+	.ppeds_enable_pri2tid = dp_ppeds_vdev_enable_pri2tid_be,
+};
+
 static void dp_ppeds_rings_status(struct dp_soc *soc)
 {
 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
@@ -456,11 +468,58 @@ dp_hw_cookie_conversion_deinit(struct dp_soc_be *be_soc,
 }
 #endif
 
+#ifdef WLAN_SUPPORT_PPEDS
+static QDF_STATUS dp_soc_ppe_attach_be(struct dp_soc *soc)
+{
+	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
+	struct cdp_ops *cdp_ops = soc->cdp_soc.ops;
+
+	/*
+	 * Check if PPE DS is enabled.
+	 */
+	if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc->wlan_cfg_ctx))
+		return QDF_STATUS_SUCCESS;
+
+	if (dp_ppeds_attach_soc_be(be_soc) != QDF_STATUS_SUCCESS)
+		return QDF_STATUS_SUCCESS;
+
+	cdp_ops->ppe_ops = &dp_ops_ppe_be;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS dp_soc_ppe_detach_be(struct dp_soc *soc)
+{
+	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
+	struct cdp_ops *cdp_ops = soc->cdp_soc.ops;
+
+	if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc->wlan_cfg_ctx))
+		return QDF_STATUS_E_FAILURE;
+
+	dp_ppeds_detach_soc_be(be_soc);
+
+	cdp_ops->ppe_ops = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS dp_soc_ppe_attach_be(struct dp_soc *soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_soc_ppe_detach_be(struct dp_soc *soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_SUPPORT_PPEDS */
+
 static QDF_STATUS dp_soc_detach_be(struct dp_soc *soc)
 {
 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
 	int i = 0;
 
+	dp_soc_ppe_detach_be(soc);
 
 	for (i = 0; i < MAX_TXDESC_POOLS; i++)
 		dp_hw_cookie_conversion_detach(be_soc,
@@ -586,6 +645,10 @@ static QDF_STATUS dp_soc_attach_be(struct dp_soc *soc,
 
 	dp_soc_mlo_fill_params(soc, params);
 
+	qdf_status = dp_soc_ppe_attach_be(soc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		goto fail;
+
 	for (i = 0; i < MAX_TXDESC_POOLS; i++) {
 		num_entries = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
 		qdf_status =
@@ -1262,6 +1325,12 @@ static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc)
 			  soc->ctrl_psoc,
 			  WLAN_MD_DP_SRNG_PPE_RELEASE,
 			  "ppe_release_ring");
+#ifdef WLAN_SUPPORT_PPEDS
+	if (dp_ppeds_register_soc_be(be_soc)) {
+		dp_err("%pK: ppeds registration failed", soc);
+		goto fail;
+	}
+#endif
 
 	return QDF_STATUS_SUCCESS;
 fail:
@@ -2063,8 +2132,12 @@ void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
 
 #ifdef WLAN_SUPPORT_PPEDS
 	arch_ops->dp_txrx_ppeds_rings_status = dp_ppeds_rings_status;
+	arch_ops->txrx_soc_ppeds_start = dp_ppeds_start_soc_be;
+	arch_ops->txrx_soc_ppeds_stop = dp_ppeds_stop_soc_be;
 #else
 	arch_ops->dp_txrx_ppeds_rings_status = NULL;
+	arch_ops->txrx_soc_ppeds_start = NULL;
+	arch_ops->txrx_soc_ppeds_stop = NULL;
 #endif
 
 	dp_init_near_full_arch_ops_be(arch_ops);

+ 2 - 5
dp/wifi3.0/be/dp_be.h

@@ -118,11 +118,6 @@ enum CMEM_MEM_CLIENTS {
 #define DP_CMEM_OFFSET_TO_PPT_ID(offset) \
 	((offset) / DP_CC_PPT_ENTRY_SIZE_4K_ALIGNED)
 
-/* The MAX PPE PRI2TID */
-#ifdef WLAN_SUPPORT_PPEDS
-#define DP_TX_INT_PRI2TID_MAX 15
-#endif
-
 /**
  * struct dp_spt_page_desc - secondary page table page descriptors
  * @next: pointer to next linked SPT page Desc
@@ -237,6 +232,7 @@ struct dp_ppe_vp_profile {
  * @ppe_vp_tbl_lock: PPE VP table lock
  * @num_ppe_vp_entries : Number of PPE VP entries
  * @ipa_bank_id: TCL bank id used by IPA
+ * @ppeds_handle: PPEDS soc instance handle
  */
 struct dp_soc_be {
 	struct dp_soc soc;
@@ -256,6 +252,7 @@ struct dp_soc_be {
 	struct dp_srng ppe2tcl_ring;
 	struct dp_srng ppe_release_ring;
 	struct dp_ppe_vp_tbl_entry *ppe_vp_tbl;
+	void *ppeds_handle;
 	qdf_mutex_t ppe_vp_tbl_lock;
 	uint8_t num_ppe_vp_entries;
 #endif

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

@@ -6231,6 +6231,9 @@ static void dp_soc_deinit(void *txrx_soc)
 
 	qdf_atomic_set(&soc->cmn_init_done, 0);
 
+	if (soc->arch_ops.txrx_soc_ppeds_stop)
+		soc->arch_ops.txrx_soc_ppeds_stop(soc);
+
 	soc->arch_ops.txrx_soc_deinit(soc);
 
 	dp_monitor_soc_deinit(soc);
@@ -11035,6 +11038,10 @@ static QDF_STATUS dp_get_psoc_param(struct cdp_soc_t *cdp_soc,
 	case CDP_UMAC_RST_SKEL_ENABLE:
 		val->cdp_umac_rst_skel = dp_umac_rst_skel_enable_get(soc);
 		break;
+	case CDP_PPEDS_ENABLE:
+		val->cdp_psoc_param_ppeds_enabled =
+			wlan_cfg_get_dp_soc_is_ppe_enabled(soc->wlan_cfg_ctx);
+		break;
 	default:
 		dp_warn("Invalid param");
 		break;
@@ -15432,6 +15439,13 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle,
 		goto fail6;
 	}
 
+	if (soc->arch_ops.txrx_soc_ppeds_start) {
+		if (soc->arch_ops.txrx_soc_ppeds_start(soc)) {
+			dp_init_err("%pK: ppeds start failed", soc);
+			goto fail7;
+		}
+	}
+
 	wlan_cfg_set_rx_hash(soc->wlan_cfg_ctx,
 			     cfg_get(soc->ctrl_psoc, CFG_DP_RX_HASH));
 	soc->cce_disable = false;
@@ -15517,6 +15531,8 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle,
 	soc->vdev_stats_id_map = 0;
 
 	return soc;
+fail7:
+	dp_soc_tx_desc_sw_pools_deinit(soc);
 fail6:
 	htt_soc_htc_dealloc(soc->htt_handle);
 fail5:

+ 18 - 0
dp/wifi3.0/dp_tx.c

@@ -5201,6 +5201,19 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
 			desc = next;
 			continue;
 		}
+
+		if (desc->flags & DP_TX_DESC_FLAG_PPEDS) {
+			if (qdf_likely(txrx_peer))
+				dp_tx_update_peer_basic_stats(txrx_peer,
+							      desc->length,
+							      desc->tx_status,
+							      false);
+			qdf_nbuf_free(desc->nbuf);
+			dp_tx_desc_free(soc, desc, desc->pool_id);
+			desc = next;
+			continue;
+		}
+
 		if (qdf_likely(desc->flags & DP_TX_DESC_FLAG_SIMPLE)) {
 			struct dp_pdev *pdev = desc->pdev;
 
@@ -5424,6 +5437,10 @@ more_data:
 			continue;
 		}
 		tx_desc->buffer_src = buffer_src;
+
+		if (tx_desc->flags & DP_TX_DESC_FLAG_PPEDS)
+			goto add_to_pool2;
+
 		/*
 		 * If the release source is FW, process the HTT status
 		 */
@@ -5489,6 +5506,7 @@ more_data:
 add_to_pool:
 			DP_HIST_PACKET_COUNT_INC(tx_desc->pdev->pdev_id);
 
+add_to_pool2:
 			/* First ring descriptor on the cycle */
 			if (!head_desc) {
 				head_desc = tx_desc;

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

@@ -60,6 +60,12 @@
 #define DP_TX_DESC_FLAG_TX_COMP_ERR	0x1000
 #define DP_TX_DESC_FLAG_FLUSH		0x2000
 #define DP_TX_DESC_FLAG_TRAFFIC_END_IND	0x4000
+/*
+ * Since the Tx descriptor flag is of only 16-bit and no more bit is free for
+ * any new flag, therefore for time being overloading PPEDS flag with that of
+ * FLUSH flag.
+ */
+#define DP_TX_DESC_FLAG_PPEDS		0x2000
 
 #define DP_TX_EXT_DESC_FLAG_METADATA_VALID 0x1
 

+ 4 - 0
dp/wifi3.0/dp_types.h

@@ -458,6 +458,7 @@ enum dp_ctxt_type {
 /**
  * enum dp_desc_type - source type for multiple pages allocation
  * @DP_TX_DESC_TYPE: DP SW TX descriptor
+ * @DP_TX_PPEDS_DESC_TYPE: DP PPE-DS Tx descriptor
  * @DP_TX_EXT_DESC_TYPE: DP TX msdu extension descriptor
  * @DP_TX_EXT_DESC_LINK_TYPE: DP link descriptor for msdu ext_desc
  * @DP_TX_TSO_DESC_TYPE: DP TX TSO descriptor
@@ -469,6 +470,7 @@ enum dp_ctxt_type {
  */
 enum dp_desc_type {
 	DP_TX_DESC_TYPE,
+	DP_TX_PPEDS_DESC_TYPE,
 	DP_TX_EXT_DESC_TYPE,
 	DP_TX_EXT_DESC_LINK_TYPE,
 	DP_TX_TSO_DESC_TYPE,
@@ -1992,6 +1994,8 @@ struct dp_arch_ops {
 	int8_t (*ipa_get_bank_id)(struct dp_soc *soc);
 #endif
 	void (*dp_txrx_ppeds_rings_status)(struct dp_soc *soc);
+	QDF_STATUS (*txrx_soc_ppeds_start)(struct dp_soc *soc);
+	void (*txrx_soc_ppeds_stop)(struct dp_soc *soc);
 };
 
 /**

+ 2 - 0
dp/wifi3.0/li/dp_li.c

@@ -629,6 +629,8 @@ void dp_initialize_arch_ops_li(struct dp_arch_ops *arch_ops)
 	arch_ops->peer_get_reo_hash = dp_peer_get_reo_hash_li;
 	arch_ops->reo_remap_config = dp_reo_remap_config_li;
 	arch_ops->dp_txrx_ppeds_rings_status = NULL;
+	arch_ops->txrx_soc_ppeds_start = NULL;
+	arch_ops->txrx_soc_ppeds_stop = NULL;
 }
 
 #ifdef QCA_DP_TX_HW_SW_NBUF_DESC_PREFETCH