}
        mdev->mac_removed[priv->port] = 0;
 
+       priv->counter_index =
+                       mlx4_get_default_counter_index(mdev->dev, priv->port);
+
        err = mlx4_en_config_rss_steer(priv);
        if (err) {
                en_err(priv, "Failed configuring rss steering\n");
 
        /* Set port as not active */
        priv->port_up = false;
+       priv->counter_index = MLX4_SINK_COUNTER_INDEX(mdev->dev);
 
        /* Promsicuous mode */
        if (mdev->dev->caps.steering_mode ==
 
        priv = netdev_priv(dev);
        memset(priv, 0, sizeof(struct mlx4_en_priv));
+       priv->counter_index = MLX4_SINK_COUNTER_INDEX(mdev->dev);
        spin_lock_init(&priv->stats_lock);
        INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode);
        INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
 
        mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap);
 }
 
+static void mlx4_cleanup_default_counters(struct mlx4_dev *dev)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       int port;
+
+       for (port = 0; port < dev->caps.num_ports; port++)
+               if (priv->def_counter[port] != -1)
+                       mlx4_counter_free(dev,  priv->def_counter[port]);
+}
+
+static int mlx4_allocate_default_counters(struct mlx4_dev *dev)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       int port, err = 0;
+       u32 idx;
+
+       for (port = 0; port < dev->caps.num_ports; port++)
+               priv->def_counter[port] = -1;
+
+       for (port = 0; port < dev->caps.num_ports; port++) {
+               err = mlx4_counter_alloc(dev, &idx);
+
+               if (!err || err == -ENOSPC) {
+                       priv->def_counter[port] = idx;
+               } else if (err == -ENOENT) {
+                       err = 0;
+                       continue;
+               } else {
+                       mlx4_err(dev, "%s: failed to allocate default counter port %d err %d\n",
+                                __func__, port + 1, err);
+                       mlx4_cleanup_default_counters(dev);
+                       return err;
+               }
+
+               mlx4_dbg(dev, "%s: default counter index %d for port %d\n",
+                        __func__, priv->def_counter[port], port + 1);
+       }
+
+       return err;
+}
+
 int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
                return -ENOENT;
 
        *idx = mlx4_bitmap_alloc(&priv->counters_bitmap);
-       if (*idx == -1)
-               return -ENOMEM;
+       if (*idx == -1) {
+               *idx = MLX4_SINK_COUNTER_INDEX(dev);
+               return -ENOSPC;
+       }
 
        return 0;
 }
        if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS))
                return;
 
+       if (idx == MLX4_SINK_COUNTER_INDEX(dev))
+               return;
+
        __mlx4_clear_if_stat(dev, idx);
 
        mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx, MLX4_USE_RR);
 }
 EXPORT_SYMBOL_GPL(mlx4_counter_free);
 
+int mlx4_get_default_counter_index(struct mlx4_dev *dev, int port)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+
+       return priv->def_counter[port - 1];
+}
+EXPORT_SYMBOL_GPL(mlx4_get_default_counter_index);
+
 void mlx4_set_admin_guid(struct mlx4_dev *dev, __be64 guid, int entry, int port)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
                }
        }
 
+       err = mlx4_allocate_default_counters(dev);
+       if (err) {
+               mlx4_err(dev, "Failed to allocate default counters, aborting\n");
+               goto err_counters_table_free;
+       }
+
        if (!mlx4_is_slave(dev)) {
                for (port = 1; port <= dev->caps.num_ports; port++) {
                        ib_port_default_caps = 0;
                        if (err) {
                                mlx4_err(dev, "Failed to set port %d, aborting\n",
                                         port);
-                               goto err_counters_table_free;
+                               goto err_default_countes_free;
                        }
                }
        }
 
        return 0;
 
+err_default_countes_free:
+       mlx4_cleanup_default_counters(dev);
+
 err_counters_table_free:
        if (!mlx4_is_slave(dev))
                mlx4_cleanup_counters_table(dev);
        for (--port; port >= 1; --port)
                mlx4_cleanup_port_info(&priv->port[port]);
 
+       mlx4_cleanup_default_counters(dev);
        if (!mlx4_is_slave(dev))
                mlx4_cleanup_counters_table(dev);
        mlx4_cleanup_qp_table(dev);
                mlx4_free_resource_tracker(dev,
                                           RES_TR_FREE_SLAVES_ONLY);
 
+       mlx4_cleanup_default_counters(dev);
        if (!mlx4_is_slave(dev))
                mlx4_cleanup_counters_table(dev);
        mlx4_cleanup_qp_table(dev);