DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Why IP_PIPELINE is faster than L2FWD
From: Xu, Qian Q @ 2016-12-23  1:34 UTC (permalink / raw)
  To: Royce Niu, Richardson, Bruce; +Cc: dev@dpdk.org, Dumitrescu, Cristian
In-Reply-To: <CAOwUCNvHieyrgNKJLGDSw2HCtUzpLyadfUzqEnp0x1A__-47og@mail.gmail.com>

As far as I know, L2FWD only uses 1 core for all RX/TX, for all queues, but for ip_pipeline, you may use more cores. 
A simple question, are you using 1core in ip_pipeline or l3fwd test? 

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Royce Niu
> Sent: Thursday, December 22, 2016 9:36 PM
> To: Richardson, Bruce <bruce.richardson@intel.com>
> Cc: Royce Niu <royceniu@gmail.com>; dev@dpdk.org; Dumitrescu, Cristian
> <cristian.dumitrescu@intel.com>
> Subject: Re: [dpdk-dev] Why IP_PIPELINE is faster than L2FWD
> 
> Dear Bruce,
> 
> Thanks for your kind explanation.
> 
> I will try to follow your suggestion and see the source code.
> 
> On Thu, Dec 22, 2016 at 9:25 PM, Bruce Richardson <
> bruce.richardson@intel.com> wrote:
> 
> > On Thu, Dec 22, 2016 at 08:48:50PM +0800, Royce Niu wrote:
> > > But, actually, L3FWD of IP_PIPELINE is also faster than stock L2FWD,
> > which
> > > also modifies mac addr. How can explain this?
> > >
> > > Actually, I want to know why IP_PIPELINE is much faster and I can
> > > learn from IP_PIPELINE and make our own program.
> > >
> > > But, the documentation of that is not detailed enough. if it is
> > > possible, could you tell me where is the key to boost? Thanks!
> > >
> >
> > Adding Cristian as IP Pipeline maintainer.
> >
> > A lot of tuning work went into IP Pipeline and the table and port
> > libraries it uses, so I'm not sure that there is just one or two key
> > changes which give it such good performance. L2 forward just hasn't
> > had the same level of tuning and, while performing well, is also
> > simplified to make it understandable as an example. Contrast the code
> > in l2fwd against equivalent vector code in l3fwd-lpm* files e.g.
> l3fwd_lpm_sse.h.
> > The latter is very high performing, the former is more readable.
> >
> > Regards,
> > /Bruce
> >
> > > On Thu, Dec 22, 2016 at 7:15 PM, Bruce Richardson <
> > > bruce.richardson@intel.com> wrote:
> > >
> > > > On Thu, Dec 22, 2016 at 12:18:12AM +0800, Royce Niu wrote:
> > > > > Hi all,
> > > > >
> > > > > I tested default L2FWD and IP_PIPELINE (pass-through). The
> > throughput of
> > > > > IP_PIPELINE is higher immensely.
> > > > >
> > > > > There are only two virtual NICs in KVM. The experiment is just
> > > > > moving packet from vNIC0  to vNIC1. I think the function is so
> > > > > simple. Why
> > L2FWD
> > > > > is much slower?
> > > > >
> > > > > How can I improve L2FWD, to make L2FWD faster?
> > > > >
> > > > Is IP_PIPELINE in passthrough mode modifying the packets? L2FWD
> > > > swaps the mac addresses on each packet as it processes them, which
> > > > can slow
> > it
> > > > down. L2FWD is also more an example of how the APIs work than
> > > > anything else. For fastest possible port-to-port forwarding,
> > > > testpmd should give the highest performance.
> > > >
> > > > /Bruce
> > > >
> > >
> > >
> > >
> > > --
> > > Regards,
> > >
> > > Royce
> >
> 
> 
> 
> --
> Regards,
> 
> Royce

^ permalink raw reply

* [PATCH v2 8/8] net/qede/base: fix VF over legacy PF
From: Rasesh Mody @ 2016-12-23  0:50 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, stable, Dept-EngDPDKDev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>

Apparently VF over Legacy PF doesn't work, as VF would fail after
getting the initial rejection message [instead of sending an additional
one where it asks for a FW override and see if it works].

Fixes: 22d07d939c3c ("net/qede/base: update")

Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
---
 drivers/net/qede/base/ecore_vf.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/qede/base/ecore_vf.c b/drivers/net/qede/base/ecore_vf.c
index 161b317..c26b602 100644
--- a/drivers/net/qede/base/ecore_vf.c
+++ b/drivers/net/qede/base/ecore_vf.c
@@ -294,6 +294,7 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn)
 						" override\n");
 					req->vfdev_info.capabilities |=
 						VFPF_ACQUIRE_CAP_PRE_FP_HSI;
+					continue;
 				}
 			}
 
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 7/8] net/qede/base: fix to handle acquire request from VF
From: Rasesh Mody @ 2016-12-23  0:50 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, stable, Dept-EngDPDKDev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>

Add a check and fail the VF's probe request if VF is already in
VF_ACQUIRED state.

Fixes: 22d07d939c3c ("net/qede/base: update")

Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
---
 drivers/net/qede/base/ecore_sriov.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c
index 1255296..c2fbee8 100644
--- a/drivers/net/qede/base/ecore_sriov.c
+++ b/drivers/net/qede/base/ecore_sriov.c
@@ -1459,6 +1459,18 @@ static void ecore_iov_vf_mbx_acquire(struct ecore_hwfn       *p_hwfn,
 	pfdev_info->major_fp_hsi = ETH_HSI_VER_MAJOR;
 	pfdev_info->minor_fp_hsi = ETH_HSI_VER_MINOR;
 
+	/* TODO - not doing anything is bad since we'll assert, but this isn't
+	 * necessarily the right behavior - perhaps we should have allowed some
+	 * versatility here.
+	 */
+	if (vf->state != VF_FREE &&
+	    vf->state != VF_STOPPED) {
+		DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
+			   "VF[%d] sent ACQUIRE but is already in state %d - fail request\n",
+			   vf->abs_vf_id, vf->state);
+		goto out;
+	}
+
 	/* Validate FW compatibility */
 	if (req->vfdev_info.eth_fp_hsi_major != ETH_HSI_VER_MAJOR) {
 		if (req->vfdev_info.capabilities &
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 6/8] net/qede/base: fix Rx queue access by malicious VFs
From: Rasesh Mody @ 2016-12-23  0:50 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, stable, Dept-EngDPDKDev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>

Rx queue access is still done prior to the index being validated by PF.
Hence move Rx queue and status block validation check before accessing
Rx queue to prevent malicious VFs from using out-of-bound queue indices.

Fixes: 98bc693e1938 ("net/qede/base: change queue start")

Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
---
 drivers/net/qede/base/ecore_sriov.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c
index de54b9a..1255296 100644
--- a/drivers/net/qede/base/ecore_sriov.c
+++ b/drivers/net/qede/base/ecore_sriov.c
@@ -1968,6 +1968,11 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
 	enum _ecore_status_t rc;
 
 	req = &mbx->req_virt->start_rxq;
+
+	if (!ecore_iov_validate_rxq(p_hwfn, vf, req->rx_qid) ||
+	    !ecore_iov_validate_sb(p_hwfn, vf, req->hw_sb))
+		goto out;
+
 	OSAL_MEMSET(&p_params, 0, sizeof(p_params));
 	p_params.queue_id = (u8)vf->vf_queues[req->rx_qid].fw_rx_qid;
 	p_params.vf_qid = req->rx_qid;
@@ -1976,10 +1981,6 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
 	p_params.sb = req->hw_sb;
 	p_params.sb_idx = req->sb_index;
 
-	if (!ecore_iov_validate_rxq(p_hwfn, vf, req->rx_qid) ||
-	    !ecore_iov_validate_sb(p_hwfn, vf, req->hw_sb))
-		goto out;
-
 	/* Legacy VFs have their Producers in a different location, which they
 	 * calculate on their own and clean the producer prior to this.
 	 */
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 5/8] net/qede/base: fix mutex in freeing context manager
From: Rasesh Mody @ 2016-12-23  0:50 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, stable, Dept-EngDPDKDev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>

Fix OSAL_MUTEX_DEALLOC() in freeing the context manager.

Fixes: 22d07d939c3c ("net/qede/base: update")

Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
---
 drivers/net/qede/base/ecore_cxt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/qede/base/ecore_cxt.c b/drivers/net/qede/base/ecore_cxt.c
index 3dd953d..5ea4f5c 100644
--- a/drivers/net/qede/base/ecore_cxt.c
+++ b/drivers/net/qede/base/ecore_cxt.c
@@ -1155,7 +1155,7 @@ void ecore_cxt_mngr_free(struct ecore_hwfn *p_hwfn)
 	ecore_cid_map_free(p_hwfn);
 	ecore_cxt_src_t2_free(p_hwfn);
 	ecore_ilt_shadow_free(p_hwfn);
-	OSAL_MUTEX_DEALLOC(&p_mngr->mutex);
+	OSAL_MUTEX_DEALLOC(&p_hwfn->p_cxt_mngr->mutex);
 	OSAL_FREE(p_hwfn->p_dev, p_hwfn->p_cxt_mngr);
 
 	p_hwfn->p_cxt_mngr = OSAL_NULL;
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 4/8] net/qede/base: fix error return code in resc alloc
From: Rasesh Mody @ 2016-12-23  0:50 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, stable, Dept-EngDPDKDev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>

Fix to return error code ECORE_INVAL instead of 0 when EQ elements
is too large as done elsewhere in this function.

Fixes: 22d07d939c3c ("net/qede/base: update")

Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
---
 drivers/net/qede/base/ecore_dev.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index 6060f9e..58b9387 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -667,6 +667,7 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev)
 			DP_ERR(p_hwfn, "Cannot allocate 0x%x EQ elements."
 				       "The maximum of a u16 chain is 0x%x\n",
 			       n_eqes, 0xFFFF);
+			rc = ECORE_INVAL;
 			goto alloc_err;
 		}
 
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 3/8] net/qede/base: fix multiple acquisition requests by VF
From: Rasesh Mody @ 2016-12-23  0:49 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, stable, Dept-EngDPDKDev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>

There are certain conditions under which VF would infinitely send
ACQUIRE messages, as it will fail to understand that PF has rejected
the ACQUIRE request. Fix to reject multiple acquisition requests by VF.

Fixes: 22d07d939c3c ("net/qede/base: update")

Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
---
 drivers/net/qede/base/ecore_vf.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/qede/base/ecore_vf.c b/drivers/net/qede/base/ecore_vf.c
index be8b1ec..161b317 100644
--- a/drivers/net/qede/base/ecore_vf.c
+++ b/drivers/net/qede/base/ecore_vf.c
@@ -296,6 +296,14 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn)
 						VFPF_ACQUIRE_CAP_PRE_FP_HSI;
 				}
 			}
+
+			/* If PF/VF are using same Major, PF must have had
+			 * it's reasons. Simply fail.
+			 */
+			DP_NOTICE(p_hwfn, false,
+				  "PF rejected acquisition by VF\n");
+			rc = ECORE_INVAL;
+			goto exit;
 		} else {
 			DP_ERR(p_hwfn,
 			       "PF returned err %d to VF acquisition request\n",
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 2/8] net/qede/base: fix sriov printouts
From: Rasesh Mody @ 2016-12-23  0:49 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, stable, Dept-EngDPDKDev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>

Remove unmeaningful function ID value in print.

Don't print the number of Multicast filters as part of Acquire response,
as this is an obsolete field which isn't enforced by PF.

Fixes: 86a2265e59d7 ("qede: add SRIOV support")

Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
---
 drivers/net/qede/base/ecore_sriov.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c
index b28d728..de54b9a 100644
--- a/drivers/net/qede/base/ecore_sriov.c
+++ b/drivers/net/qede/base/ecore_sriov.c
@@ -317,10 +317,9 @@ static enum _ecore_status_t ecore_iov_pci_cfg_info(struct ecore_dev *p_dev)
 
 	OSAL_PCI_READ_CONFIG_BYTE(p_dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
 
-	DP_VERBOSE(p_dev, ECORE_MSG_IOV, "IOV info[%d]: nres %d, cap 0x%x,"
+	DP_VERBOSE(p_dev, ECORE_MSG_IOV, "IOV info: nres %d, cap 0x%x,"
 		   "ctrl 0x%x, total %d, initial %d, num vfs %d, offset %d,"
-		   " stride %d, page size 0x%x\n", 0,
-		   /* @@@TBD MichalK - function id */
+		   " stride %d, page size 0x%x\n",
 		   iov->nres, iov->cap, iov->ctrl,
 		   iov->total_vfs, iov->initial_vfs, iov->nr_virtfn,
 		   iov->offset, iov->stride, iov->pgsz);
@@ -1575,12 +1574,12 @@ static void ecore_iov_vf_mbx_acquire(struct ecore_hwfn       *p_hwfn,
 		   "VF[%d] ACQUIRE_RESPONSE: pfdev_info- chip_num=0x%x,"
 		   " db_size=%d, idx_per_sb=%d, pf_cap=0x%lx\n"
 		   "resources- n_rxq-%d, n_txq-%d, n_sbs-%d, n_macs-%d,"
-		   " n_vlans-%d, n_mcs-%d\n",
+		   " n_vlans-%d\n",
 		   vf->abs_vf_id, resp->pfdev_info.chip_num,
 		   resp->pfdev_info.db_size, resp->pfdev_info.indices_per_sb,
 		   (unsigned long)resp->pfdev_info.capabilities, resc->num_rxqs,
 		   resc->num_txqs, resc->num_sbs, resc->num_mac_filters,
-		   resc->num_vlan_filters, resc->num_mc_filters);
+		   resc->num_vlan_filters);
 
 	vf->state = VF_ACQUIRED;
 
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 1/8] net/qede: fix to get vendor/device id info
From: Rasesh Mody @ 2016-12-23  0:49 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, stable, Dept-EngDPDKDev
In-Reply-To: <eba57a02-fccd-d0e7-f271-421981e11c7d@intel.com>

The vendor_id and device_id are used to determine device type. If you
don't have them, then check for determining device type fails and is
always set to default device type.

Fixes: ec94dbc57362 ("qede: add base driver")

Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
---
 drivers/net/qede/qede_ethdev.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 2c600c1..4943358 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1422,6 +1422,10 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
+	/* @DPDK */
+	edev->vendor_id = pci_dev->id.vendor_id;
+	edev->device_id = pci_dev->id.device_id;
+
 	qed_ops = qed_get_eth_ops();
 	if (!qed_ops) {
 		DP_ERR(edev, "Failed to get qed_eth_ops_pass\n");
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 4/7] net/qede: add fastpath support for VXLAN tunneling
From: Harish Patil @ 2016-12-23  0:48 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Harish Patil, dev, Dept-EngDPDKDev
In-Reply-To: <91ac9846-530c-2dd3-4bd6-2c3b9143405b@intel.com>

- Support HW checksum and RSS offload for VXLAN traffic
- Identify inner/outer packet_types using lookup table
- Update documentation

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 doc/guides/nics/features/qede.ini |    3 +
 doc/guides/nics/qede.rst          |    3 +-
 drivers/net/qede/qede_eth_if.h    |    3 +
 drivers/net/qede/qede_ethdev.c    |   18 +--
 drivers/net/qede/qede_ethdev.h    |    3 +
 drivers/net/qede/qede_main.c      |    2 +
 drivers/net/qede/qede_rxtx.c      |  280 ++++++++++++++++++++++++++-----------
 drivers/net/qede/qede_rxtx.h      |   46 ++++++
 8 files changed, 269 insertions(+), 89 deletions(-)

diff --git a/doc/guides/nics/features/qede.ini b/doc/guides/nics/features/qede.ini
index 7d75030..8858e5d 100644
--- a/doc/guides/nics/features/qede.ini
+++ b/doc/guides/nics/features/qede.ini
@@ -23,6 +23,9 @@ CRC offload          = Y
 VLAN offload         = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
+Tunnel filter        = Y
+Inner L3 checksum    = Y
+Inner L4 checksum    = Y
 Packet type parsing  = Y
 Basic stats          = Y
 Extended stats       = Y
diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index d22ecdd..999df95 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -59,12 +59,13 @@ Supported Features
 - MTU change
 - Multiprocess aware
 - Scatter-Gather
+- VXLAN tunneling offload
 
 Non-supported Features
 ----------------------
 
 - SR-IOV PF
-- Tunneling offloads
+- GENEVE and NVGRE Tunneling offloads
 - LRO/TSO
 - NPAR
 
diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h
index 9c0db87..d67b312 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -42,6 +42,9 @@ struct qed_dev_eth_info {
 	struct ether_addr port_mac;
 	uint16_t num_vlan_filters;
 	uint32_t num_mac_addrs;
+
+	/* Legacy VF - this affects the datapath */
+	bool is_legacy;
 };
 
 struct qed_update_vport_rss_params {
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 7a95560..ec48306 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -919,14 +919,16 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
 		.txq_flags = QEDE_TXQ_FLAGS,
 	};
 
-	dev_info->rx_offload_capa = (DEV_RX_OFFLOAD_VLAN_STRIP |
-				     DEV_RX_OFFLOAD_IPV4_CKSUM |
-				     DEV_RX_OFFLOAD_UDP_CKSUM |
-				     DEV_RX_OFFLOAD_TCP_CKSUM);
-	dev_info->tx_offload_capa = (DEV_TX_OFFLOAD_VLAN_INSERT |
-				     DEV_TX_OFFLOAD_IPV4_CKSUM |
-				     DEV_TX_OFFLOAD_UDP_CKSUM |
-				     DEV_TX_OFFLOAD_TCP_CKSUM);
+	dev_info->rx_offload_capa = (DEV_RX_OFFLOAD_VLAN_STRIP	|
+				     DEV_RX_OFFLOAD_IPV4_CKSUM	|
+				     DEV_RX_OFFLOAD_UDP_CKSUM	|
+				     DEV_RX_OFFLOAD_TCP_CKSUM	|
+				     DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM);
+	dev_info->tx_offload_capa = (DEV_TX_OFFLOAD_VLAN_INSERT	|
+				     DEV_TX_OFFLOAD_IPV4_CKSUM	|
+				     DEV_TX_OFFLOAD_UDP_CKSUM	|
+				     DEV_TX_OFFLOAD_TCP_CKSUM	|
+				     DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM);
 
 	memset(&link, 0, sizeof(struct qed_link_output));
 	qdev->ops->common->get_link(edev, &link);
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 6d0616e..d736246 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -15,6 +15,7 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_dev.h>
+#include <rte_ip.h>
 
 /* ecore includes */
 #include "base/bcm_osal.h"
@@ -184,6 +185,8 @@ static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
 				struct rte_eth_rss_reta_entry64 *reta_conf,
 				uint16_t reta_size);
 
+static inline uint32_t qede_rx_cqe_to_pkt_type(uint16_t flags);
+
 /* Non-static functions */
 void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf);
 
diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
index efc99ee..b769673 100644
--- a/drivers/net/qede/qede_main.c
+++ b/drivers/net/qede/qede_main.c
@@ -414,6 +414,8 @@ qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
 
 		ecore_vf_get_port_mac(&edev->hwfns[0],
 				      (uint8_t *)&info->port_mac);
+
+		info->is_legacy = ecore_vf_get_pre_fp_hsi(&edev->hwfns[0]);
 	}
 
 	qed_fill_dev_info(edev, &info->common);
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index 2e181c8..828d3cc 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -701,79 +701,64 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 	return 0;
 }
 
-#ifdef ENC_SUPPORTED
 static bool qede_tunn_exist(uint16_t flag)
 {
 	return !!((PARSING_AND_ERR_FLAGS_TUNNELEXIST_MASK <<
 		    PARSING_AND_ERR_FLAGS_TUNNELEXIST_SHIFT) & flag);
 }
 
-static inline uint8_t qede_check_tunn_csum(uint16_t flag)
+/*
+ * qede_check_tunn_csum_l4:
+ * Returns:
+ * 1 : If L4 csum is enabled AND if the validation has failed.
+ * 0 : Otherwise
+ */
+static inline uint8_t qede_check_tunn_csum_l4(uint16_t flag)
 {
-	uint8_t tcsum = 0;
-	uint16_t csum_flag = 0;
-
 	if ((PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMWASCALCULATED_MASK <<
 	     PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMWASCALCULATED_SHIFT) & flag)
-		csum_flag |= PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_MASK <<
-		    PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_SHIFT;
-
-	if ((PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_MASK <<
-	     PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_SHIFT) & flag) {
-		csum_flag |= PARSING_AND_ERR_FLAGS_L4CHKSMERROR_MASK <<
-		    PARSING_AND_ERR_FLAGS_L4CHKSMERROR_SHIFT;
-		tcsum = QEDE_TUNN_CSUM_UNNECESSARY;
-	}
-
-	csum_flag |= PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_MASK <<
-	    PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_SHIFT |
-	    PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK <<
-	    PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT;
-
-	if (csum_flag & flag)
-		return QEDE_CSUM_ERROR;
-
-	return QEDE_CSUM_UNNECESSARY | tcsum;
-}
-#else
-static inline uint8_t qede_tunn_exist(uint16_t flag)
-{
-	return 0;
-}
+		return !!((PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_MASK <<
+			PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_SHIFT) & flag);
 
-static inline uint8_t qede_check_tunn_csum(uint16_t flag)
-{
 	return 0;
 }
-#endif
 
-static inline uint8_t qede_check_notunn_csum(uint16_t flag)
+static inline uint8_t qede_check_notunn_csum_l4(uint16_t flag)
 {
-	uint8_t csum = 0;
-	uint16_t csum_flag = 0;
-
 	if ((PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_MASK <<
-	     PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_SHIFT) & flag) {
-		csum_flag |= PARSING_AND_ERR_FLAGS_L4CHKSMERROR_MASK <<
-		    PARSING_AND_ERR_FLAGS_L4CHKSMERROR_SHIFT;
-		csum = QEDE_CSUM_UNNECESSARY;
-	}
-
-	csum_flag |= PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK <<
-	    PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT;
-
-	if (csum_flag & flag)
-		return QEDE_CSUM_ERROR;
+	     PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_SHIFT) & flag)
+		return !!((PARSING_AND_ERR_FLAGS_L4CHKSMERROR_MASK <<
+			   PARSING_AND_ERR_FLAGS_L4CHKSMERROR_SHIFT) & flag);
 
-	return csum;
+	return 0;
 }
 
-static inline uint8_t qede_check_csum(uint16_t flag)
+static inline uint8_t
+qede_check_notunn_csum_l3(struct rte_mbuf *m, uint16_t flag)
 {
-	if (likely(!qede_tunn_exist(flag)))
-		return qede_check_notunn_csum(flag);
-	else
-		return qede_check_tunn_csum(flag);
+	struct ipv4_hdr *ip;
+	uint16_t pkt_csum;
+	uint16_t calc_csum;
+	uint16_t val;
+
+	val = ((PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK <<
+		PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT) & flag);
+
+	if (unlikely(val)) {
+		m->packet_type = qede_rx_cqe_to_pkt_type(flag);
+		if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+			ip = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
+					   sizeof(struct ether_hdr));
+			pkt_csum = ip->hdr_checksum;
+			ip->hdr_checksum = 0;
+			calc_csum = rte_ipv4_cksum(ip);
+			ip->hdr_checksum = pkt_csum;
+			return (calc_csum != pkt_csum);
+		} else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+			return 1;
+		}
+	}
+	return 0;
 }
 
 static inline void qede_rx_bd_ring_consume(struct qede_rx_queue *rxq)
@@ -818,22 +803,93 @@ qede_recycle_rx_bd_ring(struct qede_rx_queue *rxq,
 
 static inline uint32_t qede_rx_cqe_to_pkt_type(uint16_t flags)
 {
-	uint32_t p_type;
-	/* TBD - L4 indications needed ? */
-	uint16_t protocol = ((PARSING_AND_ERR_FLAGS_L3TYPE_MASK <<
-			      PARSING_AND_ERR_FLAGS_L3TYPE_SHIFT) & flags);
-
-	/* protocol = 3 means LLC/SNAP over Ethernet */
-	if (unlikely(protocol == 0 || protocol == 3))
-		p_type = RTE_PTYPE_UNKNOWN;
-	else if (protocol == 1)
-		p_type = RTE_PTYPE_L3_IPV4;
-	else if (protocol == 2)
-		p_type = RTE_PTYPE_L3_IPV6;
-
-	return RTE_PTYPE_L2_ETHER | p_type;
+	uint16_t val;
+
+	/* Lookup table */
+	static const uint32_t
+	ptype_lkup_tbl[QEDE_PKT_TYPE_MAX] __rte_cache_aligned = {
+		[QEDE_PKT_TYPE_IPV4] = RTE_PTYPE_L3_IPV4,
+		[QEDE_PKT_TYPE_IPV6] = RTE_PTYPE_L3_IPV6,
+		[QEDE_PKT_TYPE_IPV4_TCP] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+		[QEDE_PKT_TYPE_IPV6_TCP] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+		[QEDE_PKT_TYPE_IPV4_UDP] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+		[QEDE_PKT_TYPE_IPV6_UDP] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+	};
+
+	/* Bits (0..3) provides L3/L4 protocol type */
+	val = ((PARSING_AND_ERR_FLAGS_L3TYPE_MASK <<
+	       PARSING_AND_ERR_FLAGS_L3TYPE_SHIFT) |
+	       (PARSING_AND_ERR_FLAGS_L4PROTOCOL_MASK <<
+		PARSING_AND_ERR_FLAGS_L4PROTOCOL_SHIFT)) & flags;
+
+	if (val < QEDE_PKT_TYPE_MAX)
+		return ptype_lkup_tbl[val] | RTE_PTYPE_L2_ETHER;
+	else
+		return RTE_PTYPE_UNKNOWN;
+}
+
+static inline uint32_t qede_rx_cqe_to_tunn_pkt_type(uint16_t flags)
+{
+	uint32_t val;
+
+	/* Lookup table */
+	static const uint32_t
+	ptype_tunn_lkup_tbl[QEDE_PKT_TYPE_TUNN_MAX_TYPE] __rte_cache_aligned = {
+		[QEDE_PKT_TYPE_UNKNOWN] = RTE_PTYPE_UNKNOWN,
+		[QEDE_PKT_TYPE_TUNN_GENEVE] = RTE_PTYPE_TUNNEL_GENEVE,
+		[QEDE_PKT_TYPE_TUNN_GRE] = RTE_PTYPE_TUNNEL_GRE,
+		[QEDE_PKT_TYPE_TUNN_VXLAN] = RTE_PTYPE_TUNNEL_VXLAN,
+		[QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_GENEVE] =
+				RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L2_ETHER,
+		[QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_GRE] =
+				RTE_PTYPE_TUNNEL_GRE | RTE_PTYPE_L2_ETHER,
+		[QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_VXLAN] =
+				RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L2_ETHER,
+		[QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_GENEVE] =
+				RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L2_ETHER,
+		[QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_GRE] =
+				RTE_PTYPE_TUNNEL_GRE | RTE_PTYPE_L2_ETHER,
+		[QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_VXLAN] =
+				RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L2_ETHER,
+		[QEDE_PKT_TYPE_TUNN_IPV4_TENID_NOEXIST_GENEVE] =
+				RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L3_IPV4,
+		[QEDE_PKT_TYPE_TUNN_IPV4_TENID_NOEXIST_GRE] =
+				RTE_PTYPE_TUNNEL_GRE | RTE_PTYPE_L3_IPV4,
+		[QEDE_PKT_TYPE_TUNN_IPV4_TENID_NOEXIST_VXLAN] =
+				RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L3_IPV4,
+		[QEDE_PKT_TYPE_TUNN_IPV4_TENID_EXIST_GENEVE] =
+				RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L3_IPV4,
+		[QEDE_PKT_TYPE_TUNN_IPV4_TENID_EXIST_GRE] =
+				RTE_PTYPE_TUNNEL_GRE | RTE_PTYPE_L3_IPV4,
+		[QEDE_PKT_TYPE_TUNN_IPV4_TENID_EXIST_VXLAN] =
+				RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L3_IPV4,
+		[QEDE_PKT_TYPE_TUNN_IPV6_TENID_NOEXIST_GENEVE] =
+				RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L3_IPV6,
+		[QEDE_PKT_TYPE_TUNN_IPV6_TENID_NOEXIST_GRE] =
+				RTE_PTYPE_TUNNEL_GRE | RTE_PTYPE_L3_IPV6,
+		[QEDE_PKT_TYPE_TUNN_IPV6_TENID_NOEXIST_VXLAN] =
+				RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L3_IPV6,
+		[QEDE_PKT_TYPE_TUNN_IPV6_TENID_EXIST_GENEVE] =
+				RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L3_IPV6,
+		[QEDE_PKT_TYPE_TUNN_IPV6_TENID_EXIST_GRE] =
+				RTE_PTYPE_TUNNEL_GRE | RTE_PTYPE_L3_IPV6,
+		[QEDE_PKT_TYPE_TUNN_IPV6_TENID_EXIST_VXLAN] =
+				RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L3_IPV6,
+	};
+
+	/* Cover bits[4-0] to include tunn_type and next protocol */
+	val = ((ETH_TUNNEL_PARSING_FLAGS_TYPE_MASK <<
+		ETH_TUNNEL_PARSING_FLAGS_TYPE_SHIFT) |
+		(ETH_TUNNEL_PARSING_FLAGS_NEXT_PROTOCOL_MASK <<
+		ETH_TUNNEL_PARSING_FLAGS_NEXT_PROTOCOL_SHIFT)) & flags;
+
+	if (val < QEDE_PKT_TYPE_TUNN_MAX_TYPE)
+		return ptype_tunn_lkup_tbl[val];
+	else
+		return RTE_PTYPE_UNKNOWN;
 }
 
+
 int qede_process_sg_pkts(void *p_rxq,  struct rte_mbuf *rx_mb,
 			 int num_segs, uint16_t pkt_len)
 {
@@ -904,6 +960,7 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	uint16_t len, pad, preload_idx, pkt_len, parse_flag;
 	uint8_t csum_flag, num_segs;
 	enum rss_hash_type htype;
+	uint8_t tunn_parse_flag;
 	int ret;
 
 	hw_comp_cons = rte_le_to_cpu_16(*rxq->hw_cons_ptr);
@@ -950,17 +1007,47 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		/* If this is an error packet then drop it */
 		parse_flag =
 		    rte_le_to_cpu_16(cqe->fast_path_regular.pars_flags.flags);
-		csum_flag = qede_check_csum(parse_flag);
-		if (unlikely(csum_flag == QEDE_CSUM_ERROR)) {
-			PMD_RX_LOG(ERR, rxq,
-				   "CQE in CONS = %u has error, flags = 0x%x "
-				   "dropping incoming packet\n",
-				   sw_comp_cons, parse_flag);
-			rxq->rx_hw_errors++;
-			qede_recycle_rx_bd_ring(rxq, qdev, fp_cqe->bd_num);
-			goto next_cqe;
+
+		rx_mb->ol_flags = 0;
+
+		if (qede_tunn_exist(parse_flag)) {
+			PMD_RX_LOG(DEBUG, rxq, "Rx tunneled packet\n");
+			if (unlikely(qede_check_tunn_csum_l4(parse_flag))) {
+				PMD_RX_LOG(ERR, rxq,
+					    "L4 csum failed, flags = 0x%x\n",
+					    parse_flag);
+				rxq->rx_hw_errors++;
+				rx_mb->ol_flags |= PKT_RX_L4_CKSUM_BAD;
+			} else {
+				tunn_parse_flag =
+						fp_cqe->tunnel_pars_flags.flags;
+				rx_mb->packet_type =
+					qede_rx_cqe_to_tunn_pkt_type(
+							tunn_parse_flag);
+			}
+		} else {
+			PMD_RX_LOG(DEBUG, rxq, "Rx non-tunneled packet\n");
+			if (unlikely(qede_check_notunn_csum_l4(parse_flag))) {
+				PMD_RX_LOG(ERR, rxq,
+					    "L4 csum failed, flags = 0x%x\n",
+					    parse_flag);
+				rxq->rx_hw_errors++;
+				rx_mb->ol_flags |= PKT_RX_L4_CKSUM_BAD;
+			} else if (unlikely(qede_check_notunn_csum_l3(rx_mb,
+							parse_flag))) {
+				PMD_RX_LOG(ERR, rxq,
+					   "IP csum failed, flags = 0x%x\n",
+					   parse_flag);
+				rxq->rx_hw_errors++;
+				rx_mb->ol_flags |= PKT_RX_IP_CKSUM_BAD;
+			} else {
+				rx_mb->packet_type =
+					qede_rx_cqe_to_pkt_type(parse_flag);
+			}
 		}
 
+		PMD_RX_LOG(INFO, rxq, "packet_type 0x%x\n", rx_mb->packet_type);
+
 		if (unlikely(qede_alloc_rx_buffer(rxq) != 0)) {
 			PMD_RX_LOG(ERR, rxq,
 				   "New buffer allocation failed,"
@@ -995,14 +1082,12 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		preload_idx = rxq->sw_rx_cons & NUM_RX_BDS(rxq);
 		rte_prefetch0(rxq->sw_rx_ring[preload_idx].mbuf);
 
-		/* Update MBUF fields */
-		rx_mb->ol_flags = 0;
+		/* Update rest of the MBUF fields */
 		rx_mb->data_off = pad + RTE_PKTMBUF_HEADROOM;
 		rx_mb->nb_segs = fp_cqe->bd_num;
 		rx_mb->data_len = len;
 		rx_mb->pkt_len = fp_cqe->pkt_len;
 		rx_mb->port = rxq->port_id;
-		rx_mb->packet_type = qede_rx_cqe_to_pkt_type(parse_flag);
 
 		htype = (uint8_t)GET_FIELD(fp_cqe->bitfields,
 				ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE);
@@ -1206,8 +1291,39 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		QEDE_BD_SET_ADDR_LEN(bd1, rte_mbuf_data_dma_addr(mbuf),
 				     mbuf->pkt_len);
 
+		if (RTE_ETH_IS_TUNNEL_PKT(mbuf->packet_type)) {
+			PMD_TX_LOG(INFO, txq, "Tx tunnel packet\n");
+			/* First indicate its a tunnel pkt */
+			bd1->data.bd_flags.bitfields |=
+				ETH_TX_DATA_1ST_BD_TUNN_FLAG_MASK <<
+				ETH_TX_DATA_1ST_BD_TUNN_FLAG_SHIFT;
+
+			/* Legacy FW had flipped behavior in regard to this bit
+			 * i.e. it needed to set to prevent FW from touching
+			 * encapsulated packets when it didn't need to.
+			 */
+			if (unlikely(txq->is_legacy))
+				bd1->data.bitfields ^=
+					1 << ETH_TX_DATA_1ST_BD_TUNN_FLAG_SHIFT;
+
+			/* Outer IP checksum offload */
+			if (mbuf->ol_flags & PKT_TX_OUTER_IP_CKSUM) {
+				PMD_TX_LOG(INFO, txq, "OuterIP csum offload\n");
+				bd1->data.bd_flags.bitfields |=
+					ETH_TX_1ST_BD_FLAGS_TUNN_IP_CSUM_MASK <<
+					ETH_TX_1ST_BD_FLAGS_TUNN_IP_CSUM_SHIFT;
+			}
+
+			/* Outer UDP checksum offload */
+			bd1->data.bd_flags.bitfields |=
+				ETH_TX_1ST_BD_FLAGS_TUNN_L4_CSUM_MASK <<
+				ETH_TX_1ST_BD_FLAGS_TUNN_L4_CSUM_SHIFT;
+		}
+
 		/* Descriptor based VLAN insertion */
 		if (mbuf->ol_flags & (PKT_TX_VLAN_PKT | PKT_TX_QINQ_PKT)) {
+			PMD_TX_LOG(INFO, txq, "Insert VLAN 0x%x\n",
+				   mbuf->vlan_tci);
 			bd1->data.vlan = rte_cpu_to_le_16(mbuf->vlan_tci);
 			bd1->data.bd_flags.bitfields |=
 			    1 << ETH_TX_1ST_BD_FLAGS_VLAN_INSERTION_SHIFT;
@@ -1215,12 +1331,14 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 
 		/* Offload the IP checksum in the hardware */
 		if (mbuf->ol_flags & PKT_TX_IP_CKSUM) {
+			PMD_TX_LOG(INFO, txq, "IP csum offload\n");
 			bd1->data.bd_flags.bitfields |=
 			    1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT;
 		}
 
 		/* L4 checksum offload (tcp or udp) */
 		if (mbuf->ol_flags & (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
+			PMD_TX_LOG(INFO, txq, "L4 csum offload\n");
 			bd1->data.bd_flags.bitfields |=
 			    1 << ETH_TX_1ST_BD_FLAGS_L4_CSUM_SHIFT;
 			/* IPv6 + extn. -> later */
@@ -1278,6 +1396,8 @@ static void qede_init_fp_queue(struct rte_eth_dev *eth_dev)
 				fp->txqs[tc] =
 					eth_dev->data->tx_queues[txq_index];
 				fp->txqs[tc]->queue_id = txq_index;
+				if (qdev->dev_info.is_legacy)
+					fp->txqs[tc]->is_legacy = true;
 			}
 			txq++;
 		}
diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h
index 4a50afe..3e1e977 100644
--- a/drivers/net/qede/qede_rxtx.h
+++ b/drivers/net/qede/qede_rxtx.h
@@ -74,6 +74,51 @@
 
 #define for_each_queue(i) for (i = 0; i < qdev->num_queues; i++)
 
+
+/* Macros for non-tunnel packet types lkup table */
+#define QEDE_PKT_TYPE_UNKNOWN				0x0
+#define QEDE_PKT_TYPE_MAX				0xf
+#define QEDE_PKT_TYPE_IPV4				0x1
+#define QEDE_PKT_TYPE_IPV6				0x2
+#define QEDE_PKT_TYPE_IPV4_TCP				0x5
+#define QEDE_PKT_TYPE_IPV6_TCP				0x6
+#define QEDE_PKT_TYPE_IPV4_UDP				0x9
+#define QEDE_PKT_TYPE_IPV6_UDP				0xa
+
+/* Macros for tunneled packets with next protocol lkup table */
+#define QEDE_PKT_TYPE_TUNN_GENEVE			0x1
+#define QEDE_PKT_TYPE_TUNN_GRE				0x2
+#define QEDE_PKT_TYPE_TUNN_VXLAN			0x3
+
+/* Bit 2 is don't care bit */
+#define QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_GENEVE	0x9
+#define QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_GRE	0xa
+#define QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_VXLAN	0xb
+
+#define QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_GENEVE	0xd
+#define QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_GRE		0xe
+#define QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_VXLAN	0xf
+
+
+#define QEDE_PKT_TYPE_TUNN_IPV4_TENID_NOEXIST_GENEVE    0x11
+#define QEDE_PKT_TYPE_TUNN_IPV4_TENID_NOEXIST_GRE       0x12
+#define QEDE_PKT_TYPE_TUNN_IPV4_TENID_NOEXIST_VXLAN     0x13
+
+#define QEDE_PKT_TYPE_TUNN_IPV4_TENID_EXIST_GENEVE	0x15
+#define QEDE_PKT_TYPE_TUNN_IPV4_TENID_EXIST_GRE	0x16
+#define QEDE_PKT_TYPE_TUNN_IPV4_TENID_EXIST_VXLAN	0x17
+
+
+#define QEDE_PKT_TYPE_TUNN_IPV6_TENID_NOEXIST_GENEVE    0x19
+#define QEDE_PKT_TYPE_TUNN_IPV6_TENID_NOEXIST_GRE       0x1a
+#define QEDE_PKT_TYPE_TUNN_IPV6_TENID_NOEXIST_VXLAN     0x1b
+
+#define QEDE_PKT_TYPE_TUNN_IPV6_TENID_EXIST_GENEVE      0x1d
+#define QEDE_PKT_TYPE_TUNN_IPV6_TENID_EXIST_GRE		0x1e
+#define QEDE_PKT_TYPE_TUNN_IPV6_TENID_EXIST_VXLAN       0x1f
+
+#define QEDE_PKT_TYPE_TUNN_MAX_TYPE			0x20 /* 2^5 */
+
 /*
  * RX BD descriptor ring
  */
@@ -133,6 +178,7 @@ struct qede_tx_queue {
 	volatile union db_prod tx_db;
 	uint16_t port_id;
 	uint64_t xmit_pkts;
+	bool is_legacy;
 	struct qede_dev *qdev;
 };
 
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 1/7] net/qede: reduce noise in debug logs
From: Harish Patil @ 2016-12-23  0:48 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Harish Patil, dev, Dept-EngDPDKDev
In-Reply-To: <91ac9846-530c-2dd3-4bd6-2c3b9143405b@intel.com>

Move DP_NOTICE msg under CONFIG_RTE_LIBRTE_QEDE_DEBUG_INFO.

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_logs.h |   13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/qede/qede_logs.h b/drivers/net/qede/qede_logs.h
index 45c4af0..13b76a7 100644
--- a/drivers/net/qede/qede_logs.h
+++ b/drivers/net/qede/qede_logs.h
@@ -16,15 +16,18 @@
 		(p_dev)->name ? (p_dev)->name : "", \
 		##__VA_ARGS__)
 
+#ifdef RTE_LIBRTE_QEDE_DEBUG_INFO
 #define DP_NOTICE(p_dev, is_assert, fmt, ...) \
 	rte_log(RTE_LOG_NOTICE, RTE_LOGTYPE_PMD,\
 		"[QEDE PMD: (%s)]%s:" fmt, \
 		(p_dev)->name ? (p_dev)->name : "", \
 		 __func__, \
 		##__VA_ARGS__)
+#else
+#define DP_NOTICE(p_dev, fmt, ...) do { } while (0)
+#endif
 
 #ifdef RTE_LIBRTE_QEDE_DEBUG_INFO
-
 #define DP_INFO(p_dev, fmt, ...) \
 	rte_log(RTE_LOG_INFO, RTE_LOGTYPE_PMD, \
 		"[%s:%d(%s)]" fmt, \
@@ -33,7 +36,6 @@
 		##__VA_ARGS__)
 #else
 #define DP_INFO(p_dev, fmt, ...) do { } while (0)
-
 #endif
 
 #ifdef RTE_LIBRTE_QEDE_DEBUG_DRIVER
@@ -77,13 +79,6 @@ do { \
 #define PMD_RX_LOG(level, q, fmt, args...) do { } while (0)
 #endif
 
-#ifdef RTE_LIBRTE_QEDE_DEBUG_DRIVER
-#define PMD_DRV_LOG_RAW(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt, __func__, ## args)
-#else
-#define PMD_DRV_LOG_RAW(level, fmt, args...) do { } while (0)
-#endif
-
 #define PMD_DRV_LOG(level, fmt, args...) \
 	PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
 
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 3/7] net/qede: add slowpath support for VXLAN tunneling
From: Harish Patil @ 2016-12-23  0:48 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Harish Patil, dev, Dept-EngDPDKDev
In-Reply-To: <91ac9846-530c-2dd3-4bd6-2c3b9143405b@intel.com>

- Enable/disable VXLAN tunneling
- Add/remove VXLAN classification rules
- Destination UDP port configuration

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/base/ecore_l2.c     |    3 +
 drivers/net/qede/base/ecore_l2_api.h |    1 +
 drivers/net/qede/qede_ethdev.c       |  400 +++++++++++++++++++++++++++++++++-
 drivers/net/qede/qede_ethdev.h       |    7 +
 drivers/net/qede/qede_main.c         |   14 --
 drivers/net/qede/qede_rxtx.h         |    2 +-
 6 files changed, 411 insertions(+), 16 deletions(-)

diff --git a/drivers/net/qede/base/ecore_l2.c b/drivers/net/qede/base/ecore_l2.c
index 74f61b0..a893cb9 100644
--- a/drivers/net/qede/base/ecore_l2.c
+++ b/drivers/net/qede/base/ecore_l2.c
@@ -1093,6 +1093,9 @@ ecore_filter_ucast_common(struct ecore_hwfn *p_hwfn,
 	case ECORE_FILTER_VNI:
 		p_first_filter->type = ETH_FILTER_TYPE_VNI;
 		break;
+	case ECORE_FILTER_UNUSED: /* @DPDK */
+		p_first_filter->type = MAX_ETH_FILTER_TYPE;
+		break;
 	}
 
 	if ((p_first_filter->type == ETH_FILTER_TYPE_MAC) ||
diff --git a/drivers/net/qede/base/ecore_l2_api.h b/drivers/net/qede/base/ecore_l2_api.h
index 326fa45..c338f5d 100644
--- a/drivers/net/qede/base/ecore_l2_api.h
+++ b/drivers/net/qede/base/ecore_l2_api.h
@@ -89,6 +89,7 @@ enum ecore_filter_ucast_type {
 	ECORE_FILTER_INNER_MAC_VNI_PAIR,
 	ECORE_FILTER_MAC_VNI_PAIR,
 	ECORE_FILTER_VNI,
+	ECORE_FILTER_UNUSED, /* @DPDK */
 };
 
 struct ecore_filter_ucast {
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 73f1824..7a95560 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -14,6 +14,111 @@
 static const struct qed_eth_ops *qed_ops;
 static int64_t timer_period = 1;
 
+/* VXLAN tunnel classification mapping */
+const struct _qede_vxlan_tunn_types {
+	uint16_t rte_filter_type;
+	enum ecore_filter_ucast_type qede_type;
+	enum ecore_tunn_clss qede_tunn_clss;
+	const char *string;
+} qede_tunn_types[] = {
+	{
+		ETH_TUNNEL_FILTER_OMAC,
+		ECORE_FILTER_MAC,
+		ECORE_TUNN_CLSS_MAC_VLAN,
+		"outer-mac"
+	},
+	{
+		ETH_TUNNEL_FILTER_TENID,
+		ECORE_FILTER_VNI,
+		ECORE_TUNN_CLSS_MAC_VNI,
+		"vni"
+	},
+	{
+		ETH_TUNNEL_FILTER_IMAC,
+		ECORE_FILTER_INNER_MAC,
+		ECORE_TUNN_CLSS_INNER_MAC_VLAN,
+		"inner-mac"
+	},
+	{
+		ETH_TUNNEL_FILTER_IVLAN,
+		ECORE_FILTER_INNER_VLAN,
+		ECORE_TUNN_CLSS_INNER_MAC_VLAN,
+		"inner-vlan"
+	},
+	{
+		ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_TENID,
+		ECORE_FILTER_MAC_VNI_PAIR,
+		ECORE_TUNN_CLSS_MAC_VNI,
+		"outer-mac and vni"
+	},
+	{
+		ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_IMAC,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"outer-mac and inner-mac"
+	},
+	{
+		ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_IVLAN,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"outer-mac and inner-vlan"
+	},
+	{
+		ETH_TUNNEL_FILTER_TENID | ETH_TUNNEL_FILTER_IMAC,
+		ECORE_FILTER_INNER_MAC_VNI_PAIR,
+		ECORE_TUNN_CLSS_INNER_MAC_VNI,
+		"vni and inner-mac",
+	},
+	{
+		ETH_TUNNEL_FILTER_TENID | ETH_TUNNEL_FILTER_IVLAN,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"vni and inner-vlan",
+	},
+	{
+		ETH_TUNNEL_FILTER_IMAC | ETH_TUNNEL_FILTER_IVLAN,
+		ECORE_FILTER_INNER_PAIR,
+		ECORE_TUNN_CLSS_INNER_MAC_VLAN,
+		"inner-mac and inner-vlan",
+	},
+	{
+		ETH_TUNNEL_FILTER_OIP,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"outer-IP"
+	},
+	{
+		ETH_TUNNEL_FILTER_IIP,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"inner-IP"
+	},
+	{
+		RTE_TUNNEL_FILTER_IMAC_IVLAN,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"IMAC_IVLAN"
+	},
+	{
+		RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"IMAC_IVLAN_TENID"
+	},
+	{
+		RTE_TUNNEL_FILTER_IMAC_TENID,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"IMAC_TENID"
+	},
+	{
+		RTE_TUNNEL_FILTER_OMAC_TENID_IMAC,
+		ECORE_FILTER_UNUSED,
+		MAX_ECORE_TUNN_CLSS,
+		"OMAC_TENID_IMAC"
+	},
+};
+
 struct rte_qede_xstats_name_off {
 	char name[RTE_ETH_XSTATS_NAME_SIZE];
 	uint64_t offset;
@@ -230,6 +335,17 @@ static void qede_set_ucast_cmn_params(struct ecore_filter_ucast *ucast)
 	/* ucast->assert_on_error = true; - For debug */
 }
 
+static void qede_set_cmn_tunn_param(struct ecore_tunn_update_params *params,
+				     uint8_t clss, uint64_t mode, uint64_t mask)
+{
+	memset(params, 0, sizeof(struct ecore_tunn_update_params));
+	params->tunn_mode = mode;
+	params->tunn_mode_update_mask = mask;
+	params->update_tx_pf_clss = 1;
+	params->update_rx_pf_clss = 1;
+	params->tunn_clss_vxlan = clss;
+}
+
 static int
 qede_ucast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
 		  bool add)
@@ -260,13 +376,15 @@ qede_ucast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
 		}
 		ether_addr_copy(mac_addr, &u->mac);
 		u->vlan = ucast->vlan;
+		u->vni = ucast->vni;
 		SLIST_INSERT_HEAD(&qdev->uc_list_head, u, list);
 		qdev->num_uc_addr++;
 	} else {
 		SLIST_FOREACH(tmp, &qdev->uc_list_head, list) {
 			if ((memcmp(mac_addr, &tmp->mac,
 				    ETHER_ADDR_LEN) == 0) &&
-			    ucast->vlan == tmp->vlan)
+			    ucast->vlan == tmp->vlan	  &&
+			    ucast->vni == tmp->vni)
 			break;
 		}
 		if (tmp == NULL) {
@@ -1420,6 +1538,283 @@ int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+static int
+qede_conf_udp_dst_port(struct rte_eth_dev *eth_dev,
+		       struct rte_eth_udp_tunnel *tunnel_udp,
+		       bool add)
+{
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ecore_tunn_update_params params;
+	struct ecore_hwfn *p_hwfn;
+	int rc, i;
+
+	PMD_INIT_FUNC_TRACE(edev);
+
+	memset(&params, 0, sizeof(params));
+	if (tunnel_udp->prot_type == RTE_TUNNEL_TYPE_VXLAN) {
+		params.update_vxlan_udp_port = 1;
+		params.vxlan_udp_port = (add) ? tunnel_udp->udp_port :
+					QEDE_VXLAN_DEF_PORT;
+		for_each_hwfn(edev, i) {
+			p_hwfn = &edev->hwfns[i];
+			rc = ecore_sp_pf_update_tunn_cfg(p_hwfn, &params,
+						ECORE_SPQ_MODE_CB, NULL);
+			if (rc != ECORE_SUCCESS) {
+				DP_ERR(edev, "Unable to config UDP port %u\n",
+					params.vxlan_udp_port);
+				return rc;
+			}
+		}
+	}
+
+	return 0;
+}
+
+int
+qede_udp_dst_port_del(struct rte_eth_dev *eth_dev,
+		      struct rte_eth_udp_tunnel *tunnel_udp)
+{
+	return qede_conf_udp_dst_port(eth_dev, tunnel_udp, false);
+}
+
+int
+qede_udp_dst_port_add(struct rte_eth_dev *eth_dev,
+		      struct rte_eth_udp_tunnel *tunnel_udp)
+{
+	return qede_conf_udp_dst_port(eth_dev, tunnel_udp, true);
+}
+
+static void qede_get_ecore_tunn_params(uint32_t filter, uint32_t *type,
+				       uint32_t *clss, char *str)
+{
+	uint16_t j;
+	*clss = MAX_ECORE_TUNN_CLSS;
+
+	for (j = 0; j < RTE_DIM(qede_tunn_types); j++) {
+		if (filter == qede_tunn_types[j].rte_filter_type) {
+			*type = qede_tunn_types[j].qede_type;
+			*clss = qede_tunn_types[j].qede_tunn_clss;
+			strcpy(str, qede_tunn_types[j].string);
+			return;
+		}
+	}
+}
+
+static int
+qede_set_ucast_tunn_cmn_param(struct ecore_filter_ucast *ucast,
+			      const struct rte_eth_tunnel_filter_conf *conf,
+			      uint32_t type)
+{
+	/* Init commmon ucast params first */
+	qede_set_ucast_cmn_params(ucast);
+
+	/* Copy out the required fields based on classification type */
+	ucast->type = type;
+
+	switch (type) {
+	case ECORE_FILTER_VNI:
+		ucast->vni = conf->tenant_id;
+	break;
+	case ECORE_FILTER_INNER_VLAN:
+		ucast->vlan = conf->inner_vlan;
+	break;
+	case ECORE_FILTER_MAC:
+		memcpy(ucast->mac, conf->outer_mac.addr_bytes,
+		       ETHER_ADDR_LEN);
+	break;
+	case ECORE_FILTER_INNER_MAC:
+		memcpy(ucast->mac, conf->inner_mac.addr_bytes,
+		       ETHER_ADDR_LEN);
+	break;
+	case ECORE_FILTER_MAC_VNI_PAIR:
+		memcpy(ucast->mac, conf->outer_mac.addr_bytes,
+			ETHER_ADDR_LEN);
+		ucast->vni = conf->tenant_id;
+	break;
+	case ECORE_FILTER_INNER_MAC_VNI_PAIR:
+		memcpy(ucast->mac, conf->inner_mac.addr_bytes,
+			ETHER_ADDR_LEN);
+		ucast->vni = conf->tenant_id;
+	break;
+	case ECORE_FILTER_INNER_PAIR:
+		memcpy(ucast->mac, conf->inner_mac.addr_bytes,
+			ETHER_ADDR_LEN);
+		ucast->vlan = conf->inner_vlan;
+	break;
+	default:
+		return -EINVAL;
+	}
+
+	return ECORE_SUCCESS;
+}
+
+static int qede_vxlan_tunn_config(struct rte_eth_dev *eth_dev,
+				  enum rte_filter_op filter_op,
+				  const struct rte_eth_tunnel_filter_conf *conf)
+{
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ecore_tunn_update_params params;
+	struct ecore_hwfn *p_hwfn;
+	enum ecore_filter_ucast_type type;
+	enum ecore_tunn_clss clss;
+	struct ecore_filter_ucast ucast;
+	char str[80];
+	uint16_t filter_type;
+	int rc, i;
+
+	filter_type = conf->filter_type | qdev->vxlan_filter_type;
+	/* First determine if the given filter classification is supported */
+	qede_get_ecore_tunn_params(filter_type, &type, &clss, str);
+	if (clss == MAX_ECORE_TUNN_CLSS) {
+		DP_ERR(edev, "Wrong filter type\n");
+		return -EINVAL;
+	}
+	/* Init tunnel ucast params */
+	rc = qede_set_ucast_tunn_cmn_param(&ucast, conf, type);
+	if (rc != ECORE_SUCCESS) {
+		DP_ERR(edev, "Unsupported VxLAN filter type 0x%x\n",
+				conf->filter_type);
+		return rc;
+	}
+	DP_INFO(edev, "Rule: \"%s\", op %d, type 0x%x\n",
+		str, filter_op, ucast.type);
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ucast.opcode = ECORE_FILTER_ADD;
+
+		/* Skip MAC/VLAN if filter is based on VNI */
+		if (!(filter_type & ETH_TUNNEL_FILTER_TENID)) {
+			rc = qede_mac_int_ops(eth_dev, &ucast, 1);
+			if (rc == 0) {
+				/* Enable accept anyvlan */
+				qede_config_accept_any_vlan(qdev, true);
+			}
+		} else {
+			rc = qede_ucast_filter(eth_dev, &ucast, 1);
+			if (rc == 0)
+				rc = ecore_filter_ucast_cmd(edev, &ucast,
+						    ECORE_SPQ_MODE_CB, NULL);
+		}
+
+		if (rc != ECORE_SUCCESS)
+			return rc;
+
+		qdev->vxlan_filter_type = filter_type;
+
+		DP_INFO(edev, "Enabling VXLAN tunneling\n");
+		qede_set_cmn_tunn_param(&params, clss,
+					(1 << ECORE_MODE_VXLAN_TUNN),
+					(1 << ECORE_MODE_VXLAN_TUNN));
+		for_each_hwfn(edev, i) {
+			p_hwfn = &edev->hwfns[i];
+			rc = ecore_sp_pf_update_tunn_cfg(p_hwfn,
+				&params, ECORE_SPQ_MODE_CB, NULL);
+			if (rc != ECORE_SUCCESS) {
+				DP_ERR(edev, "Failed to update tunn_clss %u\n",
+					params.tunn_clss_vxlan);
+			}
+		}
+		qdev->num_tunn_filters++; /* Filter added successfully */
+	break;
+	case RTE_ETH_FILTER_DELETE:
+		ucast.opcode = ECORE_FILTER_REMOVE;
+
+		if (!(filter_type & ETH_TUNNEL_FILTER_TENID)) {
+			rc = qede_mac_int_ops(eth_dev, &ucast, 0);
+		} else {
+			rc = qede_ucast_filter(eth_dev, &ucast, 0);
+			if (rc == 0)
+				rc = ecore_filter_ucast_cmd(edev, &ucast,
+						    ECORE_SPQ_MODE_CB, NULL);
+		}
+		if (rc != ECORE_SUCCESS)
+			return rc;
+
+		qdev->vxlan_filter_type = filter_type;
+		qdev->num_tunn_filters--;
+
+		/* Disable VXLAN if VXLAN filters become 0 */
+		if (qdev->num_tunn_filters == 0) {
+			DP_INFO(edev, "Disabling VXLAN tunneling\n");
+
+			/* Use 0 as tunnel mode */
+			qede_set_cmn_tunn_param(&params, clss, 0,
+						(1 << ECORE_MODE_VXLAN_TUNN));
+			for_each_hwfn(edev, i) {
+				p_hwfn = &edev->hwfns[i];
+				rc = ecore_sp_pf_update_tunn_cfg(p_hwfn,
+					&params, ECORE_SPQ_MODE_CB, NULL);
+				if (rc != ECORE_SUCCESS) {
+					DP_ERR(edev,
+						"Failed to update tunn_clss %u\n",
+						params.tunn_clss_vxlan);
+					break;
+				}
+			}
+		}
+	break;
+	default:
+		DP_ERR(edev, "Unsupported operation %d\n", filter_op);
+		return -EINVAL;
+	}
+	DP_INFO(edev, "Current VXLAN filters %d\n", qdev->num_tunn_filters);
+
+	return 0;
+}
+
+int qede_dev_filter_ctrl(struct rte_eth_dev *eth_dev,
+			 enum rte_filter_type filter_type,
+			 enum rte_filter_op filter_op,
+			 void *arg)
+{
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct rte_eth_tunnel_filter_conf *filter_conf =
+			(struct rte_eth_tunnel_filter_conf *)arg;
+
+	switch (filter_type) {
+	case RTE_ETH_FILTER_TUNNEL:
+		switch (filter_conf->tunnel_type) {
+		case RTE_TUNNEL_TYPE_VXLAN:
+			DP_INFO(edev,
+				"Packet steering to the specified Rx queue"
+				" is not supported with VXLAN tunneling");
+			return(qede_vxlan_tunn_config(eth_dev, filter_op,
+						      filter_conf));
+		/* Place holders for future tunneling support */
+		case RTE_TUNNEL_TYPE_GENEVE:
+		case RTE_TUNNEL_TYPE_TEREDO:
+		case RTE_TUNNEL_TYPE_NVGRE:
+		case RTE_TUNNEL_TYPE_IP_IN_GRE:
+		case RTE_L2_TUNNEL_TYPE_E_TAG:
+			DP_ERR(edev, "Unsupported tunnel type %d\n",
+				filter_conf->tunnel_type);
+			return -EINVAL;
+		case RTE_TUNNEL_TYPE_NONE:
+		default:
+			return 0;
+		}
+		break;
+	case RTE_ETH_FILTER_FDIR:
+	case RTE_ETH_FILTER_MACVLAN:
+	case RTE_ETH_FILTER_ETHERTYPE:
+	case RTE_ETH_FILTER_FLEXIBLE:
+	case RTE_ETH_FILTER_SYN:
+	case RTE_ETH_FILTER_NTUPLE:
+	case RTE_ETH_FILTER_HASH:
+	case RTE_ETH_FILTER_L2_TUNNEL:
+	case RTE_ETH_FILTER_MAX:
+	default:
+		DP_ERR(edev, "Unsupported filter type %d\n",
+			filter_type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static const struct eth_dev_ops qede_eth_dev_ops = {
 	.dev_configure = qede_dev_configure,
 	.dev_infos_get = qede_dev_info_get,
@@ -1455,6 +1850,9 @@ static const struct eth_dev_ops qede_eth_dev_ops = {
 	.reta_update  = qede_rss_reta_update,
 	.reta_query  = qede_rss_reta_query,
 	.mtu_set = qede_set_mtu,
+	.filter_ctrl = qede_dev_filter_ctrl,
+	.udp_tunnel_port_add = qede_udp_dst_port_add,
+	.udp_tunnel_port_del = qede_udp_dst_port_del,
 };
 
 static const struct eth_dev_ops qede_eth_vf_dev_ops = {
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index a35ea8b..6d0616e 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -31,6 +31,8 @@
 #include "base/ecore_iov_api.h"
 #include "base/ecore_cxt.h"
 #include "base/nvm_cfg.h"
+#include "base/ecore_iov_api.h"
+#include "base/ecore_sp_commands.h"
 
 #include "qede_logs.h"
 #include "qede_if.h"
@@ -108,6 +110,8 @@
 #define PCI_DEVICE_ID_57980S_IOV        CHIP_NUM_57980S_IOV
 #define PCI_DEVICE_ID_57980S_100        CHIP_NUM_57980S_100
 
+#define QEDE_VXLAN_DEF_PORT		8472
+
 extern char fw_file[];
 
 /* Port/function states */
@@ -131,6 +135,7 @@ struct qede_mcast_entry {
 struct qede_ucast_entry {
 	struct ether_addr mac;
 	uint16_t vlan;
+	uint16_t vni;
 	SLIST_ENTRY(qede_ucast_entry) list;
 };
 
@@ -163,6 +168,8 @@ struct qede_dev {
 	SLIST_HEAD(uc_list_head, qede_ucast_entry) uc_list_head;
 	uint16_t num_uc_addr;
 	bool handle_hw_err;
+	uint16_t num_tunn_filters;
+	uint16_t vxlan_filter_type;
 	char drv_ver[QEDE_PMD_DRV_VER_STR_SIZE];
 };
 
diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
index b666e1c..efc99ee 100644
--- a/drivers/net/qede/qede_main.c
+++ b/drivers/net/qede/qede_main.c
@@ -228,9 +228,6 @@ static int qed_slowpath_start(struct ecore_dev *edev,
 	struct ecore_hw_init_params hw_init_params;
 	struct qede_dev *qdev = (struct qede_dev *)edev;
 	int rc;
-#ifdef QED_ENC_SUPPORTED
-	struct ecore_tunn_start_params tunn_info;
-#endif
 
 #ifdef CONFIG_ECORE_BINARY_FW
 	if (IS_PF(edev)) {
@@ -273,17 +270,6 @@ static int qed_slowpath_start(struct ecore_dev *edev,
 
 	/* Start the slowpath */
 	memset(&hw_init_params, 0, sizeof(hw_init_params));
-#ifdef QED_ENC_SUPPORTED
-	memset(&tunn_info, 0, sizeof(tunn_info));
-	tunn_info.tunn_mode |= 1 << QED_MODE_VXLAN_TUNN |
-	    1 << QED_MODE_L2GRE_TUNN |
-	    1 << QED_MODE_IPGRE_TUNN |
-	    1 << QED_MODE_L2GENEVE_TUNN | 1 << QED_MODE_IPGENEVE_TUNN;
-	tunn_info.tunn_clss_vxlan = QED_TUNN_CLSS_MAC_VLAN;
-	tunn_info.tunn_clss_l2gre = QED_TUNN_CLSS_MAC_VLAN;
-	tunn_info.tunn_clss_ipgre = QED_TUNN_CLSS_MAC_VLAN;
-	hw_init_params.p_tunn = &tunn_info;
-#endif
 	hw_init_params.b_hw_start = true;
 	hw_init_params.int_mode = ECORE_INT_MODE_MSIX;
 	hw_init_params.allow_npar_tx_switch = allow_npar_tx_switching;
diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h
index ed9a529..4a50afe 100644
--- a/drivers/net/qede/qede_rxtx.h
+++ b/drivers/net/qede/qede_rxtx.h
@@ -66,7 +66,7 @@
 
 /* TBD: Excluding IPV6 */
 #define QEDE_RSS_OFFLOAD_ALL    (ETH_RSS_IPV4 | ETH_RSS_NONFRAG_IPV4_TCP | \
-				 ETH_RSS_NONFRAG_IPV4_UDP)
+				 ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_VXLAN)
 
 #define QEDE_TXQ_FLAGS		((uint32_t)ETH_TXQ_FLAGS_NOMULTSEGS)
 
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 7/7] net/qede: restrict maximum queues for PF/VF
From: Harish Patil @ 2016-12-23  0:48 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Harish Patil, dev, stable, Dept-EngDPDKDev
In-Reply-To: <91ac9846-530c-2dd3-4bd6-2c3b9143405b@intel.com>

HW can support upto 128 queues based on the NIC config/personality.
But most of the testing is done with 32 queues for PF and 16 for VF
device across different qede devices, so change here is to advertise
only those many instead of returning max queues supported by HW.

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_ethdev.c |   13 ++++++++++---
 drivers/net/qede/qede_ethdev.h |    3 +++
 drivers/net/qede/qede_main.c   |    5 -----
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 93817ac..d748d54 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -973,8 +973,15 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
 	dev_info->max_rx_pktlen = (uint32_t)ETH_TX_MAX_NON_LSO_PKT_LEN;
 	dev_info->rx_desc_lim = qede_rx_desc_lim;
 	dev_info->tx_desc_lim = qede_tx_desc_lim;
-	dev_info->max_rx_queues = (uint16_t)QEDE_MAX_RSS_CNT(qdev);
+
+	if (IS_PF(edev))
+		dev_info->max_rx_queues = (uint16_t)RTE_MIN(
+			QEDE_MAX_RSS_CNT(qdev), QEDE_PF_NUM_CONNS / 2);
+	else
+		dev_info->max_rx_queues = (uint16_t)RTE_MIN(
+			QEDE_MAX_RSS_CNT(qdev), ECORE_MAX_VF_CHAINS_PER_PF);
 	dev_info->max_tx_queues = dev_info->max_rx_queues;
+
 	dev_info->max_mac_addrs = qdev->dev_info.num_mac_addrs;
 	dev_info->max_vfs = 0;
 	dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE;
@@ -2016,9 +2023,9 @@ static const struct eth_dev_ops qede_eth_vf_dev_ops = {
 static void qede_update_pf_params(struct ecore_dev *edev)
 {
 	struct ecore_pf_params pf_params;
-	/* 32 rx + 32 tx */
+
 	memset(&pf_params, 0, sizeof(struct ecore_pf_params));
-	pf_params.eth_pf_params.num_cons = 64;
+	pf_params.eth_pf_params.num_cons = QEDE_PF_NUM_CONNS;
 	qed_ops->common->update_pf_params(edev, &pf_params);
 }
 
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index bd85ba3..95e06ef 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -115,6 +115,9 @@
 
 extern char fw_file[];
 
+/* Number of PF connections - 32 RX + 32 TX */
+#define QEDE_PF_NUM_CONNS		(64)
+
 /* Port/function states */
 enum qede_dev_state {
 	QEDE_DEV_INIT, /* Init the chip and Slowpath */
diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
index b769673..491c921 100644
--- a/drivers/net/qede/qede_main.c
+++ b/drivers/net/qede/qede_main.c
@@ -402,11 +402,6 @@ qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
 		if (edev->num_hwfns > 1) {
 			ecore_vf_get_num_rxqs(&edev->hwfns[1], &queues);
 			info->num_queues += queues;
-			/* Restrict 100G VF to advertise 16 queues till the
-			 * required support is available to go beyond 16.
-			 */
-			info->num_queues = RTE_MIN(info->num_queues,
-						   ECORE_MAX_VF_CHAINS_PER_PF);
 		}
 
 		ecore_vf_get_num_vlan_filters(&edev->hwfns[0],
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 6/7] net/qede: fix reporting of SR-IOV PF driver as disabled
From: Harish Patil @ 2016-12-23  0:48 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Harish Patil, dev, stable, Dept-EngDPDKDev
In-Reply-To: <91ac9846-530c-2dd3-4bd6-2c3b9143405b@intel.com>

qede PMD does not support SR-IOV PF driver functionality, so
max_vfs is set to 0 to imply the same.

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_ethdev.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 00af0f6..93817ac 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -976,10 +976,7 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
 	dev_info->max_rx_queues = (uint16_t)QEDE_MAX_RSS_CNT(qdev);
 	dev_info->max_tx_queues = dev_info->max_rx_queues;
 	dev_info->max_mac_addrs = qdev->dev_info.num_mac_addrs;
-	if (IS_VF(edev))
-		dev_info->max_vfs = 0;
-	else
-		dev_info->max_vfs = (uint16_t)NUM_OF_VFS(&qdev->edev);
+	dev_info->max_vfs = 0;
 	dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE;
 	dev_info->hash_key_size = ECORE_RSS_KEY_SIZE * sizeof(uint32_t);
 	dev_info->flow_type_rss_offloads = (uint64_t)QEDE_RSS_OFFLOAD_ALL;
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 5/7] net/qede: fix RSS related issue
From: Harish Patil @ 2016-12-23  0:48 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Harish Patil, dev, stable, Dept-EngDPDKDev
In-Reply-To: <91ac9846-530c-2dd3-4bd6-2c3b9143405b@intel.com>

This patch includes the following:

- Fix missing hash_key_size advertisement
- Fix RSS hash query function
- Update RSS offload flag
- Accept user provided RSS configuration params via rx_adv_conf
  in dev_configure()
- Decouple RSS configuration from common qed_update_vport() and
  instead make use of existing RSS APIs for default RSS configuration

Fixes: 6d9e26c42c0d ("net/qede: get RSS hash configuration")
Fixes: 9c5d0a669f9b ("net/qede: fix RSS")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_eth_if.c |   79 +++++--------
 drivers/net/qede/qede_eth_if.h |    9 +-
 drivers/net/qede/qede_ethdev.c |  255 ++++++++++++++++++++++++++++++----------
 drivers/net/qede/qede_ethdev.h |    9 +-
 drivers/net/qede/qede_rxtx.c   |   90 +-------------
 drivers/net/qede/qede_rxtx.h   |   10 +-
 6 files changed, 240 insertions(+), 212 deletions(-)

diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index 30fded0..7d21200 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -68,6 +68,33 @@ static int qed_stop_vport(struct ecore_dev *edev, uint8_t vport_id)
 	return 0;
 }
 
+bool qed_update_rss_parm_cmt(struct ecore_dev *edev, uint16_t *p_tbl)
+{
+	uint16_t max = 0, k;
+	bool rss_mode = 0; /* disable */
+	int divisor;
+
+	/* Find largest entry, since it's possible RSS needs to
+	 * be disabled [in case only 1 queue per-hwfn]
+	 */
+	for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++)
+		max = (max > p_tbl[k]) ?  max : p_tbl[k];
+
+	/* Either fix RSS values or disable RSS */
+	if (edev->num_hwfns < max + 1) {
+		divisor = (max + edev->num_hwfns - 1) / edev->num_hwfns;
+		DP_VERBOSE(edev, ECORE_MSG_SPQ,
+			   "CMT - fixing RSS values (modulo %02x)\n",
+			   divisor);
+		for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++)
+			p_tbl[k] = p_tbl[k] % divisor;
+
+		rss_mode = 1;
+	}
+
+	return rss_mode;
+}
+
 static int
 qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params)
 {
@@ -94,58 +121,6 @@ qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params)
 	    params->update_accept_any_vlan_flg;
 	sp_params.mtu = params->mtu;
 
-	/* RSS - is a bit tricky, since upper-layer isn't familiar with hwfns.
-	 * We need to re-fix the rss values per engine for CMT.
-	 */
-
-	if (edev->num_hwfns > 1 && params->update_rss_flg) {
-		struct qed_update_vport_rss_params *rss = &params->rss_params;
-		int k, max = 0;
-
-		/* Find largest entry, since it's possible RSS needs to
-		 * be disabled [in case only 1 queue per-hwfn]
-		 */
-		for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++)
-			max = (max > rss->rss_ind_table[k]) ?
-			    max : rss->rss_ind_table[k];
-
-		/* Either fix RSS values or disable RSS */
-		if (edev->num_hwfns < max + 1) {
-			int divisor = (max + edev->num_hwfns - 1) /
-			    edev->num_hwfns;
-
-			DP_VERBOSE(edev, ECORE_MSG_SPQ,
-				   "CMT - fixing RSS values (modulo %02x)\n",
-				   divisor);
-
-			for (k = 0; k < ECORE_RSS_IND_TABLE_SIZE; k++)
-				rss->rss_ind_table[k] =
-				    rss->rss_ind_table[k] % divisor;
-		} else {
-			DP_VERBOSE(edev, ECORE_MSG_SPQ,
-				   "CMT - 1 queue per-hwfn; Disabling RSS\n");
-			params->update_rss_flg = 0;
-		}
-	}
-
-	/* Now, update the RSS configuration for actual configuration */
-	if (params->update_rss_flg) {
-		sp_rss_params.update_rss_config = 1;
-		sp_rss_params.rss_enable = 1;
-		sp_rss_params.update_rss_capabilities = 1;
-		sp_rss_params.update_rss_ind_table = 1;
-		sp_rss_params.update_rss_key = 1;
-		sp_rss_params.rss_caps = ECORE_RSS_IPV4 | ECORE_RSS_IPV6 |
-		    ECORE_RSS_IPV4_TCP | ECORE_RSS_IPV6_TCP;
-		sp_rss_params.rss_table_size_log = 7;	/* 2^7 = 128 */
-		rte_memcpy(sp_rss_params.rss_ind_table,
-		       params->rss_params.rss_ind_table,
-		       ECORE_RSS_IND_TABLE_SIZE * sizeof(uint16_t));
-		rte_memcpy(sp_rss_params.rss_key, params->rss_params.rss_key,
-		       ECORE_RSS_KEY_SIZE * sizeof(uint32_t));
-		sp_params.rss_params = &sp_rss_params;
-	}
-
 	for_each_hwfn(edev, i) {
 		struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
 
diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h
index d67b312..f0c489c 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -47,12 +47,6 @@ struct qed_dev_eth_info {
 	bool is_legacy;
 };
 
-struct qed_update_vport_rss_params {
-	uint16_t rss_ind_table[128];
-	uint32_t rss_key[10];
-	u8 rss_caps;
-};
-
 struct qed_stop_rxq_params {
 	uint8_t rss_id;
 	uint8_t rx_queue_id;
@@ -71,7 +65,6 @@ struct qed_update_vport_params {
 	uint8_t update_accept_any_vlan_flg;
 	uint8_t accept_any_vlan;
 	uint8_t update_rss_flg;
-	struct qed_update_vport_rss_params rss_params;
 	uint16_t mtu;
 };
 
@@ -145,4 +138,6 @@ const struct qed_eth_ops *qed_get_eth_ops();
 int qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev,
 				 enum qed_filter_rx_mode_type type);
 
+bool qed_update_rss_parm_cmt(struct ecore_dev *edev, uint16_t *p_tbl);
+
 #endif /* _QEDE_ETH_IF_H */
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index ec48306..00af0f6 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -788,6 +788,54 @@ static int qede_init_vport(struct qede_dev *qdev)
 	return 0;
 }
 
+static void qede_prandom_bytes(uint32_t *buff)
+{
+	uint8_t i;
+
+	srand((unsigned int)time(NULL));
+	for (i = 0; i < ECORE_RSS_KEY_SIZE; i++)
+		buff[i] = rand();
+}
+
+static int qede_config_rss(struct rte_eth_dev *eth_dev)
+{
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	uint32_t def_rss_key[ECORE_RSS_KEY_SIZE];
+	struct rte_eth_rss_reta_entry64 reta_conf[2];
+	struct rte_eth_rss_conf rss_conf;
+	uint32_t i, id, pos, q;
+
+	rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
+	if (!rss_conf.rss_key) {
+		DP_INFO(edev, "Applying driver default key\n");
+		rss_conf.rss_key_len = ECORE_RSS_KEY_SIZE * sizeof(uint32_t);
+		qede_prandom_bytes(&def_rss_key[0]);
+		rss_conf.rss_key = (uint8_t *)&def_rss_key[0];
+	}
+
+	/* Configure RSS hash */
+	if (qede_rss_hash_update(eth_dev, &rss_conf))
+		return -EINVAL;
+
+	/* Configure default RETA */
+	memset(reta_conf, 0, sizeof(reta_conf));
+	for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++)
+		reta_conf[i / RTE_RETA_GROUP_SIZE].mask = UINT64_MAX;
+
+	for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) {
+		id = i / RTE_RETA_GROUP_SIZE;
+		pos = i % RTE_RETA_GROUP_SIZE;
+		q = i % QEDE_RSS_COUNT(qdev);
+		reta_conf[id].reta[pos] = q;
+	}
+	if (qede_rss_reta_update(eth_dev, &reta_conf[0],
+				 ECORE_RSS_IND_TABLE_SIZE))
+		return -EINVAL;
+
+	return 0;
+}
+
 static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
@@ -856,6 +904,26 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 	if (rc != 0)
 		return rc;
 
+	/* Do RSS configuration after vport-start */
+	switch (rxmode->mq_mode) {
+	case ETH_MQ_RX_RSS:
+		rc = qede_config_rss(eth_dev);
+		if (rc != 0) {
+			qdev->ops->vport_stop(edev, 0);
+			qede_dealloc_fp_resc(eth_dev);
+			return -EINVAL;
+		}
+	break;
+	case ETH_MQ_RX_NONE:
+		DP_INFO(edev, "RSS is disabled\n");
+	break;
+	default:
+		DP_ERR(edev, "Unsupported RSS mode\n");
+		qdev->ops->vport_stop(edev, 0);
+		qede_dealloc_fp_resc(eth_dev);
+		return -EINVAL;
+	}
+
 	SLIST_INIT(&qdev->vlan_list_head);
 
 	/* Add primary mac for PF */
@@ -913,6 +981,7 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
 	else
 		dev_info->max_vfs = (uint16_t)NUM_OF_VFS(&qdev->edev);
 	dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE;
+	dev_info->hash_key_size = ECORE_RSS_KEY_SIZE * sizeof(uint32_t);
 	dev_info->flow_type_rss_offloads = (uint64_t)QEDE_RSS_OFFLOAD_ALL;
 
 	dev_info->default_txconf = (struct rte_eth_txconf) {
@@ -1367,7 +1436,7 @@ qede_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev)
 	return NULL;
 }
 
-void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf)
+static void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf)
 {
 	*rss_caps = 0;
 	*rss_caps |= (hf & ETH_RSS_IPV4)              ? ECORE_RSS_IPV4 : 0;
@@ -1381,71 +1450,100 @@ void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf)
 static int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
 				struct rte_eth_rss_conf *rss_conf)
 {
-	struct qed_update_vport_params vport_update_params;
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ecore_sp_vport_update_params vport_update_params;
+	struct ecore_rss_params rss_params;
+	struct ecore_rss_params params;
+	struct ecore_hwfn *p_hwfn;
 	uint32_t *key = (uint32_t *)rss_conf->rss_key;
 	uint64_t hf = rss_conf->rss_hf;
-	int i;
+	uint8_t len = rss_conf->rss_key_len;
+	uint8_t i;
+	int rc;
 
 	memset(&vport_update_params, 0, sizeof(vport_update_params));
+	memset(&rss_params, 0, sizeof(rss_params));
+
+	DP_INFO(edev, "RSS hf = 0x%lx len = %u key = %p\n",
+		(unsigned long)hf, len, key);
 
 	if (hf != 0) {
-		/* Enable RSS */
-		qede_init_rss_caps(&qdev->rss_params.rss_caps, hf);
-		memcpy(&vport_update_params.rss_params, &qdev->rss_params,
-		       sizeof(vport_update_params.rss_params));
-		if (key)
-			memcpy(qdev->rss_params.rss_key, rss_conf->rss_key,
-			       rss_conf->rss_key_len);
-		vport_update_params.update_rss_flg = 1;
-		qdev->rss_enabled = 1;
-	} else {
-		/* Disable RSS */
-		qdev->rss_enabled = 0;
+		/* Enabling RSS */
+		DP_INFO(edev, "Enabling rss\n");
+
+		/* RSS caps */
+		qede_init_rss_caps(&rss_params.rss_caps, hf);
+		rss_params.update_rss_capabilities = 1;
+
+		/* RSS hash key */
+		if (key) {
+			if (len > (ECORE_RSS_KEY_SIZE * sizeof(uint32_t))) {
+				DP_ERR(edev, "RSS key length exceeds limit\n");
+				return -EINVAL;
+			}
+			DP_INFO(edev, "Applying user supplied hash key\n");
+			rss_params.update_rss_key = 1;
+			memcpy(&rss_params.rss_key, key, len);
+		}
+		rss_params.rss_enable = 1;
 	}
 
-	/* If the mapping doesn't fit any supported, return */
-	if (qdev->rss_params.rss_caps == 0 && hf != 0)
-		return -EINVAL;
-
-	DP_INFO(edev, "%s\n", (vport_update_params.update_rss_flg) ?
-				"Enabling RSS" : "Disabling RSS");
-
+	rss_params.update_rss_config = 1;
+	/* tbl_size has to be set with capabilities */
+	rss_params.rss_table_size_log = 7;
 	vport_update_params.vport_id = 0;
+	vport_update_params.rss_params = &rss_params;
+
+	for_each_hwfn(edev, i) {
+		p_hwfn = &edev->hwfns[i];
+		vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
+		rc = ecore_sp_vport_update(p_hwfn, &vport_update_params,
+					   ECORE_SPQ_MODE_EBLOCK, NULL);
+		if (rc) {
+			DP_ERR(edev, "vport-update for RSS failed\n");
+			return rc;
+		}
+	}
+	qdev->rss_enable = rss_params.rss_enable;
+
+	/* Update local structure for hash query */
+	qdev->rss_conf.rss_hf = hf;
+	qdev->rss_conf.rss_key_len = len;
+	if (qdev->rss_enable) {
+		if  (qdev->rss_conf.rss_key == NULL) {
+			qdev->rss_conf.rss_key = (uint8_t *)malloc(len);
+			if (qdev->rss_conf.rss_key == NULL) {
+				DP_ERR(edev, "No memory to store RSS key\n");
+				return -ENOMEM;
+			}
+		}
+		if (key && len) {
+			DP_INFO(edev, "Storing RSS key\n");
+			memcpy(qdev->rss_conf.rss_key, key, len);
+		}
+	} else if (!qdev->rss_enable && len == 0) {
+		if (qdev->rss_conf.rss_key) {
+			free(qdev->rss_conf.rss_key);
+			qdev->rss_conf.rss_key = NULL;
+			DP_INFO(edev, "Free RSS key\n");
+		}
+	}
 
-	return qdev->ops->vport_update(edev, &vport_update_params);
+	return 0;
 }
 
-int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
+static int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
 			   struct rte_eth_rss_conf *rss_conf)
 {
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	uint64_t hf;
-
-	if (rss_conf->rss_key_len < sizeof(qdev->rss_params.rss_key))
-		return -EINVAL;
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 
-	if (rss_conf->rss_key)
-		memcpy(rss_conf->rss_key, qdev->rss_params.rss_key,
-		       sizeof(qdev->rss_params.rss_key));
-
-	hf = 0;
-	hf |= (qdev->rss_params.rss_caps & ECORE_RSS_IPV4)     ?
-			ETH_RSS_IPV4 : 0;
-	hf |= (qdev->rss_params.rss_caps & ECORE_RSS_IPV6)     ?
-			ETH_RSS_IPV6 : 0;
-	hf |= (qdev->rss_params.rss_caps & ECORE_RSS_IPV6)     ?
-			ETH_RSS_IPV6_EX : 0;
-	hf |= (qdev->rss_params.rss_caps & ECORE_RSS_IPV4_TCP) ?
-			ETH_RSS_NONFRAG_IPV4_TCP : 0;
-	hf |= (qdev->rss_params.rss_caps & ECORE_RSS_IPV6_TCP) ?
-			ETH_RSS_NONFRAG_IPV6_TCP : 0;
-	hf |= (qdev->rss_params.rss_caps & ECORE_RSS_IPV6_TCP) ?
-			ETH_RSS_IPV6_TCP_EX : 0;
-
-	rss_conf->rss_hf = hf;
+	rss_conf->rss_hf = qdev->rss_conf.rss_hf;
+	rss_conf->rss_key_len = qdev->rss_conf.rss_key_len;
 
+	if (rss_conf->rss_key && qdev->rss_conf.rss_key)
+		memcpy(rss_conf->rss_key, qdev->rss_conf.rss_key,
+		       rss_conf->rss_key_len);
 	return 0;
 }
 
@@ -1453,10 +1551,14 @@ static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
 				struct rte_eth_rss_reta_entry64 *reta_conf,
 				uint16_t reta_size)
 {
-	struct qed_update_vport_params vport_update_params;
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ecore_sp_vport_update_params vport_update_params;
+	struct ecore_rss_params params;
+	struct ecore_hwfn *p_hwfn;
 	uint16_t i, idx, shift;
+	uint8_t entry;
+	int rc;
 
 	if (reta_size > ETH_RSS_RETA_SIZE_128) {
 		DP_ERR(edev, "reta_size %d is not supported by hardware\n",
@@ -1465,42 +1567,67 @@ static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
 	}
 
 	memset(&vport_update_params, 0, sizeof(vport_update_params));
-	memcpy(&vport_update_params.rss_params, &qdev->rss_params,
-	       sizeof(vport_update_params.rss_params));
+	memset(&params, 0, sizeof(params));
 
 	for (i = 0; i < reta_size; i++) {
 		idx = i / RTE_RETA_GROUP_SIZE;
 		shift = i % RTE_RETA_GROUP_SIZE;
 		if (reta_conf[idx].mask & (1ULL << shift)) {
-			uint8_t entry = reta_conf[idx].reta[shift];
-			qdev->rss_params.rss_ind_table[i] = entry;
+			entry = reta_conf[idx].reta[shift];
+			params.rss_ind_table[i] = entry;
 		}
 	}
 
-	vport_update_params.update_rss_flg = 1;
+	/* Fix up RETA for CMT mode device */
+	if (edev->num_hwfns > 1)
+		qdev->rss_enable = qed_update_rss_parm_cmt(edev,
+					&params.rss_ind_table[0]);
+	params.update_rss_ind_table = 1;
+	params.rss_table_size_log = 7;
+	params.update_rss_config = 1;
 	vport_update_params.vport_id = 0;
+	/* Use the current value of rss_enable */
+	params.rss_enable = qdev->rss_enable;
+	vport_update_params.rss_params = &params;
+
+	for_each_hwfn(edev, i) {
+		p_hwfn = &edev->hwfns[i];
+		vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
+		rc = ecore_sp_vport_update(p_hwfn, &vport_update_params,
+					   ECORE_SPQ_MODE_EBLOCK, NULL);
+		if (rc) {
+			DP_ERR(edev, "vport-update for RSS failed\n");
+			return rc;
+		}
+	}
 
-	return qdev->ops->vport_update(edev, &vport_update_params);
+	/* Update the local copy for RETA query command */
+	memcpy(qdev->rss_ind_table, params.rss_ind_table,
+	       sizeof(params.rss_ind_table));
+
+	return 0;
 }
 
-int qede_rss_reta_query(struct rte_eth_dev *eth_dev,
-			struct rte_eth_rss_reta_entry64 *reta_conf,
-			uint16_t reta_size)
+static int qede_rss_reta_query(struct rte_eth_dev *eth_dev,
+			       struct rte_eth_rss_reta_entry64 *reta_conf,
+			       uint16_t reta_size)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
+	struct ecore_dev *edev = &qdev->edev;
 	uint16_t i, idx, shift;
+	uint8_t entry;
 
 	if (reta_size > ETH_RSS_RETA_SIZE_128) {
-		struct ecore_dev *edev = &qdev->edev;
 		DP_ERR(edev, "reta_size %d is not supported\n",
 		       reta_size);
+		return -EINVAL;
 	}
 
 	for (i = 0; i < reta_size; i++) {
 		idx = i / RTE_RETA_GROUP_SIZE;
 		shift = i % RTE_RETA_GROUP_SIZE;
 		if (reta_conf[idx].mask & (1ULL << shift)) {
-			uint8_t entry = qdev->rss_params.rss_ind_table[i];
+			entry = qdev->rss_ind_table[i];
 			reta_conf[idx].reta[shift] = entry;
 		}
 	}
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index d736246..bd85ba3 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -152,8 +152,11 @@ struct qede_dev {
 	struct qede_fastpath *fp_array;
 	uint8_t num_tc;
 	uint16_t mtu;
-	bool rss_enabled;
-	struct qed_update_vport_rss_params rss_params;
+	bool rss_enable;
+	struct rte_eth_rss_conf rss_conf;
+	uint16_t rss_ind_table[ECORE_RSS_IND_TABLE_SIZE];
+	uint64_t rss_hf;
+	uint8_t rss_key_len;
 	uint32_t flags;
 	bool gro_disable;
 	uint16_t num_queues;
@@ -185,6 +188,8 @@ static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
 				struct rte_eth_rss_reta_entry64 *reta_conf,
 				uint16_t reta_size);
 
+static void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf);
+
 static inline uint32_t qede_rx_cqe_to_pkt_type(uint16_t flags);
 
 /* Non-static functions */
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index 828d3cc..2a8939a 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -507,83 +507,11 @@ qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq)
 	PMD_RX_LOG(DEBUG, rxq, "bd_prod %u  cqe_prod %u\n", bd_prod, cqe_prod);
 }
 
-static inline uint32_t
-qede_rxfh_indir_default(uint32_t index, uint32_t n_rx_rings)
-{
-	return index % n_rx_rings;
-}
-
-static void qede_prandom_bytes(uint32_t *buff, size_t bytes)
-{
-	unsigned int i;
-
-	srand((unsigned int)time(NULL));
-
-	for (i = 0; i < ECORE_RSS_KEY_SIZE; i++)
-		buff[i] = rand();
-}
-
-static bool
-qede_check_vport_rss_enable(struct rte_eth_dev *eth_dev,
-			    struct qed_update_vport_rss_params *rss_params)
-{
-	struct rte_eth_rss_conf rss_conf;
-	enum rte_eth_rx_mq_mode mode = eth_dev->data->dev_conf.rxmode.mq_mode;
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
-	uint8_t rss_caps;
-	unsigned int i;
-	uint64_t hf;
-	uint32_t *key;
-
-	PMD_INIT_FUNC_TRACE(edev);
-
-	rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
-	key = (uint32_t *)rss_conf.rss_key;
-	hf = rss_conf.rss_hf;
-
-	/* Check if RSS conditions are met.
-	 * Note: Even though its meaningless to enable RSS with one queue, it
-	 * could be used to produce RSS Hash, so skipping that check.
-	 */
-	if (!(mode & ETH_MQ_RX_RSS)) {
-		DP_INFO(edev, "RSS flag is not set\n");
-		return false;
-	}
-
-	if (hf == 0) {
-		DP_INFO(edev, "Request to disable RSS\n");
-		return false;
-	}
-
-	memset(rss_params, 0, sizeof(*rss_params));
-
-	for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++)
-		rss_params->rss_ind_table[i] = qede_rxfh_indir_default(i,
-							QEDE_RSS_COUNT(qdev));
-
-	if (!key)
-		qede_prandom_bytes(rss_params->rss_key,
-				   sizeof(rss_params->rss_key));
-	else
-		memcpy(rss_params->rss_key, rss_conf.rss_key,
-		       rss_conf.rss_key_len);
-
-	qede_init_rss_caps(&rss_caps, hf);
-
-	rss_params->rss_caps = rss_caps;
-
-	DP_INFO(edev, "RSS conditions are met\n");
-
-	return true;
-}
-
 static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	struct ecore_queue_start_common_params q_params;
-	struct qed_update_vport_rss_params *rss_params = &qdev->rss_params;
 	struct qed_dev_info *qed_info = &qdev->dev_info.common;
 	struct qed_update_vport_params vport_update_params;
 	struct qede_tx_queue *txq;
@@ -682,16 +610,6 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 		vport_update_params.tx_switching_flg = 1;
 	}
 
-	if (qede_check_vport_rss_enable(eth_dev, rss_params)) {
-		vport_update_params.update_rss_flg = 1;
-		qdev->rss_enabled = 1;
-	} else {
-		qdev->rss_enabled = 0;
-	}
-
-	rte_memcpy(&vport_update_params.rss_params, rss_params,
-	       sizeof(*rss_params));
-
 	rc = qdev->ops->vport_update(edev, &vport_update_params);
 	if (rc) {
 		DP_ERR(edev, "Update V-PORT failed %d\n", rc);
@@ -1091,7 +1009,7 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 
 		htype = (uint8_t)GET_FIELD(fp_cqe->bitfields,
 				ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE);
-		if (qdev->rss_enabled && htype) {
+		if (qdev->rss_enable && htype) {
 			rx_mb->ol_flags |= PKT_RX_RSS_HASH;
 			rx_mb->hash.rss = rte_le_to_cpu_32(fp_cqe->rss_hash);
 			PMD_RX_LOG(DEBUG, rxq, "Hash result 0x%x\n",
@@ -1410,7 +1328,7 @@ int qede_dev_start(struct rte_eth_dev *eth_dev)
 	struct ecore_dev *edev = &qdev->edev;
 	struct qed_link_output link_output;
 	struct qede_fastpath *fp;
-	int rc, i;
+	int rc;
 
 	DP_INFO(edev, "Device state is %d\n", qdev->state);
 
@@ -1620,10 +1538,14 @@ void qede_free_mem_load(struct rte_eth_dev *eth_dev)
 	for_each_queue(id) {
 		fp = &qdev->fp_array[id];
 		if (fp->type & QEDE_FASTPATH_RX) {
+			if (!fp->rxq)
+				continue;
 			qede_rx_queue_release(fp->rxq);
 			eth_dev->data->rx_queues[id] = NULL;
 		} else {
 			for (tc = 0; tc < qdev->num_tc; tc++) {
+				if (!fp->txqs[tc])
+					continue;
 				txq_idx = fp->txqs[tc]->queue_id;
 				qede_tx_queue_release(fp->txqs[tc]);
 				eth_dev->data->tx_queues[txq_idx] = NULL;
diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h
index 3e1e977..2a8645a 100644
--- a/drivers/net/qede/qede_rxtx.h
+++ b/drivers/net/qede/qede_rxtx.h
@@ -64,9 +64,13 @@
 
 #define QEDE_ETH_OVERHEAD       (ETHER_HDR_LEN + 8 + 8 + QEDE_FW_RX_ALIGN_END)
 
-/* TBD: Excluding IPV6 */
-#define QEDE_RSS_OFFLOAD_ALL    (ETH_RSS_IPV4 | ETH_RSS_NONFRAG_IPV4_TCP | \
-				 ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_VXLAN)
+#define QEDE_RSS_OFFLOAD_ALL    (ETH_RSS_IPV4			|\
+				 ETH_RSS_NONFRAG_IPV4_TCP	|\
+				 ETH_RSS_NONFRAG_IPV4_UDP	|\
+				 ETH_RSS_IPV6			|\
+				 ETH_RSS_NONFRAG_IPV6_TCP	|\
+				 ETH_RSS_NONFRAG_IPV6_UDP	|\
+				 ETH_RSS_VXLAN)
 
 #define QEDE_TXQ_FLAGS		((uint32_t)ETH_TXQ_FLAGS_NOMULTSEGS)
 
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 2/7] net/qede: fix filtering code
From: Harish Patil @ 2016-12-23  0:48 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Harish Patil, dev, stable, Dept-EngDPDKDev
In-Reply-To: <91ac9846-530c-2dd3-4bd6-2c3b9143405b@intel.com>

In qede_mac_addr_add() a check is added to differentiate between
unicast/multicast mac to prevent a multicast mac from being wrongly added
to unicast filter table. Secondly, two separate lists will be used to keep
track of unicast/multicast mac filters to prevent duplicate filter
programming. The other change is to remove filter_config from struct
qed_eth_ops_pass and invoke the base APIs directly. This avoids the need
to have multiple structs and function calls.

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_eth_if.c |  101 +-------------
 drivers/net/qede/qede_eth_if.h |   36 +----
 drivers/net/qede/qede_ethdev.c |  303 ++++++++++++++++++++++++++++------------
 drivers/net/qede/qede_ethdev.h |   15 ++
 4 files changed, 230 insertions(+), 225 deletions(-)

diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index 1ae6127..30fded0 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -310,86 +310,11 @@ qed_get_vport_stats(struct ecore_dev *edev, struct ecore_eth_stats *stats)
 	ecore_get_vport_stats(edev, stats);
 }
 
-static int
-qed_configure_filter_ucast(struct ecore_dev *edev,
-			   struct qed_filter_ucast_params *params)
-{
-	struct ecore_filter_ucast ucast;
-
-	if (!params->vlan_valid && !params->mac_valid) {
-		DP_NOTICE(edev, true,
-			  "Tried configuring a unicast filter,"
-			  "but both MAC and VLAN are not set\n");
-		return -EINVAL;
-	}
-
-	memset(&ucast, 0, sizeof(ucast));
-	switch (params->type) {
-	case QED_FILTER_XCAST_TYPE_ADD:
-		ucast.opcode = ECORE_FILTER_ADD;
-		break;
-	case QED_FILTER_XCAST_TYPE_DEL:
-		ucast.opcode = ECORE_FILTER_REMOVE;
-		break;
-	case QED_FILTER_XCAST_TYPE_REPLACE:
-		ucast.opcode = ECORE_FILTER_REPLACE;
-		break;
-	default:
-		DP_NOTICE(edev, true, "Unknown unicast filter type %d\n",
-			  params->type);
-	}
-
-	if (params->vlan_valid && params->mac_valid) {
-		ucast.type = ECORE_FILTER_MAC_VLAN;
-		ether_addr_copy((struct ether_addr *)&params->mac,
-				(struct ether_addr *)&ucast.mac);
-		ucast.vlan = params->vlan;
-	} else if (params->mac_valid) {
-		ucast.type = ECORE_FILTER_MAC;
-		ether_addr_copy((struct ether_addr *)&params->mac,
-				(struct ether_addr *)&ucast.mac);
-	} else {
-		ucast.type = ECORE_FILTER_VLAN;
-		ucast.vlan = params->vlan;
-	}
-
-	ucast.is_rx_filter = true;
-	ucast.is_tx_filter = true;
-
-	return ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
-}
-
-static int
-qed_configure_filter_mcast(struct ecore_dev *edev,
-			   struct qed_filter_mcast_params *params)
-{
-	struct ecore_filter_mcast mcast;
-	int i;
-
-	memset(&mcast, 0, sizeof(mcast));
-	switch (params->type) {
-	case QED_FILTER_XCAST_TYPE_ADD:
-		mcast.opcode = ECORE_FILTER_ADD;
-		break;
-	case QED_FILTER_XCAST_TYPE_DEL:
-		mcast.opcode = ECORE_FILTER_REMOVE;
-		break;
-	default:
-		DP_NOTICE(edev, true, "Unknown multicast filter type %d\n",
-			  params->type);
-	}
-
-	mcast.num_mc_addrs = params->num;
-	for (i = 0; i < mcast.num_mc_addrs; i++)
-		ether_addr_copy((struct ether_addr *)&params->mac[i],
-				(struct ether_addr *)&mcast.mac[i]);
-
-	return ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL);
-}
-
-int qed_configure_filter_rx_mode(struct ecore_dev *edev,
+int qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev,
 				 enum qed_filter_rx_mode_type type)
 {
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
 	struct ecore_filter_accept_flags flags;
 
 	memset(&flags, 0, sizeof(flags));
@@ -422,25 +347,6 @@ int qed_configure_filter_rx_mode(struct ecore_dev *edev,
 				       ECORE_SPQ_MODE_CB, NULL);
 }
 
-static int
-qed_configure_filter(struct ecore_dev *edev, struct qed_filter_params *params)
-{
-	switch (params->type) {
-	case QED_FILTER_TYPE_UCAST:
-		return qed_configure_filter_ucast(edev, &params->filter.ucast);
-	case QED_FILTER_TYPE_MCAST:
-		return qed_configure_filter_mcast(edev, &params->filter.mcast);
-	case QED_FILTER_TYPE_RX_MODE:
-		return qed_configure_filter_rx_mode(edev,
-						    params->filter.
-						    accept_flags);
-	default:
-		DP_NOTICE(edev, true, "Unknown filter type %d\n",
-			  (int)params->type);
-		return -EINVAL;
-	}
-}
-
 static const struct qed_eth_ops qed_eth_ops_pass = {
 	INIT_STRUCT_FIELD(common, &qed_common_ops_pass),
 	INIT_STRUCT_FIELD(fill_dev_info, &qed_fill_eth_dev_info),
@@ -455,7 +361,6 @@ static const struct qed_eth_ops qed_eth_ops_pass = {
 	INIT_STRUCT_FIELD(fastpath_stop, &qed_fastpath_stop),
 	INIT_STRUCT_FIELD(fastpath_start, &qed_fastpath_start),
 	INIT_STRUCT_FIELD(get_vport_stats, &qed_get_vport_stats),
-	INIT_STRUCT_FIELD(filter_config, &qed_configure_filter),
 };
 
 const struct qed_eth_ops *qed_get_eth_ops(void)
diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h
index 33655c3..9c0db87 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -26,12 +26,6 @@ enum qed_filter_rx_mode_type {
 	QED_FILTER_RX_MODE_TYPE_PROMISC,
 };
 
-enum qed_filter_xcast_params_type {
-	QED_FILTER_XCAST_TYPE_ADD,
-	QED_FILTER_XCAST_TYPE_DEL,
-	QED_FILTER_XCAST_TYPE_REPLACE,
-};
-
 enum qed_filter_type {
 	QED_FILTER_TYPE_UCAST,
 	QED_FILTER_TYPE_MCAST,
@@ -93,31 +87,6 @@ struct qed_stop_txq_params {
 	uint8_t tx_queue_id;
 };
 
-struct qed_filter_ucast_params {
-	enum qed_filter_xcast_params_type type;
-	uint8_t vlan_valid;
-	uint16_t vlan;
-	uint8_t mac_valid;
-	unsigned char mac[ETHER_ADDR_LEN];
-};
-
-struct qed_filter_mcast_params {
-	enum qed_filter_xcast_params_type type;
-	uint8_t num;
-	unsigned char mac[QEDE_MAX_MCAST_FILTERS][ETHER_ADDR_LEN];
-};
-
-union qed_filter_type_params {
-	enum qed_filter_rx_mode_type accept_flags;
-	struct qed_filter_ucast_params ucast;
-	struct qed_filter_mcast_params mcast;
-};
-
-struct qed_filter_params {
-	enum qed_filter_type type;
-	union qed_filter_type_params filter;
-};
-
 struct qed_eth_ops {
 	const struct qed_common_ops *common;
 
@@ -162,9 +131,6 @@ struct qed_eth_ops {
 
 	void (*get_vport_stats)(struct ecore_dev *edev,
 				struct ecore_eth_stats *stats);
-
-	int (*filter_config)(struct ecore_dev *edev,
-			     struct qed_filter_params *params);
 };
 
 /* externs */
@@ -173,7 +139,7 @@ extern const struct qed_common_ops qed_common_ops_pass;
 
 const struct qed_eth_ops *qed_get_eth_ops();
 
-int qed_configure_filter_rx_mode(struct ecore_dev *edev,
+int qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev,
 				 enum qed_filter_rx_mode_type type);
 
 #endif /* _QEDE_ETH_IF_H */
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 4943358..73f1824 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -222,47 +222,181 @@ static void qede_print_adapter_info(struct qede_dev *qdev)
 	DP_INFO(edev, "*********************************\n");
 }
 
+static void qede_set_ucast_cmn_params(struct ecore_filter_ucast *ucast)
+{
+	memset(ucast, 0, sizeof(struct ecore_filter_ucast));
+	ucast->is_rx_filter = true;
+	ucast->is_tx_filter = true;
+	/* ucast->assert_on_error = true; - For debug */
+}
+
 static int
-qede_set_ucast_rx_mac(struct qede_dev *qdev,
-		      enum qed_filter_xcast_params_type opcode,
-		      uint8_t mac[ETHER_ADDR_LEN])
+qede_ucast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
+		  bool add)
 {
-	struct ecore_dev *edev = &qdev->edev;
-	struct qed_filter_params filter_cmd;
-
-	memset(&filter_cmd, 0, sizeof(filter_cmd));
-	filter_cmd.type = QED_FILTER_TYPE_UCAST;
-	filter_cmd.filter.ucast.type = opcode;
-	filter_cmd.filter.ucast.mac_valid = 1;
-	rte_memcpy(&filter_cmd.filter.ucast.mac[0], &mac[0], ETHER_ADDR_LEN);
-	return qdev->ops->filter_config(edev, &filter_cmd);
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct qede_ucast_entry *tmp = NULL;
+	struct qede_ucast_entry *u;
+	struct ether_addr *mac_addr;
+
+	mac_addr  = (struct ether_addr *)ucast->mac;
+	if (add) {
+		SLIST_FOREACH(tmp, &qdev->uc_list_head, list) {
+			if ((memcmp(mac_addr, &tmp->mac,
+				    ETHER_ADDR_LEN) == 0) &&
+			     ucast->vlan == tmp->vlan) {
+				DP_ERR(edev, "Unicast MAC is already added"
+				       " with vlan = %u, vni = %u\n",
+				       ucast->vlan,  ucast->vni);
+					return -EEXIST;
+			}
+		}
+		u = rte_malloc(NULL, sizeof(struct qede_ucast_entry),
+			       RTE_CACHE_LINE_SIZE);
+		if (!u) {
+			DP_ERR(edev, "Did not allocate memory for ucast\n");
+			return -ENOMEM;
+		}
+		ether_addr_copy(mac_addr, &u->mac);
+		u->vlan = ucast->vlan;
+		SLIST_INSERT_HEAD(&qdev->uc_list_head, u, list);
+		qdev->num_uc_addr++;
+	} else {
+		SLIST_FOREACH(tmp, &qdev->uc_list_head, list) {
+			if ((memcmp(mac_addr, &tmp->mac,
+				    ETHER_ADDR_LEN) == 0) &&
+			    ucast->vlan == tmp->vlan)
+			break;
+		}
+		if (tmp == NULL) {
+			DP_INFO(edev, "Unicast MAC is not found\n");
+			return -EINVAL;
+		}
+		SLIST_REMOVE(&qdev->uc_list_head, tmp, qede_ucast_entry, list);
+		qdev->num_uc_addr--;
+	}
+
+	return 0;
 }
 
-static void
-qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr,
-		  uint32_t index, __rte_unused uint32_t pool)
+static int
+qede_mcast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *mcast,
+		  bool add)
 {
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
-	int rc;
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ether_addr *mac_addr;
+	struct qede_mcast_entry *tmp = NULL;
+	struct qede_mcast_entry *m;
+
+	mac_addr  = (struct ether_addr *)mcast->mac;
+	if (add) {
+		SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
+			if (memcmp(mac_addr, &tmp->mac, ETHER_ADDR_LEN) == 0) {
+				DP_ERR(edev,
+					"Multicast MAC is already added\n");
+				return -EEXIST;
+			}
+		}
+		m = rte_malloc(NULL, sizeof(struct qede_mcast_entry),
+			RTE_CACHE_LINE_SIZE);
+		if (!m) {
+			DP_ERR(edev,
+				"Did not allocate memory for mcast\n");
+			return -ENOMEM;
+		}
+		ether_addr_copy(mac_addr, &m->mac);
+		SLIST_INSERT_HEAD(&qdev->mc_list_head, m, list);
+		qdev->num_mc_addr++;
+	} else {
+		SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
+			if (memcmp(mac_addr, &tmp->mac, ETHER_ADDR_LEN) == 0)
+				break;
+		}
+		if (tmp == NULL) {
+			DP_INFO(edev, "Multicast mac is not found\n");
+			return -EINVAL;
+		}
+		SLIST_REMOVE(&qdev->mc_list_head, tmp,
+			     qede_mcast_entry, list);
+		qdev->num_mc_addr--;
+	}
 
-	PMD_INIT_FUNC_TRACE(edev);
+	return 0;
+}
 
-	if (index >= qdev->dev_info.num_mac_addrs) {
-		DP_ERR(edev, "Index %u is above MAC filter limit %u\n",
-		       index, qdev->dev_info.num_mac_addrs);
-		return;
+static enum _ecore_status_t
+qede_mac_int_ops(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
+		 bool add)
+{
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	enum _ecore_status_t rc;
+	struct ecore_filter_mcast mcast;
+	struct qede_mcast_entry *tmp;
+	uint16_t j = 0;
+
+	/* Multicast */
+	if (is_multicast_ether_addr((struct ether_addr *)ucast->mac)) {
+		if (add) {
+			if (qdev->num_mc_addr >= ECORE_MAX_MC_ADDRS) {
+				DP_ERR(edev,
+				       "Mcast filter table limit exceeded, "
+				       "Please enable mcast promisc mode\n");
+				return -ECORE_INVAL;
+			}
+		}
+		rc = qede_mcast_filter(eth_dev, ucast, add);
+		if (rc == 0) {
+			DP_INFO(edev, "num_mc_addrs = %u\n", qdev->num_mc_addr);
+			memset(&mcast, 0, sizeof(mcast));
+			mcast.num_mc_addrs = qdev->num_mc_addr;
+			mcast.opcode = ECORE_FILTER_ADD;
+			SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
+				ether_addr_copy(&tmp->mac,
+					(struct ether_addr *)&mcast.mac[j]);
+				j++;
+			}
+			rc = ecore_filter_mcast_cmd(edev, &mcast,
+						    ECORE_SPQ_MODE_CB, NULL);
+		}
+		if (rc != ECORE_SUCCESS) {
+			DP_ERR(edev, "Failed to add multicast filter"
+			       " rc = %d, op = %d\n", rc, add);
+		}
+	} else { /* Unicast */
+		if (add) {
+			if (qdev->num_uc_addr >= qdev->dev_info.num_mac_addrs) {
+				DP_ERR(edev,
+				       "Ucast filter table limit exceeded,"
+				       " Please enable promisc mode\n");
+				return -ECORE_INVAL;
+			}
+		}
+		rc = qede_ucast_filter(eth_dev, ucast, add);
+		if (rc == 0)
+			rc = ecore_filter_ucast_cmd(edev, ucast,
+						    ECORE_SPQ_MODE_CB, NULL);
+		if (rc != ECORE_SUCCESS) {
+			DP_ERR(edev, "MAC filter failed, rc = %d, op = %d\n",
+			       rc, add);
+		}
 	}
 
-	/* Adding macaddr even though promiscuous mode is set */
-	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1)
-		DP_INFO(edev, "Port is in promisc mode, yet adding it\n");
+	return rc;
+}
 
-	/* Add MAC filters according to the unicast secondary macs */
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_ADD,
-				   mac_addr->addr_bytes);
-	if (rc)
-		DP_ERR(edev, "Unable to add macaddr rc=%d\n", rc);
+static void
+qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr,
+		  uint32_t index, __rte_unused uint32_t pool)
+{
+	struct ecore_filter_ucast ucast;
+
+	qede_set_ucast_cmn_params(&ucast);
+	ucast.type = ECORE_FILTER_MAC;
+	ether_addr_copy(mac_addr, (struct ether_addr *)&ucast.mac);
+	(void)qede_mac_int_ops(eth_dev, &ucast, 1);
 }
 
 static void
@@ -271,6 +405,7 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	struct ether_addr mac_addr;
+	struct ecore_filter_ucast ucast;
 	int rc;
 
 	PMD_INIT_FUNC_TRACE(edev);
@@ -281,12 +416,15 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 		return;
 	}
 
+	qede_set_ucast_cmn_params(&ucast);
+	ucast.opcode = ECORE_FILTER_REMOVE;
+	ucast.type = ECORE_FILTER_MAC;
+
 	/* Use the index maintained by rte */
-	ether_addr_copy(&eth_dev->data->mac_addrs[index], &mac_addr);
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_DEL,
-				   mac_addr.addr_bytes);
-	if (rc)
-		DP_ERR(edev, "Unable to remove macaddr rc=%d\n", rc);
+	ether_addr_copy(&eth_dev->data->mac_addrs[index],
+			(struct ether_addr *)&ucast.mac);
+
+	ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
 }
 
 static void
@@ -294,6 +432,7 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ecore_filter_ucast ucast;
 	int rc;
 
 	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
@@ -305,10 +444,13 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	}
 
 	/* First remove the primary mac */
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_DEL,
-				   qdev->primary_mac.addr_bytes);
-
-	if (rc) {
+	qede_set_ucast_cmn_params(&ucast);
+	ucast.opcode = ECORE_FILTER_REMOVE;
+	ucast.type = ECORE_FILTER_MAC;
+	ether_addr_copy(&qdev->primary_mac,
+			(struct ether_addr *)&ucast.mac);
+	rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
+	if (rc != 0) {
 		DP_ERR(edev, "Unable to remove current macaddr"
 			     " Reverting to previous default mac\n");
 		ether_addr_copy(&qdev->primary_mac,
@@ -317,18 +459,15 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	}
 
 	/* Add new MAC */
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_ADD,
-				   mac_addr->addr_bytes);
-
-	if (rc)
+	ucast.opcode = ECORE_FILTER_ADD;
+	ether_addr_copy(mac_addr, (struct ether_addr *)&ucast.mac);
+	rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
+	if (rc != 0)
 		DP_ERR(edev, "Unable to add new default mac\n");
 	else
 		ether_addr_copy(mac_addr, &qdev->primary_mac);
 }
 
-
-
-
 static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool action)
 {
 	struct ecore_dev *edev = &qdev->edev;
@@ -414,22 +553,6 @@ static void qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
 		mask, rxmode->hw_vlan_strip, rxmode->hw_vlan_filter);
 }
 
-static int qede_set_ucast_rx_vlan(struct qede_dev *qdev,
-				  enum qed_filter_xcast_params_type opcode,
-				  uint16_t vid)
-{
-	struct qed_filter_params filter_cmd;
-	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
-
-	memset(&filter_cmd, 0, sizeof(filter_cmd));
-	filter_cmd.type = QED_FILTER_TYPE_UCAST;
-	filter_cmd.filter.ucast.type = opcode;
-	filter_cmd.filter.ucast.vlan_valid = 1;
-	filter_cmd.filter.ucast.vlan = vid;
-
-	return qdev->ops->filter_config(edev, &filter_cmd);
-}
-
 static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 				uint16_t vlan_id, int on)
 {
@@ -438,6 +561,7 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 	struct qed_dev_eth_info *dev_info = &qdev->dev_info;
 	struct qede_vlan_entry *tmp = NULL;
 	struct qede_vlan_entry *vlan;
+	struct ecore_filter_ucast ucast;
 	int rc;
 
 	if (on) {
@@ -464,9 +588,13 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 			return -ENOMEM;
 		}
 
-		rc = qede_set_ucast_rx_vlan(qdev, QED_FILTER_XCAST_TYPE_ADD,
-					    vlan_id);
-		if (rc) {
+		qede_set_ucast_cmn_params(&ucast);
+		ucast.opcode = ECORE_FILTER_ADD;
+		ucast.type = ECORE_FILTER_VLAN;
+		ucast.vlan = vlan_id;
+		rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB,
+					    NULL);
+		if (rc != 0) {
 			DP_ERR(edev, "Failed to add VLAN %u rc %d\n", vlan_id,
 			       rc);
 			rte_free(vlan);
@@ -496,9 +624,13 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 
 		SLIST_REMOVE(&qdev->vlan_list_head, tmp, qede_vlan_entry, list);
 
-		rc = qede_set_ucast_rx_vlan(qdev, QED_FILTER_XCAST_TYPE_DEL,
-					    vlan_id);
-		if (rc) {
+		qede_set_ucast_cmn_params(&ucast);
+		ucast.opcode = ECORE_FILTER_REMOVE;
+		ucast.type = ECORE_FILTER_VLAN;
+		ucast.vlan = vlan_id;
+		rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB,
+					    NULL);
+		if (rc != 0) {
 			DP_ERR(edev, "Failed to delete VLAN %u rc %d\n",
 			       vlan_id, rc);
 		} else {
@@ -740,22 +872,6 @@ qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete)
 	return ((curr->link_status == link.link_up) ? -1 : 0);
 }
 
-static void
-qede_rx_mode_setting(struct rte_eth_dev *eth_dev,
-		     enum qed_filter_rx_mode_type accept_flags)
-{
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
-	struct qed_filter_params rx_mode;
-
-	DP_INFO(edev, "%s mode %u\n", __func__, accept_flags);
-
-	memset(&rx_mode, 0, sizeof(struct qed_filter_params));
-	rx_mode.type = QED_FILTER_TYPE_RX_MODE;
-	rx_mode.filter.accept_flags = accept_flags;
-	qdev->ops->filter_config(edev, &rx_mode);
-}
-
 static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
@@ -768,7 +884,7 @@ static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
 	if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
 		type |= QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC;
 
-	qede_rx_mode_setting(eth_dev, type);
+	qed_configure_filter_rx_mode(eth_dev, type);
 }
 
 static void qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
@@ -779,10 +895,11 @@ static void qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
 	PMD_INIT_FUNC_TRACE(edev);
 
 	if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
-		qede_rx_mode_setting(eth_dev,
-				     QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC);
+		qed_configure_filter_rx_mode(eth_dev,
+				QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC);
 	else
-		qede_rx_mode_setting(eth_dev, QED_FILTER_RX_MODE_TYPE_REGULAR);
+		qed_configure_filter_rx_mode(eth_dev,
+				QED_FILTER_RX_MODE_TYPE_REGULAR);
 }
 
 static void qede_poll_sp_sb_cb(void *param)
@@ -1040,15 +1157,17 @@ static void qede_allmulticast_enable(struct rte_eth_dev *eth_dev)
 	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1)
 		type |= QED_FILTER_RX_MODE_TYPE_PROMISC;
 
-	qede_rx_mode_setting(eth_dev, type);
+	qed_configure_filter_rx_mode(eth_dev, type);
 }
 
 static void qede_allmulticast_disable(struct rte_eth_dev *eth_dev)
 {
 	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1)
-		qede_rx_mode_setting(eth_dev, QED_FILTER_RX_MODE_TYPE_PROMISC);
+		qed_configure_filter_rx_mode(eth_dev,
+				QED_FILTER_RX_MODE_TYPE_PROMISC);
 	else
-		qede_rx_mode_setting(eth_dev, QED_FILTER_RX_MODE_TYPE_REGULAR);
+		qed_configure_filter_rx_mode(eth_dev,
+				QED_FILTER_RX_MODE_TYPE_REGULAR);
 }
 
 static int qede_flow_ctrl_set(struct rte_eth_dev *eth_dev,
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index a97e3d9..a35ea8b 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -123,6 +123,17 @@ struct qede_vlan_entry {
 	uint16_t vid;
 };
 
+struct qede_mcast_entry {
+	struct ether_addr mac;
+	SLIST_ENTRY(qede_mcast_entry) list;
+};
+
+struct qede_ucast_entry {
+	struct ether_addr mac;
+	uint16_t vlan;
+	SLIST_ENTRY(qede_ucast_entry) list;
+};
+
 /*
  *  Structure to store private data for each port.
  */
@@ -147,6 +158,10 @@ struct qede_dev {
 	uint16_t configured_vlans;
 	bool accept_any_vlan;
 	struct ether_addr primary_mac;
+	SLIST_HEAD(mc_list_head, qede_mcast_entry) mc_list_head;
+	uint16_t num_mc_addr;
+	SLIST_HEAD(uc_list_head, qede_ucast_entry) uc_list_head;
+	uint16_t num_uc_addr;
 	bool handle_hw_err;
 	char drv_ver[QEDE_PMD_DRV_VER_STR_SIZE];
 };
-- 
1.7.10.3

^ permalink raw reply related

* Re: [PATCH v4 22/23] ethdev: Decouple interrupt handling from PCI device
From: Jan Blunck @ 2016-12-22 18:26 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Shreyansh Jain, David Marchand, Stephen Hemminger
In-Reply-To: <8699988.5R756v89bM@xps13>

On Thu, Dec 22, 2016 at 4:13 PM, Thomas Monjalon
<thomas.monjalon@6wind.com> wrote:
> 2016-12-21 16:09, Jan Blunck:
>> The struct rte_intr_handle is an abstraction layer for different types of
>> interrupt mechanisms. It is embedded in the low-level device (e.g. PCI).
>> On allocation of a struct rte_eth_dev a reference to the intr_handle
>> should be stored for devices supporting interrupts.
> [...]
>> --- a/lib/librte_ether/rte_ethdev.h
>> +++ b/lib/librte_ether/rte_ethdev.h
>> @@ -1629,6 +1629,7 @@ struct rte_eth_dev {
>>       const struct eth_driver *driver;/**< Driver for this device */
>>       const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
>>       struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
>> +     struct rte_intr_handle *intr_handle; /**< Device interrupt handle */
>>       /** User application callbacks for NIC interrupts */
>>       struct rte_eth_dev_cb_list link_intr_cbs;
>>       /**
>
> Why adding interrupt in ethdev?
> Shouldn't it be a property of rte_device?

Good question. I don't think that rte_device should become an
abstraction layer for all kind of real/virtual devices functionality.
There are devices that do not support interrupts and this
functionality is around enabling irqs per queue. Since this is a
concept of the ethdev I believe the right place to keep a reference to
the IRQ implementation is the rte_eth_dev.

^ permalink raw reply

* Re: [PATCH v4 18/23] ethdev: Helper to map to struct rte_pci_device
From: Jan Blunck @ 2016-12-22 18:13 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Shreyansh Jain, David Marchand, Stephen Hemminger
In-Reply-To: <2253386.A4pj8ELuPQ@xps13>

On Thu, Dec 22, 2016 at 4:21 PM, Thomas Monjalon
<thomas.monjalon@6wind.com> wrote:
> 2016-12-21 16:09, Jan Blunck:
>> PCI drivers could use this helper instead of directly accessing fields of
>> rte_eth_dev to map to rte_pci_device.
> [...]
>> +/**
>> + * @internal
>> + * Helper for drivers that need to convert from rte_eth_dev to rte_pci_device.
>> + */
>> +static inline struct rte_pci_device *__attribute__((always_inline))
>> +rte_eth_dev_to_pci(struct rte_eth_dev *eth_dev)
>> +{
>> +     return eth_dev->pci_dev;
>> +}
>
> Why adding this function instead of just using DEV_PCI_DEV(eth_dev->device)?
>
> I think we must try to avoid any PCI (or other bus) reference inside ethdev.h.

David requested to move it from rte_pci.h to rte_ethdev.h.

It could get forward declared here if one doesn't use it. On the other
hand the rte_pci.h would be required to include rte_ethdev.h if we
move it.

^ permalink raw reply

* Re: [PATCH v14 6/8] vmxnet3: add Tx preparation
From: Yong Wang @ 2016-12-22 17:59 UTC (permalink / raw)
  To: Tomasz Kulasek, dev@dpdk.org; +Cc: Ananyev, Konstantin
In-Reply-To: <1482411919-7620-7-git-send-email-tomaszx.kulasek@intel.com>

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Tomasz Kulasek
> Sent: Thursday, December 22, 2016 5:05 AM
> To: dev@dpdk.org
> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Subject: [dpdk-dev] [PATCH v14 6/8] vmxnet3: add Tx preparation
> 
> From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
> 
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---

Acked-by: Yong Wang <yongwang@vmware.com>

^ permalink raw reply

* Re: [PATCH] net/i40e: fix wrong return value when handling PF message
From: Ferruh Yigit @ 2016-12-22 16:59 UTC (permalink / raw)
  To: Wenzhuo Lu, dev
In-Reply-To: <1482308980-76777-1-git-send-email-wenzhuo.lu@intel.com>

On 12/21/2016 8:29 AM, Wenzhuo Lu wrote:
> When VF receives a message from PF, it should check the return
> value. But in i40evf_execute_vf_cmd the value is ignored and not
> returned to the caller.
> 
> Fixes: 95cd21f45d1b ("i40evf: allocate virtchnl commands buffer per VF")
> 
> Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.h    | 2 +-
>  drivers/net/i40e/i40e_ethdev_vf.c | 1 +
>  2 files changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
> index 298cef4..28111a7 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -527,7 +527,7 @@ struct i40e_vf {
>  	enum i40e_aq_link_speed link_speed;
>  	bool vf_reset;
>  	volatile uint32_t pend_cmd; /* pending command not finished yet */
> -	uint32_t cmd_retval; /* return value of the cmd response from PF */
> +	int32_t cmd_retval; /* return value of the cmd response from PF */
>  	u16 pend_msg; /* flags indicates events from pf not handled yet */
>  	uint8_t *aq_resp; /* buffer to store the adminq response from PF */
>  
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
> index 12da0ec..5d25764 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -361,6 +361,7 @@ struct rte_i40evf_xstats_name_off {
>  		err = -1;
>  		do {
>  			ret = i40evf_read_pfmsg(dev, &info);
> +			vf->cmd_retval = info.result;

This is for op_version, and op_get_vf_resources! Which seems good.

Is something similar required for other commands (default case of the
switch),
but for them not sure how to get retval (event.desc.cookie_low to
vf->cmd_retval) ?

>  			if (ret == I40EVF_MSG_CMD) {
>  				err = 0;
>  				break;
> 

^ permalink raw reply

* [PATCH] crypto test: add integrity check for mbuf data
From: Fiona Trahe @ 2016-12-22 16:51 UTC (permalink / raw)
  To: dev; +Cc: john.griffin, deepak.k.jain, pablo.de.lara.guarch, fiona.trahe

In block cipher test cases, add checks that the source
and destination mbufs are not modified except where expected.

Signed-off-by: Fiona Trahe <fiona.trahe@intel.com>
---
 app/test/test_cryptodev_blockcipher.c | 139 ++++++++++++++++++++++++++++++++--
 1 file changed, 134 insertions(+), 5 deletions(-)

diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c
index 37b10cf..1757c76 100644
--- a/app/test/test_cryptodev_blockcipher.c
+++ b/app/test/test_cryptodev_blockcipher.c
@@ -45,6 +45,7 @@
 #include "test_cryptodev_aes_test_vectors.h"
 #include "test_cryptodev_des_test_vectors.h"
 #include "test_cryptodev_hash_test_vectors.h"
+#include "test_cryptodev.h"
 
 static int
 test_blockcipher_one_case(const struct blockcipher_test_case *t,
@@ -71,6 +72,10 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 	uint32_t buf_len = tdata->ciphertext.len;
 	uint32_t digest_len = 0;
 	char *buf_p = NULL;
+	uint8_t src_pattern = 0xa5;
+	uint8_t dst_pattern = 0xb6;
+	uint8_t tmp_src_buf[MBUF_SIZE];
+	uint8_t tmp_dst_buf[MBUF_SIZE];
 
 	if (tdata->cipher_key.len)
 		memcpy(cipher_key, tdata->cipher_key.data,
@@ -104,6 +109,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 		status = TEST_FAILED;
 		goto error_exit;
 	}
+	memset(ibuf->buf_addr, src_pattern, ibuf->buf_len);
 
 	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
 		buf_len += tdata->iv.len;
@@ -152,6 +158,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 			status = TEST_FAILED;
 			goto error_exit;
 		}
+		memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
 
 		buf_p = rte_pktmbuf_append(obuf, buf_len);
 		if (!buf_p) {
@@ -342,6 +349,17 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 		rte_crypto_op_attach_sym_session(op, sess);
 	}
 
+	TEST_HEXDUMP(stdout, "m_src(before):",
+			sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
+	rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr,
+						sym_op->m_src->buf_len);
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
+		TEST_HEXDUMP(stdout, "m_dst(before):",
+			sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
+		rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr,
+						sym_op->m_dst->buf_len);
+	}
+
 	/* Process crypto operation */
 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
@@ -364,12 +382,11 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 		goto error_exit;
 	}
 
-	TEST_HEXDUMP(stdout, "m_src:",
-		rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len);
+	TEST_HEXDUMP(stdout, "m_src(after):",
+			sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP)
-		TEST_HEXDUMP(stdout, "m_dst:",
-			rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *),
-			buf_len);
+		TEST_HEXDUMP(stdout, "m_dst(after):",
+			sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
 
 	/* Verify results */
 	if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
@@ -430,6 +447,118 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 		}
 	}
 
+	/* The only parts that should have changed in the buffer are
+	 * plaintext/ciphertext and digest.
+	 * In OOP only the dest buffer should change.
+	 */
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
+		struct rte_mbuf *mbuf;
+		uint8_t value;
+		uint32_t head_unchanged_len = 0, changed_len = 0;
+		uint32_t i;
+
+		mbuf = sym_op->m_src;
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) {
+			/* white-box test: PMDs use some of the
+			 * tailroom as temp storage in verify case
+			 */
+			head_unchanged_len = rte_pktmbuf_headroom(mbuf)
+					+ rte_pktmbuf_data_len(mbuf);
+			changed_len = digest_len;
+		} else {
+			head_unchanged_len = mbuf->buf_len;
+			changed_len = 0;
+		}
+
+		for (i = 0; i < mbuf->buf_len; i++) {
+			if (i == head_unchanged_len)
+				i += changed_len;
+			value = *((uint8_t *)(mbuf->buf_addr)+i);
+			if (value != tmp_src_buf[i]) {
+				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+	"line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)",
+					__LINE__, value, tmp_src_buf[i]);
+				status = TEST_FAILED;
+				goto error_exit;
+			}
+		}
+
+		mbuf = sym_op->m_dst;
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
+			head_unchanged_len = rte_pktmbuf_headroom(mbuf) +
+						sym_op->auth.data.offset;
+			changed_len = sym_op->auth.data.length;
+			if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
+				changed_len += sym_op->auth.digest.length;
+		} else {
+			/* cipher-only */
+			head_unchanged_len = rte_pktmbuf_headroom(mbuf) +
+					sym_op->cipher.data.offset;
+			changed_len = sym_op->cipher.data.length;
+		}
+
+		for (i = 0; i < mbuf->buf_len; i++) {
+			if (i == head_unchanged_len)
+				i += changed_len;
+			value = *((uint8_t *)(mbuf->buf_addr)+i);
+			if (value != tmp_dst_buf[i]) {
+				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+	"line %u FAILED: OOP dst outer mbuf data (0x%x) not as expected (0x%x)",
+					__LINE__, value, tmp_dst_buf[i]);
+				status = TEST_FAILED;
+				goto error_exit;
+			}
+		}
+	} else {
+		/* In-place operation */
+		struct rte_mbuf *mbuf;
+		uint8_t value;
+		uint32_t head_unchanged_len = 0, changed_len = 0;
+		uint32_t i;
+
+		mbuf = sym_op->m_src;
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+			head_unchanged_len = rte_pktmbuf_headroom(mbuf) +
+					sym_op->cipher.data.offset;
+			changed_len = sym_op->cipher.data.length;
+		} else {
+			/* auth-only */
+			head_unchanged_len = rte_pktmbuf_headroom(mbuf) +
+					sym_op->auth.data.offset +
+					sym_op->auth.data.length;
+			changed_len = 0;
+		}
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
+			changed_len += sym_op->auth.digest.length;
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) {
+			/* white-box test: PMDs use some of the
+			 * tailroom as temp storage in verify case
+			 */
+			if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+				/* This is simplified, not checking digest*/
+				changed_len += digest_len*2;
+			} else {
+				head_unchanged_len += digest_len;
+				changed_len += digest_len;
+			}
+		}
+
+		for (i = 0; i < mbuf->buf_len; i++) {
+			if (i == head_unchanged_len)
+				i += changed_len;
+			value = *((uint8_t *)(mbuf->buf_addr)+i);
+			if (value != tmp_src_buf[i]) {
+				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+		"line %u FAILED: outer mbuf data (0x%x) not as expected (0x%x)",
+					__LINE__, value, tmp_src_buf[i]);
+				status = TEST_FAILED;
+				goto error_exit;
+			}
+		}
+	}
+
 	snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
 
 error_exit:
-- 
2.5.0

^ permalink raw reply related

* Re: [PATCH v5 29/29] net/i40e: set/clear VF stats from PF
From: Iremonger, Bernard @ 2016-12-22 16:38 UTC (permalink / raw)
  To: Lu, Wenzhuo, Yigit, Ferruh, dev@dpdk.org
  Cc: Wu, Jingjing, Zhang, Helin, Zhang, Qi Z, Chen, Jing D,
	Iremonger, Bernard
In-Reply-To: <6A0DE07E22DDAD4C9103DF62FEBC09093B54C602@shsmsx102.ccr.corp.intel.com>



> -----Original Message-----
> From: Lu, Wenzhuo
> Sent: Wednesday, December 21, 2016 12:56 AM
> To: Iremonger, Bernard <bernard.iremonger@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>; dev@dpdk.org
> Cc: Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Chen, Jing D
> <jing.d.chen@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v5 29/29] net/i40e: set/clear VF stats from PF
> 
> Hi all,
> 
> 
> > -----Original Message-----
> > From: Iremonger, Bernard
> > Sent: Tuesday, December 20, 2016 9:40 PM
> > To: Yigit, Ferruh; dev@dpdk.org
> > Cc: Wu, Jingjing; Zhang, Helin; Zhang, Qi Z; Lu, Wenzhuo; Chen, Jing D
> > Subject: RE: [dpdk-dev] [PATCH v5 29/29] net/i40e: set/clear VF stats
> > from PF
> >
> > Hi Ferruh,
> >
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> > > Sent: Tuesday, December 20, 2016 1:25 PM
> > > To: dev@dpdk.org
> > > Cc: Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin
> > > <helin.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Lu,
> > > Wenzhuo <wenzhuo.lu@intel.com>; Chen, Jing D
> <jing.d.chen@intel.com>
> > > Subject: Re: [dpdk-dev] [PATCH v5 29/29] net/i40e: set/clear VF
> > > stats from PF
> > >
> > > On 12/16/2016 7:02 PM, Ferruh Yigit wrote:
> > > > From: Qi Zhang <qi.z.zhang@intel.com>
> > > >
> > > > This patch add support to get/clear VF statistics from PF side.
> > > > Two APIs are added:
> > > > rte_pmd_i40e_get_vf_stats.
> > > > rte_pmd_i40e_reset_vf_stats.
> > > >
> > > > Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> > > > ---
> > >
> > > <...>
> > >
> > > > diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map
> > > > b/drivers/net/i40e/rte_pmd_i40e_version.map
> > > > index 8ac1bc8..7a5d211 100644
> > > > --- a/drivers/net/i40e/rte_pmd_i40e_version.map
> > > > +++ b/drivers/net/i40e/rte_pmd_i40e_version.map
> > > > @@ -6,7 +6,9 @@ DPDK_2.0 {
> > > >  DPDK_17.02 {
> > > >  	global:
> > > >
> > > > +	rte_pmd_i40e_get_vf_stats;
> > > >  	rte_pmd_i40e_ping_vfs;
> > > > +	rte_pmd_i40e_reset_vf_stats;
> > > >  	rte_pmd_i40e_set_tx_loopback;
> > > >  	rte_pmd_i40e_set_vf_broadcast;
> > > >  	rte_pmd_i40e_set_vf_mac_addr;
> > >
> > > Hi Wenzhuo, Mark,
> > >
> > > I think this is the list of all APIs added with this patchset.
> > >
> > > Just a question, what do you think following a logic in API naming as:
> > > <name_space>_<object>_<action> ?
> > >
> > > So API names become:
> > > rte_pmd_i40e_tx_loopback_set;
> > > rte_pmd_i40e_vf_broadcast_set;
> > > rte_pmd_i40e_vf_mac_addr_set;
> > > rte_pmd_i40e_vfs_ping;
> > > rte_pmd_i40e_vf_stats_get;
> > > rte_pmd_i40e_vf_stats_reset;
> > >
> > >
> > > After above rename, rte_pmd_i40e_tx_loopback_set() is not giving a
> > > hint that this is something related to the PF controlling VF,
> > > perhaps we can rename the API ?
> > >
> > > Also rte_pmd_i40e_vfs_ping() can become rte_pmd_i40e_vf_ping_all()
> > > to be more consistent about _vf_ usage.
> > >
> > > Overall, they can be something like:
> > > rte_pmd_i40e_vf_broadcast_set;
> > > rte_pmd_i40e_vf_mac_addr_set;
> > > rte_pmd_i40e_vf_ping_all;
> > > rte_pmd_i40e_vf_stats_get;
> > > rte_pmd_i40e_vf_stats_reset;
> > > rte_pmd_i40e_vf_tx_loopback_set;
> > >
> > > What do you think?
> > >
> >
> > I think the naming should be consistent with what has already been
> > implemented for the ixgbe PMD.
> > 	rte_pmd_ixgbe_set_all_queues_drop_en;
> > 	rte_pmd_ixgbe_set_tx_loopback;
> > 	rte_pmd_ixgbe_set_vf_mac_addr;
> > 	rte_pmd_ixgbe_set_vf_mac_anti_spoof;
> > 	rte_pmd_ixgbe_set_vf_split_drop_en;
> > 	rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
> > 	rte_pmd_ixgbe_set_vf_vlan_insert;
> > 	rte_pmd_ixgbe_set_vf_vlan_stripq;
> >
> > 	rte_pmd_ixgbe_set_vf_rate_limit;
> > 	rte_pmd_ixgbe_set_vf_rx;
> > 	rte_pmd_ixgbe_set_vf_rxmode;
> > 	rte_pmd_ixgbe_set_vf_tx;
> > 	rte_pmd_ixgbe_set_vf_vlan_filter;
> So, seems better to use the current names. Rework both ixgbe and i40e's
> later. Not sure if it'll be counted as the ABI change if we change the ixgbe's
> name.
> 

A similar naming convention was used originally in the ethdev:
rte_eth_dev_set_vf_rxmode
rte_eth_dev_set_vf_rx
rte_eth_dev_set_vf_tx
rte_eth_dev_set_vf_vlan_filter
rte_eth_dev_set_vf_rate_limit

rte_eth_dev has just been replaced with rte_pmd_<ixgbe|i40e>

Regards,

Bernard.

^ permalink raw reply

* Re: [PATCH v2 1/5] lib: distributor performance enhancements
From: Hunt, David @ 2016-12-22 16:14 UTC (permalink / raw)
  To: Jerin Jacob; +Cc: dev, bruce.richardson
In-Reply-To: <20161222124753.GB8778@localhost.localdomain>


Thanks for the review, Jerin, I very much appreciate it. I'll address 
all the minor comments, and I've a comment or two on the remaining 
changes below.


On 22/12/2016 12:47 PM, Jerin Jacob wrote:

> On Thu, Dec 22, 2016 at 04:37:04AM +0000, David Hunt wrote:
>

--snip--

>> +
>> +	/* set the GET_BUF but even if we got no returns */
>> +	buf->retptr64[0] |= RTE_DISTRIB_GET_BUF;
>> +
>> +	return 0;
>> +}
>> +
>> +#if RTE_MACHINE_CPUFLAG_SSE2
>> +static inline void
> Move SSE version of the code to separate file so that later other SIMD arch
> specific version like NEON can be incorporated.
>

Sure. Will do. I'll model it on the i40e SIMD layout.


>> +		switch (d->dist_match_fn) {
>> +#ifdef RTE_MACHINE_CPUFLAG_SSE2
> Is this conditional compilation flag is really required ? i.e
> RTE_DIST_MATCH_SSE will not enabled in non SSE case

So I can always leave the call to find_match_sse2 in there, but the 
run-time cpu flags check will
take care of whether it's called or not? OK sure.


Thanks,
Dave.

^ permalink raw reply

* Re: [PATCH v2 1/2] crypto/qat: add SGL capability to Intel QuickAssist driver
From: Trahe, Fiona @ 2016-12-22 16:01 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, dev@dpdk.org
  Cc: De Lara Guarch, Pablo, Griffin, John, Jain, Deepak K,
	Trahe, Fiona
In-Reply-To: <1482401702-11039-2-git-send-email-arkadiuszx.kusztal@intel.com>



> -----Original Message-----
> From: Kusztal, ArkadiuszX
> Sent: Thursday, December 22, 2016 10:15 AM
> To: dev@dpdk.org
> Cc: Trahe, Fiona <fiona.trahe@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Griffin, John <john.griffin@intel.com>;
> Jain, Deepak K <deepak.k.jain@intel.com>; Kusztal, ArkadiuszX
> <arkadiuszx.kusztal@intel.com>
> Subject: [PATCH v2 1/2] crypto/qat: add SGL capability to Intel QuickAssist
> driver
> 
> This commit adds scatter-gather list capability to Intel QuickAssist
> Technology driver.
> 
> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
Nack
 fix needed below and some unnecessary white space changes


> ---
>  doc/guides/rel_notes/release_17_02.rst |   2 +
>  drivers/crypto/qat/qat_adf/qat_algs.h  |  14 +++-
>  drivers/crypto/qat/qat_crypto.c        | 130
> +++++++++++++++++++++++++++++++--
>  drivers/crypto/qat/qat_crypto.h        |   3 +
>  drivers/crypto/qat/qat_qp.c            |  55 +++++++++++++-
>  5 files changed, 195 insertions(+), 9 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/release_17_02.rst
> b/doc/guides/rel_notes/release_17_02.rst
> index f3e7bb6..7eaf98e 100644
> --- a/doc/guides/rel_notes/release_17_02.rst
> +++ b/doc/guides/rel_notes/release_17_02.rst
> @@ -44,6 +44,8 @@ New Features
> 
>    * DES algorithm.
> 
> +  * Scatter-gather list (SGL) support.
> +
> 
>  Resolved Issues
>  ---------------
> diff --git a/drivers/crypto/qat/qat_adf/qat_algs.h
> b/drivers/crypto/qat/qat_adf/qat_algs.h
> index 5409e1e..e01b9d7 100644
> --- a/drivers/crypto/qat/qat_adf/qat_algs.h
> +++ b/drivers/crypto/qat/qat_adf/qat_algs.h
> @@ -47,6 +47,7 @@
>  #ifndef _ICP_QAT_ALGS_H_
>  #define _ICP_QAT_ALGS_H_
>  #include <rte_memory.h>
> +#include <rte_crypto.h>
>  #include "icp_qat_hw.h"
>  #include "icp_qat_fw.h"
>  #include "icp_qat_fw_la.h"
> @@ -79,13 +80,24 @@ struct qat_alg_buf {
>  	uint64_t addr;
>  } __rte_packed;
> 
> +/*
> + * Maximum number of SGL entries
> + */
> +#define QAT_SGL_MAX_NUMBER	16
> +
>  struct qat_alg_buf_list {
>  	uint64_t resrvd;
>  	uint32_t num_bufs;
>  	uint32_t num_mapped_bufs;
> -	struct qat_alg_buf bufers[];
> +	struct qat_alg_buf bufers[QAT_SGL_MAX_NUMBER];
>  } __rte_packed __rte_cache_aligned;
> 
> +struct qat_crypto_op_cookie {
> +	struct qat_alg_buf_list qat_sgl_list;
> +	struct qat_alg_buf_list qat_sgl_list_oop;
> +	phys_addr_t cookie_phys_addr;
> +};
> +
>  /* Common content descriptor */
>  struct qat_alg_cd {
>  	struct icp_qat_hw_cipher_algo_blk cipher;
> diff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c
> index fa78c60..27e40fd 100644
> --- a/drivers/crypto/qat/qat_crypto.c
> +++ b/drivers/crypto/qat/qat_crypto.c
> @@ -67,6 +67,10 @@
> 
>  #define BYTE_LENGTH    8
> 
> +#define SGL_SECOND_COOKIE_ADDR(arg, cast)	((cast)(arg) \
> +				+ offsetof(struct qat_crypto_op_cookie, \
> +					qat_sgl_list_oop))
> +
>  static const struct rte_cryptodev_capabilities qat_pmd_capabilities[] = {
>  	{	/* SHA1 HMAC */
>  		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
> @@ -523,7 +527,8 @@ static inline uint32_t
>  adf_modulo(uint32_t data, uint32_t shift);
> 
>  static inline int
> -qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg);
> +qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg,
> +		struct qat_crypto_op_cookie *qat_op_cookie);
> 
>  void qat_crypto_sym_clear_session(struct rte_cryptodev *dev,
>  		void *session)
> @@ -900,9 +905,17 @@ qat_pmd_enqueue_op_burst(void *qp, struct
> rte_crypto_op **ops,
>  	}
> 
>  	while (nb_ops_sent != nb_ops_possible) {
> -		ret = qat_write_hw_desc_entry(*cur_op, base_addr + tail);
> +
> +		ret = qat_write_hw_desc_entry(*cur_op, base_addr + tail,
> +				tmp_qp->sgl_cookies[tail / queue->msg_size]);
>  		if (ret != 0) {
>  			tmp_qp->stats.enqueue_err_count++;
> +			/*
> +			 * This message cannot be enqueued,
> +			 * decrease number of ops that wasnt sent
> +			 */
> +			rte_atomic16_sub(&tmp_qp->inflights16,
> +					nb_ops_possible - nb_ops_sent);
>  			if (nb_ops_sent == 0)
>  				return 0;
>  			goto kick_tail;
> @@ -911,6 +924,7 @@ qat_pmd_enqueue_op_burst(void *qp, struct
> rte_crypto_op **ops,
>  		tail = adf_modulo(tail + queue->msg_size, queue->modulo);
>  		nb_ops_sent++;
>  		cur_op++;
> +
>  	}
>  kick_tail:
>  	WRITE_CSR_RING_TAIL(tmp_qp->mmap_bar_addr, queue-
> >hw_bundle_number,
> @@ -936,12 +950,13 @@ qat_pmd_dequeue_op_burst(void *qp, struct
> rte_crypto_op **ops,
> 
>  	while (*(uint32_t *)resp_msg != ADF_RING_EMPTY_SIG &&
>  			msg_counter != nb_ops) {
> +
>  		rx_op = (struct rte_crypto_op *)(uintptr_t)
>  				(resp_msg->opaque_data);
> 
>  #ifdef RTE_LIBRTE_PMD_QAT_DEBUG_RX
>  		rte_hexdump(stdout, "qat_response:", (uint8_t *)resp_msg,
> -				sizeof(struct icp_qat_fw_comn_resp));
> +			sizeof(struct icp_qat_fw_comn_resp));
>  #endif
>  		if (ICP_QAT_FW_COMN_STATUS_FLAG_OK !=
> 
> 	ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(
> @@ -950,7 +965,9 @@ qat_pmd_dequeue_op_burst(void *qp, struct
> rte_crypto_op **ops,
>  		} else {
>  			rx_op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
>  		}
> +
>  		*(uint32_t *)resp_msg = ADF_RING_EMPTY_SIG;
> +
>  		queue->head = adf_modulo(queue->head +
>  				queue->msg_size,
>  				ADF_RING_SIZE_MODULO(queue-
> >queue_size));
> @@ -972,8 +989,61 @@ qat_pmd_dequeue_op_burst(void *qp, struct
> rte_crypto_op **ops,
>  }
> 
>  static inline int
> -qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg)
> +qat_sgl_fill_array(struct rte_mbuf *buf, uint64_t buff_start,
> +		void *sgl_cookie, uint32_t data_len)
> +{
> +	int nr = 1;
> +	struct qat_alg_buf_list *list = sgl_cookie;
> +
> +	uint32_t buf_len = rte_pktmbuf_mtophys(buf) -
> +			buff_start + rte_pktmbuf_data_len(buf);
> +
> +	list->bufers[0].addr = buff_start;
> +	list->bufers[0].resrvd = 0;
> +	list->bufers[0].len = buf_len;
> +
> +	if (data_len < buf_len) {
> +		list->num_bufs = nr;
> +		list->bufers[0].len = rte_pktmbuf_mtophys(buf) -
> +			buff_start + data_len;
> +		return 0;
> +	}
data_len= buf_len should be handled here too and return.

Also readjustment of .len should be just = data_len

> +
> +	buf = buf->next;
> +	while (buf) {
> +		if (unlikely(nr == QAT_SGL_MAX_NUMBER)) {
> +			PMD_DRV_LOG(ERR, "QAT PMD exceeded size of QAT
> SGL"
> +					" entry(%u)",
> +					QAT_SGL_MAX_NUMBER);
> +			return -EINVAL;
> +		}
> +
> +		list->bufers[nr].len = rte_pktmbuf_data_len(buf);
> +		list->bufers[nr].resrvd = 0;
> +		list->bufers[nr].addr = rte_pktmbuf_mtophys(buf);
> +
> +		buf_len += list->bufers[nr].len;
> +		buf = buf->next;
> +
> +		if (buf_len > data_len) {
> +			list->bufers[nr].len -=
> +				buf_len - data_len;
> +			buf = NULL;
> +		}
> +
> +		++nr;
> +	}
> +
> +	list->num_bufs = nr;
> +
> +	return 0;
> +}
> +
> +static inline int
> +qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg,
> +		struct qat_crypto_op_cookie *qat_op_cookie)
>  {
> +	int ret = 0;
>  	struct qat_session *ctx;
>  	struct icp_qat_fw_la_cipher_req_params *cipher_param;
>  	struct icp_qat_fw_la_auth_req_params *auth_param;
> @@ -983,6 +1053,7 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op,
> uint8_t *out_msg)
>  	uint32_t auth_len = 0, auth_ofs = 0;
>  	uint32_t min_ofs = 0;
>  	uint64_t src_buf_start = 0, dst_buf_start = 0;
> +	uint8_t do_sgl = 0;
> 
> 
>  #ifdef RTE_LIBRTE_PMD_QAT_DEBUG_TX
> @@ -1100,10 +1171,16 @@ qat_write_hw_desc_entry(struct rte_crypto_op
> *op, uint8_t *out_msg)
> 
>  	}
> 
> +	if (op->sym->m_src->next || (op->sym->m_dst && op->sym->m_dst-
> >next))
> +		do_sgl = 1;
> +
>  	/* adjust for chain case */
>  	if (do_cipher && do_auth)
>  		min_ofs = cipher_ofs < auth_ofs ? cipher_ofs : auth_ofs;
> 
> +	if (unlikely(min_ofs >= rte_pktmbuf_data_len(op->sym->m_src) &&
> do_sgl))
> +		min_ofs = 0;
> +
>  	if (unlikely(op->sym->m_dst != NULL)) {
>  		/* Out-of-place operation (OOP)
>  		 * Don't align DMA start. DMA the minimum data-set
> @@ -1113,6 +1190,7 @@ qat_write_hw_desc_entry(struct rte_crypto_op
> *op, uint8_t *out_msg)
>  			rte_pktmbuf_mtophys_offset(op->sym->m_src,
> min_ofs);
>  		dst_buf_start =
>  			rte_pktmbuf_mtophys_offset(op->sym->m_dst,
> min_ofs);
> +
>  	} else {
>  		/* In-place operation
>  		 * Start DMA at nearest aligned address below min_ofs
> @@ -1158,8 +1236,47 @@ qat_write_hw_desc_entry(struct rte_crypto_op
> *op, uint8_t *out_msg)
>  		(cipher_param->cipher_offset + cipher_param->cipher_length)
>  		: (auth_param->auth_off + auth_param->auth_len);
> 
> -	qat_req->comn_mid.src_data_addr = src_buf_start;
> -	qat_req->comn_mid.dest_data_addr = dst_buf_start;
> +	if (do_sgl) {
> +
> +		ICP_QAT_FW_COMN_PTR_TYPE_SET(qat_req-
> >comn_hdr.comn_req_flags,
> +				QAT_COMN_PTR_TYPE_SGL);
> +		ret = qat_sgl_fill_array(op->sym->m_src, src_buf_start,
> +				&qat_op_cookie->qat_sgl_list,
> +				qat_req->comn_mid.src_length);
> +		if (ret) {
> +			PMD_DRV_LOG(ERR, "QAT PMD Cannot fill sgl
> array");
> +			return ret;
> +		}
> +
> +		if (likely(op->sym->m_dst == NULL))
> +			qat_req->comn_mid.dest_data_addr =
> +				qat_req->comn_mid.src_data_addr =
> +				qat_op_cookie->cookie_phys_addr;
> +		else {
> +			ret = qat_sgl_fill_array(op->sym->m_dst,
> +					dst_buf_start,
> +					&qat_op_cookie->qat_sgl_list_oop,
> +						qat_req-
> >comn_mid.dst_length);
> +
> +			if (ret) {
> +				PMD_DRV_LOG(ERR, "QAT PMD Cannot "
> +						"fill sgl array");
> +				return ret;
> +			}
> +
> +			qat_req->comn_mid.src_data_addr =
> +				qat_op_cookie->cookie_phys_addr;
> +
> +			qat_req->comn_mid.dest_data_addr =
> +				SGL_SECOND_COOKIE_ADDR(
> +						qat_op_cookie-
> >cookie_phys_addr,
> +						phys_addr_t);
> +		}
> +
> +	} else {
> +		qat_req->comn_mid.src_data_addr = src_buf_start;
> +		qat_req->comn_mid.dest_data_addr = dst_buf_start;
> +	}
> 
>  	if (ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128 ||
>  			ctx->qat_hash_alg ==
> ICP_QAT_HW_AUTH_ALGO_GALOIS_64) {
> @@ -1191,7 +1308,6 @@ qat_write_hw_desc_entry(struct rte_crypto_op
> *op, uint8_t *out_msg)
>  		}
>  	}
> 
> -
>  #ifdef RTE_LIBRTE_PMD_QAT_DEBUG_TX
>  	rte_hexdump(stdout, "qat_req:", qat_req,
>  			sizeof(struct icp_qat_fw_la_bulk_req));
> diff --git a/drivers/crypto/qat/qat_crypto.h b/drivers/crypto/qat/qat_crypto.h
> index 6b84488..ef90281 100644
> --- a/drivers/crypto/qat/qat_crypto.h
> +++ b/drivers/crypto/qat/qat_crypto.h
> @@ -69,6 +69,9 @@ struct qat_qp {
>  	struct	qat_queue	tx_q;
>  	struct	qat_queue	rx_q;
>  	struct	rte_cryptodev_stats stats;
> +	struct rte_mempool *sgl_pool;
> +	void **sgl_cookies;
> +	uint32_t nb_descriptors;
>  } __rte_cache_aligned;
> 
>  /** private data structure for each QAT device */
> diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
> index 2e7188b..331ff31 100644
> --- a/drivers/crypto/qat/qat_qp.c
> +++ b/drivers/crypto/qat/qat_qp.c
> @@ -41,6 +41,7 @@
> 
>  #include "qat_logs.h"
>  #include "qat_crypto.h"
> +#include "qat_algs.h"
>  #include "adf_transport_access_macros.h"
> 
>  #define ADF_MAX_SYM_DESC			4096
> @@ -136,6 +137,8 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev
> *dev, uint16_t queue_pair_id,
>  {
>  	struct qat_qp *qp;
>  	int ret;
> +	char sgl_pool_name[RTE_RING_NAMESIZE];
> +	uint32_t i;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> @@ -166,7 +169,6 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev
> *dev, uint16_t queue_pair_id,
>  				queue_pair_id);
>  		return -EINVAL;
>  	}
> -
>  	/* Allocate the queue pair data structure. */
>  	qp = rte_zmalloc("qat PMD qp metadata",
>  			sizeof(*qp), RTE_CACHE_LINE_SIZE);
> @@ -174,6 +176,11 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev
> *dev, uint16_t queue_pair_id,
>  		PMD_DRV_LOG(ERR, "Failed to alloc mem for qp struct");
>  		return -ENOMEM;
>  	}
> +	qp->nb_descriptors = qp_conf->nb_descriptors;
> +	qp->sgl_cookies = rte_zmalloc("qat PMD SGL cookie pointer",
> +			qp_conf->nb_descriptors * sizeof(*qp->sgl_cookies),
> +			RTE_CACHE_LINE_SIZE);
> +
>  	qp->mmap_bar_addr = dev->pci_dev->mem_resource[0].addr;
>  	rte_atomic16_init(&qp->inflights16);
> 
> @@ -191,9 +198,45 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev
> *dev, uint16_t queue_pair_id,
>  		qat_queue_delete(&(qp->tx_q));
>  		goto create_err;
>  	}
> +
>  	adf_configure_queues(qp);
>  	adf_queue_arb_enable(&qp->tx_q, qp->mmap_bar_addr);
> +
> +	snprintf(sgl_pool_name, RTE_RING_NAMESIZE,
> "%s_qp_sgl_%d_%hu",
> +		dev->driver->pci_drv.driver.name, dev->data->dev_id,
> +		queue_pair_id);
> +
> +	qp->sgl_pool = rte_mempool_lookup(sgl_pool_name);
> +
> +	if (qp->sgl_pool == NULL)
> +		qp->sgl_pool = rte_mempool_create(sgl_pool_name,
> +				qp->nb_descriptors,
> +				sizeof(struct qat_crypto_op_cookie), 64, 0,
> +				NULL, NULL, NULL, NULL, socket_id,
> +				0);
> +	if (!qp->sgl_pool) {
> +		PMD_DRV_LOG(ERR, "QAT PMD Cannot create"
> +				" sgl mempool");
> +		goto create_err;
> +	}
> +
> +	for (i = 0; i < qp->nb_descriptors; i++) {
> +		if (rte_mempool_get(qp->sgl_pool, &qp->sgl_cookies[i])) {
> +			PMD_DRV_LOG(ERR, "QAT PMD Cannot get
> sgl_cookie");
> +			return -EFAULT;
> +		}
> +
> +		struct qat_crypto_op_cookie *sql_cookie =
> +				qp->sgl_cookies[i];
> +
> +		sql_cookie->cookie_phys_addr =
> +				rte_mempool_virt2phy(qp->sgl_pool,
> +				sql_cookie) +
> +				offsetof(struct qat_crypto_op_cookie,
> +				qat_sgl_list);
> +	}
>  	dev->data->queue_pairs[queue_pair_id] = qp;
> +
>  	return 0;
> 
>  create_err:
> @@ -206,6 +249,8 @@ int qat_crypto_sym_qp_release(struct rte_cryptodev
> *dev, uint16_t queue_pair_id)
>  	struct qat_qp *qp =
>  			(struct qat_qp *)dev->data-
> >queue_pairs[queue_pair_id];
> 
> +	uint32_t i;
> +
>  	PMD_INIT_FUNC_TRACE();
>  	if (qp == NULL) {
>  		PMD_DRV_LOG(DEBUG, "qp already freed");
> @@ -221,6 +266,14 @@ int qat_crypto_sym_qp_release(struct
> rte_cryptodev *dev, uint16_t queue_pair_id)
>  	}
> 
>  	adf_queue_arb_disable(&(qp->tx_q), qp->mmap_bar_addr);
> +
> +	for (i = 0; i < qp->nb_descriptors; i++)
> +		rte_mempool_put(qp->sgl_pool, qp->sgl_cookies[i]);
> +
> +	if (qp->sgl_pool)
> +		rte_mempool_free(qp->sgl_pool);
> +
> +	rte_free(qp->sgl_cookies);
>  	rte_free(qp);
>  	dev->data->queue_pairs[queue_pair_id] = NULL;
>  	return 0;
> --
> 2.1.0

^ permalink raw reply

* Re: [PATCH 12/13] i40e: return -errno when intr setup fails
From: Ferruh Yigit @ 2016-12-22 15:45 UTC (permalink / raw)
  To: Michał Mirosław, dev
In-Reply-To: <7f9c82cc9331585b82fcf680ffe873700808408f.1481590851.git.mirq-linux@rere.qmqm.pl>

On 12/13/2016 1:08 AM, Michał Mirosław wrote:
> Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> ---
>  drivers/net/i40e/i40e_ethdev.c               | 5 +++--
>  lib/librte_eal/linuxapp/eal/eal_interrupts.c | 2 +-
>  2 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 67778ba..39fbcfe 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -1692,8 +1692,9 @@ i40e_dev_start(struct rte_eth_dev *dev)
>  	     !RTE_ETH_DEV_SRIOV(dev).active) &&
>  	    dev->data->dev_conf.intr_conf.rxq != 0) {
>  		intr_vector = dev->data->nb_rx_queues;
> -		if (rte_intr_efd_enable(intr_handle, intr_vector))
> -			return -1;
> +		ret = rte_intr_efd_enable(intr_handle, intr_vector);
> +		if (ret)
> +			return ret;

What is the benefit of returning -errno instead of -1?

>  	}
>  
>  	if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
> diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
> index 47a3b20..f7a8ce3 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
> @@ -1157,7 +1157,7 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
>  				RTE_LOG(ERR, EAL,
>  					"can't setup eventfd, error %i (%s)\n",
>  					errno, strerror(errno));
> -				return -1;
> +				return -errno;
>  			}
>  			intr_handle->efds[i] = fd;
>  		}
> 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox