From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 1D98BA0554;
	Fri, 26 Aug 2022 12:36:30 +0200 (CEST)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id CD9B942829;
	Fri, 26 Aug 2022 12:36:15 +0200 (CEST)
Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31])
 by mails.dpdk.org (Postfix) with ESMTP id 5549F40143
 for <dev@dpdk.org>; Fri, 26 Aug 2022 12:36:11 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple;
 d=intel.com; i=@intel.com; q=dns/txt; s=Intel;
 t=1661510171; x=1693046171;
 h=from:to:subject:date:message-id:in-reply-to:references:
 mime-version:content-transfer-encoding;
 bh=kohfYz5OkYujxjOl5j8VnlJCSwrypbwXmoBsOpYBPio=;
 b=IeKGE18fwDNcm08qpd+Jj291HBen59Grh0s+0vMG1ASUjOehOydXCiR6
 Ij3SHcTXw8nRa+IURnEOQlSfaJ2LBOwM2QsSnVdeKPWG5pSKvV+3F6nLl
 9TMn6iVzpV0yCyUses0216kumD5oZyTzdhI1TGAOkkeJt5KQTSJRF//il
 vZVpQ2/pLZKP63XbGW2Gk9K07zzXOBOcMTRasRO1T/jYYp9VP132Cje1u
 85+sWqledPUx/hUCb4vkHIfJ2LgPdVdwhD0XfVF5UPuLCHJSkpbvbjbzS
 +OV0RUY5Eb0lja59lpMd5ETGk79BnDk78v52ZAoYdJiu9PDWfZjhbGHlr Q==;
X-IronPort-AV: E=McAfee;i="6500,9779,10450"; a="356194327"
X-IronPort-AV: E=Sophos;i="5.93,265,1654585200"; d="scan'208";a="356194327"
Received: from fmsmga008.fm.intel.com ([10.253.24.58])
 by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
 26 Aug 2022 03:36:10 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.93,265,1654585200"; d="scan'208";a="671414283"
Received: from silpixa00400573.ir.intel.com (HELO
 silpixa00400573.ger.corp.intel.com.) ([10.237.223.157])
 by fmsmga008.fm.intel.com with ESMTP; 26 Aug 2022 03:36:09 -0700
From: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
To: dev@dpdk.org
Subject: [PATCH 4/7] pipeline: support direct registers on the control path
Date: Fri, 26 Aug 2022 10:36:02 +0000
Message-Id: <20220826103605.1579589-5-cristian.dumitrescu@intel.com>
X-Mailer: git-send-email 2.34.1
In-Reply-To: <20220826103605.1579589-1-cristian.dumitrescu@intel.com>
References: <20220826103605.1579589-1-cristian.dumitrescu@intel.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

Add pipeline control path API to read/write direct registers. These
registers are identified by a table key, whose entry ID is used as the
index into the register array.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 lib/pipeline/rte_swx_ctl.h      |  52 ++++++++
 lib/pipeline/rte_swx_pipeline.c | 214 ++++++++++++++++++++++++++++++++
 lib/pipeline/version.map        |   2 +
 3 files changed, 268 insertions(+)

diff --git a/lib/pipeline/rte_swx_ctl.h b/lib/pipeline/rte_swx_ctl.h
index 0694df557a..1b47820441 100644
--- a/lib/pipeline/rte_swx_ctl.h
+++ b/lib/pipeline/rte_swx_ctl.h
@@ -1237,6 +1237,58 @@ rte_swx_ctl_pipeline_regarray_write(struct rte_swx_pipeline *p,
 				   uint32_t regarray_index,
 				   uint64_t value);
 
+/**
+ * Register read with table key lookup
+ *
+ * @param[in] p
+ *   Pipeline handle.
+ * @param[in] regarray_name
+ *   Register array name.
+ * @param[in] table_name
+ *   Regular or learner table name.
+ * @param[in] table_key
+ *   Table key.
+ * @param[out] value
+ *   Current register value.
+ * @return
+ *   0 on success or the following error codes otherwise:
+ *   -EINVAL: Invalid argument;
+ *   -ENOMEM: Not enough memory.
+ */
+__rte_experimental
+int
+rte_swx_ctl_pipeline_regarray_read_with_key(struct rte_swx_pipeline *p,
+					    const char *regarray_name,
+					    const char *table_name,
+					    uint8_t *table_key,
+					    uint64_t *value);
+
+/**
+ * Register write with table key lookup
+ *
+ * @param[in] p
+ *   Pipeline handle.
+ * @param[in] regarray_name
+ *   Register array name.
+ * @param[in] table_name
+ *   Regular or learner table name.
+ * @param[in] table_key
+ *   Table key.
+ * @param[in] value
+ *   Value to be written to the register.
+ * @return
+ *   0 on success or the following error codes otherwise:
+ *   -EINVAL: Invalid argument;
+ *   -ENOMEM: Not enough memory.
+ */
+__rte_experimental
+int
+rte_swx_ctl_pipeline_regarray_write_with_key(struct rte_swx_pipeline *p,
+					     const char *regarray_name,
+					     const char *table_name,
+					     uint8_t *table_key,
+					     uint64_t value);
+
 /*
  * Meter Array Query and Configuration API.
  */
diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c
index ec8268b7f8..e726bf1575 100644
--- a/lib/pipeline/rte_swx_pipeline.c
+++ b/lib/pipeline/rte_swx_pipeline.c
@@ -11101,6 +11101,220 @@ rte_swx_ctl_pipeline_mirroring_session_set(struct rte_swx_pipeline *p,
 	return 0;
 }
 
+static int
+rte_swx_ctl_pipeline_table_lookup(struct rte_swx_pipeline *p,
+				  const char *table_name,
+				  uint8_t *key,
+				  uint64_t *action_id,
+				  uint8_t **action_data,
+				  size_t *entry_id,
+				  int *hit)
+{
+	struct table *t;
+	void *mailbox = NULL;
+
+	/* Check input arguments. */
+	if (!p ||
+	    !p->build_done ||
+	    !table_name ||
+	    !table_name[0] ||
+	    !key ||
+	    !entry_id ||
+	    !hit)
+		return -EINVAL;
+
+	/* Find the table. */
+	t = table_find(p, table_name);
+	if (!t)
+		return -EINVAL;
+
+	if (!t->type) {
+		*hit = 0;
+		return 0;
+	}
+
+	/* Setup mailbox.  */
+	if (t->type->ops.mailbox_size_get) {
+		uint64_t mailbox_size;
+
+		mailbox_size = t->type->ops.mailbox_size_get();
+		if (mailbox_size) {
+			mailbox = calloc(1, mailbox_size);
+			if (!mailbox)
+				return -ENOMEM;
+		}
+	}
+
+	/* Table lookup operation. */
+	for ( ; ; ) {
+		struct rte_swx_table_state *ts = &p->table_state[t->id];
+		int done;
+
+		done = t->type->ops.lkp(ts->obj,
+					mailbox,
+					&key,
+					action_id,
+					action_data,
+					entry_id,
+					hit);
+		if (done)
+			break;
+	}
+
+	/* Free mailbox. */
+	free(mailbox);
+
+	return 0;
+}
+
+static int
+rte_swx_ctl_pipeline_learner_lookup(struct rte_swx_pipeline *p,
+				    const char *learner_name,
+				    uint8_t *key,
+				    uint64_t *action_id,
+				    uint8_t **action_data,
+				    size_t *entry_id,
+				    int *hit)
+{
+	struct learner *l;
+	void *mailbox = NULL;
+	uint64_t mailbox_size, time;
+
+	/* Check input arguments. */
+	if (!p ||
+	    !p->build_done ||
+	    !learner_name ||
+	    !learner_name[0] ||
+	    !key ||
+	    !entry_id ||
+	    !hit)
+		return -EINVAL;
+
+	/* Find the learner table. */
+	l = learner_find(p, learner_name);
+	if (!l)
+		return -EINVAL;
+
+	/* Setup mailbox.  */
+	mailbox_size = rte_swx_table_learner_mailbox_size_get();
+	if (mailbox_size) {
+		mailbox = calloc(1, mailbox_size);
+		if (!mailbox)
+			return -ENOMEM;
+	}
+
+	/* Learner table lookup operation. */
+	time = rte_get_tsc_cycles();
+	for ( ; ; ) {
+		uint32_t pos = p->n_tables + p->n_selectors + l->id;
+		struct rte_swx_table_state *ts = &p->table_state[pos];
+		int done;
+
+		done = rte_swx_table_learner_lookup(ts->obj,
+						    mailbox,
+						    time,
+						    &key,
+						    action_id,
+						    action_data,
+						    entry_id,
+						    hit);
+		if (done)
+			break;
+	}
+
+	/* Free mailbox. */
+	free(mailbox);
+
+	return 0;
+}
+
+static int
+rte_swx_ctl_pipeline_table_entry_id_get(struct rte_swx_pipeline *p,
+					const char *table_name,
+					uint8_t *table_key,
+					size_t *table_entry_id)
+{
+	struct table *t;
+	struct learner *l;
+	uint64_t action_id;
+	uint8_t *action_data;
+	size_t entry_id = 0;
+	int hit = 0, status;
+
+	/* Check input arguments. */
+	if (!p ||
+	    !p->build_done ||
+	    !table_name ||
+	    !table_name[0] ||
+	    !table_key ||
+	    !table_entry_id)
+		return -EINVAL;
+
+	t = table_find(p, table_name);
+	l = learner_find(p, table_name);
+	if (!t && !l)
+		return -EINVAL;
+
+	/* Table lookup operation. */
+	if (t)
+		status = rte_swx_ctl_pipeline_table_lookup(p,
+							   table_name,
+							   table_key,
+							   &action_id,
+							   &action_data,
+							   &entry_id,
+							   &hit);
+	else
+		status = rte_swx_ctl_pipeline_learner_lookup(p,
+							     table_name,
+							     table_key,
+							     &action_id,
+							     &action_data,
+							     &entry_id,
+							     &hit);
+	if (status)
+		return status;
+
+	/* Reserve entry ID 0 for the table default entry. */
+	*table_entry_id = hit ? (1 + entry_id) : 0;
+
+	return 0;
+}
+
+int
+rte_swx_ctl_pipeline_regarray_read_with_key(struct rte_swx_pipeline *p,
+					    const char *regarray_name,
+					    const char *table_name,
+					    uint8_t *table_key,
+					    uint64_t *value)
+{
+	size_t entry_id = 0;
+	int status;
+
+	status = rte_swx_ctl_pipeline_table_entry_id_get(p, table_name, table_key, &entry_id);
+	if (status)
+		return status;
+
+	return rte_swx_ctl_pipeline_regarray_read(p, regarray_name, entry_id, value);
+}
+
+int
+rte_swx_ctl_pipeline_regarray_write_with_key(struct rte_swx_pipeline *p,
+					     const char *regarray_name,
+					     const char *table_name,
+					     uint8_t *table_key,
+					     uint64_t value)
+{
+	size_t entry_id = 0;
+	int status;
+
+	status = rte_swx_ctl_pipeline_table_entry_id_get(p, table_name, table_key, &entry_id);
+	if (status)
+		return status;
+
+	return rte_swx_ctl_pipeline_regarray_write(p, regarray_name, entry_id, value);
+}
+
 /*
  * Pipeline compilation.
  */
diff --git a/lib/pipeline/version.map b/lib/pipeline/version.map
index 16806e6802..8ed92042d6 100644
--- a/lib/pipeline/version.map
+++ b/lib/pipeline/version.map
@@ -147,6 +147,8 @@ EXPERIMENTAL {
 
 	#added in 22.11
 	rte_swx_ctl_pipeline_find;
+	rte_swx_ctl_pipeline_regarray_read_with_key;
+	rte_swx_ctl_pipeline_regarray_write_with_key;
 	rte_swx_pipeline_build_from_lib;
 	rte_swx_pipeline_codegen;
 	rte_swx_pipeline_find;
-- 
2.34.1