diff mbox series

[v2,07/58] net/bnxt: support L2 Context TCAM ops

Message ID 20210613000652.28191-8-ajit.khaparde@broadcom.com (mailing list archive)
State Accepted, archived
Delegated to: Ajit Khaparde
Headers show
Series enhancements to host based flow table management | expand

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Ajit Khaparde June 13, 2021, 12:06 a.m. UTC
From: Jay Ding <jay.ding@broadcom.com>

- Implement TCAM get in host
- Add Thor support for TCAM set/free

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Signed-off-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Reviewed-by: Peter Spreadborough <peter.spreadborough@broadcom.com>
Reviewed-by: Farah Smith <farah.smith@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/tf_core/hwrm_tf.h       |  1 +
 drivers/net/bnxt/tf_core/tf_core.c       | 65 +++++++++++++++--
 drivers/net/bnxt/tf_core/tf_device.h     | 12 ++++
 drivers/net/bnxt/tf_core/tf_device_p4.c  |  6 ++
 drivers/net/bnxt/tf_core/tf_device_p58.c |  9 ++-
 drivers/net/bnxt/tf_core/tf_msg.c        | 52 ++++++++++++++
 drivers/net/bnxt/tf_core/tf_msg.h        | 16 +++++
 drivers/net/bnxt/tf_core/tf_tcam.c       | 89 +++++++++++++++++++++++-
 drivers/net/bnxt/tf_core/tf_tcam.h       |  4 ++
 9 files changed, 248 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/bnxt/tf_core/hwrm_tf.h b/drivers/net/bnxt/tf_core/hwrm_tf.h
index a707cd2758..9cc9a1435c 100644
--- a/drivers/net/bnxt/tf_core/hwrm_tf.h
+++ b/drivers/net/bnxt/tf_core/hwrm_tf.h
@@ -65,6 +65,7 @@  typedef enum tf_subtype {
 
 #define TF_BITS2BYTES(x) (((x) + 7) >> 3)
 #define TF_BITS2BYTES_WORD_ALIGN(x) ((((x) + 31) >> 5) * 4)
+#define TF_BITS2BYTES_64B_WORD_ALIGN(x) ((((x) + 63) >> 6) * 8)
 
 struct tf_set_global_cfg_input;
 struct tf_get_global_cfg_input;
diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index ebe0fc34aa..a3b6afbc88 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -764,7 +764,8 @@  tf_set_tcam_entry(struct tf *tfp,
 		return rc;
 	}
 
-	if (dev->ops->tf_dev_set_tcam == NULL) {
+	if (dev->ops->tf_dev_set_tcam == NULL ||
+	    dev->ops->tf_dev_word_align == NULL) {
 		rc = -EOPNOTSUPP;
 		TFP_DRV_LOG(ERR,
 			    "%s: Operation not supported, rc:%s\n",
@@ -778,7 +779,7 @@  tf_set_tcam_entry(struct tf *tfp,
 	sparms.idx = parms->idx;
 	sparms.key = parms->key;
 	sparms.mask = parms->mask;
-	sparms.key_size = TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits);
+	sparms.key_size = dev->ops->tf_dev_word_align(parms->key_sz_in_bits);
 	sparms.result = parms->result;
 	sparms.result_size = TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits);
 
@@ -796,10 +797,66 @@  tf_set_tcam_entry(struct tf *tfp,
 
 int
 tf_get_tcam_entry(struct tf *tfp __rte_unused,
-		  struct tf_get_tcam_entry_parms *parms __rte_unused)
+		  struct tf_get_tcam_entry_parms *parms)
 {
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	struct tf_tcam_get_parms gparms;
+
 	TF_CHECK_PARMS2(tfp, parms);
-	return -EOPNOTSUPP;
+
+	memset(&gparms, 0, sizeof(struct tf_tcam_get_parms));
+
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup device, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (dev->ops->tf_dev_get_tcam == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	gparms.dir = parms->dir;
+	gparms.type = parms->tcam_tbl_type;
+	gparms.idx = parms->idx;
+	gparms.key = parms->key;
+	gparms.mask = parms->mask;
+	gparms.result = parms->result;
+
+	rc = dev->ops->tf_dev_get_tcam(tfp, &gparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: TCAM get failed, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+	parms->key_sz_in_bits = gparms.key_size * 8;
+	parms->result_sz_in_bits = gparms.result_size * 8;
+
+	return 0;
 }
 
 int
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index cbacc09ea5..4f4120c603 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -736,6 +736,18 @@  struct tf_dev_ops {
 	 *      mailbox
 	 */
 	int (*tf_dev_get_mailbox)(void);
+
+	/**
+	 * Convert length in bit to length in byte and align to word.
+	 * The word length depends on device type.
+	 *
+	 * [in] size
+	 *   Size in bit
+	 *
+	 * Returns
+	 *   Size in byte
+	 */
+	int (*tf_dev_word_align)(uint16_t size);
 };
 
 /**
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index f6c8f5efd0..fbe92b7733 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -212,6 +212,10 @@  static int tf_dev_p4_get_mailbox(void)
 	return TF_KONG_MB;
 }
 
+static int tf_dev_p4_word_align(uint16_t size)
+{
+	return ((((size) + 31) >> 5) * 4);
+}
 
 /**
  * Truflow P4 device specific functions
@@ -250,6 +254,7 @@  const struct tf_dev_ops tf_dev_ops_p4_init = {
 	.tf_dev_set_global_cfg = NULL,
 	.tf_dev_get_global_cfg = NULL,
 	.tf_dev_get_mailbox = tf_dev_p4_get_mailbox,
+	.tf_dev_word_align = NULL,
 };
 
 /**
@@ -289,4 +294,5 @@  const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_set_global_cfg = tf_global_cfg_set,
 	.tf_dev_get_global_cfg = tf_global_cfg_get,
 	.tf_dev_get_mailbox = tf_dev_p4_get_mailbox,
+	.tf_dev_word_align = tf_dev_p4_word_align,
 };
diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c
index 6cef1d5ba5..688d987cb7 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p58.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p58.c
@@ -193,6 +193,11 @@  static int tf_dev_p58_get_mailbox(void)
 	return TF_CHIMP_MB;
 }
 
+static int tf_dev_p58_word_align(uint16_t size)
+{
+	return ((((size) + 63) >> 6) * 8);
+}
+
 /**
  * Truflow P58 device specific functions
  */
@@ -230,6 +235,7 @@  const struct tf_dev_ops tf_dev_ops_p58_init = {
 	.tf_dev_set_global_cfg = NULL,
 	.tf_dev_get_global_cfg = NULL,
 	.tf_dev_get_mailbox = tf_dev_p58_get_mailbox,
+	.tf_dev_word_align = NULL,
 };
 
 /**
@@ -255,7 +261,7 @@  const struct tf_dev_ops tf_dev_ops_p58 = {
 	.tf_dev_free_tcam = tf_tcam_free,
 	.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,
 	.tf_dev_set_tcam = tf_tcam_set,
-	.tf_dev_get_tcam = NULL,
+	.tf_dev_get_tcam = tf_tcam_get,
 	.tf_dev_insert_int_em_entry = tf_em_hash_insert_int_entry,
 	.tf_dev_delete_int_em_entry = tf_em_hash_delete_int_entry,
 	.tf_dev_insert_ext_em_entry = NULL,
@@ -269,4 +275,5 @@  const struct tf_dev_ops tf_dev_ops_p58 = {
 	.tf_dev_set_global_cfg = tf_global_cfg_set,
 	.tf_dev_get_global_cfg = tf_global_cfg_get,
 	.tf_dev_get_mailbox = tf_dev_p58_get_mailbox,
+	.tf_dev_word_align = tf_dev_p58_word_align,
 };
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index 39d7e3eace..1af5c6d11c 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -1212,6 +1212,58 @@  tf_msg_tcam_entry_set(struct tf *tfp,
 	return rc;
 }
 
+int
+tf_msg_tcam_entry_get(struct tf *tfp,
+		      struct tf_dev_info *dev,
+		      struct tf_tcam_get_parms *parms)
+{
+	int rc;
+	struct tfp_send_msg_parms mparms = { 0 };
+	struct hwrm_tf_tcam_get_input req = { 0 };
+	struct hwrm_tf_tcam_get_output resp = { 0 };
+	uint8_t fw_session_id;
+
+	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Unable to lookup FW id, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Populate the request */
+	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
+	req.type = parms->hcapi_type;
+	req.idx = tfp_cpu_to_le_16(parms->idx);
+	if (parms->dir == TF_DIR_TX)
+		req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX;
+
+	mparms.tf_type = HWRM_TF_TCAM_GET;
+	mparms.req_data = (uint32_t *)&req;
+	mparms.req_size = sizeof(req);
+	mparms.resp_data = (uint32_t *)&resp;
+	mparms.resp_size = sizeof(resp);
+	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
+
+	rc = tfp_send_msg_direct(tfp,
+				 &mparms);
+
+	if (rc != 0)
+		return rc;
+
+	if (mparms.tf_resp_code != 0)
+		return tfp_le_to_cpu_32(mparms.tf_resp_code);
+
+	parms->key_size = resp.key_size;
+	parms->result_size = resp.result_size;
+	tfp_memcpy(parms->key, resp.dev_data, resp.key_size);
+	tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size);
+	tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size);
+
+	return tfp_le_to_cpu_32(mparms.tf_resp_code);
+}
+
 int
 tf_msg_tcam_entry_free(struct tf *tfp,
 		       struct tf_dev_info *dev,
diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h
index 1d82ce5049..a14bcd3927 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.h
+++ b/drivers/net/bnxt/tf_core/tf_msg.h
@@ -412,6 +412,22 @@  int tf_msg_tcam_entry_set(struct tf *tfp,
 			  struct tf_dev_info *dev,
 			  struct tf_tcam_set_parms *parms);
 
+/**
+ * Sends tcam entry 'get' to the Firmware.
+ *
+ * [in] tfp
+ *   Pointer to session handle
+ *
+ * [in] parms
+ *   Pointer to get parameters
+ *
+ * Returns:
+ *  0 on Success else internal Truflow error
+ */
+int tf_msg_tcam_entry_get(struct tf *tfp,
+			  struct tf_dev_info *dev,
+			  struct tf_tcam_get_parms *parms);
+
 /**
  * Sends tcam entry 'free' to the Firmware.
  *
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c
index 038aa40e92..a18d0e1e19 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam.c
@@ -686,7 +686,94 @@  tf_tcam_set(struct tf *tfp __rte_unused,
 
 int
 tf_tcam_get(struct tf *tfp __rte_unused,
-	    struct tf_tcam_get_parms *parms __rte_unused)
+	    struct tf_tcam_get_parms *parms)
 {
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	struct tf_rm_is_allocated_parms aparms;
+	struct tf_rm_get_hcapi_parms hparms;
+	uint16_t num_slice_per_row = 1;
+	int allocated = 0;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No TCAM DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Need to retrieve row size etc */
+	rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
+						  parms->type,
+						  parms->key_size,
+						  &num_slice_per_row);
+	if (rc)
+		return rc;
+
+	/* Check if element is in use */
+	memset(&aparms, 0, sizeof(aparms));
+
+	aparms.rm_db = tcam_db[parms->dir];
+	aparms.db_index = parms->type;
+	aparms.index = parms->idx / num_slice_per_row;
+	aparms.allocated = &allocated;
+	rc = tf_rm_is_allocated(&aparms);
+	if (rc)
+		return rc;
+
+	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry is not allocated, type:%d, index:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    parms->idx);
+		return -EINVAL;
+	}
+
+	/* Convert TF type to HCAPI RM type */
+	memset(&hparms, 0, sizeof(hparms));
+
+	hparms.rm_db = tcam_db[parms->dir];
+	hparms.db_index = parms->type;
+	hparms.hcapi_type = &parms->hcapi_type;
+
+	rc = tf_rm_get_hcapi_type(&hparms);
+	if (rc)
+		return rc;
+
+	rc = tf_msg_tcam_entry_get(tfp, dev, parms);
+	if (rc) {
+		/* Log error */
+		TFP_DRV_LOG(ERR,
+			    "%s: %s: Entry %d set failed, rc:%s",
+			    tf_dir_2_str(parms->dir),
+			    tf_tcam_tbl_2_str(parms->type),
+			    parms->idx,
+			    strerror(-rc));
+		return rc;
+	}
+
 	return 0;
 }
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.h b/drivers/net/bnxt/tf_core/tf_tcam.h
index 40d010b09a..b550fa43ca 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.h
+++ b/drivers/net/bnxt/tf_core/tf_tcam.h
@@ -207,6 +207,10 @@  struct tf_tcam_get_parms {
 	 * [in] Type of object to get
 	 */
 	enum tf_tcam_tbl_type type;
+	/**
+	 * [in] Type of HCAPI
+	 */
+	uint16_t hcapi_type;
 	/**
 	 * [in] Entry index to read
 	 */