* 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
++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;
}
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;