DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 1/4] net/enic: fix fdir usage with scattered Rx
@ 2016-09-29 20:56 John Daley
  2016-09-29 20:56 ` [dpdk-dev] [PATCH 2/4] net/enic: fix segfault when restarting with fdir filters John Daley
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: John Daley @ 2016-09-29 20:56 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, John Daley

The wrong queue id was being used in the enic
flow director code after the scattered Rx feature
was added.

Fixes: 856d7ba7ed22 ("net/enic: support scattered Rx")

Signed-off-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/enic_clsf.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/enic/enic_clsf.c b/drivers/net/enic/enic_clsf.c
index e6f57be..b251b7f 100644
--- a/drivers/net/enic/enic_clsf.c
+++ b/drivers/net/enic/enic_clsf.c
@@ -120,7 +120,9 @@ int enic_fdir_add_fltr(struct enic *enic, struct rte_eth_fdir_filter *params)
 		return -ENOTSUP;
 	}
 
-	queue = params->action.rx_queue;
+	/* Get the enicpmd RQ from the DPDK Rx queue */
+	queue = enic_sop_rq(params->action.rx_queue);
+
 	/* See if the key is already there in the table */
 	pos = rte_hash_del_key(enic->fdir.hash, params);
 	switch (pos) {
-- 
2.10.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH 2/4] net/enic: fix segfault when restarting with fdir filters
  2016-09-29 20:56 [dpdk-dev] [PATCH 1/4] net/enic: fix fdir usage with scattered Rx John Daley
@ 2016-09-29 20:56 ` John Daley
  2016-09-29 20:56 ` [dpdk-dev] [PATCH 3/4] net/enic: update VIC interface file John Daley
  2016-09-29 20:56 ` [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300 series adapters John Daley
  2 siblings, 0 replies; 10+ messages in thread
From: John Daley @ 2016-09-29 20:56 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, John Daley

When flow director filters where removed when an enic device is
stopped, the filters were freed but the pointer was not set to
NULL so the next stop would try to free them again.

Fixes: fefed3d1e62c ("enic: new driver")

Signed-off-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/enic_clsf.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/enic/enic_clsf.c b/drivers/net/enic/enic_clsf.c
index b251b7f..111b194 100644
--- a/drivers/net/enic/enic_clsf.c
+++ b/drivers/net/enic/enic_clsf.c
@@ -240,6 +240,7 @@ void enic_clsf_destroy(struct enic *enic)
 			vnic_dev_classifier(enic->vdev, CLSF_DEL,
 				&key->fltr_id, NULL);
 			rte_free(key);
+			enic->fdir.nodes[index] = NULL;
 		}
 	}
 
-- 
2.10.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH 3/4] net/enic: update VIC interface file
  2016-09-29 20:56 [dpdk-dev] [PATCH 1/4] net/enic: fix fdir usage with scattered Rx John Daley
  2016-09-29 20:56 ` [dpdk-dev] [PATCH 2/4] net/enic: fix segfault when restarting with fdir filters John Daley
@ 2016-09-29 20:56 ` John Daley
  2016-09-29 20:56 ` [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300 series adapters John Daley
  2 siblings, 0 replies; 10+ messages in thread
From: John Daley @ 2016-09-29 20:56 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, John Daley

Update the VIC adapter file which is common with the firmware and
other VIC drivers. This is needed to support new capabilities
for 1300 adapters, including advanced filtering, which is available
in VIC firmware version 2.0(13) for UCS rack and 3.1(2).

Signed-off-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/base/vnic_devcmd.h | 346 ++++++++++++++++++++++++++++++++----
 1 file changed, 308 insertions(+), 38 deletions(-)

diff --git a/drivers/net/enic/base/vnic_devcmd.h b/drivers/net/enic/base/vnic_devcmd.h
index b3d5a6c..785fd6f 100644
--- a/drivers/net/enic/base/vnic_devcmd.h
+++ b/drivers/net/enic/base/vnic_devcmd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2010 Cisco Systems, Inc.  All rights reserved.
+ * Copyright 2008-2016 Cisco Systems, Inc.  All rights reserved.
  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
  *
  * Copyright (c) 2014, Cisco Systems, Inc.
@@ -126,7 +126,8 @@ enum vnic_devcmd_cmd {
 
 	/* dev-specific block member:
 	 *    in: (u16)a0=offset,(u8)a1=size
-	 *    out: a0=value */
+	 *    out: a0=value
+	 */
 	CMD_DEV_SPEC            = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 2),
 
 	/* stats clear */
@@ -146,8 +147,9 @@ enum vnic_devcmd_cmd {
 	CMD_HANG_NOTIFY         = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8),
 
 	/* MAC address in (u48)a0 */
-	CMD_GET_MAC_ADDR	= _CMDC(_CMD_DIR_READ,
+	CMD_MAC_ADDR            = _CMDC(_CMD_DIR_READ,
 					_CMD_VTYPE_ENET | _CMD_VTYPE_FC, 9),
+#define CMD_GET_MAC_ADDR CMD_MAC_ADDR   /* some uses are aliased */
 
 	/* add addr from (u48)a0 */
 	CMD_ADDR_ADD            = _CMDCNW(_CMD_DIR_WRITE,
@@ -387,9 +389,8 @@ enum vnic_devcmd_cmd {
 	 * Subvnic migration from MQ <--> VF.
 	 * Enable the LIF migration from MQ to VF and vice versa. MQ and VF
 	 * indexes are statically bound at the time of initialization.
-	 * Based on the
-	 * direction of migration, the resources of either MQ or the VF shall
-	 * be attached to the LIF.
+	 * Based on the direction of migration, the resources of either MQ or
+	 * the VF shall be attached to the LIF.
 	 * in:        (u32)a0=Direction of Migration
 	 *					0=> Migrate to VF
 	 *					1=> Migrate to MQ
@@ -397,7 +398,6 @@ enum vnic_devcmd_cmd {
 	 */
 	CMD_MIGRATE_SUBVNIC = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 53),
 
-
 	/*
 	 * Register / Deregister the notification block for MQ subvnics
 	 * in:
@@ -433,6 +433,10 @@ enum vnic_devcmd_cmd {
 	 * in: (u64) a0= filter address
 	 *     (u32) a1= size of filter
 	 * out: (u32) a0=filter identifier
+	 *
+	 * Capability query:
+	 * out: (u64) a0= 1 if capability query supported
+	 *      (u64) a1= MAX filter type supported
 	 */
 	CMD_ADD_FILTER = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 58),
 
@@ -471,23 +475,133 @@ enum vnic_devcmd_cmd {
 	CMD_QP_STATS_CLEAR = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 63),
 
 	/*
-	 * Enable/Disable overlay offloads on the given vnic
+	 * UEFI BOOT API: (u64)a0= UEFI FLS_CMD_xxx
+	 * (ui64)a1= paddr for the info buffer
+	 */
+	CMD_FC_REQ = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_FC, 64),
+
+	/*
+	 * Return the iSCSI config details required by the EFI Option ROM
+	 * in:  (u32) a0=0 Get Boot Info for PXE eNIC as per pxe_boot_config_t
+	 *            a0=1 Get Boot info for iSCSI enic as per
+	 *            iscsi_boot_efi_cfg_t
+	 * in:  (u64) a1=Host address where iSCSI config info is returned
+	 */
+	CMD_VNIC_BOOT_CONFIG_INFO = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 65),
+
+	/*
+	 * Create a Queue Pair (RoCE)
+	 * in: (u32) a0 = Queue Pair number
+	 *     (u32) a1 = Remote QP
+	 *     (u32) a2 = RDMA-RQ
+	 *     (u16) a3 = RQ Res Group
+	 *     (u16) a4 = SQ Res Group
+	 *     (u32) a5 = Protection Domain
+	 *     (u64) a6 = Remote MAC
+	 *     (u32) a7 = start PSN
+	 *     (u16) a8 = MSS
+	 *     (u32) a9 = protocol version
+	 */
+	CMD_RDMA_QP_CREATE = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 66),
+
+	/*
+	 * Delete a Queue Pair (RoCE)
+	 * in: (u32) a0 = Queue Pair number
+	 */
+	CMD_RDMA_QP_DELETE = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 67),
+
+	/*
+	 * Retrieve a Queue Pair's status information (RoCE)
+	 * in: (u32) a0 = Queue Pair number
+	 *     (u64) a1 = host buffer addr for QP status struct
+	 *     (u32) a2 = length of the buffer
+	 */
+	CMD_RDMA_QP_STATUS = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 68),
+
+	/*
+	 * Use this devcmd for agreeing on the highest common version supported
+	 * by both driver and fw for by features who need such a facility.
+	 *  in:  (u64) a0 = feature (driver requests for the supported versions
+	 *                  on this feature)
+	 *  out: (u64) a0 = bitmap of all supported versions for that feature
+	 */
+	CMD_GET_SUPP_FEATURE_VER = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 69),
+
+	/*
+	 * Initialize the RDMA notification work queue
+	 * in: (u64) a0 = host buffer address
+	 * in: (u16) a1 = number of entries in buffer
+	 * in: (u16) a2 = resource group number
+	 * in: (u16) a3 = CQ number to post completion
+	 */
+	CMD_RDMA_INIT_INFO_BUF = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 70),
+
+	/*
+	 * De-init the RDMA notification work queue
+	 * in: (u64) a0=resource group number
+	 */
+	CMD_RDMA_DEINIT_INFO_BUF = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 71),
+
+	/*
+	 * Control (Enable/Disable) overlay offloads on the given vnic
 	 * in: (u8) a0 = OVERLAY_FEATURE_NVGRE : NVGRE
 	 *          a0 = OVERLAY_FEATURE_VXLAN : VxLAN
-	 * in: (u8) a1 = OVERLAY_OFFLOAD_ENABLE : Enable
-	 *          a1 = OVERLAY_OFFLOAD_DISABLE : Disable
+	 * in: (u8) a1 = OVERLAY_OFFLOAD_ENABLE : Enable or
+	 *          a1 = OVERLAY_OFFLOAD_DISABLE : Disable or
+	 *          a1 = OVERLAY_OFFLOAD_ENABLE_V2 : Enable with version 2
 	 */
-	CMD_OVERLAY_OFFLOAD_ENABLE_DISABLE =
-		_CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 72),
+	CMD_OVERLAY_OFFLOAD_CTRL =
+				_CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 72),
 
 	/*
 	 * Configuration of overlay offloads feature on a given vNIC
-	 * in: (u8) a0 = DEVCMD_OVERLAY_NVGRE : NVGRE
-	 *          a0 = DEVCMD_OVERLAY_VXLAN : VxLAN
-	 * in: (u8) a1 = VXLAN_PORT_UPDATE : VxLAN
-	 * in: (u16) a2 = unsigned short int port information
+	 * in: (u8) a0 = OVERLAY_CFG_VXLAN_PORT_UPDATE : VxLAN
+	 * in: (u16) a1 = unsigned short int port information
 	 */
 	CMD_OVERLAY_OFFLOAD_CFG = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 73),
+
+	/*
+	 * Return the configured name for the device
+	 * in: (u64) a0=Host address where the name is copied
+	 *     (u32) a1=Size of the buffer
+	 */
+	CMD_GET_CONFIG_NAME = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 74),
+
+	/*
+	 * Enable group interrupt for the VF
+	 * in: (u32) a0 = GRPINTR_ENABLE : enable
+	 *           a0 = GRPINTR_DISABLE : disable
+	 *           a0 = GRPINTR_UPD_VECT: update group vector addr
+	 * in: (u32) a1 = interrupt group count
+	 * in: (u64) a2 = Start of host buffer address for DMAing group
+	 *           vector bitmap
+	 * in: (u64) a3 = Stride between group vectors
+	 */
+	CMD_CONFIG_GRPINTR = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 75),
+
+	/*
+	 * Set cq arrary base and size in a list of consective wqs and
+	 * rqs for a device
+	 * in: (u16) a0 = the wq relative index in the device.
+	 *		-1 indicates skipping wq configuration
+	 * in: (u16) a1 = the wcq relative index in the device
+	 * in: (u16) a2 = the rq relative index in the device
+	 *		-1 indicates skipping rq configuration
+	 * in: (u16) a3 = the rcq relative index in the device
+	 */
+	CMD_CONFIG_CQ_ARRAY = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 76),
+
+	/*
+	 * Add an advanced filter.
+	 * in: (u64) a0= filter address
+	 *     (u32) a1= size of filter
+	 * out: (u32) a0=filter identifier
+	 *
+	 * Capability query:
+	 * out: (u64) a0= 1 if capabliity query supported
+	 *      (u64) a1= MAX filter type supported
+	 */
+	CMD_ADD_ADV_FILTER = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 77),
 };
 
 /* CMD_ENABLE2 flags */
@@ -520,6 +634,9 @@ enum vnic_devcmd_status {
 	STAT_NONE = 0,
 	STAT_BUSY = 1 << 0,	/* cmd in progress */
 	STAT_ERROR = 1 << 1,	/* last cmd caused error (code in a0) */
+	STAT_FAILOVER = 1 << 2, /* always set on vnics in pci standby state
+				 * if seen a failover to the standby happened
+				 */
 };
 
 enum vnic_devcmd_error {
@@ -558,9 +675,9 @@ enum fwinfo_asic_type {
 	FWINFO_ASIC_TYPE_UNKNOWN,
 	FWINFO_ASIC_TYPE_PALO,
 	FWINFO_ASIC_TYPE_SERENO,
+	FWINFO_ASIC_TYPE_CRUZ,
 };
 
-
 struct vnic_devcmd_notify {
 	u32 csum;		/* checksum over following words */
 
@@ -595,25 +712,16 @@ struct vnic_devcmd_provinfo {
  */
 #define FILTER_FIELD_VALID(fld) (1 << (fld - 1))
 
-#define FILTER_FIELDS_USNIC (FILTER_FIELD_VALID(1) | \
-			     FILTER_FIELD_VALID(2) | \
-			     FILTER_FIELD_VALID(3) | \
-			     FILTER_FIELD_VALID(4))
-
-#define FILTER_FIELDS_IPV4_5TUPLE (FILTER_FIELD_VALID(1) | \
-				   FILTER_FIELD_VALID(2) | \
-				   FILTER_FIELD_VALID(3) | \
-				   FILTER_FIELD_VALID(4) | \
-				   FILTER_FIELD_VALID(5))
-
-#define FILTER_FIELDS_MAC_VLAN (FILTER_FIELD_VALID(1) | \
-				FILTER_FIELD_VALID(2))
-
 #define FILTER_FIELD_USNIC_VLAN    FILTER_FIELD_VALID(1)
 #define FILTER_FIELD_USNIC_ETHTYPE FILTER_FIELD_VALID(2)
 #define FILTER_FIELD_USNIC_PROTO   FILTER_FIELD_VALID(3)
 #define FILTER_FIELD_USNIC_ID      FILTER_FIELD_VALID(4)
 
+#define FILTER_FIELDS_USNIC (FILTER_FIELD_USNIC_VLAN | \
+			     FILTER_FIELD_USNIC_ETHTYPE | \
+			     FILTER_FIELD_USNIC_PROTO | \
+			     FILTER_FIELD_USNIC_ID)
+
 struct filter_usnic_id {
 	u32 flags;
 	u16 vlan;
@@ -628,10 +736,18 @@ struct filter_usnic_id {
 #define FILTER_FIELD_5TUP_SRC_PT FILTER_FIELD_VALID(4)
 #define FILTER_FIELD_5TUP_DST_PT FILTER_FIELD_VALID(5)
 
+#define FILTER_FIELDS_IPV4_5TUPLE (FILTER_FIELD_5TUP_PROTO | \
+				   FILTER_FIELD_5TUP_SRC_AD | \
+				   FILTER_FIELD_5TUP_DST_AD | \
+				   FILTER_FIELD_5TUP_SRC_PT | \
+				   FILTER_FIELD_5TUP_DST_PT)
+
 /* Enums for the protocol field. */
 enum protocol_e {
 	PROTO_UDP = 0,
 	PROTO_TCP = 1,
+	PROTO_IPV4 = 2,
+	PROTO_IPV6 = 3
 };
 
 struct filter_ipv4_5tuple {
@@ -646,12 +762,78 @@ struct filter_ipv4_5tuple {
 #define FILTER_FIELD_VMQ_VLAN   FILTER_FIELD_VALID(1)
 #define FILTER_FIELD_VMQ_MAC    FILTER_FIELD_VALID(2)
 
+#define FILTER_FIELDS_MAC_VLAN (FILTER_FIELD_VMQ_VLAN | \
+				FILTER_FIELD_VMQ_MAC)
+
+#define FILTER_FIELDS_NVGRE    FILTER_FIELD_VMQ_MAC
+
 struct filter_mac_vlan {
 	u32 flags;
 	u16 vlan;
 	u8 mac_addr[6];
 } __attribute__((packed));
 
+#define FILTER_FIELD_VLAN_IP_3TUP_VLAN      FILTER_FIELD_VALID(1)
+#define FILTER_FIELD_VLAN_IP_3TUP_L3_PROTO  FILTER_FIELD_VALID(2)
+#define FILTER_FIELD_VLAN_IP_3TUP_DST_AD    FILTER_FIELD_VALID(3)
+#define FILTER_FIELD_VLAN_IP_3TUP_L4_PROTO  FILTER_FIELD_VALID(4)
+#define FILTER_FIELD_VLAN_IP_3TUP_DST_PT    FILTER_FIELD_VALID(5)
+
+#define FILTER_FIELDS_VLAN_IP_3TUP (FILTER_FIELD_VLAN_IP_3TUP_VLAN | \
+				    FILTER_FIELD_VLAN_IP_3TUP_L3_PROTO | \
+				    FILTER_FIELD_VLAN_IP_3TUP_DST_AD | \
+				    FILTER_FIELD_VLAN_IP_3TUP_L4_PROTO | \
+				    FILTER_FIELD_VLAN_IP_3TUP_DST_PT)
+
+struct filter_vlan_ip_3tuple {
+	u32 flags;
+	u16 vlan;
+	u16 l3_protocol;
+	union {
+		u32 dst_addr_v4;
+		u8 dst_addr_v6[16];
+	} u;
+	u32 l4_protocol;
+	u16 dst_port;
+} __attribute__((packed));
+
+#define FILTER_GENERIC_1_BYTES 64
+
+enum filter_generic_1_layer {
+	FILTER_GENERIC_1_L2,
+	FILTER_GENERIC_1_L3,
+	FILTER_GENERIC_1_L4,
+	FILTER_GENERIC_1_L5,
+	FILTER_GENERIC_1_NUM_LAYERS
+};
+
+#define FILTER_GENERIC_1_IPV4       (1 << 0)
+#define FILTER_GENERIC_1_IPV6       (1 << 1)
+#define FILTER_GENERIC_1_UDP        (1 << 2)
+#define FILTER_GENERIC_1_TCP        (1 << 3)
+#define FILTER_GENERIC_1_TCP_OR_UDP (1 << 4)
+#define FILTER_GENERIC_1_IP4SUM_OK  (1 << 5)
+#define FILTER_GENERIC_1_L4SUM_OK   (1 << 6)
+#define FILTER_GENERIC_1_IPFRAG     (1 << 7)
+
+#define FILTER_GENERIC_1_KEY_LEN 64
+
+/*
+ * Version 1 of generic filter specification
+ * position is only 16 bits, reserving positions > 64k to be used by firmware
+ */
+struct filter_generic_1 {
+	u16 position;       /* lower position comes first */
+	u32 mask_flags;
+	u32 val_flags;
+	u16 mask_vlan;
+	u16 val_vlan;
+	struct {
+		u8 mask[FILTER_GENERIC_1_KEY_LEN]; /* 0 bit means "don't care"*/
+		u8 val[FILTER_GENERIC_1_KEY_LEN];
+	} __attribute__((packed)) layer[FILTER_GENERIC_1_NUM_LAYERS];
+} __attribute__((packed));
+
 /* Specifies the filter_action type. */
 enum {
 	FILTER_ACTION_RQ_STEERING = 0,
@@ -670,6 +852,10 @@ enum filter_type {
 	FILTER_USNIC_ID = 0,
 	FILTER_IPV4_5TUPLE = 1,
 	FILTER_MAC_VLAN = 2,
+	FILTER_VLAN_IP_3TUPLE = 3,
+	FILTER_NVGRE_VMQ = 4,
+	FILTER_USNIC_IP = 5,
+	FILTER_DPDK_1 = 6,
 	FILTER_MAX
 };
 
@@ -679,6 +865,27 @@ struct filter {
 		struct filter_usnic_id usnic;
 		struct filter_ipv4_5tuple ipv4;
 		struct filter_mac_vlan mac_vlan;
+		struct filter_vlan_ip_3tuple vlan_3tuple;
+	} u;
+} __attribute__((packed));
+
+/*
+ * This is a strict superset of "struct filter" and exists only
+ * because many drivers use "sizeof (struct filter)" in deciding TLV size.
+ * This new, larger struct filter would cause any code that uses that method
+ * to not work with older firmware, so we add filter_v2 to hold the
+ * new filter types.  Drivers should use vnic_filter_size() to determine
+ * the TLV size instead of sizeof (struct fiter_v2) to guard against future
+ * growth.
+ */
+struct filter_v2 {
+	u32 type;
+	union {
+		struct filter_usnic_id usnic;
+		struct filter_ipv4_5tuple ipv4;
+		struct filter_mac_vlan mac_vlan;
+		struct filter_vlan_ip_3tuple vlan_3tuple;
+		struct filter_generic_1 generic_1;
 	} u;
 } __attribute__((packed));
 
@@ -687,14 +894,55 @@ enum {
 	CLSF_TLV_ACTION = 1,
 };
 
-#define FILTER_MAX_BUF_SIZE 100  /* Maximum size of buffer to CMD_ADD_FILTER */
-
 struct filter_tlv {
-	uint32_t type;
-	uint32_t length;
-	uint32_t val[0];
+	u_int32_t type;
+	u_int32_t length;
+	u_int32_t val[0];
 };
 
+/* Data for CMD_ADD_FILTER is 2 TLV and filter + action structs */
+#define FILTER_MAX_BUF_SIZE 100
+#define FILTER_V2_MAX_BUF_SIZE (sizeof(struct filter_v2) + \
+	sizeof(struct filter_action) + \
+	(2 * sizeof(struct filter_tlv)))
+
+/*
+ * Compute actual structure size given filter type.  To be "future-proof,"
+ * drivers should use this instead of "sizeof (struct filter_v2)" when
+ * computing length for TLV.
+ */
+static inline u_int32_t
+vnic_filter_size(struct filter_v2 *fp)
+{
+	u_int32_t size;
+
+	switch (fp->type) {
+	case FILTER_USNIC_ID:
+		size = sizeof(fp->u.usnic);
+		break;
+	case FILTER_IPV4_5TUPLE:
+		size = sizeof(fp->u.ipv4);
+		break;
+	case FILTER_MAC_VLAN:
+	case FILTER_NVGRE_VMQ:
+		size = sizeof(fp->u.mac_vlan);
+		break;
+	case FILTER_VLAN_IP_3TUPLE:
+		size = sizeof(fp->u.vlan_3tuple);
+		break;
+	case FILTER_USNIC_IP:
+	case FILTER_DPDK_1:
+		size = sizeof(fp->u.generic_1);
+		break;
+	default:
+		size = sizeof(fp->u);
+		break;
+	}
+	size += sizeof(fp->type);
+	return size;
+}
+
+
 enum {
 	CLSF_ADD = 0,
 	CLSF_DEL = 1,
@@ -766,8 +1014,30 @@ typedef enum {
 	OVERLAY_FEATURE_MAX,
 } overlay_feature_t;
 
-#define OVERLAY_OFFLOAD_ENABLE 0
-#define OVERLAY_OFFLOAD_DISABLE 1
+#define OVERLAY_OFFLOAD_ENABLE          0
+#define OVERLAY_OFFLOAD_DISABLE         1
+#define OVERLAY_OFFLOAD_ENABLE_V2       2
 
 #define OVERLAY_CFG_VXLAN_PORT_UPDATE 0
+
+/*
+ * Use this enum to get the supported versions for each of these features
+ * If you need to use the devcmd_get_supported_feature_version(), add
+ * the new feature into this enum and install function handler in devcmd.c
+ */
+typedef enum {
+	VIC_FEATURE_VXLAN,
+	VIC_FEATURE_RDMA,
+	VIC_FEATURE_MAX,
+} vic_feature_t;
+
+/*
+ * CMD_CONFIG_GRPINTR subcommands
+ */
+typedef enum {
+	GRPINTR_ENABLE = 1,
+	GRPINTR_DISABLE,
+	GRPINTR_UPD_VECT,
+} grpintr_subcmd_t;
+
 #endif /* _VNIC_DEVCMD_H_ */
-- 
2.10.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300 series adapters
  2016-09-29 20:56 [dpdk-dev] [PATCH 1/4] net/enic: fix fdir usage with scattered Rx John Daley
  2016-09-29 20:56 ` [dpdk-dev] [PATCH 2/4] net/enic: fix segfault when restarting with fdir filters John Daley
  2016-09-29 20:56 ` [dpdk-dev] [PATCH 3/4] net/enic: update VIC interface file John Daley
@ 2016-09-29 20:56 ` John Daley
  2016-10-11  9:22   ` Ferruh Yigit
  2 siblings, 1 reply; 10+ messages in thread
From: John Daley @ 2016-09-29 20:56 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, John Daley

1300 series Cisco adapter firmware version 2.0(13) for UCS
C-series servers and 3.1(2) for blade servers supports more
filtering capabilities. The feature can be enabled via Cisco
CIMC or USCM with the 'advanced filters' radio button. When
enabled, the these additional flow director modes are available:
	RTE_ETH_FLOW_NONFRAG_IPV4_OTHER
	RTE_ETH_FLOW_NONFRAG_IPV4_SCTP
	RTE_ETH_FLOW_NONFRAG_IPV6_UDP
	RTE_ETH_FLOW_NONFRAG_IPV6_TCP
	RTE_ETH_FLOW_NONFRAG_IPV6_SCTP
	RTE_ETH_FLOW_NONFRAG_IPV6_OTHER

Changes:
- Detect and set an 'advanced filters' flag dependent on the adapter
  capability.
- Implement RTE_ETH_FILTER_INFO filter op to return the flow types
  available dependent on whether advanced filters are enabled.
- Use a function pointer to select how filters are added to the adapter:
  copy_fltr_v1() for older firmware/adapters or copy_fltr_v2() for
  adapters which support advanced filters.
- Apply fdir global masks to filters when in advanced filter mode.
- Update documentation.

Signed-off-by: John Daley <johndale@cisco.com>
Reviewed-by: Nelson Escobar <neescoba@cisco.com>
---
 doc/guides/nics/enic.rst          |  30 +++-
 doc/guides/nics/features/enic.ini |   1 +
 drivers/net/enic/base/vnic_dev.c  |  33 ++++-
 drivers/net/enic/base/vnic_dev.h  |   3 +-
 drivers/net/enic/enic.h           |  13 ++
 drivers/net/enic/enic_clsf.c      | 292 +++++++++++++++++++++++++++++++++++---
 drivers/net/enic/enic_ethdev.c    |   4 +-
 drivers/net/enic/enic_main.c      |   3 +
 drivers/net/enic/enic_res.c       |   5 +
 9 files changed, 351 insertions(+), 33 deletions(-)

diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index bff5c77..c535b58 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -122,6 +122,24 @@ Configuration information
     uses this interrupt to get information about link status and errors
     in the fast path.
 
+.. _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 feilds 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.
+
 Limitations
 -----------
 
@@ -145,6 +163,12 @@ Limitations
      vlan_offload |= ETH_VLAN_STRIP_OFFLOAD;
      rte_eth_dev_set_vlan_offload(port, vlan_offload);
 
+- 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)
+
 How to build the suite?
 -----------------------
 The build instructions for the DPDK suite should be followed. By default
@@ -170,9 +194,6 @@ ENIC PMD supports all recent generations of Cisco VIC adapters including:
 - VIC 1385
 - VIC 1387
 
-- Flow director features are not supported on generation 1 Cisco VIC adapters
-   (M81KR and P81E)
-
 Supported Operating Systems
 ---------------------------
 Any Linux distribution fulfilling the conditions described in Dependencies
@@ -187,8 +208,7 @@ Supported features
 - IP checksum offload
 - Receive side VLAN stripping
 - Multiple receive and transmit queues
-- Flow Director ADD, UPDATE, DELETE, STATS operation support for IPV4 5-TUPLE
-  flows
+- 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)
diff --git a/doc/guides/nics/features/enic.ini b/doc/guides/nics/features/enic.ini
index 7d3f801..523d4f1 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -17,6 +17,7 @@ RSS hash             = Y
 VLAN filter          = Y
 CRC offload          = Y
 VLAN offload         = Y
+Flow director        = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
 Packet type parsing  = Y
diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index 4db21a4..84e4840 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -470,6 +470,18 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	}
 }
 
+int vnic_dev_capable_adv_filters(struct vnic_dev *vdev)
+{
+	u64 a0 = (u32)CMD_ADD_ADV_FILTER, a1 = 0;
+	int wait = 1000;
+	int err;
+
+	err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
+	if (err)
+		return 0;
+	return (a1 >= (u32)FILTER_DPDK_1);
+}
+
 static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd)
 {
 	u64 a0 = (u32)cmd, a1 = 0;
@@ -1007,7 +1019,7 @@ int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
  * @data: filter data
  */
 int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry,
-	struct filter *data)
+	struct filter_v2 *data)
 {
 	u64 a0, a1;
 	int wait = 1000;
@@ -1016,11 +1028,20 @@ int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry,
 	struct filter_tlv *tlv, *tlv_va;
 	struct filter_action *action;
 	u64 tlv_size;
+	u32 filter_size;
 	static unsigned int unique_id;
 	char z_name[RTE_MEMZONE_NAMESIZE];
+	enum vnic_devcmd_cmd dev_cmd;
+
 
 	if (cmd == CLSF_ADD) {
-		tlv_size = sizeof(struct filter) +
+		if (data->type == FILTER_DPDK_1)
+			dev_cmd = CMD_ADD_ADV_FILTER;
+		else
+			dev_cmd = CMD_ADD_FILTER;
+
+		filter_size = vnic_filter_size(data);
+		tlv_size = filter_size +
 		    sizeof(struct filter_action) +
 		    2*sizeof(struct filter_tlv);
 		snprintf((char *)z_name, sizeof(z_name),
@@ -1034,12 +1055,12 @@ int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry,
 		a1 = tlv_size;
 		memset(tlv, 0, tlv_size);
 		tlv->type = CLSF_TLV_FILTER;
-		tlv->length = sizeof(struct filter);
-		*(struct filter *)&tlv->val = *data;
+		tlv->length = filter_size;
+		memcpy(&tlv->val, (void *)data, filter_size);
 
 		tlv = (struct filter_tlv *)((char *)tlv +
 					 sizeof(struct filter_tlv) +
-					 sizeof(struct filter));
+					 filter_size);
 
 		tlv->type = CLSF_TLV_ACTION;
 		tlv->length = sizeof(struct filter_action);
@@ -1047,7 +1068,7 @@ int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry,
 		action->type = FILTER_ACTION_RQ_STEERING;
 		action->u.rq_idx = *entry;
 
-		ret = vnic_dev_cmd(vdev, CMD_ADD_FILTER, &a0, &a1, wait);
+		ret = vnic_dev_cmd(vdev, dev_cmd, &a0, &a1, wait);
 		*entry = (u16)a0;
 		vdev->free_consistent(vdev->priv, tlv_size, tlv_va, tlv_pa);
 	} else if (cmd == CLSF_DEL) {
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 689442f..06ebd4c 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -134,6 +134,7 @@ void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf);
 void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev);
 int vnic_dev_fw_info(struct vnic_dev *vdev,
 	struct vnic_devcmd_fw_info **fw_info);
+int vnic_dev_capable_adv_filters(struct vnic_dev *vdev);
 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);
@@ -201,7 +202,7 @@ int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status);
 int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status);
 int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
 int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry,
-	struct filter *data);
+	struct filter_v2 *data);
 #ifdef ENIC_VXLAN
 int vnic_dev_overlay_offload_enable_disable(struct vnic_dev *vdev,
 	u8 overlay, u8 config);
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 17d6c05..4ea4e4a 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -92,6 +92,11 @@ struct enic_fdir {
 	struct rte_eth_fdir_stats stats;
 	struct rte_hash *hash;
 	struct enic_fdir_node *nodes[ENICPMD_FDIR_MAX];
+	u32 modes;
+	u32 types_mask;
+	void (*copy_fltr_fn)(struct filter_v2 *filt,
+			     struct rte_eth_fdir_input *input,
+			     struct rte_eth_fdir_masks *masks);
 };
 
 struct enic_soft_stats {
@@ -128,6 +133,7 @@ struct enic {
 	int link_status;
 	u8 hw_ip_checksum;
 	u16 max_mtu;
+	u16 adv_filters;
 
 	unsigned int flags;
 	unsigned int priv_flags;
@@ -283,4 +289,11 @@ uint16_t enic_xmit_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);
+void enic_fdir_info(struct enic *enic);
+void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info *stats);
+void copy_fltr_v1(struct filter_v2 *fltr, struct rte_eth_fdir_input *input,
+		  struct rte_eth_fdir_masks *masks);
+void copy_fltr_v2(__rte_unused struct filter_v2 *fltr,
+		  __rte_unused struct rte_eth_fdir_input *input,
+		  __rte_unused struct rte_eth_fdir_masks *masks);
 #endif /* _ENIC_H_ */
diff --git a/drivers/net/enic/enic_clsf.c b/drivers/net/enic/enic_clsf.c
index 111b194..04034c7 100644
--- a/drivers/net/enic/enic_clsf.c
+++ b/drivers/net/enic/enic_clsf.c
@@ -38,6 +38,11 @@
 #include <rte_malloc.h>
 #include <rte_hash.h>
 #include <rte_byteorder.h>
+#include <rte_ip.h>
+#include <rte_tcp.h>
+#include <rte_udp.h>
+#include <rte_sctp.h>
+#include <rte_eth_ctrl.h>
 
 #include "enic_compat.h"
 #include "enic.h"
@@ -67,6 +72,264 @@ void enic_fdir_stats_get(struct enic *enic, struct rte_eth_fdir_stats *stats)
 	*stats = enic->fdir.stats;
 }
 
+void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info *info)
+{
+	info->mode = enic->fdir.modes;
+	info->flow_types_mask[0] = enic->fdir.types_mask;
+}
+
+void enic_fdir_info(struct enic *enic)
+{
+	enic->fdir.modes = (u32)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 |
+					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP |
+					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER;
+		enic->fdir.copy_fltr_fn = copy_fltr_v2;
+	} else {
+		enic->fdir.copy_fltr_fn = copy_fltr_v1;
+	}
+}
+
+static void
+enic_set_layer(struct filter_generic_1 *gp, unsigned int flag,
+	       enum filter_generic_1_layer layer, void *mask, void *val,
+	       unsigned int len)
+{
+	gp->mask_flags |= flag;
+	gp->val_flags |= gp->mask_flags;
+	memcpy(gp->layer[layer].mask, mask, len);
+	memcpy(gp->layer[layer].val, val, len);
+}
+
+/* Copy Flow Director filter to a VIC ipv4 filter (for Cisco VICs
+ * without advanced filter support.
+ */
+void
+copy_fltr_v1(struct filter_v2 *fltr, struct rte_eth_fdir_input *input,
+	     __rte_unused struct rte_eth_fdir_masks *masks)
+{
+	fltr->type = FILTER_IPV4_5TUPLE;
+	fltr->u.ipv4.src_addr = rte_be_to_cpu_32(
+		input->flow.ip4_flow.src_ip);
+	fltr->u.ipv4.dst_addr = rte_be_to_cpu_32(
+		input->flow.ip4_flow.dst_ip);
+	fltr->u.ipv4.src_port = rte_be_to_cpu_16(
+		input->flow.udp4_flow.src_port);
+	fltr->u.ipv4.dst_port = rte_be_to_cpu_16(
+		input->flow.udp4_flow.dst_port);
+
+	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_TCP)
+		fltr->u.ipv4.protocol = PROTO_TCP;
+	else
+		fltr->u.ipv4.protocol = PROTO_UDP;
+
+	fltr->u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE;
+}
+
+/* Copy Flow Director filter to a VIC generic filter (requires advanced
+ * filter support.
+ */
+void
+copy_fltr_v2(struct filter_v2 *fltr, struct rte_eth_fdir_input *input,
+	     struct rte_eth_fdir_masks *masks)
+{
+	struct filter_generic_1 *gp = &fltr->u.generic_1;
+	int i;
+
+	RTE_ASSERT(enic->adv_filters);
+
+	fltr->type = FILTER_DPDK_1;
+	memset(gp, 0, sizeof(*gp));
+
+	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_UDP) {
+		struct udp_hdr udp_mask, udp_val;
+		memset(&udp_mask, 0, sizeof(udp_mask));
+		memset(&udp_val, 0, sizeof(udp_val));
+
+		if (input->flow.udp4_flow.src_port) {
+			udp_mask.src_port = masks->src_port_mask;
+			udp_val.src_port = input->flow.udp4_flow.src_port;
+		}
+		if (input->flow.udp4_flow.dst_port) {
+			udp_mask.src_port = masks->dst_port_mask;
+			udp_val.dst_port = input->flow.udp4_flow.dst_port;
+		}
+
+		enic_set_layer(gp, FILTER_GENERIC_1_UDP, FILTER_GENERIC_1_L4,
+			       &udp_mask, &udp_val, sizeof(struct udp_hdr));
+	} else if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_TCP) {
+		struct tcp_hdr tcp_mask, tcp_val;
+		memset(&tcp_mask, 0, sizeof(tcp_mask));
+		memset(&tcp_val, 0, sizeof(tcp_val));
+
+		if (input->flow.tcp4_flow.src_port) {
+			tcp_mask.src_port = masks->src_port_mask;
+			tcp_val.src_port = input->flow.tcp4_flow.src_port;
+		}
+		if (input->flow.tcp4_flow.dst_port) {
+			tcp_mask.dst_port = masks->dst_port_mask;
+			tcp_val.dst_port = input->flow.tcp4_flow.dst_port;
+		}
+
+		enic_set_layer(gp, FILTER_GENERIC_1_TCP, FILTER_GENERIC_1_L4,
+			       &tcp_mask, &tcp_val, sizeof(struct tcp_hdr));
+	} else if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) {
+		struct sctp_hdr sctp_mask, sctp_val;
+		memset(&sctp_mask, 0, sizeof(sctp_mask));
+		memset(&sctp_val, 0, sizeof(sctp_val));
+
+		if (input->flow.sctp4_flow.src_port) {
+			sctp_mask.src_port = masks->src_port_mask;
+			sctp_val.src_port = input->flow.sctp4_flow.src_port;
+		}
+		if (input->flow.sctp4_flow.dst_port) {
+			sctp_mask.dst_port = masks->dst_port_mask;
+			sctp_val.dst_port = input->flow.sctp4_flow.dst_port;
+		}
+		if (input->flow.sctp4_flow.verify_tag) {
+			sctp_mask.tag = 0xffffffff;
+			sctp_val.tag = input->flow.sctp4_flow.verify_tag;
+		}
+
+		/* v4 proto should be 132, override ip4_flow.proto */
+		input->flow.ip4_flow.proto = 132;
+
+		enic_set_layer(gp, 0, FILTER_GENERIC_1_L4, &sctp_mask,
+			       &sctp_val, sizeof(struct sctp_hdr));
+	}
+
+	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_UDP ||
+	    input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_TCP ||
+	    input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_SCTP ||
+	    input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) {
+		struct ipv4_hdr ip4_mask, ip4_val;
+		memset(&ip4_mask, 0, sizeof(struct ipv4_hdr));
+		memset(&ip4_val, 0, sizeof(struct ipv4_hdr));
+
+		if (input->flow.ip4_flow.tos) {
+			ip4_mask.type_of_service = 0xff;
+			ip4_val.type_of_service = input->flow.ip4_flow.tos;
+		}
+		if (input->flow.ip4_flow.ttl) {
+			ip4_mask.time_to_live = 0xff;
+			ip4_val.time_to_live = input->flow.ip4_flow.ttl;
+		}
+		if (input->flow.ip4_flow.proto) {
+			ip4_mask.next_proto_id = 0xff;
+			ip4_val.next_proto_id = input->flow.ip4_flow.proto;
+		}
+		if (input->flow.ip4_flow.src_ip) {
+			ip4_mask.src_addr =  masks->ipv4_mask.src_ip;
+			ip4_val.src_addr = input->flow.ip4_flow.src_ip;
+		}
+		if (input->flow.ip4_flow.dst_ip) {
+			ip4_mask.dst_addr =  masks->ipv4_mask.dst_ip;
+			ip4_val.dst_addr = input->flow.ip4_flow.dst_ip;
+		}
+
+		enic_set_layer(gp, FILTER_GENERIC_1_IPV4, FILTER_GENERIC_1_L3,
+			       &ip4_mask, &ip4_val, sizeof(struct ipv4_hdr));
+	}
+
+	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_UDP) {
+		struct udp_hdr udp_mask, udp_val;
+		memset(&udp_mask, 0, sizeof(udp_mask));
+		memset(&udp_val, 0, sizeof(udp_val));
+
+		if (input->flow.udp6_flow.src_port) {
+			udp_mask.src_port = masks->src_port_mask;
+			udp_val.src_port = input->flow.udp6_flow.src_port;
+		}
+		if (input->flow.udp6_flow.dst_port) {
+			udp_mask.dst_port = masks->dst_port_mask;
+			udp_val.dst_port = input->flow.udp6_flow.dst_port;
+		}
+		enic_set_layer(gp, FILTER_GENERIC_1_UDP, FILTER_GENERIC_1_L4,
+			       &udp_mask, &udp_val, sizeof(struct udp_hdr));
+	} else if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_TCP) {
+		struct tcp_hdr tcp_mask, tcp_val;
+		memset(&tcp_mask, 0, sizeof(tcp_mask));
+		memset(&tcp_val, 0, sizeof(tcp_val));
+
+		if (input->flow.tcp6_flow.src_port) {
+			tcp_mask.src_port = masks->src_port_mask;
+			tcp_val.src_port = input->flow.tcp6_flow.src_port;
+		}
+		if (input->flow.tcp6_flow.dst_port) {
+			tcp_mask.dst_port = masks->dst_port_mask;
+			tcp_val.dst_port = input->flow.tcp6_flow.dst_port;
+		}
+		enic_set_layer(gp, FILTER_GENERIC_1_TCP, FILTER_GENERIC_1_L4,
+			       &tcp_mask, &tcp_val, sizeof(struct tcp_hdr));
+	} else if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) {
+		struct sctp_hdr sctp_mask, sctp_val;
+		memset(&sctp_mask, 0, sizeof(sctp_mask));
+		memset(&sctp_val, 0, sizeof(sctp_val));
+
+		if (input->flow.sctp6_flow.src_port) {
+			sctp_mask.src_port = masks->src_port_mask;
+			sctp_val.src_port = input->flow.sctp6_flow.src_port;
+		}
+		if (input->flow.sctp6_flow.dst_port) {
+			sctp_mask.dst_port = masks->dst_port_mask;
+			sctp_val.dst_port = input->flow.sctp6_flow.dst_port;
+		}
+		if (input->flow.sctp6_flow.verify_tag) {
+			sctp_mask.tag = 0xffffffff;
+			sctp_val.tag = input->flow.sctp6_flow.verify_tag;
+		}
+
+		/* v4 proto should be 132, override ipv6_flow.proto */
+		input->flow.ipv6_flow.proto = 132;
+
+		enic_set_layer(gp, 0, FILTER_GENERIC_1_L4, &sctp_mask,
+			       &sctp_val, sizeof(struct sctp_hdr));
+	}
+
+	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_UDP ||
+	    input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_TCP ||
+	    input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_SCTP ||
+	    input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) {
+		struct ipv6_hdr ipv6_mask, ipv6_val;
+		memset(&ipv6_mask, 0, sizeof(struct ipv6_hdr));
+		memset(&ipv6_val, 0, sizeof(struct ipv6_hdr));
+
+		if (input->flow.ipv6_flow.proto) {
+			ipv6_mask.proto = 0xff;
+			ipv6_val.proto = input->flow.ipv6_flow.proto;
+		}
+		for (i = 0; i < 4; i++) {
+			*(uint32_t *)&ipv6_mask.src_addr[i * 4] =
+					masks->ipv6_mask.src_ip[i];
+			*(uint32_t *)&ipv6_val.src_addr[i * 4] =
+					input->flow.ipv6_flow.src_ip[i];
+		}
+		for (i = 0; i < 4; i++) {
+			*(uint32_t *)&ipv6_mask.dst_addr[i * 4] =
+					masks->ipv6_mask.src_ip[i];
+			*(uint32_t *)&ipv6_val.dst_addr[i * 4] =
+					input->flow.ipv6_flow.dst_ip[i];
+		}
+		if (input->flow.ipv6_flow.tc) {
+			ipv6_mask.vtc_flow = 0x00ff0000;
+			ipv6_val.vtc_flow = input->flow.ipv6_flow.tc << 16;
+		}
+		if (input->flow.ipv6_flow.hop_limits) {
+			ipv6_mask.hop_limits = 0xff;
+			ipv6_val.hop_limits = input->flow.ipv6_flow.hop_limits;
+		}
+
+		enic_set_layer(gp, FILTER_GENERIC_1_IPV6, FILTER_GENERIC_1_L3,
+			       &ipv6_mask, &ipv6_val, sizeof(struct ipv6_hdr));
+	}
+}
+
 int enic_fdir_del_fltr(struct enic *enic, struct rte_eth_fdir_filter *params)
 {
 	int32_t pos;
@@ -97,7 +360,7 @@ int enic_fdir_del_fltr(struct enic *enic, struct rte_eth_fdir_filter *params)
 int enic_fdir_add_fltr(struct enic *enic, struct rte_eth_fdir_filter *params)
 {
 	struct enic_fdir_node *key;
-	struct filter fltr = {0};
+	struct filter_v2 fltr;
 	int32_t pos;
 	u8 do_free = 0;
 	u16 old_fltr_id = 0;
@@ -105,9 +368,9 @@ int enic_fdir_add_fltr(struct enic *enic, struct rte_eth_fdir_filter *params)
 	u16 flex_bytes;
 	u16 queue;
 
-	flowtype_supported = (
-		(RTE_ETH_FLOW_NONFRAG_IPV4_TCP == params->input.flow_type) ||
-		(RTE_ETH_FLOW_NONFRAG_IPV4_UDP == params->input.flow_type));
+	memset(&fltr, 0, sizeof(fltr));
+	flowtype_supported = enic->fdir.types_mask
+			     & (1 << params->input.flow_type);
 
 	flex_bytes = ((params->input.flow_ext.flexbytes[1] << 8 & 0xFF00) |
 		(params->input.flow_ext.flexbytes[0] & 0xFF));
@@ -123,6 +386,9 @@ int enic_fdir_add_fltr(struct enic *enic, struct rte_eth_fdir_filter *params)
 	/* Get the enicpmd RQ from the DPDK Rx queue */
 	queue = enic_sop_rq(params->action.rx_queue);
 
+	if (!enic->rq[queue].in_use)
+		return -EINVAL;
+
 	/* See if the key is already there in the table */
 	pos = rte_hash_del_key(enic->fdir.hash, params);
 	switch (pos) {
@@ -185,22 +451,8 @@ int enic_fdir_add_fltr(struct enic *enic, struct rte_eth_fdir_filter *params)
 	key->filter = *params;
 	key->rq_index = queue;
 
-	fltr.type = FILTER_IPV4_5TUPLE;
-	fltr.u.ipv4.src_addr = rte_be_to_cpu_32(
-		params->input.flow.ip4_flow.src_ip);
-	fltr.u.ipv4.dst_addr = rte_be_to_cpu_32(
-		params->input.flow.ip4_flow.dst_ip);
-	fltr.u.ipv4.src_port = rte_be_to_cpu_16(
-		params->input.flow.udp4_flow.src_port);
-	fltr.u.ipv4.dst_port = rte_be_to_cpu_16(
-		params->input.flow.udp4_flow.dst_port);
-
-	if (RTE_ETH_FLOW_NONFRAG_IPV4_TCP == params->input.flow_type)
-		fltr.u.ipv4.protocol = PROTO_TCP;
-	else
-		fltr.u.ipv4.protocol = PROTO_UDP;
-
-	fltr.u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE;
+	enic->fdir.copy_fltr_fn(&fltr, &params->input,
+				&enic->rte_dev->data->dev_conf.fdir_conf.mask);
 
 	if (!vnic_dev_classifier(enic->vdev, CLSF_ADD, &queue, &fltr)) {
 		key->fltr_id = queue;
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index d20637f..51262da 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -95,10 +95,12 @@ enicpmd_fdir_ctrl_func(struct rte_eth_dev *eth_dev,
 		break;
 
 	case RTE_ETH_FILTER_FLUSH:
-	case RTE_ETH_FILTER_INFO:
 		dev_warning(enic, "unsupported operation %u", filter_op);
 		ret = -ENOTSUP;
 		break;
+	case RTE_ETH_FILTER_INFO:
+		enic_fdir_info_get(enic, (struct rte_eth_fdir_info *)arg);
+		break;
 	default:
 		dev_err(enic, "unknown operation %u", filter_op);
 		ret = -EINVAL;
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index e3e58fb..622b317 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1293,6 +1293,9 @@ static int enic_dev_init(struct enic *enic)
 		return -EINVAL;
 	}
 
+	/* Get the supported filters */
+	enic_fdir_info(enic);
+
 	eth_dev->data->mac_addrs = rte_zmalloc("enic_mac_addr", ETH_ALEN, 0);
 	if (!eth_dev->data->mac_addrs) {
 		dev_err(enic, "mac addr storage alloc failed, aborting.\n");
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 84c5d33..8a230a1 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -62,6 +62,7 @@ int enic_get_vnic_config(struct enic *enic)
 		return err;
 	}
 
+
 #define GET_CONFIG(m) \
 	do { \
 		err = vnic_dev_spec(enic->vdev, \
@@ -98,6 +99,10 @@ int enic_get_vnic_config(struct enic *enic)
 	enic->rte_dev->data->mtu = min_t(u16, enic->max_mtu,
 					 max_t(u16, 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)
+		 ? "" : "not "));
+
 	c->wq_desc_count =
 		min_t(u32, ENIC_MAX_WQ_DESCS,
 		max_t(u32, ENIC_MIN_WQ_DESCS,
-- 
2.10.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300 series adapters
  2016-09-29 20:56 ` [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300 series adapters John Daley
@ 2016-10-11  9:22   ` Ferruh Yigit
  2016-10-11  9:25     ` John Daley (johndale)
  0 siblings, 1 reply; 10+ messages in thread
From: Ferruh Yigit @ 2016-10-11  9:22 UTC (permalink / raw)
  To: John Daley, bruce.richardson; +Cc: dev

Hi John,

On 9/29/2016 9:56 PM, John Daley wrote:
> 1300 series Cisco adapter firmware version 2.0(13) for UCS
> C-series servers and 3.1(2) for blade servers supports more
> filtering capabilities. The feature can be enabled via Cisco
> CIMC or USCM with the 'advanced filters' radio button. When
> enabled, the these additional flow director modes are available:
> 	RTE_ETH_FLOW_NONFRAG_IPV4_OTHER
> 	RTE_ETH_FLOW_NONFRAG_IPV4_SCTP
> 	RTE_ETH_FLOW_NONFRAG_IPV6_UDP
> 	RTE_ETH_FLOW_NONFRAG_IPV6_TCP
> 	RTE_ETH_FLOW_NONFRAG_IPV6_SCTP
> 	RTE_ETH_FLOW_NONFRAG_IPV6_OTHER
> 
> Changes:
> - Detect and set an 'advanced filters' flag dependent on the adapter
>   capability.
> - Implement RTE_ETH_FILTER_INFO filter op to return the flow types
>   available dependent on whether advanced filters are enabled.
> - Use a function pointer to select how filters are added to the adapter:
>   copy_fltr_v1() for older firmware/adapters or copy_fltr_v2() for
>   adapters which support advanced filters.
> - Apply fdir global masks to filters when in advanced filter mode.
> - Update documentation.
> 
> Signed-off-by: John Daley <johndale@cisco.com>
> Reviewed-by: Nelson Escobar <neescoba@cisco.com>
> ---

<...>

>  
> +void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info *info)
> +{
> +	info->mode = enic->fdir.modes;

This cause a icc build error:
.../drivers/net/enic/enic_clsf.c(77):
error #188: enumerated type mixed with another type
        info->mode = enic->fdir.modes;
                   ^

Just casting to the enum fixes it:
+       info->mode = (enum rte_fdir_mode)enic->fdir.modes;

Since the modification is trivial, if you agree with the change, we can
apply it without needing a new version of the patch?

<...>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300 series adapters
  2016-10-11  9:22   ` Ferruh Yigit
@ 2016-10-11  9:25     ` John Daley (johndale)
  2016-10-12 16:24       ` Bruce Richardson
  0 siblings, 1 reply; 10+ messages in thread
From: John Daley (johndale) @ 2016-10-11  9:25 UTC (permalink / raw)
  To: Ferruh Yigit, bruce.richardson; +Cc: dev



> -----Original Message-----
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Tuesday, October 11, 2016 2:22 AM
> To: John Daley (johndale) <johndale@cisco.com>;
> bruce.richardson@intel.com
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300
> series adapters
> 
> Hi John,
> 
> On 9/29/2016 9:56 PM, John Daley wrote:
> > 1300 series Cisco adapter firmware version 2.0(13) for UCS C-series
> > servers and 3.1(2) for blade servers supports more filtering
> > capabilities. The feature can be enabled via Cisco CIMC or USCM with
> > the 'advanced filters' radio button. When enabled, the these
> > additional flow director modes are available:
> > 	RTE_ETH_FLOW_NONFRAG_IPV4_OTHER
> > 	RTE_ETH_FLOW_NONFRAG_IPV4_SCTP
> > 	RTE_ETH_FLOW_NONFRAG_IPV6_UDP
> > 	RTE_ETH_FLOW_NONFRAG_IPV6_TCP
> > 	RTE_ETH_FLOW_NONFRAG_IPV6_SCTP
> > 	RTE_ETH_FLOW_NONFRAG_IPV6_OTHER
> >
> > Changes:
> > - Detect and set an 'advanced filters' flag dependent on the adapter
> >   capability.
> > - Implement RTE_ETH_FILTER_INFO filter op to return the flow types
> >   available dependent on whether advanced filters are enabled.
> > - Use a function pointer to select how filters are added to the adapter:
> >   copy_fltr_v1() for older firmware/adapters or copy_fltr_v2() for
> >   adapters which support advanced filters.
> > - Apply fdir global masks to filters when in advanced filter mode.
> > - Update documentation.
> >
> > Signed-off-by: John Daley <johndale@cisco.com>
> > Reviewed-by: Nelson Escobar <neescoba@cisco.com>
> > ---
> 
> <...>
> 
> >
> > +void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info
> > +*info) {
> > +	info->mode = enic->fdir.modes;
> 
> This cause a icc build error:
> .../drivers/net/enic/enic_clsf.c(77):
> error #188: enumerated type mixed with another type
>         info->mode = enic->fdir.modes;
>                    ^
> 
> Just casting to the enum fixes it:
> +       info->mode = (enum rte_fdir_mode)enic->fdir.modes;
> 
> Since the modification is trivial, if you agree with the change, we can apply it
> without needing a new version of the patch?
> 

Looks good, thank you and sorry for the trouble.
-john

> <...>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300 series adapters
  2016-10-11  9:25     ` John Daley (johndale)
@ 2016-10-12 16:24       ` Bruce Richardson
  2016-10-12 18:09         ` [dpdk-dev] [PATCH] net/enic: remove assert which causes compile error John Daley
  0 siblings, 1 reply; 10+ messages in thread
From: Bruce Richardson @ 2016-10-12 16:24 UTC (permalink / raw)
  To: John Daley (johndale); +Cc: Ferruh Yigit, dev

On Tue, Oct 11, 2016 at 09:25:45AM +0000, John Daley (johndale) wrote:
> 
> 
> > -----Original Message-----
> > From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> > Sent: Tuesday, October 11, 2016 2:22 AM
> > To: John Daley (johndale) <johndale@cisco.com>;
> > bruce.richardson@intel.com
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300
> > series adapters
> > 
> > Hi John,
> > 
> > On 9/29/2016 9:56 PM, John Daley wrote:
> > > 1300 series Cisco adapter firmware version 2.0(13) for UCS C-series
> > > servers and 3.1(2) for blade servers supports more filtering
> > > capabilities. The feature can be enabled via Cisco CIMC or USCM with
> > > the 'advanced filters' radio button. When enabled, the these
> > > additional flow director modes are available:
> > > 	RTE_ETH_FLOW_NONFRAG_IPV4_OTHER
> > > 	RTE_ETH_FLOW_NONFRAG_IPV4_SCTP
> > > 	RTE_ETH_FLOW_NONFRAG_IPV6_UDP
> > > 	RTE_ETH_FLOW_NONFRAG_IPV6_TCP
> > > 	RTE_ETH_FLOW_NONFRAG_IPV6_SCTP
> > > 	RTE_ETH_FLOW_NONFRAG_IPV6_OTHER
> > >
> > > Changes:
> > > - Detect and set an 'advanced filters' flag dependent on the adapter
> > >   capability.
> > > - Implement RTE_ETH_FILTER_INFO filter op to return the flow types
> > >   available dependent on whether advanced filters are enabled.
> > > - Use a function pointer to select how filters are added to the adapter:
> > >   copy_fltr_v1() for older firmware/adapters or copy_fltr_v2() for
> > >   adapters which support advanced filters.
> > > - Apply fdir global masks to filters when in advanced filter mode.
> > > - Update documentation.
> > >
> > > Signed-off-by: John Daley <johndale@cisco.com>
> > > Reviewed-by: Nelson Escobar <neescoba@cisco.com>
> > > ---
> > 
> > <...>
> > 
> > >
> > > +void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info
> > > +*info) {
> > > +	info->mode = enic->fdir.modes;
> > 
> > This cause a icc build error:
> > .../drivers/net/enic/enic_clsf.c(77):
> > error #188: enumerated type mixed with another type
> >         info->mode = enic->fdir.modes;
> >                    ^
> > 
> > Just casting to the enum fixes it:
> > +       info->mode = (enum rte_fdir_mode)enic->fdir.modes;
> > 
> > Since the modification is trivial, if you agree with the change, we can apply it
> > without needing a new version of the patch?
> > 
> 
> Looks good, thank you and sorry for the trouble.
> -john
> 
Series applied to dpdk-next-net/rel_16_11

/Bruce

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH] net/enic: remove assert which causes compile error
  2016-10-12 16:24       ` Bruce Richardson
@ 2016-10-12 18:09         ` John Daley
  2016-10-13 13:22           ` Bruce Richardson
  0 siblings, 1 reply; 10+ messages in thread
From: John Daley @ 2016-10-12 18:09 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, John Daley

Remove an RTE_ASSERT which will not compile if enabled and is not needed.

Fixes: a1f7c7b3b5b2 ("net/enic: extend fdir support for 1300 series adapters")

Signed-off-by: John Daley <johndale@cisco.com>
---
Would have been nice if I caught this yesterday before you applied a1f7c7b3 :(

 drivers/net/enic/enic_clsf.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/enic/enic_clsf.c b/drivers/net/enic/enic_clsf.c
index c709be9..d2413d7 100644
--- a/drivers/net/enic/enic_clsf.c
+++ b/drivers/net/enic/enic_clsf.c
@@ -142,8 +142,6 @@ copy_fltr_v2(struct filter_v2 *fltr, struct rte_eth_fdir_input *input,
 	struct filter_generic_1 *gp = &fltr->u.generic_1;
 	int i;
 
-	RTE_ASSERT(enic->adv_filters);
-
 	fltr->type = FILTER_DPDK_1;
 	memset(gp, 0, sizeof(*gp));
 
-- 
2.10.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH] net/enic: remove assert which causes compile error
  2016-10-12 18:09         ` [dpdk-dev] [PATCH] net/enic: remove assert which causes compile error John Daley
@ 2016-10-13 13:22           ` Bruce Richardson
  2016-10-13 13:37             ` Bruce Richardson
  0 siblings, 1 reply; 10+ messages in thread
From: Bruce Richardson @ 2016-10-13 13:22 UTC (permalink / raw)
  To: John Daley; +Cc: dev

On Wed, Oct 12, 2016 at 11:09:35AM -0700, John Daley wrote:
> Remove an RTE_ASSERT which will not compile if enabled and is not needed.
> 
> Fixes: a1f7c7b3b5b2 ("net/enic: extend fdir support for 1300 series adapters")
> 
> Signed-off-by: John Daley <johndale@cisco.com>
> ---
> Would have been nice if I caught this yesterday before you applied a1f7c7b3 :(
> 
Since commit a1f7c7b3 has not been pulled into the dpdk.org mainline, I can still
merge this commit into the origin one that has the bug. Unless you object, I 
shall do so now.

/Bruce

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH] net/enic: remove assert which causes compile error
  2016-10-13 13:22           ` Bruce Richardson
@ 2016-10-13 13:37             ` Bruce Richardson
  0 siblings, 0 replies; 10+ messages in thread
From: Bruce Richardson @ 2016-10-13 13:37 UTC (permalink / raw)
  To: John Daley; +Cc: dev

On Thu, Oct 13, 2016 at 02:22:16PM +0100, Bruce Richardson wrote:
> On Wed, Oct 12, 2016 at 11:09:35AM -0700, John Daley wrote:
> > Remove an RTE_ASSERT which will not compile if enabled and is not needed.
> > 
> > Fixes: a1f7c7b3b5b2 ("net/enic: extend fdir support for 1300 series adapters")
> > 
> > Signed-off-by: John Daley <johndale@cisco.com>
> > ---
> > Would have been nice if I caught this yesterday before you applied a1f7c7b3 :(
> > 
> Since commit a1f7c7b3 has not been pulled into the dpdk.org mainline, I can still
> merge this commit into the origin one that has the bug. Unless you object, I 
> shall do so now.
> 
> /Bruce
Done. Fix merged into original commit

/Bruce

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-10-13 13:37 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-29 20:56 [dpdk-dev] [PATCH 1/4] net/enic: fix fdir usage with scattered Rx John Daley
2016-09-29 20:56 ` [dpdk-dev] [PATCH 2/4] net/enic: fix segfault when restarting with fdir filters John Daley
2016-09-29 20:56 ` [dpdk-dev] [PATCH 3/4] net/enic: update VIC interface file John Daley
2016-09-29 20:56 ` [dpdk-dev] [PATCH 4/4] net/enic: extend fdir support for 1300 series adapters John Daley
2016-10-11  9:22   ` Ferruh Yigit
2016-10-11  9:25     ` John Daley (johndale)
2016-10-12 16:24       ` Bruce Richardson
2016-10-12 18:09         ` [dpdk-dev] [PATCH] net/enic: remove assert which causes compile error John Daley
2016-10-13 13:22           ` Bruce Richardson
2016-10-13 13:37             ` Bruce Richardson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).