DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/5] vmxnet3: Avoid memory leak in vmxnet3_dev_tx_queue_setup.
From: nickcooper-zhangtonghao @ 2017-01-05 10:43 UTC (permalink / raw)
  To: dev; +Cc: nickcooper-zhangtonghao
In-Reply-To: <1483612983-3545-1-git-send-email-nic@opencloud.tech>

This patch will check the "nb_desc" parameter for tx queue,
release the txq and re-allocation it soon.

Signed-off-by: nickcooper-zhangtonghao <nic@opencloud.tech>
---
 drivers/net/vmxnet3/vmxnet3_rxtx.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index 9822fa0..077baac 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -828,6 +828,23 @@
 		return -EINVAL;
 	}
 
+    /* Tx vmxnet ring length should be between 512-4096 */
+	if (nb_desc < VMXNET3_DEF_TX_RING_SIZE) {
+		PMD_INIT_LOG(ERR, "VMXNET3 Tx Ring Size Min: %u",
+			     VMXNET3_DEF_TX_RING_SIZE);
+		return -EINVAL;
+	} else if (nb_desc > VMXNET3_TX_RING_MAX_SIZE) {
+		PMD_INIT_LOG(ERR, "VMXNET3 Tx Ring Size Max: %u",
+			     VMXNET3_TX_RING_MAX_SIZE);
+		return -EINVAL;
+	}
+
+    /* Free memory prior to re-allocation if needed... */
+    if (dev->data->tx_queues[queue_idx] != NULL) {
+        vmxnet3_dev_tx_queue_release(dev->data->tx_queues[queue_idx]);
+        dev->data->tx_queues[queue_idx] = NULL;
+    }
+
 	txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue),
 			  RTE_CACHE_LINE_SIZE);
 	if (txq == NULL) {
@@ -846,19 +863,8 @@
 	comp_ring = &txq->comp_ring;
 	data_ring = &txq->data_ring;
 
-	/* Tx vmxnet ring length should be between 512-4096 */
-	if (nb_desc < VMXNET3_DEF_TX_RING_SIZE) {
-		PMD_INIT_LOG(ERR, "VMXNET3 Tx Ring Size Min: %u",
-			     VMXNET3_DEF_TX_RING_SIZE);
-		return -EINVAL;
-	} else if (nb_desc > VMXNET3_TX_RING_MAX_SIZE) {
-		PMD_INIT_LOG(ERR, "VMXNET3 Tx Ring Size Max: %u",
-			     VMXNET3_TX_RING_MAX_SIZE);
-		return -EINVAL;
-	} else {
-		ring->size = nb_desc;
-		ring->size &= ~VMXNET3_RING_SIZE_MASK;
-	}
+    ring->size = nb_desc;
+    ring->size &= ~VMXNET3_RING_SIZE_MASK;
 	comp_ring->size = data_ring->size = ring->size;
 
 	/* Tx vmxnet rings structure initialization*/
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 2/5] vmxnet3: Avoid memory leak in vmxnet3_dev_rx_queue_setup.
From: nickcooper-zhangtonghao @ 2017-01-05 10:43 UTC (permalink / raw)
  To: dev; +Cc: nickcooper-zhangtonghao
In-Reply-To: <1483612983-3545-1-git-send-email-nic@opencloud.tech>

This patch will check the "nb_desc" parameter for rx queue,
release the rxq and re-allocation it soon.

Signed-off-by: nickcooper-zhangtonghao <nic@opencloud.tech>
---
 drivers/net/vmxnet3/vmxnet3_rxtx.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index b109168..e83ac05 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -926,6 +926,21 @@
 
 	PMD_INIT_FUNC_TRACE();
 
+	/* Rx vmxnet rings length should be between 128-4096 */
+	if (nb_desc < VMXNET3_DEF_RX_RING_SIZE) {
+		PMD_INIT_LOG(ERR, "VMXNET3 Rx Ring Size Min: 128");
+		return -EINVAL;
+	} else if (nb_desc > VMXNET3_RX_RING_MAX_SIZE) {
+		PMD_INIT_LOG(ERR, "VMXNET3 Rx Ring Size Max: 4096");
+		return -EINVAL;
+	}
+
+	/* Free memory prior to re-allocation if needed. */
+    if (dev->data->rx_queues[queue_idx] != NULL) {
+            vmxnet3_dev_rx_queue_release(dev->data->rx_queues[queue_idx]);
+            dev->data->rx_queues[queue_idx] = NULL;
+    }
+
 	rxq = rte_zmalloc("ethdev_rx_queue", sizeof(struct vmxnet3_rx_queue),
 			  RTE_CACHE_LINE_SIZE);
 	if (rxq == NULL) {
@@ -946,18 +961,9 @@
 	ring1 = &rxq->cmd_ring[1];
 	comp_ring = &rxq->comp_ring;
 
-	/* Rx vmxnet rings length should be between 256-4096 */
-	if (nb_desc < VMXNET3_DEF_RX_RING_SIZE) {
-		PMD_INIT_LOG(ERR, "VMXNET3 Rx Ring Size Min: 256");
-		return -EINVAL;
-	} else if (nb_desc > VMXNET3_RX_RING_MAX_SIZE) {
-		PMD_INIT_LOG(ERR, "VMXNET3 Rx Ring Size Max: 4096");
-		return -EINVAL;
-	} else {
-		ring0->size = nb_desc;
-		ring0->size &= ~VMXNET3_RING_SIZE_MASK;
-		ring1->size = ring0->size;
-	}
+	ring0->size = nb_desc;
+	ring0->size &= ~VMXNET3_RING_SIZE_MASK;
+	ring1->size = ring0->size;
 
 	comp_ring->size = ring0->size + ring1->size;
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 1/5] NUMA: Set numa node value for system which not support NUMA.
From: nickcooper-zhangtonghao @ 2017-01-05 10:42 UTC (permalink / raw)
  To: dev; +Cc: nickcooper-zhangtonghao

The NUMA node information for PCI devices provided through
sysfs is invalid for AMD Opteron(TM) Processor 62xx and 63xx
on Red Hat Enterprise Linux 6, and VMs on some hypervisors.

Signed-off-by: nickcooper-zhangtonghao <nic@opencloud.tech>
---
 lib/librte_eal/linuxapp/eal/eal_pci.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 4350134..3ffac23 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -317,7 +317,13 @@
 			free(dev);
 			return -1;
 		}
-		dev->device.numa_node = tmp;
+        /* The NUMA node information for PCI devices provided through
+         * sysfs is invalid for AMD Opteron(TM) Processor 62xx and 63xx
+         * on Red Hat Enterprise Linux 6, and VMs on some hypervisors.
+         * In the upstream linux kernel, the numa_node is an integer,
+         * which data type is int, not unsigned long.
+         */
+		dev->device.numa_node = (int)tmp > 0 ? (int)tmp : 0;
 	}
 
 	/* parse resources */
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 3/5] vmxnet3: Avoid segfault caused by vmxnet3_dev_rx_queue_setup.
From: nickcooper-zhangtonghao @ 2017-01-05 10:43 UTC (permalink / raw)
  To: dev; +Cc: nickcooper-zhangtonghao
In-Reply-To: <1483612983-3545-1-git-send-email-nic@opencloud.tech>

We should allocate RX ring for max possible mumber of hardware
descriptors. If we config RX queue with 2048 RX queue size,
and 4096 soon, there will be segment fault when calling other
ethernet API (e.g. rte_eth_dev_start).

Signed-off-by: nickcooper-zhangtonghao <nic@opencloud.tech>
---
 drivers/net/vmxnet3/vmxnet3_rxtx.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index e83ac05..9822fa0 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -977,8 +977,11 @@
 	comp_ring->next2proc = 0;
 	comp_ring->gen = VMXNET3_INIT_GEN;
 
-	size = sizeof(struct Vmxnet3_RxDesc) * (ring0->size + ring1->size);
-	size += sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
+    /* Allocate RX ring for max possible mumber of hardware descriptors. */
+	size = sizeof(struct Vmxnet3_RxDesc) *
+        (VMXNET3_RX_RING_MAX_SIZE * VMXNET3_RX_CMDRING_SIZE);
+	size += sizeof(struct Vmxnet3_RxCompDesc) *
+        (VMXNET3_RX_RING_MAX_SIZE * VMXNET3_RX_CMDRING_SIZE);
 
 	mz = ring_dma_zone_reserve(dev, "rxdesc", queue_idx, size, socket_id);
 	if (mz == NULL) {
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH] net/mlx5: add support for ConnectX-5 NICs
From: Adrien Mazarguil @ 2017-01-05 10:38 UTC (permalink / raw)
  To: Yongseok Koh; +Cc: ferruh.yigit, dev
In-Reply-To: <20170105023219.10146-1-yskoh@mellanox.com>

Hi Koh,

On Wed, Jan 04, 2017 at 06:32:19PM -0800, Yongseok Koh wrote:
> Add PCI device ID for ConnectX-5 and enable multi-packet send for PF and
> VF.
> 
> Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
> ---
> 
> ConnectX-5 is a newly announced NIC of Mellanox. This patch includes basic
> enablement of ConnectX-5.
> 
>  drivers/net/mlx5/mlx5.c        | 42 +++++++++++++++++++++++++++++++++++++-----
>  drivers/net/mlx5/mlx5.h        |  4 ++++
>  drivers/net/mlx5/mlx5_ethdev.c |  7 ++-----
>  drivers/net/mlx5/mlx5_txq.c    |  2 +-
>  4 files changed, 44 insertions(+), 11 deletions(-)
[...]

While the changes made by this patch are fine, it is missing the mandatory
update of related documentation, specifically:

- doc/guides/nics/mlx5.rst: places where ConnectX-4 is also mentioned must
  be updated.

- doc/guides/rel_notes/release_17_02.rst: support for ConnectX-5 must appear
  somewhere (you can use past release notes as a template).

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply

* Re: Running DPDK as an unprivileged user
From: Sergio Gonzalez Monroy @ 2017-01-05 10:16 UTC (permalink / raw)
  To: Walker, Benjamin, Tan, Jianfeng, dev@dpdk.org
In-Reply-To: <d3ec1c98-a394-00c5-36a8-6ec9d839b65c@intel.com>

On 05/01/2017 10:09, Sergio Gonzalez Monroy wrote:
> On 04/01/2017 21:34, Walker, Benjamin wrote:
>> On Wed, 2017-01-04 at 19:39 +0800, Tan, Jianfeng wrote:
>>> Hi Benjamin,
>>>
>>>
>>> On 12/30/2016 4:41 AM, Walker, Benjamin wrote:
>>>> DPDK today begins by allocating all of the required
>>>> hugepages, then finds all of the physical addresses for
>>>> those hugepages using /proc/self/pagemap, sorts the
>>>> hugepages by physical address, then remaps the pages to
>>>> contiguous virtual addresses. Later on and if vfio is
>>>> enabled, it asks vfio to pin the hugepages and to set their
>>>> DMA addresses in the IOMMU to be the physical addresses
>>>> discovered earlier. Of course, running as an unprivileged
>>>> user means all of the physical addresses in
>>>> /proc/self/pagemap are just 0, so this doesn't end up
>>>> working. Further, there is no real reason to choose the
>>>> physical address as the DMA address in the IOMMU - it would
>>>> be better to just count up starting at 0.
>>> Why not just using virtual address as the DMA address in this case to
>>> avoid maintaining another kind of addresses?
>> That's a valid choice, although I'm just storing the DMA address in the
>> physical address field that already exists. You either have a physical
>> address or a DMA address and never both.
>>
>>>>    Also, because the
>>>> pages are pinned after the virtual to physical mapping is
>>>> looked up, there is a window where a page could be moved.
>>>> Hugepage mappings can be moved on more recent kernels (at
>>>> least 4.x), and the reliability of hugepages having static
>>>> mappings decreases with every kernel release.
>>> Do you mean kernel might take back a physical page after mapping it 
>>> to a
>>> virtual page (maybe copy the data to another physical page)? Could you
>>> please show some links or kernel commits?
>> Yes - the kernel can move a physical page to another physical page
>> and change the virtual mapping at any time. For a concise example
>> see 'man migrate_pages(2)', or for a more serious example the code
>> that performs memory page compaction in the kernel which was
>> recently extended to support hugepages.
>>
>> Before we go down the path of me proving that the mapping isn't static,
>> let me turn that line of thinking around. Do you have any documentation
>> demonstrating that the mapping is static? It's not static for 4k 
>> pages, so
>> why are we assuming that it is static for 2MB pages? I understand that
>> it happened to be static for some versions of the kernel, but my 
>> understanding
>> is that this was purely by coincidence and never by intention.
>
> It looks to me as if you are talking about Transparent hugepages, and 
> not hugetlbfs managed hugepages (DPDK usecase).
> AFAIK memory (hugepages) managed by hugetlbfs is not compacted and/or 
> moved, they are not part of the kernel memory management.
>

Please forgive my loose/poor use of words here when saying that "they 
are not part of the kernel memory management", I mean to say that
they are not part of the kernel memory management process you were 
mentioning, ie. compacting, moving, etc.

Sergio

> So again, do you have some references to code/articles where this 
> "dynamic" behavior of hugepages managed by hugetlbfs is mentioned?
>
> Sergio
>
>>>> Note that this
>>>> probably means that using uio on recent kernels is subtly
>>>> broken and cannot be supported going forward because there
>>>> is no uio mechanism to pin the memory.
>>>>
>>>> The first open question I have is whether DPDK should allow
>>>> uio at all on recent (4.x) kernels. My current understanding
>>>> is that there is no way to pin memory and hugepages can now
>>>> be moved around, so uio would be unsafe. What does the
>>>> community think here?
>>>>
>>>> My second question is whether the user should be allowed to
>>>> mix uio and vfio usage simultaneously. For vfio, the
>>>> physical addresses are really DMA addresses and are best
>>>> when arbitrarily chosen to appear sequential relative to
>>>> their virtual addresses.
>>> Why "sequential relative to their virtual addresses"? IOMMU table is 
>>> for
>>> DMA addr -> physical addr mapping. So we need to DMA addresses
>>> "sequential relative to their physical addresses"? Based on your above
>>> analysis on how hugepages are initialized, virtual addresses is a good
>>> candidate for DMA address?
>> The code already goes through a separate organizational step on all of
>> the pages that remaps the virtual addresses such that they're sequential
>> relative to the physical backing pages, so this mostly ends up as the 
>> same
>> thing.
>> Choosing to use the virtual address is a totally valid choice, but I 
>> worry it
>> may lead to confusion during debugging or in a multi-process scenario.
>> I'm open to making this choice instead of starting from zero, though.
>>
>>> Thanks,
>>> Jianfeng
>
>

^ permalink raw reply

* Re: Running DPDK as an unprivileged user
From: Sergio Gonzalez Monroy @ 2017-01-05 10:09 UTC (permalink / raw)
  To: Walker, Benjamin, Tan, Jianfeng, dev@dpdk.org
In-Reply-To: <1483565664.9482.3.camel@intel.com>

On 04/01/2017 21:34, Walker, Benjamin wrote:
> On Wed, 2017-01-04 at 19:39 +0800, Tan, Jianfeng wrote:
>> Hi Benjamin,
>>
>>
>> On 12/30/2016 4:41 AM, Walker, Benjamin wrote:
>>> DPDK today begins by allocating all of the required
>>> hugepages, then finds all of the physical addresses for
>>> those hugepages using /proc/self/pagemap, sorts the
>>> hugepages by physical address, then remaps the pages to
>>> contiguous virtual addresses. Later on and if vfio is
>>> enabled, it asks vfio to pin the hugepages and to set their
>>> DMA addresses in the IOMMU to be the physical addresses
>>> discovered earlier. Of course, running as an unprivileged
>>> user means all of the physical addresses in
>>> /proc/self/pagemap are just 0, so this doesn't end up
>>> working. Further, there is no real reason to choose the
>>> physical address as the DMA address in the IOMMU - it would
>>> be better to just count up starting at 0.
>> Why not just using virtual address as the DMA address in this case to
>> avoid maintaining another kind of addresses?
> That's a valid choice, although I'm just storing the DMA address in the
> physical address field that already exists. You either have a physical
> address or a DMA address and never both.
>
>>>    Also, because the
>>> pages are pinned after the virtual to physical mapping is
>>> looked up, there is a window where a page could be moved.
>>> Hugepage mappings can be moved on more recent kernels (at
>>> least 4.x), and the reliability of hugepages having static
>>> mappings decreases with every kernel release.
>> Do you mean kernel might take back a physical page after mapping it to a
>> virtual page (maybe copy the data to another physical page)? Could you
>> please show some links or kernel commits?
> Yes - the kernel can move a physical page to another physical page
> and change the virtual mapping at any time. For a concise example
> see 'man migrate_pages(2)', or for a more serious example the code
> that performs memory page compaction in the kernel which was
> recently extended to support hugepages.
>
> Before we go down the path of me proving that the mapping isn't static,
> let me turn that line of thinking around. Do you have any documentation
> demonstrating that the mapping is static? It's not static for 4k pages, so
> why are we assuming that it is static for 2MB pages? I understand that
> it happened to be static for some versions of the kernel, but my understanding
> is that this was purely by coincidence and never by intention.

It looks to me as if you are talking about Transparent hugepages, and 
not hugetlbfs managed hugepages (DPDK usecase).
AFAIK memory (hugepages) managed by hugetlbfs is not compacted and/or 
moved, they are not part of the kernel memory management.

So again, do you have some references to code/articles where this 
"dynamic" behavior of hugepages managed by hugetlbfs is mentioned?

Sergio

>>> Note that this
>>> probably means that using uio on recent kernels is subtly
>>> broken and cannot be supported going forward because there
>>> is no uio mechanism to pin the memory.
>>>
>>> The first open question I have is whether DPDK should allow
>>> uio at all on recent (4.x) kernels. My current understanding
>>> is that there is no way to pin memory and hugepages can now
>>> be moved around, so uio would be unsafe. What does the
>>> community think here?
>>>
>>> My second question is whether the user should be allowed to
>>> mix uio and vfio usage simultaneously. For vfio, the
>>> physical addresses are really DMA addresses and are best
>>> when arbitrarily chosen to appear sequential relative to
>>> their virtual addresses.
>> Why "sequential relative to their virtual addresses"? IOMMU table is for
>> DMA addr -> physical addr mapping. So we need to DMA addresses
>> "sequential relative to their physical addresses"? Based on your above
>> analysis on how hugepages are initialized, virtual addresses is a good
>> candidate for DMA address?
> The code already goes through a separate organizational step on all of
> the pages that remaps the virtual addresses such that they're sequential
> relative to the physical backing pages, so this mostly ends up as the same
> thing.
> Choosing to use the virtual address is a totally valid choice, but I worry it
> may lead to confusion during debugging or in a multi-process scenario.
> I'm open to making this choice instead of starting from zero, though.
>
>> Thanks,
>> Jianfeng

^ permalink raw reply

* Re: [PATCH v5 3/8] ethdev: reserve capability flags for PMD-specific API
From: Tiwei Bie @ 2017-01-05 10:05 UTC (permalink / raw)
  To: thomas.monjalon@6wind.com, olivier.matz@6wind.com
  Cc: Adrien Mazarguil, Ananyev, Konstantin, dev@dpdk.org, Lu, Wenzhuo,
	Mcnamara, John, Zhang, Helin, Dai, Wei, Wang, Xiao W
In-Reply-To: <20170105083322.GK12822@6wind.com>

On Thu, Jan 05, 2017 at 09:33:22AM +0100, Adrien Mazarguil wrote:
> On Thu, Jan 05, 2017 at 07:56:08AM +0800, Tiwei Bie wrote:
> > On Thu, Jan 05, 2017 at 01:44:18AM +0800, Ananyev, Konstantin wrote:
> > [...]
> > > > >
> > > > > I understand that.
> > > > > My question was: suppose user would like to create a bonded device over 2 NICs.
> > > > > One of them is ixgbe, while other would be some other type.
> > > > > In future get_dev_info() for each of them might return DEV_RX_OFFLOAD_RESERVED_0  bit as set.
> > > > > But it would mean completely different thing.
> > > > > How bonded device would know that to deal properly?
> > > > >
> > > > > Another example - user has 2 NICs of different type and would like to send the same packet on both of them simultaneously.
> > > > > As PKT_TX_RESERVED might mean different things for these devices, and user would like to use let say
> > > > > PKT_TX_IXGBE_MACSEC on one of them, he would need to do a copy of them, instead just increment a refcnt.
> > > > >
> > > > > Similar issues might arise at RX handling: user got a packet with PKT_RX_RESERVED_0 set.
> > > > > What does it really mean if there are different NIC types in the system?
> > > > > The only way to answer that question, as I can see,  is to keep track from what NIC that packet was received.
> > > > > Which I suppose, is not always convenient.
> > > > >
> > > > 
> > > > The main purpose is to put the PMD-specific APIs in a separate
> > > > namespace instead of mixing the PMD-specific APIs and global APIs
> > > > up, and also save the bits in mbuf.ol_flags.
> > > > 
> > > > There are other ways to achieve this goal, such as introducing
> > > > the PMD specific ol_flags in mbuf second cache line as you said.
> > > > I just thought defining some reserved bits seems to be the most
> > > > simple way which won't introduce many changes.
> > > > 
> > > > What's your suggestions? Should I just revert the changes and
> > > > define the generic flags directly?
> > > 
> > > Yes, that would be my preference.
> > > As I said above - spending extra bit in ol_flags  doesn't look like a big problem to me.
> > > In return there would be no need to consider how to handle all that confusing scenarios in future.
> > 
> > Okay. I'll update my patches. Thanks a lot for your comments.
> 
> Well, I do not agree with Konstantin (no one saw this coming eh?) and do not
> think you need to update your series again.
> 

Hi Adrien,

Thank you very much! :-)

Hi Thomas and Olivier,

I don't have strong opinions here, although I prefer to put
the PMD-specific APIs in a separate namespace. I'd like to
hear or follow your opinions since you are the maintainers
of ethdev and mbuf.

Best regards,
Tiwei Bie

> PMD-specific symbols have nothing to do in the global namespace in my
> opinion, they are not versioned and may evolve without notice. Neither
> applications nor the bonding PMD can rely on them. That's the trade-off.
> 
> Therefore until APIs are made global, the safe compromise is to define
> neutral, reserved symbols that any PMD can use to implement their own
> temporary APIs for testing purposes. These can be renamed later without
> changing their value as long as a single PMD uses them.
> 
> -- 
> Adrien Mazarguil
> 6WIND

^ permalink raw reply

* [PATCH v3 5/5] test: add sgl unit tests for crypto devices
From: Tomasz Kulasek @ 2017-01-05  9:12 UTC (permalink / raw)
  To: dev; +Cc: Daniel Mrzyglod
In-Reply-To: <1483607556-21460-1-git-send-email-tomaszx.kulasek@intel.com>

This patch provides unit tests for set of cipher/hash combinations covering
currently implemented crypto PMD's and allowing to verify scatter gather
support.

Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
---
 app/test/test_cryptodev.c                  |  386 ++++++++++++++++++-
 app/test/test_cryptodev.h                  |  139 +++++++
 app/test/test_cryptodev_aes_test_vectors.h |   52 +++
 app/test/test_cryptodev_blockcipher.c      |  180 +++++----
 app/test/test_cryptodev_blockcipher.h      |    1 +
 app/test/test_cryptodev_gcm_test_vectors.h |  553 ++++++++++++++++++++++++++++
 6 files changed, 1241 insertions(+), 70 deletions(-)

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 3eaf1b7..4c9a54f 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -1736,6 +1736,10 @@ struct crypto_unittest_params {
 
 	TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv");
 
+	/* For OOP operation both buffers must have the same size */
+	if (ut_params->obuf)
+		rte_pktmbuf_prepend(ut_params->obuf, iv_pad_len);
+
 	memset(sym_op->cipher.iv.data, 0, iv_pad_len);
 	sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf);
 	sym_op->cipher.iv.length = iv_pad_len;
@@ -2557,6 +2561,83 @@ struct crypto_unittest_params {
 }
 
 static int
+test_kasumi_encryption_sgl(const struct kasumi_test_data *tdata)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+
+	unsigned int plaintext_pad_len;
+	unsigned int plaintext_len;
+
+	uint8_t buffer[10000];
+	const uint8_t *ciphertext;
+
+	struct rte_cryptodev_info dev_info;
+
+	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
+		printf("Device doesn't support scatter-gather. "
+				"Test Skipped.\n");
+		return 0;
+	}
+
+	/* Create KASUMI session */
+	retval = create_wireless_algo_cipher_session(ts_params->valid_devs[0],
+					RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+					RTE_CRYPTO_CIPHER_KASUMI_F8,
+					tdata->key.data, tdata->key.len);
+	if (retval < 0)
+		return retval;
+
+	plaintext_len = ceil_byte_length(tdata->plaintext.len);
+
+
+	/* Append data which is padded to a multiple */
+	/* of the algorithms block size */
+	plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 8);
+
+	ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool,
+			plaintext_pad_len, 10);
+
+	pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data);
+
+	/* Create KASUMI operation */
+	retval = create_wireless_algo_cipher_operation(tdata->iv.data,
+					tdata->iv.len,
+					tdata->plaintext.len,
+					tdata->validCipherOffsetLenInBits.len,
+					RTE_CRYPTO_CIPHER_KASUMI_F8);
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+						ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf");
+
+	ut_params->obuf = ut_params->op->sym->m_dst;
+
+	if (ut_params->obuf)
+		ciphertext = rte_pktmbuf_read(ut_params->obuf, tdata->iv.len,
+				plaintext_len, buffer);
+	else
+		ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len,
+				plaintext_len, buffer);
+
+	/* Validate obuf */
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len);
+
+		/* Validate obuf */
+		TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(
+			ciphertext,
+			tdata->ciphertext.data,
+			tdata->validCipherLenInBits.len,
+			"KASUMI Ciphertext data not as expected");
+		return 0;
+}
+
+static int
 test_kasumi_encryption_oop(const struct kasumi_test_data *tdata)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -2625,6 +2706,81 @@ struct crypto_unittest_params {
 }
 
 static int
+test_kasumi_encryption_oop_sgl(const struct kasumi_test_data *tdata)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+	unsigned int plaintext_pad_len;
+	unsigned int plaintext_len;
+
+	const uint8_t *ciphertext;
+	uint8_t buffer[2048];
+
+	struct rte_cryptodev_info dev_info;
+
+	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
+		printf("Device doesn't support scatter-gather. "
+				"Test Skipped.\n");
+		return 0;
+	}
+
+	/* Create KASUMI session */
+	retval = create_wireless_algo_cipher_session(ts_params->valid_devs[0],
+					RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+					RTE_CRYPTO_CIPHER_KASUMI_F8,
+					tdata->key.data, tdata->key.len);
+	if (retval < 0)
+		return retval;
+
+	plaintext_len = ceil_byte_length(tdata->plaintext.len);
+	/* Append data which is padded to a multiple */
+	/* of the algorithms block size */
+	plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 8);
+
+	ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool,
+			plaintext_pad_len, 10);
+	ut_params->obuf = create_segmented_mbuf(ts_params->mbuf_pool,
+			plaintext_pad_len, 3);
+
+	/* Append data which is padded to a multiple */
+	/* of the algorithms block size */
+	pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data);
+
+	/* Create KASUMI operation */
+	retval = create_wireless_algo_cipher_operation_oop(tdata->iv.data,
+					tdata->iv.len,
+					tdata->plaintext.len,
+					tdata->validCipherOffsetLenInBits.len,
+					RTE_CRYPTO_CIPHER_KASUMI_F8);
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+						ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf");
+
+	ut_params->obuf = ut_params->op->sym->m_dst;
+	if (ut_params->obuf)
+		ciphertext = rte_pktmbuf_read(ut_params->obuf, tdata->iv.len,
+				plaintext_pad_len, buffer);
+	else
+		ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len,
+				plaintext_pad_len, buffer);
+
+	/* Validate obuf */
+	TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(
+		ciphertext,
+		tdata->ciphertext.data,
+		tdata->validCipherLenInBits.len,
+		"KASUMI Ciphertext data not as expected");
+	return 0;
+}
+
+
+static int
 test_kasumi_decryption_oop(const struct kasumi_test_data *tdata)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -2897,6 +3053,85 @@ struct crypto_unittest_params {
 	return 0;
 }
 
+static int
+test_snow3g_encryption_oop_sgl(const struct snow3g_test_data *tdata)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+	unsigned int plaintext_pad_len;
+	unsigned int plaintext_len;
+	uint8_t buffer[10000];
+	const uint8_t *ciphertext;
+
+	struct rte_cryptodev_info dev_info;
+
+	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
+		printf("Device doesn't support scatter-gather. "
+				"Test Skipped.\n");
+		return 0;
+	}
+
+	/* Create SNOW 3G session */
+	retval = create_wireless_algo_cipher_session(ts_params->valid_devs[0],
+					RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+					RTE_CRYPTO_CIPHER_SNOW3G_UEA2,
+					tdata->key.data, tdata->key.len);
+	if (retval < 0)
+		return retval;
+
+	plaintext_len = ceil_byte_length(tdata->plaintext.len);
+	/* Append data which is padded to a multiple of */
+	/* the algorithms block size */
+	plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16);
+
+	ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool,
+			plaintext_pad_len, 10);
+	ut_params->obuf = create_segmented_mbuf(ts_params->mbuf_pool,
+			plaintext_pad_len, 3);
+
+	TEST_ASSERT_NOT_NULL(ut_params->ibuf,
+			"Failed to allocate input buffer in mempool");
+	TEST_ASSERT_NOT_NULL(ut_params->obuf,
+			"Failed to allocate output buffer in mempool");
+
+	pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data);
+
+	/* Create SNOW 3G operation */
+	retval = create_wireless_algo_cipher_operation_oop(tdata->iv.data,
+					tdata->iv.len,
+					tdata->validCipherLenInBits.len,
+					tdata->validCipherOffsetLenInBits.len,
+					RTE_CRYPTO_CIPHER_SNOW3G_UEA2);
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+						ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf");
+
+	ut_params->obuf = ut_params->op->sym->m_dst;
+	if (ut_params->obuf)
+		ciphertext = rte_pktmbuf_read(ut_params->obuf, tdata->iv.len,
+				plaintext_len, buffer);
+	else
+		ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len,
+				plaintext_len, buffer);
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len);
+
+	/* Validate obuf */
+	TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(
+		ciphertext,
+		tdata->ciphertext.data,
+		tdata->validDataLenInBits.len,
+		"SNOW 3G Ciphertext data not as expected");
+
+	return 0;
+}
+
 /* Shift right a buffer by "offset" bits, "offset" < 8 */
 static void
 buffer_shift_right(uint8_t *buffer, uint32_t length, uint8_t offset)
@@ -3552,6 +3787,84 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 }
 
 static int
+test_zuc_encryption_sgl(const struct zuc_test_data *tdata)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+
+	unsigned int plaintext_pad_len;
+	unsigned int plaintext_len;
+	const uint8_t *ciphertext;
+	uint8_t ciphertext_buffer[2048];
+	struct rte_cryptodev_info dev_info;
+
+	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
+		printf("Device doesn't support scatter-gather. "
+				"Test Skipped.\n");
+		return 0;
+	}
+
+	plaintext_len = ceil_byte_length(tdata->plaintext.len);
+
+	/* Append data which is padded to a multiple */
+	/* of the algorithms block size */
+	plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 8);
+
+	ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool,
+			plaintext_pad_len, 10);
+
+	pktmbuf_write(ut_params->ibuf, 0, plaintext_len,
+			tdata->plaintext.data);
+
+	/* Create ZUC session */
+	retval = create_wireless_algo_cipher_session(ts_params->valid_devs[0],
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+			RTE_CRYPTO_CIPHER_ZUC_EEA3,
+			tdata->key.data, tdata->key.len);
+	if (retval < 0)
+		return retval;
+
+	/* Clear mbuf payload */
+
+	pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data);
+
+	/* Create ZUC operation */
+	retval = create_wireless_algo_cipher_operation(tdata->iv.data,
+			tdata->iv.len, tdata->plaintext.len,
+			tdata->validCipherOffsetLenInBits.len,
+			RTE_CRYPTO_CIPHER_ZUC_EEA3);
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+						ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf");
+
+	ut_params->obuf = ut_params->op->sym->m_dst;
+	if (ut_params->obuf)
+		ciphertext = rte_pktmbuf_read(ut_params->obuf,
+			tdata->iv.len, plaintext_len, ciphertext_buffer);
+	else
+		ciphertext = rte_pktmbuf_read(ut_params->ibuf,
+			tdata->iv.len, plaintext_len, ciphertext_buffer);
+
+	/* Validate obuf */
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len);
+
+	/* Validate obuf */
+	TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(
+		ciphertext,
+		tdata->ciphertext.data,
+		tdata->validCipherLenInBits.len,
+		"ZUC Ciphertext data not as expected");
+
+	return 0;
+}
+
+static int
 test_zuc_authentication(const struct zuc_hash_test_data *tdata)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -3619,12 +3932,24 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 }
 
 static int
+test_kasumi_encryption_test_case_1_sgl(void)
+{
+	return test_kasumi_encryption_sgl(&kasumi_test_case_1);
+}
+
+static int
 test_kasumi_encryption_test_case_1_oop(void)
 {
 	return test_kasumi_encryption_oop(&kasumi_test_case_1);
 }
 
 static int
+test_kasumi_encryption_test_case_1_oop_sgl(void)
+{
+	return test_kasumi_encryption_oop_sgl(&kasumi_test_case_1);
+}
+
+static int
 test_kasumi_encryption_test_case_2(void)
 {
 	return test_kasumi_encryption(&kasumi_test_case_2);
@@ -3696,6 +4021,13 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 }
 
 static int
+test_snow3g_encryption_test_case_1_oop_sgl(void)
+{
+	return test_snow3g_encryption_oop_sgl(&snow3g_test_case_1);
+}
+
+
+static int
 test_snow3g_encryption_test_case_1_offset_oop(void)
 {
 	return test_snow3g_encryption_offset_oop(&snow3g_test_case_1);
@@ -3815,6 +4147,12 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 }
 
 static int
+test_zuc_encryption_test_case_6_sgl(void)
+{
+	return test_zuc_encryption_sgl(&zuc_test_case_1);
+}
+
+static int
 test_zuc_hash_generate_test_case_1(void)
 {
 	return test_zuc_authentication(&zuc_hash_test_case_1);
@@ -3998,12 +4336,21 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 
 	struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
 
-	sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
-			ut_params->ibuf, auth_tag_len);
-	TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
-			"no room to append digest");
-	sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
-			ut_params->ibuf, data_pad_len);
+	if (ut_params->obuf) {
+		sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+				ut_params->obuf, auth_tag_len);
+		TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+				"no room to append digest");
+		sym_op->auth.digest.phys_addr = sgl_pktmbuf_mtophys_offset(
+				ut_params->obuf, data_pad_len);
+	} else {
+		sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+				ut_params->ibuf, auth_tag_len);
+		TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+				"no room to append digest");
+		sym_op->auth.digest.phys_addr = sgl_pktmbuf_mtophys_offset(
+				ut_params->ibuf, data_pad_len);
+	}
 	sym_op->auth.digest.length = auth_tag_len;
 
 	if (op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
@@ -4050,6 +4397,11 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 	TEST_HEXDUMP(stdout, "aad:",
 			sym_op->auth.aad.data, aad_len);
 
+	if (ut_params->obuf) {
+		rte_pktmbuf_prepend(ut_params->obuf, iv_pad_len);
+		rte_pktmbuf_prepend(ut_params->obuf, aad_buffer_len);
+	}
+
 	sym_op->cipher.data.length = data_len;
 	sym_op->cipher.data.offset = aad_buffer_len + iv_pad_len;
 
@@ -6312,6 +6664,14 @@ struct test_crypto_vector {
 }
 
 static int
+test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg(void)
+{
+	return test_AES_GCM_authenticated_encryption_SGL(
+			&gcm_test_case_8, OUT_OF_PLACE, 400,
+			gcm_test_case_8.plaintext.len);
+}
+
+static int
 test_AES_GCM_auth_encrypt_SGL_in_place_1500B(void)
 {
 
@@ -6683,6 +7043,10 @@ struct test_crypto_vector {
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_AES_GMAC_authentication_verify_test_case_4),
 
+		/** Scatter-Gather */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg),
+
 		/** Negative tests */
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			authentication_verify_HMAC_SHA1_fail_data_corrupt),
@@ -6751,6 +7115,8 @@ struct test_crypto_vector {
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_kasumi_encryption_test_case_1),
 		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_kasumi_encryption_test_case_1_sgl),
+		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_kasumi_encryption_test_case_2),
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_kasumi_encryption_test_case_3),
@@ -6773,6 +7139,10 @@ struct test_crypto_vector {
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_kasumi_encryption_test_case_1_oop),
 		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_kasumi_encryption_test_case_1_oop_sgl),
+
+
+		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_kasumi_decryption_test_case_1_oop),
 
 		/** KASUMI hash only (UIA1) */
@@ -6825,6 +7195,8 @@ struct test_crypto_vector {
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_snow3g_encryption_test_case_1_oop),
 		TEST_CASE_ST(ut_setup, ut_teardown,
+				test_snow3g_encryption_test_case_1_oop_sgl),
+		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_snow3g_decryption_test_case_1_oop),
 
 		TEST_CASE_ST(ut_setup, ut_teardown,
@@ -6902,6 +7274,8 @@ struct test_crypto_vector {
 			test_zuc_hash_generate_test_case_4),
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_zuc_hash_generate_test_case_5),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_zuc_encryption_test_case_6_sgl),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h
index a9089aa..77cd826 100644
--- a/app/test/test_cryptodev.h
+++ b/app/test/test_cryptodev.h
@@ -71,4 +71,143 @@
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA384		(24)
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA512		(32)
 
+/**
+ * Write (spread) data from buffer to mbuf data
+ *
+ * @param mbuf
+ *   Destination mbuf
+ * @param offset
+ *   Start offset in mbuf
+ * @param len
+ *   Number of bytes to copy
+ * @param buffer
+ *   Continuous source buffer
+ */
+static inline void
+pktmbuf_write(struct rte_mbuf *mbuf, int offset, int len, const uint8_t *buffer)
+{
+	int n = len;
+	int l;
+	struct rte_mbuf *m;
+	char *dst;
+
+	for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next)
+		offset -= m->data_len;
+
+	l = m->data_len - offset;
+
+	/* copy data from first segment */
+	dst = rte_pktmbuf_mtod_offset(m, char *, offset);
+	if (len <= l) {
+		rte_memcpy(dst, buffer, len);
+		return;
+	}
+
+	rte_memcpy(dst, buffer, l);
+	buffer += l;
+	n -= l;
+
+	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		dst = rte_pktmbuf_mtod(m, char *);
+		l = m->data_len;
+		if (n < l) {
+			rte_memcpy(dst, buffer, n);
+			return;
+		}
+		rte_memcpy(dst, buffer, l);
+		buffer += l;
+		n -= l;
+	}
+}
+
+static inline uint8_t *
+sgl_pktmbuf_mtod_offset(struct rte_mbuf *mbuf, int offset) {
+	struct rte_mbuf *m;
+
+	for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next)
+		offset -= m->data_len;
+
+	if (!m) {
+		printf("sgl_pktmbuf_mtod_offset: offset out of buffer\n");
+		return NULL;
+	}
+	return rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+}
+
+static inline phys_addr_t
+sgl_pktmbuf_mtophys_offset(struct rte_mbuf *mbuf, int offset) {
+	struct rte_mbuf *m;
+
+	for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next)
+		offset -= m->data_len;
+
+	if (!m) {
+		printf("sgl_pktmbuf_mtophys_offset: offset out of buffer\n");
+		return 0;
+	}
+	return rte_pktmbuf_mtophys_offset(m, offset);
+}
+
+static inline struct rte_mbuf *
+create_segmented_mbuf(struct rte_mempool *mbuf_pool, int pkt_len,
+		int nb_segs) {
+
+	struct rte_mbuf *m = NULL, *mbuf = NULL;
+	uint8_t *dst;
+	int data_len = 0;
+	int i, size;
+	int t_len;
+
+	if (pkt_len < 1) {
+		printf("Packet size must be 1 or more (is %d)\n", pkt_len);
+		return NULL;
+	}
+
+	if (nb_segs < 1) {
+		printf("Number of segments must be 1 or more (is %d)\n",
+				nb_segs);
+		return NULL;
+	}
+
+	t_len = pkt_len >= nb_segs ? pkt_len / nb_segs : 1;
+	size = pkt_len;
+
+	/* Create chained mbuf_src and fill it generated data */
+	for (i = 0; size > 0; i++) {
+
+		m = rte_pktmbuf_alloc(mbuf_pool);
+		if (i == 0)
+			mbuf = m;
+
+		if (!m) {
+			printf("Cannot create segment for source mbuf");
+			goto fail;
+		}
+
+		/* Make sure if tailroom is zeroed */
+		memset(rte_pktmbuf_mtod(m, uint8_t *), 0,
+				rte_pktmbuf_tailroom(m));
+
+		data_len = size > t_len ? t_len : size;
+		dst = (uint8_t *)rte_pktmbuf_append(m, data_len);
+		if (!dst) {
+			printf("Cannot append %d bytes to the mbuf\n",
+					data_len);
+			goto fail;
+		}
+
+		if (mbuf != m)
+			rte_pktmbuf_chain(mbuf, m);
+
+		size -= data_len;
+
+	}
+	return mbuf;
+
+fail:
+	if (mbuf)
+		rte_pktmbuf_free(mbuf);
+	return NULL;
+}
+
 #endif /* TEST_CRYPTODEV_H_ */
diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h
index 898aae1..e566548 100644
--- a/app/test/test_cryptodev_aes_test_vectors.h
+++ b/app/test/test_cryptodev_aes_test_vectors.h
@@ -858,6 +858,16 @@
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
+		.test_descr = "AES-192-CTR XCBC Decryption Digest Verify "
+				"Scatter Gather",
+		.test_data = &aes_test_data_2,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SG |
+			BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
 		.test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest",
 		.test_data = &aes_test_data_3,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
@@ -883,6 +893,18 @@
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
+		.test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest "
+				"Scatter Gather",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SG |
+			BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+
+	},
+	{
 		.test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest "
 			"Verify",
 		.test_data = &aes_test_data_4,
@@ -926,6 +948,17 @@
 			BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
 	},
 	{
+		.test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest "
+				"Scatter Gather Sessionless",
+		.test_data = &aes_test_data_6,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS |
+			BLOCKCIPHER_TEST_FEATURE_SG |
+			BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
+	},
+	{
 		.test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest "
 			"Verify",
 		.test_data = &aes_test_data_6,
@@ -935,6 +968,17 @@
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
+		.test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest "
+			"Verify Scatter Gather",
+		.test_data = &aes_test_data_6,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SG |
+			BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
 		.test_descr = "AES-128-CBC XCBC Encryption Digest",
 		.test_data = &aes_test_data_7,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
@@ -1045,6 +1089,14 @@
 			BLOCKCIPHER_TEST_TARGET_PMD_MB
 	},
 	{
+		.test_descr = "AES-192-CBC Encryption Scater gather",
+		.test_data = &aes_test_data_10,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SG |
+			BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL
+	},
+	{
 		.test_descr = "AES-192-CBC Decryption",
 		.test_data = &aes_test_data_10,
 		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c
index 03dd073..2290c66 100644
--- a/app/test/test_cryptodev_blockcipher.c
+++ b/app/test/test_cryptodev_blockcipher.c
@@ -41,6 +41,7 @@
 #include <rte_cryptodev_pmd.h>
 
 #include "test.h"
+#include "test_cryptodev.h"
 #include "test_cryptodev_blockcipher.h"
 #include "test_cryptodev_aes_test_vectors.h"
 #include "test_cryptodev_des_test_vectors.h"
@@ -63,6 +64,7 @@
 	struct rte_crypto_sym_op *sym_op = NULL;
 	struct rte_crypto_op *op = NULL;
 	struct rte_cryptodev_sym_session *sess = NULL;
+	struct rte_cryptodev_info dev_info;
 
 	int status = TEST_SUCCESS;
 	const struct blockcipher_test_data *tdata = t->test_data;
@@ -72,6 +74,19 @@
 	uint32_t digest_len = 0;
 	char *buf_p = NULL;
 
+	int nb_segs = 3;
+	int nb_segs_oop = 1;
+
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
+		rte_cryptodev_info_get(dev_id, &dev_info);
+		if (!(dev_info.feature_flags &
+				RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
+			printf("Device doesn't support scatter-gather. "
+					"Test Skipped.\n");
+			return 0;
+		}
+	}
+
 	if (tdata->cipher_key.len)
 		memcpy(cipher_key, tdata->cipher_key.data,
 			tdata->cipher_key.len);
@@ -96,72 +111,112 @@
 	}
 
 	/* preparing data */
-	ibuf = rte_pktmbuf_alloc(mbuf_pool);
-	if (!ibuf) {
-		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
-			"line %u FAILED: %s",
-			__LINE__, "Allocation of rte_mbuf failed");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
 
 	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
 		buf_len += tdata->iv.len;
 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
 		buf_len += digest_len;
 
-	buf_p = rte_pktmbuf_append(ibuf, buf_len);
-	if (!buf_p) {
-		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
-			"line %u FAILED: %s",
-			__LINE__, "No room to append mbuf");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
 
-	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
-		rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len);
-		buf_p += tdata->iv.len;
-	}
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
+			ibuf = create_segmented_mbuf(mbuf_pool,
+					tdata->plaintext.len, nb_segs);
+			pktmbuf_write(ibuf, 0, tdata->plaintext.len,
+					tdata->plaintext.data);
+		} else {
+			ibuf = create_segmented_mbuf(mbuf_pool,
+					tdata->ciphertext.len, nb_segs);
+			pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
+					tdata->ciphertext.data);
+		}
 
-	/* only encryption requires plaintext.data input,
-	 * decryption/(digest gen)/(digest verify) use ciphertext.data
-	 * to be computed
-	 */
-	if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
-		rte_memcpy(buf_p, tdata->plaintext.data,
-			tdata->plaintext.len);
-		buf_p += tdata->plaintext.len;
-	} else {
-		rte_memcpy(buf_p, tdata->ciphertext.data,
-			tdata->ciphertext.len);
-		buf_p += tdata->ciphertext.len;
-	}
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+			rte_memcpy(rte_pktmbuf_prepend(ibuf, tdata->iv.len),
+					tdata->iv.data, tdata->iv.len);
+		}
 
-	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
-		rte_memcpy(buf_p, tdata->digest.data, digest_len);
-	else
-		memset(buf_p, 0, digest_len);
+		buf_p = rte_pktmbuf_append(ibuf, digest_len);
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
+			rte_memcpy(buf_p, tdata->digest.data, digest_len);
+		else
+			memset(buf_p, 0, digest_len);
 
-	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
-		obuf = rte_pktmbuf_alloc(mbuf_pool);
-		if (!obuf) {
-			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__,
-				"Allocation of rte_mbuf failed");
+	} else {
+		ibuf = rte_pktmbuf_alloc(mbuf_pool);
+		if (!ibuf) {
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+					"line %u FAILED: %s",
+					__LINE__,
+					"Allocation of rte_mbuf failed");
 			status = TEST_FAILED;
 			goto error_exit;
 		}
 
-		buf_p = rte_pktmbuf_append(obuf, buf_len);
+		buf_p = rte_pktmbuf_append(ibuf, buf_len);
 		if (!buf_p) {
-			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__,
-				"No room to append mbuf");
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+					"line %u FAILED: %s",
+					__LINE__, "No room to append mbuf");
 			status = TEST_FAILED;
 			goto error_exit;
 		}
-		memset(buf_p, 0, buf_len);
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+			rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len);
+			buf_p += tdata->iv.len;
+		}
+
+		/* only encryption requires plaintext.data input,
+		 * decryption/(digest gen)/(digest verify) use ciphertext.data
+		 * to be computed
+		 */
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
+			rte_memcpy(buf_p, tdata->plaintext.data,
+					tdata->plaintext.len);
+			buf_p += tdata->plaintext.len;
+		} else {
+			rte_memcpy(buf_p, tdata->ciphertext.data,
+					tdata->ciphertext.len);
+			buf_p += tdata->ciphertext.len;
+		}
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
+			rte_memcpy(buf_p, tdata->digest.data, digest_len);
+		else
+			memset(buf_p, 0, digest_len);
+	}
+
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
+		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
+			obuf = create_segmented_mbuf(mbuf_pool, buf_len,
+					nb_segs_oop);
+			if (!obuf) {
+				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+						"line %u FAILED: %s", __LINE__,
+						"Allocation of rte_mbuf failed");
+				status = TEST_FAILED;
+				goto error_exit;
+			}
+		} else {
+			obuf = rte_pktmbuf_alloc(mbuf_pool);
+			if (!obuf) {
+				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+						"line %u FAILED: %s", __LINE__,
+						"Allocation of rte_mbuf failed");
+				status = TEST_FAILED;
+				goto error_exit;
+			}
+			buf_p = rte_pktmbuf_append(obuf, buf_len);
+			if (!buf_p) {
+				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+						"line %u FAILED: %s", __LINE__,
+						"No room to append mbuf");
+				status = TEST_FAILED;
+				goto error_exit;
+			}
+			memset(buf_p, 0, buf_len);
+		}
 	}
 
 	/* Generate Crypto op data structure */
@@ -307,17 +362,17 @@
 
 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
 			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
-			sym_op->auth.digest.data = rte_pktmbuf_mtod_offset
-				(iobuf, uint8_t *, digest_offset);
+			sym_op->auth.digest.data = sgl_pktmbuf_mtod_offset
+				(iobuf, digest_offset);
 			sym_op->auth.digest.phys_addr =
-				rte_pktmbuf_mtophys_offset(iobuf,
+				sgl_pktmbuf_mtophys_offset(iobuf,
 					digest_offset);
 		} else {
 			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
-			sym_op->auth.digest.data = rte_pktmbuf_mtod_offset
-				(sym_op->m_src, uint8_t *, digest_offset);
+			sym_op->auth.digest.data = sgl_pktmbuf_mtod_offset
+				(sym_op->m_src, digest_offset);
 			sym_op->auth.digest.phys_addr =
-				rte_pktmbuf_mtophys_offset(sym_op->m_src,
+				sgl_pktmbuf_mtophys_offset(sym_op->m_src,
 					digest_offset);
 		}
 
@@ -386,13 +441,10 @@
 	}
 
 	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
-		uint8_t *crypto_res;
+		uint8_t buffer[2048];
 		const uint8_t *compare_ref;
 		uint32_t compare_len;
 
-		crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *,
-			tdata->iv.len);
-
 		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
 			compare_ref = tdata->ciphertext.data;
 			compare_len = tdata->ciphertext.len;
@@ -401,7 +453,8 @@
 			compare_len = tdata->plaintext.len;
 		}
 
-		if (memcmp(crypto_res, compare_ref, compare_len)) {
+		if (memcmp(rte_pktmbuf_read(iobuf, tdata->iv.len, compare_len,
+				buffer), compare_ref, compare_len)) {
 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
 				"FAILED: %s", __LINE__,
 				"Crypto data not as expected");
@@ -414,12 +467,11 @@
 		uint8_t *auth_res;
 
 		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
-			auth_res = rte_pktmbuf_mtod_offset(iobuf,
-				uint8_t *,
-				tdata->iv.len + tdata->ciphertext.len);
+			auth_res = sgl_pktmbuf_mtod_offset(iobuf,
+					tdata->iv.len + tdata->ciphertext.len);
 		else
-			auth_res = rte_pktmbuf_mtod_offset(iobuf,
-				uint8_t *, tdata->ciphertext.len);
+			auth_res = sgl_pktmbuf_mtod_offset(iobuf,
+					tdata->ciphertext.len);
 
 		if (memcmp(auth_res, tdata->digest.data, digest_len)) {
 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h
index fe97e4c..7256f6b 100644
--- a/app/test/test_cryptodev_blockcipher.h
+++ b/app/test/test_cryptodev_blockcipher.h
@@ -45,6 +45,7 @@
 #define BLOCKCIPHER_TEST_FEATURE_OOP			0x01
 #define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS	0x02
 #define BLOCKCIPHER_TEST_FEATURE_STOPPER	0x04 /* stop upon failing */
+#define BLOCKCIPHER_TEST_FEATURE_SG		0x08 /* Scatter Gather */
 
 #define BLOCKCIPHER_TEST_TARGET_PMD_MB		0x0001 /* Multi-buffer flag */
 #define BLOCKCIPHER_TEST_TARGET_PMD_QAT			0x0002 /* QAT flag */
diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h
index df984fc..45ea3d4 100644
--- a/app/test/test_cryptodev_gcm_test_vectors.h
+++ b/app/test/test_cryptodev_gcm_test_vectors.h
@@ -450,6 +450,559 @@ struct gmac_test_data {
 	}
 };
 
+static const struct gcm_test_data gcm_test_case_8 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88
+		},
+		.len = 12
+	},
+	.aad = {
+		.data = {
+			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+			0xfe, 0xed, 0xfa, 0xce
+		},
+		.len = 12
+	},
+	.plaintext = {
+		.data = {
+			0xC5, 0x34, 0x2E, 0x83, 0xEB, 0x4C, 0x02, 0x03,
+			0xF7, 0xB2, 0x57, 0x35, 0x26, 0x81, 0x63, 0xAE,
+			0x1F, 0xCD, 0x2D, 0x02, 0x91, 0x5A, 0xDB, 0x3A,
+			0xF1, 0x38, 0xD8, 0x75, 0x86, 0x20, 0xCC, 0x1E,
+			0xE6, 0xDC, 0xFF, 0xB5, 0xEA, 0x0E, 0x18, 0x7A,
+			0x86, 0x6C, 0xAB, 0x39, 0x2D, 0x90, 0xAC, 0x77,
+			0x5D, 0xED, 0x65, 0xB3, 0x05, 0x29, 0xBB, 0x09,
+			0xD0, 0x21, 0x74, 0x6A, 0x67, 0x1C, 0x95, 0x42,
+			0x55, 0xAD, 0xC8, 0x91, 0x28, 0xFE, 0x16, 0x9A,
+			0xE1, 0xCB, 0xCD, 0x68, 0x3B, 0xDF, 0x3E, 0x3A,
+			0x34, 0xFE, 0x9B, 0xFB, 0xF5, 0x15, 0x2A, 0x29,
+			0x18, 0x99, 0x24, 0xBF, 0xB6, 0x43, 0xDB, 0xD1,
+			0x69, 0x26, 0x1E, 0x31, 0x2C, 0x8C, 0x3C, 0x6B,
+			0x7F, 0x06, 0xA6, 0x03, 0xE2, 0x1A, 0x50, 0xFE,
+			0x7C, 0x69, 0xE5, 0x5F, 0x35, 0x93, 0xE9, 0x20,
+			0x14, 0xB1, 0xCA, 0x61, 0xE7, 0x9C, 0x89, 0x08,
+			0xD6, 0xB1, 0xC2, 0x63, 0x1B, 0x86, 0x5E, 0xF1,
+			0xF5, 0x23, 0x0E, 0x9B, 0xE5, 0xBD, 0x5D, 0x04,
+			0xF7, 0xEF, 0x8E, 0x46, 0xB0, 0x11, 0x4F, 0x69,
+			0x62, 0x35, 0x51, 0xB7, 0x24, 0xA2, 0x31, 0xD0,
+			0x32, 0x4E, 0xB8, 0x44, 0xC7, 0x59, 0xDE, 0x25,
+			0xEA, 0x2D, 0x00, 0x0E, 0xF1, 0x07, 0xBA, 0xBB,
+			0x9A, 0xBC, 0x4F, 0x57, 0xB7, 0x13, 0x57, 0xEF,
+			0xD9, 0xF6, 0x80, 0x69, 0xEA, 0xE8, 0x47, 0x9C,
+			0x51, 0x71, 0xE6, 0x8F, 0x69, 0x29, 0xB4, 0x60,
+			0xE8, 0x50, 0xE5, 0xD0, 0x9B, 0xD2, 0x62, 0x6F,
+			0x09, 0x5C, 0xD1, 0x4B, 0x85, 0xE2, 0xFD, 0xD3,
+			0xEB, 0x28, 0x55, 0x77, 0x97, 0xCA, 0xD6, 0xA8,
+			0xDC, 0x35, 0x68, 0xF7, 0x6A, 0xCF, 0x48, 0x3F,
+			0x49, 0x31, 0x00, 0x65, 0xB7, 0x31, 0x1A, 0x49,
+			0x75, 0xDE, 0xCE, 0x7F, 0x18, 0xB5, 0x31, 0x9A,
+			0x64, 0x6D, 0xE5, 0x49, 0x1D, 0x6D, 0xF2, 0x21,
+			0x9F, 0xF5, 0xFF, 0x7C, 0x41, 0x30, 0x33, 0x06,
+			0x7B, 0xA4, 0xD8, 0x99, 0xF6, 0xCC, 0xDF, 0xC4,
+			0x3F, 0xF3, 0xCD, 0xE7, 0x74, 0xC4, 0x4A, 0x19,
+			0x5C, 0xCA, 0x42, 0x31, 0xF1, 0x3B, 0x65, 0x1C,
+			0x3D, 0x56, 0x08, 0xBE, 0x15, 0x37, 0x23, 0x50,
+			0xD6, 0xA3, 0x57, 0x64, 0x25, 0xBE, 0xDA, 0xC2,
+			0x4E, 0xF5, 0x1A, 0xAD, 0x6F, 0x43, 0x78, 0x21,
+			0xF9, 0x36, 0x39, 0x1F, 0x5F, 0xF7, 0x1B, 0xA0,
+			0xEE, 0x8B, 0x4F, 0x8A, 0x9D, 0xD8, 0xED, 0x37,
+			0xCE, 0x0D, 0x70, 0xE0, 0x3F, 0xE7, 0x11, 0x30,
+			0x17, 0x1D, 0x03, 0x5E, 0xA0, 0x3D, 0x3F, 0x9E,
+			0xF5, 0xD3, 0x74, 0x2E, 0xC1, 0xD6, 0xFF, 0xF7,
+			0x2E, 0xE7, 0x80, 0x88, 0xCF, 0x0E, 0x7F, 0x12,
+			0x71, 0x62, 0xC7, 0xF1, 0xC4, 0x2B, 0x64, 0x5D,
+			0x1C, 0x9A, 0xB4, 0xCB, 0xB8, 0x24, 0xB3, 0x0B,
+			0x33, 0xF2, 0x8A, 0x8F, 0x76, 0xC8, 0x81, 0xDA,
+			0x1A, 0x10, 0xB5, 0xA9, 0xCD, 0xDC, 0x1A, 0x02,
+			0xC1, 0xAE, 0x4F, 0x02, 0x1B, 0x13, 0x96, 0x5A,
+			0x2E, 0x03, 0xA2, 0x68, 0xB2, 0x29, 0xAC, 0x28,
+			0xB8, 0xDC, 0xD5, 0x27, 0x55, 0xEC, 0x43, 0xDC,
+			0xB7, 0x49, 0x1D, 0xE1, 0x30, 0x25, 0x81, 0xA6,
+			0x90, 0x1F, 0x75, 0xBA, 0x19, 0x1E, 0xF7, 0xC5,
+			0x77, 0x35, 0xEE, 0x68, 0x71, 0x22, 0xA0, 0xB4,
+			0xCC, 0x99, 0x86, 0x1B, 0x1B, 0xC8, 0x27, 0xFC,
+			0x6D, 0x8D, 0xE7, 0x8B, 0xC3, 0x40, 0x3D, 0xA8,
+			0xCB, 0x9B, 0xC4, 0x12, 0x07, 0xDD, 0xA1, 0x92,
+			0xE5, 0x80, 0x7A, 0xF4, 0xDB, 0x4C, 0xE6, 0xEE,
+			0xF9, 0xD5, 0x1C, 0x20, 0x18, 0xD3, 0x8F, 0xDF,
+			0x1C, 0xD3, 0x51, 0x4E, 0x0E, 0xED, 0x06, 0x61,
+			0xF7, 0xBA, 0x81, 0x3A, 0x2F, 0xEA, 0xED, 0x70,
+			0xA9, 0xD9, 0x54, 0x4D, 0xFC, 0x1D, 0x19, 0xEA,
+			0xA6, 0x39, 0x8C, 0x6C, 0x78, 0xA8, 0x05, 0xEB,
+			0xF2, 0xB5, 0xDE, 0x06, 0x9D, 0x8A, 0x78, 0x2A,
+			0xF5, 0x50, 0xA4, 0xBD, 0x9B, 0xDA, 0xCA, 0x66,
+			0xC0, 0x23, 0xAB, 0xE8, 0x95, 0x7E, 0xC9, 0xD2,
+			0x6F, 0x09, 0xF2, 0x9A, 0x17, 0x89, 0xDA, 0x47,
+			0x65, 0x8C, 0x20, 0xFA, 0x4E, 0x86, 0x18, 0xEB,
+			0x7C, 0x08, 0xEC, 0x8A, 0x05, 0x54, 0x96, 0xD2,
+			0x7A, 0x8A, 0x81, 0x58, 0x75, 0x8C, 0x7B, 0x02,
+			0xEE, 0x1F, 0x51, 0x88, 0xD0, 0xD1, 0x90, 0x99,
+			0x0C, 0xAE, 0x51, 0x2E, 0x54, 0x3E, 0xB1, 0x7D,
+			0xBC, 0xE8, 0x54, 0x93, 0x6D, 0x10, 0x3C, 0xC6,
+			0x71, 0xF6, 0xF5, 0x0B, 0x07, 0x0A, 0x6E, 0x59,
+			0x20, 0x45, 0x21, 0x7D, 0x37, 0x64, 0x92, 0x09,
+			0xA7, 0xE2, 0x34, 0x6F, 0xFC, 0xCC, 0x66, 0x0E,
+			0x88, 0x1B, 0x19, 0x86, 0x11, 0xD7, 0x81, 0x25,
+			0xF1, 0x8A, 0x03, 0xB7, 0x7A, 0xF0, 0x98, 0x4A,
+			0x5C, 0xA1, 0x6D, 0x85, 0xA4, 0x8C, 0x4B, 0x65,
+			0x9F, 0x72, 0x64, 0x14, 0xBA, 0x74, 0xEE, 0xA3,
+			0x88, 0xFE, 0x1B, 0xCF, 0x11, 0x4F, 0xD1, 0xAC,
+			0xFA, 0x14, 0xC3, 0xA7, 0xDD, 0x06, 0x85, 0x4E,
+			0x64, 0x06, 0x92, 0x9C, 0xDF, 0x06, 0x09, 0xF1,
+			0x4D, 0xE8, 0xF8, 0x2F, 0x69, 0xB6, 0x8A, 0xAF,
+			0x25, 0x21, 0xB5, 0x48, 0x59, 0xF8, 0x9D, 0x60,
+			0xAE, 0x42, 0x11, 0x7A, 0x68, 0x4D, 0x7E, 0x76,
+			0xB0, 0xD2, 0xE3, 0xD9, 0x24, 0x16, 0x20, 0x0A,
+			0xEB, 0xE0, 0x68, 0xCB, 0xBC, 0xAB, 0x67, 0xE4,
+			0xF3, 0x25, 0x1F, 0xD3, 0x85, 0xA7, 0x1D, 0x7E,
+			0x3C, 0x63, 0xCB, 0xC2, 0x50, 0x90, 0x0F, 0x4B,
+			0x6E, 0x68, 0x06, 0x84, 0x65, 0xF7, 0xD0, 0xD4,
+			0x12, 0xED, 0xFA, 0xC9, 0x40, 0xE2, 0xC0, 0xC9,
+			0x46, 0x22, 0x47, 0x5E, 0x6D, 0xC1, 0x63, 0xDB,
+			0x51, 0x98, 0xDA, 0x1A, 0xC4, 0xB9, 0xED, 0xE9,
+			0x09, 0xB9, 0xCF, 0x91, 0x04, 0x1C, 0x63, 0xD8,
+			0xC5, 0xA5, 0xAE, 0x53, 0x7B, 0xA1, 0x29, 0x83,
+			0x37, 0xFB, 0xBF, 0x96, 0xBB, 0x24, 0x3D, 0x77,
+			0x8C, 0x0F, 0xB3, 0x4B, 0x66, 0x9C, 0x54, 0xBB,
+			0xF6, 0xDD, 0xD1, 0xB4, 0xD2, 0xF6, 0xAA, 0xED,
+			0x18, 0x56, 0x63, 0x3E, 0x0B, 0xCA, 0xAB, 0x70,
+			0xBB, 0x63, 0xEA, 0xB1, 0x00, 0x65, 0x90, 0x18,
+			0xB8, 0x63, 0xA2, 0xF2, 0xB6, 0x1E, 0x61, 0x7B,
+			0xD5, 0x01, 0xD9, 0x4D, 0xC9, 0x9D, 0x99, 0xC1,
+			0x57, 0x9D, 0x6F, 0xAE, 0x64, 0xE4, 0x0C, 0x7E,
+			0xFA, 0x15, 0x5E, 0xB6, 0x43, 0xB8, 0x8B, 0x89,
+			0x87, 0xCD, 0x4F, 0xAD, 0x30, 0x1E, 0xA5, 0x03,
+			0x7A, 0xC2, 0x10, 0x42, 0x14, 0x88, 0xD6, 0x7A,
+			0x6D, 0x56, 0x52, 0x2E, 0x8D, 0x1B, 0x5D, 0x36,
+			0x27, 0xA0, 0x21, 0x4B, 0x64, 0xF0, 0xC5, 0x41,
+			0xAD, 0x05, 0x4A, 0x24, 0xE4, 0x70, 0x88, 0x63,
+			0x12, 0xD0, 0xBC, 0x05, 0x38, 0xD9, 0x41, 0x68,
+			0x9F, 0x16, 0x9A, 0x54, 0x09, 0x21, 0x64, 0x36,
+			0x63, 0x97, 0x3A, 0xB5, 0xE0, 0x25, 0x43, 0x8A,
+			0x6A, 0x59, 0x97, 0xC1, 0x31, 0xA5, 0x66, 0xD2,
+			0xF0, 0x1C, 0xDF, 0x97, 0x51, 0xD0, 0x61, 0xBA,
+			0x55, 0x5F, 0xD7, 0x0D, 0xD4, 0x75, 0x8E, 0x79,
+			0x04, 0x75, 0x00, 0xB9, 0xC0, 0x7A, 0x66, 0x05,
+			0x9F, 0x2B, 0x44, 0x42, 0x75, 0x0F, 0xD5, 0x15,
+			0xD6, 0x16, 0x8F, 0x6C, 0x6E, 0xD4, 0x37, 0xCF,
+			0xB4, 0xDA, 0x93, 0x00, 0x11, 0xFB, 0xBE, 0xEE,
+			0x3B, 0x6D, 0x1D, 0xBA, 0x33, 0xD1, 0x52, 0x8B,
+			0x16, 0x39, 0x42, 0x27, 0xE6, 0x56, 0x4C, 0x41,
+			0x91, 0xB0, 0x98, 0xAE, 0x9B, 0x2D, 0x9B, 0x23,
+			0x80, 0x4C, 0xEA, 0x98, 0x57, 0x95, 0x28, 0x94,
+			0x43, 0xD3, 0x88, 0x12, 0xDF, 0x89, 0x5A, 0x7B,
+			0xC5, 0xCB, 0x36, 0x54, 0x65, 0x74, 0xB8, 0x4E,
+			0xE2, 0x4D, 0x01, 0xD5, 0x9C, 0x82, 0xB9, 0x1A,
+			0x09, 0xD2, 0xCE, 0x04, 0x36, 0xD8, 0x41, 0xAC,
+			0x4C, 0xAD, 0xC6, 0x52, 0x91, 0x1A, 0x06, 0x6D,
+			0xFC, 0xAB, 0x29, 0x93, 0x87, 0x88, 0xB9, 0x8C,
+			0xFA, 0x57, 0x2B, 0x05, 0x03, 0xD0, 0x18, 0xED,
+			0x7A, 0x7B, 0x81, 0x6A, 0x97, 0x65, 0x5B, 0x90,
+			0xDE, 0xA9, 0xFC, 0x8F, 0xFC, 0xBB, 0x98, 0xD8,
+			0xFA, 0x32, 0x3F, 0x3F, 0x7F, 0x74, 0x65, 0x38,
+			0xC4, 0x28, 0xEC, 0x27, 0x1F, 0x28, 0x01, 0xB1,
+			0xAF, 0x2B, 0x8A, 0x05, 0x38, 0x7B, 0x77, 0xC9,
+			0x61, 0x77, 0x34, 0x2C, 0x22, 0xE5, 0xEB, 0xDC,
+			0x9D, 0x18, 0x6E, 0x23, 0x25, 0x52, 0x69, 0xB7,
+			0x05, 0xDB, 0x66, 0x5D, 0xEA, 0x76, 0x83, 0x82,
+			0x97, 0x39, 0xAF, 0xC0, 0x50, 0x81, 0x18, 0x0D,
+			0x22, 0xFA, 0xB7, 0x44, 0x5C, 0x3F, 0x69, 0xF3,
+			0xAC, 0xC5, 0x63, 0x9F, 0xD8, 0x72, 0x7E, 0x9A,
+			0xC2, 0xEB, 0x79, 0xD0, 0x74, 0x65, 0xE8, 0xCA,
+			0xFD, 0xA8, 0x7D, 0x23, 0x07, 0x99, 0x3E, 0xAF,
+			0xDB, 0x67, 0x10, 0xC0, 0xE5, 0x61, 0x77, 0xC6,
+			0x8D, 0xC4, 0x0E, 0xAA, 0x55, 0xE3, 0xC0, 0xC7,
+			0xA5, 0x36, 0x28, 0x61, 0xDB, 0x16, 0x96, 0x5E,
+			0x01, 0x47, 0x82, 0xE3, 0xEB, 0x20, 0x3F, 0x10,
+			0xFA, 0x5A, 0xBC, 0xD3, 0xF9, 0xCE, 0x04, 0x87,
+			0x51, 0x07, 0xF9, 0xD0, 0xE7, 0x6D, 0xCB, 0xCC,
+			0xC4, 0x15, 0x00, 0xE2, 0xDC, 0x8E, 0x7B, 0x5C,
+			0x9A, 0xF2, 0x78, 0x70, 0x4D, 0xA1, 0xAA, 0xB5,
+			0x13, 0xCC, 0x71, 0x66, 0x5A, 0x79, 0x13, 0x3B,
+			0x12, 0xCD, 0x40, 0x30, 0x5A, 0x49, 0xD4, 0x20,
+			0xED, 0xCF, 0x4A, 0x75, 0xE6, 0xD5, 0xDD, 0x0F,
+			0xD4, 0xBE, 0x98, 0x9F, 0xD7, 0x1F, 0xC0, 0x02,
+			0x31, 0xFA, 0x67, 0x37, 0x25, 0x86, 0x56, 0x85,
+			0x2B, 0xA2, 0x57, 0xCD, 0x8E, 0x74, 0xE7, 0x69,
+			0xEE, 0x33, 0x5A, 0x3F, 0xCD, 0x1E, 0xE3, 0xB9,
+			0xAA, 0x52, 0xF5, 0x22, 0x4E, 0xE3, 0xFF, 0xC8,
+			0xE3, 0x13, 0xA3, 0x9A, 0x63, 0x23, 0xC3, 0xD7,
+			0xE5, 0x88, 0x3E, 0x0A, 0x4B, 0xA5, 0x01, 0xE6,
+			0x13, 0xCF, 0xED, 0xEE, 0x2A, 0x58, 0x09, 0x3F,
+			0x2F, 0x28, 0xE7, 0xC4, 0x6B, 0xEC, 0x49, 0x51,
+			0x79, 0x8F, 0xD5, 0x19, 0x5D, 0xA5, 0x10, 0xCE,
+			0x8E, 0xF6, 0x26, 0x78, 0x7A, 0xA8, 0x11, 0x52,
+			0x5F, 0x97, 0x14, 0xC9, 0x29, 0x87, 0xB8, 0xA0,
+			0x2D, 0xE6, 0xA7, 0x2A, 0xD4, 0xFF, 0xEB, 0xBA,
+			0xFD, 0x58, 0x39, 0x33, 0xB1, 0xCE, 0x0E, 0x78,
+			0x67, 0x1E, 0xA1, 0x92, 0x77, 0x63, 0xF8, 0xC0,
+			0x02, 0x49, 0x73, 0xC0, 0xA1, 0x26, 0x83, 0x04,
+			0x9A, 0x5D, 0x85, 0x68, 0x2A, 0x2F, 0xCB, 0x88,
+			0x8D, 0x14, 0xB1, 0x33, 0xFA, 0xFB, 0xE9, 0x05,
+			0xBE, 0x24, 0x1A, 0x6B, 0x29, 0x2B, 0x3F, 0x52,
+			0x8F, 0xFB, 0xE6, 0x02, 0x77, 0x50, 0x71, 0xDB,
+			0xE9, 0x92, 0x3F, 0xE1, 0x20, 0x62, 0x80, 0xAE,
+			0xA4, 0x98, 0xC6, 0xCD, 0xE0, 0xB1, 0xC3, 0x33,
+			0xB1, 0xC5, 0x91, 0x3C, 0x19, 0x34, 0xA8, 0xD9,
+			0xB3, 0x25, 0x69, 0xE3, 0x9C, 0x5F, 0x78, 0xD0,
+			0x83, 0x1F, 0xAB, 0x85, 0x13, 0x56, 0x69, 0xB5,
+			0x06, 0x47, 0x62, 0x37, 0x27, 0x15, 0x14, 0x05,
+			0x4A, 0xF4, 0x6A, 0x68, 0x2A, 0x6A, 0xC3, 0x5A,
+			0xDF, 0xB5, 0xAE, 0x2F, 0x8D, 0x8F, 0x21, 0xDB,
+			0x33, 0x00, 0x9B, 0xD4, 0xC4, 0x08, 0x3B, 0x81,
+			0x63, 0x4C, 0xB0, 0x39, 0x4C, 0x0A, 0xD5, 0x71,
+			0x3E, 0x5A, 0x50, 0x58, 0x9C, 0x07, 0x89, 0x79,
+			0x79, 0x2F, 0x0B, 0xD9, 0x50, 0xBC, 0xCF, 0x46,
+			0x7A, 0x68, 0x5C, 0xBF, 0x1E, 0x49, 0x77, 0x92,
+			0x85, 0x11, 0x39, 0xA6, 0x2F, 0xDA, 0x7B, 0xFA,
+			0x72, 0x87, 0x06, 0xCD, 0x84, 0x41, 0x20, 0x1B,
+			0x66, 0x3F, 0x42, 0x0C, 0x9E, 0x19, 0xD3, 0x18,
+			0x57, 0xA0, 0xEE, 0x16, 0x3A, 0xC7, 0xF9, 0xD3,
+			0x8B, 0xC9, 0x24, 0x70, 0x70, 0x51, 0x7C, 0x06,
+			0x68, 0xD3, 0x29, 0xC9, 0x85, 0x9A, 0x1C, 0xE6,
+			0x8C, 0x17, 0xF4, 0x88, 0xDF, 0xEA, 0xFF, 0x44,
+			0x8D, 0x54, 0xBE, 0x22, 0x07, 0xA5, 0x7C, 0x0C,
+			0xF4, 0x8D, 0xB1, 0x0C, 0x07, 0xED, 0xBD, 0x28,
+			0x19, 0xDA, 0x07, 0x71, 0xA8, 0xA1, 0xE0, 0xDD,
+			0xEE, 0x08, 0x18, 0xA5, 0xBD, 0xDD, 0x32, 0x0B,
+			0x70, 0x1C, 0xD9, 0xEE, 0x19, 0xC2, 0xAE, 0x5C,
+			0xE3, 0x02, 0x74, 0x70, 0x96, 0x61, 0xB1, 0x73,
+			0x3B, 0xD6, 0x74, 0xC0, 0x82, 0xA9, 0x1F, 0xE0,
+			0xF1, 0x22, 0x50, 0xF3, 0x9F, 0xE5, 0x13, 0x92,
+			0xFC, 0x0A, 0x1A, 0x3C, 0xB4, 0x46, 0xFB, 0x81,
+			0x00, 0x84, 0xA4, 0x5E, 0x6B, 0x8C, 0x25, 0x6E,
+			0xD7, 0xB7, 0x3B, 0x01, 0x65, 0xFB, 0x0B, 0x46,
+			0x67, 0x27, 0x2D, 0x51, 0xAD, 0xB5, 0xE0, 0x85,
+			0xC2, 0x95, 0xA3, 0xE3, 0x68, 0x4D, 0x9E, 0x8C,
+			0x11, 0x53, 0xF0, 0xB2, 0x85, 0xFA, 0x52, 0x4E,
+			0xEC, 0xF9, 0xB7, 0x3C, 0x89, 0x2C, 0x4D, 0x32,
+			0x9A, 0xCB, 0x17, 0xF3, 0x16, 0xBF, 0x44, 0x40,
+			0xE9, 0x5E, 0x51, 0x8C, 0x1E, 0x52, 0x0A, 0xC2,
+			0xCD, 0xA5, 0xAA, 0x03, 0x27, 0xB0, 0x8F, 0x64,
+			0xDB, 0xD7, 0x03, 0x01, 0x8A, 0x24, 0x28, 0x7E,
+			0x53, 0x6F, 0x24, 0xFD, 0xAA, 0xE3, 0x78, 0xB6,
+			0xA5, 0x5D, 0x5A, 0x67, 0x20, 0xE2, 0xBE, 0x3A,
+			0x2B, 0xE7, 0x86, 0x11, 0xDD, 0x96, 0xCB, 0x09,
+			0x65, 0xA0, 0x36, 0xF9, 0xB0, 0x20, 0x21, 0x8E,
+			0xDB, 0xC0, 0x73, 0xC7, 0x79, 0xD8, 0xDA, 0xC2,
+			0x66, 0x13, 0x64, 0x34, 0x0C, 0xE1, 0x22, 0x24,
+			0x61, 0x67, 0x08, 0x39, 0x97, 0x3F, 0x33, 0x96,
+			0xF2, 0x44, 0x18, 0x75, 0xBB, 0xF5, 0x6A, 0x5C,
+			0x2C, 0xAE, 0x2A, 0x79, 0x3D, 0x47, 0x19, 0x53,
+			0x50, 0x6C, 0x9F, 0xB3, 0x82, 0x55, 0x09, 0x78,
+			0x7B, 0xAD, 0xBC, 0x05, 0x6F, 0xC8, 0x3D, 0xB6,
+			0x7B, 0x30, 0xE6, 0xBB, 0x8B, 0xD0, 0x2F, 0xA6,
+			0x15, 0xCC, 0x77, 0x8C, 0x21, 0xBA, 0x03, 0xED,
+			0x56, 0x85, 0x82, 0x4F, 0x97, 0x8C, 0x59, 0x4F,
+			0x53, 0x5A, 0xD2, 0x70, 0xD9, 0x07, 0xB3, 0xBD,
+			0x1D, 0x3E, 0x97, 0xD4, 0x7D, 0x93, 0x35, 0xA4,
+			0x82, 0x6E, 0xEA, 0x4B, 0xC8, 0x6C, 0xF5, 0xE6,
+			0xEB, 0xAF, 0x11, 0xB0, 0xB4, 0x71, 0x8F, 0x7B,
+			0xC4, 0x8C, 0xE2, 0x66, 0x51, 0x31, 0x99, 0x01,
+			0x5B, 0xE7, 0x48, 0xF8, 0x4C, 0xE3, 0x9A, 0x77,
+			0xF1, 0xC6, 0x09, 0xDE, 0x76, 0xD4, 0xE3, 0x5C,
+			0xDF, 0xA3, 0xEC, 0x3C, 0x86, 0x7C, 0xA5, 0x3F,
+			0x8D, 0x2A, 0xF3, 0x0B, 0x54, 0xB7, 0x54, 0xA2,
+			0xC1, 0x69, 0xC0, 0x6F, 0x1C, 0x1C, 0x76, 0xD8,
+			0x9F, 0x7A, 0x32, 0xB0, 0xA1, 0xA6, 0x9B, 0xB7,
+			0x21, 0x56, 0x28, 0x2D, 0xB6, 0x97, 0x03, 0x5E,
+			0x65, 0xE3, 0x74, 0x9A, 0x96, 0x7A, 0xF9, 0xF5,
+			0xDD, 0x85, 0xCA, 0x4C, 0xB4, 0x03, 0x6A, 0xCD,
+			0xB6, 0x01, 0xDC, 0x8B, 0xD8, 0x73, 0x8F, 0x4D,
+			0x7F, 0xD6, 0x71, 0xEC, 0xD7, 0xC6, 0x0B, 0x5F,
+			0x09, 0x21, 0xB2, 0x78, 0xA8, 0xAF, 0xAD, 0x2C,
+			0xD4, 0x93, 0x9F, 0x71, 0xF7, 0x05, 0x89, 0x42,
+			0xC9, 0x15, 0x6F, 0x2D, 0xE0, 0xBA, 0xC3, 0xD6,
+			0xBF, 0xAC, 0xF8, 0x24, 0x58, 0x79, 0xA9, 0xC4,
+			0xB4, 0x49, 0x3E, 0x0B, 0x9E, 0x5E, 0xE4, 0xA6,
+			0x8B, 0xE8, 0xDE, 0xFB, 0x4A, 0xF1, 0x69, 0x9D,
+			0x4F, 0x77, 0x83, 0x78, 0x55, 0x19, 0x42, 0x45,
+			0xBF, 0xBD, 0xBD, 0x12, 0x0F, 0xEF, 0x8D, 0x04,
+			0xD8, 0x5C, 0xF2, 0xC9, 0xF1, 0xA6, 0xE0, 0x3E,
+			0x22, 0xA8, 0xA2, 0x5E, 0x66, 0xE9, 0xAB, 0xB4,
+			0x71, 0xBE, 0x4B, 0x3F, 0xBE, 0xC4, 0xBA, 0x4A
+		},
+		.len = 2048
+	},
+	.ciphertext = {
+		.data = {
+			0x5E, 0x86, 0x02, 0x64, 0x32, 0xBF, 0x70, 0xC2,
+			0x19, 0x99, 0x7F, 0x47, 0x0D, 0xA4, 0x91, 0xA8,
+			0x7A, 0xC0, 0xA5, 0x7E, 0xA8, 0x6C, 0x88, 0x00,
+			0xEA, 0xB5, 0x96, 0x6B, 0x25, 0xBD, 0xE7, 0x42,
+			0xDB, 0x35, 0xE7, 0x92, 0x2B, 0x00, 0x82, 0x35,
+			0xD4, 0x2C, 0xCF, 0x47, 0xC8, 0xB2, 0xB3, 0x57,
+			0xF7, 0x24, 0x83, 0x7F, 0xC5, 0x2E, 0xF1, 0xC9,
+			0x57, 0x1A, 0xEF, 0xC2, 0x3A, 0x8C, 0x1E, 0x92,
+			0x88, 0x05, 0xAF, 0x55, 0xE6, 0x0C, 0xA7, 0x6B,
+			0x59, 0x62, 0x32, 0x21, 0xF1, 0xFF, 0xB5, 0x5B,
+			0x22, 0x26, 0x6F, 0x0A, 0x36, 0xDC, 0x0D, 0x16,
+			0x3B, 0x4E, 0x7C, 0xA3, 0x75, 0x30, 0x3F, 0xB0,
+			0x99, 0x38, 0x42, 0x8E, 0x89, 0xA3, 0x7C, 0x99,
+			0x2F, 0x0A, 0xA1, 0xC7, 0xFD, 0x2D, 0x21, 0x8F,
+			0xBD, 0xD4, 0x11, 0xEA, 0x55, 0xF5, 0x6A, 0x50,
+			0x90, 0x3B, 0x60, 0x57, 0xE1, 0x86, 0x1E, 0x50,
+			0x28, 0x67, 0x3F, 0xD2, 0xF3, 0xBD, 0xFA, 0xEE,
+			0xD6, 0x5A, 0x38, 0x30, 0xA3, 0xDD, 0x78, 0xC4,
+			0x37, 0x59, 0x52, 0xC0, 0x92, 0x54, 0xC7, 0x53,
+			0xF0, 0xE6, 0xA9, 0x63, 0x1F, 0x9B, 0x97, 0xFB,
+			0x40, 0x23, 0xFE, 0x52, 0x6A, 0xF0, 0x3A, 0x94,
+			0xEB, 0x6A, 0x9E, 0x8F, 0xC5, 0x05, 0x9C, 0x04,
+			0x1B, 0x00, 0x34, 0x96, 0x12, 0xDA, 0x60, 0xC6,
+			0xAA, 0x1A, 0x3E, 0xEB, 0x70, 0x17, 0x10, 0xBC,
+			0xF5, 0xC2, 0xE2, 0x71, 0xF3, 0xB8, 0x1D, 0xCE,
+			0x47, 0x94, 0x21, 0x71, 0x34, 0x8C, 0xCC, 0xDD,
+			0x27, 0xCE, 0x6F, 0x68, 0xFF, 0x91, 0x4E, 0xC4,
+			0xA0, 0xCA, 0xB0, 0x4F, 0x17, 0x53, 0x73, 0x92,
+			0x6C, 0xA8, 0x16, 0x06, 0xE3, 0xD9, 0x92, 0x99,
+			0xBE, 0xB0, 0x7D, 0x56, 0xF2, 0x72, 0x30, 0xDA,
+			0xC4, 0x4E, 0xF4, 0xA6, 0x8F, 0xD2, 0xC7, 0x8A,
+			0xA2, 0xFC, 0xF5, 0x63, 0x17, 0x48, 0x56, 0x4D,
+			0xBE, 0x94, 0xFE, 0xF5, 0xB1, 0xA9, 0x96, 0xAB,
+			0x3F, 0x2D, 0xD4, 0x15, 0xEE, 0x4F, 0xFA, 0x2C,
+			0xBE, 0x91, 0xB7, 0xBC, 0x18, 0xC8, 0xDB, 0x02,
+			0x20, 0x29, 0xF1, 0xC1, 0x88, 0x8C, 0x8D, 0xD1,
+			0xB3, 0x4E, 0x93, 0x96, 0xDD, 0x22, 0xAB, 0x55,
+			0xB5, 0x9F, 0x8B, 0x20, 0xAE, 0xC6, 0x0E, 0x26,
+			0xC6, 0xFE, 0x2D, 0x5F, 0x95, 0x89, 0x06, 0x15,
+			0x3D, 0x88, 0x16, 0xEC, 0x9B, 0x4A, 0x1B, 0x5D,
+			0x2E, 0xB2, 0x13, 0x56, 0x9F, 0x33, 0xB3, 0x45,
+			0xBF, 0x5F, 0x25, 0x7E, 0x75, 0x22, 0xD2, 0xE6,
+			0x9F, 0xAC, 0x2D, 0xFD, 0x99, 0xC2, 0x9B, 0xFC,
+			0xD7, 0x7A, 0x9B, 0x05, 0x30, 0x0F, 0xB7, 0x4A,
+			0xFE, 0x24, 0xDD, 0x39, 0x9B, 0xBB, 0x2F, 0xDD,
+			0xF9, 0xFB, 0xCA, 0x6C, 0x87, 0xBA, 0x73, 0xD4,
+			0x85, 0x7B, 0xB2, 0x6F, 0x5C, 0xD8, 0xFB, 0xE9,
+			0x41, 0x24, 0x3A, 0x3B, 0x4F, 0x91, 0x77, 0xA2,
+			0x35, 0x78, 0xE5, 0x4C, 0xFE, 0x8B, 0x04, 0x03,
+			0xD3, 0x84, 0xA9, 0x1C, 0xA7, 0x7C, 0x45, 0x13,
+			0x7D, 0xC5, 0x0A, 0x2F, 0x02, 0xF8, 0x56, 0xD5,
+			0x5F, 0x35, 0xED, 0x06, 0xBF, 0x67, 0xBA, 0x51,
+			0x02, 0x95, 0x36, 0xF2, 0x9A, 0xBA, 0x9D, 0xF6,
+			0xD6, 0x77, 0x50, 0xC9, 0xFC, 0x1E, 0x32, 0xB5,
+			0x2F, 0xEA, 0x3C, 0x76, 0xB4, 0xE1, 0xCC, 0x42,
+			0xEB, 0x71, 0x79, 0xD3, 0x7D, 0xB7, 0xC0, 0x88,
+			0x25, 0x81, 0xE8, 0xC0, 0xB8, 0x38, 0x7E, 0x7B,
+			0xFD, 0x18, 0xAB, 0x08, 0xB2, 0x71, 0xA5, 0xAD,
+			0xA7, 0xBE, 0x48, 0x5F, 0x86, 0xE2, 0x41, 0x3D,
+			0x7C, 0x37, 0x7A, 0xAB, 0xDB, 0xE0, 0x3B, 0x3D,
+			0xB6, 0xE8, 0x23, 0x7C, 0xF1, 0x8F, 0xBA, 0xB7,
+			0xE9, 0x78, 0x0B, 0xCA, 0x67, 0xA8, 0x10, 0x36,
+			0xEB, 0x72, 0xED, 0xDD, 0xF0, 0x5C, 0x74, 0x8E,
+			0xE5, 0x2A, 0xAE, 0x6E, 0xC4, 0xF1, 0xFC, 0xD8,
+			0xEE, 0x56, 0x07, 0x88, 0x02, 0xDC, 0x9D, 0xB7,
+			0xF9, 0x13, 0xE1, 0xE1, 0x9D, 0x89, 0x26, 0x0B,
+			0x23, 0x74, 0x4A, 0x43, 0xAA, 0xA0, 0xA8, 0x97,
+			0x85, 0x15, 0x58, 0xAB, 0x2B, 0xB5, 0xDA, 0x1A,
+			0xBA, 0x29, 0x62, 0xCF, 0xDD, 0xA3, 0xBA, 0x9D,
+			0x7D, 0x83, 0xA5, 0x18, 0xD4, 0x03, 0x0F, 0x61,
+			0x9F, 0xB1, 0x7E, 0xEC, 0xD2, 0x6E, 0xAF, 0xCF,
+			0x1E, 0xC1, 0x88, 0x97, 0x99, 0xD6, 0xBF, 0x47,
+			0xB9, 0x0A, 0x69, 0x11, 0x3A, 0x55, 0x8B, 0x1D,
+			0x2D, 0xFF, 0x78, 0xC8, 0xDE, 0x82, 0x29, 0xD6,
+			0x08, 0x3C, 0xC4, 0xCB, 0x2F, 0x01, 0xD0, 0xE8,
+			0xB1, 0x75, 0x5E, 0x23, 0xE0, 0x37, 0x7C, 0x1C,
+			0xB6, 0xD9, 0x47, 0xDE, 0x23, 0x87, 0xD3, 0x68,
+			0x47, 0x46, 0x78, 0xF3, 0xBF, 0x54, 0xA3, 0xB9,
+			0x54, 0xD5, 0xC5, 0x0A, 0x7C, 0x92, 0x2A, 0xC2,
+			0x14, 0x76, 0xA6, 0x5C, 0x6D, 0x0B, 0x94, 0x56,
+			0x00, 0x6B, 0x5C, 0x27, 0xDE, 0x77, 0x9B, 0xF1,
+			0xB1, 0x8C, 0xA7, 0x49, 0x77, 0xFC, 0x4E, 0x29,
+			0x23, 0x8F, 0x2F, 0xF7, 0x83, 0x8D, 0x36, 0xD9,
+			0xAB, 0x0E, 0x78, 0xF5, 0x90, 0x05, 0xB9, 0x79,
+			0x70, 0x88, 0x59, 0x6F, 0xE2, 0xC5, 0xD7, 0x80,
+			0x95, 0x04, 0x29, 0xE0, 0xFA, 0x37, 0xE8, 0x8B,
+			0xC5, 0x21, 0x51, 0x1A, 0x62, 0xCE, 0x93, 0xAF,
+			0x1A, 0xFE, 0xC3, 0x6F, 0x86, 0x94, 0x5E, 0x13,
+			0xA6, 0x9A, 0x26, 0xF0, 0xB5, 0x7C, 0x41, 0x9A,
+			0x80, 0xB8, 0x84, 0x5A, 0x55, 0xA9, 0xB0, 0x6A,
+			0xFA, 0xEB, 0x46, 0x32, 0x0B, 0xE2, 0x9C, 0x65,
+			0x86, 0x11, 0x39, 0x7E, 0xAF, 0x93, 0x19, 0x09,
+			0x70, 0x40, 0x80, 0x14, 0xBA, 0x1D, 0xB3, 0x62,
+			0x5B, 0xF3, 0x9A, 0x21, 0x98, 0x7E, 0x63, 0xB6,
+			0x1A, 0xBD, 0x65, 0x98, 0x35, 0x2A, 0xA9, 0x76,
+			0x29, 0x59, 0x84, 0x25, 0x81, 0xB8, 0xDE, 0x25,
+			0x32, 0x10, 0x50, 0xB7, 0xD3, 0xB3, 0x69, 0xC8,
+			0xE1, 0x33, 0xCB, 0x9E, 0x9C, 0x7A, 0x7C, 0xD2,
+			0x6C, 0x92, 0x97, 0xA9, 0xFA, 0xAF, 0x30, 0xBA,
+			0x9A, 0xB3, 0x3D, 0x9A, 0xE5, 0x0A, 0x9B, 0x8D,
+			0x89, 0xE2, 0x2B, 0xB8, 0xBC, 0xF0, 0x23, 0xFF,
+			0x7B, 0x0D, 0x00, 0x36, 0xEE, 0x79, 0xCB, 0xA5,
+			0x70, 0x4C, 0x66, 0x02, 0x79, 0x2E, 0x5B, 0x83,
+			0xCE, 0x55, 0x8B, 0x89, 0xD6, 0xE3, 0x71, 0x63,
+			0xBC, 0xB1, 0x5F, 0x67, 0xB4, 0x7E, 0x05, 0x0D,
+			0xAC, 0x6D, 0x4E, 0x2C, 0xA5, 0xF4, 0x47, 0x89,
+			0xAC, 0x5E, 0xBE, 0x2F, 0xFC, 0x9B, 0x2F, 0x0B,
+			0xBE, 0x63, 0x54, 0x97, 0xBB, 0x23, 0x27, 0xCD,
+			0xB9, 0xB2, 0x28, 0x0D, 0xA4, 0x78, 0x2C, 0xAB,
+			0xD1, 0xC9, 0x94, 0x40, 0x54, 0xF2, 0x35, 0x61,
+			0x49, 0x01, 0x87, 0x55, 0xA5, 0xB5, 0x1E, 0x84,
+			0x92, 0x9E, 0xC1, 0xA4, 0x0B, 0x66, 0x2B, 0xF8,
+			0xAF, 0xC3, 0x1E, 0xAF, 0x66, 0x3F, 0x6F, 0x5F,
+			0x70, 0xEC, 0x25, 0x29, 0xE4, 0x65, 0xB2, 0x04,
+			0x47, 0xF6, 0x3C, 0xB5, 0x5F, 0x66, 0x9F, 0xA4,
+			0x1B, 0xFC, 0xA2, 0xD5, 0x3E, 0x84, 0xBA, 0x88,
+			0x0D, 0xF1, 0x6A, 0xF2, 0xF6, 0x1D, 0xF1, 0xA3,
+			0x45, 0xB2, 0x51, 0xD8, 0xA2, 0x8F, 0x55, 0xA6,
+			0x89, 0xC4, 0x15, 0xD5, 0x73, 0xA8, 0xB1, 0x31,
+			0x66, 0x9E, 0xC1, 0x43, 0xE1, 0x5D, 0x4E, 0x04,
+			0x84, 0x8F, 0xF2, 0xBC, 0xE1, 0x4E, 0x4D, 0x60,
+			0x81, 0xCA, 0x53, 0x34, 0x95, 0x17, 0x3B, 0xAE,
+			0x8F, 0x95, 0xA7, 0xC6, 0x47, 0xC6, 0xAC, 0x32,
+			0x12, 0x39, 0xCA, 0xEF, 0xE0, 0x07, 0xBF, 0x17,
+			0x4F, 0xDC, 0x1B, 0x4E, 0x3C, 0x84, 0xF1, 0x9F,
+			0x43, 0x70, 0x19, 0xE6, 0xF3, 0x8B, 0x8B, 0x5D,
+			0xDB, 0xD2, 0x9D, 0xD4, 0xB2, 0x30, 0x45, 0x55,
+			0xA2, 0x67, 0xA2, 0x76, 0x4A, 0x74, 0xAD, 0x88,
+			0x71, 0xE6, 0x3E, 0x13, 0x06, 0x30, 0x17, 0xE1,
+			0xEF, 0xAC, 0x71, 0xFB, 0x43, 0xCD, 0xF6, 0xFA,
+			0x0E, 0x4C, 0x4E, 0x16, 0xF6, 0x6A, 0x09, 0x86,
+			0x6B, 0xEA, 0x47, 0x6C, 0x70, 0xE7, 0xAD, 0xA2,
+			0xE0, 0xFD, 0x7F, 0xF0, 0x5C, 0x21, 0x53, 0x0F,
+			0x28, 0xA1, 0x43, 0xE1, 0x06, 0xCA, 0x0B, 0x31,
+			0x88, 0x22, 0xA6, 0xE6, 0x34, 0x5B, 0xE6, 0xCF,
+			0x25, 0x81, 0x63, 0xFF, 0x78, 0x66, 0x85, 0x19,
+			0xE2, 0x0A, 0x7E, 0x81, 0x8A, 0x17, 0x1A, 0x18,
+			0x8A, 0x5F, 0x5D, 0x9E, 0x82, 0x13, 0x10, 0xB9,
+			0xD3, 0xE6, 0x93, 0x1C, 0xE4, 0x2C, 0xCB, 0x49,
+			0x1E, 0xB6, 0x36, 0x13, 0xBF, 0x28, 0xEE, 0xCC,
+			0x49, 0xF5, 0x79, 0xFC, 0x20, 0x65, 0xBD, 0xE8,
+			0xF0, 0x1B, 0x4E, 0xC0, 0x0D, 0x3E, 0x89, 0x91,
+			0xCC, 0x64, 0x10, 0xC0, 0x2A, 0x2B, 0xA3, 0xFA,
+			0x60, 0x3D, 0xC3, 0x52, 0x2F, 0x93, 0xDE, 0xB7,
+			0x6E, 0x8A, 0xDF, 0x6C, 0x08, 0xCC, 0x8B, 0x3B,
+			0xC8, 0x50, 0xEF, 0x58, 0x64, 0x9A, 0x3D, 0x16,
+			0x70, 0x94, 0x11, 0xD8, 0x94, 0x2B, 0x70, 0x91,
+			0x10, 0x70, 0x88, 0xF0, 0x40, 0x75, 0x9A, 0x2B,
+			0x39, 0xA1, 0x27, 0x3F, 0x2E, 0x91, 0xEA, 0xA1,
+			0xCC, 0x12, 0xC1, 0x7F, 0x73, 0x8C, 0x5C, 0x6B,
+			0xFC, 0xC5, 0x6A, 0x1C, 0x05, 0xF1, 0x3D, 0x30,
+			0x82, 0x4A, 0x65, 0x35, 0xCE, 0x80, 0x10, 0xBB,
+			0x41, 0x94, 0xFB, 0x84, 0x80, 0x7B, 0x91, 0xC4,
+			0x4D, 0xA3, 0x5F, 0xB9, 0xFB, 0xF9, 0xC9, 0x1D,
+			0x4F, 0x99, 0x1C, 0x1F, 0x47, 0x44, 0x89, 0x0E,
+			0xED, 0x6D, 0xB5, 0x85, 0x41, 0x94, 0xEF, 0xF9,
+			0x2E, 0xA0, 0xC8, 0xCA, 0xFB, 0x44, 0x02, 0xC6,
+			0xBF, 0x96, 0x87, 0x80, 0x1D, 0xEF, 0x2A, 0x81,
+			0xAB, 0xB2, 0x56, 0xDF, 0x54, 0x8B, 0xAB, 0xAF,
+			0xFE, 0x18, 0x8C, 0xAA, 0xD4, 0x00, 0x17, 0xBE,
+			0xCF, 0x06, 0xE5, 0xA6, 0xBF, 0x5A, 0x52, 0x3B,
+			0x4E, 0xF5, 0x65, 0x60, 0x95, 0xDE, 0x8A, 0x25,
+			0x88, 0xA5, 0x24, 0x96, 0x29, 0x13, 0x0D, 0x19,
+			0x45, 0x95, 0x91, 0x08, 0xD2, 0x9C, 0x4C, 0x34,
+			0x42, 0xF0, 0xA5, 0x72, 0xEB, 0xFB, 0x5E, 0xAA,
+			0x68, 0x80, 0x82, 0xAC, 0x34, 0xAD, 0x89, 0xF6,
+			0xAF, 0x54, 0x82, 0xCF, 0x98, 0x8C, 0x75, 0x63,
+			0x8D, 0xBD, 0x1C, 0x2A, 0xD7, 0x00, 0xA7, 0x8E,
+			0xB9, 0x33, 0xB6, 0x3B, 0x95, 0x9A, 0x59, 0x1D,
+			0x3F, 0x23, 0x6B, 0x18, 0xF8, 0x4F, 0x1A, 0x8D,
+			0xC0, 0x26, 0x9F, 0x87, 0x61, 0xB6, 0xC6, 0x60,
+			0x38, 0x22, 0x73, 0x1C, 0x99, 0x23, 0xEF, 0xD9,
+			0xFD, 0xCB, 0x54, 0x74, 0xBB, 0x77, 0x14, 0xA3,
+			0xA9, 0xE6, 0x7C, 0x7E, 0x03, 0x3A, 0x13, 0x6E,
+			0x1D, 0x6F, 0x64, 0xB3, 0xFA, 0xFB, 0x52, 0xDE,
+			0xDF, 0x08, 0xFB, 0x6F, 0xC5, 0xFA, 0x51, 0x6A,
+			0x69, 0x29, 0x9B, 0x96, 0xE8, 0x16, 0xC8, 0xD1,
+			0xE4, 0x19, 0xBD, 0x14, 0x74, 0x27, 0xE7, 0x10,
+			0xF0, 0xC3, 0xE2, 0xA7, 0x60, 0x48, 0xBF, 0xDD,
+			0xC4, 0x0D, 0xD0, 0xF2, 0xEF, 0xA6, 0xC9, 0xA2,
+			0x73, 0xD1, 0xCF, 0x41, 0xE1, 0x3B, 0xE5, 0x49,
+			0x91, 0x5D, 0x09, 0xFD, 0x1D, 0x95, 0x29, 0xDB,
+			0x52, 0x48, 0xEB, 0xF5, 0x1D, 0xF8, 0x06, 0x67,
+			0x75, 0xF2, 0x57, 0xA4, 0x20, 0x60, 0xEA, 0xB0,
+			0x85, 0x93, 0x7C, 0xDD, 0x52, 0x01, 0xD4, 0x57,
+			0xA8, 0x31, 0x2D, 0xF9, 0x0A, 0xD2, 0x2A, 0xD1,
+			0x34, 0x18, 0x35, 0x16, 0xB6, 0x8B, 0x0F, 0x0B,
+			0xCF, 0x50, 0x80, 0xFE, 0x76, 0xCC, 0x4F, 0x30,
+			0x98, 0x19, 0x16, 0x3D, 0x01, 0xEA, 0x8D, 0x8A,
+			0x3D, 0xDC, 0xFB, 0x1F, 0x77, 0x8D, 0x72, 0x76,
+			0x02, 0x3C, 0x5D, 0xEE, 0x55, 0x13, 0x5B, 0x6E,
+			0x5A, 0x2D, 0xD5, 0x77, 0xD7, 0x01, 0x84, 0x7D,
+			0x21, 0x8C, 0xDD, 0x94, 0x7D, 0x31, 0x3D, 0xF0,
+			0xE7, 0x28, 0xF5, 0x72, 0x36, 0x60, 0xE0, 0x59,
+			0x5F, 0xFE, 0x38, 0xF8, 0x2F, 0xDB, 0x9E, 0x55,
+			0x5A, 0xD6, 0xBA, 0x6C, 0x87, 0xF3, 0xC0, 0x76,
+			0x5F, 0xA3, 0x0A, 0xC3, 0xA3, 0x8D, 0x0E, 0x52,
+			0xA8, 0xDA, 0x26, 0x3A, 0xF9, 0x3E, 0x36, 0xB1,
+			0x06, 0xF8, 0x20, 0x2D, 0x1C, 0x0B, 0x93, 0xBB,
+			0xD3, 0x64, 0x77, 0xCE, 0x11, 0xFC, 0xA2, 0x0E,
+			0x1B, 0x5B, 0x9E, 0x13, 0x9F, 0x20, 0x8B, 0xAA,
+			0xCD, 0x72, 0xD7, 0xA6, 0xF3, 0x1E, 0x4F, 0x72,
+			0xC6, 0x49, 0x0F, 0x7B, 0xF0, 0x4C, 0x61, 0x1F,
+			0x43, 0x0D, 0x4F, 0x0D, 0x33, 0x13, 0xED, 0x63,
+			0xE5, 0xDB, 0x71, 0xAB, 0xA4, 0x83, 0xEF, 0xDC,
+			0x86, 0x9D, 0x4B, 0xBD, 0x1B, 0x8A, 0xFE, 0x39,
+			0xA8, 0x8B, 0xBA, 0x4C, 0x85, 0x28, 0xFC, 0xB3,
+			0x62, 0x85, 0xD2, 0xF0, 0x38, 0xD0, 0x4B, 0xA4,
+			0xD1, 0x3B, 0xD4, 0xD0, 0x2C, 0x78, 0x6C, 0x6A,
+			0xC2, 0x64, 0x2C, 0x31, 0x4A, 0xD8, 0x69, 0x24,
+			0xED, 0x77, 0x7D, 0x68, 0x9A, 0xA1, 0x78, 0x81,
+			0xD9, 0x7E, 0x6C, 0xFE, 0x0A, 0x0D, 0x76, 0xF7,
+			0x4B, 0x58, 0xE7, 0xC9, 0xB5, 0x11, 0x07, 0x87,
+			0x88, 0x6A, 0x9F, 0x3D, 0xE0, 0xEE, 0xCC, 0x60,
+			0x6B, 0x6B, 0xE6, 0xB5, 0x54, 0x8B, 0x32, 0x1F,
+			0x04, 0x1D, 0x0E, 0x9E, 0xFA, 0x6D, 0xB0, 0xE0,
+			0x6D, 0xF9, 0x79, 0xB4, 0xAB, 0x5E, 0xDF, 0x23,
+			0x7F, 0x95, 0xAD, 0x80, 0x17, 0x23, 0x90, 0x1F,
+			0xF0, 0xC3, 0xD9, 0x2D, 0xAC, 0x3F, 0x63, 0xF5,
+			0x77, 0xC5, 0x05, 0xAC, 0x06, 0xB6, 0xA1, 0xB4,
+			0xA2, 0x40, 0xB3, 0x99, 0x34, 0x7D, 0x31, 0xD4,
+			0xB1, 0xD4, 0xC1, 0xBB, 0x71, 0x1E, 0xDA, 0x3F,
+			0xA9, 0x12, 0x68, 0xFA, 0x5B, 0x20, 0x24, 0x6D,
+			0x4D, 0x72, 0x43, 0x18, 0xBF, 0x66, 0x71, 0x69,
+			0x26, 0x7D, 0x77, 0x78, 0xF8, 0xE5, 0x20, 0xAE,
+			0x56, 0x6C, 0x0F, 0x72, 0x94, 0x42, 0x85, 0x4F,
+			0xE4, 0xFB, 0x32, 0x26, 0x1B, 0x1C, 0x6E, 0x0B,
+			0xF0, 0xB8, 0x58, 0x00, 0xD2, 0x36, 0x64, 0xAD,
+			0xA9, 0x00, 0xCE, 0x35, 0x3C, 0x88, 0x79, 0x94,
+			0x0C, 0x0C, 0x9B, 0xF2, 0xDA, 0xBD, 0xCA, 0x93,
+			0x37, 0x26, 0xD3, 0x08, 0x54, 0xD2, 0x0D, 0xBC,
+			0x5D, 0x43, 0x5F, 0xCF, 0x28, 0xB5, 0xAA, 0x15,
+			0x28, 0x46, 0x45, 0x6B, 0xE8, 0xDF, 0xE8, 0xCE,
+			0x8F, 0xC0, 0x1A, 0x53, 0x63, 0x3B, 0x53, 0x75,
+			0xDD, 0x43, 0x1F, 0x07, 0x0A, 0xD5, 0xA1, 0x2A,
+			0x6E, 0x28, 0xE1, 0xD7, 0xD0, 0x09, 0xCF, 0x62,
+			0xC1, 0x5F, 0x21, 0xDB, 0xC5, 0x40, 0x99, 0x48,
+			0x87, 0x6E, 0x11, 0xF5, 0x5A, 0x4E, 0xBC, 0xF9,
+			0xA8, 0x02, 0x7C, 0x47, 0x39, 0xA5, 0xD8, 0x52,
+			0xB1, 0x80, 0xDC, 0xFE, 0x08, 0x4B, 0x5D, 0x09,
+			0xDE, 0x06, 0xF3, 0x2A, 0xAD, 0x14, 0x76, 0x40,
+			0x2F, 0x82, 0x28, 0x6A, 0xB6, 0x43, 0xEF, 0x71,
+			0x63, 0xC2, 0x56, 0xEB, 0x3B, 0x4B, 0x52, 0x2F,
+			0x93, 0xD3, 0x18, 0x3E, 0x18, 0xA8, 0xF7, 0x58,
+			0xFC, 0x8B, 0x3D, 0x4D, 0x4B, 0x72, 0xBD, 0xF7,
+			0x04, 0xC9, 0xB8, 0xD7, 0x6C, 0x8C, 0x67, 0xBB,
+			0x4C, 0x9B, 0x57, 0xF7, 0x22, 0x4E, 0x41, 0xB6,
+			0xFD, 0xD9, 0xF8, 0x41, 0x62, 0x0F, 0xFF, 0xAA,
+			0xC6, 0x87, 0x95, 0xFF, 0xFD, 0x58, 0xD9, 0xB2,
+			0xBA, 0x47, 0x61, 0x24, 0xEA, 0x92, 0x6E, 0x74,
+			0xB3, 0xDA, 0xE5, 0x83, 0x99, 0x24, 0xB1, 0x71,
+			0x2A, 0x33, 0xB2, 0xD5, 0x8F, 0xF0, 0x32, 0xCE,
+			0x37, 0xCF, 0xC7, 0x1C, 0xE8, 0xDE, 0x46, 0x78,
+			0x96, 0x97, 0xF6, 0x73, 0x90, 0xE5, 0x71, 0x05,
+			0xEA, 0x0D, 0xC2, 0x1D, 0x9E, 0x43, 0x34, 0xBC,
+			0x8F, 0x45, 0xE5, 0x08, 0xCA, 0x20, 0x0C, 0x84
+		},
+		.len = 2048
+	},
+	.auth_tag = {
+		.data = {
+			0xD0, 0x62, 0x1F, 0x20, 0x1C, 0xE8, 0xDD, 0x36,
+			0x00, 0x74, 0xF6, 0xD7, 0xFD, 0x2C, 0xA0, 0xAF
+		},
+		.len = 16
+	}
+};
+
 /** GMAC Test Vectors */
 static uint8_t gmac_plaintext[GMAC_LARGE_PLAINTEXT_LENGTH] = {
 			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 4/5] crypto: add sgl support in openssl PMD
From: Tomasz Kulasek @ 2017-01-05  9:12 UTC (permalink / raw)
  To: dev
In-Reply-To: <1483607556-21460-1-git-send-email-tomaszx.kulasek@intel.com>

Previous implementation uses EVP_EncryptUpdate() on whole source buffer
limiting its usage to the contiguous buffers.

This implementation calls EVP_EncryptUpdate() on each segment for cipher
operations in continuous mode, before finalization allowing to provide
chained mbuf as a source.

However, libcrypto library expects continuous destination buffer for
output of cipher operations and implementation of openssl PMD is limited
the same way, requiring contiguous destination mbuf.


Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
---
 doc/guides/cryptodevs/openssl.rst        |    3 +-
 drivers/crypto/openssl/rte_openssl_pmd.c |  329 +++++++++++++++++++++++-------
 2 files changed, 259 insertions(+), 73 deletions(-)

diff --git a/doc/guides/cryptodevs/openssl.rst b/doc/guides/cryptodevs/openssl.rst
index d2b5906..d0b1eeb 100644
--- a/doc/guides/cryptodevs/openssl.rst
+++ b/doc/guides/cryptodevs/openssl.rst
@@ -112,6 +112,7 @@ Limitations
 -----------
 
 * Maximum number of sessions is 2048.
-* Chained mbufs are not supported.
+* Chained mbufs are supported only for source mbuf (destination must be
+  contiguous).
 * Hash only is not supported for GCM and GMAC.
 * Cipher only is not supported for GCM and GMAC.
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 832ea1d..e466c79 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -484,24 +484,112 @@
  * Process Operations
  *------------------------------------------------------------------------------
  */
+static inline int
+process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
+		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
+{
+	struct rte_mbuf *m;
+	int dstlen;
+	int l, n = srclen;
+	uint8_t *src;
+
+	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
+			m = m->next)
+		offset -= rte_pktmbuf_data_len(m);
+
+	if (m == 0)
+		return -1;
+
+	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+
+	l = rte_pktmbuf_data_len(m) - offset;
+	if (srclen <= l) {
+		if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, srclen) <= 0)
+			return -1;
+		*dst += l;
+		return 0;
+	}
+
+	if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
+		return -1;
+
+	*dst += dstlen;
+	n -= l;
+
+	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		src = rte_pktmbuf_mtod(m, uint8_t *);
+		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
+			return -1;
+		*dst += dstlen;
+		n -= l;
+	}
+
+	return 0;
+}
+
+static inline int
+process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
+		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
+{
+	struct rte_mbuf *m;
+	int dstlen;
+	int l, n = srclen;
+	uint8_t *src;
+
+	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
+			m = m->next)
+		offset -= rte_pktmbuf_data_len(m);
+
+	if (m == 0)
+		return -1;
+
+	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+
+	l = rte_pktmbuf_data_len(m) - offset;
+	if (srclen <= l) {
+		if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, srclen) <= 0)
+			return -1;
+		*dst += l;
+		return 0;
+	}
+
+	if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
+		return -1;
+
+	*dst += dstlen;
+	n -= l;
+
+	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		src = rte_pktmbuf_mtod(m, uint8_t *);
+		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
+			return -1;
+		*dst += dstlen;
+		n -= l;
+	}
+
+	return 0;
+}
 
 /** Process standard openssl cipher encryption */
 static int
-process_openssl_cipher_encrypt(uint8_t *src, uint8_t *dst,
-		uint8_t *iv, uint8_t *key, int srclen,
+process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
+		int offset, uint8_t *iv, uint8_t *key, int srclen,
 		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
 {
-	int dstlen, totlen;
+	int totlen;
 
 	if (EVP_EncryptInit_ex(ctx, algo, NULL, key, iv) <= 0)
 		goto process_cipher_encrypt_err;
 
 	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
-	if (EVP_EncryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0)
+	if (process_openssl_encryption_update(mbuf_src, offset, &dst,
+			srclen, ctx))
 		goto process_cipher_encrypt_err;
 
-	if (EVP_EncryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0)
+	if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0)
 		goto process_cipher_encrypt_err;
 
 	return 0;
@@ -513,11 +601,11 @@
 
 /** Process standard openssl cipher decryption */
 static int
-process_openssl_cipher_decrypt(uint8_t *src, uint8_t *dst,
-		uint8_t *iv, uint8_t *key, int srclen,
+process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
+		int offset, uint8_t *iv, uint8_t *key, int srclen,
 		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
 {
-	int dstlen, totlen;
+	int totlen;
 
 	if (EVP_DecryptInit_ex(ctx, algo, NULL, key, iv) <= 0)
 		goto process_cipher_decrypt_err;
@@ -525,12 +613,12 @@
 	if (EVP_CIPHER_CTX_set_padding(ctx, 0) <= 0)
 		goto process_cipher_decrypt_err;
 
-	if (EVP_DecryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0)
+	if (process_openssl_decryption_update(mbuf_src, offset, &dst,
+			srclen, ctx))
 		goto process_cipher_decrypt_err;
 
-	if (EVP_DecryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0)
+	if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0)
 		goto process_cipher_decrypt_err;
-
 	return 0;
 
 process_cipher_decrypt_err:
@@ -540,11 +628,25 @@
 
 /** Process cipher des 3 ctr encryption, decryption algorithm */
 static int
-process_openssl_cipher_des3ctr(uint8_t *src, uint8_t *dst,
-		uint8_t *iv, uint8_t *key, int srclen, EVP_CIPHER_CTX *ctx)
+process_openssl_cipher_des3ctr(struct rte_mbuf *mbuf_src, uint8_t *dst,
+		int offset, uint8_t *iv, uint8_t *key, int srclen,
+		EVP_CIPHER_CTX *ctx)
 {
 	uint8_t ebuf[8], ctr[8];
 	int unused, n;
+	struct rte_mbuf *m;
+	uint8_t *src;
+	int l;
+
+	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
+			m = m->next)
+		offset -= rte_pktmbuf_data_len(m);
+
+	if (m == 0)
+		goto process_cipher_des3ctr_err;
+
+	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+	l = rte_pktmbuf_data_len(m) - offset;
 
 	/* We use 3DES encryption also for decryption.
 	 * IV is not important for 3DES ecb
@@ -553,9 +655,8 @@
 		goto process_cipher_des3ctr_err;
 
 	memcpy(ctr, iv, 8);
-	n = 0;
 
-	while (n < srclen) {
+	for (n = 0; n < srclen; n++) {
 		if (n % 8 == 0) {
 			if (EVP_EncryptUpdate(ctx,
 					(unsigned char *)&ebuf, &unused,
@@ -563,8 +664,16 @@
 				goto process_cipher_des3ctr_err;
 			ctr_inc(ctr);
 		}
-		dst[n] = src[n] ^ ebuf[n % 8];
-		n++;
+		dst[n] = *(src++) ^ ebuf[n % 8];
+
+		l--;
+		if (!l) {
+			m = m->next;
+			if (m) {
+				src = rte_pktmbuf_mtod(m, uint8_t *);
+				l = rte_pktmbuf_data_len(m);
+			}
+		}
 	}
 
 	return 0;
@@ -576,9 +685,9 @@
 
 /** Process auth/encription aes-gcm algorithm */
 static int
-process_openssl_auth_encryption_gcm(uint8_t *src, int srclen,
-		uint8_t *aad, int aadlen, uint8_t *iv, int ivlen,
-		uint8_t *key, uint8_t *dst,	uint8_t *tag,
+process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset,
+		int srclen, uint8_t *aad, int aadlen, uint8_t *iv, int ivlen,
+		uint8_t *key, uint8_t *dst, uint8_t *tag,
 		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
 {
 	int len = 0, unused = 0;
@@ -593,20 +702,20 @@
 	if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
 		goto process_auth_encryption_gcm_err;
 
-	if (aadlen > 0) {
+	if (aadlen > 0)
 		if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0)
 			goto process_auth_encryption_gcm_err;
 
-		/* Workaround open ssl bug in version less then 1.0.1f */
-		if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
-			goto process_auth_encryption_gcm_err;
-	}
-
 	if (srclen > 0)
-		if (EVP_EncryptUpdate(ctx, dst, &len, src, srclen) <= 0)
+		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
+				srclen, ctx))
 			goto process_auth_encryption_gcm_err;
 
-	if (EVP_EncryptFinal_ex(ctx, dst + len, &len) <= 0)
+	/* Workaround open ssl bug in version less then 1.0.1f */
+	if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
+		goto process_auth_encryption_gcm_err;
+
+	if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0)
 		goto process_auth_encryption_gcm_err;
 
 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0)
@@ -620,10 +729,10 @@
 }
 
 static int
-process_openssl_auth_decryption_gcm(uint8_t *src, int srclen,
-		uint8_t *aad, int aadlen, uint8_t *iv, int ivlen,
-		uint8_t *key, uint8_t *dst, uint8_t *tag,
-		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
+process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
+		int srclen, uint8_t *aad, int aadlen, uint8_t *iv, int ivlen,
+		uint8_t *key, uint8_t *dst, uint8_t *tag, EVP_CIPHER_CTX *ctx,
+		const EVP_CIPHER *algo)
 {
 	int len = 0, unused = 0;
 	uint8_t empty[] = {};
@@ -640,20 +749,20 @@
 	if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
 		goto process_auth_decryption_gcm_err;
 
-	if (aadlen > 0) {
+	if (aadlen > 0)
 		if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0)
 			goto process_auth_decryption_gcm_err;
 
-		/* Workaround open ssl bug in version less then 1.0.1f */
-		if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
-			goto process_auth_decryption_gcm_err;
-	}
-
 	if (srclen > 0)
-		if (EVP_DecryptUpdate(ctx, dst, &len, src, srclen) <= 0)
+		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
+				srclen, ctx))
 			goto process_auth_decryption_gcm_err;
 
-	if (EVP_DecryptFinal_ex(ctx, dst + len, &len) <= 0)
+	/* Workaround open ssl bug in version less then 1.0.1f */
+	if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
+		goto process_auth_decryption_gcm_err;
+
+	if (EVP_DecryptFinal_ex(ctx, dst, &len) <= 0)
 		goto process_auth_decryption_gcm_final_err;
 
 	return 0;
@@ -668,21 +777,50 @@
 
 /** Process standard openssl auth algorithms */
 static int
-process_openssl_auth(uint8_t *src, uint8_t *dst,
+process_openssl_auth(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset,
 		__rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey,
 		int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo)
 {
 	size_t dstlen;
+	struct rte_mbuf *m;
+	int l, n = srclen;
+	uint8_t *src;
+
+	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
+			m = m->next)
+		offset -= rte_pktmbuf_data_len(m);
+
+	if (m == 0)
+		goto process_auth_err;
 
 	if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0)
 		goto process_auth_err;
 
-	if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0)
+	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+
+	l = rte_pktmbuf_data_len(m) - offset;
+	if (srclen <= l) {
+		if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0)
+			goto process_auth_err;
+		goto process_auth_final;
+	}
+
+	if (EVP_DigestUpdate(ctx, (char *)src, l) <= 0)
 		goto process_auth_err;
 
+	n -= l;
+
+	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		src = rte_pktmbuf_mtod(m, uint8_t *);
+		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		if (EVP_DigestUpdate(ctx, (char *)src, l) <= 0)
+			goto process_auth_err;
+		n -= l;
+	}
+
+process_auth_final:
 	if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0)
 		goto process_auth_err;
-
 	return 0;
 
 process_auth_err:
@@ -692,18 +830,48 @@
 
 /** Process standard openssl auth algorithms with hmac */
 static int
-process_openssl_auth_hmac(uint8_t *src, uint8_t *dst,
+process_openssl_auth_hmac(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset,
 		__rte_unused uint8_t *iv, EVP_PKEY *pkey,
-		int srclen,	EVP_MD_CTX *ctx, const EVP_MD *algo)
+		int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo)
 {
 	size_t dstlen;
+	struct rte_mbuf *m;
+	int l, n = srclen;
+	uint8_t *src;
+
+	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
+			m = m->next)
+		offset -= rte_pktmbuf_data_len(m);
+
+	if (m == 0)
+		goto process_auth_err;
 
 	if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <= 0)
 		goto process_auth_err;
 
-	if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0)
+	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+
+	l = rte_pktmbuf_data_len(m) - offset;
+	if (srclen <= l) {
+		if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0)
+			goto process_auth_err;
+		goto process_auth_final;
+	}
+
+	if (EVP_DigestSignUpdate(ctx, (char *)src, l) <= 0)
 		goto process_auth_err;
 
+	n -= l;
+
+	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		src = rte_pktmbuf_mtod(m, uint8_t *);
+		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		if (EVP_DigestSignUpdate(ctx, (char *)src, l) <= 0)
+			goto process_auth_err;
+		n -= l;
+	}
+
+process_auth_final:
 	if (EVP_DigestSignFinal(ctx, dst, &dstlen) <= 0)
 		goto process_auth_err;
 
@@ -723,9 +891,18 @@
 		struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
 {
 	/* cipher */
-	uint8_t *src = NULL, *dst = NULL, *iv, *tag, *aad;
+	uint8_t *dst = NULL, *iv, *tag, *aad;
 	int srclen, ivlen, aadlen, status = -1;
 
+	/*
+	 * Segmented destination buffer is not supported for
+	 * encryption/decryption
+	 */
+	if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
+		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+		return;
+	}
+
 	iv = op->sym->cipher.iv.data;
 	ivlen = op->sym->cipher.iv.length;
 	aad = op->sym->auth.aad.data;
@@ -741,22 +918,22 @@
 		srclen = 0;
 	else {
 		srclen = op->sym->cipher.data.length;
-		src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
-				op->sym->cipher.data.offset);
 		dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
 				op->sym->cipher.data.offset);
 	}
 
 	if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
 		status = process_openssl_auth_encryption_gcm(
-				src, srclen, aad, aadlen, iv, ivlen,
-				sess->cipher.key.data, dst, tag,
-				sess->cipher.ctx, sess->cipher.evp_algo);
+				mbuf_src, op->sym->cipher.data.offset, srclen,
+				aad, aadlen, iv, ivlen, sess->cipher.key.data,
+				dst, tag, sess->cipher.ctx,
+				sess->cipher.evp_algo);
 	else
 		status = process_openssl_auth_decryption_gcm(
-				src, srclen, aad, aadlen, iv, ivlen,
-				sess->cipher.key.data, dst, tag,
-				sess->cipher.ctx, sess->cipher.evp_algo);
+				mbuf_src, op->sym->cipher.data.offset, srclen,
+				aad, aadlen, iv, ivlen, sess->cipher.key.data,
+				dst, tag, sess->cipher.ctx,
+				sess->cipher.evp_algo);
 
 	if (status != 0) {
 		if (status == (-EFAULT) &&
@@ -774,12 +951,19 @@
 		(struct rte_crypto_op *op, struct openssl_session *sess,
 		struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
 {
-	uint8_t *src, *dst, *iv;
+	uint8_t *dst, *iv;
 	int srclen, status;
 
+	/*
+	 * Segmented destination buffer is not supported for
+	 * encryption/decryption
+	 */
+	if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
+		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+		return;
+	}
+
 	srclen = op->sym->cipher.data.length;
-	src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
-			op->sym->cipher.data.offset);
 	dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
 			op->sym->cipher.data.offset);
 
@@ -787,17 +971,20 @@
 
 	if (sess->cipher.mode == OPENSSL_CIPHER_LIB)
 		if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
-			status = process_openssl_cipher_encrypt(src, dst, iv,
+			status = process_openssl_cipher_encrypt(mbuf_src, dst,
+					op->sym->cipher.data.offset, iv,
 					sess->cipher.key.data, srclen,
 					sess->cipher.ctx,
 					sess->cipher.evp_algo);
 		else
-			status = process_openssl_cipher_decrypt(src, dst, iv,
+			status = process_openssl_cipher_decrypt(mbuf_src, dst,
+					op->sym->cipher.data.offset, iv,
 					sess->cipher.key.data, srclen,
 					sess->cipher.ctx,
 					sess->cipher.evp_algo);
 	else
-		status = process_openssl_cipher_des3ctr(src, dst, iv,
+		status = process_openssl_cipher_des3ctr(mbuf_src, dst,
+				op->sym->cipher.data.offset, iv,
 				sess->cipher.key.data, srclen,
 				sess->cipher.ctx);
 
@@ -811,12 +998,10 @@
 		(struct rte_crypto_op *op, struct openssl_session *sess,
 		struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
 {
-	uint8_t *src, *dst;
+	uint8_t *dst;
 	int srclen, status;
 
 	srclen = op->sym->auth.data.length;
-	src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
-			op->sym->auth.data.offset);
 
 	if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY)
 		dst = (uint8_t *)rte_pktmbuf_append(mbuf_src,
@@ -831,13 +1016,14 @@
 
 	switch (sess->auth.mode) {
 	case OPENSSL_AUTH_AS_AUTH:
-		status = process_openssl_auth(src, dst,
-				NULL, NULL,	srclen,
+		status = process_openssl_auth(mbuf_src, dst,
+				op->sym->auth.data.offset, NULL, NULL, srclen,
 				sess->auth.auth.ctx, sess->auth.auth.evp_algo);
 		break;
 	case OPENSSL_AUTH_AS_HMAC:
-		status = process_openssl_auth_hmac(src, dst,
-				NULL, sess->auth.hmac.pkey, srclen,
+		status = process_openssl_auth_hmac(mbuf_src, dst,
+				op->sym->auth.data.offset, NULL,
+				sess->auth.hmac.pkey, srclen,
 				sess->auth.hmac.ctx, sess->auth.hmac.evp_algo);
 		break;
 	default:
@@ -851,8 +1037,7 @@
 			op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
 		}
 		/* Trim area used for digest from mbuf. */
-		rte_pktmbuf_trim(mbuf_src,
-				op->sym->auth.digest.length);
+		rte_pktmbuf_trim(mbuf_src, op->sym->auth.digest.length);
 	}
 
 	if (status != 0)
@@ -903,7 +1088,6 @@
 		op->sym->session = NULL;
 	}
 
-
 	if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
 		op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
 
@@ -997,7 +1181,8 @@
 
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_CPU_AESNI;
+			RTE_CRYPTODEV_FF_CPU_AESNI |
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
 
 	/* Set vector instructions mode supported */
 	internals = dev->data->dev_private;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 3/5] crypto: add sgl support in sw PMDs
From: Tomasz Kulasek @ 2017-01-05  9:12 UTC (permalink / raw)
  To: dev
In-Reply-To: <1483607556-21460-1-git-send-email-tomaszx.kulasek@intel.com>

This patch introduces RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER feature flag
informing that selected crypto device supports segmented mbufs natively
and doesn't need to be coalesced before crypto operation.

While using segmented buffers in crypto devices may have unpredictable
results, for PMDs which doesn't support it natively, additional check is
made for debug compilation.

Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
---
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c   |   14 ++++++++++++++
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c |   19 ++++++++++++++++---
 drivers/crypto/kasumi/rte_kasumi_pmd.c     |   13 +++++++++++++
 drivers/crypto/null/null_crypto_pmd.c      |    3 ++-
 drivers/crypto/snow3g/rte_snow3g_pmd.c     |   15 +++++++++++++++
 drivers/crypto/zuc/rte_zuc_pmd.c           |   13 +++++++++++++
 lib/librte_cryptodev/rte_cryptodev.c       |    4 ++--
 lib/librte_cryptodev/rte_cryptodev.h       |    2 ++
 8 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index dba5e15..1a6120c 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -375,6 +375,20 @@
 			break;
 		}
 
+#ifdef RTE_LIBRTE_PMD_AESNI_GCM_DEBUG
+		if (!rte_pktmbuf_is_contiguous(ops[i]->sym->m_src) ||
+				(ops[i]->sym->m_dst != NULL &&
+				!rte_pktmbuf_is_contiguous(
+						ops[i]->sym->m_dst))) {
+			ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+			GCM_LOG_ERR("PMD supports only contiguous mbufs, "
+				"op (%p) provides noncontiguous mbuf as "
+				"source/destination buffer.\n", ops[i]);
+			qp->qp_stats.enqueue_err_count++;
+			break;
+		}
+#endif
+
 		retval = process_gcm_crypto_op(qp, ops[i]->sym, sess);
 		if (retval < 0) {
 			ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index 6d27d75..25f681b 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -571,15 +571,28 @@
 	int i, processed_jobs = 0;
 
 	for (i = 0; i < nb_ops; i++) {
-#ifdef RTE_LIBRTE_AESNI_MB_DEBUG
-		if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC)) {
+#ifdef RTE_LIBRTE_PMD_AESNI_MB_DEBUG
+		if (unlikely(ops[i]->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC)) {
 			MB_LOG_ERR("PMD only supports symmetric crypto "
 				"operation requests, op (%p) is not a "
-				"symmetric operation.", op);
+				"symmetric operation.", ops[i]);
+			qp->stats.enqueue_err_count++;
+			goto flush_jobs;
+		}
+
+		if (!rte_pktmbuf_is_contiguous(ops[i]->sym->m_src) ||
+				(ops[i]->sym->m_dst != NULL &&
+				!rte_pktmbuf_is_contiguous(
+						ops[i]->sym->m_dst))) {
+			MB_LOG_ERR("PMD supports only contiguous mbufs, "
+				"op (%p) provides noncontiguous mbuf as "
+				"source/destination buffer.\n", ops[i]);
+			ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
 			qp->stats.enqueue_err_count++;
 			goto flush_jobs;
 		}
 #endif
+
 		sess = get_session(qp, ops[i]);
 		if (unlikely(sess == NULL)) {
 			qp->stats.enqueue_err_count++;
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index b119da2..4bdd7bb 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -455,6 +455,19 @@
 	for (i = 0; i < nb_ops; i++) {
 		curr_c_op = ops[i];
 
+#ifdef RTE_LIBRTE_PMD_KASUMI_DEBUG
+		if (!rte_pktmbuf_is_contiguous(curr_c_op->sym->m_src) ||
+				(curr_c_op->sym->m_dst != NULL &&
+				!rte_pktmbuf_is_contiguous(
+						curr_c_op->sym->m_dst))) {
+			KASUMI_LOG_ERR("PMD supports only contiguous mbufs, "
+				"op (%p) provides noncontiguous mbuf as "
+				"source/destination buffer.\n", curr_c_op);
+			curr_c_op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+			break;
+		}
+#endif
+
 		/* Set status as enqueued (not processed yet) by default. */
 		curr_c_op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
 
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index c69606b..c37d3d6 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -216,7 +216,8 @@
 	dev->enqueue_burst = null_crypto_pmd_enqueue_burst;
 
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
-			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING;
+			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
 
 	internals = dev->data->dev_private;
 
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index 3b4292a..9a6f16d 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -330,6 +330,21 @@
 	unsigned i;
 	unsigned enqueued_ops, processed_ops;
 
+#ifdef RTE_LIBRTE_PMD_SNOW3G_DEBUG
+	for (i = 0; i < num_ops; i++) {
+		if (!rte_pktmbuf_is_contiguous(ops[i]->sym->m_src) ||
+				(ops[i]->sym->m_dst != NULL &&
+				!rte_pktmbuf_is_contiguous(
+						ops[i]->sym->m_dst))) {
+			SNOW3G_LOG_ERR("PMD supports only contiguous mbufs, "
+				"op (%p) provides noncontiguous mbuf as "
+				"source/destination buffer.\n", ops[i]);
+			ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+			return 0;
+		}
+	}
+#endif
+
 	switch (session->op) {
 	case SNOW3G_OP_ONLY_CIPHER:
 		processed_ops = process_snow3g_cipher_op(ops,
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index 3849119..bf53f76 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -211,6 +211,19 @@
 			break;
 		}
 
+#ifdef RTE_LIBRTE_PMD_ZUC_DEBUG
+		if (!rte_pktmbuf_is_contiguous(ops[i]->sym->m_src) ||
+				(ops[i]->sym->m_dst != NULL &&
+				!rte_pktmbuf_is_contiguous(
+						ops[i]->sym->m_dst))) {
+			ZUC_LOG_ERR("PMD supports only contiguous mbufs, "
+				"op (%p) provides noncontiguous mbuf as "
+				"source/destination buffer.\n", ops[i]);
+			ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+			break;
+		}
+#endif
+
 		src[i] = rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +
 				(ops[i]->sym->cipher.data.offset >> 3);
 		dst[i] = ops[i]->sym->m_dst ?
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 54e95d5..bbab4b3 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -211,13 +211,13 @@ struct rte_cryptodev_callback {
 		return "CPU_AESNI";
 	case RTE_CRYPTODEV_FF_HW_ACCELERATED:
 		return "HW_ACCELERATED";
-
+	case RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER:
+		return "MBUF_SCATTER_GATHER";
 	default:
 		return NULL;
 	}
 }
 
-
 int
 rte_cryptodev_create_vdev(const char *name, const char *args)
 {
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 29d8eec..fa311a9 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -227,6 +227,8 @@ struct rte_cryptodev_capabilities {
 /**< Operations are off-loaded to an external hardware accelerator */
 #define	RTE_CRYPTODEV_FF_CPU_AVX512		(1ULL << 8)
 /**< Utilises CPU SIMD AVX512 instructions */
+#define	RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER	(1ULL << 9)
+/**< Scatter-gather mbufs are supported */
 
 
 /**
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 2/5] test: add rte_pktmbuf_linearize unit tests
From: Tomasz Kulasek @ 2017-01-05  9:12 UTC (permalink / raw)
  To: dev
In-Reply-To: <1483607556-21460-1-git-send-email-tomaszx.kulasek@intel.com>

This patch tests rte_pktmbuf_linearize functionality:

 1) Creates banch of segmented mbufs with different size and number of
    segments.
 2) Generates pkt_len bytes of random data.
 3) Fills noncontigouos mbuf with randomly generated data.
 4) Uses rte_pktmbuf_linearize to coalesce segmented buffer into one
    contiguous.
 5) Verifies data in linearized buffer.

Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
---
 app/test/test_mbuf.c |  123 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index c0823ea..39577e7 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -930,6 +930,124 @@
 	return 0;
 }
 
+static int
+test_mbuf_linearize(int pkt_len, int nb_segs) {
+
+	struct rte_mbuf *m = NULL, *mbuf_src = NULL;
+	uint8_t data[pkt_len], *src, *dst;
+	int data_len = 0;
+	int i, size;
+	int t_len;
+
+	if (pkt_len < 1) {
+		printf("Packet size must be 1 or more (is %d)\n", pkt_len);
+		return -1;
+	}
+
+	if (nb_segs < 1) {
+		printf("Number of segments must be 1 or more (is %d)\n",
+				nb_segs);
+		return -1;
+	}
+
+	/* Setup buffer */
+	for (i = 0; i < pkt_len; i++)
+		data[i] = (uint8_t) rte_rand();
+
+	t_len = pkt_len >= nb_segs ? pkt_len / nb_segs : 1;
+	src = data;
+	size = pkt_len;
+
+	/* Create chained mbuf_src and fill it generated data */
+	for (i = 0; size > 0; i++) {
+
+		m = rte_pktmbuf_alloc(pktmbuf_pool);
+		if (i == 0)
+			mbuf_src = m;
+
+		if (!m) {
+			printf("Cannot create segment for source mbuf");
+			goto fail;
+		}
+
+		/* Make sure if tailroom is zeroed */
+		memset(rte_pktmbuf_mtod(m, uint8_t *), 0,
+				rte_pktmbuf_tailroom(m));
+
+		data_len = size > t_len ? t_len : size;
+		dst = (uint8_t *)rte_pktmbuf_append(m, data_len);
+		if (!dst) {
+			printf("Cannot append %d bytes to the mbuf\n",
+					data_len);
+			goto fail;
+		}
+
+		rte_memcpy(dst, src, data_len);
+		src += data_len;
+
+		if (mbuf_src != m)
+			rte_pktmbuf_chain(mbuf_src, m);
+
+		size -= data_len;
+
+	}
+
+	/* Create destination buffer to store coalesced data */
+	if (rte_pktmbuf_linearize(mbuf_src)) {
+		printf("Mbuf linearization failed\n");
+		goto fail;
+	}
+
+	if (!rte_pktmbuf_is_contiguous(mbuf_src)) {
+		printf("Source buffer should be contiguous after "
+				"linearization\n");
+		goto fail;
+	}
+
+	src = rte_pktmbuf_mtod(mbuf_src, uint8_t *);
+
+	if (memcmp(src, data, rte_pktmbuf_pkt_len(mbuf_src))) {
+		printf("Incorrect data in coalesced mbuf\n");
+		goto fail;
+	}
+
+	if (mbuf_src)
+		rte_pktmbuf_free(mbuf_src);
+	return 0;
+
+fail:
+	if (mbuf_src)
+		rte_pktmbuf_free(mbuf_src);
+	return -1;
+}
+
+static int
+test_mbuf_linearize_check(void)
+{
+	struct test_mbuf_array {
+		int size;
+		int nb_segs;
+	} mbuf_array[5] = {
+			{ 128, 1 },
+			{ 64, 64 },
+			{ 512, 10 },
+			{ 250, 11 },
+			{ 123, 8 },
+	};
+	unsigned int i;
+
+	printf("Test mbuf linearize API\n");
+
+	for (i = 0; i < RTE_DIM(mbuf_array); i++)
+		if (test_mbuf_linearize(mbuf_array[i].size,
+				mbuf_array[i].nb_segs)) {
+			printf("Test failed for %d, %d\n", mbuf_array[i].size,
+					mbuf_array[i].nb_segs);
+			return -1;
+		}
+
+	return 0;
+}
 
 static int
 test_mbuf(void)
@@ -1023,6 +1141,11 @@
 		printf("test_failing_mbuf_sanity_check() failed\n");
 		return -1;
 	}
+
+	if (test_mbuf_linearize_check() < 0) {
+		printf("test_mbuf_linearize_check() failed\n");
+		return -1;
+	}
 	return 0;
 }
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 1/5] rte_mbuf: add rte_pktmbuf_linearize
From: Tomasz Kulasek @ 2017-01-05  9:12 UTC (permalink / raw)
  To: dev
In-Reply-To: <1483607556-21460-1-git-send-email-tomaszx.kulasek@intel.com>

This patch adds function rte_pktmbuf_linearize to let crypto PMD coalesce
chained mbuf before crypto operation and extend their capabilities to
support segmented mbufs when device cannot handle them natively.

Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
---
 lib/librte_mbuf/rte_mbuf.h |   56 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index ead7c6e..b11a31d 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -1647,6 +1647,62 @@ static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail
 }
 
 /**
+ * Linearize data in mbuf.
+ *
+ * This function coalesce mbuf merging data in the first segment, unchaining
+ * rest, and then frees them.
+ *
+ * All operations are done in-place, so the structure of incoming mbuf
+ * is changed.
+ *
+ * @param mbuf
+ *   mbuf to linearize
+ * @return
+ *   - 0, on success
+ *   - -1, on error
+ */
+static inline int
+rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
+{
+	int l, n;
+	struct rte_mbuf *m;
+	struct rte_mbuf *m_next;
+	char *buffer;
+
+	if (rte_pktmbuf_is_contiguous(mbuf))
+		return 0;
+
+	/* Extend first segment to the total packet length
+	 */
+	n = rte_pktmbuf_pkt_len(mbuf) - rte_pktmbuf_data_len(mbuf);
+
+	if (unlikely(n > rte_pktmbuf_tailroom(mbuf)))
+		return -1;
+
+	buffer = rte_pktmbuf_mtod_offset(mbuf, char *, mbuf->data_len);
+	mbuf->data_len = (uint16_t)(mbuf->pkt_len);
+
+	/* Append data from next segments to the first one
+	 */
+	m = mbuf->next;
+	while (m != NULL) {
+		m_next = m->next;
+
+		l = rte_pktmbuf_data_len(m);
+		rte_memcpy(buffer, rte_pktmbuf_mtod(m, char *), l);
+		buffer += l;
+
+		rte_pktmbuf_free_seg(m);
+		m = m_next;
+	}
+
+	mbuf->next = NULL;
+	mbuf->nb_segs = 1;
+
+	return 0;
+}
+
+/**
  * Dump an mbuf structure to a file.
  *
  * Dump all fields for the given packet mbuf and all its associated
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 0/5] Chained Mbufs support in SW PMDs
From: Tomasz Kulasek @ 2017-01-05  9:12 UTC (permalink / raw)
  To: dev
In-Reply-To: <1483031543-21196-1-git-send-email-tomaszx.kulasek@intel.com>

This patch set adds support of scattered-gather list for SW PMDs.

As of now, application needs to reserve continuous block of memory for
mbufs which is not always the case. Hence needed to support chaining of
mbufs which are smaller in size but can be used if chained.


Above work involves:
--------------------

 a) Create mbuf functions to coalesce mbuf chains into a single mbuf.
 b) For each software poll mode driver code to detect chained mbufs
    support and coalesce these before preforming crypto.
 c) Add relevant unit tests to test the functionality.


Known limitations for openssl PMD:
----------------------------------

While libcrypto library expects continuous destination buffer for
output of cipher operations, implementation of openssl PMD is limited
the same way, and requires contigous destination mbuf.


Dependencies:
-------------

This patch set shares some unit tests with SGL implementation for QAT
(already merged in dpdk-next-crypto) and should be applied on top of it,
and after applying fix "app/test: fix aad padding size in SGL operation"
by Arek Kusztal.


changes in v3:
 - rebased to dpdk-next-crypto
 - reused tests for AES GCM SGL support in opensll from "app/test: add
   SGL tests to cryptodev QAT suite"

changes in v2:
 - add support for sgl in openssl PMD
 - rte_pktmbuf_coalesce replaced with rte_pktmbuf_linearize
 - extended test vector data for aes gcm from 60 to 2048 bytes

Tomasz Kulasek (5):
  rte_mbuf: add rte_pktmbuf_linearize
  test: add rte_pktmbuf_linearize unit tests
  crypto: add sgl support in sw PMDs
  crypto: add sgl support in openssl PMD
  test: add sgl unit tests for crypto devices

 app/test/test_cryptodev.c                  |  386 ++++++++++++++++++-
 app/test/test_cryptodev.h                  |  139 +++++++
 app/test/test_cryptodev_aes_test_vectors.h |   52 +++
 app/test/test_cryptodev_blockcipher.c      |  180 +++++----
 app/test/test_cryptodev_blockcipher.h      |    1 +
 app/test/test_cryptodev_gcm_test_vectors.h |  553 ++++++++++++++++++++++++++++
 app/test/test_mbuf.c                       |  123 +++++++
 doc/guides/cryptodevs/openssl.rst          |    3 +-
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c   |   14 +
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c |   19 +-
 drivers/crypto/kasumi/rte_kasumi_pmd.c     |   13 +
 drivers/crypto/null/null_crypto_pmd.c      |    3 +-
 drivers/crypto/openssl/rte_openssl_pmd.c   |  329 +++++++++++++----
 drivers/crypto/snow3g/rte_snow3g_pmd.c     |   15 +
 drivers/crypto/zuc/rte_zuc_pmd.c           |   13 +
 lib/librte_cryptodev/rte_cryptodev.c       |    4 +-
 lib/librte_cryptodev/rte_cryptodev.h       |    2 +
 lib/librte_mbuf/rte_mbuf.h                 |   56 +++
 18 files changed, 1756 insertions(+), 149 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* Re: [PATCH v7 04/27] net/i40e: set VF VLAN anti-spoofing from PF
From: Wu, Jingjing @ 2017-01-05  8:52 UTC (permalink / raw)
  To: Lu, Wenzhuo, dev@dpdk.org; +Cc: Lu, Wenzhuo
In-Reply-To: <1483426488-117332-5-git-send-email-wenzhuo.lu@intel.com>



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wenzhuo Lu
> Sent: Tuesday, January 3, 2017 2:54 PM
> To: dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>
> Subject: [dpdk-dev] [PATCH v7 04/27] net/i40e: set VF VLAN anti-spoofing from
> PF
> 
> Support enabling/disabling VF VLAN anti-spoofing from PF.
> User can call the API on PF to enable/disable a specific VF's VLAN anti-spoofing.
> 
> Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c            | 116
> +++++++++++++++++++++++++++++-
>  drivers/net/i40e/i40e_ethdev.h            |   1 +
>  drivers/net/i40e/rte_pmd_i40e.h           |  19 +++++
>  drivers/net/i40e/rte_pmd_i40e_version.map |   1 +
>  4 files changed, 135 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 68c07de..bcc59b2 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -4418,6 +4418,7 @@ struct i40e_vsi *
>  	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
>  	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
>  	vsi->user_param = user_param;
> +	vsi->vlan_anti_spoof_on = 0;
>  	/* Allocate queues */
>  	switch (vsi->type) {
>  	case I40E_VSI_MAIN  :
> @@ -5761,17 +5762,35 @@ struct i40e_vsi *
>  			 uint16_t vlan_id, bool on)
>  {
>  	uint32_t vid_idx, vid_bit;
> +	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
> +	struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
> +	int ret;
> 
>  	if (vlan_id > ETH_VLAN_ID_MAX)
>  		return;
> 
>  	vid_idx = I40E_VFTA_IDX(vlan_id);
>  	vid_bit = I40E_VFTA_BIT(vlan_id);
> +	vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
> 
> -	if (on)
> +	if (on) {
> +		if (vsi->vlan_anti_spoof_on) {
> +			ret = i40e_aq_add_vlan(hw, vsi->seid,
> +					       &vlan_data, 1, NULL);
> +			if (ret != I40E_SUCCESS)
> +				PMD_DRV_LOG(ERR, "Failed to add vlan filter");
> +		}
>  		vsi->vfta[vid_idx] |= vid_bit;
> -	else
> +	} else {
> +		if (vsi->vlan_anti_spoof_on) {
> +			ret = i40e_aq_remove_vlan(hw, vsi->seid,
> +						  &vlan_data, 1, NULL);
> +			if (ret != I40E_SUCCESS)
> +				PMD_DRV_LOG(ERR,
> +					    "Failed to remove vlan filter");
> +		}
>  		vsi->vfta[vid_idx] &= ~vid_bit;
> +	}
>  }
> 
The function i40e_set_vlan_filter is used to store the vlan info
in vsi structure. I think it will be better to move the hardware vlan filter handling
to i40e_vsi_add_vlan who called the i40e_set_vlan_filter function to let the
code more easy to maintain.

Thanks
Jingjing

^ permalink raw reply

* Re: [PATCH v2 14/18] net/ixgbe: parse L2 tunnel filter
From: Adrien Mazarguil @ 2017-01-05  8:52 UTC (permalink / raw)
  To: Zhao1, Wei; +Cc: dev@dpdk.org, Lu, Wenzhuo
In-Reply-To: <A2573D2ACFCADC41BB3BE09C6DE313CA0201B648@PGSMSX103.gar.corp.intel.com>

On Thu, Jan 05, 2017 at 03:12:01AM +0000, Zhao1, Wei wrote:
> Hi, adrien
> 
> > -----Original Message-----
> > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > Sent: Tuesday, January 3, 2017 10:08 PM
> > To: Zhao1, Wei <wei.zhao1@intel.com>
> > Cc: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH v2 14/18] net/ixgbe: parse L2 tunnel filter
> > 
> > Hi Wei,
> > 
> > On Fri, Dec 30, 2016 at 03:53:06PM +0800, Wei Zhao wrote:
> > > check if the rule is a L2 tunnel rule, and get the L2 tunnel info.
> > >
> > > Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
> > > Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
> > >
> > > ---
> > >
> > > v2:
> > > --add new error set function
> > > --change return value type of parser function
> > > ---
> > >  drivers/net/ixgbe/ixgbe_ethdev.c | 269
> > +++++++++++++++++++++++++++++++++++----
> > >  lib/librte_ether/rte_flow.h      |  32 +++++
> > >  2 files changed, 273 insertions(+), 28 deletions(-)
> > [...]
> > > diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
> > > index 98084ac..e9e6220 100644
> > > --- a/lib/librte_ether/rte_flow.h
> > > +++ b/lib/librte_ether/rte_flow.h
> > > @@ -268,6 +268,13 @@ enum rte_flow_item_type {
> > >  	 * See struct rte_flow_item_vxlan.
> > >  	 */
> > >  	RTE_FLOW_ITEM_TYPE_VXLAN,
> > > +
> > > +	/**
> > > +	  * Matches a E_TAG header.
> > > +	  *
> > > +	  * See struct rte_flow_item_e_tag.
> > > +	  */
> > > +	RTE_FLOW_ITEM_TYPE_E_TAG,
> > >  };
> > >
> > >  /**
> > > @@ -454,6 +461,31 @@ struct rte_flow_item_vxlan {  };
> > >
> > >  /**
> > > + * RTE_FLOW_ITEM_TYPE_E_TAG.
> > > + *
> > > + * Matches a E-tag header.
> > > + */
> > > +struct rte_flow_item_e_tag {
> > > +	struct ether_addr dst; /**< Destination MAC. */
> > > +	struct ether_addr src; /**< Source MAC. */
> > > +	uint16_t e_tag_ethertype; /**< E-tag EtherType, 0x893F. */
> > > +	uint16_t e_pcp:3; /**<  E-PCP */
> > > +	uint16_t dei:1; /**< DEI */
> > > +	uint16_t in_e_cid_base:12; /**< Ingress E-CID base */
> > > +	uint16_t rsv:2; /**< reserved */
> > > +	uint16_t grp:2; /**< GRP */
> > > +	uint16_t e_cid_base:12; /**< E-CID base */
> > > +	uint16_t in_e_cid_ext:8; /**< Ingress E-CID extend */
> > > +	uint16_t e_cid_ext:8; /**< E-CID extend */
> > > +	uint16_t type; /**< MAC type. */
> > > +	unsigned int tags; /**< Number of 802.1Q/ad tags defined. */
> > > +	struct {
> > > +		uint16_t tpid; /**< Tag protocol identifier. */
> > > +		uint16_t tci; /**< Tag control information. */
> > > +	} tag[]; /**< 802.1Q/ad tag definitions, outermost first. */ };
> > [...]
> > 
> > See my previous reply [1], this definition is not endian-safe and comprises
> > protocols defined as independent items (namely ETH and VLAN). Here is an
> > untested suggestion:
> > 
> >  struct rte_flow_item_e_tag {
> >      uint16_t tpid; /**< Tag protocol identifier (0x893F). */
> >      /** E-Tag control information (E-TCI). */
> >      uint16_t epcp_edei_in_ecid_b; /**< E-PCP (3b), E-DEI (1b), ingress E-CID
> > base (12b). */
> >      uint16_t rsvd_grp_ecid_b; /**< Reserved (2b), GRP (2b), E-CID base (12b).
> > */
> >      uint8_t in_ecid_e; /**< Ingress E-CID ext. */
> >      uint8_t ecid_e; /**< E-CID ext. */
> >  };
> > 
> > Applications are responsibile for breaking down and filling individual fields
> > properly. Ethernet header would be provided as its own item as shown in
> > this testpmd flow command example:
> > 
> >  flow create 0 ingress pattern eth / e_tag in_ecid_base is 42 / end actions
> > drop / end
> > 
> 
> In this case , is  eth  an option or mandatory? 
> I think it is optional, because user may do not have any parameter in ETH  config.

Normally, protocol items start from L2 so applications *should* provide
ETH otherwise it is an error.

Now a PMD may also allow it to be implicit when it is unambiguous (e.g. an
imaginary ETH item provided without a mask) as described in the "UDPv6
anywhere" example [2]. It's up to you.

> > Note, all multibyte values are in network order like other protocol header
> > definitions.
> > 
> > [1] http://dpdk.org/ml/archives/dev/2016-December/053181.html
> >     Message ID: 20161223081310.GH10340@6wind.com

[2] http://dpdk.org/doc/guides/prog_guide/rte_flow.html#matching-pattern

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply

* Re: [PATCH v5 3/8] ethdev: reserve capability flags for PMD-specific API
From: Adrien Mazarguil @ 2017-01-05  8:33 UTC (permalink / raw)
  To: Tiwei Bie
  Cc: Ananyev, Konstantin, dev@dpdk.org, Lu, Wenzhuo, Mcnamara, John,
	olivier.matz@6wind.com, thomas.monjalon@6wind.com, Zhang, Helin,
	Dai, Wei, Wang, Xiao W
In-Reply-To: <20170104235608.GA133542@dpdk19>

On Thu, Jan 05, 2017 at 07:56:08AM +0800, Tiwei Bie wrote:
> On Thu, Jan 05, 2017 at 01:44:18AM +0800, Ananyev, Konstantin wrote:
> [...]
> > > >
> > > > I understand that.
> > > > My question was: suppose user would like to create a bonded device over 2 NICs.
> > > > One of them is ixgbe, while other would be some other type.
> > > > In future get_dev_info() for each of them might return DEV_RX_OFFLOAD_RESERVED_0  bit as set.
> > > > But it would mean completely different thing.
> > > > How bonded device would know that to deal properly?
> > > >
> > > > Another example - user has 2 NICs of different type and would like to send the same packet on both of them simultaneously.
> > > > As PKT_TX_RESERVED might mean different things for these devices, and user would like to use let say
> > > > PKT_TX_IXGBE_MACSEC on one of them, he would need to do a copy of them, instead just increment a refcnt.
> > > >
> > > > Similar issues might arise at RX handling: user got a packet with PKT_RX_RESERVED_0 set.
> > > > What does it really mean if there are different NIC types in the system?
> > > > The only way to answer that question, as I can see,  is to keep track from what NIC that packet was received.
> > > > Which I suppose, is not always convenient.
> > > >
> > > 
> > > The main purpose is to put the PMD-specific APIs in a separate
> > > namespace instead of mixing the PMD-specific APIs and global APIs
> > > up, and also save the bits in mbuf.ol_flags.
> > > 
> > > There are other ways to achieve this goal, such as introducing
> > > the PMD specific ol_flags in mbuf second cache line as you said.
> > > I just thought defining some reserved bits seems to be the most
> > > simple way which won't introduce many changes.
> > > 
> > > What's your suggestions? Should I just revert the changes and
> > > define the generic flags directly?
> > 
> > Yes, that would be my preference.
> > As I said above - spending extra bit in ol_flags  doesn't look like a big problem to me.
> > In return there would be no need to consider how to handle all that confusing scenarios in future.
> 
> Okay. I'll update my patches. Thanks a lot for your comments.

Well, I do not agree with Konstantin (no one saw this coming eh?) and do not
think you need to update your series again.

PMD-specific symbols have nothing to do in the global namespace in my
opinion, they are not versioned and may evolve without notice. Neither
applications nor the bonding PMD can rely on them. That's the trade-off.

Therefore until APIs are made global, the safe compromise is to define
neutral, reserved symbols that any PMD can use to implement their own
temporary APIs for testing purposes. These can be renamed later without
changing their value as long as a single PMD uses them.

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply

* Re: [PATCH v2 09/29] eal/arm64: define I/O device memory barriers for arm64
From: Jerin Jacob @ 2017-01-05  7:22 UTC (permalink / raw)
  To: Jianbo Liu
  Cc: dev, Ananyev, Konstantin, Thomas Monjalon, Bruce Richardson,
	Jan Viktorin, Santosh Shukla, David Marchand
In-Reply-To: <CAP4Qi38t+oNR1jQnOyoVG9Upz-TpS3G2pZGZOutoHjJF_c_uOw@mail.gmail.com>

On Thu, Jan 05, 2017 at 02:47:27PM +0800, Jianbo Liu wrote:
> On 5 January 2017 at 14:24, Jerin Jacob <jerin.jacob@caviumnetworks.com> wrote:
> > On Thu, Jan 05, 2017 at 01:31:44PM +0800, Jianbo Liu wrote:
> >> On 4 January 2017 at 18:01, Jerin Jacob <jerin.jacob@caviumnetworks.com> wrote:
> >> > On Tue, Jan 03, 2017 at 03:48:32PM +0800, Jianbo Liu wrote:
> >> >> On 27 December 2016 at 17:49, Jerin Jacob
> >> >> <jerin.jacob@caviumnetworks.com> wrote:
> >> >> > CC: Jianbo Liu <jianbo.liu@linaro.org>
> >> >> I think it's better to use outer shareable dmb for io barrier, instead of dsb.
> >> >
> >> > Its is difficult to generalize. AFAIK, from the IO barrier perspective
> >> > dsb would be the right candidate. But just for the DMA barrier between IO may
> >> > be outer sharable dmb is enough. In-terms of performance implication, the
> >> > fastpath code(door bell write) has been changed to relaxed write in all
> >> > the drivers in this patchset and rte_io_* will be only
> >> > used by rte_[read/write]8/16/32/64 which will be in slow-path.
> >> > So, IMO, it better stick with dsb and its safe from the complete IO barrier
> >> > perspective.
> >>
> >> If so, why not use *mb() directly?
> >
> > Adding David Marchand, EAL Maintainer.
> >
> > Instead of rte_io_?. I thought, IO specific constraints can be abstracted
> > here in rte_io_*. Apart from arm, there other arch like "arc" has similar
> > constraints. IMHO, no harm in keeping that abstraction.
> >
> > Thoughts ?
> >
> > http://lxr.free-electrons.com/ident?i=__iormb
> >
> >>
> >> >
> >> > At least on ThunderX, I couldn't see any performance difference between
> >> > using dsb(st) and dmb(oshst) for dma write barrier before the doorbell register
> >> > write in fastpath. In case there are platforms which has such performance difference,
> >> > may be could add rte_dma_wmb() and rte_dma_rmb() in future like Linux kernel
> >> > dma_wmb() and dma_rmb().(But i couldn't  see all the driver are using it,
> >> > though)
> >> >
> >>
> >> But there is no io_*mb() in the kernel, so you want to be different?
> >
> > It is their for arm,arm64,arc architectures in Linux kernel. Please check writel
> > implementation for arm64
> >
> > http://lxr.free-electrons.com/source/arch/arm64/include/asm/io.h#L143
> >
> 
> Yes, I knew. But I'm afraid it will be mixed with dma_*mb by someone else.

OK. Got it. To me both are totally different.
Feel free introduce additional dma_*mb* then, if you think its solving
any problem in DPDK.I am not seeing any performance different between
dsb sy and dmb outer one. If you have any platform that has performance
difference then I _think_ you can introduce dma_*mb()

^ permalink raw reply

* Re: [PATCH 23/25] net/qede/base: semantic/formatting changes
From: Mody, Rasesh @ 2017-01-05  7:16 UTC (permalink / raw)
  To: Ferruh Yigit, dev@dpdk.org; +Cc: Dept-Eng DPDK Dev
In-Reply-To: <fe5187ff-7154-4151-5bf8-975bf9c80933@intel.com>

> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Tuesday, January 03, 2017 7:41 AM
> 
> On 12/31/2016 7:41 AM, Mody, Rasesh wrote:
> >> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> >> Sent: Friday, December 23, 2016 7:42 AM
> >>
> >> On 12/3/2016 9:11 AM, Rasesh Mody wrote:
> >>> This patch consists of semantic/formatting changes. It also includes
> >>> comment additions.
> >>
> >> As far as I can see majority of the changes are formatting, but not all.
> >>
> >> Functional changes are hard to detect in this patch, what do you
> >> think separating formatting/comments patches into another patch, so
> >> functional changes can become more visible?
> >
> > There are few of places(ecore_hw_bar_size(), ecore_get_hw_info() and
> ecore_init_cmd_*), where there is a bit of code refactoring. However, they
> are not a major change. We have tried to isolate most of the functional
> changes and made them part of the separate patches as fit. I think, we can
> include a bit of description in commit message to cover it in this patch. Please
> let me know if you think otherwise.
> 
> I believe it is good to separate code refactoring into different patch if
> possible, instead of covering this in commit log.
> 
> This makes functional changes easy to find in the future. In this patch hard to
> spot them.

V2 series has been submitted to separate code refactoring changes and address few other comments received for this patch set.
Thanks!
-Rasesh
 
> Thanks,
> ferruh
> 
> >
> >>>
> >>> Signed-off-by: Rasesh Mody <Rasesh.Mody@cavium.com>
> >>> ---
> >> <...>

^ permalink raw reply

* [PATCH v2 25/26] net/qede/base: dcbx changes for base driver
From: Rasesh Mody @ 2017-01-05  7:04 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, Dept-EngDPDKDev
In-Reply-To: <1480756289-11835-1-git-send-email-Rasesh.Mody@cavium.com>

This patch includes changes for DCBX like:
 - Return empty parameters for oper-params query when negotiation is not
   complete
 - Use the ieee specific mask value for reading the ethtype value in the
   ieee dcbx mode
 - Endian-ness conversion is not needed for priority<->TC field, as the
   data is already being read/written by ecore in the bigendian way
 - While writing the ets config, base driver incorrectly merges the input
   values with the operational values. The values should be either set
   or unset
 - CEE selection field must be set regardless CEE/IEEE mode
 - Fail the dcbx query for VF interfaces
 - Semantic changes

Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
---
 drivers/net/qede/base/ecore.h          |    3 +
 drivers/net/qede/base/ecore_dcbx.c     |  375 ++++++++++++++------------------
 drivers/net/qede/base/ecore_dcbx_api.h |    1 +
 drivers/net/qede/base/ecore_dev.c      |   24 +-
 4 files changed, 185 insertions(+), 218 deletions(-)

diff --git a/drivers/net/qede/base/ecore.h b/drivers/net/qede/base/ecore.h
index b1b0a2e..b41ff4a 100644
--- a/drivers/net/qede/base/ecore.h
+++ b/drivers/net/qede/base/ecore.h
@@ -373,6 +373,9 @@ struct ecore_hw_info {
 	u32 port_mode;
 	u32	hw_mode;
 	unsigned long device_capabilities;
+
+	/* Default DCBX mode */
+	u8 dcbx_mode;
 };
 
 struct ecore_hw_cid_data {
diff --git a/drivers/net/qede/base/ecore_dcbx.c b/drivers/net/qede/base/ecore_dcbx.c
index 5932948..9fbddec 100644
--- a/drivers/net/qede/base/ecore_dcbx.c
+++ b/drivers/net/qede/base/ecore_dcbx.c
@@ -28,99 +28,75 @@
 
 static bool ecore_dcbx_app_ethtype(u32 app_info_bitmap)
 {
-	return (ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
-		DCBX_APP_SF_ETHTYPE) ? true : false;
+	return !!(ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
+		  DCBX_APP_SF_ETHTYPE);
 }
 
-static bool ecore_dcbx_app_port(u32 app_info_bitmap)
-{
-	return (ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
-		DCBX_APP_SF_PORT) ? true : false;
-}
-
-static bool ecore_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type)
+static bool ecore_dcbx_ieee_app_ethtype(u32 app_info_bitmap)
 {
 	u8 mfw_val = ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
 
 	/* Old MFW */
 	if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
-		return ecore_dcbx_app_port(app_info_bitmap);
+		return ecore_dcbx_app_ethtype(app_info_bitmap);
 
-	return (mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT) ?
-		true : false;
+	return !!(mfw_val == DCBX_APP_SF_IEEE_ETHTYPE);
 }
 
-static bool ecore_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id)
+static bool ecore_dcbx_app_port(u32 app_info_bitmap)
 {
-	return (ecore_dcbx_app_ethtype(app_info_bitmap) &&
-		proto_id == ECORE_ETH_TYPE_DEFAULT) ? true : false;
+	return !!(ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
+		  DCBX_APP_SF_PORT);
 }
 
-static bool ecore_dcbx_enabled(u32 dcbx_cfg_bitmap)
+static bool ecore_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type)
 {
-	return (ECORE_MFW_GET_FIELD(dcbx_cfg_bitmap, DCBX_CONFIG_VERSION) ==
-		DCBX_CONFIG_VERSION_DISABLED) ? false : true;
-}
+	u8 mfw_val = ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
 
-static bool ecore_dcbx_cee(u32 dcbx_cfg_bitmap)
-{
-	return (ECORE_MFW_GET_FIELD(dcbx_cfg_bitmap, DCBX_CONFIG_VERSION) ==
-		DCBX_CONFIG_VERSION_CEE) ? true : false;
-}
+	/* Old MFW */
+	if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
+		return ecore_dcbx_app_port(app_info_bitmap);
 
-static bool ecore_dcbx_ieee(u32 dcbx_cfg_bitmap)
-{
-	return (ECORE_MFW_GET_FIELD(dcbx_cfg_bitmap, DCBX_CONFIG_VERSION) ==
-		DCBX_CONFIG_VERSION_IEEE) ? true : false;
+	return !!(mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT);
 }
 
-static bool ecore_dcbx_local(u32 dcbx_cfg_bitmap)
+static bool ecore_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
 {
-	return (ECORE_MFW_GET_FIELD(dcbx_cfg_bitmap, DCBX_CONFIG_VERSION) ==
-		DCBX_CONFIG_VERSION_STATIC) ? true : false;
+	bool ethtype;
+
+	if (ieee)
+		ethtype = ecore_dcbx_ieee_app_ethtype(app_info_bitmap);
+	else
+		ethtype = ecore_dcbx_app_ethtype(app_info_bitmap);
+
+	return !!(ethtype && (proto_id == ECORE_ETH_TYPE_DEFAULT));
 }
 
 static void
 ecore_dcbx_dp_protocol(struct ecore_hwfn *p_hwfn,
 		       struct ecore_dcbx_results *p_data)
 {
-	struct ecore_hw_info *p_info = &p_hwfn->hw_info;
 	enum dcbx_protocol_type id;
-	u8 prio, tc, size, update;
-	bool enable;
-	const char *name;	/* @DPDK */
 	int i;
 
-	size = OSAL_ARRAY_SIZE(ecore_dcbx_app_update);
+	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "DCBX negotiated: %d\n",
+		   p_data->dcbx_enabled);
 
-	DP_INFO(p_hwfn, "DCBX negotiated: %d\n", p_data->dcbx_enabled);
-
-	for (i = 0; i < size; i++) {
+	for (i = 0; i < OSAL_ARRAY_SIZE(ecore_dcbx_app_update); i++) {
 		id = ecore_dcbx_app_update[i].id;
-		name = ecore_dcbx_app_update[i].name;
 
-		enable = p_data->arr[id].enable;
-		update = p_data->arr[id].update;
-		tc = p_data->arr[id].tc;
-		prio = p_data->arr[id].priority;
-
-		DP_INFO(p_hwfn,
-			"%s info: update %d, enable %d, prio %d, tc %d,"
-			" num_active_tc %d dscp_enable = %d dscp_val = %d\n",
-			name, update, enable, prio, tc, p_info->num_active_tc,
-			p_data->arr[id].dscp_enable, p_data->arr[id].dscp_val);
+		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
+			   "%s info: update %d, enable %d, prio %d, tc %d,"
+			   " num_active_tc %d dscp_enable = %d dscp_val = %d\n",
+			   ecore_dcbx_app_update[i].name,
+			   p_data->arr[id].update,
+			   p_data->arr[id].enable, p_data->arr[id].priority,
+			   p_data->arr[id].tc, p_hwfn->hw_info.num_active_tc,
+			   p_data->arr[id].dscp_enable,
+			   p_data->arr[id].dscp_val);
 	}
 }
 
-static void
-ecore_dcbx_set_pf_tcs(struct ecore_hw_info *p_info,
-		      u8 tc, enum ecore_pci_personality personality)
-{
-	/* QM reconf data */
-	if (p_info->personality == personality)
-		p_info->offload_tc = tc;
-}
-
 void
 ecore_dcbx_set_params(struct ecore_dcbx_results *p_data,
 		      struct ecore_hwfn *p_hwfn,
@@ -152,7 +128,12 @@ ecore_dcbx_set_params(struct ecore_dcbx_results *p_data,
 	else
 		p_data->arr[type].update = DONT_UPDATE_DCB_DHCP;
 
-	ecore_dcbx_set_pf_tcs(&p_hwfn->hw_info, tc, personality);
+	/* QM reconf data */
+	if (p_hwfn->hw_info.personality == personality) {
+		p_hwfn->hw_info.offload_tc = tc;
+		if (personality == ECORE_PCI_ISCSI)
+			p_hwfn->hw_info.ooo_tc = DCBX_ISCSI_OOO_TC;
+	}
 }
 
 /* Update app protocol data and hw_info fields with the TLV info */
@@ -165,12 +146,9 @@ ecore_dcbx_update_app_info(struct ecore_dcbx_results *p_data,
 	enum ecore_pci_personality personality;
 	enum dcbx_protocol_type id;
 	const char *name;	/* @DPDK */
-	u8 size;
 	int i;
 
-	size = OSAL_ARRAY_SIZE(ecore_dcbx_app_update);
-
-	for (i = 0; i < size; i++) {
+	for (i = 0; i < OSAL_ARRAY_SIZE(ecore_dcbx_app_update); i++) {
 		id = ecore_dcbx_app_update[i].id;
 
 		if (type != id)
@@ -218,20 +196,18 @@ ecore_dcbx_get_app_protocol_type(struct ecore_hwfn *p_hwfn,
 				 u32 app_prio_bitmap, u16 id,
 				 enum dcbx_protocol_type *type, bool ieee)
 {
-	bool status = false;
-
-	if (ecore_dcbx_default_tlv(app_prio_bitmap, id)) {
+	if (ecore_dcbx_default_tlv(app_prio_bitmap, id, ieee)) {
 		*type = DCBX_PROTOCOL_ETH;
-		status = true;
 	} else {
 		*type = DCBX_MAX_PROTOCOL_TYPE;
 		DP_ERR(p_hwfn,
 		       "No action required, App TLV id = 0x%x"
 		       " app_prio_bitmap = 0x%x\n",
 		       id, app_prio_bitmap);
+		return false;
 	}
 
-	return status;
+	return true;
 }
 
 /*  Parse app TLV's to update TC information in hw_info structure for
@@ -243,11 +219,12 @@ ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn,
 		       struct dcbx_app_priority_entry *p_tbl, u32 pri_tc_tbl,
 		       int count, u8 dcbx_version)
 {
-	enum _ecore_status_t rc = ECORE_SUCCESS;
-	u8 tc, priority, priority_map;
 	enum dcbx_protocol_type type;
+	u8 tc, priority_map;
 	bool enable, ieee;
 	u16 protocol_id;
+	u8 priority;
+	enum _ecore_status_t rc = ECORE_SUCCESS;
 	int i;
 
 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "Num APP entries = %d\n", count);
@@ -262,7 +239,7 @@ ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn,
 		rc = ecore_dcbx_get_app_priority(priority_map, &priority);
 		if (rc == ECORE_INVAL) {
 			DP_ERR(p_hwfn, "Invalid priority\n");
-			return rc;
+			return ECORE_INVAL;
 		}
 
 		tc = ECORE_DCBX_PRIO2TC(pri_tc_tbl, priority);
@@ -275,7 +252,7 @@ ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn,
 			 * indication, but we only got here if there was an
 			 * app tlv for the protocol, so dcbx must be enabled.
 			 */
-			enable = (type == DCBX_PROTOCOL_ETH ? false : true);
+			enable = !(type == DCBX_PROTOCOL_ETH);
 
 			ecore_dcbx_update_app_info(p_data, p_hwfn, enable, true,
 						   priority, tc, type);
@@ -357,6 +334,9 @@ ecore_dcbx_copy_mib(struct ecore_hwfn *p_hwfn,
 	u32 prefix_seq_num, suffix_seq_num;
 	int read_count = 0;
 
+	/* The data is considered to be valid only if both sequence numbers are
+	 * the same.
+	 */
 	do {
 		if (type == ECORE_DCBX_REMOTE_LLDP_MIB) {
 			ecore_memcpy_from(p_hwfn, p_ptt, p_data->lldp_remote,
@@ -389,21 +369,20 @@ ecore_dcbx_copy_mib(struct ecore_hwfn *p_hwfn,
 	return rc;
 }
 
-static enum _ecore_status_t
+static void
 ecore_dcbx_get_priority_info(struct ecore_hwfn *p_hwfn,
 			     struct ecore_dcbx_app_prio *p_prio,
 			     struct ecore_dcbx_results *p_results)
 {
-	enum _ecore_status_t rc = ECORE_SUCCESS;
+	u8 val;
 
 	if (p_results->arr[DCBX_PROTOCOL_ETH].update &&
-	    p_results->arr[DCBX_PROTOCOL_ETH].enable) {
+	    p_results->arr[DCBX_PROTOCOL_ETH].enable)
 		p_prio->eth = p_results->arr[DCBX_PROTOCOL_ETH].priority;
-		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
-			   "Priority: eth %d\n", p_prio->eth);
-	}
 
-	return rc;
+	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
+		   "Priorities: eth %d\n",
+		   p_prio->eth);
 }
 
 static void
@@ -526,7 +505,7 @@ ecore_dcbx_get_ets_data(struct ecore_hwfn *p_hwfn,
 	bw_map[1] = OSAL_BE32_TO_CPU(p_ets->tc_bw_tbl[1]);
 	tsa_map[0] = OSAL_BE32_TO_CPU(p_ets->tc_tsa_tbl[0]);
 	tsa_map[1] = OSAL_BE32_TO_CPU(p_ets->tc_tsa_tbl[1]);
-	pri_map = OSAL_BE32_TO_CPU(p_ets->pri_tc_tbl[0]);
+	pri_map = p_ets->pri_tc_tbl[0];
 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) {
 		p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i];
 		p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i];
@@ -538,7 +517,7 @@ ecore_dcbx_get_ets_data(struct ecore_hwfn *p_hwfn,
 	}
 }
 
-static enum _ecore_status_t
+static void
 ecore_dcbx_get_common_params(struct ecore_hwfn *p_hwfn,
 			     struct dcbx_app_priority_feature *p_app,
 			     struct dcbx_app_priority_entry *p_tbl,
@@ -549,60 +528,35 @@ ecore_dcbx_get_common_params(struct ecore_hwfn *p_hwfn,
 	ecore_dcbx_get_app_data(p_hwfn, p_app, p_tbl, p_params, ieee);
 	ecore_dcbx_get_ets_data(p_hwfn, p_ets, p_params);
 	ecore_dcbx_get_pfc_data(p_hwfn, pfc, p_params);
-
-	return ECORE_SUCCESS;
 }
 
-static enum _ecore_status_t
+static void
 ecore_dcbx_get_local_params(struct ecore_hwfn *p_hwfn,
 			    struct ecore_ptt *p_ptt,
 			    struct ecore_dcbx_get *params)
 {
-	struct ecore_dcbx_admin_params *p_local;
-	struct dcbx_app_priority_feature *p_app;
-	struct dcbx_app_priority_entry *p_tbl;
-	struct ecore_dcbx_params *p_data;
-	struct dcbx_ets_feature *p_ets;
-	u32 pfc;
-
-	p_local = &params->local;
-	p_data = &p_local->params;
-	p_app = &p_hwfn->p_dcbx_info->local_admin.features.app;
-	p_tbl = p_app->app_pri_tbl;
-	p_ets = &p_hwfn->p_dcbx_info->local_admin.features.ets;
-	pfc = p_hwfn->p_dcbx_info->local_admin.features.pfc;
-
-	ecore_dcbx_get_common_params(p_hwfn, p_app, p_tbl, p_ets, pfc, p_data,
-				     false);
-	p_local->valid = true;
+	struct dcbx_features *p_feat;
 
-	return ECORE_SUCCESS;
+	p_feat = &p_hwfn->p_dcbx_info->local_admin.features;
+	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
+				     p_feat->app.app_pri_tbl, &p_feat->ets,
+				     p_feat->pfc, &params->local.params, false);
+	params->local.valid = true;
 }
 
-static enum _ecore_status_t
+static void
 ecore_dcbx_get_remote_params(struct ecore_hwfn *p_hwfn,
 			     struct ecore_ptt *p_ptt,
 			     struct ecore_dcbx_get *params)
 {
-	struct ecore_dcbx_remote_params *p_remote;
-	struct dcbx_app_priority_feature *p_app;
-	struct dcbx_app_priority_entry *p_tbl;
-	struct ecore_dcbx_params *p_data;
-	struct dcbx_ets_feature *p_ets;
-	u32 pfc;
-
-	p_remote = &params->remote;
-	p_data = &p_remote->params;
-	p_app = &p_hwfn->p_dcbx_info->remote.features.app;
-	p_tbl = p_app->app_pri_tbl;
-	p_ets = &p_hwfn->p_dcbx_info->remote.features.ets;
-	pfc = p_hwfn->p_dcbx_info->remote.features.pfc;
+	struct dcbx_features *p_feat;
 
-	ecore_dcbx_get_common_params(p_hwfn, p_app, p_tbl, p_ets, pfc, p_data,
+	p_feat = &p_hwfn->p_dcbx_info->remote.features;
+	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
+				     p_feat->app.app_pri_tbl, &p_feat->ets,
+				     p_feat->pfc, &params->remote.params,
 				     false);
-	p_remote->valid = true;
-
-	return ECORE_SUCCESS;
+	params->remote.valid = true;
 }
 
 static enum _ecore_status_t
@@ -611,14 +565,11 @@ ecore_dcbx_get_operational_params(struct ecore_hwfn *p_hwfn,
 				  struct ecore_dcbx_get *params)
 {
 	struct ecore_dcbx_operational_params *p_operational;
-	enum _ecore_status_t rc = ECORE_SUCCESS;
-	struct dcbx_app_priority_feature *p_app;
-	struct dcbx_app_priority_entry *p_tbl;
 	struct ecore_dcbx_results *p_results;
-	struct ecore_dcbx_params *p_data;
-	struct dcbx_ets_feature *p_ets;
+	struct dcbx_features *p_feat;
 	bool enabled, err;
-	u32 pfc, flags;
+	u32 flags;
+	bool val;
 
 	flags = p_hwfn->p_dcbx_info->operational.flags;
 
@@ -626,42 +577,49 @@ ecore_dcbx_get_operational_params(struct ecore_hwfn *p_hwfn,
 	 * was successfuly performed
 	 */
 	p_operational = &params->operational;
-	enabled = ecore_dcbx_enabled(flags);
+	enabled = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) !=
+		     DCBX_CONFIG_VERSION_DISABLED);
 	if (!enabled) {
 		p_operational->enabled = enabled;
 		p_operational->valid = false;
 		return ECORE_INVAL;
 	}
 
-	p_data = &p_operational->params;
+	p_feat = &p_hwfn->p_dcbx_info->operational.features;
 	p_results = &p_hwfn->p_dcbx_info->results;
-	p_app = &p_hwfn->p_dcbx_info->operational.features.app;
-	p_tbl = p_app->app_pri_tbl;
-	p_ets = &p_hwfn->p_dcbx_info->operational.features.ets;
-	pfc = p_hwfn->p_dcbx_info->operational.features.pfc;
 
-	p_operational->ieee = ecore_dcbx_ieee(flags);
-	p_operational->cee = ecore_dcbx_cee(flags);
-	p_operational->local = ecore_dcbx_local(flags);
+	val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
+		 DCBX_CONFIG_VERSION_IEEE);
+	p_operational->ieee = val;
+
+	val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
+		 DCBX_CONFIG_VERSION_CEE);
+	p_operational->cee = val;
+
+	val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
+		 DCBX_CONFIG_VERSION_STATIC);
+	p_operational->local = val;
 
 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 		   "Version support: ieee %d, cee %d, static %d\n",
 		   p_operational->ieee, p_operational->cee,
 		   p_operational->local);
 
-	ecore_dcbx_get_common_params(p_hwfn, p_app, p_tbl, p_ets, pfc, p_data,
+	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
+				     p_feat->app.app_pri_tbl, &p_feat->ets,
+				     p_feat->pfc, &params->operational.params,
 				     p_operational->ieee);
 	ecore_dcbx_get_priority_info(p_hwfn, &p_operational->app_prio,
 				     p_results);
-	err = ECORE_MFW_GET_FIELD(p_app->flags, DCBX_APP_ERROR);
+	err = ECORE_MFW_GET_FIELD(p_feat->app.flags, DCBX_APP_ERROR);
 	p_operational->err = err;
 	p_operational->enabled = enabled;
 	p_operational->valid = true;
 
-	return rc;
+	return ECORE_SUCCESS;
 }
 
-static enum _ecore_status_t
+static void
 ecore_dcbx_get_dscp_params(struct ecore_hwfn *p_hwfn,
 			   struct ecore_ptt *p_ptt,
 			   struct ecore_dcbx_get *params)
@@ -686,62 +644,46 @@ ecore_dcbx_get_dscp_params(struct ecore_hwfn *p_hwfn,
 			p_dscp->dscp_pri_map[entry] = (u32)(pri_map >>
 							   (j * 4)) & 0xf;
 	}
-
-	return ECORE_SUCCESS;
 }
 
-static enum _ecore_status_t
+static void
 ecore_dcbx_get_local_lldp_params(struct ecore_hwfn *p_hwfn,
 				 struct ecore_ptt *p_ptt,
 				 struct ecore_dcbx_get *params)
 {
-	struct ecore_dcbx_lldp_local *p_local;
-	osal_size_t size;
-	u32 *dest;
-
-	p_local = &params->lldp_local;
+	struct lldp_config_params_s *p_local;
 
-	size = OSAL_ARRAY_SIZE(p_local->local_chassis_id);
-	dest = p_hwfn->p_dcbx_info->get.lldp_local.local_chassis_id;
-	OSAL_MEMCPY(dest, p_local->local_chassis_id, size);
+	p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE];
 
-	size = OSAL_ARRAY_SIZE(p_local->local_port_id);
-	dest = p_hwfn->p_dcbx_info->get.lldp_local.local_port_id;
-	OSAL_MEMCPY(dest, p_local->local_port_id, size);
-
-	return ECORE_SUCCESS;
+	OSAL_MEMCPY(params->lldp_local.local_chassis_id,
+		    p_local->local_chassis_id,
+		    OSAL_ARRAY_SIZE(p_local->local_chassis_id));
+	OSAL_MEMCPY(params->lldp_local.local_port_id, p_local->local_port_id,
+		    OSAL_ARRAY_SIZE(p_local->local_port_id));
 }
 
-static enum _ecore_status_t
+static void
 ecore_dcbx_get_remote_lldp_params(struct ecore_hwfn *p_hwfn,
 				  struct ecore_ptt *p_ptt,
 				  struct ecore_dcbx_get *params)
 {
-	struct ecore_dcbx_lldp_remote *p_remote;
-	osal_size_t size;
-	u32 *dest;
-
-	p_remote = &params->lldp_remote;
+	struct lldp_status_params_s *p_remote;
 
-	size = OSAL_ARRAY_SIZE(p_remote->peer_chassis_id);
-	dest = p_hwfn->p_dcbx_info->get.lldp_remote.peer_chassis_id;
-	OSAL_MEMCPY(dest, p_remote->peer_chassis_id, size);
+	p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE];
 
-	size = OSAL_ARRAY_SIZE(p_remote->peer_port_id);
-	dest = p_hwfn->p_dcbx_info->get.lldp_remote.peer_port_id;
-	OSAL_MEMCPY(dest, p_remote->peer_port_id, size);
-
-	return ECORE_SUCCESS;
+	OSAL_MEMCPY(params->lldp_remote.peer_chassis_id,
+		    p_remote->peer_chassis_id,
+		    OSAL_ARRAY_SIZE(p_remote->peer_chassis_id));
+	OSAL_MEMCPY(params->lldp_remote.peer_port_id, p_remote->peer_port_id,
+		    OSAL_ARRAY_SIZE(p_remote->peer_port_id));
 }
 
 static enum _ecore_status_t
-ecore_dcbx_get_params(struct ecore_hwfn *p_hwfn,
-		      struct ecore_ptt *p_ptt, enum ecore_mib_read_type type)
+ecore_dcbx_get_params(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
+		      struct ecore_dcbx_get *p_params,
+		      enum ecore_mib_read_type type)
 {
 	enum _ecore_status_t rc = ECORE_SUCCESS;
-	struct ecore_dcbx_get *p_params;
-
-	p_params = &p_hwfn->p_dcbx_info->get;
 
 	switch (type) {
 	case ECORE_DCBX_REMOTE_MIB:
@@ -754,10 +696,10 @@ ecore_dcbx_get_params(struct ecore_hwfn *p_hwfn,
 		ecore_dcbx_get_operational_params(p_hwfn, p_ptt, p_params);
 		break;
 	case ECORE_DCBX_REMOTE_LLDP_MIB:
-		rc = ecore_dcbx_get_remote_lldp_params(p_hwfn, p_ptt, p_params);
+		ecore_dcbx_get_remote_lldp_params(p_hwfn, p_ptt, p_params);
 		break;
 	case ECORE_DCBX_LOCAL_LLDP_MIB:
-		rc = ecore_dcbx_get_local_lldp_params(p_hwfn, p_ptt, p_params);
+		ecore_dcbx_get_local_lldp_params(p_hwfn, p_ptt, p_params);
 		break;
 	default:
 		DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
@@ -771,9 +713,10 @@ static enum _ecore_status_t
 ecore_dcbx_read_local_lldp_mib(struct ecore_hwfn *p_hwfn,
 			       struct ecore_ptt *p_ptt)
 {
-	enum _ecore_status_t rc = ECORE_SUCCESS;
 	struct ecore_dcbx_mib_meta_data data;
+	enum _ecore_status_t rc = ECORE_SUCCESS;
 
+	OSAL_MEM_ZERO(&data, sizeof(data));
 	data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
 							   lldp_config_params);
 	data.lldp_local = p_hwfn->p_dcbx_info->lldp_local;
@@ -788,8 +731,8 @@ ecore_dcbx_read_remote_lldp_mib(struct ecore_hwfn *p_hwfn,
 				struct ecore_ptt *p_ptt,
 				enum ecore_mib_read_type type)
 {
-	enum _ecore_status_t rc = ECORE_SUCCESS;
 	struct ecore_dcbx_mib_meta_data data;
+	enum _ecore_status_t rc = ECORE_SUCCESS;
 
 	OSAL_MEM_ZERO(&data, sizeof(data));
 	data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
@@ -843,6 +786,7 @@ ecore_dcbx_read_local_mib(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
 	struct ecore_dcbx_mib_meta_data data;
 	enum _ecore_status_t rc = ECORE_SUCCESS;
 
+	OSAL_MEM_ZERO(&data, sizeof(data));
 	data.addr = p_hwfn->mcp_info->port_addr +
 	    offsetof(struct public_port, local_admin_dcbx_mib);
 	data.local_admin = &p_hwfn->p_dcbx_info->local_admin;
@@ -869,7 +813,7 @@ static enum _ecore_status_t ecore_dcbx_read_mib(struct ecore_hwfn *p_hwfn,
 						struct ecore_ptt *p_ptt,
 						enum ecore_mib_read_type type)
 {
-	enum _ecore_status_t rc = ECORE_SUCCESS;
+	enum _ecore_status_t rc = ECORE_INVAL;
 
 	switch (type) {
 	case ECORE_DCBX_OPERATIONAL_MIB:
@@ -890,7 +834,6 @@ static enum _ecore_status_t ecore_dcbx_read_mib(struct ecore_hwfn *p_hwfn,
 		break;
 	default:
 		DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
-		return ECORE_INVAL;
 	}
 
 	return rc;
@@ -933,7 +876,7 @@ ecore_dcbx_mib_update_event(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
 			enabled = p_hwfn->p_dcbx_info->results.dcbx_enabled;
 		}
 	}
-	ecore_dcbx_get_params(p_hwfn, p_ptt, type);
+	ecore_dcbx_get_params(p_hwfn, p_ptt, &p_hwfn->p_dcbx_info->get, type);
 
 	/* Update the DSCP to TC mapping bit if required */
 	if ((type == ECORE_DCBX_OPERATIONAL_MIB) &&
@@ -952,7 +895,7 @@ enum _ecore_status_t ecore_dcbx_info_alloc(struct ecore_hwfn *p_hwfn)
 	enum _ecore_status_t rc = ECORE_SUCCESS;
 
 	p_hwfn->p_dcbx_info = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
-					  sizeof(struct ecore_dcbx_info));
+					  sizeof(*p_hwfn->p_dcbx_info));
 	if (!p_hwfn->p_dcbx_info) {
 		DP_NOTICE(p_hwfn, true,
 			  "Failed to allocate `struct ecore_dcbx_info'");
@@ -995,13 +938,16 @@ void ecore_dcbx_set_pf_update_params(struct ecore_dcbx_results *p_src,
 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH);
 }
 
-static
-enum _ecore_status_t ecore_dcbx_query(struct ecore_hwfn *p_hwfn,
-				      enum ecore_mib_read_type type)
+enum _ecore_status_t ecore_dcbx_query_params(struct ecore_hwfn *p_hwfn,
+					     struct ecore_dcbx_get *p_get,
+					     enum ecore_mib_read_type type)
 {
 	struct ecore_ptt *p_ptt;
 	enum _ecore_status_t rc;
 
+	if (IS_VF(p_hwfn->p_dev))
+		return ECORE_INVAL;
+
 	p_ptt = ecore_ptt_acquire(p_hwfn);
 	if (!p_ptt) {
 		rc = ECORE_TIMEOUT;
@@ -1013,30 +959,13 @@ enum _ecore_status_t ecore_dcbx_query(struct ecore_hwfn *p_hwfn,
 	if (rc != ECORE_SUCCESS)
 		goto out;
 
-	rc = ecore_dcbx_get_params(p_hwfn, p_ptt, type);
+	rc = ecore_dcbx_get_params(p_hwfn, p_ptt, p_get, type);
 
 out:
 	ecore_ptt_release(p_hwfn, p_ptt);
 	return rc;
 }
 
-enum _ecore_status_t ecore_dcbx_query_params(struct ecore_hwfn *p_hwfn,
-					     struct ecore_dcbx_get *p_get,
-					     enum ecore_mib_read_type type)
-{
-	enum _ecore_status_t rc;
-
-	rc = ecore_dcbx_query(p_hwfn, type);
-	if (rc)
-		return rc;
-
-	if (p_get != OSAL_NULL)
-		OSAL_MEMCPY(p_get, &p_hwfn->p_dcbx_info->get,
-			    sizeof(struct ecore_dcbx_get));
-
-	return rc;
-}
-
 static void
 ecore_dcbx_set_pfc_data(struct ecore_hwfn *p_hwfn,
 			u32 *pfc, struct ecore_dcbx_params *p_params)
@@ -1059,8 +988,8 @@ ecore_dcbx_set_pfc_data(struct ecore_hwfn *p_hwfn,
 
 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++)
 		if (p_params->pfc.prio[i])
-			pfc_map |= (0x1 << i);
-
+			pfc_map |= (1 << i);
+	*pfc &= ~DCBX_PFC_PRI_EN_BITMAP_MASK;
 	*pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT);
 
 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "pfc = 0x%x\n", *pfc);
@@ -1072,6 +1001,7 @@ ecore_dcbx_set_ets_data(struct ecore_hwfn *p_hwfn,
 			struct ecore_dcbx_params *p_params)
 {
 	u8 *bw_map, *tsa_map;
+	u32 val;
 	int i;
 
 	if (p_params->ets_willing)
@@ -1098,10 +1028,12 @@ ecore_dcbx_set_ets_data(struct ecore_hwfn *p_hwfn,
 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) {
 		bw_map[i] = p_params->ets_tc_bw_tbl[i];
 		tsa_map[i] = p_params->ets_tc_tsa_tbl[i];
-		p_ets->pri_tc_tbl[0] |= (((u32)p_params->ets_pri_tc_tbl[i]) <<
-					 ((7 - i) * 4));
+		/* Copy the priority value to the corresponding 4 bits in the
+		 * traffic class table.
+		 */
+		val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4));
+		p_ets->pri_tc_tbl[0] |= val;
 	}
-	p_ets->pri_tc_tbl[0] = OSAL_CPU_TO_BE32(p_ets->pri_tc_tbl[0]);
 	for (i = 0; i < 2; i++) {
 		p_ets->tc_bw_tbl[i] = OSAL_CPU_TO_BE32(p_ets->tc_bw_tbl[i]);
 		p_ets->tc_tsa_tbl[i] = OSAL_CPU_TO_BE32(p_ets->tc_tsa_tbl[i]);
@@ -1132,24 +1064,33 @@ ecore_dcbx_set_app_data(struct ecore_hwfn *p_hwfn,
 
 	for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
 		entry = &p_app->app_pri_tbl[i].entry;
+		*entry = 0;
 		if (ieee) {
-			*entry &= ~DCBX_APP_SF_IEEE_MASK;
+			*entry &= ~(DCBX_APP_SF_IEEE_MASK | DCBX_APP_SF_MASK);
 			switch (p_params->app_entry[i].sf_ieee) {
 			case ECORE_DCBX_SF_IEEE_ETHTYPE:
 				*entry  |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE <<
 					    DCBX_APP_SF_IEEE_SHIFT);
+				*entry  |= ((u32)DCBX_APP_SF_ETHTYPE <<
+					    DCBX_APP_SF_SHIFT);
 				break;
 			case ECORE_DCBX_SF_IEEE_TCP_PORT:
 				*entry  |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT <<
 					    DCBX_APP_SF_IEEE_SHIFT);
+				*entry  |= ((u32)DCBX_APP_SF_PORT <<
+					    DCBX_APP_SF_SHIFT);
 				break;
 			case ECORE_DCBX_SF_IEEE_UDP_PORT:
 				*entry  |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT <<
 					    DCBX_APP_SF_IEEE_SHIFT);
+				*entry  |= ((u32)DCBX_APP_SF_PORT <<
+					    DCBX_APP_SF_SHIFT);
 				break;
 			case ECORE_DCBX_SF_IEEE_TCP_UDP_PORT:
 				*entry  |= (u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT <<
 					    DCBX_APP_SF_IEEE_SHIFT;
+				*entry  |= ((u32)DCBX_APP_SF_PORT <<
+					    DCBX_APP_SF_SHIFT);
 				break;
 			}
 		} else {
@@ -1180,7 +1121,7 @@ ecore_dcbx_set_local_params(struct ecore_hwfn *p_hwfn,
 	local_admin->flags = 0;
 	OSAL_MEMCPY(&local_admin->features,
 		    &p_hwfn->p_dcbx_info->operational.features,
-		    sizeof(struct dcbx_features));
+		    sizeof(local_admin->features));
 
 	if (params->enabled) {
 		local_admin->config = params->ver_num;
@@ -1215,10 +1156,9 @@ ecore_dcbx_set_dscp_params(struct ecore_hwfn *p_hwfn,
 	OSAL_MEMCPY(p_dscp_map, &p_hwfn->p_dcbx_info->dscp_map,
 		    sizeof(*p_dscp_map));
 
+	p_dscp_map->flags &= ~DCB_DSCP_ENABLE_MASK;
 	if (p_params->dscp.enabled)
 		p_dscp_map->flags |= DCB_DSCP_ENABLE_MASK;
-	else
-		p_dscp_map->flags &= ~DCB_DSCP_ENABLE_MASK;
 
 	for (i = 0, entry = 0; i < 8; i++) {
 		val = 0;
@@ -1239,15 +1179,15 @@ enum _ecore_status_t ecore_dcbx_config_params(struct ecore_hwfn *p_hwfn,
 					      struct ecore_dcbx_set *params,
 					      bool hw_commit)
 {
-	enum _ecore_status_t rc = ECORE_SUCCESS;
-	struct ecore_dcbx_mib_meta_data data;
 	struct dcbx_local_params local_admin;
+	struct ecore_dcbx_mib_meta_data data;
 	struct dcb_dscp_map dscp_map;
 	u32 resp = 0, param = 0;
+	enum _ecore_status_t rc = ECORE_SUCCESS;
 
 	if (!hw_commit) {
 		OSAL_MEMCPY(&p_hwfn->p_dcbx_info->set, params,
-			    sizeof(struct ecore_dcbx_set));
+			    sizeof(p_hwfn->p_dcbx_info->set));
 		return ECORE_SUCCESS;
 	}
 
@@ -1300,12 +1240,13 @@ enum _ecore_status_t ecore_dcbx_get_config_params(struct ecore_hwfn *p_hwfn,
 	}
 
 	dcbx_info = OSAL_ALLOC(p_hwfn->p_dev, GFP_KERNEL,
-			       sizeof(struct ecore_dcbx_get));
+			       sizeof(*dcbx_info));
 	if (!dcbx_info) {
 		DP_ERR(p_hwfn, "Failed to allocate struct ecore_dcbx_info\n");
 		return ECORE_NOMEM;
 	}
 
+	OSAL_MEMSET(dcbx_info, 0, sizeof(*dcbx_info));
 	rc = ecore_dcbx_query_params(p_hwfn, dcbx_info,
 				     ECORE_DCBX_OPERATIONAL_MIB);
 	if (rc) {
diff --git a/drivers/net/qede/base/ecore_dcbx_api.h b/drivers/net/qede/base/ecore_dcbx_api.h
index 82416e7..3a1712f 100644
--- a/drivers/net/qede/base/ecore_dcbx_api.h
+++ b/drivers/net/qede/base/ecore_dcbx_api.h
@@ -147,6 +147,7 @@ struct ecore_dcbx_get {
 #define ECORE_DCBX_VERSION_DISABLED	0
 #define ECORE_DCBX_VERSION_IEEE		1
 #define ECORE_DCBX_VERSION_CEE		2
+#define ECORE_DCBX_VERSION_DYNAMIC	3
 
 struct ecore_dcbx_set {
 #define ECORE_DCBX_OVERRIDE_STATE	(1 << 0)
diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index b754028..0518fc7 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -2405,7 +2405,7 @@ static enum _ecore_status_t ecore_hw_get_resc(struct ecore_hwfn *p_hwfn,
 static enum _ecore_status_t ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
 						  struct ecore_ptt *p_ptt)
 {
-	u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg;
+	u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg, dcbx_mode;
 	u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities;
 	struct ecore_mcp_link_params *link;
 
@@ -2469,6 +2469,28 @@ static enum _ecore_status_t ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
 		break;
 	}
 
+	/* Read DCBX configuration */
+	port_cfg_addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
+			OFFSETOF(struct nvm_cfg1, port[MFW_PORT(p_hwfn)]);
+	dcbx_mode = ecore_rd(p_hwfn, p_ptt,
+			     port_cfg_addr +
+			     OFFSETOF(struct nvm_cfg1_port, generic_cont0));
+	dcbx_mode = (dcbx_mode & NVM_CFG1_PORT_DCBX_MODE_MASK)
+		>> NVM_CFG1_PORT_DCBX_MODE_OFFSET;
+	switch (dcbx_mode) {
+	case NVM_CFG1_PORT_DCBX_MODE_DYNAMIC:
+		p_hwfn->hw_info.dcbx_mode = ECORE_DCBX_VERSION_DYNAMIC;
+		break;
+	case NVM_CFG1_PORT_DCBX_MODE_CEE:
+		p_hwfn->hw_info.dcbx_mode = ECORE_DCBX_VERSION_CEE;
+		break;
+	case NVM_CFG1_PORT_DCBX_MODE_IEEE:
+		p_hwfn->hw_info.dcbx_mode = ECORE_DCBX_VERSION_IEEE;
+		break;
+	default:
+		p_hwfn->hw_info.dcbx_mode = ECORE_DCBX_VERSION_DISABLED;
+	}
+
 	/* Read default link configuration */
 	link = &p_hwfn->mcp_info->link_input;
 	port_cfg_addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 26/26] net/qede: update PMD version to 2.0.0.1
From: Rasesh Mody @ 2017-01-05  7:04 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, Dept-EngDPDKDev
In-Reply-To: <1480756289-11835-1-git-send-email-Rasesh.Mody@cavium.com>

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

diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 9701d73..be54f31 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -46,8 +46,8 @@
 
 /* Driver versions */
 #define QEDE_PMD_VER_PREFIX		"QEDE PMD"
-#define QEDE_PMD_VERSION_MAJOR		1
-#define QEDE_PMD_VERSION_MINOR	        2
+#define QEDE_PMD_VERSION_MAJOR		2
+#define QEDE_PMD_VERSION_MINOR	        0
 #define QEDE_PMD_VERSION_REVISION       0
 #define QEDE_PMD_VERSION_PATCH	        1
 
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 24/26] net/qede/base: refactor some code bits
From: Rasesh Mody @ 2017-01-05  7:04 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, Dept-EngDPDKDev
In-Reply-To: <1480756289-11835-1-git-send-email-Rasesh.Mody@cavium.com>

Bits of code refactoring in ecore_hw_bar_size(), ecore_get_hw_info()
and ecore_init_cmd_*.

Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
---
 drivers/net/qede/base/ecore_dev.c      |   39 ++++++++++++++++----------------
 drivers/net/qede/base/ecore_init_ops.c |   19 +++++++---------
 2 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index f7a36c9..b754028 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -70,28 +70,26 @@ static u32 ecore_hw_bar_size(struct ecore_hwfn *p_hwfn, enum BAR_ID bar_id)
 	}
 
 	val = ecore_rd(p_hwfn, p_hwfn->p_main_ptt, bar_reg);
+	if (val)
+		return 1 << (val + 15);
 
 	/* The above registers were updated in the past only in CMT mode. Since
 	 * they were found to be useful MFW started updating them from 8.7.7.0.
 	 * In older MFW versions they are set to 0 which means disabled.
 	 */
-	if (!val) {
-		if (p_hwfn->p_dev->num_hwfns > 1) {
-			DP_NOTICE(p_hwfn, false,
-				  "BAR size not configured. Assuming BAR size");
-			DP_NOTICE(p_hwfn, false,
-				  "of 256kB for GRC and 512kB for DB\n");
-			return BAR_ID_0 ? 256 * 1024 : 512 * 1024;
-		} else {
-			DP_NOTICE(p_hwfn, false,
-				  "BAR size not configured. Assuming BAR size");
-			DP_NOTICE(p_hwfn, false,
-				  "of 512kB for GRC and 512kB for DB\n");
-			return 512 * 1024;
-		}
+	if (p_hwfn->p_dev->num_hwfns > 1) {
+		DP_NOTICE(p_hwfn, false,
+			  "BAR size not configured. Assuming BAR size of 256kB"
+			  " for GRC and 512kB for DB\n");
+		val = BAR_ID_0 ? 256 * 1024 : 512 * 1024;
+	} else {
+		DP_NOTICE(p_hwfn, false,
+			  "BAR size not configured. Assuming BAR size of 512kB"
+			  " for GRC and 512kB for DB\n");
+		val = 512 * 1024;
 	}
 
-	return 1 << (val + 15);
+	return val;
 }
 
 void ecore_init_dp(struct ecore_dev *p_dev,
@@ -2785,11 +2783,14 @@ ecore_get_hw_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
 		ecore_mcp_cmd_port_init(p_hwfn, p_ptt);
 	}
 
-	if (personality != ECORE_PCI_DEFAULT)
+	if (personality != ECORE_PCI_DEFAULT) {
 		p_hwfn->hw_info.personality = personality;
-	else if (ecore_mcp_is_init(p_hwfn))
-		p_hwfn->hw_info.personality =
-		    p_hwfn->mcp_info->func_info.protocol;
+	} else if (ecore_mcp_is_init(p_hwfn)) {
+		enum ecore_pci_personality protocol;
+
+		protocol = p_hwfn->mcp_info->func_info.protocol;
+		p_hwfn->hw_info.personality = protocol;
+	}
 
 #ifndef ASIC_ONLY
 	/* To overcome ILT lack for emulation, until at least until we'll have
diff --git a/drivers/net/qede/base/ecore_init_ops.c b/drivers/net/qede/base/ecore_init_ops.c
index a6ed590..b907a95 100644
--- a/drivers/net/qede/base/ecore_init_ops.c
+++ b/drivers/net/qede/base/ecore_init_ops.c
@@ -190,19 +190,19 @@ static enum _ecore_status_t ecore_init_cmd_array(struct ecore_hwfn *p_hwfn,
 						 bool b_must_dmae,
 						 bool b_can_dmae)
 {
+	u32 dmae_array_offset = OSAL_LE32_TO_CPU(cmd->args.array_offset);
+	u32 data = OSAL_LE32_TO_CPU(cmd->data);
+	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
 #ifdef CONFIG_ECORE_ZIPPED_FW
 	u32 offset, output_len, input_len, max_size;
 #endif
-	u32 dmae_array_offset = OSAL_LE32_TO_CPU(cmd->args.array_offset);
 	struct ecore_dev *p_dev = p_hwfn->p_dev;
-	enum _ecore_status_t rc = ECORE_SUCCESS;
 	union init_array_hdr *hdr;
 	const u32 *array_data;
-	u32 size, addr, data;
+	enum _ecore_status_t rc = ECORE_SUCCESS;
+	u32 size;
 
 	array_data = p_dev->fw_data->arr_data;
-	data = OSAL_LE32_TO_CPU(cmd->data);
-	addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
 
 	hdr = (union init_array_hdr *)
 		(uintptr_t)(array_data + dmae_array_offset);
@@ -272,13 +272,10 @@ static enum _ecore_status_t ecore_init_cmd_wr(struct ecore_hwfn *p_hwfn,
 					      struct init_write_op *p_cmd,
 					      bool b_can_dmae)
 {
+	u32 data = OSAL_LE32_TO_CPU(p_cmd->data);
+	bool b_must_dmae = GET_FIELD(data, INIT_WRITE_OP_WIDE_BUS);
+	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
 	enum _ecore_status_t rc = ECORE_SUCCESS;
-	bool b_must_dmae;
-	u32 addr, data;
-
-	data = OSAL_LE32_TO_CPU(p_cmd->data);
-	b_must_dmae = GET_FIELD(data, INIT_WRITE_OP_WIDE_BUS);
-	addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
 
 	/* Sanitize */
 	if (b_must_dmae && !b_can_dmae) {
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 22/26] net/qede/base: add support for new firmware
From: Rasesh Mody @ 2017-01-05  7:04 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, Dept-EngDPDKDev
In-Reply-To: <1480756289-11835-1-git-send-email-Rasesh.Mody@cavium.com>

Add support for 8.14.x.x firmware.

The new firmware adds support for external PHY BCM8485x; configures
fixed link speed with transceiver/cable not supporting negotiation;
supports engine swap; supports overriding PCIe preset equalization
value; checks pause too long for ports and reads die temperature
every second for shutdown threshold.
It includes change in FLR flow when there is a SW initiated FLR.

Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
---
 doc/guides/nics/qede.rst                      |    8 +--
 drivers/net/qede/base/common_hsi.h            |    6 +-
 drivers/net/qede/base/ecore.h                 |    9 ---
 drivers/net/qede/base/ecore_dcbx.c            |   17 +----
 drivers/net/qede/base/ecore_dcbx.h            |    6 --
 drivers/net/qede/base/ecore_dev.c             |   66 +++++++-------------
 drivers/net/qede/base/ecore_gtt_reg_addr.h    |   20 +++---
 drivers/net/qede/base/ecore_hsi_common.h      |   81 +++++++++++++-----------
 drivers/net/qede/base/ecore_hsi_debug_tools.h |   26 +++++---
 drivers/net/qede/base/ecore_hsi_eth.h         |   10 ++-
 drivers/net/qede/base/ecore_hsi_init_tool.h   |   82 +++++++++++--------------
 drivers/net/qede/base/ecore_init_fw_funcs.c   |   45 ++------------
 drivers/net/qede/base/ecore_init_ops.c        |    3 +-
 drivers/net/qede/base/ecore_iov_api.h         |   11 ++++
 drivers/net/qede/base/ecore_iro_values.h      |    4 +-
 drivers/net/qede/base/ecore_mcp.c             |    5 +-
 drivers/net/qede/base/ecore_sp_commands.c     |    4 +-
 drivers/net/qede/base/ecore_spq.c             |    3 +
 drivers/net/qede/base/ecore_sriov.c           |   12 ++++
 drivers/net/qede/base/eth_common.h            |   34 +++++++---
 drivers/net/qede/base/nvm_cfg.h               |   66 +++++++++++++++++++-
 drivers/net/qede/qede_main.c                  |    5 +-
 22 files changed, 279 insertions(+), 244 deletions(-)

diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index 9341eaa..e687f6b 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -77,10 +77,10 @@ Supported QLogic Adapters
 Prerequisites
 -------------
 
-- Requires firmware version **8.10.x.** and management firmware
-  version **8.10.x or higher**. Firmware may be available
+- Requires firmware version **8.14.x.** and management firmware
+  version **8.14.x or higher**. Firmware may be available
   inbox in certain newer Linux distros under the standard directory
-  ``E.g. /lib/firmware/qed/qed_init_values-8.10.9.0.bin``
+  ``E.g. /lib/firmware/qed/qed_init_values-8.14.6.0.bin``
 
 - If the required firmware files are not available then visit
   `QLogic Driver Download Center <http://driverdownloads.qlogic.com>`_.
@@ -119,7 +119,7 @@ enabling debugging options may affect system performance.
 - ``CONFIG_RTE_LIBRTE_QEDE_FW`` (default **""**)
 
   Gives absolute path of firmware file.
-  ``Eg: "/lib/firmware/qed/qed_init_values_zipped-8.10.9.0.bin"``
+  ``Eg: "/lib/firmware/qed/qed_init_values_zipped-8.14.6.0.bin"``
   Empty string indicates driver will pick up the firmware file
   from the default location.
 
diff --git a/drivers/net/qede/base/common_hsi.h b/drivers/net/qede/base/common_hsi.h
index b431c78..4083e86 100644
--- a/drivers/net/qede/base/common_hsi.h
+++ b/drivers/net/qede/base/common_hsi.h
@@ -89,8 +89,8 @@
 
 
 #define FW_MAJOR_VERSION		8
-#define FW_MINOR_VERSION		10
-#define FW_REVISION_VERSION		9
+#define FW_MINOR_VERSION		14
+#define FW_REVISION_VERSION		6
 #define FW_ENGINEERING_VERSION	0
 
 /***********************/
@@ -726,8 +726,6 @@ union event_ring_data {
 	struct malicious_vf_eqe_data malicious_vf /* Malicious VF data */;
 	struct initial_cleanup_eqe_data vf_init_cleanup
 	    /* VF Initial Cleanup data */;
-/* Host handle for the Async Completions */
-	struct regpair iwarp_handle;
 };
 /* Event Ring Entry */
 struct event_ring_entry {
diff --git a/drivers/net/qede/base/ecore.h b/drivers/net/qede/base/ecore.h
index 034e885..b1b0a2e 100644
--- a/drivers/net/qede/base/ecore.h
+++ b/drivers/net/qede/base/ecore.h
@@ -765,15 +765,6 @@ struct ecore_dev {
 #define NUM_OF_ENG_PFS(dev)	(ECORE_IS_BB(dev) ? MAX_NUM_PFS_BB \
 						  : MAX_NUM_PFS_K2)
 
-#ifndef REAL_ASIC_ONLY
-#define ENABLE_EAGLE_ENG1_WORKAROUND(p_hwfn) ( \
-	(ECORE_IS_BB_A0(p_hwfn->p_dev)) && \
-	(ECORE_PATH_ID(p_hwfn) == 1) && \
-	((p_hwfn->hw_info.port_mode == ECORE_PORT_MODE_DE_2X40G) || \
-	 (p_hwfn->hw_info.port_mode == ECORE_PORT_MODE_DE_2X50G) || \
-	 (p_hwfn->hw_info.port_mode == ECORE_PORT_MODE_DE_2X25G)))
-#endif
-
 /**
  * @brief ecore_concrete_to_sw_fid - get the sw function id from
  *        the concrete value.
diff --git a/drivers/net/qede/base/ecore_dcbx.c b/drivers/net/qede/base/ecore_dcbx.c
index 8175619..5932948 100644
--- a/drivers/net/qede/base/ecore_dcbx.c
+++ b/drivers/net/qede/base/ecore_dcbx.c
@@ -13,6 +13,7 @@
 #include "ecore_cxt.h"
 #include "ecore_gtt_reg_addr.h"
 #include "ecore_iro.h"
+#include "ecore_iov_api.h"
 
 #define ECORE_DCBX_MAX_MIB_READ_TRY	(100)
 #define ECORE_ETH_TYPE_DEFAULT		(0)
@@ -79,21 +80,6 @@ static bool ecore_dcbx_local(u32 dcbx_cfg_bitmap)
 		DCBX_CONFIG_VERSION_STATIC) ? true : false;
 }
 
-/* @@@TBD A0 Eagle workaround */
-void ecore_dcbx_eagle_workaround(struct ecore_hwfn *p_hwfn,
-				 struct ecore_ptt *p_ptt, bool set_to_pfc)
-{
-	if (!ENABLE_EAGLE_ENG1_WORKAROUND(p_hwfn))
-		return;
-
-	ecore_wr(p_hwfn, p_ptt,
-		 YSEM_REG_FAST_MEMORY + 0x20000 /* RAM in FASTMEM */  +
-		 YSTORM_FLOW_CONTROL_MODE_OFFSET,
-		 set_to_pfc ? flow_ctrl_pfc : flow_ctrl_pause);
-	ecore_wr(p_hwfn, p_ptt, NIG_REG_FLOWCTRL_MODE,
-		 EAGLE_ENG1_WORKAROUND_NIG_FLOWCTRL_MODE);
-}
-
 static void
 ecore_dcbx_dp_protocol(struct ecore_hwfn *p_hwfn,
 		       struct ecore_dcbx_results *p_data)
@@ -945,7 +931,6 @@ ecore_dcbx_mib_update_event(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
 			 * according to negotiation results
 			 */
 			enabled = p_hwfn->p_dcbx_info->results.dcbx_enabled;
-			ecore_dcbx_eagle_workaround(p_hwfn, p_ptt, enabled);
 		}
 	}
 	ecore_dcbx_get_params(p_hwfn, p_ptt, type);
diff --git a/drivers/net/qede/base/ecore_dcbx.h b/drivers/net/qede/base/ecore_dcbx.h
index 1518624..2ce4465 100644
--- a/drivers/net/qede/base/ecore_dcbx.h
+++ b/drivers/net/qede/base/ecore_dcbx.h
@@ -56,10 +56,4 @@ void ecore_dcbx_info_free(struct ecore_hwfn *, struct ecore_dcbx_info *);
 void ecore_dcbx_set_pf_update_params(struct ecore_dcbx_results *p_src,
 				     struct pf_update_ramrod_data *p_dest);
 
-#ifndef REAL_ASIC_ONLY
-/* @@@TBD eagle phy workaround */
-void ecore_dcbx_eagle_workaround(struct ecore_hwfn *, struct ecore_ptt *,
-				 bool set_to_pfc);
-#endif
-
 #endif /* __ECORE_DCBX_H__ */
diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index 03620d9..15db09f 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -711,7 +711,7 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev)
 	}
 
 	p_dev->reset_stats = OSAL_ZALLOC(p_dev, GFP_KERNEL,
-					 sizeof(struct ecore_eth_stats));
+					 sizeof(*p_dev->reset_stats));
 	if (!p_dev->reset_stats) {
 		DP_NOTICE(p_dev, true, "Failed to allocate reset statistics\n");
 		goto alloc_no_mem;
@@ -823,9 +823,7 @@ static enum _ecore_status_t ecore_calc_hw_mode(struct ecore_hwfn *p_hwfn)
 {
 	int hw_mode = 0;
 
-	if (ECORE_IS_BB_A0(p_hwfn->p_dev)) {
-		hw_mode |= 1 << MODE_BB_A0;
-	} else if (ECORE_IS_BB_B0(p_hwfn->p_dev)) {
+	if (ECORE_IS_BB_B0(p_hwfn->p_dev)) {
 		hw_mode |= 1 << MODE_BB_B0;
 	} else if (ECORE_IS_AH(p_hwfn->p_dev)) {
 		hw_mode |= 1 << MODE_K2;
@@ -881,11 +879,6 @@ static enum _ecore_status_t ecore_calc_hw_mode(struct ecore_hwfn *p_hwfn)
 #endif
 		hw_mode |= 1 << MODE_ASIC;
 
-#ifndef REAL_ASIC_ONLY
-	if (ENABLE_EAGLE_ENG1_WORKAROUND(p_hwfn))
-		hw_mode |= 1 << MODE_EAGLE_ENG1_WORKAROUND;
-#endif
-
 	if (p_hwfn->p_dev->num_hwfns > 1)
 		hw_mode |= 1 << MODE_100G;
 
@@ -991,7 +984,7 @@ static enum _ecore_status_t ecore_hw_init_common(struct ecore_hwfn *p_hwfn,
 	ecore_gtt_init(p_hwfn);
 
 #ifndef ASIC_ONLY
-	if (CHIP_REV_IS_EMUL(p_hwfn->p_dev)) {
+	if (CHIP_REV_IS_EMUL(p_dev)) {
 		rc = ecore_hw_init_chip(p_hwfn, p_hwfn->p_main_ptt);
 		if (rc != ECORE_SUCCESS)
 			return rc;
@@ -1006,7 +999,7 @@ static enum _ecore_status_t ecore_hw_init_common(struct ecore_hwfn *p_hwfn,
 	}
 
 	ecore_qm_common_rt_init(p_hwfn,
-				p_hwfn->p_dev->num_ports_in_engines,
+				p_dev->num_ports_in_engines,
 				qm_info->max_phys_tcs_per_port,
 				qm_info->pf_rl_en, qm_info->pf_wfq_en,
 				qm_info->vport_rl_en, qm_info->vport_wfq_en,
@@ -1036,11 +1029,11 @@ static enum _ecore_status_t ecore_hw_init_common(struct ecore_hwfn *p_hwfn,
 	ecore_wr(p_hwfn, p_ptt, PSWRQ2_REG_L2P_VALIDATE_VFID, 0);
 	ecore_wr(p_hwfn, p_ptt, PGLUE_B_REG_USE_CLIENTID_IN_TAG, 1);
 
-	if (ECORE_IS_BB(p_hwfn->p_dev)) {
+	if (ECORE_IS_BB(p_dev)) {
 		/* Workaround clears ROCE search for all functions to prevent
 		 * involving non initialized function in processing ROCE packet.
 		 */
-		num_pfs = NUM_OF_ENG_PFS(p_hwfn->p_dev);
+		num_pfs = NUM_OF_ENG_PFS(p_dev);
 		for (pf_id = 0; pf_id < num_pfs; pf_id++) {
 			ecore_fid_pretend(p_hwfn, p_ptt, pf_id);
 			ecore_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_ROCE, 0x0);
@@ -1056,8 +1049,7 @@ static enum _ecore_status_t ecore_hw_init_common(struct ecore_hwfn *p_hwfn,
 	 * This is not done inside the init tool since it currently can't
 	 * perform a pretending to VFs.
 	 */
-	max_num_vfs = ECORE_IS_AH(p_hwfn->p_dev) ? MAX_NUM_VFS_K2
-	    : MAX_NUM_VFS_BB;
+	max_num_vfs = ECORE_IS_AH(p_dev) ? MAX_NUM_VFS_K2 : MAX_NUM_VFS_BB;
 	for (vf_id = 0; vf_id < max_num_vfs; vf_id++) {
 		concrete_fid = ecore_vfid_to_concrete(p_hwfn, vf_id);
 		ecore_fid_pretend(p_hwfn, p_ptt, (u16)concrete_fid);
@@ -1536,7 +1528,9 @@ ecore_hw_init_pf(struct ecore_hwfn *p_hwfn,
 		return rc;
 	if (b_hw_start) {
 		/* enable interrupts */
-		ecore_int_igu_enable(p_hwfn, p_ptt, int_mode);
+		rc = ecore_int_igu_enable(p_hwfn, p_ptt, int_mode);
+		if (rc != ECORE_SUCCESS)
+			return rc;
 
 		/* send function start command */
 		rc = ecore_sp_pf_start(p_hwfn, p_tunn, p_hwfn->p_dev->mf_mode,
@@ -1627,7 +1621,7 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
 {
 	enum _ecore_status_t rc, mfw_rc;
 	u32 load_code, param;
-	int i, j;
+	int i;
 
 	if (p_params->int_mode == ECORE_INT_MODE_MSI && p_dev->num_hwfns > 1) {
 		DP_NOTICE(p_dev, false,
@@ -1711,25 +1705,6 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
 						p_hwfn->hw_info.hw_mode);
 			if (rc)
 				break;
-
-#ifndef REAL_ASIC_ONLY
-			if (ENABLE_EAGLE_ENG1_WORKAROUND(p_hwfn)) {
-				struct init_nig_pri_tc_map_req tc_map;
-
-				OSAL_MEM_ZERO(&tc_map, sizeof(tc_map));
-
-				/* remove this once flow control is
-				 * implemented
-				 */
-				for (j = 0; j < NUM_OF_VLAN_PRIORITIES; j++) {
-					tc_map.pri[j].tc_id = 0;
-					tc_map.pri[j].valid = 1;
-				}
-				ecore_init_nig_pri_tc_map(p_hwfn,
-							  p_hwfn->p_main_ptt,
-							  &tc_map);
-			}
-#endif
 			/* Fall into */
 		case FW_MSG_CODE_DRV_LOAD_FUNCTION:
 			rc = ecore_hw_init_pf(p_hwfn, p_hwfn->p_main_ptt,
@@ -1802,13 +1777,14 @@ static void ecore_hw_timers_stop(struct ecore_dev *p_dev,
 		 */
 		OSAL_MSLEEP(1);
 	}
-	if (i == ECORE_HW_STOP_RETRY_LIMIT)
-		DP_NOTICE(p_hwfn, true,
-			  "Timers linear scans are not over [Connection %02x Tasks %02x]\n",
-			  (u8)ecore_rd(p_hwfn, p_ptt,
-					TM_REG_PF_SCAN_ACTIVE_CONN),
-			  (u8)ecore_rd(p_hwfn, p_ptt,
-					TM_REG_PF_SCAN_ACTIVE_TASK));
+
+	if (i < ECORE_HW_STOP_RETRY_LIMIT)
+		return;
+
+	DP_NOTICE(p_hwfn, true, "Timers linear scans are not over"
+		  " [Connection %02x Tasks %02x]\n",
+		  (u8)ecore_rd(p_hwfn, p_ptt, TM_REG_PF_SCAN_ACTIVE_CONN),
+		  (u8)ecore_rd(p_hwfn, p_ptt, TM_REG_PF_SCAN_ACTIVE_TASK));
 }
 
 void ecore_hw_timers_stop_all(struct ecore_dev *p_dev)
@@ -3127,7 +3103,7 @@ enum _ecore_status_t ecore_hw_prepare(struct ecore_dev *p_dev,
 		}
 	}
 
-	return ECORE_SUCCESS;
+	return rc;
 }
 
 void ecore_hw_remove(struct ecore_dev *p_dev)
@@ -3819,8 +3795,8 @@ static enum _ecore_status_t ecore_set_coalesce(struct ecore_hwfn *p_hwfn,
 		return ECORE_INVAL;
 	}
 
-	OSAL_MEMSET(p_eth_qzone, 0, eth_qzone_size);
 	p_coal_timeset = p_eth_qzone;
+	OSAL_MEMSET(p_eth_qzone, 0, eth_qzone_size);
 	SET_FIELD(p_coal_timeset->value, COALESCING_TIMESET_TIMESET, timeset);
 	SET_FIELD(p_coal_timeset->value, COALESCING_TIMESET_VALID, 1);
 	ecore_memcpy_to(p_hwfn, p_ptt, hw_addr, p_eth_qzone, eth_qzone_size);
diff --git a/drivers/net/qede/base/ecore_gtt_reg_addr.h b/drivers/net/qede/base/ecore_gtt_reg_addr.h
index 6395b7c..070588d 100644
--- a/drivers/net/qede/base/ecore_gtt_reg_addr.h
+++ b/drivers/net/qede/base/ecore_gtt_reg_addr.h
@@ -10,43 +10,43 @@
 #define GTT_REG_ADDR_H
 
 /* Win 2 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_IGU_CMD                                      0x00f000UL
 
 /* Win 3 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_TSDM_RAM                                     0x010000UL
 
 /* Win 4 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_MSDM_RAM                                     0x011000UL
 
 /* Win 5 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_MSDM_RAM_1024                                0x012000UL
 
 /* Win 6 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_USDM_RAM                                     0x013000UL
 
 /* Win 7 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_USDM_RAM_1024                                0x014000UL
 
 /* Win 8 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_USDM_RAM_2048                                0x015000UL
 
 /* Win 9 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_XSDM_RAM                                     0x016000UL
 
 /* Win 10 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_YSDM_RAM                                     0x017000UL
 
 /* Win 11 */
-/* Access:RW   DataWidth:0x20    Chips: BB_A0 BB_B0 K2 */
+/* Access:RW   DataWidth:0x20    Chips: BB_B0 K2 E5 */
 #define GTT_BAR0_MAP_REG_PSDM_RAM                                     0x018000UL
 
 #endif
diff --git a/drivers/net/qede/base/ecore_hsi_common.h b/drivers/net/qede/base/ecore_hsi_common.h
index 179d410..6ddbe1a 100644
--- a/drivers/net/qede/base/ecore_hsi_common.h
+++ b/drivers/net/qede/base/ecore_hsi_common.h
@@ -660,6 +660,7 @@ enum core_event_opcode {
 	CORE_EVENT_TX_QUEUE_STOP,
 	CORE_EVENT_RX_QUEUE_START,
 	CORE_EVENT_RX_QUEUE_STOP,
+	CORE_EVENT_RX_QUEUE_FLUSH,
 	MAX_CORE_EVENT_OPCODE
 };
 
@@ -743,6 +744,7 @@ enum core_ramrod_cmd_id {
 	CORE_RAMROD_TX_QUEUE_START /* TX Queue Start Ramrod */,
 	CORE_RAMROD_RX_QUEUE_STOP /* RX Queue Stop Ramrod */,
 	CORE_RAMROD_TX_QUEUE_STOP /* TX Queue Stop Ramrod */,
+	CORE_RAMROD_RX_QUEUE_FLUSH /* RX Flush queue Ramrod */,
 	MAX_CORE_RAMROD_CMD_ID
 };
 
@@ -860,7 +862,8 @@ struct core_rx_slow_path_cqe {
 	u8 type /* CQE type */;
 	u8 ramrod_cmd_id;
 	__le16 echo;
-	__le32 reserved1[7];
+	struct core_rx_cqe_opaque_data opaque_data /* Opaque Data */;
+	__le32 reserved1[5];
 };
 
 /*
@@ -926,36 +929,51 @@ struct core_rx_stop_ramrod_data {
 /*
  * Flags for Core TX BD
  */
-struct core_tx_bd_flags {
-	u8 as_bitfield;
+struct core_tx_bd_data {
+	__le16 as_bitfield;
 /* Do not allow additional VLAN manipulations on this packet (DCB) */
-#define CORE_TX_BD_FLAGS_FORCE_VLAN_MODE_MASK      0x1
-#define CORE_TX_BD_FLAGS_FORCE_VLAN_MODE_SHIFT     0
+#define CORE_TX_BD_DATA_FORCE_VLAN_MODE_MASK      0x1
+#define CORE_TX_BD_DATA_FORCE_VLAN_MODE_SHIFT     0
 /* Insert VLAN into packet */
-#define CORE_TX_BD_FLAGS_VLAN_INSERTION_MASK       0x1
-#define CORE_TX_BD_FLAGS_VLAN_INSERTION_SHIFT      1
+#define CORE_TX_BD_DATA_VLAN_INSERTION_MASK       0x1
+#define CORE_TX_BD_DATA_VLAN_INSERTION_SHIFT      1
 /* This is the first BD of the packet (for debug) */
-#define CORE_TX_BD_FLAGS_START_BD_MASK             0x1
-#define CORE_TX_BD_FLAGS_START_BD_SHIFT            2
+#define CORE_TX_BD_DATA_START_BD_MASK             0x1
+#define CORE_TX_BD_DATA_START_BD_SHIFT            2
 /* Calculate the IP checksum for the packet */
-#define CORE_TX_BD_FLAGS_IP_CSUM_MASK              0x1
-#define CORE_TX_BD_FLAGS_IP_CSUM_SHIFT             3
+#define CORE_TX_BD_DATA_IP_CSUM_MASK              0x1
+#define CORE_TX_BD_DATA_IP_CSUM_SHIFT             3
 /* Calculate the L4 checksum for the packet */
-#define CORE_TX_BD_FLAGS_L4_CSUM_MASK              0x1
-#define CORE_TX_BD_FLAGS_L4_CSUM_SHIFT             4
+#define CORE_TX_BD_DATA_L4_CSUM_MASK              0x1
+#define CORE_TX_BD_DATA_L4_CSUM_SHIFT             4
 /* Packet is IPv6 with extensions */
-#define CORE_TX_BD_FLAGS_IPV6_EXT_MASK             0x1
-#define CORE_TX_BD_FLAGS_IPV6_EXT_SHIFT            5
+#define CORE_TX_BD_DATA_IPV6_EXT_MASK             0x1
+#define CORE_TX_BD_DATA_IPV6_EXT_SHIFT            5
 /* If IPv6+ext, and if l4_csum is 1, than this field indicates L4 protocol:
  * 0-TCP, 1-UDP
  */
-#define CORE_TX_BD_FLAGS_L4_PROTOCOL_MASK          0x1
-#define CORE_TX_BD_FLAGS_L4_PROTOCOL_SHIFT         6
+#define CORE_TX_BD_DATA_L4_PROTOCOL_MASK          0x1
+#define CORE_TX_BD_DATA_L4_PROTOCOL_SHIFT         6
 /* The pseudo checksum mode to place in the L4 checksum field. Required only
- *  when IPv6+ext and l4_csum is set. (use enum core_l4_pseudo_checksum_mode)
+ * when IPv6+ext and l4_csum is set. (use enum core_l4_pseudo_checksum_mode)
+ */
+#define CORE_TX_BD_DATA_L4_PSEUDO_CSUM_MODE_MASK  0x1
+#define CORE_TX_BD_DATA_L4_PSEUDO_CSUM_MODE_SHIFT 7
+/* Number of BDs that make up one packet - width wide enough to present
+ * CORE_LL2_TX_MAX_BDS_PER_PACKET
+ */
+#define CORE_TX_BD_DATA_NBDS_MASK                 0xF
+#define CORE_TX_BD_DATA_NBDS_SHIFT                8
+/* Use roce_flavor enum - Differentiate between Roce flavors is valid when
+ * connType is ROCE (use enum core_roce_flavor_type)
  */
-#define CORE_TX_BD_FLAGS_L4_PSEUDO_CSUM_MODE_MASK  0x1
-#define CORE_TX_BD_FLAGS_L4_PSEUDO_CSUM_MODE_SHIFT 7
+#define CORE_TX_BD_DATA_ROCE_FLAV_MASK            0x1
+#define CORE_TX_BD_DATA_ROCE_FLAV_SHIFT           12
+/* Calculate ip length */
+#define CORE_TX_BD_DATA_IP_LEN_MASK               0x1
+#define CORE_TX_BD_DATA_IP_LEN_SHIFT              13
+#define CORE_TX_BD_DATA_RESERVED0_MASK            0x3
+#define CORE_TX_BD_DATA_RESERVED0_SHIFT           14
 };
 
 /*
@@ -968,28 +986,18 @@ struct core_tx_bd {
  * packets: echo data to pass to Rx
  */
 	__le16 nw_vlan_or_lb_echo;
-	u8 bitfield0;
-/* Number of BDs that make up one packet - width wide enough to present
- * X_CORE_LL2_NUM_OF_BDS_ON_ST_CT
- */
-#define CORE_TX_BD_NBDS_MASK             0xF
-#define CORE_TX_BD_NBDS_SHIFT            0
-/* Use roce_flavor enum - Diffrentiate between Roce flavors is valid when
- * connType is ROCE (use enum core_roce_flavor_type)
- */
-#define CORE_TX_BD_ROCE_FLAV_MASK        0x1
-#define CORE_TX_BD_ROCE_FLAV_SHIFT       4
-#define CORE_TX_BD_RESERVED0_MASK        0x7
-#define CORE_TX_BD_RESERVED0_SHIFT       5
-	struct core_tx_bd_flags bd_flags /* BD Flags */;
+	struct core_tx_bd_data bd_data /* BD Flags */;
 	__le16 bitfield1;
+/* L4 Header Offset from start of packet (in Words). This is needed if both
+ * l4_csum and ipv6_ext are set
+ */
 #define CORE_TX_BD_L4_HDR_OFFSET_W_MASK  0x3FFF
 #define CORE_TX_BD_L4_HDR_OFFSET_W_SHIFT 0
 /* Packet destination - Network, LB (use enum core_tx_dest) */
 #define CORE_TX_BD_TX_DST_MASK           0x1
 #define CORE_TX_BD_TX_DST_SHIFT          14
-#define CORE_TX_BD_RESERVED1_MASK        0x1
-#define CORE_TX_BD_RESERVED1_SHIFT       15
+#define CORE_TX_BD_RESERVED_MASK         0x1
+#define CORE_TX_BD_RESERVED_SHIFT        15
 };
 
 
@@ -1265,6 +1273,7 @@ enum malicious_vf_error_id {
 /* Tunneled packet with IPv6+Ext without a proper number of BDs */
 	ETH_TUNN_IPV6_EXT_NBD_ERR,
 	ETH_CONTROL_PACKET_VIOLATION /* VF sent control frame such as PFC */,
+	ETH_ANTI_SPOOFING_ERR /* Anti-Spoofing verification failure */,
 	MAX_MALICIOUS_VF_ERROR_ID
 };
 
diff --git a/drivers/net/qede/base/ecore_hsi_debug_tools.h b/drivers/net/qede/base/ecore_hsi_debug_tools.h
index e82b0d4..effb6ed 100644
--- a/drivers/net/qede/base/ecore_hsi_debug_tools.h
+++ b/drivers/net/qede/base/ecore_hsi_debug_tools.h
@@ -92,6 +92,11 @@ enum block_addr {
 	GRCBASE_MS = 0x6a0000,
 	GRCBASE_PHY_PCIE = 0x620000,
 	GRCBASE_LED = 0x6b8000,
+	GRCBASE_AVS_WRAP = 0x6b0000,
+	GRCBASE_RGFS = 0x19d0000,
+	GRCBASE_TGFS = 0x19e0000,
+	GRCBASE_PTLD = 0x19f0000,
+	GRCBASE_YPLD = 0x1a10000,
 	GRCBASE_MISC_AEU = 0x8000,
 	GRCBASE_BAR0_MAP = 0x1c00000,
 	MAX_BLOCK_ADDR
@@ -177,6 +182,11 @@ enum block_id {
 	BLOCK_MS,
 	BLOCK_PHY_PCIE,
 	BLOCK_LED,
+	BLOCK_AVS_WRAP,
+	BLOCK_RGFS,
+	BLOCK_TGFS,
+	BLOCK_PTLD,
+	BLOCK_YPLD,
 	BLOCK_MISC_AEU,
 	BLOCK_BAR0_MAP,
 	MAX_BLOCK_ID
@@ -708,7 +718,7 @@ struct dbg_bus_data {
 	struct dbg_bus_pci_buf_data pci_buf;
 	__le16 reserved;
 /* Debug Bus data for each block */
-	struct dbg_bus_block_data blocks[80];
+	struct dbg_bus_block_data blocks[88];
 /* Debug Bus data for each block */
 	struct dbg_bus_storm_data storms[6];
 };
@@ -846,12 +856,12 @@ enum dbg_bus_targets {
  * GRC Dump data
  */
 struct dbg_grc_data {
+/* Indicates if the GRC parameters were initialized */
+	u8 params_initialized;
+	u8 reserved1;
+	__le16 reserved2;
 /* Value of each GRC parameter. Array size must match enum dbg_grc_params. */
-	__le32 param_val[40];
-/* Indicates for each GRC parameter if it was set by the user (0/1).
- * Array size must match the enum dbg_grc_params.
- */
-	u8 param_set_by_user[40];
+	__le32 param_val[48];
 };
 
 
@@ -901,6 +911,8 @@ enum dbg_grc_params {
 	DBG_GRC_PARAM_PARITY_SAFE,
 	DBG_GRC_PARAM_DUMP_CM /* dump CM memories (0/1) */,
 	DBG_GRC_PARAM_DUMP_PHY /* dump PHY memories (0/1) */,
+	DBG_GRC_PARAM_NO_MCP /* dont perform MCP commands (0/1) */,
+	DBG_GRC_PARAM_NO_FW_VER /* dont read FW/MFW version (0/1) */,
 	MAX_DBG_GRC_PARAMS
 };
 
@@ -1014,7 +1026,7 @@ struct dbg_tools_data {
 	struct idle_chk_data idle_chk /* Idle Check data */;
 	u8 mode_enable[40] /* Indicates if a mode is enabled (0/1) */;
 /* Indicates if a block is in reset state (0/1) */
-	u8 block_in_reset[80];
+	u8 block_in_reset[88];
 	u8 chip_id /* Chip ID (from enum chip_ids) */;
 	u8 platform_id /* Platform ID (from enum platform_ids) */;
 	u8 initialized /* Indicates if the data was initialized */;
diff --git a/drivers/net/qede/base/ecore_hsi_eth.h b/drivers/net/qede/base/ecore_hsi_eth.h
index e26c183..e8373d7 100644
--- a/drivers/net/qede/base/ecore_hsi_eth.h
+++ b/drivers/net/qede/base/ecore_hsi_eth.h
@@ -1446,7 +1446,15 @@ struct vport_update_ramrod_data_cmn {
 /* If set, MTU will be updated. Vport must be not active. */
 	u8 update_mtu_flg;
 	__le16 mtu /* New MTU value. Used if update_mtu_flg are set */;
-	u8 reserved[2];
+/* If set, ctl_frame_mac_check_en and ctl_frame_ethtype_check_en will be
+ * updated
+ */
+	u8 update_ctl_frame_checks_en_flg;
+/* If set, Contorl frames will be filtered according to MAC check. */
+	u8 ctl_frame_mac_check_en;
+/* If set, Contorl frames will be filtered according to ethtype check. */
+	u8 ctl_frame_ethtype_check_en;
+	u8 reserved[15];
 };
 
 struct vport_update_ramrod_mcast {
diff --git a/drivers/net/qede/base/ecore_hsi_init_tool.h b/drivers/net/qede/base/ecore_hsi_init_tool.h
index 410b0bc..d07549c 100644
--- a/drivers/net/qede/base/ecore_hsi_init_tool.h
+++ b/drivers/net/qede/base/ecore_hsi_init_tool.h
@@ -22,6 +22,43 @@
 /* Max size in dwords of a zipped array */
 #define MAX_ZIPPED_SIZE			8192
 
+enum init_modes {
+	MODE_BB_A0_DEPRECATED,
+	MODE_BB_B0,
+	MODE_K2,
+	MODE_ASIC,
+	MODE_EMUL_REDUCED,
+	MODE_EMUL_FULL,
+	MODE_FPGA,
+	MODE_CHIPSIM,
+	MODE_SF,
+	MODE_MF_SD,
+	MODE_MF_SI,
+	MODE_PORTS_PER_ENG_1,
+	MODE_PORTS_PER_ENG_2,
+	MODE_PORTS_PER_ENG_4,
+	MODE_100G,
+	MODE_E5,
+	MAX_INIT_MODES
+};
+
+enum init_phases {
+	PHASE_ENGINE,
+	PHASE_PORT,
+	PHASE_PF,
+	PHASE_VF,
+	PHASE_QM_PF,
+	MAX_INIT_PHASES
+};
+
+enum init_split_types {
+	SPLIT_TYPE_NONE,
+	SPLIT_TYPE_PORT,
+	SPLIT_TYPE_PF,
+	SPLIT_TYPE_PORT_PF,
+	SPLIT_TYPE_VF,
+	MAX_INIT_SPLIT_TYPES
+};
 
 struct fw_asserts_ram_section {
 /* The offset of the section in the RAM in RAM lines (64-bit units) */
@@ -69,51 +106,6 @@ struct fw_info_location {
 	__le32 size;
 };
 
-
-
-
-enum init_modes {
-	MODE_BB_A0,
-	MODE_BB_B0,
-	MODE_K2,
-	MODE_ASIC,
-	MODE_EMUL_REDUCED,
-	MODE_EMUL_FULL,
-	MODE_FPGA,
-	MODE_CHIPSIM,
-	MODE_SF,
-	MODE_MF_SD,
-	MODE_MF_SI,
-	MODE_PORTS_PER_ENG_1,
-	MODE_PORTS_PER_ENG_2,
-	MODE_PORTS_PER_ENG_4,
-	MODE_100G,
-	MODE_40G,
-	MODE_EAGLE_ENG1_WORKAROUND,
-	MAX_INIT_MODES
-};
-
-
-enum init_phases {
-	PHASE_ENGINE,
-	PHASE_PORT,
-	PHASE_PF,
-	PHASE_VF,
-	PHASE_QM_PF,
-	MAX_INIT_PHASES
-};
-
-
-enum init_split_types {
-	SPLIT_TYPE_NONE,
-	SPLIT_TYPE_PORT,
-	SPLIT_TYPE_PF,
-	SPLIT_TYPE_PORT_PF,
-	SPLIT_TYPE_VF,
-	MAX_INIT_SPLIT_TYPES
-};
-
-
 /*
  * Binary buffer header
  */
diff --git a/drivers/net/qede/base/ecore_init_fw_funcs.c b/drivers/net/qede/base/ecore_init_fw_funcs.c
index e83eeb8..a5437b5 100644
--- a/drivers/net/qede/base/ecore_init_fw_funcs.c
+++ b/drivers/net/qede/base/ecore_init_fw_funcs.c
@@ -176,12 +176,6 @@ static void ecore_cmdq_lines_voq_rt_init(struct ecore_hwfn *p_hwfn,
 					 u8 voq, u16 cmdq_lines)
 {
 	u32 qm_line_crd;
-	/* In A0 - Limit the size of pbf queue so that only 511 commands
-	 * with the minimum size of 4 (FCoE minimum size)
-	 */
-	bool is_bb_a0 = ECORE_IS_BB_A0(p_hwfn->p_dev);
-	if (is_bb_a0)
-		cmdq_lines = OSAL_MIN_T(u32, cmdq_lines, 1022);
 	qm_line_crd = QM_VOQ_LINE_CRD(cmdq_lines);
 	OVERWRITE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(voq),
 			 (u32)cmdq_lines);
@@ -327,11 +321,9 @@ static void ecore_tx_pq_map_rt_init(struct ecore_hwfn *p_hwfn,
 	u16 num_pqs = num_pf_pqs + num_vf_pqs;
 	u16 first_pq_group = start_pq / QM_PF_QUEUE_GROUP_SIZE;
 	u16 last_pq_group = (start_pq + num_pqs - 1) / QM_PF_QUEUE_GROUP_SIZE;
-	bool is_bb_a0 = ECORE_IS_BB_A0(p_hwfn->p_dev);
 	/* a bit per Tx PQ indicating if the PQ is associated with a VF */
 	u32 tx_pq_vf_mask[MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE] = { 0 };
-	u32 tx_pq_vf_mask_width = is_bb_a0 ? 32 : QM_PF_QUEUE_GROUP_SIZE;
-	u32 num_tx_pq_vf_masks = MAX_QM_TX_QUEUES / tx_pq_vf_mask_width;
+	u32 num_tx_pq_vf_masks = MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE;
 	u32 pq_mem_4kb = QM_PQ_MEM_4KB(num_pf_cids);
 	u32 vport_pq_mem_4kb = QM_PQ_MEM_4KB(num_vf_cids);
 	u32 mem_addr_4kb = base_mem_addr_4kb;
@@ -397,8 +389,8 @@ static void ecore_tx_pq_map_rt_init(struct ecore_hwfn *p_hwfn,
 			/* if PQ is associated with a VF, add indication to PQ
 			 * VF mask
 			 */
-			tx_pq_vf_mask[pq_id / tx_pq_vf_mask_width] |=
-			    (1 << (pq_id % tx_pq_vf_mask_width));
+			tx_pq_vf_mask[pq_id / QM_PF_QUEUE_GROUP_SIZE] |=
+				(1 << (pq_id % QM_PF_QUEUE_GROUP_SIZE));
 			mem_addr_4kb += vport_pq_mem_4kb;
 		} else {
 			mem_addr_4kb += pq_mem_4kb;
@@ -406,23 +398,9 @@ static void ecore_tx_pq_map_rt_init(struct ecore_hwfn *p_hwfn,
 	}
 	/* store Tx PQ VF mask to size select register */
 	for (i = 0; i < num_tx_pq_vf_masks; i++) {
-		if (tx_pq_vf_mask[i]) {
-			if (is_bb_a0) {
-				/* A0-only: perform read-modify-write
-				 *(fixed in B0)
-				 */
-				u32 curr_mask =
-				    is_first_pf ? 0 : ecore_rd(p_hwfn, p_ptt,
-						       QM_REG_MAXPQSIZETXSEL_0
-								+ i * 4);
-				STORE_RT_REG(p_hwfn,
-					     QM_REG_MAXPQSIZETXSEL_0_RT_OFFSET +
-					     i, curr_mask | tx_pq_vf_mask[i]);
-			} else
-				STORE_RT_REG(p_hwfn,
-					     QM_REG_MAXPQSIZETXSEL_0_RT_OFFSET +
-					     i, tx_pq_vf_mask[i]);
-		}
+		if (tx_pq_vf_mask[i])
+			STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZETXSEL_0_RT_OFFSET +
+				     i, tx_pq_vf_mask[i]);
 	}
 }
 
@@ -1246,9 +1224,6 @@ void ecore_set_gre_enable(struct ecore_hwfn *p_hwfn,
 void ecore_set_geneve_dest_port(struct ecore_hwfn *p_hwfn,
 				struct ecore_ptt *p_ptt, u16 dest_port)
 {
-	/* geneve tunnel not supported in BB_A0 */
-	if (ECORE_IS_BB_A0(p_hwfn->p_dev))
-		return;
 	/* update PRS register */
 	ecore_wr(p_hwfn, p_ptt, PRS_REG_NGE_PORT, dest_port);
 	/* update NIG register */
@@ -1262,9 +1237,6 @@ void ecore_set_geneve_enable(struct ecore_hwfn *p_hwfn,
 			     bool eth_geneve_enable, bool ip_geneve_enable)
 {
 	u32 reg_val;
-	/* geneve tunnel not supported in BB_A0 */
-	if (ECORE_IS_BB_A0(p_hwfn->p_dev))
-		return;
 	/* update PRS register */
 	reg_val = ecore_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN);
 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val,
@@ -1283,11 +1255,6 @@ void ecore_set_geneve_enable(struct ecore_hwfn *p_hwfn,
 		 eth_geneve_enable ? 1 : 0);
 	ecore_wr(p_hwfn, p_ptt, NIG_REG_NGE_IP_ENABLE,
 		 ip_geneve_enable ? 1 : 0);
-	/* comp ver */
-	reg_val = (ip_geneve_enable || eth_geneve_enable) ? 1 : 0;
-	ecore_wr(p_hwfn, p_ptt, NIG_REG_NGE_COMP_VER, reg_val);
-	ecore_wr(p_hwfn, p_ptt, PBF_REG_NGE_COMP_VER, reg_val);
-	ecore_wr(p_hwfn, p_ptt, PRS_REG_NGE_COMP_VER, reg_val);
 	/* EDPM with geneve tunnel not supported in BB_B0 */
 	if (ECORE_IS_BB_B0(p_hwfn->p_dev))
 		return;
diff --git a/drivers/net/qede/base/ecore_init_ops.c b/drivers/net/qede/base/ecore_init_ops.c
index 351e946..faeca68 100644
--- a/drivers/net/qede/base/ecore_init_ops.c
+++ b/drivers/net/qede/base/ecore_init_ops.c
@@ -573,8 +573,7 @@ enum _ecore_status_t ecore_init_fw_data(struct ecore_dev *p_dev,
 		return ECORE_INVAL;
 	}
 
-	/* First Dword contains metadata and should be skipped */
-	buf_hdr = (struct bin_buffer_hdr *)((uintptr_t)(data + sizeof(u32)));
+	buf_hdr = (struct bin_buffer_hdr *)(uintptr_t)data;
 
 	offset = buf_hdr[BIN_BUF_INIT_FW_VER_INFO].offset;
 	fw->fw_ver_info = (struct fw_ver_info *)((uintptr_t)(data + offset));
diff --git a/drivers/net/qede/base/ecore_iov_api.h b/drivers/net/qede/base/ecore_iov_api.h
index 0b857bb..24a43d3 100644
--- a/drivers/net/qede/base/ecore_iov_api.h
+++ b/drivers/net/qede/base/ecore_iov_api.h
@@ -664,6 +664,17 @@ bool ecore_iov_is_vf_initialized(struct ecore_hwfn *p_hwfn,
 				 u16 rel_vf_id);
 
 /**
+ * @brief - Returm true if VF has started in FW
+ *
+ * @param p_hwfn
+ * @param rel_vf_id
+ *
+ * @return
+ */
+bool ecore_iov_is_vf_started(struct ecore_hwfn *p_hwfn,
+			     u16 rel_vf_id);
+
+/**
  * @brief - Get VF's vport min rate configured.
  * @param p_hwfn
  * @param rel_vf_id
diff --git a/drivers/net/qede/base/ecore_iro_values.h b/drivers/net/qede/base/ecore_iro_values.h
index 43e01e4..4ff7e95 100644
--- a/drivers/net/qede/base/ecore_iro_values.h
+++ b/drivers/net/qede/base/ecore_iro_values.h
@@ -91,9 +91,9 @@ static const struct iro iro_arr[47] = {
 /* USTORM_ISCSI_RX_STATS_OFFSET(pf_id) */
 	{  0x11aa0,     0x38,      0x0,      0x0,     0x18},
 /* XSTORM_ISCSI_TX_STATS_OFFSET(pf_id) */
-	{   0xa8c0,     0x30,      0x0,      0x0,     0x10},
+	{   0xa8c0,     0x38,      0x0,      0x0,     0x10},
 /* YSTORM_ISCSI_TX_STATS_OFFSET(pf_id) */
-	{   0x86f8,     0x28,      0x0,      0x0,     0x18},
+	{   0x86f8,     0x30,      0x0,      0x0,     0x18},
 /* PSTORM_ISCSI_TX_STATS_OFFSET(pf_id) */
 	{  0x101f8,     0x10,      0x0,      0x0,     0x10},
 /* TSTORM_FCOE_RX_STATS_OFFSET(pf_id) */
diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c
index adcb0f0..e641a77 100644
--- a/drivers/net/qede/base/ecore_mcp.c
+++ b/drivers/net/qede/base/ecore_mcp.c
@@ -801,9 +801,6 @@ static void ecore_mcp_handle_link_change(struct ecore_hwfn *p_hwfn,
 
 	p_link->sfp_tx_fault = !!(status & LINK_STATUS_SFP_TX_FAULT);
 
-	if (p_link->link_up)
-		ecore_dcbx_eagle_workaround(p_hwfn, p_ptt, p_link->pfc_enabled);
-
 	OSAL_LINK_UPDATE(p_hwfn);
 }
 
@@ -2267,7 +2264,7 @@ enum _ecore_status_t ecore_mcp_bist_register_test(struct ecore_hwfn *p_hwfn,
 enum _ecore_status_t ecore_mcp_bist_clock_test(struct ecore_hwfn *p_hwfn,
 					       struct ecore_ptt *p_ptt)
 {
-	u32 drv_mb_param = 0, rsp, param;
+	u32 drv_mb_param, rsp, param;
 	enum _ecore_status_t rc = ECORE_SUCCESS;
 
 	drv_mb_param = (DRV_MB_PARAM_BIST_CLOCK_TEST <<
diff --git a/drivers/net/qede/base/ecore_sp_commands.c b/drivers/net/qede/base/ecore_sp_commands.c
index b3736a8..23ebab7 100644
--- a/drivers/net/qede/base/ecore_sp_commands.c
+++ b/drivers/net/qede/base/ecore_sp_commands.c
@@ -31,7 +31,7 @@ enum _ecore_status_t ecore_sp_init_request(struct ecore_hwfn *p_hwfn,
 {
 	u32 opaque_cid = p_data->opaque_fid << 16 | p_data->cid;
 	struct ecore_spq_entry *p_ent = OSAL_NULL;
-	enum _ecore_status_t rc = ECORE_NOTIMPL;
+	enum _ecore_status_t rc;
 
 	if (!pp_ent)
 		return ECORE_INVAL;
@@ -564,7 +564,7 @@ enum _ecore_status_t ecore_sp_heartbeat_ramrod(struct ecore_hwfn *p_hwfn)
 {
 	struct ecore_spq_entry *p_ent = OSAL_NULL;
 	struct ecore_sp_init_data init_data;
-	enum _ecore_status_t rc = ECORE_NOTIMPL;
+	enum _ecore_status_t rc;
 
 	/* Get SPQ entry */
 	OSAL_MEMSET(&init_data, 0, sizeof(init_data));
diff --git a/drivers/net/qede/base/ecore_spq.c b/drivers/net/qede/base/ecore_spq.c
index c524cab..e371492 100644
--- a/drivers/net/qede/base/ecore_spq.c
+++ b/drivers/net/qede/base/ecore_spq.c
@@ -924,6 +924,9 @@ enum _ecore_status_t ecore_spq_completion(struct ecore_hwfn *p_hwfn,
 	if (found->comp_cb.function)
 		found->comp_cb.function(p_hwfn, found->comp_cb.cookie, p_data,
 					fw_return_code);
+	else
+		DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ,
+			   "Got a completion without a callback function\n");
 
 	if ((found->comp_mode != ECORE_SPQ_MODE_EBLOCK) ||
 	    (found->queue == &p_spq->unlimited_pending))
diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c
index eaad843..e8f1ebe 100644
--- a/drivers/net/qede/base/ecore_sriov.c
+++ b/drivers/net/qede/base/ecore_sriov.c
@@ -3964,6 +3964,18 @@ bool ecore_iov_is_vf_initialized(struct ecore_hwfn *p_hwfn, u16 rel_vf_id)
 	return (p_vf->state == VF_ENABLED);
 }
 
+bool ecore_iov_is_vf_started(struct ecore_hwfn *p_hwfn,
+			     u16 rel_vf_id)
+{
+	struct ecore_vf_info *p_vf;
+
+	p_vf = ecore_iov_get_vf_info(p_hwfn, rel_vf_id, true);
+	if (!p_vf)
+		return false;
+
+	return (p_vf->state != VF_FREE && p_vf->state != VF_STOPPED);
+}
+
 enum _ecore_status_t
 ecore_iov_get_vf_min_rate(struct ecore_hwfn *p_hwfn, int vfid)
 {
diff --git a/drivers/net/qede/base/eth_common.h b/drivers/net/qede/base/eth_common.h
index 3213070..d2ebce8 100644
--- a/drivers/net/qede/base/eth_common.h
+++ b/drivers/net/qede/base/eth_common.h
@@ -34,6 +34,14 @@
 #define ETH_RX_CQE_PAGE_SIZE_BYTES          4096
 #define ETH_RX_NUM_NEXT_PAGE_BDS            2
 
+/* Limitation for Tunneled LSO Packets on the offset (in bytes) of the inner IP
+ * header (relevant to LSO for tunneled packet):
+ */
+/* Offset is limited to 253 bytes (inclusive). */
+#define ETH_MAX_TUNN_LSO_INNER_IPV4_OFFSET          253
+/* Offset is limited to 251 bytes (inclusive). */
+#define ETH_MAX_TUNN_LSO_INNER_IPV6_OFFSET          251
+
 #define ETH_TX_MIN_BDS_PER_NON_LSO_PKT              1
 #define ETH_TX_MAX_BDS_PER_NON_LSO_PACKET           18
 #define ETH_TX_MAX_BDS_PER_LSO_PACKET               255
@@ -141,16 +149,23 @@ struct eth_tx_1st_bd_flags {
 /* Do not allow additional VLAN manipulations on this packet. */
 #define ETH_TX_1ST_BD_FLAGS_FORCE_VLAN_MODE_MASK  0x1
 #define ETH_TX_1ST_BD_FLAGS_FORCE_VLAN_MODE_SHIFT 1
-/* IP checksum recalculation in needed */
+/* Recalculate IP checksum. For tunneled packet - relevant to inner header. */
 #define ETH_TX_1ST_BD_FLAGS_IP_CSUM_MASK          0x1
 #define ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT         2
-/* TCP/UDP checksum recalculation in needed */
+/* Recalculate TCP/UDP checksum.
+ * For tunneled packet - relevant to inner header.
+ */
 #define ETH_TX_1ST_BD_FLAGS_L4_CSUM_MASK          0x1
 #define ETH_TX_1ST_BD_FLAGS_L4_CSUM_SHIFT         3
-/* If set, need to add the VLAN in vlan field to the packet. */
+/* If set, insert VLAN tag from vlan field to the packet.
+ * For tunneled packet - relevant to outer header.
+ */
 #define ETH_TX_1ST_BD_FLAGS_VLAN_INSERTION_MASK   0x1
 #define ETH_TX_1ST_BD_FLAGS_VLAN_INSERTION_SHIFT  4
-/* If set, this is an LSO packet. */
+/* If set, this is an LSO packet. Note: For Tunneled LSO packets, the offset of
+ * the inner IPV4 (and IPV6) header is limited to 253 (and 251 respectively)
+ * bytes, inclusive.
+ */
 #define ETH_TX_1ST_BD_FLAGS_LSO_MASK              0x1
 #define ETH_TX_1ST_BD_FLAGS_LSO_SHIFT             5
 /* Recalculate Tunnel IP Checksum (if Tunnel IP Header is IPv4) */
@@ -165,7 +180,8 @@ struct eth_tx_1st_bd_flags {
  * The parsing information data for the first tx bd of a given packet.
  */
 struct eth_tx_data_1st_bd {
-	__le16 vlan /* VLAN tag to insert to packet (if needed). */;
+/* VLAN tag to insert to packet (if enabled by vlan_insertion flag). */
+	__le16 vlan;
 /* Number of BDs in packet. Should be at least 2 in non-LSO packet and at least
  * 3 in LSO (or Tunnel with IPv6+ext) packet.
  */
@@ -209,10 +225,14 @@ struct eth_tx_data_2nd_bd {
 /* For LSO / Tunnel header with IPv6+ext - Set if inner header is IPv6 */
 #define ETH_TX_DATA_2ND_BD_TUNN_INNER_IPV6_MASK           0x1
 #define ETH_TX_DATA_2ND_BD_TUNN_INNER_IPV6_SHIFT          11
-/* For LSO / Tunnel header with IPv6+ext - Set if outer header has IPv6+ext */
+/* In tunneling mode - Set to 1 when the Inner header is IPv6 with extension.
+ * Otherwise set to 1 if the header is IPv6 with extension.
+ */
 #define ETH_TX_DATA_2ND_BD_IPV6_EXT_MASK                  0x1
 #define ETH_TX_DATA_2ND_BD_IPV6_EXT_SHIFT                 12
-/* Set if Tunnel header has IPv6 ext. (3rd BD is required) */
+/* Set to 1 if Tunnel (outer = encapsulating) header has IPv6 ext. (Note: 3rd BD
+ * is required, hence EDPM does not support Tunnel [outer] header with Ipv6Ext)
+ */
 #define ETH_TX_DATA_2ND_BD_TUNN_IPV6_EXT_MASK             0x1
 #define ETH_TX_DATA_2ND_BD_TUNN_IPV6_EXT_SHIFT            13
 /* Set if (inner) L4 protocol is UDP. (Required when IPv6+ext (or tunnel with
diff --git a/drivers/net/qede/base/nvm_cfg.h b/drivers/net/qede/base/nvm_cfg.h
index 4edffac..68abc2d 100644
--- a/drivers/net/qede/base/nvm_cfg.h
+++ b/drivers/net/qede/base/nvm_cfg.h
@@ -13,7 +13,7 @@
  * Description: NVM config file - Generated file from nvm cfg excel.
  *              DO NOT MODIFY !!!
  *
- * Created:     5/9/2016
+ * Created:     9/6/2016
  *
  ****************************************************************************/
 
@@ -477,6 +477,9 @@ struct nvm_cfg1_glob {
 		#define NVM_CFG1_GLOB_MANUF1_TIME_OFFSET 6
 		#define NVM_CFG1_GLOB_MANUF2_TIME_MASK 0x0003F000
 		#define NVM_CFG1_GLOB_MANUF2_TIME_OFFSET 12
+	/*  Max MSIX for Ethernet in default mode */
+		#define NVM_CFG1_GLOB_MAX_MSIX_MASK 0x03FC0000
+		#define NVM_CFG1_GLOB_MAX_MSIX_OFFSET 18
 	u32 led_global_settings; /* 0x74 */
 		#define NVM_CFG1_GLOB_LED_SWAP_0_MASK 0x0000000F
 		#define NVM_CFG1_GLOB_LED_SWAP_0_OFFSET 0
@@ -497,6 +500,14 @@ struct nvm_cfg1_glob {
 		#define NVM_CFG1_GLOB_LANE2_SWAP_OFFSET 14
 		#define NVM_CFG1_GLOB_LANE3_SWAP_MASK 0x00030000
 		#define NVM_CFG1_GLOB_LANE3_SWAP_OFFSET 16
+	/*  Enable option 195 - Overriding the PCIe Preset value */
+		#define NVM_CFG1_GLOB_OVERRIDE_PCIE_PRESET_EQUAL_MASK 0x00040000
+		#define NVM_CFG1_GLOB_OVERRIDE_PCIE_PRESET_EQUAL_OFFSET 18
+		#define NVM_CFG1_GLOB_OVERRIDE_PCIE_PRESET_EQUAL_DISABLED 0x0
+		#define NVM_CFG1_GLOB_OVERRIDE_PCIE_PRESET_EQUAL_ENABLED 0x1
+	/*  PCIe Preset value - applies only if option 194 is enabled */
+		#define NVM_CFG1_GLOB_PCIE_PRESET_VALUE_MASK 0x00780000
+		#define NVM_CFG1_GLOB_PCIE_PRESET_VALUE_OFFSET 19
 	u32 mbi_version; /* 0x7C */
 		#define NVM_CFG1_GLOB_MBI_VERSION_0_MASK 0x000000FF
 		#define NVM_CFG1_GLOB_MBI_VERSION_0_OFFSET 0
@@ -623,6 +634,44 @@ struct nvm_cfg1_port {
 		#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_ETHERNET 0x1
 		#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_FCOE 0x2
 		#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_ISCSI 0x4
+	/* GPIO for HW reset the PHY. In case it is the same for all ports,
+	 * need to set same value for all ports
+	 */
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_MASK 0xFF000000
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_OFFSET 24
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_NA 0x0
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO0 0x1
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO1 0x2
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO2 0x3
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO3 0x4
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO4 0x5
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO5 0x6
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO6 0x7
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO7 0x8
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO8 0x9
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO9 0xA
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO10 0xB
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO11 0xC
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO12 0xD
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO13 0xE
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO14 0xF
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO15 0x10
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO16 0x11
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO17 0x12
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO18 0x13
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO19 0x14
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO20 0x15
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO21 0x16
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO22 0x17
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO23 0x18
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO24 0x19
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO25 0x1A
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO26 0x1B
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO27 0x1C
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO28 0x1D
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO29 0x1E
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO30 0x1F
+		#define NVM_CFG1_PORT_EXT_PHY_RESET_GPIO31 0x20
 	u32 pcie_cfg; /* 0xC */
 		#define NVM_CFG1_PORT_RESERVED15_MASK 0x00000007
 		#define NVM_CFG1_PORT_RESERVED15_OFFSET 0
@@ -699,6 +748,7 @@ struct nvm_cfg1_port {
 		#define NVM_CFG1_PORT_FEC_FORCE_MODE_NONE 0x0
 		#define NVM_CFG1_PORT_FEC_FORCE_MODE_FIRECODE 0x1
 		#define NVM_CFG1_PORT_FEC_FORCE_MODE_RS 0x2
+		#define NVM_CFG1_PORT_FEC_FORCE_MODE_AUTO 0x7
 	u32 phy_cfg; /* 0x1C */
 		#define NVM_CFG1_PORT_OPTIONAL_LINK_MODES_MASK 0x0000FFFF
 		#define NVM_CFG1_PORT_OPTIONAL_LINK_MODES_OFFSET 0
@@ -738,9 +788,16 @@ struct nvm_cfg1_port {
 		#define NVM_CFG1_PORT_EXTERNAL_PHY_TYPE_MASK 0x000000FF
 		#define NVM_CFG1_PORT_EXTERNAL_PHY_TYPE_OFFSET 0
 		#define NVM_CFG1_PORT_EXTERNAL_PHY_TYPE_NONE 0x0
-		#define NVM_CFG1_PORT_EXTERNAL_PHY_TYPE_BCM84844 0x1
+		#define NVM_CFG1_PORT_EXTERNAL_PHY_TYPE_BCM8485X 0x1
 		#define NVM_CFG1_PORT_EXTERNAL_PHY_ADDRESS_MASK 0x0000FF00
 		#define NVM_CFG1_PORT_EXTERNAL_PHY_ADDRESS_OFFSET 8
+	/*  EEE power saving mode */
+		#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_MASK 0x00FF0000
+		#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_OFFSET 16
+		#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_DISABLED 0x0
+		#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_BALANCED 0x1
+		#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_AGGRESSIVE 0x2
+		#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_LOW_LATENCY 0x3
 	u32 mba_cfg1; /* 0x28 */
 		#define NVM_CFG1_PORT_PREBOOT_OPROM_MASK 0x00000001
 		#define NVM_CFG1_PORT_PREBOOT_OPROM_OFFSET 0
@@ -972,6 +1029,7 @@ struct nvm_cfg1_port {
 		#define NVM_CFG1_PORT_MNM_10G_FEC_FORCE_MODE_NONE 0x0
 		#define NVM_CFG1_PORT_MNM_10G_FEC_FORCE_MODE_FIRECODE 0x1
 		#define NVM_CFG1_PORT_MNM_10G_FEC_FORCE_MODE_RS 0x2
+		#define NVM_CFG1_PORT_MNM_10G_FEC_FORCE_MODE_AUTO 0x7
 	u32 mnm_25g_cap; /* 0x58 */
 		#define NVM_CFG1_PORT_MNM_25G_DRV_SPEED_CAPABILITY_MASK_MASK \
 			0x0000FFFF
@@ -1049,6 +1107,7 @@ struct nvm_cfg1_port {
 		#define NVM_CFG1_PORT_MNM_25G_FEC_FORCE_MODE_NONE 0x0
 		#define NVM_CFG1_PORT_MNM_25G_FEC_FORCE_MODE_FIRECODE 0x1
 		#define NVM_CFG1_PORT_MNM_25G_FEC_FORCE_MODE_RS 0x2
+		#define NVM_CFG1_PORT_MNM_25G_FEC_FORCE_MODE_AUTO 0x7
 	u32 mnm_40g_cap; /* 0x64 */
 		#define NVM_CFG1_PORT_MNM_40G_DRV_SPEED_CAPABILITY_MASK_MASK \
 			0x0000FFFF
@@ -1126,6 +1185,7 @@ struct nvm_cfg1_port {
 		#define NVM_CFG1_PORT_MNM_40G_FEC_FORCE_MODE_NONE 0x0
 		#define NVM_CFG1_PORT_MNM_40G_FEC_FORCE_MODE_FIRECODE 0x1
 		#define NVM_CFG1_PORT_MNM_40G_FEC_FORCE_MODE_RS 0x2
+		#define NVM_CFG1_PORT_MNM_40G_FEC_FORCE_MODE_AUTO 0x7
 	u32 mnm_50g_cap; /* 0x70 */
 		#define NVM_CFG1_PORT_MNM_50G_DRV_SPEED_CAPABILITY_MASK_MASK \
 			0x0000FFFF
@@ -1205,6 +1265,7 @@ struct nvm_cfg1_port {
 		#define NVM_CFG1_PORT_MNM_50G_FEC_FORCE_MODE_NONE 0x0
 		#define NVM_CFG1_PORT_MNM_50G_FEC_FORCE_MODE_FIRECODE 0x1
 		#define NVM_CFG1_PORT_MNM_50G_FEC_FORCE_MODE_RS 0x2
+		#define NVM_CFG1_PORT_MNM_50G_FEC_FORCE_MODE_AUTO 0x7
 	u32 mnm_100g_cap; /* 0x7C */
 		#define NVM_CFG1_PORT_MNM_100G_DRV_SPEED_CAP_MASK_MASK \
 			0x0000FFFF
@@ -1279,6 +1340,7 @@ struct nvm_cfg1_port {
 		#define NVM_CFG1_PORT_MNM_100G_FEC_FORCE_MODE_NONE 0x0
 		#define NVM_CFG1_PORT_MNM_100G_FEC_FORCE_MODE_FIRECODE 0x1
 		#define NVM_CFG1_PORT_MNM_100G_FEC_FORCE_MODE_RS 0x2
+		#define NVM_CFG1_PORT_MNM_100G_FEC_FORCE_MODE_AUTO 0x7
 	u32 reserved[116]; /* 0x88 */
 };
 
diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
index 92ed404..8a4d68a 100644
--- a/drivers/net/qede/qede_main.c
+++ b/drivers/net/qede/qede_main.c
@@ -21,7 +21,7 @@ static uint8_t npar_tx_switching = 1;
 char fw_file[PATH_MAX];
 
 const char *QEDE_DEFAULT_FIRMWARE =
-	"/lib/firmware/qed/qed_init_values-8.10.9.0.bin";
+	"/lib/firmware/qed/qed_init_values-8.14.6.0.bin";
 
 static void
 qed_update_pf_params(struct ecore_dev *edev, struct ecore_pf_params *params)
@@ -234,8 +234,7 @@ static int qed_slowpath_start(struct ecore_dev *edev,
 	if (IS_PF(edev)) {
 		rc = qed_load_firmware_data(edev);
 		if (rc) {
-			DP_NOTICE(edev, true,
-				  "Failed to find fw file %s\n", fw_file);
+			DP_ERR(edev, "Failed to find fw file %s\n", fw_file);
 			goto err;
 		}
 	}
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 23/26] net/qede/base: semantic/formatting changes
From: Rasesh Mody @ 2017-01-05  7:04 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, Dept-EngDPDKDev
In-Reply-To: <1480756289-11835-1-git-send-email-Rasesh.Mody@cavium.com>

This patch consists of semantic/formatting changes. It also includes
comment additions.

Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
---
 drivers/net/qede/base/common_hsi.h       |    5 +-
 drivers/net/qede/base/ecore_dev.c        |   14 +-
 drivers/net/qede/base/ecore_hsi_common.h |   14 +-
 drivers/net/qede/base/ecore_hw.c         |    4 +-
 drivers/net/qede/base/ecore_init_ops.c   |    4 +-
 drivers/net/qede/base/ecore_int.c        |    6 +-
 drivers/net/qede/base/ecore_mcp.c        |    5 +-
 drivers/net/qede/base/ecore_spq.c        |    3 +-
 drivers/net/qede/base/ecore_sriov.c      |    8 +-
 drivers/net/qede/base/mcp_public.h       |  262 ++++++++++++++----------------
 10 files changed, 158 insertions(+), 167 deletions(-)

diff --git a/drivers/net/qede/base/common_hsi.h b/drivers/net/qede/base/common_hsi.h
index 4083e86..2f84148 100644
--- a/drivers/net/qede/base/common_hsi.h
+++ b/drivers/net/qede/base/common_hsi.h
@@ -721,8 +721,7 @@ union event_ring_data {
 	u8 bytes[8] /* Byte Array */;
 	struct vf_pf_channel_eqe_data vf_pf_channel /* VF-PF Channel data */;
 	struct iscsi_eqe_data iscsi_info /* Dedicated fields to iscsi data */;
-	    /* Dedicated field for RoCE affiliated asynchronous error */;
-	struct regpair roceHandle;
+	struct regpair roceHandle /* Dedicated field for RDMA data */;
 	struct malicious_vf_eqe_data malicious_vf /* Malicious VF data */;
 	struct initial_cleanup_eqe_data vf_init_cleanup
 	    /* VF Initial Cleanup data */;
@@ -766,6 +765,8 @@ enum protocol_type {
 	MAX_PROTOCOL_TYPE
 };
 
+
+
 /*
  * Ustorm Queue Zone
  */
diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index 15db09f..f7a36c9 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -1623,7 +1623,8 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
 	u32 load_code, param;
 	int i;
 
-	if (p_params->int_mode == ECORE_INT_MODE_MSI && p_dev->num_hwfns > 1) {
+	if ((p_params->int_mode == ECORE_INT_MODE_MSI) &&
+	    (p_dev->num_hwfns > 1)) {
 		DP_NOTICE(p_dev, false,
 			  "MSI mode is not supported for CMT devices\n");
 		return ECORE_INVAL;
@@ -2937,8 +2938,9 @@ void ecore_prepare_hibernate(struct ecore_dev *p_dev)
 #endif
 
 static enum _ecore_status_t
-ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn, void OSAL_IOMEM *p_regview,
-			void OSAL_IOMEM *p_doorbells,
+ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn,
+			void OSAL_IOMEM * p_regview,
+			void OSAL_IOMEM * p_doorbells,
 			struct ecore_hw_prepare_params *p_params)
 {
 	struct ecore_dev *p_dev = p_hwfn->p_dev;
@@ -3280,8 +3282,8 @@ ecore_chain_alloc_next_ptr(struct ecore_dev *p_dev, struct ecore_chain *p_chain)
 static enum _ecore_status_t
 ecore_chain_alloc_single(struct ecore_dev *p_dev, struct ecore_chain *p_chain)
 {
-	void *p_virt = OSAL_NULL;
 	dma_addr_t p_phys = 0;
+	void *p_virt = OSAL_NULL;
 
 	p_virt = OSAL_DMA_ALLOC_COHERENT(p_dev, &p_phys, ECORE_CHAIN_PAGE_SIZE);
 	if (!p_virt) {
@@ -3809,10 +3811,10 @@ enum _ecore_status_t ecore_set_rxq_coalesce(struct ecore_hwfn *p_hwfn,
 					    u16 coalesce, u8 qid, u16 sb_id)
 {
 	struct ustorm_eth_queue_zone eth_qzone;
+	u8 timeset, timer_res;
 	u16 fw_qid = 0;
 	u32 address;
 	enum _ecore_status_t rc;
-	u8 timeset, timer_res;
 
 	/* Coalesce = (timeset << timer-resolution), timeset is 7bit wide */
 	if (coalesce <= 0x7F) {
@@ -3852,10 +3854,10 @@ enum _ecore_status_t ecore_set_txq_coalesce(struct ecore_hwfn *p_hwfn,
 					    u16 coalesce, u8 qid, u16 sb_id)
 {
 	struct xstorm_eth_queue_zone eth_qzone;
+	u8 timeset, timer_res;
 	u16 fw_qid = 0;
 	u32 address;
 	enum _ecore_status_t rc;
-	u8 timeset, timer_res;
 
 	/* Coalesce = (timeset << timer-resolution), timeset is 7bit wide */
 	if (coalesce <= 0x7F) {
diff --git a/drivers/net/qede/base/ecore_hsi_common.h b/drivers/net/qede/base/ecore_hsi_common.h
index 6ddbe1a..d978bb0 100644
--- a/drivers/net/qede/base/ecore_hsi_common.h
+++ b/drivers/net/qede/base/ecore_hsi_common.h
@@ -1320,9 +1320,13 @@ enum personality_type {
  * tunnel configuration
  */
 struct pf_start_tunnel_config {
-/* Set VXLAN tunnel UDP destination port. */
+/* Set VXLAN tunnel UDP destination port to vxlan_udp_port. If not set -
+ * FW will use a default port
+ */
 	u8 set_vxlan_udp_port_flg;
-/* Set GENEVE tunnel UDP destination port. */
+/* Set GENEVE tunnel UDP destination port to geneve_udp_port. If not set -
+ * FW will use a default port
+ */
 	u8 set_geneve_udp_port_flg;
 	u8 tx_enable_vxlan /* If set, enable VXLAN tunnel in TX path. */;
 /* If set, enable l2 GENEVE tunnel in TX path. */
@@ -1338,8 +1342,10 @@ struct pf_start_tunnel_config {
 	u8 tunnel_clss_ipgeneve;
 	u8 tunnel_clss_l2gre /* Classification scheme for l2 GRE tunnel. */;
 	u8 tunnel_clss_ipgre /* Classification scheme for ip GRE tunnel. */;
-	__le16 vxlan_udp_port /* VXLAN tunnel UDP destination port. */;
-	__le16 geneve_udp_port /* GENEVE tunnel UDP destination port. */;
+/* VXLAN tunnel UDP destination port. Valid if set_vxlan_udp_port_flg=1 */
+	__le16 vxlan_udp_port;
+/* GENEVE tunnel UDP destination port. Valid if set_geneve_udp_port_flg=1 */
+	__le16 geneve_udp_port;
 };
 
 /*
diff --git a/drivers/net/qede/base/ecore_hw.c b/drivers/net/qede/base/ecore_hw.c
index 8abe60a..22da415 100644
--- a/drivers/net/qede/base/ecore_hw.c
+++ b/drivers/net/qede/base/ecore_hw.c
@@ -496,8 +496,8 @@ static u32 ecore_dmae_idx_to_go_cmd(u8 idx)
 	return DMAE_REG_GO_C0 + (idx << 2);
 }
 
-static enum _ecore_status_t
-ecore_dmae_post_command(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
+static enum _ecore_status_t ecore_dmae_post_command(struct ecore_hwfn *p_hwfn,
+						    struct ecore_ptt *p_ptt)
 {
 	struct dmae_cmd *p_command = p_hwfn->dmae_info.p_dmae_cmd;
 	u8 idx_cmd = p_hwfn->dmae_info.channel, i;
diff --git a/drivers/net/qede/base/ecore_init_ops.c b/drivers/net/qede/base/ecore_init_ops.c
index faeca68..a6ed590 100644
--- a/drivers/net/qede/base/ecore_init_ops.c
+++ b/drivers/net/qede/base/ecore_init_ops.c
@@ -63,8 +63,8 @@ static enum _ecore_status_t ecore_init_rt(struct ecore_hwfn *p_hwfn,
 {
 	u32 *p_init_val = &p_hwfn->rt_data.init_val[rt_offset];
 	bool *p_valid = &p_hwfn->rt_data.b_valid[rt_offset];
-	enum _ecore_status_t rc = ECORE_SUCCESS;
 	u16 i, segment;
+	enum _ecore_status_t rc = ECORE_SUCCESS;
 
 	/* Since not all RT entries are initialized, go over the RT and
 	 * for each segment of initialized values use DMA.
@@ -452,10 +452,10 @@ enum _ecore_status_t ecore_init_run(struct ecore_hwfn *p_hwfn,
 				    int phase, int phase_id, int modes)
 {
 	struct ecore_dev *p_dev = p_hwfn->p_dev;
-	enum _ecore_status_t rc = ECORE_SUCCESS;
 	u32 cmd_num, num_init_ops;
 	union init_op *init_ops;
 	bool b_dmae = false;
+	enum _ecore_status_t rc = ECORE_SUCCESS;
 
 	num_init_ops = p_dev->fw_data->init_ops_size;
 	init_ops = p_dev->fw_data->init_ops;
diff --git a/drivers/net/qede/base/ecore_int.c b/drivers/net/qede/base/ecore_int.c
index 6fb037d..96f283b 100644
--- a/drivers/net/qede/base/ecore_int.c
+++ b/drivers/net/qede/base/ecore_int.c
@@ -1234,7 +1234,7 @@ static enum _ecore_status_t ecore_int_sb_attn_alloc(struct ecore_hwfn *p_hwfn,
 	p_sb = OSAL_ALLOC(p_dev, GFP_KERNEL, sizeof(*p_sb));
 	if (!p_sb) {
 		DP_NOTICE(p_dev, true,
-			  "Failed to allocate `struct ecore_sb_attn_info'");
+			  "Failed to allocate `struct ecore_sb_attn_info'\n");
 		return ECORE_NOMEM;
 	}
 
@@ -1243,7 +1243,7 @@ static enum _ecore_status_t ecore_int_sb_attn_alloc(struct ecore_hwfn *p_hwfn,
 					 SB_ATTN_ALIGNED_SIZE(p_hwfn));
 	if (!p_virt) {
 		DP_NOTICE(p_dev, true,
-			  "Failed to allocate status block (attentions)");
+			  "Failed to allocate status block (attentions)\n");
 		OSAL_FREE(p_dev, p_sb);
 		return ECORE_NOMEM;
 	}
@@ -2127,8 +2127,8 @@ enum _ecore_status_t ecore_int_set_timer_res(struct ecore_hwfn *p_hwfn,
 					     struct ecore_ptt *p_ptt,
 					     u8 timer_res, u16 sb_id, bool tx)
 {
-	enum _ecore_status_t rc;
 	struct cau_sb_entry sb_entry;
+	enum _ecore_status_t rc;
 
 	if (!p_hwfn->hw_init_done) {
 		DP_ERR(p_hwfn, "hardware not initialized yet\n");
diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c
index e641a77..bb13828 100644
--- a/drivers/net/qede/base/ecore_mcp.c
+++ b/drivers/net/qede/base/ecore_mcp.c
@@ -945,9 +945,8 @@ static void ecore_mcp_send_protocol_stats(struct ecore_hwfn *p_hwfn,
 	ecore_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
 }
 
-static void
-ecore_read_pf_bandwidth(struct ecore_hwfn *p_hwfn,
-			struct public_func *p_shmem_info)
+static void ecore_read_pf_bandwidth(struct ecore_hwfn *p_hwfn,
+				    struct public_func *p_shmem_info)
 {
 	struct ecore_mcp_function_info *p_info;
 
diff --git a/drivers/net/qede/base/ecore_spq.c b/drivers/net/qede/base/ecore_spq.c
index e371492..9f5fdf8 100644
--- a/drivers/net/qede/base/ecore_spq.c
+++ b/drivers/net/qede/base/ecore_spq.c
@@ -380,8 +380,7 @@ struct ecore_eq *ecore_eq_alloc(struct ecore_hwfn *p_hwfn, u16 num_elem)
 	}
 
 	/* register EQ completion on the SP SB */
-	ecore_int_register_cb(p_hwfn,
-			      ecore_eq_completion,
+	ecore_int_register_cb(p_hwfn, ecore_eq_completion,
 			      p_eq, &p_eq->eq_sb_index, &p_eq->p_fw_cons);
 
 	return p_eq;
diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c
index e8f1ebe..4c1a078 100644
--- a/drivers/net/qede/base/ecore_sriov.c
+++ b/drivers/net/qede/base/ecore_sriov.c
@@ -1675,11 +1675,9 @@ ecore_iov_reconfigure_unicast_vlan(struct ecore_hwfn *p_hwfn,
 		DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
 			   "Reconfiguring VLAN [0x%04x] for VF [%04x]\n",
 			   filter.vlan, p_vf->relative_vf_id);
-		rc = ecore_sp_eth_filter_ucast(p_hwfn,
-					       p_vf->opaque_fid,
-					       &filter,
-					       ECORE_SPQ_MODE_CB,
-						       OSAL_NULL);
+		rc = ecore_sp_eth_filter_ucast(p_hwfn, p_vf->opaque_fid,
+					       &filter, ECORE_SPQ_MODE_CB,
+					       OSAL_NULL);
 		if (rc) {
 			DP_NOTICE(p_hwfn, true,
 				  "Failed to configure VLAN [%04x]"
diff --git a/drivers/net/qede/base/mcp_public.h b/drivers/net/qede/base/mcp_public.h
index b8a9ae3..81567d1 100644
--- a/drivers/net/qede/base/mcp_public.h
+++ b/drivers/net/qede/base/mcp_public.h
@@ -584,23 +584,20 @@ struct public_port {
 #define MCP_VALIDITY_ACTIVE_MFW_NONE            0x000001c0
 
 	u32 link_status;
-#define LINK_STATUS_LINK_UP					0x00000001
-#define LINK_STATUS_SPEED_AND_DUPLEX_MASK			0x0000001e
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD		(1 << 1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD		(2 << 1)
+#define LINK_STATUS_LINK_UP				0x00000001
+#define LINK_STATUS_SPEED_AND_DUPLEX_MASK		0x0000001e
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD			(1 << 1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD			(2 << 1)
 #define LINK_STATUS_SPEED_AND_DUPLEX_10G			(3 << 1)
 #define LINK_STATUS_SPEED_AND_DUPLEX_20G			(4 << 1)
 #define LINK_STATUS_SPEED_AND_DUPLEX_40G			(5 << 1)
 #define LINK_STATUS_SPEED_AND_DUPLEX_50G			(6 << 1)
 #define LINK_STATUS_SPEED_AND_DUPLEX_100G			(7 << 1)
 #define LINK_STATUS_SPEED_AND_DUPLEX_25G			(8 << 1)
-
-#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED			0x00000020
-
-#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE			0x00000040
-#define LINK_STATUS_PARALLEL_DETECTION_USED			0x00000080
-
-#define LINK_STATUS_PFC_ENABLED					0x00000100
+#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED		0x00000020
+#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE		0x00000040
+#define LINK_STATUS_PARALLEL_DETECTION_USED		0x00000080
+#define LINK_STATUS_PFC_ENABLED				0x00000100
 #define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE	0x00000200
 #define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE	0x00000400
 #define LINK_STATUS_LINK_PARTNER_10G_CAPABLE		0x00000800
@@ -609,22 +606,19 @@ struct public_port {
 #define LINK_STATUS_LINK_PARTNER_50G_CAPABLE		0x00004000
 #define LINK_STATUS_LINK_PARTNER_100G_CAPABLE		0x00008000
 #define LINK_STATUS_LINK_PARTNER_25G_CAPABLE		0x00010000
-
 #define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK	0x000C0000
-#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE	(0 << 18)
-#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE	(1 << 18)
-#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE	(2 << 18)
+#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE		(0 << 18)
+#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE		(1 << 18)
+#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE		(2 << 18)
 #define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE			(3 << 18)
-
-#define LINK_STATUS_SFP_TX_FAULT				0x00100000
-#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED			0x00200000
-#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED			0x00400000
-#define LINK_STATUS_RX_SIGNAL_PRESENT               0x00800000
-#define LINK_STATUS_MAC_LOCAL_FAULT                 0x01000000
-#define LINK_STATUS_MAC_REMOTE_FAULT                0x02000000
-#define LINK_STATUS_UNSUPPORTED_SPD_REQ				0x04000000
-
-#define LINK_STATUS_FEC_MODE_MASK				0x38000000
+#define LINK_STATUS_SFP_TX_FAULT			0x00100000
+#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED		0x00200000
+#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED		0x00400000
+#define LINK_STATUS_RX_SIGNAL_PRESENT			0x00800000
+#define LINK_STATUS_MAC_LOCAL_FAULT			0x01000000
+#define LINK_STATUS_MAC_REMOTE_FAULT			0x02000000
+#define LINK_STATUS_UNSUPPORTED_SPD_REQ			0x04000000
+#define LINK_STATUS_FEC_MODE_MASK			0x38000000
 #define LINK_STATUS_FEC_MODE_NONE				(0 << 27)
 #define LINK_STATUS_FEC_MODE_FIRECODE_CL74			(1 << 27)
 #define LINK_STATUS_FEC_MODE_RS_CL91				(2 << 27)
@@ -686,45 +680,47 @@ struct public_port {
 	u32 fc_npiv_nvram_tbl_addr;
 	u32 fc_npiv_nvram_tbl_size;
 	u32 transceiver_data;
-#define ETH_TRANSCEIVER_STATE_MASK		0x000000FF
-#define ETH_TRANSCEIVER_STATE_SHIFT		0x00000000
-#define ETH_TRANSCEIVER_STATE_UNPLUGGED		0x00000000
-#define ETH_TRANSCEIVER_STATE_PRESENT		0x00000001
-#define ETH_TRANSCEIVER_STATE_VALID		0x00000003
-#define ETH_TRANSCEIVER_STATE_UPDATING		0x00000008
-#define ETH_TRANSCEIVER_TYPE_MASK		0x0000FF00
-#define ETH_TRANSCEIVER_TYPE_SHIFT		0x00000008
-#define ETH_TRANSCEIVER_TYPE_NONE		0x00000000
-#define ETH_TRANSCEIVER_TYPE_UNKNOWN		0x000000FF
+#define ETH_TRANSCEIVER_STATE_MASK			0x000000FF
+#define ETH_TRANSCEIVER_STATE_SHIFT			0x00000000
+#define ETH_TRANSCEIVER_STATE_UNPLUGGED			0x00000000
+#define ETH_TRANSCEIVER_STATE_PRESENT			0x00000001
+#define ETH_TRANSCEIVER_STATE_VALID			0x00000003
+#define ETH_TRANSCEIVER_STATE_UPDATING			0x00000008
+#define ETH_TRANSCEIVER_TYPE_MASK			0x0000FF00
+#define ETH_TRANSCEIVER_TYPE_SHIFT			0x00000008
+#define ETH_TRANSCEIVER_TYPE_NONE			0x00000000
+#define ETH_TRANSCEIVER_TYPE_UNKNOWN			0x000000FF
 /* 1G Passive copper cable */
-#define ETH_TRANSCEIVER_TYPE_1G_PCC		0x01
+#define ETH_TRANSCEIVER_TYPE_1G_PCC			0x01
 /* 1G Active copper cable  */
-#define ETH_TRANSCEIVER_TYPE_1G_ACC		0x02
-#define ETH_TRANSCEIVER_TYPE_1G_LX		0x03
-#define ETH_TRANSCEIVER_TYPE_1G_SX		0x04
-#define ETH_TRANSCEIVER_TYPE_10G_SR		0x05
-#define ETH_TRANSCEIVER_TYPE_10G_LR		0x06
-#define ETH_TRANSCEIVER_TYPE_10G_LRM		0x07
-#define ETH_TRANSCEIVER_TYPE_10G_ER		0x08
+#define ETH_TRANSCEIVER_TYPE_1G_ACC			0x02
+#define ETH_TRANSCEIVER_TYPE_1G_LX			0x03
+#define ETH_TRANSCEIVER_TYPE_1G_SX			0x04
+#define ETH_TRANSCEIVER_TYPE_10G_SR			0x05
+#define ETH_TRANSCEIVER_TYPE_10G_LR			0x06
+#define ETH_TRANSCEIVER_TYPE_10G_LRM			0x07
+#define ETH_TRANSCEIVER_TYPE_10G_ER			0x08
 /* 10G Passive copper cable */
-#define ETH_TRANSCEIVER_TYPE_10G_PCC		0x09
+#define ETH_TRANSCEIVER_TYPE_10G_PCC			0x09
 /* 10G Active copper cable  */
-#define ETH_TRANSCEIVER_TYPE_10G_ACC		0x0a
-#define ETH_TRANSCEIVER_TYPE_XLPPI		0x0b
-#define ETH_TRANSCEIVER_TYPE_40G_LR4		0x0c
-#define ETH_TRANSCEIVER_TYPE_40G_SR4		0x0d
-#define ETH_TRANSCEIVER_TYPE_40G_CR4		0x0e
-#define ETH_TRANSCEIVER_TYPE_100G_AOC		0x0f /* Active optical cable */
-#define ETH_TRANSCEIVER_TYPE_100G_SR4		0x10
-#define ETH_TRANSCEIVER_TYPE_100G_LR4		0x11
-#define ETH_TRANSCEIVER_TYPE_100G_ER4		0x12
-#define ETH_TRANSCEIVER_TYPE_100G_ACC		0x13 /* Active copper cable */
-#define ETH_TRANSCEIVER_TYPE_100G_CR4		0x14
-#define ETH_TRANSCEIVER_TYPE_4x10G_SR		0x15
+#define ETH_TRANSCEIVER_TYPE_10G_ACC			0x0a
+#define ETH_TRANSCEIVER_TYPE_XLPPI			0x0b
+#define ETH_TRANSCEIVER_TYPE_40G_LR4			0x0c
+#define ETH_TRANSCEIVER_TYPE_40G_SR4			0x0d
+#define ETH_TRANSCEIVER_TYPE_40G_CR4			0x0e
+/* Active optical cable */
+#define ETH_TRANSCEIVER_TYPE_100G_AOC			0x0f
+#define ETH_TRANSCEIVER_TYPE_100G_SR4			0x10
+#define ETH_TRANSCEIVER_TYPE_100G_LR4			0x11
+#define ETH_TRANSCEIVER_TYPE_100G_ER4			0x12
+/* Active copper cable */
+#define ETH_TRANSCEIVER_TYPE_100G_ACC			0x13
+#define ETH_TRANSCEIVER_TYPE_100G_CR4			0x14
+#define ETH_TRANSCEIVER_TYPE_4x10G_SR			0x15
 /* 25G Passive copper cable - short */
-#define ETH_TRANSCEIVER_TYPE_25G_CA_N		0x16
+#define ETH_TRANSCEIVER_TYPE_25G_CA_N			0x16
 /* 25G Active copper cable  - short */
-#define ETH_TRANSCEIVER_TYPE_25G_ACC_S		0x17
+#define ETH_TRANSCEIVER_TYPE_25G_ACC_S			0x17
 /* 25G Passive copper cable - medium */
 #define ETH_TRANSCEIVER_TYPE_25G_CA_S			0x18
 /* 25G Active copper cable  - medium */
@@ -1153,6 +1149,23 @@ struct public_drv_mb {
  * MCP_REG_CPU_STATE/MCP_REG_CPU_MODE registers.
  */
 #define DRV_MSG_CODE_MCP_HALT			0x00100000
+/* Set virtual mac address, params [31:6] - reserved, [5:4] - type,
+ * [3:0] - func, drv_data[7:0] - MAC/WWNN/WWPN
+ */
+#define DRV_MSG_CODE_SET_VMAC                   0x00110000
+/* Set virtual mac address, params [31:6] - reserved, [5:4] - type,
+ * [3:0] - func, drv_data[7:0] - MAC/WWNN/WWPN
+ */
+#define DRV_MSG_CODE_GET_VMAC                   0x00120000
+	#define DRV_MSG_CODE_VMAC_TYPE_MAC              1
+	#define DRV_MSG_CODE_VMAC_TYPE_WWNN             2
+	#define DRV_MSG_CODE_VMAC_TYPE_WWPN             3
+/* Get statistics from pf, params [31:4] - reserved, [3:0] - stats type */
+#define DRV_MSG_CODE_GET_STATS                  0x00130000
+	#define DRV_MSG_CODE_STATS_TYPE_LAN             1
+	#define DRV_MSG_CODE_STATS_TYPE_FCOE            2
+	#define DRV_MSG_CODE_STATS_TYPE_ISCSI           3
+	#define DRV_MSG_CODE_STATS_TYPE_RDMA            4
 /* Host shall provide buffer and size for MFW  */
 #define DRV_MSG_CODE_PMD_DIAG_DUMP		0x00140000
 /* Host shall provide buffer and size for MFW  */
@@ -1165,29 +1178,8 @@ struct public_drv_mb {
  * [16:31] - offset
  */
 #define DRV_MSG_CODE_TRANSCEIVER_WRITE		0x00170000
-
-/* Set virtual mac address, params [31:6] - reserved, [5:4] - type,
- * [3:0] - func, drv_data[7:0] - MAC/WWNN/WWPN
- */
-#define DRV_MSG_CODE_SET_VMAC                   0x00110000
-/* Set virtual mac address, params [31:6] - reserved, [5:4] - type,
- * [3:0] - func, drv_data[7:0] - MAC/WWNN/WWPN
- */
-#define DRV_MSG_CODE_GET_VMAC                   0x00120000
-#define DRV_MSG_CODE_VMAC_TYPE_MAC              1
-#define DRV_MSG_CODE_VMAC_TYPE_WWNN             2
-#define DRV_MSG_CODE_VMAC_TYPE_WWPN             3
-
-/* Get statistics from pf, params [31:4] - reserved, [3:0] - stats type */
-#define DRV_MSG_CODE_GET_STATS                  0x00130000
-#define DRV_MSG_CODE_STATS_TYPE_LAN             1
-#define DRV_MSG_CODE_STATS_TYPE_FCOE            2
-#define DRV_MSG_CODE_STATS_TYPE_ISCSI           3
-#define DRV_MSG_CODE_STATS_TYPE_RDMA		4
-
 /* indicate OCBB related information */
 #define DRV_MSG_CODE_OCBB_DATA			0x00180000
-
 /* Set function BW, params[15:8] - min, params[7:0] - max */
 #define DRV_MSG_CODE_SET_BW			0x00190000
 #define BW_MAX_MASK				0x000000ff
@@ -1201,16 +1193,12 @@ struct public_drv_mb {
 #define DRV_MSG_CODE_MASK_PARITIES		0x001a0000
 /* param[0] - Simulate fan failure,  param[1] - simulate over temp. */
 #define DRV_MSG_CODE_INDUCE_FAILURE		0x001b0000
-#define DRV_MSG_FAN_FAILURE_TYPE		(1 << 0)
-#define DRV_MSG_TEMPERATURE_FAILURE_TYPE	(1 << 1)
-
+	#define DRV_MSG_FAN_FAILURE_TYPE		(1 << 0)
+	#define DRV_MSG_TEMPERATURE_FAILURE_TYPE	(1 << 1)
 /* Param: [0:15] - gpio number */
 #define DRV_MSG_CODE_GPIO_READ			0x001c0000
 /* Param: [0:15] - gpio number, [16:31] - gpio value */
 #define DRV_MSG_CODE_GPIO_WRITE			0x001d0000
-/* Param: [0:15] - gpio number */
-#define DRV_MSG_CODE_GPIO_INFO		    0x00270000
-
 /* Param: [0:7] - test enum, [8:15] - image index, [16:31] - reserved */
 #define DRV_MSG_CODE_BIST_TEST			0x001e0000
 #define DRV_MSG_CODE_GET_TEMPERATURE            0x001f0000
@@ -1227,55 +1215,53 @@ struct public_drv_mb {
  * param[15:8] - age
  */
 #define DRV_MSG_CODE_RESOURCE_CMD		0x00230000
-
-/* request resource ownership with default aging */
-#define RESOURCE_OPCODE_REQ			1
-/* request resource ownership without aging */
-#define RESOURCE_OPCODE_REQ_WO_AGING		2
-/* request resource ownership with specific aging timer (in seconds) */
-#define RESOURCE_OPCODE_REQ_W_AGING		3
-#define RESOURCE_OPCODE_RELEASE			4 /* release resource */
-#define RESOURCE_OPCODE_FORCE_RELEASE		5 /* force resource release */
-
-/* resource is free and granted to requester */
-#define RESOURCE_OPCODE_GNT			1
-/* resource is busy, param[7:0] indicates owner as follow 0-15 = PF0-15,
- * 16 = MFW, 17 = diag over serial
- */
-#define RESOURCE_OPCODE_BUSY			2
-/* indicate release request was acknowledged */
-#define RESOURCE_OPCODE_RELEASED		3
-/* indicate release request was previously received by other owner */
-#define RESOURCE_OPCODE_RELEASED_PREVIOUS	4
-/* indicate wrong owner during release */
-#define RESOURCE_OPCODE_WRONG_OWNER		5
-#define RESOURCE_OPCODE_UNKNOWN_CMD		255
-/* dedicate resource 0 for dump */
-#define RESOURCE_DUMP				(1 << 0)
-
+	/* request resource ownership with default aging */
+	#define RESOURCE_OPCODE_REQ			1
+	/* request resource ownership without aging */
+	#define RESOURCE_OPCODE_REQ_WO_AGING		2
+	/* request resource ownership with specific aging timer (in seconds) */
+	#define RESOURCE_OPCODE_REQ_W_AGING		3
+	#define RESOURCE_OPCODE_RELEASE			4 /* release resource */
+	/* force resource release */
+	#define RESOURCE_OPCODE_FORCE_RELEASE		5
+	/* resource is free and granted to requester */
+	#define RESOURCE_OPCODE_GNT			1
+	/* resource is busy, param[7:0] indicates owner as follow 0-15 = PF0-15,
+	 * 16 = MFW, 17 = diag over serial
+	 */
+	#define RESOURCE_OPCODE_BUSY			2
+	/* indicate release request was acknowledged */
+	#define RESOURCE_OPCODE_RELEASED		3
+	/* indicate release request was previously received by other owner */
+	#define RESOURCE_OPCODE_RELEASED_PREVIOUS	4
+	/* indicate wrong owner during release */
+	#define RESOURCE_OPCODE_WRONG_OWNER		5
+	#define RESOURCE_OPCODE_UNKNOWN_CMD		255
+	/* dedicate resource 0 for dump */
+	#define RESOURCE_DUMP				(1 << 0)
 #define DRV_MSG_CODE_GET_MBA_VERSION		0x00240000 /* Get MBA version */
-
 /* Send crash dump commands with param[3:0] - opcode */
 #define DRV_MSG_CODE_MDUMP_CMD			0x00250000
-#define MDUMP_DRV_PARAM_OPCODE_MASK		0x0000000f
-/* acknowledge reception of error indication */
-#define DRV_MSG_CODE_MDUMP_ACK			0x01
-/* set epoc and personality as follow: drv_data[3:0] - epoch,
- * drv_data[7:4] - personality
- */
-#define DRV_MSG_CODE_MDUMP_SET_VALUES		0x02
-/* trigger crash dump procedure */
-#define DRV_MSG_CODE_MDUMP_TRIGGER		0x03
-/* Request valid logs and config words */
-#define DRV_MSG_CODE_MDUMP_GET_CONFIG		0x04
-/* Set triggers mask. drv_mb_param should indicate (bitwise) which trigger
- * enabled
- */
-#define DRV_MSG_CODE_MDUMP_SET_ENABLE		0x05
-#define DRV_MSG_CODE_MDUMP_CLEAR_LOGS		0x06 /* Clear all logs */
-
-
+	#define MDUMP_DRV_PARAM_OPCODE_MASK		0x0000000f
+	/* acknowledge reception of error indication */
+	#define DRV_MSG_CODE_MDUMP_ACK			0x01
+	/* set epoc and personality as follow: drv_data[3:0] - epoch,
+	 * drv_data[7:4] - personality
+	 */
+	#define DRV_MSG_CODE_MDUMP_SET_VALUES		0x02
+	/* trigger crash dump procedure */
+	#define DRV_MSG_CODE_MDUMP_TRIGGER		0x03
+	/* Request valid logs and config words */
+	#define DRV_MSG_CODE_MDUMP_GET_CONFIG		0x04
+	/* Set triggers mask. drv_mb_param should indicate (bitwise) which
+	 * trigger enabled
+	 */
+	#define DRV_MSG_CODE_MDUMP_SET_ENABLE		0x05
+	/* Clear all logs */
+	#define DRV_MSG_CODE_MDUMP_CLEAR_LOGS		0x06
 #define DRV_MSG_CODE_MEM_ECC_EVENTS		0x00260000 /* Param: None */
+/* Param: [0:15] - gpio number */
+#define DRV_MSG_CODE_GPIO_INFO			0x00270000
 /* Value will be placed in union */
 #define DRV_MSG_CODE_EXT_PHY_READ		0x00280000
 /* Value should be placed in union */
@@ -1502,22 +1488,22 @@ struct public_drv_mb {
 #define FW_MSG_MODE_PHY_PRIVILEGE_ERROR		0x00150000
 #define FW_MSG_CODE_OK				0x00160000
 #define FW_MSG_CODE_LED_MODE_INVALID		0x00170000
-#define FW_MSG_CODE_PHY_DIAG_OK           0x00160000
-#define FW_MSG_CODE_PHY_DIAG_ERROR        0x00170000
+#define FW_MSG_CODE_PHY_DIAG_OK			0x00160000
+#define FW_MSG_CODE_PHY_DIAG_ERROR		0x00170000
 #define FW_MSG_CODE_INIT_HW_FAILED_TO_ALLOCATE_PAGE	0x00040000
 #define FW_MSG_CODE_INIT_HW_FAILED_BAD_STATE    0x00170000
 #define FW_MSG_CODE_INIT_HW_FAILED_TO_SET_WINDOW 0x000d0000
 #define FW_MSG_CODE_INIT_HW_FAILED_NO_IMAGE	0x000c0000
 #define FW_MSG_CODE_INIT_HW_FAILED_VERSION_MISMATCH	0x00100000
-#define FW_MSG_CODE_TRANSCEIVER_DIAG_OK           0x00160000
-#define FW_MSG_CODE_TRANSCEIVER_DIAG_ERROR        0x00170000
+#define FW_MSG_CODE_TRANSCEIVER_DIAG_OK			0x00160000
+#define FW_MSG_CODE_TRANSCEIVER_DIAG_ERROR		0x00170000
 #define FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT		0x00020000
-#define FW_MSG_CODE_TRANSCEIVER_BAD_BUFFER_SIZE	0x000f0000
-#define FW_MSG_CODE_GPIO_OK           0x00160000
-#define FW_MSG_CODE_GPIO_DIRECTION_ERR        0x00170000
+#define FW_MSG_CODE_TRANSCEIVER_BAD_BUFFER_SIZE		0x000f0000
+#define FW_MSG_CODE_GPIO_OK			0x00160000
+#define FW_MSG_CODE_GPIO_DIRECTION_ERR		0x00170000
 #define FW_MSG_CODE_GPIO_CTRL_ERR		0x00020000
 #define FW_MSG_CODE_GPIO_INVALID		0x000f0000
-#define FW_MSG_CODE_GPIO_INVALID_VALUE	0x00050000
+#define FW_MSG_CODE_GPIO_INVALID_VALUE		0x00050000
 #define FW_MSG_CODE_BIST_TEST_INVALID		0x000f0000
 #define FW_MSG_CODE_EXTPHY_INVALID_IMAGE_HEADER	0x00700000
 #define FW_MSG_CODE_EXTPHY_INVALID_PHY_TYPE	0x00710000
-- 
1.7.10.3

^ permalink raw reply related

* [PATCH v2 20/26] net/qede: add PCI ids for new chip variant
From: Rasesh Mody @ 2017-01-05  7:04 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: Rasesh Mody, dev, Dept-EngDPDKDev
In-Reply-To: <1480756289-11835-1-git-send-email-Rasesh.Mody@cavium.com>

Add PCI IDs for new asic type (defined as CHIP_NUM_AH_xxx).
It supports 50G, 40G, 25G and 10G speeds.

Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
---
 drivers/net/qede/base/ecore_dev.c |    7 +++++-
 drivers/net/qede/qede_ethdev.c    |   29 +++++++++++++++++------
 drivers/net/qede/qede_ethdev.h    |   47 +++++++++++++++++++++++--------------
 3 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index 5a29c45..03620d9 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -2365,7 +2365,12 @@ static enum _ecore_status_t ecore_hw_get_resc(struct ecore_hwfn *p_hwfn,
 #endif
 
 	for (res_id = 0; res_id < ECORE_MAX_RESC; res_id++) {
-		rc = ecore_hw_set_resc_info(p_hwfn, res_id, drv_resc_alloc);
+		/* @@@TMP for AH:
+		 * Force the driver's default resource allocation in case there
+		 * is a diff with the MFW allocation value.
+		 */
+		rc = ecore_hw_set_resc_info(p_hwfn, res_id,
+					    b_ah || drv_resc_alloc);
 		if (rc != ECORE_SUCCESS)
 			return rc;
 	}
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index d748d54..9ec240b 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -2264,10 +2264,13 @@ static int qedevf_eth_dev_uninit(struct rte_eth_dev *eth_dev)
 static struct rte_pci_id pci_id_qedevf_map[] = {
 #define QEDEVF_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev)
 	{
-		QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_NX2_VF)
+		QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_VF)
 	},
 	{
-		QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_57980S_IOV)
+		QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_IOV)
+	},
+	{
+		QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_IOV)
 	},
 	{.vendor_id = 0,}
 };
@@ -2275,19 +2278,31 @@ static struct rte_pci_id pci_id_qedevf_map[] = {
 static struct rte_pci_id pci_id_qede_map[] = {
 #define QEDE_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev)
 	{
-		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_NX2_57980E)
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980E)
+	},
+	{
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980S)
+	},
+	{
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_40)
+	},
+	{
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_25)
+	},
+	{
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_100)
 	},
 	{
-		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_NX2_57980S)
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_50G)
 	},
 	{
-		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_57980S_40)
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_10G)
 	},
 	{
-		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_57980S_25)
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_40G)
 	},
 	{
-		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_57980S_100)
+		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_25G)
 	},
 	{.vendor_id = 0,}
 };
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 95e06ef..19a4ece 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -92,24 +92,35 @@
 	struct ecore_dev *edev = &qdev->edev;			\
 }
 
-/************* QLogic 25G/40G/100G vendor/devices ids *************/
-#define PCI_VENDOR_ID_QLOGIC            0x1077
-
-#define CHIP_NUM_57980E                 0x1634
-#define CHIP_NUM_57980S                 0x1629
-#define CHIP_NUM_VF                     0x1630
-#define CHIP_NUM_57980S_40              0x1634
-#define CHIP_NUM_57980S_25              0x1656
-#define CHIP_NUM_57980S_IOV             0x1664
-#define CHIP_NUM_57980S_100             0x1644
-
-#define PCI_DEVICE_ID_NX2_57980E        CHIP_NUM_57980E
-#define PCI_DEVICE_ID_NX2_57980S        CHIP_NUM_57980S
-#define PCI_DEVICE_ID_NX2_VF            CHIP_NUM_VF
-#define PCI_DEVICE_ID_57980S_40         CHIP_NUM_57980S_40
-#define PCI_DEVICE_ID_57980S_25         CHIP_NUM_57980S_25
-#define PCI_DEVICE_ID_57980S_IOV        CHIP_NUM_57980S_IOV
-#define PCI_DEVICE_ID_57980S_100        CHIP_NUM_57980S_100
+/************* QLogic 10G/25G/40G/50G/100G vendor/devices ids *************/
+#define PCI_VENDOR_ID_QLOGIC                   0x1077
+
+#define CHIP_NUM_57980E                        0x1634
+#define CHIP_NUM_57980S                        0x1629
+#define CHIP_NUM_VF                            0x1630
+#define CHIP_NUM_57980S_40                     0x1634
+#define CHIP_NUM_57980S_25                     0x1656
+#define CHIP_NUM_57980S_IOV                    0x1664
+#define CHIP_NUM_57980S_100                    0x1644
+#define CHIP_NUM_AH_50G	                       0x8070
+#define CHIP_NUM_AH_10G                        0x8071
+#define CHIP_NUM_AH_40G			       0x8072
+#define CHIP_NUM_AH_25G			       0x8073
+#define CHIP_NUM_AH_IOV			       0x8090
+
+#define PCI_DEVICE_ID_QLOGIC_NX2_57980E        CHIP_NUM_57980E
+#define PCI_DEVICE_ID_QLOGIC_NX2_57980S        CHIP_NUM_57980S
+#define PCI_DEVICE_ID_QLOGIC_NX2_VF            CHIP_NUM_VF
+#define PCI_DEVICE_ID_QLOGIC_57980S_40         CHIP_NUM_57980S_40
+#define PCI_DEVICE_ID_QLOGIC_57980S_25         CHIP_NUM_57980S_25
+#define PCI_DEVICE_ID_QLOGIC_57980S_IOV        CHIP_NUM_57980S_IOV
+#define PCI_DEVICE_ID_QLOGIC_57980S_100        CHIP_NUM_57980S_100
+#define PCI_DEVICE_ID_QLOGIC_AH_50G            CHIP_NUM_AH_50G
+#define PCI_DEVICE_ID_QLOGIC_AH_10G            CHIP_NUM_AH_10G
+#define PCI_DEVICE_ID_QLOGIC_AH_40G            CHIP_NUM_AH_40G
+#define PCI_DEVICE_ID_QLOGIC_AH_25G            CHIP_NUM_AH_25G
+#define PCI_DEVICE_ID_QLOGIC_AH_IOV            CHIP_NUM_AH_IOV
+
 
 #define QEDE_VXLAN_DEF_PORT		8472
 
-- 
1.7.10.3

^ permalink raw reply related


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