void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
 void mlx5e_update_hw_rep_counters(struct mlx5e_priv *priv);
 
+int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv);
+
+int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv);
+void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv);
+
 int mlx5e_create_direct_rqts(struct mlx5e_priv *priv);
-void mlx5e_destroy_rqt(struct mlx5e_priv *priv, struct mlx5e_rqt *rqt);
+void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv);
 int mlx5e_create_direct_tirs(struct mlx5e_priv *priv);
 void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv);
+void mlx5e_destroy_rqt(struct mlx5e_priv *priv, struct mlx5e_rqt *rqt);
+
 int mlx5e_create_tises(struct mlx5e_priv *priv);
 void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv);
 int mlx5e_close(struct net_device *netdev);
 int mlx5e_attach_netdev(struct mlx5e_priv *priv);
 void mlx5e_detach_netdev(struct mlx5e_priv *priv);
 void mlx5e_destroy_netdev(struct mlx5e_priv *priv);
+void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
+                           struct mlx5e_params *params,
+                           u16 max_channels);
 
 #endif /* __MLX5_EN_H__ */
 
        mlx5_core_destroy_rqt(priv->mdev, rqt->rqtn);
 }
 
-static int mlx5e_create_indirect_rqts(struct mlx5e_priv *priv)
+int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv)
 {
        struct mlx5e_rqt *rqt = &priv->indir_rqt;
+       int err;
 
-       return mlx5e_create_rqt(priv, MLX5E_INDIR_RQT_SIZE, rqt);
+       err = mlx5e_create_rqt(priv, MLX5E_INDIR_RQT_SIZE, rqt);
+       if (err)
+               mlx5_core_warn(priv->mdev, "create indirect rqts failed, %d\n", err);
+       return err;
 }
 
 int mlx5e_create_direct_rqts(struct mlx5e_priv *priv)
        return 0;
 
 err_destroy_rqts:
+       mlx5_core_warn(priv->mdev, "create direct rqts failed, %d\n", err);
        for (ix--; ix >= 0; ix--)
                mlx5e_destroy_rqt(priv, &priv->direct_tir[ix].rqt);
 
        return err;
 }
 
+void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < priv->profile->max_nch(priv->mdev); i++)
+               mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
+}
+
 static int mlx5e_rx_hash_fn(int hfunc)
 {
        return (hfunc == ETH_RSS_HASH_TOP) ?
        MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_INVERTED_XOR8);
 }
 
-static int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv)
+int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv)
 {
        struct mlx5e_tir *tir;
        void *tirc;
        return 0;
 
 err_destroy_tirs:
+       mlx5_core_warn(priv->mdev, "create indirect tirs failed, %d\n", err);
        for (tt--; tt >= 0; tt--)
                mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[tt]);
 
        return 0;
 
 err_destroy_ch_tirs:
+       mlx5_core_warn(priv->mdev, "create direct tirs failed, %d\n", err);
        for (ix--; ix >= 0; ix--)
                mlx5e_destroy_tir(priv->mdev, &priv->direct_tir[ix]);
 
        return err;
 }
 
-static void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv)
+void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv)
 {
        int i;
 
        return MLX5_CAP_ETH(mdev, lro_timer_supported_periods[i]);
 }
 
-static void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
-                                  struct mlx5e_params *params,
-                                  u16 max_channels)
+void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
+                           struct mlx5e_params *params,
+                           u16 max_channels)
 {
        u8 cq_period_mode = 0;
        u32 link_speed = 0;
 {
        struct mlx5_core_dev *mdev = priv->mdev;
        int err;
-       int i;
 
-       err = mlx5e_create_indirect_rqts(priv);
-       if (err) {
-               mlx5_core_warn(mdev, "create indirect rqts failed, %d\n", err);
+       err = mlx5e_create_indirect_rqt(priv);
+       if (err)
                return err;
-       }
 
        err = mlx5e_create_direct_rqts(priv);
-       if (err) {
-               mlx5_core_warn(mdev, "create direct rqts failed, %d\n", err);
+       if (err)
                goto err_destroy_indirect_rqts;
-       }
 
        err = mlx5e_create_indirect_tirs(priv);
-       if (err) {
-               mlx5_core_warn(mdev, "create indirect tirs failed, %d\n", err);
+       if (err)
                goto err_destroy_direct_rqts;
-       }
 
        err = mlx5e_create_direct_tirs(priv);
-       if (err) {
-               mlx5_core_warn(mdev, "create direct tirs failed, %d\n", err);
+       if (err)
                goto err_destroy_indirect_tirs;
-       }
 
        err = mlx5e_create_flow_steering(priv);
        if (err) {
 err_destroy_indirect_tirs:
        mlx5e_destroy_indirect_tirs(priv);
 err_destroy_direct_rqts:
-       for (i = 0; i < priv->profile->max_nch(mdev); i++)
-               mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
+       mlx5e_destroy_direct_rqts(priv);
 err_destroy_indirect_rqts:
        mlx5e_destroy_rqt(priv, &priv->indir_rqt);
        return err;
 
 static void mlx5e_cleanup_nic_rx(struct mlx5e_priv *priv)
 {
-       int i;
-
        mlx5e_tc_cleanup(priv);
        mlx5e_destroy_flow_steering(priv);
        mlx5e_destroy_direct_tirs(priv);
        mlx5e_destroy_indirect_tirs(priv);
-       for (i = 0; i < priv->profile->max_nch(priv->mdev); i++)
-               mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
+       mlx5e_destroy_direct_rqts(priv);
        mlx5e_destroy_rqt(priv, &priv->indir_rqt);
 }
 
 
 {
        struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
        struct mlx5_eswitch_rep *rep = priv->ppriv;
-       struct mlx5_core_dev *mdev = priv->mdev;
        struct mlx5_flow_handle *flow_rule;
        int err;
-       int i;
 
        mlx5e_init_l2_addr(priv);
 
        err = mlx5e_create_direct_rqts(priv);
-       if (err) {
-               mlx5_core_warn(mdev, "create direct rqts failed, %d\n", err);
+       if (err)
                return err;
-       }
 
        err = mlx5e_create_direct_tirs(priv);
-       if (err) {
-               mlx5_core_warn(mdev, "create direct tirs failed, %d\n", err);
+       if (err)
                goto err_destroy_direct_rqts;
-       }
 
        flow_rule = mlx5_eswitch_create_vport_rx_rule(esw,
                                                      rep->vport,
 err_destroy_direct_tirs:
        mlx5e_destroy_direct_tirs(priv);
 err_destroy_direct_rqts:
-       for (i = 0; i < priv->channels.params.num_channels; i++)
-               mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
+       mlx5e_destroy_direct_rqts(priv);
        return err;
 }
 
 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
 {
        struct mlx5_eswitch_rep *rep = priv->ppriv;
-       int i;
 
        mlx5e_tc_cleanup(priv);
        mlx5_del_flow_rules(rep->vport_rx_rule);
        mlx5e_destroy_direct_tirs(priv);
-       for (i = 0; i < priv->channels.params.num_channels; i++)
-               mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
+       mlx5e_destroy_direct_rqts(priv);
 }
 
 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
 
 {
        struct mlx5e_priv *priv  = mlx5i_epriv(netdev);
 
-       priv->ppriv = ppriv;
-       /*  TODO: init netdev and mlx5e_params here */
+       priv->mdev        = mdev;
+       priv->netdev      = netdev;
+       priv->profile     = profile;
+       priv->ppriv       = ppriv;
+
+       mlx5e_build_nic_params(mdev, &priv->channels.params, profile->max_nch(mdev));
+
+       mutex_init(&priv->state_lock);
+       /* TODO : init netdev features here */
 }
 
 /* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */
 
 static int mlx5i_init_rx(struct mlx5e_priv *priv)
 {
-       /* TODO: create IPoIB RX HW steering contexts */
+       int err;
+
+       err = mlx5e_create_indirect_rqt(priv);
+       if (err)
+               return err;
+
+       err = mlx5e_create_direct_rqts(priv);
+       if (err)
+               goto err_destroy_indirect_rqts;
+
+       err = mlx5e_create_indirect_tirs(priv);
+       if (err)
+               goto err_destroy_direct_rqts;
+
+       err = mlx5e_create_direct_tirs(priv);
+       if (err)
+               goto err_destroy_indirect_tirs;
+
        return 0;
+
+err_destroy_indirect_tirs:
+       mlx5e_destroy_indirect_tirs(priv);
+err_destroy_direct_rqts:
+       mlx5e_destroy_direct_rqts(priv);
+err_destroy_indirect_rqts:
+       mlx5e_destroy_rqt(priv, &priv->indir_rqt);
+       return err;
 }
 
 static void mlx5i_cleanup_rx(struct mlx5e_priv *priv)
 {
+       mlx5e_destroy_direct_tirs(priv);
+       mlx5e_destroy_indirect_tirs(priv);
+       mlx5e_destroy_direct_rqts(priv);
+       mlx5e_destroy_rqt(priv, &priv->indir_rqt);
 }
 
 static const struct mlx5e_profile mlx5i_nic_profile = {