[21/50] net/bnxt: support two level priority for TCAMs

Message ID 20200612132934.16488-22-somnath.kotur@broadcom.com (mailing list archive)
State Superseded, archived
Delegated to: Ajit Khaparde
Headers
Series add features for host-based flow management |

Checks

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

Commit Message

Somnath Kotur June 12, 2020, 1:29 p.m. UTC
  From: Jay Ding <jay.ding@broadcom.com>

Allow TCAM indexes to be allocated from top or bottom.
If the priority is set to 0, allocate from the
lowest tcam indexes i.e. from top. Any other value,
allocate it from the highest tcam indexes i.e. from
bottom.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
---
 drivers/net/bnxt/tf_core/bitalloc.c  | 107 +++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/bitalloc.h  |   5 ++
 drivers/net/bnxt/tf_core/tf_rm_new.c |   9 ++-
 drivers/net/bnxt/tf_core/tf_rm_new.h |   8 +++
 drivers/net/bnxt/tf_core/tf_tcam.c   |   1 +
 5 files changed, 129 insertions(+), 1 deletion(-)
  

Patch

diff --git a/drivers/net/bnxt/tf_core/bitalloc.c b/drivers/net/bnxt/tf_core/bitalloc.c
index fb4df9a..918cabf 100644
--- a/drivers/net/bnxt/tf_core/bitalloc.c
+++ b/drivers/net/bnxt/tf_core/bitalloc.c
@@ -7,6 +7,40 @@ 
 
 #define BITALLOC_MAX_LEVELS 6
 
+
+/* Finds the last bit set plus 1, equivalent to gcc __builtin_fls */
+static int
+ba_fls(bitalloc_word_t v)
+{
+	int c = 32;
+
+	if (!v)
+		return 0;
+
+	if (!(v & 0xFFFF0000u)) {
+		v <<= 16;
+		c -= 16;
+	}
+	if (!(v & 0xFF000000u)) {
+		v <<= 8;
+		c -= 8;
+	}
+	if (!(v & 0xF0000000u)) {
+		v <<= 4;
+		c -= 4;
+	}
+	if (!(v & 0xC0000000u)) {
+		v <<= 2;
+		c -= 2;
+	}
+	if (!(v & 0x80000000u)) {
+		v <<= 1;
+		c -= 1;
+	}
+
+	return c;
+}
+
 /* Finds the first bit set plus 1, equivalent to gcc __builtin_ffs */
 static int
 ba_ffs(bitalloc_word_t v)
@@ -120,6 +154,79 @@  ba_alloc(struct bitalloc *pool)
 	return ba_alloc_helper(pool, 0, 1, 32, 0, &clear);
 }
 
+/**
+ * Help function to alloc entry from highest available index
+ *
+ * Searching the pool from highest index for the empty entry.
+ *
+ * [in] pool
+ *   Pointer to the resource pool
+ *
+ * [in] offset
+ *   Offset of the storage in the pool
+ *
+ * [in] words
+ *   Number of words in this level
+ *
+ * [in] size
+ *   Number of entries in this level
+ *
+ * [in] index
+ *   Index of words that has the entry
+ *
+ * [in] clear
+ *   Indicate if a bit needs to be clear due to the entry is allocated
+ *
+ * Returns:
+ *     0 - Success
+ *    -1 - Failure
+ */
+static int
+ba_alloc_reverse_helper(struct bitalloc *pool,
+			int offset,
+			int words,
+			unsigned int size,
+			int index,
+			int *clear)
+{
+	bitalloc_word_t *storage = &pool->storage[offset];
+	int loc = ba_fls(storage[index]);
+	int r;
+
+	if (loc == 0)
+		return -1;
+
+	loc--;
+
+	if (pool->size > size) {
+		r = ba_alloc_reverse_helper(pool,
+					    offset + words + 1,
+					    storage[words],
+					    size * 32,
+					    index * 32 + loc,
+					    clear);
+	} else {
+		r = index * 32 + loc;
+		*clear = 1;
+		pool->free_count--;
+	}
+
+	if (*clear) {
+		storage[index] &= ~(1 << loc);
+		*clear = (storage[index] == 0);
+	}
+
+	return r;
+}
+
+int
+ba_alloc_reverse(struct bitalloc *pool)
+{
+	int clear = 0;
+
+	return ba_alloc_reverse_helper(pool, 0, 1, 32, 0, &clear);
+}
+
 static int
 ba_alloc_index_helper(struct bitalloc *pool,
 		      int              offset,
diff --git a/drivers/net/bnxt/tf_core/bitalloc.h b/drivers/net/bnxt/tf_core/bitalloc.h
index 563c853..2825bb3 100644
--- a/drivers/net/bnxt/tf_core/bitalloc.h
+++ b/drivers/net/bnxt/tf_core/bitalloc.h
@@ -73,6 +73,11 @@  int ba_alloc(struct bitalloc *pool);
 int ba_alloc_index(struct bitalloc *pool, int index);
 
 /**
+ * Returns -1 on failure, or index of allocated entry
+ */
+int ba_alloc_reverse(struct bitalloc *pool);
+
+/**
  * Query a particular index in a pool to check if its in use.
  *
  * Returns -1 on invalid index, 1 if the index is allocated, 0 if it
diff --git a/drivers/net/bnxt/tf_core/tf_rm_new.c b/drivers/net/bnxt/tf_core/tf_rm_new.c
index 02b4b5c..de8f119 100644
--- a/drivers/net/bnxt/tf_core/tf_rm_new.c
+++ b/drivers/net/bnxt/tf_core/tf_rm_new.c
@@ -671,7 +671,14 @@  tf_rm_allocate(struct tf_rm_allocate_parms *parms)
 		return rc;
 	}
 
-	id = ba_alloc(rm_db->db[parms->db_index].pool);
+	/*
+	 * priority  0: allocate from top of the tcam i.e. high
+	 * priority !0: allocate index from bottom i.e lowest
+	 */
+	if (parms->priority)
+		id = ba_alloc_reverse(rm_db->db[parms->db_index].pool);
+	else
+		id = ba_alloc(rm_db->db[parms->db_index].pool);
 	if (id == BA_FAIL) {
 		rc = -ENOMEM;
 		TFP_DRV_LOG(ERR,
diff --git a/drivers/net/bnxt/tf_core/tf_rm_new.h b/drivers/net/bnxt/tf_core/tf_rm_new.h
index a40296e..5cb6889 100644
--- a/drivers/net/bnxt/tf_core/tf_rm_new.h
+++ b/drivers/net/bnxt/tf_core/tf_rm_new.h
@@ -185,6 +185,14 @@  struct tf_rm_allocate_parms {
 	 * i.e. Full Action Record offsets.
 	 */
 	uint32_t *index;
+	/**
+	 * [in] Priority, indicates the prority of the entry
+	 * priority  0: allocate from top of the tcam (from index 0
+	 *              or lowest available index)
+	 * priority !0: allocate from bottom of the tcam (from highest
+	 *              available index)
+	 */
+	uint32_t priority;
 };
 
 /**
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c
index 2f4441d..260fb15 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam.c
@@ -157,6 +157,7 @@  tf_tcam_alloc(struct tf *tfp,
 	/* Allocate requested element */
 	aparms.rm_db = tcam_db[parms->dir];
 	aparms.db_index = parms->type;
+	aparms.priority = parms->priority;
 	aparms.index = (uint32_t *)&parms->idx;
 	rc = tf_rm_allocate(&aparms);
 	if (rc) {