[21/33] net/bnxt: add support to alloc and program key and act tbls

Message ID 1584459511-5353-22-git-send-email-venkatkumar.duvvuru@broadcom.com (mailing list archive)
State Superseded, archived
Delegated to: Ajit Khaparde
Headers
Series add support for host based flow table management |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Venkat Duvvuru March 17, 2020, 3:38 p.m. UTC
  From: Mike Baucom <michael.baucom@broadcom.com>

This patch does the following
1. Gets the action tables information from the action template id
2. Gets the class tables information from the class template id
3. Initializes the registry file
4. Allocates a flow id from the flow table
5. Process the class & action tables

Signed-off-by: Mike Baucom <michael.baucom@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Reviewed-by: Lance Richardson <lance.richardson@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_flow_db.c         |  37 +++++
 drivers/net/bnxt/tf_ulp/ulp_flow_db.h         |  13 ++
 drivers/net/bnxt/tf_ulp/ulp_mapper.c          | 196 ++++++++++++++++++++++++--
 drivers/net/bnxt/tf_ulp/ulp_mapper.h          |  15 ++
 drivers/net/bnxt/tf_ulp/ulp_template_db.c     |  22 +++
 drivers/net/bnxt/tf_ulp/ulp_template_db.h     |   7 +
 drivers/net/bnxt/tf_ulp/ulp_template_struct.h |  31 +++-
 7 files changed, 310 insertions(+), 11 deletions(-)
  

Patch

diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c
index 8449db3..76ec856 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c
@@ -303,6 +303,43 @@  int32_t	ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
 }
 
 /*
+ * Allocate the flow database entry
+ *
+ * ulp_ctxt [in] Ptr to ulp_context
+ * tbl_idx [in] Specify it is regular or default flow
+ * fid [out] The index to the flow entry
+ *
+ * returns 0 on success and negative on failure.
+ */
+int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context		*ulp_ctxt,
+			      enum bnxt_ulp_flow_db_tables	tbl_idx,
+			      uint32_t				*fid)
+{
+	struct bnxt_ulp_flow_db		*flow_db;
+	struct bnxt_ulp_flow_tbl	*flow_tbl;
+
+	*fid = 0; /* Initialize fid to invalid value */
+	flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
+	if (!flow_db) {
+		BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+		return -EINVAL;
+	}
+
+	flow_tbl = &flow_db->flow_tbl[tbl_idx];
+	/* check for max flows */
+	if (flow_tbl->num_flows <= flow_tbl->head_index) {
+		BNXT_TF_DBG(ERR, "Flow database has reached max flows\n");
+		return -ENOMEM;
+	}
+	*fid = flow_tbl->flow_tbl_stack[flow_tbl->head_index];
+	flow_tbl->head_index++;
+	ulp_flow_db_active_flow_set(flow_tbl, *fid, 1);
+
+	/* all good, return success */
+	return 0;
+}
+
+/*
  * Allocate the flow database entry.
  * The params->critical_resource has to be set to 0 to allocate a new resource.
  *
diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h
index 20109b9..eb5effa 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h
@@ -84,6 +84,19 @@  int32_t	ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt);
 int32_t	ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt);
 
 /*
+ * Allocate the flow database entry
+ *
+ * ulp_ctxt [in] Ptr to ulp_context
+ * tbl_idx [in] Specify it is regular or default flow
+ * fid [out] The index to the flow entry
+ *
+ * returns 0 on success and negative on failure.
+ */
+int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context		*ulp_ctxt,
+			      enum bnxt_ulp_flow_db_tables	tbl_idx,
+			      uint32_t				*fid);
+
+/*
  * Allocate the flow database entry.
  * The params->critical_resource has to be set to 0 to allocate a new resource.
  *
diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index cc85557..852d9e3 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -16,12 +16,6 @@ 
 #include "ulp_flow_db.h"
 #include "ulp_mapper.h"
 
-int32_t
-ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms);
-
-int32_t
-ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms);
-
 /*
  * Get the size of the action property for a given index.
  *
@@ -38,7 +32,76 @@  ulp_mapper_act_prop_size_get(uint32_t idx)
 }
 
 /*
- * Get the list of result fields that implement the flow action
+ * Get the list of result fields that implement the flow action.
+ * Gets a device dependent list of tables that implement the action template id.
+ *
+ * dev_id [in] The device id of the forwarding element
+ *
+ * tid [in] The action template id that matches the flow
+ *
+ * num_tbls [out] The number of action tables in the returned array
+ *
+ * Returns An array of action tables to implement the flow, or NULL on error.
+ */
+static struct bnxt_ulp_mapper_act_tbl_info *
+ulp_mapper_action_tbl_list_get(uint32_t dev_id,
+			       uint32_t tid,
+			       uint32_t *num_tbls)
+{
+	uint32_t	idx;
+	uint32_t	tidx;
+
+	if (!num_tbls) {
+		BNXT_TF_DBG(ERR, "Invalid arguments\n");
+		return NULL;
+	}
+
+	/* template shift and device mask */
+	tidx = ULP_DEVICE_PARAMS_INDEX(tid, dev_id);
+
+	/* NOTE: Need to have something from template compiler to help validate
+	 * range of dev_id and act_tid
+	 */
+	idx		= ulp_act_tmpl_list[tidx].start_tbl_idx;
+	*num_tbls	= ulp_act_tmpl_list[tidx].num_tbls;
+
+	return &ulp_act_tbl_list[idx];
+}
+
+/** Get a list of classifier tables that implement the flow
+ * Gets a device dependent list of tables that implement the class template id
+ *
+ * dev_id [in] The device id of the forwarding element
+ *
+ * tid [in] The template id that matches the flow
+ *
+ * num_tbls [out] The number of classifier tables in the returned array
+ *
+ * returns An array of classifier tables to implement the flow, or NULL on
+ * error
+ */
+static struct bnxt_ulp_mapper_class_tbl_info *
+ulp_mapper_class_tbl_list_get(uint32_t dev_id,
+			      uint32_t tid,
+			      uint32_t *num_tbls)
+{
+	uint32_t idx;
+	uint32_t tidx = ULP_DEVICE_PARAMS_INDEX(tid, dev_id);
+
+	if (!num_tbls)
+		return NULL;
+
+	/* NOTE: Need to have something from template compiler to help validate
+	 * range of dev_id and tid
+	 */
+	idx		= ulp_class_tmpl_list[tidx].start_tbl_idx;
+	*num_tbls	= ulp_class_tmpl_list[tidx].num_tbls;
+
+	return &ulp_class_tbl_list[idx];
+}
+
+/*
+ * Get the list of key fields that implement the flow.
  *
  * ctxt [in] The ulp context
  *
@@ -46,7 +109,7 @@  ulp_mapper_act_prop_size_get(uint32_t idx)
  *
  * num_flds [out] The number of key fields in the returned array
  *
- * returns array of Key fields, or NULL on error
+ * Returns array of Key fields, or NULL on error.
  */
 static struct bnxt_ulp_mapper_class_key_field_info *
 ulp_mapper_key_fields_get(struct bnxt_ulp_mapper_class_tbl_info *tbl,
@@ -1147,7 +1210,7 @@  ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms *parms,
  * Function to process the action template. Iterate through the list
  * action info templates and process it.
  */
-int32_t
+static int32_t
 ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms)
 {
 	uint32_t	i;
@@ -1169,7 +1232,7 @@  ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms)
 }
 
 /* Create the classifier table entries for a flow. */
-int32_t
+static int32_t
 ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms)
 {
 	uint32_t	i;
@@ -1324,3 +1387,116 @@  ulp_mapper_flow_destroy(struct bnxt_ulp_context	*ulp_ctx, uint32_t fid)
 					 fid,
 					 BNXT_ULP_REGULAR_FLOW_TABLE);
 }
+
+/* Function to handle the mapping of the Flow to be compatible
+ * with the underlying hardware.
+ */
+int32_t
+ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
+		       uint32_t app_priority __rte_unused,
+		       struct ulp_rte_hdr_bitmap *hdr_bitmap __rte_unused,
+		       struct ulp_rte_hdr_field *hdr_field,
+		       struct ulp_rte_act_bitmap *act_bitmap,
+		       struct ulp_rte_act_prop *act_prop,
+		       uint32_t class_tid,
+		       uint32_t act_tid,
+		       uint32_t *flow_id)
+{
+	struct ulp_regfile		regfile;
+	struct bnxt_ulp_mapper_parms	parms;
+	struct bnxt_ulp_device_params	*device_params;
+	int32_t				rc, trc;
+
+	/* Initialize the parms structure */
+	memset(&parms, 0, sizeof(parms));
+	parms.act_prop = act_prop;
+	parms.act_bitmap = act_bitmap;
+	parms.regfile = &regfile;
+	parms.hdr_field = hdr_field;
+	parms.tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
+	parms.ulp_ctx = ulp_ctx;
+
+	/* Get the device id from the ulp context */
+	if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) {
+		BNXT_TF_DBG(ERR, "Invalid ulp context\n");
+		return -EINVAL;
+	}
+
+	/* Get the action table entry from device id and act context id */
+	parms.act_tid = act_tid;
+	parms.atbls = ulp_mapper_action_tbl_list_get(parms.dev_id,
+						     parms.act_tid,
+						     &parms.num_atbls);
+	if (!parms.atbls || !parms.num_atbls) {
+		BNXT_TF_DBG(ERR, "No action tables for %d:%d\n",
+			    parms.dev_id, parms.act_tid);
+		return -EINVAL;
+	}
+
+	/* Get the class table entry from device id and act context id */
+	parms.class_tid = class_tid;
+	parms.ctbls = ulp_mapper_class_tbl_list_get(parms.dev_id,
+						    parms.class_tid,
+						    &parms.num_ctbls);
+	if (!parms.ctbls || !parms.num_ctbls) {
+		BNXT_TF_DBG(ERR, "No class tables for %d:%d\n",
+			    parms.dev_id, parms.class_tid);
+		return -EINVAL;
+	}
+
+	/* Get the byte order for the further processing from device params */
+	device_params = bnxt_ulp_device_params_get(parms.dev_id);
+	if (!device_params) {
+		BNXT_TF_DBG(ERR, "No class tables for %d:%d\n",
+			    parms.dev_id, parms.class_tid);
+		return -EINVAL;
+	}
+	parms.order = device_params->byte_order;
+	parms.encap_byte_swap = device_params->encap_byte_swap;
+
+	/* initialize the registry file for further processing */
+	if (!ulp_regfile_init(parms.regfile)) {
+		BNXT_TF_DBG(ERR, "regfile initialization failed.\n");
+		return -EINVAL;
+	}
+
+	/* Allocate a Flow ID for attaching all resources for the flow to.
+	 * Once allocated, all errors have to walk the list of resources and
+	 * free each of them.
+	 */
+	rc = ulp_flow_db_fid_alloc(ulp_ctx,
+				   BNXT_ULP_REGULAR_FLOW_TABLE,
+				   &parms.fid);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n");
+		return rc;
+	}
+
+	/* Process the action template list from the selected action table*/
+	rc = ulp_mapper_action_tbls_process(&parms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "action tables failed creation for %d:%d\n",
+			    parms.dev_id, parms.act_tid);
+		goto flow_error;
+	}
+
+	/* All good. Now process the class template */
+	rc = ulp_mapper_class_tbls_process(&parms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "class tables failed creation for %d:%d\n",
+			    parms.dev_id, parms.class_tid);
+		goto flow_error;
+	}
+
+	*flow_id = parms.fid;
+
+	return rc;
+
+flow_error:
+	/* Free all resources that were allocated during flow creation */
+	trc = ulp_mapper_flow_destroy(ulp_ctx, parms.fid);
+	if (trc)
+		BNXT_TF_DBG(ERR, "Failed to free all resources rc=%d\n", trc);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.h b/drivers/net/bnxt/tf_ulp/ulp_mapper.h
index 8655728..5f3d46e 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.h
@@ -38,6 +38,21 @@  struct bnxt_ulp_mapper_parms {
 	enum bnxt_ulp_flow_db_tables		tbl_idx;
 };
 
+/*
+ * Function to handle the mapping of the Flow to be compatible
+ * with the underlying hardware.
+ */
+int32_t
+ulp_mapper_flow_create(struct bnxt_ulp_context	*ulp_ctx,
+		       uint32_t		app_priority,
+		       struct ulp_rte_hdr_bitmap  *hdr_bitmap,
+		       struct ulp_rte_hdr_field *hdr_field,
+		       struct ulp_rte_act_bitmap *act,
+		       struct ulp_rte_act_prop *act_prop,
+		       uint32_t		class_tid,
+		       uint32_t		act_tid,
+		       uint32_t		*flow_id);
+
 /* Function that frees all resources associated with the flow. */
 int32_t
 ulp_mapper_flow_destroy(struct bnxt_ulp_context	*ulp_ctx, uint32_t fid);
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db.c b/drivers/net/bnxt/tf_ulp/ulp_template_db.c
index ba06493..5ec7adc 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_db.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_db.c
@@ -1004,6 +1004,28 @@  struct bnxt_ulp_mapper_ident_info ulp_ident_list[] = {
 	}
 };
 
+struct bnxt_ulp_mapper_tbl_list_info ulp_act_tmpl_list[] = {
+	[((0 << BNXT_ULP_LOG2_MAX_NUM_DEV) | BNXT_ULP_DEVICE_ID_WH_PLUS)] = {
+	.device_name = BNXT_ULP_DEVICE_ID_WH_PLUS,
+	.num_tbls = 1,
+	.start_tbl_idx = 0
+	}
+};
+
+struct bnxt_ulp_mapper_act_tbl_info ulp_act_tbl_list[] = {
+	{
+	.resource_func = BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE,
+	.table_type = TF_TBL_TYPE_EXT,
+	.direction = TF_DIR_RX,
+	.srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO,
+	.result_start_idx = 0,
+	.result_bit_size = 128,
+	.result_num_fields = 26,
+	.encap_num_fields = 0,
+	.regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_ACTION_PTR_MAIN
+	}
+};
+
 struct bnxt_ulp_mapper_result_field_info ulp_act_result_field_list[] = {
 	{
 	.field_bit_size = 14,
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db.h b/drivers/net/bnxt/tf_ulp/ulp_template_db.h
index 733836a..957b21a 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_db.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_db.h
@@ -12,6 +12,7 @@ 
 #define ULP_TEMPLATE_DB_H_
 
 #define BNXT_ULP_MAX_NUM_DEVICES 4
+#define BNXT_ULP_LOG2_MAX_NUM_DEV 2
 
 enum bnxt_ulp_action_bit {
 	BNXT_ULP_ACTION_BIT_MARK             = 0x0000000000000001,
@@ -127,6 +128,12 @@  enum bnxt_ulp_result_opc {
 	BNXT_ULP_RESULT_OPC_LAST = 4
 };
 
+enum bnxt_ulp_search_before_alloc {
+	BNXT_ULP_SEARCH_BEFORE_ALLOC_NO = 0,
+	BNXT_ULP_SEARCH_BEFORE_ALLOC_YES = 1,
+	BNXT_ULP_SEARCH_BEFORE_ALLOC_LAST = 2
+};
+
 enum bnxt_ulp_spec_opc {
 	BNXT_ULP_SPEC_OPC_SET_TO_CONSTANT = 0,
 	BNXT_ULP_SPEC_OPC_SET_TO_HDR_FIELD = 1,
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
index e28d049..b7094c5 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
@@ -17,6 +17,10 @@ 
 #include "rte_flow.h"
 #include "tf_core.h"
 
+struct ulp_rte_hdr_bitmap {
+	uint64_t	bits;
+};
+
 /* Structure to store the protocol fields */
 #define RTE_PARSER_FLOW_HDR_FIELD_SIZE		16
 struct ulp_rte_hdr_field {
@@ -51,6 +55,13 @@  struct bnxt_ulp_device_params {
 	uint32_t			num_resources_per_flow;
 };
 
+/* Flow Mapper */
+struct bnxt_ulp_mapper_tbl_list_info {
+	uint32_t	device_name;
+	uint32_t	start_tbl_idx;
+	uint32_t	num_tbls;
+};
+
 struct bnxt_ulp_mapper_class_tbl_info {
 	enum bnxt_ulp_resource_func	resource_func;
 	uint32_t	table_type;
@@ -132,7 +143,25 @@  struct bnxt_ulp_mapper_ident_info {
 extern struct bnxt_ulp_device_params ulp_device_params[];
 
 /*
- * The ulp_data_field_list provides the instructions for creating an action
+ * The ulp_class_tmpl_list and ulp_act_tmpl_list are indexed by the dev_id
+ * and template id (either class or action) returned by the matcher.
+ * The result provides the start index and number of entries in the connected
+ * ulp_class_tbl_list/ulp_act_tbl_list.
+ */
+extern struct bnxt_ulp_mapper_tbl_list_info	ulp_class_tmpl_list[];
+extern struct bnxt_ulp_mapper_tbl_list_info	ulp_act_tmpl_list[];
+
+/*
+ * The ulp_class_tbl_list and ulp_act_tbl_list are indexed based on the results
+ * of the template lists.  Each entry describes the high level details of the
+ * table entry to include the start index and number of instructions in the
+ * field lists.
+ */
+extern struct bnxt_ulp_mapper_class_tbl_info	ulp_class_tbl_list[];
+extern struct bnxt_ulp_mapper_act_tbl_info	ulp_act_tbl_list[];
+
+/*
+ * The ulp_class_result_field_list provides the instructions for creating result
  * records such as tcam/em results.
  */
 extern struct bnxt_ulp_mapper_result_field_info	ulp_class_result_field_list[];