struct mlx5e_arfs_tables        arfs;
 };
 
-struct mlx5e_direct_tir {
+struct mlx5e_tir {
        u32              tirn;
        u32              rqtn;
+       struct list_head list;
 };
 
 enum {
        struct mlx5e_channel     **channel;
        u32                        tisn[MLX5E_MAX_NUM_TC];
        u32                        indir_rqtn;
-       u32                        indir_tirn[MLX5E_NUM_INDIR_TIRS];
-       struct mlx5e_direct_tir    direct_tir[MLX5E_MAX_NUM_CHANNELS];
+       struct mlx5e_tir           indir_tir[MLX5E_NUM_INDIR_TIRS];
+       struct mlx5e_tir           direct_tir[MLX5E_MAX_NUM_CHANNELS];
        u32                        tx_rates[MLX5E_MAX_NUM_SQS];
 
        struct mlx5e_flow_steering fs;
 #endif
 
 u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev);
+int mlx5e_create_tir(struct mlx5_core_dev *mdev,
+                    struct mlx5e_tir *tir, u32 *in, int inlen);
+void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
+                      struct mlx5e_tir *tir);
 int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev);
 void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev);
+int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5_core_dev *mdev);
 
 #endif /* __MLX5_EN_H__ */
 
 static int arfs_disable(struct mlx5e_priv *priv)
 {
        struct mlx5_flow_destination dest;
-       u32 *tirn = priv->indir_tirn;
+       struct mlx5e_tir *tir = priv->indir_tir;
        int err = 0;
        int tt;
        int i;
 
        dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
        for (i = 0; i < ARFS_NUM_TYPES; i++) {
-               dest.tir_num = tirn[i];
+               dest.tir_num = tir[i].tirn;
                tt = arfs_get_tt(i);
                /* Modify ttc rules destination to bypass the aRFS tables*/
                err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt],
        struct arfs_table *arfs_t = &priv->fs.arfs.arfs_tables[type];
        struct mlx5_flow_destination dest;
        u8 match_criteria_enable = 0;
-       u32 *tirn = priv->indir_tirn;
+       struct mlx5e_tir *tir = priv->indir_tir;
        u32 *match_criteria;
        u32 *match_value;
        int err = 0;
        dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
        switch (type) {
        case ARFS_IPV4_TCP:
-               dest.tir_num = tirn[MLX5E_TT_IPV4_TCP];
+               dest.tir_num = tir[MLX5E_TT_IPV4_TCP].tirn;
                break;
        case ARFS_IPV4_UDP:
-               dest.tir_num = tirn[MLX5E_TT_IPV4_UDP];
+               dest.tir_num = tir[MLX5E_TT_IPV4_UDP].tirn;
                break;
        case ARFS_IPV6_TCP:
-               dest.tir_num = tirn[MLX5E_TT_IPV6_TCP];
+               dest.tir_num = tir[MLX5E_TT_IPV6_TCP].tirn;
                break;
        case ARFS_IPV6_UDP:
-               dest.tir_num = tirn[MLX5E_TT_IPV6_UDP];
+               dest.tir_num = tir[MLX5E_TT_IPV6_UDP].tirn;
                break;
        default:
                err = -EINVAL;
 
  * Global resources are common to all the netdevices crated on the same nic.
  */
 
+int mlx5e_create_tir(struct mlx5_core_dev *mdev,
+                    struct mlx5e_tir *tir, u32 *in, int inlen)
+{
+       int err;
+
+       err = mlx5_core_create_tir(mdev, in, inlen, &tir->tirn);
+       if (err)
+               return err;
+
+       list_add(&tir->list, &mdev->mlx5e_res.td.tirs_list);
+
+       return 0;
+}
+
+void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
+                      struct mlx5e_tir *tir)
+{
+       mlx5_core_destroy_tir(mdev, tir->tirn);
+       list_del(&tir->list);
+}
+
 static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn,
                             struct mlx5_core_mkey *mkey)
 {
                goto err_dealloc_transport_domain;
        }
 
+       INIT_LIST_HEAD(&mdev->mlx5e_res.td.tirs_list);
+
        return 0;
 
 err_dealloc_transport_domain:
        mlx5_core_dealloc_pd(mdev, res->pdn);
        mlx5_unmap_free_uar(mdev, &res->cq_uar);
 }
+
+int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5_core_dev *mdev)
+{
+       struct mlx5e_tir *tir;
+       void *in;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
+       in = mlx5_vzalloc(inlen);
+       if (!in)
+               return -ENOMEM;
+
+       MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1);
+
+       list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) {
+               err = mlx5_core_modify_tir(mdev, tir->tirn, in, inlen);
+               if (err)
+                       return err;
+       }
+
+       kvfree(in);
+
+       return 0;
+}
 
        mlx5e_build_tir_ctx_hash(tirc, priv);
 
        for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
-               mlx5_core_modify_tir(mdev, priv->indir_tirn[i], in, inlen);
+               mlx5_core_modify_tir(mdev, priv->indir_tir[i].tirn, in, inlen);
 }
 
 static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
 
                if (tt == MLX5E_TT_ANY)
                        dest.tir_num = priv->direct_tir[0].tirn;
                else
-                       dest.tir_num = priv->indir_tirn[tt];
+                       dest.tir_num = priv->indir_tir[tt].tirn;
                rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
                                                    ttc_rules[tt].etype,
                                                    ttc_rules[tt].proto);
 
        mlx5e_build_tir_ctx_lro(tirc, priv);
 
        for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
-               err = mlx5_core_modify_tir(mdev, priv->indir_tirn[tt], in,
+               err = mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in,
                                           inlen);
                if (err)
                        goto free_in;
        return err;
 }
 
-static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv)
-{
-       void *in;
-       int inlen;
-       int err;
-       int i;
-
-       inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
-       in = mlx5_vzalloc(inlen);
-       if (!in)
-               return -ENOMEM;
-
-       MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1);
-
-       for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++) {
-               err = mlx5_core_modify_tir(priv->mdev, priv->indir_tirn[i], in,
-                                          inlen);
-               if (err)
-                       return err;
-       }
-
-       for (i = 0; i < priv->params.num_channels; i++) {
-               err = mlx5_core_modify_tir(priv->mdev,
-                                          priv->direct_tir[i].tirn, in,
-                                          inlen);
-               if (err)
-                       return err;
-       }
-
-       kvfree(in);
-
-       return 0;
-}
-
 static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu)
 {
        struct mlx5_core_dev *mdev = priv->mdev;
                goto err_clear_state_opened_flag;
        }
 
-       err = mlx5e_refresh_tirs_self_loopback_enable(priv);
+       err = mlx5e_refresh_tirs_self_loopback_enable(priv->mdev);
        if (err) {
                netdev_err(netdev, "%s: mlx5e_refresh_tirs_self_loopback_enable failed, %d\n",
                           __func__, err);
 static int mlx5e_create_tirs(struct mlx5e_priv *priv)
 {
        int nch = mlx5e_get_max_num_channels(priv->mdev);
+       struct mlx5e_tir *tir;
        void *tirc;
        int inlen;
-       u32 *tirn;
        int err;
        u32 *in;
        int ix;
        /* indirect tirs */
        for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
                memset(in, 0, inlen);
-               tirn = &priv->indir_tirn[tt];
+               tir = &priv->indir_tir[tt];
                tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
                mlx5e_build_indir_tir_ctx(priv, tirc, tt);
-               err = mlx5_core_create_tir(priv->mdev, in, inlen, tirn);
+               err = mlx5e_create_tir(priv->mdev, tir, in, inlen);
                if (err)
                        goto err_destroy_tirs;
        }
        /* direct tirs */
        for (ix = 0; ix < nch; ix++) {
                memset(in, 0, inlen);
-               tirn = &priv->direct_tir[ix].tirn;
+               tir = &priv->direct_tir[ix];
                tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
                mlx5e_build_direct_tir_ctx(priv, tirc,
                                           priv->direct_tir[ix].rqtn);
-               err = mlx5_core_create_tir(priv->mdev, in, inlen, tirn);
+               err = mlx5e_create_tir(priv->mdev, tir, in, inlen);
                if (err)
                        goto err_destroy_ch_tirs;
        }
 
 err_destroy_ch_tirs:
        for (ix--; ix >= 0; ix--)
-               mlx5_core_destroy_tir(priv->mdev, priv->direct_tir[ix].tirn);
+               mlx5e_destroy_tir(priv->mdev, &priv->direct_tir[ix]);
 
 err_destroy_tirs:
        for (tt--; tt >= 0; tt--)
-               mlx5_core_destroy_tir(priv->mdev, priv->indir_tirn[tt]);
+               mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[tt]);
 
        kvfree(in);
 
        int i;
 
        for (i = 0; i < nch; i++)
-               mlx5_core_destroy_tir(priv->mdev, priv->direct_tir[i].tirn);
+               mlx5e_destroy_tir(priv->mdev, &priv->direct_tir[i]);
 
        for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
-               mlx5_core_destroy_tir(priv->mdev, priv->indir_tirn[i]);
+               mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[i]);
 }
 
 int mlx5e_modify_rqs_vsd(struct mlx5e_priv *priv, bool vsd)