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.dumitre...@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

Reply via email to