From 76631541aa2de49562e262af085f9e4afdeb1baf Mon Sep 17 00:00:00 2001 From: Ivan Malov Date: Wed, 6 Jan 2021 13:06:00 +0300 Subject: [PATCH] common/sfc_efx/base: fix MAE match spec class comparison API The helper exits once it encounters a field which hasn't its capability status reported by the FW. Handle the corner case when the two mask-value pairs match for the field, which, in the absence of capability information, is sufficient to deem the class unaffected by the field. Explain this in a comment. Fixes: bb71f7e0a35a ("common/sfc_efx/base: add match specs class comparison API") Cc: stable@dpdk.org Reviewed-by: Andy Moreton Reviewed-by: Andrew Rybchenko Signed-off-by: Ivan Malov --- drivers/common/sfc_efx/base/efx.h | 5 ++++ drivers/common/sfc_efx/base/efx_mae.c | 34 +++++++++++++++++---------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 3b40e28b4e..ccf9c7ab8a 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4283,6 +4283,11 @@ efx_mae_action_set_specs_equal( * Conduct a comparison to check whether two match specifications * of equal rule type (action / outer) and priority would map to * the very same rule class from the firmware's standpoint. + * + * For match specification fields that are not supported by firmware, + * the rule class only matches if the mask/value pairs for that field + * are equal. Clients should use efx_mae_match_spec_is_valid() before + * calling this API to detect usage of unsupported fields. */ LIBEFX_API extern __checkReturn efx_rc_t diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index 7fd42218f6..eb91753ec5 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -1426,18 +1426,32 @@ efx_mae_match_specs_class_cmp( ++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; - - if (descp->emmd_mask_size == 0) + const uint8_t *lmaskp = mvpl + descp->emmd_mask_offset; + const uint8_t *rmaskp = mvpr + descp->emmd_mask_offset; + size_t mask_size = descp->emmd_mask_size; + const uint8_t *lvalp = mvpl + descp->emmd_value_offset; + const uint8_t *rvalp = mvpr + descp->emmd_value_offset; + size_t value_size = descp->emmd_value_size; + + if (mask_size == 0) continue; /* Skip array gap */ - if ((unsigned int)field_cap_id >= field_ncaps) - break; + if ((unsigned int)field_cap_id >= field_ncaps) { + /* + * The FW has not reported capability status for this + * field. It's unknown whether any difference between + * the two masks / values affects the class. The only + * case when the class must be the same is when these + * mask-value pairs match. Otherwise, report mismatch. + */ + if ((memcmp(lmaskp, rmaskp, mask_size) == 0) && + (memcmp(lvalp, rvalp, value_size) == 0)) + continue; + else + break; + } if (field_caps[field_cap_id].emfc_mask_affects_class) { - const uint8_t *lmaskp = mvpl + descp->emmd_mask_offset; - const uint8_t *rmaskp = mvpr + descp->emmd_mask_offset; - size_t mask_size = descp->emmd_mask_size; - if (memcmp(lmaskp, rmaskp, mask_size) != 0) { have_same_class = B_FALSE; break; @@ -1445,10 +1459,6 @@ efx_mae_match_specs_class_cmp( } if (field_caps[field_cap_id].emfc_match_affects_class) { - const uint8_t *lvalp = mvpl + descp->emmd_value_offset; - const uint8_t *rvalp = mvpr + descp->emmd_value_offset; - size_t value_size = descp->emmd_value_size; - if (memcmp(lvalp, rvalp, value_size) != 0) { have_same_class = B_FALSE; break; -- 2.20.1