common/sfc_efx/base: indicate MAE support for encapsulation
[dpdk.git] / drivers / common / sfc_efx / base / efx_mae.c
index 38a7c1a..58b323d 100644 (file)
@@ -39,9 +39,29 @@ efx_mae_get_capabilities(
                goto fail2;
        }
 
+       maep->em_max_n_outer_prios =
+           MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_OUTER_PRIOS);
+
        maep->em_max_n_action_prios =
            MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_ACTION_PRIOS);
 
+       maep->em_encap_types_supported = 0;
+
+       if (MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_ENCAP_TYPE_VXLAN) == 1) {
+               maep->em_encap_types_supported |=
+                   (1U << EFX_TUNNEL_PROTOCOL_VXLAN);
+       }
+
+       if (MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_ENCAP_TYPE_GENEVE) == 1) {
+               maep->em_encap_types_supported |=
+                   (1U << EFX_TUNNEL_PROTOCOL_GENEVE);
+       }
+
+       if (MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_ENCAP_TYPE_NVGRE) == 1) {
+               maep->em_encap_types_supported |=
+                   (1U << EFX_TUNNEL_PROTOCOL_NVGRE);
+       }
+
        maep->em_max_nfields =
            MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_MATCH_FIELD_COUNT);
 
@@ -225,7 +245,9 @@ efx_mae_get_limits(
                goto fail1;
        }
 
+       emlp->eml_max_n_outer_prios = maep->em_max_n_outer_prios;
        emlp->eml_max_n_action_prios = maep->em_max_n_action_prios;
+       emlp->eml_encap_types_supported = maep->em_encap_types_supported;
 
        return (0);
 
@@ -286,6 +308,20 @@ typedef enum efx_mae_field_cap_id_e {
        EFX_MAE_FIELD_ID_ETHER_TYPE_BE = MAE_FIELD_ETHER_TYPE,
        EFX_MAE_FIELD_ID_ETH_SADDR_BE = MAE_FIELD_ETH_SADDR,
        EFX_MAE_FIELD_ID_ETH_DADDR_BE = MAE_FIELD_ETH_DADDR,
+       EFX_MAE_FIELD_ID_VLAN0_TCI_BE = MAE_FIELD_VLAN0_TCI,
+       EFX_MAE_FIELD_ID_VLAN0_PROTO_BE = MAE_FIELD_VLAN0_PROTO,
+       EFX_MAE_FIELD_ID_VLAN1_TCI_BE = MAE_FIELD_VLAN1_TCI,
+       EFX_MAE_FIELD_ID_VLAN1_PROTO_BE = MAE_FIELD_VLAN1_PROTO,
+       EFX_MAE_FIELD_ID_SRC_IP4_BE = MAE_FIELD_SRC_IP4,
+       EFX_MAE_FIELD_ID_DST_IP4_BE = MAE_FIELD_DST_IP4,
+       EFX_MAE_FIELD_ID_IP_PROTO = MAE_FIELD_IP_PROTO,
+       EFX_MAE_FIELD_ID_IP_TOS = MAE_FIELD_IP_TOS,
+       EFX_MAE_FIELD_ID_IP_TTL = MAE_FIELD_IP_TTL,
+       EFX_MAE_FIELD_ID_SRC_IP6_BE = MAE_FIELD_SRC_IP6,
+       EFX_MAE_FIELD_ID_DST_IP6_BE = MAE_FIELD_DST_IP6,
+       EFX_MAE_FIELD_ID_L4_SPORT_BE = MAE_FIELD_L4_SPORT,
+       EFX_MAE_FIELD_ID_L4_DPORT_BE = MAE_FIELD_L4_DPORT,
+       EFX_MAE_FIELD_ID_TCP_FLAGS_BE = MAE_FIELD_TCP_FLAGS,
 
        EFX_MAE_FIELD_CAP_NIDS
 } efx_mae_field_cap_id_t;
@@ -331,6 +367,20 @@ static const efx_mae_mv_desc_t __efx_mae_action_rule_mv_desc_set[] = {
        EFX_MAE_MV_DESC(ETHER_TYPE_BE, EFX_MAE_FIELD_BE),
        EFX_MAE_MV_DESC(ETH_SADDR_BE, EFX_MAE_FIELD_BE),
        EFX_MAE_MV_DESC(ETH_DADDR_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(VLAN0_TCI_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(VLAN0_PROTO_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(VLAN1_TCI_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(VLAN1_PROTO_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(SRC_IP4_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(DST_IP4_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(IP_PROTO, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(IP_TOS, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(IP_TTL, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(SRC_IP6_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(DST_IP6_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(L4_SPORT_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(L4_DPORT_BE, EFX_MAE_FIELD_BE),
+       EFX_MAE_MV_DESC(TCP_FLAGS_BE, EFX_MAE_FIELD_BE),
 
 #undef EFX_MAE_MV_DESC
 };
@@ -357,6 +407,45 @@ efx_mae_mport_by_phy_port(
 
        return (0);
 
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn                   efx_rc_t
+efx_mae_mport_by_pcie_function(
+       __in                            uint32_t pf,
+       __in                            uint32_t vf,
+       __out                           efx_mport_sel_t *mportp)
+{
+       efx_dword_t dword;
+       efx_rc_t rc;
+
+       EFX_STATIC_ASSERT(EFX_PCI_VF_INVALID ==
+           MAE_MPORT_SELECTOR_FUNC_VF_ID_NULL);
+
+       if (pf > EFX_MASK32(MAE_MPORT_SELECTOR_FUNC_PF_ID)) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if (vf > EFX_MASK32(MAE_MPORT_SELECTOR_FUNC_VF_ID)) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       EFX_POPULATE_DWORD_3(dword,
+           MAE_MPORT_SELECTOR_TYPE, MAE_MPORT_SELECTOR_TYPE_FUNC,
+           MAE_MPORT_SELECTOR_FUNC_PF_ID, pf,
+           MAE_MPORT_SELECTOR_FUNC_VF_ID, vf);
+
+       memset(mportp, 0, sizeof (*mportp));
+       mportp->sel = dword.ed_u32[0];
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
 fail1:
        EFSYS_PROBE1(fail1, efx_rc_t, rc);
        return (rc);
@@ -746,6 +835,35 @@ fail1:
        return (rc);
 }
 
+static __checkReturn                   efx_rc_t
+efx_mae_action_set_add_mark(
+       __in                            efx_mae_actions_t *spec,
+       __in                            size_t arg_size,
+       __in_bcount(arg_size)           const uint8_t *arg)
+{
+       efx_rc_t rc;
+
+       if (arg_size != sizeof (spec->ema_mark_value)) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if (arg == NULL) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       memcpy(&spec->ema_mark_value, arg, arg_size);
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
 static __checkReturn                   efx_rc_t
 efx_mae_action_set_add_deliver(
        __in                            efx_mae_actions_t *spec,
@@ -791,6 +909,9 @@ static const efx_mae_action_desc_t efx_mae_actions[EFX_MAE_NACTIONS] = {
        [EFX_MAE_ACTION_FLAG] = {
                .emad_add = efx_mae_action_set_add_flag
        },
+       [EFX_MAE_ACTION_MARK] = {
+               .emad_add = efx_mae_action_set_add_mark
+       },
        [EFX_MAE_ACTION_DELIVER] = {
                .emad_add = efx_mae_action_set_add_deliver
        }
@@ -800,6 +921,7 @@ static const uint32_t efx_mae_action_ordered_map =
        (1U << EFX_MAE_ACTION_VLAN_POP) |
        (1U << EFX_MAE_ACTION_VLAN_PUSH) |
        (1U << EFX_MAE_ACTION_FLAG) |
+       (1U << EFX_MAE_ACTION_MARK) |
        (1U << EFX_MAE_ACTION_DELIVER);
 
 /*
@@ -808,7 +930,8 @@ static const uint32_t efx_mae_action_ordered_map =
  * strictly ordered actions.
  */
 static const uint32_t efx_mae_action_nonstrict_map =
-       (1U << EFX_MAE_ACTION_FLAG);
+       (1U << EFX_MAE_ACTION_FLAG) |
+       (1U << EFX_MAE_ACTION_MARK);
 
 static const uint32_t efx_mae_action_repeat_map =
        (1U << EFX_MAE_ACTION_VLAN_POP) |
@@ -836,7 +959,8 @@ efx_mae_action_set_spec_populate(
            (sizeof (efx_mae_action_repeat_map) * 8));
 
        EFX_STATIC_ASSERT(EFX_MAE_ACTION_DELIVER + 1 == EFX_MAE_NACTIONS);
-       EFX_STATIC_ASSERT(EFX_MAE_ACTION_FLAG + 1 == EFX_MAE_ACTION_DELIVER);
+       EFX_STATIC_ASSERT(EFX_MAE_ACTION_FLAG + 1 == EFX_MAE_ACTION_MARK);
+       EFX_STATIC_ASSERT(EFX_MAE_ACTION_MARK + 1 == EFX_MAE_ACTION_DELIVER);
 
        if (type >= EFX_ARRAY_SIZE(efx_mae_actions)) {
                rc = EINVAL;
@@ -920,6 +1044,17 @@ efx_mae_action_set_populate_flag(
            EFX_MAE_ACTION_FLAG, 0, NULL));
 }
 
+       __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_mark(
+       __in                            efx_mae_actions_t *spec,
+       __in                            uint32_t mark_value)
+{
+       const uint8_t *arg = (const uint8_t *)&mark_value;
+
+       return (efx_mae_action_set_spec_populate(spec,
+           EFX_MAE_ACTION_MARK, sizeof (mark_value), arg));
+}
+
        __checkReturn                   efx_rc_t
 efx_mae_action_set_populate_deliver(
        __in                            efx_mae_actions_t *spec,
@@ -943,6 +1078,25 @@ fail1:
        return (rc);
 }
 
+       __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_drop(
+       __in                            efx_mae_actions_t *spec)
+{
+       efx_mport_sel_t mport;
+       const uint8_t *arg;
+       efx_dword_t dword;
+
+       EFX_POPULATE_DWORD_1(dword,
+           MAE_MPORT_SELECTOR_FLAT, MAE_MPORT_SELECTOR_NULL);
+
+       mport.sel = dword.ed_u32[0];
+
+       arg = (const uint8_t *)&mport.sel;
+
+       return (efx_mae_action_set_spec_populate(spec,
+           EFX_MAE_ACTION_DELIVER, sizeof (mport.sel), arg));
+}
+
        __checkReturn                   boolean_t
 efx_mae_action_set_specs_equal(
        __in                            const efx_mae_actions_t *left,
@@ -1117,6 +1271,14 @@ efx_mae_action_set_alloc(
                    MAE_ACTION_SET_ALLOC_IN_FLAG, 1);
        }
 
+       if ((spec->ema_actions & (1U << EFX_MAE_ACTION_MARK)) != 0) {
+               MCDI_IN_SET_DWORD_FIELD(req, MAE_ACTION_SET_ALLOC_IN_FLAGS,
+                   MAE_ACTION_SET_ALLOC_IN_MARK, 1);
+
+               MCDI_IN_SET_DWORD(req,
+                   MAE_ACTION_SET_ALLOC_IN_MARK_VALUE, spec->ema_mark_value);
+       }
+
        MCDI_IN_SET_DWORD(req,
            MAE_ACTION_SET_ALLOC_IN_DELIVER, spec->ema_deliver_mport.sel);