Re: [PATCH] net/enic: avoid extra unlock when setting MTU in enic

2023-11-01 Thread John Daley (johndale)
Reviewed-by: John Daley 

Thanks,
John

From: Weiguo Li 
Date: Wednesday, November 1, 2023 at 12:28 AM
To: John Daley (johndale) 
Cc: dev@dpdk.org , sta...@dpdk.org , Weiguo Li 

Subject: [PATCH] net/enic: avoid extra unlock when setting MTU in enic
The 'set_mtu_done' goto statement is being executed in a context
where the 'mtu_lock' has not been previously locked.

To avoid the extra unlocking operation, replace the goto statement
with a return statement.

Fixes: c3e09182bcd6 ("net/enic: support scatter Rx in MTU update")
Cc: sta...@dpdk.org

Signed-off-by: Weiguo Li 
---
 .mailmap | 2 +-
 drivers/net/enic/enic_main.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.mailmap b/.mailmap
index 3f5bab26a8..b4f0ae26b8 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1500,7 +1500,7 @@ Waterman Cao 
 Weichun Chen 
 Wei Dai 
 Weifeng Li 
-Weiguo Li 
+Weiguo Li  
 Wei Huang 
 Wei Hu 
 Wei Hu (Xavier) 
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 19a99a82c5..a6aaa760ca 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1639,7 +1639,7 @@ int enic_set_mtu(struct enic *enic, uint16_t new_mtu)
  * packet length.
  */
 if (!eth_dev->data->dev_started)
-   goto set_mtu_done;
+   return rc;

 /*
  * The device has started, re-do RQs on the fly. In the process, we
--
2.34.1


Re: [PATCH 1/2] drivers: use macro for PCI address format

2023-10-19 Thread John Daley (johndale)
Acked-by: John Daley 


From: Thomas Monjalon 
Date: Thursday, October 19, 2023 at 8:41 AM
To: dev@dpdk.org 
Cc: David Marchand , chen...@nvidia.com 
, Jerin Jacob , Michal Krawczyk 
, Shai Brandes , Evgeny Schemeilin 
, Igor Chauskin , Ron Beider 
, John Daley (johndale) , Hyong Youb 
Kim (hyonkim) , Ziyang Xuan , 
Xiaoyun Wang , Guoyang Zhou 
, Matan Azrad , Viacheslav Ovsiienko 
, Ori Kam , Suanming Mou 
, Maciej Czekaj 
Subject: [PATCH 1/2] drivers: use macro for PCI address format
Some places were not using the macro PCI_PRI_FMT
as print format of a PCI address.

Note: RTE prefix is missing in the name of some PCI macros.

Signed-off-by: Thomas Monjalon 
---
 drivers/event/skeleton/skeleton_eventdev.c | 2 +-
 drivers/net/ena/ena_ethdev.c   | 2 +-
 drivers/net/enic/enic.h| 3 +--
 drivers/net/enic/enic_ethdev.c | 2 +-
 drivers/net/enic/enic_vf_representor.c | 2 +-
 drivers/net/hinic/hinic_pmd_ethdev.c   | 4 ++--
 drivers/net/mlx5/linux/mlx5_os.c   | 2 +-
 drivers/net/thunderx/nicvf_ethdev.c| 2 +-
 8 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/event/skeleton/skeleton_eventdev.c 
b/drivers/event/skeleton/skeleton_eventdev.c
index dc9b131641..dd2dab2e27 100644
--- a/drivers/event/skeleton/skeleton_eventdev.c
+++ b/drivers/event/skeleton/skeleton_eventdev.c
@@ -373,7 +373,7 @@ skeleton_eventdev_init(struct rte_eventdev *eventdev)
 skel->subsystem_device_id = pci_dev->id.subsystem_device_id;
 skel->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;

-   PMD_DRV_LOG(DEBUG, "pci device (%x:%x) %u:%u:%u:%u",
+   PMD_DRV_LOG(DEBUG, "PCI device (%x:%x) " PCI_PRI_FMT,
 pci_dev->id.vendor_id, pci_dev->id.device_id,
 pci_dev->addr.domain, pci_dev->addr.bus,
 pci_dev->addr.devid, pci_dev->addr.function);
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 7345e480f8..b39ec629e7 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -2125,7 +2125,7 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)

 pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);

-   PMD_INIT_LOG(INFO, "Initializing %x:%x:%x.%d\n",
+   PMD_INIT_LOG(INFO, "Initializing " PCI_PRI_FMT "\n",
  pci_dev->addr.domain,
  pci_dev->addr.bus,
  pci_dev->addr.devid,
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 163a1f037e..78778704f2 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,6 @@

 #define ENICPMD_SETTING(enic, f) ((enic->config.flags & VENETF_##f) ? 1 : 0)

-#define ENICPMD_BDF_LENGTH  13   /* :00:00.0'\0' */
 #define ENIC_CALC_IP_CKSUM  1
 #define ENIC_CALC_TCP_UDP_CKSUM 2
 #define ENIC_MAX_MTU9000
@@ -101,7 +100,7 @@ struct enic {
 bool overlay_offload;
 struct rte_eth_dev *rte_dev;
 struct rte_eth_dev_data *dev_data;
-   char bdf_name[ENICPMD_BDF_LENGTH];
+   char bdf_name[PCI_PRI_STR_SIZE];
 int dev_fd;
 int iommu_group_fd;
 int iommu_groupid;
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index a487256fa1..b04b6c9aa1 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -1274,7 +1274,7 @@ static int eth_enic_dev_init(struct rte_eth_dev *eth_dev,
 enic->pdev = pdev;
 addr = &pdev->addr;

-   snprintf(enic->bdf_name, ENICPMD_BDF_LENGTH, "%04x:%02x:%02x.%x",
+   snprintf(enic->bdf_name, PCI_PRI_STR_SIZE, PCI_PRI_FMT,
 addr->domain, addr->bus, addr->devid, addr->function);

 err = enic_check_devargs(eth_dev);
diff --git a/drivers/net/enic/enic_vf_representor.c 
b/drivers/net/enic/enic_vf_representor.c
index 46f85964e9..5d8d29135c 100644
--- a/drivers/net/enic/enic_vf_representor.c
+++ b/drivers/net/enic/enic_vf_representor.c
@@ -707,7 +707,7 @@ int enic_vf_representor_init(struct rte_eth_dev *eth_dev, 
void *init_params)
 LIST_INIT(&vf_enic->memzone_list);
 rte_spinlock_init(&vf_enic->memzone_list_lock);
 addr = &vf->bdf;
-   snprintf(vf_enic->bdf_name, ENICPMD_BDF_LENGTH, "%04x:%02x:%02x.%x",
+   snprintf(vf_enic->bdf_name, PCI_PRI_STR_SIZE, PCI_PRI_FMT,
  addr->domain, addr->bus, addr->devid, addr->function);
 return 0;
 }
diff --git a/drivers/net/hinic/hinic_pmd_ethdev.c 
b/drivers/net/hinic/hinic_pmd_ethdev.c
index adc9f75c81..d4978e0649 100644
--- a/drivers/net/hinic/hinic_pmd_ethdev.c
+++ b/drivers/net/hinic/hinic_pmd_ethdev.c
@@ -3086,7 +3086,7 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev)

 snprintf(nic_dev->proc_dev_

Re: [PATCH v5 14/40] net/enic: check RSS hash algorithms

2023-10-12 Thread John Daley (johndale)
> also 'enicpmd_dev_configure()' looks like can be updated.
Where would it be updated? With the patch, the check will be done at the bottom 
of the function in call to enic_init_rss_nic_cfg -> enic_set_niccfg



From: Ferruh Yigit 
Date: Wednesday, October 11, 2023 at 10:32 AM
To: Jie Hai , dev@dpdk.org , John Daley 
(johndale) , Hyong Youb Kim (hyonkim) 
Cc: lihuis...@huawei.com , fengcheng...@huawei.com 
, liudongdo...@huawei.com 
Subject: Re: [PATCH v5 14/40] net/enic: check RSS hash algorithms
On 10/11/2023 10:27 AM, Jie Hai wrote:
> A new field 'algorithm' has been added to rss_conf, check it
> in case of ignoring unsupported values.
>
> Signed-off-by: Jie Hai 
> ---
>  drivers/net/enic/enic_ethdev.c | 1 +
>  drivers/net/enic/enic_main.c   | 3 +++
>  2 files changed, 4 insertions(+)
>
> diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
> index cdf091559196..164f423a85c8 100644
> --- a/drivers/net/enic/enic_ethdev.c
> +++ b/drivers/net/enic/enic_ethdev.c
> @@ -834,6 +834,7 @@ static int enicpmd_dev_rss_hash_conf_get(struct 
> rte_eth_dev *dev,
>ENICPMD_FUNC_TRACE();
>if (rss_conf == NULL)
>return -EINVAL;
> +
>

unintended change.

also 'enicpmd_dev_configure()' looks like can be updated.


>if (rss_conf->rss_key != NULL &&
>rss_conf->rss_key_len < ENIC_RSS_HASH_KEY_SIZE) {
>dev_err(enic, "rss_hash_conf_get: wrong rss_key_len. given=%u"
> diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
> index 19a99a82c501..2eafe7637b3a 100644
> --- a/drivers/net/enic/enic_main.c
> +++ b/drivers/net/enic/enic_main.c
> @@ -1428,6 +1428,9 @@ int enic_set_rss_conf(struct enic *enic, struct 
> rte_eth_rss_conf *rss_conf)
>}
>}
>
> + if (rss_enable && rss_conf->algorithm != RTE_ETH_HASH_FUNCTION_DEFAULT)
> + return -EINVAL;
> +
>ret = enic_set_niccfg(enic, ENIC_RSS_DEFAULT_CPU, rss_hash_type,
>  ENIC_RSS_HASH_BITS, ENIC_RSS_BASE_CPU,
>  rss_enable);


Re: [PATCH v2 13/44] net/enic: fix segment fault when parse devargs

2023-03-20 Thread John Daley (johndale)
Reviewed-by: John Daley johnd...@cisco.com<mailto:johnd...@cisco.com>

From: Chengwen Feng 
Date: Monday, March 20, 2023 at 2:28 AM
To: tho...@monjalon.net , ferruh.yi...@amd.com 
, John Daley (johndale) , Hyong Youb 
Kim (hyonkim) 
Cc: dev@dpdk.org 
Subject: [PATCH v2 13/44] net/enic: fix segment fault when parse devargs
The rte_kvargs_process() was used to parse KV pairs, it also supports
to parse 'only keys' (e.g. socket_id) type. And the callback function
parameter 'value' is NULL when parsed 'only keys'.

This patch fixes segment fault when parse input args with 'only keys'.

Fixes: 93fb21fdbe23 ("net/enic: enable overlay offload for VXLAN and GENEVE")
Fixes: e39c2756e21a ("net/enic: add devarg to specify ingress VLAN rewrite 
mode")
Cc: sta...@dpdk.org

Signed-off-by: Chengwen Feng 
---
 drivers/net/enic/enic_ethdev.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index cdf0915591..b67016e0a3 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -1148,6 +1148,9 @@ static int enic_parse_zero_one(const char *key,
 struct enic *enic;
 bool b;

+   if (value == NULL)
+   return -EINVAL;
+
 enic = (struct enic *)opaque;
 if (strcmp(value, "0") == 0) {
 b = false;
@@ -1173,6 +1176,9 @@ static int enic_parse_ig_vlan_rewrite(__rte_unused const 
char *key,
 {
 struct enic *enic;

+   if (value == NULL)
+   return -EINVAL;
+
 enic = (struct enic *)opaque;
 if (strcmp(value, "trunk") == 0) {
 /* Trunk mode: always tag */
--
2.17.1


Re: [Bug 1185] enic: no longer accepting 2048 descriptor size in 20.11.6

2023-03-15 Thread John Daley (johndale)
Thank you, I will take a look and get back to you.
-john

From: Kevin Traynor 
Date: Wednesday, March 15, 2023 at 10:47 AM
To: John Daley (johndale) , Hyong Youb Kim (hyonkim) 

Cc: Luca Boccassi , David Marchand 
, dev@dpdk.org 
Subject: Fwd: [Bug 1185] enic: no longer accepting 2048 descriptor size in 
20.11.6
Hi John/Hyong Youb,

Not sure if you are monitoring dpdk bugzilla, but wanted to draw your
attention to https://bugs.dpdk.org/show_bug.cgi?id=1185

Maybe you have some clues about it and if we need to backport the
mentioned commit?

thanks,
Kevin.

 Forwarded Message 
Subject: [Bug 1185] enic: no longer accepting 2048 descriptor size in
20.11.6
Date: Wed, 15 Mar 2023 17:33:52 +
From: bugzi...@dpdk.org
To: dev@dpdk.org

https://bugs.dpdk.org/show_bug.cgi?id=1185

 Bug ID: 1185
Summary: enic: no longer accepting 2048 descriptor size in
 20.11.6
Product: DPDK
Version: 20.11
   Hardware: All
 OS: All
 Status: UNCONFIRMED
   Severity: normal
   Priority: Normal
  Component: core
   Assignee: dev@dpdk.org
   Reporter: ktray...@redhat.com
   Target Milestone: ---

Hi enic maintainers,

With openvswitch 2.15 using dpdk 20.11.6, enic driver is reporting that it
cannot accept setup with default OVS number of tx descriptors (2048).

2022-08-19T16:29:38.555Z|00204|dpdk|ERR|Invalid value for nb_tx_desc(=2048),
should be: <= 256, >= 64, and a product of 32

OVS has used 2048 as default for many years and the code in 20.11.6 does not
look like it changed much from previous releases either.

The commit below [0] on dpdk main branch (but not on 20.11 branch),
changes how
max descriptor values are calculated.

So any idea why the 2048 can no longer be used with 20.11.6 ? some commit I
missed? different firmware?

or is it an incorrect calculation and the commit [0] is needed on stable
branches to correct this?

Thanks.

Reference: https://bugzilla.redhat.com/show_bug.cgi?id=2119876

[0]
commit 22572e84fbda2c195707ffbb0dd6af4433d7a219
Author: John Daley 
Date:   Fri Jan 28 09:58:13 2022 -0800

 net/enic: support max descriptors allowed by adapter

 Newer VIC adapters have the max number of supported RX and TX
 descriptors in their configuration. Use these values as the
 maximums.

 Signed-off-by: John Daley 
 Reviewed-by: Hyong Youb Kim 

--
You are receiving this mail because:
You are the assignee for the bug.


Re: [PATCH 6/7] enic: replace zero length array with flex array

2023-01-13 Thread John Daley (johndale)
Acked-by: John Daley 

From: Stephen Hemminger 
Date: Friday, January 13, 2023 at 1:52 PM
To: dev@dpdk.org 
Cc: Stephen Hemminger , John Daley (johndale) 
, Hyong Youb Kim (hyonkim) 
Subject: [PATCH 6/7] enic: replace zero length array with flex array
Zero length arrays are GNU extension. Replace with
standard flex array.

Signed-off-by: Stephen Hemminger 
---
 drivers/net/enic/base/vnic_devcmd.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/enic/base/vnic_devcmd.h 
b/drivers/net/enic/base/vnic_devcmd.h
index 253a791c3f65..f91cc3078d63 100644
--- a/drivers/net/enic/base/vnic_devcmd.h
+++ b/drivers/net/enic/base/vnic_devcmd.h
@@ -765,7 +765,7 @@ struct vnic_devcmd_notify {
 struct vnic_devcmd_provinfo {
 uint8_t oui[3];
 uint8_t type;
-   uint8_t data[0];
+   uint8_t data[];
 };

 /*
--
2.39.0


[PATCH] net/enic: fix dereference before null check

2022-02-14 Thread John Daley
This patch fixes an issue found by coverity. It checks for a possible
null value of "error" before dereferencing it.

CID: 375064: Dereference after null check
Either the check against null is unnecessary, or there may be a null
pointer dereference.

Coverity issue: 375064
Fixes: ee806eea59fe ("net/enic: support GENEVE flow item")

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_fm_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index f0bda19a70..c87d3af847 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -1204,7 +1204,7 @@ enic_fm_copy_entry(struct enic_flowman *fm,
ret = item_info->copy_item(&args);
if (ret) {
/* If copy_item set the error, return that */
-   if (error->type != RTE_FLOW_ERROR_TYPE_NONE)
+   if (error && error->type != RTE_FLOW_ERROR_TYPE_NONE)
return ret;
goto item_not_supported;
}
-- 
2.33.1



[PATCH v4 3/3] net/enic: support max descriptors allowed by adapter

2022-01-28 Thread John Daley
Newer VIC adapters have the max number of supported RX and TX
descriptors in their configuration. Use these values as the
maximums.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/cq_enet_desc.h |  6 -
 drivers/net/enic/enic_res.c  | 20 
 drivers/net/enic/enic_res.h  |  6 +++--
 drivers/net/enic/enic_rxtx.c | 35 +++-
 4 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/drivers/net/enic/base/cq_enet_desc.h 
b/drivers/net/enic/base/cq_enet_desc.h
index a34a4f5400..02db85b9a0 100644
--- a/drivers/net/enic/base/cq_enet_desc.h
+++ b/drivers/net/enic/base/cq_enet_desc.h
@@ -67,7 +67,8 @@ struct cq_enet_rq_desc_64 {
uint16_t vlan;
uint16_t checksum_fcoe;
uint8_t flags;
-   uint8_t unused[48];
+   uint8_t fetch_idx_flags;
+   uint8_t unused[47];
uint8_t type_color;
 };
 
@@ -92,6 +93,9 @@ struct cq_enet_rq_desc_64 {
 #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS  14
 #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK \
((1 << CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS) - 1)
+#define CQ_ENET_RQ_DESC_FETCH_IDX_BITS  2
+#define CQ_ENET_RQ_DESC_FETCH_IDX_MASK \
+   ((1 << CQ_ENET_RQ_DESC_FETCH_IDX_BITS) - 1)
 #define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14)
 #define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15)
 
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 9cfb857939..caf773bab2 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -26,6 +26,7 @@ int enic_get_vnic_config(struct enic *enic)
struct vnic_enet_config *c = &enic->config;
int err;
uint64_t sizes;
+   uint32_t max_rq_descs, max_wq_descs;
 
err = vnic_dev_get_mac_addr(enic->vdev, enic->mac_addr);
if (err) {
@@ -57,6 +58,8 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(loop_tag);
GET_CONFIG(num_arfs);
GET_CONFIG(max_pkt_size);
+   GET_CONFIG(max_rq_ring);
+   GET_CONFIG(max_wq_ring);
 
/* max packet size is only defined in newer VIC firmware
 * and will be 0 for legacy firmware and VICs
@@ -101,20 +104,29 @@ int enic_get_vnic_config(struct enic *enic)
((enic->filter_actions & FILTER_ACTION_COUNTER_FLAG) ?
 "count " : ""));
 
-   c->wq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_WQ_DESCS,
+   /* The max size of RQ and WQ rings are specified in 1500 series VICs and
+* beyond. If they are not specified by the VIC or if 64B CQ descriptors
+* are not being used, the max number of descriptors is 4096.
+*/
+   max_wq_descs = (enic->cq64_request && c->max_wq_ring) ? c->max_wq_ring :
+  ENIC_LEGACY_MAX_WQ_DESCS;
+   c->wq_desc_count = RTE_MIN(max_wq_descs,
RTE_MAX((uint32_t)ENIC_MIN_WQ_DESCS, c->wq_desc_count));
c->wq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
-
-   c->rq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_RQ_DESCS,
+   max_rq_descs = (enic->cq64_request && c->max_rq_ring) ? c->max_rq_ring
+  : ENIC_LEGACY_MAX_WQ_DESCS;
+   c->rq_desc_count = RTE_MIN(max_rq_descs,
RTE_MAX((uint32_t)ENIC_MIN_RQ_DESCS, c->rq_desc_count));
c->rq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
+   dev_debug(NULL, "Max supported VIC descriptors: WQ:%u, RQ:%u\n",
+ max_wq_descs, max_rq_descs);
 
c->intr_timer_usec = RTE_MIN(c->intr_timer_usec,
  vnic_dev_get_intr_coal_timer_max(enic->vdev));
 
dev_info(enic_get_dev(enic),
"vNIC MAC addr " RTE_ETHER_ADDR_PRT_FMT
-   "wq/rq %d/%d mtu %d, max mtu:%d\n",
+   " wq/rq %d/%d mtu %d, max mtu:%d\n",
enic->mac_addr[0], enic->mac_addr[1], enic->mac_addr[2],
enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5],
c->wq_desc_count, c->rq_desc_count,
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 34f15d5a42..ae979d52be 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -12,9 +12,11 @@
 #include "vnic_rq.h"
 
 #define ENIC_MIN_WQ_DESCS  64
-#define ENIC_MAX_WQ_DESCS  4096
 #define ENIC_MIN_RQ_DESCS  64
-#define ENIC_MAX_RQ_DESCS  4096
+
+/* 1400 series VICs and prior all have 4K max, after that it's in the config */
+#define ENIC_LEGACY_MAX_WQ_DESCS4096
+#define ENIC_LEGACY_MAX_RQ_DESCS4096
 
 /* A descriptor ring has a multiple of 32 descriptors */
 #define ENIC_ALIGN_DESCS   32

[PATCH v4 2/3] net/enic: update VIC firmware API

2022-01-28 Thread John Daley
Update the configuration structure used between the adapter and
driver. The structure is compatible with all Cisco VIC adapters.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/vnic_enet.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/enic/base/vnic_enet.h 
b/drivers/net/enic/base/vnic_enet.h
index 2a97a33044..66261d9127 100644
--- a/drivers/net/enic/base/vnic_enet.h
+++ b/drivers/net/enic/base/vnic_enet.h
@@ -31,6 +31,28 @@ struct vnic_enet_config {
uint32_t rdma_mr_id;
uint32_t rdma_mr_count;
uint32_t max_pkt_size;
+   uint16_t vf_subvnic_count;
+   uint16_t mq_subvnic_count;
+   uint32_t mq_flags;
+
+   /* the following 3 fields are per-MQ-vnic counts */
+   uint32_t mq_rdma_mr_count;
+   uint16_t mq_rdma_qp_count;
+   uint16_t mq_rdma_resgrp;
+
+   uint16_t rdma_max_sq_ring_sz;
+   uint16_t rdma_max_rq_ring_sz;
+   uint32_t rdma_max_cq_ring_sz;
+   uint16_t rdma_max_wr_sge;
+   uint16_t rdma_max_mr_sge;
+   uint8_t rdma_max_rd_per_qp;
+   uint8_t unused; /* available */
+   uint16_t mq_rdma_engine_count;
+   uint32_t intr_coal_tick_ns; /* coalescing timer tick in nsec */
+   uint32_t max_rq_ring;   /* MAX RQ ring size */
+   uint32_t max_wq_ring;   /* MAX WQ ring size */
+   uint32_t max_cq_ring;   /* MAX CQ ring size */
+   uint32_t rdma_rsvd_lkey;/* Reserved (privileged) LKey */
 };
 
 #define VENETF_TSO 0x1 /* TSO enabled */
-- 
2.33.1



[PATCH v4 1/3] net/enic: add support for eCPRI matching

2022-01-28 Thread John Daley
eCPRI message can be over Ethernet layer (.1Q supported also) or over
UDP layer. Message header formats are the same in these two variants.

Only up though the first packet header in the PDU can be matched.
RSS on the eCPRI payload is not supported.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 doc/guides/nics/features/enic.ini  |  1 +
 doc/guides/rel_notes/release_22_03.rst |  1 +
 drivers/net/enic/enic_fm_flow.c| 65 ++
 3 files changed, 67 insertions(+)

diff --git a/doc/guides/nics/features/enic.ini 
b/doc/guides/nics/features/enic.ini
index 00231baf85..61bec4910e 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -39,6 +39,7 @@ x86-64   = Y
 Usage doc= Y
 
 [rte_flow items]
+ecpri= Y
 eth  = Y
 geneve   = Y
 geneve_opt   = Y
diff --git a/doc/guides/rel_notes/release_22_03.rst 
b/doc/guides/rel_notes/release_22_03.rst
index 33be3241b9..6786eb3b48 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -58,6 +58,7 @@ New Features
 * **Updated Cisco enic driver.**
 
   * Added rte_flow support for matching GENEVE packets.
+  * Added rte_flow support for matching eCPRI packets.
 
 Removed Items
 -
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index d8718d17ef..f0bda19a70 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -237,6 +237,7 @@ static enic_copy_item_fn enic_fm_copy_item_vxlan;
 static enic_copy_item_fn enic_fm_copy_item_gtp;
 static enic_copy_item_fn enic_fm_copy_item_geneve;
 static enic_copy_item_fn enic_fm_copy_item_geneve_opt;
+static enic_copy_item_fn enic_fm_copy_item_ecpri;
 
 /* Ingress actions */
 static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -392,6 +393,15 @@ static const struct enic_fm_items enic_fm_items[] = {
   RTE_FLOW_ITEM_TYPE_END,
},
},
+   [RTE_FLOW_ITEM_TYPE_ECPRI] = {
+   .copy_item = enic_fm_copy_item_ecpri,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_ETH,
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
 };
 
 static int
@@ -877,6 +887,61 @@ enic_fm_copy_item_geneve_opt(struct copy_item_args *arg)
return 0;
 }
 
+/* Match eCPRI combined message header */
+static int
+enic_fm_copy_item_ecpri(struct copy_item_args *arg)
+{
+   const struct rte_flow_item *item = arg->item;
+   const struct rte_flow_item_ecpri *spec = item->spec;
+   const struct rte_flow_item_ecpri *mask = item->mask;
+   struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+   struct fm_header_set *fm_data, *fm_mask;
+   uint8_t *fm_data_to, *fm_mask_to;
+
+   ENICPMD_FUNC_TRACE();
+
+   /* Tunneling not supported- only matching on inner eCPRI fields. */
+   if (arg->header_level > 0)
+   return -EINVAL;
+
+   /* Need both spec and mask */
+   if (!spec || !mask)
+   return -EINVAL;
+
+   fm_data = &entry->ftm_data.fk_hdrset[0];
+   fm_mask = &entry->ftm_mask.fk_hdrset[0];
+
+   /* eCPRI can only follow L2/VLAN layer if ethernet type is 0xAEFE. */
+   if (!(fm_data->fk_metadata & FKM_UDP) &&
+   (fm_mask->l2.eth.fk_ethtype != UINT16_MAX ||
+   rte_cpu_to_be_16(fm_data->l2.eth.fk_ethtype) !=
+   RTE_ETHER_TYPE_ECPRI))
+   return -EINVAL;
+
+   if (fm_data->fk_metadata & FKM_UDP) {
+   /* eCPRI on UDP */
+   fm_data->fk_header_select |= FKH_L4RAW;
+   fm_mask->fk_header_select |= FKH_L4RAW;
+   fm_data_to = &fm_data->l4.rawdata[sizeof(fm_data->l4.udp)];
+   fm_mask_to = &fm_mask->l4.rawdata[sizeof(fm_data->l4.udp)];
+   } else {
+   /* eCPRI directly after Etherent header */
+   fm_data->fk_header_select |= FKH_L3RAW;
+   fm_mask->fk_header_select |= FKH_L3RAW;
+   fm_data_to = &fm_data->l3.rawdata[0];
+   fm_mask_to = &fm_mask->l3.rawdata[0];
+   }
+
+   /*
+* Use the raw L3 or L4 buffer to match eCPRI since fm_header_set does
+* not have eCPRI header. Only 1st message header of PDU can be matched.
+* "C" * bit ignored.
+*/
+   memcpy(fm_data_to, spec, sizeof(*spec));
+   memcpy(fm_mask_to, mask, sizeof(*mask));
+   return 0;
+}
+
 /*
  * Currently, raw pattern match is very limited. It is intended for matching
  * UDP tunnel header (e.g. vxlan or geneve).
-- 
2.33.1



[PATCH v3] net/enic: support max descriptors allowed by adapter

2022-01-27 Thread John Daley
Newer VIC adapters have the max number of supported RX and TX
descriptors in their configuration. Use these values as the
maximums.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
v3: add line just below so 0-day bot applies dependency
Depends-on: patch-105799 ("net/enic: update VIC firmware API")

 drivers/net/enic/base/cq_enet_desc.h |  6 -
 drivers/net/enic/enic_res.c  | 20 
 drivers/net/enic/enic_res.h  |  6 +++--
 drivers/net/enic/enic_rxtx.c | 35 +++-
 4 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/drivers/net/enic/base/cq_enet_desc.h 
b/drivers/net/enic/base/cq_enet_desc.h
index a34a4f5400..02db85b9a0 100644
--- a/drivers/net/enic/base/cq_enet_desc.h
+++ b/drivers/net/enic/base/cq_enet_desc.h
@@ -67,7 +67,8 @@ struct cq_enet_rq_desc_64 {
uint16_t vlan;
uint16_t checksum_fcoe;
uint8_t flags;
-   uint8_t unused[48];
+   uint8_t fetch_idx_flags;
+   uint8_t unused[47];
uint8_t type_color;
 };
 
@@ -92,6 +93,9 @@ struct cq_enet_rq_desc_64 {
 #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS  14
 #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK \
((1 << CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS) - 1)
+#define CQ_ENET_RQ_DESC_FETCH_IDX_BITS  2
+#define CQ_ENET_RQ_DESC_FETCH_IDX_MASK \
+   ((1 << CQ_ENET_RQ_DESC_FETCH_IDX_BITS) - 1)
 #define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14)
 #define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15)
 
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 9cfb857939..caf773bab2 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -26,6 +26,7 @@ int enic_get_vnic_config(struct enic *enic)
struct vnic_enet_config *c = &enic->config;
int err;
uint64_t sizes;
+   uint32_t max_rq_descs, max_wq_descs;
 
err = vnic_dev_get_mac_addr(enic->vdev, enic->mac_addr);
if (err) {
@@ -57,6 +58,8 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(loop_tag);
GET_CONFIG(num_arfs);
GET_CONFIG(max_pkt_size);
+   GET_CONFIG(max_rq_ring);
+   GET_CONFIG(max_wq_ring);
 
/* max packet size is only defined in newer VIC firmware
 * and will be 0 for legacy firmware and VICs
@@ -101,20 +104,29 @@ int enic_get_vnic_config(struct enic *enic)
((enic->filter_actions & FILTER_ACTION_COUNTER_FLAG) ?
 "count " : ""));
 
-   c->wq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_WQ_DESCS,
+   /* The max size of RQ and WQ rings are specified in 1500 series VICs and
+* beyond. If they are not specified by the VIC or if 64B CQ descriptors
+* are not being used, the max number of descriptors is 4096.
+*/
+   max_wq_descs = (enic->cq64_request && c->max_wq_ring) ? c->max_wq_ring :
+  ENIC_LEGACY_MAX_WQ_DESCS;
+   c->wq_desc_count = RTE_MIN(max_wq_descs,
RTE_MAX((uint32_t)ENIC_MIN_WQ_DESCS, c->wq_desc_count));
c->wq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
-
-   c->rq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_RQ_DESCS,
+   max_rq_descs = (enic->cq64_request && c->max_rq_ring) ? c->max_rq_ring
+  : ENIC_LEGACY_MAX_WQ_DESCS;
+   c->rq_desc_count = RTE_MIN(max_rq_descs,
RTE_MAX((uint32_t)ENIC_MIN_RQ_DESCS, c->rq_desc_count));
c->rq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
+   dev_debug(NULL, "Max supported VIC descriptors: WQ:%u, RQ:%u\n",
+ max_wq_descs, max_rq_descs);
 
c->intr_timer_usec = RTE_MIN(c->intr_timer_usec,
  vnic_dev_get_intr_coal_timer_max(enic->vdev));
 
dev_info(enic_get_dev(enic),
"vNIC MAC addr " RTE_ETHER_ADDR_PRT_FMT
-   "wq/rq %d/%d mtu %d, max mtu:%d\n",
+   " wq/rq %d/%d mtu %d, max mtu:%d\n",
enic->mac_addr[0], enic->mac_addr[1], enic->mac_addr[2],
enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5],
c->wq_desc_count, c->rq_desc_count,
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 34f15d5a42..ae979d52be 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -12,9 +12,11 @@
 #include "vnic_rq.h"
 
 #define ENIC_MIN_WQ_DESCS  64
-#define ENIC_MAX_WQ_DESCS  4096
 #define ENIC_MIN_RQ_DESCS  64
-#define ENIC_MAX_RQ_DESCS  4096
+
+/* 1400 series VICs and prior all have 4K max, after that it's in the config */
+#define ENIC_LEGACY_MAX_WQ_DESCS4096
+#define ENIC_LEGACY_M

[PATCH v3] net/enic: add support for eCPRI matching

2022-01-27 Thread John Daley
eCPRI message can be over Ethernet layer (.1Q supported also) or over
UDP layer. Message header formats are the same in these two variants.

Only up though the first packet header in the PDU can be matched.
RSS on the eCPRI payload is not supported.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---

v3: put new rte flow item feature in alphabetical order

 doc/guides/nics/features/enic.ini  |  1 +
 doc/guides/rel_notes/release_22_03.rst |  1 +
 drivers/net/enic/enic_fm_flow.c| 67 +-
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/enic.ini 
b/doc/guides/nics/features/enic.ini
index 00231baf85..61bec4910e 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -39,6 +39,7 @@ x86-64   = Y
 Usage doc= Y
 
 [rte_flow items]
+ecpri= Y
 eth  = Y
 geneve   = Y
 geneve_opt   = Y
diff --git a/doc/guides/rel_notes/release_22_03.rst 
b/doc/guides/rel_notes/release_22_03.rst
index 33be3241b9..6786eb3b48 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -58,6 +58,7 @@ New Features
 * **Updated Cisco enic driver.**
 
   * Added rte_flow support for matching GENEVE packets.
+  * Added rte_flow support for matching eCPRI packets.
 
 Removed Items
 -
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index bf04d714d0..f0bda19a70 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -237,6 +237,7 @@ static enic_copy_item_fn enic_fm_copy_item_vxlan;
 static enic_copy_item_fn enic_fm_copy_item_gtp;
 static enic_copy_item_fn enic_fm_copy_item_geneve;
 static enic_copy_item_fn enic_fm_copy_item_geneve_opt;
+static enic_copy_item_fn enic_fm_copy_item_ecpri;
 
 /* Ingress actions */
 static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -392,6 +393,15 @@ static const struct enic_fm_items enic_fm_items[] = {
   RTE_FLOW_ITEM_TYPE_END,
},
},
+   [RTE_FLOW_ITEM_TYPE_ECPRI] = {
+   .copy_item = enic_fm_copy_item_ecpri,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_ETH,
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
 };
 
 static int
@@ -877,6 +887,61 @@ enic_fm_copy_item_geneve_opt(struct copy_item_args *arg)
return 0;
 }
 
+/* Match eCPRI combined message header */
+static int
+enic_fm_copy_item_ecpri(struct copy_item_args *arg)
+{
+   const struct rte_flow_item *item = arg->item;
+   const struct rte_flow_item_ecpri *spec = item->spec;
+   const struct rte_flow_item_ecpri *mask = item->mask;
+   struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+   struct fm_header_set *fm_data, *fm_mask;
+   uint8_t *fm_data_to, *fm_mask_to;
+
+   ENICPMD_FUNC_TRACE();
+
+   /* Tunneling not supported- only matching on inner eCPRI fields. */
+   if (arg->header_level > 0)
+   return -EINVAL;
+
+   /* Need both spec and mask */
+   if (!spec || !mask)
+   return -EINVAL;
+
+   fm_data = &entry->ftm_data.fk_hdrset[0];
+   fm_mask = &entry->ftm_mask.fk_hdrset[0];
+
+   /* eCPRI can only follow L2/VLAN layer if ethernet type is 0xAEFE. */
+   if (!(fm_data->fk_metadata & FKM_UDP) &&
+   (fm_mask->l2.eth.fk_ethtype != UINT16_MAX ||
+   rte_cpu_to_be_16(fm_data->l2.eth.fk_ethtype) !=
+   RTE_ETHER_TYPE_ECPRI))
+   return -EINVAL;
+
+   if (fm_data->fk_metadata & FKM_UDP) {
+   /* eCPRI on UDP */
+   fm_data->fk_header_select |= FKH_L4RAW;
+   fm_mask->fk_header_select |= FKH_L4RAW;
+   fm_data_to = &fm_data->l4.rawdata[sizeof(fm_data->l4.udp)];
+   fm_mask_to = &fm_mask->l4.rawdata[sizeof(fm_data->l4.udp)];
+   } else {
+   /* eCPRI directly after Etherent header */
+   fm_data->fk_header_select |= FKH_L3RAW;
+   fm_mask->fk_header_select |= FKH_L3RAW;
+   fm_data_to = &fm_data->l3.rawdata[0];
+   fm_mask_to = &fm_mask->l3.rawdata[0];
+   }
+
+   /*
+* Use the raw L3 or L4 buffer to match eCPRI since fm_header_set does
+* not have eCPRI header. Only 1st message header of PDU can be matched.
+* "C" * bit ignored.
+*/
+   memcpy(fm_data_to, spec, sizeof(*spec));
+   memcpy(fm_mask_to, mask, sizeof(*mask));
+   return 0;
+}
+
 /*
  * Currently, raw pattern match is very limited. It is intended for matching
  * UDP tunnel head

RE: [PATCH] net/enic: adjust memory check and use in proper order

2022-01-26 Thread John Daley (johndale)
Reviewed-by: John Daley 

Thanks,
John

-Original Message-
From: Weiguo Li  
Sent: Tuesday, January 25, 2022 4:01 AM
To: John Daley (johndale) 
Cc: dev@dpdk.org
Subject: [PATCH] net/enic: adjust memory check and use in proper order

Fixes: bb66d562aefc ("net/enic: share flow actions with same signature")

Signed-off-by: Weiguo Li 
---
 drivers/net/enic/enic_fm_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c 
index bf04d714d0..d8718d17ef 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -2521,11 +2521,11 @@ enic_action_handle_get(struct enic_flowman *fm, struct 
fm_action *action_in,
memcpy(fma, action_in, sizeof(*fma));
 
ah = calloc(1, sizeof(*ah));
-   memcpy(&ah->key, action_in, sizeof(struct fm_action));
if (ah == NULL)
return rte_flow_error_set(error, ENOMEM,
   RTE_FLOW_ERROR_TYPE_HANDLE,
   NULL, "enic: calloc(fm-action)");
+   memcpy(&ah->key, action_in, sizeof(struct fm_action));
args[0] = FM_ACTION_ALLOC;
args[1] = fm->cmd.pa;
ret = flowman_cmd(fm, args, 2);
--
2.25.1



[PATCH v2] net/enic: support max descriptors allowed by adapter

2022-01-26 Thread John Daley
Newer VIC adapters have the max number of supported RX and TX
descriptors in their configuration. Use these values as the
maximums.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---

v2: fix RTE_ASSERT

 drivers/net/enic/base/cq_enet_desc.h |  6 -
 drivers/net/enic/enic_res.c  | 20 
 drivers/net/enic/enic_res.h  |  6 +++--
 drivers/net/enic/enic_rxtx.c | 35 +++-
 4 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/drivers/net/enic/base/cq_enet_desc.h 
b/drivers/net/enic/base/cq_enet_desc.h
index a34a4f5400..02db85b9a0 100644
--- a/drivers/net/enic/base/cq_enet_desc.h
+++ b/drivers/net/enic/base/cq_enet_desc.h
@@ -67,7 +67,8 @@ struct cq_enet_rq_desc_64 {
uint16_t vlan;
uint16_t checksum_fcoe;
uint8_t flags;
-   uint8_t unused[48];
+   uint8_t fetch_idx_flags;
+   uint8_t unused[47];
uint8_t type_color;
 };
 
@@ -92,6 +93,9 @@ struct cq_enet_rq_desc_64 {
 #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS  14
 #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK \
((1 << CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS) - 1)
+#define CQ_ENET_RQ_DESC_FETCH_IDX_BITS  2
+#define CQ_ENET_RQ_DESC_FETCH_IDX_MASK \
+   ((1 << CQ_ENET_RQ_DESC_FETCH_IDX_BITS) - 1)
 #define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14)
 #define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15)
 
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 9cfb857939..caf773bab2 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -26,6 +26,7 @@ int enic_get_vnic_config(struct enic *enic)
struct vnic_enet_config *c = &enic->config;
int err;
uint64_t sizes;
+   uint32_t max_rq_descs, max_wq_descs;
 
err = vnic_dev_get_mac_addr(enic->vdev, enic->mac_addr);
if (err) {
@@ -57,6 +58,8 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(loop_tag);
GET_CONFIG(num_arfs);
GET_CONFIG(max_pkt_size);
+   GET_CONFIG(max_rq_ring);
+   GET_CONFIG(max_wq_ring);
 
/* max packet size is only defined in newer VIC firmware
 * and will be 0 for legacy firmware and VICs
@@ -101,20 +104,29 @@ int enic_get_vnic_config(struct enic *enic)
((enic->filter_actions & FILTER_ACTION_COUNTER_FLAG) ?
 "count " : ""));
 
-   c->wq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_WQ_DESCS,
+   /* The max size of RQ and WQ rings are specified in 1500 series VICs and
+* beyond. If they are not specified by the VIC or if 64B CQ descriptors
+* are not being used, the max number of descriptors is 4096.
+*/
+   max_wq_descs = (enic->cq64_request && c->max_wq_ring) ? c->max_wq_ring :
+  ENIC_LEGACY_MAX_WQ_DESCS;
+   c->wq_desc_count = RTE_MIN(max_wq_descs,
RTE_MAX((uint32_t)ENIC_MIN_WQ_DESCS, c->wq_desc_count));
c->wq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
-
-   c->rq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_RQ_DESCS,
+   max_rq_descs = (enic->cq64_request && c->max_rq_ring) ? c->max_rq_ring
+  : ENIC_LEGACY_MAX_WQ_DESCS;
+   c->rq_desc_count = RTE_MIN(max_rq_descs,
RTE_MAX((uint32_t)ENIC_MIN_RQ_DESCS, c->rq_desc_count));
c->rq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
+   dev_debug(NULL, "Max supported VIC descriptors: WQ:%u, RQ:%u\n",
+ max_wq_descs, max_rq_descs);
 
c->intr_timer_usec = RTE_MIN(c->intr_timer_usec,
  vnic_dev_get_intr_coal_timer_max(enic->vdev));
 
dev_info(enic_get_dev(enic),
"vNIC MAC addr " RTE_ETHER_ADDR_PRT_FMT
-   "wq/rq %d/%d mtu %d, max mtu:%d\n",
+   " wq/rq %d/%d mtu %d, max mtu:%d\n",
enic->mac_addr[0], enic->mac_addr[1], enic->mac_addr[2],
enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5],
c->wq_desc_count, c->rq_desc_count,
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 34f15d5a42..ae979d52be 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -12,9 +12,11 @@
 #include "vnic_rq.h"
 
 #define ENIC_MIN_WQ_DESCS  64
-#define ENIC_MAX_WQ_DESCS  4096
 #define ENIC_MIN_RQ_DESCS  64
-#define ENIC_MAX_RQ_DESCS  4096
+
+/* 1400 series VICs and prior all have 4K max, after that it's in the config */
+#define ENIC_LEGACY_MAX_WQ_DESCS4096
+#define ENIC_LEGACY_MAX_RQ_DESCS4096
 
 /* A descriptor ring has a multiple of 32 descriptors */
 #define ENIC_ALIG

[PATCH v2] net/enic: add support for eCPRI matching

2022-01-26 Thread John Daley
eCPRI message can be over Ethernet layer (.1Q supported also) or over
UDP layer. Message header formats are the same in these two variants.

Only up though the first packet header in the PDU can be matched.
RSS on the eCPRI header fields is not supported.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
v2 - include enic.ini update

 doc/guides/nics/features/enic.ini  |  1 +
 doc/guides/rel_notes/release_22_03.rst |  1 +
 drivers/net/enic/enic_fm_flow.c| 65 ++
 3 files changed, 67 insertions(+)

diff --git a/doc/guides/nics/features/enic.ini 
b/doc/guides/nics/features/enic.ini
index c3bcead05e..88e4ef8c64 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -53,6 +53,7 @@ vlan = Y
 vxlan= Y
 geneve   = Y
 geneve_opt   = Y
+ecpri= Y
 
 [rte_flow actions]
 count= Y
diff --git a/doc/guides/rel_notes/release_22_03.rst 
b/doc/guides/rel_notes/release_22_03.rst
index b38dc54e62..52d1e32cf6 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -58,6 +58,7 @@ New Features
 * **Updated Cisco enic driver.**
 
   * Added rte_flow support for matching GENEVE packets.
+  * Added rte_flow support for matching eCPRI packets.
 
 Removed Items
 -
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 752ffeb5c5..589c9253e1 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -237,6 +237,7 @@ static enic_copy_item_fn enic_fm_copy_item_vxlan;
 static enic_copy_item_fn enic_fm_copy_item_gtp;
 static enic_copy_item_fn enic_fm_copy_item_geneve;
 static enic_copy_item_fn enic_fm_copy_item_geneve_opt;
+static enic_copy_item_fn enic_fm_copy_item_ecpri;
 
 /* Ingress actions */
 static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -392,6 +393,15 @@ static const struct enic_fm_items enic_fm_items[] = {
   RTE_FLOW_ITEM_TYPE_END,
},
},
+   [RTE_FLOW_ITEM_TYPE_ECPRI] = {
+   .copy_item = enic_fm_copy_item_ecpri,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_ETH,
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
 };
 
 static int
@@ -877,6 +887,61 @@ enic_fm_copy_item_geneve_opt(struct copy_item_args *arg)
return 0;
 }
 
+/* Match eCPRI combined message header */
+static int
+enic_fm_copy_item_ecpri(struct copy_item_args *arg)
+{
+   const struct rte_flow_item *item = arg->item;
+   const struct rte_flow_item_ecpri *spec = item->spec;
+   const struct rte_flow_item_ecpri *mask = item->mask;
+   struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+   struct fm_header_set *fm_data, *fm_mask;
+   uint8_t *fm_data_to, *fm_mask_to;
+
+   ENICPMD_FUNC_TRACE();
+
+   /* Tunneling not supported- only matching on inner eCPRI fields. */
+   if (arg->header_level > 0)
+   return -EINVAL;
+
+   /* Need both spec and mask */
+   if (!spec || !mask)
+   return -EINVAL;
+
+   fm_data = &entry->ftm_data.fk_hdrset[0];
+   fm_mask = &entry->ftm_mask.fk_hdrset[0];
+
+   /* eCPRI can only follow L2/VLAN layer if ethernet type is 0xAEFE. */
+   if (!(fm_data->fk_metadata & FKM_UDP) &&
+   (fm_mask->l2.eth.fk_ethtype != UINT16_MAX ||
+   rte_cpu_to_be_16(fm_data->l2.eth.fk_ethtype) !=
+   RTE_ETHER_TYPE_ECPRI))
+   return -EINVAL;
+
+   if (fm_data->fk_metadata & FKM_UDP) {
+   /* eCPRI on UDP */
+   fm_data->fk_header_select |= FKH_L4RAW;
+   fm_mask->fk_header_select |= FKH_L4RAW;
+   fm_data_to = &fm_data->l4.rawdata[sizeof(fm_data->l4.udp)];
+   fm_mask_to = &fm_mask->l4.rawdata[sizeof(fm_data->l4.udp)];
+   } else {
+   /* eCPRI directly after Etherent header */
+   fm_data->fk_header_select |= FKH_L3RAW;
+   fm_mask->fk_header_select |= FKH_L3RAW;
+   fm_data_to = &fm_data->l3.rawdata[0];
+   fm_mask_to = &fm_mask->l3.rawdata[0];
+   }
+
+   /*
+* Use the raw L3 or L4 buffer to match eCPRI since fm_header_set does
+* not have eCPRI header. Only 1st message header of PDU can be matched.
+* "C" * bit ignored.
+*/
+   memcpy(fm_data_to, spec, sizeof(*spec));
+   memcpy(fm_mask_to, mask, sizeof(*mask));
+   return 0;
+}
+
 /*
  * Currently, raw pattern match is very limited. It is intended for matching
  * UDP tunnel header (e.g. vxlan or geneve).
-- 
2.33.1



[PATCH 3/3] net/enic: support max descriptors allowed by adapter

2022-01-13 Thread John Daley
Newer VIC adapters have the max number of supported RX and TX
descriptors in their configuration. Use these values as the
maximums.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/cq_enet_desc.h |  6 -
 drivers/net/enic/enic_res.c  | 20 +
 drivers/net/enic/enic_res.h  |  6 +++--
 drivers/net/enic/enic_rxtx.c | 33 +++-
 4 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/drivers/net/enic/base/cq_enet_desc.h 
b/drivers/net/enic/base/cq_enet_desc.h
index a34a4f5400..02db85b9a0 100644
--- a/drivers/net/enic/base/cq_enet_desc.h
+++ b/drivers/net/enic/base/cq_enet_desc.h
@@ -67,7 +67,8 @@ struct cq_enet_rq_desc_64 {
uint16_t vlan;
uint16_t checksum_fcoe;
uint8_t flags;
-   uint8_t unused[48];
+   uint8_t fetch_idx_flags;
+   uint8_t unused[47];
uint8_t type_color;
 };
 
@@ -92,6 +93,9 @@ struct cq_enet_rq_desc_64 {
 #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS  14
 #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK \
((1 << CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS) - 1)
+#define CQ_ENET_RQ_DESC_FETCH_IDX_BITS  2
+#define CQ_ENET_RQ_DESC_FETCH_IDX_MASK \
+   ((1 << CQ_ENET_RQ_DESC_FETCH_IDX_BITS) - 1)
 #define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14)
 #define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15)
 
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 9cfb857939..caf773bab2 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -26,6 +26,7 @@ int enic_get_vnic_config(struct enic *enic)
struct vnic_enet_config *c = &enic->config;
int err;
uint64_t sizes;
+   uint32_t max_rq_descs, max_wq_descs;
 
err = vnic_dev_get_mac_addr(enic->vdev, enic->mac_addr);
if (err) {
@@ -57,6 +58,8 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(loop_tag);
GET_CONFIG(num_arfs);
GET_CONFIG(max_pkt_size);
+   GET_CONFIG(max_rq_ring);
+   GET_CONFIG(max_wq_ring);
 
/* max packet size is only defined in newer VIC firmware
 * and will be 0 for legacy firmware and VICs
@@ -101,20 +104,29 @@ int enic_get_vnic_config(struct enic *enic)
((enic->filter_actions & FILTER_ACTION_COUNTER_FLAG) ?
 "count " : ""));
 
-   c->wq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_WQ_DESCS,
+   /* The max size of RQ and WQ rings are specified in 1500 series VICs and
+* beyond. If they are not specified by the VIC or if 64B CQ descriptors
+* are not being used, the max number of descriptors is 4096.
+*/
+   max_wq_descs = (enic->cq64_request && c->max_wq_ring) ? c->max_wq_ring :
+  ENIC_LEGACY_MAX_WQ_DESCS;
+   c->wq_desc_count = RTE_MIN(max_wq_descs,
RTE_MAX((uint32_t)ENIC_MIN_WQ_DESCS, c->wq_desc_count));
c->wq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
-
-   c->rq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_RQ_DESCS,
+   max_rq_descs = (enic->cq64_request && c->max_rq_ring) ? c->max_rq_ring
+  : ENIC_LEGACY_MAX_WQ_DESCS;
+   c->rq_desc_count = RTE_MIN(max_rq_descs,
RTE_MAX((uint32_t)ENIC_MIN_RQ_DESCS, c->rq_desc_count));
c->rq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
+   dev_debug(NULL, "Max supported VIC descriptors: WQ:%u, RQ:%u\n",
+ max_wq_descs, max_rq_descs);
 
c->intr_timer_usec = RTE_MIN(c->intr_timer_usec,
  vnic_dev_get_intr_coal_timer_max(enic->vdev));
 
dev_info(enic_get_dev(enic),
"vNIC MAC addr " RTE_ETHER_ADDR_PRT_FMT
-   "wq/rq %d/%d mtu %d, max mtu:%d\n",
+   " wq/rq %d/%d mtu %d, max mtu:%d\n",
enic->mac_addr[0], enic->mac_addr[1], enic->mac_addr[2],
enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5],
c->wq_desc_count, c->rq_desc_count,
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 34f15d5a42..ae979d52be 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -12,9 +12,11 @@
 #include "vnic_rq.h"
 
 #define ENIC_MIN_WQ_DESCS  64
-#define ENIC_MAX_WQ_DESCS  4096
 #define ENIC_MIN_RQ_DESCS  64
-#define ENIC_MAX_RQ_DESCS  4096
+
+/* 1400 series VICs and prior all have 4K max, after that it's in the config */
+#define ENIC_LEGACY_MAX_WQ_DESCS4096
+#define ENIC_LEGACY_MAX_RQ_DESCS4096
 
 /* A descriptor ring has a multiple of 32 descriptors */
 #define ENIC_ALIGN_DESCS   32

[PATCH 2/3] net/enic: update VIC firmware API

2022-01-13 Thread John Daley
Update the configuration structure used between the adapter and
driver. The structure is compatible with all Cisco VIC adapters.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/vnic_enet.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/enic/base/vnic_enet.h 
b/drivers/net/enic/base/vnic_enet.h
index 2a97a33044..66261d9127 100644
--- a/drivers/net/enic/base/vnic_enet.h
+++ b/drivers/net/enic/base/vnic_enet.h
@@ -31,6 +31,28 @@ struct vnic_enet_config {
uint32_t rdma_mr_id;
uint32_t rdma_mr_count;
uint32_t max_pkt_size;
+   uint16_t vf_subvnic_count;
+   uint16_t mq_subvnic_count;
+   uint32_t mq_flags;
+
+   /* the following 3 fields are per-MQ-vnic counts */
+   uint32_t mq_rdma_mr_count;
+   uint16_t mq_rdma_qp_count;
+   uint16_t mq_rdma_resgrp;
+
+   uint16_t rdma_max_sq_ring_sz;
+   uint16_t rdma_max_rq_ring_sz;
+   uint32_t rdma_max_cq_ring_sz;
+   uint16_t rdma_max_wr_sge;
+   uint16_t rdma_max_mr_sge;
+   uint8_t rdma_max_rd_per_qp;
+   uint8_t unused; /* available */
+   uint16_t mq_rdma_engine_count;
+   uint32_t intr_coal_tick_ns; /* coalescing timer tick in nsec */
+   uint32_t max_rq_ring;   /* MAX RQ ring size */
+   uint32_t max_wq_ring;   /* MAX WQ ring size */
+   uint32_t max_cq_ring;   /* MAX CQ ring size */
+   uint32_t rdma_rsvd_lkey;/* Reserved (privileged) LKey */
 };
 
 #define VENETF_TSO 0x1 /* TSO enabled */
-- 
2.33.1



[PATCH 1/3] net/enic: add support for eCPRI matching

2022-01-13 Thread John Daley
eCPRI message can be over Ethernet layer (.1Q supported also) or over
UDP layer. Message header formats are the same in these two variants.

Only up though the first packet header in the PDU can be matched.
RSS on the eCPRI header fields is not supported.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 doc/guides/rel_notes/release_22_03.rst |  1 +
 drivers/net/enic/enic_fm_flow.c| 65 ++
 2 files changed, 66 insertions(+)

diff --git a/doc/guides/rel_notes/release_22_03.rst 
b/doc/guides/rel_notes/release_22_03.rst
index b38dc54e62..52d1e32cf6 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -58,6 +58,7 @@ New Features
 * **Updated Cisco enic driver.**
 
   * Added rte_flow support for matching GENEVE packets.
+  * Added rte_flow support for matching eCPRI packets.
 
 Removed Items
 -
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 752ffeb5c5..589c9253e1 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -237,6 +237,7 @@ static enic_copy_item_fn enic_fm_copy_item_vxlan;
 static enic_copy_item_fn enic_fm_copy_item_gtp;
 static enic_copy_item_fn enic_fm_copy_item_geneve;
 static enic_copy_item_fn enic_fm_copy_item_geneve_opt;
+static enic_copy_item_fn enic_fm_copy_item_ecpri;
 
 /* Ingress actions */
 static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -392,6 +393,15 @@ static const struct enic_fm_items enic_fm_items[] = {
   RTE_FLOW_ITEM_TYPE_END,
},
},
+   [RTE_FLOW_ITEM_TYPE_ECPRI] = {
+   .copy_item = enic_fm_copy_item_ecpri,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_ETH,
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
 };
 
 static int
@@ -877,6 +887,61 @@ enic_fm_copy_item_geneve_opt(struct copy_item_args *arg)
return 0;
 }
 
+/* Match eCPRI combined message header */
+static int
+enic_fm_copy_item_ecpri(struct copy_item_args *arg)
+{
+   const struct rte_flow_item *item = arg->item;
+   const struct rte_flow_item_ecpri *spec = item->spec;
+   const struct rte_flow_item_ecpri *mask = item->mask;
+   struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+   struct fm_header_set *fm_data, *fm_mask;
+   uint8_t *fm_data_to, *fm_mask_to;
+
+   ENICPMD_FUNC_TRACE();
+
+   /* Tunneling not supported- only matching on inner eCPRI fields. */
+   if (arg->header_level > 0)
+   return -EINVAL;
+
+   /* Need both spec and mask */
+   if (!spec || !mask)
+   return -EINVAL;
+
+   fm_data = &entry->ftm_data.fk_hdrset[0];
+   fm_mask = &entry->ftm_mask.fk_hdrset[0];
+
+   /* eCPRI can only follow L2/VLAN layer if ethernet type is 0xAEFE. */
+   if (!(fm_data->fk_metadata & FKM_UDP) &&
+   (fm_mask->l2.eth.fk_ethtype != UINT16_MAX ||
+   rte_cpu_to_be_16(fm_data->l2.eth.fk_ethtype) !=
+   RTE_ETHER_TYPE_ECPRI))
+   return -EINVAL;
+
+   if (fm_data->fk_metadata & FKM_UDP) {
+   /* eCPRI on UDP */
+   fm_data->fk_header_select |= FKH_L4RAW;
+   fm_mask->fk_header_select |= FKH_L4RAW;
+   fm_data_to = &fm_data->l4.rawdata[sizeof(fm_data->l4.udp)];
+   fm_mask_to = &fm_mask->l4.rawdata[sizeof(fm_data->l4.udp)];
+   } else {
+   /* eCPRI directly after Etherent header */
+   fm_data->fk_header_select |= FKH_L3RAW;
+   fm_mask->fk_header_select |= FKH_L3RAW;
+   fm_data_to = &fm_data->l3.rawdata[0];
+   fm_mask_to = &fm_mask->l3.rawdata[0];
+   }
+
+   /*
+* Use the raw L3 or L4 buffer to match eCPRI since fm_header_set does
+* not have eCPRI header. Only 1st message header of PDU can be matched.
+* "C" * bit ignored.
+*/
+   memcpy(fm_data_to, spec, sizeof(*spec));
+   memcpy(fm_mask_to, mask, sizeof(*mask));
+   return 0;
+}
+
 /*
  * Currently, raw pattern match is very limited. It is intended for matching
  * UDP tunnel header (e.g. vxlan or geneve).
-- 
2.33.1



[PATCH 0/3] enic PMD patches

2022-01-13 Thread John Daley
Here are a couple patches to the enic PMD that should apply on top of
the patch:
'net/enic: support GENEVE flow item' by Hyong Youb Kim.

John Daley (3):
  net/enic: add support for eCPRI matching
  net/enic: update VIC firmware API
  net/enic: support max descriptors allowed by adapter

 doc/guides/rel_notes/release_22_03.rst |  1 +
 drivers/net/enic/base/cq_enet_desc.h   |  6 ++-
 drivers/net/enic/base/vnic_enet.h  | 22 +
 drivers/net/enic/enic_fm_flow.c| 65 ++
 drivers/net/enic/enic_res.c| 20 ++--
 drivers/net/enic/enic_res.h|  6 ++-
 drivers/net/enic/enic_rxtx.c   | 33 +
 7 files changed, 136 insertions(+), 17 deletions(-)

-- 
2.33.1



[dpdk-dev] [PATCH v3] net/enic: support GTP header flow matching

2021-10-28 Thread John Daley
The GTP, GTP-U, GTP-C header fields can be matched, however NIC does not
support GTP tunneling so no items after the GTP header can be specified.
If a GTP-U or GTP-C item is specified without a preceding UDP item, the
UDP destination port is implicitly matched. For GTP, the destination UDP
port must be specified but its value is not enforced.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
v2: Fixed specification of the max enic flowman item
v3: Fixed endianness of UDP dst port

 doc/guides/nics/enic.rst   |   2 +
 doc/guides/nics/features/enic.ini  |   3 +
 doc/guides/rel_notes/release_21_11.rst |   4 +
 drivers/net/enic/enic_fm_flow.c| 123 -
 4 files changed, 128 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index f2ee49fe82..5e2054fc8a 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -473,6 +473,8 @@ RTE_MBUF_F_RX_VLAN_STRIPPED mbuf flags would not be set. 
This mode is enabled wi
 packets and then receive them normally. These require 1400 series VIC 
adapters
 and latest firmware.
   - RAW items are limited to matching UDP tunnel headers like VXLAN.
+  - GTP, GTP-C and GTP-U header matching is enabled, however matching items 
within
+the tunnel is not supported.
   - For 1400 VICs, all flows using the RSS action on a port use same hash
 configuration. The RETA is ignored. The queues used in the RSS group must 
be
 sequential. There is a performance hit if the number of queues is not a 
power of 2.
diff --git a/doc/guides/nics/features/enic.ini 
b/doc/guides/nics/features/enic.ini
index 3064336162..1177752c15 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -40,6 +40,9 @@ Usage doc= Y
 
 [rte_flow items]
 eth  = Y
+gtp  = Y
+gtpc = Y
+gtpu = Y
 ipv4 = Y
 ipv6 = Y
 raw  = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst 
b/doc/guides/rel_notes/release_21_11.rst
index 1ccac87b73..2cee5347f3 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -154,6 +154,10 @@ New Features
   * Implement support for tunnel offload.
   * Updated HWRM API to version 1.10.2.44
 
+* **Updated Cisco enic driver.**
+
+  * Added rte_flow support for matching GTP, GTP-C and GTP-U headers.
+
 * **Updated Intel e1000 emulated driver.**
 
   * Added Intel e1000 support on Windows.
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 2c60bb864e..ae43f36bc0 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -22,9 +22,6 @@
 #define IP_DEFTTL  64   /* from RFC 1340. */
 #define IP6_VTC_FLOW 0x6000
 
-/* Highest Item type supported by Flowman */
-#define FM_MAX_ITEM_TYPE RTE_FLOW_ITEM_TYPE_VXLAN
-
 /* Up to 1024 TCAM entries */
 #define FM_MAX_TCAM_TABLE_SIZE 1024
 
@@ -235,6 +232,7 @@ static enic_copy_item_fn enic_fm_copy_item_tcp;
 static enic_copy_item_fn enic_fm_copy_item_udp;
 static enic_copy_item_fn enic_fm_copy_item_vlan;
 static enic_copy_item_fn enic_fm_copy_item_vxlan;
+static enic_copy_item_fn enic_fm_copy_item_gtp;
 
 /* Ingress actions */
 static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -346,6 +344,30 @@ static const struct enic_fm_items enic_fm_items[] = {
   RTE_FLOW_ITEM_TYPE_END,
},
},
+   [RTE_FLOW_ITEM_TYPE_GTP] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 0,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
+   [RTE_FLOW_ITEM_TYPE_GTPC] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
+   [RTE_FLOW_ITEM_TYPE_GTPU] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
 };
 
 static int
@@ -629,6 +651,99 @@ enic_fm_copy_item_vxlan(struct copy_item_args *arg)
return 0;
 }
 
+static int
+enic_fm_copy_item_gtp(struct copy_item_args *arg)
+{
+   const struct rte_flow_item *item = arg->item;
+   const struct rte_flow_item_gtp *spec = item->spec;
+   const struct rte_flow_item_gtp *mask = item->mask;
+   struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+   struct f

[dpdk-dev] [PATCH v2] net/enic: support GTP header flow matching

2021-10-27 Thread John Daley
The GTP, GTP-U, GTP-C header fields can be matched, however NIC does not
support GTP tunneling so no items after the GTP header can be specified.
If a GTP-U or GTP-C item is specified without a preceding UDP item, the
UDP destination port is implicitly matched. For GTP, the destination UDP
port must be specified but its value is not enforced.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
v2: Fixed specification of the max enic flowman item

 doc/guides/nics/enic.rst   |   2 +
 doc/guides/nics/features/enic.ini  |   3 +
 doc/guides/rel_notes/release_21_11.rst |   4 +
 drivers/net/enic/enic_fm_flow.c| 124 -
 4 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index f2ee49fe82..5e2054fc8a 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -473,6 +473,8 @@ RTE_MBUF_F_RX_VLAN_STRIPPED mbuf flags would not be set. 
This mode is enabled wi
 packets and then receive them normally. These require 1400 series VIC 
adapters
 and latest firmware.
   - RAW items are limited to matching UDP tunnel headers like VXLAN.
+  - GTP, GTP-C and GTP-U header matching is enabled, however matching items 
within
+the tunnel is not supported.
   - For 1400 VICs, all flows using the RSS action on a port use same hash
 configuration. The RETA is ignored. The queues used in the RSS group must 
be
 sequential. There is a performance hit if the number of queues is not a 
power of 2.
diff --git a/doc/guides/nics/features/enic.ini 
b/doc/guides/nics/features/enic.ini
index 3064336162..1177752c15 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -40,6 +40,9 @@ Usage doc= Y
 
 [rte_flow items]
 eth  = Y
+gtp  = Y
+gtpc = Y
+gtpu = Y
 ipv4 = Y
 ipv6 = Y
 raw  = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst 
b/doc/guides/rel_notes/release_21_11.rst
index 1ccac87b73..2cee5347f3 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -154,6 +154,10 @@ New Features
   * Implement support for tunnel offload.
   * Updated HWRM API to version 1.10.2.44
 
+* **Updated Cisco enic driver.**
+
+  * Added rte_flow support for matching GTP, GTP-C and GTP-U headers.
+
 * **Updated Intel e1000 emulated driver.**
 
   * Added Intel e1000 support on Windows.
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 2c60bb864e..48ea1d0ff9 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -22,9 +22,6 @@
 #define IP_DEFTTL  64   /* from RFC 1340. */
 #define IP6_VTC_FLOW 0x6000
 
-/* Highest Item type supported by Flowman */
-#define FM_MAX_ITEM_TYPE RTE_FLOW_ITEM_TYPE_VXLAN
-
 /* Up to 1024 TCAM entries */
 #define FM_MAX_TCAM_TABLE_SIZE 1024
 
@@ -235,6 +232,7 @@ static enic_copy_item_fn enic_fm_copy_item_tcp;
 static enic_copy_item_fn enic_fm_copy_item_udp;
 static enic_copy_item_fn enic_fm_copy_item_vlan;
 static enic_copy_item_fn enic_fm_copy_item_vxlan;
+static enic_copy_item_fn enic_fm_copy_item_gtp;
 
 /* Ingress actions */
 static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -346,6 +344,30 @@ static const struct enic_fm_items enic_fm_items[] = {
   RTE_FLOW_ITEM_TYPE_END,
},
},
+   [RTE_FLOW_ITEM_TYPE_GTP] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 0,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
+   [RTE_FLOW_ITEM_TYPE_GTPC] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
+   [RTE_FLOW_ITEM_TYPE_GTPU] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
 };
 
 static int
@@ -629,6 +651,100 @@ enic_fm_copy_item_vxlan(struct copy_item_args *arg)
return 0;
 }
 
+static int
+enic_fm_copy_item_gtp(struct copy_item_args *arg)
+{
+   const struct rte_flow_item *item = arg->item;
+   const struct rte_flow_item_gtp *spec = item->spec;
+   const struct rte_flow_item_gtp *mask = item->mask;
+   struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+   struct fm_header_set *fm_data, *fm_mask;
+  

[dpdk-dev] [PATCH] net/enic: support GTP header flow matching

2021-10-25 Thread John Daley
The GTP, GTP-U, GTP-C header fields can be matched, however NIC does not
support GTP tunneling so no items after the GTP header can be specified.
If a GTP-U or GTP-C item is specified without a preceding UDP item, the
UDP destination port is implicitly matched. For GTP, the destination UDP
port must be specified but its value is not enforced.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 doc/guides/nics/enic.rst   |   2 +
 doc/guides/nics/features/enic.ini  |   3 +
 doc/guides/rel_notes/release_21_11.rst |   4 +
 drivers/net/enic/enic_fm_flow.c| 119 +
 4 files changed, 128 insertions(+)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index f2ee49fe82..5e2054fc8a 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -473,6 +473,8 @@ RTE_MBUF_F_RX_VLAN_STRIPPED mbuf flags would not be set. 
This mode is enabled wi
 packets and then receive them normally. These require 1400 series VIC 
adapters
 and latest firmware.
   - RAW items are limited to matching UDP tunnel headers like VXLAN.
+  - GTP, GTP-C and GTP-U header matching is enabled, however matching items 
within
+the tunnel is not supported.
   - For 1400 VICs, all flows using the RSS action on a port use same hash
 configuration. The RETA is ignored. The queues used in the RSS group must 
be
 sequential. There is a performance hit if the number of queues is not a 
power of 2.
diff --git a/doc/guides/nics/features/enic.ini 
b/doc/guides/nics/features/enic.ini
index 3064336162..1177752c15 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -40,6 +40,9 @@ Usage doc= Y
 
 [rte_flow items]
 eth  = Y
+gtp  = Y
+gtpc = Y
+gtpu = Y
 ipv4 = Y
 ipv6 = Y
 raw  = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst 
b/doc/guides/rel_notes/release_21_11.rst
index 1ccac87b73..2cee5347f3 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -154,6 +154,10 @@ New Features
   * Implement support for tunnel offload.
   * Updated HWRM API to version 1.10.2.44
 
+* **Updated Cisco enic driver.**
+
+  * Added rte_flow support for matching GTP, GTP-C and GTP-U headers.
+
 * **Updated Intel e1000 emulated driver.**
 
   * Added Intel e1000 support on Windows.
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 2c60bb864e..e318a5f828 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -235,6 +235,7 @@ static enic_copy_item_fn enic_fm_copy_item_tcp;
 static enic_copy_item_fn enic_fm_copy_item_udp;
 static enic_copy_item_fn enic_fm_copy_item_vlan;
 static enic_copy_item_fn enic_fm_copy_item_vxlan;
+static enic_copy_item_fn enic_fm_copy_item_gtp;
 
 /* Ingress actions */
 static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -346,6 +347,30 @@ static const struct enic_fm_items enic_fm_items[] = {
   RTE_FLOW_ITEM_TYPE_END,
},
},
+   [RTE_FLOW_ITEM_TYPE_GTP] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 0,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
+   [RTE_FLOW_ITEM_TYPE_GTPC] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
+   [RTE_FLOW_ITEM_TYPE_GTPU] = {
+   .copy_item = enic_fm_copy_item_gtp,
+   .valid_start_item = 1,
+   .prev_items = (const enum rte_flow_item_type[]) {
+  RTE_FLOW_ITEM_TYPE_UDP,
+  RTE_FLOW_ITEM_TYPE_END,
+   },
+   },
 };
 
 static int
@@ -629,6 +654,100 @@ enic_fm_copy_item_vxlan(struct copy_item_args *arg)
return 0;
 }
 
+static int
+enic_fm_copy_item_gtp(struct copy_item_args *arg)
+{
+   const struct rte_flow_item *item = arg->item;
+   const struct rte_flow_item_gtp *spec = item->spec;
+   const struct rte_flow_item_gtp *mask = item->mask;
+   struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+   struct fm_header_set *fm_data, *fm_mask;
+   int off;
+   uint16_t udp_gtp_uc_port = 0;
+
+   ENICPMD_FUNC_TRACE();
+   /* Only 2 header levels (outer and inner) allowed */
+   if (arg->header_level > 0)
+   return -EINVAL;
+
+   fm_data = &entry->ftm_data.fk_hdrset[0];
+   fm_mask = &entry->ftm_mask.fk_hdrset[

[dpdk-dev] [PATCH v1] net/enic: enable GENEVE offload via VNIC configuration

2021-05-11 Thread John Daley
The admin-configured vNIC settings (i.e. via CIMC or UCSM) now include
Geneve offload. Use that setting to decide whether to enable or
disable Geneve offload and remove the devarg 'geneve-opt'.

Also, the firmware now allows the driver to change the Geneve port
number. So extend udp_tunnel_port_{add,del} to accept Geneve port, in
addition to VXLAN.

Fixes: 93fb21fdbe23 ("net/enic: enable overlay offload for VXLAN and GENEVE")
Cc: sta...@dpdk.org

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---

v1: update release notes

 doc/guides/nics/enic.rst   |  32 +++--
 doc/guides/rel_notes/release_20_05.rst |   7 ++
 drivers/net/enic/base/vnic_dev.c   |   2 +-
 drivers/net/enic/base/vnic_enet.h  |   1 +
 drivers/net/enic/enic.h|   4 +-
 drivers/net/enic/enic_ethdev.c |  71 ++-
 drivers/net/enic/enic_main.c   | 161 +++--
 drivers/net/enic/enic_res.c|   7 +-
 8 files changed, 161 insertions(+), 124 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 4e7629c5cd..91bdcd065a 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -294,35 +294,31 @@ inner and outer packets can be IPv4 or IPv6.
 
   RSS hash calculation, therefore queue selection, is done on inner packets.
 
-In order to enable overlay offload, the 'Enable VXLAN' box should be checked
+In order to enable overlay offload, enable VXLAN and/or Geneve on vNIC
 via CIMC or UCSM followed by a reboot of the server. When PMD successfully
-enables overlay offload, it prints the following message on the console.
+enables overlay offload, it prints one of the following messages on the 
console.
 
 .. code-block:: console
 
-Overlay offload is enabled
+Overlay offload is enabled (VxLAN)
+Overlay offload is enabled (Geneve)
+Overlay offload is enabled (VxLAN, Geneve)
 
 By default, PMD enables overlay offload if hardware supports it. To disable
 it, set ``devargs`` parameter ``disable-overlay=1``. For example::
 
 -a 12:00.0,disable-overlay=1
 
-By default, the NIC uses 4789 as the VXLAN port. The user may change
-it through ``rte_eth_dev_udp_tunnel_port_{add,delete}``. However, as
-the current NIC has a single VXLAN port number, the user cannot
-configure multiple port numbers.
-
-Geneve headers with non-zero options are not supported by default. To
-use Geneve with options, update the VIC firmware to the latest version
-and then set ``devargs`` parameter ``geneve-opt=1``. When Geneve with
-options is enabled, flow API cannot be used as the features are
-currently mutually exclusive. When this feature is successfully
-enabled, PMD prints the following message.
-
-.. code-block:: console
-
-Geneve with options is enabled
+By default, the NIC uses 4789 and 6081 as the VXLAN and Geneve ports,
+respectively. The user may change them through
+``rte_eth_dev_udp_tunnel_port_{add,delete}``. However, as the current
+NIC has a single VXLAN port number and a single Geneve port number,
+the user cannot configure multiple port numbers for each tunnel type.
 
+Geneve offload support has evolved over VIC models. On older models,
+Geneve offload and advanced filters are mutually exclusive.  This is
+enforced by UCSM and CIMC, which only allow one of the two features
+to be selected at one time. Newer VIC models do not have this restriction.
 
 Ingress VLAN Rewrite
 
diff --git a/doc/guides/rel_notes/release_20_05.rst 
b/doc/guides/rel_notes/release_20_05.rst
index 985c845de4..81cd4b5d2e 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -178,6 +178,13 @@ New Features
   * Added support for flow patterns with wildcard VLAN items (without VID 
value).
   * Updated support for matching on GTP headers, added match on GTP flags.
 
+* **Updated Cisco enic driver.**
+
+  Updated Cisco enic driver GENEVE tunneling support:
+
+  * Added support to control GENEVE tunneling via UCSM/CIMC and removed devarg.
+  * Added GENEVE port number configuration.
+
 * **Added Chacha20-Poly1305 algorithm to Cryptodev API.**
 
   Added support for Chacha20-Poly1305 AEAD algorithm in Cryptodev.
diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index 526273cef5..55c08eb3dc 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -1318,7 +1318,7 @@ int vnic_dev_capable_geneve(struct vnic_dev *vdev)
int ret;
 
ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, &a1, wait);
-   return ret == 0 && (a1 & FEATURE_GENEVE_OPTIONS);
+   return ret == 0 && !!(a1 & FEATURE_GENEVE_OPTIONS);
 }
 
 uint64_t vnic_dev_capable_cq_entry_size(struct vnic_dev *vdev)
diff --git a/drivers/net/enic/base/vnic_enet.h 
b/drivers/net/enic/base/vnic_enet.h
index 7687951c90..2a97a33044 100644
--- a/drivers/net/enic/base/vnic_enet.h
++

[dpdk-dev] [PATCH] net/enic: enable GENEVE offload via VNIC configuration

2021-05-05 Thread John Daley
The admin-configured vNIC settings (i.e. via CIMC or UCSM) now include
Geneve offload. Use that setting to decide whether to enable or
disable Geneve offload and remove the devarg 'geneve-opt'.

Also, the firmware now allows the driver to change the Geneve port
number. So extend udp_tunnel_port_{add,del} to accept Geneve port, in
addition to VXLAN.

Fixes: 93fb21fdbe23 ("net/enic: enable overlay offload for VXLAN and GENEVE")
Cc: sta...@dpdk.org

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 doc/guides/nics/enic.rst  |  32 +++---
 drivers/net/enic/base/vnic_dev.c  |   2 +-
 drivers/net/enic/base/vnic_enet.h |   1 +
 drivers/net/enic/enic.h   |   4 +-
 drivers/net/enic/enic_ethdev.c|  71 +++--
 drivers/net/enic/enic_main.c  | 161 +-
 drivers/net/enic/enic_res.c   |   7 +-
 7 files changed, 154 insertions(+), 124 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 4e7629c5cd..91bdcd065a 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -294,35 +294,31 @@ inner and outer packets can be IPv4 or IPv6.
 
   RSS hash calculation, therefore queue selection, is done on inner packets.
 
-In order to enable overlay offload, the 'Enable VXLAN' box should be checked
+In order to enable overlay offload, enable VXLAN and/or Geneve on vNIC
 via CIMC or UCSM followed by a reboot of the server. When PMD successfully
-enables overlay offload, it prints the following message on the console.
+enables overlay offload, it prints one of the following messages on the 
console.
 
 .. code-block:: console
 
-Overlay offload is enabled
+Overlay offload is enabled (VxLAN)
+Overlay offload is enabled (Geneve)
+Overlay offload is enabled (VxLAN, Geneve)
 
 By default, PMD enables overlay offload if hardware supports it. To disable
 it, set ``devargs`` parameter ``disable-overlay=1``. For example::
 
 -a 12:00.0,disable-overlay=1
 
-By default, the NIC uses 4789 as the VXLAN port. The user may change
-it through ``rte_eth_dev_udp_tunnel_port_{add,delete}``. However, as
-the current NIC has a single VXLAN port number, the user cannot
-configure multiple port numbers.
-
-Geneve headers with non-zero options are not supported by default. To
-use Geneve with options, update the VIC firmware to the latest version
-and then set ``devargs`` parameter ``geneve-opt=1``. When Geneve with
-options is enabled, flow API cannot be used as the features are
-currently mutually exclusive. When this feature is successfully
-enabled, PMD prints the following message.
-
-.. code-block:: console
-
-Geneve with options is enabled
+By default, the NIC uses 4789 and 6081 as the VXLAN and Geneve ports,
+respectively. The user may change them through
+``rte_eth_dev_udp_tunnel_port_{add,delete}``. However, as the current
+NIC has a single VXLAN port number and a single Geneve port number,
+the user cannot configure multiple port numbers for each tunnel type.
 
+Geneve offload support has evolved over VIC models. On older models,
+Geneve offload and advanced filters are mutually exclusive.  This is
+enforced by UCSM and CIMC, which only allow one of the two features
+to be selected at one time. Newer VIC models do not have this restriction.
 
 Ingress VLAN Rewrite
 
diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index 526273cef5..55c08eb3dc 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -1318,7 +1318,7 @@ int vnic_dev_capable_geneve(struct vnic_dev *vdev)
int ret;
 
ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, &a1, wait);
-   return ret == 0 && (a1 & FEATURE_GENEVE_OPTIONS);
+   return ret == 0 && !!(a1 & FEATURE_GENEVE_OPTIONS);
 }
 
 uint64_t vnic_dev_capable_cq_entry_size(struct vnic_dev *vdev)
diff --git a/drivers/net/enic/base/vnic_enet.h 
b/drivers/net/enic/base/vnic_enet.h
index 7687951c90..2a97a33044 100644
--- a/drivers/net/enic/base/vnic_enet.h
+++ b/drivers/net/enic/base/vnic_enet.h
@@ -55,6 +55,7 @@ struct vnic_enet_config {
 #define VENETF_NICSWITCH0x8 /* NICSWITCH enabled */
 #define VENETF_RSSHASH_UDPIPV4  0x10 /* Hash on UDP + IPv4 fields */
 #define VENETF_RSSHASH_UDPIPV6  0x20 /* Hash on UDP + IPv6 fields */
+#define VENETF_GENEVE  0x40 /* GENEVE offload */
 
 #define VENET_INTR_TYPE_MIN0   /* Timer specs min interrupt spacing */
 #define VENET_INTR_TYPE_IDLE   1   /* Timer specs idle time before irq */
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index cd66348f2f..47bfdac2cf 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -118,17 +118,17 @@ struct enic {
uint32_t flow_filter_mode;
uint8_t filter_actions; /* HW supported actions */
uint64_t cq_entry_sizes; /* supported CQ entry sizes

[dpdk-dev] [PATCH v1] net/enic: fix completion pointer calculation

2021-04-12 Thread John Daley
The completion queue index could be implicitly extended past its
uint16_t size when multiplied by the size of the descriptor. While
this should not be a problem, coverity flags it. Do the extension
explicitly by casting the index to uintptr_t.

Coverity issue: 161317
Fixes: 8b428cb5a92e ("net/enic: use 64B completion queue entries if available")
Cc: sta...@dpdk.org

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
v1: fix typo

 drivers/net/enic/enic_rxtx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index a2a02227e3..3899907d6d 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -70,7 +70,7 @@ enic_recv_pkts_common(void *rx_queue, struct rte_mbuf 
**rx_pkts,
cq = &enic->cq[enic_cq_rq(enic, sop_rq->index)];
cq_idx = cq->to_clean;  /* index of cqd, rqd, mbuf_table */
cqd_ptr = (struct cq_desc *)((uintptr_t)(cq->ring.descs) +
-cq_idx * desc_size);
+(uintptr_t)cq_idx * desc_size);
color = cq->last_color;
 
data_rq = &enic->rq[sop_rq->data_queue_idx];
@@ -126,7 +126,7 @@ enic_recv_pkts_common(void *rx_queue, struct rte_mbuf 
**rx_pkts,
 
/* Prefetch next mbuf & desc while processing current one */
cqd_ptr = (struct cq_desc *)((uintptr_t)(cq->ring.descs) +
-cq_idx * desc_size);
+(uintptr_t)cq_idx * desc_size);
rte_enic_prefetch(cqd_ptr);
 
ciflags = enic_cq_rx_desc_ciflags(
-- 
2.26.2



[dpdk-dev] [PATCH] net/enic: fix completion pointer calculation

2021-04-12 Thread John Daley
The completion queue index could be implicitly extended past its
uint16_t size when multiplied by the size of the descriptor. While
this should not be a problem, coverity flags it. Do the extention
explicitly by casting the index to uintptr_t.

Coverity issue: 161317
Fixes: 8b428cb5a92e ("net/enic: use 64B completion queue entries if available")
Cc: sta...@dpdk.org

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_rxtx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index a2a02227e3..3899907d6d 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -70,7 +70,7 @@ enic_recv_pkts_common(void *rx_queue, struct rte_mbuf 
**rx_pkts,
cq = &enic->cq[enic_cq_rq(enic, sop_rq->index)];
cq_idx = cq->to_clean;  /* index of cqd, rqd, mbuf_table */
cqd_ptr = (struct cq_desc *)((uintptr_t)(cq->ring.descs) +
-cq_idx * desc_size);
+(uintptr_t)cq_idx * desc_size);
color = cq->last_color;
 
data_rq = &enic->rq[sop_rq->data_queue_idx];
@@ -126,7 +126,7 @@ enic_recv_pkts_common(void *rx_queue, struct rte_mbuf 
**rx_pkts,
 
/* Prefetch next mbuf & desc while processing current one */
cqd_ptr = (struct cq_desc *)((uintptr_t)(cq->ring.descs) +
-cq_idx * desc_size);
+(uintptr_t)cq_idx * desc_size);
rte_enic_prefetch(cqd_ptr);
 
ciflags = enic_cq_rx_desc_ciflags(
-- 
2.26.2



[dpdk-dev] [PATCH] net/enic: fix flow initialization error handling

2021-04-08 Thread John Daley
Fix a rare case in rte_flow initialization where the action hash table
is not freed if allocating a NIC match table fails.

Fixes: ea7768b5bba8 ("net/enic: add flow implementation based on Flow Manager 
API")
Cc: sta...@dpdk.org

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_fm_flow.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 21d9b1cef7..cd364ee16b 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -2890,7 +2890,7 @@ enic_fm_init(struct enic *enic)
rc = enic_fm_init_actions(fm);
if (rc) {
ENICPMD_LOG(ERR, "cannot create action hash, error:%d", rc);
-   goto error_tables;
+   goto error_counters;
}
/*
 * One default exact match table for each direction. We hold onto
@@ -2899,7 +2899,7 @@ enic_fm_init(struct enic *enic)
rc = enic_fet_alloc(fm, 1, NULL, 128, &fm->default_ig_fet);
if (rc) {
ENICPMD_LOG(ERR, "cannot alloc default IG exact match table");
-   goto error_counters;
+   goto error_actions;
}
fm->default_ig_fet->ref = 1;
rc = enic_fet_alloc(fm, 0, NULL, 128, &fm->default_eg_fet);
@@ -2914,6 +2914,8 @@ enic_fm_init(struct enic *enic)
 
 error_ig_fet:
enic_fet_free(fm, fm->default_ig_fet);
+error_actions:
+   rte_hash_free(fm->action_hash);
 error_counters:
enic_fm_free_all_counters(fm);
 error_tables:
-- 
2.26.2



[dpdk-dev] [PATCH] net/enic: remove deprecated FDIR code

2020-12-16 Thread John Daley
The Flow Director (FDIR) API was removed in release 20.11.
This patch removes the remainder of the FDIR code in the
PMD.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic.h   |  23 --
 drivers/net/enic/enic_clsf.c  | 334 --
 drivers/net/enic/enic_flow.c  |   5 +-
 drivers/net/enic/enic_fm_flow.c   |   4 +
 drivers/net/enic/enic_main.c  |   7 -
 drivers/net/enic/enic_rxtx_vec_avx2.c |   5 -
 drivers/net/enic/meson.build  |   1 -
 7 files changed, 8 insertions(+), 371 deletions(-)
 delete mode 100644 drivers/net/enic/enic_clsf.c

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 079f194275..4ee75253cc 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -51,8 +51,6 @@
 /* Special Filter id for non-specific packet flagging. Don't change value */
 #define ENIC_MAGIC_FILTER_ID 0x
 
-#define ENICPMD_FDIR_MAX   64
-
 /*
  * Interrupt 0: LSC and errors
  * Interrupt 1: rx queue 0
@@ -62,23 +60,6 @@
 #define ENICPMD_LSC_INTR_OFFSET 0
 #define ENICPMD_RXQ_INTR_OFFSET 1
 
-struct enic_fdir_node {
-   struct rte_eth_fdir_filter filter;
-   uint16_t fltr_id;
-   uint16_t rq_index;
-};
-
-struct enic_fdir {
-   struct rte_eth_fdir_stats stats;
-   struct rte_hash *hash;
-   struct enic_fdir_node *nodes[ENICPMD_FDIR_MAX];
-   uint32_t modes;
-   uint32_t types_mask;
-   void (*copy_fltr_fn)(struct filter_v2 *filt,
-const struct rte_eth_fdir_input *input,
-const struct rte_eth_fdir_masks *masks);
-};
-
 struct enic_soft_stats {
rte_atomic64_t rx_nombuf;
rte_atomic64_t rx_packet_errors;
@@ -120,7 +101,6 @@ struct enic {
bool overlay_offload;
struct rte_eth_dev *rte_dev;
struct rte_eth_dev_data *dev_data;
-   struct enic_fdir fdir;
char bdf_name[ENICPMD_BDF_LENGTH];
int dev_fd;
int iommu_group_fd;
@@ -431,8 +411,6 @@ void enic_send_pkt(struct enic *enic, struct vnic_wq *wq,
 
 void enic_post_wq_index(struct vnic_wq *wq);
 int enic_probe(struct enic *enic);
-int enic_clsf_init(struct enic *enic);
-void enic_clsf_destroy(struct enic *enic);
 int enic_fm_init(struct enic *enic);
 void enic_fm_destroy(struct enic *enic);
 void *enic_alloc_consistent(void *priv, size_t size, dma_addr_t *dma_handle,
@@ -457,7 +435,6 @@ int enic_link_update(struct rte_eth_dev *eth_dev);
 bool enic_use_vector_rx_handler(struct rte_eth_dev *eth_dev);
 void enic_pick_rx_handler(struct rte_eth_dev *eth_dev);
 void enic_pick_tx_handler(struct rte_eth_dev *eth_dev);
-void enic_fdir_info(struct enic *enic);
 int enic_vf_representor_init(struct rte_eth_dev *eth_dev, void *init_params);
 int enic_vf_representor_uninit(struct rte_eth_dev *ethdev);
 int enic_fm_allocate_switch_domain(struct enic *pf);
diff --git a/drivers/net/enic/enic_clsf.c b/drivers/net/enic/enic_clsf.c
deleted file mode 100644
index 1c837a4d09..00
--- a/drivers/net/enic/enic_clsf.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2008-2017 Cisco Systems, Inc.  All rights reserved.
- * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "enic_compat.h"
-#include "enic.h"
-#include "wq_enet_desc.h"
-#include "rq_enet_desc.h"
-#include "cq_enet_desc.h"
-#include "vnic_enet.h"
-#include "vnic_dev.h"
-#include "vnic_wq.h"
-#include "vnic_rq.h"
-#include "vnic_cq.h"
-#include "vnic_intr.h"
-#include "vnic_nic.h"
-
-#ifdef RTE_ARCH_X86
-#include 
-#define DEFAULT_HASH_FUNC   rte_hash_crc
-#else
-#include 
-#define DEFAULT_HASH_FUNC   rte_jhash
-#endif
-
-#define ENICPMD_CLSF_HASH_ENTRIES   ENICPMD_FDIR_MAX
-
-static void copy_fltr_v1(struct filter_v2 *fltr,
-   const struct rte_eth_fdir_input *input,
-   const struct rte_eth_fdir_masks *masks);
-static void copy_fltr_v2(struct filter_v2 *fltr,
-   const struct rte_eth_fdir_input *input,
-   const struct rte_eth_fdir_masks *masks);
-
-void enic_fdir_info(struct enic *enic)
-{
-   enic->fdir.modes = (uint32_t)RTE_FDIR_MODE_PERFECT;
-   enic->fdir.types_mask  = 1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP |
-1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP;
-   if (enic->adv_filters) {
-   enic->fdir.types_mask |= 1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER |
-1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP |
-1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP |
-1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP |
-  

[dpdk-dev] [PATCH] net/enic: check return code

2020-10-14 Thread John Daley
Coverity issue: 363046
Fixes: bb66d562aefc ("net/enic: share flow actions with same signature")

Signed-off-by: John Daley 
---
 drivers/net/enic/enic_fm_flow.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 96ec360a85..9cea94269c 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -2232,7 +2232,11 @@ enic_action_handle_get(struct enic_flowman *fm, struct 
fm_action *action_in,
 error_with_action_handle:
args[0] = FM_ACTION_FREE;
args[1] = ah->handle;
-   flowman_cmd(fm, args, 2);
+   ret = flowman_cmd(fm, args, 2);
+   if (ret != 0)
+   rte_flow_error_set(error, -ret,
+  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+  NULL, "enic: devcmd(action-free)");
 error_with_ah:
free(ah);
return ret;
-- 
2.26.2



[dpdk-dev] [PATCH] net/enic: share flow actions with the same signature

2020-09-29 Thread John Daley
Flow actions are a limited resource on the Cisco VIC, but they
can be shared between flows if they are exactly the same.
Use a hash table and a reference count in the PMD to enable sharing
actions with the same signature between flows.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_fm_flow.c | 175 +---
 1 file changed, 141 insertions(+), 34 deletions(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 34c9005ee2..96ec360a85 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -8,6 +8,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -43,6 +45,9 @@
 /* Tag used for implicit VF <-> representor flows */
 #define FM_VF_REP_TAG 1
 
+/* Max number of actions supported by VIC is 2K. Make hash table double that. 
*/
+#define FM_MAX_ACTION_TABLE_SIZE 4096
+
 /*
  * Flow exact match tables (FET) in the VIC and rte_flow groups.
  * Use a simple scheme to map groups to tables.
@@ -90,11 +95,17 @@ struct enic_fm_counter {
uint32_t handle;
 };
 
+struct enic_fm_action {
+   int ref;
+   uint64_t handle;
+   struct fm_action key;
+};
+
 /* rte_flow.fm */
 struct enic_fm_flow {
bool counter_valid;
uint64_t entry_handle;
-   uint64_t action_handle;
+   struct enic_fm_action  *action;
struct enic_fm_counter *counter;
struct enic_fm_fet *fet;
/* Auto-added steer action for hairpin flows (e.g. vnic->vnic) */
@@ -155,6 +166,8 @@ struct enic_flowman {
 */
struct enic_fm_fet *default_eg_fet;
struct enic_fm_fet *default_ig_fet;
+   /* hash table for Action reuse */
+   struct rte_hash *action_hash;
/* Flows that jump to the default table above */
TAILQ_HEAD(jump_flow_list, enic_fm_jump_flow) jump_list;
/*
@@ -1953,19 +1966,26 @@ enic_fm_counter_alloc(struct enic_flowman *fm, struct 
rte_flow_error *error,
 }
 
 static int
-enic_fm_action_free(struct enic_flowman *fm, uint64_t handle)
+enic_fm_action_free(struct enic_flowman *fm, struct enic_fm_action *ah)
 {
uint64_t args[2];
-   int rc;
+   int ret = 0;
 
ENICPMD_FUNC_TRACE();
-   args[0] = FM_ACTION_FREE;
-   args[1] = handle;
-   rc = flowman_cmd(fm, args, 2);
-   if (rc)
-   ENICPMD_LOG(ERR, "cannot free action: rc=%d handle=0x%" PRIx64,
-   rc, handle);
-   return rc;
+   RTE_ASSERT(ah->ref > 0);
+   ah->ref--;
+   if (ah->ref == 0) {
+   args[0] = FM_ACTION_FREE;
+   args[1] = ah->handle;
+   ret = flowman_cmd(fm, args, 2);
+   if (ret)
+   /* This is a "should never happen" error. */
+   ENICPMD_LOG(ERR, "freeing action rc=%d handle=0x%"
+   PRIx64, ret, ah->handle);
+   rte_hash_del_key(fm->action_hash, (const void *)&ah->key);
+   free(ah);
+   }
+   return ret;
 }
 
 static int
@@ -2041,9 +2061,9 @@ __enic_fm_flow_free(struct enic_flowman *fm, struct 
enic_fm_flow *fm_flow)
enic_fm_entry_free(fm, fm_flow->entry_handle);
fm_flow->entry_handle = FM_INVALID_HANDLE;
}
-   if (fm_flow->action_handle != FM_INVALID_HANDLE) {
-   enic_fm_action_free(fm, fm_flow->action_handle);
-   fm_flow->action_handle = FM_INVALID_HANDLE;
+   if (fm_flow->action != NULL) {
+   enic_fm_action_free(fm, fm_flow->action);
+   fm_flow->action = NULL;
}
enic_fm_counter_free(fm, fm_flow);
if (fm_flow->fet) {
@@ -2153,6 +2173,71 @@ enic_fm_add_exact_entry(struct enic_flowman *fm,
return 0;
 }
 
+static int
+enic_action_handle_get(struct enic_flowman *fm, struct fm_action *action_in,
+  struct rte_flow_error *error,
+  struct enic_fm_action **ah_o)
+{
+   struct enic_fm_action *ah;
+   struct fm_action *fma;
+   uint64_t args[2];
+   int ret = 0;
+
+   ret = rte_hash_lookup_data(fm->action_hash, action_in,
+  (void **)&ah);
+   if (ret < 0 && ret != -ENOENT)
+   return rte_flow_error_set(error, -ret,
+  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+  NULL, "enic: rte_hash_lookup(aciton)");
+
+   if (ret == -ENOENT) {
+   /* Allocate a new action on the NIC. */
+   fma = &fm->cmd.va->fm_action;
+   memcpy(fma, action_in, sizeof(*fma));
+
+   ah = calloc(1, sizeof(*ah));
+   memcpy(&ah->key, action_in, sizeof(struct fm_action));
+   if (ah == N

[dpdk-dev] [PATCH 5/5] net/enic: allow multiple mark and flag actions

2020-04-14 Thread John Daley
1400 series adapters support multiple MARK and FLAG action types.
  e.g.: mark id 10 / queue index 2 / mark id 11 / queue index 3

Remove the restriction in the Flow Manager implementation.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_fm_flow.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 86efeffc64..6ee0224372 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -1086,11 +1086,10 @@ enic_fm_copy_action(struct enic_flowman *fm,
 {
enum {
FATE = 1 << 0,
-   MARK = 1 << 1,
+   DECAP = 1 << 1,
PASSTHRU = 1 << 2,
COUNT = 1 << 3,
ENCAP = 1 << 4,
-   DECAP = 1 << 5,
};
struct fm_tcam_match_entry *fmt;
struct fm_action_op fm_op;
@@ -1141,9 +1140,6 @@ enic_fm_copy_action(struct enic_flowman *fm,
const struct rte_flow_action_mark *mark =
actions->conf;
 
-   if (overlap & MARK)
-   goto unsupported;
-   overlap |= MARK;
if (mark->id >= ENIC_MAGIC_FILTER_ID - 1)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION,
@@ -1157,9 +1153,6 @@ enic_fm_copy_action(struct enic_flowman *fm,
break;
}
case RTE_FLOW_ACTION_TYPE_FLAG: {
-   if (overlap & MARK)
-   goto unsupported;
-   overlap |= MARK;
/* ENIC_MAGIC_FILTER_ID is reserved for flagging */
memset(&fm_op, 0, sizeof(fm_op));
fm_op.fa_op = FMOP_MARK;
-- 
2.22.0



[dpdk-dev] [PATCH 4/5] net/enic: support flow API RSS ranges on outer headers

2020-04-14 Thread John Daley
Support rte_flow RSS action on outer headers (level 0). RSS ranges on
the non-default port is OK.
Restrictions:
 - The RETA is ignored. The hash function is simply applied across
   the RSS queue range.
 - The queues used in the RSS group must be sequential.
 - There is a performance hit if the number of queues is not a power
   of 2.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 doc/guides/nics/enic.rst|  4 +++
 drivers/net/enic/enic_fm_flow.c | 56 ++---
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 65e536d422..aa4fdc0e39 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -459,6 +459,10 @@ PKT_RX_VLAN_STRIPPED mbuf flags would not be set. This 
mode is enabled with the
 packets and then receive them normally. These require 1400 series VIC 
adapters
 and latest firmware.
   - RAW items are limited to matching UDP tunnel headers like VXLAN.
+  - For 1400 VICs, all flows using the RSS action on a port use same hash
+configuration. The RETA is ignored. The queues used in the RSS group must 
be
+sequential. There is a performance hit if the number of queues is not a 
power of 2.
+Only level 0 (outer header) RSS is allowed.
 
 - **Statistics**
 
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 8d715fc436..86efeffc64 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -1174,8 +1174,8 @@ enic_fm_copy_action(struct enic_flowman *fm,
actions->conf;
 
/*
-* If other fate kind is set, fail.  Multiple
-* queue actions are ok.
+* If fate other than QUEUE or RSS, fail. Multiple
+* rss and queue actions are ok.
 */
if ((overlap & FATE) && first_rq)
goto unsupported;
@@ -1185,6 +1185,7 @@ enic_fm_copy_action(struct enic_flowman *fm,
fm_op.fa_op = FMOP_RQ_STEER;
fm_op.rq_steer.rq_index =
enic_rte_rq_idx_to_sop_idx(queue->index);
+   fm_op.rq_steer.rq_count = 1;
fm_op.rq_steer.vnic_handle = vnic_h;
ret = enic_fm_append_action_op(fm, &fm_op, error);
if (ret)
@@ -1219,27 +1220,44 @@ enic_fm_copy_action(struct enic_flowman *fm,
uint16_t i;
 
/*
-* Hardware does not support general RSS actions, but
-* we can still support the dummy one that is used to
-* "receive normally".
+* If fate other than QUEUE or RSS, fail. Multiple
+* rss and queue actions are ok.
+*/
+   if ((overlap & FATE) && first_rq)
+   goto unsupported;
+   first_rq = false;
+   overlap |= FATE;
+
+   /*
+* Hardware only supports RSS actions on outer level
+* with default type and function. Queues must be
+* sequential.
 */
allow = rss->func == RTE_ETH_HASH_FUNCTION_DEFAULT &&
-   rss->level == 0 &&
-   (rss->types == 0 ||
-rss->types == enic->rss_hf) &&
-   rss->queue_num == enic->rq_count &&
-   rss->key_len == 0;
-   /* Identity queue map is ok */
-   for (i = 0; i < rss->queue_num; i++)
-   allow = allow && (i == rss->queue[i]);
+   rss->level == 0 && (rss->types == 0 ||
+   rss->types == enic->rss_hf) &&
+   rss->queue_num <= enic->rq_count &&
+   rss->queue[rss->queue_num - 1] < enic->rq_count;
+
+
+   /* Identity queue map needs to be sequential */
+   for (i = 1; i < rss->queue_num; i++)
+   allow = allow && (rss->queue[i] ==
+   rss->queue[i - 1] + 1);
if (!allow)
goto unsupported;
-   if (overlap & FATE)
-   goto unsupported;
-   /* Need MARK or FLAG

[dpdk-dev] [PATCH 2/5] net/enic: flow manager API update

2020-04-14 Thread John Daley
Update the VIC Flow Manager API. The extentions will allow support for:
  - Decap and strip VLAN
  - Remove outer VLAN
  - Set Egress port
  - Set VLAN when replicating encapped packets
  - RSS queue ranges on outer header

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/vnic_flowman.h | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/net/enic/base/vnic_flowman.h 
b/drivers/net/enic/base/vnic_flowman.h
index 49f743f5fb..81e2cff1b0 100644
--- a/drivers/net/enic/base/vnic_flowman.h
+++ b/drivers/net/enic/base/vnic_flowman.h
@@ -236,6 +236,20 @@ enum {
FMOP_SET_OVLAN,
/* Decap when vlan_strip is off */
FMOP_DECAP_NOSTRIP,
+   /* Decap and strip VLAN */
+   FMOP_DECAP_STRIP,
+   /* Remove outer VLAN */
+   FMOP_POP_VLAN,
+   /* Set Egress port */
+   FMOP_SET_EGPORT,
+   /* Steer to an RQ without entering EMIT state */
+   FMOP_RQ_STEER_ONLY,
+   /* Set VLAN when replicating encapped packets */
+   FMOP_SET_ENCAP_VLAN,
+   /* Enter EMIT state */
+   FMOP_EMIT,
+   /* Enter MODIFY state */
+   FMOP_MODIFY,
FMOP_OP_MAX,
 };
 
@@ -260,12 +274,16 @@ struct fm_action_op {
uint8_t template_len;
} __rte_packed encap;
struct {
-   uint32_t rq_index;
+   uint16_t rq_index;
+   uint16_t rq_count;
uint64_t vnic_handle;
} __rte_packed rq_steer;
struct {
uint16_t vlan;
} __rte_packed ovlan;
+   struct {
+   uint16_t vlan;
+   } __rte_packed set_encap_vlan;
struct {
uint16_t mark;
} __rte_packed mark;
@@ -278,6 +296,9 @@ struct fm_action_op {
struct {
uint64_t handle;
} __rte_packed exact;
+   struct {
+   uint32_t egport;
+   } __rte_packed set_egport;
} __rte_packed;
 } __rte_packed;
 
-- 
2.22.0



[dpdk-dev] [PATCH 3/5] net/enic: change Rx queue ordering to enable RSS action

2020-04-14 Thread John Daley
Each RTE RQ is represented on enic as a Start Of Packet (SOP) queue and
and overflow queue (DATA). There were arranged SOP0/DATA0, SOP1/DATA1,...
but need to be arranged SOP0, SOP1,..., DATA0, DATA1... so that
rte_flow RSS queue ranges work.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic.h| 13 +++--
 drivers/net/enic/enic_ethdev.c |  2 +-
 drivers/net/enic/enic_main.c   | 13 ++---
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index c9901faf5f..a95e51eea8 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -221,25 +221,26 @@ static inline uint32_t enic_mtu_to_max_rx_pktlen(uint32_t 
mtu)
 /* Get the CQ index from a Start of Packet(SOP) RQ index */
 static inline unsigned int enic_sop_rq_idx_to_cq_idx(unsigned int sop_idx)
 {
-   return sop_idx / 2;
+   return sop_idx;
 }
 
 /* Get the RTE RQ index from a Start of Packet(SOP) RQ index */
 static inline unsigned int enic_sop_rq_idx_to_rte_idx(unsigned int sop_idx)
 {
-   return sop_idx / 2;
+   return sop_idx;
 }
 
 /* Get the Start of Packet(SOP) RQ index from a RTE RQ index */
 static inline unsigned int enic_rte_rq_idx_to_sop_idx(unsigned int rte_idx)
 {
-   return rte_idx * 2;
+   return rte_idx;
 }
 
 /* Get the Data RQ index from a RTE RQ index */
-static inline unsigned int enic_rte_rq_idx_to_data_idx(unsigned int rte_idx)
+static inline unsigned int enic_rte_rq_idx_to_data_idx(unsigned int rte_idx,
+  struct enic *enic)
 {
-   return rte_idx * 2 + 1;
+   return enic->rq_count + rte_idx;
 }
 
 static inline unsigned int enic_vnic_rq_count(struct enic *enic)
@@ -253,7 +254,7 @@ static inline unsigned int enic_cq_rq(__rte_unused struct 
enic *enic, unsigned i
 * completion queue, so the completion queue number is no
 * longer the same as the rq number.
 */
-   return rq / 2;
+   return rq;
 }
 
 static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq)
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index a7a178e41b..32d5397f85 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -940,7 +940,7 @@ static void enicpmd_dev_rxq_info_get(struct rte_eth_dev 
*dev,
 
ENICPMD_FUNC_TRACE();
sop_queue_idx = enic_rte_rq_idx_to_sop_idx(rx_queue_id);
-   data_queue_idx = enic_rte_rq_idx_to_data_idx(rx_queue_id);
+   data_queue_idx = enic_rte_rq_idx_to_data_idx(rx_queue_id, enic);
rq_sop = &enic->rq[sop_queue_idx];
rq_data = &enic->rq[data_queue_idx]; /* valid if data_queue_enable */
qinfo->mp = rq_sop->mp;
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 78e2dd133c..7942b0df6b 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -222,13 +222,12 @@ void enic_init_vnic_resources(struct enic *enic)
error_interrupt_enable,
error_interrupt_offset);
 
-   data_rq = &enic->rq[enic_rte_rq_idx_to_data_idx(index)];
+   data_rq = &enic->rq[enic_rte_rq_idx_to_data_idx(index, enic)];
if (data_rq->in_use)
vnic_rq_init(data_rq,
 cq_idx,
 error_interrupt_enable,
 error_interrupt_offset);
-
vnic_cq_init(&enic->cq[cq_idx],
0 /* flow_control_enable */,
1 /* color_enable */,
@@ -620,7 +619,7 @@ int enic_enable(struct enic *enic)
return err;
}
err = enic_alloc_rx_queue_mbufs(enic,
-   &enic->rq[enic_rte_rq_idx_to_data_idx(index)]);
+   &enic->rq[enic_rte_rq_idx_to_data_idx(index, enic)]);
if (err) {
/* release the allocated mbufs for the sop rq*/
enic_rxmbuf_queue_release(enic,
@@ -808,7 +807,7 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
 {
int rc;
uint16_t sop_queue_idx = enic_rte_rq_idx_to_sop_idx(queue_idx);
-   uint16_t data_queue_idx = enic_rte_rq_idx_to_data_idx(queue_idx);
+   uint16_t data_queue_idx = enic_rte_rq_idx_to_data_idx(queue_idx, enic);
struct vnic_rq *rq_sop = &enic->rq[sop_queue_idx];
struct vnic_rq *rq_data = &enic->rq[data_queue_idx];
unsigned int mbuf_size, mbufs_per_pkt;
@@ -1475,7 +1474,7 @@ enic_reinit_rq(struct enic *enic, unsigned int rq_idx)
int rc = 0;
 
sop_rq = &enic->rq[enic_rte_rq_idx_to_sop_idx(rq_idx)];
-   data_rq = &enic->rq[enic_rte_rq_idx_to_data_idx(rq_idx)];
+   data_rq = &enic->rq[enic_r

[dpdk-dev] [PATCH 1/5] net/enic: fix action reordering

2020-04-14 Thread John Daley
From: Hyong Youb Kim 

The current implementation produces wrong ordering for several cases
like these:

1. mark, decap, steer
Current: steer, mark, decap
Correct: mark, steer, decap

2. decap, steer, steer
Current: steer, steer, decap
Correct: steer, decap, steer

Simplify the logic and swap 1st steer and decap.
Also, allow just one decap action per flow.

Fixes: ea7768b5bba8 ("net/enic: add flow implementation based on Flow Manager 
API")
Cc: sta...@dpdk.org

Signed-off-by: Hyong Youb Kim 
Signed-off-by: John Daley 
---
 drivers/net/enic/enic_fm_flow.c | 63 +++--
 1 file changed, 29 insertions(+), 34 deletions(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index d815f369ed..8d715fc436 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -870,46 +870,36 @@ enic_fm_append_action_op(struct enic_flowman *fm,
return 0;
 }
 
-/* Steer operations need to appear before other ops */
+/* NIC requires that 1st steer appear before decap.
+ * Correct example: steer, decap, steer, steer, ...
+ */
 static void
 enic_fm_reorder_action_op(struct enic_flowman *fm)
 {
-   struct fm_action_op *dst, *dst_head, *src, *src_head;
+   struct fm_action_op *op, *steer, *decap;
+   struct fm_action_op tmp_op;
 
ENICPMD_FUNC_TRACE();
-   /* Move steer ops to the front. */
-   src = fm->action.fma_action_ops;
-   src_head = src;
-   dst = fm->action_tmp.fma_action_ops;
-   dst_head = dst;
-   /* Copy steer ops to tmp */
-   while (src->fa_op != FMOP_END) {
-   if (src->fa_op == FMOP_RQ_STEER) {
-   ENICPMD_LOG(DEBUG, "move op: %ld -> dst %ld",
-   (long)(src - src_head),
-   (long)(dst - dst_head));
-   *dst = *src;
-   dst++;
-   }
-   src++;
-   }
-   /* Then append non-steer ops */
-   src = src_head;
-   while (src->fa_op != FMOP_END) {
-   if (src->fa_op != FMOP_RQ_STEER) {
-   ENICPMD_LOG(DEBUG, "move op: %ld -> dst %ld",
-   (long)(src - src_head),
-   (long)(dst - dst_head));
-   *dst = *src;
-   dst++;
-   }
-   src++;
+   /* Find 1st steer and decap */
+   op = fm->action.fma_action_ops;
+   steer = NULL;
+   decap = NULL;
+   while (op->fa_op != FMOP_END) {
+   if (!decap && op->fa_op == FMOP_DECAP_NOSTRIP)
+   decap = op;
+   else if (!steer && op->fa_op == FMOP_RQ_STEER)
+   steer = op;
+   op++;
+   }
+   /* If decap is before steer, swap */
+   if (steer && decap && decap < steer) {
+   op = fm->action.fma_action_ops;
+   ENICPMD_LOG(DEBUG, "swap decap %ld <-> steer %ld",
+   (long)(decap - op), (long)(steer - op));
+   tmp_op = *decap;
+   *decap = *steer;
+   *steer = tmp_op;
}
-   /* Copy END */
-   *dst = *src;
-   /* Finally replace the original action with the reordered one */
-   memcpy(fm->action.fma_action_ops, fm->action_tmp.fma_action_ops,
-  sizeof(fm->action.fma_action_ops));
 }
 
 /* VXLAN decap is done via flowman compound action */
@@ -1100,6 +1090,7 @@ enic_fm_copy_action(struct enic_flowman *fm,
PASSTHRU = 1 << 2,
COUNT = 1 << 3,
ENCAP = 1 << 4,
+   DECAP = 1 << 5,
};
struct fm_tcam_match_entry *fmt;
struct fm_action_op fm_op;
@@ -1282,6 +1273,10 @@ enic_fm_copy_action(struct enic_flowman *fm,
break;
}
case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: {
+   if (overlap & DECAP)
+   goto unsupported;
+   overlap |= DECAP;
+
ret = enic_fm_copy_vxlan_decap(fm, fmt, actions,
error);
if (ret != 0)
-- 
2.22.0



[dpdk-dev] [PATCH v2] net/enic: use RTE min and max macros

2020-01-21 Thread John Daley
Use the RTE_MIN and RTE_MAX macros instead of private macros.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---

v2 - remove the min_t and max_t macros all together

 drivers/net/enic/enic_compat.h | 10 --
 drivers/net/enic/enic_res.c| 20 
 2 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/drivers/net/enic/enic_compat.h b/drivers/net/enic/enic_compat.h
index eb1fc941e4..7741273037 100644
--- a/drivers/net/enic/enic_compat.h
+++ b/drivers/net/enic/enic_compat.h
@@ -73,14 +73,4 @@ static inline void writel(unsigned int val, volatile void 
__iomem *addr)
rte_write32(val, addr);
 }
 
-#define min_t(type, x, y) ({\
-   type __min1 = (x);  \
-   type __min2 = (y);  \
-   __min1 < __min2 ? __min1 : __min2; })
-
-#define max_t(type, x, y) ({\
-   type __max1 = (x);  \
-   type __max2 = (y);  \
-   __max1 > __max2 ? __max1 : __max2; })
-
 #endif /* _ENIC_COMPAT_H_ */
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index d72bef233b..20888eb257 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -68,8 +68,8 @@ int enic_get_vnic_config(struct enic *enic)
if (c->mtu == 0)
c->mtu = 1500;
 
-   enic->rte_dev->data->mtu = min_t(uint16_t, enic->max_mtu,
-max_t(uint16_t, ENIC_MIN_MTU, c->mtu));
+   enic->rte_dev->data->mtu = RTE_MIN(enic->max_mtu,
+   RTE_MAX((uint16_t)ENIC_MIN_MTU, c->mtu));
 
enic->adv_filters = vnic_dev_capable_adv_filters(enic->vdev);
dev_info(enic, "Advanced Filters %savailable\n", ((enic->adv_filters)
@@ -100,20 +100,16 @@ int enic_get_vnic_config(struct enic *enic)
((enic->filter_actions & FILTER_ACTION_COUNTER_FLAG) ?
 "count " : ""));
 
-   c->wq_desc_count =
-   min_t(uint32_t, ENIC_MAX_WQ_DESCS,
-   max_t(uint32_t, ENIC_MIN_WQ_DESCS,
-   c->wq_desc_count));
+   c->wq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_WQ_DESCS,
+   RTE_MAX((uint32_t)ENIC_MIN_WQ_DESCS, c->wq_desc_count));
c->wq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
 
-   c->rq_desc_count =
-   min_t(uint32_t, ENIC_MAX_RQ_DESCS,
-   max_t(uint32_t, ENIC_MIN_RQ_DESCS,
-   c->rq_desc_count));
+   c->rq_desc_count = RTE_MIN((uint32_t)ENIC_MAX_RQ_DESCS,
+   RTE_MAX((uint32_t)ENIC_MIN_RQ_DESCS, c->rq_desc_count));
c->rq_desc_count &= 0xffe0; /* must be aligned to groups of 32 */
 
-   c->intr_timer_usec = min_t(uint32_t, c->intr_timer_usec,
-   vnic_dev_get_intr_coal_timer_max(enic->vdev));
+   c->intr_timer_usec = RTE_MIN(c->intr_timer_usec,
+ vnic_dev_get_intr_coal_timer_max(enic->vdev));
 
dev_info(enic_get_dev(enic),
"vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x "
-- 
2.22.0



Re: [dpdk-dev] [PATCH] net/enic: move macro to the correct file

2020-01-21 Thread John Daley (johndale)
You are right, just need to cast #define parameters, then can use the RTE_MIN 
and MAX.
Will do a patch.
Thanks,
john

> -Original Message-
> From: Thomas Monjalon 
> Sent: Sunday, January 19, 2020 12:24 PM
> To: John Daley (johndale) ; Hyong Youb Kim
> (hyonkim) 
> Cc: ferruh.yi...@intel.com; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] net/enic: move macro to the correct file
> 
> 14/01/2020 01:24, John Daley:
> > +#define min_t(type, x, y) ({\
> > +   type __min1 = (x);  \
> > +   type __min2 = (y);  \
> > +   __min1 < __min2 ? __min1 : __min2; })
> > +
> > +#define max_t(type, x, y) ({\
> > +   type __max1 = (x);  \
> > +   type __max2 = (y);  \
> > +   __max1 > __max2 ? __max1 : __max2; })
> 
> Why not using RTE_MIN/RTE_MAX which use typeof?
> You need to specify a type?
> 



[dpdk-dev] [PATCH] net/enic: move macro to the correct file

2020-01-13 Thread John Daley
Move a macro from a widely included header file to a header file
used only by the one caller of the macro.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_compat.h | 10 --
 drivers/net/enic/enic_res.h| 11 ++-
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/net/enic/enic_compat.h b/drivers/net/enic/enic_compat.h
index eb1fc941e4..7741273037 100644
--- a/drivers/net/enic/enic_compat.h
+++ b/drivers/net/enic/enic_compat.h
@@ -73,14 +73,4 @@ static inline void writel(unsigned int val, volatile void 
__iomem *addr)
rte_write32(val, addr);
 }
 
-#define min_t(type, x, y) ({\
-   type __min1 = (x);  \
-   type __min2 = (y);  \
-   __min1 < __min2 ? __min1 : __min2; })
-
-#define max_t(type, x, y) ({\
-   type __max1 = (x);  \
-   type __max2 = (y);  \
-   __max1 > __max2 ? __max1 : __max2; })
-
 #endif /* _ENIC_COMPAT_H_ */
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 9700b0d3e6..b3bd4b27d3 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -11,6 +11,16 @@
 #include "vnic_wq.h"
 #include "vnic_rq.h"
 
+#define min_t(type, x, y) ({\
+   type __min1 = (x);  \
+   type __min2 = (y);  \
+   __min1 < __min2 ? __min1 : __min2; })
+
+#define max_t(type, x, y) ({\
+   type __max1 = (x);  \
+   type __max2 = (y);  \
+   __max1 > __max2 ? __max1 : __max2; })
+
 #define ENIC_MIN_WQ_DESCS  64
 #define ENIC_MAX_WQ_DESCS  4096
 #define ENIC_MIN_RQ_DESCS  64
@@ -55,7 +65,6 @@
 
 #define ENIC_SETTING(enic, f) ((enic->config.flags & VENETF_##f) ? 1 : 0)
 
-
 struct enic;
 
 int enic_get_vnic_config(struct enic *);
-- 
2.22.0



[dpdk-dev] [PATCH] net/enic: use standard RTE defines

2020-01-13 Thread John Daley
Use the memzone namesize, Ethernet address length defines from the RTE
header files instead of locally defined versions.
Use the RTE byte swap functions instead of the x86 specific locally
defined versions.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/cq_desc.h  |  9 ---
 drivers/net/enic/base/cq_enet_desc.h | 39 ++--
 drivers/net/enic/base/rq_enet_desc.h | 12 +
 drivers/net/enic/base/vnic_cq.c  |  3 ++-
 drivers/net/enic/base/vnic_dev.c | 21 ---
 drivers/net/enic/base/vnic_rq.c  |  3 ++-
 drivers/net/enic/base/vnic_wq.c  |  2 +-
 drivers/net/enic/base/wq_enet_desc.h | 36 +
 drivers/net/enic/enic.h  |  4 +--
 drivers/net/enic/enic_compat.h   |  8 --
 drivers/net/enic/enic_fm_flow.c  |  5 ++--
 drivers/net/enic/enic_main.c | 10 +++
 drivers/net/enic/enic_rxtx_common.h  | 17 +++-
 13 files changed, 87 insertions(+), 82 deletions(-)

diff --git a/drivers/net/enic/base/cq_desc.h b/drivers/net/enic/base/cq_desc.h
index ae8847c6d9..52e0402bdf 100644
--- a/drivers/net/enic/base/cq_desc.h
+++ b/drivers/net/enic/base/cq_desc.h
@@ -5,6 +5,7 @@
 
 #ifndef _CQ_DESC_H_
 #define _CQ_DESC_H_
+#include 
 
 /*
  * Completion queue descriptor types
@@ -58,8 +59,8 @@ static inline void cq_desc_enc(struct cq_desc *desc,
 {
desc->type_color = (type & CQ_DESC_TYPE_MASK) |
((color & CQ_DESC_COLOR_MASK) << CQ_DESC_COLOR_SHIFT);
-   desc->q_number = cpu_to_le16(q_number & CQ_DESC_Q_NUM_MASK);
-   desc->completed_index = cpu_to_le16(completed_index &
+   desc->q_number = rte_cpu_to_le_16(q_number & CQ_DESC_Q_NUM_MASK);
+   desc->completed_index = rte_cpu_to_le_16(completed_index &
CQ_DESC_COMP_NDX_MASK);
 }
 
@@ -82,8 +83,8 @@ static inline void cq_desc_dec(const struct cq_desc *desc_arg,
rmb();
 
*type = type_color & CQ_DESC_TYPE_MASK;
-   *q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK;
-   *completed_index = le16_to_cpu(desc->completed_index) &
+   *q_number = rte_le_to_cpu_16(desc->q_number) & CQ_DESC_Q_NUM_MASK;
+   *completed_index = rte_le_to_cpu_16(desc->completed_index) &
CQ_DESC_COMP_NDX_MASK;
 }
 
diff --git a/drivers/net/enic/base/cq_enet_desc.h 
b/drivers/net/enic/base/cq_enet_desc.h
index 5ced63cb16..995b9cca98 100644
--- a/drivers/net/enic/base/cq_enet_desc.h
+++ b/drivers/net/enic/base/cq_enet_desc.h
@@ -6,6 +6,7 @@
 #ifndef _CQ_ENET_DESC_H_
 #define _CQ_ENET_DESC_H_
 
+#include 
 #include "cq_desc.h"
 
 /* Ethernet completion queue descriptor: 16B */
@@ -118,33 +119,33 @@ static inline void cq_enet_rq_desc_enc(struct 
cq_enet_rq_desc *desc,
cq_desc_enc((struct cq_desc *)desc, type,
color, q_number, completed_index);
 
-   desc->completed_index_flags |= cpu_to_le16(
-   (ingress_port ? CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT : 0) |
+   desc->completed_index_flags |= rte_cpu_to_le_16
+   ((ingress_port ? CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT : 0) |
(fcoe ? CQ_ENET_RQ_DESC_FLAGS_FCOE : 0) |
(eop ? CQ_ENET_RQ_DESC_FLAGS_EOP : 0) |
(sop ? CQ_ENET_RQ_DESC_FLAGS_SOP : 0));
 
-   desc->q_number_rss_type_flags |= cpu_to_le16(
-   ((rss_type & CQ_ENET_RQ_DESC_RSS_TYPE_MASK) <<
+   desc->q_number_rss_type_flags |= rte_cpu_to_le_16
+   (((rss_type & CQ_ENET_RQ_DESC_RSS_TYPE_MASK) <<
CQ_DESC_Q_NUM_BITS) |
(csum_not_calc ? CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC : 0));
 
-   desc->rss_hash = cpu_to_le32(rss_hash);
+   desc->rss_hash = rte_cpu_to_le_32(rss_hash);
 
-   desc->bytes_written_flags = cpu_to_le16(
-   (bytes_written & CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK) |
+   desc->bytes_written_flags = rte_cpu_to_le_16
+   ((bytes_written & CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK) |
(packet_error ? CQ_ENET_RQ_DESC_FLAGS_TRUNCATED : 0) |
(vlan_stripped ? CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED : 0));
 
-   desc->vlan = cpu_to_le16(vlan);
+   desc->vlan = rte_cpu_to_le_16(vlan);
 
if (fcoe) {
-   desc->checksum_fcoe = cpu_to_le16(
-   (fcoe_sof & CQ_ENET_RQ_DESC_FCOE_SOF_MASK) |
+   desc->checksum_fcoe = rte_cpu_to_le_16
+   ((fcoe_sof & CQ_ENET_RQ_DESC_FCOE_SOF_MASK) |
((fcoe_eof & CQ_ENET_RQ_DESC_FCOE_EOF_MASK) <<
CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT));
} else {
-   desc->checksum_fcoe = cpu_to_le16(checksum);
+   desc->checksum_fcoe = rte_cpu_to_le_16(checksum);
}
 
desc->fla

[dpdk-dev] [PATCH] net/enic: consolidate and remove some defines

2020-01-13 Thread John Daley
There were defines which originally allowed sharing of some code with
the enic kernel driver. The code has long since diverged and now the
abstraction just makes the code harder to read. Mostly mechanical
replacement of defines and reformatting.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/cq_desc.h   |  25 +-
 drivers/net/enic/base/cq_enet_desc.h  |  91 +++---
 drivers/net/enic/base/rq_enet_desc.h  |  14 +-
 drivers/net/enic/base/vnic_cq.c   |   6 +-
 drivers/net/enic/base/vnic_cq.h   |  48 +--
 drivers/net/enic/base/vnic_dev.c  | 215 ++---
 drivers/net/enic/base/vnic_dev.h  |  83 ++---
 drivers/net/enic/base/vnic_devcmd.h   | 436 ++
 drivers/net/enic/base/vnic_enet.h |  36 +--
 drivers/net/enic/base/vnic_intr.c |   4 +-
 drivers/net/enic/base/vnic_intr.h |  36 +--
 drivers/net/enic/base/vnic_nic.h  |  10 +-
 drivers/net/enic/base/vnic_resource.h |  22 +-
 drivers/net/enic/base/vnic_rq.c   |  10 +-
 drivers/net/enic/base/vnic_rq.h   |  62 ++--
 drivers/net/enic/base/vnic_rss.h  |  12 +-
 drivers/net/enic/base/vnic_stats.h|  68 ++--
 drivers/net/enic/base/vnic_wq.c   |   6 +-
 drivers/net/enic/base/vnic_wq.h   |  45 +--
 drivers/net/enic/base/wq_enet_desc.h  |  37 ++-
 drivers/net/enic/enic.h   |  22 +-
 drivers/net/enic/enic_clsf.c  |  14 +-
 drivers/net/enic/enic_compat.h|  22 --
 drivers/net/enic/enic_flow.c  |  26 +-
 drivers/net/enic/enic_fm_flow.c   |  28 +-
 drivers/net/enic/enic_main.c  |  25 +-
 drivers/net/enic/enic_res.c   |  33 +-
 drivers/net/enic/enic_res.h   |  11 +-
 drivers/net/enic/enic_rxtx.c  |   5 +-
 29 files changed, 737 insertions(+), 715 deletions(-)

diff --git a/drivers/net/enic/base/cq_desc.h b/drivers/net/enic/base/cq_desc.h
index 52e0402bdf..7151353cbf 100644
--- a/drivers/net/enic/base/cq_desc.h
+++ b/drivers/net/enic/base/cq_desc.h
@@ -25,14 +25,14 @@ enum cq_desc_types {
 /* Completion queue descriptor: 16B
  *
  * All completion queues have this basic layout.  The
- * type_specfic area is unique for each completion
+ * type_specific area is unique for each completion
  * queue type.
  */
 struct cq_desc {
-   __le16 completed_index;
-   __le16 q_number;
-   u8 type_specfic[11];
-   u8 type_color;
+   uint16_t completed_index;
+   uint16_t q_number;
+   uint8_t type_specific[11];
+   uint8_t type_color;
 };
 
 #define CQ_DESC_TYPE_BITS4
@@ -45,7 +45,7 @@ struct cq_desc {
 #define CQ_DESC_COMP_NDX_BITS12
 #define CQ_DESC_COMP_NDX_MASK((1 << CQ_DESC_COMP_NDX_BITS) - 1)
 
-static inline void cq_color_enc(struct cq_desc *desc, const u8 color)
+static inline void cq_color_enc(struct cq_desc *desc, const uint8_t color)
 {
if (color)
desc->type_color |=  (1 << CQ_DESC_COLOR_SHIFT);
@@ -54,8 +54,8 @@ static inline void cq_color_enc(struct cq_desc *desc, const 
u8 color)
 }
 
 static inline void cq_desc_enc(struct cq_desc *desc,
-   const u8 type, const u8 color, const u16 q_number,
-   const u16 completed_index)
+   const uint8_t type, const uint8_t color, const uint16_t q_number,
+   const uint16_t completed_index)
 {
desc->type_color = (type & CQ_DESC_TYPE_MASK) |
((color & CQ_DESC_COLOR_MASK) << CQ_DESC_COLOR_SHIFT);
@@ -65,10 +65,11 @@ static inline void cq_desc_enc(struct cq_desc *desc,
 }
 
 static inline void cq_desc_dec(const struct cq_desc *desc_arg,
-   u8 *type, u8 *color, u16 *q_number, u16 *completed_index)
+   uint8_t *type, uint8_t *color, uint16_t *q_number,
+   uint16_t *completed_index)
 {
const struct cq_desc *desc = desc_arg;
-   const u8 type_color = desc->type_color;
+   const uint8_t type_color = desc->type_color;
 
*color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
 
@@ -80,7 +81,7 @@ static inline void cq_desc_dec(const struct cq_desc *desc_arg,
 * result in reading stale values.
 */
 
-   rmb();
+   rte_rmb();
 
*type = type_color & CQ_DESC_TYPE_MASK;
*q_number = rte_le_to_cpu_16(desc->q_number) & CQ_DESC_Q_NUM_MASK;
@@ -88,7 +89,7 @@ static inline void cq_desc_dec(const struct cq_desc *desc_arg,
CQ_DESC_COMP_NDX_MASK;
 }
 
-static inline void cq_color_dec(const struct cq_desc *desc_arg, u8 *color)
+static inline void cq_color_dec(const struct cq_desc *desc_arg, uint8_t *color)
 {
volatile const struct cq_desc *desc = desc_arg;
 
diff --git a/drivers/net/enic/base/cq_enet_desc.h 
b/drivers/net/enic/base/cq_enet_desc.h
index 995b9cca98..602ac22b65 100644
--- a/drivers/net/enic/base/cq_enet_desc.h
+++ b/drivers/net/enic/base/cq_enet_desc.h
@@ -11,21 +11,23 @@
 
 /* Ethernet completion queue descriptor: 16B */
 struct cq_enet_wq_desc {
-   __le16 completed_index;
-

[dpdk-dev] [PATCH 2/2] doc: remove comments about deprecated fdir in enic guide

2019-09-05 Thread John Daley
The legacy filter API "flow director" has been superseded by rte_flow
since 2017. Remove comments in the enic guide regarding the deprecated
feature.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 doc/guides/nics/enic.rst | 33 +++--
 1 file changed, 7 insertions(+), 26 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 5681bdb54..5e80398bf 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -107,24 +107,6 @@ Configuration information
 TCP, IPv4, TCP-IPv4, IPv6, TCP-IPv6, IPv6 Extension, TCP-IPv6 Extension.
 
 
-.. _enic-flow-director:
-
-Flow director support
--
-
-Advanced filtering support was added to 1300 series VIC firmware starting
-with version 2.0.13 for C-series UCS servers and version 3.1.2 for UCSM
-managed blade servers. In order to enable advanced filtering the 'Advanced
-filter' radio button should be enabled via CIMC or UCSM followed by a reboot
-of the server.
-
-With advanced filters, perfect matching of all fields of IPv4, IPv6 headers
-as well as TCP, UDP and SCTP L4 headers is available through flow director.
-Masking of these fields for partial match is also supported.
-
-Without advanced filter support, the flow director is limited to IPv4
-perfect filtering of the 5-tuple with no masking of fields supported.
-
 SR-IOV mode utilization
 ---
 
@@ -229,7 +211,13 @@ the use of SR-IOV.
 Generic Flow API support
 
 
-Generic Flow API is supported. The baseline support is:
+Generic Flow API (also called "rte_flow" API) is supported. More advanced
+capabilities are available when "Advanced Filtering" is enabled on the adapter.
+Advanced filtering was added to 1300 series VIC firmware starting with version
+2.0.13 for C-series UCS servers and version 3.1.2 for UCSM managed blade
+servers. Advanced filtering is available on 1400 series adapters and beyond.
+To enable advanced filtering, the 'Advanced filter' radio button should be
+selected via CIMC or UCSM followed by a reboot of the server.
 
 - **1200 series VICs**
 
@@ -420,12 +408,6 @@ PKT_RX_VLAN_STRIPPED mbuf flags would not be set. This 
mode is enabled with the
 
 -w 12:00.0,ig-vlan-rewrite=untag
 
-- Limited flow director support on 1200 series and 1300 series Cisco VIC
-  adapters with old firmware. Please see :ref:`enic-flow-director`.
-
-- Flow director features are not supported on generation 1 Cisco VIC adapters
-  (M81KR and P81E)
-
 - **SR-IOV**
 
   - KVM hypervisor support only. VMware has not been tested.
@@ -512,7 +494,6 @@ Supported features
 - IP checksum offload
 - Receive side VLAN stripping
 - Multiple receive and transmit queues
-- Flow Director ADD, UPDATE, DELETE, STATS operation support IPv4 and IPv6
 - Promiscuous mode
 - Setting RX VLAN (supported via UCSM/CIMC only)
 - VLAN filtering (supported via UCSM/CIMC only)
-- 
2.22.0



[dpdk-dev] [PATCH 1/2] net/enic: add PCI ID for new virtual function

2019-09-05 Thread John Daley
Probe for the PCI ID of a new mode of VF which will be added to VIC
adapter firmware. When fully implemented, the new mode will operate
independent of the Cisco Virtual Machine Fabric Extender (VM-FEX) and
will not need to be provisioned through libvirt. The new mode is dubbed
"Standalone vNic" mode or "SN" mode.

Also, minor formatting changes.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic.h| 2 ++
 drivers/net/enic/enic_ethdev.c | 5 +++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 5a92508f0..ff4de8898 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -42,6 +42,8 @@
 
 #define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043  /* ethernet vnic */
 #define PCI_DEVICE_ID_CISCO_VIC_ENET_VF  0x0071  /* enet SRIOV VF */
+/* enet SRIOV Standalone vNic VF */
+#define PCI_DEVICE_ID_CISCO_VIC_ENET_SN  0x02B7
 
 /* Special Filter id for non-specific packet flagging. Don't change value */
 #define ENIC_MAGIC_FILTER_ID 0x
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 06dc67122..5560af151 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -28,8 +28,9 @@ int enic_pmd_logtype;
  */
 #define CISCO_PCI_VENDOR_ID 0x1137
 static const struct rte_pci_id pci_id_enic_map[] = {
-   { RTE_PCI_DEVICE(CISCO_PCI_VENDOR_ID, PCI_DEVICE_ID_CISCO_VIC_ENET) },
-   { RTE_PCI_DEVICE(CISCO_PCI_VENDOR_ID, PCI_DEVICE_ID_CISCO_VIC_ENET_VF) 
},
+   {RTE_PCI_DEVICE(CISCO_PCI_VENDOR_ID, PCI_DEVICE_ID_CISCO_VIC_ENET)},
+   {RTE_PCI_DEVICE(CISCO_PCI_VENDOR_ID, PCI_DEVICE_ID_CISCO_VIC_ENET_VF)},
+   {RTE_PCI_DEVICE(CISCO_PCI_VENDOR_ID, PCI_DEVICE_ID_CISCO_VIC_ENET_SN)},
{.vendor_id = 0, /* sentinel */},
 };
 
-- 
2.22.0



Re: [dpdk-dev] [PATCH] net/enic: retain previous message logging

2019-07-26 Thread John Daley (johndale)



> -Original Message-
> From: Stephen Hemminger 
> Sent: Friday, July 26, 2019 1:51 PM
> To: Hyong Youb Kim (hyonkim) 
> Cc: John Daley (johndale) ; Ferruh Yigit
> ; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] net/enic: retain previous message logging
> 
> On Fri, 26 Jul 2019 04:21:23 +
> "Hyong Youb Kim (hyonkim)"  wrote:
> 
> > > -Original Message-
> > > From: John Daley (johndale)
> > > Sent: Friday, July 26, 2019 5:26 AM
> > > To: Ferruh Yigit 
> > > Cc: dev@dpdk.org; Hyong Youb Kim (hyonkim) 
> > > Subject: RE: [PATCH] net/enic: retain previous message logging
> > >
> > > Ok, lets NAK this patch. See comment inline.
> > > Thanks,
> > > John
> > >
> > [...]
> > > > On 7/25/2019 3:46 AM, John Daley wrote:
> > > > > Prior to fix, RTE_LOGTYPE_INFO messages would display in testpmd
> > > > > by default. After the fix, using dynamic logging, only NOTICE
> > > > > level and higher were displayed by default and INFO level were
> > > > > not. Change the messages to NOTICE level so they continue to display.
> > > > >
> > > > > DTS uses testpmd and parses messages and some tests failed
> > > > > because messages were no longer displayed. Other apps may also
> > > > > depend on the messages.
> > > >
> > > > If you need messages for the test framework, why not just increase
> > > > the log level for enic PMD via application parameter [1], or as
> > > > command to testpmd[2]?
> > > > Since it is dynamic debug now, you don't need to change the
> > > > default, can change the level on demand.
> > >
> > > I have no problem modifying our test scripts. The bigger concern was
> > > about any other scripts out there that might break because the
> > > default enic PMD messages changed. I suppose chances are slim and
> > > any such scripts can easily be modified to set the log level to info.
> > >
> >
> > Hi John, Ferruh,
> >
> > Can you guys reconsider? John's commit message makes it sound like he
> > is modifying PMD to avoid modifying test scripts. That is not the
> > issue at all. The real problem is that his previous commit causes a
> > customer visible change, which can lead to a lot of headache for both
> > us (doing tech support) and customers (wondering what's changed).
> >
> > Prior to commit bbd8ecc05434 ("net/enic: remove PMD log type
> references"):
> >
> > enic prints vNIC config related messages (rq/cq/wq info and such) via
> > dev_info(). And, dev_info() uses LOGTYPE_PMD and the INFO level.
> > LOGTYPE_PMD defaults to the INFO level, so these messages appear by
> > default. Customers and tech support use them for debugging and so on.
> >
> > After the commit:
> >
> > dev_info() is now enic_pmd_logtype, which defaults to NOTICE. The
> > macro is still using the INFO level. So, config messages are
> > suppressed by default. This was never the intention. The current patch
> > tries to fix that by elevating dev_info to dev_notice, because we do
> > want these messages to appear by default. Should have done it as part
> > of the previous commit, but we missed it.
> >
> > Down the line, we will have to guide our customers to exploit dynamic
> > log levels, but not this way (i.e. suddenly hiding messages that they
> > used to see/rely on).
> >
> > Thanks a lot.
> > -Hyong
> >
> 
> Drivers should be silent unless they see a problem.
> We don't want every driver outputting messages by default.
> 
> For your current issue, why not just register the default log level as info?

Yes, that is better and what Ferruh suggested also. It is what the v2 patch is: 
http://patches.dpdk.org/patch/57199/.
Thanks, John



Re: [dpdk-dev] [PATCH] net/enic: retain previous message logging

2019-07-26 Thread John Daley (johndale)


> -Original Message-
> From: Ferruh Yigit 
> Sent: Friday, July 26, 2019 3:01 AM
> To: John Daley (johndale) 
> Cc: dev@dpdk.org; Hyong Youb Kim (hyonkim) 
> Subject: Re: [PATCH] net/enic: retain previous message logging
> 
> On 7/26/2019 9:17 AM, John Daley (johndale) wrote:
> > Actually, after talking to a couple internal folks, we'd like to get the 
> > patch in
> if possible- many of our customer issues are due to the wrong number of
> queues, etc, which are reported in the default logs. To ask them to add --log-
> level=enic,info would be a pain, esp. for apps like OVS, fd.io.
> 
> As I said to Hyong, I believe it is not good approach to have logs to debug
> customer issues enabled by default.

Yes, we need to migrate away from this, but to suddenly hide messages that have 
been there all along is worse. We definitely need to work towards less verbose 
default messaging.
> 
> But I see you want to keep the your logging same, instead of replacing all
> 'dev_info' with 'dev_notice', what about setting default log level for driver 
> to
> 'RTE_LOG_INFO', this is easier change with same affect?
> 
> And when more fine grained update done on which logs to really set to
> 'dev_notice', the default log level can be updated back to 'RTE_LOG_NOTICE'

I agree this is a better way to go. I have a V2 patch coming which sets the 
enic PMD default log level to RTE_LOG_INFO. We can submit fine grained updates 
in future commits.
Thanks, John.
>
> > -john
> >
> >> -Original Message-
> >> From: John Daley (johndale)
> >> Sent: Thursday, July 25, 2019 1:26 PM
> >> To: Ferruh Yigit 
> >> Cc: dev@dpdk.org; Hyong Youb Kim (hyonkim) 
> >> Subject: RE: [PATCH] net/enic: retain previous message logging
> >>
> >> Ok, lets NAK this patch. See comment inline.
> >> Thanks,
> >> John
> >>
> >>> -----Original Message-
> >>> From: Ferruh Yigit 
> >>> Sent: Thursday, July 25, 2019 3:07 AM
> >>> To: John Daley (johndale) 
> >>> Cc: dev@dpdk.org
> >>> Subject: Re: [PATCH] net/enic: retain previous message logging
> >>>
> >>> On 7/25/2019 3:46 AM, John Daley wrote:
> >>>> Prior to fix, RTE_LOGTYPE_INFO messages would display in testpmd by
> >>>> default. After the fix, using dynamic logging, only NOTICE level
> >>>> and higher were displayed by default and INFO level were not.
> >>>> Change the messages to NOTICE level so they continue to display.
> >>>>
> >>>> DTS uses testpmd and parses messages and some tests failed because
> >>>> messages were no longer displayed. Other apps may also depend on
> >>>> the messages.
> >>>
> >>> If you need messages for the test framework, why not just increase
> >>> the log level for enic PMD via application parameter [1], or as
> >>> command to testpmd[2]?
> >>> Since it is dynamic debug now, you don't need to change the default,
> >>> can change the level on demand.
> >>
> >> I have no problem modifying our test scripts. The bigger concern was
> >> about any other scripts out there that might break because the
> >> default enic PMD messages changed. I suppose chances are slim and any
> >> such scripts can easily be modified to set the log level to info.
> >>
> >>>
> >>> [1]
> >>> starting testpmd with following option should do it:
> >>> --log-level=pmd.net.enic.*:info
> >>>
> >>> testpmd --log-level=pmd.net.enic.*:info -- -i
> >>>
> >>>
> >>> [2]
> >>> after testpmd started, can change the debug level:
> >>> testpmd> set log pmd.net.enic 7
> >>>
> >>>
> >>> [3] bonus, see current log levels
> >>> testpmd> dump_log_types
> >>
> >> Nice! I didn't know about this.
> >>
> >>>
> >>>
> >>>
> >>>>
> >>>> Fixes: bbd8ecc05434 ("net/enic: remove PMD log type references")
> >>>>
> >>>> Signed-off-by: John Daley 
> >>>
> >>> <...>
> >



[dpdk-dev] [PATCH v2] net/enic: retain previous message logging

2019-07-26 Thread John Daley
Prior to the fix, RTE_LOGTYPE_INFO messages were displayed by default.
After the fix, only NOTICE level and higher were displayed by default
and INFO level were not. There are INFO level vNIC config related
messages which customers and tech support currently depend on for
debugging and so on and to suddenly hide these messages is not a good
idea.

This patch changes the default log level to RTE_LOG_INFO for enic so
messages are printed as before the fix.

Fixes: bbd8ecc05434 ("net/enic: remove PMD log type references")

Signed-off-by: John Daley 
---

v2: Change default log level to 'RTE_LOG_INFO' instead of changing the
'dev_info' messages to 'dev_notice'

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

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 6051689a6..0ade57370 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -73,7 +73,7 @@ RTE_INIT(enicpmd_init_log)
 {
enic_pmd_logtype = rte_log_register("pmd.net.enic");
if (enic_pmd_logtype >= 0)
-   rte_log_set_level(enic_pmd_logtype, RTE_LOG_NOTICE);
+   rte_log_set_level(enic_pmd_logtype, RTE_LOG_INFO);
 }
 
 static int
-- 
2.22.0



Re: [dpdk-dev] [PATCH] net/enic: retain previous message logging

2019-07-26 Thread John Daley (johndale)
Actually, after talking to a couple internal folks, we'd like to get the patch 
in if possible- many of our customer issues are due to the wrong number of 
queues, etc, which are reported in the default logs. To ask them to add 
--log-level=enic,info would be a pain, esp. for apps like OVS, fd.io.
-john

> -Original Message-
> From: John Daley (johndale)
> Sent: Thursday, July 25, 2019 1:26 PM
> To: Ferruh Yigit 
> Cc: dev@dpdk.org; Hyong Youb Kim (hyonkim) 
> Subject: RE: [PATCH] net/enic: retain previous message logging
> 
> Ok, lets NAK this patch. See comment inline.
> Thanks,
> John
> 
> > -Original Message-
> > From: Ferruh Yigit 
> > Sent: Thursday, July 25, 2019 3:07 AM
> > To: John Daley (johndale) 
> > Cc: dev@dpdk.org
> > Subject: Re: [PATCH] net/enic: retain previous message logging
> >
> > On 7/25/2019 3:46 AM, John Daley wrote:
> > > Prior to fix, RTE_LOGTYPE_INFO messages would display in testpmd by
> > > default. After the fix, using dynamic logging, only NOTICE level and
> > > higher were displayed by default and INFO level were not. Change the
> > > messages to NOTICE level so they continue to display.
> > >
> > > DTS uses testpmd and parses messages and some tests failed because
> > > messages were no longer displayed. Other apps may also depend on the
> > > messages.
> >
> > If you need messages for the test framework, why not just increase the
> > log level for enic PMD via application parameter [1], or as command to
> > testpmd[2]?
> > Since it is dynamic debug now, you don't need to change the default,
> > can change the level on demand.
> 
> I have no problem modifying our test scripts. The bigger concern was about
> any other scripts out there that might break because the default enic PMD
> messages changed. I suppose chances are slim and any such scripts can
> easily be modified to set the log level to info.
> 
> >
> > [1]
> > starting testpmd with following option should do it:
> > --log-level=pmd.net.enic.*:info
> >
> > testpmd --log-level=pmd.net.enic.*:info -- -i
> >
> >
> > [2]
> > after testpmd started, can change the debug level:
> > testpmd> set log pmd.net.enic 7
> >
> >
> > [3] bonus, see current log levels
> > testpmd> dump_log_types
> 
> Nice! I didn't know about this.
> 
> >
> >
> >
> > >
> > > Fixes: bbd8ecc05434 ("net/enic: remove PMD log type references")
> > >
> > > Signed-off-by: John Daley 
> >
> > <...>



Re: [dpdk-dev] [PATCH] net/enic: retain previous message logging

2019-07-25 Thread John Daley (johndale)
Ok, lets NAK this patch. See comment inline.
Thanks,
John

> -Original Message-
> From: Ferruh Yigit 
> Sent: Thursday, July 25, 2019 3:07 AM
> To: John Daley (johndale) 
> Cc: dev@dpdk.org
> Subject: Re: [PATCH] net/enic: retain previous message logging
> 
> On 7/25/2019 3:46 AM, John Daley wrote:
> > Prior to fix, RTE_LOGTYPE_INFO messages would display in testpmd by
> > default. After the fix, using dynamic logging, only NOTICE level and
> > higher were displayed by default and INFO level were not. Change the
> > messages to NOTICE level so they continue to display.
> >
> > DTS uses testpmd and parses messages and some tests failed because
> > messages were no longer displayed. Other apps may also depend on the
> > messages.
> 
> If you need messages for the test framework, why not just increase the log
> level for enic PMD via application parameter [1], or as command to
> testpmd[2]?
> Since it is dynamic debug now, you don't need to change the default, can
> change the level on demand.

I have no problem modifying our test scripts. The bigger concern was about any 
other scripts out there that might break because the default enic PMD messages 
changed. I suppose chances are slim and any such scripts can easily be modified 
to set the log level to info.

> 
> [1]
> starting testpmd with following option should do it:
> --log-level=pmd.net.enic.*:info
> 
> testpmd --log-level=pmd.net.enic.*:info -- -i
> 
> 
> [2]
> after testpmd started, can change the debug level:
> testpmd> set log pmd.net.enic 7
> 
> 
> [3] bonus, see current log levels
> testpmd> dump_log_types

Nice! I didn't know about this.

> 
> 
> 
> >
> > Fixes: bbd8ecc05434 ("net/enic: remove PMD log type references")
> >
> > Signed-off-by: John Daley 
> 
> <...>



[dpdk-dev] [PATCH] net/enic: retain previous message logging

2019-07-24 Thread John Daley
Prior to fix, RTE_LOGTYPE_INFO messages would display in testpmd by
default. After the fix, using dynamic logging, only NOTICE level and
higher were displayed by default and INFO level were not. Change the
messages to NOTICE level so they continue to display.

DTS uses testpmd and parses messages and some tests failed because
messages were no longer displayed. Other apps may also depend on
the messages.

Fixes: bbd8ecc05434 ("net/enic: remove PMD log type references")

Signed-off-by: John Daley 
---
 drivers/net/enic/enic_compat.h |  2 +-
 drivers/net/enic/enic_main.c   | 25 -
 drivers/net/enic/enic_res.c| 10 +-
 3 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/net/enic/enic_compat.h b/drivers/net/enic/enic_compat.h
index bf9e998a6..0447bfc14 100644
--- a/drivers/net/enic/enic_compat.h
+++ b/drivers/net/enic/enic_compat.h
@@ -54,7 +54,7 @@ extern int enic_pmd_logtype;
"PMD: rte_enic_pmd: " fmt, ##args)
 
 #define dev_err(x, args...) dev_printk(ERR, args)
-#define dev_info(x, args...) dev_printk(INFO,  args)
+#define dev_notice(x, args...) dev_printk(NOTICE,  args)
 #define dev_warning(x, args...) dev_printk(WARNING, args)
 #define dev_debug(x, args...) dev_printk(DEBUG, args)
 
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 40af3781b..17331dc44 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -654,8 +654,7 @@ int enic_alloc_intr_resources(struct enic *enic)
int err;
unsigned int i;
 
-   dev_info(enic, "vNIC resources used:  "\
-   "wq %d rq %d cq %d intr %d\n",
+   dev_notice(enic, "vNIC resources used:  wq %d rq %d cq %d intr %d\n",
enic->wq_count, enic_vnic_rq_count(enic),
enic->cq_count, enic->intr_count);
 
@@ -811,11 +810,11 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
 
if (enic->rte_dev->data->dev_conf.rxmode.offloads &
DEV_RX_OFFLOAD_SCATTER) {
-   dev_info(enic, "Rq %u Scatter rx mode enabled\n", queue_idx);
+   dev_notice(enic, "Rq %u Scatter rx mode enabled\n", queue_idx);
/* ceil((max pkt len)/mbuf_size) */
mbufs_per_pkt = (max_rx_pkt_len + mbuf_size - 1) / mbuf_size;
} else {
-   dev_info(enic, "Scatter rx mode disabled\n");
+   dev_notice(enic, "Scatter rx mode disabled\n");
mbufs_per_pkt = 1;
if (max_rx_pkt_len > mbuf_size) {
dev_warning(enic, "The maximum Rx packet size (%u) is"
@@ -827,7 +826,7 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
}
 
if (mbufs_per_pkt > 1) {
-   dev_info(enic, "Rq %u Scatter rx mode in use\n", queue_idx);
+   dev_notice(enic, "Rq %u Scatter rx mode in use\n", queue_idx);
rq_sop->data_queue_enable = 1;
rq_data->in_use = 1;
/*
@@ -843,7 +842,7 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
" when scatter rx mode is in use.\n");
}
} else {
-   dev_info(enic, "Rq %u Scatter rx mode not being used\n",
+   dev_notice(enic, "Rq %u Scatter rx mode not being used\n",
 queue_idx);
rq_sop->data_queue_enable = 0;
rq_data->in_use = 0;
@@ -881,12 +880,12 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
nb_data_desc = max_data;
}
if (mbufs_per_pkt > 1) {
-   dev_info(enic, "For max packet size %u and mbuf size %u valid"
+   dev_notice(enic, "For max packet size %u and mbuf size %u valid"
 " rx descriptor range is %u to %u\n",
 max_rx_pkt_len, mbuf_size, min_sop + min_data,
 max_sop + max_data);
}
-   dev_info(enic, "Using %d rx descriptors (sop %d, data %d)\n",
+   dev_notice(enic, "Using %d rx descriptors (sop %d, data %d)\n",
 nb_sop_desc + nb_data_desc, nb_sop_desc, nb_data_desc);
 
/* Allocate sop queue resources */
@@ -992,7 +991,7 @@ int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
 * rte_eth_tx_queue_setup() checks min, max, and alignment. So just
 * print an info message for diagnostics.
 */
-   dev_info(enic, "TX Queues - effective number of descs:%d\n", nb_desc);
+   dev_notice(enic, "TX Queues - effective number of descs:%d\n", nb_desc);
 
/* Allocate queue resources */
err = vnic_wq_alloc(enic->vdev, &enic->wq[queue_idx], queue_idx,
@@

[dpdk-dev] [PATCH] net/enic: remove PMD log type references

2019-07-15 Thread John Daley
Don't use RTE_LOGTYPE_PMD as it is too general.

Also, just use 1 log type for all of enic PMD (pmd.net.enic)

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_compat.h| 13 ++--
 drivers/net/enic/enic_ethdev.c| 32 -
 drivers/net/enic/enic_flow.c  | 99 +--
 drivers/net/enic/enic_main.c  | 10 +--
 drivers/net/enic/enic_rxtx_vec_avx2.c |  2 +-
 5 files changed, 72 insertions(+), 84 deletions(-)

diff --git a/drivers/net/enic/enic_compat.h b/drivers/net/enic/enic_compat.h
index ceb1b0962..bf9e998a6 100644
--- a/drivers/net/enic/enic_compat.h
+++ b/drivers/net/enic/enic_compat.h
@@ -47,20 +47,21 @@
 #define kzalloc(size, flags) calloc(1, size)
 #define kfree(x) free(x)
 
+extern int enic_pmd_logtype;
+
 #define dev_printk(level, fmt, args...)\
-   RTE_LOG(level, PMD, "rte_enic_pmd: " fmt, ## args)
+   rte_log(RTE_LOG_ ## level, enic_pmd_logtype, \
+   "PMD: rte_enic_pmd: " fmt, ##args)
 
 #define dev_err(x, args...) dev_printk(ERR, args)
 #define dev_info(x, args...) dev_printk(INFO,  args)
 #define dev_warning(x, args...) dev_printk(WARNING, args)
 #define dev_debug(x, args...) dev_printk(DEBUG, args)
 
-extern int enicpmd_logtype_flow;
-extern int enicpmd_logtype_init;
-
-#define PMD_INIT_LOG(level, fmt, args...) \
-   rte_log(RTE_LOG_ ## level, enicpmd_logtype_init, \
+#define ENICPMD_LOG(level, fmt, args...) \
+   rte_log(RTE_LOG_ ## level, enic_pmd_logtype, \
"%s" fmt "\n", __func__, ##args)
+#define ENICPMD_FUNC_TRACE() ENICPMD_LOG(DEBUG, " >>")
 
 #define __le16 u16
 #define __le32 u32
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 5cfbd31a2..87df4da8e 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -21,10 +21,7 @@
 #include "vnic_enet.h"
 #include "enic.h"
 
-int enicpmd_logtype_init;
-int enicpmd_logtype_flow;
-
-#define ENICPMD_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
+int enic_pmd_logtype;
 
 /*
  * The set of PCI devices this driver supports
@@ -74,12 +71,9 @@ static const struct vic_speed_capa {
 
 RTE_INIT(enicpmd_init_log)
 {
-   enicpmd_logtype_init = rte_log_register("pmd.net.enic.init");
-   if (enicpmd_logtype_init >= 0)
-   rte_log_set_level(enicpmd_logtype_init, RTE_LOG_NOTICE);
-   enicpmd_logtype_flow = rte_log_register("pmd.net.enic.flow");
-   if (enicpmd_logtype_flow >= 0)
-   rte_log_set_level(enicpmd_logtype_flow, RTE_LOG_NOTICE);
+   enic_pmd_logtype = rte_log_register("pmd.net.enic");
+   if (enic_pmd_logtype >= 0)
+   rte_log_set_level(enic_pmd_logtype, RTE_LOG_NOTICE);
 }
 
 static int
@@ -702,7 +696,7 @@ static void debug_log_add_del_addr(struct rte_ether_addr 
*addr, bool add)
char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
 
rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr);
-   PMD_INIT_LOG(DEBUG, " %s address %s\n",
+   ENICPMD_LOG(DEBUG, " %s address %s\n",
 add ? "add" : "remove", mac_str);
 }
 
@@ -725,7 +719,7 @@ static int enicpmd_set_mc_addr_list(struct rte_eth_dev 
*eth_dev,
rte_is_broadcast_ether_addr(addr)) {
rte_ether_format_addr(mac_str,
RTE_ETHER_ADDR_FMT_SIZE, addr);
-   PMD_INIT_LOG(ERR, " invalid multicast address %s\n",
+   ENICPMD_LOG(ERR, " invalid multicast address %s\n",
 mac_str);
return -EINVAL;
}
@@ -733,7 +727,7 @@ static int enicpmd_set_mc_addr_list(struct rte_eth_dev 
*eth_dev,
 
/* Flush all if requested */
if (nb_mc_addr == 0 || mc_addr_set == NULL) {
-   PMD_INIT_LOG(DEBUG, " flush multicast addresses\n");
+   ENICPMD_LOG(DEBUG, " flush multicast addresses\n");
for (i = 0; i < enic->mc_count; i++) {
addr = &enic->mc_addrs[i];
debug_log_add_del_addr(addr, false);
@@ -746,7 +740,7 @@ static int enicpmd_set_mc_addr_list(struct rte_eth_dev 
*eth_dev,
}
 
if (nb_mc_addr > ENIC_MULTICAST_PERFECT_FILTERS) {
-   PMD_INIT_LOG(ERR, " too many multicast addresses: max=%d\n",
+   ENICPMD_LOG(ERR, " too many multicast addresses: max=%d\n",
 ENIC_MULTICAST_PERFECT_FILTERS);
return -ENOSPC;
}
@@ -966,7 +960,7 @@ static int udp_tunnel_common_check(struct enic *enic,
if (tnl->prot_type != RTE_TUNNEL_TYPE_VXLAN)
return -ENOTSUP;
if (!enic->overlay_offload) {
-  

Re: [dpdk-dev] [PATCH v2] net/enic: add private API to set ingress VLAN rewrite mode

2019-03-13 Thread John Daley (johndale)
Due to time zone differences, I'll answer for Hyong (below).
-john

> -Original Message-
> From: Thomas Monjalon 
> Sent: Wednesday, March 13, 2019 1:36 PM
> To: Ferruh Yigit ; Hyong Youb Kim (hyonkim)
> 
> Cc: Andrew Rybchenko ; Qi Zhang
> ; dev@dpdk.org; John Daley (johndale)
> ; Shahaf Shuler ; Jerin Jacob
> ; David Marchand
> ; Maxime Coquelin
> ; Konstantin Ananyev
> ; Hemant Agrawal
> ; Stephen Hemminger
> 
> Subject: Re: [PATCH v2] net/enic: add private API to set ingress VLAN rewrite
> mode
> 
> 13/03/2019 19:32, Ferruh Yigit:
> > On 3/5/2019 7:11 AM, Hyong Youb Kim wrote:
> > > The driver currently has a devarg to set the rewrite mode during
> > > init. Some apps want to programatically set it after running
> > > rte_eal_init() and finding that ports are VIC. Add a private
> > > function to support such applications.
> >
> > It is not good idea to have PMD specific APIs (although we already have
> some).
> >
> > Specific to this case, as far as I can see it is to pass a config
> > value and do the action related to it, what would you think having a
> > generic key/value set/get API in ethdev for this? Similar to rawdev
> get_attr/set_attr [1]?
> >
> > My concern is it may turn into something like ioctl with many things
> > pushed to it, and cause possible duplication ...
> 
> Yes, it is clearly ioctl style.
> 
> Please could you explain more what is the rewrite mode?
> Does it apply to the port or the queue?
> 
It applies to a port. By default the Cisco VIC VLAN tags every packet on 
ingress even if they were untagged coming in on the wire. They are tagged with 
VLAN 0 or a VLAN id programmed into the NIC depending on the configuration. Its 
part of the original design, to maintain priority bits, ancient history.

Some apps don't like this (VPP) or take a slower path (OVS). Hyong added a 
ig-vlan-rewrite=untag devarg to disable this (leave untagged/default vlan 
packets untagged) during rte_eal_init and this is helpful for OVS, but VPP 
likes to set the rewrite mode after rte_eal_init() and finding the ports are 
VIC ports. So that is the reasoning behind the private API call.





[dpdk-dev] [PATCH v2] net/enic: fix counter action

2018-10-10 Thread John Daley
- track whether counter DMAs are active or not so they can be stopped if
  needed before DMA memory is freed
- fix counter DMA shut-down by changing vnic_dev_counter_dma_cfg() to
  take the number of counters to DMA instead of high counter index and
  use num counters = 0 to shut off DMAs
- remove unnecessary checks that DMA counter memory is valid and that
  counter DMAs are in use
- change the minimum DMA period to match what 1400 series adapter is
  capable of
- fix comments and change a couple variable names to make more sense

Fixes: fc6dec87f4cb ("net/enic: support flow counter action")

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
v2 - fix typo

 drivers/net/enic/base/vnic_dev.c| 40 -
 drivers/net/enic/base/vnic_dev.h|  2 +-
 drivers/net/enic/base/vnic_devcmd.h |  1 +
 drivers/net/enic/enic.h |  4 +++-
 drivers/net/enic/enic_flow.c|  4 ++--
 drivers/net/enic/enic_main.c|  2 +-
 6 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index 1a3656f87..fd303fece 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -59,6 +59,7 @@ struct vnic_dev {
dma_addr_t dma_handle);
struct vnic_counter_counts *flow_counters;
dma_addr_t flow_counters_pa;
+   u8 flow_counters_dma_active;
 };
 
 #define VNIC_MAX_RES_HDR_SIZE \
@@ -618,18 +619,30 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct 
vnic_stats **stats)
 /*
  * Configure counter DMA
  */
-int vnic_dev_counter_dma_cfg(struct vnic_dev *vdev, u32 period, u32 
counter_idx)
+int vnic_dev_counter_dma_cfg(struct vnic_dev *vdev, u32 period,
+u32 num_counters)
 {
u64 args[3];
int wait = 1000;
+   int err;
 
-   if (!vdev->flow_counters || counter_idx >= VNIC_MAX_FLOW_COUNTERS)
+   if (num_counters > VNIC_MAX_FLOW_COUNTERS)
return -ENOMEM;
+   if (period > 0 && (period < VNIC_COUNTER_DMA_MIN_PERIOD ||
+   num_counters == 0))
+   return -EINVAL;
 
-   args[0] = counter_idx + 1;
+   args[0] = num_counters;
args[1] = vdev->flow_counters_pa;
args[2] = period;
-   return vnic_dev_cmd_args(vdev, CMD_COUNTER_DMA_CONFIG, args, 3, wait);
+   err =  vnic_dev_cmd_args(vdev, CMD_COUNTER_DMA_CONFIG, args, 3, wait);
+
+   /* record if DMAs need to be stopped on close */
+   if (!err)
+   vdev->flow_counters_dma_active = (num_counters != 0 &&
+ period != 0);
+
+   return err;
 }
 
 int vnic_dev_close(struct vnic_dev *vdev)
@@ -974,6 +987,7 @@ int vnic_dev_alloc_counter_mem(struct vnic_dev *vdev)
 * VNIC_MAX_FLOW_COUNTERS,
 &vdev->flow_counters_pa,
 (u8 *)name);
+   vdev->flow_counters_dma_active = 0;
return vdev->flow_counters == NULL ? -ENOMEM : 0;
 }
 
@@ -991,7 +1005,8 @@ void vnic_dev_unregister(struct vnic_dev *vdev)
vdev->stats, vdev->stats_pa);
if (vdev->flow_counters) {
/* turn off counter DMAs before freeing memory */
-   vnic_dev_counter_dma_cfg(vdev, 0, 0);
+   if (vdev->flow_counters_dma_active)
+   vnic_dev_counter_dma_cfg(vdev, 0, 0);
 
vdev->free_consistent(vdev->priv,
sizeof(struct vnic_counter_counts)
@@ -1171,19 +1186,16 @@ bool vnic_dev_counter_query(struct vnic_dev *vdev, 
uint32_t idx,
u64 a1 = reset ? 1 : 0;
int wait = 1000;
 
-   if (vdev->flow_counters) {
-   /* Using counter DMA API, so counters avail in host memory */
-   *packets = vdev->flow_counters[idx].vcc_packets;
-   *bytes = vdev->flow_counters[idx].vcc_bytes;
-   if (reset)
-   if (vnic_dev_cmd(vdev, CMD_COUNTER_QUERY, &a0, &a1,
-   wait))
-   return false;
-   } else {
+   if (reset) {
+   /* query/reset returns updated counters */
if (vnic_dev_cmd(vdev, CMD_COUNTER_QUERY, &a0, &a1, wait))
return false;
*packets = a0;
*bytes = a1;
+   } else {
+   /* Get values DMA'd from the adapter */
+   *packets = vdev->flow_counters[idx].vcc_packets;
+   *bytes = vdev->flow_counters[idx].vcc_bytes;
}
return true;
 }
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 63751d8c5..de2645c43 100644
--- a/dr

Re: [dpdk-dev] [PATCH] app/testpmd: fix flow query failure

2018-10-10 Thread John Daley (johndale)
Ok, makes sense now, both flow query and flow list work with this patch, yeah.

Tested-by: John Daley 

Remember that https://patches.dpdk.org/patch/46221/ still needs to be reverted 
out of dpdk-next-net/master otherwise we are still broken. The patch was 
squished into e5b652ea34.

-johnd

> -Original Message-
> From: dev  On Behalf Of Mordechay Haimovsky
> Sent: Wednesday, October 10, 2018 10:05 AM
> To: Adrien Mazarguil ; Shahaf Shuler
> ; Ori Kam 
> Cc: dev@dpdk.org; Mordechay Haimovsky 
> Subject: [dpdk-dev] [PATCH] app/testpmd: fix flow query failure
> 
> This patch fixes a bug found in port_flow_query routine which caused flow
> query command to fail with the following error "Caught error type 1 (cause
> unspecified): unknown object type to retrieve the name
> of: Invalid argument".
> 
> Fixes: f7ba5e7a0f8c ("app/testpmd: rely on flow API conversion function")
> 
> Signed-off-by: Moti Haimovsky 
> ---
>  app/test-pmd/config.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> 009c92c..b11317b 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -1239,7 +1239,8 @@ void print_valid_ports(void)
>   return -ENOENT;
>   }
>   ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
> - &name, sizeof(name), action, &error);
> + &name, sizeof(name),
> + (void *)(uintptr_t)action->type, &error);
>   if (ret < 0)
>   return port_flow_complain(&error);
>   switch (action->type) {
> --
> 1.8.3.1



[dpdk-dev] [PATCH] net/enic: fix counter action

2018-10-09 Thread John Daley
- track whether counter DMAs are active or not so they can be stopped if
  needed before DMA memory is freed
- fix counter DMA shut-down by changing vnic_dev_counter_dma_cfg() to
  take the number of counters to DMA instead of high counter index and
  use num counters = 0 to shut off DMAs
- remove unnecessary checks that DMA counter memory is valid and that
  counter DMAs are in use
- change the minimum DMA period to match what 1400 series adapter is
  capable of
- fix comments and change a couple varible names to make more sense

Fixes: fc6dec87f4cb ("net/enic: support flow counter action")

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/vnic_dev.c| 40 -
 drivers/net/enic/base/vnic_dev.h|  2 +-
 drivers/net/enic/base/vnic_devcmd.h |  1 +
 drivers/net/enic/enic.h |  4 +++-
 drivers/net/enic/enic_flow.c|  4 ++--
 drivers/net/enic/enic_main.c|  2 +-
 6 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index 1a3656f87..fd303fece 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -59,6 +59,7 @@ struct vnic_dev {
dma_addr_t dma_handle);
struct vnic_counter_counts *flow_counters;
dma_addr_t flow_counters_pa;
+   u8 flow_counters_dma_active;
 };
 
 #define VNIC_MAX_RES_HDR_SIZE \
@@ -618,18 +619,30 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct 
vnic_stats **stats)
 /*
  * Configure counter DMA
  */
-int vnic_dev_counter_dma_cfg(struct vnic_dev *vdev, u32 period, u32 
counter_idx)
+int vnic_dev_counter_dma_cfg(struct vnic_dev *vdev, u32 period,
+u32 num_counters)
 {
u64 args[3];
int wait = 1000;
+   int err;
 
-   if (!vdev->flow_counters || counter_idx >= VNIC_MAX_FLOW_COUNTERS)
+   if (num_counters > VNIC_MAX_FLOW_COUNTERS)
return -ENOMEM;
+   if (period > 0 && (period < VNIC_COUNTER_DMA_MIN_PERIOD ||
+   num_counters == 0))
+   return -EINVAL;
 
-   args[0] = counter_idx + 1;
+   args[0] = num_counters;
args[1] = vdev->flow_counters_pa;
args[2] = period;
-   return vnic_dev_cmd_args(vdev, CMD_COUNTER_DMA_CONFIG, args, 3, wait);
+   err =  vnic_dev_cmd_args(vdev, CMD_COUNTER_DMA_CONFIG, args, 3, wait);
+
+   /* record if DMAs need to be stopped on close */
+   if (!err)
+   vdev->flow_counters_dma_active = (num_counters != 0 &&
+ period != 0);
+
+   return err;
 }
 
 int vnic_dev_close(struct vnic_dev *vdev)
@@ -974,6 +987,7 @@ int vnic_dev_alloc_counter_mem(struct vnic_dev *vdev)
 * VNIC_MAX_FLOW_COUNTERS,
 &vdev->flow_counters_pa,
 (u8 *)name);
+   vdev->flow_counters_dma_active = 0;
return vdev->flow_counters == NULL ? -ENOMEM : 0;
 }
 
@@ -991,7 +1005,8 @@ void vnic_dev_unregister(struct vnic_dev *vdev)
vdev->stats, vdev->stats_pa);
if (vdev->flow_counters) {
/* turn off counter DMAs before freeing memory */
-   vnic_dev_counter_dma_cfg(vdev, 0, 0);
+   if (vdev->flow_counters_dma_active)
+   vnic_dev_counter_dma_cfg(vdev, 0, 0);
 
vdev->free_consistent(vdev->priv,
sizeof(struct vnic_counter_counts)
@@ -1171,19 +1186,16 @@ bool vnic_dev_counter_query(struct vnic_dev *vdev, 
uint32_t idx,
u64 a1 = reset ? 1 : 0;
int wait = 1000;
 
-   if (vdev->flow_counters) {
-   /* Using counter DMA API, so counters avail in host memory */
-   *packets = vdev->flow_counters[idx].vcc_packets;
-   *bytes = vdev->flow_counters[idx].vcc_bytes;
-   if (reset)
-   if (vnic_dev_cmd(vdev, CMD_COUNTER_QUERY, &a0, &a1,
-   wait))
-   return false;
-   } else {
+   if (reset) {
+   /* query/reset returns updated counters */
if (vnic_dev_cmd(vdev, CMD_COUNTER_QUERY, &a0, &a1, wait))
return false;
*packets = a0;
*bytes = a1;
+   } else {
+   /* Get values DMA'd from the adapter */
+   *packets = vdev->flow_counters[idx].vcc_packets;
+   *bytes = vdev->flow_counters[idx].vcc_bytes;
}
return true;
 }
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 63751d8c5..de2645c43 100644
--- a/drivers/net/enic/

[dpdk-dev] [PATCH] app/testpmd: fix flow list command

2018-10-09 Thread John Daley
This patch fixes the 'flow list ' command which caused a
segfault when passing the action or item 'type' field instead
of the action or item struct pointer in the call to rte_flow_conv.

Fixes: 7d94dcedf7ce ("app/testpmd: rely on flow API conversion function")

Signed-off-by: John Daley 
---
 app/test-pmd/config.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 86c205806..2ce40f3e1 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1354,7 +1354,7 @@ port_flow_list(portid_t port_id, uint32_t n, const 
uint32_t group[n])
while (item->type != RTE_FLOW_ITEM_TYPE_END) {
if (rte_flow_conv(RTE_FLOW_CONV_OP_ITEM_NAME_PTR,
  &name, sizeof(name),
- (void *)(uintptr_t)item->type,
+ (void *)(uintptr_t)item,
  NULL) <= 0)
name = "[UNKNOWN]";
if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
@@ -1365,7 +1365,7 @@ port_flow_list(portid_t port_id, uint32_t n, const 
uint32_t group[n])
while (action->type != RTE_FLOW_ACTION_TYPE_END) {
if (rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
  &name, sizeof(name),
- (void *)(uintptr_t)action->type,
+ (void *)(uintptr_t)action,
  NULL) <= 0)
name = "[UNKNOWN]";
if (action->type != RTE_FLOW_ACTION_TYPE_VOID)
-- 
2.16.2



[dpdk-dev] [PATCH v4 2/2] net/enic: add AVX2 based vectorized Rx handler

2018-10-03 Thread John Daley
From: Hyong Youb Kim 

Add the vectorized version of the no-scatter Rx handler. It aims to
process 8 descriptors per loop using AVX2 SIMD instructions. This
handler is in its own file enic_rxtx_vec_avx2.c, and makefile and
meson.build are modified to compile it when the compiler supports
AVX2. Under ideal conditions, the vectorized handler reduces
cycles/packet by more than 30%, when compared against the no-scatter
Rx handler. Most implementation ideas come from i40e's AVX2 based
handler, so credit goes to its authors.

At this point, the new handler is meant for field trials, and is not
selected by default. So add a new devarg enable-avx2-rx to allow the
user to request the use of the new handler. When enable-avx2-rx=1, the
driver will consider using the new handler.

Also update the guide doc and introduce the vectorized handler.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
v2: remove bool type from stucture (found by checkpatch)
v3: re-add Reviewed-by
v4: Address Ferruh's comments regarding doc, comment, and log message.
Fix makefile and meson.build to compile the avx2 handler when 'machine'
does not support avx2 but the compiler does

 doc/guides/nics/enic.rst  |  35 ++
 drivers/net/enic/Makefile |  28 ++
 drivers/net/enic/enic.h   |   7 +
 drivers/net/enic/enic_ethdev.c|  27 +-
 drivers/net/enic/enic_main.c  |  37 +-
 drivers/net/enic/enic_rxtx_vec_avx2.c | 831 ++
 drivers/net/enic/meson.build  |  16 +
 7 files changed, 972 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/enic/enic_rxtx_vec_avx2.c

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 1f2951ea9..623b26247 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -351,6 +351,41 @@ suitable for others. Such applications may change the mode 
by setting
   applications such as OVS-DPDK performance benchmarks that utilize
   only the default VLAN and want to see only untagged packets.
 
+
+Vectorized Rx Handler
+-
+
+ENIC PMD includes a version of the receive handler that is vectorized using
+AVX2 SIMD instructions. It is meant for bulk, throughput oriented workloads
+where reducing cycles/packet in PMD is a priority. In order to use the
+vectorized handler, take the following steps.
+
+- Use a recent version of gcc, icc, or clang and build 64-bit DPDK. If
+  the compiler is known to support AVX2, DPDK build system
+  automatically compiles the vectorized handler. Otherwise, the
+  handler is not available.
+
+- Set ``devargs`` parameter ``enable-avx2-rx=1`` to explicitly request that
+  PMD consider the vectorized handler when selecting the receive handler.
+  For example::
+
+-w 12:00.0,enable-avx2-rx=1
+
+  As the current implementation is intended for field trials, by default, the
+  vectorized handler is not considerd (``enable-avx2-rx=0``).
+
+- Run on a UCS M4 or later server with CPUs that support AVX2.
+
+PMD selects the vectorized handler when the handler is compiled into
+the driver, the user requests its use via ``enable-avx2-rx=1``, CPU
+supports AVX2, and scatter Rx is not used. To verify that the
+vectorized handler is selected, enable debug logging
+(``--log-level=pmd,debug``) and check the following message.
+
+.. code-block:: console
+
+enic_use_vector_rx_handler use the non-scatter avx2 Rx handler
+
 .. _enic_limitations:
 
 Limitations
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 7c6c29cc0..e39e47631 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -39,4 +39,32 @@ SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_intr.c
 SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_rq.c
 SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_rss.c
 
+# The current implementation assumes 64-bit pointers
+CC_AVX2_SUPPORT=0
+ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
+# Figure out if the compiler supports avx2. The extra check using
+# -march=core-avx2 is necessary to support users who build for the
+# 'default' machine (corei7 which has no avx2) and run the binary on
+# newer CPUs that have avx2.
+# This part is verbatim from i40e makefile.
+ifeq ($(findstring 
RTE_MACHINE_CPUFLAG_AVX2,$(CFLAGS)),RTE_MACHINE_CPUFLAG_AVX2)
+   CC_AVX2_SUPPORT=1
+else
+   CC_AVX2_SUPPORT=\
+   $(shell $(CC) -march=core-avx2 -dM -E - &1 | \
+   grep -q AVX2 && echo 1)
+   ifeq ($(CC_AVX2_SUPPORT), 1)
+   ifeq ($(CONFIG_RTE_TOOLCHAIN_ICC),y)
+   CFLAGS_enic_rxtx_vec_avx2.o += -march=core-avx2
+   else
+   CFLAGS_enic_rxtx_vec_avx2.o += -mavx2
+   endif
+   endif
+endif
+endif
+
+ifeq ($(CC_AVX2_SUPPORT), 1)
+   SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic_rxtx_vec_avx2.c
+endif
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 775cd5d5

[dpdk-dev] [PATCH v4 1/2] net/enic: move common Rx functions to a new header file

2018-10-03 Thread John Daley
From: Hyong Youb Kim 

Move a number of Rx functions to the header file so that the avx2
based Rx handler can use them.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
v2: remove bool type from stucture (found by checkpatch)
v3: re-add Reviewed-by
v4: Address Ferruh's comments regarding doc, comment, and log message.
Fix makefile and meson.build to compile the avx2 handler when 'machine'
does not support avx2 but the compiler does

 drivers/net/enic/enic_rxtx.c| 263 +-
 drivers/net/enic/enic_rxtx_common.h | 271 
 2 files changed, 272 insertions(+), 262 deletions(-)
 create mode 100644 drivers/net/enic/enic_rxtx_common.h

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 276a2e559..5189ee635 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -11,6 +11,7 @@
 #include "enic_compat.h"
 #include "rq_enet_desc.h"
 #include "enic.h"
+#include "enic_rxtx_common.h"
 #include 
 #include 
 #include 
@@ -30,268 +31,6 @@
 #define rte_packet_prefetch(p) do {} while (0)
 #endif
 
-static inline uint16_t
-enic_cq_rx_desc_ciflags(struct cq_enet_rq_desc *crd)
-{
-   return le16_to_cpu(crd->completed_index_flags) & ~CQ_DESC_COMP_NDX_MASK;
-}
-
-static inline uint16_t
-enic_cq_rx_desc_bwflags(struct cq_enet_rq_desc *crd)
-{
-   return le16_to_cpu(crd->bytes_written_flags) &
-  ~CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_packet_error(uint16_t bwflags)
-{
-   return (bwflags & CQ_ENET_RQ_DESC_FLAGS_TRUNCATED) ==
-   CQ_ENET_RQ_DESC_FLAGS_TRUNCATED;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_eop(uint16_t ciflags)
-{
-   return (ciflags & CQ_ENET_RQ_DESC_FLAGS_EOP)
-   == CQ_ENET_RQ_DESC_FLAGS_EOP;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_csum_not_calc(struct cq_enet_rq_desc *cqrd)
-{
-   return (le16_to_cpu(cqrd->q_number_rss_type_flags) &
-   CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC) ==
-   CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_ipv4_csum_ok(struct cq_enet_rq_desc *cqrd)
-{
-   return (cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK) ==
-   CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_tcp_udp_csum_ok(struct cq_enet_rq_desc *cqrd)
-{
-   return (cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK) ==
-   CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_rss_type(struct cq_enet_rq_desc *cqrd)
-{
-   return (uint8_t)((le16_to_cpu(cqrd->q_number_rss_type_flags) >>
-   CQ_DESC_Q_NUM_BITS) & CQ_ENET_RQ_DESC_RSS_TYPE_MASK);
-}
-
-static inline uint32_t
-enic_cq_rx_desc_rss_hash(struct cq_enet_rq_desc *cqrd)
-{
-   return le32_to_cpu(cqrd->rss_hash);
-}
-
-static inline uint16_t
-enic_cq_rx_desc_vlan(struct cq_enet_rq_desc *cqrd)
-{
-   return le16_to_cpu(cqrd->vlan);
-}
-
-static inline uint16_t
-enic_cq_rx_desc_n_bytes(struct cq_desc *cqd)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   return le16_to_cpu(cqrd->bytes_written_flags) &
-   CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
-}
-
-
-static inline uint8_t
-enic_cq_rx_check_err(struct cq_desc *cqd)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   uint16_t bwflags;
-
-   bwflags = enic_cq_rx_desc_bwflags(cqrd);
-   if (unlikely(enic_cq_rx_desc_packet_error(bwflags)))
-   return 1;
-   return 0;
-}
-
-/* Lookup table to translate RX CQ flags to mbuf flags. */
-static inline uint32_t
-enic_cq_rx_flags_to_pkt_type(struct cq_desc *cqd, uint8_t tnl)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   uint8_t cqrd_flags = cqrd->flags;
-   /*
-* Odd-numbered entries are for tunnel packets. All packet type info
-* applies to the inner packet, and there is no info on the outer
-* packet. The outer flags in these entries exist only to avoid
-* changing enic_cq_rx_to_pkt_flags(). They are cleared from mbuf
-* afterwards.
-*
-* Also, as there is no tunnel type info (VXLAN, NVGRE, or GENEVE), set
-* RTE_PTYPE_TUNNEL_GRENAT..
-*/
-   static const uint32_t cq_type_table[128] __rte_cache_aligned = {
-   [0x00] = RTE_PTYPE_UNKNOWN,
-   [0x01] = RTE_PTYPE_UNKNOWN |
-RTE_PTYPE_TUNNEL_GRENAT |
-RTE_PTYPE_INNER_L2_ETHER,
-   [0x20] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG,
-   [0x21] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG |
-RTE_PTYPE_T

[dpdk-dev] [PATCH v2 2/2] net/enic: add AVX2 based vectorized Rx handler

2018-09-28 Thread John Daley
From: Hyong Youb Kim 

Add the vectorized version of the no-scatter Rx handler. It aims to
process 8 descriptors per loop using AVX2 SIMD instructions. This
handler is in its own file enic_rxtx_vec_avx2.c, and makefile and
meson.build are modified to compile it when the compiler supports
AVX2. Under ideal conditions, the vectorized handler reduces
cycles/packet by more than 30%, when compared against the no-scatter
Rx handler. Most implementation ideas come from i40e's AVX2 based
handler, so credit goes to its authors.

At this point, the new handler is meant for field trials, and is not
selected by default. So add a new devarg enable-avx2-rx to allow the
user to request the use of the new handler. When enable-avx2-rx=1, the
driver will consider using the new handler.

Also update the guide doc and introduce the vectorized handler.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---

v2: remove bool type from stucture (found by checkpatch)
v3: re-add Reviewed-by

 doc/guides/nics/enic.rst  |  32 ++
 drivers/net/enic/Makefile |   7 +
 drivers/net/enic/enic.h   |   3 +
 drivers/net/enic/enic_ethdev.c|  27 +-
 drivers/net/enic/enic_main.c  |  34 +-
 drivers/net/enic/enic_rxtx_vec_avx2.c | 832 ++
 drivers/net/enic/meson.build  |   5 +
 7 files changed, 931 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/enic/enic_rxtx_vec_avx2.c

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 86941fdb2..b31f4eef9 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -351,6 +351,38 @@ suitable for others. Such applications may change the mode 
by setting
   applications such as OVS-DPDK performance benchmarks that utilize
   only the default VLAN and want to see only untagged packets.
 
+
+Vectorized Rx Handler
+-
+
+ENIC PMD includes a version of the receive handler that is vectorized using
+AVX2 SIMD instructions. It is meant for bulk, throughput oriented workloads
+where reducing cycles/packet in PMD is a priority. In order to use the
+vectorized handler, take the following steps.
+
+- Use a recent version of gcc, icc, or clang and build 64-bit DPDK. If
+  the compiler is known to support AVX2, DPDK build system
+  automatically compiles the vectorized handler. Otherwise, the
+  handler is not available.
+
+- Set ``devargs`` parameter ``enable-avx2-rx=1`` to explicitly request that
+  PMD consider the vectorized handler when selecting the receive handler.
+
+  As the current implementation is intended for field trials, by default, the
+  vectorized handler is not considerd (``enable-avx2-rx=0``).
+
+- Run on a UCS M4 or later server with CPUs that support AVX2.
+
+PMD selects the vectorized handler when the handler is compiled into
+the driver, the user requests its use via ``enable-avx2-rx=1``, CPU
+supports AVX2, and scatter Rx is not used. To verify that the
+vectorized handler is selected, enable debug logging
+(``--log-level=pmd,debug``) and check the following message.
+
+.. code-block:: console
+
+enic_use_vector_rx_handler use the non-scatter avx2 Rx handler
+
 .. _enic_limitations:
 
 Limitations
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 7c6c29cc0..3ec6f9159 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -39,4 +39,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_intr.c
 SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_rq.c
 SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_rss.c
 
+ifeq ($(findstring 
RTE_MACHINE_CPUFLAG_AVX2,$(CFLAGS)),RTE_MACHINE_CPUFLAG_AVX2)
+# The current implementation assumes 64-bit pointers
+ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
+   SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic_rxtx_vec_avx2.c
+endif
+endif
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 775cd5d55..665f5668a 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -106,6 +106,7 @@ struct enic {
struct vnic_dev_bar bar0;
struct vnic_dev *vdev;
 
+   uint64_t mbuf_initializer;
unsigned int port_id;
bool overlay_offload;
struct rte_eth_dev *rte_dev;
@@ -128,6 +129,7 @@ struct enic {
u8 filter_actions; /* HW supported actions */
bool vxlan;
bool disable_overlay; /* devargs disable_overlay=1 */
+   uint8_t enable_avx2_rx;  /* devargs enable-avx2-rx=1 */
bool nic_cfg_chk; /* NIC_CFG_CHK available */
bool udp_rss_weak;/* Bodega style UDP RSS */
uint8_t ig_vlan_rewrite_mode; /* devargs ig-vlan-rewrite */
@@ -329,6 +331,7 @@ uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
uint16_t nb_pkts);
 int enic_set_mtu(struct enic *enic, uint16_t new_mtu);
 int enic_link_update(struct enic *enic);
+bool enic_use_vector_rx_handler(struct enic *enic);
 void enic_fdir_info(struct enic *enic);

[dpdk-dev] [PATCH v2 1/2] net/enic: move common Rx functions to a new header file

2018-09-28 Thread John Daley
From: Hyong Youb Kim 

Move a number of Rx functions to the header file so that the avx2
based Rx handler can use them.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---

v3: re-add Reviewed-by

 drivers/net/enic/enic_rxtx.c| 263 +-
 drivers/net/enic/enic_rxtx_common.h | 271 
 2 files changed, 272 insertions(+), 262 deletions(-)
 create mode 100644 drivers/net/enic/enic_rxtx_common.h

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 276a2e559..5189ee635 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -11,6 +11,7 @@
 #include "enic_compat.h"
 #include "rq_enet_desc.h"
 #include "enic.h"
+#include "enic_rxtx_common.h"
 #include 
 #include 
 #include 
@@ -30,268 +31,6 @@
 #define rte_packet_prefetch(p) do {} while (0)
 #endif
 
-static inline uint16_t
-enic_cq_rx_desc_ciflags(struct cq_enet_rq_desc *crd)
-{
-   return le16_to_cpu(crd->completed_index_flags) & ~CQ_DESC_COMP_NDX_MASK;
-}
-
-static inline uint16_t
-enic_cq_rx_desc_bwflags(struct cq_enet_rq_desc *crd)
-{
-   return le16_to_cpu(crd->bytes_written_flags) &
-  ~CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_packet_error(uint16_t bwflags)
-{
-   return (bwflags & CQ_ENET_RQ_DESC_FLAGS_TRUNCATED) ==
-   CQ_ENET_RQ_DESC_FLAGS_TRUNCATED;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_eop(uint16_t ciflags)
-{
-   return (ciflags & CQ_ENET_RQ_DESC_FLAGS_EOP)
-   == CQ_ENET_RQ_DESC_FLAGS_EOP;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_csum_not_calc(struct cq_enet_rq_desc *cqrd)
-{
-   return (le16_to_cpu(cqrd->q_number_rss_type_flags) &
-   CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC) ==
-   CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_ipv4_csum_ok(struct cq_enet_rq_desc *cqrd)
-{
-   return (cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK) ==
-   CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_tcp_udp_csum_ok(struct cq_enet_rq_desc *cqrd)
-{
-   return (cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK) ==
-   CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_rss_type(struct cq_enet_rq_desc *cqrd)
-{
-   return (uint8_t)((le16_to_cpu(cqrd->q_number_rss_type_flags) >>
-   CQ_DESC_Q_NUM_BITS) & CQ_ENET_RQ_DESC_RSS_TYPE_MASK);
-}
-
-static inline uint32_t
-enic_cq_rx_desc_rss_hash(struct cq_enet_rq_desc *cqrd)
-{
-   return le32_to_cpu(cqrd->rss_hash);
-}
-
-static inline uint16_t
-enic_cq_rx_desc_vlan(struct cq_enet_rq_desc *cqrd)
-{
-   return le16_to_cpu(cqrd->vlan);
-}
-
-static inline uint16_t
-enic_cq_rx_desc_n_bytes(struct cq_desc *cqd)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   return le16_to_cpu(cqrd->bytes_written_flags) &
-   CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
-}
-
-
-static inline uint8_t
-enic_cq_rx_check_err(struct cq_desc *cqd)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   uint16_t bwflags;
-
-   bwflags = enic_cq_rx_desc_bwflags(cqrd);
-   if (unlikely(enic_cq_rx_desc_packet_error(bwflags)))
-   return 1;
-   return 0;
-}
-
-/* Lookup table to translate RX CQ flags to mbuf flags. */
-static inline uint32_t
-enic_cq_rx_flags_to_pkt_type(struct cq_desc *cqd, uint8_t tnl)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   uint8_t cqrd_flags = cqrd->flags;
-   /*
-* Odd-numbered entries are for tunnel packets. All packet type info
-* applies to the inner packet, and there is no info on the outer
-* packet. The outer flags in these entries exist only to avoid
-* changing enic_cq_rx_to_pkt_flags(). They are cleared from mbuf
-* afterwards.
-*
-* Also, as there is no tunnel type info (VXLAN, NVGRE, or GENEVE), set
-* RTE_PTYPE_TUNNEL_GRENAT..
-*/
-   static const uint32_t cq_type_table[128] __rte_cache_aligned = {
-   [0x00] = RTE_PTYPE_UNKNOWN,
-   [0x01] = RTE_PTYPE_UNKNOWN |
-RTE_PTYPE_TUNNEL_GRENAT |
-RTE_PTYPE_INNER_L2_ETHER,
-   [0x20] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG,
-   [0x21] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG |
-RTE_PTYPE_TUNNEL_GRENAT |
-RTE_PTYPE_INNER_L2_ETHER |
-RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
-RTE_PTYPE_INNER_L4_NONFRAG,
-   [0x22] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
-   

[dpdk-dev] [PATCH v2 2/2] net/enic: add AVX2 based vectorized Rx handler

2018-09-28 Thread John Daley
From: Hyong Youb Kim 

Add the vectorized version of the no-scatter Rx handler. It aims to
process 8 descriptors per loop using AVX2 SIMD instructions. This
handler is in its own file enic_rxtx_vec_avx2.c, and makefile and
meson.build are modified to compile it when the compiler supports
AVX2. Under ideal conditions, the vectorized handler reduces
cycles/packet by more than 30%, when compared against the no-scatter
Rx handler. Most implementation ideas come from i40e's AVX2 based
handler, so credit goes to its authors.

At this point, the new handler is meant for field trials, and is not
selected by default. So add a new devarg enable-avx2-rx to allow the
user to request the use of the new handler. When enable-avx2-rx=1, the
driver will consider using the new handler.

Also update the guide doc and introduce the vectorized handler.

Signed-off-by: Hyong Youb Kim 
---

v2: remove bool type from stucture (found by checkpatch)

 doc/guides/nics/enic.rst  |  32 ++
 drivers/net/enic/Makefile |   7 +
 drivers/net/enic/enic.h   |   3 +
 drivers/net/enic/enic_ethdev.c|  27 +-
 drivers/net/enic/enic_main.c  |  34 +-
 drivers/net/enic/enic_rxtx_vec_avx2.c | 832 ++
 drivers/net/enic/meson.build  |   5 +
 7 files changed, 931 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/enic/enic_rxtx_vec_avx2.c

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 86941fdb2..b31f4eef9 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -351,6 +351,38 @@ suitable for others. Such applications may change the mode 
by setting
   applications such as OVS-DPDK performance benchmarks that utilize
   only the default VLAN and want to see only untagged packets.
 
+
+Vectorized Rx Handler
+-
+
+ENIC PMD includes a version of the receive handler that is vectorized using
+AVX2 SIMD instructions. It is meant for bulk, throughput oriented workloads
+where reducing cycles/packet in PMD is a priority. In order to use the
+vectorized handler, take the following steps.
+
+- Use a recent version of gcc, icc, or clang and build 64-bit DPDK. If
+  the compiler is known to support AVX2, DPDK build system
+  automatically compiles the vectorized handler. Otherwise, the
+  handler is not available.
+
+- Set ``devargs`` parameter ``enable-avx2-rx=1`` to explicitly request that
+  PMD consider the vectorized handler when selecting the receive handler.
+
+  As the current implementation is intended for field trials, by default, the
+  vectorized handler is not considerd (``enable-avx2-rx=0``).
+
+- Run on a UCS M4 or later server with CPUs that support AVX2.
+
+PMD selects the vectorized handler when the handler is compiled into
+the driver, the user requests its use via ``enable-avx2-rx=1``, CPU
+supports AVX2, and scatter Rx is not used. To verify that the
+vectorized handler is selected, enable debug logging
+(``--log-level=pmd,debug``) and check the following message.
+
+.. code-block:: console
+
+enic_use_vector_rx_handler use the non-scatter avx2 Rx handler
+
 .. _enic_limitations:
 
 Limitations
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 7c6c29cc0..3ec6f9159 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -39,4 +39,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_intr.c
 SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_rq.c
 SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_rss.c
 
+ifeq ($(findstring 
RTE_MACHINE_CPUFLAG_AVX2,$(CFLAGS)),RTE_MACHINE_CPUFLAG_AVX2)
+# The current implementation assumes 64-bit pointers
+ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
+   SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic_rxtx_vec_avx2.c
+endif
+endif
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 775cd5d55..665f5668a 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -106,6 +106,7 @@ struct enic {
struct vnic_dev_bar bar0;
struct vnic_dev *vdev;
 
+   uint64_t mbuf_initializer;
unsigned int port_id;
bool overlay_offload;
struct rte_eth_dev *rte_dev;
@@ -128,6 +129,7 @@ struct enic {
u8 filter_actions; /* HW supported actions */
bool vxlan;
bool disable_overlay; /* devargs disable_overlay=1 */
+   uint8_t enable_avx2_rx;  /* devargs enable-avx2-rx=1 */
bool nic_cfg_chk; /* NIC_CFG_CHK available */
bool udp_rss_weak;/* Bodega style UDP RSS */
uint8_t ig_vlan_rewrite_mode; /* devargs ig-vlan-rewrite */
@@ -329,6 +331,7 @@ uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
uint16_t nb_pkts);
 int enic_set_mtu(struct enic *enic, uint16_t new_mtu);
 int enic_link_update(struct enic *enic);
+bool enic_use_vector_rx_handler(struct enic *enic);
 void enic_fdir_info(struct enic *enic);
 void enic_fdir_info_get(struct enic *enic, struct rte

[dpdk-dev] [PATCH v2 1/2] net/enic: move common Rx functions to a new header file

2018-09-28 Thread John Daley
From: Hyong Youb Kim 

Move a number of Rx functions to the header file so that the avx2
based Rx handler can use them.

Signed-off-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_rxtx.c| 263 +-
 drivers/net/enic/enic_rxtx_common.h | 271 
 2 files changed, 272 insertions(+), 262 deletions(-)
 create mode 100644 drivers/net/enic/enic_rxtx_common.h

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 276a2e559..5189ee635 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -11,6 +11,7 @@
 #include "enic_compat.h"
 #include "rq_enet_desc.h"
 #include "enic.h"
+#include "enic_rxtx_common.h"
 #include 
 #include 
 #include 
@@ -30,268 +31,6 @@
 #define rte_packet_prefetch(p) do {} while (0)
 #endif
 
-static inline uint16_t
-enic_cq_rx_desc_ciflags(struct cq_enet_rq_desc *crd)
-{
-   return le16_to_cpu(crd->completed_index_flags) & ~CQ_DESC_COMP_NDX_MASK;
-}
-
-static inline uint16_t
-enic_cq_rx_desc_bwflags(struct cq_enet_rq_desc *crd)
-{
-   return le16_to_cpu(crd->bytes_written_flags) &
-  ~CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_packet_error(uint16_t bwflags)
-{
-   return (bwflags & CQ_ENET_RQ_DESC_FLAGS_TRUNCATED) ==
-   CQ_ENET_RQ_DESC_FLAGS_TRUNCATED;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_eop(uint16_t ciflags)
-{
-   return (ciflags & CQ_ENET_RQ_DESC_FLAGS_EOP)
-   == CQ_ENET_RQ_DESC_FLAGS_EOP;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_csum_not_calc(struct cq_enet_rq_desc *cqrd)
-{
-   return (le16_to_cpu(cqrd->q_number_rss_type_flags) &
-   CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC) ==
-   CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_ipv4_csum_ok(struct cq_enet_rq_desc *cqrd)
-{
-   return (cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK) ==
-   CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_tcp_udp_csum_ok(struct cq_enet_rq_desc *cqrd)
-{
-   return (cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK) ==
-   CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_rss_type(struct cq_enet_rq_desc *cqrd)
-{
-   return (uint8_t)((le16_to_cpu(cqrd->q_number_rss_type_flags) >>
-   CQ_DESC_Q_NUM_BITS) & CQ_ENET_RQ_DESC_RSS_TYPE_MASK);
-}
-
-static inline uint32_t
-enic_cq_rx_desc_rss_hash(struct cq_enet_rq_desc *cqrd)
-{
-   return le32_to_cpu(cqrd->rss_hash);
-}
-
-static inline uint16_t
-enic_cq_rx_desc_vlan(struct cq_enet_rq_desc *cqrd)
-{
-   return le16_to_cpu(cqrd->vlan);
-}
-
-static inline uint16_t
-enic_cq_rx_desc_n_bytes(struct cq_desc *cqd)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   return le16_to_cpu(cqrd->bytes_written_flags) &
-   CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
-}
-
-
-static inline uint8_t
-enic_cq_rx_check_err(struct cq_desc *cqd)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   uint16_t bwflags;
-
-   bwflags = enic_cq_rx_desc_bwflags(cqrd);
-   if (unlikely(enic_cq_rx_desc_packet_error(bwflags)))
-   return 1;
-   return 0;
-}
-
-/* Lookup table to translate RX CQ flags to mbuf flags. */
-static inline uint32_t
-enic_cq_rx_flags_to_pkt_type(struct cq_desc *cqd, uint8_t tnl)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   uint8_t cqrd_flags = cqrd->flags;
-   /*
-* Odd-numbered entries are for tunnel packets. All packet type info
-* applies to the inner packet, and there is no info on the outer
-* packet. The outer flags in these entries exist only to avoid
-* changing enic_cq_rx_to_pkt_flags(). They are cleared from mbuf
-* afterwards.
-*
-* Also, as there is no tunnel type info (VXLAN, NVGRE, or GENEVE), set
-* RTE_PTYPE_TUNNEL_GRENAT..
-*/
-   static const uint32_t cq_type_table[128] __rte_cache_aligned = {
-   [0x00] = RTE_PTYPE_UNKNOWN,
-   [0x01] = RTE_PTYPE_UNKNOWN |
-RTE_PTYPE_TUNNEL_GRENAT |
-RTE_PTYPE_INNER_L2_ETHER,
-   [0x20] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG,
-   [0x21] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG |
-RTE_PTYPE_TUNNEL_GRENAT |
-RTE_PTYPE_INNER_L2_ETHER |
-RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
-RTE_PTYPE_INNER_L4_NONFRAG,
-   [0x22] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
-   [0x23] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP |
-RTE_PTYPE_TUNNEL_GRENAT |
-RTE_PTYPE_INNER_L2_ETHER |
-RTE_PTYPE_INNER

[dpdk-dev] [PATCH v2 3/3] doc: update enic guide for flow API counter action

2018-09-27 Thread John Daley
Add counter action support

Signed-off-by: John Daley 
---
 doc/guides/nics/enic.rst | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 438a83d5f..86941fdb2 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -260,6 +260,12 @@ Generic Flow API is supported. The baseline support is:
   - Selectors: 'is', 'spec' and 'mask'. 'last' is not supported
   - In total, up to 64 bytes of mask is allowed across all headers
 
+- **1400 and later series VICS with advanced filters enabled**
+
+  All the above plus:
+
+  - Action: count
+
 More features may be added in future firmware and new versions of the VIC.
 Please refer to the release notes.
 
-- 
2.16.2



[dpdk-dev] [PATCH v2 2/3] net/enic: support for flow counter action

2018-09-27 Thread John Daley
Support counter action for 1400 series adapters.

The adapter API for allocating and freeing counters is independent of
the adapter match/action API. If the filter action is requested, a
counter is first allocated and then assigned to the filter, and when
the filter is deleted, the counter must also be deleted.

Counters are DMAd to pre-allocated consistent memory periodically,
controlled by the define VNIC_FLOW_COUNTER_UPDATE_MSECS. The default is
100 milliseconds.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
v2: fix parens (coding style)

 drivers/net/enic/base/vnic_dev.c|  93 +++
 drivers/net/enic/base/vnic_dev.h|   8 ++
 drivers/net/enic/base/vnic_devcmd.h |  57 +++-
 drivers/net/enic/enic.h |   3 +
 drivers/net/enic/enic_flow.c| 178 
 drivers/net/enic/enic_main.c|  11 ++-
 drivers/net/enic/enic_res.c |   6 +-
 7 files changed, 331 insertions(+), 25 deletions(-)

diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index 16e8814a6..1a3656f87 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -57,6 +57,8 @@ struct vnic_dev {
void (*free_consistent)(void *priv,
size_t size, void *vaddr,
dma_addr_t dma_handle);
+   struct vnic_counter_counts *flow_counters;
+   dma_addr_t flow_counters_pa;
 };
 
 #define VNIC_MAX_RES_HDR_SIZE \
@@ -64,6 +66,8 @@ struct vnic_dev {
sizeof(struct vnic_resource) * RES_TYPE_MAX)
 #define VNIC_RES_STRIDE128
 
+#define VNIC_MAX_FLOW_COUNTERS 2048
+
 void *vnic_dev_priv(struct vnic_dev *vdev)
 {
return vdev->priv;
@@ -611,6 +615,23 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct 
vnic_stats **stats)
return vnic_dev_cmd(vdev, CMD_STATS_DUMP, &a0, &a1, wait);
 }
 
+/*
+ * Configure counter DMA
+ */
+int vnic_dev_counter_dma_cfg(struct vnic_dev *vdev, u32 period, u32 
counter_idx)
+{
+   u64 args[3];
+   int wait = 1000;
+
+   if (!vdev->flow_counters || counter_idx >= VNIC_MAX_FLOW_COUNTERS)
+   return -ENOMEM;
+
+   args[0] = counter_idx + 1;
+   args[1] = vdev->flow_counters_pa;
+   args[2] = period;
+   return vnic_dev_cmd_args(vdev, CMD_COUNTER_DMA_CONFIG, args, 3, wait);
+}
+
 int vnic_dev_close(struct vnic_dev *vdev)
 {
u64 a0 = 0, a1 = 0;
@@ -939,6 +960,23 @@ int vnic_dev_alloc_stats_mem(struct vnic_dev *vdev)
return vdev->stats == NULL ? -ENOMEM : 0;
 }
 
+/*
+ * Initialize for up to VNIC_MAX_FLOW_COUNTERS
+ */
+int vnic_dev_alloc_counter_mem(struct vnic_dev *vdev)
+{
+   char name[NAME_MAX];
+   static u32 instance;
+
+   snprintf((char *)name, sizeof(name), "vnic_flow_ctrs-%u", instance++);
+   vdev->flow_counters = vdev->alloc_consistent(vdev->priv,
+sizeof(struct vnic_counter_counts)
+* VNIC_MAX_FLOW_COUNTERS,
+&vdev->flow_counters_pa,
+(u8 *)name);
+   return vdev->flow_counters == NULL ? -ENOMEM : 0;
+}
+
 void vnic_dev_unregister(struct vnic_dev *vdev)
 {
if (vdev) {
@@ -951,6 +989,15 @@ void vnic_dev_unregister(struct vnic_dev *vdev)
vdev->free_consistent(vdev->priv,
sizeof(struct vnic_stats),
vdev->stats, vdev->stats_pa);
+   if (vdev->flow_counters) {
+   /* turn off counter DMAs before freeing memory */
+   vnic_dev_counter_dma_cfg(vdev, 0, 0);
+
+   vdev->free_consistent(vdev->priv,
+   sizeof(struct vnic_counter_counts)
+   * VNIC_MAX_FLOW_COUNTERS,
+   vdev->flow_counters, vdev->flow_counters_pa);
+   }
if (vdev->fw_info)
vdev->free_consistent(vdev->priv,
sizeof(struct vnic_devcmd_fw_info),
@@ -1094,3 +1141,49 @@ int vnic_dev_capable_vxlan(struct vnic_dev *vdev)
(a1 & (FEATURE_VXLAN_IPV6 | FEATURE_VXLAN_MULTI_WQ)) ==
(FEATURE_VXLAN_IPV6 | FEATURE_VXLAN_MULTI_WQ);
 }
+
+bool vnic_dev_counter_alloc(struct vnic_dev *vdev, uint32_t *idx)
+{
+   u64 a0 = 0;
+   u64 a1 = 0;
+   int wait = 1000;
+
+   if (vnic_dev_cmd(vdev, CMD_COUNTER_ALLOC, &a0, &a1, wait))
+   return false;
+   *idx = (uint32_t)a0;
+   return true;
+}
+
+bool vnic_dev_counter_free(struct vnic_dev *vdev, uint32_t idx)
+{
+   u64 a0 = idx;
+   u64 a1 = 0;
+   int wait = 1000;
+
+   return vnic_dev_cmd(vdev, CMD_COUNTER_FREE, &a0, &a1,
+

[dpdk-dev] [PATCH v2 1/3] net/enic: fix flow API memory leak

2018-09-27 Thread John Daley
rte_flow structures were not being freed when destroyed or flushed.

Fixes: 6ced137607d0 ("net/enic: flow API for NICs with advanced filters 
enabled")
Cc: sta...@dpdk.org

Signed-off-by: Hyong Youb Kim 
Signed-off-by: John Daley 
---
v2: fix signoff

 drivers/net/enic/enic_flow.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
index 0cf04aefd..9b612f1d5 100644
--- a/drivers/net/enic/enic_flow.c
+++ b/drivers/net/enic/enic_flow.c
@@ -1532,6 +1532,7 @@ enic_flow_destroy(struct rte_eth_dev *dev, struct 
rte_flow *flow,
enic_flow_del_filter(enic, flow->enic_filter_id, error);
LIST_REMOVE(flow, next);
rte_spinlock_unlock(&enic->flows_lock);
+   rte_free(flow);
return 0;
 }
 
@@ -1555,6 +1556,7 @@ enic_flow_flush(struct rte_eth_dev *dev, struct 
rte_flow_error *error)
flow = LIST_FIRST(&enic->flows);
enic_flow_del_filter(enic, flow->enic_filter_id, error);
LIST_REMOVE(flow, next);
+   rte_free(flow);
}
rte_spinlock_unlock(&enic->flows_lock);
return 0;
-- 
2.16.2



[dpdk-dev] [PATCH 1/2] net/enic: move common Rx functions to a new header file

2018-09-27 Thread John Daley
From: Hyong Youb Kim 

Move a number of Rx functions to the header file so that the avx2
based Rx handler can use them.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_rxtx.c| 263 +-
 drivers/net/enic/enic_rxtx_common.h | 271 
 2 files changed, 272 insertions(+), 262 deletions(-)
 create mode 100644 drivers/net/enic/enic_rxtx_common.h

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 276a2e559..5189ee635 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -11,6 +11,7 @@
 #include "enic_compat.h"
 #include "rq_enet_desc.h"
 #include "enic.h"
+#include "enic_rxtx_common.h"
 #include 
 #include 
 #include 
@@ -30,268 +31,6 @@
 #define rte_packet_prefetch(p) do {} while (0)
 #endif
 
-static inline uint16_t
-enic_cq_rx_desc_ciflags(struct cq_enet_rq_desc *crd)
-{
-   return le16_to_cpu(crd->completed_index_flags) & ~CQ_DESC_COMP_NDX_MASK;
-}
-
-static inline uint16_t
-enic_cq_rx_desc_bwflags(struct cq_enet_rq_desc *crd)
-{
-   return le16_to_cpu(crd->bytes_written_flags) &
-  ~CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_packet_error(uint16_t bwflags)
-{
-   return (bwflags & CQ_ENET_RQ_DESC_FLAGS_TRUNCATED) ==
-   CQ_ENET_RQ_DESC_FLAGS_TRUNCATED;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_eop(uint16_t ciflags)
-{
-   return (ciflags & CQ_ENET_RQ_DESC_FLAGS_EOP)
-   == CQ_ENET_RQ_DESC_FLAGS_EOP;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_csum_not_calc(struct cq_enet_rq_desc *cqrd)
-{
-   return (le16_to_cpu(cqrd->q_number_rss_type_flags) &
-   CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC) ==
-   CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_ipv4_csum_ok(struct cq_enet_rq_desc *cqrd)
-{
-   return (cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK) ==
-   CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_tcp_udp_csum_ok(struct cq_enet_rq_desc *cqrd)
-{
-   return (cqrd->flags & CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK) ==
-   CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK;
-}
-
-static inline uint8_t
-enic_cq_rx_desc_rss_type(struct cq_enet_rq_desc *cqrd)
-{
-   return (uint8_t)((le16_to_cpu(cqrd->q_number_rss_type_flags) >>
-   CQ_DESC_Q_NUM_BITS) & CQ_ENET_RQ_DESC_RSS_TYPE_MASK);
-}
-
-static inline uint32_t
-enic_cq_rx_desc_rss_hash(struct cq_enet_rq_desc *cqrd)
-{
-   return le32_to_cpu(cqrd->rss_hash);
-}
-
-static inline uint16_t
-enic_cq_rx_desc_vlan(struct cq_enet_rq_desc *cqrd)
-{
-   return le16_to_cpu(cqrd->vlan);
-}
-
-static inline uint16_t
-enic_cq_rx_desc_n_bytes(struct cq_desc *cqd)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   return le16_to_cpu(cqrd->bytes_written_flags) &
-   CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
-}
-
-
-static inline uint8_t
-enic_cq_rx_check_err(struct cq_desc *cqd)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   uint16_t bwflags;
-
-   bwflags = enic_cq_rx_desc_bwflags(cqrd);
-   if (unlikely(enic_cq_rx_desc_packet_error(bwflags)))
-   return 1;
-   return 0;
-}
-
-/* Lookup table to translate RX CQ flags to mbuf flags. */
-static inline uint32_t
-enic_cq_rx_flags_to_pkt_type(struct cq_desc *cqd, uint8_t tnl)
-{
-   struct cq_enet_rq_desc *cqrd = (struct cq_enet_rq_desc *)cqd;
-   uint8_t cqrd_flags = cqrd->flags;
-   /*
-* Odd-numbered entries are for tunnel packets. All packet type info
-* applies to the inner packet, and there is no info on the outer
-* packet. The outer flags in these entries exist only to avoid
-* changing enic_cq_rx_to_pkt_flags(). They are cleared from mbuf
-* afterwards.
-*
-* Also, as there is no tunnel type info (VXLAN, NVGRE, or GENEVE), set
-* RTE_PTYPE_TUNNEL_GRENAT..
-*/
-   static const uint32_t cq_type_table[128] __rte_cache_aligned = {
-   [0x00] = RTE_PTYPE_UNKNOWN,
-   [0x01] = RTE_PTYPE_UNKNOWN |
-RTE_PTYPE_TUNNEL_GRENAT |
-RTE_PTYPE_INNER_L2_ETHER,
-   [0x20] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG,
-   [0x21] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG |
-RTE_PTYPE_TUNNEL_GRENAT |
-RTE_PTYPE_INNER_L2_ETHER |
-RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
-RTE_PTYPE_INNER_L4_NONFRAG,
-   [0x22] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
-   [0x23] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTY

[dpdk-dev] [PATCH 2/2] net/enic: add AVX2 based vectorized Rx handler

2018-09-27 Thread John Daley
From: Hyong Youb Kim 

Add the vectorized version of the no-scatter Rx handler. It aims to
process 8 descriptors per loop using AVX2 SIMD instructions. This
handler is in its own file enic_rxtx_vec_avx2.c, and makefile and
meson.build are modified to compile it when the compiler supports
AVX2. Under ideal conditions, the vectorized handler reduces
cycles/packet by more than 30%, when compared against the no-scatter
Rx handler. Most implementation ideas come from i40e's AVX2 based
handler, so credit goes to its authors.

At this point, the new handler is meant for field trials, and is not
selected by default. So add a new devarg enable-avx2-rx to allow the
user to request the use of the new handler. When enable-avx2-rx=1, the
driver will consider using the new handler.

Also update the guide doc and introduce the vectorized handler.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 doc/guides/nics/enic.rst  |  32 ++
 drivers/net/enic/Makefile |   7 +
 drivers/net/enic/enic.h   |   3 +
 drivers/net/enic/enic_ethdev.c|  27 +-
 drivers/net/enic/enic_main.c  |  34 +-
 drivers/net/enic/enic_rxtx_vec_avx2.c | 832 ++
 drivers/net/enic/meson.build  |   5 +
 7 files changed, 931 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/enic/enic_rxtx_vec_avx2.c

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 86941fdb2..b31f4eef9 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -351,6 +351,38 @@ suitable for others. Such applications may change the mode 
by setting
   applications such as OVS-DPDK performance benchmarks that utilize
   only the default VLAN and want to see only untagged packets.
 
+
+Vectorized Rx Handler
+-
+
+ENIC PMD includes a version of the receive handler that is vectorized using
+AVX2 SIMD instructions. It is meant for bulk, throughput oriented workloads
+where reducing cycles/packet in PMD is a priority. In order to use the
+vectorized handler, take the following steps.
+
+- Use a recent version of gcc, icc, or clang and build 64-bit DPDK. If
+  the compiler is known to support AVX2, DPDK build system
+  automatically compiles the vectorized handler. Otherwise, the
+  handler is not available.
+
+- Set ``devargs`` parameter ``enable-avx2-rx=1`` to explicitly request that
+  PMD consider the vectorized handler when selecting the receive handler.
+
+  As the current implementation is intended for field trials, by default, the
+  vectorized handler is not considerd (``enable-avx2-rx=0``).
+
+- Run on a UCS M4 or later server with CPUs that support AVX2.
+
+PMD selects the vectorized handler when the handler is compiled into
+the driver, the user requests its use via ``enable-avx2-rx=1``, CPU
+supports AVX2, and scatter Rx is not used. To verify that the
+vectorized handler is selected, enable debug logging
+(``--log-level=pmd,debug``) and check the following message.
+
+.. code-block:: console
+
+enic_use_vector_rx_handler use the non-scatter avx2 Rx handler
+
 .. _enic_limitations:
 
 Limitations
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 7c6c29cc0..3ec6f9159 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -39,4 +39,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_intr.c
 SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_rq.c
 SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += base/vnic_rss.c
 
+ifeq ($(findstring 
RTE_MACHINE_CPUFLAG_AVX2,$(CFLAGS)),RTE_MACHINE_CPUFLAG_AVX2)
+# The current implementation assumes 64-bit pointers
+ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
+   SRCS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic_rxtx_vec_avx2.c
+endif
+endif
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 775cd5d55..ff35f4396 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -106,6 +106,7 @@ struct enic {
struct vnic_dev_bar bar0;
struct vnic_dev *vdev;
 
+   uint64_t mbuf_initializer;
unsigned int port_id;
bool overlay_offload;
struct rte_eth_dev *rte_dev;
@@ -128,6 +129,7 @@ struct enic {
u8 filter_actions; /* HW supported actions */
bool vxlan;
bool disable_overlay; /* devargs disable_overlay=1 */
+   bool enable_avx2_rx;  /* devargs enable-avx2-rx=1 */
bool nic_cfg_chk; /* NIC_CFG_CHK available */
bool udp_rss_weak;/* Bodega style UDP RSS */
uint8_t ig_vlan_rewrite_mode; /* devargs ig-vlan-rewrite */
@@ -329,6 +331,7 @@ uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
uint16_t nb_pkts);
 int enic_set_mtu(struct enic *enic, uint16_t new_mtu);
 int enic_link_update(struct enic *enic);
+bool enic_use_vector_rx_handler(struct enic *enic);
 void enic_fdir_info(struct enic *enic);
 void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info *stats);

[dpdk-dev] [PATCH 3/3] doc: update enic guide for flow API counter action

2018-09-27 Thread John Daley
Add counter action support

Signed-off-by: John Daley 
---
 doc/guides/nics/enic.rst | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 438a83d5f..86941fdb2 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -260,6 +260,12 @@ Generic Flow API is supported. The baseline support is:
   - Selectors: 'is', 'spec' and 'mask'. 'last' is not supported
   - In total, up to 64 bytes of mask is allowed across all headers
 
+- **1400 and later series VICS with advanced filters enabled**
+
+  All the above plus:
+
+  - Action: count
+
 More features may be added in future firmware and new versions of the VIC.
 Please refer to the release notes.
 
-- 
2.16.2



[dpdk-dev] [PATCH 2/3] net/enic: support for flow counter action

2018-09-27 Thread John Daley
Support counter action for 1400 series adapters.

The adapter API for allocating and freeing counters is independent of
the adapter match/action API. If the filter action is requested, a
counter is first allocated and then assigned to the filter, and when
the filter is deleted, the counter must also be deleted.

Counters are DMAd to pre-allocated consistent memory periodically,
controlled by the define VNIC_FLOW_COUNTER_UPDATE_MSECS. The default is
100 milliseconds.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/base/vnic_dev.c|  93 +++
 drivers/net/enic/base/vnic_dev.h|   8 ++
 drivers/net/enic/base/vnic_devcmd.h |  57 +++-
 drivers/net/enic/enic.h |   3 +
 drivers/net/enic/enic_flow.c| 178 
 drivers/net/enic/enic_main.c|  11 ++-
 drivers/net/enic/enic_res.c |   6 +-
 7 files changed, 331 insertions(+), 25 deletions(-)

diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index 16e8814a6..04285b68b 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -57,6 +57,8 @@ struct vnic_dev {
void (*free_consistent)(void *priv,
size_t size, void *vaddr,
dma_addr_t dma_handle);
+   struct vnic_counter_counts *flow_counters;
+   dma_addr_t flow_counters_pa;
 };
 
 #define VNIC_MAX_RES_HDR_SIZE \
@@ -64,6 +66,8 @@ struct vnic_dev {
sizeof(struct vnic_resource) * RES_TYPE_MAX)
 #define VNIC_RES_STRIDE128
 
+#define VNIC_MAX_FLOW_COUNTERS 2048
+
 void *vnic_dev_priv(struct vnic_dev *vdev)
 {
return vdev->priv;
@@ -611,6 +615,23 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct 
vnic_stats **stats)
return vnic_dev_cmd(vdev, CMD_STATS_DUMP, &a0, &a1, wait);
 }
 
+/*
+ * Configure counter DMA
+ */
+int vnic_dev_counter_dma_cfg(struct vnic_dev *vdev, u32 period, u32 
counter_idx)
+{
+   u64 args[3];
+   int wait = 1000;
+
+   if (!vdev->flow_counters || (counter_idx >= VNIC_MAX_FLOW_COUNTERS))
+   return -ENOMEM;
+
+   args[0] = counter_idx + 1;
+   args[1] = vdev->flow_counters_pa;
+   args[2] = period;
+   return vnic_dev_cmd_args(vdev, CMD_COUNTER_DMA_CONFIG, args, 3, wait);
+}
+
 int vnic_dev_close(struct vnic_dev *vdev)
 {
u64 a0 = 0, a1 = 0;
@@ -939,6 +960,23 @@ int vnic_dev_alloc_stats_mem(struct vnic_dev *vdev)
return vdev->stats == NULL ? -ENOMEM : 0;
 }
 
+/*
+ * Initialize for up to VNIC_MAX_FLOW_COUNTERS
+ */
+int vnic_dev_alloc_counter_mem(struct vnic_dev *vdev)
+{
+   char name[NAME_MAX];
+   static u32 instance;
+
+   snprintf((char *)name, sizeof(name), "vnic_flow_ctrs-%u", instance++);
+   vdev->flow_counters = vdev->alloc_consistent(vdev->priv,
+sizeof(struct vnic_counter_counts)
+* VNIC_MAX_FLOW_COUNTERS,
+&vdev->flow_counters_pa,
+(u8 *)name);
+   return vdev->flow_counters == NULL ? -ENOMEM : 0;
+}
+
 void vnic_dev_unregister(struct vnic_dev *vdev)
 {
if (vdev) {
@@ -951,6 +989,15 @@ void vnic_dev_unregister(struct vnic_dev *vdev)
vdev->free_consistent(vdev->priv,
sizeof(struct vnic_stats),
vdev->stats, vdev->stats_pa);
+   if (vdev->flow_counters) {
+   /* turn off counter DMAs before freeing memory */
+   vnic_dev_counter_dma_cfg(vdev, 0, 0);
+
+   vdev->free_consistent(vdev->priv,
+   sizeof(struct vnic_counter_counts)
+   * VNIC_MAX_FLOW_COUNTERS,
+   vdev->flow_counters, vdev->flow_counters_pa);
+   }
if (vdev->fw_info)
vdev->free_consistent(vdev->priv,
sizeof(struct vnic_devcmd_fw_info),
@@ -1094,3 +1141,49 @@ int vnic_dev_capable_vxlan(struct vnic_dev *vdev)
(a1 & (FEATURE_VXLAN_IPV6 | FEATURE_VXLAN_MULTI_WQ)) ==
(FEATURE_VXLAN_IPV6 | FEATURE_VXLAN_MULTI_WQ);
 }
+
+bool vnic_dev_counter_alloc(struct vnic_dev *vdev, uint32_t *idx)
+{
+   u64 a0 = 0;
+   u64 a1 = 0;
+   int wait = 1000;
+
+   if (vnic_dev_cmd(vdev, CMD_COUNTER_ALLOC, &a0, &a1, wait))
+   return false;
+   *idx = (uint32_t)a0;
+   return true;
+}
+
+bool vnic_dev_counter_free(struct vnic_dev *vdev, uint32_t idx)
+{
+   u64 a0 = idx;
+   u64 a1 = 0;
+   int wait = 1000;
+
+   return vnic_dev_cmd(vdev, CMD_COUNTER_FREE, &a0, &a1,
+   wait) == 0;
+}
+
+bool 

[dpdk-dev] [PATCH 1/3] net/enic: fix flow API memory leak

2018-09-27 Thread John Daley
rte_flow structures were not being freed when destroyed or flushed.

Fixes: 6ced137607d0 ("net/enic: flow API for NICs with advanced filters 
enabled")
Cc: sta...@dpdk.org

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_flow.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
index 0cf04aefd..9b612f1d5 100644
--- a/drivers/net/enic/enic_flow.c
+++ b/drivers/net/enic/enic_flow.c
@@ -1532,6 +1532,7 @@ enic_flow_destroy(struct rte_eth_dev *dev, struct 
rte_flow *flow,
enic_flow_del_filter(enic, flow->enic_filter_id, error);
LIST_REMOVE(flow, next);
rte_spinlock_unlock(&enic->flows_lock);
+   rte_free(flow);
return 0;
 }
 
@@ -1555,6 +1556,7 @@ enic_flow_flush(struct rte_eth_dev *dev, struct 
rte_flow_error *error)
flow = LIST_FIRST(&enic->flows);
enic_flow_del_filter(enic, flow->enic_filter_id, error);
LIST_REMOVE(flow, next);
+   rte_free(flow);
}
rte_spinlock_unlock(&enic->flows_lock);
return 0;
-- 
2.16.2



[dpdk-dev] [PATCH] app/testpmd: check Rx VLAN offload flag to print VLAN TCI

2018-09-25 Thread John Daley
From: Hyong Youb Kim 

Since the following commit, PKT_RX_VLAN indicates the presence of
mbuf's vlan_tci, not PKT_RX_VLAN_STRIPPED.

commit 380a7aab1ae2 ("mbuf: rename deprecated VLAN flags")
Cc: olivier.m...@6wind.com

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 app/test-pmd/rxonly.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
index a93d80612..e8d226624 100644
--- a/app/test-pmd/rxonly.c
+++ b/app/test-pmd/rxonly.c
@@ -130,7 +130,7 @@ pkt_burst_receive(struct fwd_stream *fs)
}
if (ol_flags & PKT_RX_TIMESTAMP)
printf(" - timestamp %"PRIu64" ", mb->timestamp);
-   if (ol_flags & PKT_RX_VLAN_STRIPPED)
+   if (ol_flags & PKT_RX_VLAN)
printf(" - VLAN tci=0x%x", mb->vlan_tci);
if (ol_flags & PKT_RX_QINQ_STRIPPED)
printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x",
-- 
2.16.2



[dpdk-dev] [PATCH 6/6] net/enic: explicitly disable overlay offload

2018-09-25 Thread John Daley
From: Hyong Youb Kim 

Reopening vNIC does not automatically disable overlay offload. If it
is previously enabled, it remains enabled even when the user restarts
DPDK and requests overlay offload to be disabled via devarg
disable-overlay=1. So explicitly disable overlay offload when
requested.

Fixes: 93fb21fdbe23 ("net/enic: enable overlay offload for VXLAN and GENEVE")
Cc: sta...@dpdk.org

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_main.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 03c5ef741..af29f9d90 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1652,6 +1652,19 @@ static int enic_dev_init(struct enic *enic)
vnic_dev_notify_set(enic->vdev, -1); /* No Intr for notify */
 
enic->overlay_offload = false;
+   if (enic->disable_overlay && enic->vxlan) {
+   /*
+* Explicitly disable overlay offload as the setting is
+* sticky, and resetting vNIC does not disable it.
+*/
+   if (vnic_dev_overlay_offload_ctrl(enic->vdev,
+ OVERLAY_FEATURE_VXLAN,
+ OVERLAY_OFFLOAD_DISABLE)) {
+   dev_err(enic, "failed to disable overlay offload\n");
+   } else {
+   dev_info(enic, "Overlay offload is disabled\n");
+   }
+   }
if (!enic->disable_overlay && enic->vxlan &&
/* 'VXLAN feature' enables VXLAN, NVGRE, and GENEVE. */
vnic_dev_overlay_offload_ctrl(enic->vdev,
-- 
2.16.2



[dpdk-dev] [PATCH 5/6] net/enic: add VLAN and csum offloads to simple Tx handler

2018-09-25 Thread John Daley
From: Hyong Youb Kim 

Currently the simple Tx handler supports no offloads, which makes it
usable only for a small number of benchmarks. Add vlan and checksum
offloads to the handler, as cycles/packet increases only by about 3
cycles, and applications commonly use those offloads.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_main.c | 14 +++---
 drivers/net/enic/enic_rxtx.c | 21 +
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index fd940c583..03c5ef741 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -534,6 +534,7 @@ int enic_enable(struct enic *enic)
unsigned int index;
int err;
struct rte_eth_dev *eth_dev = enic->rte_dev;
+   uint64_t simple_tx_offloads;
 
eth_dev->data->dev_link.link_speed = vnic_dev_port_speed(enic->vdev);
eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
@@ -572,10 +573,17 @@ int enic_enable(struct enic *enic)
}
 
/*
-* Use the simple TX handler if possible. All offloads must be
-* disabled.
+* Use the simple TX handler if possible. Only checksum offloads
+* and vlan insertion are supported.
 */
-   if (eth_dev->data->dev_conf.txmode.offloads == 0) {
+   simple_tx_offloads = enic->tx_offload_capa &
+   (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+DEV_TX_OFFLOAD_VLAN_INSERT |
+DEV_TX_OFFLOAD_IPV4_CKSUM |
+DEV_TX_OFFLOAD_UDP_CKSUM |
+DEV_TX_OFFLOAD_TCP_CKSUM);
+   if ((eth_dev->data->dev_conf.txmode.offloads &
+~simple_tx_offloads) == 0) {
PMD_INIT_LOG(DEBUG, " use the simple tx handler");
eth_dev->tx_pkt_burst = &enic_simple_xmit_pkts;
for (index = 0; index < enic->wq_count; index++)
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 8d57c418f..276a2e559 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -842,12 +842,33 @@ static void enqueue_simple_pkts(struct rte_mbuf **pkts,
struct enic *enic)
 {
struct rte_mbuf *p;
+   uint16_t mss;
 
while (n) {
n--;
p = *pkts++;
desc->address = p->buf_iova + p->data_off;
desc->length = p->pkt_len;
+   /* VLAN insert */
+   desc->vlan_tag = p->vlan_tci;
+   desc->header_length_flags &=
+   ((1 << WQ_ENET_FLAGS_EOP_SHIFT) |
+(1 << WQ_ENET_FLAGS_CQ_ENTRY_SHIFT));
+   if (p->ol_flags & PKT_TX_VLAN) {
+   desc->header_length_flags |=
+   1 << WQ_ENET_FLAGS_VLAN_TAG_INSERT_SHIFT;
+   }
+   /*
+* Checksum offload. We use WQ_ENET_OFFLOAD_MODE_CSUM, which
+* is 0, so no need to set offload_mode.
+*/
+   mss = 0;
+   if (p->ol_flags & PKT_TX_IP_CKSUM)
+   mss |= ENIC_CALC_IP_CKSUM << WQ_ENET_MSS_SHIFT;
+   if (p->ol_flags & PKT_TX_L4_MASK)
+   mss |= ENIC_CALC_TCP_UDP_CKSUM << WQ_ENET_MSS_SHIFT;
+   desc->mss_loopback = mss;
+
/*
 * The app should not send oversized
 * packets. tx_pkt_prepare includes a check as
-- 
2.16.2



[dpdk-dev] [PATCH 4/6] net/enic: do not use deprecated Tx VLAN packet flag

2018-09-25 Thread John Daley
From: Hyong Youb Kim 

Replace PKT_TX_VLAN_PKT (deprecated) with PKT_TX_VLAN.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_res.c  | 2 +-
 drivers/net/enic/enic_rxtx.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index abe004b24..84486cace 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -200,7 +200,7 @@ int enic_get_vnic_config(struct enic *enic)
DEV_RX_OFFLOAD_UDP_CKSUM |
DEV_RX_OFFLOAD_TCP_CKSUM;
enic->tx_offload_mask =
-   PKT_TX_VLAN_PKT |
+   PKT_TX_VLAN |
PKT_TX_IP_CKSUM |
PKT_TX_L4_MASK |
PKT_TX_TCP_SEG;
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 0eb113d75..8d57c418f 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -709,7 +709,7 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
wq_desc_avail = vnic_wq_desc_avail(wq);
head_idx = wq->head_idx;
desc_count = wq->ring.desc_count;
-   ol_flags_mask = PKT_TX_VLAN_PKT | PKT_TX_IP_CKSUM | PKT_TX_L4_MASK;
+   ol_flags_mask = PKT_TX_VLAN | PKT_TX_IP_CKSUM | PKT_TX_L4_MASK;
tx_oversized = &enic->soft_stats.tx_oversized;
 
nb_pkts = RTE_MIN(nb_pkts, ENIC_TX_XMIT_MAX);
@@ -737,7 +737,7 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
mss = 0;
vlan_id = tx_pkt->vlan_tci;
-   vlan_tag_insert = !!(ol_flags & PKT_TX_VLAN_PKT);
+   vlan_tag_insert = !!(ol_flags & PKT_TX_VLAN);
bus_addr = (dma_addr_t)
   (tx_pkt->buf_iova + tx_pkt->data_off);
 
-- 
2.16.2



[dpdk-dev] [PATCH 3/6] net/enic: set Rx VLAN offload flag for non-stripped packets

2018-09-25 Thread John Daley
From: Hyong Youb Kim 

The NIC indicates VLAN TCI to the driver even when VLAN stripping is
disabled. The driver sets mbuf's vlan_tci but not PKT_RX_VLAN. Set
PKT_RX_VLAN to indicate that vlan_tci is valid.

Fixes: c6f455507411 ("net/enic: add ethernet VLAN packet type")
Cc: sta...@dpdk.org

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_rxtx.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 7129e1217..0eb113d75 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -233,10 +233,12 @@ enic_cq_rx_to_pkt_flags(struct cq_desc *cqd, struct 
rte_mbuf *mbuf)
pkt_flags |= PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED;
mbuf->packet_type |= RTE_PTYPE_L2_ETHER;
} else {
-   if (vlan_tci != 0)
+   if (vlan_tci != 0) {
+   pkt_flags |= PKT_RX_VLAN;
mbuf->packet_type |= RTE_PTYPE_L2_ETHER_VLAN;
-   else
+   } else {
mbuf->packet_type |= RTE_PTYPE_L2_ETHER;
+   }
}
mbuf->vlan_tci = vlan_tci;
 
-- 
2.16.2



[dpdk-dev] [PATCH 1/6] net/enic: do not use non-standard integer types

2018-09-25 Thread John Daley
From: Hyong Youb Kim 

Bugzilla ID: 39
Fixes: 9913fbb91df0 ("enic/base: common code")
Fixes: 322b355f2183 ("net/enic/base: bring NIC interface functions up to date")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/base/vnic_devcmd.h | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/enic/base/vnic_devcmd.h 
b/drivers/net/enic/base/vnic_devcmd.h
index a22d8a76c..fffe307e0 100644
--- a/drivers/net/enic/base/vnic_devcmd.h
+++ b/drivers/net/enic/base/vnic_devcmd.h
@@ -875,7 +875,7 @@ struct filter_action_v2 {
u32 rq_idx;
u32 flags; /* use FILTER_ACTION_XXX_FLAG defines */
u16 filter_id;
-   u_int8_t reserved[32]; /* for future expansion */
+   uint8_t reserved[32]; /* for future expansion */
 } __attribute__((packed));
 
 /* Specifies the filter type. */
@@ -941,9 +941,9 @@ enum {
 };
 
 struct filter_tlv {
-   u_int32_t type;
-   u_int32_t length;
-   u_int32_t val[0];
+   uint32_t type;
+   uint32_t length;
+   uint32_t val[0];
 };
 
 /* Data for CMD_ADD_FILTER is 2 TLV and filter + action structs */
@@ -957,10 +957,10 @@ struct filter_tlv {
  * drivers should use this instead of "sizeof (struct filter_v2)" when
  * computing length for TLV.
  */
-static inline u_int32_t
+static inline uint32_t
 vnic_filter_size(struct filter_v2 *fp)
 {
-   u_int32_t size;
+   uint32_t size;
 
switch (fp->type) {
case FILTER_USNIC_ID:
@@ -999,10 +999,10 @@ enum {
  * drivers should use this instead of "sizeof (struct filter_action_v2)"
  * when computing length for TLV.
  */
-static inline u_int32_t
+static inline uint32_t
 vnic_action_size(struct filter_action_v2 *fap)
 {
-   u_int32_t size;
+   uint32_t size;
 
switch (fap->type) {
case FILTER_ACTION_RQ_STEERING:
-- 
2.16.2



[dpdk-dev] [PATCH 2/6] net/enic: enable IOVA mode

2018-09-25 Thread John Daley
From: Hyong Youb Kim 

Cisco VIC models support RTE_IOVA_VA, so enable it. This change allows
the driver to work properly when --no-huge is used, in combination
with vfio and iommu.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_ethdev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index b3d57771f..65333c47a 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -1044,7 +1044,8 @@ static int eth_enic_pci_remove(struct rte_pci_device 
*pci_dev)
 
 static struct rte_pci_driver rte_enic_pmd = {
.id_table = pci_id_enic_map,
-   .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+   .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
+RTE_PCI_DRV_IOVA_AS_VA,
.probe = eth_enic_pci_probe,
.remove = eth_enic_pci_remove,
 };
-- 
2.16.2



[dpdk-dev] [PATCH v2] net/enic: reset the vxlan port during vNIC initialization

2018-07-31 Thread John Daley
From: Hyong Youb Kim 

The NIC persists the vxlan port number across vNIC init/de-init
(e.g. restart testpmd). So, explicitly reset the setting to the
default value (4789) as part of the initialization.

Fixes: 8a4efd17410c ("net/enic: add handlers to add/delete vxlan port number")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---

v2: fix signoff

 drivers/net/enic/enic_main.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index f04dc0878..03bde76b2 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1664,6 +1664,16 @@ static int enic_dev_init(struct enic *enic)
enic->overlay_offload = true;
enic->vxlan_port = ENIC_DEFAULT_VXLAN_PORT;
dev_info(enic, "Overlay offload is enabled\n");
+   /*
+* Reset the vxlan port to the default, as the NIC firmware
+* does not reset it automatically and keeps the old setting.
+*/
+   if (vnic_dev_overlay_offload_cfg(enic->vdev,
+OVERLAY_CFG_VXLAN_PORT_UPDATE,
+ENIC_DEFAULT_VXLAN_PORT)) {
+   dev_err(enic, "failed to update vxlan port\n");
+   return -EINVAL;
+   }
}
 
return 0;
-- 
2.16.2



[dpdk-dev] [PATCH] net/enic: reset the vxlan port during vNIC initialization

2018-07-31 Thread John Daley
From: Hyong Youb Kim 

The NIC persists the vxlan port number across vNIC init/de-init
(e.g. restart testpmd). So, explicitly reset the setting to the
default value (4789) as part of the initialization.

Fixes: 8a4efd17410c ("net/enic: add handlers to add/delete vxlan port number")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley johnd...@cisco.com>
---
 drivers/net/enic/enic_main.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index f04dc0878..03bde76b2 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1664,6 +1664,16 @@ static int enic_dev_init(struct enic *enic)
enic->overlay_offload = true;
enic->vxlan_port = ENIC_DEFAULT_VXLAN_PORT;
dev_info(enic, "Overlay offload is enabled\n");
+   /*
+* Reset the vxlan port to the default, as the NIC firmware
+* does not reset it automatically and keeps the old setting.
+*/
+   if (vnic_dev_overlay_offload_cfg(enic->vdev,
+OVERLAY_CFG_VXLAN_PORT_UPDATE,
+ENIC_DEFAULT_VXLAN_PORT)) {
+   dev_err(enic, "failed to update vxlan port\n");
+   return -EINVAL;
+   }
}
 
return 0;
-- 
2.16.2



[dpdk-dev] [PATCH] net/enic: revert support for mbuf fast free offload

2018-07-25 Thread John Daley
From: Hyong Youb Kim 

This reverts the patch that enabled mbuf fast free.

There are two main reasons.

First, enic_fast_free_wq_bufs is broken. When
DEV_TX_OFFLOAD_MBUF_FAST_FREE is enabled, the driver calls this
function to free transmitted mbufs. This function currently does not
reset next and nb_segs. This is simply wrong as the fast-free flag
does not imply anything about next and nb_segs.

We could fix enic_fast_free_wq_bufs by making it to call
rte_pktmbuf_prefree_seg to reset the required fields. But, it negates
most of cycle saving.

Second, there are customer applications that blindly enable all Tx
offloads supported by the device. Some of these applications do not
satisfy the requirements of mbuf fast free (i.e. a single pool per
queue and refcnt = 1), and end up crashing or behaving badly.

Fixes: bcaa54c1a148 ("net/enic: support mbuf fast free offload")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 doc/guides/nics/features/enic.ini  |  1 -
 doc/guides/rel_notes/release_18_08.rst |  3 +--
 drivers/net/enic/enic_main.c   |  7 +++
 drivers/net/enic/enic_res.c|  2 +-
 drivers/net/enic/enic_rxtx.c   | 30 +-
 5 files changed, 6 insertions(+), 37 deletions(-)

diff --git a/doc/guides/nics/features/enic.ini 
b/doc/guides/nics/features/enic.ini
index d2b866b66..8a4bad29f 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -6,7 +6,6 @@
 [Features]
 Link status  = Y
 Link status event= Y
-Fast mbuf free   = Y
 Rx interrupt = Y
 Queue start/stop = Y
 MTU update   = Y
diff --git a/doc/guides/rel_notes/release_18_08.rst 
b/doc/guides/rel_notes/release_18_08.rst
index df0ad61f7..b882f2615 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -70,8 +70,7 @@ New Features
 
 * **Updated the enic driver.**
 
-  * Add support for mbuf fast free offload.
-  * Add low cycle count Tx handler for no-offload Tx (except mbuf fast free).
+  * Add low cycle count Tx handler for no-offload Tx.
   * Add low cycle count Rx handler for non-scattered Rx.
   * Minor performance improvements to scattered Rx handler.
   * Add handlers to add/delete VxLAN port number.
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index f04dc0878..d9ce602ba 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -572,11 +572,10 @@ int enic_enable(struct enic *enic)
}
 
/*
-* Use the simple TX handler if possible. All offloads must be disabled
-* except mbuf fast free.
+* Use the simple TX handler if possible. All offloads must be
+* disabled.
 */
-   if ((eth_dev->data->dev_conf.txmode.offloads &
-~DEV_TX_OFFLOAD_MBUF_FAST_FREE) == 0) {
+   if (eth_dev->data->dev_conf.txmode.offloads == 0) {
PMD_INIT_LOG(DEBUG, " use the simple tx handler");
eth_dev->tx_pkt_burst = &enic_simple_xmit_pkts;
for (index = 0; index < enic->wq_count; index++)
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 11d66a626..8d493ffed 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -183,7 +183,7 @@ int enic_get_vnic_config(struct enic *enic)
 * Default hardware capabilities. enic_dev_init() may add additional
 * flags if it enables overlay offloads.
 */
-   enic->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+   enic->tx_queue_offload_capa = 0;
enic->tx_offload_capa =
enic->tx_queue_offload_capa |
DEV_TX_OFFLOAD_MULTI_SEGS |
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 7ae03f31b..7129e1217 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -588,31 +588,6 @@ enic_noscatter_recv_pkts(void *rx_queue, struct rte_mbuf 
**rx_pkts,
return rx - rx_pkts;
 }
 
-static void enic_fast_free_wq_bufs(struct vnic_wq *wq, u16 completed_index)
-{
-   unsigned int desc_count, n, nb_to_free, tail_idx;
-   struct rte_mempool *pool;
-   struct rte_mbuf **m;
-
-   desc_count = wq->ring.desc_count;
-   nb_to_free = enic_ring_sub(desc_count, wq->tail_idx, completed_index)
-  + 1;
-   tail_idx = wq->tail_idx;
-   wq->tail_idx += nb_to_free;
-   wq->ring.desc_avail += nb_to_free;
-   if (wq->tail_idx >= desc_count)
-   wq->tail_idx -= desc_count;
-   /* First, free at most until the end of ring */
-   m = &wq->bufs[tail_idx];
-   pool = (*m)->pool;
-   n = RTE_MIN(nb_to_free, desc_count - tail_idx);
-   rte_mempool_put_bulk(pool, (void **)m, n);
-   n = nb_to_free - n;
-   /* Then wrap and free the rest */
-   if (unlikely

Re: [dpdk-dev] [PATCH v2 00/15] enic PMD fixes and performance improvements

2018-07-25 Thread John Daley (johndale)
Hi Kevin,
Inline.
-john

> -Original Message-
> From: Kevin Traynor 
> Sent: Wednesday, July 25, 2018 11:37 AM
> To: John Daley (johndale) ; ferruh.yi...@intel.com
> Cc: dev@dpdk.org; sta...@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 00/15] enic PMD fixes and performance
> improvements
> 
> On 06/29/2018 10:29 AM, John Daley wrote:
> > Updated a few commits in the patchset per suggestions by Ferrus Yigit.
> > thanks,
> > John
> >
> > Hyong Youb Kim (12):
> >   net/enic: fix receive packet types
> >   net/enic: update the UDP RSS detection mechanism
> >   net/enic: do not overwrite admin Tx queue limit
> >   net/enic: initialize RQ fetch index before enabling RQ
> >   net/enic: report ring limits and preferred default values
> >   net/enic: add devarg to specify ingress VLAN rewrite mode
> >   net/enic: add handlers to add/delete vxlan port number
> >   net/enic: use mbuf pointer array for inflight Tx packets
> >   net/enic: support mbuf fast free offload
> >   net/enic: reduce Tx completion updates
> >   net/enic: add the simple version of Tx handler
> >   net/enic: check maximum packet size in Tx prepare handler
> >
> > John Daley (3):
> >   net/enic: add simple Rx handler
> >   net/enic: cap Rx packet processing to end of desc ring
> >   doc: update release notes with new enic features
> >
> 
> Hi John, seems like many of these would be candidates for stable branches?

Yes, a few of them. We will backport, test and submit to the stable branches as 
soon as we are done with 18.08 testing.
Thanks,
John

> 
> >  doc/guides/nics/enic.rst   |  15 +-
> >  doc/guides/nics/features/enic.ini  |   1 +
> >  doc/guides/rel_notes/release_18_08.rst |   8 +
> >  drivers/net/enic/base/cq_desc.h|   1 +
> >  drivers/net/enic/base/vnic_dev.c   |  16 ++
> >  drivers/net/enic/base/vnic_dev.h   |   4 +
> >  drivers/net/enic/base/vnic_devcmd.h|  23 ++-
> >  drivers/net/enic/base/vnic_enet.h  |   5 +-
> >  drivers/net/enic/base/vnic_nic.h   |   4 +-
> >  drivers/net/enic/base/vnic_rq.h|   2 +
> >  drivers/net/enic/base/vnic_wq.c|   9 +-
> >  drivers/net/enic/base/vnic_wq.h|  12 +-
> >  drivers/net/enic/enic.h|  12 ++
> >  drivers/net/enic/enic_compat.h |   5 +
> >  drivers/net/enic/enic_ethdev.c | 168 +++--
> >  drivers/net/enic/enic_main.c   | 125 ++---
> >  drivers/net/enic/enic_res.c|  13 +-
> >  drivers/net/enic/enic_res.h|  16 ++
> >  drivers/net/enic/enic_rxtx.c   | 333 
> > +---
> -
> >  19 files changed, 668 insertions(+), 104 deletions(-)
> >



[dpdk-dev] [PATCH] doc: update the enic guide and features

2018-07-17 Thread John Daley
From: Hyong Youb Kim 

Make a few updates in preparation for 18.08.
- Use SPDX
- Add 1400 series VIC adapters to supported models
- Describe the VXLAN port number
- Expand the description for ig-vlan-rewrite
- Add inner RSS and checksum to the features

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 doc/guides/nics/enic.rst  | 76 +++
 doc/guides/nics/features/enic.ini |  3 ++
 2 files changed, 48 insertions(+), 31 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 7764c8648..438a83d5f 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -1,32 +1,7 @@
-..  BSD LICENSE
+..  SPDX-License-Identifier: BSD-3-Clause
 Copyright (c) 2017, Cisco Systems, Inc.
 All rights reserved.
 
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in
-the documentation and/or other materials provided with the
-distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
 ENIC Poll Mode Driver
 =
 
@@ -336,6 +311,40 @@ it, set ``devargs`` parameter ``disable-overlay=1``. For 
example::
 
 -w 12:00.0,disable-overlay=1
 
+By default, the NIC uses 4789 as the VXLAN port. The user may change
+it through ``rte_eth_dev_udp_tunnel_port_{add,delete}``. However, as
+the current NIC has a single VXLAN port number, the user cannot
+configure multiple port numbers.
+
+Ingress VLAN Rewrite
+
+
+VIC adapters can tag, untag, or modify the VLAN headers of ingress
+packets. The ingress VLAN rewrite mode controls this behavior. By
+default, it is set to pass-through, where the NIC does not modify the
+VLAN header in any way so that the application can see the original
+header. This mode is sufficient for many applications, but may not be
+suitable for others. Such applications may change the mode by setting
+``devargs`` parameter ``ig-vlan-rewrite`` to one of the following.
+
+- ``pass``: Pass-through mode. The NIC does not modify the VLAN
+  header. This is the default mode.
+
+- ``priority``: Priority-tag default VLAN mode. If the ingress packet
+  is tagged with the default VLAN, the NIC replaces its VLAN header
+  with the priority tag (VLAN ID 0).
+
+- ``trunk``: Default trunk mode. The NIC tags untagged ingress packets
+  with the default VLAN. Tagged ingress packets are not modified. To
+  the application, every packet appears as tagged.
+
+- ``untag``: Untag default VLAN mode. If the ingress packet is tagged
+  with the default VLAN, the NIC removes or untags its VLAN header so
+  that the application sees an untagged packet. As a result, the
+  default VLAN becomes `untagged`. This mode can be useful for
+  applications such as OVS-DPDK performance benchmarks that utilize
+  only the default VLAN and want to see only untagged packets.
+
 .. _enic_limitations:
 
 Limitations
@@ -366,9 +375,9 @@ Another alternative is modify the adapter's ingress VLAN 
rewrite mode so that
 packets with the default VLAN tag are stripped by the adapter and presented to
 DPDK as untagged packets. In this case mbuf->vlan_tci and the PKT_RX_VLAN and
 PKT_RX_VLAN_STRIPPED mbuf flags would not be set. This mode is enabled with the
-``devargs`` parameter ``ig-vlan-rewrite=1``. For example::
+``devargs`` parameter ``ig-vlan-rewrite=untag``. For example::
 
--w 12:00.0,ig-vlan-rewrite=1
+-w 12:00.0,ig-vlan-rewrite=untag
 
 - Limited flow director support on 1200 series and 1300 series Cisco VIC
   adapters with old firmware. Please see :ref:`enic-flow-director`.
@@ -405,10 +414,14 @@ PKT_RX_VLAN_STRIPPED mbuf flags would not be set. This 
mode is enabled with the
 
   - ``rx_good_bytes`` (ibytes) always includes VLAN header (4B) and CRC bytes 
(4B).
 This behavior applies to 1300 and older series VIC adapters.
+1400 series VIC

[dpdk-dev] [PATCH v2] net/enic: pick the right Rx handler after changing MTU

2018-07-17 Thread John Daley
From: Hyong Youb Kim 

enic_set_mtu always reverts to the default Rx handler after changing
MTU. Try to use the simpler, non-scatter handler in this case as well.

Fixes: 35e2cb6a1795 ("net/enic: add simple Rx handler")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
v2: remember to actually assign default handler

 drivers/net/enic/enic_main.c | 25 +
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index c8456c4b7..f04dc0878 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -514,6 +514,21 @@ static void enic_prep_wq_for_simple_tx(struct enic *enic, 
uint16_t queue_idx)
}
 }
 
+static void pick_rx_handler(struct enic *enic)
+{
+   struct rte_eth_dev *eth_dev;
+
+   /* Use the non-scatter, simplified RX handler if possible. */
+   eth_dev = enic->rte_dev;
+   if (enic->rq_count > 0 && enic->rq[0].data_queue_enable == 0) {
+   PMD_INIT_LOG(DEBUG, " use the non-scatter Rx handler");
+   eth_dev->rx_pkt_burst = &enic_noscatter_recv_pkts;
+   } else {
+   PMD_INIT_LOG(DEBUG, " use the normal Rx handler");
+   eth_dev->rx_pkt_burst = &enic_recv_pkts;
+   }
+}
+
 int enic_enable(struct enic *enic)
 {
unsigned int index;
@@ -571,13 +586,7 @@ int enic_enable(struct enic *enic)
eth_dev->tx_pkt_burst = &enic_xmit_pkts;
}
 
-   /* Use the non-scatter, simplified RX handler if possible. */
-   if (enic->rq_count > 0 && enic->rq[0].data_queue_enable == 0) {
-   PMD_INIT_LOG(DEBUG, " use the non-scatter Rx handler");
-   eth_dev->rx_pkt_burst = &enic_noscatter_recv_pkts;
-   } else {
-   PMD_INIT_LOG(DEBUG, " use the normal Rx handler");
-   }
+   pick_rx_handler(enic);
 
for (index = 0; index < enic->wq_count; index++)
enic_start_wq(enic, index);
@@ -1550,7 +1559,7 @@ int enic_set_mtu(struct enic *enic, uint16_t new_mtu)
 
/* put back the real receive function */
rte_mb();
-   eth_dev->rx_pkt_burst = enic_recv_pkts;
+   pick_rx_handler(enic);
rte_mb();
 
/* restart Rx traffic */
-- 
2.16.2



[dpdk-dev] [PATCH] net/enic: pick the right Rx handler after changing MTU

2018-07-13 Thread John Daley
From: Hyong Youb Kim 

enic_set_mtu always reverts to the default Rx handler after changing
MTU. Try to use the simpler, non-scatter handler in this case as well.

Fixes: 1187012c1ede ("net/enic: add simple Rx handler")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_main.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index c8456c4b7..aa3f79df5 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -514,6 +514,20 @@ static void enic_prep_wq_for_simple_tx(struct enic *enic, 
uint16_t queue_idx)
}
 }
 
+static void pick_rx_handler(struct enic *enic)
+{
+   struct rte_eth_dev *eth_dev;
+
+   /* Use the non-scatter, simplified RX handler if possible. */
+   if (enic->rq_count > 0 && enic->rq[0].data_queue_enable == 0) {
+   PMD_INIT_LOG(DEBUG, " use the non-scatter Rx handler");
+   eth_dev = enic->rte_dev;
+   eth_dev->rx_pkt_burst = &enic_noscatter_recv_pkts;
+   } else {
+   PMD_INIT_LOG(DEBUG, " use the normal Rx handler");
+   }
+}
+
 int enic_enable(struct enic *enic)
 {
unsigned int index;
@@ -571,13 +585,7 @@ int enic_enable(struct enic *enic)
eth_dev->tx_pkt_burst = &enic_xmit_pkts;
}
 
-   /* Use the non-scatter, simplified RX handler if possible. */
-   if (enic->rq_count > 0 && enic->rq[0].data_queue_enable == 0) {
-   PMD_INIT_LOG(DEBUG, " use the non-scatter Rx handler");
-   eth_dev->rx_pkt_burst = &enic_noscatter_recv_pkts;
-   } else {
-   PMD_INIT_LOG(DEBUG, " use the normal Rx handler");
-   }
+   pick_rx_handler(enic);
 
for (index = 0; index < enic->wq_count; index++)
enic_start_wq(enic, index);
@@ -1550,7 +1558,7 @@ int enic_set_mtu(struct enic *enic, uint16_t new_mtu)
 
/* put back the real receive function */
rte_mb();
-   eth_dev->rx_pkt_burst = enic_recv_pkts;
+   pick_rx_handler(enic);
rte_mb();
 
/* restart Rx traffic */
-- 
2.16.2



[dpdk-dev] [PATCH v2 15/15] doc: update release notes with new enic features

2018-06-29 Thread John Daley
Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 doc/guides/rel_notes/release_18_08.rst | 8 
 1 file changed, 8 insertions(+)

diff --git a/doc/guides/rel_notes/release_18_08.rst 
b/doc/guides/rel_notes/release_18_08.rst
index bc0124295..903f046c8 100644
--- a/doc/guides/rel_notes/release_18_08.rst
+++ b/doc/guides/rel_notes/release_18_08.rst
@@ -46,6 +46,14 @@ New Features
   Flow API support has been added to CXGBE Poll Mode Driver to offload
   flows to Chelsio T5/T6 NICs.
 
+* **Updated the enic driver.**
+
+  * Add support for mbuf fast free offload.
+  * Add low cycle count Tx handler for no-offload Tx (except mbuf fast free).
+  * Add low cycle count Rx handler for non-scattered Rx.
+  * Minor performance improvements to scattered Rx handler.
+  * Add handlers to add/delete VxLAN port number.
+  * Add devarg to specify ingress VLAN rewrite mode.
 
 API Changes
 ---
-- 
2.16.2



[dpdk-dev] [PATCH v2 13/15] net/enic: add simple Rx handler

2018-06-29 Thread John Daley
Add an optimized Rx handler for non-scattered Rx.

Signed-off-by: Hyong Youb Kim 
Signed-off-by: John Daley 
---
 drivers/net/enic/base/cq_desc.h |   1 +
 drivers/net/enic/base/vnic_rq.h |   2 +
 drivers/net/enic/enic.h |   2 +
 drivers/net/enic/enic_ethdev.c  |   3 +-
 drivers/net/enic/enic_main.c|  36 -
 drivers/net/enic/enic_res.h |   1 +
 drivers/net/enic/enic_rxtx.c| 114 
 7 files changed, 156 insertions(+), 3 deletions(-)

diff --git a/drivers/net/enic/base/cq_desc.h b/drivers/net/enic/base/cq_desc.h
index 7e1380270..ae8847c6d 100644
--- a/drivers/net/enic/base/cq_desc.h
+++ b/drivers/net/enic/base/cq_desc.h
@@ -38,6 +38,7 @@ struct cq_desc {
 #define CQ_DESC_TYPE_MASK((1 << CQ_DESC_TYPE_BITS) - 1)
 #define CQ_DESC_COLOR_MASK   1
 #define CQ_DESC_COLOR_SHIFT  7
+#define CQ_DESC_COLOR_MASK_NOSHIFT 0x80
 #define CQ_DESC_Q_NUM_BITS   10
 #define CQ_DESC_Q_NUM_MASK   ((1 << CQ_DESC_Q_NUM_BITS) - 1)
 #define CQ_DESC_COMP_NDX_BITS12
diff --git a/drivers/net/enic/base/vnic_rq.h b/drivers/net/enic/base/vnic_rq.h
index 9619290de..d8e67f747 100644
--- a/drivers/net/enic/base/vnic_rq.h
+++ b/drivers/net/enic/base/vnic_rq.h
@@ -52,6 +52,8 @@ struct vnic_rq {
struct vnic_dev *vdev;
struct vnic_rq_ctrl __iomem *ctrl;  /* memory-mapped */
struct vnic_dev_ring ring;
+   struct rte_mbuf **free_mbufs;   /* reserve of free mbufs */
+   int num_free_mbufs;
struct rte_mbuf **mbuf_ring;/* array of allocated mbufs */
unsigned int mbuf_next_idx; /* next mb to consume */
void *os_buf_head;
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index a40ea790e..7c27bd513 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -313,6 +313,8 @@ int enic_clsf_init(struct enic *enic);
 void enic_clsf_destroy(struct enic *enic);
 uint16_t enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
+uint16_t enic_noscatter_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts);
 uint16_t enic_dummy_recv_pkts(void *rx_queue,
  struct rte_mbuf **rx_pkts,
  uint16_t nb_pkts);
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 15d93711d..28bd0ff94 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -524,7 +524,8 @@ static const uint32_t 
*enicpmd_dev_supported_ptypes_get(struct rte_eth_dev *dev)
RTE_PTYPE_UNKNOWN
};
 
-   if (dev->rx_pkt_burst == enic_recv_pkts)
+   if (dev->rx_pkt_burst == enic_recv_pkts ||
+   dev->rx_pkt_burst == enic_noscatter_recv_pkts)
return ptypes;
return NULL;
 }
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index e89105d96..c8456c4b7 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -571,6 +571,14 @@ int enic_enable(struct enic *enic)
eth_dev->tx_pkt_burst = &enic_xmit_pkts;
}
 
+   /* Use the non-scatter, simplified RX handler if possible. */
+   if (enic->rq_count > 0 && enic->rq[0].data_queue_enable == 0) {
+   PMD_INIT_LOG(DEBUG, " use the non-scatter Rx handler");
+   eth_dev->rx_pkt_burst = &enic_noscatter_recv_pkts;
+   } else {
+   PMD_INIT_LOG(DEBUG, " use the normal Rx handler");
+   }
+
for (index = 0; index < enic->wq_count; index++)
enic_start_wq(enic, index);
for (index = 0; index < enic->rq_count; index++)
@@ -623,6 +631,19 @@ void enic_free_rq(void *rxq)
enic = vnic_dev_priv(rq_sop->vdev);
rq_data = &enic->rq[rq_sop->data_queue_idx];
 
+   if (rq_sop->free_mbufs) {
+   struct rte_mbuf **mb;
+   int i;
+
+   mb = rq_sop->free_mbufs;
+   for (i = ENIC_RX_BURST_MAX - rq_sop->num_free_mbufs;
+i < ENIC_RX_BURST_MAX; i++)
+   rte_pktmbuf_free(mb[i]);
+   rte_free(rq_sop->free_mbufs);
+   rq_sop->free_mbufs = NULL;
+   rq_sop->num_free_mbufs = 0;
+   }
+
enic_rxmbuf_queue_release(enic, rq_sop);
if (rq_data->in_use)
enic_rxmbuf_queue_release(enic, rq_data);
@@ -786,13 +807,13 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
rq_data->max_mbufs_per_pkt = mbufs_per_pkt;
 
if (mbufs_per_pkt > 1) {
-   min_sop = 64;
+   min_sop = ENIC_RX_BURST_MAX;
max_sop = ((enic->config.rq_desc_count /
(mbufs_per_pkt - 1)) & ENIC_ALIGN_DESCS_MASK);
min_data

[dpdk-dev] [PATCH v2 14/15] net/enic: cap Rx packet processing to end of desc ring

2018-06-29 Thread John Daley
In the default Rx handler stop processing packets at the end of
the completion ring so that wrapping doesn't have to be checked
in the inner while loop.

Also, check the color bit in the completion without using a conditional.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_rxtx.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index e0f93dd5e..7ae03f31b 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -310,7 +310,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
struct vnic_rq *rq;
struct enic *enic = vnic_dev_priv(sop_rq->vdev);
uint16_t cq_idx;
-   uint16_t rq_idx;
+   uint16_t rq_idx, max_rx;
uint16_t rq_num;
struct rte_mbuf *nmb, *rxmb;
uint16_t nb_rx = 0;
@@ -325,19 +325,23 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
cq = &enic->cq[enic_cq_rq(enic, sop_rq->index)];
cq_idx = cq->to_clean;  /* index of cqd, rqd, mbuf_table */
cqd_ptr = (struct cq_desc *)(cq->ring.descs) + cq_idx;
+   color = cq->last_color;
 
data_rq = &enic->rq[sop_rq->data_queue_idx];
 
-   while (nb_rx < nb_pkts) {
+   /* Receive until the end of the ring, at most. */
+   max_rx = RTE_MIN(nb_pkts, cq->ring.desc_count - cq_idx);
+
+   while (max_rx) {
volatile struct rq_enet_desc *rqd_ptr;
struct cq_desc cqd;
uint8_t packet_error;
uint16_t ciflags;
 
+   max_rx--;
+
/* Check for pkts available */
-   color = (cqd_ptr->type_color >> CQ_DESC_COLOR_SHIFT)
-   & CQ_DESC_COLOR_MASK;
-   if (color == cq->last_color)
+   if ((cqd_ptr->type_color & CQ_DESC_COLOR_MASK_NOSHIFT) == color)
break;
 
/* Get the cq descriptor and extract rq info from it */
@@ -361,13 +365,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
/* Get the mbuf to return and replace with one just allocated */
rxmb = rq->mbuf_ring[rq_idx];
rq->mbuf_ring[rq_idx] = nmb;
-
-   /* Increment cqd, rqd, mbuf_table index */
cq_idx++;
-   if (unlikely(cq_idx == cq->ring.desc_count)) {
-   cq_idx = 0;
-   cq->last_color = cq->last_color ? 0 : 1;
-   }
 
/* Prefetch next mbuf & desc while processing current one */
cqd_ptr = (struct cq_desc *)(cq->ring.descs) + cq_idx;
@@ -419,6 +417,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
first_seg->packet_type =
enic_cq_rx_flags_to_pkt_type(&cqd, tnl);
enic_cq_rx_to_pkt_flags(&cqd, first_seg);
+
/* Wipe the outer types set by enic_cq_rx_flags_to_pkt_type() */
if (tnl) {
first_seg->packet_type &= ~(RTE_PTYPE_L3_MASK |
@@ -438,6 +437,10 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
/* store the mbuf address into the next entry of the array */
rx_pkts[nb_rx++] = first_seg;
}
+   if (unlikely(cq_idx == cq->ring.desc_count)) {
+   cq_idx = 0;
+   cq->last_color ^= CQ_DESC_COLOR_MASK_NOSHIFT;
+   }
 
sop_rq->pkt_first_seg = first_seg;
sop_rq->pkt_last_seg = last_seg;
-- 
2.16.2



[dpdk-dev] [PATCH v2 12/15] net/enic: check maximum packet size in Tx prepare handler

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

The default tx handler checks the maximum packet size. Check it in the
prepare handler too. WQ stops working if the app/driver tries to send
oversized packets, so these checks are unavoidable.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_rxtx.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 7dec486fe..04a77fcb4 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -563,6 +563,10 @@ uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
for (i = 0; i != nb_pkts; i++) {
m = tx_pkts[i];
+   if (unlikely(m->pkt_len > ENIC_TX_MAX_PKT_SIZE)) {
+   rte_errno = EINVAL;
+   return i;
+   }
ol_flags = m->ol_flags;
if (ol_flags & wq->tx_offload_notsup_mask) {
rte_errno = ENOTSUP;
-- 
2.16.2



[dpdk-dev] [PATCH v2 11/15] net/enic: add the simple version of Tx handler

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

Add a much-simplified handler that works when all offloads are
disabled, except mbuf fast free. When compared against the default
handler, under ideal conditions, cycles per packet drop by 60+%.
The driver tries to use the simple handler first.

The idea of using specialized/simplified handlers is from the Intel
and Mellanox drivers.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---

v2: removed devarg to disable handler

 drivers/net/enic/enic.h|  2 ++
 drivers/net/enic/enic_compat.h |  5 +++
 drivers/net/enic/enic_ethdev.c |  4 ---
 drivers/net/enic/enic_main.c   | 36 
 drivers/net/enic/enic_rxtx.c   | 77 ++
 5 files changed, 120 insertions(+), 4 deletions(-)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index af790fc2e..a40ea790e 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -318,6 +318,8 @@ uint16_t enic_dummy_recv_pkts(void *rx_queue,
  uint16_t nb_pkts);
 uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+uint16_t enic_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+  uint16_t nb_pkts);
 uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
 int enic_set_mtu(struct enic *enic, uint16_t new_mtu);
diff --git a/drivers/net/enic/enic_compat.h b/drivers/net/enic/enic_compat.h
index c0af1ed29..ceb1b0962 100644
--- a/drivers/net/enic/enic_compat.h
+++ b/drivers/net/enic/enic_compat.h
@@ -56,6 +56,11 @@
 #define dev_debug(x, args...) dev_printk(DEBUG, args)
 
 extern int enicpmd_logtype_flow;
+extern int enicpmd_logtype_init;
+
+#define PMD_INIT_LOG(level, fmt, args...) \
+   rte_log(RTE_LOG_ ## level, enicpmd_logtype_init, \
+   "%s" fmt "\n", __func__, ##args)
 
 #define __le16 u16
 #define __le32 u32
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index ef18f8802..15d93711d 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -24,10 +24,6 @@
 int enicpmd_logtype_init;
 int enicpmd_logtype_flow;
 
-#define PMD_INIT_LOG(level, fmt, args...) \
-   rte_log(RTE_LOG_ ## level, enicpmd_logtype_init, \
-   "%s" fmt "\n", __func__, ##args)
-
 #define ENICPMD_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
 
 /*
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index c03ec247a..e89105d96 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -493,6 +493,27 @@ static void enic_rxq_intr_deinit(struct enic *enic)
}
 }
 
+static void enic_prep_wq_for_simple_tx(struct enic *enic, uint16_t queue_idx)
+{
+   struct wq_enet_desc *desc;
+   struct vnic_wq *wq;
+   unsigned int i;
+
+   /*
+* Fill WQ descriptor fields that never change. Every descriptor is
+* one packet, so set EOP. Also set CQ_ENTRY every ENIC_WQ_CQ_THRESH
+* descriptors (i.e. request one completion update every 32 packets).
+*/
+   wq = &enic->wq[queue_idx];
+   desc = (struct wq_enet_desc *)wq->ring.descs;
+   for (i = 0; i < wq->ring.desc_count; i++, desc++) {
+   desc->header_length_flags = 1 << WQ_ENET_FLAGS_EOP_SHIFT;
+   if (i % ENIC_WQ_CQ_THRESH == ENIC_WQ_CQ_THRESH - 1)
+   desc->header_length_flags |=
+   (1 << WQ_ENET_FLAGS_CQ_ENTRY_SHIFT);
+   }
+}
+
 int enic_enable(struct enic *enic)
 {
unsigned int index;
@@ -535,6 +556,21 @@ int enic_enable(struct enic *enic)
}
}
 
+   /*
+* Use the simple TX handler if possible. All offloads must be disabled
+* except mbuf fast free.
+*/
+   if ((eth_dev->data->dev_conf.txmode.offloads &
+~DEV_TX_OFFLOAD_MBUF_FAST_FREE) == 0) {
+   PMD_INIT_LOG(DEBUG, " use the simple tx handler");
+   eth_dev->tx_pkt_burst = &enic_simple_xmit_pkts;
+   for (index = 0; index < enic->wq_count; index++)
+   enic_prep_wq_for_simple_tx(enic, index);
+   } else {
+   PMD_INIT_LOG(DEBUG, " use the default tx handler");
+   eth_dev->tx_pkt_burst = &enic_xmit_pkts;
+   }
+
for (index = 0; index < enic->wq_count; index++)
enic_start_wq(enic, index);
for (index = 0; index < enic->rq_count; index++)
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 7cddb53d9..7dec486fe 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -741,4 +741,81 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
return index;
 }
 
+stati

[dpdk-dev] [PATCH v2 10/15] net/enic: reduce Tx completion updates

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

Request one completion update per roughly 32 buffers. It saves DMA
resources on the NIC, PCIe utilization, and cache miss rates.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/base/vnic_wq.c |  1 +
 drivers/net/enic/base/vnic_wq.h |  1 +
 drivers/net/enic/enic_res.h |  3 +++
 drivers/net/enic/enic_rxtx.c| 23 +--
 4 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/net/enic/base/vnic_wq.c b/drivers/net/enic/base/vnic_wq.c
index a4c08a769..c9bf3572c 100644
--- a/drivers/net/enic/base/vnic_wq.c
+++ b/drivers/net/enic/base/vnic_wq.c
@@ -113,6 +113,7 @@ void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
vnic_wq_init_start(wq, cq_index, 0, 0,
error_interrupt_enable,
error_interrupt_offset);
+   wq->cq_pend = 0;
wq->last_completed_index = 0;
 }
 
diff --git a/drivers/net/enic/base/vnic_wq.h b/drivers/net/enic/base/vnic_wq.h
index 6622a8a2d..236cf6962 100644
--- a/drivers/net/enic/base/vnic_wq.h
+++ b/drivers/net/enic/base/vnic_wq.h
@@ -44,6 +44,7 @@ struct vnic_wq {
struct vnic_dev_ring ring;
struct rte_mbuf **bufs;
unsigned int head_idx;
+   unsigned int cq_pend;
unsigned int tail_idx;
unsigned int socket_id;
const struct rte_memzone *cqmsg_rz;
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 6a3a0c5cc..6b1f6acad 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -20,6 +20,9 @@
 #define ENIC_ALIGN_DESCS   32
 #define ENIC_ALIGN_DESCS_MASK  ~(ENIC_ALIGN_DESCS - 1)
 
+/* Request a completion index every 32 buffers (roughly packets) */
+#define ENIC_WQ_CQ_THRESH  32
+
 #define ENIC_MIN_MTU   68
 
 /* Does not include (possible) inserted VLAN tag and FCS */
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 89a1e66fe..7cddb53d9 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -603,7 +603,7 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
struct wq_enet_desc *descs, *desc_p, desc_tmp;
uint16_t mss;
uint8_t vlan_tag_insert;
-   uint8_t eop;
+   uint8_t eop, cq;
uint64_t bus_addr;
uint8_t offload_mode;
uint16_t header_len;
@@ -686,10 +686,14 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
break;
}
}
-
-
+   wq->cq_pend++;
+   cq = 0;
+   if (eop && wq->cq_pend >= ENIC_WQ_CQ_THRESH) {
+   cq = 1;
+   wq->cq_pend = 0;
+   }
wq_enet_desc_enc(&desc_tmp, bus_addr, data_len, mss, header_len,
-offload_mode, eop, eop, 0, vlan_tag_insert,
+offload_mode, eop, cq, 0, vlan_tag_insert,
 vlan_id, 0);
 
*desc_p = desc_tmp;
@@ -702,14 +706,21 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
tx_pkt->next) {
data_len = tx_pkt->data_len;
 
-   if (tx_pkt->next == NULL)
+   wq->cq_pend++;
+   cq = 0;
+   if (tx_pkt->next == NULL) {
eop = 1;
+   if (wq->cq_pend >= ENIC_WQ_CQ_THRESH) {
+   cq = 1;
+   wq->cq_pend = 0;
+   }
+   }
desc_p = descs + head_idx;
bus_addr = (dma_addr_t)(tx_pkt->buf_iova
   + tx_pkt->data_off);
wq_enet_desc_enc((struct wq_enet_desc *)
 &desc_tmp, bus_addr, data_len,
-mss, 0, offload_mode, eop, eop,
+mss, 0, offload_mode, eop, cq,
 0, vlan_tag_insert, vlan_id,
 0);
 
-- 
2.16.2



[dpdk-dev] [PATCH v2 09/15] net/enic: support mbuf fast free offload

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---

v2: documented new feature in enic.ini file

 doc/guides/nics/features/enic.ini |  1 +
 drivers/net/enic/base/vnic_wq.h   |  1 +
 drivers/net/enic/enic.h   |  1 +
 drivers/net/enic/enic_ethdev.c| 11 ---
 drivers/net/enic/enic_res.c   |  2 ++
 drivers/net/enic/enic_rxtx.c  | 30 +-
 6 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/features/enic.ini 
b/doc/guides/nics/features/enic.ini
index ae46d299a..31a3fb5cf 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -6,6 +6,7 @@
 [Features]
 Link status  = Y
 Link status event= Y
+Fast mbuf free   = Y
 Rx interrupt = Y
 Queue start/stop = Y
 MTU update   = Y
diff --git a/drivers/net/enic/base/vnic_wq.h b/drivers/net/enic/base/vnic_wq.h
index 86ac10e28..6622a8a2d 100644
--- a/drivers/net/enic/base/vnic_wq.h
+++ b/drivers/net/enic/base/vnic_wq.h
@@ -48,6 +48,7 @@ struct vnic_wq {
unsigned int socket_id;
const struct rte_memzone *cqmsg_rz;
uint16_t last_completed_index;
+   uint64_t offloads;
 };
 
 static inline unsigned int vnic_wq_desc_avail(struct vnic_wq *wq)
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index b611f0a24..af790fc2e 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -183,6 +183,7 @@ struct enic {
 
uint64_t rx_offload_capa; /* DEV_RX_OFFLOAD flags */
uint64_t tx_offload_capa; /* DEV_TX_OFFLOAD flags */
+   uint64_t tx_queue_offload_capa; /* DEV_TX_OFFLOAD flags */
uint64_t tx_offload_mask; /* PKT_TX flags accepted */
 };
 
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 117b362de..ef18f8802 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -185,17 +185,21 @@ static int enicpmd_dev_tx_queue_setup(struct rte_eth_dev 
*eth_dev,
uint16_t queue_idx,
uint16_t nb_desc,
unsigned int socket_id,
-   __rte_unused const struct rte_eth_txconf *tx_conf)
+   const struct rte_eth_txconf *tx_conf)
 {
int ret;
struct enic *enic = pmd_priv(eth_dev);
+   struct vnic_wq *wq;
 
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return -E_RTE_SECONDARY;
 
ENICPMD_FUNC_TRACE();
RTE_ASSERT(queue_idx < enic->conf_wq_count);
-   eth_dev->data->tx_queues[queue_idx] = (void *)&enic->wq[queue_idx];
+   wq = &enic->wq[queue_idx];
+   wq->offloads = tx_conf->offloads |
+   eth_dev->data->dev_conf.txmode.offloads;
+   eth_dev->data->tx_queues[queue_idx] = (void *)wq;
 
ret = enic_alloc_wq(enic, queue_idx, socket_id, nb_desc);
if (ret) {
@@ -477,6 +481,7 @@ static void enicpmd_dev_info_get(struct rte_eth_dev 
*eth_dev,
device_info->max_mac_addrs = ENIC_MAX_MAC_ADDR;
device_info->rx_offload_capa = enic->rx_offload_capa;
device_info->tx_offload_capa = enic->tx_offload_capa;
+   device_info->tx_queue_offload_capa = enic->tx_queue_offload_capa;
device_info->default_rxconf = (struct rte_eth_rxconf) {
.rx_free_thresh = ENIC_DEFAULT_RX_FREE_THRESH
};
@@ -765,7 +770,7 @@ static void enicpmd_dev_txq_info_get(struct rte_eth_dev 
*dev,
ENICPMD_FUNC_TRACE();
qinfo->nb_desc = wq->ring.desc_count;
memset(&qinfo->conf, 0, sizeof(qinfo->conf));
-   qinfo->conf.offloads = enic->tx_offload_capa;
+   qinfo->conf.offloads = wq->offloads;
/* tx_thresh, and all the other fields are not applicable for enic */
 }
 
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index d1113b2f1..11d66a626 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -183,7 +183,9 @@ int enic_get_vnic_config(struct enic *enic)
 * Default hardware capabilities. enic_dev_init() may add additional
 * flags if it enables overlay offloads.
 */
+   enic->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
enic->tx_offload_capa =
+   enic->tx_queue_offload_capa |
DEV_TX_OFFLOAD_MULTI_SEGS |
DEV_TX_OFFLOAD_VLAN_INSERT |
DEV_TX_OFFLOAD_IPV4_CKSUM |
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 549288c20..89a1e66fe 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -471,6 +471,31 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
return nb_rx;
 }
 
+static void enic_fast_free_wq_bufs(struct vnic_wq *wq, u16 completed_index)
+{
+   unsigned int desc_count, n, nb_to_free, tail_idx;
+   struct rte_mempool *pool;
+   struct rte_mbuf **m;
+
+   desc_

[dpdk-dev] [PATCH v2 08/15] net/enic: use mbuf pointer array for inflight Tx packets

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

WQ is currently using vnic_wq_buf to store mbuf pointers for Tx
packets. But, it contains an unused mempool pointer and mbuf is
unnecessarily cast to void pointer. Remove vnic_wq_buf entirely and
use an mbuf pointer array instead.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/base/vnic_wq.c |  8 
 drivers/net/enic/base/vnic_wq.h | 10 ++
 drivers/net/enic/enic_main.c|  6 +++---
 drivers/net/enic/enic_rxtx.c| 18 ++
 4 files changed, 15 insertions(+), 27 deletions(-)

diff --git a/drivers/net/enic/base/vnic_wq.c b/drivers/net/enic/base/vnic_wq.c
index d61c4c6e2..a4c08a769 100644
--- a/drivers/net/enic/base/vnic_wq.c
+++ b/drivers/net/enic/base/vnic_wq.c
@@ -32,8 +32,8 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
 {
unsigned int count = wq->ring.desc_count;
/* Allocate the mbuf ring */
-   wq->bufs = (struct vnic_wq_buf *)rte_zmalloc_socket("wq->bufs",
-   sizeof(struct vnic_wq_buf) * count,
+   wq->bufs = (struct rte_mbuf **)rte_zmalloc_socket("wq->bufs",
+   sizeof(struct rte_mbuf *) * count,
RTE_CACHE_LINE_SIZE, wq->socket_id);
wq->head_idx = 0;
wq->tail_idx = 0;
@@ -145,9 +145,9 @@ int vnic_wq_disable(struct vnic_wq *wq)
 }
 
 void vnic_wq_clean(struct vnic_wq *wq,
-  void (*buf_clean)(struct vnic_wq_buf *buf))
+  void (*buf_clean)(struct rte_mbuf **buf))
 {
-   struct vnic_wq_buf *buf;
+   struct rte_mbuf **buf;
unsigned int  to_clean = wq->tail_idx;
 
buf = &wq->bufs[to_clean];
diff --git a/drivers/net/enic/base/vnic_wq.h b/drivers/net/enic/base/vnic_wq.h
index 0135bffc5..86ac10e28 100644
--- a/drivers/net/enic/base/vnic_wq.h
+++ b/drivers/net/enic/base/vnic_wq.h
@@ -36,19 +36,13 @@ struct vnic_wq_ctrl {
u32 pad9;
 };
 
-/* 16 bytes */
-struct vnic_wq_buf {
-   struct rte_mempool *pool;
-   void *mb;
-};
-
 struct vnic_wq {
unsigned int index;
uint64_t tx_offload_notsup_mask;
struct vnic_dev *vdev;
struct vnic_wq_ctrl __iomem *ctrl;  /* memory-mapped */
struct vnic_dev_ring ring;
-   struct vnic_wq_buf *bufs;
+   struct rte_mbuf **bufs;
unsigned int head_idx;
unsigned int tail_idx;
unsigned int socket_id;
@@ -164,5 +158,5 @@ unsigned int vnic_wq_error_status(struct vnic_wq *wq);
 void vnic_wq_enable(struct vnic_wq *wq);
 int vnic_wq_disable(struct vnic_wq *wq);
 void vnic_wq_clean(struct vnic_wq *wq,
-  void (*buf_clean)(struct vnic_wq_buf *buf));
+  void (*buf_clean)(struct rte_mbuf **buf));
 #endif /* _VNIC_WQ_H_ */
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index e20256986..c03ec247a 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -69,12 +69,12 @@ enic_rxmbuf_queue_release(__rte_unused struct enic *enic, 
struct vnic_rq *rq)
}
 }
 
-static void enic_free_wq_buf(struct vnic_wq_buf *buf)
+static void enic_free_wq_buf(struct rte_mbuf **buf)
 {
-   struct rte_mbuf *mbuf = (struct rte_mbuf *)buf->mb;
+   struct rte_mbuf *mbuf = *buf;
 
rte_pktmbuf_free_seg(mbuf);
-   buf->mb = NULL;
+   *buf = NULL;
 }
 
 static void enic_log_q_error(struct enic *enic)
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index bbb0444ad..549288c20 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -473,7 +473,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 
 static inline void enic_free_wq_bufs(struct vnic_wq *wq, u16 completed_index)
 {
-   struct vnic_wq_buf *buf;
+   struct rte_mbuf *buf;
struct rte_mbuf *m, *free[ENIC_MAX_WQ_DESCS];
unsigned int nb_to_free, nb_free = 0, i;
struct rte_mempool *pool;
@@ -483,13 +483,10 @@ static inline void enic_free_wq_bufs(struct vnic_wq *wq, 
u16 completed_index)
nb_to_free = enic_ring_sub(desc_count, wq->tail_idx, completed_index)
   + 1;
tail_idx = wq->tail_idx;
-   buf = &wq->bufs[tail_idx];
-   pool = ((struct rte_mbuf *)buf->mb)->pool;
+   pool = wq->bufs[tail_idx]->pool;
for (i = 0; i < nb_to_free; i++) {
-   buf = &wq->bufs[tail_idx];
-   m = rte_pktmbuf_prefree_seg((struct rte_mbuf *)(buf->mb));
-   buf->mb = NULL;
-
+   buf = wq->bufs[tail_idx];
+   m = rte_pktmbuf_prefree_seg(buf);
if (unlikely(m == NULL)) {
tail_idx = enic_ring_incr(desc_count, tail_idx);
continue;
@@ -574,7 +571,6 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts,
uint64_t ol_flags_mask;
unsigned int wq_desc_avail

[dpdk-dev] [PATCH v2 05/15] net/enic: report ring limits and preferred default values

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

Report min/max ring sizes, alignments, and so on, and rely on the
common checks implemented in the rte_ethdev layer.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_ethdev.c | 24 
 drivers/net/enic/enic_main.c   | 24 
 drivers/net/enic/enic_res.h| 12 
 3 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 6ebad8d96..697dd6508 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -482,6 +482,30 @@ static void enicpmd_dev_info_get(struct rte_eth_dev 
*eth_dev,
device_info->reta_size = enic->reta_size;
device_info->hash_key_size = enic->hash_key_size;
device_info->flow_type_rss_offloads = enic->flow_type_rss_offloads;
+   device_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+   .nb_max = enic->config.rq_desc_count,
+   .nb_min = ENIC_MIN_RQ_DESCS,
+   .nb_align = ENIC_ALIGN_DESCS,
+   };
+   device_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+   .nb_max = enic->config.wq_desc_count,
+   .nb_min = ENIC_MIN_WQ_DESCS,
+   .nb_align = ENIC_ALIGN_DESCS,
+   .nb_seg_max = ENIC_TX_XMIT_MAX,
+   .nb_mtu_seg_max = ENIC_NON_TSO_MAX_DESC,
+   };
+   device_info->default_rxportconf = (struct rte_eth_dev_portconf) {
+   .burst_size = ENIC_DEFAULT_RX_BURST,
+   .ring_size = RTE_MIN(device_info->rx_desc_lim.nb_max,
+   ENIC_DEFAULT_RX_RING_SIZE),
+   .nb_queues = ENIC_DEFAULT_RX_RINGS,
+   };
+   device_info->default_txportconf = (struct rte_eth_dev_portconf) {
+   .burst_size = ENIC_DEFAULT_TX_BURST,
+   .ring_size = RTE_MIN(device_info->tx_desc_lim.nb_max,
+   ENIC_DEFAULT_TX_RING_SIZE),
+   .nb_queues = ENIC_DEFAULT_TX_RINGS,
+   };
 }
 
 static const uint32_t *enicpmd_dev_supported_ptypes_get(struct rte_eth_dev 
*dev)
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 863d2463c..2cd85168d 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -743,8 +743,8 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
}
 
/* number of descriptors have to be a multiple of 32 */
-   nb_sop_desc = (nb_desc / mbufs_per_pkt) & ~0x1F;
-   nb_data_desc = (nb_desc - nb_sop_desc) & ~0x1F;
+   nb_sop_desc = (nb_desc / mbufs_per_pkt) & ENIC_ALIGN_DESCS_MASK;
+   nb_data_desc = (nb_desc - nb_sop_desc) & ENIC_ALIGN_DESCS_MASK;
 
rq_sop->max_mbufs_per_pkt = mbufs_per_pkt;
rq_data->max_mbufs_per_pkt = mbufs_per_pkt;
@@ -752,7 +752,7 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
if (mbufs_per_pkt > 1) {
min_sop = 64;
max_sop = ((enic->config.rq_desc_count /
-   (mbufs_per_pkt - 1)) & ~0x1F);
+   (mbufs_per_pkt - 1)) & ENIC_ALIGN_DESCS_MASK);
min_data = min_sop * (mbufs_per_pkt - 1);
max_data = enic->config.rq_desc_count;
} else {
@@ -870,19 +870,11 @@ int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
static int instance;
 
wq->socket_id = socket_id;
-   if (nb_desc > enic->config.wq_desc_count) {
-   dev_warning(enic,
-   "WQ %d - number of tx desc in cmd line (%d) "
-   "is greater than that in the UCSM/CIMC adapter "
-   "policy.  Applying the value in the adapter "
-   "policy (%d)\n",
-   queue_idx, nb_desc, enic->config.wq_desc_count);
-   nb_desc = enic->config.wq_desc_count;
-   } else if (nb_desc != enic->config.wq_desc_count) {
-   dev_info(enic,
-"TX Queues - effective number of descs:%d\n",
-nb_desc);
-   }
+   /*
+* rte_eth_tx_queue_setup() checks min, max, and alignment. So just
+* print an info message for diagnostics.
+*/
+   dev_info(enic, "TX Queues - effective number of descs:%d\n", nb_desc);
 
/* Allocate queue resources */
err = vnic_wq_alloc(enic->vdev, &enic->wq[queue_idx], queue_idx,
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index e68f1307b..6a3a0c5cc 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -16,6 +16,10 @@
 #define ENIC_MIN_RQ_DESCS  64
 #define ENIC_MAX_RQ_DESCS  4096
 
+/* A descriptor ring has a multiple of 32 descriptors */
+#define ENIC_A

[dpdk-dev] [PATCH v2 07/15] net/enic: add handlers to add/delete vxlan port number

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

The NIC has one configurable VXLAN port, which is set to the default
4789 upon vNIC reset. Adding a non-default port replaces this single
VXLAN port. Deleting the previously added non-default port restores
the VXLAN port to the hardware default.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic.h|  4 +++
 drivers/net/enic/enic_ethdev.c | 75 ++
 drivers/net/enic/enic_main.c   |  1 +
 3 files changed, 80 insertions(+)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index f1895fe70..b611f0a24 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -50,6 +50,9 @@
 
 #define ENICPMD_FDIR_MAX   64
 
+/* HW default VXLAN port */
+#define ENIC_DEFAULT_VXLAN_PORT   4789
+
 /*
  * Interrupt 0: LSC and errors
  * Interrupt 1: rx queue 0
@@ -126,6 +129,7 @@ struct enic {
bool nic_cfg_chk; /* NIC_CFG_CHK available */
bool udp_rss_weak;/* Bodega style UDP RSS */
uint8_t ig_vlan_rewrite_mode; /* devargs ig-vlan-rewrite */
+   uint16_t vxlan_port;  /* current vxlan port pushed to NIC */
 
unsigned int flags;
unsigned int priv_flags;
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 111bdc82c..117b362de 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -789,6 +789,79 @@ static int enicpmd_dev_rx_queue_intr_disable(struct 
rte_eth_dev *eth_dev,
return 0;
 }
 
+static int udp_tunnel_common_check(struct enic *enic,
+  struct rte_eth_udp_tunnel *tnl)
+{
+   if (tnl->prot_type != RTE_TUNNEL_TYPE_VXLAN)
+   return -ENOTSUP;
+   if (!enic->overlay_offload) {
+   PMD_INIT_LOG(DEBUG, " vxlan (overlay offload) is not "
+"supported\n");
+   return -ENOTSUP;
+   }
+   return 0;
+}
+
+static int update_vxlan_port(struct enic *enic, uint16_t port)
+{
+   if (vnic_dev_overlay_offload_cfg(enic->vdev,
+OVERLAY_CFG_VXLAN_PORT_UPDATE,
+port)) {
+   PMD_INIT_LOG(DEBUG, " failed to update vxlan port\n");
+   return -EINVAL;
+   }
+   PMD_INIT_LOG(DEBUG, " updated vxlan port to %u\n", port);
+   enic->vxlan_port = port;
+   return 0;
+}
+
+static int enicpmd_dev_udp_tunnel_port_add(struct rte_eth_dev *eth_dev,
+  struct rte_eth_udp_tunnel *tnl)
+{
+   struct enic *enic = pmd_priv(eth_dev);
+   int ret;
+
+   ENICPMD_FUNC_TRACE();
+   ret = udp_tunnel_common_check(enic, tnl);
+   if (ret)
+   return ret;
+   /*
+* The NIC has 1 configurable VXLAN port number. "Adding" a new port
+* number replaces it.
+*/
+   if (tnl->udp_port == enic->vxlan_port || tnl->udp_port == 0) {
+   PMD_INIT_LOG(DEBUG, " %u is already configured or invalid\n",
+tnl->udp_port);
+   return -EINVAL;
+   }
+   return update_vxlan_port(enic, tnl->udp_port);
+}
+
+static int enicpmd_dev_udp_tunnel_port_del(struct rte_eth_dev *eth_dev,
+  struct rte_eth_udp_tunnel *tnl)
+{
+   struct enic *enic = pmd_priv(eth_dev);
+   int ret;
+
+   ENICPMD_FUNC_TRACE();
+   ret = udp_tunnel_common_check(enic, tnl);
+   if (ret)
+   return ret;
+   /*
+* Clear the previously set port number and restore the
+* hardware default port number. Some drivers disable VXLAN
+* offloads when there are no configured port numbers. But
+* enic does not do that as VXLAN is part of overlay offload,
+* which is tied to inner RSS and TSO.
+*/
+   if (tnl->udp_port != enic->vxlan_port) {
+   PMD_INIT_LOG(DEBUG, " %u is not a configured vxlan port\n",
+tnl->udp_port);
+   return -EINVAL;
+   }
+   return update_vxlan_port(enic, ENIC_DEFAULT_VXLAN_PORT);
+}
+
 static const struct eth_dev_ops enicpmd_eth_dev_ops = {
.dev_configure= enicpmd_dev_configure,
.dev_start= enicpmd_dev_start,
@@ -838,6 +911,8 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
.reta_update  = enicpmd_dev_rss_reta_update,
.rss_hash_conf_get= enicpmd_dev_rss_hash_conf_get,
.rss_hash_update  = enicpmd_dev_rss_hash_update,
+   .udp_tunnel_port_add  = enicpmd_dev_udp_tunnel_port_add,
+   .udp_tunnel_port_del  = enicpmd_dev_udp_tunnel_port_del,
 };
 
 static int enic_parse_disable_overlay(__rte_unused const char *key,
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 24

[dpdk-dev] [PATCH v2 06/15] net/enic: add devarg to specify ingress VLAN rewrite mode

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

Add a new devarg "ig-vlan-rewrite" to allow the user to set
non-default rewrite mode. The UCS VIC may add/remove/modify the VLAN
header of an ingress packet depending on the ingress VLAN rewrite
mode.

By default, the driver sets the pass-through mode, which tells the NIC
"do not touch VLAN header and preserve it as is". This mode is usually
sufficient, but can complicate deployments for certain environments.
For example, OVS-DPDK in UCS blade environments may want to use "untag
default VLAN mode", which removes the VLAN header from an ingress
packet if it matches vNIC's default VLAN.

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---

v2: documented new devarg in enic driver documentation.

 doc/guides/nics/enic.rst   | 15 +++---
 drivers/net/enic/enic.h|  1 +
 drivers/net/enic/enic_ethdev.c | 46 +++---
 drivers/net/enic/enic_main.c   |  4 +++-
 4 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index d650ba0f7..7764c8648 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -351,9 +351,10 @@ Limitations
   In test setups where an Ethernet port of a Cisco adapter in TRUNK mode is
   connected point-to-point to another adapter port or connected though a router
   instead of a switch, all ingress packets will be VLAN tagged. Programs such
-  as l3fwd which do not account for VLAN tags in packets will misbehave. The
-  solution is to enable VLAN stripping on ingress. The following code fragment 
is
-  an example of how to accomplish this:
+  as l3fwd may not account for VLAN tags in packets and may misbehave. One
+  solution is to enable VLAN stripping on ingress so the VLAN tag is removed
+  from the packet and put into the mbuf->vlan_tci field. Here is an example
+  of how to accomplish this:
 
 .. code-block:: console
 
@@ -361,6 +362,14 @@ Limitations
  vlan_offload |= ETH_VLAN_STRIP_OFFLOAD;
  rte_eth_dev_set_vlan_offload(port, vlan_offload);
 
+Another alternative is modify the adapter's ingress VLAN rewrite mode so that
+packets with the default VLAN tag are stripped by the adapter and presented to
+DPDK as untagged packets. In this case mbuf->vlan_tci and the PKT_RX_VLAN and
+PKT_RX_VLAN_STRIPPED mbuf flags would not be set. This mode is enabled with the
+``devargs`` parameter ``ig-vlan-rewrite=1``. For example::
+
+-w 12:00.0,ig-vlan-rewrite=1
+
 - Limited flow director support on 1200 series and 1300 series Cisco VIC
   adapters with old firmware. Please see :ref:`enic-flow-director`.
 
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index ea0a688d3..f1895fe70 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -125,6 +125,7 @@ struct enic {
bool disable_overlay; /* devargs disable_overlay=1 */
bool nic_cfg_chk; /* NIC_CFG_CHK available */
bool udp_rss_weak;/* Bodega style UDP RSS */
+   uint8_t ig_vlan_rewrite_mode; /* devargs ig-vlan-rewrite */
 
unsigned int flags;
unsigned int priv_flags;
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 697dd6508..111bdc82c 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -41,6 +41,7 @@ static const struct rte_pci_id pci_id_enic_map[] = {
 };
 
 #define ENIC_DEVARG_DISABLE_OVERLAY "disable-overlay"
+#define ENIC_DEVARG_IG_VLAN_REWRITE "ig-vlan-rewrite"
 
 RTE_INIT(enicpmd_init_log);
 static void
@@ -858,23 +859,61 @@ static int enic_parse_disable_overlay(__rte_unused const 
char *key,
return 0;
 }
 
+static int enic_parse_ig_vlan_rewrite(__rte_unused const char *key,
+ const char *value,
+ void *opaque)
+{
+   struct enic *enic;
+
+   enic = (struct enic *)opaque;
+   if (strcmp(value, "trunk") == 0) {
+   /* Trunk mode: always tag */
+   enic->ig_vlan_rewrite_mode = IG_VLAN_REWRITE_MODE_DEFAULT_TRUNK;
+   } else if (strcmp(value, "untag") == 0) {
+   /* Untag default VLAN mode: untag if VLAN = default VLAN */
+   enic->ig_vlan_rewrite_mode =
+   IG_VLAN_REWRITE_MODE_UNTAG_DEFAULT_VLAN;
+   } else if (strcmp(value, "priority") == 0) {
+   /*
+* Priority-tag default VLAN mode: priority tag (VLAN header
+* with ID=0) if VLAN = default
+*/
+   enic->ig_vlan_rewrite_mode =
+   IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN;
+   } else if (strcmp(value, "pass") == 0) {
+   /* Pass through mode: do not touch tags */
+   enic->ig_vlan_rewrite_mode = IG_VLAN_REWRITE_MODE_PASS_THRU;
+   } else {
+   dev_err(enic, &qu

[dpdk-dev] [PATCH v2 04/15] net/enic: initialize RQ fetch index before enabling RQ

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

The fetch index must be initialized only when RQ is
disabled. Otherwise, it may lead to stale entries in IG descriptor
cache on the VIC.

Fixes: a74629cfa3a1 ("net/enic: enable RQ first and then post Rx buffers")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index aba2ff5a7..863d2463c 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -320,6 +320,8 @@ enic_alloc_rx_queue_mbufs(struct enic *enic, struct vnic_rq 
*rq)
 * enic_start_rq().
 */
rq->need_initial_post = true;
+   /* Initialize fetch index while RQ is disabled */
+   iowrite32(0, &rq->ctrl->fetch_index);
return 0;
 }
 
@@ -345,7 +347,6 @@ enic_initial_post_rx(struct enic *enic, struct vnic_rq *rq)
dev_debug(enic, "port=%u, qidx=%u, Write %u posted idx, %u sw held\n",
enic->port_id, rq->index, rq->posted_index, rq->rx_nb_hold);
iowrite32(rq->posted_index, &rq->ctrl->posted_index);
-   iowrite32(0, &rq->ctrl->fetch_index);
rte_rmb();
rq->need_initial_post = false;
 }
-- 
2.16.2



[dpdk-dev] [PATCH v2 03/15] net/enic: do not overwrite admin Tx queue limit

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

Currently, enic_alloc_wq (via rte_eth_tx_queue_setup) may overwrite
the admin limit with a lower value. This is wrong as seen in the
following sequence.

1. UCS admin-set Tx queue limit (config.wq_desc_count) = 4096
2. Set up tx queue with 512 descriptors
   The admin limit (config.wq_desc_count) becomes 512.
3. Stop ports and now set up Tx queue with 1024 descriptors.
   This fails because 1024 is greater than the admin limit (512).

Do not modify the admin limit, and when queried, report the current
number of descriptors instead of the admin limit. The rx queue setup
(enic_alloc_rq) does not this problem.

Fixes: fefed3d1e62c ("enic: new driver")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_ethdev.c |  5 +++--
 drivers/net/enic/enic_main.c   | 30 ++
 2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 286308924..6ebad8d96 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -731,13 +731,14 @@ static void enicpmd_dev_rxq_info_get(struct rte_eth_dev 
*dev,
 }
 
 static void enicpmd_dev_txq_info_get(struct rte_eth_dev *dev,
-__rte_unused uint16_t tx_queue_id,
+uint16_t tx_queue_id,
 struct rte_eth_txq_info *qinfo)
 {
struct enic *enic = pmd_priv(dev);
+   struct vnic_wq *wq = &enic->wq[tx_queue_id];
 
ENICPMD_FUNC_TRACE();
-   qinfo->nb_desc = enic->config.wq_desc_count;
+   qinfo->nb_desc = wq->ring.desc_count;
memset(&qinfo->conf, 0, sizeof(qinfo->conf));
qinfo->conf.offloads = enic->tx_offload_capa;
/* tx_thresh, and all the other fields are not applicable for enic */
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 899603fa7..aba2ff5a7 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -869,25 +869,23 @@ int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
static int instance;
 
wq->socket_id = socket_id;
-   if (nb_desc) {
-   if (nb_desc > enic->config.wq_desc_count) {
-   dev_warning(enic,
-   "WQ %d - number of tx desc in cmd line (%d)"\
-   "is greater than that in the UCSM/CIMC adapter"\
-   "policy.  Applying the value in the adapter "\
-   "policy (%d)\n",
-   queue_idx, nb_desc, enic->config.wq_desc_count);
-   } else if (nb_desc != enic->config.wq_desc_count) {
-   enic->config.wq_desc_count = nb_desc;
-   dev_info(enic,
-   "TX Queues - effective number of descs:%d\n",
-   nb_desc);
-   }
+   if (nb_desc > enic->config.wq_desc_count) {
+   dev_warning(enic,
+   "WQ %d - number of tx desc in cmd line (%d) "
+   "is greater than that in the UCSM/CIMC adapter "
+   "policy.  Applying the value in the adapter "
+   "policy (%d)\n",
+   queue_idx, nb_desc, enic->config.wq_desc_count);
+   nb_desc = enic->config.wq_desc_count;
+   } else if (nb_desc != enic->config.wq_desc_count) {
+   dev_info(enic,
+"TX Queues - effective number of descs:%d\n",
+nb_desc);
}
 
/* Allocate queue resources */
err = vnic_wq_alloc(enic->vdev, &enic->wq[queue_idx], queue_idx,
-   enic->config.wq_desc_count,
+   nb_desc,
sizeof(struct wq_enet_desc));
if (err) {
dev_err(enic, "error in allocation of wq\n");
@@ -895,7 +893,7 @@ int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
}
 
err = vnic_cq_alloc(enic->vdev, &enic->cq[cq_index], cq_index,
-   socket_id, enic->config.wq_desc_count,
+   socket_id, nb_desc,
sizeof(struct cq_enet_wq_desc));
if (err) {
vnic_wq_free(wq);
-- 
2.16.2



[dpdk-dev] [PATCH v2 02/15] net/enic: update the UDP RSS detection mechanism

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

The UDP RSS interface has changed in the release firmware for 100G VIC
adapters. The capability bit is now in NIC_CFG. Also the driver is
supposed to use CMD_NIC_CFG_CHK and check if RSS config is
successful. No more changes are expected with respect to UDP RSS API.

Fixes: 94c351895888 ("net/enic: update UDP RSS controls")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/base/vnic_dev.c| 16 
 drivers/net/enic/base/vnic_dev.h|  4 
 drivers/net/enic/base/vnic_devcmd.h | 23 ++-
 drivers/net/enic/base/vnic_enet.h   |  5 ++---
 drivers/net/enic/base/vnic_nic.h|  4 ++--
 drivers/net/enic/enic.h |  2 ++
 drivers/net/enic/enic_main.c|  9 ++---
 drivers/net/enic/enic_res.c | 11 +++
 8 files changed, 61 insertions(+), 13 deletions(-)

diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index 8483f76f3..16e8814a6 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -528,6 +528,22 @@ int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, 
u32 *mode,
return 0;
 }
 
+void vnic_dev_capable_udp_rss_weak(struct vnic_dev *vdev, bool *cfg_chk,
+  bool *weak)
+{
+   u64 a0 = CMD_NIC_CFG, a1 = 0;
+   int wait = 1000;
+   int err;
+
+   *cfg_chk = false;
+   *weak = false;
+   err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
+   if (err == 0 && a0 != 0 && a1 != 0) {
+   *cfg_chk = true;
+   *weak = !!((a1 >> 32) & CMD_NIC_CFG_CAPF_UDP_WEAK);
+   }
+}
+
 int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd)
 {
u64 a0 = (u32)cmd, a1 = 0;
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 3c9084304..270a47bd2 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -6,6 +6,8 @@
 #ifndef _VNIC_DEV_H_
 #define _VNIC_DEV_H_
 
+#include 
+
 #include 
 #include 
 
@@ -109,6 +111,8 @@ int vnic_dev_capable_adv_filters(struct vnic_dev *vdev);
 int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd);
 int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode,
 u8 *filter_actions);
+void vnic_dev_capable_udp_rss_weak(struct vnic_dev *vdev, bool *cfg_chk,
+  bool *weak);
 int vnic_dev_asic_info(struct vnic_dev *vdev, u16 *asic_type, u16 *asic_rev);
 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, size_t size,
void *value);
diff --git a/drivers/net/enic/base/vnic_devcmd.h 
b/drivers/net/enic/base/vnic_devcmd.h
index 2865eb4d4..a22d8a76c 100644
--- a/drivers/net/enic/base/vnic_devcmd.h
+++ b/drivers/net/enic/base/vnic_devcmd.h
@@ -138,9 +138,27 @@ enum vnic_devcmd_cmd {
/* del VLAN id in (u16)a0 */
CMD_VLAN_DEL= _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 15),
 
-   /* nic_cfg in (u32)a0 */
+   /*
+* nic_cfg in (u32)a0
+*
+* Capability query:
+* out: (u64) a0= 1 if a1 is valid
+*  (u64) a1= (NIC_CFG bits supported) | (flags << 32)
+*  (flags are CMD_NIC_CFG_CAPF_xxx)
+*/
CMD_NIC_CFG = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 16),
 
+   /*
+* nic_cfg_chk  (same as nic_cfg, but may return error)
+* in (u32)a0
+*
+* Capability query:
+* out: (u64) a0= 1 if a1 is valid
+*  (u64) a1= (NIC_CFG bits supported) | (flags << 32)
+*  (flags are CMD_NIC_CFG_CAPF_xxx)
+*/
+   CMD_NIC_CFG_CHK = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 16),
+
/* union vnic_rss_key in mem: (u64)a0=paddr, (u16)a1=len */
CMD_RSS_KEY = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 17),
 
@@ -605,6 +623,9 @@ enum filter_cap_mode {
 /* flags for CMD_INIT */
 #define CMD_INITF_DEFAULT_MAC  0x1 /* init with default mac addr */
 
+/* flags for CMD_NIC_CFG */
+#define CMD_NIC_CFG_CAPF_UDP_WEAK  (1ULL << 0) /* Bodega-style UDP RSS */
+
 /* flags for CMD_PACKET_FILTER */
 #define CMD_PFILTER_DIRECTED   0x01
 #define CMD_PFILTER_MULTICAST  0x02
diff --git a/drivers/net/enic/base/vnic_enet.h 
b/drivers/net/enic/base/vnic_enet.h
index 49504a7da..901f3b46e 100644
--- a/drivers/net/enic/base/vnic_enet.h
+++ b/drivers/net/enic/base/vnic_enet.h
@@ -53,9 +53,8 @@ struct vnic_enet_config {
 #define VENETF_NVGRE0x2 /* NVGRE offload */
 #define VENETF_GRPINTR  0x4 /* group interrupt */
 #define VENETF_NICSWITCH0x8 /* NICSWITCH enabled */
-#define VENETF_RSSHASH_UDP_WEAK 0x10 /* VIC has Bodega-style UDP RSS */
-#define VENETF_RSSHASH_UDPIPV4  0x20 /* Hash on UDP + IPv4 fields */
-#define VENETF_RSSH

[dpdk-dev] [PATCH v2 01/15] net/enic: fix receive packet types

2018-06-29 Thread John Daley
From: Hyong Youb Kim 

Fix missing or incorrect packet types discovered by DTS.
- Non-IP inner packets
  Set the tunnel flag.
- Inner Ethernet packets
  All supported tunnel packets have Ethernet as inner packets. So, set
  INNER_L2_ETHER for all tunnel types.
- IPv4 fragments carrying TCP/UDP
  The NIC indicates TCP/UDP based on the protocol in IP header. For
  fragments, ignore that bit and always set L4_FRAG.
- IPv6 fragments
  The NIC does regconize fragments (IPv6 packets with fragment extension
  headers). Set packet types for these.

Fixes: 93fb21fdbe23 ("net/enic: enable overlay offload for VXLAN and GENEVE")

Signed-off-by: Hyong Youb Kim 
Reviewed-by: John Daley 
---
 drivers/net/enic/enic_rxtx.c | 42 --
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 8853a2044..bbb0444ad 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -137,51 +137,81 @@ enic_cq_rx_flags_to_pkt_type(struct cq_desc *cqd, uint8_t 
tnl)
 */
static const uint32_t cq_type_table[128] __rte_cache_aligned = {
[0x00] = RTE_PTYPE_UNKNOWN,
+   [0x01] = RTE_PTYPE_UNKNOWN |
+RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER,
[0x20] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG,
[0x21] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER |
 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
 RTE_PTYPE_INNER_L4_NONFRAG,
[0x22] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
[0x23] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER |
 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
 RTE_PTYPE_INNER_L4_UDP,
[0x24] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP,
[0x25] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER |
 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
 RTE_PTYPE_INNER_L4_TCP,
[0x60] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_FRAG,
[0x61] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_FRAG |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER |
 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
 RTE_PTYPE_INNER_L4_FRAG,
-   [0x62] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
-   [0x63] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP |
+   [0x62] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_FRAG,
+   [0x63] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_FRAG |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER |
 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
-RTE_PTYPE_INNER_L4_UDP,
-   [0x64] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP,
-   [0x65] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP |
+RTE_PTYPE_INNER_L4_FRAG,
+   [0x64] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_FRAG,
+   [0x65] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_FRAG |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER |
 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
-RTE_PTYPE_INNER_L4_TCP,
+RTE_PTYPE_INNER_L4_FRAG,
[0x10] = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG,
[0x11] = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_NONFRAG |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER |
 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
 RTE_PTYPE_INNER_L4_NONFRAG,
[0x12] = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
[0x13] = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_UDP |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNER_L2_ETHER |
 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
 RTE_PTYPE_INNER_L4_UDP,
[0x14] = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_TCP,
[0x15] = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_TCP |
 RTE_PTYPE_TUNNEL_GRENAT |
+RTE_PTYPE_INNE

[dpdk-dev] [PATCH v2 00/15] enic PMD fixes and performance improvements

2018-06-29 Thread John Daley
Updated a few commits in the patchset per suggestions by Ferrus Yigit.
thanks,
John

Hyong Youb Kim (12):
  net/enic: fix receive packet types
  net/enic: update the UDP RSS detection mechanism
  net/enic: do not overwrite admin Tx queue limit
  net/enic: initialize RQ fetch index before enabling RQ
  net/enic: report ring limits and preferred default values
  net/enic: add devarg to specify ingress VLAN rewrite mode
  net/enic: add handlers to add/delete vxlan port number
  net/enic: use mbuf pointer array for inflight Tx packets
  net/enic: support mbuf fast free offload
  net/enic: reduce Tx completion updates
  net/enic: add the simple version of Tx handler
  net/enic: check maximum packet size in Tx prepare handler

John Daley (3):
  net/enic: add simple Rx handler
  net/enic: cap Rx packet processing to end of desc ring
  doc: update release notes with new enic features

 doc/guides/nics/enic.rst   |  15 +-
 doc/guides/nics/features/enic.ini  |   1 +
 doc/guides/rel_notes/release_18_08.rst |   8 +
 drivers/net/enic/base/cq_desc.h|   1 +
 drivers/net/enic/base/vnic_dev.c   |  16 ++
 drivers/net/enic/base/vnic_dev.h   |   4 +
 drivers/net/enic/base/vnic_devcmd.h|  23 ++-
 drivers/net/enic/base/vnic_enet.h  |   5 +-
 drivers/net/enic/base/vnic_nic.h   |   4 +-
 drivers/net/enic/base/vnic_rq.h|   2 +
 drivers/net/enic/base/vnic_wq.c|   9 +-
 drivers/net/enic/base/vnic_wq.h|  12 +-
 drivers/net/enic/enic.h|  12 ++
 drivers/net/enic/enic_compat.h |   5 +
 drivers/net/enic/enic_ethdev.c | 168 +++--
 drivers/net/enic/enic_main.c   | 125 ++---
 drivers/net/enic/enic_res.c|  13 +-
 drivers/net/enic/enic_res.h|  16 ++
 drivers/net/enic/enic_rxtx.c   | 333 +
 19 files changed, 668 insertions(+), 104 deletions(-)

-- 
2.16.2



[dpdk-dev] [PATCH 14/14] net/enic: cap Rx packet processing to end of desc ring

2018-06-27 Thread John Daley
In the default Rx handler stop processing packets at the end of
the completion ring so that wrapping doesn't have to be checked
in the inner while loop.

Also, check the color bit in the completion without using a conditional.

Signed-off-by: John Daley 
Reviewed-by: Hyong Youb Kim 
---
 drivers/net/enic/enic_rxtx.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index e0f93dd5e..7ae03f31b 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -310,7 +310,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
struct vnic_rq *rq;
struct enic *enic = vnic_dev_priv(sop_rq->vdev);
uint16_t cq_idx;
-   uint16_t rq_idx;
+   uint16_t rq_idx, max_rx;
uint16_t rq_num;
struct rte_mbuf *nmb, *rxmb;
uint16_t nb_rx = 0;
@@ -325,19 +325,23 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
cq = &enic->cq[enic_cq_rq(enic, sop_rq->index)];
cq_idx = cq->to_clean;  /* index of cqd, rqd, mbuf_table */
cqd_ptr = (struct cq_desc *)(cq->ring.descs) + cq_idx;
+   color = cq->last_color;
 
data_rq = &enic->rq[sop_rq->data_queue_idx];
 
-   while (nb_rx < nb_pkts) {
+   /* Receive until the end of the ring, at most. */
+   max_rx = RTE_MIN(nb_pkts, cq->ring.desc_count - cq_idx);
+
+   while (max_rx) {
volatile struct rq_enet_desc *rqd_ptr;
struct cq_desc cqd;
uint8_t packet_error;
uint16_t ciflags;
 
+   max_rx--;
+
/* Check for pkts available */
-   color = (cqd_ptr->type_color >> CQ_DESC_COLOR_SHIFT)
-   & CQ_DESC_COLOR_MASK;
-   if (color == cq->last_color)
+   if ((cqd_ptr->type_color & CQ_DESC_COLOR_MASK_NOSHIFT) == color)
break;
 
/* Get the cq descriptor and extract rq info from it */
@@ -361,13 +365,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
/* Get the mbuf to return and replace with one just allocated */
rxmb = rq->mbuf_ring[rq_idx];
rq->mbuf_ring[rq_idx] = nmb;
-
-   /* Increment cqd, rqd, mbuf_table index */
cq_idx++;
-   if (unlikely(cq_idx == cq->ring.desc_count)) {
-   cq_idx = 0;
-   cq->last_color = cq->last_color ? 0 : 1;
-   }
 
/* Prefetch next mbuf & desc while processing current one */
cqd_ptr = (struct cq_desc *)(cq->ring.descs) + cq_idx;
@@ -419,6 +417,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
first_seg->packet_type =
enic_cq_rx_flags_to_pkt_type(&cqd, tnl);
enic_cq_rx_to_pkt_flags(&cqd, first_seg);
+
/* Wipe the outer types set by enic_cq_rx_flags_to_pkt_type() */
if (tnl) {
first_seg->packet_type &= ~(RTE_PTYPE_L3_MASK |
@@ -438,6 +437,10 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
/* store the mbuf address into the next entry of the array */
rx_pkts[nb_rx++] = first_seg;
}
+   if (unlikely(cq_idx == cq->ring.desc_count)) {
+   cq_idx = 0;
+   cq->last_color ^= CQ_DESC_COLOR_MASK_NOSHIFT;
+   }
 
sop_rq->pkt_first_seg = first_seg;
sop_rq->pkt_last_seg = last_seg;
-- 
2.16.2



[dpdk-dev] [PATCH 13/14] net/enic: add simple Rx handler

2018-06-27 Thread John Daley
Add an optimized Rx handler for non-scattered Rx.

Signed-off-by: Hyong Youb Kim 
Signed-off-by: John Daley 
---
 drivers/net/enic/base/cq_desc.h |   1 +
 drivers/net/enic/base/vnic_rq.h |   2 +
 drivers/net/enic/enic.h |   2 +
 drivers/net/enic/enic_ethdev.c  |   3 +-
 drivers/net/enic/enic_main.c|  36 -
 drivers/net/enic/enic_res.h |   1 +
 drivers/net/enic/enic_rxtx.c| 114 
 7 files changed, 156 insertions(+), 3 deletions(-)

diff --git a/drivers/net/enic/base/cq_desc.h b/drivers/net/enic/base/cq_desc.h
index 7e1380270..ae8847c6d 100644
--- a/drivers/net/enic/base/cq_desc.h
+++ b/drivers/net/enic/base/cq_desc.h
@@ -38,6 +38,7 @@ struct cq_desc {
 #define CQ_DESC_TYPE_MASK((1 << CQ_DESC_TYPE_BITS) - 1)
 #define CQ_DESC_COLOR_MASK   1
 #define CQ_DESC_COLOR_SHIFT  7
+#define CQ_DESC_COLOR_MASK_NOSHIFT 0x80
 #define CQ_DESC_Q_NUM_BITS   10
 #define CQ_DESC_Q_NUM_MASK   ((1 << CQ_DESC_Q_NUM_BITS) - 1)
 #define CQ_DESC_COMP_NDX_BITS12
diff --git a/drivers/net/enic/base/vnic_rq.h b/drivers/net/enic/base/vnic_rq.h
index 9619290de..d8e67f747 100644
--- a/drivers/net/enic/base/vnic_rq.h
+++ b/drivers/net/enic/base/vnic_rq.h
@@ -52,6 +52,8 @@ struct vnic_rq {
struct vnic_dev *vdev;
struct vnic_rq_ctrl __iomem *ctrl;  /* memory-mapped */
struct vnic_dev_ring ring;
+   struct rte_mbuf **free_mbufs;   /* reserve of free mbufs */
+   int num_free_mbufs;
struct rte_mbuf **mbuf_ring;/* array of allocated mbufs */
unsigned int mbuf_next_idx; /* next mb to consume */
void *os_buf_head;
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index e1d0ea552..d0ffc7783 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -314,6 +314,8 @@ int enic_clsf_init(struct enic *enic);
 void enic_clsf_destroy(struct enic *enic);
 uint16_t enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
+uint16_t enic_noscatter_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts);
 uint16_t enic_dummy_recv_pkts(void *rx_queue,
  struct rte_mbuf **rx_pkts,
  uint16_t nb_pkts);
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index d01f9..0d63cb466 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -525,7 +525,8 @@ static const uint32_t 
*enicpmd_dev_supported_ptypes_get(struct rte_eth_dev *dev)
RTE_PTYPE_UNKNOWN
};
 
-   if (dev->rx_pkt_burst == enic_recv_pkts)
+   if (dev->rx_pkt_burst == enic_recv_pkts ||
+   dev->rx_pkt_burst == enic_noscatter_recv_pkts)
return ptypes;
return NULL;
 }
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 66706448c..0651ed95f 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -572,6 +572,14 @@ int enic_enable(struct enic *enic)
eth_dev->tx_pkt_burst = &enic_xmit_pkts;
}
 
+   /* Use the non-scatter, simplified RX handler if possible. */
+   if (enic->rq_count > 0 && enic->rq[0].data_queue_enable == 0) {
+   PMD_INIT_LOG(DEBUG, " use the non-scatter Rx handler");
+   eth_dev->rx_pkt_burst = &enic_noscatter_recv_pkts;
+   } else {
+   PMD_INIT_LOG(DEBUG, " use the normal Rx handler");
+   }
+
for (index = 0; index < enic->wq_count; index++)
enic_start_wq(enic, index);
for (index = 0; index < enic->rq_count; index++)
@@ -624,6 +632,19 @@ void enic_free_rq(void *rxq)
enic = vnic_dev_priv(rq_sop->vdev);
rq_data = &enic->rq[rq_sop->data_queue_idx];
 
+   if (rq_sop->free_mbufs) {
+   struct rte_mbuf **mb;
+   int i;
+
+   mb = rq_sop->free_mbufs;
+   for (i = ENIC_RX_BURST_MAX - rq_sop->num_free_mbufs;
+i < ENIC_RX_BURST_MAX; i++)
+   rte_pktmbuf_free(mb[i]);
+   rte_free(rq_sop->free_mbufs);
+   rq_sop->free_mbufs = NULL;
+   rq_sop->num_free_mbufs = 0;
+   }
+
enic_rxmbuf_queue_release(enic, rq_sop);
if (rq_data->in_use)
enic_rxmbuf_queue_release(enic, rq_data);
@@ -787,13 +808,13 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
rq_data->max_mbufs_per_pkt = mbufs_per_pkt;
 
if (mbufs_per_pkt > 1) {
-   min_sop = 64;
+   min_sop = ENIC_RX_BURST_MAX;
max_sop = ((enic->config.rq_desc_count /
(mbufs_per_pkt - 1)) & ENIC_ALIGN_DESCS_MASK);
min_data

  1   2   3   4   >