DPDK patches and discussions
 help / color / mirror / Atom feed
From: Jingjing Wu <jingjing.wu@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v4 05/21] i40e: implement operations to add/delete flow director
Date: Wed, 22 Oct 2014 09:01:11 +0800
Message-ID: <1413939687-11177-6-git-send-email-jingjing.wu@intel.com> (raw)
In-Reply-To: <1413939687-11177-1-git-send-email-jingjing.wu@intel.com>

deal with two operations for flow director
 - RTE_ETH_FILTER_ADD
 - RTE_ETH_FILTER_DELETE
encode the flow inputs to programming packet
sent the packet to filter programming queue and check status on the status report queue

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_i40e/i40e_ethdev.c |   6 +-
 lib/librte_pmd_i40e/i40e_ethdev.h |   3 +
 lib/librte_pmd_i40e/i40e_fdir.c   | 622 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 629 insertions(+), 2 deletions(-)

diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c
index 59a4b6a..f56a4f6 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev.c
@@ -4241,14 +4241,16 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
 		     enum rte_filter_op filter_op,
 		     void *arg)
 {
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	int ret = 0;
-	(void)filter_op;
-	(void)arg;
 
 	if (dev == NULL)
 		return -EINVAL;
 
 	switch (filter_type) {
+	case RTE_ETH_FILTER_FDIR:
+		ret = i40e_fdir_ctrl_func(pf, filter_op, arg);
+		break;
 	default:
 		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
 							filter_type);
diff --git a/lib/librte_pmd_i40e/i40e_ethdev.h b/lib/librte_pmd_i40e/i40e_ethdev.h
index d998980..a20c00e 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev.h
+++ b/lib/librte_pmd_i40e/i40e_ethdev.h
@@ -375,6 +375,9 @@ enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf,
 				    unsigned int socket_id);
 int i40e_fdir_setup(struct i40e_pf *pf);
 void i40e_fdir_teardown(struct i40e_pf *pf);
+int i40e_fdir_ctrl_func(struct i40e_pf *pf,
+			  enum rte_filter_op filter_op,
+			  void *arg);
 
 /* I40E_DEV_PRIVATE_TO */
 #define I40E_DEV_PRIVATE_TO_PF(adapter) \
diff --git a/lib/librte_pmd_i40e/i40e_fdir.c b/lib/librte_pmd_i40e/i40e_fdir.c
index 848fb92..8996a1c 100644
--- a/lib/librte_pmd_i40e/i40e_fdir.c
+++ b/lib/librte_pmd_i40e/i40e_fdir.c
@@ -44,6 +44,10 @@
 #include <rte_log.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
+#include <rte_ip.h>
+#include <rte_udp.h>
+#include <rte_tcp.h>
+#include <rte_sctp.h>
 
 #include "i40e_logs.h"
 #include "i40e/i40e_type.h"
@@ -51,7 +55,23 @@
 #include "i40e_rxtx.h"
 
 #define I40E_FDIR_MZ_NAME          "FDIR_MEMZONE"
+#ifndef IPV6_ADDR_LEN
+#define IPV6_ADDR_LEN              16
+#endif
+
 #define I40E_FDIR_PKT_LEN                   512
+#define I40E_FDIR_IP_DEFAULT_LEN            420
+#define I40E_FDIR_IP_DEFAULT_TTL            0x40
+#define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
+#define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
+#define I40E_FDIR_IPv6_PAYLOAD_LEN          380
+#define I40E_FDIR_UDP_DEFAULT_LEN           400
+
+/* Wait count and inteval for fdir filter programming */
+#define I40E_FDIR_WAIT_COUNT       10
+#define I40E_FDIR_WAIT_INTERVAL_US 1000
 
 #define I40E_COUNTER_PF           2
 /* Statistic counter index for one pf */
@@ -59,6 +79,16 @@
 #define I40E_FLX_OFFSET_IN_FIELD_VECTOR   50
 
 static int i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq);
+static int i40e_fdir_construct_pkt(struct i40e_pf *pf,
+				     struct rte_eth_fdir_input *fdir_input,
+				     unsigned char *raw_pkt);
+static int i40e_add_del_fdir_filter(struct i40e_pf *pf,
+			    struct rte_eth_fdir_filter *filter,
+			    bool add);
+static int i40e_fdir_filter_programming(struct i40e_pf *pf,
+			enum i40e_filter_pctype pctype,
+			struct rte_eth_fdir_filter *filter,
+			bool add);
 
 static int
 i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq)
@@ -288,3 +318,595 @@ i40e_fdir_teardown(struct i40e_pf *pf)
 	pf->fdir.fdir_vsi = NULL;
 	return;
 }
+
+/*
+ * i40e_fdir_construct_pkt - construct packet based on fields in input
+ * @pf: board private structure
+ * @fdir_input: input set of the flow director entry
+ * @raw_pkt: a packet to be constructed
+ */
+static int
+i40e_fdir_construct_pkt(struct i40e_pf *pf,
+			     struct rte_eth_fdir_input *fdir_input,
+			     unsigned char *raw_pkt)
+{
+	struct ether_hdr *ether;
+	unsigned char *payload;
+	struct ipv4_hdr *ip;
+	struct ipv6_hdr *ip6;
+	struct udp_hdr *udp;
+	struct tcp_hdr *tcp;
+	struct sctp_hdr *sctp;
+	uint8_t size = 0;
+	int i, set_idx = 2; /* set_idx = 2 means using l4 pyload by default*/
+
+	switch (fdir_input->flow_type) {
+	case RTE_ETH_FLOW_TYPE_UDPV4:
+		ether = (struct ether_hdr *)raw_pkt;
+		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
+				sizeof(struct ipv4_hdr));
+		payload = raw_pkt + sizeof(struct ether_hdr) +
+			  sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr);
+
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
+		/* set len to by default */
+		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
+		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+
+		/*
+		 * The source and destination fields in the transmitted packet
+		 * need to be presented in a reversed order with respect
+		 * to the expected received packets.
+		 */
+		ip->src_addr = fdir_input->flow.udp4_flow.dst_ip;
+		ip->dst_addr = fdir_input->flow.udp4_flow.src_ip;
+		ip->next_proto_id = IPPROTO_UDP;
+		udp->src_port = fdir_input->flow.udp4_flow.dst_port;
+		udp->dst_port = fdir_input->flow.udp4_flow.src_port;
+		udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN);
+		break;
+
+	case RTE_ETH_FLOW_TYPE_TCPV4:
+		ether = (struct ether_hdr *)raw_pkt;
+		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
+					 sizeof(struct ipv4_hdr));
+		payload = raw_pkt + sizeof(struct ether_hdr) +
+			  sizeof(struct ipv4_hdr) + sizeof(struct tcp_hdr);
+
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
+		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
+		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+
+		/*
+		 * The source and destination fields in the transmitted packet
+		 * need to be presented in a reversed order with respect
+		 * to the expected received packets.
+		 */
+		ip->src_addr = fdir_input->flow.tcp4_flow.dst_ip;
+		ip->dst_addr = fdir_input->flow.tcp4_flow.src_ip;
+		ip->next_proto_id = IPPROTO_TCP;
+		tcp->src_port = fdir_input->flow.tcp4_flow.dst_port;
+		tcp->dst_port = fdir_input->flow.tcp4_flow.src_port;
+		tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF;
+		break;
+
+	case RTE_ETH_FLOW_TYPE_SCTPV4:
+		ether = (struct ether_hdr *)raw_pkt;
+		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
+					   sizeof(struct ipv4_hdr));
+		payload = raw_pkt + sizeof(struct ether_hdr) +
+			  sizeof(struct ipv4_hdr) + sizeof(struct sctp_hdr);
+
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
+		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
+		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+
+		/*
+		 * The source and destination fields in the transmitted packet
+		 * need to be presented in a reversed order with respect
+		 * to the expected received packets.
+		 */
+		ip->src_addr = fdir_input->flow.sctp4_flow.dst_ip;
+		ip->dst_addr = fdir_input->flow.sctp4_flow.src_ip;
+		ip->next_proto_id = IPPROTO_SCTP;
+		sctp->tag = fdir_input->flow.sctp4_flow.verify_tag;
+		break;
+
+	case RTE_ETH_FLOW_TYPE_IPV4_OTHER:
+		ether = (struct ether_hdr *)raw_pkt;
+		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		payload = raw_pkt + sizeof(struct ether_hdr) +
+			  sizeof(struct ipv4_hdr);
+
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
+		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
+		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = IPPROTO_IP;
+
+		/*
+		 * The source and destination fields in the transmitted packet
+		 * need to be presented in a reversed order with respect
+		 * to the expected received packets.
+		 */
+		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
+		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
+		set_idx = 1; /* l3 pyload */
+		break;
+
+	case RTE_ETH_FLOW_TYPE_UDPV6:
+		ether = (struct ether_hdr *)raw_pkt;
+		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
+					 sizeof(struct ipv6_hdr));
+		payload = raw_pkt + sizeof(struct ether_hdr) +
+			  sizeof(struct ipv6_hdr) + sizeof(struct udp_hdr);
+
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		ip6->vtc_flow = rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+		ip6->payload_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
+		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
+
+		/*
+		 * The source and destination fields in the transmitted packet
+		 * need to be presented in a reversed order with respect
+		 * to the expected received packets.
+		 */
+		rte_memcpy(&(ip6->src_addr), &(fdir_input->flow.udp6_flow.dst_ip),
+			IPV6_ADDR_LEN);
+		rte_memcpy(&(ip6->dst_addr), &(fdir_input->flow.udp6_flow.src_ip),
+			IPV6_ADDR_LEN);
+		ip6->proto = IPPROTO_UDP;
+		udp->src_port = fdir_input->flow.udp6_flow.dst_port;
+		udp->dst_port = fdir_input->flow.udp6_flow.src_port;
+		udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
+		break;
+
+	case RTE_ETH_FLOW_TYPE_TCPV6:
+		ether = (struct ether_hdr *)raw_pkt;
+		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
+					 sizeof(struct ipv6_hdr));
+		payload = raw_pkt + sizeof(struct ether_hdr) +
+				sizeof(struct ipv6_hdr) + sizeof(struct tcp_hdr);
+
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		ip6->vtc_flow = rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+		ip6->payload_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
+		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
+
+		/*
+		 * The source and destination fields in the transmitted packet
+		 * need to be presented in a reversed order with respect
+		 * to the expected received packets.
+		 */
+		rte_memcpy(&(ip6->src_addr), &(fdir_input->flow.tcp6_flow.dst_ip),
+			IPV6_ADDR_LEN);
+		rte_memcpy(&(ip6->dst_addr), &(fdir_input->flow.tcp6_flow.src_ip),
+			IPV6_ADDR_LEN);
+		ip6->proto = IPPROTO_TCP;
+		tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF;
+		tcp->src_port = fdir_input->flow.udp6_flow.dst_port;
+		tcp->dst_port = fdir_input->flow.udp6_flow.src_port;
+		break;
+
+	case RTE_ETH_FLOW_TYPE_SCTPV6:
+		ether = (struct ether_hdr *)raw_pkt;
+		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
+					   sizeof(struct ipv6_hdr));
+		payload = raw_pkt + sizeof(struct ether_hdr) +
+			  sizeof(struct ipv6_hdr) + sizeof(struct sctp_hdr);
+
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		ip6->vtc_flow = rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+		ip6->payload_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
+		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
+
+		/*
+		 * The source and destination fields in the transmitted packet
+		 * need to be presented in a reversed order with respect
+		 * to the expected received packets.
+		 */
+		rte_memcpy(&(ip6->src_addr), &(fdir_input->flow.sctp6_flow.dst_ip),
+			IPV6_ADDR_LEN);
+		rte_memcpy(&(ip6->dst_addr), &(fdir_input->flow.sctp6_flow.src_ip),
+			IPV6_ADDR_LEN);
+		ip6->proto = IPPROTO_SCTP;
+		sctp->tag = fdir_input->flow.sctp6_flow.verify_tag;
+		break;
+
+	case RTE_ETH_FLOW_TYPE_IPV6_OTHER:
+		ether = (struct ether_hdr *)raw_pkt;
+		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		payload = raw_pkt + sizeof(struct ether_hdr) + sizeof(struct ipv6_hdr);
+
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		ip6->vtc_flow = rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+		ip6->proto = IPPROTO_NONE;
+		ip6->payload_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
+		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
+
+		/*
+		 * The source and destination fields in the transmitted packet
+		 * need to be presented in a reversed order with respect
+		 * to the expected received packets.
+		 */
+		rte_memcpy(&(ip6->src_addr), &(fdir_input->flow.ip6_flow.dst_ip),
+			IPV6_ADDR_LEN);
+		rte_memcpy(&(ip6->dst_addr), &(fdir_input->flow.ip6_flow.src_ip),
+			IPV6_ADDR_LEN);
+		set_idx = 1; /* l3 pyload */
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unknown flow type %u.", fdir_input->flow_type);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < 3; i++) {
+		if (pf->fdir.flex_set[set_idx][i].size == 0)
+			break;
+		(void)rte_memcpy(payload + 2 * pf->fdir.flex_set[set_idx][i].offset,
+				 fdir_input->flow_ext.flexwords + size,
+				 2 * pf->fdir.flex_set[set_idx][i].size);
+		size = pf->fdir.flex_set[set_idx][i].size;
+	}
+	return 0;
+}
+
+/* Construct the tx flags */
+static inline uint64_t
+i40e_build_ctob(uint32_t td_cmd,
+		uint32_t td_offset,
+		unsigned int size,
+		uint32_t td_tag)
+{
+	return rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DATA |
+			((uint64_t)td_cmd  << I40E_TXD_QW1_CMD_SHIFT) |
+			((uint64_t)td_offset << I40E_TXD_QW1_OFFSET_SHIFT) |
+			((uint64_t)size  << I40E_TXD_QW1_TX_BUF_SZ_SHIFT) |
+			((uint64_t)td_tag  << I40E_TXD_QW1_L2TAG1_SHIFT));
+}
+
+/*
+ * check the programming status descriptor in rx queue.
+ * done after Programming Flow Director is programmed on
+ * tx queue
+ */
+static inline int
+i40e_check_fdir_programming_status(struct i40e_rx_queue *rxq)
+{
+	volatile union i40e_rx_desc *rxdp;
+	uint64_t qword1;
+	uint32_t rx_status;
+	uint32_t len, id;
+	uint32_t error;
+	int ret = 0;
+
+	rxdp = &rxq->rx_ring[rxq->rx_tail];
+	qword1 = rte_le_to_cpu_64(rxdp->wb.qword1.status_error_len);
+	rx_status = (qword1 & I40E_RXD_QW1_STATUS_MASK)
+			>> I40E_RXD_QW1_STATUS_SHIFT;
+
+	if (rx_status & (1 << I40E_RX_DESC_STATUS_DD_SHIFT)) {
+		len = qword1 >> I40E_RX_PROG_STATUS_DESC_LENGTH_SHIFT;
+		id = (qword1 & I40E_RX_PROG_STATUS_DESC_QW1_PROGID_MASK) >>
+			    I40E_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT;
+
+		if (len  == I40E_RX_PROG_STATUS_DESC_LENGTH &&
+		    id == I40E_RX_PROG_STATUS_DESC_FD_FILTER_STATUS) {
+			error = (qword1 &
+				I40E_RX_PROG_STATUS_DESC_QW1_ERROR_MASK) >>
+				I40E_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT;
+			if (error == (0x1 <<
+				I40E_RX_PROG_STATUS_DESC_FD_TBL_FULL_SHIFT)) {
+				PMD_DRV_LOG(ERR, "Failed to add FDIR filter"
+					    " (FD_ID %u): programming status"
+					    " reported.",
+					    rxdp->wb.qword0.hi_dword.fd_id);
+				ret = -1;
+			} else if (error == (0x1 <<
+				I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) {
+				PMD_DRV_LOG(ERR, "Failed to delete FDIR filter"
+					    " (FD_ID %u): programming status"
+					    " reported.",
+					    rxdp->wb.qword0.hi_dword.fd_id);
+				ret = -1;
+			} else
+				PMD_DRV_LOG(ERR, "invalid programming status"
+					    " reported, error = %u.", error);
+		} else
+			PMD_DRV_LOG(ERR, "unknown programming status"
+				    " reported, len = %d, id = %u.", len, id);
+		rxdp->wb.qword1.status_error_len = 0;
+		rxq->rx_tail++;
+		if (unlikely(rxq->rx_tail == rxq->nb_rx_desc))
+			rxq->rx_tail = 0;
+	}
+	return ret;
+}
+
+/*
+ * i40e_add_del_fdir_filter - add or remove a flow diretor filter.
+ * @pf: board private structure
+ * @filter: fdir filter entry
+ * @add: 0 - delelet, 1 - add
+ */
+static int
+i40e_add_del_fdir_filter(struct i40e_pf *pf,
+			    struct rte_eth_fdir_filter *filter,
+			    bool add)
+{
+	int ret = 0;
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+
+	if (!(pf->flags & I40E_FLAG_FDIR)) {
+		PMD_DRV_LOG(ERR, "FDIR is not enabled.");
+		return -ENOTSUP;
+	}
+
+	memset(pkt, 0, I40E_FDIR_PKT_LEN);
+
+	ret = i40e_fdir_construct_pkt(pf, &filter->input, pkt);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "construct packet for fdir fails.");
+		return ret;
+	}
+
+	switch (filter->input.flow_type) {
+	case RTE_ETH_FLOW_TYPE_UDPV4:
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_IPV4_UDP fdir programming fails.");
+		break;
+	case RTE_ETH_FLOW_TYPE_TCPV4:
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_IPV4_TCP fdir programming fails.");
+		break;
+	case RTE_ETH_FLOW_TYPE_SCTPV4:
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_IPV4_SCTP fdir programming fails.");
+		break;
+	case RTE_ETH_FLOW_TYPE_IPV4_OTHER:
+		/* program on both NONF_IPV4 and FRAG_IPV4 PCTYPE*/
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_IPV4_OTHER fdir programming fails.");
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_FRAG_IPV4,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_FRAG_IPV4 fdir programming fails.");
+		break;
+	case RTE_ETH_FLOW_TYPE_UDPV6:
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_IPV6_UDP fdir programming fails.");
+		break;
+	case RTE_ETH_FLOW_TYPE_TCPV6:
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_IPV6_TCP fdir programming fails.");
+		break;
+	case RTE_ETH_FLOW_TYPE_SCTPV6:
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_IPV6_SCTP fdir programming fails.");
+		break;
+	case RTE_ETH_FLOW_TYPE_IPV6_OTHER:
+		/* program on both NONF_IPV6 and FRAG_IPV6 PCTYPE*/
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_IPV6_OTHER fdir programming fails.");
+		ret = i40e_fdir_filter_programming(pf,
+			I40E_FILTER_PCTYPE_FRAG_IPV6,
+			filter, add);
+		if (ret < 0)
+			PMD_DRV_LOG(ERR, "NONF_FRAG_IPV6 fdir programming fails.");
+		break;
+	default:
+		PMD_DRV_LOG(ERR, " invalid flow_type input.");
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+/*
+ * i40e_fdir_filter_programming - Program a flow diretor filter rule.
+ * Is done by Flow Director Programming Descriptor followed by packet
+ * structure that contains the filter fields need to match.
+ * @pf: board private structure
+ * @pctype: pctype
+ * @filter: fdir filter entry
+ * @add: 0 - delelet, 1 - add
+ */
+static int
+i40e_fdir_filter_programming(struct i40e_pf *pf,
+			enum i40e_filter_pctype pctype,
+			struct rte_eth_fdir_filter *filter,
+			bool add)
+{
+	struct i40e_tx_queue *txq = pf->fdir.txq;
+	struct i40e_rx_queue *rxq = pf->fdir.rxq;
+	struct rte_eth_fdir_input *fdir_input = &filter->input;
+	struct rte_eth_fdir_action *fdir_action = &filter->action;
+	volatile struct i40e_tx_desc *txdp;
+	volatile struct i40e_filter_program_desc *fdirdp;
+	uint32_t td_cmd;
+	uint16_t i;
+	uint8_t dest;
+
+	PMD_DRV_LOG(INFO, "filling filter programming descriptor.");
+	fdirdp = (volatile struct i40e_filter_program_desc *)
+			(&(txq->tx_ring[txq->tx_tail]));
+
+	fdirdp->qindex_flex_ptype_vsi =
+			rte_cpu_to_le_32((fdir_action->rx_queue <<
+					  I40E_TXD_FLTR_QW0_QINDEX_SHIFT) &
+					  I40E_TXD_FLTR_QW0_QINDEX_MASK);
+
+	fdirdp->qindex_flex_ptype_vsi |=
+			rte_cpu_to_le_32((fdir_action->flex_off <<
+					  I40E_TXD_FLTR_QW0_FLEXOFF_SHIFT) &
+					  I40E_TXD_FLTR_QW0_FLEXOFF_MASK);
+
+	fdirdp->qindex_flex_ptype_vsi |=
+			rte_cpu_to_le_32((pctype <<
+					  I40E_TXD_FLTR_QW0_PCTYPE_SHIFT) &
+					  I40E_TXD_FLTR_QW0_PCTYPE_MASK);
+
+	/* Use LAN VSI Id if not programmed by user */
+	if (fdir_input->flow_ext.dest_id == 0)
+		fdirdp->qindex_flex_ptype_vsi |=
+			rte_cpu_to_le_32((pf->main_vsi->vsi_id <<
+					  I40E_TXD_FLTR_QW0_DEST_VSI_SHIFT) &
+					  I40E_TXD_FLTR_QW0_DEST_VSI_MASK);
+	else
+		fdirdp->qindex_flex_ptype_vsi |=
+			rte_cpu_to_le_32((fdir_input->flow_ext.dest_id <<
+					  I40E_TXD_FLTR_QW0_DEST_VSI_SHIFT) &
+					  I40E_TXD_FLTR_QW0_DEST_VSI_MASK);
+
+	fdirdp->dtype_cmd_cntindex =
+			rte_cpu_to_le_32(I40E_TX_DESC_DTYPE_FILTER_PROG);
+
+	if (add)
+		fdirdp->dtype_cmd_cntindex |= rte_cpu_to_le_32(
+				I40E_FILTER_PROGRAM_DESC_PCMD_ADD_UPDATE <<
+				I40E_TXD_FLTR_QW1_PCMD_SHIFT);
+	else
+		fdirdp->dtype_cmd_cntindex |= rte_cpu_to_le_32(
+				I40E_FILTER_PROGRAM_DESC_PCMD_REMOVE <<
+				I40E_TXD_FLTR_QW1_PCMD_SHIFT);
+
+	if (fdir_action->drop)
+		dest = I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET;
+	else
+		dest = I40E_FILTER_PROGRAM_DESC_DEST_DIRECT_PACKET_QINDEX;
+	fdirdp->dtype_cmd_cntindex |= rte_cpu_to_le_32((dest <<
+				I40E_TXD_FLTR_QW1_DEST_SHIFT) &
+				I40E_TXD_FLTR_QW1_DEST_MASK);
+
+	fdirdp->dtype_cmd_cntindex |=
+		rte_cpu_to_le_32((fdir_action->report_status<<
+				I40E_TXD_FLTR_QW1_FD_STATUS_SHIFT) &
+				I40E_TXD_FLTR_QW1_FD_STATUS_MASK);
+
+	fdirdp->dtype_cmd_cntindex |=
+			rte_cpu_to_le_32(I40E_TXD_FLTR_QW1_CNT_ENA_MASK);
+	if (fdir_action->cnt_idx != 0)
+		fdirdp->dtype_cmd_cntindex |=
+				rte_cpu_to_le_32((fdir_action->cnt_idx <<
+				I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) &
+				I40E_TXD_FLTR_QW1_CNTINDEX_MASK);
+	else
+		fdirdp->dtype_cmd_cntindex |=
+				rte_cpu_to_le_32((pf->fdir.match_counter_index <<
+				I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) &
+				I40E_TXD_FLTR_QW1_CNTINDEX_MASK);
+
+	fdirdp->fd_id = rte_cpu_to_le_32(filter->soft_id);
+	txq->tx_tail++;
+	if (txq->tx_tail >= txq->nb_tx_desc)
+		txq->tx_tail = 0;
+
+	PMD_DRV_LOG(INFO, "filling transmit descriptor.");
+	txdp = &(txq->tx_ring[txq->tx_tail]);
+	txdp->buffer_addr = rte_cpu_to_le_64(pf->fdir.dma_addr);
+	td_cmd = I40E_TX_DESC_CMD_EOP |
+		 I40E_TX_DESC_CMD_RS  |
+		 I40E_TX_DESC_CMD_DUMMY;
+
+	txdp->cmd_type_offset_bsz =
+		i40e_build_ctob(td_cmd, 0, I40E_FDIR_PKT_LEN, 0);
+
+	txq->tx_tail++;
+	if (txq->tx_tail >= txq->nb_tx_desc)
+		txq->tx_tail = 0;
+	/* Update the tx tail register */
+	rte_wmb();
+	I40E_PCI_REG_WRITE(txq->qtx_tail, txq->tx_tail);
+
+	for (i = 0; i < I40E_FDIR_WAIT_COUNT; i++) {
+		rte_delay_us(I40E_FDIR_WAIT_INTERVAL_US);
+		if (txdp->cmd_type_offset_bsz &
+				rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE))
+			break;
+	}
+	if (i >= I40E_FDIR_WAIT_COUNT) {
+		PMD_DRV_LOG(ERR, "Failed to program FDIR filter:"
+			    " timeout to get DD on tx queue.");
+		return -ETIMEDOUT;
+	}
+	/* totally delay 10 ms to check programming status*/
+	rte_delay_us((I40E_FDIR_WAIT_COUNT - i) * I40E_FDIR_WAIT_INTERVAL_US);
+	if (i40e_check_fdir_programming_status(rxq) < 0) {
+		PMD_DRV_LOG(ERR, "Failed to program FDIR filter:"
+			    " programming status reported.");
+		return -ENOSYS;
+	}
+
+	return 0;
+}
+
+/*
+ * i40e_fdir_ctrl_func - deal with all operations on flow director.
+ * @pf: board private structure
+ * @filter_op:operation will be taken.
+ * @arg: a pointer to specific structure corresponding to the filter_op
+ */
+int
+i40e_fdir_ctrl_func(struct i40e_pf *pf, enum rte_filter_op filter_op, void *arg)
+{
+	int ret = 0;
+
+	if (arg == NULL && filter_op != RTE_ETH_FILTER_NOP &&
+	    filter_op != RTE_ETH_FILTER_FLUSH)
+		return -EINVAL;
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_NOP:
+		if (!(pf->flags & I40E_FLAG_FDIR))
+			ret = -ENOTSUP;
+		break;
+	case RTE_ETH_FILTER_ADD:
+		ret = i40e_add_del_fdir_filter(pf,
+			(struct rte_eth_fdir_filter *)arg,
+			TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = i40e_add_del_fdir_filter(pf,
+			(struct rte_eth_fdir_filter *)arg,
+			FALSE);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unknown operation %u.", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
-- 
1.8.1.4

  parent reply	other threads:[~2014-10-22  0:53 UTC|newest]

Thread overview: 123+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-26  6:03 [dpdk-dev] [PATCH v3 00/20] Support flow director programming on Fortville Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 01/20] i40e: set up and initialize flow director Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 02/20] i40e: tear down " Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 03/20] i40e: initialize flexible payload setting Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 04/20] lib/librte_ether: new filter APIs definition Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 05/20] lib/librte_ether: define structures for adding/deleting flow director Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 06/20] i40e: implement operations to add/delete " Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 07/20] app/test-pmd: add test commands to add/delete flow director filter Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 08/20] i40e: match counter for flow director Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 09/20] i40e: report flow director match info to mbuf Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 10/20] lib/librte_ether: define structures for getting flow director information Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 11/20] i40e: implement operations to get fdir info Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 12/20] app/test-pmd: display fdir statistics Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 13/20] i40e: implement operation to flush flow director table Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 14/20] app/test-pmd: add test command " Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 15/20] lib/librte_ether: define structures for configuring flexible payload Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v316/20] i40e: implement operations to configure " Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 17/20] app/test-pmd: add test command " Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 18/20] lib/librte_ether: define structures for configuring flex masks Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 19/20] i40e: implement operations to configure flexible masks Jingjing Wu
2014-09-26  6:03 ` [dpdk-dev] [PATCH v3 20/20] app/test-pmd: add test command " Jingjing Wu
2014-10-13 15:58   ` De Lara Guarch, Pablo
2014-10-22  1:01 ` [dpdk-dev] [PATCH v4 00/21] Support flow director programming on Fortville Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 01/21] i40e: set up and initialize flow director Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 02/21] i40e: tear down " Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 03/21] i40e: initialize flexible payload setting Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 04/21] ethdev: define structures for adding/deleting flow director Jingjing Wu
2014-10-27 16:57     ` Thomas Monjalon
2014-10-28  1:18       ` Wu, Jingjing
2014-10-28 13:17         ` Thomas Monjalon
2014-10-29  1:29           ` Wu, Jingjing
2014-10-22  1:01   ` Jingjing Wu [this message]
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 06/21] testpmd: add test commands to add/delete flow director filter Jingjing Wu
2014-10-28 13:23     ` Thomas Monjalon
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 07/21] i40e: match counter for flow director Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 08/21] mbuf: extend fdir field Jingjing Wu
2014-10-28 13:28     ` Thomas Monjalon
2014-10-29  1:45       ` Wu, Jingjing
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 09/21] i40e: report flow director match info to mbuf Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 10/21] testpmd: print extended fdir info in mbuf Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 11/21] ethdev: define structures for getting flow director information Jingjing Wu
2014-10-28 13:44     ` Thomas Monjalon
2014-10-29  2:10       ` Wu, Jingjing
2014-10-29  9:48         ` Thomas Monjalon
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 12/21] i40e: implement operations to get fdir info Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 13/21] testpmd: display fdir statistics Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 14/21] i40e: implement operation to flush flow director table Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 15/21] testpmd: add test command " Jingjing Wu
2014-10-28 13:53     ` Thomas Monjalon
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 16/21] ethdev: define structures for configuring flexible payload Jingjing Wu
2014-10-28 14:14     ` Thomas Monjalon
2014-10-29  3:21       ` Wu, Jingjing
2014-10-29  9:55         ` Thomas Monjalon
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 17/21] i40e: implement operations to configure " Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 18/21] testpmd: add test command " Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 19/21] ethdev: define structures for configuring flex masks Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 20/21] i40e: implement operations to configure flexible masks Jingjing Wu
2014-10-22  1:01   ` [dpdk-dev] [PATCH v4 21/21] testpmd: add test command " Jingjing Wu
2014-10-28 14:18     ` Thomas Monjalon
2014-10-29  2:35       ` Wu, Jingjing
2014-10-27 15:22   ` [dpdk-dev] [PATCH v4 00/21] Support flow director programming on Fortville Thomas Monjalon
2014-10-28  0:48   ` Zhang, Helin
2014-10-30  7:26   ` [dpdk-dev] [PATCH v5 " Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 01/21] i40e: set up and initialize flow director Jingjing Wu
2014-10-30  8:25       ` Wu, Jingjing
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 02/21] i40e: tear down " Jingjing Wu
2014-11-19  7:53       ` Cao, Min
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 03/21] i40e: initialize flexible payload setting Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 04/21] ethdev: define structures for adding/deleting flow director Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 05/21] i40e: implement operations to add/delete " Jingjing Wu
2014-11-05 21:18       ` De Lara Guarch, Pablo
2014-11-13  9:50         ` Thomas Monjalon
2014-11-13 11:36           ` Wu, Jingjing
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 06/21] testpmd: add test commands to add/delete flow director filter Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 07/21] i40e: match counter for flow director Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 08/21] mbuf: extend fdir field Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 09/21] i40e: report flow director match info to mbuf Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 10/21] testpmd: print extended fdir info in mbuf Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 11/21] ethdev: define structures for getting flow director information Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 12/21] i40e: implement operations to get fdir info Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 13/21] testpmd: display fdir statistics Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 14/21] i40e: implement operation to flush flow director table Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 15/21] testpmd: add test command " Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 16/21] ethdev: define structures for configuring flexible payload Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 17/21] i40e: implement operations to configure " Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 18/21] testpmd: add test command " Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 19/21] ethdev: define structures for configuring flex masks Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 20/21] i40e: implement operations to configure flexible masks Jingjing Wu
2014-10-30  7:26     ` [dpdk-dev] [PATCH v5 21/21] testpmd: add test command " Jingjing Wu
2014-10-30  8:07     ` [dpdk-dev] [PATCH v5 01/21] i40e: set up and initialize flow director Jingjing Wu
2014-11-21  0:46     ` [dpdk-dev] [PATCH v6 00/22] Support flow director programming on Fortville Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 01/22] i40e: set up and initialize flow director Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 02/22] i40e: tear down " Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 03/22] i40e: initialize flexible payload setting Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 04/22] ethdev: define structures for adding/deleting flow director Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 05/22] i40e: define functions for transition between flow_type and pctype Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 06/22] i40e: implement operations to add/delete flow director Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 07/22] testpmd: add test commands to add/delete flow director filter Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 08/22] i40e: match counter for flow director Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 09/22] mbuf: extend fdir field Jingjing Wu
2014-11-21 17:03         ` Chilikin, Andrey
2014-11-21 19:34           ` Ananyev, Konstantin
2014-11-21 19:37             ` Chilikin, Andrey
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 10/22] i40e: report flow director match info to mbuf Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 11/22] testpmd: print extended fdir info in mbuf Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 12/22] i40e: implement operation to flush flow director table Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 13/22] testpmd: add test command " Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 14/22] ethdev: define structures for getting flow director information Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 15/22] i40e: implement operations to get fdir info Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 16/22] ethdev: define structures for getting flow director statistics Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 17/22] i40e: implement operations to get fdir statistics Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 18/22] testpmd: display fdir info Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 19/22] ethdev: add flexible payload setting in eth_conf Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 20/22] i40e: take flow director flexible payload configuration Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 21/22] testpmd: add test command to configure flexible mask Jingjing Wu
2014-11-21  0:46       ` [dpdk-dev] [PATCH v6 22/22] testpmd: add test command to configure flexible payload Jingjing Wu
2014-11-21 11:34       ` [dpdk-dev] [PATCH v6 00/22] Support flow director programming on Fortville Ananyev, Konstantin
2014-11-24 23:20         ` Thomas Monjalon
2014-11-25  4:51           ` Wu, Jingjing
2014-11-25  9:23             ` Thomas Monjalon
2014-10-30  7:34   ` [dpdk-dev] [PATCH v4 00/21] " Cao, Min
2014-11-19  7:53   ` Cao, Min
2014-10-30  7:12 ` [dpdk-dev] [PATCH v3 00/20] " Cao, Min

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1413939687-11177-6-git-send-email-jingjing.wu@intel.com \
    --to=jingjing.wu@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git