common/sfc_efx/base: support adding flag action to set
authorIvan Malov <ivan.malov@oktetlabs.ru>
Tue, 20 Oct 2020 09:13:10 +0000 (10:13 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 3 Nov 2020 22:24:25 +0000 (23:24 +0100)
This action can be added at any point before DELIVER.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
drivers/common/sfc_efx/base/efx.h
drivers/common/sfc_efx/base/efx_impl.h
drivers/common/sfc_efx/base/efx_mae.c
drivers/common/sfc_efx/version.map

index 193ffff..e03da22 100644 (file)
@@ -4178,6 +4178,11 @@ efx_mae_action_set_populate_vlan_push(
        __in                            uint16_t tpid_be,
        __in                            uint16_t tci_be);
 
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_flag(
+       __in                            efx_mae_actions_t *spec);
+
 LIBEFX_API
 extern __checkReturn                   efx_rc_t
 efx_mae_action_set_populate_deliver(
index 84276dc..24e53a2 100644 (file)
@@ -1704,6 +1704,14 @@ typedef enum efx_mae_action_e {
        EFX_MAE_ACTION_VLAN_POP,
        EFX_MAE_ACTION_VLAN_PUSH,
 
+       /*
+        * These actions are not strictly ordered and can
+        * be passed by a client in any order (before DELIVER).
+        * However, these enumerants must be kept compactly
+        * in the end of the enumeration (before DELIVER).
+        */
+       EFX_MAE_ACTION_FLAG,
+
        /* DELIVER is always the last action. */
        EFX_MAE_ACTION_DELIVER,
 
index f3d7bf7..38a7c1a 100644 (file)
@@ -715,6 +715,37 @@ fail1:
        return (rc);
 }
 
+static __checkReturn                   efx_rc_t
+efx_mae_action_set_add_flag(
+       __in                            efx_mae_actions_t *spec,
+       __in                            size_t arg_size,
+       __in_bcount(arg_size)           const uint8_t *arg)
+{
+       efx_rc_t rc;
+
+       _NOTE(ARGUNUSED(spec))
+
+       if (arg_size != 0) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if (arg != NULL) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       /* This action does not have any arguments, so do nothing here. */
+
+       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,
@@ -757,6 +788,9 @@ static const efx_mae_action_desc_t efx_mae_actions[EFX_MAE_NACTIONS] = {
        [EFX_MAE_ACTION_VLAN_PUSH] = {
                .emad_add = efx_mae_action_set_add_vlan_push
        },
+       [EFX_MAE_ACTION_FLAG] = {
+               .emad_add = efx_mae_action_set_add_flag
+       },
        [EFX_MAE_ACTION_DELIVER] = {
                .emad_add = efx_mae_action_set_add_deliver
        }
@@ -765,8 +799,17 @@ static const efx_mae_action_desc_t efx_mae_actions[EFX_MAE_NACTIONS] = {
 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_DELIVER);
 
+/*
+ * These actions must not be added after DELIVER, but
+ * they can have any place among the rest of
+ * strictly ordered actions.
+ */
+static const uint32_t efx_mae_action_nonstrict_map =
+       (1U << EFX_MAE_ACTION_FLAG);
+
 static const uint32_t efx_mae_action_repeat_map =
        (1U << EFX_MAE_ACTION_VLAN_POP) |
        (1U << EFX_MAE_ACTION_VLAN_PUSH);
@@ -793,6 +836,7 @@ 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);
 
        if (type >= EFX_ARRAY_SIZE(efx_mae_actions)) {
                rc = EINVAL;
@@ -811,9 +855,10 @@ efx_mae_action_set_spec_populate(
        }
 
        if ((efx_mae_action_ordered_map & action_mask) != 0) {
+               uint32_t strict_ordered_map =
+                   efx_mae_action_ordered_map & ~efx_mae_action_nonstrict_map;
                uint32_t later_actions_mask =
-                       efx_mae_action_ordered_map &
-                       ~(action_mask | (action_mask - 1));
+                   strict_ordered_map & ~(action_mask | (action_mask - 1));
 
                if ((spec->ema_actions & later_actions_mask) != 0) {
                        /* Cannot add an action after later ordered actions. */
@@ -867,6 +912,14 @@ efx_mae_action_set_populate_vlan_push(
            EFX_MAE_ACTION_VLAN_PUSH, sizeof (action), arg));
 }
 
+       __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_flag(
+       __in                            efx_mae_actions_t *spec)
+{
+       return (efx_mae_action_set_spec_populate(spec,
+           EFX_MAE_ACTION_FLAG, 0, NULL));
+}
+
        __checkReturn                   efx_rc_t
 efx_mae_action_set_populate_deliver(
        __in                            efx_mae_actions_t *spec,
@@ -1059,6 +1112,11 @@ efx_mae_action_set_alloc(
                    spec->ema_vlan_push_descs[outer_tag_idx].emavp_tci_be);
        }
 
+       if ((spec->ema_actions & (1U << EFX_MAE_ACTION_FLAG)) != 0) {
+               MCDI_IN_SET_DWORD_FIELD(req, MAE_ACTION_SET_ALLOC_IN_FLAGS,
+                   MAE_ACTION_SET_ALLOC_IN_FLAG, 1);
+       }
+
        MCDI_IN_SET_DWORD(req,
            MAE_ACTION_SET_ALLOC_IN_DELIVER, spec->ema_deliver_mport.sel);
 
index be11b6a..f57f4a3 100644 (file)
@@ -90,6 +90,7 @@ INTERNAL {
        efx_mae_action_set_alloc;
        efx_mae_action_set_free;
        efx_mae_action_set_populate_deliver;
+       efx_mae_action_set_populate_flag;
        efx_mae_action_set_populate_vlan_pop;
        efx_mae_action_set_populate_vlan_push;
        efx_mae_action_set_spec_fini;