diff options
author | Amir Vadai <amirva@mellanox.com> | 2016-05-13 08:55:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-16 13:43:51 -0400 |
commit | 9dc0b289c4c09bc1a92bdcc055cb37af9b72eb28 (patch) | |
tree | 2cfc535ac1d6ec859ed59b6a9112701c5d79d9b9 | |
parent | 42ca502e179d0654ef441333a9d0f35c948734f3 (diff) |
net/mlx5_core: Firmware commands to support flow counters
Getting packet/byte statistics on flows is done through flow counters.
Implement the firmware commands to alloc, free and query flow counters.
Signed-off-by: Amir Vadai <amirva@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c | 66 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h | 5 | ||||
-rw-r--r-- | include/linux/mlx5/mlx5_ifc.h | 99 |
4 files changed, 173 insertions, 3 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index 63cac841cfa9..dcd2df6518de 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c | |||
@@ -294,6 +294,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, | |||
294 | case MLX5_CMD_OP_DESTROY_FLOW_TABLE: | 294 | case MLX5_CMD_OP_DESTROY_FLOW_TABLE: |
295 | case MLX5_CMD_OP_DESTROY_FLOW_GROUP: | 295 | case MLX5_CMD_OP_DESTROY_FLOW_GROUP: |
296 | case MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY: | 296 | case MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY: |
297 | case MLX5_CMD_OP_DEALLOC_FLOW_COUNTER: | ||
297 | return MLX5_CMD_STAT_OK; | 298 | return MLX5_CMD_STAT_OK; |
298 | 299 | ||
299 | case MLX5_CMD_OP_QUERY_HCA_CAP: | 300 | case MLX5_CMD_OP_QUERY_HCA_CAP: |
@@ -395,6 +396,8 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, | |||
395 | case MLX5_CMD_OP_QUERY_FLOW_GROUP: | 396 | case MLX5_CMD_OP_QUERY_FLOW_GROUP: |
396 | case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: | 397 | case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: |
397 | case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: | 398 | case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: |
399 | case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: | ||
400 | case MLX5_CMD_OP_QUERY_FLOW_COUNTER: | ||
398 | *status = MLX5_DRIVER_STATUS_ABORTED; | 401 | *status = MLX5_DRIVER_STATUS_ABORTED; |
399 | *synd = MLX5_DRIVER_SYND; | 402 | *synd = MLX5_DRIVER_SYND; |
400 | return -EIO; | 403 | return -EIO; |
@@ -539,6 +542,9 @@ const char *mlx5_command_str(int command) | |||
539 | MLX5_COMMAND_STR_CASE(SET_FLOW_TABLE_ENTRY); | 542 | MLX5_COMMAND_STR_CASE(SET_FLOW_TABLE_ENTRY); |
540 | MLX5_COMMAND_STR_CASE(QUERY_FLOW_TABLE_ENTRY); | 543 | MLX5_COMMAND_STR_CASE(QUERY_FLOW_TABLE_ENTRY); |
541 | MLX5_COMMAND_STR_CASE(DELETE_FLOW_TABLE_ENTRY); | 544 | MLX5_COMMAND_STR_CASE(DELETE_FLOW_TABLE_ENTRY); |
545 | MLX5_COMMAND_STR_CASE(ALLOC_FLOW_COUNTER); | ||
546 | MLX5_COMMAND_STR_CASE(DEALLOC_FLOW_COUNTER); | ||
547 | MLX5_COMMAND_STR_CASE(QUERY_FLOW_COUNTER); | ||
542 | default: return "unknown command opcode"; | 548 | default: return "unknown command opcode"; |
543 | } | 549 | } |
544 | } | 550 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c index 9797768891ee..ccb63a0bb54a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c | |||
@@ -323,3 +323,69 @@ int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev, | |||
323 | 323 | ||
324 | return err; | 324 | return err; |
325 | } | 325 | } |
326 | |||
327 | int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u16 *id) | ||
328 | { | ||
329 | u32 in[MLX5_ST_SZ_DW(alloc_flow_counter_in)]; | ||
330 | u32 out[MLX5_ST_SZ_DW(alloc_flow_counter_out)]; | ||
331 | int err; | ||
332 | |||
333 | memset(in, 0, sizeof(in)); | ||
334 | memset(out, 0, sizeof(out)); | ||
335 | |||
336 | MLX5_SET(alloc_flow_counter_in, in, opcode, | ||
337 | MLX5_CMD_OP_ALLOC_FLOW_COUNTER); | ||
338 | |||
339 | err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, | ||
340 | sizeof(out)); | ||
341 | if (err) | ||
342 | return err; | ||
343 | |||
344 | *id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id); | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u16 id) | ||
350 | { | ||
351 | u32 in[MLX5_ST_SZ_DW(dealloc_flow_counter_in)]; | ||
352 | u32 out[MLX5_ST_SZ_DW(dealloc_flow_counter_out)]; | ||
353 | |||
354 | memset(in, 0, sizeof(in)); | ||
355 | memset(out, 0, sizeof(out)); | ||
356 | |||
357 | MLX5_SET(dealloc_flow_counter_in, in, opcode, | ||
358 | MLX5_CMD_OP_DEALLOC_FLOW_COUNTER); | ||
359 | MLX5_SET(dealloc_flow_counter_in, in, flow_counter_id, id); | ||
360 | |||
361 | return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, | ||
362 | sizeof(out)); | ||
363 | } | ||
364 | |||
365 | int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u16 id, | ||
366 | u64 *packets, u64 *bytes) | ||
367 | { | ||
368 | u32 out[MLX5_ST_SZ_BYTES(query_flow_counter_out) + | ||
369 | MLX5_ST_SZ_BYTES(traffic_counter)]; | ||
370 | u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)]; | ||
371 | void *stats; | ||
372 | int err = 0; | ||
373 | |||
374 | memset(in, 0, sizeof(in)); | ||
375 | memset(out, 0, sizeof(out)); | ||
376 | |||
377 | MLX5_SET(query_flow_counter_in, in, opcode, | ||
378 | MLX5_CMD_OP_QUERY_FLOW_COUNTER); | ||
379 | MLX5_SET(query_flow_counter_in, in, op_mod, 0); | ||
380 | MLX5_SET(query_flow_counter_in, in, flow_counter_id, id); | ||
381 | |||
382 | err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); | ||
383 | if (err) | ||
384 | return err; | ||
385 | |||
386 | stats = MLX5_ADDR_OF(query_flow_counter_out, out, flow_statistics); | ||
387 | *packets = MLX5_GET64(traffic_counter, stats, packets); | ||
388 | *bytes = MLX5_GET64(traffic_counter, stats, octets); | ||
389 | |||
390 | return 0; | ||
391 | } | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h index c97b4a03eeed..18c111a4691f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h | |||
@@ -70,4 +70,9 @@ int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev, | |||
70 | 70 | ||
71 | int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, | 71 | int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, |
72 | struct mlx5_flow_table *ft); | 72 | struct mlx5_flow_table *ft); |
73 | |||
74 | int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u16 *id); | ||
75 | int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u16 id); | ||
76 | int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u16 id, | ||
77 | u64 *packets, u64 *bytes); | ||
73 | #endif | 78 | #endif |
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 4ce4ea422a10..614c795eadea 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h | |||
@@ -202,6 +202,9 @@ enum { | |||
202 | MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY = 0x936, | 202 | MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY = 0x936, |
203 | MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY = 0x937, | 203 | MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY = 0x937, |
204 | MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY = 0x938, | 204 | MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY = 0x938, |
205 | MLX5_CMD_OP_ALLOC_FLOW_COUNTER = 0x939, | ||
206 | MLX5_CMD_OP_DEALLOC_FLOW_COUNTER = 0x93a, | ||
207 | MLX5_CMD_OP_QUERY_FLOW_COUNTER = 0x93b, | ||
205 | MLX5_CMD_OP_MODIFY_FLOW_TABLE = 0x93c | 208 | MLX5_CMD_OP_MODIFY_FLOW_TABLE = 0x93c |
206 | }; | 209 | }; |
207 | 210 | ||
@@ -265,7 +268,8 @@ struct mlx5_ifc_flow_table_fields_supported_bits { | |||
265 | 268 | ||
266 | struct mlx5_ifc_flow_table_prop_layout_bits { | 269 | struct mlx5_ifc_flow_table_prop_layout_bits { |
267 | u8 ft_support[0x1]; | 270 | u8 ft_support[0x1]; |
268 | u8 reserved_at_1[0x2]; | 271 | u8 reserved_at_1[0x1]; |
272 | u8 flow_counter[0x1]; | ||
269 | u8 flow_modify_en[0x1]; | 273 | u8 flow_modify_en[0x1]; |
270 | u8 modify_root[0x1]; | 274 | u8 modify_root[0x1]; |
271 | u8 identified_miss_table_mode[0x1]; | 275 | u8 identified_miss_table_mode[0x1]; |
@@ -941,6 +945,19 @@ struct mlx5_ifc_dest_format_struct_bits { | |||
941 | u8 reserved_at_20[0x20]; | 945 | u8 reserved_at_20[0x20]; |
942 | }; | 946 | }; |
943 | 947 | ||
948 | struct mlx5_ifc_flow_counter_list_bits { | ||
949 | u8 reserved_at_0[0x10]; | ||
950 | u8 flow_counter_id[0x10]; | ||
951 | |||
952 | u8 reserved_at_20[0x20]; | ||
953 | }; | ||
954 | |||
955 | union mlx5_ifc_dest_format_struct_flow_counter_list_auto_bits { | ||
956 | struct mlx5_ifc_dest_format_struct_bits dest_format_struct; | ||
957 | struct mlx5_ifc_flow_counter_list_bits flow_counter_list; | ||
958 | u8 reserved_at_0[0x40]; | ||
959 | }; | ||
960 | |||
944 | struct mlx5_ifc_fte_match_param_bits { | 961 | struct mlx5_ifc_fte_match_param_bits { |
945 | struct mlx5_ifc_fte_match_set_lyr_2_4_bits outer_headers; | 962 | struct mlx5_ifc_fte_match_set_lyr_2_4_bits outer_headers; |
946 | 963 | ||
@@ -2006,6 +2023,7 @@ enum { | |||
2006 | MLX5_FLOW_CONTEXT_ACTION_ALLOW = 0x1, | 2023 | MLX5_FLOW_CONTEXT_ACTION_ALLOW = 0x1, |
2007 | MLX5_FLOW_CONTEXT_ACTION_DROP = 0x2, | 2024 | MLX5_FLOW_CONTEXT_ACTION_DROP = 0x2, |
2008 | MLX5_FLOW_CONTEXT_ACTION_FWD_DEST = 0x4, | 2025 | MLX5_FLOW_CONTEXT_ACTION_FWD_DEST = 0x4, |
2026 | MLX5_FLOW_CONTEXT_ACTION_COUNT = 0x8, | ||
2009 | }; | 2027 | }; |
2010 | 2028 | ||
2011 | struct mlx5_ifc_flow_context_bits { | 2029 | struct mlx5_ifc_flow_context_bits { |
@@ -2022,13 +2040,16 @@ struct mlx5_ifc_flow_context_bits { | |||
2022 | u8 reserved_at_80[0x8]; | 2040 | u8 reserved_at_80[0x8]; |
2023 | u8 destination_list_size[0x18]; | 2041 | u8 destination_list_size[0x18]; |
2024 | 2042 | ||
2025 | u8 reserved_at_a0[0x160]; | 2043 | u8 reserved_at_a0[0x8]; |
2044 | u8 flow_counter_list_size[0x18]; | ||
2045 | |||
2046 | u8 reserved_at_c0[0x140]; | ||
2026 | 2047 | ||
2027 | struct mlx5_ifc_fte_match_param_bits match_value; | 2048 | struct mlx5_ifc_fte_match_param_bits match_value; |
2028 | 2049 | ||
2029 | u8 reserved_at_1200[0x600]; | 2050 | u8 reserved_at_1200[0x600]; |
2030 | 2051 | ||
2031 | struct mlx5_ifc_dest_format_struct_bits destination[0]; | 2052 | union mlx5_ifc_dest_format_struct_flow_counter_list_auto_bits destination[0]; |
2032 | }; | 2053 | }; |
2033 | 2054 | ||
2034 | enum { | 2055 | enum { |
@@ -3937,6 +3958,34 @@ struct mlx5_ifc_query_flow_group_in_bits { | |||
3937 | u8 reserved_at_e0[0x120]; | 3958 | u8 reserved_at_e0[0x120]; |
3938 | }; | 3959 | }; |
3939 | 3960 | ||
3961 | struct mlx5_ifc_query_flow_counter_out_bits { | ||
3962 | u8 status[0x8]; | ||
3963 | u8 reserved_at_8[0x18]; | ||
3964 | |||
3965 | u8 syndrome[0x20]; | ||
3966 | |||
3967 | u8 reserved_at_40[0x40]; | ||
3968 | |||
3969 | struct mlx5_ifc_traffic_counter_bits flow_statistics[0]; | ||
3970 | }; | ||
3971 | |||
3972 | struct mlx5_ifc_query_flow_counter_in_bits { | ||
3973 | u8 opcode[0x10]; | ||
3974 | u8 reserved_at_10[0x10]; | ||
3975 | |||
3976 | u8 reserved_at_20[0x10]; | ||
3977 | u8 op_mod[0x10]; | ||
3978 | |||
3979 | u8 reserved_at_40[0x80]; | ||
3980 | |||
3981 | u8 clear[0x1]; | ||
3982 | u8 reserved_at_c1[0xf]; | ||
3983 | u8 num_of_counters[0x10]; | ||
3984 | |||
3985 | u8 reserved_at_e0[0x10]; | ||
3986 | u8 flow_counter_id[0x10]; | ||
3987 | }; | ||
3988 | |||
3940 | struct mlx5_ifc_query_esw_vport_context_out_bits { | 3989 | struct mlx5_ifc_query_esw_vport_context_out_bits { |
3941 | u8 status[0x8]; | 3990 | u8 status[0x8]; |
3942 | u8 reserved_at_8[0x18]; | 3991 | u8 reserved_at_8[0x18]; |
@@ -5510,6 +5559,28 @@ struct mlx5_ifc_dealloc_pd_in_bits { | |||
5510 | u8 reserved_at_60[0x20]; | 5559 | u8 reserved_at_60[0x20]; |
5511 | }; | 5560 | }; |
5512 | 5561 | ||
5562 | struct mlx5_ifc_dealloc_flow_counter_out_bits { | ||
5563 | u8 status[0x8]; | ||
5564 | u8 reserved_at_8[0x18]; | ||
5565 | |||
5566 | u8 syndrome[0x20]; | ||
5567 | |||
5568 | u8 reserved_at_40[0x40]; | ||
5569 | }; | ||
5570 | |||
5571 | struct mlx5_ifc_dealloc_flow_counter_in_bits { | ||
5572 | u8 opcode[0x10]; | ||
5573 | u8 reserved_at_10[0x10]; | ||
5574 | |||
5575 | u8 reserved_at_20[0x10]; | ||
5576 | u8 op_mod[0x10]; | ||
5577 | |||
5578 | u8 reserved_at_40[0x10]; | ||
5579 | u8 flow_counter_id[0x10]; | ||
5580 | |||
5581 | u8 reserved_at_60[0x20]; | ||
5582 | }; | ||
5583 | |||
5513 | struct mlx5_ifc_create_xrc_srq_out_bits { | 5584 | struct mlx5_ifc_create_xrc_srq_out_bits { |
5514 | u8 status[0x8]; | 5585 | u8 status[0x8]; |
5515 | u8 reserved_at_8[0x18]; | 5586 | u8 reserved_at_8[0x18]; |
@@ -6237,6 +6308,28 @@ struct mlx5_ifc_alloc_pd_in_bits { | |||
6237 | u8 reserved_at_40[0x40]; | 6308 | u8 reserved_at_40[0x40]; |
6238 | }; | 6309 | }; |
6239 | 6310 | ||
6311 | struct mlx5_ifc_alloc_flow_counter_out_bits { | ||
6312 | u8 status[0x8]; | ||
6313 | u8 reserved_at_8[0x18]; | ||
6314 | |||
6315 | u8 syndrome[0x20]; | ||
6316 | |||
6317 | u8 reserved_at_40[0x10]; | ||
6318 | u8 flow_counter_id[0x10]; | ||
6319 | |||
6320 | u8 reserved_at_60[0x20]; | ||
6321 | }; | ||
6322 | |||
6323 | struct mlx5_ifc_alloc_flow_counter_in_bits { | ||
6324 | u8 opcode[0x10]; | ||
6325 | u8 reserved_at_10[0x10]; | ||
6326 | |||
6327 | u8 reserved_at_20[0x10]; | ||
6328 | u8 op_mod[0x10]; | ||
6329 | |||
6330 | u8 reserved_at_40[0x40]; | ||
6331 | }; | ||
6332 | |||
6240 | struct mlx5_ifc_add_vxlan_udp_dport_out_bits { | 6333 | struct mlx5_ifc_add_vxlan_udp_dport_out_bits { |
6241 | u8 status[0x8]; | 6334 | u8 status[0x8]; |
6242 | u8 reserved_at_8[0x18]; | 6335 | u8 reserved_at_8[0x18]; |