All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rasesh Mody <rasesh.mody@cavium.com>
To: <dev@dpdk.org>
Cc: Rasesh Mody <rasesh.mody@cavium.com>, <Dept-EngDPDKDev@cavium.com>
Subject: [PATCH 56/61] net/qede/base: add multi-Txq support on same queue-zone for VFs
Date: Sun, 26 Feb 2017 23:57:12 -0800	[thread overview]
Message-ID: <1488182237-10247-57-git-send-email-rasesh.mody@cavium.com> (raw)
In-Reply-To: <1488182237-10247-1-git-send-email-rasesh.mody@cavium.com>

A step toward having multi-Txq support on same queue-zone for VFs.

This change takes care of:

 - VFs assume a single CID per-queue, where queue X receives CID X.
   Switch to a model similar to that of PF - I.e., Use different CIDs
   for Rx/Tx, and use mapping to acquire/release those. Each VF
   currently will have 32 CIDs available for it [for its possible 16
   Rx & 16 Tx queues].

 - To retain the same interface for PFs/VFs when initializing queues,
   the base driver would have to retain a unique number per-each queue
   that would be communicated in some extended TLV [current TLV
   interface allows the PF to send only the queue-id]. The new TLV isn't
   part of the current change but base driver would now start adding
   such unique keys internally to queue_cids. This would also force
   us to start having alloc/setup/free for L2 [we've refrained from
   doing so until now]
   The limit would be no-more than 64 queues per qzone [This could be
   changed if needed, but hopefully no one needs so many queues]

 - In IOV, Add infrastructure for up to 64 qids per-qzone, although
   at the moment hard-code '0' for Rx and '1' for Tx [Since VF still
   isn't communicating via new TLV which index to associate with a
   given queue in its queue-zone].

Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
---
 drivers/net/qede/base/ecore.h         |    4 +
 drivers/net/qede/base/ecore_cxt.c     |  230 +++++++++++++++-----
 drivers/net/qede/base/ecore_cxt.h     |   53 ++++-
 drivers/net/qede/base/ecore_cxt_api.h |   13 --
 drivers/net/qede/base/ecore_dev.c     |   24 +-
 drivers/net/qede/base/ecore_l2.c      |  248 ++++++++++++++++++---
 drivers/net/qede/base/ecore_l2.h      |   46 +++-
 drivers/net/qede/base/ecore_sriov.c   |  387 ++++++++++++++++++++++-----------
 drivers/net/qede/base/ecore_sriov.h   |   17 +-
 drivers/net/qede/base/ecore_vf.c      |    6 +
 drivers/net/qede/base/ecore_vf_api.h  |    9 +
 11 files changed, 794 insertions(+), 243 deletions(-)

diff --git a/drivers/net/qede/base/ecore.h b/drivers/net/qede/base/ecore.h
index 7379b3f..fab8193 100644
--- a/drivers/net/qede/base/ecore.h
+++ b/drivers/net/qede/base/ecore.h
@@ -200,6 +200,7 @@ enum DP_MODULE {
 struct ecore_dma_mem;
 struct ecore_sb_sp_info;
 struct ecore_ll2_info;
+struct ecore_l2_info;
 struct ecore_igu_info;
 struct ecore_mcp_info;
 struct ecore_dcbx_info;
@@ -598,6 +599,9 @@ struct ecore_hwfn {
 	/* If one of the following is set then EDPM shouldn't be used */
 	u8				dcbx_no_edpm;
 	u8				db_bar_no_edpm;
+
+	/* L2-related */
+	struct ecore_l2_info		*p_l2_info;
 };
 
 #ifndef __EXTRACT__LINUX__
diff --git a/drivers/net/qede/base/ecore_cxt.c b/drivers/net/qede/base/ecore_cxt.c
index 837a19f..b3d939a 100644
--- a/drivers/net/qede/base/ecore_cxt.c
+++ b/drivers/net/qede/base/ecore_cxt.c
@@ -8,6 +8,7 @@
 
 #include "bcm_osal.h"
 #include "reg_addr.h"
+#include "common_hsi.h"
 #include "ecore_hsi_common.h"
 #include "ecore_hsi_eth.h"
 #include "ecore_rt_defs.h"
@@ -101,7 +102,6 @@ struct ecore_tid_seg {
 
 struct ecore_conn_type_cfg {
 	u32 cid_count;
-	u32 cid_start;
 	u32 cids_per_vf;
 	struct ecore_tid_seg tid_seg[TASK_SEGMENTS];
 };
@@ -197,6 +197,9 @@ struct ecore_cxt_mngr {
 
 	/* Acquired CIDs */
 	struct ecore_cid_acquired_map acquired[MAX_CONN_TYPES];
+	/* TBD - do we want this allocated to reserve space? */
+	struct ecore_cid_acquired_map
+		acquired_vf[MAX_CONN_TYPES][COMMON_MAX_NUM_VFS];
 
 	/* ILT  shadow table */
 	struct ecore_dma_mem *ilt_shadow;
@@ -1016,44 +1019,75 @@ static enum _ecore_status_t ecore_ilt_shadow_alloc(struct ecore_hwfn *p_hwfn)
 static void ecore_cid_map_free(struct ecore_hwfn *p_hwfn)
 {
 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
-	u32 type;
+	u32 type, vf;
 
 	for (type = 0; type < MAX_CONN_TYPES; type++) {
 		OSAL_FREE(p_hwfn->p_dev, p_mngr->acquired[type].cid_map);
 		p_mngr->acquired[type].max_count = 0;
 		p_mngr->acquired[type].start_cid = 0;
+
+		for (vf = 0; vf < COMMON_MAX_NUM_VFS; vf++) {
+			OSAL_FREE(p_hwfn->p_dev,
+				  p_mngr->acquired_vf[type][vf].cid_map);
+			p_mngr->acquired_vf[type][vf].max_count = 0;
+			p_mngr->acquired_vf[type][vf].start_cid = 0;
+		}
 	}
 }
 
+static enum _ecore_status_t
+ecore_cid_map_alloc_single(struct ecore_hwfn *p_hwfn, u32 type,
+			   u32 cid_start, u32 cid_count,
+			   struct ecore_cid_acquired_map *p_map)
+{
+	u32 size;
+
+	if (!cid_count)
+		return ECORE_SUCCESS;
+
+	size = MAP_WORD_SIZE * DIV_ROUND_UP(cid_count, BITS_PER_MAP_WORD);
+	p_map->cid_map = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, size);
+	if (p_map->cid_map == OSAL_NULL)
+		return ECORE_NOMEM;
+
+	p_map->max_count = cid_count;
+	p_map->start_cid = cid_start;
+
+	DP_VERBOSE(p_hwfn, ECORE_MSG_CXT,
+		   "Type %08x start: %08x count %08x\n",
+		   type, p_map->start_cid, p_map->max_count);
+
+	return ECORE_SUCCESS;
+}
+
 static enum _ecore_status_t ecore_cid_map_alloc(struct ecore_hwfn *p_hwfn)
 {
 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
-	u32 start_cid = 0;
-	u32 type;
+	u32 start_cid = 0, vf_start_cid = 0;
+	u32 type, vf;
 
 	for (type = 0; type < MAX_CONN_TYPES; type++) {
-		u32 cid_cnt = p_hwfn->p_cxt_mngr->conn_cfg[type].cid_count;
-		u32 size;
-
-		if (cid_cnt == 0)
-			continue;
+		struct ecore_conn_type_cfg *p_cfg = &p_mngr->conn_cfg[type];
+		struct ecore_cid_acquired_map *p_map;
 
-		size = MAP_WORD_SIZE * DIV_ROUND_UP(cid_cnt, BITS_PER_MAP_WORD);
-		p_mngr->acquired[type].cid_map = OSAL_ZALLOC(p_hwfn->p_dev,
-							     GFP_KERNEL, size);
-		if (!p_mngr->acquired[type].cid_map)
+		/* Handle PF maps */
+		p_map = &p_mngr->acquired[type];
+		if (ecore_cid_map_alloc_single(p_hwfn, type, start_cid,
+					       p_cfg->cid_count, p_map))
 			goto cid_map_fail;
 
-		p_mngr->acquired[type].max_count = cid_cnt;
-		p_mngr->acquired[type].start_cid = start_cid;
-
-		p_hwfn->p_cxt_mngr->conn_cfg[type].cid_start = start_cid;
+		/* Handle VF maps */
+		for (vf = 0; vf < COMMON_MAX_NUM_VFS; vf++) {
+			p_map = &p_mngr->acquired_vf[type][vf];
+			if (ecore_cid_map_alloc_single(p_hwfn, type,
+						       vf_start_cid,
+						       p_cfg->cids_per_vf,
+						       p_map))
+				goto cid_map_fail;
+		}
 
-		DP_VERBOSE(p_hwfn, ECORE_MSG_CXT,
-			   "Type %08x start: %08x count %08x\n",
-			   type, p_mngr->acquired[type].start_cid,
-			   p_mngr->acquired[type].max_count);
-		start_cid += cid_cnt;
+		start_cid += p_cfg->cid_count;
+		vf_start_cid += p_cfg->cids_per_vf;
 	}
 
 	return ECORE_SUCCESS;
@@ -1174,18 +1208,34 @@ void ecore_cxt_mngr_free(struct ecore_hwfn *p_hwfn)
 void ecore_cxt_mngr_setup(struct ecore_hwfn *p_hwfn)
 {
 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
+	struct ecore_cid_acquired_map *p_map;
+	struct ecore_conn_type_cfg *p_cfg;
 	int type;
+	u32 len;
 
 	/* Reset acquired cids */
 	for (type = 0; type < MAX_CONN_TYPES; type++) {
-		u32 cid_cnt = p_hwfn->p_cxt_mngr->conn_cfg[type].cid_count;
-		u32 i;
+		u32 vf;
+
+		p_cfg = &p_mngr->conn_cfg[type];
+		if (p_cfg->cid_count) {
+			p_map = &p_mngr->acquired[type];
+			len = DIV_ROUND_UP(p_map->max_count,
+					   BITS_PER_MAP_WORD) *
+			      MAP_WORD_SIZE;
+			OSAL_MEM_ZERO(p_map->cid_map, len);
+		}
 
-		if (cid_cnt == 0)
+		if (!p_cfg->cids_per_vf)
 			continue;
 
-		for (i = 0; i < DIV_ROUND_UP(cid_cnt, BITS_PER_MAP_WORD); i++)
-			p_mngr->acquired[type].cid_map[i] = 0;
+		for (vf = 0; vf < COMMON_MAX_NUM_VFS; vf++) {
+			p_map = &p_mngr->acquired_vf[type][vf];
+			len = DIV_ROUND_UP(p_map->max_count,
+					   BITS_PER_MAP_WORD) *
+			      MAP_WORD_SIZE;
+			OSAL_MEM_ZERO(p_map->cid_map, len);
+		}
 	}
 }
 
@@ -1726,93 +1776,150 @@ void ecore_cxt_hw_init_pf(struct ecore_hwfn *p_hwfn)
 	ecore_prs_init_pf(p_hwfn);
 }
 
-enum _ecore_status_t ecore_cxt_acquire_cid(struct ecore_hwfn *p_hwfn,
-					   enum protocol_type type, u32 *p_cid)
+enum _ecore_status_t _ecore_cxt_acquire_cid(struct ecore_hwfn *p_hwfn,
+					    enum protocol_type type,
+					    u32 *p_cid, u8 vfid)
 {
 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
+	struct ecore_cid_acquired_map *p_map;
 	u32 rel_cid;
 
-	if (type >= MAX_CONN_TYPES || !p_mngr->acquired[type].cid_map) {
+	if (type >= MAX_CONN_TYPES) {
 		DP_NOTICE(p_hwfn, true, "Invalid protocol type %d", type);
 		return ECORE_INVAL;
 	}
 
-	rel_cid = OSAL_FIND_FIRST_ZERO_BIT(p_mngr->acquired[type].cid_map,
-					   p_mngr->acquired[type].max_count);
+	if (vfid >= COMMON_MAX_NUM_VFS && vfid != ECORE_CXT_PF_CID) {
+		DP_NOTICE(p_hwfn, true, "VF [%02x] is out of range\n", vfid);
+		return ECORE_INVAL;
+	}
+
+	/* Determine the right map to take this CID from */
+	if (vfid == ECORE_CXT_PF_CID)
+		p_map = &p_mngr->acquired[type];
+	else
+		p_map = &p_mngr->acquired_vf[type][vfid];
 
-	if (rel_cid >= p_mngr->acquired[type].max_count) {
+	if (p_map->cid_map == OSAL_NULL) {
+		DP_NOTICE(p_hwfn, true, "Invalid protocol type %d", type);
+		return ECORE_INVAL;
+	}
+
+	rel_cid = OSAL_FIND_FIRST_ZERO_BIT(p_map->cid_map,
+					   p_map->max_count);
+
+	if (rel_cid >= p_map->max_count) {
 		DP_NOTICE(p_hwfn, false, "no CID available for protocol %d\n",
 			  type);
 		return ECORE_NORESOURCES;
 	}
 
-	OSAL_SET_BIT(rel_cid, p_mngr->acquired[type].cid_map);
+	OSAL_SET_BIT(rel_cid, p_map->cid_map);
 
-	*p_cid = rel_cid + p_mngr->acquired[type].start_cid;
+	*p_cid = rel_cid + p_map->start_cid;
+
+	DP_VERBOSE(p_hwfn, ECORE_MSG_CXT,
+		   "Acquired cid 0x%08x [rel. %08x] vfid %02x type %d\n",
+		   *p_cid, rel_cid, vfid, type);
 
 	return ECORE_SUCCESS;
 }
 
+enum _ecore_status_t ecore_cxt_acquire_cid(struct ecore_hwfn *p_hwfn,
+					   enum protocol_type type,
+					   u32 *p_cid)
+{
+	return _ecore_cxt_acquire_cid(p_hwfn, type, p_cid, ECORE_CXT_PF_CID);
+}
+
 static bool ecore_cxt_test_cid_acquired(struct ecore_hwfn *p_hwfn,
-					u32 cid, enum protocol_type *p_type)
+					u32 cid, u8 vfid,
+					enum protocol_type *p_type,
+					struct ecore_cid_acquired_map **pp_map)
 {
 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
-	struct ecore_cid_acquired_map *p_map;
-	enum protocol_type p;
 	u32 rel_cid;
 
 	/* Iterate over protocols and find matching cid range */
-	for (p = 0; p < MAX_CONN_TYPES; p++) {
-		p_map = &p_mngr->acquired[p];
+	for (*p_type = 0; *p_type < MAX_CONN_TYPES; (*p_type)++) {
+		if (vfid == ECORE_CXT_PF_CID)
+			*pp_map = &p_mngr->acquired[*p_type];
+		else
+			*pp_map = &p_mngr->acquired_vf[*p_type][vfid];
 
-		if (!p_map->cid_map)
+		if (!((*pp_map)->cid_map))
 			continue;
-		if (cid >= p_map->start_cid &&
-		    cid < p_map->start_cid + p_map->max_count) {
+		if (cid >= (*pp_map)->start_cid &&
+		    cid < (*pp_map)->start_cid + (*pp_map)->max_count) {
 			break;
 		}
 	}
-	*p_type = p;
-
-	if (p == MAX_CONN_TYPES) {
-		DP_NOTICE(p_hwfn, true, "Invalid CID %d", cid);
-		return false;
+	if (*p_type == MAX_CONN_TYPES) {
+		DP_NOTICE(p_hwfn, true, "Invalid CID %d vfid %02x", cid, vfid);
+		goto fail;
 	}
-	rel_cid = cid - p_map->start_cid;
-	if (!OSAL_TEST_BIT(rel_cid, p_map->cid_map)) {
-		DP_NOTICE(p_hwfn, true, "CID %d not acquired", cid);
-		return false;
+
+	rel_cid = cid - (*pp_map)->start_cid;
+	if (!OSAL_TEST_BIT(rel_cid, (*pp_map)->cid_map)) {
+		DP_NOTICE(p_hwfn, true,
+			  "CID %d [vifd %02x] not acquired", cid, vfid);
+		goto fail;
 	}
+
 	return true;
+fail:
+	*p_type = MAX_CONN_TYPES;
+	*pp_map = OSAL_NULL;
+	return false;
 }
 
-void ecore_cxt_release_cid(struct ecore_hwfn *p_hwfn, u32 cid)
+void _ecore_cxt_release_cid(struct ecore_hwfn *p_hwfn, u32 cid, u8 vfid)
 {
-	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
+	struct ecore_cid_acquired_map *p_map = OSAL_NULL;
 	enum protocol_type type;
 	bool b_acquired;
 	u32 rel_cid;
 
+	if (vfid != ECORE_CXT_PF_CID && vfid > COMMON_MAX_NUM_VFS) {
+		DP_NOTICE(p_hwfn, true,
+			  "Trying to return incorrect CID belonging to VF %02x\n",
+			  vfid);
+		return;
+	}
+
 	/* Test acquired and find matching per-protocol map */
-	b_acquired = ecore_cxt_test_cid_acquired(p_hwfn, cid, &type);
+	b_acquired = ecore_cxt_test_cid_acquired(p_hwfn, cid, vfid,
+						 &type, &p_map);
 
 	if (!b_acquired)
 		return;
 
-	rel_cid = cid - p_mngr->acquired[type].start_cid;
-	OSAL_CLEAR_BIT(rel_cid, p_mngr->acquired[type].cid_map);
+	rel_cid = cid - p_map->start_cid;
+	OSAL_CLEAR_BIT(rel_cid, p_map->cid_map);
+
+	DP_VERBOSE(p_hwfn, ECORE_MSG_CXT,
+		   "Released CID 0x%08x [rel. %08x] vfid %02x type %d\n",
+		   cid, rel_cid, vfid, type);
+}
+
+void ecore_cxt_release_cid(struct ecore_hwfn *p_hwfn, u32 cid)
+{
+	_ecore_cxt_release_cid(p_hwfn, cid, ECORE_CXT_PF_CID);
 }
 
 enum _ecore_status_t ecore_cxt_get_cid_info(struct ecore_hwfn *p_hwfn,
 					    struct ecore_cxt_info *p_info)
 {
 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
+	struct ecore_cid_acquired_map *p_map = OSAL_NULL;
 	u32 conn_cxt_size, hw_p_size, cxts_per_p, line;
 	enum protocol_type type;
 	bool b_acquired;
 
 	/* Test acquired and find matching per-protocol map */
-	b_acquired = ecore_cxt_test_cid_acquired(p_hwfn, p_info->iid, &type);
+	b_acquired = ecore_cxt_test_cid_acquired(p_hwfn, p_info->iid,
+						 ECORE_CXT_PF_CID,
+						 &type, &p_map);
 
 	if (!b_acquired)
 		return ECORE_INVAL;
@@ -1868,9 +1975,14 @@ enum _ecore_status_t ecore_cxt_set_pf_params(struct ecore_hwfn *p_hwfn)
 			struct ecore_eth_pf_params *p_params =
 			    &p_hwfn->pf_params.eth_pf_params;
 
+			/* TODO - we probably want to add VF number to the PF
+			 * params;
+			 * As of now, allocates 16 * 2 per-VF [to retain regular
+			 * functionality].
+			 */
 			ecore_cxt_set_proto_cid_count(p_hwfn,
 				PROTOCOLID_ETH,
-				p_params->num_cons, 1);	/* FIXME VF count... */
+				p_params->num_cons, 32);
 
 			break;
 		}
diff --git a/drivers/net/qede/base/ecore_cxt.h b/drivers/net/qede/base/ecore_cxt.h
index 5379d7b..1128051 100644
--- a/drivers/net/qede/base/ecore_cxt.h
+++ b/drivers/net/qede/base/ecore_cxt.h
@@ -130,14 +130,53 @@ void ecore_cxt_qm_iids(struct ecore_hwfn *p_hwfn,
 enum _ecore_status_t ecore_qm_reconf(struct ecore_hwfn *p_hwfn,
 				     struct ecore_ptt *p_ptt);
 
+#define ECORE_CXT_PF_CID (0xff)
+
+/**
+ * @brief ecore_cxt_release - Release a cid
+ *
+ * @param p_hwfn
+ * @param cid
+ */
+void ecore_cxt_release_cid(struct ecore_hwfn *p_hwfn, u32 cid);
+
 /**
-* @brief ecore_cxt_release - Release a cid
-*
-* @param p_hwfn
-* @param cid
-*/
-void ecore_cxt_release_cid(struct ecore_hwfn *p_hwfn,
-			   u32 cid);
+ * @brief ecore_cxt_release - Release a cid belonging to a vf-queue
+ *
+ * @param p_hwfn
+ * @param cid
+ * @param vfid - engine relative index. ECORE_CXT_PF_CID if belongs to PF
+ */
+void _ecore_cxt_release_cid(struct ecore_hwfn *p_hwfn,
+			    u32 cid, u8 vfid);
+
+/**
+ * @brief ecore_cxt_acquire - Acquire a new cid of a specific protocol type
+ *
+ * @param p_hwfn
+ * @param type
+ * @param p_cid
+ *
+ * @return enum _ecore_status_t
+ */
+enum _ecore_status_t ecore_cxt_acquire_cid(struct ecore_hwfn *p_hwfn,
+					   enum protocol_type type,
+					   u32 *p_cid);
+
+/**
+ * @brief _ecore_cxt_acquire - Acquire a new cid of a specific protocol type
+ *                             for a vf-queue
+ *
+ * @param p_hwfn
+ * @param type
+ * @param p_cid
+ * @param vfid - engine relative index. ECORE_CXT_PF_CID if belongs to PF
+ *
+ * @return enum _ecore_status_t
+ */
+enum _ecore_status_t _ecore_cxt_acquire_cid(struct ecore_hwfn *p_hwfn,
+					    enum protocol_type type,
+					    u32 *p_cid, u8 vfid);
 
 /**
  * @brief ecore_cxt_get_tid_mem_info - function checks if the
diff --git a/drivers/net/qede/base/ecore_cxt_api.h b/drivers/net/qede/base/ecore_cxt_api.h
index 6a50412..f154e0d 100644
--- a/drivers/net/qede/base/ecore_cxt_api.h
+++ b/drivers/net/qede/base/ecore_cxt_api.h
@@ -26,19 +26,6 @@ struct ecore_tid_mem {
 };
 
 /**
-* @brief ecore_cxt_acquire - Acquire a new cid of a specific protocol type
-*
-* @param p_hwfn
-* @param type
-* @param p_cid
-*
-* @return enum _ecore_status_t
-*/
-enum _ecore_status_t ecore_cxt_acquire_cid(struct ecore_hwfn  *p_hwfn,
-					   enum protocol_type type,
-					   u32 *p_cid);
-
-/**
 * @brief ecoreo_cid_get_cxt_info - Returns the context info for a specific cid
 *
 *
diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index 7baa1b0..0f60010 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -150,8 +150,11 @@ void ecore_resc_free(struct ecore_dev *p_dev)
 {
 	int i;
 
-	if (IS_VF(p_dev))
+	if (IS_VF(p_dev)) {
+		for_each_hwfn(p_dev, i)
+			ecore_l2_free(&p_dev->hwfns[i]);
 		return;
+	}
 
 	OSAL_FREE(p_dev, p_dev->fw_data);
 	p_dev->fw_data = OSAL_NULL;
@@ -169,6 +172,7 @@ void ecore_resc_free(struct ecore_dev *p_dev)
 		ecore_consq_free(p_hwfn);
 		ecore_int_free(p_hwfn);
 		ecore_iov_free(p_hwfn);
+		ecore_l2_free(p_hwfn);
 		ecore_dmae_info_free(p_hwfn);
 		ecore_dcbx_info_free(p_hwfn, p_hwfn->p_dcbx_info);
 		/* @@@TBD Flush work-queue ? */
@@ -845,8 +849,14 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev)
 	enum _ecore_status_t rc = ECORE_SUCCESS;
 	int i;
 
-	if (IS_VF(p_dev))
+	if (IS_VF(p_dev)) {
+		for_each_hwfn(p_dev, i) {
+			rc = ecore_l2_alloc(&p_dev->hwfns[i]);
+			if (rc != ECORE_SUCCESS)
+				return rc;
+		}
 		return rc;
+	}
 
 	p_dev->fw_data = OSAL_ZALLOC(p_dev, GFP_KERNEL,
 				     sizeof(*p_dev->fw_data));
@@ -967,6 +977,10 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev)
 		if (rc)
 			goto alloc_err;
 
+		rc = ecore_l2_alloc(p_hwfn);
+		if (rc != ECORE_SUCCESS)
+			goto alloc_err;
+
 		/* DMA info initialization */
 		rc = ecore_dmae_info_alloc(p_hwfn);
 		if (rc) {
@@ -1005,8 +1019,11 @@ void ecore_resc_setup(struct ecore_dev *p_dev)
 {
 	int i;
 
-	if (IS_VF(p_dev))
+	if (IS_VF(p_dev)) {
+		for_each_hwfn(p_dev, i)
+			ecore_l2_setup(&p_dev->hwfns[i]);
 		return;
+	}
 
 	for_each_hwfn(p_dev, i) {
 		struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
@@ -1024,6 +1041,7 @@ void ecore_resc_setup(struct ecore_dev *p_dev)
 
 		ecore_int_setup(p_hwfn, p_hwfn->p_main_ptt);
 
+		ecore_l2_setup(p_hwfn);
 		ecore_iov_setup(p_hwfn, p_hwfn->p_main_ptt);
 	}
 }
diff --git a/drivers/net/qede/base/ecore_l2.c b/drivers/net/qede/base/ecore_l2.c
index 4d26e19..adb5e47 100644
--- a/drivers/net/qede/base/ecore_l2.c
+++ b/drivers/net/qede/base/ecore_l2.c
@@ -29,24 +29,172 @@
 #define ECORE_MAX_SGES_NUM 16
 #define CRC32_POLY 0x1edc6f41
 
+struct ecore_l2_info {
+	u32 queues;
+	unsigned long **pp_qid_usage;
+
+	/* The lock is meant to synchronize access to the qid usage */
+	osal_mutex_t lock;
+};
+
+enum _ecore_status_t ecore_l2_alloc(struct ecore_hwfn *p_hwfn)
+{
+	struct ecore_l2_info *p_l2_info;
+	unsigned long **pp_qids;
+	u32 i;
+
+	if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
+		return ECORE_SUCCESS;
+
+	p_l2_info = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_l2_info));
+	if (!p_l2_info)
+		return ECORE_NOMEM;
+	p_hwfn->p_l2_info = p_l2_info;
+
+	if (IS_PF(p_hwfn->p_dev)) {
+		p_l2_info->queues = RESC_NUM(p_hwfn, ECORE_L2_QUEUE);
+	} else {
+		u8 rx = 0, tx = 0;
+
+		ecore_vf_get_num_rxqs(p_hwfn, &rx);
+		ecore_vf_get_num_txqs(p_hwfn, &tx);
+
+		p_l2_info->queues = (u32)OSAL_MAX_T(u8, rx, tx);
+	}
+
+	pp_qids = OSAL_VZALLOC(p_hwfn->p_dev,
+			       sizeof(unsigned long *) *
+			       p_l2_info->queues);
+	if (pp_qids == OSAL_NULL)
+		return ECORE_NOMEM;
+	p_l2_info->pp_qid_usage = pp_qids;
+
+	for (i = 0; i < p_l2_info->queues; i++) {
+		pp_qids[i] = OSAL_VZALLOC(p_hwfn->p_dev,
+					  MAX_QUEUES_PER_QZONE / 8);
+		if (pp_qids[i] == OSAL_NULL)
+			return ECORE_NOMEM;
+	}
+
+#ifdef CONFIG_ECORE_LOCK_ALLOC
+	OSAL_MUTEX_ALLOC(p_hwfn, &p_l2_info->lock);
+#endif
+
+	return ECORE_SUCCESS;
+}
+
+void ecore_l2_setup(struct ecore_hwfn *p_hwfn)
+{
+	if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
+		return;
+
+	OSAL_MUTEX_INIT(&p_hwfn->p_l2_info->lock);
+}
+
+void ecore_l2_free(struct ecore_hwfn *p_hwfn)
+{
+	u32 i;
+
+	if (!ECORE_IS_L2_PERSONALITY(p_hwfn))
+		return;
+
+	if (p_hwfn->p_l2_info == OSAL_NULL)
+		return;
+
+	if (p_hwfn->p_l2_info->pp_qid_usage == OSAL_NULL)
+		goto out_l2_info;
+
+	/* Free until hit first uninitialized entry */
+	for (i = 0; i < p_hwfn->p_l2_info->queues; i++) {
+		if (p_hwfn->p_l2_info->pp_qid_usage[i] == OSAL_NULL)
+			break;
+		OSAL_VFREE(p_hwfn->p_dev,
+			   p_hwfn->p_l2_info->pp_qid_usage[i]);
+	}
+
+#ifdef CONFIG_ECORE_LOCK_ALLOC
+	/* Lock is last to initialize, if everything else was */
+	if (i == p_hwfn->p_l2_info->queues)
+		OSAL_MUTEX_DEALLOC(&p_hwfn->p_l2_info->lock);
+#endif
+
+	OSAL_VFREE(p_hwfn->p_dev, p_hwfn->p_l2_info->pp_qid_usage);
+
+out_l2_info:
+	OSAL_VFREE(p_hwfn->p_dev, p_hwfn->p_l2_info);
+	p_hwfn->p_l2_info = OSAL_NULL;
+}
+
+/* TODO - we'll need locking around these... */
+static bool ecore_eth_queue_qid_usage_add(struct ecore_hwfn *p_hwfn,
+					  struct ecore_queue_cid *p_cid)
+{
+	struct ecore_l2_info *p_l2_info = p_hwfn->p_l2_info;
+	u16 queue_id = p_cid->rel.queue_id;
+	bool b_rc = true;
+	u8 first;
+
+	OSAL_MUTEX_ACQUIRE(&p_l2_info->lock);
+
+	if (queue_id > p_l2_info->queues) {
+		DP_NOTICE(p_hwfn, true,
+			  "Requested to increase usage for qzone %04x out of %08x\n",
+			  queue_id, p_l2_info->queues);
+		b_rc = false;
+		goto out;
+	}
+
+	first = (u8)OSAL_FIND_FIRST_ZERO_BIT(p_l2_info->pp_qid_usage[queue_id],
+					     MAX_QUEUES_PER_QZONE);
+	if (first >= MAX_QUEUES_PER_QZONE) {
+		b_rc = false;
+		goto out;
+	}
+
+	OSAL_SET_BIT(first, p_l2_info->pp_qid_usage[queue_id]);
+	p_cid->qid_usage_idx = first;
+
+out:
+	OSAL_MUTEX_RELEASE(&p_l2_info->lock);
+	return b_rc;
+}
+
+static void ecore_eth_queue_qid_usage_del(struct ecore_hwfn *p_hwfn,
+					  struct ecore_queue_cid *p_cid)
+{
+	OSAL_MUTEX_ACQUIRE(&p_hwfn->p_l2_info->lock);
+
+	OSAL_CLEAR_BIT(p_cid->qid_usage_idx,
+		       p_hwfn->p_l2_info->pp_qid_usage[p_cid->rel.queue_id]);
+
+	OSAL_MUTEX_RELEASE(&p_hwfn->p_l2_info->lock);
+}
+
 void ecore_eth_queue_cid_release(struct ecore_hwfn *p_hwfn,
 				 struct ecore_queue_cid *p_cid)
 {
+	/* For VF-queues, stuff is a bit complicated as:
+	 *  - They always maintain the qid_usage on their own.
+	 *  - In legacy mode, they also maintain their CIDs.
+	 */
+
 	/* VFs' CIDs are 0-based in PF-view, and uninitialized on VF */
-	if (!p_cid->is_vf && IS_PF(p_hwfn->p_dev))
-		ecore_cxt_release_cid(p_hwfn, p_cid->cid);
+	if (IS_PF(p_hwfn->p_dev) && !p_cid->b_legacy_vf)
+		_ecore_cxt_release_cid(p_hwfn, p_cid->cid, p_cid->vfid);
+	if (!p_cid->b_legacy_vf)
+		ecore_eth_queue_qid_usage_del(p_hwfn, p_cid);
 	OSAL_VFREE(p_hwfn->p_dev, p_cid);
 }
 
 /* The internal is only meant to be directly called by PFs initializeing CIDs
  * for their VFs.
  */
-struct ecore_queue_cid *
+static struct ecore_queue_cid *
 _ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
-			u16 opaque_fid, u32 cid, u8 vf_qid,
-			struct ecore_queue_start_common_params *p_params)
+			u16 opaque_fid, u32 cid,
+			struct ecore_queue_start_common_params *p_params,
+			struct ecore_queue_cid_vf_params *p_vf_params)
 {
-	bool b_is_same = (p_hwfn->hw_info.opaque_fid == opaque_fid);
 	struct ecore_queue_cid *p_cid;
 	enum _ecore_status_t rc;
 
@@ -56,13 +204,22 @@ struct ecore_queue_cid *
 
 	p_cid->opaque_fid = opaque_fid;
 	p_cid->cid = cid;
-	p_cid->vf_qid = vf_qid;
 	p_cid->rel = *p_params;
 	p_cid->p_owner = p_hwfn;
 
+	/* Fill-in bits related to VFs' queues if information was provided */
+	if (p_vf_params != OSAL_NULL) {
+		p_cid->vfid = p_vf_params->vfid;
+		p_cid->vf_qid = p_vf_params->vf_qid;
+		p_cid->b_legacy_vf = p_vf_params->b_legacy;
+	} else {
+		p_cid->vfid = ECORE_QUEUE_CID_PF;
+	}
+
 	/* Don't try calculating the absolute indices for VFs */
 	if (IS_VF(p_hwfn->p_dev)) {
 		p_cid->abs = p_cid->rel;
+
 		goto out;
 	}
 
@@ -82,7 +239,7 @@ struct ecore_queue_cid *
 	/* In case of a PF configuring its VF's queues, the stats-id is already
 	 * absolute [since there's a single index that's suitable per-VF].
 	 */
-	if (b_is_same) {
+	if (p_cid->vfid == ECORE_QUEUE_CID_PF) {
 		rc = ecore_fw_vport(p_hwfn, p_cid->rel.stats_id,
 				    &p_cid->abs.stats_id);
 		if (rc != ECORE_SUCCESS)
@@ -95,17 +252,23 @@ struct ecore_queue_cid *
 	p_cid->abs.sb = p_cid->rel.sb;
 	p_cid->abs.sb_idx = p_cid->rel.sb_idx;
 
-	/* This is tricky - we're actually interested in whehter this is a PF
-	 * entry meant for the VF.
-	 */
-	if (!b_is_same)
-		p_cid->is_vf = true;
 out:
+	/* VF-images have provided the qid_usage_idx on their own.
+	 * Otherwise, we need to allocate a unique one.
+	 */
+	if (!p_vf_params) {
+		if (!ecore_eth_queue_qid_usage_add(p_hwfn, p_cid))
+			goto fail;
+	} else {
+		p_cid->qid_usage_idx = p_vf_params->qid_usage_idx;
+	}
+
 	DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
-		   "opaque_fid: %04x CID %08x vport %02x [%02x] qzone %04x [%04x] stats %02x [%02x] SB %04x PI %02x\n",
+		   "opaque_fid: %04x CID %08x vport %02x [%02x] qzone %04x.%02x [%04x] stats %02x [%02x] SB %04x PI %02x\n",
 		   p_cid->opaque_fid, p_cid->cid,
 		   p_cid->rel.vport_id, p_cid->abs.vport_id,
-		   p_cid->rel.queue_id, p_cid->abs.queue_id,
+		   p_cid->rel.queue_id,	p_cid->qid_usage_idx,
+		   p_cid->abs.queue_id,
 		   p_cid->rel.stats_id, p_cid->abs.stats_id,
 		   p_cid->abs.sb, p_cid->abs.sb_idx);
 
@@ -116,33 +279,56 @@ struct ecore_queue_cid *
 	return OSAL_NULL;
 }
 
-static struct ecore_queue_cid *
-ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
-		       u16 opaque_fid,
-		       struct ecore_queue_start_common_params *p_params)
+struct ecore_queue_cid *
+ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
+		       struct ecore_queue_start_common_params *p_params,
+		       struct ecore_queue_cid_vf_params *p_vf_params)
 {
 	struct ecore_queue_cid *p_cid;
+	u8 vfid = ECORE_CXT_PF_CID;
+	bool b_legacy_vf = false;
 	u32 cid = 0;
 
+	/* In case of legacy VFs, The CID can be derived from the additional
+	 * VF parameters - the VF assumes queue X uses CID X, so we can simply
+	 * use the vf_qid for this purpose as well.
+	 */
+	if (p_vf_params) {
+		vfid = p_vf_params->vfid;
+
+		if (p_vf_params->b_legacy) {
+			b_legacy_vf = true;
+			cid = p_vf_params->vf_qid;
+		}
+	}
+
 	/* Get a unique firmware CID for this queue, in case it's a PF.
 	 * VF's don't need a CID as the queue configuration will be done
 	 * by PF.
 	 */
-	if (IS_PF(p_hwfn->p_dev)) {
-		if (ecore_cxt_acquire_cid(p_hwfn, PROTOCOLID_ETH,
-					  &cid) != ECORE_SUCCESS) {
+	if (IS_PF(p_hwfn->p_dev) && !b_legacy_vf) {
+		if (_ecore_cxt_acquire_cid(p_hwfn, PROTOCOLID_ETH,
+					   &cid, vfid) != ECORE_SUCCESS) {
 			DP_NOTICE(p_hwfn, true, "Failed to acquire cid\n");
 			return OSAL_NULL;
 		}
 	}
 
-	p_cid = _ecore_eth_queue_to_cid(p_hwfn, opaque_fid, cid, 0, p_params);
-	if ((p_cid == OSAL_NULL) && IS_PF(p_hwfn->p_dev))
-		ecore_cxt_release_cid(p_hwfn, cid);
+	p_cid = _ecore_eth_queue_to_cid(p_hwfn, opaque_fid, cid,
+					p_params, p_vf_params);
+	if ((p_cid == OSAL_NULL) && IS_PF(p_hwfn->p_dev) && !b_legacy_vf)
+		_ecore_cxt_release_cid(p_hwfn, cid, vfid);
 
 	return p_cid;
 }
 
+static struct ecore_queue_cid *
+ecore_eth_queue_to_cid_pf(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
+			  struct ecore_queue_start_common_params *p_params)
+{
+	return ecore_eth_queue_to_cid(p_hwfn, opaque_fid, p_params, OSAL_NULL);
+}
+
 enum _ecore_status_t
 ecore_sp_eth_vport_start(struct ecore_hwfn *p_hwfn,
 			 struct ecore_sp_vport_start_params *p_params)
@@ -741,7 +927,7 @@ enum _ecore_status_t
 	p_ramrod->num_of_pbl_pages = OSAL_CPU_TO_LE16(cqe_pbl_size);
 	DMA_REGPAIR_LE(p_ramrod->cqe_pbl_addr, cqe_pbl_addr);
 
-	if (p_cid->is_vf) {
+	if (p_cid->vfid != ECORE_QUEUE_CID_PF) {
 		p_ramrod->vf_rx_prod_index = p_cid->vf_qid;
 		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
 			   "Queue%s is meant for VF rxq[%02x]\n",
@@ -793,7 +979,7 @@ enum _ecore_status_t
 	enum _ecore_status_t rc;
 
 	/* Allocate a CID for the queue */
-	p_cid = ecore_eth_queue_to_cid(p_hwfn, opaque_fid, p_params);
+	p_cid = ecore_eth_queue_to_cid_pf(p_hwfn, opaque_fid, p_params);
 	if (p_cid == OSAL_NULL)
 		return ECORE_NOMEM;
 
@@ -905,9 +1091,11 @@ enum _ecore_status_t
 	/* Cleaning the queue requires the completion to arrive there.
 	 * In addition, VFs require the answer to come as eqe to PF.
 	 */
-	p_ramrod->complete_cqe_flg = (!p_cid->is_vf && !b_eq_completion_only) ||
+	p_ramrod->complete_cqe_flg = ((p_cid->vfid == ECORE_QUEUE_CID_PF) &&
+				      !b_eq_completion_only) ||
 				     b_cqe_completion;
-	p_ramrod->complete_event_flg = p_cid->is_vf || b_eq_completion_only;
+	p_ramrod->complete_event_flg = (p_cid->vfid != ECORE_QUEUE_CID_PF) ||
+				       b_eq_completion_only;
 
 	return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
 }
@@ -1007,7 +1195,7 @@ enum _ecore_status_t
 	struct ecore_queue_cid *p_cid;
 	enum _ecore_status_t rc;
 
-	p_cid = ecore_eth_queue_to_cid(p_hwfn, opaque_fid, p_params);
+	p_cid = ecore_eth_queue_to_cid_pf(p_hwfn, opaque_fid, p_params);
 	if (p_cid == OSAL_NULL)
 		return ECORE_INVAL;
 
diff --git a/drivers/net/qede/base/ecore_l2.h b/drivers/net/qede/base/ecore_l2.h
index 4b0ccb4..3f86eac 100644
--- a/drivers/net/qede/base/ecore_l2.h
+++ b/drivers/net/qede/base/ecore_l2.h
@@ -15,6 +15,34 @@
 #include "ecore_spq.h"
 #include "ecore_l2_api.h"
 
+#define MAX_QUEUES_PER_QZONE	(sizeof(unsigned long) * 8)
+#define ECORE_QUEUE_CID_PF	(0xff)
+
+/* Additional parameters required for initialization of the queue_cid
+ * and are relevant only for a PF initializing one for its VFs.
+ */
+struct ecore_queue_cid_vf_params {
+	/* Should match the VF's relative index */
+	u8 vfid;
+
+	/* 0-based queue index. Should reflect the relative qzone the
+	 * VF thinks is associated with it [in its range].
+	 */
+	u8 vf_qid;
+
+	/* Indicates a VF is legacy, making it differ in several things:
+	 *  - Producers would be placed in a different place.
+	 *  - Makes assumptions regarding the CIDs.
+	 */
+	bool b_legacy;
+
+	/* For VFs, this index arrives via TLV to diffrentiate between
+	 * different queues opened on the same qzone, and is passed
+	 * [where the PF would have allocated it internally for its own].
+	 */
+	u8 qid_usage_idx;
+};
+
 struct ecore_queue_cid {
 	/* 'Relative' is a relative term ;-). Usually the indices [not counting
 	 * SBs] would be PF-relative, but there are some cases where that isn't
@@ -31,22 +59,32 @@ struct ecore_queue_cid {
 	 * Notice this is relevant on the *PF* queue-cid of its VF's queues,
 	 * and not on the VF itself.
 	 */
-	bool is_vf;
+	u8 vfid;
 	u8 vf_qid;
 
+	/* We need an additional index to diffrentiate between queues opened
+	 * for same queue-zone, as VFs would have to communicate the info
+	 * to the PF [otherwise PF has no way to diffrentiate].
+	 */
+	u8 qid_usage_idx;
+
 	/* Legacy VFs might have Rx producer located elsewhere */
 	bool b_legacy_vf;
 
 	struct ecore_hwfn *p_owner;
 };
 
+enum _ecore_status_t ecore_l2_alloc(struct ecore_hwfn *p_hwfn);
+void ecore_l2_setup(struct ecore_hwfn *p_hwfn);
+void ecore_l2_free(struct ecore_hwfn *p_hwfn);
+
 void ecore_eth_queue_cid_release(struct ecore_hwfn *p_hwfn,
 				 struct ecore_queue_cid *p_cid);
 
 struct ecore_queue_cid *
-_ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
-			u16 opaque_fid, u32 cid, u8 vf_qid,
-			struct ecore_queue_start_common_params *p_params);
+ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn, u16 opaque_fid,
+		       struct ecore_queue_start_common_params *p_params,
+		       struct ecore_queue_cid_vf_params *p_vf_params);
 
 enum _ecore_status_t
 ecore_sp_eth_vport_start(struct ecore_hwfn *p_hwfn,
diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c
index dc01c6d..557644a 100644
--- a/drivers/net/qede/base/ecore_sriov.c
+++ b/drivers/net/qede/base/ecore_sriov.c
@@ -192,28 +192,90 @@ struct ecore_vf_info *ecore_iov_get_vf_info(struct ecore_hwfn *p_hwfn,
 	return vf;
 }
 
+static struct ecore_queue_cid *
+ecore_iov_get_vf_rx_queue_cid(struct ecore_hwfn *p_hwfn,
+			      struct ecore_vf_info *p_vf,
+			      struct ecore_vf_queue *p_queue)
+{
+	int i;
+
+	for (i = 0; i < MAX_QUEUES_PER_QZONE; i++) {
+		if (p_queue->cids[i].p_cid &&
+		    !p_queue->cids[i].b_is_tx)
+			return p_queue->cids[i].p_cid;
+	}
+
+	return OSAL_NULL;
+}
+
+enum ecore_iov_validate_q_mode {
+	ECORE_IOV_VALIDATE_Q_NA,
+	ECORE_IOV_VALIDATE_Q_ENABLE,
+	ECORE_IOV_VALIDATE_Q_DISABLE,
+};
+
+static bool ecore_iov_validate_queue_mode(struct ecore_hwfn *p_hwfn,
+					  struct ecore_vf_info *p_vf,
+					  u16 qid,
+					  enum ecore_iov_validate_q_mode mode,
+					  bool b_is_tx)
+{
+	int i;
+
+	if (mode == ECORE_IOV_VALIDATE_Q_NA)
+		return true;
+
+	for (i = 0; i < MAX_QUEUES_PER_QZONE; i++) {
+		struct ecore_vf_queue_cid *p_qcid;
+
+		p_qcid = &p_vf->vf_queues[qid].cids[i];
+
+		if (p_qcid->p_cid == OSAL_NULL)
+			continue;
+
+		if (p_qcid->b_is_tx != b_is_tx)
+			continue;
+
+		/* Found. It's enabled. */
+		return (mode == ECORE_IOV_VALIDATE_Q_ENABLE);
+	}
+
+	/* In case we haven't found any valid cid, then its disabled */
+	return (mode == ECORE_IOV_VALIDATE_Q_DISABLE);
+}
+
 static bool ecore_iov_validate_rxq(struct ecore_hwfn *p_hwfn,
 				   struct ecore_vf_info *p_vf,
-				   u16 rx_qid)
+				   u16 rx_qid,
+				   enum ecore_iov_validate_q_mode mode)
 {
-	if (rx_qid >= p_vf->num_rxqs)
+	if (rx_qid >= p_vf->num_rxqs) {
 		DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
 			   "VF[0x%02x] - can't touch Rx queue[%04x];"
 			   " Only 0x%04x are allocated\n",
 			   p_vf->abs_vf_id, rx_qid, p_vf->num_rxqs);
-	return rx_qid < p_vf->num_rxqs;
+		return false;
+	}
+
+	return ecore_iov_validate_queue_mode(p_hwfn, p_vf, rx_qid,
+					     mode, false);
 }
 
 static bool ecore_iov_validate_txq(struct ecore_hwfn *p_hwfn,
 				   struct ecore_vf_info *p_vf,
-				   u16 tx_qid)
+				   u16 tx_qid,
+				   enum ecore_iov_validate_q_mode mode)
 {
-	if (tx_qid >= p_vf->num_txqs)
+	if (tx_qid >= p_vf->num_txqs) {
 		DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
 			   "VF[0x%02x] - can't touch Tx queue[%04x];"
 			   " Only 0x%04x are allocated\n",
 			   p_vf->abs_vf_id, tx_qid, p_vf->num_txqs);
-	return tx_qid < p_vf->num_txqs;
+		return false;
+	}
+
+	return ecore_iov_validate_queue_mode(p_hwfn, p_vf, tx_qid,
+					     mode, true);
 }
 
 static bool ecore_iov_validate_sb(struct ecore_hwfn *p_hwfn,
@@ -234,13 +296,16 @@ static bool ecore_iov_validate_sb(struct ecore_hwfn *p_hwfn,
 	return false;
 }
 
+/* Is there at least 1 queue open? */
 static bool ecore_iov_validate_active_rxq(struct ecore_hwfn *p_hwfn,
 					  struct ecore_vf_info *p_vf)
 {
 	u8 i;
 
 	for (i = 0; i < p_vf->num_rxqs; i++)
-		if (p_vf->vf_queues[i].p_rx_cid)
+		if (ecore_iov_validate_queue_mode(p_hwfn, p_vf, i,
+						  ECORE_IOV_VALIDATE_Q_ENABLE,
+						  false))
 			return true;
 
 	return false;
@@ -251,8 +316,10 @@ static bool ecore_iov_validate_active_txq(struct ecore_hwfn *p_hwfn,
 {
 	u8 i;
 
-	for (i = 0; i < p_vf->num_rxqs; i++)
-		if (p_vf->vf_queues[i].p_tx_cid)
+	for (i = 0; i < p_vf->num_txqs; i++)
+		if (ecore_iov_validate_queue_mode(p_hwfn, p_vf, i,
+						  ECORE_IOV_VALIDATE_Q_ENABLE,
+						  true))
 			return true;
 
 	return false;
@@ -1098,19 +1165,15 @@ enum _ecore_status_t
 	vf->num_txqs = num_of_vf_available_chains;
 
 	for (i = 0; i < vf->num_rxqs; i++) {
-		struct ecore_vf_q_info *p_queue = &vf->vf_queues[i];
+		struct ecore_vf_queue *p_queue = &vf->vf_queues[i];
 
 		p_queue->fw_rx_qid = p_params->req_rx_queue[i];
 		p_queue->fw_tx_qid = p_params->req_tx_queue[i];
 
-		/* CIDs are per-VF, so no problem having them 0-based. */
-		p_queue->fw_cid = i;
-
 		DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
-			   "VF[%d] - Q[%d] SB %04x, qid [Rx %04x Tx %04x]  CID %04x\n",
+			   "VF[%d] - Q[%d] SB %04x, qid [Rx %04x Tx %04x]\n",
 			   vf->relative_vf_id, i, vf->igu_sbs[i],
-			   p_queue->fw_rx_qid, p_queue->fw_tx_qid,
-			   p_queue->fw_cid);
+			   p_queue->fw_rx_qid, p_queue->fw_tx_qid);
 	}
 
 	/* Update the link configuration in bulletin.
@@ -1446,7 +1509,7 @@ struct ecore_public_vf_info
 static void ecore_iov_vf_cleanup(struct ecore_hwfn *p_hwfn,
 				 struct ecore_vf_info *p_vf)
 {
-	u32 i;
+	u32 i, j;
 	p_vf->vf_bulletin = 0;
 	p_vf->vport_instance = 0;
 	p_vf->configured_features = 0;
@@ -1458,18 +1521,15 @@ static void ecore_iov_vf_cleanup(struct ecore_hwfn *p_hwfn,
 	p_vf->num_active_rxqs = 0;
 
 	for (i = 0; i < ECORE_MAX_VF_CHAINS_PER_PF; i++) {
-		struct ecore_vf_q_info *p_queue = &p_vf->vf_queues[i];
+		struct ecore_vf_queue *p_queue = &p_vf->vf_queues[i];
 
-		if (p_queue->p_rx_cid) {
-			ecore_eth_queue_cid_release(p_hwfn,
-						    p_queue->p_rx_cid);
-			p_queue->p_rx_cid = OSAL_NULL;
-		}
+		for (j = 0; j < MAX_QUEUES_PER_QZONE; j++) {
+			if (!p_queue->cids[j].p_cid)
+				continue;
 
-		if (p_queue->p_tx_cid) {
 			ecore_eth_queue_cid_release(p_hwfn,
-						    p_queue->p_tx_cid);
-			p_queue->p_tx_cid = OSAL_NULL;
+						    p_queue->cids[j].p_cid);
+			p_queue->cids[j].p_cid = OSAL_NULL;
 		}
 	}
 
@@ -1484,7 +1544,7 @@ static u8 ecore_iov_vf_mbx_acquire_resc(struct ecore_hwfn *p_hwfn,
 					struct vf_pf_resc_request *p_req,
 					struct pf_vf_resc *p_resp)
 {
-	int i;
+	u8 i;
 
 	/* Queue related information */
 	p_resp->num_rxqs = p_vf->num_rxqs;
@@ -1505,7 +1565,7 @@ static u8 ecore_iov_vf_mbx_acquire_resc(struct ecore_hwfn *p_hwfn,
 	for (i = 0; i < p_resp->num_rxqs; i++) {
 		ecore_fw_l2_queue(p_hwfn, p_vf->vf_queues[i].fw_rx_qid,
 				  (u16 *)&p_resp->hw_qid[i]);
-		p_resp->cid[i] = p_vf->vf_queues[i].fw_cid;
+		p_resp->cid[i] = i;
 	}
 
 	/* Filter related information */
@@ -1908,9 +1968,12 @@ static void ecore_iov_vf_mbx_acquire(struct ecore_hwfn       *p_hwfn,
 
 		/* Update all the Rx queues */
 		for (i = 0; i < ECORE_MAX_VF_CHAINS_PER_PF; i++) {
-			struct ecore_queue_cid *p_cid;
+			struct ecore_vf_queue *p_queue = &p_vf->vf_queues[i];
+			struct ecore_queue_cid *p_cid = OSAL_NULL;
 
-			p_cid = p_vf->vf_queues[i].p_rx_cid;
+			/* There can be at most 1 Rx queue on qzone. Find it */
+			p_cid = ecore_iov_get_vf_rx_queue_cid(p_hwfn, p_vf,
+							      p_queue);
 			if (p_cid == OSAL_NULL)
 				continue;
 
@@ -2116,19 +2179,32 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
 				       struct ecore_vf_info *vf)
 {
 	struct ecore_queue_start_common_params params;
+	struct ecore_queue_cid_vf_params vf_params;
 	struct ecore_iov_vf_mbx *mbx = &vf->vf_mbx;
 	u8 status = PFVF_STATUS_NO_RESOURCE;
-	struct ecore_vf_q_info *p_queue;
+	struct ecore_vf_queue *p_queue;
 	struct vfpf_start_rxq_tlv *req;
+	struct ecore_queue_cid *p_cid;
 	bool b_legacy_vf = false;
+	u8 qid_usage_idx;
 	enum _ecore_status_t rc;
 
 	req = &mbx->req_virt->start_rxq;
 
-	if (!ecore_iov_validate_rxq(p_hwfn, vf, req->rx_qid) ||
+	if (!ecore_iov_validate_rxq(p_hwfn, vf, req->rx_qid,
+				    ECORE_IOV_VALIDATE_Q_DISABLE) ||
 	    !ecore_iov_validate_sb(p_hwfn, vf, req->hw_sb))
 		goto out;
 
+	/* Legacy VFs made assumptions on the CID their queues connected to,
+	 * assuming queue X used CID X.
+	 * TODO - need to validate that there was no official release post
+	 * the current legacy scheme that still made that assumption.
+	 */
+	if (vf->acquire.vfdev_info.eth_fp_hsi_minor ==
+	    ETH_HSI_VER_NO_PKT_LEN_TUNN)
+		b_legacy_vf = true;
+
 	/* Acquire a new queue-cid */
 	p_queue = &vf->vf_queues[req->rx_qid];
 
@@ -2139,39 +2215,42 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
 	params.sb = req->hw_sb;
 	params.sb_idx = req->sb_index;
 
-	p_queue->p_rx_cid = _ecore_eth_queue_to_cid(p_hwfn,
-						    vf->opaque_fid,
-						    p_queue->fw_cid,
-						    (u8)req->rx_qid,
-						    &params);
-	if (p_queue->p_rx_cid == OSAL_NULL)
+	/* TODO - set qid_usage_idx according to extended TLV. For now, use
+	 * '0' for Rx.
+	 */
+	qid_usage_idx = 0;
+
+	OSAL_MEM_ZERO(&vf_params, sizeof(vf_params));
+	vf_params.vfid = vf->relative_vf_id;
+	vf_params.vf_qid = (u8)req->rx_qid;
+	vf_params.b_legacy = b_legacy_vf;
+	vf_params.qid_usage_idx = qid_usage_idx;
+
+	p_cid = ecore_eth_queue_to_cid(p_hwfn, vf->opaque_fid,
+				       &params, &vf_params);
+	if (p_cid == OSAL_NULL)
 		goto out;
 
 	/* Legacy VFs have their Producers in a different location, which they
 	 * calculate on their own and clean the producer prior to this.
 	 */
-	if (vf->acquire.vfdev_info.eth_fp_hsi_minor ==
-	    ETH_HSI_VER_NO_PKT_LEN_TUNN)
-		b_legacy_vf = true;
-	else
+	if (!b_legacy_vf)
 		REG_WR(p_hwfn,
 		       GTT_BAR0_MAP_REG_MSDM_RAM +
 		       MSTORM_ETH_VF_PRODS_OFFSET(vf->abs_vf_id, req->rx_qid),
 		       0);
-	p_queue->p_rx_cid->b_legacy_vf = b_legacy_vf;
 
-
-	rc = ecore_eth_rxq_start_ramrod(p_hwfn,
-					p_queue->p_rx_cid,
+	rc = ecore_eth_rxq_start_ramrod(p_hwfn, p_cid,
 					req->bd_max_bytes,
 					req->rxq_addr,
 					req->cqe_pbl_addr,
 					req->cqe_pbl_size);
 	if (rc != ECORE_SUCCESS) {
 		status = PFVF_STATUS_FAILURE;
-		ecore_eth_queue_cid_release(p_hwfn, p_queue->p_rx_cid);
-		p_queue->p_rx_cid = OSAL_NULL;
+		ecore_eth_queue_cid_release(p_hwfn, p_cid);
 	} else {
+		p_queue->cids[qid_usage_idx].p_cid = p_cid;
+		p_queue->cids[qid_usage_idx].b_is_tx = false;
 		status = PFVF_STATUS_SUCCESS;
 		vf->num_active_rxqs++;
 	}
@@ -2334,6 +2413,7 @@ static void ecore_iov_vf_mbx_update_tunn_param(struct ecore_hwfn *p_hwfn,
 static void ecore_iov_vf_mbx_start_txq_resp(struct ecore_hwfn *p_hwfn,
 					    struct ecore_ptt *p_ptt,
 					    struct ecore_vf_info *p_vf,
+					    u32 cid,
 					    u8 status)
 {
 	struct ecore_iov_vf_mbx *mbx = &p_vf->vf_mbx;
@@ -2362,12 +2442,8 @@ static void ecore_iov_vf_mbx_start_txq_resp(struct ecore_hwfn *p_hwfn,
 		      sizeof(struct channel_list_end_tlv));
 
 	/* Update the TLV with the response */
-	if ((status == PFVF_STATUS_SUCCESS) && !b_legacy) {
-		u16 qid = mbx->req_virt->start_txq.tx_qid;
-
-		p_tlv->offset = DB_ADDR_VF(p_vf->vf_queues[qid].fw_cid,
-					   DQ_DEMS_LEGACY);
-	}
+	if ((status == PFVF_STATUS_SUCCESS) && !b_legacy)
+		p_tlv->offset = DB_ADDR_VF(cid, DQ_DEMS_LEGACY);
 
 	ecore_iov_send_response(p_hwfn, p_ptt, p_vf, length, status);
 }
@@ -2377,20 +2453,34 @@ static void ecore_iov_vf_mbx_start_txq(struct ecore_hwfn *p_hwfn,
 				       struct ecore_vf_info *vf)
 {
 	struct ecore_queue_start_common_params params;
+	struct ecore_queue_cid_vf_params vf_params;
 	struct ecore_iov_vf_mbx *mbx = &vf->vf_mbx;
 	u8 status = PFVF_STATUS_NO_RESOURCE;
-	struct ecore_vf_q_info *p_queue;
+	struct ecore_vf_queue *p_queue;
 	struct vfpf_start_txq_tlv *req;
+	struct ecore_queue_cid *p_cid;
+	bool b_legacy_vf = false;
+	u8 qid_usage_idx;
+	u32 cid = 0;
 	enum _ecore_status_t rc;
 	u16 pq;
 
 	OSAL_MEMSET(&params, 0, sizeof(params));
 	req = &mbx->req_virt->start_txq;
 
-	if (!ecore_iov_validate_txq(p_hwfn, vf, req->tx_qid) ||
+	if (!ecore_iov_validate_txq(p_hwfn, vf, req->tx_qid,
+				    ECORE_IOV_VALIDATE_Q_NA) ||
 	    !ecore_iov_validate_sb(p_hwfn, vf, req->hw_sb))
 		goto out;
 
+	/* In case this is a legacy VF - need to know to use the right cids.
+	 * TODO - need to validate that there was no official release post
+	 * the current legacy scheme that still made that assumption.
+	 */
+	if (vf->acquire.vfdev_info.eth_fp_hsi_minor ==
+	    ETH_HSI_VER_NO_PKT_LEN_TUNN)
+		b_legacy_vf = true;
+
 	/* Acquire a new queue-cid */
 	p_queue = &vf->vf_queues[req->tx_qid];
 
@@ -2400,29 +2490,42 @@ static void ecore_iov_vf_mbx_start_txq(struct ecore_hwfn *p_hwfn,
 	params.sb = req->hw_sb;
 	params.sb_idx = req->sb_index;
 
-	p_queue->p_tx_cid = _ecore_eth_queue_to_cid(p_hwfn,
-						    vf->opaque_fid,
-						    p_queue->fw_cid,
-						    (u8)req->tx_qid,
-						    &params);
-	if (p_queue->p_tx_cid == OSAL_NULL)
+	/* TODO - set qid_usage_idx according to extended TLV. For now, use
+	 * '1' for Tx.
+	 */
+	qid_usage_idx = 1;
+
+	if (p_queue->cids[qid_usage_idx].p_cid)
+		goto out;
+
+	OSAL_MEM_ZERO(&vf_params, sizeof(vf_params));
+	vf_params.vfid = vf->relative_vf_id;
+	vf_params.vf_qid = (u8)req->tx_qid;
+	vf_params.b_legacy = b_legacy_vf;
+	vf_params.qid_usage_idx = qid_usage_idx;
+
+	p_cid = ecore_eth_queue_to_cid(p_hwfn, vf->opaque_fid,
+				       &params, &vf_params);
+	if (p_cid == OSAL_NULL)
 		goto out;
 
 	pq = ecore_get_cm_pq_idx_vf(p_hwfn,
 				    vf->relative_vf_id);
-	rc = ecore_eth_txq_start_ramrod(p_hwfn, p_queue->p_tx_cid,
+	rc = ecore_eth_txq_start_ramrod(p_hwfn, p_cid,
 					req->pbl_addr, req->pbl_size, pq);
 	if (rc != ECORE_SUCCESS) {
 		status = PFVF_STATUS_FAILURE;
-		ecore_eth_queue_cid_release(p_hwfn,
-					    p_queue->p_tx_cid);
-		p_queue->p_tx_cid = OSAL_NULL;
+		ecore_eth_queue_cid_release(p_hwfn, p_cid);
 	} else {
 		status = PFVF_STATUS_SUCCESS;
+		p_queue->cids[qid_usage_idx].p_cid = p_cid;
+		p_queue->cids[qid_usage_idx].b_is_tx = true;
+		cid = p_cid->cid;
 	}
 
 out:
-	ecore_iov_vf_mbx_start_txq_resp(p_hwfn, p_ptt, vf, status);
+	ecore_iov_vf_mbx_start_txq_resp(p_hwfn, p_ptt, vf,
+					cid, status);
 }
 
 static enum _ecore_status_t ecore_iov_vf_stop_rxqs(struct ecore_hwfn *p_hwfn,
@@ -2431,26 +2534,38 @@ static enum _ecore_status_t ecore_iov_vf_stop_rxqs(struct ecore_hwfn *p_hwfn,
 						   u8 num_rxqs,
 						   bool cqe_completion)
 {
-	struct ecore_vf_q_info *p_queue;
 	enum _ecore_status_t rc = ECORE_SUCCESS;
-	int qid;
+	int qid, i;
 
+	/* TODO - improve validation [wrap around] */
 	if (rxq_id + num_rxqs > OSAL_ARRAY_SIZE(vf->vf_queues))
 		return ECORE_INVAL;
 
 	for (qid = rxq_id; qid < rxq_id + num_rxqs; qid++) {
-		p_queue = &vf->vf_queues[qid];
-
-		if (!p_queue->p_rx_cid)
+		struct ecore_vf_queue *p_queue = &vf->vf_queues[qid];
+		struct ecore_queue_cid **pp_cid = OSAL_NULL;
+
+		/* There can be at most a single Rx per qzone. Find it */
+		for (i = 0; i < MAX_QUEUES_PER_QZONE; i++) {
+			if (p_queue->cids[i].p_cid &&
+			    !p_queue->cids[i].b_is_tx) {
+				pp_cid = &p_queue->cids[i].p_cid;
+				break;
+			}
+		}
+		if (pp_cid == OSAL_NULL) {
+			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
+				   "Ignoring VF[%02x] request of closing Rx queue %04x - closed\n",
+				   vf->relative_vf_id, qid);
 			continue;
+		}
 
-		rc = ecore_eth_rx_queue_stop(p_hwfn,
-					     p_queue->p_rx_cid,
+		rc = ecore_eth_rx_queue_stop(p_hwfn, *pp_cid,
 					     false, cqe_completion);
 		if (rc != ECORE_SUCCESS)
 			return rc;
 
-		vf->vf_queues[qid].p_rx_cid = OSAL_NULL;
+		*pp_cid = OSAL_NULL;
 		vf->num_active_rxqs--;
 	}
 
@@ -2462,24 +2577,33 @@ static enum _ecore_status_t ecore_iov_vf_stop_txqs(struct ecore_hwfn *p_hwfn,
 						   u16 txq_id, u8 num_txqs)
 {
 	enum _ecore_status_t rc = ECORE_SUCCESS;
-	struct ecore_vf_q_info *p_queue;
-	int qid;
+	struct ecore_vf_queue *p_queue;
+	int qid, j;
 
-	if (txq_id + num_txqs > OSAL_ARRAY_SIZE(vf->vf_queues))
+	if (!ecore_iov_validate_txq(p_hwfn, vf, txq_id,
+				    ECORE_IOV_VALIDATE_Q_NA) ||
+	    !ecore_iov_validate_txq(p_hwfn, vf, txq_id + num_txqs,
+				    ECORE_IOV_VALIDATE_Q_NA))
 		return ECORE_INVAL;
 
 	for (qid = txq_id; qid < txq_id + num_txqs; qid++) {
 		p_queue = &vf->vf_queues[qid];
-		if (!p_queue->p_tx_cid)
-			continue;
+		for (j = 0; j < MAX_QUEUES_PER_QZONE; j++) {
+			if (p_queue->cids[j].p_cid == OSAL_NULL)
+				continue;
 
-		rc = ecore_eth_tx_queue_stop(p_hwfn,
-					     p_queue->p_tx_cid);
-		if (rc != ECORE_SUCCESS)
-			return rc;
+			if (!p_queue->cids[j].b_is_tx)
+				continue;
+
+			rc = ecore_eth_tx_queue_stop(p_hwfn,
+						     p_queue->cids[j].p_cid);
+			if (rc != ECORE_SUCCESS)
+				return rc;
 
-		p_queue->p_tx_cid = OSAL_NULL;
+			p_queue->cids[j].p_cid = OSAL_NULL;
+		}
 	}
+
 	return rc;
 }
 
@@ -2541,33 +2665,32 @@ static void ecore_iov_vf_mbx_update_rxqs(struct ecore_hwfn *p_hwfn,
 	u8 status = PFVF_STATUS_FAILURE;
 	u8 complete_event_flg;
 	u8 complete_cqe_flg;
-	u16 qid;
 	enum _ecore_status_t rc;
-	u8 i;
+	u16 i;
 
 	req = &mbx->req_virt->update_rxq;
 	complete_cqe_flg = !!(req->flags & VFPF_RXQ_UPD_COMPLETE_CQE_FLAG);
 	complete_event_flg = !!(req->flags & VFPF_RXQ_UPD_COMPLETE_EVENT_FLAG);
 
-	/* Validaute inputs */
-	if (req->num_rxqs + req->rx_qid > ECORE_MAX_VF_CHAINS_PER_PF ||
-	    !ecore_iov_validate_rxq(p_hwfn, vf, req->rx_qid)) {
-		DP_INFO(p_hwfn, "VF[%d]: Incorrect Rxqs [%04x, %02x]\n",
-			vf->relative_vf_id, req->rx_qid, req->num_rxqs);
-		goto out;
+	/* Validate inputs */
+	for (i = req->rx_qid; i < req->rx_qid + req->num_rxqs; i++) {
+		if (!ecore_iov_validate_rxq(p_hwfn, vf, i,
+					    ECORE_IOV_VALIDATE_Q_ENABLE)) {
+			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
+				   "VF[%d]: Incorrect Rxqs [%04x, %02x]\n",
+				   vf->relative_vf_id, req->rx_qid,
+				   req->num_rxqs);
+			goto out;
+		}
 	}
 
 	for (i = 0; i < req->num_rxqs; i++) {
-		qid = req->rx_qid + i;
-
-		if (!vf->vf_queues[qid].p_rx_cid) {
-			DP_INFO(p_hwfn,
-				"VF[%d] rx_qid = %d isn`t active!\n",
-				vf->relative_vf_id, qid);
-			goto out;
-		}
+		struct ecore_vf_queue *p_queue;
+		u16 qid = req->rx_qid + i;
 
-		handlers[i] = vf->vf_queues[qid].p_rx_cid;
+		p_queue = &vf->vf_queues[qid];
+		handlers[i] = ecore_iov_get_vf_rx_queue_cid(p_hwfn, vf,
+							    p_queue);
 	}
 
 	rc = ecore_sp_eth_rx_queues_update(p_hwfn, (void **)&handlers,
@@ -2799,8 +2922,11 @@ void *ecore_iov_search_list_tlvs(struct ecore_hwfn *p_hwfn,
 				(1 << p_rss_tlv->rss_table_size_log));
 
 	for (i = 0; i < table_size; i++) {
+		struct ecore_queue_cid *p_cid;
+
 		q_idx = p_rss_tlv->rss_ind_table[i];
-		if (!ecore_iov_validate_rxq(p_hwfn, vf, q_idx)) {
+		if (!ecore_iov_validate_rxq(p_hwfn, vf, q_idx,
+					    ECORE_IOV_VALIDATE_Q_ENABLE)) {
 			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
 				   "VF[%d]: Omitting RSS due to wrong queue %04x\n",
 				   vf->relative_vf_id, q_idx);
@@ -2808,15 +2934,9 @@ void *ecore_iov_search_list_tlvs(struct ecore_hwfn *p_hwfn,
 			goto out;
 		}
 
-		if (!vf->vf_queues[q_idx].p_rx_cid) {
-			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
-				   "VF[%d]: Omitting RSS due to inactive queue %08x\n",
-				   vf->relative_vf_id, q_idx);
-			b_reject = true;
-			goto out;
-		}
-
-		p_rss->rss_ind_table[i] = vf->vf_queues[q_idx].p_rx_cid;
+		p_cid = ecore_iov_get_vf_rx_queue_cid(p_hwfn, vf,
+						      &vf->vf_queues[q_idx]);
+		p_rss->rss_ind_table[i] = p_cid;
 	}
 
 	p_data->rss_params = p_rss;
@@ -3275,22 +3395,26 @@ static void ecore_iov_vf_pf_set_coalesce(struct ecore_hwfn *p_hwfn,
 	u8 status = PFVF_STATUS_FAILURE;
 	struct ecore_queue_cid *p_cid;
 	u16 rx_coal, tx_coal;
-	u16  qid;
+	u16 qid;
+	int i;
 
 	req = &mbx->req_virt->update_coalesce;
 
 	rx_coal = req->rx_coal;
 	tx_coal = req->tx_coal;
 	qid = req->qid;
-	p_cid = vf->vf_queues[qid].p_rx_cid;
 
-	if (!ecore_iov_validate_rxq(p_hwfn, vf, qid)) {
+	if (!ecore_iov_validate_rxq(p_hwfn, vf, qid,
+				    ECORE_IOV_VALIDATE_Q_ENABLE) &&
+	    rx_coal) {
 		DP_ERR(p_hwfn, "VF[%d]: Invalid Rx queue_id = %d\n",
 		       vf->abs_vf_id, qid);
 		goto out;
 	}
 
-	if (!ecore_iov_validate_txq(p_hwfn, vf, qid)) {
+	if (!ecore_iov_validate_txq(p_hwfn, vf, qid,
+				    ECORE_IOV_VALIDATE_Q_ENABLE) &&
+	    tx_coal) {
 		DP_ERR(p_hwfn, "VF[%d]: Invalid Tx queue_id = %d\n",
 		       vf->abs_vf_id, qid);
 		goto out;
@@ -3299,7 +3423,11 @@ static void ecore_iov_vf_pf_set_coalesce(struct ecore_hwfn *p_hwfn,
 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
 		   "VF[%d]: Setting coalesce for VF rx_coal = %d, tx_coal = %d at queue = %d\n",
 		   vf->abs_vf_id, rx_coal, tx_coal, qid);
+
 	if (rx_coal) {
+		p_cid = ecore_iov_get_vf_rx_queue_cid(p_hwfn, vf,
+						      &vf->vf_queues[qid]);
+
 		rc = ecore_set_rxq_coalesce(p_hwfn, p_ptt, rx_coal, p_cid);
 		if (rc != ECORE_SUCCESS) {
 			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
@@ -3308,13 +3436,28 @@ static void ecore_iov_vf_pf_set_coalesce(struct ecore_hwfn *p_hwfn,
 			goto out;
 		}
 	}
+
+	/* TODO - in future, it might be possible to pass this in a per-cid
+	 * granularity. For now, do this for all Tx queues.
+	 */
 	if (tx_coal) {
-		rc =  ecore_set_txq_coalesce(p_hwfn, p_ptt, tx_coal, p_cid);
-		if (rc != ECORE_SUCCESS) {
-			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
-				   "VF[%d]: Unable to set tx queue = %d coalesce\n",
-				   vf->abs_vf_id, vf->vf_queues[qid].fw_tx_qid);
-			goto out;
+		struct ecore_vf_queue *p_queue = &vf->vf_queues[qid];
+
+		for (i = 0; i < MAX_QUEUES_PER_QZONE; i++) {
+			if (p_queue->cids[i].p_cid == OSAL_NULL)
+				continue;
+
+			if (!p_queue->cids[i].b_is_tx)
+				continue;
+
+			rc = ecore_set_txq_coalesce(p_hwfn, p_ptt, tx_coal,
+						    p_queue->cids[i].p_cid);
+			if (rc != ECORE_SUCCESS) {
+				DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
+					   "VF[%d]: Unable to set tx queue coalesce\n",
+					   vf->abs_vf_id);
+				goto out;
+			}
 		}
 	}
 
diff --git a/drivers/net/qede/base/ecore_sriov.h b/drivers/net/qede/base/ecore_sriov.h
index 66e9271..3c2f58b 100644
--- a/drivers/net/qede/base/ecore_sriov.h
+++ b/drivers/net/qede/base/ecore_sriov.h
@@ -13,6 +13,7 @@
 #include "ecore_vfpf_if.h"
 #include "ecore_iov_api.h"
 #include "ecore_hsi_common.h"
+#include "ecore_l2.h"
 
 #define ECORE_ETH_MAX_VF_NUM_VLAN_FILTERS \
 	(E4_MAX_NUM_VFS * ECORE_ETH_VF_NUM_VLAN_FILTERS)
@@ -62,12 +63,18 @@ struct ecore_iov_vf_mbx {
 					 */
 };
 
-struct ecore_vf_q_info {
+struct ecore_vf_queue_cid {
+	bool b_is_tx;
+	struct ecore_queue_cid *p_cid;
+};
+
+/* Describes a qzone associated with the VF */
+struct ecore_vf_queue {
+	/* Input from upper-layer, mapping relateive queue to queue-zone */
 	u16 fw_rx_qid;
-	struct ecore_queue_cid *p_rx_cid;
 	u16 fw_tx_qid;
-	struct ecore_queue_cid *p_tx_cid;
-	u8 fw_cid;
+
+	struct ecore_vf_queue_cid cids[MAX_QUEUES_PER_QZONE];
 };
 
 enum vf_state {
@@ -127,7 +134,7 @@ struct ecore_vf_info {
 	u8			num_mac_filters;
 	u8			num_vlan_filters;
 
-	struct ecore_vf_q_info	vf_queues[ECORE_MAX_VF_CHAINS_PER_PF];
+	struct ecore_vf_queue	vf_queues[ECORE_MAX_VF_CHAINS_PER_PF];
 	u16			igu_sbs[ECORE_MAX_VF_CHAINS_PER_PF];
 
 	/* TODO - Only windows is using it - should be removed */
diff --git a/drivers/net/qede/base/ecore_vf.c b/drivers/net/qede/base/ecore_vf.c
index c6743ed..53fc0cf 100644
--- a/drivers/net/qede/base/ecore_vf.c
+++ b/drivers/net/qede/base/ecore_vf.c
@@ -1583,6 +1583,12 @@ void ecore_vf_get_num_rxqs(struct ecore_hwfn *p_hwfn, u8 *num_rxqs)
 	*num_rxqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_rxqs;
 }
 
+void ecore_vf_get_num_txqs(struct ecore_hwfn *p_hwfn,
+			   u8 *num_txqs)
+{
+	*num_txqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_txqs;
+}
+
 void ecore_vf_get_port_mac(struct ecore_hwfn *p_hwfn, u8 *port_mac)
 {
 	OSAL_MEMCPY(port_mac,
diff --git a/drivers/net/qede/base/ecore_vf_api.h b/drivers/net/qede/base/ecore_vf_api.h
index a6e5f32..be3a326 100644
--- a/drivers/net/qede/base/ecore_vf_api.h
+++ b/drivers/net/qede/base/ecore_vf_api.h
@@ -61,6 +61,15 @@ void ecore_vf_get_num_rxqs(struct ecore_hwfn *p_hwfn,
 			   u8 *num_rxqs);
 
 /**
+ * @brief Get number of Rx queues allocated for VF by ecore
+ *
+ *  @param p_hwfn
+ *  @param num_txqs - allocated RX queues
+ */
+void ecore_vf_get_num_txqs(struct ecore_hwfn *p_hwfn,
+			   u8 *num_txqs);
+
+/**
  * @brief Get port mac address for VF
  *
  * @param p_hwfn
-- 
1.7.10.3

  parent reply	other threads:[~2017-02-27  7:58 UTC|newest]

Thread overview: 329+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-27  7:56 [PATCH 00/61] net/qede/base: qede PMD enhancements Rasesh Mody
2017-02-27  7:56 ` [PATCH 01/61] net/qede/base: return an initialized return value Rasesh Mody
2017-02-27  7:56 ` [PATCH 02/61] send FW version driver state to MFW Rasesh Mody
2017-03-03 10:26   ` Ferruh Yigit
2017-02-27  7:56 ` [PATCH 03/61] net/qede/base: mask Rx buffer attention bits Rasesh Mody
2017-02-27  7:56 ` [PATCH 04/61] net/qede/base: print various indication on Tx-timeouts Rasesh Mody
2017-02-27  7:56 ` [PATCH 05/61] net/qede/base: utilize FW 8.18.9.0 Rasesh Mody
2017-02-27  7:56 ` [PATCH 06/61] drivers/net/qede: upgrade the FW to 8.18.9.0 Rasesh Mody
2017-02-27  7:56 ` [PATCH 07/61] net/qede/base: decrease MAX_HWFNS_PER_DEVICE from 4 to 2 Rasesh Mody
2017-02-27  7:56 ` [PATCH 08/61] net/qede/base: move mask constants defining NIC type Rasesh Mody
2017-02-27  7:56 ` [PATCH 09/61] net/qede/base: remove attribute field from update current config Rasesh Mody
2017-02-27  7:56 ` [PATCH 10/61] net/qede/base: add nvram options Rasesh Mody
2017-02-27  7:56 ` [PATCH 11/61] net/qede/base: add comment Rasesh Mody
2017-02-27  7:56 ` [PATCH 12/61] net/qede/base: use default mtu from shared memory Rasesh Mody
2017-02-27  7:56 ` [PATCH 13/61] net/qede/base: change queue/sb-id from 8 bit to 16 bit Rasesh Mody
2017-02-27  7:56 ` [PATCH 14/61] net/qede/base: update MFW when default mtu is changed Rasesh Mody
2017-02-27  7:56 ` [PATCH 15/61] net/qede/base: prevent device init failure Rasesh Mody
2017-02-27  7:56 ` [PATCH 16/61] net/qede/base: add support to read personality via MFW commands Rasesh Mody
2017-02-27  7:56 ` [PATCH 17/61] net/qede/base: allow probe to succeed with minor HW-issues Rasesh Mody
2017-02-27  7:56 ` [PATCH 18/61] net/qede/base: remove unneeded step in HW init Rasesh Mody
2017-02-27  7:56 ` [PATCH 19/61] net/qede/base: allow only trusted VFs to be promisc/multi-promisc Rasesh Mody
2017-02-27  7:56 ` [PATCH 20/61] net/qede/base: qm initialization revamp Rasesh Mody
2017-02-27  7:56 ` [PATCH 21/61] net/qede/base: add a printout of the FW, MFW and MBI versions Rasesh Mody
2017-02-27  7:56 ` [PATCH 22/61] net/qede/base: check active VF queues before stopping Rasesh Mody
2017-02-27  7:56 ` [PATCH 23/61] net/qede/base: set the drv_type before sending load request Rasesh Mody
2017-02-27  7:56 ` [PATCH 24/61] net/qede/base: prevent driver laod with invalid resources Rasesh Mody
2017-02-27  7:56 ` [PATCH 25/61] net/qede/base: add interfaces for MFW TLV request processing Rasesh Mody
2017-02-27  7:56 ` [PATCH 26/61] net/qede/base: fix to set pointers to NULL after freeing Rasesh Mody
2017-02-27  7:56 ` [PATCH 27/61] net/qede/base: L2 handler changes Rasesh Mody
2017-02-27  7:56 ` [PATCH 28/61] net/qede/base: add support for handling TLV request from MFW Rasesh Mody
2017-02-27  7:56 ` [PATCH 29/61] net/qede/base: optimize cache-line access Rasesh Mody
2017-02-27  7:56 ` [PATCH 30/61] net/qede/base: infrastructure changes for VF tunnelling Rasesh Mody
2017-02-27  7:56 ` [PATCH 31/61] net/qede/base: revise tunnel APIs/structs Rasesh Mody
2017-02-27  7:56 ` [PATCH 32/61] net/qede/base: add tunnelling support for VFs Rasesh Mody
2017-02-27  7:56 ` [PATCH 33/61] net/qede/base: formatting changes Rasesh Mody
2017-02-27  7:56 ` [PATCH 34/61] net/qede/base: prevent transmitter stuck condition Rasesh Mody
2017-02-27  7:56 ` [PATCH 35/61] net/qede/base: add mask/shift defines for resource command Rasesh Mody
2017-02-27  7:56 ` [PATCH 36/61] net/qede/base: add API for using MFW resource lock Rasesh Mody
2017-02-27  7:56 ` [PATCH 37/61] net/qede/base: remove clock slowdown option Rasesh Mody
2017-02-27  7:56 ` [PATCH 38/61] net/qede/base: add new image types Rasesh Mody
2017-02-27  7:56 ` [PATCH 39/61] net/qede/base: use L2-handles for RSS configuration Rasesh Mody
2017-02-27  7:56 ` [PATCH 40/61] net/qede/base: change valloc to vzalloc Rasesh Mody
2017-02-27  7:56 ` [PATCH 41/61] net/qede/base: add support for previous driver unload Rasesh Mody
2017-02-27  7:56 ` [PATCH 42/61] net/qede/base: add non-l2 dcbx tlv application support Rasesh Mody
2017-02-27  7:56 ` [PATCH 43/61] net/qede/base: update bulletin board with link state during init Rasesh Mody
2017-02-27  7:57 ` [PATCH 44/61] net/qede/base: add coalescing support for VFs Rasesh Mody
2017-02-27  7:57 ` [PATCH 45/61] net/qede/base: add macro got resource value message Rasesh Mody
2017-02-27  7:57 ` [PATCH 46/61] net/qede/base: add mailbox for resource allocation Rasesh Mody
2017-02-27  7:57 ` [PATCH 47/61] net/qede/base: add macro for unsupported command Rasesh Mody
2017-02-27  7:57 ` [PATCH 48/61] net/qede/base: Add support to set max values of soft resoruces Rasesh Mody
2017-02-27  7:57 ` [PATCH 49/61] net/qede/base: add return code check Rasesh Mody
2017-02-27  7:57 ` [PATCH 50/61] net/qede/base: zero out MFW mailbox data Rasesh Mody
2017-02-27  7:57 ` [PATCH 51/61] net/qede/base: move code bits Rasesh Mody
2017-02-27  7:57 ` [PATCH 52/61] net/qede/base: add PF parameter Rasesh Mody
2017-02-27  7:57 ` [PATCH 53/61] net/qede/base: allow PMD to control vport-id and rss-eng-id Rasesh Mody
2017-02-27  7:57 ` [PATCH 54/61] net/qede/base: add udp ports in bulletin board message Rasesh Mody
2017-02-27  7:57 ` [PATCH 55/61] net/qede/base: prevent DMAE transactions during recovery Rasesh Mody
2017-02-27  7:57 ` Rasesh Mody [this message]
2017-02-27  7:57 ` [PATCH 57/61] net/qede/base: fix race cond between MFW attentions and PF stop Rasesh Mody
2017-02-27  7:57 ` [PATCH 58/61] net/qede/base: semantic changes Rasesh Mody
2017-02-27  7:57 ` [PATCH 59/61] net/qede/base: add support for arfs mode Rasesh Mody
2017-02-27  7:57 ` [PATCH 60/61] net/qede: add ntuple and flow director filter support Rasesh Mody
2017-02-27  7:57 ` [PATCH 61/61] net/qede: add LRO/TSO offloads support Rasesh Mody
2017-03-03 10:25 ` [PATCH 00/61] net/qede/base: qede PMD enhancements Ferruh Yigit
2017-03-18  7:05   ` [PATCH v2 " Rasesh Mody
2017-03-20 16:59     ` Ferruh Yigit
2017-03-24  7:27       ` [PATCH v3 " Rasesh Mody
2017-03-24 11:08         ` Ferruh Yigit
2017-03-28  6:42           ` [PATCH 01/62] net/qede/base: return an initialized return value Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 00/62] net/qede/base: update PMD to 2.4.0.1 Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 " Rasesh Mody
2017-03-30 12:23               ` Ferruh Yigit
2017-03-29 20:36             ` [PATCH v5 01/62] net/qede/base: return an initialized return value Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 02/62] net/qede/base: send FW version driver state to MFW Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 03/62] net/qede/base: mask Rx buffer attention bits Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 04/62] net/qede/base: print various indication on Tx-timeouts Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 05/62] net/qede/base: utilize FW 8.18.9.0 Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 06/62] net/qede: upgrade the FW to 8.18.9.0 Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 07/62] net/qede/base: decrease maximum HW func per device Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 08/62] net/qede/base: move mask constants defining NIC type Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 09/62] net/qede/base: remove attribute from update current config Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 10/62] net/qede/base: add nvram options Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 11/62] net/qede/base: add comment Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 12/62] net/qede/base: use default MTU from shared memory Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 13/62] net/qede/base: change queue/sb-id from 8 bit to 16 bit Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 14/62] net/qede/base: update MFW when default MTU is changed Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 15/62] net/qede/base: prevent device init failure Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 16/62] net/qede/base: read card personality via MFW commands Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 17/62] net/qede/base: allow probe to succeed with minor HW-issues Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 18/62] net/qede/base: remove unneeded step in HW init Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 19/62] net/qede/base: allow only trusted VFs to be promisc Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 20/62] net/qede/base: qm initialization revamp Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 21/62] net/qede/base: print firmware MFW and MBI versions Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 22/62] net/qede/base: check active VF queues before stopping Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 23/62] net/qede/base: set driver type before sending load request Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 24/62] net/qede/base: prevent driver load with invalid resources Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 25/62] net/qede/base: add interfaces for MFW TLV request processing Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 26/62] net/qede/base: code refactoring of SP queues Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 27/62] net/qede/base: make L2 queues handle based Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 28/62] net/qede/base: add support for handling TLV request from MFW Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 29/62] net/qede/base: optimize cache-line access Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 30/62] net/qede/base: infrastructure changes for VF tunnelling Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 31/62] net/qede/base: revise tunnel APIs/structs Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 32/62] net/qede/base: add tunnelling support for VFs Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 33/62] net/qede/base: formatting changes Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 34/62] net/qede/base: prevent transmitter stuck condition Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 35/62] net/qede/base: add mask/shift defines for resource command Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 36/62] net/qede/base: add API for using MFW resource lock Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 37/62] net/qede/base: remove clock slowdown option Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 38/62] net/qede/base: add new image types Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 39/62] net/qede/base: use L2-handles for RSS configuration Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 40/62] net/qede/base: change valloc to vzalloc Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 41/62] net/qede/base: add support for previous driver unload Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 42/62] net/qede/base: add non-L2 dcbx tlv application support Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 43/62] net/qede/base: update bulletin board during VF init Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 44/62] net/qede/base: add coalescing support for VFs Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 45/62] net/qede/base: add macro got resource value message Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 46/62] net/qede/base: add mailbox for resource allocation Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 47/62] net/qede/base: add macro for unsupported command Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 48/62] net/qede/base: set max values for soft resources Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 49/62] net/qede/base: add return code check Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 50/62] net/qede/base: zero out MFW mailbox data Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 51/62] net/qede/base: move code bits Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 52/62] net/qede/base: add PF parameter Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 53/62] net/qede/base: allow PMD to control vport and RSS engine ids Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 54/62] net/qede/base: add udp ports in bulletin board message Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 55/62] net/qede/base: prevent DMAE transactions during recovery Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 56/62] net/qede/base: multi-Txq support on same queue-zone for VFs Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 57/62] net/qede/base: prevent race condition during unload Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 58/62] net/qede/base: semantic changes Rasesh Mody
2017-03-29 20:36             ` [PATCH v5 59/62] net/qede/base: add support for arfs mode Rasesh Mody
2017-03-29 20:37             ` [PATCH v5 60/62] net/qede: add ntuple and flow director filter support Rasesh Mody
2017-03-29 20:37             ` [PATCH v5 61/62] net/qede: add LRO/TSO offloads support Rasesh Mody
2017-03-29 20:37             ` [PATCH v5 62/62] net/qede: update PMD version to 2.4.0.1 Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 01/62] net/qede/base: return an initialized return value Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 02/62] net/qede/base: send FW version driver state to MFW Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 03/62] net/qede/base: mask Rx buffer attention bits Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 04/62] net/qede/base: print various indication on Tx-timeouts Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 05/62] net/qede/base: utilize FW 8.18.9.0 Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 06/62] net/qede: upgrade the FW to 8.18.9.0 Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 07/62] net/qede/base: decrease maximum HW func per device Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 08/62] net/qede/base: move mask constants defining NIC type Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 09/62] net/qede/base: remove attribute from update current config Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 10/62] net/qede/base: add nvram options Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 11/62] net/qede/base: add comment Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 12/62] net/qede/base: use default MTU from shared memory Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 13/62] net/qede/base: change queue/sb-id from 8 bit to 16 bit Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 14/62] net/qede/base: update MFW when default MTU is changed Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 15/62] net/qede/base: prevent device init failure Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 16/62] net/qede/base: read card personality via MFW commands Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 17/62] net/qede/base: allow probe to succeed with minor HW-issues Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 18/62] net/qede/base: remove unneeded step in HW init Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 19/62] net/qede/base: allow only trusted VFs to be promisc Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 20/62] net/qede/base: qm initialization revamp Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 21/62] net/qede/base: print firmware MFW and MBI versions Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 22/62] net/qede/base: check active VF queues before stopping Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 23/62] net/qede/base: set driver type before sending load request Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 24/62] net/qede/base: prevent driver load with invalid resources Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 25/62] net/qede/base: add interfaces for MFW TLV request processing Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 26/62] net/qede/base: code refactoring of SP queues Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 27/62] net/qede/base: make L2 queues handle based Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 28/62] net/qede/base: add support for handling TLV request from MFW Rasesh Mody
2017-03-28  6:51           ` [PATCH v4 29/62] net/qede/base: optimize cache-line access Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 30/62] net/qede/base: infrastructure changes for VF tunnelling Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 31/62] net/qede/base: revise tunnel APIs/structs Rasesh Mody
2017-03-28 11:22             ` Ferruh Yigit
2017-03-28 21:18               ` Mody, Rasesh
2017-03-29  9:23                 ` Ferruh Yigit
2017-03-29 20:48                   ` Mody, Rasesh
2017-03-28  6:52           ` [PATCH v4 32/62] net/qede/base: add tunnelling support for VFs Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 33/62] net/qede/base: formatting changes Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 34/62] net/qede/base: prevent transmitter stuck condition Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 35/62] net/qede/base: add mask/shift defines for resource command Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 36/62] net/qede/base: add API for using MFW resource lock Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 37/62] net/qede/base: remove clock slowdown option Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 38/62] net/qede/base: add new image types Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 39/62] net/qede/base: use L2-handles for RSS configuration Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 40/62] net/qede/base: change valloc to vzalloc Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 41/62] net/qede/base: add support for previous driver unload Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 42/62] net/qede/base: add non-L2 dcbx tlv application support Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 43/62] net/qede/base: update bulletin board during VF init Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 44/62] net/qede/base: add coalescing support for VFs Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 45/62] net/qede/base: add macro got resource value message Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 46/62] net/qede/base: add mailbox for resource allocation Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 47/62] net/qede/base: add macro for unsupported command Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 48/62] net/qede/base: set max values for soft resources Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 49/62] net/qede/base: add return code check Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 50/62] net/qede/base: zero out MFW mailbox data Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 51/62] net/qede/base: move code bits Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 52/62] net/qede/base: add PF parameter Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 53/62] net/qede/base: allow PMD to control vport and RSS engine ids Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 54/62] net/qede/base: add udp ports in bulletin board message Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 55/62] net/qede/base: prevent DMAE transactions during recovery Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 56/62] net/qede/base: multi-Txq support on same queue-zone for VFs Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 57/62] net/qede/base: prevent race condition during unload Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 58/62] net/qede/base: semantic changes Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 59/62] net/qede/base: add support for arfs mode Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 60/62] net/qede: add ntuple and flow director filter support Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 61/62] net/qede: add LRO/TSO offloads support Rasesh Mody
2017-03-28  6:52           ` [PATCH v4 62/62] net/qede: update PMD version to 2.4.0.1 Rasesh Mody
     [not found]           ` <1490683278-23776-1-git-send-email-y>
2017-03-28  6:54             ` [PATCH 00/62] net/qede/base: update PMD " Mody, Rasesh
2017-03-24  7:27       ` [PATCH v3 01/61] net/qede/base: return an initialized return value Rasesh Mody
2017-03-24  7:27       ` [PATCH v3 02/61] net/qede/base: send FW version driver state to MFW Rasesh Mody
2017-03-24  7:27       ` [PATCH v3 03/61] net/qede/base: mask Rx buffer attention bits Rasesh Mody
2017-03-24  7:27       ` [PATCH v3 04/61] net/qede/base: print various indication on Tx-timeouts Rasesh Mody
2017-03-24  7:27       ` [PATCH v3 05/61] net/qede/base: utilize FW 8.18.9.0 Rasesh Mody
2017-03-24  7:27       ` [PATCH v3 06/61] net/qede: upgrade the FW to 8.18.9.0 Rasesh Mody
2017-03-24  7:27       ` [PATCH v3 07/61] net/qede/base: decrease maximum HW func per device Rasesh Mody
2017-03-24  7:27       ` [PATCH v3 08/61] net/qede/base: move mask constants defining NIC type Rasesh Mody
2017-03-24  7:27       ` [PATCH v3 09/61] net/qede/base: remove attribute from update current config Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 10/61] net/qede/base: add nvram options Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 11/61] net/qede/base: add comment Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 12/61] net/qede/base: use default MTU from shared memory Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 13/61] net/qede/base: change queue/sb-id from 8 bit to 16 bit Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 14/61] net/qede/base: update MFW when default MTU is changed Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 15/61] net/qede/base: prevent device init failure Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 16/61] net/qede/base: read card personality via MFW commands Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 17/61] net/qede/base: allow probe to succeed with minor HW-issues Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 18/61] net/qede/base: remove unneeded step in HW init Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 19/61] net/qede/base: allow only trusted VFs to be promisc Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 20/61] net/qede/base: qm initialization revamp Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 21/61] net/qede/base: print firmware MFW and MBI versions Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 22/61] net/qede/base: check active VF queues before stopping Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 23/61] net/qede/base: set driver type before sending load request Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 24/61] net/qede/base: prevent driver laod with invalid resources Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 25/61] net/qede/base: add interfaces for MFW TLV request processing Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 26/61] net/qede/base: code refactoring of SP queues Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 27/61] net/qede/base: make L2 queues handle based Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 28/61] net/qede/base: add support for handling TLV request from MFW Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 29/61] net/qede/base: optimize cache-line access Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 30/61] net/qede/base: infrastructure changes for VF tunnelling Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 31/61] net/qede/base: revise tunnel APIs/structs Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 32/61] net/qede/base: add tunnelling support for VFs Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 33/61] net/qede/base: formatting changes Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 34/61] net/qede/base: prevent transmitter stuck condition Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 35/61] net/qede/base: add mask/shift defines for resource command Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 36/61] net/qede/base: add API for using MFW resource lock Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 37/61] net/qede/base: remove clock slowdown option Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 38/61] net/qede/base: add new image types Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 39/61] net/qede/base: use L2-handles for RSS configuration Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 40/61] net/qede/base: change valloc to vzalloc Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 41/61] net/qede/base: add support for previous driver unload Rasesh Mody
2017-03-24 11:00         ` Ferruh Yigit
2017-03-25  6:25           ` Mody, Rasesh
2017-03-24  7:28       ` [PATCH v3 42/61] net/qede/base: add non-L2 dcbx tlv application support Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 43/61] net/qede/base: update bulletin board during VF init Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 44/61] net/qede/base: add coalescing support for VFs Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 45/61] net/qede/base: add macro got resource value message Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 46/61] net/qede/base: add mailbox for resource allocation Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 47/61] net/qede/base: add macro for unsupported command Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 48/61] net/qede/base: set max values for soft resoruces Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 49/61] net/qede/base: add return code check Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 50/61] net/qede/base: zero out MFW mailbox data Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 51/61] net/qede/base: move code bits Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 52/61] net/qede/base: add PF parameter Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 53/61] net/qede/base: allow PMD to control vport and RSS engine ids Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 54/61] net/qede/base: add udp ports in bulletin board message Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 55/61] net/qede/base: prevent DMAE transactions during recovery Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 56/61] net/qede/base: multi-Txq support on same queue-zone for VFs Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 57/61] net/qede/base: prevent race condition during unload Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 58/61] net/qede/base: semantic changes Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 59/61] net/qede/base: add support for arfs mode Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 60/61] net/qede: add ntuple and flow director filter support Rasesh Mody
2017-03-24  7:28       ` [PATCH v3 61/61] net/qede: add LRO/TSO offloads support Rasesh Mody
2017-03-24  7:45       ` [PATCH v2 00/61] net/qede/base: qede PMD enhancements Mody, Rasesh
2017-03-18  7:05   ` [PATCH v2 01/61] net/qede/base: return an initialized return value Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 02/61] net/qede/base: send FW version driver state to MFW Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 03/61] net/qede/base: mask Rx buffer attention bits Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 04/61] net/qede/base: print various indication on Tx-timeouts Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 05/61] net/qede/base: utilize FW 8.18.9.0 Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 06/61] net/qede: upgrade the FW to 8.18.9.0 Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 07/61] net/qede/base: decrease maximum HW func per device Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 08/61] net/qede/base: move mask constants defining NIC type Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 09/61] net/qede/base: remove attribute from update current config Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 10/61] net/qede/base: add nvram options Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 11/61] net/qede/base: add comment Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 12/61] net/qede/base: use default MTU from shared memory Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 13/61] net/qede/base: change queue/sb-id from 8 bit to 16 bit Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 14/61] net/qede/base: update MFW when default MTU is changed Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 15/61] net/qede/base: prevent device init failure Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 16/61] net/qede/base: read card personality via MFW commands Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 17/61] net/qede/base: allow probe to succeed with minor HW-issues Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 18/61] net/qede/base: remove unneeded step in HW init Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 19/61] net/qede/base: allow only trusted VFs to be promisc Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 20/61] net/qede/base: qm initialization revamp Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 21/61] net/qede/base: print firmware MFW and MBI versions Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 22/61] net/qede/base: check active VF queues before stopping Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 23/61] net/qede/base: set driver type before sending load request Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 24/61] net/qede/base: prevent driver laod with invalid resources Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 25/61] net/qede/base: add interfaces for MFW TLV request processing Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 26/61] net/qede/base: code refactoring of SP queues Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 27/61] net/qede/base: make L2 queues handle based Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 28/61] net/qede/base: add support for handling TLV request from MFW Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 29/61] net/qede/base: optimize cache-line access Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 30/61] net/qede/base: infrastructure changes for VF tunnelling Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 31/61] net/qede/base: revise tunnel APIs/structs Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 32/61] net/qede/base: add tunnelling support for VFs Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 33/61] net/qede/base: formatting changes Rasesh Mody
2017-03-18  7:05   ` [PATCH v2 34/61] net/qede/base: prevent transmitter stuck condition Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 35/61] net/qede/base: add mask/shift defines for resource command Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 36/61] net/qede/base: add API for using MFW resource lock Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 37/61] net/qede/base: remove clock slowdown option Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 38/61] net/qede/base: add new image types Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 39/61] net/qede/base: use L2-handles for RSS configuration Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 40/61] net/qede/base: change valloc to vzalloc Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 41/61] net/qede/base: add support for previous driver unload Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 42/61] net/qede/base: add non-L2 dcbx tlv application support Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 43/61] net/qede/base: update bulletin board during VF init Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 44/61] net/qede/base: add coalescing support for VFs Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 45/61] net/qede/base: add macro got resource value message Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 46/61] net/qede/base: add mailbox for resource allocation Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 47/61] net/qede/base: add macro for unsupported command Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 48/61] net/qede/base: set max values for soft resoruces Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 49/61] net/qede/base: add return code check Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 50/61] net/qede/base: zero out MFW mailbox data Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 51/61] net/qede/base: move code bits Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 52/61] net/qede/base: add PF parameter Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 53/61] net/qede/base: allow PMD to control vport and RSS engine ids Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 54/61] net/qede/base: add udp ports in bulletin board message Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 55/61] net/qede/base: prevent DMAE transactions during recovery Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 56/61] net/qede/base: multi-Txq support on same queue-zone for VFs Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 57/61] net/qede/base: prevent race condition during unload Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 58/61] net/qede/base: semantic changes Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 59/61] net/qede/base: add support for arfs mode Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 60/61] net/qede: add ntuple and flow director filter support Rasesh Mody
2017-03-18  7:06   ` [PATCH v2 61/61] net/qede: add LRO/TSO offloads support Rasesh Mody
2017-03-24 11:58     ` Ferruh Yigit
2017-03-25  6:28       ` Mody, Rasesh
2017-03-18  7:18   ` [PATCH 00/61] net/qede/base: qede PMD enhancements Mody, Rasesh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1488182237-10247-57-git-send-email-rasesh.mody@cavium.com \
    --to=rasesh.mody@cavium.com \
    --cc=Dept-EngDPDKDev@cavium.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.