From f80487b9c79cc0cc3710c28e3115a348da022772 Mon Sep 17 00:00:00 2001 From: Ivan Malov Date: Mon, 18 Jan 2021 01:21:11 +0300 Subject: [PATCH] common/sfc_efx/base: apply mask to value on match field set An application may submit all-zeros masks for a given field to be used in two given specifications and, in the meantime, use different unmasked values. Later on, when compared, the two specifications will prove unequal, and, if the rules in question are outer, the client driver will have to allocate a separate rule for the second specification. Provided that all other match criteria are the same, the HW will deem the two outer rules being duplicates, which is in fact the case. Apply masks to values in efx_mae_match_spec_field_set() API to fix the issue and avoid duplicate outer rule allocations. Fixes: 370ed675a952 ("common/sfc_efx/base: support setting PPORT in match spec") Cc: stable@dpdk.org Reported-by: Andrew Rybchenko Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx_mae.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index cc5d8cfc4f..338a0013f9 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -707,12 +707,32 @@ efx_mae_match_spec_field_set( } if (descp->emmd_endianness == EFX_MAE_FIELD_BE) { + unsigned int i; + /* * The mask/value are in network (big endian) order. * The MCDI request field is also big endian. */ - memcpy(mvp + descp->emmd_value_offset, value, value_size); - memcpy(mvp + descp->emmd_mask_offset, mask, mask_size); + + EFSYS_ASSERT3U(value_size, ==, mask_size); + + for (i = 0; i < value_size; ++i) { + uint8_t *v_bytep = mvp + descp->emmd_value_offset + i; + uint8_t *m_bytep = mvp + descp->emmd_mask_offset + i; + + /* + * Apply the mask (which may be all-zeros) to the value. + * + * If this API is provided with some value to set for a + * given field in one specification and with some other + * value to set for this field in another specification, + * then, if the two masks are all-zeros, the field will + * avoid being counted as a mismatch when comparing the + * specifications using efx_mae_match_specs_equal() API. + */ + *v_bytep = value[i] & mask[i]; + *m_bytep = mask[i]; + } } else { efx_dword_t dword; -- 2.20.1