sfc: add Layer 3 flag matches to ef100 TC offload
authorEdward Cree <ecree.xilinx@gmail.com>
Thu, 3 Nov 2022 15:27:30 +0000 (15:27 +0000)
committerJakub Kicinski <kuba@kernel.org>
Sat, 5 Nov 2022 02:54:24 +0000 (19:54 -0700)
Support matching on ip_frag and ip_firstfrag.

Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/sfc/mae.c
drivers/net/ethernet/sfc/tc.c
drivers/net/ethernet/sfc/tc.h

index b894fc658867c9484fff6d3ea6f599778dc93cca..e24436ba699cc3b157ddec9d6e5d336888ff9b0d 100644 (file)
@@ -263,6 +263,18 @@ static int efx_mae_match_check_cap_typ(u8 support, enum mask_type typ)
                                       mask_type_name(typ), #_field);          \
        rc;                                                                    \
 })
+/* Booleans need special handling */
+#define CHECK_BIT(_mcdi, _field)       ({                                     \
+       enum mask_type typ = mask->_field ? MASK_ONES : MASK_ZEROES;           \
+                                                                              \
+       rc = efx_mae_match_check_cap_typ(supported_fields[MAE_FIELD_ ## _mcdi],\
+                                        typ);                                 \
+       if (rc)                                                                \
+               NL_SET_ERR_MSG_FMT_MOD(extack,                                 \
+                                      "No support for %s mask in field %s",   \
+                                      mask_type_name(typ), #_field);          \
+       rc;                                                                    \
+})
 
 int efx_mae_match_check_caps(struct efx_nic *efx,
                             const struct efx_tc_match_fields *mask,
@@ -299,10 +311,13 @@ int efx_mae_match_check_caps(struct efx_nic *efx,
            CHECK(SRC_IP6, src_ip6) ||
            CHECK(DST_IP6, dst_ip6) ||
 #endif
+           CHECK_BIT(IS_IP_FRAG, ip_frag) ||
+           CHECK_BIT(IP_FIRST_FRAG, ip_firstfrag) ||
            CHECK(RECIRC_ID, recirc_id))
                return rc;
        return 0;
 }
+#undef CHECK_BIT
 #undef CHECK
 
 static bool efx_mae_asl_id(u32 id)
@@ -472,6 +487,16 @@ static int efx_mae_populate_match_criteria(MCDI_DECLARE_STRUCT_PTR(match_crit),
        }
        MCDI_STRUCT_SET_DWORD(match_crit, MAE_FIELD_MASK_VALUE_PAIRS_V2_INGRESS_MPORT_SELECTOR_MASK,
                              match->mask.ingress_port);
+       EFX_POPULATE_DWORD_2(*_MCDI_STRUCT_DWORD(match_crit, MAE_FIELD_MASK_VALUE_PAIRS_V2_FLAGS),
+                            MAE_FIELD_MASK_VALUE_PAIRS_V2_IS_IP_FRAG,
+                            match->value.ip_frag,
+                            MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_FIRST_FRAG,
+                            match->value.ip_firstfrag);
+       EFX_POPULATE_DWORD_2(*_MCDI_STRUCT_DWORD(match_crit, MAE_FIELD_MASK_VALUE_PAIRS_V2_FLAGS_MASK),
+                            MAE_FIELD_MASK_VALUE_PAIRS_V2_IS_IP_FRAG,
+                            match->mask.ip_frag,
+                            MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_FIRST_FRAG,
+                            match->mask.ip_firstfrag);
        MCDI_STRUCT_SET_BYTE(match_crit, MAE_FIELD_MASK_VALUE_PAIRS_V2_RECIRC_ID,
                             match->value.recirc_id);
        MCDI_STRUCT_SET_BYTE(match_crit, MAE_FIELD_MASK_VALUE_PAIRS_V2_RECIRC_ID_MASK,
index d992fafc844e5c6e32653625fbea4790d1713da1..1a9cc2ad13356e11d6b2a3856703fc4102ebf76a 100644 (file)
@@ -168,7 +168,15 @@ static int efx_tc_flower_parse_match(struct efx_nic *efx,
                                break;
                        }
 
-               if (fm.mask->flags) {
+               if (fm.mask->flags & FLOW_DIS_IS_FRAGMENT) {
+                       match->value.ip_frag = fm.key->flags & FLOW_DIS_IS_FRAGMENT;
+                       match->mask.ip_frag = true;
+               }
+               if (fm.mask->flags & FLOW_DIS_FIRST_FRAG) {
+                       match->value.ip_firstfrag = fm.key->flags & FLOW_DIS_FIRST_FRAG;
+                       match->mask.ip_firstfrag = true;
+               }
+               if (fm.mask->flags & ~(FLOW_DIS_IS_FRAGMENT | FLOW_DIS_FIRST_FRAG)) {
                        NL_SET_ERR_MSG_FMT_MOD(extack, "Unsupported match on control.flags %#x",
                                               fm.mask->flags);
                        return -EOPNOTSUPP;
index aebe9c251b2cca4cb2e56ce99151b6dde6a8bc12..d2b61926657b91ff7b8d117b5cc119563aa9a827 100644 (file)
@@ -38,6 +38,7 @@ struct efx_tc_match_fields {
 #ifdef CONFIG_IPV6
        struct in6_addr src_ip6, dst_ip6;
 #endif
+       bool ip_frag, ip_firstfrag;
 };
 
 struct efx_tc_match {