[dpdk-dev] [PATCH 01/14] net/sfc/base: support filters for encapsulated packets

Andrew Rybchenko arybchenko at solarflare.com
Tue Feb 27 13:45:13 CET 2018


From: Roman Zhukov <Roman.Zhukov at oktetlabs.ru>

This adds filters for encapsulated packets to the list
returned by ef10_filter_supported_filters().

Signed-off-by: Roman Zhukov <Roman.Zhukov at oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
Reviewed-by: Andy Moreton <amoreton at solarflare.com>
---
 drivers/net/sfc/base/ef10_filter.c | 65 ++++++++++++++++++++++++++++++++------
 1 file changed, 55 insertions(+), 10 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_filter.c b/drivers/net/sfc/base/ef10_filter.c
index 27b5998..f643cdb 100644
--- a/drivers/net/sfc/base/ef10_filter.c
+++ b/drivers/net/sfc/base/ef10_filter.c
@@ -890,6 +890,7 @@ efx_mcdi_get_parser_disp_info(
 	__in				efx_nic_t *enp,
 	__out_ecount(buffer_length)	uint32_t *buffer,
 	__in				size_t buffer_length,
+	__in				boolean_t encap,
 	__out				size_t *list_lengthp)
 {
 	efx_mcdi_req_t req;
@@ -906,7 +907,8 @@ efx_mcdi_get_parser_disp_info(
 	req.emr_out_buf = payload;
 	req.emr_out_length = MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX;
 
-	MCDI_IN_SET_DWORD(req, GET_PARSER_DISP_INFO_OUT_OP,
+	MCDI_IN_SET_DWORD(req, GET_PARSER_DISP_INFO_OUT_OP, encap ?
+	    MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_ENCAP_RX_MATCHES :
 	    MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES);
 
 	efx_mcdi_execute(enp, &req);
@@ -966,28 +968,66 @@ ef10_filter_supported_filters(
 	__in				size_t buffer_length,
 	__out				size_t *list_lengthp)
 {
-
+	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	size_t mcdi_list_length;
+	size_t mcdi_encap_list_length;
 	size_t list_length;
 	uint32_t i;
+	uint32_t next_buf_idx;
+	size_t next_buf_length;
 	efx_rc_t rc;
+	boolean_t no_space = B_FALSE;
 	efx_filter_match_flags_t all_filter_flags =
 	    (EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_LOC_HOST |
 	    EFX_FILTER_MATCH_REM_MAC | EFX_FILTER_MATCH_REM_PORT |
 	    EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_PORT |
 	    EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_INNER_VID |
 	    EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_IP_PROTO |
+	    EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST |
+	    EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST |
 	    EFX_FILTER_MATCH_UNKNOWN_MCAST_DST |
 	    EFX_FILTER_MATCH_UNKNOWN_UCAST_DST);
 
-	rc = efx_mcdi_get_parser_disp_info(enp, buffer, buffer_length,
-					    &mcdi_list_length);
+	/*
+	 * Two calls to MC_CMD_GET_PARSER_DISP_INFO are needed: one to get the
+	 * list of supported filters for ordinary packets, and then another to
+	 * get the list of supported filters for encapsulated packets.
+	 */
+	rc = efx_mcdi_get_parser_disp_info(enp, buffer, buffer_length, B_FALSE,
+	    &mcdi_list_length);
 	if (rc != 0) {
-		if (rc == ENOSPC) {
-			/* Pass through mcdi_list_length for the list length */
-			*list_lengthp = mcdi_list_length;
+		if (rc == ENOSPC)
+			no_space = B_TRUE;
+		else
+			goto fail1;
+	}
+
+	if (no_space) {
+		next_buf_idx = 0;
+		next_buf_length = 0;
+	} else {
+		EFSYS_ASSERT(mcdi_list_length < buffer_length);
+		next_buf_idx = mcdi_list_length;
+		next_buf_length = buffer_length - mcdi_list_length;
+	}
+
+	if (encp->enc_tunnel_encapsulations_supported != 0) {
+		rc = efx_mcdi_get_parser_disp_info(enp, &buffer[next_buf_idx],
+		    next_buf_length, B_TRUE, &mcdi_encap_list_length);
+		if (rc != 0) {
+			if (rc == ENOSPC)
+				no_space = B_TRUE;
+			else
+				goto fail2;
 		}
-		goto fail1;
+	} else {
+		mcdi_encap_list_length = 0;
+	}
+
+	if (no_space) {
+		*list_lengthp = mcdi_list_length + mcdi_encap_list_length;
+		rc = ENOSPC;
+		goto fail3;
 	}
 
 	/*
@@ -1000,9 +1040,10 @@ ef10_filter_supported_filters(
 	 * of the matches is preserved as they are ordered from highest to
 	 * lowest priority.
 	 */
-	EFSYS_ASSERT(mcdi_list_length <= buffer_length);
+	EFSYS_ASSERT(mcdi_list_length + mcdi_encap_list_length <=
+	    buffer_length);
 	list_length = 0;
-	for (i = 0; i < mcdi_list_length; i++) {
+	for (i = 0; i < mcdi_list_length + mcdi_encap_list_length; i++) {
 		if ((buffer[i] & ~all_filter_flags) == 0) {
 			buffer[list_length] = buffer[i];
 			list_length++;
@@ -1013,6 +1054,10 @@ ef10_filter_supported_filters(
 
 	return (0);
 
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
-- 
2.7.4



More information about the dev mailing list