From patchwork Tue Dec 1 07:30:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 84648 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 867CDA04DB; Tue, 1 Dec 2020 08:30:43 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D1914C954; Tue, 1 Dec 2020 08:30:40 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by dpdk.org (Postfix) with ESMTP id EC9CC4C7B; Tue, 1 Dec 2020 08:30:37 +0100 (CET) Received: from localhost.localdomain (unknown [188.242.7.54]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by shelob.oktetlabs.ru (Postfix) with ESMTPSA id 90E7B7F41F; Tue, 1 Dec 2020 10:30:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 90E7B7F41F DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=oktetlabs.ru; s=default; t=1606807836; bh=OBz99bQJwhhTSEQpIez7flO1ONqSPS45UyM1Br/lkzs=; h=From:To:Cc:Subject:Date; b=QvlZj0JQUyeec+1Es4v3ENYvc3gwMUuGOfRqf/MQbPQEH+EBxuOOKsBoVQBRbRvY4 ZlvhBI1bRqDIkh8nctJ3gChMl6Ru87JZReCIVdsQpi7FxDHrpgOQGNgjLkbnbDazAW 3/L/V8iGwwBLQ+DT2kQGlVw9wOTqZCu9nKz2QNhc= From: Ivan Malov To: dev@dpdk.org Cc: stable@dpdk.org, Andrew Rybchenko , Andy Moreton Date: Tue, 1 Dec 2020 10:30:10 +0300 Message-Id: <20201201073010.10166-1-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH] common/sfc_efx/base: support alternative MAE match fields X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" If MAE slice is configured without conntrack support, outer rules must match on IP SRC/DST. This isn't reported clearly by the FW because IPv4 and IPv6 have separate SRC/DST pairs. The FW reports status ALWAYS for all these four fields, and having an all-zeros mask for either field prevents the spec from being certified by the existing spec validation method. Extend the spec validation to take the "alternative" fields into account so that legitimate specs don't get turned down. Fixes: ed15d7f8e064 ("common/sfc_efx/base: validate and compare outer match specs") Cc: stable@dpdk.org Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx_mae.c | 52 ++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index 2f5b16727..a54d5f6e6 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -463,6 +463,10 @@ typedef enum efx_mae_field_endianness_e { * The information in it is meant to be used internally by * APIs for addressing a given field in a mask-value pairs * structure and for validation purposes. + * + * A field may have an alternative one. This structure + * has additional members to reference the alternative + * field's mask. See efx_mae_match_spec_is_valid(). */ typedef struct efx_mae_mv_desc_s { efx_mae_field_cap_id_t emmd_field_cap_id; @@ -472,6 +476,14 @@ typedef struct efx_mae_mv_desc_s { size_t emmd_mask_size; size_t emmd_mask_offset; + /* + * Having the alternative field's mask size set to 0 + * means that there's no alternative field specified. + */ + size_t emmd_alt_mask_size; + size_t emmd_alt_mask_offset; + + /* Primary field and the alternative one are of the same endianness. */ efx_mae_field_endianness_t emmd_endianness; } efx_mae_mv_desc_t; @@ -485,6 +497,7 @@ static const efx_mae_mv_desc_t __efx_mae_action_rule_mv_desc_set[] = { MAE_FIELD_MASK_VALUE_PAIRS_##_name##_OFST, \ MAE_FIELD_MASK_VALUE_PAIRS_##_name##_MASK_LEN, \ MAE_FIELD_MASK_VALUE_PAIRS_##_name##_MASK_OFST, \ + 0, 0 /* no alternative field */, \ _endianness \ } @@ -522,6 +535,21 @@ static const efx_mae_mv_desc_t __efx_mae_outer_rule_mv_desc_set[] = { MAE_ENC_FIELD_PAIRS_##_name##_OFST, \ MAE_ENC_FIELD_PAIRS_##_name##_MASK_LEN, \ MAE_ENC_FIELD_PAIRS_##_name##_MASK_OFST, \ + 0, 0 /* no alternative field */, \ + _endianness \ + } + +/* Same as EFX_MAE_MV_DESC(), but also indicates an alternative field. */ +#define EFX_MAE_MV_DESC_ALT(_name, _alt_name, _endianness) \ + [EFX_MAE_FIELD_##_name] = \ + { \ + EFX_MAE_FIELD_ID_##_name, \ + MAE_ENC_FIELD_PAIRS_##_name##_LEN, \ + MAE_ENC_FIELD_PAIRS_##_name##_OFST, \ + MAE_ENC_FIELD_PAIRS_##_name##_MASK_LEN, \ + MAE_ENC_FIELD_PAIRS_##_name##_MASK_OFST, \ + MAE_ENC_FIELD_PAIRS_##_alt_name##_MASK_LEN, \ + MAE_ENC_FIELD_PAIRS_##_alt_name##_MASK_OFST, \ _endianness \ } @@ -533,16 +561,17 @@ static const efx_mae_mv_desc_t __efx_mae_outer_rule_mv_desc_set[] = { EFX_MAE_MV_DESC(ENC_VLAN0_PROTO_BE, EFX_MAE_FIELD_BE), EFX_MAE_MV_DESC(ENC_VLAN1_TCI_BE, EFX_MAE_FIELD_BE), EFX_MAE_MV_DESC(ENC_VLAN1_PROTO_BE, EFX_MAE_FIELD_BE), - EFX_MAE_MV_DESC(ENC_SRC_IP4_BE, EFX_MAE_FIELD_BE), - EFX_MAE_MV_DESC(ENC_DST_IP4_BE, EFX_MAE_FIELD_BE), + EFX_MAE_MV_DESC_ALT(ENC_SRC_IP4_BE, ENC_SRC_IP6_BE, EFX_MAE_FIELD_BE), + EFX_MAE_MV_DESC_ALT(ENC_DST_IP4_BE, ENC_DST_IP6_BE, EFX_MAE_FIELD_BE), EFX_MAE_MV_DESC(ENC_IP_PROTO, EFX_MAE_FIELD_BE), EFX_MAE_MV_DESC(ENC_IP_TOS, EFX_MAE_FIELD_BE), EFX_MAE_MV_DESC(ENC_IP_TTL, EFX_MAE_FIELD_BE), - EFX_MAE_MV_DESC(ENC_SRC_IP6_BE, EFX_MAE_FIELD_BE), - EFX_MAE_MV_DESC(ENC_DST_IP6_BE, EFX_MAE_FIELD_BE), + EFX_MAE_MV_DESC_ALT(ENC_SRC_IP6_BE, ENC_SRC_IP4_BE, EFX_MAE_FIELD_BE), + EFX_MAE_MV_DESC_ALT(ENC_DST_IP6_BE, ENC_DST_IP4_BE, EFX_MAE_FIELD_BE), EFX_MAE_MV_DESC(ENC_L4_SPORT_BE, EFX_MAE_FIELD_BE), EFX_MAE_MV_DESC(ENC_L4_DPORT_BE, EFX_MAE_FIELD_BE), +#undef EFX_MAE_MV_DESC_ALT #undef EFX_MAE_MV_DESC }; @@ -848,7 +877,9 @@ efx_mae_match_spec_is_valid( ++field_id) { const efx_mae_mv_desc_t *descp = &desc_setp[field_id]; efx_mae_field_cap_id_t field_cap_id = descp->emmd_field_cap_id; + const uint8_t *alt_m_buf = mvp + descp->emmd_alt_mask_offset; const uint8_t *m_buf = mvp + descp->emmd_mask_offset; + size_t alt_m_size = descp->emmd_alt_mask_size; size_t m_size = descp->emmd_mask_size; if (m_size == 0) @@ -870,6 +901,19 @@ efx_mae_match_spec_is_valid( break; case MAE_FIELD_SUPPORTED_MATCH_ALWAYS: is_valid = efx_mask_is_all_ones(m_size, m_buf); + + if ((is_valid == B_FALSE) && (alt_m_size != 0)) { + /* + * This field has an alternative one. The FW + * reports ALWAYS for both implying that one + * of them is required to have all-ones mask. + * + * The primary field's mask is incorrect; go + * on to check that of the alternative field. + */ + is_valid = efx_mask_is_all_ones(alt_m_size, + alt_m_buf); + } break; case MAE_FIELD_SUPPORTED_MATCH_NEVER: case MAE_FIELD_UNSUPPORTED: