goto err_destroy_direct_tirs;
        }
 
-       err = mlx5e_tc_init(priv);
+       err = mlx5e_tc_nic_init(priv);
        if (err)
                goto err_destroy_flow_steering;
 
 
 static void mlx5e_cleanup_nic_rx(struct mlx5e_priv *priv)
 {
-       mlx5e_tc_cleanup(priv);
+       mlx5e_tc_nic_cleanup(priv);
        mlx5e_destroy_flow_steering(priv);
        mlx5e_destroy_direct_tirs(priv);
        mlx5e_destroy_indirect_tirs(priv);
 
        }
        rpriv->vport_rx_rule = flow_rule;
 
-       err = mlx5e_tc_init(priv);
-       if (err)
-               goto err_del_flow_rule;
-
        return 0;
 
-err_del_flow_rule:
-       mlx5_del_flow_rules(rpriv->vport_rx_rule);
 err_destroy_direct_tirs:
        mlx5e_destroy_direct_tirs(priv);
 err_destroy_direct_rqts:
 {
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
 
-       mlx5e_tc_cleanup(priv);
        mlx5_del_flow_rules(rpriv->vport_rx_rule);
        mlx5e_destroy_direct_tirs(priv);
        mlx5e_destroy_direct_rqts(priv);
        if (err)
                goto err_remove_sqs;
 
+       /* init shared tc flow table */
+       err = mlx5e_tc_esw_init(&rpriv->tc_ht);
+       if (err)
+               goto  err_neigh_cleanup;
+
        return 0;
 
+err_neigh_cleanup:
+       mlx5e_rep_neigh_cleanup(rpriv);
 err_remove_sqs:
        mlx5e_remove_sqs_fwd_rules(priv);
        return err;
        if (test_bit(MLX5E_STATE_OPENED, &priv->state))
                mlx5e_remove_sqs_fwd_rules(priv);
 
-       /* clean (and re-init) existing uplink offloaded TC rules */
-       mlx5e_tc_cleanup(priv);
-       mlx5e_tc_init(priv);
+       /* clean uplink offloaded TC rules, delete shared tc flow table */
+       mlx5e_tc_esw_cleanup(&rpriv->tc_ht);
 
        mlx5e_rep_neigh_cleanup(rpriv);
 }
 
        struct net_device      *netdev;
        struct mlx5_flow_handle *vport_rx_rule;
        struct list_head       vport_sqs_list;
+       struct rhashtable      tc_ht; /* valid for uplink rep */
 };
 
 static inline
 
 
 struct mlx5e_tc_flow {
        struct rhash_head       node;
+       struct mlx5e_priv       *priv;
        u64                     cookie;
        u8                      flags;
        struct mlx5_flow_handle *rule;
 
 static struct rhashtable *get_tc_ht(struct mlx5e_priv *priv)
 {
-       return &priv->fs.tc.ht;
+       struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+       struct mlx5e_rep_priv *uplink_rpriv;
+
+       if (MLX5_VPORT_MANAGER(priv->mdev) && esw->mode == SRIOV_OFFLOADS) {
+               uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
+               return &uplink_rpriv->tc_ht;
+       } else
+               return &priv->fs.tc.ht;
 }
 
 int mlx5e_configure_flower(struct mlx5e_priv *priv,
 
        flow->cookie = f->cookie;
        flow->flags = flow_flags;
+       flow->priv = priv;
 
        err = parse_cls_flower(priv, flow, &parse_attr->spec, f);
        if (err < 0)
        return 0;
 }
 
-int mlx5e_tc_init(struct mlx5e_priv *priv)
+int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
 {
        struct mlx5e_tc_table *tc = &priv->fs.tc;
 
 static void _mlx5e_tc_del_flow(void *ptr, void *arg)
 {
        struct mlx5e_tc_flow *flow = ptr;
-       struct mlx5e_priv *priv = arg;
+       struct mlx5e_priv *priv = flow->priv;
 
        mlx5e_tc_del_flow(priv, flow);
        kfree(flow);
 }
 
-void mlx5e_tc_cleanup(struct mlx5e_priv *priv)
+void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv)
 {
        struct mlx5e_tc_table *tc = &priv->fs.tc;
 
-       rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, priv);
+       rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL);
 
        if (!IS_ERR_OR_NULL(tc->t)) {
                mlx5_destroy_flow_table(tc->t);
                tc->t = NULL;
        }
 }
+
+int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
+{
+       return rhashtable_init(tc_ht, &tc_ht_params);
+}
+
+void mlx5e_tc_esw_cleanup(struct rhashtable *tc_ht)
+{
+       rhashtable_free_and_destroy(tc_ht, _mlx5e_tc_del_flow, NULL);
+}
 
        MLX5E_TC_LAST_EXPORTED_BIT = 1,
 };
 
-int mlx5e_tc_init(struct mlx5e_priv *priv);
-void mlx5e_tc_cleanup(struct mlx5e_priv *priv);
+int mlx5e_tc_nic_init(struct mlx5e_priv *priv);
+void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv);
+
+int mlx5e_tc_esw_init(struct rhashtable *tc_ht);
+void mlx5e_tc_esw_cleanup(struct rhashtable *tc_ht);
 
 int mlx5e_configure_flower(struct mlx5e_priv *priv,
                           struct tc_cls_flower_offload *f, int flags);
 }
 
 #else /* CONFIG_MLX5_ESWITCH */
-static inline int  mlx5e_tc_init(struct mlx5e_priv *priv) { return 0; }
-static inline void mlx5e_tc_cleanup(struct mlx5e_priv *priv) {}
+static inline int  mlx5e_tc_nic_init(struct mlx5e_priv *priv) { return 0; }
+static inline void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) {}
 static inline int  mlx5e_tc_num_filters(struct mlx5e_priv *priv) { return 0; }
 #endif