aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/main.c
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2011-06-15 10:47:14 -0400
committerRoland Dreier <roland@purestorage.com>2011-07-19 00:04:34 -0400
commitf2a3f6a32cf64db1495b5ced8625b9a80bde44e5 (patch)
tree68508cf4a5f67e2380b6b6fa158bb776e3b69a91 /drivers/net/mlx4/main.c
parent98a13e487a3bdac8508e4dcb98d63385fabe6767 (diff)
mlx4_core: Add network flow counters
ConnectX devices support a set of flow counters that can be attached to a set containing one or more QPs. Each such counter tracks receive and transmit packets and bytes of these QPs. This patch queries the device to check support for counters, handles initialization of the HCA to enable counters, and initializes a bitmap allocator to control counter allocations. Derived from patch by Eli Cohen <eli@mellanox.co.il>. Signed-off-by: Or Gerlitz <ogerlitz@mellanox.co.il> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/net/mlx4/main.c')
-rw-r--r--drivers/net/mlx4/main.c53
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
146static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) 147static 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
840static 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
852static void mlx4_cleanup_counters_table(struct mlx4_dev *dev)
853{
854 mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap);
855}
856
857int 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}
870EXPORT_SYMBOL_GPL(mlx4_counter_alloc);
871
872void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
873{
874 mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx);
875 return;
876}
877EXPORT_SYMBOL_GPL(mlx4_counter_free);
878
837static int mlx4_setup_hca(struct mlx4_dev *dev) 879static 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)
964err_mcg_table_free: 1012err_mcg_table_free:
965 mlx4_cleanup_mcg_table(dev); 1013 mlx4_cleanup_mcg_table(dev);
966 1014
1015err_counters_table_free:
1016 mlx4_cleanup_counters_table(dev);
1017
967err_qp_table_free: 1018err_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);