diff options
Diffstat (limited to 'drivers/net/mlx4/main.c')
-rw-r--r-- | drivers/net/mlx4/main.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 650f4ca8606e..932dac5e4db7 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -143,6 +143,7 @@ static void mlx4_set_port_mask(struct mlx4_dev *dev) | |||
143 | if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB) | 143 | if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB) |
144 | dev->caps.port_mask |= 1 << (i - 1); | 144 | dev->caps.port_mask |= 1 << (i - 1); |
145 | } | 145 | } |
146 | |||
146 | static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | 147 | static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) |
147 | { | 148 | { |
148 | int err; | 149 | int err; |
@@ -257,6 +258,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
257 | 258 | ||
258 | mlx4_set_port_mask(dev); | 259 | mlx4_set_port_mask(dev); |
259 | 260 | ||
261 | dev->caps.max_counters = 1 << ilog2(dev_cap->max_counters); | ||
262 | |||
260 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps; | 263 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps; |
261 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] = | 264 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] = |
262 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] = | 265 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] = |
@@ -834,6 +837,45 @@ err_stop_fw: | |||
834 | return err; | 837 | return err; |
835 | } | 838 | } |
836 | 839 | ||
840 | static int mlx4_init_counters_table(struct mlx4_dev *dev) | ||
841 | { | ||
842 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
843 | int nent; | ||
844 | |||
845 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS)) | ||
846 | return -ENOENT; | ||
847 | |||
848 | nent = dev->caps.max_counters; | ||
849 | return mlx4_bitmap_init(&priv->counters_bitmap, nent, nent - 1, 0, 0); | ||
850 | } | ||
851 | |||
852 | static void mlx4_cleanup_counters_table(struct mlx4_dev *dev) | ||
853 | { | ||
854 | mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap); | ||
855 | } | ||
856 | |||
857 | int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) | ||
858 | { | ||
859 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
860 | |||
861 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS)) | ||
862 | return -ENOENT; | ||
863 | |||
864 | *idx = mlx4_bitmap_alloc(&priv->counters_bitmap); | ||
865 | if (*idx == -1) | ||
866 | return -ENOMEM; | ||
867 | |||
868 | return 0; | ||
869 | } | ||
870 | EXPORT_SYMBOL_GPL(mlx4_counter_alloc); | ||
871 | |||
872 | void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) | ||
873 | { | ||
874 | mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx); | ||
875 | return; | ||
876 | } | ||
877 | EXPORT_SYMBOL_GPL(mlx4_counter_free); | ||
878 | |||
837 | static int mlx4_setup_hca(struct mlx4_dev *dev) | 879 | static int mlx4_setup_hca(struct mlx4_dev *dev) |
838 | { | 880 | { |
839 | struct mlx4_priv *priv = mlx4_priv(dev); | 881 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -938,6 +980,12 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
938 | goto err_qp_table_free; | 980 | goto err_qp_table_free; |
939 | } | 981 | } |
940 | 982 | ||
983 | err = mlx4_init_counters_table(dev); | ||
984 | if (err && err != -ENOENT) { | ||
985 | mlx4_err(dev, "Failed to initialize counters table, aborting.\n"); | ||
986 | goto err_counters_table_free; | ||
987 | } | ||
988 | |||
941 | for (port = 1; port <= dev->caps.num_ports; port++) { | 989 | for (port = 1; port <= dev->caps.num_ports; port++) { |
942 | enum mlx4_port_type port_type = 0; | 990 | enum mlx4_port_type port_type = 0; |
943 | mlx4_SENSE_PORT(dev, port, &port_type); | 991 | mlx4_SENSE_PORT(dev, port, &port_type); |
@@ -964,6 +1012,9 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
964 | err_mcg_table_free: | 1012 | err_mcg_table_free: |
965 | mlx4_cleanup_mcg_table(dev); | 1013 | mlx4_cleanup_mcg_table(dev); |
966 | 1014 | ||
1015 | err_counters_table_free: | ||
1016 | mlx4_cleanup_counters_table(dev); | ||
1017 | |||
967 | err_qp_table_free: | 1018 | err_qp_table_free: |
968 | mlx4_cleanup_qp_table(dev); | 1019 | mlx4_cleanup_qp_table(dev); |
969 | 1020 | ||
@@ -1294,6 +1345,7 @@ err_port: | |||
1294 | for (--port; port >= 1; --port) | 1345 | for (--port; port >= 1; --port) |
1295 | mlx4_cleanup_port_info(&priv->port[port]); | 1346 | mlx4_cleanup_port_info(&priv->port[port]); |
1296 | 1347 | ||
1348 | mlx4_cleanup_counters_table(dev); | ||
1297 | mlx4_cleanup_mcg_table(dev); | 1349 | mlx4_cleanup_mcg_table(dev); |
1298 | mlx4_cleanup_qp_table(dev); | 1350 | mlx4_cleanup_qp_table(dev); |
1299 | mlx4_cleanup_srq_table(dev); | 1351 | mlx4_cleanup_srq_table(dev); |
@@ -1354,6 +1406,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) | |||
1354 | mlx4_CLOSE_PORT(dev, p); | 1406 | mlx4_CLOSE_PORT(dev, p); |
1355 | } | 1407 | } |
1356 | 1408 | ||
1409 | mlx4_cleanup_counters_table(dev); | ||
1357 | mlx4_cleanup_mcg_table(dev); | 1410 | mlx4_cleanup_mcg_table(dev); |
1358 | mlx4_cleanup_qp_table(dev); | 1411 | mlx4_cleanup_qp_table(dev); |
1359 | mlx4_cleanup_srq_table(dev); | 1412 | mlx4_cleanup_srq_table(dev); |