patches for DPDK stable branches
 help / color / Atom feed
* [dpdk-stable] [PATCH 01/12] net/cxgbe: add cxgbe_ prefix to global functions
       [not found] <cover.1567799552.git.rahul.lakkireddy@chelsio.com>
@ 2019-09-06 21:52 ` Rahul Lakkireddy
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 02/12] net/cxgbe: fix NULL access when allocating CLIP entry Rahul Lakkireddy
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-06 21:52 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

To avoid name collisions, add cxgbe_ prefix to some global functions.
Also, make some local functions static in cxgbe_filter.c.

Cc: stable@dpdk.org
Fixes: ee61f5113b17 ("net/cxgbe: parse and validate flows")
Fixes: 9eb2c9a48072 ("net/cxgbe: implement flow create operation")
Fixes: 3a381a4116ed ("net/cxgbe: query firmware for HASH filter resources")
Fixes: af44a577988b ("net/cxgbe: support to offload flows to HASH region")
Fixes: 41dc98b0827a ("net/cxgbe: support to delete flows in HASH region")
Fixes: 23af667f1507 ("net/cxgbe: add API to program hardware layer 2 table")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/cxgbe_filter.c | 30 ++++++++++++++++--------------
 drivers/net/cxgbe/cxgbe_filter.h | 19 +++++++++----------
 drivers/net/cxgbe/cxgbe_flow.c   |  6 +++---
 drivers/net/cxgbe/cxgbe_main.c   | 10 +++++-----
 drivers/net/cxgbe/l2t.c          |  3 ++-
 drivers/net/cxgbe/l2t.h          |  3 ++-
 6 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index 7fcee5c0a..cc8774c1d 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -14,7 +14,7 @@
 /**
  * Initialize Hash Filters
  */
-int init_hash_filter(struct adapter *adap)
+int cxgbe_init_hash_filter(struct adapter *adap)
 {
 	unsigned int n_user_filters;
 	unsigned int user_filter_perc;
@@ -53,7 +53,8 @@ int init_hash_filter(struct adapter *adap)
  * Validate if the requested filter specification can be set by checking
  * if the requested features have been enabled
  */
-int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)
+int cxgbe_validate_filter(struct adapter *adapter,
+			  struct ch_filter_specification *fs)
 {
 	u32 fconf;
 
@@ -133,7 +134,7 @@ static unsigned int get_filter_steerq(struct rte_eth_dev *dev,
 }
 
 /* Return an error number if the indicated filter isn't writable ... */
-int writable_filter(struct filter_entry *f)
+static int writable_filter(struct filter_entry *f)
 {
 	if (f->locked)
 		return -EPERM;
@@ -214,7 +215,7 @@ static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
 /**
  * Check if entry already filled.
  */
-bool is_filter_set(struct tid_info *t, int fidx, int family)
+bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
 {
 	bool result = FALSE;
 	int i, max;
@@ -527,7 +528,7 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
 	int atid, size;
 	int ret = 0;
 
-	ret = validate_filter(adapter, fs);
+	ret = cxgbe_validate_filter(adapter, fs);
 	if (ret)
 		return ret;
 
@@ -618,7 +619,7 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
  * Clear a filter and release any of its resources that we own.  This also
  * clears the filter's "pending" status.
  */
-void clear_filter(struct filter_entry *f)
+static void clear_filter(struct filter_entry *f)
 {
 	if (f->clipt)
 		cxgbe_clip_release(f->dev, f->clipt);
@@ -690,7 +691,7 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 	return 0;
 }
 
-int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
+static int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 {
 	struct adapter *adapter = ethdev2adap(dev);
 	struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
@@ -868,7 +869,7 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 
 	chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
 
-	ret = is_filter_set(&adapter->tids, filter_id, fs->type);
+	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
 	if (!ret) {
 		dev_warn(adap, "%s: could not find filter entry: %u\n",
 			 __func__, filter_id);
@@ -940,7 +941,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 
 	chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
 
-	ret = validate_filter(adapter, fs);
+	ret = cxgbe_validate_filter(adapter, fs);
 	if (ret)
 		return ret;
 
@@ -951,7 +952,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	if (fs->type)
 		filter_id &= ~(0x3);
 
-	ret = is_filter_set(&adapter->tids, filter_id, fs->type);
+	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
 	if (ret)
 		return -EBUSY;
 
@@ -1091,7 +1092,8 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 /**
  * Handle a Hash filter write reply.
  */
-void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl)
+void cxgbe_hash_filter_rpl(struct adapter *adap,
+			   const struct cpl_act_open_rpl *rpl)
 {
 	struct tid_info *t = &adap->tids;
 	struct filter_entry *f;
@@ -1159,7 +1161,7 @@ void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl)
 /**
  * Handle a LE-TCAM filter write/deletion reply.
  */
-void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
+void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
 {
 	struct filter_entry *f = NULL;
 	unsigned int tid = GET_TID(rpl);
@@ -1357,8 +1359,8 @@ int cxgbe_clear_filter_count(struct adapter *adapter, unsigned int fidx,
 /**
  * Handle a Hash filter delete reply.
  */
-void hash_del_filter_rpl(struct adapter *adap,
-			 const struct cpl_abort_rpl_rss *rpl)
+void cxgbe_hash_del_filter_rpl(struct adapter *adap,
+			       const struct cpl_abort_rpl_rss *rpl)
 {
 	struct tid_info *t = &adap->tids;
 	struct filter_entry *f;
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 0c67d2d15..1964730ba 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -248,11 +248,8 @@ cxgbe_bitmap_find_free_region(struct rte_bitmap *bmap, unsigned int size,
 	return idx;
 }
 
-bool is_filter_set(struct tid_info *, int fidx, int family);
-void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
-void clear_filter(struct filter_entry *f);
-int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx);
-int writable_filter(struct filter_entry *f);
+bool cxgbe_is_filter_set(struct tid_info *, int fidx, int family);
+void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
 int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		     struct ch_filter_specification *fs,
 		     struct filter_ctx *ctx);
@@ -260,11 +257,13 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		     struct ch_filter_specification *fs,
 		     struct filter_ctx *ctx);
 int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family);
-int init_hash_filter(struct adapter *adap);
-void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl);
-void hash_del_filter_rpl(struct adapter *adap,
-			 const struct cpl_abort_rpl_rss *rpl);
-int validate_filter(struct adapter *adap, struct ch_filter_specification *fs);
+int cxgbe_init_hash_filter(struct adapter *adap);
+void cxgbe_hash_filter_rpl(struct adapter *adap,
+			   const struct cpl_act_open_rpl *rpl);
+void cxgbe_hash_del_filter_rpl(struct adapter *adap,
+			       const struct cpl_abort_rpl_rss *rpl);
+int cxgbe_validate_filter(struct adapter *adap,
+			  struct ch_filter_specification *fs);
 int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,
 			   u64 *c, int hash, bool get_byte);
 int cxgbe_clear_filter_count(struct adapter *adapter, unsigned int fidx,
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index d3de689c3..848c61f02 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -309,7 +309,7 @@ static int cxgbe_validate_fidxondel(struct filter_entry *f, unsigned int fidx)
 		dev_err(adap, "invalid flow index %d.\n", fidx);
 		return -EINVAL;
 	}
-	if (!is_filter_set(&adap->tids, fidx, fs.type)) {
+	if (!cxgbe_is_filter_set(&adap->tids, fidx, fs.type)) {
 		dev_err(adap, "Already free fidx:%d f:%p\n", fidx, f);
 		return -EINVAL;
 	}
@@ -321,7 +321,7 @@ static int
 cxgbe_validate_fidxonadd(struct ch_filter_specification *fs,
 			 struct adapter *adap, unsigned int fidx)
 {
-	if (is_filter_set(&adap->tids, fidx, fs->type)) {
+	if (cxgbe_is_filter_set(&adap->tids, fidx, fs->type)) {
 		dev_err(adap, "filter index: %d is busy.\n", fidx);
 		return -EBUSY;
 	}
@@ -1019,7 +1019,7 @@ cxgbe_flow_validate(struct rte_eth_dev *dev,
 		return ret;
 	}
 
-	if (validate_filter(adap, &flow->fs)) {
+	if (cxgbe_validate_filter(adap, &flow->fs)) {
 		t4_os_free(flow);
 		return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
 				NULL,
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 620f60b4d..c3e6b9557 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -92,19 +92,19 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
 	} else if (opcode == CPL_ABORT_RPL_RSS) {
 		const struct cpl_abort_rpl_rss *p = (const void *)rsp;
 
-		hash_del_filter_rpl(q->adapter, p);
+		cxgbe_hash_del_filter_rpl(q->adapter, p);
 	} else if (opcode == CPL_SET_TCB_RPL) {
 		const struct cpl_set_tcb_rpl *p = (const void *)rsp;
 
-		filter_rpl(q->adapter, p);
+		cxgbe_filter_rpl(q->adapter, p);
 	} else if (opcode == CPL_ACT_OPEN_RPL) {
 		const struct cpl_act_open_rpl *p = (const void *)rsp;
 
-		hash_filter_rpl(q->adapter, p);
+		cxgbe_hash_filter_rpl(q->adapter, p);
 	} else if (opcode == CPL_L2T_WRITE_RPL) {
 		const struct cpl_l2t_write_rpl *p = (const void *)rsp;
 
-		do_l2t_write_rpl(q->adapter, p);
+		cxgbe_do_l2t_write_rpl(q->adapter, p);
 	} else {
 		dev_err(adapter, "unexpected CPL %#x on FW event queue\n",
 			opcode);
@@ -1179,7 +1179,7 @@ static int adap_init0(struct adapter *adap)
 
 	if ((caps_cmd.niccaps & cpu_to_be16(FW_CAPS_CONFIG_NIC_HASHFILTER)) &&
 	    is_t6(adap->params.chip)) {
-		if (init_hash_filter(adap) < 0)
+		if (cxgbe_init_hash_filter(adap) < 0)
 			goto bye;
 	}
 
diff --git a/drivers/net/cxgbe/l2t.c b/drivers/net/cxgbe/l2t.c
index 6faf624f7..f9d651fe0 100644
--- a/drivers/net/cxgbe/l2t.c
+++ b/drivers/net/cxgbe/l2t.c
@@ -22,7 +22,8 @@ void cxgbe_l2t_release(struct l2t_entry *e)
  * Process a CPL_L2T_WRITE_RPL. Note that the TID in the reply is really
  * the L2T index it refers to.
  */
-void do_l2t_write_rpl(struct adapter *adap, const struct cpl_l2t_write_rpl *rpl)
+void cxgbe_do_l2t_write_rpl(struct adapter *adap,
+			    const struct cpl_l2t_write_rpl *rpl)
 {
 	struct l2t_data *d = adap->l2t;
 	unsigned int tid = GET_TID(rpl);
diff --git a/drivers/net/cxgbe/l2t.h b/drivers/net/cxgbe/l2t.h
index 326abfde4..2c489e4aa 100644
--- a/drivers/net/cxgbe/l2t.h
+++ b/drivers/net/cxgbe/l2t.h
@@ -53,5 +53,6 @@ void t4_cleanup_l2t(struct adapter *adap);
 struct l2t_entry *cxgbe_l2t_alloc_switching(struct rte_eth_dev *dev, u16 vlan,
 					    u8 port, u8 *dmac);
 void cxgbe_l2t_release(struct l2t_entry *e);
-void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl);
+void cxgbe_do_l2t_write_rpl(struct adapter *p,
+			    const struct cpl_l2t_write_rpl *rpl);
 #endif /* _CXGBE_L2T_H_ */
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH 02/12] net/cxgbe: fix NULL access when allocating CLIP entry
       [not found] <cover.1567799552.git.rahul.lakkireddy@chelsio.com>
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 01/12] net/cxgbe: add cxgbe_ prefix to global functions Rahul Lakkireddy
@ 2019-09-06 21:52 ` Rahul Lakkireddy
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 03/12] net/cxgbe: fix slot allocation for IPv6 flows Rahul Lakkireddy
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-06 21:52 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

Pass correct arguments to CLIP allocation code to avoid NULL pointer
dereference.

Cc: stable@dpdk.org
Fixes: 3f2c1e209cfc ("net/cxgbe: add Compressed Local IP region")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/cxgbe_filter.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index cc8774c1d..3b7966d04 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -1052,7 +1052,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	 */
 	if (chip_ver > CHELSIO_T5 && fs->type &&
 	    memcmp(fs->val.lip, bitoff, sizeof(bitoff))) {
-		f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
+		f->clipt = cxgbe_clip_alloc(dev, (u32 *)&fs->val.lip);
 		if (!f->clipt)
 			goto free_tid;
 	}
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH 03/12] net/cxgbe: fix slot allocation for IPv6 flows
       [not found] <cover.1567799552.git.rahul.lakkireddy@chelsio.com>
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 01/12] net/cxgbe: add cxgbe_ prefix to global functions Rahul Lakkireddy
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 02/12] net/cxgbe: fix NULL access when allocating CLIP entry Rahul Lakkireddy
@ 2019-09-06 21:52 ` Rahul Lakkireddy
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 04/12] net/cxgbe: fix parsing VLAN ID rewrite action Rahul Lakkireddy
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-06 21:52 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

IPv6 flows occupy only 2 slots on Chelsio T6 NICs. Fix the slot
calculation logic to return correct number of slots.

Cc: stable@dpdk.org
Fixes: ee61f5113b17 ("net/cxgbe: parse and validate flows")
Fixes: 9eb2c9a48072 ("net/cxgbe: implement flow create operation")
Fixes: 3f2c1e209cfc ("net/cxgbe: add Compressed Local IP region")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/cxgbe_filter.c | 193 +++++++++++--------------------
 drivers/net/cxgbe/cxgbe_filter.h |   5 +-
 drivers/net/cxgbe/cxgbe_flow.c   |  15 ++-
 3 files changed, 85 insertions(+), 128 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index 3b7966d04..33b95a69a 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -213,20 +213,32 @@ static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
 }
 
 /**
- * Check if entry already filled.
+ * IPv6 requires 2 slots on T6 and 4 slots for cards below T6.
+ * IPv4 requires only 1 slot on all cards.
  */
-bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
+u8 cxgbe_filter_slots(struct adapter *adap, u8 family)
 {
-	bool result = FALSE;
-	int i, max;
+	if (family == FILTER_TYPE_IPV6) {
+		if (CHELSIO_CHIP_VERSION(adap->params.chip) < CHELSIO_T6)
+			return 4;
 
-	/* IPv6 requires four slots and IPv4 requires only 1 slot.
-	 * Ensure, there's enough slots available.
-	 */
-	max = family == FILTER_TYPE_IPV6 ? fidx + 3 : fidx;
+		return 2;
+	}
+
+	return 1;
+}
+
+/**
+ * Check if entries are already filled.
+ */
+bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries)
+{
+	bool result = FALSE;
+	u32 i;
 
+	/* Ensure there's enough slots available. */
 	t4_os_lock(&t->ftid_lock);
-	for (i = fidx; i <= max; i++) {
+	for (i = fidx; i < fidx + nentries; i++) {
 		if (rte_bitmap_get(t->ftid_bmap, i)) {
 			result = TRUE;
 			break;
@@ -237,17 +249,18 @@ bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
 }
 
 /**
- * Allocate a available free entry
+ * Allocate available free entries.
  */
-int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family)
+int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries)
 {
 	struct tid_info *t = &adap->tids;
 	int pos;
 	int size = t->nftids;
 
 	t4_os_lock(&t->ftid_lock);
-	if (family == FILTER_TYPE_IPV6)
-		pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size, 4);
+	if (nentries > 1)
+		pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size,
+						    nentries);
 	else
 		pos = cxgbe_find_first_zero_bit(t->ftid_bmap, size);
 	t4_os_unlock(&t->ftid_lock);
@@ -565,7 +578,7 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
 	if (atid < 0)
 		goto out_err;
 
-	if (f->fs.type) {
+	if (f->fs.type == FILTER_TYPE_IPV6) {
 		/* IPv6 hash filter */
 		f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
 		if (!f->clipt)
@@ -804,44 +817,34 @@ static int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 }
 
 /**
- * Set the corresponding entry in the bitmap. 4 slots are
- * marked for IPv6, whereas only 1 slot is marked for IPv4.
+ * Set the corresponding entries in the bitmap.
  */
-static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
+static int cxgbe_set_ftid(struct tid_info *t, u32 fidx, u8 nentries)
 {
+	u32 i;
+
 	t4_os_lock(&t->ftid_lock);
 	if (rte_bitmap_get(t->ftid_bmap, fidx)) {
 		t4_os_unlock(&t->ftid_lock);
 		return -EBUSY;
 	}
 
-	if (family == FILTER_TYPE_IPV4) {
-		rte_bitmap_set(t->ftid_bmap, fidx);
-	} else {
-		rte_bitmap_set(t->ftid_bmap, fidx);
-		rte_bitmap_set(t->ftid_bmap, fidx + 1);
-		rte_bitmap_set(t->ftid_bmap, fidx + 2);
-		rte_bitmap_set(t->ftid_bmap, fidx + 3);
-	}
+	for (i = fidx; i < fidx + nentries; i++)
+		rte_bitmap_set(t->ftid_bmap, i);
 	t4_os_unlock(&t->ftid_lock);
 	return 0;
 }
 
 /**
- * Clear the corresponding entry in the bitmap. 4 slots are
- * cleared for IPv6, whereas only 1 slot is cleared for IPv4.
+ * Clear the corresponding entries in the bitmap.
  */
-static void cxgbe_clear_ftid(struct tid_info *t, int fidx, int family)
+static void cxgbe_clear_ftid(struct tid_info *t, u32 fidx, u8 nentries)
 {
+	u32 i;
+
 	t4_os_lock(&t->ftid_lock);
-	if (family == FILTER_TYPE_IPV4) {
-		rte_bitmap_clear(t->ftid_bmap, fidx);
-	} else {
-		rte_bitmap_clear(t->ftid_bmap, fidx);
-		rte_bitmap_clear(t->ftid_bmap, fidx + 1);
-		rte_bitmap_clear(t->ftid_bmap, fidx + 2);
-		rte_bitmap_clear(t->ftid_bmap, fidx + 3);
-	}
+	for (i = fidx; i < fidx + nentries; i++)
+		rte_bitmap_clear(t->ftid_bmap, i);
 	t4_os_unlock(&t->ftid_lock);
 }
 
@@ -859,6 +862,7 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	struct adapter *adapter = pi->adapter;
 	struct filter_entry *f;
 	unsigned int chip_ver;
+	u8 nentries;
 	int ret;
 
 	if (is_hashfilter(adapter) && fs->cap)
@@ -869,24 +873,25 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 
 	chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
 
-	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
-	if (!ret) {
-		dev_warn(adap, "%s: could not find filter entry: %u\n",
-			 __func__, filter_id);
-		return -EINVAL;
-	}
-
 	/*
-	 * Ensure filter id is aligned on the 2 slot boundary for T6,
+	 * Ensure IPv6 filter id is aligned on the 2 slot boundary for T6,
 	 * and 4 slot boundary for cards below T6.
 	 */
-	if (fs->type) {
+	if (fs->type == FILTER_TYPE_IPV6) {
 		if (chip_ver < CHELSIO_T6)
 			filter_id &= ~(0x3);
 		else
 			filter_id &= ~(0x1);
 	}
 
+	nentries = cxgbe_filter_slots(adapter, fs->type);
+	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
+	if (!ret) {
+		dev_warn(adap, "%s: could not find filter entry: %u\n",
+			 __func__, filter_id);
+		return -EINVAL;
+	}
+
 	f = &adapter->tids.ftid_tab[filter_id];
 	ret = writable_filter(f);
 	if (ret)
@@ -896,8 +901,7 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		f->ctx = ctx;
 		cxgbe_clear_ftid(&adapter->tids,
 				 f->tid - adapter->tids.ftid_base,
-				 f->fs.type ? FILTER_TYPE_IPV6 :
-					      FILTER_TYPE_IPV4);
+				 nentries);
 		return del_filter_wr(dev, filter_id);
 	}
 
@@ -927,10 +931,10 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 {
 	struct port_info *pi = ethdev2pinfo(dev);
 	struct adapter *adapter = pi->adapter;
-	unsigned int fidx, iq, fid_bit = 0;
+	unsigned int fidx, iq;
 	struct filter_entry *f;
 	unsigned int chip_ver;
-	uint8_t bitoff[16] = {0};
+	u8 nentries, bitoff[16] = {0};
 	int ret;
 
 	if (is_hashfilter(adapter) && fs->cap)
@@ -945,80 +949,31 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	if (ret)
 		return ret;
 
-	/*
-	 * Ensure filter id is aligned on the 4 slot boundary for IPv6
-	 * maskfull filters.
-	 */
-	if (fs->type)
-		filter_id &= ~(0x3);
-
-	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
-	if (ret)
-		return -EBUSY;
-
-	iq = get_filter_steerq(dev, fs);
-
 	/*
 	 * IPv6 filters occupy four slots and must be aligned on four-slot
 	 * boundaries for T5. On T6, IPv6 filters occupy two-slots and
 	 * must be aligned on two-slot boundaries.
 	 *
 	 * IPv4 filters only occupy a single slot and have no alignment
-	 * requirements but writing a new IPv4 filter into the middle
-	 * of an existing IPv6 filter requires clearing the old IPv6
-	 * filter.
+	 * requirements.
 	 */
-	if (fs->type == FILTER_TYPE_IPV4) { /* IPv4 */
-		/*
-		 * For T6, If our IPv4 filter isn't being written to a
-		 * multiple of two filter index and there's an IPv6
-		 * filter at the multiple of 2 base slot, then we need
-		 * to delete that IPv6 filter ...
-		 * For adapters below T6, IPv6 filter occupies 4 entries.
-		 */
+	fidx = filter_id;
+	if (fs->type == FILTER_TYPE_IPV6) {
 		if (chip_ver < CHELSIO_T6)
-			fidx = filter_id & ~0x3;
+			fidx &= ~(0x3);
 		else
-			fidx = filter_id & ~0x1;
-
-		if (fidx != filter_id && adapter->tids.ftid_tab[fidx].fs.type) {
-			f = &adapter->tids.ftid_tab[fidx];
-			if (f->valid)
-				return -EBUSY;
-		}
-	} else { /* IPv6 */
-		unsigned int max_filter_id;
-
-		if (chip_ver < CHELSIO_T6) {
-			/*
-			 * Ensure that the IPv6 filter is aligned on a
-			 * multiple of 4 boundary.
-			 */
-			if (filter_id & 0x3)
-				return -EINVAL;
+			fidx &= ~(0x1);
+	}
 
-			max_filter_id = filter_id + 4;
-		} else {
-			/*
-			 * For T6, CLIP being enabled, IPv6 filter would occupy
-			 * 2 entries.
-			 */
-			if (filter_id & 0x1)
-				return -EINVAL;
+	if (fidx != filter_id)
+		return -EINVAL;
 
-			max_filter_id = filter_id + 2;
-		}
+	nentries = cxgbe_filter_slots(adapter, fs->type);
+	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
+	if (ret)
+		return -EBUSY;
 
-		/*
-		 * Check all except the base overlapping IPv4 filter
-		 * slots.
-		 */
-		for (fidx = filter_id + 1; fidx < max_filter_id; fidx++) {
-			f = &adapter->tids.ftid_tab[fidx];
-			if (f->valid)
-				return -EBUSY;
-		}
-	}
+	iq = get_filter_steerq(dev, fs);
 
 	/*
 	 * Check to make sure that provided filter index is not
@@ -1029,9 +984,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		return -EBUSY;
 
 	fidx = adapter->tids.ftid_base + filter_id;
-	fid_bit = filter_id;
-	ret = cxgbe_set_ftid(&adapter->tids, fid_bit,
-			     fs->type ? FILTER_TYPE_IPV6 : FILTER_TYPE_IPV4);
+	ret = cxgbe_set_ftid(&adapter->tids, filter_id, nentries);
 	if (ret)
 		return ret;
 
@@ -1041,9 +994,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	ret = writable_filter(f);
 	if (ret) {
 		/* Clear the bits we have set above */
-		cxgbe_clear_ftid(&adapter->tids, fid_bit,
-				 fs->type ? FILTER_TYPE_IPV6 :
-					    FILTER_TYPE_IPV4);
+		cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
 		return ret;
 	}
 
@@ -1074,17 +1025,13 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	f->ctx = ctx;
 	f->tid = fidx; /* Save the actual tid */
 	ret = set_filter_wr(dev, filter_id);
-	if (ret) {
-		fid_bit = f->tid - adapter->tids.ftid_base;
+	if (ret)
 		goto free_tid;
-	}
 
 	return ret;
 
 free_tid:
-	cxgbe_clear_ftid(&adapter->tids, fid_bit,
-			 fs->type ? FILTER_TYPE_IPV6 :
-				    FILTER_TYPE_IPV4);
+	cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
 	clear_filter(f);
 	return ret;
 }
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 1964730ba..06021c854 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -248,7 +248,8 @@ cxgbe_bitmap_find_free_region(struct rte_bitmap *bmap, unsigned int size,
 	return idx;
 }
 
-bool cxgbe_is_filter_set(struct tid_info *, int fidx, int family);
+u8 cxgbe_filter_slots(struct adapter *adap, u8 family);
+bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries);
 void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
 int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		     struct ch_filter_specification *fs,
@@ -256,7 +257,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		     struct ch_filter_specification *fs,
 		     struct filter_ctx *ctx);
-int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family);
+int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries);
 int cxgbe_init_hash_filter(struct adapter *adap);
 void cxgbe_hash_filter_rpl(struct adapter *adap,
 			   const struct cpl_act_open_rpl *rpl);
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index 848c61f02..8a5d06ff3 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -304,12 +304,15 @@ static int cxgbe_validate_fidxondel(struct filter_entry *f, unsigned int fidx)
 {
 	struct adapter *adap = ethdev2adap(f->dev);
 	struct ch_filter_specification fs = f->fs;
+	u8 nentries;
 
 	if (fidx >= adap->tids.nftids) {
 		dev_err(adap, "invalid flow index %d.\n", fidx);
 		return -EINVAL;
 	}
-	if (!cxgbe_is_filter_set(&adap->tids, fidx, fs.type)) {
+
+	nentries = cxgbe_filter_slots(adap, fs.type);
+	if (!cxgbe_is_filter_set(&adap->tids, fidx, nentries)) {
 		dev_err(adap, "Already free fidx:%d f:%p\n", fidx, f);
 		return -EINVAL;
 	}
@@ -321,10 +324,14 @@ static int
 cxgbe_validate_fidxonadd(struct ch_filter_specification *fs,
 			 struct adapter *adap, unsigned int fidx)
 {
-	if (cxgbe_is_filter_set(&adap->tids, fidx, fs->type)) {
+	u8 nentries;
+
+	nentries = cxgbe_filter_slots(adap, fs->type);
+	if (cxgbe_is_filter_set(&adap->tids, fidx, nentries)) {
 		dev_err(adap, "filter index: %d is busy.\n", fidx);
 		return -EBUSY;
 	}
+
 	if (fidx >= adap->tids.nftids) {
 		dev_err(adap, "filter index (%u) >= max(%u)\n",
 			fidx, adap->tids.nftids);
@@ -351,9 +358,11 @@ static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx)
 
 	/* For tcam get the next available slot, if default value specified */
 	if (flow->fidx == FILTER_ID_MAX) {
+		u8 nentries;
 		int idx;
 
-		idx = cxgbe_alloc_ftid(adap, fs->type);
+		nentries = cxgbe_filter_slots(adap, fs->type);
+		idx = cxgbe_alloc_ftid(adap, nentries);
 		if (idx < 0) {
 			dev_err(adap, "unable to get a filter index in tcam\n");
 			return -ENOMEM;
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH 04/12] net/cxgbe: fix parsing VLAN ID rewrite action
       [not found] <cover.1567799552.git.rahul.lakkireddy@chelsio.com>
                   ` (2 preceding siblings ...)
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 03/12] net/cxgbe: fix slot allocation for IPv6 flows Rahul Lakkireddy
@ 2019-09-06 21:52 ` Rahul Lakkireddy
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 05/12] net/cxgbe: fix prefetch for non-coalesced Tx packets Rahul Lakkireddy
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-06 21:52 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

Set VLAN action mode to VLAN_REWRITE only if VLAN_INSERT has not been
set yet. Otherwise, the resulting VLAN packets will have their VLAN
header rewritten, instead of pushing a new outer VLAN header.

Also fix the VLAN ID extraction logic and endianness issues.

Cc: stable@dpdk.org
Fixes: 1decc62b1cbe ("net/cxgbe: add flow operations to offload VLAN actions")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/cxgbe_flow.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index 8a5d06ff3..4c8553039 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -446,18 +446,27 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
 	const struct rte_flow_action_set_tp *tp_port;
 	const struct rte_flow_action_phy_port *port;
 	int item_index;
+	u16 tmp_vlan;
 
 	switch (a->type) {
 	case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
 		vlanid = (const struct rte_flow_action_of_set_vlan_vid *)
 			  a->conf;
-		fs->newvlan = VLAN_REWRITE;
-		fs->vlan = vlanid->vlan_vid;
+		/* If explicitly asked to push a new VLAN header,
+		 * then don't set rewrite mode. Otherwise, the
+		 * incoming VLAN packets will get their VLAN fields
+		 * rewritten, instead of adding an additional outer
+		 * VLAN header.
+		 */
+		if (fs->newvlan != VLAN_INSERT)
+			fs->newvlan = VLAN_REWRITE;
+		tmp_vlan = fs->vlan & 0xe000;
+		fs->vlan = (be16_to_cpu(vlanid->vlan_vid) & 0xfff) | tmp_vlan;
 		break;
 	case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
 		pushvlan = (const struct rte_flow_action_of_push_vlan *)
 			    a->conf;
-		if (pushvlan->ethertype != RTE_ETHER_TYPE_VLAN)
+		if (be16_to_cpu(pushvlan->ethertype) != RTE_ETHER_TYPE_VLAN)
 			return rte_flow_error_set(e, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ACTION, a,
 						  "only ethertype 0x8100 "
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH 05/12] net/cxgbe: fix prefetch for non-coalesced Tx packets
       [not found] <cover.1567799552.git.rahul.lakkireddy@chelsio.com>
                   ` (3 preceding siblings ...)
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 04/12] net/cxgbe: fix parsing VLAN ID rewrite action Rahul Lakkireddy
@ 2019-09-06 21:52 ` Rahul Lakkireddy
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 06/12] net/cxgbe: avoid polling link status before device start Rahul Lakkireddy
       [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
  6 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-06 21:52 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

Move prefetch code out of Tx coalesce path to allow prefetching for
non-coalesced Tx packets, as well.

Cc: stable@dpdk.org
Fixes: bf89cbedd2d9 ("cxgbe: optimize forwarding performance for 40G")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 9 +++++++--
 drivers/net/cxgbe/sge.c          | 1 -
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index efb458d47..fb174f8d4 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -67,6 +67,7 @@ uint16_t cxgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	struct sge_eth_txq *txq = (struct sge_eth_txq *)tx_queue;
 	uint16_t pkts_sent, pkts_remain;
 	uint16_t total_sent = 0;
+	uint16_t idx = 0;
 	int ret = 0;
 
 	CXGBE_DEBUG_TX(adapter, "%s: txq = %p; tx_pkts = %p; nb_pkts = %d\n",
@@ -75,12 +76,16 @@ uint16_t cxgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	t4_os_lock(&txq->txq_lock);
 	/* free up desc from already completed tx */
 	reclaim_completed_tx(&txq->q);
+	rte_prefetch0(rte_pktmbuf_mtod(tx_pkts[0], volatile void *));
 	while (total_sent < nb_pkts) {
 		pkts_remain = nb_pkts - total_sent;
 
 		for (pkts_sent = 0; pkts_sent < pkts_remain; pkts_sent++) {
-			ret = t4_eth_xmit(txq, tx_pkts[total_sent + pkts_sent],
-					  nb_pkts);
+			idx = total_sent + pkts_sent;
+			if ((idx + 1) < nb_pkts)
+				rte_prefetch0(rte_pktmbuf_mtod(tx_pkts[idx + 1],
+							volatile void *));
+			ret = t4_eth_xmit(txq, tx_pkts[idx], nb_pkts);
 			if (ret < 0)
 				break;
 		}
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 641be9657..bf3190211 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -1154,7 +1154,6 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
 				txq->stats.mapping_err++;
 				goto out_free;
 			}
-			rte_prefetch0((volatile void *)addr);
 			return tx_do_packet_coalesce(txq, mbuf, cflits, adap,
 						     pi, addr, nb_pkts);
 		} else {
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH 06/12] net/cxgbe: avoid polling link status before device start
       [not found] <cover.1567799552.git.rahul.lakkireddy@chelsio.com>
                   ` (4 preceding siblings ...)
  2019-09-06 21:52 ` [dpdk-stable] [PATCH 05/12] net/cxgbe: fix prefetch for non-coalesced Tx packets Rahul Lakkireddy
@ 2019-09-06 21:52 ` Rahul Lakkireddy
       [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
  6 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-06 21:52 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

Link updates come in firmware event queue, which is only created
when device starts. So, don't poll for link status if firmware
event queue is not yet created.

This fixes NULL dereference when accessing non existent firmware
event queue.

Cc: stable@dpdk.org
Fixes: 265af08e75ba ("net/cxgbe: add link up and down ops")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index fb174f8d4..381dd273d 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -204,6 +204,9 @@ int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
 	u8 old_link = pi->link_cfg.link_ok;
 
 	for (i = 0; i < CXGBE_LINK_STATUS_POLL_CNT; i++) {
+		if (!s->fw_evtq.desc)
+			break;
+
 		cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
 
 		/* Exit if link status changed or always forced up */
@@ -237,6 +240,9 @@ int cxgbe_dev_set_link_up(struct rte_eth_dev *dev)
 	struct sge *s = &adapter->sge;
 	int ret;
 
+	if (!s->fw_evtq.desc)
+		return -ENOMEM;
+
 	/* Flush all link events */
 	cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
 
@@ -263,6 +269,9 @@ int cxgbe_dev_set_link_down(struct rte_eth_dev *dev)
 	struct sge *s = &adapter->sge;
 	int ret;
 
+	if (!s->fw_evtq.desc)
+		return -ENOMEM;
+
 	/* Flush all link events */
 	cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
 
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH v2 01/12] net/cxgbe: add cxgbe_ prefix to global functions
       [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
@ 2019-09-27 20:30   ` Rahul Lakkireddy
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 02/12] net/cxgbe: fix NULL access when allocating CLIP entry Rahul Lakkireddy
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-27 20:30 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

To avoid name collisions, add cxgbe_ prefix to some global functions.
Also, make some local functions static in cxgbe_filter.c.

Cc: stable@dpdk.org
Fixes: ee61f5113b17 ("net/cxgbe: parse and validate flows")
Fixes: 9eb2c9a48072 ("net/cxgbe: implement flow create operation")
Fixes: 3a381a4116ed ("net/cxgbe: query firmware for HASH filter resources")
Fixes: af44a577988b ("net/cxgbe: support to offload flows to HASH region")
Fixes: 41dc98b0827a ("net/cxgbe: support to delete flows in HASH region")
Fixes: 23af667f1507 ("net/cxgbe: add API to program hardware layer 2 table")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/cxgbe_filter.c | 30 ++++++++++++++++--------------
 drivers/net/cxgbe/cxgbe_filter.h | 19 +++++++++----------
 drivers/net/cxgbe/cxgbe_flow.c   |  6 +++---
 drivers/net/cxgbe/cxgbe_main.c   | 10 +++++-----
 drivers/net/cxgbe/l2t.c          |  3 ++-
 drivers/net/cxgbe/l2t.h          |  3 ++-
 6 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index 7fcee5c0a..cc8774c1d 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -14,7 +14,7 @@
 /**
  * Initialize Hash Filters
  */
-int init_hash_filter(struct adapter *adap)
+int cxgbe_init_hash_filter(struct adapter *adap)
 {
 	unsigned int n_user_filters;
 	unsigned int user_filter_perc;
@@ -53,7 +53,8 @@ int init_hash_filter(struct adapter *adap)
  * Validate if the requested filter specification can be set by checking
  * if the requested features have been enabled
  */
-int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)
+int cxgbe_validate_filter(struct adapter *adapter,
+			  struct ch_filter_specification *fs)
 {
 	u32 fconf;
 
@@ -133,7 +134,7 @@ static unsigned int get_filter_steerq(struct rte_eth_dev *dev,
 }
 
 /* Return an error number if the indicated filter isn't writable ... */
-int writable_filter(struct filter_entry *f)
+static int writable_filter(struct filter_entry *f)
 {
 	if (f->locked)
 		return -EPERM;
@@ -214,7 +215,7 @@ static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
 /**
  * Check if entry already filled.
  */
-bool is_filter_set(struct tid_info *t, int fidx, int family)
+bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
 {
 	bool result = FALSE;
 	int i, max;
@@ -527,7 +528,7 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
 	int atid, size;
 	int ret = 0;
 
-	ret = validate_filter(adapter, fs);
+	ret = cxgbe_validate_filter(adapter, fs);
 	if (ret)
 		return ret;
 
@@ -618,7 +619,7 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
  * Clear a filter and release any of its resources that we own.  This also
  * clears the filter's "pending" status.
  */
-void clear_filter(struct filter_entry *f)
+static void clear_filter(struct filter_entry *f)
 {
 	if (f->clipt)
 		cxgbe_clip_release(f->dev, f->clipt);
@@ -690,7 +691,7 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 	return 0;
 }
 
-int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
+static int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 {
 	struct adapter *adapter = ethdev2adap(dev);
 	struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
@@ -868,7 +869,7 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 
 	chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
 
-	ret = is_filter_set(&adapter->tids, filter_id, fs->type);
+	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
 	if (!ret) {
 		dev_warn(adap, "%s: could not find filter entry: %u\n",
 			 __func__, filter_id);
@@ -940,7 +941,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 
 	chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
 
-	ret = validate_filter(adapter, fs);
+	ret = cxgbe_validate_filter(adapter, fs);
 	if (ret)
 		return ret;
 
@@ -951,7 +952,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	if (fs->type)
 		filter_id &= ~(0x3);
 
-	ret = is_filter_set(&adapter->tids, filter_id, fs->type);
+	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
 	if (ret)
 		return -EBUSY;
 
@@ -1091,7 +1092,8 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 /**
  * Handle a Hash filter write reply.
  */
-void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl)
+void cxgbe_hash_filter_rpl(struct adapter *adap,
+			   const struct cpl_act_open_rpl *rpl)
 {
 	struct tid_info *t = &adap->tids;
 	struct filter_entry *f;
@@ -1159,7 +1161,7 @@ void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl)
 /**
  * Handle a LE-TCAM filter write/deletion reply.
  */
-void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
+void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
 {
 	struct filter_entry *f = NULL;
 	unsigned int tid = GET_TID(rpl);
@@ -1357,8 +1359,8 @@ int cxgbe_clear_filter_count(struct adapter *adapter, unsigned int fidx,
 /**
  * Handle a Hash filter delete reply.
  */
-void hash_del_filter_rpl(struct adapter *adap,
-			 const struct cpl_abort_rpl_rss *rpl)
+void cxgbe_hash_del_filter_rpl(struct adapter *adap,
+			       const struct cpl_abort_rpl_rss *rpl)
 {
 	struct tid_info *t = &adap->tids;
 	struct filter_entry *f;
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 0c67d2d15..1964730ba 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -248,11 +248,8 @@ cxgbe_bitmap_find_free_region(struct rte_bitmap *bmap, unsigned int size,
 	return idx;
 }
 
-bool is_filter_set(struct tid_info *, int fidx, int family);
-void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
-void clear_filter(struct filter_entry *f);
-int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx);
-int writable_filter(struct filter_entry *f);
+bool cxgbe_is_filter_set(struct tid_info *, int fidx, int family);
+void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
 int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		     struct ch_filter_specification *fs,
 		     struct filter_ctx *ctx);
@@ -260,11 +257,13 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		     struct ch_filter_specification *fs,
 		     struct filter_ctx *ctx);
 int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family);
-int init_hash_filter(struct adapter *adap);
-void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl);
-void hash_del_filter_rpl(struct adapter *adap,
-			 const struct cpl_abort_rpl_rss *rpl);
-int validate_filter(struct adapter *adap, struct ch_filter_specification *fs);
+int cxgbe_init_hash_filter(struct adapter *adap);
+void cxgbe_hash_filter_rpl(struct adapter *adap,
+			   const struct cpl_act_open_rpl *rpl);
+void cxgbe_hash_del_filter_rpl(struct adapter *adap,
+			       const struct cpl_abort_rpl_rss *rpl);
+int cxgbe_validate_filter(struct adapter *adap,
+			  struct ch_filter_specification *fs);
 int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,
 			   u64 *c, int hash, bool get_byte);
 int cxgbe_clear_filter_count(struct adapter *adapter, unsigned int fidx,
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index d3de689c3..848c61f02 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -309,7 +309,7 @@ static int cxgbe_validate_fidxondel(struct filter_entry *f, unsigned int fidx)
 		dev_err(adap, "invalid flow index %d.\n", fidx);
 		return -EINVAL;
 	}
-	if (!is_filter_set(&adap->tids, fidx, fs.type)) {
+	if (!cxgbe_is_filter_set(&adap->tids, fidx, fs.type)) {
 		dev_err(adap, "Already free fidx:%d f:%p\n", fidx, f);
 		return -EINVAL;
 	}
@@ -321,7 +321,7 @@ static int
 cxgbe_validate_fidxonadd(struct ch_filter_specification *fs,
 			 struct adapter *adap, unsigned int fidx)
 {
-	if (is_filter_set(&adap->tids, fidx, fs->type)) {
+	if (cxgbe_is_filter_set(&adap->tids, fidx, fs->type)) {
 		dev_err(adap, "filter index: %d is busy.\n", fidx);
 		return -EBUSY;
 	}
@@ -1019,7 +1019,7 @@ cxgbe_flow_validate(struct rte_eth_dev *dev,
 		return ret;
 	}
 
-	if (validate_filter(adap, &flow->fs)) {
+	if (cxgbe_validate_filter(adap, &flow->fs)) {
 		t4_os_free(flow);
 		return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
 				NULL,
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 620f60b4d..c3e6b9557 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -92,19 +92,19 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
 	} else if (opcode == CPL_ABORT_RPL_RSS) {
 		const struct cpl_abort_rpl_rss *p = (const void *)rsp;
 
-		hash_del_filter_rpl(q->adapter, p);
+		cxgbe_hash_del_filter_rpl(q->adapter, p);
 	} else if (opcode == CPL_SET_TCB_RPL) {
 		const struct cpl_set_tcb_rpl *p = (const void *)rsp;
 
-		filter_rpl(q->adapter, p);
+		cxgbe_filter_rpl(q->adapter, p);
 	} else if (opcode == CPL_ACT_OPEN_RPL) {
 		const struct cpl_act_open_rpl *p = (const void *)rsp;
 
-		hash_filter_rpl(q->adapter, p);
+		cxgbe_hash_filter_rpl(q->adapter, p);
 	} else if (opcode == CPL_L2T_WRITE_RPL) {
 		const struct cpl_l2t_write_rpl *p = (const void *)rsp;
 
-		do_l2t_write_rpl(q->adapter, p);
+		cxgbe_do_l2t_write_rpl(q->adapter, p);
 	} else {
 		dev_err(adapter, "unexpected CPL %#x on FW event queue\n",
 			opcode);
@@ -1179,7 +1179,7 @@ static int adap_init0(struct adapter *adap)
 
 	if ((caps_cmd.niccaps & cpu_to_be16(FW_CAPS_CONFIG_NIC_HASHFILTER)) &&
 	    is_t6(adap->params.chip)) {
-		if (init_hash_filter(adap) < 0)
+		if (cxgbe_init_hash_filter(adap) < 0)
 			goto bye;
 	}
 
diff --git a/drivers/net/cxgbe/l2t.c b/drivers/net/cxgbe/l2t.c
index 6faf624f7..f9d651fe0 100644
--- a/drivers/net/cxgbe/l2t.c
+++ b/drivers/net/cxgbe/l2t.c
@@ -22,7 +22,8 @@ void cxgbe_l2t_release(struct l2t_entry *e)
  * Process a CPL_L2T_WRITE_RPL. Note that the TID in the reply is really
  * the L2T index it refers to.
  */
-void do_l2t_write_rpl(struct adapter *adap, const struct cpl_l2t_write_rpl *rpl)
+void cxgbe_do_l2t_write_rpl(struct adapter *adap,
+			    const struct cpl_l2t_write_rpl *rpl)
 {
 	struct l2t_data *d = adap->l2t;
 	unsigned int tid = GET_TID(rpl);
diff --git a/drivers/net/cxgbe/l2t.h b/drivers/net/cxgbe/l2t.h
index 326abfde4..2c489e4aa 100644
--- a/drivers/net/cxgbe/l2t.h
+++ b/drivers/net/cxgbe/l2t.h
@@ -53,5 +53,6 @@ void t4_cleanup_l2t(struct adapter *adap);
 struct l2t_entry *cxgbe_l2t_alloc_switching(struct rte_eth_dev *dev, u16 vlan,
 					    u8 port, u8 *dmac);
 void cxgbe_l2t_release(struct l2t_entry *e);
-void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl);
+void cxgbe_do_l2t_write_rpl(struct adapter *p,
+			    const struct cpl_l2t_write_rpl *rpl);
 #endif /* _CXGBE_L2T_H_ */
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH v2 02/12] net/cxgbe: fix NULL access when allocating CLIP entry
       [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 01/12] net/cxgbe: add cxgbe_ prefix to global functions Rahul Lakkireddy
@ 2019-09-27 20:30   ` Rahul Lakkireddy
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 03/12] net/cxgbe: fix slot allocation for IPv6 flows Rahul Lakkireddy
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-27 20:30 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

Pass correct arguments to CLIP allocation code to avoid NULL pointer
dereference.

Cc: stable@dpdk.org
Fixes: 3f2c1e209cfc ("net/cxgbe: add Compressed Local IP region")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/cxgbe_filter.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index cc8774c1d..3b7966d04 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -1052,7 +1052,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	 */
 	if (chip_ver > CHELSIO_T5 && fs->type &&
 	    memcmp(fs->val.lip, bitoff, sizeof(bitoff))) {
-		f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
+		f->clipt = cxgbe_clip_alloc(dev, (u32 *)&fs->val.lip);
 		if (!f->clipt)
 			goto free_tid;
 	}
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH v2 03/12] net/cxgbe: fix slot allocation for IPv6 flows
       [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 01/12] net/cxgbe: add cxgbe_ prefix to global functions Rahul Lakkireddy
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 02/12] net/cxgbe: fix NULL access when allocating CLIP entry Rahul Lakkireddy
@ 2019-09-27 20:30   ` Rahul Lakkireddy
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 04/12] net/cxgbe: fix parsing VLAN ID rewrite action Rahul Lakkireddy
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-27 20:30 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

IPv6 flows occupy only 2 slots on Chelsio T6 NICs. Fix the slot
calculation logic to return correct number of slots.

Cc: stable@dpdk.org
Fixes: ee61f5113b17 ("net/cxgbe: parse and validate flows")
Fixes: 9eb2c9a48072 ("net/cxgbe: implement flow create operation")
Fixes: 3f2c1e209cfc ("net/cxgbe: add Compressed Local IP region")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/cxgbe_filter.c | 193 +++++++++++--------------------
 drivers/net/cxgbe/cxgbe_filter.h |   5 +-
 drivers/net/cxgbe/cxgbe_flow.c   |  15 ++-
 3 files changed, 85 insertions(+), 128 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index 3b7966d04..33b95a69a 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -213,20 +213,32 @@ static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
 }
 
 /**
- * Check if entry already filled.
+ * IPv6 requires 2 slots on T6 and 4 slots for cards below T6.
+ * IPv4 requires only 1 slot on all cards.
  */
-bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
+u8 cxgbe_filter_slots(struct adapter *adap, u8 family)
 {
-	bool result = FALSE;
-	int i, max;
+	if (family == FILTER_TYPE_IPV6) {
+		if (CHELSIO_CHIP_VERSION(adap->params.chip) < CHELSIO_T6)
+			return 4;
 
-	/* IPv6 requires four slots and IPv4 requires only 1 slot.
-	 * Ensure, there's enough slots available.
-	 */
-	max = family == FILTER_TYPE_IPV6 ? fidx + 3 : fidx;
+		return 2;
+	}
+
+	return 1;
+}
+
+/**
+ * Check if entries are already filled.
+ */
+bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries)
+{
+	bool result = FALSE;
+	u32 i;
 
+	/* Ensure there's enough slots available. */
 	t4_os_lock(&t->ftid_lock);
-	for (i = fidx; i <= max; i++) {
+	for (i = fidx; i < fidx + nentries; i++) {
 		if (rte_bitmap_get(t->ftid_bmap, i)) {
 			result = TRUE;
 			break;
@@ -237,17 +249,18 @@ bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
 }
 
 /**
- * Allocate a available free entry
+ * Allocate available free entries.
  */
-int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family)
+int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries)
 {
 	struct tid_info *t = &adap->tids;
 	int pos;
 	int size = t->nftids;
 
 	t4_os_lock(&t->ftid_lock);
-	if (family == FILTER_TYPE_IPV6)
-		pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size, 4);
+	if (nentries > 1)
+		pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size,
+						    nentries);
 	else
 		pos = cxgbe_find_first_zero_bit(t->ftid_bmap, size);
 	t4_os_unlock(&t->ftid_lock);
@@ -565,7 +578,7 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
 	if (atid < 0)
 		goto out_err;
 
-	if (f->fs.type) {
+	if (f->fs.type == FILTER_TYPE_IPV6) {
 		/* IPv6 hash filter */
 		f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
 		if (!f->clipt)
@@ -804,44 +817,34 @@ static int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 }
 
 /**
- * Set the corresponding entry in the bitmap. 4 slots are
- * marked for IPv6, whereas only 1 slot is marked for IPv4.
+ * Set the corresponding entries in the bitmap.
  */
-static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
+static int cxgbe_set_ftid(struct tid_info *t, u32 fidx, u8 nentries)
 {
+	u32 i;
+
 	t4_os_lock(&t->ftid_lock);
 	if (rte_bitmap_get(t->ftid_bmap, fidx)) {
 		t4_os_unlock(&t->ftid_lock);
 		return -EBUSY;
 	}
 
-	if (family == FILTER_TYPE_IPV4) {
-		rte_bitmap_set(t->ftid_bmap, fidx);
-	} else {
-		rte_bitmap_set(t->ftid_bmap, fidx);
-		rte_bitmap_set(t->ftid_bmap, fidx + 1);
-		rte_bitmap_set(t->ftid_bmap, fidx + 2);
-		rte_bitmap_set(t->ftid_bmap, fidx + 3);
-	}
+	for (i = fidx; i < fidx + nentries; i++)
+		rte_bitmap_set(t->ftid_bmap, i);
 	t4_os_unlock(&t->ftid_lock);
 	return 0;
 }
 
 /**
- * Clear the corresponding entry in the bitmap. 4 slots are
- * cleared for IPv6, whereas only 1 slot is cleared for IPv4.
+ * Clear the corresponding entries in the bitmap.
  */
-static void cxgbe_clear_ftid(struct tid_info *t, int fidx, int family)
+static void cxgbe_clear_ftid(struct tid_info *t, u32 fidx, u8 nentries)
 {
+	u32 i;
+
 	t4_os_lock(&t->ftid_lock);
-	if (family == FILTER_TYPE_IPV4) {
-		rte_bitmap_clear(t->ftid_bmap, fidx);
-	} else {
-		rte_bitmap_clear(t->ftid_bmap, fidx);
-		rte_bitmap_clear(t->ftid_bmap, fidx + 1);
-		rte_bitmap_clear(t->ftid_bmap, fidx + 2);
-		rte_bitmap_clear(t->ftid_bmap, fidx + 3);
-	}
+	for (i = fidx; i < fidx + nentries; i++)
+		rte_bitmap_clear(t->ftid_bmap, i);
 	t4_os_unlock(&t->ftid_lock);
 }
 
@@ -859,6 +862,7 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	struct adapter *adapter = pi->adapter;
 	struct filter_entry *f;
 	unsigned int chip_ver;
+	u8 nentries;
 	int ret;
 
 	if (is_hashfilter(adapter) && fs->cap)
@@ -869,24 +873,25 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 
 	chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
 
-	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
-	if (!ret) {
-		dev_warn(adap, "%s: could not find filter entry: %u\n",
-			 __func__, filter_id);
-		return -EINVAL;
-	}
-
 	/*
-	 * Ensure filter id is aligned on the 2 slot boundary for T6,
+	 * Ensure IPv6 filter id is aligned on the 2 slot boundary for T6,
 	 * and 4 slot boundary for cards below T6.
 	 */
-	if (fs->type) {
+	if (fs->type == FILTER_TYPE_IPV6) {
 		if (chip_ver < CHELSIO_T6)
 			filter_id &= ~(0x3);
 		else
 			filter_id &= ~(0x1);
 	}
 
+	nentries = cxgbe_filter_slots(adapter, fs->type);
+	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
+	if (!ret) {
+		dev_warn(adap, "%s: could not find filter entry: %u\n",
+			 __func__, filter_id);
+		return -EINVAL;
+	}
+
 	f = &adapter->tids.ftid_tab[filter_id];
 	ret = writable_filter(f);
 	if (ret)
@@ -896,8 +901,7 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		f->ctx = ctx;
 		cxgbe_clear_ftid(&adapter->tids,
 				 f->tid - adapter->tids.ftid_base,
-				 f->fs.type ? FILTER_TYPE_IPV6 :
-					      FILTER_TYPE_IPV4);
+				 nentries);
 		return del_filter_wr(dev, filter_id);
 	}
 
@@ -927,10 +931,10 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 {
 	struct port_info *pi = ethdev2pinfo(dev);
 	struct adapter *adapter = pi->adapter;
-	unsigned int fidx, iq, fid_bit = 0;
+	unsigned int fidx, iq;
 	struct filter_entry *f;
 	unsigned int chip_ver;
-	uint8_t bitoff[16] = {0};
+	u8 nentries, bitoff[16] = {0};
 	int ret;
 
 	if (is_hashfilter(adapter) && fs->cap)
@@ -945,80 +949,31 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	if (ret)
 		return ret;
 
-	/*
-	 * Ensure filter id is aligned on the 4 slot boundary for IPv6
-	 * maskfull filters.
-	 */
-	if (fs->type)
-		filter_id &= ~(0x3);
-
-	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
-	if (ret)
-		return -EBUSY;
-
-	iq = get_filter_steerq(dev, fs);
-
 	/*
 	 * IPv6 filters occupy four slots and must be aligned on four-slot
 	 * boundaries for T5. On T6, IPv6 filters occupy two-slots and
 	 * must be aligned on two-slot boundaries.
 	 *
 	 * IPv4 filters only occupy a single slot and have no alignment
-	 * requirements but writing a new IPv4 filter into the middle
-	 * of an existing IPv6 filter requires clearing the old IPv6
-	 * filter.
+	 * requirements.
 	 */
-	if (fs->type == FILTER_TYPE_IPV4) { /* IPv4 */
-		/*
-		 * For T6, If our IPv4 filter isn't being written to a
-		 * multiple of two filter index and there's an IPv6
-		 * filter at the multiple of 2 base slot, then we need
-		 * to delete that IPv6 filter ...
-		 * For adapters below T6, IPv6 filter occupies 4 entries.
-		 */
+	fidx = filter_id;
+	if (fs->type == FILTER_TYPE_IPV6) {
 		if (chip_ver < CHELSIO_T6)
-			fidx = filter_id & ~0x3;
+			fidx &= ~(0x3);
 		else
-			fidx = filter_id & ~0x1;
-
-		if (fidx != filter_id && adapter->tids.ftid_tab[fidx].fs.type) {
-			f = &adapter->tids.ftid_tab[fidx];
-			if (f->valid)
-				return -EBUSY;
-		}
-	} else { /* IPv6 */
-		unsigned int max_filter_id;
-
-		if (chip_ver < CHELSIO_T6) {
-			/*
-			 * Ensure that the IPv6 filter is aligned on a
-			 * multiple of 4 boundary.
-			 */
-			if (filter_id & 0x3)
-				return -EINVAL;
+			fidx &= ~(0x1);
+	}
 
-			max_filter_id = filter_id + 4;
-		} else {
-			/*
-			 * For T6, CLIP being enabled, IPv6 filter would occupy
-			 * 2 entries.
-			 */
-			if (filter_id & 0x1)
-				return -EINVAL;
+	if (fidx != filter_id)
+		return -EINVAL;
 
-			max_filter_id = filter_id + 2;
-		}
+	nentries = cxgbe_filter_slots(adapter, fs->type);
+	ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
+	if (ret)
+		return -EBUSY;
 
-		/*
-		 * Check all except the base overlapping IPv4 filter
-		 * slots.
-		 */
-		for (fidx = filter_id + 1; fidx < max_filter_id; fidx++) {
-			f = &adapter->tids.ftid_tab[fidx];
-			if (f->valid)
-				return -EBUSY;
-		}
-	}
+	iq = get_filter_steerq(dev, fs);
 
 	/*
 	 * Check to make sure that provided filter index is not
@@ -1029,9 +984,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		return -EBUSY;
 
 	fidx = adapter->tids.ftid_base + filter_id;
-	fid_bit = filter_id;
-	ret = cxgbe_set_ftid(&adapter->tids, fid_bit,
-			     fs->type ? FILTER_TYPE_IPV6 : FILTER_TYPE_IPV4);
+	ret = cxgbe_set_ftid(&adapter->tids, filter_id, nentries);
 	if (ret)
 		return ret;
 
@@ -1041,9 +994,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	ret = writable_filter(f);
 	if (ret) {
 		/* Clear the bits we have set above */
-		cxgbe_clear_ftid(&adapter->tids, fid_bit,
-				 fs->type ? FILTER_TYPE_IPV6 :
-					    FILTER_TYPE_IPV4);
+		cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
 		return ret;
 	}
 
@@ -1074,17 +1025,13 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 	f->ctx = ctx;
 	f->tid = fidx; /* Save the actual tid */
 	ret = set_filter_wr(dev, filter_id);
-	if (ret) {
-		fid_bit = f->tid - adapter->tids.ftid_base;
+	if (ret)
 		goto free_tid;
-	}
 
 	return ret;
 
 free_tid:
-	cxgbe_clear_ftid(&adapter->tids, fid_bit,
-			 fs->type ? FILTER_TYPE_IPV6 :
-				    FILTER_TYPE_IPV4);
+	cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
 	clear_filter(f);
 	return ret;
 }
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 1964730ba..06021c854 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -248,7 +248,8 @@ cxgbe_bitmap_find_free_region(struct rte_bitmap *bmap, unsigned int size,
 	return idx;
 }
 
-bool cxgbe_is_filter_set(struct tid_info *, int fidx, int family);
+u8 cxgbe_filter_slots(struct adapter *adap, u8 family);
+bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries);
 void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
 int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		     struct ch_filter_specification *fs,
@@ -256,7 +257,7 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
 		     struct ch_filter_specification *fs,
 		     struct filter_ctx *ctx);
-int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family);
+int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries);
 int cxgbe_init_hash_filter(struct adapter *adap);
 void cxgbe_hash_filter_rpl(struct adapter *adap,
 			   const struct cpl_act_open_rpl *rpl);
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index 848c61f02..8a5d06ff3 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -304,12 +304,15 @@ static int cxgbe_validate_fidxondel(struct filter_entry *f, unsigned int fidx)
 {
 	struct adapter *adap = ethdev2adap(f->dev);
 	struct ch_filter_specification fs = f->fs;
+	u8 nentries;
 
 	if (fidx >= adap->tids.nftids) {
 		dev_err(adap, "invalid flow index %d.\n", fidx);
 		return -EINVAL;
 	}
-	if (!cxgbe_is_filter_set(&adap->tids, fidx, fs.type)) {
+
+	nentries = cxgbe_filter_slots(adap, fs.type);
+	if (!cxgbe_is_filter_set(&adap->tids, fidx, nentries)) {
 		dev_err(adap, "Already free fidx:%d f:%p\n", fidx, f);
 		return -EINVAL;
 	}
@@ -321,10 +324,14 @@ static int
 cxgbe_validate_fidxonadd(struct ch_filter_specification *fs,
 			 struct adapter *adap, unsigned int fidx)
 {
-	if (cxgbe_is_filter_set(&adap->tids, fidx, fs->type)) {
+	u8 nentries;
+
+	nentries = cxgbe_filter_slots(adap, fs->type);
+	if (cxgbe_is_filter_set(&adap->tids, fidx, nentries)) {
 		dev_err(adap, "filter index: %d is busy.\n", fidx);
 		return -EBUSY;
 	}
+
 	if (fidx >= adap->tids.nftids) {
 		dev_err(adap, "filter index (%u) >= max(%u)\n",
 			fidx, adap->tids.nftids);
@@ -351,9 +358,11 @@ static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx)
 
 	/* For tcam get the next available slot, if default value specified */
 	if (flow->fidx == FILTER_ID_MAX) {
+		u8 nentries;
 		int idx;
 
-		idx = cxgbe_alloc_ftid(adap, fs->type);
+		nentries = cxgbe_filter_slots(adap, fs->type);
+		idx = cxgbe_alloc_ftid(adap, nentries);
 		if (idx < 0) {
 			dev_err(adap, "unable to get a filter index in tcam\n");
 			return -ENOMEM;
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH v2 04/12] net/cxgbe: fix parsing VLAN ID rewrite action
       [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
                     ` (2 preceding siblings ...)
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 03/12] net/cxgbe: fix slot allocation for IPv6 flows Rahul Lakkireddy
@ 2019-09-27 20:30   ` Rahul Lakkireddy
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 05/12] net/cxgbe: fix prefetch for non-coalesced Tx packets Rahul Lakkireddy
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 06/12] net/cxgbe: avoid polling link status before device start Rahul Lakkireddy
  5 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-27 20:30 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

Set VLAN action mode to VLAN_REWRITE only if VLAN_INSERT has not been
set yet. Otherwise, the resulting VLAN packets will have their VLAN
header rewritten, instead of pushing a new outer VLAN header.

Also fix the VLAN ID extraction logic and endianness issues.

Cc: stable@dpdk.org
Fixes: 1decc62b1cbe ("net/cxgbe: add flow operations to offload VLAN actions")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/cxgbe_flow.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index 8a5d06ff3..4c8553039 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -446,18 +446,27 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
 	const struct rte_flow_action_set_tp *tp_port;
 	const struct rte_flow_action_phy_port *port;
 	int item_index;
+	u16 tmp_vlan;
 
 	switch (a->type) {
 	case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
 		vlanid = (const struct rte_flow_action_of_set_vlan_vid *)
 			  a->conf;
-		fs->newvlan = VLAN_REWRITE;
-		fs->vlan = vlanid->vlan_vid;
+		/* If explicitly asked to push a new VLAN header,
+		 * then don't set rewrite mode. Otherwise, the
+		 * incoming VLAN packets will get their VLAN fields
+		 * rewritten, instead of adding an additional outer
+		 * VLAN header.
+		 */
+		if (fs->newvlan != VLAN_INSERT)
+			fs->newvlan = VLAN_REWRITE;
+		tmp_vlan = fs->vlan & 0xe000;
+		fs->vlan = (be16_to_cpu(vlanid->vlan_vid) & 0xfff) | tmp_vlan;
 		break;
 	case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
 		pushvlan = (const struct rte_flow_action_of_push_vlan *)
 			    a->conf;
-		if (pushvlan->ethertype != RTE_ETHER_TYPE_VLAN)
+		if (be16_to_cpu(pushvlan->ethertype) != RTE_ETHER_TYPE_VLAN)
 			return rte_flow_error_set(e, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ACTION, a,
 						  "only ethertype 0x8100 "
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH v2 05/12] net/cxgbe: fix prefetch for non-coalesced Tx packets
       [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
                     ` (3 preceding siblings ...)
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 04/12] net/cxgbe: fix parsing VLAN ID rewrite action Rahul Lakkireddy
@ 2019-09-27 20:30   ` Rahul Lakkireddy
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 06/12] net/cxgbe: avoid polling link status before device start Rahul Lakkireddy
  5 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-27 20:30 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

Move prefetch code out of Tx coalesce path to allow prefetching for
non-coalesced Tx packets, as well.

Cc: stable@dpdk.org
Fixes: bf89cbedd2d9 ("cxgbe: optimize forwarding performance for 40G")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/cxgbe_ethdev.c | 9 +++++++--
 drivers/net/cxgbe/sge.c          | 1 -
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 7d7be69ed..5d74f8ba3 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -67,6 +67,7 @@ uint16_t cxgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	struct sge_eth_txq *txq = (struct sge_eth_txq *)tx_queue;
 	uint16_t pkts_sent, pkts_remain;
 	uint16_t total_sent = 0;
+	uint16_t idx = 0;
 	int ret = 0;
 
 	CXGBE_DEBUG_TX(adapter, "%s: txq = %p; tx_pkts = %p; nb_pkts = %d\n",
@@ -75,12 +76,16 @@ uint16_t cxgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	t4_os_lock(&txq->txq_lock);
 	/* free up desc from already completed tx */
 	reclaim_completed_tx(&txq->q);
+	rte_prefetch0(rte_pktmbuf_mtod(tx_pkts[0], volatile void *));
 	while (total_sent < nb_pkts) {
 		pkts_remain = nb_pkts - total_sent;
 
 		for (pkts_sent = 0; pkts_sent < pkts_remain; pkts_sent++) {
-			ret = t4_eth_xmit(txq, tx_pkts[total_sent + pkts_sent],
-					  nb_pkts);
+			idx = total_sent + pkts_sent;
+			if ((idx + 1) < nb_pkts)
+				rte_prefetch0(rte_pktmbuf_mtod(tx_pkts[idx + 1],
+							volatile void *));
+			ret = t4_eth_xmit(txq, tx_pkts[idx], nb_pkts);
 			if (ret < 0)
 				break;
 		}
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 641be9657..bf3190211 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -1154,7 +1154,6 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
 				txq->stats.mapping_err++;
 				goto out_free;
 			}
-			rte_prefetch0((volatile void *)addr);
 			return tx_do_packet_coalesce(txq, mbuf, cflits, adap,
 						     pi, addr, nb_pkts);
 		} else {
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [dpdk-stable] [PATCH v2 06/12] net/cxgbe: avoid polling link status before device start
       [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
                     ` (4 preceding siblings ...)
  2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 05/12] net/cxgbe: fix prefetch for non-coalesced Tx packets Rahul Lakkireddy
@ 2019-09-27 20:30   ` Rahul Lakkireddy
  5 siblings, 0 replies; 12+ messages in thread
From: Rahul Lakkireddy @ 2019-09-27 20:30 UTC (permalink / raw)
  To: dev; +Cc: nirranjan, stable

Link updates come in firmware event queue, which is only created
when device starts. So, don't poll for link status if firmware
event queue is not yet created.

This fixes NULL dereference when accessing non existent firmware
event queue.

Cc: stable@dpdk.org
Fixes: 265af08e75ba ("net/cxgbe: add link up and down ops")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/cxgbe_ethdev.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 5d74f8ba3..5df8d746c 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -206,6 +206,9 @@ int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
 	u8 old_link = pi->link_cfg.link_ok;
 
 	for (i = 0; i < CXGBE_LINK_STATUS_POLL_CNT; i++) {
+		if (!s->fw_evtq.desc)
+			break;
+
 		cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
 
 		/* Exit if link status changed or always forced up */
@@ -239,6 +242,9 @@ int cxgbe_dev_set_link_up(struct rte_eth_dev *dev)
 	struct sge *s = &adapter->sge;
 	int ret;
 
+	if (!s->fw_evtq.desc)
+		return -ENOMEM;
+
 	/* Flush all link events */
 	cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
 
@@ -265,6 +271,9 @@ int cxgbe_dev_set_link_down(struct rte_eth_dev *dev)
 	struct sge *s = &adapter->sge;
 	int ret;
 
+	if (!s->fw_evtq.desc)
+		return -ENOMEM;
+
 	/* Flush all link events */
 	cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
 
-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, back to index

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1567799552.git.rahul.lakkireddy@chelsio.com>
2019-09-06 21:52 ` [dpdk-stable] [PATCH 01/12] net/cxgbe: add cxgbe_ prefix to global functions Rahul Lakkireddy
2019-09-06 21:52 ` [dpdk-stable] [PATCH 02/12] net/cxgbe: fix NULL access when allocating CLIP entry Rahul Lakkireddy
2019-09-06 21:52 ` [dpdk-stable] [PATCH 03/12] net/cxgbe: fix slot allocation for IPv6 flows Rahul Lakkireddy
2019-09-06 21:52 ` [dpdk-stable] [PATCH 04/12] net/cxgbe: fix parsing VLAN ID rewrite action Rahul Lakkireddy
2019-09-06 21:52 ` [dpdk-stable] [PATCH 05/12] net/cxgbe: fix prefetch for non-coalesced Tx packets Rahul Lakkireddy
2019-09-06 21:52 ` [dpdk-stable] [PATCH 06/12] net/cxgbe: avoid polling link status before device start Rahul Lakkireddy
     [not found] ` <cover.1569611036.git.rahul.lakkireddy@chelsio.com>
2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 01/12] net/cxgbe: add cxgbe_ prefix to global functions Rahul Lakkireddy
2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 02/12] net/cxgbe: fix NULL access when allocating CLIP entry Rahul Lakkireddy
2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 03/12] net/cxgbe: fix slot allocation for IPv6 flows Rahul Lakkireddy
2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 04/12] net/cxgbe: fix parsing VLAN ID rewrite action Rahul Lakkireddy
2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 05/12] net/cxgbe: fix prefetch for non-coalesced Tx packets Rahul Lakkireddy
2019-09-27 20:30   ` [dpdk-stable] [PATCH v2 06/12] net/cxgbe: avoid polling link status before device start Rahul Lakkireddy

patches for DPDK stable branches

Archives are clonable:
	git clone --mirror http://inbox.dpdk.org/stable/0 stable/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 stable stable/ http://inbox.dpdk.org/stable \
		stable@dpdk.org
	public-inbox-index stable


Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.stable


AGPL code for this site: git clone https://public-inbox.org/ public-inbox