aboutsummaryrefslogtreecommitdiffstats
path: root/dpdk
diff options
context:
space:
mode:
authorJohn Lo <loj@cisco.com>2016-03-29 16:14:35 -0400
committerJohn Lo <loj@cisco.com>2016-03-29 16:14:35 -0400
commit23650e6cada50246ba211cec168ddd6738a26f67 (patch)
tree0d3e05b84f1ded554d1bf70a60534092aaf63725 /dpdk
parent13f3c450ccd03ed00a6a114061faedd1fc553ddd (diff)
Update ENIC driver patches for DPDK 2.2.0
This includes all patches in ENIC driver which are up-streamed to DPDK to improve RX performance, fix buffer/error handling and interoperation with link bonding PMD library. Change-Id: Id4c71a350d5234834951f9261c69db5476ba396b Signed-off-by: John Lo <loj@cisco.com>
Diffstat (limited to 'dpdk')
-rw-r--r--dpdk/dpdk-2.2.0_patches/0011-Fix-link-bonding-PMD-slave-status-polling-path-used-.patch34
-rw-r--r--dpdk/dpdk-2.2.0_patches/0011-enic-improve-Rx-performance.patch (renamed from dpdk/dpdk-2.2.0_patches/0013-Replacement-of-ENIC-PMD-receive-path-to-improve-perf.patch)49
-rw-r--r--dpdk/dpdk-2.2.0_patches/0012-enic-fix-last-packet-not-being-sent.patch (renamed from dpdk/dpdk-2.2.0_patches/0012-Fix-ENIC-PMD-problem-with-not-sending-the-first-pack.patch)23
-rw-r--r--dpdk/dpdk-2.2.0_patches/0013-enic-add-missing-newline-to-print-statements.patch42
-rw-r--r--dpdk/dpdk-2.2.0_patches/0015-enic-fix-crash-when-allocating-too-many-queues.patch46
-rw-r--r--dpdk/dpdk-2.2.0_patches/0016-enic-fix-mbuf-flags-on-Rx.patch38
-rw-r--r--dpdk/dpdk-2.2.0_patches/0017-enic-fix-error-packets-handling.patch112
-rw-r--r--dpdk/dpdk-2.2.0_patches/0018-enic-remove-packet-error-conditional.patch53
-rw-r--r--dpdk/dpdk-2.2.0_patches/0019-enic-update-maintainers.patch36
-rw-r--r--dpdk/dpdk-2.2.0_patches/0020-enic-fix-Rx-descriptor-limit.patch61
-rw-r--r--dpdk/dpdk-2.2.0_patches/0021-enic-fix-TX-hang-when-number-of-packets-gt-queue-size.patch82
-rw-r--r--dpdk/dpdk-2.2.0_patches/0022-bonding-fix-bond-link-detect-in-non-interrupt-mode.patch71
12 files changed, 573 insertions, 74 deletions
diff --git a/dpdk/dpdk-2.2.0_patches/0011-Fix-link-bonding-PMD-slave-status-polling-path-used-.patch b/dpdk/dpdk-2.2.0_patches/0011-Fix-link-bonding-PMD-slave-status-polling-path-used-.patch
deleted file mode 100644
index 210ee458ba4..00000000000
--- a/dpdk/dpdk-2.2.0_patches/0011-Fix-link-bonding-PMD-slave-status-polling-path-used-.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 39272e0a1c227b1ab9360e6fbcbc497eaaed4cb0 Mon Sep 17 00:00:00 2001
-From: John Lo <loj@cisco.com>
-Date: Fri, 26 Feb 2016 12:45:55 -0500
-Subject: [PATCH 1/2] Fix link bonding PMD slave status polling path used by
- ENIC driver,
-
----
- drivers/net/bonding/rte_eth_bond_pmd.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
-index b1373c6..9efd73c 100644
---- a/drivers/net/bonding/rte_eth_bond_pmd.c
-+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
-@@ -1734,7 +1734,7 @@ bond_ethdev_slave_link_status_change_monitor(void *cb_arg)
-
- if (!bonded_ethdev->data->dev_started ||
- !internals->link_status_polling_enabled)
-- return;
-+ goto rearm_and_exit;
-
- /* If device is currently being configured then don't check slaves link
- * status, wait until next period */
-@@ -1768,6 +1768,7 @@ bond_ethdev_slave_link_status_change_monitor(void *cb_arg)
- rte_spinlock_unlock(&internals->lock);
- }
-
-+ rearm_and_exit:
- if (polling_slave_found)
- /* Set alarm to continue monitoring link status of slave ethdev's */
- rte_eal_alarm_set(internals->link_status_polling_interval_ms * 1000,
---
-1.9.1
-
diff --git a/dpdk/dpdk-2.2.0_patches/0013-Replacement-of-ENIC-PMD-receive-path-to-improve-perf.patch b/dpdk/dpdk-2.2.0_patches/0011-enic-improve-Rx-performance.patch
index 92bd1e89c7e..98824c57f9c 100644
--- a/dpdk/dpdk-2.2.0_patches/0013-Replacement-of-ENIC-PMD-receive-path-to-improve-perf.patch
+++ b/dpdk/dpdk-2.2.0_patches/0011-enic-improve-Rx-performance.patch
@@ -1,20 +1,20 @@
-From 0963caf48db910ca6f93c5cbff8d5d24b2be64dd Mon Sep 17 00:00:00 2001
-From: John Lo <loj@cisco.com>
-Date: Mon, 7 Mar 2016 14:12:29 -0500
-Subject: [PATCH 2/2] Replacement of ENIC PMD receive path to improve
- performance and code clarifty.
+commit 947d860c821f4248dcf2fc01e98671524973eeea
+Author: John Daley <johndale@cisco.com>
+Date: Fri Mar 4 13:09:00 2016 -0800
----
- drivers/net/enic/Makefile | 1 +
- drivers/net/enic/base/vnic_rq.c | 99 ++---------
- drivers/net/enic/base/vnic_rq.h | 147 +---------------
- drivers/net/enic/enic.h | 16 +-
- drivers/net/enic/enic_ethdev.c | 27 ++-
- drivers/net/enic/enic_main.c | 321 ++++++++++------------------------
- drivers/net/enic/enic_res.h | 16 +-
- drivers/net/enic/enic_rx.c | 378 ++++++++++++++++++++++++++++++++++++++++
- 8 files changed, 519 insertions(+), 486 deletions(-)
- create mode 100644 drivers/net/enic/enic_rx.c
+ enic: improve Rx performance
+
+ This is a wholesale replacement of the Enic PMD receive path in order
+ to improve performance and code clarity. The changes are:
+ - Simplify and reduce code path length of receive function.
+ - Put most of the fast-path receive functions in one file.
+ - Reduce the number of posted_index updates (pay attention to
+ rx_free_thresh)
+ - Remove the unneeded container structure around the RQ mbuf ring
+ - Prefetch next Mbuf and descriptors while processing the current one
+ - Use a lookup table for converting CQ flags to mbuf flags.
+
+ Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index f0ee093..f316274 100644
@@ -494,7 +494,7 @@ index 2a88043..6f2ada5 100644
ENICPMD_FUNC_TRACE();
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
-index 07a9810..d0c9bff 100644
+index f818c32..9fff020 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -60,6 +60,17 @@
@@ -960,10 +960,10 @@ index 49f7e22..33f2e84 100644
diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
new file mode 100644
-index 0000000..12b1f62
+index 0000000..945a60f
--- /dev/null
+++ b/drivers/net/enic/enic_rx.c
-@@ -0,0 +1,378 @@
+@@ -0,0 +1,370 @@
+/*
+ * Copyright 2008-2014 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2007 Nuova Systems, Inc. All rights reserved.
@@ -1127,20 +1127,12 @@ index 0000000..12b1f62
+
+ /* Check for packet error. Can't be more specific than MAC error */
+ if (enic_cq_rx_desc_packet_error(bwflags)) {
-+#ifdef RTE_NEXT_ABI
+ pkt_err_flags |= PKT_RX_MAC_ERR;
-+#else
-+ pkt_err_flags |= PKT_EXT_RX_PKT_ERROR;
-+#endif
+ }
+
+ /* Check for bad FCS. MAC error isn't quite, but no other choice */
+ if (!enic_cq_rx_desc_fcs_ok(cqrd)) {
-+#ifdef RTE_NEXT_ABI
+ pkt_err_flags |= PKT_RX_MAC_ERR;
-+#else
-+ pkt_err_flags |= PKT_EXT_RX_BAD_FCS;
-+#endif
+ }
+ return pkt_err_flags;
+}
@@ -1342,6 +1334,3 @@ index 0000000..12b1f62
+
+ return nb_rx;
+}
---
-1.9.1
-
diff --git a/dpdk/dpdk-2.2.0_patches/0012-Fix-ENIC-PMD-problem-with-not-sending-the-first-pack.patch b/dpdk/dpdk-2.2.0_patches/0012-enic-fix-last-packet-not-being-sent.patch
index 9730adc487e..181ca912f32 100644
--- a/dpdk/dpdk-2.2.0_patches/0012-Fix-ENIC-PMD-problem-with-not-sending-the-first-pack.patch
+++ b/dpdk/dpdk-2.2.0_patches/0012-enic-fix-last-packet-not-being-sent.patch
@@ -1,11 +1,17 @@
-From 70725980c4d8f1e01cfa352a95341893aab00e7e Mon Sep 17 00:00:00 2001
-From: John Lo <loj@cisco.com>
-Date: Mon, 7 Mar 2016 14:07:19 -0500
-Subject: [PATCH 1/2] Fix-ENIC-PMD-problem-with-not-sending-the-first-pack.
+commit aba31298526865f5db99eaa54b63eb39dc95b74f
+Author: John Daley <johndale@cisco.com>
+Date: Tue Mar 8 10:49:07 2016 -0800
----
- drivers/net/enic/base/enic_vnic_wq.h | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
+ enic: fix last packet not being sent
+
+ The last packet of the tx burst function array was not being
+ emitted until the subsequent call. The nic descriptor index
+ was being set to the current tx descriptor instead of one past
+ the descriptor as required by the nic.
+
+ Fixes: d739ba4c6abf ("enic: improve Tx packet rate")
+
+ Signed-off-by: John Daley <johndale@cisco.com>
diff --git a/drivers/net/enic/base/enic_vnic_wq.h b/drivers/net/enic/base/enic_vnic_wq.h
index e3ea574..b019109 100644
@@ -26,6 +32,3 @@ index e3ea574..b019109 100644
}
#endif /* _ENIC_VNIC_WQ_H_ */
---
-1.9.1
-
diff --git a/dpdk/dpdk-2.2.0_patches/0013-enic-add-missing-newline-to-print-statements.patch b/dpdk/dpdk-2.2.0_patches/0013-enic-add-missing-newline-to-print-statements.patch
new file mode 100644
index 00000000000..e95327d2268
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0013-enic-add-missing-newline-to-print-statements.patch
@@ -0,0 +1,42 @@
+commit bba57df3861c644e98c5e8f79e62f6ca5074cb40
+Author: Nelson Escobar <neescoba@cisco.com>
+Date: Thu Mar 17 15:48:13 2016 -0700
+
+ enic: add missing newline to print statements
+
+ Add the missing '\n' character to the end of a few print statements.
+
+ Fixes: fefed3d1e62c ("enic: new driver")
+
+ Signed-off-by: Nelson Escobar <neescoba@cisco.com>
+ Acked-by: John Daley <johndale@cisco.com>
+
+diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
+index 9fff020..e30672c 100644
+--- a/drivers/net/enic/enic_main.c
++++ b/drivers/net/enic/enic_main.c
+@@ -342,13 +342,13 @@ enic_alloc_rx_queue_mbufs(struct enic *enic, struct vnic_rq *rq)
+ unsigned i;
+ dma_addr_t dma_addr;
+
+- dev_debug(enic, "queue %u, allocating %u rx queue mbufs", rq->index,
++ dev_debug(enic, "queue %u, allocating %u rx queue mbufs\n", rq->index,
+ rq->ring.desc_count);
+
+ for (i = 0; i < rq->ring.desc_count; i++, rqd++) {
+ mb = rte_rxmbuf_alloc(rq->mp);
+ if (mb == NULL) {
+- dev_err(enic, "RX mbuf alloc failed queue_id=%u",
++ dev_err(enic, "RX mbuf alloc failed queue_id=%u\n",
+ (unsigned)rq->index);
+ return -ENOMEM;
+ }
+@@ -388,7 +388,7 @@ enic_alloc_consistent(__rte_unused void *priv, size_t size,
+ rz = rte_memzone_reserve_aligned((const char *)name,
+ size, SOCKET_ID_ANY, 0, ENIC_ALIGN);
+ if (!rz) {
+- pr_err("%s : Failed to allocate memory requested for %s",
++ pr_err("%s : Failed to allocate memory requested for %s\n",
+ __func__, name);
+ return NULL;
+ }
diff --git a/dpdk/dpdk-2.2.0_patches/0015-enic-fix-crash-when-allocating-too-many-queues.patch b/dpdk/dpdk-2.2.0_patches/0015-enic-fix-crash-when-allocating-too-many-queues.patch
new file mode 100644
index 00000000000..f8e661fc831
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0015-enic-fix-crash-when-allocating-too-many-queues.patch
@@ -0,0 +1,46 @@
+commit ddf2da3ecec97a316838f40fe13e217afafc6252
+Author: Nelson Escobar <neescoba@cisco.com>
+Date: Thu Mar 17 15:49:58 2016 -0700
+
+ enic: fix crash when allocating too many queues
+
+ Add checks to make sure we don't try to allocate more tx or rx queues
+ than we support.
+
+ Fixes: fefed3d1e62c ("enic: new driver")
+
+ Signed-off-by: Nelson Escobar <neescoba@cisco.com>
+ Reviewed-by: John Daley <johndale@cisco.com>
+
+diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
+index bab0f7d..4969476 100644
+--- a/drivers/net/enic/enic_ethdev.c
++++ b/drivers/net/enic/enic_ethdev.c
+@@ -174,6 +174,13 @@ static int enicpmd_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
+ struct enic *enic = pmd_priv(eth_dev);
+
+ ENICPMD_FUNC_TRACE();
++ if (queue_idx >= ENIC_WQ_MAX) {
++ dev_err(enic,
++ "Max number of TX queues exceeded. Max is %d\n",
++ ENIC_WQ_MAX);
++ return -EINVAL;
++ }
++
+ eth_dev->data->tx_queues[queue_idx] = (void *)&enic->wq[queue_idx];
+
+ ret = enic_alloc_wq(enic, queue_idx, socket_id, nb_desc);
+@@ -262,6 +269,13 @@ static int enicpmd_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
+ struct enic *enic = pmd_priv(eth_dev);
+
+ ENICPMD_FUNC_TRACE();
++ if (queue_idx >= ENIC_RQ_MAX) {
++ dev_err(enic,
++ "Max number of RX queues exceeded. Max is %d\n",
++ ENIC_RQ_MAX);
++ return -EINVAL;
++ }
++
+ eth_dev->data->rx_queues[queue_idx] = (void *)&enic->rq[queue_idx];
+
+ ret = enic_alloc_rq(enic, queue_idx, socket_id, mp, nb_desc);
diff --git a/dpdk/dpdk-2.2.0_patches/0016-enic-fix-mbuf-flags-on-Rx.patch b/dpdk/dpdk-2.2.0_patches/0016-enic-fix-mbuf-flags-on-Rx.patch
new file mode 100644
index 00000000000..e8f74db5bf6
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0016-enic-fix-mbuf-flags-on-Rx.patch
@@ -0,0 +1,38 @@
+commit 3253bbc79c8a1eddf791d9ec11bcea4a004d258e
+Author: John Daley <johndale@cisco.com>
+Date: Thu Mar 17 15:57:05 2016 -0700
+
+ enic: fix mbuf flags on Rx
+
+ In the receive path, the function to set mbuf ol_flags used the
+ mbuf packet_type before it was set.
+
+ Fixes: 947d860c821f ("enic: improve Rx performance")
+
+ Signed-off-by: John Daley <johndale@cisco.com>
+
+diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
+index 945a60f..59ebaa4 100644
+--- a/drivers/net/enic/enic_rx.c
++++ b/drivers/net/enic/enic_rx.c
+@@ -210,7 +210,7 @@ enic_cq_rx_to_pkt_flags(struct cq_desc *cqd, struct rte_mbuf *mbuf)
+ ciflags = enic_cq_rx_desc_ciflags(cqrd);
+ bwflags = enic_cq_rx_desc_bwflags(cqrd);
+
+- ASSERT(mbuf->ol_flags == 0);
++ mbuf->ol_flags = 0;
+
+ /* flags are meaningless if !EOP */
+ if (unlikely(!enic_cq_rx_desc_eop(ciflags)))
+@@ -340,10 +340,10 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ rxmb->pkt_len = rx_pkt_len;
+ rxmb->data_len = rx_pkt_len;
+ rxmb->port = enic->port_id;
++ rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
+ rxmb->ol_flags = ol_err_flags;
+ if (!ol_err_flags)
+ enic_cq_rx_to_pkt_flags(&cqd, rxmb);
+- rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
+
+ /* prefetch mbuf data for caller */
+ rte_packet_prefetch(RTE_PTR_ADD(rxmb->buf_addr,
diff --git a/dpdk/dpdk-2.2.0_patches/0017-enic-fix-error-packets-handling.patch b/dpdk/dpdk-2.2.0_patches/0017-enic-fix-error-packets-handling.patch
new file mode 100644
index 00000000000..058d5eb4cc5
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0017-enic-fix-error-packets-handling.patch
@@ -0,0 +1,112 @@
+commit 5776c30293bbbdb3e332c868fbccf99b2026fba0
+Author: John Daley <johndale@cisco.com>
+Date: Thu Mar 17 15:57:06 2016 -0700
+
+ enic: fix error packets handling
+
+ If the packet_error bit in the completion descriptor is set, the
+ remainder of the descriptor and data are invalid. PKT_RX_MAC_ERR
+ was set in the mbuf->ol_flags if packet_error was set and used
+ later to indicate an error packet. But since PKT_RX_MAC_ERR is
+ defined as 0, mbuf flags and packet types and length were being
+ misinterpreted.
+
+ Make the function enic_cq_rx_to_pkt_err_flags() return true for error
+ packets and use the return value instead of mbuf->ol_flags to indicate
+ error packets. Also remove warning for error packets and rely on
+ rx_error stats.
+
+ Fixes: 947d860c821f ("enic: improve Rx performance")
+
+ Signed-off-by: John Daley <johndale@cisco.com>
+
+diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
+index 59ebaa4..817a891 100644
+--- a/drivers/net/enic/enic_rx.c
++++ b/drivers/net/enic/enic_rx.c
+@@ -129,13 +129,6 @@ enic_cq_rx_desc_rss_hash(struct cq_enet_rq_desc *cqrd)
+ return le32_to_cpu(cqrd->rss_hash);
+ }
+
+-static inline uint8_t
+-enic_cq_rx_desc_fcs_ok(struct cq_enet_rq_desc *cqrd)
+-{
+- return ((cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_FCS_OK) ==
+- CQ_ENET_RQ_DESC_FLAGS_FCS_OK);
+-}
+-
+ static inline uint16_t
+ enic_cq_rx_desc_vlan(struct cq_enet_rq_desc *cqrd)
+ {
+@@ -150,25 +143,21 @@ enic_cq_rx_desc_n_bytes(struct cq_desc *cqd)
+ CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
+ }
+
+-static inline uint64_t
+-enic_cq_rx_to_pkt_err_flags(struct cq_desc *cqd)
++static inline uint8_t
++enic_cq_rx_to_pkt_err_flags(struct cq_desc *cqd, uint64_t *pkt_err_flags_out)
+ {
+ struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
+ uint16_t bwflags;
++ int ret = 0;
+ uint64_t pkt_err_flags = 0;
+
+ bwflags = enic_cq_rx_desc_bwflags(cqrd);
+-
+- /* Check for packet error. Can't be more specific than MAC error */
+- if (enic_cq_rx_desc_packet_error(bwflags)) {
+- pkt_err_flags |= PKT_RX_MAC_ERR;
+- }
+-
+- /* Check for bad FCS. MAC error isn't quite, but no other choice */
+- if (!enic_cq_rx_desc_fcs_ok(cqrd)) {
+- pkt_err_flags |= PKT_RX_MAC_ERR;
++ if (unlikely(enic_cq_rx_desc_packet_error(bwflags))) {
++ pkt_err_flags = PKT_RX_MAC_ERR;
++ ret = 1;
+ }
+- return pkt_err_flags;
++ *pkt_err_flags_out = pkt_err_flags;
++ return ret;
+ }
+
+ /*
+@@ -282,6 +271,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ dma_addr_t dma_addr;
+ struct cq_desc cqd;
+ uint64_t ol_err_flags;
++ uint8_t packet_error;
+
+ /* Check for pkts available */
+ color = (cqd_ptr->type_color >> CQ_DESC_COLOR_SHIFT)
+@@ -303,9 +293,9 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ break;
+ }
+
+- /* Check for FCS or packet errors */
+- ol_err_flags = enic_cq_rx_to_pkt_err_flags(&cqd);
+- if (ol_err_flags == 0)
++ /* A packet error means descriptor and data are untrusted */
++ packet_error = enic_cq_rx_to_pkt_err_flags(&cqd, &ol_err_flags);
++ if (!packet_error)
+ rx_pkt_len = enic_cq_rx_desc_n_bytes(&cqd);
+ else
+ rx_pkt_len = 0;
+@@ -340,10 +330,13 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ rxmb->pkt_len = rx_pkt_len;
+ rxmb->data_len = rx_pkt_len;
+ rxmb->port = enic->port_id;
+- rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
+- rxmb->ol_flags = ol_err_flags;
+- if (!ol_err_flags)
++ if (!packet_error) {
++ rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
+ enic_cq_rx_to_pkt_flags(&cqd, rxmb);
++ } else {
++ rxmb->packet_type = 0;
++ rxmb->ol_flags = 0;
++ }
+
+ /* prefetch mbuf data for caller */
+ rte_packet_prefetch(RTE_PTR_ADD(rxmb->buf_addr,
diff --git a/dpdk/dpdk-2.2.0_patches/0018-enic-remove-packet-error-conditional.patch b/dpdk/dpdk-2.2.0_patches/0018-enic-remove-packet-error-conditional.patch
new file mode 100644
index 00000000000..d3084c84c9e
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0018-enic-remove-packet-error-conditional.patch
@@ -0,0 +1,53 @@
+commit 50765c820e98a4434efbc0a58df4b9d78afb7a5f
+Author: John Daley <johndale@cisco.com>
+Date: Thu Mar 17 15:57:07 2016 -0700
+
+ enic: remove packet error conditional
+
+ small cleanup to remove conditional.
+
+ Signed-off-by: John Daley <johndale@cisco.com>
+
+diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
+index 817a891..232987a 100644
+--- a/drivers/net/enic/enic_rx.c
++++ b/drivers/net/enic/enic_rx.c
+@@ -266,7 +266,6 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ nb_hold = rq->rx_nb_hold; /* mbufs held by software */
+
+ while (nb_rx < nb_pkts) {
+- uint16_t rx_pkt_len;
+ volatile struct rq_enet_desc *rqd_ptr;
+ dma_addr_t dma_addr;
+ struct cq_desc cqd;
+@@ -295,10 +294,6 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+
+ /* A packet error means descriptor and data are untrusted */
+ packet_error = enic_cq_rx_to_pkt_err_flags(&cqd, &ol_err_flags);
+- if (!packet_error)
+- rx_pkt_len = enic_cq_rx_desc_n_bytes(&cqd);
+- else
+- rx_pkt_len = 0;
+
+ /* Get the mbuf to return and replace with one just allocated */
+ rxmb = rq->mbuf_ring[rx_id];
+@@ -327,16 +322,17 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ rxmb->data_off = RTE_PKTMBUF_HEADROOM;
+ rxmb->nb_segs = 1;
+ rxmb->next = NULL;
+- rxmb->pkt_len = rx_pkt_len;
+- rxmb->data_len = rx_pkt_len;
+ rxmb->port = enic->port_id;
+ if (!packet_error) {
++ rxmb->pkt_len = enic_cq_rx_desc_n_bytes(&cqd);
+ rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
+ enic_cq_rx_to_pkt_flags(&cqd, rxmb);
+ } else {
++ rxmb->pkt_len = 0;
+ rxmb->packet_type = 0;
+ rxmb->ol_flags = 0;
+ }
++ rxmb->data_len = rxmb->pkt_len;
+
+ /* prefetch mbuf data for caller */
+ rte_packet_prefetch(RTE_PTR_ADD(rxmb->buf_addr,
diff --git a/dpdk/dpdk-2.2.0_patches/0019-enic-update-maintainers.patch b/dpdk/dpdk-2.2.0_patches/0019-enic-update-maintainers.patch
new file mode 100644
index 00000000000..8beae3b2944
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0019-enic-update-maintainers.patch
@@ -0,0 +1,36 @@
+commit 57524648749fb7dc1daf3af3213dab472ee432de
+Author: John Daley <johndale@cisco.com>
+Date: Fri Mar 18 11:27:07 2016 -0700
+
+ enic: update maintainers
+
+ Change maintainers for ENIC PMD and fix pointer to enic
+ documentation in MAINTAINERS.
+
+ Signed-off-by: John Daley <johndale@cisco.com>
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 6ed54dd..e848ffa 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -276,8 +276,9 @@ F: doc/guides/nics/cxgbe.rst
+
+ Cisco enic
+ M: John Daley <johndale@cisco.com>
+-M: Sujith Sankar <ssujith@cisco.com>
++M: Nelson Escobar <neescoba@cisco.com>
+ F: drivers/net/enic/
++F: doc/guides/nics/enic.rst
+
+ Combo szedata2
+ M: Matej Vido <matejvido@gmail.com>
+diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
+index 2a228fd..e67c3db 100644
+--- a/doc/guides/nics/enic.rst
++++ b/doc/guides/nics/enic.rst
+@@ -218,4 +218,4 @@ Any questions or bugs should be reported to DPDK community and to the ENIC PMD
+ maintainers:
+
+ - John Daley <johndale@cisco.com>
+-- Sujith Sankar <ssujith@cisco.com>
++- Nelson Escobar <neescoba@cisco.com>
diff --git a/dpdk/dpdk-2.2.0_patches/0020-enic-fix-Rx-descriptor-limit.patch b/dpdk/dpdk-2.2.0_patches/0020-enic-fix-Rx-descriptor-limit.patch
new file mode 100644
index 00000000000..f2fb1245482
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0020-enic-fix-Rx-descriptor-limit.patch
@@ -0,0 +1,61 @@
+commit 65ca78fdf9a684743bfca278cf1fcfea4603931d
+Author: Nelson Escobar <neescoba@cisco.com>
+Date: Fri Mar 18 11:33:34 2016 -0700
+
+ enic: fix Rx descriptor limit
+
+ On initialization, the rq descriptor count was set to the limit
+ of the vic. When the requested number of rx descriptors was
+ less than this count, enic_alloc_rq() was incorrectly setting
+ the count to the lower value. This results in later calls to
+ enic_alloc_rq() incorrectly using the lower value as the adapter
+ limit.
+
+ Fixes: fefed3d1e62c ("enic: new driver")
+
+ Signed-off-by: Nelson Escobar <neescoba@cisco.com>
+ Reviewed-by: John Daley <johndale@cisco.com>
+
+diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
+index e30672c..2f79cf0 100644
+--- a/drivers/net/enic/enic_main.c
++++ b/drivers/net/enic/enic_main.c
+@@ -524,24 +524,22 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
+ "policy. Applying the value in the adapter "\
+ "policy (%d).\n",
+ queue_idx, nb_desc, enic->config.rq_desc_count);
+- } else if (nb_desc != enic->config.rq_desc_count) {
+- enic->config.rq_desc_count = nb_desc;
+- dev_info(enic,
+- "RX Queues - effective number of descs:%d\n",
+- nb_desc);
++ nb_desc = enic->config.rq_desc_count;
+ }
++ dev_info(enic, "RX Queues - effective number of descs:%d\n",
++ nb_desc);
+ }
+
+ /* Allocate queue resources */
+ rc = vnic_rq_alloc(enic->vdev, rq, queue_idx,
+- enic->config.rq_desc_count, sizeof(struct rq_enet_desc));
++ nb_desc, sizeof(struct rq_enet_desc));
+ if (rc) {
+ dev_err(enic, "error in allocation of rq\n");
+ goto err_exit;
+ }
+
+ rc = vnic_cq_alloc(enic->vdev, &enic->cq[queue_idx], queue_idx,
+- socket_id, enic->config.rq_desc_count,
++ socket_id, nb_desc,
+ sizeof(struct cq_enet_rq_desc));
+ if (rc) {
+ dev_err(enic, "error in allocation of cq for rq\n");
+@@ -550,7 +548,7 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
+
+ /* Allocate the mbuf ring */
+ rq->mbuf_ring = (struct rte_mbuf **)rte_zmalloc_socket("rq->mbuf_ring",
+- sizeof(struct rte_mbuf *) * enic->config.rq_desc_count,
++ sizeof(struct rte_mbuf *) * nb_desc,
+ RTE_CACHE_LINE_SIZE, rq->socket_id);
+
+ if (rq->mbuf_ring != NULL)
diff --git a/dpdk/dpdk-2.2.0_patches/0021-enic-fix-TX-hang-when-number-of-packets-gt-queue-size.patch b/dpdk/dpdk-2.2.0_patches/0021-enic-fix-TX-hang-when-number-of-packets-gt-queue-size.patch
new file mode 100644
index 00000000000..11e54e13fe4
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0021-enic-fix-TX-hang-when-number-of-packets-gt-queue-size.patch
@@ -0,0 +1,82 @@
+commit 67c4432ec364ce21f5059ba0696a9d0f3393356c
+Author: John Daley <johndale@cisco.com>
+Date: Thu Mar 24 14:00:39 2016 -0700
+
+ enic: fix TX hang when number of packets > queue size
+
+ If the nb_pkts parameter to rte_eth_tx_burst() was greater than
+ the TX descriptor count, a completion was not being requested
+ from the NIC, so descriptors would not be released back to the
+ host causing a lock-up.
+
+ Introduce a limit of how many TX descriptors can be used in a single
+ call to the enic PMD burst TX function before requesting a completion.
+
+ Fixes: d739ba4c6abf ("enic: improve Tx packet rate")
+
+ Signed-off-by: John Daley <johndale@cisco.com>
+
+diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
+index 4969476..6bea940 100644
+--- a/drivers/net/enic/enic_ethdev.c
++++ b/drivers/net/enic/enic_ethdev.c
+@@ -523,7 +523,7 @@ static void enicpmd_remove_mac_addr(struct rte_eth_dev *eth_dev, __rte_unused ui
+ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+ {
+- unsigned int index;
++ uint16_t index;
+ unsigned int frags;
+ unsigned int pkt_len;
+ unsigned int seg_len;
+@@ -535,6 +535,7 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ unsigned short vlan_id;
+ unsigned short ol_flags;
+ uint8_t last_seg, eop;
++ unsigned int host_tx_descs = 0;
+
+ for (index = 0; index < nb_pkts; index++) {
+ tx_pkt = *tx_pkts++;
+@@ -550,6 +551,7 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ return index;
+ }
+ }
++
+ pkt_len = tx_pkt->pkt_len;
+ vlan_id = tx_pkt->vlan_tci;
+ ol_flags = tx_pkt->ol_flags;
+@@ -559,9 +561,19 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ next_tx_pkt = tx_pkt->next;
+ seg_len = tx_pkt->data_len;
+ inc_len += seg_len;
+- eop = (pkt_len == inc_len) || (!next_tx_pkt);
+- last_seg = eop &&
+- (index == ((unsigned int)nb_pkts - 1));
++
++ host_tx_descs++;
++ last_seg = 0;
++ eop = 0;
++ if ((pkt_len == inc_len) || !next_tx_pkt) {
++ eop = 1;
++ /* post if last packet in batch or > thresh */
++ if ((index == (nb_pkts - 1)) ||
++ (host_tx_descs > ENIC_TX_POST_THRESH)) {
++ last_seg = 1;
++ host_tx_descs = 0;
++ }
++ }
+ enic_send_pkt(enic, wq, tx_pkt, (unsigned short)seg_len,
+ !frags, eop, last_seg, ol_flags, vlan_id);
+ tx_pkt = next_tx_pkt;
+diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
+index 33f2e84..00fa71d 100644
+--- a/drivers/net/enic/enic_res.h
++++ b/drivers/net/enic/enic_res.h
+@@ -53,6 +53,7 @@
+
+ #define ENIC_NON_TSO_MAX_DESC 16
+ #define ENIC_DEFAULT_RX_FREE_THRESH 32
++#define ENIC_TX_POST_THRESH (ENIC_MIN_WQ_DESCS / 2)
+
+ #define ENIC_SETTING(enic, f) ((enic->config.flags & VENETF_##f) ? 1 : 0)
+
diff --git a/dpdk/dpdk-2.2.0_patches/0022-bonding-fix-bond-link-detect-in-non-interrupt-mode.patch b/dpdk/dpdk-2.2.0_patches/0022-bonding-fix-bond-link-detect-in-non-interrupt-mode.patch
new file mode 100644
index 00000000000..9cb56d2d499
--- /dev/null
+++ b/dpdk/dpdk-2.2.0_patches/0022-bonding-fix-bond-link-detect-in-non-interrupt-mode.patch
@@ -0,0 +1,71 @@
+commit 65bcf215aae2e0b9935557e237af054ad0860bad
+Author: Nelson Escobar <neescoba@cisco.com>
+Date: Tue Mar 22 13:42:08 2016 -0700
+
+ bonding: fix bond link detect in non-interrupt mode
+
+ Stopping then re-starting a bond interface containing slaves that
+ used polling for link detection caused the bond to think all slave
+ links were down and inactive.
+
+ Move the start of the polling for link from slave_add() to
+ bond_ethdev_start() and in bond_ethdev_stop() make sure we clear
+ the last_link_status of the slaves.
+
+ Signed-off-by: Nelson Escobar <neescoba@cisco.com>
+ Signed-off-by: John Daley <johndale@cisco.com>
+
+diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
+index fb26d35..f0960c6 100644
+--- a/drivers/net/bonding/rte_eth_bond_pmd.c
++++ b/drivers/net/bonding/rte_eth_bond_pmd.c
+@@ -1454,18 +1454,11 @@ slave_add(struct bond_dev_private *internals,
+ slave_details->port_id = slave_eth_dev->data->port_id;
+ slave_details->last_link_status = 0;
+
+- /* If slave device doesn't support interrupts then we need to enabled
+- * polling to monitor link status */
++ /* Mark slave devices that don't support interrupts so we can
++ * compensate when we start the bond
++ */
+ if (!(slave_eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)) {
+ slave_details->link_status_poll_enabled = 1;
+-
+- if (!internals->link_status_polling_enabled) {
+- internals->link_status_polling_enabled = 1;
+-
+- rte_eal_alarm_set(internals->link_status_polling_interval_ms * 1000,
+- bond_ethdev_slave_link_status_change_monitor,
+- (void *)&rte_eth_devices[internals->port_id]);
+- }
+ }
+
+ slave_details->link_status_wait_to_complete = 0;
+@@ -1550,6 +1543,18 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
+ eth_dev->data->port_id, internals->slaves[i].port_id);
+ return -1;
+ }
++ /* We will need to poll for link status if any slave doesn't
++ * support interrupts
++ */
++ if (internals->slaves[i].link_status_poll_enabled)
++ internals->link_status_polling_enabled = 1;
++ }
++ /* start polling if needed */
++ if (internals->link_status_polling_enabled) {
++ rte_eal_alarm_set(
++ internals->link_status_polling_interval_ms * 1000,
++ bond_ethdev_slave_link_status_change_monitor,
++ (void *)&rte_eth_devices[internals->port_id]);
+ }
+
+ if (internals->user_defined_primary_port)
+@@ -1622,6 +1627,8 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
+
+ internals->active_slave_count = 0;
+ internals->link_status_polling_enabled = 0;
++ for (i = 0; i < internals->slave_count; i++)
++ internals->slaves[i].last_link_status = 0;
+
+ eth_dev->data->dev_link.link_status = 0;
+ eth_dev->data->dev_started = 0;