if (init_node_data(ibdev))
                goto err_map;
 
+       for (i = 0; i < ibdev->num_ports; ++i) {
+               if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) ==
+                                               IB_LINK_LAYER_ETHERNET) {
+                       err = mlx4_counter_alloc(ibdev->dev, &ibdev->counters[i]);
+                       if (err)
+                               ibdev->counters[i] = -1;
+               } else
+                               ibdev->counters[i] = -1;
+       }
+
        spin_lock_init(&ibdev->sm_lock);
        mutex_init(&ibdev->cap_mask_mutex);
 
        if (ib_register_device(&ibdev->ib_dev, NULL))
-               goto err_map;
+               goto err_counter;
 
        if (mlx4_ib_mad_init(ibdev))
                goto err_reg;
 err_reg:
        ib_unregister_device(&ibdev->ib_dev);
 
+err_counter:
+       for (; i; --i)
+               mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]);
+
 err_map:
        iounmap(ibdev->uar_map);
 
                ibdev->iboe.nb.notifier_call = NULL;
        }
        iounmap(ibdev->uar_map);
-
+       for (p = 0; p < ibdev->num_ports; ++p)
+               mlx4_counter_free(ibdev->dev, ibdev->counters[p]);
        mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
                mlx4_CLOSE_PORT(dev, p);
 
 
        struct mutex            cap_mask_mutex;
        bool                    ib_active;
        struct mlx4_ib_iboe     iboe;
+       int                     counters[MLX4_MAX_PORTS];
 };
 
 static inline struct mlx4_ib_dev *to_mdev(struct ib_device *ibdev)
 
                        --path->static_rate;
        } else
                path->static_rate = 0;
-       path->counter_index = 0xff;
 
        if (ah->ah_flags & IB_AH_GRH) {
                if (ah->grh.sgid_index >= dev->dev->caps.gid_table_len[port]) {
                }
        }
 
+       if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
+               if (dev->counters[qp->port - 1] != -1) {
+                       context->pri_path.counter_index =
+                                               dev->counters[qp->port - 1];
+                       optpar |= MLX4_QP_OPTPAR_COUNTER_INDEX;
+               } else
+                       context->pri_path.counter_index = 0xff;
+       }
+
        if (attr_mask & IB_QP_PKEY_INDEX) {
                context->pri_path.pkey_index = attr->pkey_index;
                optpar |= MLX4_QP_OPTPAR_PKEY_INDEX;
 
        MLX4_QP_OPTPAR_RETRY_COUNT              = 1 << 12,
        MLX4_QP_OPTPAR_RNR_RETRY                = 1 << 13,
        MLX4_QP_OPTPAR_ACK_TIMEOUT              = 1 << 14,
-       MLX4_QP_OPTPAR_SCHED_QUEUE              = 1 << 16
+       MLX4_QP_OPTPAR_SCHED_QUEUE              = 1 << 16,
+       MLX4_QP_OPTPAR_COUNTER_INDEX            = 1 << 20
 };
 
 enum mlx4_qp_state {