aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4
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
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')
-rw-r--r--drivers/net/mlx4/fw.c12
-rw-r--r--drivers/net/mlx4/fw.h1
-rw-r--r--drivers/net/mlx4/main.c53
-rw-r--r--drivers/net/mlx4/mlx4.h1
4 files changed, 66 insertions, 1 deletions
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 1d3fc6d7689b..7eb8ba822e97 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -104,7 +104,8 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags)
104 [38] = "Wake On LAN support", 104 [38] = "Wake On LAN support",
105 [40] = "UDP RSS support", 105 [40] = "UDP RSS support",
106 [41] = "Unicast VEP steering support", 106 [41] = "Unicast VEP steering support",
107 [42] = "Multicast VEP steering support" 107 [42] = "Multicast VEP steering support",
108 [48] = "Counters support",
108 }; 109 };
109 int i; 110 int i;
110 111
@@ -203,6 +204,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
203#define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63 204#define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63
204#define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64 205#define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64
205#define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65 206#define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65
207#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68
206#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 208#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80
207#define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 209#define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82
208#define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 210#define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84
@@ -355,6 +357,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
355 QUERY_DEV_CAP_RSVD_LKEY_OFFSET); 357 QUERY_DEV_CAP_RSVD_LKEY_OFFSET);
356 MLX4_GET(dev_cap->max_icm_sz, outbox, 358 MLX4_GET(dev_cap->max_icm_sz, outbox,
357 QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET); 359 QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET);
360 if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS)
361 MLX4_GET(dev_cap->max_counters, outbox,
362 QUERY_DEV_CAP_MAX_COUNTERS_OFFSET);
358 363
359 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 364 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
360 for (i = 1; i <= dev_cap->num_ports; ++i) { 365 for (i = 1; i <= dev_cap->num_ports; ++i) {
@@ -448,6 +453,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
448 mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n", 453 mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n",
449 dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg); 454 dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg);
450 mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz); 455 mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz);
456 mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters);
451 457
452 dump_dev_cap_flags(dev, dev_cap->flags); 458 dump_dev_cap_flags(dev, dev_cap->flags);
453 459
@@ -780,6 +786,10 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
780 if (enable_qos) 786 if (enable_qos)
781 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 2); 787 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 2);
782 788
789 /* enable counters */
790 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS)
791 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 4);
792
783 /* QPC/EEC/CQC/EQC/RDMARC attributes */ 793 /* QPC/EEC/CQC/EQC/RDMARC attributes */
784 794
785 MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); 795 MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET);
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h
index 56ed1646cced..1e8ecc3708e2 100644
--- a/drivers/net/mlx4/fw.h
+++ b/drivers/net/mlx4/fw.h
@@ -111,6 +111,7 @@ struct mlx4_dev_cap {
111 u8 supported_port_types[MLX4_MAX_PORTS + 1]; 111 u8 supported_port_types[MLX4_MAX_PORTS + 1];
112 u8 log_max_macs[MLX4_MAX_PORTS + 1]; 112 u8 log_max_macs[MLX4_MAX_PORTS + 1];
113 u8 log_max_vlans[MLX4_MAX_PORTS + 1]; 113 u8 log_max_vlans[MLX4_MAX_PORTS + 1];
114 u32 max_counters;
114}; 115};
115 116
116struct mlx4_adapter { 117struct mlx4_adapter {
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);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index dd7d745fbab4..5e405bbc8d1b 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -342,6 +342,7 @@ struct mlx4_priv {
342 struct mlx4_srq_table srq_table; 342 struct mlx4_srq_table srq_table;
343 struct mlx4_qp_table qp_table; 343 struct mlx4_qp_table qp_table;
344 struct mlx4_mcg_table mcg_table; 344 struct mlx4_mcg_table mcg_table;
345 struct mlx4_bitmap counters_bitmap;
345 346
346 struct mlx4_catas_err catas_err; 347 struct mlx4_catas_err catas_err;
347 348