Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_tc.c
index 6eba574..ba81647 100644 (file)
 #include <net/flow_offload.h>
 #include <net/sch_generic.h>
 #include <net/pkt_cls.h>
-#include <net/tc_act/tc_gact.h>
-#include <net/tc_act/tc_skbedit.h>
 #include <linux/mlx5/fs.h>
 #include <linux/mlx5/device.h>
 #include <linux/rhashtable.h>
 #include <linux/refcount.h>
 #include <linux/completion.h>
-#include <net/tc_act/tc_mirred.h>
-#include <net/tc_act/tc_vlan.h>
-#include <net/tc_act/tc_tunnel_key.h>
 #include <net/tc_act/tc_pedit.h>
 #include <net/tc_act/tc_csum.h>
-#include <net/tc_act/tc_mpls.h>
 #include <net/psample.h>
 #include <net/arp.h>
 #include <net/ipv6_stubs.h>
 #include <net/bareudp.h>
 #include <net/bonding.h>
 #include "en.h"
+#include "en/tc/post_act.h"
 #include "en_rep.h"
 #include "en/rep/tc.h"
 #include "en/rep/neigh.h"
@@ -66,7 +61,7 @@
 #include "en/mod_hdr.h"
 #include "en/tc_priv.h"
 #include "en/tc_tun_encap.h"
-#include "esw/sample.h"
+#include "en/tc/sample.h"
 #include "lib/devcom.h"
 #include "lib/geneve.h"
 #include "lib/fs_chains.h"
@@ -103,7 +98,7 @@ struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[] = {
        [MARK_TO_REG] = mark_to_reg_ct,
        [LABELS_TO_REG] = labels_to_reg_ct,
        [FTEID_TO_REG] = fteid_to_reg_ct,
-       /* For NIC rules we store the retore metadata directly
+       /* For NIC rules we store the restore metadata directly
         * into reg_b that is passed to SW since we don't
         * jump between steering domains.
         */
@@ -252,7 +247,7 @@ get_ct_priv(struct mlx5e_priv *priv)
 }
 
 #if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
-static struct mlx5_esw_psample *
+static struct mlx5e_tc_psample *
 get_sample_priv(struct mlx5e_priv *priv)
 {
        struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
@@ -263,7 +258,7 @@ get_sample_priv(struct mlx5e_priv *priv)
                uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
                uplink_priv = &uplink_rpriv->uplink_priv;
 
-               return uplink_priv->esw_psample;
+               return uplink_priv->tc_psample;
        }
 
        return NULL;
@@ -340,12 +335,12 @@ struct mlx5e_hairpin {
        struct mlx5_core_dev *func_mdev;
        struct mlx5e_priv *func_priv;
        u32 tdn;
-       u32 tirn;
+       struct mlx5e_tir direct_tir;
 
        int num_channels;
        struct mlx5e_rqt indir_rqt;
-       u32 indir_tirn[MLX5E_NUM_INDIR_TIRS];
-       struct mlx5e_ttc_table ttc;
+       struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS];
+       struct mlx5_ttc_table *ttc;
 };
 
 struct mlx5e_hairpin_entry {
@@ -482,126 +477,101 @@ struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex)
 
 static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp)
 {
-       u32 in[MLX5_ST_SZ_DW(create_tir_in)] = {};
-       void *tirc;
+       struct mlx5e_tir_builder *builder;
        int err;
 
+       builder = mlx5e_tir_builder_alloc(false);
+       if (!builder)
+               return -ENOMEM;
+
        err = mlx5_core_alloc_transport_domain(hp->func_mdev, &hp->tdn);
        if (err)
-               goto alloc_tdn_err;
-
-       tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
-
-       MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_DIRECT);
-       MLX5_SET(tirc, tirc, inline_rqn, hp->pair->rqn[0]);
-       MLX5_SET(tirc, tirc, transport_domain, hp->tdn);
+               goto out;
 
-       err = mlx5_core_create_tir(hp->func_mdev, in, &hp->tirn);
+       mlx5e_tir_builder_build_inline(builder, hp->tdn, hp->pair->rqn[0]);
+       err = mlx5e_tir_init(&hp->direct_tir, builder, hp->func_mdev, false);
        if (err)
                goto create_tir_err;
 
-       return 0;
+out:
+       mlx5e_tir_builder_free(builder);
+       return err;
 
 create_tir_err:
        mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn);
-alloc_tdn_err:
-       return err;
+
+       goto out;
 }
 
 static void mlx5e_hairpin_destroy_transport(struct mlx5e_hairpin *hp)
 {
-       mlx5_core_destroy_tir(hp->func_mdev, hp->tirn);
+       mlx5e_tir_destroy(&hp->direct_tir);
        mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn);
 }
 
-static int mlx5e_hairpin_fill_rqt_rqns(struct mlx5e_hairpin *hp, void *rqtc)
-{
-       struct mlx5e_priv *priv = hp->func_priv;
-       int i, ix, sz = MLX5E_INDIR_RQT_SIZE;
-       u32 *indirection_rqt, rqn;
-
-       indirection_rqt = kcalloc(sz, sizeof(*indirection_rqt), GFP_KERNEL);
-       if (!indirection_rqt)
-               return -ENOMEM;
-
-       mlx5e_build_default_indir_rqt(indirection_rqt, sz,
-                                     hp->num_channels);
-
-       for (i = 0; i < sz; i++) {
-               ix = i;
-               if (priv->rss_params.hfunc == ETH_RSS_HASH_XOR)
-                       ix = mlx5e_bits_invert(i, ilog2(sz));
-               ix = indirection_rqt[ix];
-               rqn = hp->pair->rqn[ix];
-               MLX5_SET(rqtc, rqtc, rq_num[i], rqn);
-       }
-
-       kfree(indirection_rqt);
-       return 0;
-}
-
 static int mlx5e_hairpin_create_indirect_rqt(struct mlx5e_hairpin *hp)
 {
-       int inlen, err, sz = MLX5E_INDIR_RQT_SIZE;
        struct mlx5e_priv *priv = hp->func_priv;
        struct mlx5_core_dev *mdev = priv->mdev;
-       void *rqtc;
-       u32 *in;
+       struct mlx5e_rss_params_indir *indir;
+       int err;
 
-       inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * sz;
-       in = kvzalloc(inlen, GFP_KERNEL);
-       if (!in)
+       indir = kvmalloc(sizeof(*indir), GFP_KERNEL);
+       if (!indir)
                return -ENOMEM;
 
-       rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
+       mlx5e_rss_params_indir_init_uniform(indir, hp->num_channels);
+       err = mlx5e_rqt_init_indir(&hp->indir_rqt, mdev, hp->pair->rqn, hp->num_channels,
+                                  mlx5e_rx_res_get_current_hash(priv->rx_res).hfunc,
+                                  indir);
 
-       MLX5_SET(rqtc, rqtc, rqt_actual_size, sz);
-       MLX5_SET(rqtc, rqtc, rqt_max_size, sz);
-
-       err = mlx5e_hairpin_fill_rqt_rqns(hp, rqtc);
-       if (err)
-               goto out;
-
-       err = mlx5_core_create_rqt(mdev, in, inlen, &hp->indir_rqt.rqtn);
-       if (!err)
-               hp->indir_rqt.enabled = true;
-
-out:
-       kvfree(in);
+       kvfree(indir);
        return err;
 }
 
 static int mlx5e_hairpin_create_indirect_tirs(struct mlx5e_hairpin *hp)
 {
        struct mlx5e_priv *priv = hp->func_priv;
-       u32 in[MLX5_ST_SZ_DW(create_tir_in)];
-       int tt, i, err;
-       void *tirc;
+       struct mlx5e_rss_params_hash rss_hash;
+       enum mlx5_traffic_types tt, max_tt;
+       struct mlx5e_tir_builder *builder;
+       int err = 0;
+
+       builder = mlx5e_tir_builder_alloc(false);
+       if (!builder)
+               return -ENOMEM;
+
+       rss_hash = mlx5e_rx_res_get_current_hash(priv->rx_res);
 
        for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
-               struct mlx5e_tirc_config ttconfig = mlx5e_tirc_get_default_config(tt);
+               struct mlx5e_rss_params_traffic_type rss_tt;
 
-               memset(in, 0, MLX5_ST_SZ_BYTES(create_tir_in));
-               tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
+               rss_tt = mlx5e_rss_get_default_tt_config(tt);
 
-               MLX5_SET(tirc, tirc, transport_domain, hp->tdn);
-               MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
-               MLX5_SET(tirc, tirc, indirect_table, hp->indir_rqt.rqtn);
-               mlx5e_build_indir_tir_ctx_hash(&priv->rss_params, &ttconfig, tirc, false);
+               mlx5e_tir_builder_build_rqt(builder, hp->tdn,
+                                           mlx5e_rqt_get_rqtn(&hp->indir_rqt),
+                                           false);
+               mlx5e_tir_builder_build_rss(builder, &rss_hash, &rss_tt, false);
 
-               err = mlx5_core_create_tir(hp->func_mdev, in,
-                                          &hp->indir_tirn[tt]);
+               err = mlx5e_tir_init(&hp->indir_tir[tt], builder, hp->func_mdev, false);
                if (err) {
                        mlx5_core_warn(hp->func_mdev, "create indirect tirs failed, %d\n", err);
                        goto err_destroy_tirs;
                }
+
+               mlx5e_tir_builder_clear(builder);
        }
-       return 0;
 
-err_destroy_tirs:
-       for (i = 0; i < tt; i++)
-               mlx5_core_destroy_tir(hp->func_mdev, hp->indir_tirn[i]);
+out:
+       mlx5e_tir_builder_free(builder);
        return err;
+
+err_destroy_tirs:
+       max_tt = tt;
+       for (tt = 0; tt < max_tt; tt++)
+               mlx5e_tir_destroy(&hp->indir_tir[tt]);
+
+       goto out;
 }
 
 static void mlx5e_hairpin_destroy_indirect_tirs(struct mlx5e_hairpin *hp)
@@ -609,7 +579,7 @@ static void mlx5e_hairpin_destroy_indirect_tirs(struct mlx5e_hairpin *hp)
        int tt;
 
        for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
-               mlx5_core_destroy_tir(hp->func_mdev, hp->indir_tirn[tt]);
+               mlx5e_tir_destroy(&hp->indir_tir[tt]);
 }
 
 static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp,
@@ -620,12 +590,16 @@ static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp,
 
        memset(ttc_params, 0, sizeof(*ttc_params));
 
-       ttc_params->any_tt_tirn = hp->tirn;
-
-       for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
-               ttc_params->indir_tirn[tt] = hp->indir_tirn[tt];
+       ttc_params->ns = mlx5_get_flow_namespace(hp->func_mdev,
+                                                MLX5_FLOW_NAMESPACE_KERNEL);
+       for (tt = 0; tt < MLX5_NUM_TT; tt++) {
+               ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
+               ttc_params->dests[tt].tir_num =
+                       tt == MLX5_TT_ANY ?
+                               mlx5e_tir_get_tirn(&hp->direct_tir) :
+                               mlx5e_tir_get_tirn(&hp->indir_tir[tt]);
+       }
 
-       ft_attr->max_fte = MLX5E_TTC_TABLE_SIZE;
        ft_attr->level = MLX5E_TC_TTC_FT_LEVEL;
        ft_attr->prio = MLX5E_TC_PRIO;
 }
@@ -645,30 +619,31 @@ static int mlx5e_hairpin_rss_init(struct mlx5e_hairpin *hp)
                goto err_create_indirect_tirs;
 
        mlx5e_hairpin_set_ttc_params(hp, &ttc_params);
-       err = mlx5e_create_ttc_table(priv, &ttc_params, &hp->ttc);
-       if (err)
+       hp->ttc = mlx5_create_ttc_table(priv->mdev, &ttc_params);
+       if (IS_ERR(hp->ttc)) {
+               err = PTR_ERR(hp->ttc);
                goto err_create_ttc_table;
+       }
 
        netdev_dbg(priv->netdev, "add hairpin: using %d channels rss ttc table id %x\n",
-                  hp->num_channels, hp->ttc.ft.t->id);
+                  hp->num_channels,
+                  mlx5_get_ttc_flow_table(priv->fs.ttc)->id);
 
        return 0;
 
 err_create_ttc_table:
        mlx5e_hairpin_destroy_indirect_tirs(hp);
 err_create_indirect_tirs:
-       mlx5e_destroy_rqt(priv, &hp->indir_rqt);
+       mlx5e_rqt_destroy(&hp->indir_rqt);
 
        return err;
 }
 
 static void mlx5e_hairpin_rss_cleanup(struct mlx5e_hairpin *hp)
 {
-       struct mlx5e_priv *priv = hp->func_priv;
-
-       mlx5e_destroy_ttc_table(priv, &hp->ttc);
+       mlx5_destroy_ttc_table(hp->ttc);
        mlx5e_hairpin_destroy_indirect_tirs(hp);
-       mlx5e_destroy_rqt(priv, &hp->indir_rqt);
+       mlx5e_rqt_destroy(&hp->indir_rqt);
 }
 
 static struct mlx5e_hairpin *
@@ -903,16 +878,17 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
        }
 
        netdev_dbg(priv->netdev, "add hairpin: tirn %x rqn %x peer %s sqn %x prio %d (log) data %d packets %d\n",
-                  hp->tirn, hp->pair->rqn[0],
+                  mlx5e_tir_get_tirn(&hp->direct_tir), hp->pair->rqn[0],
                   dev_name(hp->pair->peer_mdev->device),
                   hp->pair->sqn[0], match_prio, params.log_data_size, params.log_num_packets);
 
 attach_flow:
        if (hpe->hp->num_channels > 1) {
                flow_flag_set(flow, HAIRPIN_RSS);
-               flow->attr->nic_attr->hairpin_ft = hpe->hp->ttc.ft.t;
+               flow->attr->nic_attr->hairpin_ft =
+                       mlx5_get_ttc_flow_table(hpe->hp->ttc);
        } else {
-               flow->attr->nic_attr->hairpin_tirn = hpe->hp->tirn;
+               flow->attr->nic_attr->hairpin_tirn = mlx5e_tir_get_tirn(&hpe->hp->direct_tir);
        }
 
        flow->hpe = hpe;
@@ -1056,15 +1032,17 @@ err_ft_get:
 
 static int
 mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv,
-                     struct mlx5e_tc_flow_parse_attr *parse_attr,
                      struct mlx5e_tc_flow *flow,
                      struct netlink_ext_ack *extack)
 {
+       struct mlx5e_tc_flow_parse_attr *parse_attr;
        struct mlx5_flow_attr *attr = flow->attr;
        struct mlx5_core_dev *dev = priv->mdev;
-       struct mlx5_fc *counter = NULL;
+       struct mlx5_fc *counter;
        int err;
 
+       parse_attr = attr->parse_attr;
+
        if (flow_flag_test(flow, HAIRPIN)) {
                err = mlx5e_hairpin_flow_add(priv, flow, parse_attr, extack);
                if (err)
@@ -1170,7 +1148,8 @@ mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
                                               mod_hdr_acts);
 #if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
        } else if (flow_flag_test(flow, SAMPLE)) {
-               rule = mlx5_esw_sample_offload(get_sample_priv(flow->priv), spec, attr);
+               rule = mlx5e_tc_sample_offload(get_sample_priv(flow->priv), spec, attr,
+                                              mlx5e_tc_get_flow_tun_id(flow));
 #endif
        } else {
                rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
@@ -1209,7 +1188,7 @@ void mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
 
 #if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
        if (flow_flag_test(flow, SAMPLE)) {
-               mlx5_esw_sample_unoffload(get_sample_priv(flow->priv), flow->rule[0], attr);
+               mlx5e_tc_sample_unoffload(get_sample_priv(flow->priv), flow->rule[0], attr);
                return;
        }
 #endif
@@ -1402,9 +1381,9 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
        bool vf_tun = false, encap_valid = true;
        struct net_device *encap_dev = NULL;
        struct mlx5_esw_flow_attr *esw_attr;
-       struct mlx5_fc *counter = NULL;
        struct mlx5e_rep_priv *rpriv;
        struct mlx5e_priv *out_priv;
+       struct mlx5_fc *counter;
        u32 max_prio, max_chain;
        int err = 0;
        int out_index;
@@ -1591,6 +1570,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
                else
                        mlx5e_detach_mod_hdr(priv, flow);
        }
+       kfree(attr->sample_attr);
        kvfree(attr->parse_attr);
        kvfree(attr->esw_attr->rx_tun_attr);
 
@@ -1600,7 +1580,6 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
        if (flow_flag_test(flow, L3_TO_L2_DECAP))
                mlx5e_detach_decap(priv, flow);
 
-       kfree(flow->attr->esw_attr->sample);
        kfree(flow->attr);
 }
 
@@ -1665,17 +1644,22 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
        }
 }
 
-static int flow_has_tc_fwd_action(struct flow_cls_offload *f)
+static bool flow_requires_tunnel_mapping(u32 chain, struct flow_cls_offload *f)
 {
        struct flow_rule *rule = flow_cls_offload_flow_rule(f);
        struct flow_action *flow_action = &rule->action;
        const struct flow_action_entry *act;
        int i;
 
+       if (chain)
+               return false;
+
        flow_action_for_each(i, act, flow_action) {
                switch (act->id) {
                case FLOW_ACTION_GOTO:
                        return true;
+               case FLOW_ACTION_SAMPLE:
+                       return true;
                default:
                        continue;
                }
@@ -1916,7 +1900,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
                return -EOPNOTSUPP;
 
        needs_mapping = !!flow->attr->chain;
-       sets_mapping = !flow->attr->chain && flow_has_tc_fwd_action(f);
+       sets_mapping = flow_requires_tunnel_mapping(flow->attr->chain, f);
        *match_inner = !needs_mapping;
 
        if ((needs_mapping || sets_mapping) &&
@@ -2489,7 +2473,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
                        spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_3;
                }
        }
-       /* Currenlty supported only for MPLS over UDP */
+       /* Currently supported only for MPLS over UDP */
        if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS) &&
            !netif_is_bareudp(filter_dev)) {
                NL_SET_ERR_MSG_MOD(extack,
@@ -2743,7 +2727,9 @@ static int offload_pedit_fields(struct mlx5e_priv *priv,
                if (s_mask && a_mask) {
                        NL_SET_ERR_MSG_MOD(extack,
                                           "can't set and add to the same HW field");
-                       printk(KERN_WARNING "mlx5: can't set and add to the same HW field (%x)\n", f->field);
+                       netdev_warn(priv->netdev,
+                                   "mlx5: can't set and add to the same HW field (%x)\n",
+                                   f->field);
                        return -EOPNOTSUPP;
                }
 
@@ -2782,8 +2768,9 @@ static int offload_pedit_fields(struct mlx5e_priv *priv,
                if (first < next_z && next_z < last) {
                        NL_SET_ERR_MSG_MOD(extack,
                                           "rewrite of few sub-fields isn't supported");
-                       printk(KERN_WARNING "mlx5: rewrite of few sub-fields (mask %lx) isn't offloaded\n",
-                              mask);
+                       netdev_warn(priv->netdev,
+                                   "mlx5: rewrite of few sub-fields (mask %lx) isn't offloaded\n",
+                                   mask);
                        return -EOPNOTSUPP;
                }
 
@@ -3370,10 +3357,10 @@ static int validate_goto_chain(struct mlx5e_priv *priv,
 
 static int parse_tc_nic_actions(struct mlx5e_priv *priv,
                                struct flow_action *flow_action,
-                               struct mlx5e_tc_flow_parse_attr *parse_attr,
                                struct mlx5e_tc_flow *flow,
                                struct netlink_ext_ack *extack)
 {
+       struct mlx5e_tc_flow_parse_attr *parse_attr;
        struct mlx5_flow_attr *attr = flow->attr;
        struct pedit_headers_action hdrs[2] = {};
        const struct flow_action_entry *act;
@@ -3389,8 +3376,8 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
                return -EOPNOTSUPP;
 
        nic_attr = attr->nic_attr;
-
        nic_attr->flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
+       parse_attr = attr->parse_attr;
 
        flow_action_for_each(i, act, flow_action) {
                switch (act->id) {
@@ -3399,10 +3386,8 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
                                  MLX5_FLOW_CONTEXT_ACTION_COUNT;
                        break;
                case FLOW_ACTION_DROP:
-                       action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
-                       if (MLX5_CAP_FLOWTABLE(priv->mdev,
-                                              flow_table_properties_nic_receive.flow_counter))
-                               action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
+                       action |= MLX5_FLOW_CONTEXT_ACTION_DROP |
+                                 MLX5_FLOW_CONTEXT_ACTION_COUNT;
                        break;
                case FLOW_ACTION_MANGLE:
                case FLOW_ACTION_ADD:
@@ -3443,7 +3428,7 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
                                                   "device is not on same HW, can't offload");
                                netdev_warn(priv->netdev, "device %s not on same HW, can't offload\n",
                                            peer_dev->name);
-                               return -EINVAL;
+                               return -EOPNOTSUPP;
                        }
                        }
                        break;
@@ -3453,7 +3438,7 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
                        if (mark & ~MLX5E_TC_FLOW_ID_MASK) {
                                NL_SET_ERR_MSG_MOD(extack,
                                                   "Bad flow mark - only 16 bit is supported");
-                               return -EINVAL;
+                               return -EOPNOTSUPP;
                        }
 
                        nic_attr->flow_tag = mark;
@@ -3750,20 +3735,19 @@ static int verify_uplink_forwarding(struct mlx5e_priv *priv,
 static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
                                struct flow_action *flow_action,
                                struct mlx5e_tc_flow *flow,
-                               struct netlink_ext_ack *extack,
-                               struct net_device *filter_dev)
+                               struct netlink_ext_ack *extack)
 {
        struct pedit_headers_action hdrs[2] = {};
        struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
        struct mlx5e_tc_flow_parse_attr *parse_attr;
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
+       struct mlx5e_sample_attr sample_attr = {};
        const struct ip_tunnel_info *info = NULL;
        struct mlx5_flow_attr *attr = flow->attr;
        int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS];
        bool ft_flow = mlx5e_is_ft_flow(flow);
        const struct flow_action_entry *act;
        struct mlx5_esw_flow_attr *esw_attr;
-       struct mlx5_sample_attr sample = {};
        bool encap = false, decap = false;
        u32 action = attr->action;
        int err, i, if_count = 0;
@@ -3816,7 +3800,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
                                                   "mpls pop supported only as first action");
                                return -EOPNOTSUPP;
                        }
-                       if (!netif_is_bareudp(filter_dev)) {
+                       if (!netif_is_bareudp(parse_attr->filter_dev)) {
                                NL_SET_ERR_MSG_MOD(extack,
                                                   "mpls pop supported only on bareudp devices");
                                return -EOPNOTSUPP;
@@ -3965,7 +3949,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
                                            "devices %s %s not on same switch HW, can't offload forwarding\n",
                                            priv->netdev->name,
                                            out_dev->name);
-                               return -EINVAL;
+                               return -EOPNOTSUPP;
                        }
                        }
                        break;
@@ -4034,10 +4018,10 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
                                NL_SET_ERR_MSG_MOD(extack, "Sample action with connection tracking is not supported");
                                return -EOPNOTSUPP;
                        }
-                       sample.rate = act->sample.rate;
-                       sample.group_num = act->sample.psample_group->group_num;
+                       sample_attr.rate = act->sample.rate;
+                       sample_attr.group_num = act->sample.psample_group->group_num;
                        if (act->sample.truncate)
-                               sample.trunc_size = act->sample.trunc_size;
+                               sample_attr.trunc_size = act->sample.trunc_size;
                        flow_flag_set(flow, SAMPLE);
                        break;
                default:
@@ -4122,10 +4106,10 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
         * no errors after parsing.
         */
        if (flow_flag_test(flow, SAMPLE)) {
-               esw_attr->sample = kzalloc(sizeof(*esw_attr->sample), GFP_KERNEL);
-               if (!esw_attr->sample)
+               attr->sample_attr = kzalloc(sizeof(*attr->sample_attr), GFP_KERNEL);
+               if (!attr->sample_attr)
                        return -ENOMEM;
-               *esw_attr->sample = sample;
+               *attr->sample_attr = sample_attr;
        }
 
        return 0;
@@ -4318,7 +4302,7 @@ __mlx5e_add_fdb_flow(struct mlx5e_priv *priv,
        if (err)
                goto err_free;
 
-       err = parse_tc_fdb_actions(priv, &rule->action, flow, extack, filter_dev);
+       err = parse_tc_fdb_actions(priv, &rule->action, flow, extack);
        if (err)
                goto err_free;
 
@@ -4464,11 +4448,11 @@ mlx5e_add_nic_flow(struct mlx5e_priv *priv,
        if (err)
                goto err_free;
 
-       err = parse_tc_nic_actions(priv, &rule->action, parse_attr, flow, extack);
+       err = parse_tc_nic_actions(priv, &rule->action, flow, extack);
        if (err)
                goto err_free;
 
-       err = mlx5e_tc_add_nic_flow(priv, parse_attr, flow, extack);
+       err = mlx5e_tc_add_nic_flow(priv, flow, extack);
        if (err)
                goto err_free;
 
@@ -4723,7 +4707,7 @@ static int apply_police_params(struct mlx5e_priv *priv, u64 rate,
                rate_mbps = max_t(u32, rate, 1);
        }
 
-       err = mlx5_esw_modify_vport_rate(esw, vport_num, rate_mbps);
+       err = mlx5_esw_qos_modify_vport_rate(esw, vport_num, rate_mbps);
        if (err)
                NL_SET_ERR_MSG_MOD(extack, "failed applying action to hardware");
 
@@ -4895,6 +4879,7 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
        struct mlx5_core_dev *dev = priv->mdev;
        struct mapping_ctx *chains_mapping;
        struct mlx5_chains_attr attr = {};
+       u64 mapping_id;
        int err;
 
        mlx5e_mod_hdr_tbl_init(&tc->mod_hdr);
@@ -4908,8 +4893,12 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
 
        lockdep_set_class(&tc->ht.mutex, &tc_ht_lock_key);
 
-       chains_mapping = mapping_create(sizeof(struct mlx5_mapped_obj),
-                                       MLX5E_TC_TABLE_CHAIN_TAG_MASK, true);
+       mapping_id = mlx5_query_nic_system_image_guid(dev);
+
+       chains_mapping = mapping_create_for_id(mapping_id, MAPPING_TYPE_CHAIN,
+                                              sizeof(struct mlx5_mapped_obj),
+                                              MLX5E_TC_TABLE_CHAIN_TAG_MASK, true);
+
        if (IS_ERR(chains_mapping)) {
                err = PTR_ERR(chains_mapping);
                goto err_mapping;
@@ -4931,8 +4920,9 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
                goto err_chains;
        }
 
+       tc->post_act = mlx5e_tc_post_act_init(priv, tc->chains, MLX5_FLOW_NAMESPACE_KERNEL);
        tc->ct = mlx5_tc_ct_init(priv, tc->chains, &priv->fs.tc.mod_hdr,
-                                MLX5_FLOW_NAMESPACE_KERNEL);
+                                MLX5_FLOW_NAMESPACE_KERNEL, tc->post_act);
 
        tc->netdevice_nb.notifier_call = mlx5e_tc_netdev_event;
        err = register_netdevice_notifier_dev_net(priv->netdev,
@@ -4948,6 +4938,7 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
 
 err_reg:
        mlx5_tc_ct_clean(tc->ct);
+       mlx5e_tc_post_act_destroy(tc->post_act);
        mlx5_chains_destroy(tc->chains);
 err_chains:
        mapping_destroy(chains_mapping);
@@ -4986,6 +4977,7 @@ void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv)
        mutex_destroy(&tc->t_lock);
 
        mlx5_tc_ct_clean(tc->ct);
+       mlx5e_tc_post_act_destroy(tc->post_act);
        mapping_destroy(tc->mapping);
        mlx5_chains_destroy(tc->chains);
 }
@@ -4998,6 +4990,7 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
        struct mapping_ctx *mapping;
        struct mlx5_eswitch *esw;
        struct mlx5e_priv *priv;
+       u64 mapping_id;
        int err = 0;
 
        uplink_priv = container_of(tc_ht, struct mlx5_rep_uplink_priv, tc_ht);
@@ -5005,17 +4998,24 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
        priv = netdev_priv(rpriv->netdev);
        esw = priv->mdev->priv.eswitch;
 
+       uplink_priv->post_act = mlx5e_tc_post_act_init(priv, esw_chains(esw),
+                                                      MLX5_FLOW_NAMESPACE_FDB);
        uplink_priv->ct_priv = mlx5_tc_ct_init(netdev_priv(priv->netdev),
                                               esw_chains(esw),
                                               &esw->offloads.mod_hdr,
-                                              MLX5_FLOW_NAMESPACE_FDB);
+                                              MLX5_FLOW_NAMESPACE_FDB,
+                                              uplink_priv->post_act);
 
 #if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
-       uplink_priv->esw_psample = mlx5_esw_sample_init(netdev_priv(priv->netdev));
+       uplink_priv->tc_psample = mlx5e_tc_sample_init(esw, uplink_priv->post_act);
 #endif
 
-       mapping = mapping_create(sizeof(struct tunnel_match_key),
-                                TUNNEL_INFO_BITS_MASK, true);
+       mapping_id = mlx5_query_nic_system_image_guid(esw->dev);
+
+       mapping = mapping_create_for_id(mapping_id, MAPPING_TYPE_TUNNEL,
+                                       sizeof(struct tunnel_match_key),
+                                       TUNNEL_INFO_BITS_MASK, true);
+
        if (IS_ERR(mapping)) {
                err = PTR_ERR(mapping);
                goto err_tun_mapping;
@@ -5023,7 +5023,8 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
        uplink_priv->tunnel_mapping = mapping;
 
        /* 0xFFF is reserved for stack devices slow path table mark */
-       mapping = mapping_create(sz_enc_opts, ENC_OPTS_BITS_MASK - 1, true);
+       mapping = mapping_create_for_id(mapping_id, MAPPING_TYPE_TUNNEL_ENC_OPTS,
+                                       sz_enc_opts, ENC_OPTS_BITS_MASK - 1, true);
        if (IS_ERR(mapping)) {
                err = PTR_ERR(mapping);
                goto err_enc_opts_mapping;
@@ -5052,11 +5053,12 @@ err_enc_opts_mapping:
        mapping_destroy(uplink_priv->tunnel_mapping);
 err_tun_mapping:
 #if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
-       mlx5_esw_sample_cleanup(uplink_priv->esw_psample);
+       mlx5e_tc_sample_cleanup(uplink_priv->tc_psample);
 #endif
        mlx5_tc_ct_clean(uplink_priv->ct_priv);
        netdev_warn(priv->netdev,
                    "Failed to initialize tc (eswitch), err: %d", err);
+       mlx5e_tc_post_act_destroy(uplink_priv->post_act);
        return err;
 }
 
@@ -5073,9 +5075,10 @@ void mlx5e_tc_esw_cleanup(struct rhashtable *tc_ht)
        mapping_destroy(uplink_priv->tunnel_mapping);
 
 #if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
-       mlx5_esw_sample_cleanup(uplink_priv->esw_psample);
+       mlx5e_tc_sample_cleanup(uplink_priv->tc_psample);
 #endif
        mlx5_tc_ct_clean(uplink_priv->ct_priv);
+       mlx5e_tc_post_act_destroy(uplink_priv->post_act);
 }
 
 int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags)