DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] igb: integrate flex filter to new API
       [not found] <igbv1>
@ 2015-01-30  4:48 ` zhida zang
  2015-02-15  4:07   ` [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver " Jingjing Wu
  0 siblings, 1 reply; 14+ messages in thread
From: zhida zang @ 2015-01-30  4:48 UTC (permalink / raw)
  To: dev

changes:
igb: remove old functions that deal with flex filter
igb: add new functions that deal with flex filter(fit for new API)
testpmd: change the entry for flex filter in cmdline
testpmd: change function call to get flex filter in config
doc: change doc that describes how to use flex filter related functions

Signed-off-by: Zhida Zang <zhida.zang@intel.com>
---
 app/test-pmd/cmdline.c                      | 244 ++++++++++----------
 app/test-pmd/config.c                       |  37 ++--
 app/test-pmd/testpmd.h                      |   2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++---
 lib/librte_ether/rte_eth_ctrl.h             |  20 ++
 lib/librte_pmd_e1000/e1000_ethdev.h         |  20 ++
 lib/librte_pmd_e1000/igb_ethdev.c           | 331 +++++++++++++++++-----------
 7 files changed, 410 insertions(+), 300 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4beb404..2f99d23 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -691,14 +691,19 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"get_syn_filter (port_id) "
 			"    get syn filter info.\n\n"
 
-			"add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)"
-			" priority (prio_value) queue (queue_id) index (idx)\n"
+			"flex_filter add (port_id) len (len_value)"
+			" bytes (bytes_string) mask (mask_value)"
+			" priority (prio_value) queue (queue_id)\n"
 			"    add a flex filter.\n\n"
 
-			"remove_flex_filter (port_id) index (idx)\n"
-			"    remove a flex filter.\n\n"
+			"flex_filter del (port_id) len (len_value)"
+			" bytes (bytes_string) mask (mask_value)"
+			" priority (prio_value)\n"
+			"    del a flex filter.\n\n"
 
-			"get_flex_filter (port_id) index (idx)\n"
+			"flex_filter get (port_id) len (len_value)"
+			" bytes (bytes_string) mask (mask_value)"
+			"priority (prio_value)\n"
 			"    get info of a flex filter.\n\n"
 
 			"flow_director_filter (port_id) (add|del)"
@@ -7723,9 +7728,10 @@ cmdline_parse_inst_t cmd_get_5tuple_filter = {
 	},
 };
 
-/* *** ADD/REMOVE A flex FILTER *** */
+/* *** Add/Del/Get flex filter *** */
 struct cmd_flex_filter_result {
 	cmdline_fixed_string_t filter;
+	cmdline_fixed_string_t ops;
 	uint8_t port_id;
 	cmdline_fixed_string_t len;
 	uint8_t len_value;
@@ -7737,8 +7743,6 @@ struct cmd_flex_filter_result {
 	uint8_t priority_value;
 	cmdline_fixed_string_t queue;
 	uint16_t queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t index_value;
 };
 
 static int xdigit2val(unsigned char c)
@@ -7759,105 +7763,101 @@ cmd_flex_filter_parsed(void *parsed_result,
 			  __attribute__((unused)) void *data)
 {
 	int ret = 0;
-	struct rte_flex_filter filter;
+	struct rte_eth_flex_filter filter;
 	struct cmd_flex_filter_result *res = parsed_result;
 	char *bytes_ptr, *mask_ptr;
 	uint16_t len, i, j;
 	char c;
-	int val, mod = 0;
-	uint32_t dword = 0;
+	int val;
 	uint8_t byte = 0;
 	uint8_t hex = 0;
 
-	if (!strcmp(res->filter, "add_flex_filter")) {
-		if (res->len_value > 128) {
-			printf("the len exceed the max length 128\n");
-			return;
-		}
-		memset(&filter, 0, sizeof(struct rte_flex_filter));
-		filter.len = res->len_value;
-		filter.priority = res->priority_value;
-		bytes_ptr = res->bytes_value;
-		mask_ptr = res->mask_value;
-
-		j = 0;
-		 /* translate bytes string to uint_32 array. */
-		if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
-			(bytes_ptr[1] == 'X')))
-			bytes_ptr += 2;
-		len = strnlen(bytes_ptr, res->len_value * 2);
-		if (len == 0 || (len % 8 != 0)) {
-			printf("please check len and bytes input\n");
+	if (res->len_value > 128) {
+		printf("the len exceed the max length 128\n");
+		return;
+	}
+	memset(&filter, 0, sizeof(struct rte_eth_flex_filter));
+	filter.len = res->len_value;
+	filter.priority = res->priority_value;
+	filter.queue = res->queue_id;
+	bytes_ptr = res->bytes_value;
+	mask_ptr = res->mask_value;
+
+	j = 0;
+	 /* translate bytes string to uint_32 array. */
+	if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
+		(bytes_ptr[1] == 'X')))
+		bytes_ptr += 2;
+	len = strnlen(bytes_ptr, res->len_value * 2);
+	if (len == 0 || (len % 8 != 0)) {
+		printf("please check len and bytes input\n");
+		return;
+	}
+	for (i = 0; i < len; i++) {
+		c = bytes_ptr[i];
+		if (isxdigit(c) == 0) {
+			/* invalid characters. */
+			printf("invalid input\n");
 			return;
 		}
-		for (i = 0; i < len; i++) {
-			c = bytes_ptr[i];
-			if (isxdigit(c) == 0) {
-				/* invalid characters. */
-				printf("invalid input\n");
-				return;
-			}
-			val = xdigit2val(c);
-			mod = i % 8;
-			if (i % 2) {
-				byte |= val;
-				dword |= byte << (4 * mod - 4);
-				byte = 0;
-			} else
-				byte |= val << 4;
-			if (mod == 7) {
-				filter.dwords[j] = dword;
-				printf("dwords[%d]:%08x ", j, filter.dwords[j]);
-				j++;
-				dword = 0;
-			}
-		}
-		printf("\n");
-		 /* translate mask string to uint8_t array. */
-		j = 0;
-		if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
-			(mask_ptr[1] == 'X')))
-			mask_ptr += 2;
-		len = strnlen(mask_ptr, (res->len_value+3)/4);
-		if (len == 0) {
+		val = xdigit2val(c);
+		if (i % 2) {
+			byte |= val;
+			filter.bytes[j] = byte;
+			printf("bytes[%d]:%02x ", j, filter.bytes[j]);
+			j++;
+			byte = 0;
+		} else
+			byte |= val << 4;
+	}
+	printf("\n");
+	 /* translate mask string to uint8_t array. */
+	j = 0;
+	if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
+		(mask_ptr[1] == 'X')))
+		mask_ptr += 2;
+	len = strnlen(mask_ptr, (res->len_value+3)/4);
+	if (len == 0) {
+		printf("invalid input\n");
+		return;
+	}
+	for (i = 0; i < len; i++) {
+		c = mask_ptr[i];
+		if (isxdigit(c) == 0) {
+			/* invalid characters. */
 			printf("invalid input\n");
 			return;
 		}
-		for (i = 0; i < len; i++) {
-			c = mask_ptr[i];
-			if (isxdigit(c) == 0) {
-				/* invalid characters. */
-				printf("invalid input\n");
-				return;
-			}
-			val = xdigit2val(c);
-			hex |= (uint8_t)(val & 0x8) >> 3;
-			hex |= (uint8_t)(val & 0x4) >> 1;
-			hex |= (uint8_t)(val & 0x2) << 1;
-			hex |= (uint8_t)(val & 0x1) << 3;
-			if (i % 2) {
-				byte |= hex << 4;
-				filter.mask[j] = byte;
-				printf("mask[%d]:%02x ", j, filter.mask[j]);
-				j++;
-				byte = 0;
-			} else
-				byte |= hex;
-			hex = 0;
-		}
-		printf("\n");
-		printf("call function rte_eth_dev_add_flex_filter: "
-			"index = %d, queue-id = %d, len = %d, priority = %d\n",
-			res->index_value, res->queue_id,
-			filter.len, filter.priority);
-		ret = rte_eth_dev_add_flex_filter(res->port_id, res->index_value,
-				&filter, res->queue_id);
+		val = xdigit2val(c);
+		hex |= (uint8_t)(val & 0x8) >> 3;
+		hex |= (uint8_t)(val & 0x4) >> 1;
+		hex |= (uint8_t)(val & 0x2) << 1;
+		hex |= (uint8_t)(val & 0x1) << 3;
+		if (i % 2) {
+			byte |= hex << 4;
+			filter.mask[j] = byte;
+			printf("mask[%d]:%02x ", j, filter.mask[j]);
+			j++;
+			byte = 0;
+		} else
+			byte |= hex;
+		hex = 0;
+	}
+	printf("\n");
 
-	} else if (!strcmp(res->filter, "remove_flex_filter"))
-		ret = rte_eth_dev_remove_flex_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_flex_filter"))
-		get_flex_filter(res->port_id, res->index_value);
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_FLEXIBLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+
+	else if (!strcmp(res->ops, "del"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_FLEXIBLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
+	else if (!strcmp(res->ops, "get"))
+		get_flex_filter(res->port_id, &filter);
 
 	if (ret < 0)
 		printf("flex filter setting error: (%s)\n", strerror(-ret));
@@ -7896,21 +7896,25 @@ cmdline_parse_token_string_t cmd_flex_filter_queue =
 cmdline_parse_token_num_t cmd_flex_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_flex_filter_index =
+cmdline_parse_token_string_t cmd_flex_filter_add =
 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_flex_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
-				index_value, UINT16);
-cmdline_parse_token_string_t cmd_flex_filter_add_filter =
+				ops, "add");
+cmdline_parse_token_string_t cmd_flex_filter_del =
+	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+				ops, "del");
+cmdline_parse_token_string_t cmd_flex_filter_get =
 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "add_flex_filter");
+				ops, "get");
+cmdline_parse_token_string_t cmd_flex_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+				filter, "flex_filter");
 cmdline_parse_inst_t cmd_add_flex_filter = {
 	.f = cmd_flex_filter_parsed,
 	.data = NULL,
 	.help_str = "add a flex filter",
 	.tokens = {
-		(void *)&cmd_flex_filter_add_filter,
+		(void *)&cmd_flex_filter_filter,
+		(void *)&cmd_flex_filter_add,
 		(void *)&cmd_flex_filter_port_id,
 		(void *)&cmd_flex_filter_len,
 		(void *)&cmd_flex_filter_len_value,
@@ -7922,40 +7926,44 @@ cmdline_parse_inst_t cmd_add_flex_filter = {
 		(void *)&cmd_flex_filter_priority_value,
 		(void *)&cmd_flex_filter_queue,
 		(void *)&cmd_flex_filter_queue_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
 		NULL,
 	},
 };
-
-cmdline_parse_token_string_t cmd_flex_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "remove_flex_filter");
 cmdline_parse_inst_t cmd_remove_flex_filter = {
 	.f = cmd_flex_filter_parsed,
 	.data = NULL,
 	.help_str = "remove a flex filter",
 	.tokens = {
-		(void *)&cmd_flex_filter_remove_filter,
+		(void *)&cmd_flex_filter_filter,
+		(void *)&cmd_flex_filter_del,
 		(void *)&cmd_flex_filter_port_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
+		(void *)&cmd_flex_filter_len,
+		(void *)&cmd_flex_filter_len_value,
+		(void *)&cmd_flex_filter_bytes,
+		(void *)&cmd_flex_filter_bytes_value,
+		(void *)&cmd_flex_filter_mask,
+		(void *)&cmd_flex_filter_mask_value,
+		(void *)&cmd_flex_filter_priority,
+		(void *)&cmd_flex_filter_priority_value,
 		NULL,
 	},
 };
-
-cmdline_parse_token_string_t cmd_flex_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "get_flex_filter");
 cmdline_parse_inst_t cmd_get_flex_filter = {
 	.f = cmd_flex_filter_parsed,
 	.data = NULL,
 	.help_str = "get a flex filter",
 	.tokens = {
-		(void *)&cmd_flex_filter_get_filter,
+		(void *)&cmd_flex_filter_filter,
+		(void *)&cmd_flex_filter_get,
 		(void *)&cmd_flex_filter_port_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
+		(void *)&cmd_flex_filter_len,
+		(void *)&cmd_flex_filter_len_value,
+		(void *)&cmd_flex_filter_bytes,
+		(void *)&cmd_flex_filter_bytes_value,
+		(void *)&cmd_flex_filter_mask,
+		(void *)&cmd_flex_filter_mask_value,
+		(void *)&cmd_flex_filter_priority,
+		(void *)&cmd_flex_filter_priority_value,
 		NULL,
 	},
 };
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index c40f819..8a44e4a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2252,36 +2252,43 @@ get_5tuple_filter(uint8_t port_id, uint16_t index)
 			filter.priority, filter.tcp_flags, rx_queue);
 	}
 }
-void
-get_flex_filter(uint8_t port_id, uint16_t index)
 
+void
+get_flex_filter(uint8_t port_id, struct rte_eth_flex_filter *filter)
 {
-	struct rte_flex_filter filter;
+	struct rte_eth_flex_filter flex_filter;
 	int ret = 0;
-	uint16_t rx_queue;
 	int i, j;
 
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_flex_filter(port_id, index,
-				&filter, &rx_queue);
+	memset(&flex_filter, 0, sizeof(flex_filter));
+	flex_filter.len = filter->len;
+	memcpy(flex_filter.bytes, filter->bytes, 128);
+	memcpy(flex_filter.mask, filter->mask, 16);
+	flex_filter.priority = filter->priority;
+	ret = rte_eth_dev_filter_ctrl(port_id,
+					RTE_ETH_FILTER_FLEXIBLE,
+					RTE_ETH_FILTER_GET,
+					&flex_filter);
 	if (ret < 0) {
 		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
+			printf("filter does not exist\n");
 		else
 			printf("get flex filter fails(%s)\n", strerror(-ret));
 		return;
 	} else {
-		printf("filter[%d]: ", index);
-		printf("\n    length: %d", filter.len);
-		printf("\n    dword[]: 0x");
-		for (i = 0; i < 32; i++)
-			printf("%08x ", (unsigned)rte_be_to_cpu_32(filter.dwords[i]));
+		printf("filter: ");
+		printf("\n    length: %d", flex_filter.len);
+		printf("\n    byte[]: 0x");
+		for (i = 0; i < 8; i++)
+			printf("%02x ",
+				(unsigned)flex_filter.bytes[i]);
 		printf("\n    mask[]: 0b");
 		for (i = 0; i < 16; i++) {
 			for (j = 0; j < 8; j++)
-				printf("%c", (filter.mask[i] & (1 << j)) ? '1' : '0');
+				printf("%c", (flex_filter.mask[i] & (1 << j))
+					? '1' : '0');
 		}
 		printf("\n    priority: %d    queue: %d\n",
-			filter.priority, rx_queue);
+			flex_filter.priority, flex_filter.queue);
 	}
 }
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8f5e6c7..3f9697f 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -557,7 +557,7 @@ void get_syn_filter(uint8_t port_id);
 void get_ethertype_filter(uint8_t port_id, uint16_t index);
 void get_2tuple_filter(uint8_t port_id, uint16_t index);
 void get_5tuple_filter(uint8_t port_id, uint16_t index);
-void get_flex_filter(uint8_t port_id, uint16_t index);
+void get_flex_filter(uint8_t port_id, struct rte_eth_flex_filter *filter);
 int port_id_is_invalid(portid_t port_id);
 int rx_queue_id_is_invalid(queueid_t rxq_id);
 int tx_queue_id_is_invalid(queueid_t txq_id);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 218835a..0324fc3 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1595,15 +1595,18 @@ Example:
 
     syn filter: on, priority: high, queue: 3
 
-add_flex_filter
+flex_filter
 ~~~~~~~~~~~~~~~
 
 Add a Flex filter,
 which recognizes any arbitrary pattern within the first 128 bytes of the packet
 and routes packets into one of the receive queues.
+or
+Del(get) a Flex filter,
+which recognizes any arbitrary pattern within the first 128 bytes of the packet
 
-add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)
-priority (prio_value) queue (queue_id) index (idx)
+flex_filter (add|del|get) (port_id) len (len_value) bytes (bytes_string)
+mask (mask_value) priority (prio_value) [queue (queue_id)]
 
 The available information parameters are:
 
@@ -1617,49 +1620,18 @@ The available information parameters are:
 
 *   prio_value: the priority of this filter.
 
-*   queue_id: The receive queue associated with this Flex filter.
-
-*   index: the index of this Flex filter
+*   queue_id: The receive queue associated with this Flex filter.(used when add
+while del|get not)
 
 Example:
 
 .. code-block:: console
 
-   testpmd> add_flex_filter 0 len 16 bytes 0x00000000000000000000000008060000 mask 000C priority 3 queue 3 index 0
-
-Assign a packet whose 13th and 14th bytes are 0x0806 to queue 3.
-
-remove_flex_filter
-~~~~~~~~~~~~~~~~~~
-
-Remove a Flex filter
+   testpmd> flex_filter add 0 len 16 bytes 0x00000000000000000000000008060000
+        mask 000C priority 3 queue 3
 
-remove_flex_filter (port_id) index (idx)
+   testpmd> flex_filter del 0 len 16 bytes 0x00000000000000000000000008060000
+        mask 000C priority 3
 
-get_flex_filter
-~~~~~~~~~~~~~~~
-
-Get and display a Flex filter
-
-get_flex_filter (port_id) index (idx)
-
-Example:
-
-.. code-block:: console
-
-    testpmd> get_flex_filter 0 index 0
-
-    filter[0]:
-
-        length: 16
-
-        dword[]: 0x00000000 00000000 00000000 08060000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000
-
-        mask[]:
-    0b0000000000001100000000000000000000000000000000000000000000000000000000
-    0000000000000000000000000000000000000000000000000000000000
-
-        priority: 3   queue: 3
+   testpmd> flex_filter get 0 len 16 bytes 0x00000000000000000000000008060000
+        mask 000C priority 3
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 5d9c387..03c6b66 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -55,6 +55,7 @@ enum rte_filter_type {
 	RTE_ETH_FILTER_ETHERTYPE,
 	RTE_ETH_FILTER_TUNNEL,
 	RTE_ETH_FILTER_FDIR,
+	RTE_ETH_FILTER_FLEXIBLE,
 	RTE_ETH_FILTER_MAX
 };
 
@@ -116,6 +117,25 @@ struct rte_eth_ethertype_filter {
 	uint16_t queue;               /**< Queue assigned to when match*/
 };
 
+#define RTE_FLEX_FILTER_MAXLEN	128	/**< bytes to use in flex filter. */
+#define RTE_FLEX_FILTER_MASK_SIZE	\
+	(RTE_ALIGN(RTE_FLEX_FILTER_MAXLEN, sizeof(char)) / sizeof(char))
+					/**< mask bytes in flex filter. */
+
+/**
+ *  A structure used to define the flex filter entry
+ *  to support RTE_ETH_FILTER_FLEXIBLE with RTE_ETH_FILTER_ADD,
+ *  RTE_ETH_FILTER_DELETE and RTE_ETH_FILTER_GET operations.
+ */
+struct rte_eth_flex_filter {
+	uint16_t len;
+	uint8_t bytes[RTE_FLEX_FILTER_MAXLEN];  /**< flex bytes in big endian.*/
+	uint8_t mask[RTE_FLEX_FILTER_MASK_SIZE];    /**< if mask bit is 1b, do
+					not compare corresponding byte. */
+	uint8_t priority;
+	uint16_t queue;       /**< Queue assigned to when match. */
+};
+
 /**
  * Tunneled type.
  */
diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index d155e77..c054aaf 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -131,6 +131,24 @@ struct e1000_vf_info {
 	uint16_t tx_rate;
 };
 
+TAILQ_HEAD(e1000_flex_filter_list, e1000_flex_filter);
+
+struct e1000_flex_filter_info {
+	uint16_t len;
+	uint32_t dwords[32];  /**< flex bytes in big endian. */
+	uint8_t mask[16];     /**< if mask bit is 1b, do not compare
+				   corresponding byte in dwords. */
+	uint8_t priority;
+};
+
+/* Flex filter structure */
+struct e1000_flex_filter {
+	TAILQ_ENTRY(e1000_flex_filter) entries;
+	uint16_t index; /* index of flex filter */
+	struct e1000_flex_filter_info filter_info;
+	uint16_t queue; /* rx queue assigned to */
+};
+
 /*
  * Structure to store filters' info.
  */
@@ -138,6 +156,8 @@ struct e1000_filter_info {
 	uint8_t ethertype_mask; /* Bit mask for every used ethertype filter */
 	/* store used ethertype filters*/
 	uint16_t ethertype_filters[E1000_MAX_ETQF_FILTERS];
+	uint8_t flex_mask;	/* Bit mask for every used flex filter */
+	struct e1000_flex_filter_list flex_list;
 };
 
 /*
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 2a268b8..eaa8689 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -162,14 +162,14 @@ static int eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
 static int eth_igb_get_2tuple_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int eth_igb_get_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue);
+static int eth_igb_flex_filter_set(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter,
+			bool add);
+static int eth_igb_flex_filter_get(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter);
+static int eth_igb_flex_filter_handle(struct rte_eth_dev *dev,
+			enum rte_filter_op filter_op,
+			void *arg);
 static int eth_igb_add_5tuple_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_5tuple_filter *filter, uint16_t rx_queue);
@@ -271,9 +271,6 @@ static struct eth_dev_ops eth_igb_ops = {
 	.add_2tuple_filter       = eth_igb_add_2tuple_filter,
 	.remove_2tuple_filter    = eth_igb_remove_2tuple_filter,
 	.get_2tuple_filter       = eth_igb_get_2tuple_filter,
-	.add_flex_filter         = eth_igb_add_flex_filter,
-	.remove_flex_filter      = eth_igb_remove_flex_filter,
-	.get_flex_filter         = eth_igb_get_flex_filter,
 	.add_5tuple_filter       = eth_igb_add_5tuple_filter,
 	.remove_5tuple_filter    = eth_igb_remove_5tuple_filter,
 	.get_5tuple_filter       = eth_igb_get_5tuple_filter,
@@ -470,6 +467,8 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 	struct e1000_vfta * shadow_vfta =
 			E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 
 	pci_dev = eth_dev->pci_dev;
@@ -601,6 +600,9 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	igb_intr_enable(eth_dev);
 
+	TAILQ_INIT(&filter_info->flex_list);
+	filter_info->flex_mask = 0;
+
 	return 0;
 
 err_late:
@@ -926,7 +928,10 @@ static void
 eth_igb_stop(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 	struct rte_eth_link link;
+	struct e1000_flex_filter *p_flex;
 
 	igb_intr_disable(hw);
 	igb_pf_reset_hw(hw);
@@ -949,6 +954,13 @@ eth_igb_stop(struct rte_eth_dev *dev)
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_igb_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all flex filters of the device */
+	while ((p_flex = TAILQ_FIRST(&filter_info->flex_list))) {
+		TAILQ_REMOVE(&filter_info->flex_list, p_flex, entries);
+		rte_free(p_flex);
+	}
+	filter_info->flex_mask = 0;
 }
 
 static void
@@ -2652,161 +2664,229 @@ eth_igb_get_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
 	return -ENOENT;
 }
 
-/*
- * add a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that will be added.
- * rx_queue: the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *     - On failure, a negative value.
+/* add/del/get a flex filter
  */
+static inline struct e1000_flex_filter *
+eth_igb_flex_filter_lookup(struct e1000_flex_filter_list *filter_list,
+			struct e1000_flex_filter_info *key)
+{
+	struct e1000_flex_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_flex_filter_info)) == 0)
+			return it;
+	}
+
+	return NULL;
+}
+
 static int
-eth_igb_add_flex_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue)
+eth_igb_flex_filter_set(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter,
+			bool add)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_flex_filter *flex_filter, *it;
 	uint32_t wufc, en_bits = 0;
 	uint32_t queueing = 0;
 	uint32_t reg_off = 0;
 	uint8_t i, j = 0;
 
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	flex_filter = rte_zmalloc("e1000_flex_filter",
+			sizeof(struct e1000_flex_filter), 0);
+	if (flex_filter == NULL)
+		return -ENOMEM;
 
-	if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
-		filter->len % 8 != 0 ||
-		filter->priority > E1000_MAX_FLEX_FILTER_PRI)
-		return -EINVAL;
+	flex_filter->filter_info.len = filter->len;
+	flex_filter->filter_info.priority = filter->priority;
+	memcpy(flex_filter->filter_info.dwords, filter->bytes, filter->len);
+	memcpy(flex_filter->filter_info.mask, filter->mask,
+			RTE_ALIGN(filter->len, sizeof(char)) / sizeof(char));
 
 	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	en_bits = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
-	if ((wufc & en_bits) == en_bits)
-		return -EINVAL;  /* the filter is in use. */
+	if (flex_filter->index < E1000_MAX_FHFT)
+		reg_off = E1000_FHFT(flex_filter->index);
+	else
+		reg_off = E1000_FHFT_EXT(flex_filter->index - E1000_MAX_FHFT);
 
-	E1000_WRITE_REG(hw, E1000_WUFC,
-		wufc | E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index));
+	if (add) {
+		if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN
+			|| filter->len % 8 != 0 ||
+			filter->priority > E1000_MAX_FLEX_FILTER_PRI)
+			return -EINVAL;
+
+		if (eth_igb_flex_filter_lookup(&filter_info->flex_list,
+				&flex_filter->filter_info) != NULL) {
+			PMD_DRV_LOG(ERR, "filter exists.");
+			rte_free(flex_filter);
+			return -EEXIST;
+		}
 
-	j = 0;
-	if (index < E1000_MAX_FHFT)
-		reg_off = E1000_FHFT(index);
-	else
-		reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
-
-	for (i = 0; i < 16; i++) {
-		E1000_WRITE_REG(hw, reg_off + i*4*4, filter->dwords[j]);
-		E1000_WRITE_REG(hw, reg_off + (i*4+1)*4, filter->dwords[++j]);
-		E1000_WRITE_REG(hw, reg_off + (i*4+2)*4,
-				(uint32_t)filter->mask[i]);
-		++j;
-	}
-	queueing |= filter->len |
-		(rx_queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) |
-		(filter->priority << E1000_FHFT_QUEUEING_PRIO_SHIFT);
-	E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET, queueing);
-	return 0;
-}
+		flex_filter->queue = filter->queue;
 
-/*
- * remove a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
-static int
-eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
-				uint16_t index)
-{
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t wufc, reg_off = 0;
-	uint8_t i;
+		/*
+		 * look for an unused flex filter index
+		 * and insert the filter into the list.
+		 */
+		for (i = 0; i < E1000_MAX_FLEXIBLE_FILTERS; i++) {
+			if (!(filter_info->flex_mask & (1 << i))) {
+				filter_info->flex_mask |= 1 << i;
+				flex_filter->index = i;
+				TAILQ_INSERT_TAIL(&filter_info->flex_list,
+					flex_filter,
+					entries);
+				break;
+			}
+		}
+		if (i >= E1000_MAX_FLEXIBLE_FILTERS) {
+			PMD_DRV_LOG(ERR, "flex filters are full.");
+			rte_free(flex_filter);
+			return -ENOSYS;
+		}
 
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+		en_bits = E1000_WUFC_FLEX_HQ |
+				(E1000_WUFC_FLX0 << flex_filter->index);
+		if ((wufc & en_bits) == en_bits)
+			return -EINVAL;  /* the filter is in use. */
 
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+		E1000_WRITE_REG(hw, E1000_WUFC, wufc | E1000_WUFC_FLEX_HQ |
+				(E1000_WUFC_FLX0 << flex_filter->index));
 
-	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	E1000_WRITE_REG(hw, E1000_WUFC, wufc & (~(E1000_WUFC_FLX0 << index)));
+		j = 0;
 
-	if (index < E1000_MAX_FHFT)
-		reg_off = E1000_FHFT(index);
-	else
-		reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
 
-	for (i = 0; i < 64; i++)
-		E1000_WRITE_REG(hw, reg_off + i*4, 0);
+		for (i = 0; i < 16; i++) {
+			E1000_WRITE_REG(hw, reg_off + i*4*4,
+					flex_filter->filter_info.dwords[j]);
+			E1000_WRITE_REG(hw, reg_off + (i*4+1)*4,
+					flex_filter->filter_info.dwords[++j]);
+			E1000_WRITE_REG(hw, reg_off + (i*4+2)*4,
+					(uint32_t)filter->mask[i]);
+			++j;
+		}
+		queueing |= filter->len |
+			(filter->queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) |
+			(filter->priority << E1000_FHFT_QUEUEING_PRIO_SHIFT);
+		E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET,
+				queueing);
+	} else {
+		it = eth_igb_flex_filter_lookup(&filter_info->flex_list,
+				&flex_filter->filter_info);
+		if (it == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			rte_free(flex_filter);
+			return -ENOENT;
+		}
+
+		E1000_WRITE_REG(hw, E1000_WUFC, wufc &
+			(~(E1000_WUFC_FLX0 << it->index)));
+
+		for (i = 0; i < 64; i++)
+			E1000_WRITE_REG(hw, reg_off + i*4, 0);
+
+		filter_info->flex_mask &= ~(1 << it->index);
+		TAILQ_REMOVE(&filter_info->flex_list, it, entries);
+		rte_free(it);
+		rte_free(flex_filter);
+	}
+
 	return 0;
 }
 
-/*
- * get a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that returns.
- * *rx_queue: the pointer of the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
 static int
-eth_igb_get_flex_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue)
+eth_igb_flex_filter_get(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_flex_filter flex_filter, *it;
 	uint32_t wufc, queueing, wufc_en = 0;
-	uint8_t i, j;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
 
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&flex_filter, 0, sizeof(struct e1000_flex_filter));
+	flex_filter.filter_info.len = filter->len;
+	flex_filter.filter_info.priority = filter->priority;
+	memcpy(flex_filter.filter_info.dwords, filter->bytes, filter->len);
+	memcpy(flex_filter.filter_info.mask, filter->mask,
+			RTE_ALIGN(filter->len, sizeof(char)) / sizeof(char));
+
+	it = eth_igb_flex_filter_lookup(&filter_info->flex_list,
+			&flex_filter.filter_info);
+	if (it == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
+	}
 
 	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	wufc_en = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
+	wufc_en = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << it->index);
 
 	if ((wufc & wufc_en) == wufc_en) {
 		uint32_t reg_off = 0;
-		j = 0;
-		if (index < E1000_MAX_FHFT)
-			reg_off = E1000_FHFT(index);
+		if (it->index < E1000_MAX_FHFT)
+			reg_off = E1000_FHFT(it->index);
 		else
-			reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
-
-		for (i = 0; i < 16; i++, j = i * 2) {
-			filter->dwords[j] =
-				E1000_READ_REG(hw, reg_off + i*4*4);
-			filter->dwords[j+1] =
-				E1000_READ_REG(hw, reg_off + (i*4+1)*4);
-			filter->mask[i] =
-				E1000_READ_REG(hw, reg_off + (i*4+2)*4);
-		}
+			reg_off = E1000_FHFT_EXT(it->index - E1000_MAX_FHFT);
+
 		queueing = E1000_READ_REG(hw,
 				reg_off + E1000_FHFT_QUEUEING_OFFSET);
-		filter->len = queueing & E1000_FHFT_QUEUEING_LEN;
-		filter->priority = (queueing & E1000_FHFT_QUEUEING_PRIO) >>
-			E1000_FHFT_QUEUEING_PRIO_SHIFT;
-		*rx_queue = (queueing & E1000_FHFT_QUEUEING_QUEUE) >>
+		filter->queue = (queueing & E1000_FHFT_QUEUEING_QUEUE) >>
 			E1000_FHFT_QUEUEING_QUEUE_SHIFT;
 		return 0;
 	}
 	return -ENOENT;
 }
 
+static int
+eth_igb_flex_filter_handle(struct rte_eth_dev *dev,
+			enum rte_filter_op filter_op,
+			void *arg)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret = 0;
+
+	MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return ret;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	if (((struct rte_eth_flex_filter *)arg)->len == 0) {
+		PMD_DRV_LOG(ERR, "filter length shouldn't be 0");
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = eth_igb_flex_filter_set(dev,
+				(struct rte_eth_flex_filter *)arg,
+				TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = eth_igb_flex_filter_set(dev,
+				(struct rte_eth_flex_filter *)arg,
+				FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = eth_igb_flex_filter_get(dev,
+				(struct rte_eth_flex_filter *)arg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u\n", filter_op);
+		ret = -ENOSYS;
+		break;
+	}
+
+	return ret;
+}
+
 /*
  * add a 5tuple filter
  *
@@ -3237,6 +3317,9 @@ eth_igb_filter_ctrl(struct rte_eth_dev *dev,
 	case RTE_ETH_FILTER_ETHERTYPE:
 		ret = igb_ethertype_filter_handle(dev, filter_op, arg);
 		break;
+	case RTE_ETH_FILTER_FLEXIBLE:
+		ret = eth_igb_flex_filter_handle(dev, filter_op, arg);
+		break;
 	default:
 		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
 							filter_type);
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver to new API
  2015-01-30  4:48 ` [dpdk-dev] [PATCH] igb: integrate flex filter to new API zhida zang
@ 2015-02-15  4:07   ` Jingjing Wu
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 1/5] ethdev: define flex filter type and its structure Jingjing Wu
                       ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Jingjing Wu @ 2015-02-15  4:07 UTC (permalink / raw)
  To: dev

v2 changes:
 - split one patch to patch series
 - change the command's format in testpmd.
 - add doc changes in testpmd_funcs.rst
 - correct the errors reported by checkpatch.pl

The patch set uses new filter_ctrl API to replace old flex filter APIs.
It uses new functions and structure to replace old ones in igb driver, new commands to replace old ones in testpmd, and removes the old APIs.


Jingjing Wu (5):
  ethdev: define flex filter type and its structure
  e1000: new functions replace old ones for flex filter
  testpmd: new commands for flex filter
  ethdev: remove old APIs and structures of syn filter
  doc: commands changed in testpmd_funcs for flex filter

 app/test-pmd/cmdline.c                      | 239 ++++++++------------
 app/test-pmd/config.c                       |  33 ---
 app/test-pmd/testpmd.h                      |   1 -
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 +----
 lib/librte_ether/rte_eth_ctrl.h             |  20 ++
 lib/librte_ether/rte_ethdev.c               |  51 -----
 lib/librte_ether/rte_ethdev.h               |  89 --------
 lib/librte_pmd_e1000/e1000_ethdev.h         |  27 ++-
 lib/librte_pmd_e1000/igb_ethdev.c           | 332 +++++++++++++++++-----------
 9 files changed, 352 insertions(+), 496 deletions(-)

-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 1/5] ethdev: define flex filter type and its structure
  2015-02-15  4:07   ` [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver " Jingjing Wu
@ 2015-02-15  4:07     ` Jingjing Wu
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 2/5] e1000: new functions replace old ones for flex filter Jingjing Wu
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jingjing Wu @ 2015-02-15  4:07 UTC (permalink / raw)
  To: dev

This patch defines flex filter type RTE_ETH_FILTER_FLEXIBLE and its structure rte_eth_flex_filter.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 0ce241e..beacfa3 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -53,6 +53,7 @@ enum rte_filter_type {
 	RTE_ETH_FILTER_NONE = 0,
 	RTE_ETH_FILTER_MACVLAN,
 	RTE_ETH_FILTER_ETHERTYPE,
+	RTE_ETH_FILTER_FLEXIBLE,
 	RTE_ETH_FILTER_TUNNEL,
 	RTE_ETH_FILTER_FDIR,
 	RTE_ETH_FILTER_HASH,
@@ -116,6 +117,25 @@ struct rte_eth_ethertype_filter {
 	uint16_t queue;               /**< Queue assigned to when match*/
 };
 
+#define RTE_FLEX_FILTER_MAXLEN	128	/**< bytes to use in flex filter. */
+#define RTE_FLEX_FILTER_MASK_SIZE	\
+	(RTE_ALIGN(RTE_FLEX_FILTER_MAXLEN, CHAR_BIT) / CHAR_BIT)
+					/**< mask bytes in flex filter. */
+
+/**
+ *  A structure used to define the flex filter entry
+ *  to support RTE_ETH_FILTER_FLEXIBLE with RTE_ETH_FILTER_ADD,
+ *  RTE_ETH_FILTER_DELETE and RTE_ETH_FILTER_GET operations.
+ */
+struct rte_eth_flex_filter {
+	uint16_t len;
+	uint8_t bytes[RTE_FLEX_FILTER_MAXLEN];  /**< flex bytes in big endian.*/
+	uint8_t mask[RTE_FLEX_FILTER_MASK_SIZE];    /**< if mask bit is 1b, do
+					not compare corresponding byte. */
+	uint8_t priority;
+	uint16_t queue;       /**< Queue assigned to when match. */
+};
+
 /**
  * Tunneled type.
  */
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 2/5] e1000: new functions replace old ones for flex filter
  2015-02-15  4:07   ` [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver " Jingjing Wu
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 1/5] ethdev: define flex filter type and its structure Jingjing Wu
@ 2015-02-15  4:07     ` Jingjing Wu
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 3/5] testpmd: new commands " Jingjing Wu
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jingjing Wu @ 2015-02-15  4:07 UTC (permalink / raw)
  To: dev

This patch defines new functions dealing with flex filter.
It removes old functions of flex filter in igb driver.
Syn filter is dealt with through entrance eth_igb_filter_ctrl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_e1000/e1000_ethdev.h |  27 ++-
 lib/librte_pmd_e1000/igb_ethdev.c   | 332 ++++++++++++++++++++++--------------
 2 files changed, 231 insertions(+), 128 deletions(-)

diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index d155e77..b91fcad 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -78,11 +78,16 @@
 #define E1000_MAX_TTQF_FILTERS         8
 #define E1000_2TUPLE_MAX_PRI           7
 
-#define E1000_MAX_FLEXIBLE_FILTERS       8
+#define E1000_MAX_FLEX_FILTERS           8
 #define E1000_MAX_FHFT                   4
 #define E1000_MAX_FHFT_EXT               4
+#define E1000_FHFT_SIZE_IN_DWD           64
 #define E1000_MAX_FLEX_FILTER_PRI        7
 #define E1000_MAX_FLEX_FILTER_LEN        128
+#define E1000_MAX_FLEX_FILTER_DWDS \
+	(E1000_MAX_FLEX_FILTER_LEN / sizeof(uint32_t))
+#define E1000_FLEX_FILTERS_MASK_SIZE \
+	(E1000_MAX_FLEX_FILTER_DWDS / 4)
 #define E1000_FHFT_QUEUEING_LEN          0x0000007F
 #define E1000_FHFT_QUEUEING_QUEUE        0x00000700
 #define E1000_FHFT_QUEUEING_PRIO         0x00070000
@@ -131,6 +136,24 @@ struct e1000_vf_info {
 	uint16_t tx_rate;
 };
 
+TAILQ_HEAD(e1000_flex_filter_list, e1000_flex_filter);
+
+struct e1000_flex_filter_info {
+	uint16_t len;
+	uint32_t dwords[E1000_MAX_FLEX_FILTER_DWDS]; /* flex bytes in dword. */
+	/* if mask bit is 1b, do not compare corresponding byte in dwords. */
+	uint8_t mask[E1000_FLEX_FILTERS_MASK_SIZE];
+	uint8_t priority;
+};
+
+/* Flex filter structure */
+struct e1000_flex_filter {
+	TAILQ_ENTRY(e1000_flex_filter) entries;
+	uint16_t index; /* index of flex filter */
+	struct e1000_flex_filter_info filter_info;
+	uint16_t queue; /* rx queue assigned to */
+};
+
 /*
  * Structure to store filters' info.
  */
@@ -138,6 +161,8 @@ struct e1000_filter_info {
 	uint8_t ethertype_mask; /* Bit mask for every used ethertype filter */
 	/* store used ethertype filters*/
 	uint16_t ethertype_filters[E1000_MAX_ETQF_FILTERS];
+	uint8_t flex_mask;	/* Bit mask for every used flex filter */
+	struct e1000_flex_filter_list flex_list;
 };
 
 /*
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 2a268b8..6e9240e 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -162,14 +162,14 @@ static int eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
 static int eth_igb_get_2tuple_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index);
+static int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter,
+			bool add);
 static int eth_igb_get_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue);
+			struct rte_eth_flex_filter *filter);
+static int eth_igb_flex_filter_handle(struct rte_eth_dev *dev,
+			enum rte_filter_op filter_op,
+			void *arg);
 static int eth_igb_add_5tuple_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_5tuple_filter *filter, uint16_t rx_queue);
@@ -271,9 +271,6 @@ static struct eth_dev_ops eth_igb_ops = {
 	.add_2tuple_filter       = eth_igb_add_2tuple_filter,
 	.remove_2tuple_filter    = eth_igb_remove_2tuple_filter,
 	.get_2tuple_filter       = eth_igb_get_2tuple_filter,
-	.add_flex_filter         = eth_igb_add_flex_filter,
-	.remove_flex_filter      = eth_igb_remove_flex_filter,
-	.get_flex_filter         = eth_igb_get_flex_filter,
 	.add_5tuple_filter       = eth_igb_add_5tuple_filter,
 	.remove_5tuple_filter    = eth_igb_remove_5tuple_filter,
 	.get_5tuple_filter       = eth_igb_get_5tuple_filter,
@@ -470,6 +467,8 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 	struct e1000_vfta * shadow_vfta =
 			E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 
 	pci_dev = eth_dev->pci_dev;
@@ -601,6 +600,9 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	igb_intr_enable(eth_dev);
 
+	TAILQ_INIT(&filter_info->flex_list);
+	filter_info->flex_mask = 0;
+
 	return 0;
 
 err_late:
@@ -926,7 +928,10 @@ static void
 eth_igb_stop(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 	struct rte_eth_link link;
+	struct e1000_flex_filter *p_flex;
 
 	igb_intr_disable(hw);
 	igb_pf_reset_hw(hw);
@@ -949,6 +954,13 @@ eth_igb_stop(struct rte_eth_dev *dev)
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_igb_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all flex filters of the device */
+	while ((p_flex = TAILQ_FIRST(&filter_info->flex_list))) {
+		TAILQ_REMOVE(&filter_info->flex_list, p_flex, entries);
+		rte_free(p_flex);
+	}
+	filter_info->flex_mask = 0;
 }
 
 static void
@@ -2652,161 +2664,224 @@ eth_igb_get_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
 	return -ENOENT;
 }
 
-/*
- * add a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that will be added.
- * rx_queue: the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *     - On failure, a negative value.
- */
-static int
-eth_igb_add_flex_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue)
+static inline struct e1000_flex_filter *
+eth_igb_flex_filter_lookup(struct e1000_flex_filter_list *filter_list,
+			struct e1000_flex_filter_info *key)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t wufc, en_bits = 0;
-	uint32_t queueing = 0;
-	uint32_t reg_off = 0;
-	uint8_t i, j = 0;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
-
-	if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
-		filter->len % 8 != 0 ||
-		filter->priority > E1000_MAX_FLEX_FILTER_PRI)
-		return -EINVAL;
-
-	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	en_bits = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
-	if ((wufc & en_bits) == en_bits)
-		return -EINVAL;  /* the filter is in use. */
+	struct e1000_flex_filter *it;
 
-	E1000_WRITE_REG(hw, E1000_WUFC,
-		wufc | E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index));
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_flex_filter_info)) == 0)
+			return it;
+	}
 
-	j = 0;
-	if (index < E1000_MAX_FHFT)
-		reg_off = E1000_FHFT(index);
-	else
-		reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
-
-	for (i = 0; i < 16; i++) {
-		E1000_WRITE_REG(hw, reg_off + i*4*4, filter->dwords[j]);
-		E1000_WRITE_REG(hw, reg_off + (i*4+1)*4, filter->dwords[++j]);
-		E1000_WRITE_REG(hw, reg_off + (i*4+2)*4,
-				(uint32_t)filter->mask[i]);
-		++j;
-	}
-	queueing |= filter->len |
-		(rx_queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) |
-		(filter->priority << E1000_FHFT_QUEUEING_PRIO_SHIFT);
-	E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET, queueing);
-	return 0;
+	return NULL;
 }
 
-/*
- * remove a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
 static int
-eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
-				uint16_t index)
+eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter,
+			bool add)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t wufc, reg_off = 0;
-	uint8_t i;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_flex_filter *flex_filter, *it;
+	uint32_t wufc, queueing, mask;
+	uint32_t reg_off;
+	uint8_t shift, i, j = 0;
+
+	flex_filter = rte_zmalloc("e1000_flex_filter",
+			sizeof(struct e1000_flex_filter), 0);
+	if (flex_filter == NULL)
+		return -ENOMEM;
 
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	flex_filter->filter_info.len = filter->len;
+	flex_filter->filter_info.priority = filter->priority;
+	memcpy(flex_filter->filter_info.dwords, filter->bytes, filter->len);
+	for (i = 0; i < RTE_ALIGN(filter->len, CHAR_BIT) / CHAR_BIT; i++) {
+		mask = 0;
+		/* reverse bits in flex filter's mask*/
+		for (shift = 0; shift < CHAR_BIT; shift++) {
+			if (filter->mask[i] & (0x01 << shift))
+				mask |= (0x80 >> shift);
+		}
+		flex_filter->filter_info.mask[i] = mask;
+	}
 
 	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	E1000_WRITE_REG(hw, E1000_WUFC, wufc & (~(E1000_WUFC_FLX0 << index)));
-
-	if (index < E1000_MAX_FHFT)
-		reg_off = E1000_FHFT(index);
+	if (flex_filter->index < E1000_MAX_FHFT)
+		reg_off = E1000_FHFT(flex_filter->index);
 	else
-		reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
+		reg_off = E1000_FHFT_EXT(flex_filter->index - E1000_MAX_FHFT);
+
+	if (add) {
+		if (eth_igb_flex_filter_lookup(&filter_info->flex_list,
+				&flex_filter->filter_info) != NULL) {
+			PMD_DRV_LOG(ERR, "filter exists.");
+			rte_free(flex_filter);
+			return -EEXIST;
+		}
+		flex_filter->queue = filter->queue;
+		/*
+		 * look for an unused flex filter index
+		 * and insert the filter into the list.
+		 */
+		for (i = 0; i < E1000_MAX_FLEX_FILTERS; i++) {
+			if (!(filter_info->flex_mask & (1 << i))) {
+				filter_info->flex_mask |= 1 << i;
+				flex_filter->index = i;
+				TAILQ_INSERT_TAIL(&filter_info->flex_list,
+					flex_filter,
+					entries);
+				break;
+			}
+		}
+		if (i >= E1000_MAX_FLEX_FILTERS) {
+			PMD_DRV_LOG(ERR, "flex filters are full.");
+			rte_free(flex_filter);
+			return -ENOSYS;
+		}
+
+		E1000_WRITE_REG(hw, E1000_WUFC, wufc | E1000_WUFC_FLEX_HQ |
+				(E1000_WUFC_FLX0 << flex_filter->index));
+		queueing = filter->len |
+			(filter->queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) |
+			(filter->priority << E1000_FHFT_QUEUEING_PRIO_SHIFT);
+		E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET,
+				queueing);
+		for (i = 0; i < E1000_FLEX_FILTERS_MASK_SIZE; i++) {
+			E1000_WRITE_REG(hw, reg_off,
+					flex_filter->filter_info.dwords[j]);
+			reg_off += sizeof(uint32_t);
+			E1000_WRITE_REG(hw, reg_off,
+					flex_filter->filter_info.dwords[++j]);
+			reg_off += sizeof(uint32_t);
+			E1000_WRITE_REG(hw, reg_off,
+				(uint32_t)flex_filter->filter_info.mask[i]);
+			reg_off += sizeof(uint32_t) * 2;
+			++j;
+		}
+	} else {
+		it = eth_igb_flex_filter_lookup(&filter_info->flex_list,
+				&flex_filter->filter_info);
+		if (it == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			rte_free(flex_filter);
+			return -ENOENT;
+		}
+
+		for (i = 0; i < E1000_FHFT_SIZE_IN_DWD; i++)
+			E1000_WRITE_REG(hw, reg_off + i * sizeof(uint32_t), 0);
+		E1000_WRITE_REG(hw, E1000_WUFC, wufc &
+			(~(E1000_WUFC_FLX0 << it->index)));
+
+		filter_info->flex_mask &= ~(1 << it->index);
+		TAILQ_REMOVE(&filter_info->flex_list, it, entries);
+		rte_free(it);
+		rte_free(flex_filter);
+	}
 
-	for (i = 0; i < 64; i++)
-		E1000_WRITE_REG(hw, reg_off + i*4, 0);
 	return 0;
 }
 
-/*
- * get a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that returns.
- * *rx_queue: the pointer of the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
 static int
-eth_igb_get_flex_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue)
+eth_igb_get_flex_filter(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_flex_filter flex_filter, *it;
 	uint32_t wufc, queueing, wufc_en = 0;
-	uint8_t i, j;
 
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&flex_filter, 0, sizeof(struct e1000_flex_filter));
+	flex_filter.filter_info.len = filter->len;
+	flex_filter.filter_info.priority = filter->priority;
+	memcpy(flex_filter.filter_info.dwords, filter->bytes, filter->len);
+	memcpy(flex_filter.filter_info.mask, filter->mask,
+			RTE_ALIGN(filter->len, sizeof(char)) / sizeof(char));
+
+	it = eth_igb_flex_filter_lookup(&filter_info->flex_list,
+				&flex_filter.filter_info);
+	if (it == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
+	}
 
 	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	wufc_en = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
+	wufc_en = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << it->index);
 
 	if ((wufc & wufc_en) == wufc_en) {
 		uint32_t reg_off = 0;
-		j = 0;
-		if (index < E1000_MAX_FHFT)
-			reg_off = E1000_FHFT(index);
+		if (it->index < E1000_MAX_FHFT)
+			reg_off = E1000_FHFT(it->index);
 		else
-			reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
-
-		for (i = 0; i < 16; i++, j = i * 2) {
-			filter->dwords[j] =
-				E1000_READ_REG(hw, reg_off + i*4*4);
-			filter->dwords[j+1] =
-				E1000_READ_REG(hw, reg_off + (i*4+1)*4);
-			filter->mask[i] =
-				E1000_READ_REG(hw, reg_off + (i*4+2)*4);
-		}
+			reg_off = E1000_FHFT_EXT(it->index - E1000_MAX_FHFT);
+
 		queueing = E1000_READ_REG(hw,
 				reg_off + E1000_FHFT_QUEUEING_OFFSET);
 		filter->len = queueing & E1000_FHFT_QUEUEING_LEN;
 		filter->priority = (queueing & E1000_FHFT_QUEUEING_PRIO) >>
 			E1000_FHFT_QUEUEING_PRIO_SHIFT;
-		*rx_queue = (queueing & E1000_FHFT_QUEUEING_QUEUE) >>
+		filter->queue = (queueing & E1000_FHFT_QUEUEING_QUEUE) >>
 			E1000_FHFT_QUEUEING_QUEUE_SHIFT;
 		return 0;
 	}
 	return -ENOENT;
 }
 
+static int
+eth_igb_flex_filter_handle(struct rte_eth_dev *dev,
+			enum rte_filter_op filter_op,
+			void *arg)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_eth_flex_filter *filter;
+	int ret = 0;
+
+	MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return ret;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	filter = (struct rte_eth_flex_filter *)arg;
+	if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN
+	    || filter->len % sizeof(uint64_t) != 0) {
+		PMD_DRV_LOG(ERR, "filter's length is out of range");
+		return -EINVAL;
+	}
+	if (filter->priority > E1000_MAX_FLEX_FILTER_PRI) {
+		PMD_DRV_LOG(ERR, "filter's priority is out of range");
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = eth_igb_add_del_flex_filter(dev, filter, TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = eth_igb_add_del_flex_filter(dev, filter, FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = eth_igb_get_flex_filter(dev, filter);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
 /*
  * add a 5tuple filter
  *
@@ -3237,6 +3312,9 @@ eth_igb_filter_ctrl(struct rte_eth_dev *dev,
 	case RTE_ETH_FILTER_ETHERTYPE:
 		ret = igb_ethertype_filter_handle(dev, filter_op, arg);
 		break;
+	case RTE_ETH_FILTER_FLEXIBLE:
+		ret = eth_igb_flex_filter_handle(dev, filter_op, arg);
+		break;
 	default:
 		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
 							filter_type);
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 3/5] testpmd: new commands for flex filter
  2015-02-15  4:07   ` [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver " Jingjing Wu
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 1/5] ethdev: define flex filter type and its structure Jingjing Wu
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 2/5] e1000: new functions replace old ones for flex filter Jingjing Wu
@ 2015-02-15  4:07     ` Jingjing Wu
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 4/5] ethdev: remove old APIs and structures of " Jingjing Wu
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jingjing Wu @ 2015-02-15  4:07 UTC (permalink / raw)
  To: dev

Following commands of flex filter are removed:
  - add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)
    priority (prio_value) queue (queue_id)
  - remove_flex_filter (port_id) index (idx)
  - get_flex_filter (port_id) index (idx)
New command is added for flex filter by using filter_ctrl API and new flex filter structure:
  - flex_filter (port_id) (add|del) len (len_value) bytes (bytes_value) mask (mask_value)
    priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c | 239 +++++++++++++++++++------------------------------
 app/test-pmd/config.c  |  33 -------
 app/test-pmd/testpmd.h |   1 -
 3 files changed, 91 insertions(+), 182 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 590e427..e78c7b3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -692,15 +692,10 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"get_syn_filter (port_id) "
 			"    get syn filter info.\n\n"
 
-			"add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)"
-			" priority (prio_value) queue (queue_id) index (idx)\n"
-			"    add a flex filter.\n\n"
-
-			"remove_flex_filter (port_id) index (idx)\n"
-			"    remove a flex filter.\n\n"
-
-			"get_flex_filter (port_id) index (idx)\n"
-			"    get info of a flex filter.\n\n"
+			"flex_filter (port_id) (add|del) len (len_value)"
+			" bytes (bytes_value) mask (mask_value)"
+			" priority (prio_value) queue (queue_id)\n"
+			"    Add/Del a flex filter.\n\n"
 
 			"flow_director_filter (port_id) (add|del)"
 			" flow (ip4|ip4-frag|ip6|ip6-frag)"
@@ -7742,6 +7737,7 @@ cmdline_parse_inst_t cmd_get_5tuple_filter = {
 /* *** ADD/REMOVE A flex FILTER *** */
 struct cmd_flex_filter_result {
 	cmdline_fixed_string_t filter;
+	cmdline_fixed_string_t ops;
 	uint8_t port_id;
 	cmdline_fixed_string_t len;
 	uint8_t len_value;
@@ -7753,8 +7749,6 @@ struct cmd_flex_filter_result {
 	uint8_t priority_value;
 	cmdline_fixed_string_t queue;
 	uint16_t queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t index_value;
 };
 
 static int xdigit2val(unsigned char c)
@@ -7775,113 +7769,106 @@ cmd_flex_filter_parsed(void *parsed_result,
 			  __attribute__((unused)) void *data)
 {
 	int ret = 0;
-	struct rte_flex_filter filter;
+	struct rte_eth_flex_filter filter;
 	struct cmd_flex_filter_result *res = parsed_result;
 	char *bytes_ptr, *mask_ptr;
-	uint16_t len, i, j;
+	uint16_t len, i, j = 0;
 	char c;
-	int val, mod = 0;
-	uint32_t dword = 0;
+	int val;
 	uint8_t byte = 0;
-	uint8_t hex = 0;
 
-	if (!strcmp(res->filter, "add_flex_filter")) {
-		if (res->len_value > 128) {
-			printf("the len exceed the max length 128\n");
-			return;
-		}
-		memset(&filter, 0, sizeof(struct rte_flex_filter));
-		filter.len = res->len_value;
-		filter.priority = res->priority_value;
-		bytes_ptr = res->bytes_value;
-		mask_ptr = res->mask_value;
-
-		j = 0;
-		 /* translate bytes string to uint_32 array. */
-		if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
-			(bytes_ptr[1] == 'X')))
-			bytes_ptr += 2;
-		len = strnlen(bytes_ptr, res->len_value * 2);
-		if (len == 0 || (len % 8 != 0)) {
-			printf("please check len and bytes input\n");
+	if (res->len_value > RTE_FLEX_FILTER_MAXLEN) {
+		printf("the len exceed the max length 128\n");
+		return;
+	}
+	memset(&filter, 0, sizeof(struct rte_eth_flex_filter));
+	filter.len = res->len_value;
+	filter.priority = res->priority_value;
+	filter.queue = res->queue_id;
+	bytes_ptr = res->bytes_value;
+	mask_ptr = res->mask_value;
+
+	 /* translate bytes string to array. */
+	if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
+		(bytes_ptr[1] == 'X')))
+		bytes_ptr += 2;
+	len = strnlen(bytes_ptr, res->len_value * 2);
+	if (len == 0 || (len % 8 != 0)) {
+		printf("please check len and bytes input\n");
+		return;
+	}
+	for (i = 0; i < len; i++) {
+		c = bytes_ptr[i];
+		if (isxdigit(c) == 0) {
+			/* invalid characters. */
+			printf("invalid input\n");
 			return;
 		}
-		for (i = 0; i < len; i++) {
-			c = bytes_ptr[i];
-			if (isxdigit(c) == 0) {
-				/* invalid characters. */
-				printf("invalid input\n");
-				return;
-			}
-			val = xdigit2val(c);
-			mod = i % 8;
-			if (i % 2) {
-				byte |= val;
-				dword |= byte << (4 * mod - 4);
-				byte = 0;
-			} else
-				byte |= val << 4;
-			if (mod == 7) {
-				filter.dwords[j] = dword;
-				printf("dwords[%d]:%08x ", j, filter.dwords[j]);
-				j++;
-				dword = 0;
-			}
-		}
-		printf("\n");
-		 /* translate mask string to uint8_t array. */
-		j = 0;
-		if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
-			(mask_ptr[1] == 'X')))
-			mask_ptr += 2;
-		len = strnlen(mask_ptr, (res->len_value+3)/4);
-		if (len == 0) {
+		val = xdigit2val(c);
+		if (i % 2) {
+			byte |= val;
+			filter.bytes[j] = byte;
+			printf("bytes[%d]:%02x ", j, filter.bytes[j]);
+			j++;
+			byte = 0;
+		} else
+			byte |= val << 4;
+	}
+	printf("\n");
+	 /* translate mask string to uint8_t array. */
+	if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
+		(mask_ptr[1] == 'X')))
+		mask_ptr += 2;
+	len = strnlen(mask_ptr, (res->len_value + 3) / 4);
+	if (len == 0) {
+		printf("invalid input\n");
+		return;
+	}
+	j = 0;
+	byte = 0;
+	for (i = 0; i < len; i++) {
+		c = mask_ptr[i];
+		if (isxdigit(c) == 0) {
+			/* invalid characters. */
 			printf("invalid input\n");
 			return;
 		}
-		for (i = 0; i < len; i++) {
-			c = mask_ptr[i];
-			if (isxdigit(c) == 0) {
-				/* invalid characters. */
-				printf("invalid input\n");
-				return;
-			}
-			val = xdigit2val(c);
-			hex |= (uint8_t)(val & 0x8) >> 3;
-			hex |= (uint8_t)(val & 0x4) >> 1;
-			hex |= (uint8_t)(val & 0x2) << 1;
-			hex |= (uint8_t)(val & 0x1) << 3;
-			if (i % 2) {
-				byte |= hex << 4;
-				filter.mask[j] = byte;
-				printf("mask[%d]:%02x ", j, filter.mask[j]);
-				j++;
-				byte = 0;
-			} else
-				byte |= hex;
-			hex = 0;
-		}
-		printf("\n");
-		printf("call function rte_eth_dev_add_flex_filter: "
-			"index = %d, queue-id = %d, len = %d, priority = %d\n",
-			res->index_value, res->queue_id,
-			filter.len, filter.priority);
-		ret = rte_eth_dev_add_flex_filter(res->port_id, res->index_value,
-				&filter, res->queue_id);
+		val = xdigit2val(c);
+		if (i % 2) {
+			byte |= val;
+			filter.mask[j] = byte;
+			printf("mask[%d]:%02x ", j, filter.mask[j]);
+			j++;
+			byte = 0;
+		} else
+			byte |= val << 4;
+	}
+	printf("\n");
 
-	} else if (!strcmp(res->filter, "remove_flex_filter"))
-		ret = rte_eth_dev_remove_flex_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_flex_filter"))
-		get_flex_filter(res->port_id, res->index_value);
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_FLEXIBLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_FLEXIBLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
 
 	if (ret < 0)
 		printf("flex filter setting error: (%s)\n", strerror(-ret));
 }
 
+cmdline_parse_token_string_t cmd_flex_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+				filter, "flex_filter");
 cmdline_parse_token_num_t cmd_flex_filter_port_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
 				port_id, UINT8);
+cmdline_parse_token_string_t cmd_flex_filter_ops =
+	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+				ops, "add#del");
 cmdline_parse_token_string_t cmd_flex_filter_len =
 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
 				len, "len");
@@ -7912,22 +7899,14 @@ cmdline_parse_token_string_t cmd_flex_filter_queue =
 cmdline_parse_token_num_t cmd_flex_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_flex_filter_index =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_flex_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
-				index_value, UINT16);
-cmdline_parse_token_string_t cmd_flex_filter_add_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "add_flex_filter");
-cmdline_parse_inst_t cmd_add_flex_filter = {
+cmdline_parse_inst_t cmd_flex_filter = {
 	.f = cmd_flex_filter_parsed,
 	.data = NULL,
-	.help_str = "add a flex filter",
+	.help_str = "add/del a flex filter",
 	.tokens = {
-		(void *)&cmd_flex_filter_add_filter,
+		(void *)&cmd_flex_filter_filter,
 		(void *)&cmd_flex_filter_port_id,
+		(void *)&cmd_flex_filter_ops,
 		(void *)&cmd_flex_filter_len,
 		(void *)&cmd_flex_filter_len_value,
 		(void *)&cmd_flex_filter_bytes,
@@ -7938,40 +7917,6 @@ cmdline_parse_inst_t cmd_add_flex_filter = {
 		(void *)&cmd_flex_filter_priority_value,
 		(void *)&cmd_flex_filter_queue,
 		(void *)&cmd_flex_filter_queue_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_flex_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "remove_flex_filter");
-cmdline_parse_inst_t cmd_remove_flex_filter = {
-	.f = cmd_flex_filter_parsed,
-	.data = NULL,
-	.help_str = "remove a flex filter",
-	.tokens = {
-		(void *)&cmd_flex_filter_remove_filter,
-		(void *)&cmd_flex_filter_port_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_flex_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "get_flex_filter");
-cmdline_parse_inst_t cmd_get_flex_filter = {
-	.f = cmd_flex_filter_parsed,
-	.data = NULL,
-	.help_str = "get a flex filter",
-	.tokens = {
-		(void *)&cmd_flex_filter_get_filter,
-		(void *)&cmd_flex_filter_port_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
 		NULL,
 	},
 };
@@ -9127,9 +9072,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_add_5tuple_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_5tuple_filter,
 	(cmdline_parse_inst_t *)&cmd_get_5tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_add_flex_filter,
-	(cmdline_parse_inst_t *)&cmd_remove_flex_filter,
-	(cmdline_parse_inst_t *)&cmd_get_flex_filter,
+	(cmdline_parse_inst_t *)&cmd_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_add_del_ip_flow_director,
 	(cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director,
 	(cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index c40f819..cc5f113 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2252,36 +2252,3 @@ get_5tuple_filter(uint8_t port_id, uint16_t index)
 			filter.priority, filter.tcp_flags, rx_queue);
 	}
 }
-void
-get_flex_filter(uint8_t port_id, uint16_t index)
-
-{
-	struct rte_flex_filter filter;
-	int ret = 0;
-	uint16_t rx_queue;
-	int i, j;
-
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_flex_filter(port_id, index,
-				&filter, &rx_queue);
-	if (ret < 0) {
-		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
-		else
-			printf("get flex filter fails(%s)\n", strerror(-ret));
-		return;
-	} else {
-		printf("filter[%d]: ", index);
-		printf("\n    length: %d", filter.len);
-		printf("\n    dword[]: 0x");
-		for (i = 0; i < 32; i++)
-			printf("%08x ", (unsigned)rte_be_to_cpu_32(filter.dwords[i]));
-		printf("\n    mask[]: 0b");
-		for (i = 0; i < 16; i++) {
-			for (j = 0; j < 8; j++)
-				printf("%c", (filter.mask[i] & (1 << j)) ? '1' : '0');
-		}
-		printf("\n    priority: %d    queue: %d\n",
-			filter.priority, rx_queue);
-	}
-}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8f5e6c7..9e85a47 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -557,7 +557,6 @@ void get_syn_filter(uint8_t port_id);
 void get_ethertype_filter(uint8_t port_id, uint16_t index);
 void get_2tuple_filter(uint8_t port_id, uint16_t index);
 void get_5tuple_filter(uint8_t port_id, uint16_t index);
-void get_flex_filter(uint8_t port_id, uint16_t index);
 int port_id_is_invalid(portid_t port_id);
 int rx_queue_id_is_invalid(queueid_t rxq_id);
 int tx_queue_id_is_invalid(queueid_t txq_id);
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 4/5] ethdev: remove old APIs and structures of flex filter
  2015-02-15  4:07   ` [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver " Jingjing Wu
                       ` (2 preceding siblings ...)
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 3/5] testpmd: new commands " Jingjing Wu
@ 2015-02-15  4:07     ` Jingjing Wu
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 5/5] doc: commands changed in testpmd_funcs for " Jingjing Wu
  2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
  5 siblings, 0 replies; 14+ messages in thread
From: Jingjing Wu @ 2015-02-15  4:07 UTC (permalink / raw)
  To: dev

Structure rte_flex_filter is removed.
Following APIs are removed:
  - rte_eth_dev_add_flex_filter
  - rte_eth_dev_remove_flex_filter
  - rte_eth_dev_get_flex_filter

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 51 -------------------------
 lib/librte_ether/rte_ethdev.h | 89 -------------------------------------------
 2 files changed, 140 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index ea3a1fb..f8b1e8a 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3172,57 +3172,6 @@ rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
 }
 
 int
-rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_flex_filter, -ENOTSUP);
-	return (*dev->dev_ops->add_flex_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_remove_flex_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_flex_filter, -ENOTSUP);
-	return (*dev->dev_ops->remove_flex_filter)(dev, index);
-}
-
-int
-rte_eth_dev_get_flex_filter(uint8_t port_id, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (filter == NULL || rx_queue == NULL)
-		return -EINVAL;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_flex_filter, -ENOTSUP);
-	return (*dev->dev_ops->get_flex_filter)(dev, index, filter,
-						rx_queue);
-}
-
-int
 rte_eth_dev_filter_supported(uint8_t port_id, enum rte_filter_type filter_type)
 {
 	struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 1200c1c..7d455b5 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -992,17 +992,6 @@ struct rte_2tuple_filter {
 };
 
 /**
- *  A structure used to define a flex filter.
- */
-struct rte_flex_filter {
-	uint16_t len;
-	uint32_t dwords[32];  /**< flex bytes in big endian. */
-	uint8_t mask[16];     /**< if mask bit is 1b, do not compare
-				   corresponding byte in dwords. */
-	uint8_t priority;
-};
-
-/**
  *  A structure used to define a 5tuple filter.
  */
 struct rte_5tuple_filter {
@@ -1391,20 +1380,6 @@ typedef int (*eth_get_5tuple_filter_t)(struct rte_eth_dev *dev,
 			uint16_t *rx_queue);
 /**< @internal Get a 5tuple filter rule on an Ethernet device */
 
-typedef int (*eth_add_flex_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_flex_filter *filter,
-			uint16_t rx_queue);
-/**< @internal Setup a new flex filter rule on an Ethernet device */
-
-typedef int (*eth_remove_flex_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index);
-/**< @internal Remove a flex filter rule on an Ethernet device */
-
-typedef int (*eth_get_flex_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_flex_filter *filter,
-			uint16_t *rx_queue);
-/**< @internal Get a flex filter rule on an Ethernet device */
-
 typedef int (*eth_filter_ctrl_t)(struct rte_eth_dev *dev,
 				 enum rte_filter_type filter_type,
 				 enum rte_filter_op filter_op,
@@ -1515,9 +1490,6 @@ struct eth_dev_ops {
 	eth_add_5tuple_filter_t        add_5tuple_filter;    /**< add 5tuple filter. */
 	eth_remove_5tuple_filter_t     remove_5tuple_filter; /**< remove 5tuple filter. */
 	eth_get_5tuple_filter_t        get_5tuple_filter;    /**< get 5tuple filter. */
-	eth_add_flex_filter_t          add_flex_filter;      /**< add flex filter. */
-	eth_remove_flex_filter_t       remove_flex_filter;   /**< remove flex filter. */
-	eth_get_flex_filter_t          get_flex_filter;      /**< get flex filter. */
 	eth_filter_ctrl_t              filter_ctrl;          /**< common filter control*/
 };
 
@@ -3568,67 +3540,6 @@ int rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
 			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
 
 /**
- * Add a new flex filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of flex filter.
- * @param filter
- *   The pointer to the structure describing the flex filter rule.
- *   The *rte_flex_filter* structure includes the values of the different fields
- *   to match: the dwords (first len bytes of packet ) and relative masks.
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   flex filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support flex filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- *   - (-ENOENT) if no enabled filter in this index.
- */
-int rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a flex filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of flex filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support flex filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_remove_flex_filter(uint8_t port_id, uint16_t index);
-
-/**
- * Get an flex filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of flex filter.
- * @param filter
- *   A pointer to a structure of type *rte_flex_filter* to be filled with
- *   the information of the flex filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support flex filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- *   - (-ENOENT) if no enabled filter in this index.
- */
-int rte_eth_dev_get_flex_filter(uint8_t port_id, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue);
-
-/**
  * Check whether the filter type is supported on an Ethernet device.
  * All the supported filter types are defined in 'rte_eth_ctrl.h'.
  *
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 5/5] doc: commands changed in testpmd_funcs for flex filter
  2015-02-15  4:07   ` [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver " Jingjing Wu
                       ` (3 preceding siblings ...)
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 4/5] ethdev: remove old APIs and structures of " Jingjing Wu
@ 2015-02-15  4:07     ` Jingjing Wu
  2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
  5 siblings, 0 replies; 14+ messages in thread
From: Jingjing Wu @ 2015-02-15  4:07 UTC (permalink / raw)
  To: dev

document of new command:
  - flex_filter (add|del) (port_id) len (len_value) bytes (bytes_value)
    mask (mask_value) priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 56 ++++++-----------------------
 1 file changed, 10 insertions(+), 46 deletions(-)

diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 218835a..9e38423 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1595,15 +1595,14 @@ Example:
 
     syn filter: on, priority: high, queue: 3
 
-add_flex_filter
+flex_filter
 ~~~~~~~~~~~~~~~
 
-Add a Flex filter,
-which recognizes any arbitrary pattern within the first 128 bytes of the packet
+By flex filter, packets can be recognized by any arbitrary pattern within the first 128 bytes of the packet
 and routes packets into one of the receive queues.
 
-add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)
-priority (prio_value) queue (queue_id) index (idx)
+flex_filter (add|del) (port_id) len (len_value) bytes (bytes_value)
+mask (mask_value) priority (prio_value) queue (queue_id)
 
 The available information parameters are:
 
@@ -1611,55 +1610,20 @@ The available information parameters are:
 
 *   len_value: filter length in byte, no greater than 128.
 
-*   bytes_string: a sting in format of octal, means the value the flex filter need to match.
+*   bytes_value: a sting in format of octal, means the value the flex filter need to match.
 
-*   mask_value: a sting in format of octal, bit 1 means corresponding byte in DWORD participates in the match.
+*   mask_value: a sting in format of octal, bit 1 means corresponding byte participates in the match.
 
 *   prio_value: the priority of this filter.
 
 *   queue_id: The receive queue associated with this Flex filter.
 
-*   index: the index of this Flex filter
-
 Example:
 
 .. code-block:: console
 
-   testpmd> add_flex_filter 0 len 16 bytes 0x00000000000000000000000008060000 mask 000C priority 3 queue 3 index 0
-
-Assign a packet whose 13th and 14th bytes are 0x0806 to queue 3.
-
-remove_flex_filter
-~~~~~~~~~~~~~~~~~~
-
-Remove a Flex filter
-
-remove_flex_filter (port_id) index (idx)
+   testpmd> flex_filter 0 add len 16 bytes 0x00000000000000000000000008060000
+        mask 000C priority 3 queue 3
 
-get_flex_filter
-~~~~~~~~~~~~~~~
-
-Get and display a Flex filter
-
-get_flex_filter (port_id) index (idx)
-
-Example:
-
-.. code-block:: console
-
-    testpmd> get_flex_filter 0 index 0
-
-    filter[0]:
-
-        length: 16
-
-        dword[]: 0x00000000 00000000 00000000 08060000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000
-
-        mask[]:
-    0b0000000000001100000000000000000000000000000000000000000000000000000000
-    0000000000000000000000000000000000000000000000000000000000
-
-        priority: 3   queue: 3
+   testpmd> flex_filter 0 del len 16 bytes 0x00000000000000000000000008060000
+        mask 000C priority 3 queue 3
-- 
1.9.3

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

* [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API
  2015-02-15  4:07   ` [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver " Jingjing Wu
                       ` (4 preceding siblings ...)
  2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 5/5] doc: commands changed in testpmd_funcs for " Jingjing Wu
@ 2015-02-21  1:53     ` Pablo de Lara
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 1/5] ethdev: define flex filter type and its structure Pablo de Lara
                         ` (5 more replies)
  5 siblings, 6 replies; 14+ messages in thread
From: Pablo de Lara @ 2015-02-21  1:53 UTC (permalink / raw)
  To: dev

The patch set uses new filter_ctrl API to replace old flex filter APIs.
It uses new functions and structure to replace old ones in igb driver, new commands to replace old ones in testpmd, and removes the old APIs.

v3 changes:
 - fix testpmd documentation

v2 changes:
 - split one patch to patch series
 - change the command's format in testpmd.
 - add doc changes in testpmd_funcs.rst
 - correct the errors reported by checkpatch.pl

Jingjing Wu (5):
  ethdev: define flex filter type and its structure
  e1000: new functions replace old ones for flex filter
  testpmd: new commands for flex filter
  ethdev: remove old APIs and structures of flex filter
  doc: commands changed in testpmd_funcs for flex filter

 app/test-pmd/cmdline.c                      |  239 ++++++++------------
 app/test-pmd/config.c                       |   33 ---
 app/test-pmd/testpmd.h                      |    1 -
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   64 ++----
 lib/librte_ether/rte_eth_ctrl.h             |   20 ++
 lib/librte_ether/rte_ethdev.c               |   51 ----
 lib/librte_ether/rte_ethdev.h               |   89 -------
 lib/librte_pmd_e1000/e1000_ethdev.h         |   27 ++-
 lib/librte_pmd_e1000/igb_ethdev.c           |  332 +++++++++++++++++----------
 9 files changed, 356 insertions(+), 500 deletions(-)

-- 
1.7.4.1

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

* [dpdk-dev] [PATCH v3 1/5] ethdev: define flex filter type and its structure
  2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
@ 2015-02-21  1:53       ` Pablo de Lara
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 2/5] e1000: new functions replace old ones for flex filter Pablo de Lara
                         ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Pablo de Lara @ 2015-02-21  1:53 UTC (permalink / raw)
  To: dev

From: Jingjing Wu <jingjing.wu@intel.com>

This patch defines flex filter type RTE_ETH_FILTER_FLEXIBLE and its structure rte_eth_flex_filter.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 0ce241e..beacfa3 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -53,6 +53,7 @@ enum rte_filter_type {
 	RTE_ETH_FILTER_NONE = 0,
 	RTE_ETH_FILTER_MACVLAN,
 	RTE_ETH_FILTER_ETHERTYPE,
+	RTE_ETH_FILTER_FLEXIBLE,
 	RTE_ETH_FILTER_TUNNEL,
 	RTE_ETH_FILTER_FDIR,
 	RTE_ETH_FILTER_HASH,
@@ -116,6 +117,25 @@ struct rte_eth_ethertype_filter {
 	uint16_t queue;               /**< Queue assigned to when match*/
 };
 
+#define RTE_FLEX_FILTER_MAXLEN	128	/**< bytes to use in flex filter. */
+#define RTE_FLEX_FILTER_MASK_SIZE	\
+	(RTE_ALIGN(RTE_FLEX_FILTER_MAXLEN, CHAR_BIT) / CHAR_BIT)
+					/**< mask bytes in flex filter. */
+
+/**
+ *  A structure used to define the flex filter entry
+ *  to support RTE_ETH_FILTER_FLEXIBLE with RTE_ETH_FILTER_ADD,
+ *  RTE_ETH_FILTER_DELETE and RTE_ETH_FILTER_GET operations.
+ */
+struct rte_eth_flex_filter {
+	uint16_t len;
+	uint8_t bytes[RTE_FLEX_FILTER_MAXLEN];  /**< flex bytes in big endian.*/
+	uint8_t mask[RTE_FLEX_FILTER_MASK_SIZE];    /**< if mask bit is 1b, do
+					not compare corresponding byte. */
+	uint8_t priority;
+	uint16_t queue;       /**< Queue assigned to when match. */
+};
+
 /**
  * Tunneled type.
  */
-- 
1.7.4.1

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

* [dpdk-dev] [PATCH v3 2/5] e1000: new functions replace old ones for flex filter
  2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 1/5] ethdev: define flex filter type and its structure Pablo de Lara
@ 2015-02-21  1:53       ` Pablo de Lara
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 3/5] testpmd: new commands " Pablo de Lara
                         ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Pablo de Lara @ 2015-02-21  1:53 UTC (permalink / raw)
  To: dev

From: Jingjing Wu <jingjing.wu@intel.com>

This patch defines new functions dealing with flex filter.
It removes old functions of flex filter in igb driver.
Syn filter is dealt with through entrance eth_igb_filter_ctrl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_e1000/e1000_ethdev.h |   27 +++-
 lib/librte_pmd_e1000/igb_ethdev.c   |  332 +++++++++++++++++++++-------------
 2 files changed, 231 insertions(+), 128 deletions(-)

diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index d155e77..b91fcad 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -78,11 +78,16 @@
 #define E1000_MAX_TTQF_FILTERS         8
 #define E1000_2TUPLE_MAX_PRI           7
 
-#define E1000_MAX_FLEXIBLE_FILTERS       8
+#define E1000_MAX_FLEX_FILTERS           8
 #define E1000_MAX_FHFT                   4
 #define E1000_MAX_FHFT_EXT               4
+#define E1000_FHFT_SIZE_IN_DWD           64
 #define E1000_MAX_FLEX_FILTER_PRI        7
 #define E1000_MAX_FLEX_FILTER_LEN        128
+#define E1000_MAX_FLEX_FILTER_DWDS \
+	(E1000_MAX_FLEX_FILTER_LEN / sizeof(uint32_t))
+#define E1000_FLEX_FILTERS_MASK_SIZE \
+	(E1000_MAX_FLEX_FILTER_DWDS / 4)
 #define E1000_FHFT_QUEUEING_LEN          0x0000007F
 #define E1000_FHFT_QUEUEING_QUEUE        0x00000700
 #define E1000_FHFT_QUEUEING_PRIO         0x00070000
@@ -131,6 +136,24 @@ struct e1000_vf_info {
 	uint16_t tx_rate;
 };
 
+TAILQ_HEAD(e1000_flex_filter_list, e1000_flex_filter);
+
+struct e1000_flex_filter_info {
+	uint16_t len;
+	uint32_t dwords[E1000_MAX_FLEX_FILTER_DWDS]; /* flex bytes in dword. */
+	/* if mask bit is 1b, do not compare corresponding byte in dwords. */
+	uint8_t mask[E1000_FLEX_FILTERS_MASK_SIZE];
+	uint8_t priority;
+};
+
+/* Flex filter structure */
+struct e1000_flex_filter {
+	TAILQ_ENTRY(e1000_flex_filter) entries;
+	uint16_t index; /* index of flex filter */
+	struct e1000_flex_filter_info filter_info;
+	uint16_t queue; /* rx queue assigned to */
+};
+
 /*
  * Structure to store filters' info.
  */
@@ -138,6 +161,8 @@ struct e1000_filter_info {
 	uint8_t ethertype_mask; /* Bit mask for every used ethertype filter */
 	/* store used ethertype filters*/
 	uint16_t ethertype_filters[E1000_MAX_ETQF_FILTERS];
+	uint8_t flex_mask;	/* Bit mask for every used flex filter */
+	struct e1000_flex_filter_list flex_list;
 };
 
 /*
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 2a268b8..6e9240e 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -162,14 +162,14 @@ static int eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
 static int eth_igb_get_2tuple_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index);
+static int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter,
+			bool add);
 static int eth_igb_get_flex_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue);
+			struct rte_eth_flex_filter *filter);
+static int eth_igb_flex_filter_handle(struct rte_eth_dev *dev,
+			enum rte_filter_op filter_op,
+			void *arg);
 static int eth_igb_add_5tuple_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_5tuple_filter *filter, uint16_t rx_queue);
@@ -271,9 +271,6 @@ static struct eth_dev_ops eth_igb_ops = {
 	.add_2tuple_filter       = eth_igb_add_2tuple_filter,
 	.remove_2tuple_filter    = eth_igb_remove_2tuple_filter,
 	.get_2tuple_filter       = eth_igb_get_2tuple_filter,
-	.add_flex_filter         = eth_igb_add_flex_filter,
-	.remove_flex_filter      = eth_igb_remove_flex_filter,
-	.get_flex_filter         = eth_igb_get_flex_filter,
 	.add_5tuple_filter       = eth_igb_add_5tuple_filter,
 	.remove_5tuple_filter    = eth_igb_remove_5tuple_filter,
 	.get_5tuple_filter       = eth_igb_get_5tuple_filter,
@@ -470,6 +467,8 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 	struct e1000_vfta * shadow_vfta =
 			E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 
 	pci_dev = eth_dev->pci_dev;
@@ -601,6 +600,9 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	igb_intr_enable(eth_dev);
 
+	TAILQ_INIT(&filter_info->flex_list);
+	filter_info->flex_mask = 0;
+
 	return 0;
 
 err_late:
@@ -926,7 +928,10 @@ static void
 eth_igb_stop(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 	struct rte_eth_link link;
+	struct e1000_flex_filter *p_flex;
 
 	igb_intr_disable(hw);
 	igb_pf_reset_hw(hw);
@@ -949,6 +954,13 @@ eth_igb_stop(struct rte_eth_dev *dev)
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_igb_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all flex filters of the device */
+	while ((p_flex = TAILQ_FIRST(&filter_info->flex_list))) {
+		TAILQ_REMOVE(&filter_info->flex_list, p_flex, entries);
+		rte_free(p_flex);
+	}
+	filter_info->flex_mask = 0;
 }
 
 static void
@@ -2652,161 +2664,224 @@ eth_igb_get_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
 	return -ENOENT;
 }
 
-/*
- * add a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that will be added.
- * rx_queue: the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *     - On failure, a negative value.
- */
-static int
-eth_igb_add_flex_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue)
+static inline struct e1000_flex_filter *
+eth_igb_flex_filter_lookup(struct e1000_flex_filter_list *filter_list,
+			struct e1000_flex_filter_info *key)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t wufc, en_bits = 0;
-	uint32_t queueing = 0;
-	uint32_t reg_off = 0;
-	uint8_t i, j = 0;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
-
-	if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
-		filter->len % 8 != 0 ||
-		filter->priority > E1000_MAX_FLEX_FILTER_PRI)
-		return -EINVAL;
-
-	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	en_bits = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
-	if ((wufc & en_bits) == en_bits)
-		return -EINVAL;  /* the filter is in use. */
+	struct e1000_flex_filter *it;
 
-	E1000_WRITE_REG(hw, E1000_WUFC,
-		wufc | E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index));
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_flex_filter_info)) == 0)
+			return it;
+	}
 
-	j = 0;
-	if (index < E1000_MAX_FHFT)
-		reg_off = E1000_FHFT(index);
-	else
-		reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
-
-	for (i = 0; i < 16; i++) {
-		E1000_WRITE_REG(hw, reg_off + i*4*4, filter->dwords[j]);
-		E1000_WRITE_REG(hw, reg_off + (i*4+1)*4, filter->dwords[++j]);
-		E1000_WRITE_REG(hw, reg_off + (i*4+2)*4,
-				(uint32_t)filter->mask[i]);
-		++j;
-	}
-	queueing |= filter->len |
-		(rx_queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) |
-		(filter->priority << E1000_FHFT_QUEUEING_PRIO_SHIFT);
-	E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET, queueing);
-	return 0;
+	return NULL;
 }
 
-/*
- * remove a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
 static int
-eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
-				uint16_t index)
+eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter,
+			bool add)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t wufc, reg_off = 0;
-	uint8_t i;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_flex_filter *flex_filter, *it;
+	uint32_t wufc, queueing, mask;
+	uint32_t reg_off;
+	uint8_t shift, i, j = 0;
+
+	flex_filter = rte_zmalloc("e1000_flex_filter",
+			sizeof(struct e1000_flex_filter), 0);
+	if (flex_filter == NULL)
+		return -ENOMEM;
 
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	flex_filter->filter_info.len = filter->len;
+	flex_filter->filter_info.priority = filter->priority;
+	memcpy(flex_filter->filter_info.dwords, filter->bytes, filter->len);
+	for (i = 0; i < RTE_ALIGN(filter->len, CHAR_BIT) / CHAR_BIT; i++) {
+		mask = 0;
+		/* reverse bits in flex filter's mask*/
+		for (shift = 0; shift < CHAR_BIT; shift++) {
+			if (filter->mask[i] & (0x01 << shift))
+				mask |= (0x80 >> shift);
+		}
+		flex_filter->filter_info.mask[i] = mask;
+	}
 
 	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	E1000_WRITE_REG(hw, E1000_WUFC, wufc & (~(E1000_WUFC_FLX0 << index)));
-
-	if (index < E1000_MAX_FHFT)
-		reg_off = E1000_FHFT(index);
+	if (flex_filter->index < E1000_MAX_FHFT)
+		reg_off = E1000_FHFT(flex_filter->index);
 	else
-		reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
+		reg_off = E1000_FHFT_EXT(flex_filter->index - E1000_MAX_FHFT);
+
+	if (add) {
+		if (eth_igb_flex_filter_lookup(&filter_info->flex_list,
+				&flex_filter->filter_info) != NULL) {
+			PMD_DRV_LOG(ERR, "filter exists.");
+			rte_free(flex_filter);
+			return -EEXIST;
+		}
+		flex_filter->queue = filter->queue;
+		/*
+		 * look for an unused flex filter index
+		 * and insert the filter into the list.
+		 */
+		for (i = 0; i < E1000_MAX_FLEX_FILTERS; i++) {
+			if (!(filter_info->flex_mask & (1 << i))) {
+				filter_info->flex_mask |= 1 << i;
+				flex_filter->index = i;
+				TAILQ_INSERT_TAIL(&filter_info->flex_list,
+					flex_filter,
+					entries);
+				break;
+			}
+		}
+		if (i >= E1000_MAX_FLEX_FILTERS) {
+			PMD_DRV_LOG(ERR, "flex filters are full.");
+			rte_free(flex_filter);
+			return -ENOSYS;
+		}
+
+		E1000_WRITE_REG(hw, E1000_WUFC, wufc | E1000_WUFC_FLEX_HQ |
+				(E1000_WUFC_FLX0 << flex_filter->index));
+		queueing = filter->len |
+			(filter->queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) |
+			(filter->priority << E1000_FHFT_QUEUEING_PRIO_SHIFT);
+		E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET,
+				queueing);
+		for (i = 0; i < E1000_FLEX_FILTERS_MASK_SIZE; i++) {
+			E1000_WRITE_REG(hw, reg_off,
+					flex_filter->filter_info.dwords[j]);
+			reg_off += sizeof(uint32_t);
+			E1000_WRITE_REG(hw, reg_off,
+					flex_filter->filter_info.dwords[++j]);
+			reg_off += sizeof(uint32_t);
+			E1000_WRITE_REG(hw, reg_off,
+				(uint32_t)flex_filter->filter_info.mask[i]);
+			reg_off += sizeof(uint32_t) * 2;
+			++j;
+		}
+	} else {
+		it = eth_igb_flex_filter_lookup(&filter_info->flex_list,
+				&flex_filter->filter_info);
+		if (it == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			rte_free(flex_filter);
+			return -ENOENT;
+		}
+
+		for (i = 0; i < E1000_FHFT_SIZE_IN_DWD; i++)
+			E1000_WRITE_REG(hw, reg_off + i * sizeof(uint32_t), 0);
+		E1000_WRITE_REG(hw, E1000_WUFC, wufc &
+			(~(E1000_WUFC_FLX0 << it->index)));
+
+		filter_info->flex_mask &= ~(1 << it->index);
+		TAILQ_REMOVE(&filter_info->flex_list, it, entries);
+		rte_free(it);
+		rte_free(flex_filter);
+	}
 
-	for (i = 0; i < 64; i++)
-		E1000_WRITE_REG(hw, reg_off + i*4, 0);
 	return 0;
 }
 
-/*
- * get a flex filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that returns.
- * *rx_queue: the pointer of the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
 static int
-eth_igb_get_flex_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue)
+eth_igb_get_flex_filter(struct rte_eth_dev *dev,
+			struct rte_eth_flex_filter *filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_flex_filter flex_filter, *it;
 	uint32_t wufc, queueing, wufc_en = 0;
-	uint8_t i, j;
 
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
-	if (index >= E1000_MAX_FLEXIBLE_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&flex_filter, 0, sizeof(struct e1000_flex_filter));
+	flex_filter.filter_info.len = filter->len;
+	flex_filter.filter_info.priority = filter->priority;
+	memcpy(flex_filter.filter_info.dwords, filter->bytes, filter->len);
+	memcpy(flex_filter.filter_info.mask, filter->mask,
+			RTE_ALIGN(filter->len, sizeof(char)) / sizeof(char));
+
+	it = eth_igb_flex_filter_lookup(&filter_info->flex_list,
+				&flex_filter.filter_info);
+	if (it == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
+	}
 
 	wufc = E1000_READ_REG(hw, E1000_WUFC);
-	wufc_en = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
+	wufc_en = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << it->index);
 
 	if ((wufc & wufc_en) == wufc_en) {
 		uint32_t reg_off = 0;
-		j = 0;
-		if (index < E1000_MAX_FHFT)
-			reg_off = E1000_FHFT(index);
+		if (it->index < E1000_MAX_FHFT)
+			reg_off = E1000_FHFT(it->index);
 		else
-			reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
-
-		for (i = 0; i < 16; i++, j = i * 2) {
-			filter->dwords[j] =
-				E1000_READ_REG(hw, reg_off + i*4*4);
-			filter->dwords[j+1] =
-				E1000_READ_REG(hw, reg_off + (i*4+1)*4);
-			filter->mask[i] =
-				E1000_READ_REG(hw, reg_off + (i*4+2)*4);
-		}
+			reg_off = E1000_FHFT_EXT(it->index - E1000_MAX_FHFT);
+
 		queueing = E1000_READ_REG(hw,
 				reg_off + E1000_FHFT_QUEUEING_OFFSET);
 		filter->len = queueing & E1000_FHFT_QUEUEING_LEN;
 		filter->priority = (queueing & E1000_FHFT_QUEUEING_PRIO) >>
 			E1000_FHFT_QUEUEING_PRIO_SHIFT;
-		*rx_queue = (queueing & E1000_FHFT_QUEUEING_QUEUE) >>
+		filter->queue = (queueing & E1000_FHFT_QUEUEING_QUEUE) >>
 			E1000_FHFT_QUEUEING_QUEUE_SHIFT;
 		return 0;
 	}
 	return -ENOENT;
 }
 
+static int
+eth_igb_flex_filter_handle(struct rte_eth_dev *dev,
+			enum rte_filter_op filter_op,
+			void *arg)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_eth_flex_filter *filter;
+	int ret = 0;
+
+	MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return ret;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	filter = (struct rte_eth_flex_filter *)arg;
+	if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN
+	    || filter->len % sizeof(uint64_t) != 0) {
+		PMD_DRV_LOG(ERR, "filter's length is out of range");
+		return -EINVAL;
+	}
+	if (filter->priority > E1000_MAX_FLEX_FILTER_PRI) {
+		PMD_DRV_LOG(ERR, "filter's priority is out of range");
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = eth_igb_add_del_flex_filter(dev, filter, TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = eth_igb_add_del_flex_filter(dev, filter, FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = eth_igb_get_flex_filter(dev, filter);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
 /*
  * add a 5tuple filter
  *
@@ -3237,6 +3312,9 @@ eth_igb_filter_ctrl(struct rte_eth_dev *dev,
 	case RTE_ETH_FILTER_ETHERTYPE:
 		ret = igb_ethertype_filter_handle(dev, filter_op, arg);
 		break;
+	case RTE_ETH_FILTER_FLEXIBLE:
+		ret = eth_igb_flex_filter_handle(dev, filter_op, arg);
+		break;
 	default:
 		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
 							filter_type);
-- 
1.7.4.1

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

* [dpdk-dev] [PATCH v3 3/5] testpmd: new commands for flex filter
  2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 1/5] ethdev: define flex filter type and its structure Pablo de Lara
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 2/5] e1000: new functions replace old ones for flex filter Pablo de Lara
@ 2015-02-21  1:53       ` Pablo de Lara
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 4/5] ethdev: remove old APIs and structures of " Pablo de Lara
                         ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Pablo de Lara @ 2015-02-21  1:53 UTC (permalink / raw)
  To: dev

From: Jingjing Wu <jingjing.wu@intel.com>

Following commands of flex filter are removed:
  - add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)
    priority (prio_value) queue (queue_id)
  - remove_flex_filter (port_id) index (idx)
  - get_flex_filter (port_id) index (idx)
New command is added for flex filter by using filter_ctrl API and new flex filter structure:
  - flex_filter (port_id) (add|del) len (len_value) bytes (bytes_value) mask (mask_value)
    priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c |  239 ++++++++++++++++++------------------------------
 app/test-pmd/config.c  |   33 -------
 app/test-pmd/testpmd.h |    1 -
 3 files changed, 91 insertions(+), 182 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index d37610a..ca2ff62 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -698,15 +698,10 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"get_syn_filter (port_id) "
 			"    get syn filter info.\n\n"
 
-			"add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)"
-			" priority (prio_value) queue (queue_id) index (idx)\n"
-			"    add a flex filter.\n\n"
-
-			"remove_flex_filter (port_id) index (idx)\n"
-			"    remove a flex filter.\n\n"
-
-			"get_flex_filter (port_id) index (idx)\n"
-			"    get info of a flex filter.\n\n"
+			"flex_filter (port_id) (add|del) len (len_value)"
+			" bytes (bytes_value) mask (mask_value)"
+			" priority (prio_value) queue (queue_id)\n"
+			"    Add/Del a flex filter.\n\n"
 
 			"flow_director_filter (port_id) (add|del)"
 			" flow (ip4|ip4-frag|ip6|ip6-frag)"
@@ -7828,6 +7823,7 @@ cmdline_parse_inst_t cmd_get_5tuple_filter = {
 /* *** ADD/REMOVE A flex FILTER *** */
 struct cmd_flex_filter_result {
 	cmdline_fixed_string_t filter;
+	cmdline_fixed_string_t ops;
 	uint8_t port_id;
 	cmdline_fixed_string_t len;
 	uint8_t len_value;
@@ -7839,8 +7835,6 @@ struct cmd_flex_filter_result {
 	uint8_t priority_value;
 	cmdline_fixed_string_t queue;
 	uint16_t queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t index_value;
 };
 
 static int xdigit2val(unsigned char c)
@@ -7861,113 +7855,106 @@ cmd_flex_filter_parsed(void *parsed_result,
 			  __attribute__((unused)) void *data)
 {
 	int ret = 0;
-	struct rte_flex_filter filter;
+	struct rte_eth_flex_filter filter;
 	struct cmd_flex_filter_result *res = parsed_result;
 	char *bytes_ptr, *mask_ptr;
-	uint16_t len, i, j;
+	uint16_t len, i, j = 0;
 	char c;
-	int val, mod = 0;
-	uint32_t dword = 0;
+	int val;
 	uint8_t byte = 0;
-	uint8_t hex = 0;
 
-	if (!strcmp(res->filter, "add_flex_filter")) {
-		if (res->len_value > 128) {
-			printf("the len exceed the max length 128\n");
-			return;
-		}
-		memset(&filter, 0, sizeof(struct rte_flex_filter));
-		filter.len = res->len_value;
-		filter.priority = res->priority_value;
-		bytes_ptr = res->bytes_value;
-		mask_ptr = res->mask_value;
-
-		j = 0;
-		 /* translate bytes string to uint_32 array. */
-		if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
-			(bytes_ptr[1] == 'X')))
-			bytes_ptr += 2;
-		len = strnlen(bytes_ptr, res->len_value * 2);
-		if (len == 0 || (len % 8 != 0)) {
-			printf("please check len and bytes input\n");
+	if (res->len_value > RTE_FLEX_FILTER_MAXLEN) {
+		printf("the len exceed the max length 128\n");
+		return;
+	}
+	memset(&filter, 0, sizeof(struct rte_eth_flex_filter));
+	filter.len = res->len_value;
+	filter.priority = res->priority_value;
+	filter.queue = res->queue_id;
+	bytes_ptr = res->bytes_value;
+	mask_ptr = res->mask_value;
+
+	 /* translate bytes string to array. */
+	if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
+		(bytes_ptr[1] == 'X')))
+		bytes_ptr += 2;
+	len = strnlen(bytes_ptr, res->len_value * 2);
+	if (len == 0 || (len % 8 != 0)) {
+		printf("please check len and bytes input\n");
+		return;
+	}
+	for (i = 0; i < len; i++) {
+		c = bytes_ptr[i];
+		if (isxdigit(c) == 0) {
+			/* invalid characters. */
+			printf("invalid input\n");
 			return;
 		}
-		for (i = 0; i < len; i++) {
-			c = bytes_ptr[i];
-			if (isxdigit(c) == 0) {
-				/* invalid characters. */
-				printf("invalid input\n");
-				return;
-			}
-			val = xdigit2val(c);
-			mod = i % 8;
-			if (i % 2) {
-				byte |= val;
-				dword |= byte << (4 * mod - 4);
-				byte = 0;
-			} else
-				byte |= val << 4;
-			if (mod == 7) {
-				filter.dwords[j] = dword;
-				printf("dwords[%d]:%08x ", j, filter.dwords[j]);
-				j++;
-				dword = 0;
-			}
-		}
-		printf("\n");
-		 /* translate mask string to uint8_t array. */
-		j = 0;
-		if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
-			(mask_ptr[1] == 'X')))
-			mask_ptr += 2;
-		len = strnlen(mask_ptr, (res->len_value+3)/4);
-		if (len == 0) {
+		val = xdigit2val(c);
+		if (i % 2) {
+			byte |= val;
+			filter.bytes[j] = byte;
+			printf("bytes[%d]:%02x ", j, filter.bytes[j]);
+			j++;
+			byte = 0;
+		} else
+			byte |= val << 4;
+	}
+	printf("\n");
+	 /* translate mask string to uint8_t array. */
+	if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
+		(mask_ptr[1] == 'X')))
+		mask_ptr += 2;
+	len = strnlen(mask_ptr, (res->len_value + 3) / 4);
+	if (len == 0) {
+		printf("invalid input\n");
+		return;
+	}
+	j = 0;
+	byte = 0;
+	for (i = 0; i < len; i++) {
+		c = mask_ptr[i];
+		if (isxdigit(c) == 0) {
+			/* invalid characters. */
 			printf("invalid input\n");
 			return;
 		}
-		for (i = 0; i < len; i++) {
-			c = mask_ptr[i];
-			if (isxdigit(c) == 0) {
-				/* invalid characters. */
-				printf("invalid input\n");
-				return;
-			}
-			val = xdigit2val(c);
-			hex |= (uint8_t)(val & 0x8) >> 3;
-			hex |= (uint8_t)(val & 0x4) >> 1;
-			hex |= (uint8_t)(val & 0x2) << 1;
-			hex |= (uint8_t)(val & 0x1) << 3;
-			if (i % 2) {
-				byte |= hex << 4;
-				filter.mask[j] = byte;
-				printf("mask[%d]:%02x ", j, filter.mask[j]);
-				j++;
-				byte = 0;
-			} else
-				byte |= hex;
-			hex = 0;
-		}
-		printf("\n");
-		printf("call function rte_eth_dev_add_flex_filter: "
-			"index = %d, queue-id = %d, len = %d, priority = %d\n",
-			res->index_value, res->queue_id,
-			filter.len, filter.priority);
-		ret = rte_eth_dev_add_flex_filter(res->port_id, res->index_value,
-				&filter, res->queue_id);
+		val = xdigit2val(c);
+		if (i % 2) {
+			byte |= val;
+			filter.mask[j] = byte;
+			printf("mask[%d]:%02x ", j, filter.mask[j]);
+			j++;
+			byte = 0;
+		} else
+			byte |= val << 4;
+	}
+	printf("\n");
 
-	} else if (!strcmp(res->filter, "remove_flex_filter"))
-		ret = rte_eth_dev_remove_flex_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_flex_filter"))
-		get_flex_filter(res->port_id, res->index_value);
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_FLEXIBLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_FLEXIBLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
 
 	if (ret < 0)
 		printf("flex filter setting error: (%s)\n", strerror(-ret));
 }
 
+cmdline_parse_token_string_t cmd_flex_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+				filter, "flex_filter");
 cmdline_parse_token_num_t cmd_flex_filter_port_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
 				port_id, UINT8);
+cmdline_parse_token_string_t cmd_flex_filter_ops =
+	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+				ops, "add#del");
 cmdline_parse_token_string_t cmd_flex_filter_len =
 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
 				len, "len");
@@ -7998,22 +7985,14 @@ cmdline_parse_token_string_t cmd_flex_filter_queue =
 cmdline_parse_token_num_t cmd_flex_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_flex_filter_index =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_flex_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
-				index_value, UINT16);
-cmdline_parse_token_string_t cmd_flex_filter_add_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "add_flex_filter");
-cmdline_parse_inst_t cmd_add_flex_filter = {
+cmdline_parse_inst_t cmd_flex_filter = {
 	.f = cmd_flex_filter_parsed,
 	.data = NULL,
-	.help_str = "add a flex filter",
+	.help_str = "add/del a flex filter",
 	.tokens = {
-		(void *)&cmd_flex_filter_add_filter,
+		(void *)&cmd_flex_filter_filter,
 		(void *)&cmd_flex_filter_port_id,
+		(void *)&cmd_flex_filter_ops,
 		(void *)&cmd_flex_filter_len,
 		(void *)&cmd_flex_filter_len_value,
 		(void *)&cmd_flex_filter_bytes,
@@ -8024,40 +8003,6 @@ cmdline_parse_inst_t cmd_add_flex_filter = {
 		(void *)&cmd_flex_filter_priority_value,
 		(void *)&cmd_flex_filter_queue,
 		(void *)&cmd_flex_filter_queue_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_flex_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "remove_flex_filter");
-cmdline_parse_inst_t cmd_remove_flex_filter = {
-	.f = cmd_flex_filter_parsed,
-	.data = NULL,
-	.help_str = "remove a flex filter",
-	.tokens = {
-		(void *)&cmd_flex_filter_remove_filter,
-		(void *)&cmd_flex_filter_port_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_flex_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-				filter, "get_flex_filter");
-cmdline_parse_inst_t cmd_get_flex_filter = {
-	.f = cmd_flex_filter_parsed,
-	.data = NULL,
-	.help_str = "get a flex filter",
-	.tokens = {
-		(void *)&cmd_flex_filter_get_filter,
-		(void *)&cmd_flex_filter_port_id,
-		(void *)&cmd_flex_filter_index,
-		(void *)&cmd_flex_filter_index_value,
 		NULL,
 	},
 };
@@ -9214,9 +9159,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_add_5tuple_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_5tuple_filter,
 	(cmdline_parse_inst_t *)&cmd_get_5tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_add_flex_filter,
-	(cmdline_parse_inst_t *)&cmd_remove_flex_filter,
-	(cmdline_parse_inst_t *)&cmd_get_flex_filter,
+	(cmdline_parse_inst_t *)&cmd_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_add_del_ip_flow_director,
 	(cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director,
 	(cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 6bcd23c..a48aa5c 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2257,36 +2257,3 @@ get_5tuple_filter(uint8_t port_id, uint16_t index)
 			filter.priority, filter.tcp_flags, rx_queue);
 	}
 }
-void
-get_flex_filter(uint8_t port_id, uint16_t index)
-
-{
-	struct rte_flex_filter filter;
-	int ret = 0;
-	uint16_t rx_queue;
-	int i, j;
-
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_flex_filter(port_id, index,
-				&filter, &rx_queue);
-	if (ret < 0) {
-		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
-		else
-			printf("get flex filter fails(%s)\n", strerror(-ret));
-		return;
-	} else {
-		printf("filter[%d]: ", index);
-		printf("\n    length: %d", filter.len);
-		printf("\n    dword[]: 0x");
-		for (i = 0; i < 32; i++)
-			printf("%08x ", (unsigned)rte_be_to_cpu_32(filter.dwords[i]));
-		printf("\n    mask[]: 0b");
-		for (i = 0; i < 16; i++) {
-			for (j = 0; j < 8; j++)
-				printf("%c", (filter.mask[i] & (1 << j)) ? '1' : '0');
-		}
-		printf("\n    priority: %d    queue: %d\n",
-			filter.priority, rx_queue);
-	}
-}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 581130b..1bfaeea 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -564,7 +564,6 @@ void get_syn_filter(uint8_t port_id);
 void get_ethertype_filter(uint8_t port_id, uint16_t index);
 void get_2tuple_filter(uint8_t port_id, uint16_t index);
 void get_5tuple_filter(uint8_t port_id, uint16_t index);
-void get_flex_filter(uint8_t port_id, uint16_t index);
 int port_id_is_invalid(portid_t port_id);
 int rx_queue_id_is_invalid(queueid_t rxq_id);
 int tx_queue_id_is_invalid(queueid_t txq_id);
-- 
1.7.4.1

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

* [dpdk-dev] [PATCH v3 4/5] ethdev: remove old APIs and structures of flex filter
  2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
                         ` (2 preceding siblings ...)
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 3/5] testpmd: new commands " Pablo de Lara
@ 2015-02-21  1:53       ` Pablo de Lara
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 5/5] doc: commands changed in testpmd_funcs for " Pablo de Lara
  2015-02-22  1:29       ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Thomas Monjalon
  5 siblings, 0 replies; 14+ messages in thread
From: Pablo de Lara @ 2015-02-21  1:53 UTC (permalink / raw)
  To: dev

From: Jingjing Wu <jingjing.wu@intel.com>

Structure rte_flex_filter is removed.
Following APIs are removed:
  - rte_eth_dev_add_flex_filter
  - rte_eth_dev_remove_flex_filter
  - rte_eth_dev_get_flex_filter

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_ethdev.c |   51 -----------------------
 lib/librte_ether/rte_ethdev.h |   89 -----------------------------------------
 2 files changed, 0 insertions(+), 140 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 17be2f3..ccff0ef 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3177,57 +3177,6 @@ rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
 }
 
 int
-rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_flex_filter, -ENOTSUP);
-	return (*dev->dev_ops->add_flex_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_remove_flex_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_flex_filter, -ENOTSUP);
-	return (*dev->dev_ops->remove_flex_filter)(dev, index);
-}
-
-int
-rte_eth_dev_get_flex_filter(uint8_t port_id, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (filter == NULL || rx_queue == NULL)
-		return -EINVAL;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_flex_filter, -ENOTSUP);
-	return (*dev->dev_ops->get_flex_filter)(dev, index, filter,
-						rx_queue);
-}
-
-int
 rte_eth_dev_filter_supported(uint8_t port_id, enum rte_filter_type filter_type)
 {
 	struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index fd8451a..82f2eb1 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -996,17 +996,6 @@ struct rte_2tuple_filter {
 };
 
 /**
- *  A structure used to define a flex filter.
- */
-struct rte_flex_filter {
-	uint16_t len;
-	uint32_t dwords[32];  /**< flex bytes in big endian. */
-	uint8_t mask[16];     /**< if mask bit is 1b, do not compare
-				   corresponding byte in dwords. */
-	uint8_t priority;
-};
-
-/**
  *  A structure used to define a 5tuple filter.
  */
 struct rte_5tuple_filter {
@@ -1399,20 +1388,6 @@ typedef int (*eth_get_5tuple_filter_t)(struct rte_eth_dev *dev,
 			uint16_t *rx_queue);
 /**< @internal Get a 5tuple filter rule on an Ethernet device */
 
-typedef int (*eth_add_flex_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_flex_filter *filter,
-			uint16_t rx_queue);
-/**< @internal Setup a new flex filter rule on an Ethernet device */
-
-typedef int (*eth_remove_flex_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index);
-/**< @internal Remove a flex filter rule on an Ethernet device */
-
-typedef int (*eth_get_flex_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_flex_filter *filter,
-			uint16_t *rx_queue);
-/**< @internal Get a flex filter rule on an Ethernet device */
-
 typedef int (*eth_filter_ctrl_t)(struct rte_eth_dev *dev,
 				 enum rte_filter_type filter_type,
 				 enum rte_filter_op filter_op,
@@ -1524,9 +1499,6 @@ struct eth_dev_ops {
 	eth_add_5tuple_filter_t        add_5tuple_filter;    /**< add 5tuple filter. */
 	eth_remove_5tuple_filter_t     remove_5tuple_filter; /**< remove 5tuple filter. */
 	eth_get_5tuple_filter_t        get_5tuple_filter;    /**< get 5tuple filter. */
-	eth_add_flex_filter_t          add_flex_filter;      /**< add flex filter. */
-	eth_remove_flex_filter_t       remove_flex_filter;   /**< remove flex filter. */
-	eth_get_flex_filter_t          get_flex_filter;      /**< get flex filter. */
 	eth_filter_ctrl_t              filter_ctrl;          /**< common filter control*/
 };
 
@@ -3579,67 +3551,6 @@ int rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
 			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
 
 /**
- * Add a new flex filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of flex filter.
- * @param filter
- *   The pointer to the structure describing the flex filter rule.
- *   The *rte_flex_filter* structure includes the values of the different fields
- *   to match: the dwords (first len bytes of packet ) and relative masks.
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   flex filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support flex filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- *   - (-ENOENT) if no enabled filter in this index.
- */
-int rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a flex filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of flex filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support flex filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_remove_flex_filter(uint8_t port_id, uint16_t index);
-
-/**
- * Get an flex filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of flex filter.
- * @param filter
- *   A pointer to a structure of type *rte_flex_filter* to be filled with
- *   the information of the flex filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support flex filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- *   - (-ENOENT) if no enabled filter in this index.
- */
-int rte_eth_dev_get_flex_filter(uint8_t port_id, uint16_t index,
-			struct rte_flex_filter *filter, uint16_t *rx_queue);
-
-/**
  * Check whether the filter type is supported on an Ethernet device.
  * All the supported filter types are defined in 'rte_eth_ctrl.h'.
  *
-- 
1.7.4.1

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

* [dpdk-dev] [PATCH v3 5/5] doc: commands changed in testpmd_funcs for flex filter
  2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
                         ` (3 preceding siblings ...)
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 4/5] ethdev: remove old APIs and structures of " Pablo de Lara
@ 2015-02-21  1:53       ` Pablo de Lara
  2015-02-22  1:29       ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Thomas Monjalon
  5 siblings, 0 replies; 14+ messages in thread
From: Pablo de Lara @ 2015-02-21  1:53 UTC (permalink / raw)
  To: dev

From: Jingjing Wu <jingjing.wu@intel.com>

document of new command:
  - flex_filter (port_id) (add|del) len (len_value) bytes (bytes_value)
    mask (mask_value) priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   64 ++++++---------------------
 1 files changed, 14 insertions(+), 50 deletions(-)

diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 218835a..a0cdad7 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1595,71 +1595,35 @@ Example:
 
     syn filter: on, priority: high, queue: 3
 
-add_flex_filter
-~~~~~~~~~~~~~~~
+flex_filter
+~~~~~~~~~~~
 
-Add a Flex filter,
-which recognizes any arbitrary pattern within the first 128 bytes of the packet
+With flex filter, packets can be recognized by any arbitrary pattern within the first 128 bytes of the packet
 and routes packets into one of the receive queues.
 
-add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)
-priority (prio_value) queue (queue_id) index (idx)
+flex_filter (port_id) (add|del) len (len_value) bytes (bytes_value)
+mask (mask_value) priority (prio_value) queue (queue_id)
 
 The available information parameters are:
 
-*   port_id: the port which the Flex filter assigned on.
+*   port_id: the port which the Flex filter is assigned on.
 
-*   len_value: filter length in byte, no greater than 128.
+*   len_value: filter length in bytes, no greater than 128.
 
-*   bytes_string: a sting in format of octal, means the value the flex filter need to match.
+*   bytes_value: a string in hexadecimal, means the value the flex filter needs to match.
 
-*   mask_value: a sting in format of octal, bit 1 means corresponding byte in DWORD participates in the match.
+*   mask_value: a string in hexadecimal, bit 1 means corresponding byte participates in the match.
 
 *   prio_value: the priority of this filter.
 
-*   queue_id: The receive queue associated with this Flex filter.
-
-*   index: the index of this Flex filter
+*   queue_id: the receive queue associated with this Flex filter.
 
 Example:
 
 .. code-block:: console
 
-   testpmd> add_flex_filter 0 len 16 bytes 0x00000000000000000000000008060000 mask 000C priority 3 queue 3 index 0
-
-Assign a packet whose 13th and 14th bytes are 0x0806 to queue 3.
-
-remove_flex_filter
-~~~~~~~~~~~~~~~~~~
-
-Remove a Flex filter
-
-remove_flex_filter (port_id) index (idx)
-
-get_flex_filter
-~~~~~~~~~~~~~~~
-
-Get and display a Flex filter
-
-get_flex_filter (port_id) index (idx)
+   testpmd> flex_filter 0 add len 16 bytes 0x00000000000000000000000008060000
+        mask 000C priority 3 queue 3
 
-Example:
-
-.. code-block:: console
-
-    testpmd> get_flex_filter 0 index 0
-
-    filter[0]:
-
-        length: 16
-
-        dword[]: 0x00000000 00000000 00000000 08060000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
-    00000000 00000000 00000000 00000000 00000000 00000000 00000000
-
-        mask[]:
-    0b0000000000001100000000000000000000000000000000000000000000000000000000
-    0000000000000000000000000000000000000000000000000000000000
-
-        priority: 3   queue: 3
+   testpmd> flex_filter 0 del len 16 bytes 0x00000000000000000000000008060000
+        mask 000C priority 3 queue 3
-- 
1.7.4.1

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

* Re: [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API
  2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
                         ` (4 preceding siblings ...)
  2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 5/5] doc: commands changed in testpmd_funcs for " Pablo de Lara
@ 2015-02-22  1:29       ` Thomas Monjalon
  5 siblings, 0 replies; 14+ messages in thread
From: Thomas Monjalon @ 2015-02-22  1:29 UTC (permalink / raw)
  To: Pablo de Lara, Wu, Jingjing; +Cc: dev

2015-02-21 01:53, Pablo de Lara:
> The patch set uses new filter_ctrl API to replace old flex filter APIs.
> It uses new functions and structure to replace old ones in igb driver, new commands to replace old ones in testpmd, and removes the old APIs.
> 
> v3 changes:
>  - fix testpmd documentation
> 
> v2 changes:
>  - split one patch to patch series
>  - change the command's format in testpmd.
>  - add doc changes in testpmd_funcs.rst
>  - correct the errors reported by checkpatch.pl
> 
> Jingjing Wu (5):
>   ethdev: define flex filter type and its structure
>   e1000: new functions replace old ones for flex filter
>   testpmd: new commands for flex filter
>   ethdev: remove old APIs and structures of flex filter
>   doc: commands changed in testpmd_funcs for flex filter

Applied, thanks.
I also updated version map to remove old API.

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

end of thread, other threads:[~2015-02-22  1:30 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <igbv1>
2015-01-30  4:48 ` [dpdk-dev] [PATCH] igb: integrate flex filter to new API zhida zang
2015-02-15  4:07   ` [dpdk-dev] [PATCH v2 0/5] Integrate flex filter in igb driver " Jingjing Wu
2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 1/5] ethdev: define flex filter type and its structure Jingjing Wu
2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 2/5] e1000: new functions replace old ones for flex filter Jingjing Wu
2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 3/5] testpmd: new commands " Jingjing Wu
2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 4/5] ethdev: remove old APIs and structures of " Jingjing Wu
2015-02-15  4:07     ` [dpdk-dev] [PATCH v2 5/5] doc: commands changed in testpmd_funcs for " Jingjing Wu
2015-02-21  1:53     ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Pablo de Lara
2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 1/5] ethdev: define flex filter type and its structure Pablo de Lara
2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 2/5] e1000: new functions replace old ones for flex filter Pablo de Lara
2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 3/5] testpmd: new commands " Pablo de Lara
2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 4/5] ethdev: remove old APIs and structures of " Pablo de Lara
2015-02-21  1:53       ` [dpdk-dev] [PATCH v3 5/5] doc: commands changed in testpmd_funcs for " Pablo de Lara
2015-02-22  1:29       ` [dpdk-dev] [PATCH v3 0/5] Integrate flex filter in igb driver to new API Thomas Monjalon

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).