aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamad Haj Yahia <mohamad@mellanox.com>2016-08-11 04:21:39 -0400
committerLeon Romanovsky <leon@kernel.org>2016-10-30 09:43:12 -0400
commit813f854053c26204e2723c498def4c7870dcc7f4 (patch)
treed7f151a2c0e0ea6a6b5075d966a48a99115856be
parent86490d9a5969eaa8217a9329a6f0875cd0b041bc (diff)
net/mlx5: Introduce TSAR manipulation firmware commands
TSAR (stands for Transmit Scheduling ARbiter) is a hardware component that is responsible for selecting the next entity to serve on the transmit path. The arbitration defines the QoS policy between the agents connected to the TSAR. The TSAR is a consist two main features: 1) BW Allocation between agents: The TSAR implements a defecit weighted round robin between the agents. Each agent attached to the TSAR is assigned with a weight and it is awarded transmission tokens according to this weight. 2) Rate limer per agent: Each agent attached to the TSAR is (optionally) assigned with a rate limit. TSAR will not allow scheduling for an agent exceeding its defined rate limit. In this patch we implement the API of manipulating the TSAR. Signed-off-by: Mohamad Haj Yahia <mohamad@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: Leon Romanovsky <leon@kernel.org>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cmd.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h7
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/rl.c65
-rw-r--r--include/linux/mlx5/mlx5_ifc.h199
4 files changed, 279 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 1e639f886021..8561102f2563 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -318,6 +318,8 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
318 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 318 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
319 case MLX5_CMD_OP_SET_FLOW_TABLE_ROOT: 319 case MLX5_CMD_OP_SET_FLOW_TABLE_ROOT:
320 case MLX5_CMD_OP_DEALLOC_ENCAP_HEADER: 320 case MLX5_CMD_OP_DEALLOC_ENCAP_HEADER:
321 case MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT:
322 case MLX5_CMD_OP_DESTROY_QOS_PARA_VPORT:
321 return MLX5_CMD_STAT_OK; 323 return MLX5_CMD_STAT_OK;
322 324
323 case MLX5_CMD_OP_QUERY_HCA_CAP: 325 case MLX5_CMD_OP_QUERY_HCA_CAP:
@@ -419,11 +421,14 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
419 case MLX5_CMD_OP_QUERY_FLOW_TABLE: 421 case MLX5_CMD_OP_QUERY_FLOW_TABLE:
420 case MLX5_CMD_OP_CREATE_FLOW_GROUP: 422 case MLX5_CMD_OP_CREATE_FLOW_GROUP:
421 case MLX5_CMD_OP_QUERY_FLOW_GROUP: 423 case MLX5_CMD_OP_QUERY_FLOW_GROUP:
422
423 case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 424 case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY:
424 case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 425 case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
425 case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 426 case MLX5_CMD_OP_QUERY_FLOW_COUNTER:
426 case MLX5_CMD_OP_ALLOC_ENCAP_HEADER: 427 case MLX5_CMD_OP_ALLOC_ENCAP_HEADER:
428 case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
429 case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT:
430 case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT:
431 case MLX5_CMD_OP_CREATE_QOS_PARA_VPORT:
427 *status = MLX5_DRIVER_STATUS_ABORTED; 432 *status = MLX5_DRIVER_STATUS_ABORTED;
428 *synd = MLX5_DRIVER_SYND; 433 *synd = MLX5_DRIVER_SYND;
429 return -EIO; 434 return -EIO;
@@ -580,6 +585,12 @@ const char *mlx5_command_str(int command)
580 MLX5_COMMAND_STR_CASE(MODIFY_FLOW_TABLE); 585 MLX5_COMMAND_STR_CASE(MODIFY_FLOW_TABLE);
581 MLX5_COMMAND_STR_CASE(ALLOC_ENCAP_HEADER); 586 MLX5_COMMAND_STR_CASE(ALLOC_ENCAP_HEADER);
582 MLX5_COMMAND_STR_CASE(DEALLOC_ENCAP_HEADER); 587 MLX5_COMMAND_STR_CASE(DEALLOC_ENCAP_HEADER);
588 MLX5_COMMAND_STR_CASE(CREATE_SCHEDULING_ELEMENT);
589 MLX5_COMMAND_STR_CASE(DESTROY_SCHEDULING_ELEMENT);
590 MLX5_COMMAND_STR_CASE(QUERY_SCHEDULING_ELEMENT);
591 MLX5_COMMAND_STR_CASE(MODIFY_SCHEDULING_ELEMENT);
592 MLX5_COMMAND_STR_CASE(CREATE_QOS_PARA_VPORT);
593 MLX5_COMMAND_STR_CASE(DESTROY_QOS_PARA_VPORT);
583 default: return "unknown command opcode"; 594 default: return "unknown command opcode";
584 } 595 }
585} 596}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 3d0cfb9f18f9..bf431715172c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -91,6 +91,13 @@ int mlx5_core_sriov_configure(struct pci_dev *dev, int num_vfs);
91bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev); 91bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev);
92int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id); 92int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id);
93int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id); 93int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id);
94int mlx5_create_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
95 void *context, u32 *element_id);
96int mlx5_modify_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
97 void *context, u32 element_id,
98 u32 modify_bitmask);
99int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
100 u32 element_id);
94int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev); 101int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
95cycle_t mlx5_read_internal_timer(struct mlx5_core_dev *dev); 102cycle_t mlx5_read_internal_timer(struct mlx5_core_dev *dev);
96u32 mlx5_get_msix_vec(struct mlx5_core_dev *dev, int vecidx); 103u32 mlx5_get_msix_vec(struct mlx5_core_dev *dev, int vecidx);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rl.c b/drivers/net/ethernet/mellanox/mlx5/core/rl.c
index 104902a93a0b..e651e4c02867 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/rl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/rl.c
@@ -36,6 +36,71 @@
36#include <linux/mlx5/cmd.h> 36#include <linux/mlx5/cmd.h>
37#include "mlx5_core.h" 37#include "mlx5_core.h"
38 38
39/* Scheduling element fw management */
40int mlx5_create_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
41 void *ctx, u32 *element_id)
42{
43 u32 in[MLX5_ST_SZ_DW(create_scheduling_element_in)] = {0};
44 u32 out[MLX5_ST_SZ_DW(create_scheduling_element_in)] = {0};
45 void *schedc;
46 int err;
47
48 schedc = MLX5_ADDR_OF(create_scheduling_element_in, in,
49 scheduling_context);
50 MLX5_SET(create_scheduling_element_in, in, opcode,
51 MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT);
52 MLX5_SET(create_scheduling_element_in, in, scheduling_hierarchy,
53 hierarchy);
54 memcpy(schedc, ctx, MLX5_ST_SZ_BYTES(scheduling_context));
55
56 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
57 if (err)
58 return err;
59
60 *element_id = MLX5_GET(create_scheduling_element_out, out,
61 scheduling_element_id);
62 return 0;
63}
64
65int mlx5_modify_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
66 void *ctx, u32 element_id,
67 u32 modify_bitmask)
68{
69 u32 in[MLX5_ST_SZ_DW(modify_scheduling_element_in)] = {0};
70 u32 out[MLX5_ST_SZ_DW(modify_scheduling_element_in)] = {0};
71 void *schedc;
72
73 schedc = MLX5_ADDR_OF(modify_scheduling_element_in, in,
74 scheduling_context);
75 MLX5_SET(modify_scheduling_element_in, in, opcode,
76 MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT);
77 MLX5_SET(modify_scheduling_element_in, in, scheduling_element_id,
78 element_id);
79 MLX5_SET(modify_scheduling_element_in, in, modify_bitmask,
80 modify_bitmask);
81 MLX5_SET(modify_scheduling_element_in, in, scheduling_hierarchy,
82 hierarchy);
83 memcpy(schedc, ctx, MLX5_ST_SZ_BYTES(scheduling_context));
84
85 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
86}
87
88int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
89 u32 element_id)
90{
91 u32 in[MLX5_ST_SZ_DW(destroy_scheduling_element_in)] = {0};
92 u32 out[MLX5_ST_SZ_DW(destroy_scheduling_element_in)] = {0};
93
94 MLX5_SET(destroy_scheduling_element_in, in, opcode,
95 MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT);
96 MLX5_SET(destroy_scheduling_element_in, in, scheduling_element_id,
97 element_id);
98 MLX5_SET(destroy_scheduling_element_in, in, scheduling_hierarchy,
99 hierarchy);
100
101 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
102}
103
39/* Finds an entry where we can register the given rate 104/* Finds an entry where we can register the given rate
40 * If the rate already exists, return the entry where it is registered, 105 * If the rate already exists, return the entry where it is registered,
41 * otherwise return the first available entry. 106 * otherwise return the first available entry.
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 12f72e45a3f0..2632cb2caf10 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -145,6 +145,12 @@ enum {
145 MLX5_CMD_OP_QUERY_Q_COUNTER = 0x773, 145 MLX5_CMD_OP_QUERY_Q_COUNTER = 0x773,
146 MLX5_CMD_OP_SET_RATE_LIMIT = 0x780, 146 MLX5_CMD_OP_SET_RATE_LIMIT = 0x780,
147 MLX5_CMD_OP_QUERY_RATE_LIMIT = 0x781, 147 MLX5_CMD_OP_QUERY_RATE_LIMIT = 0x781,
148 MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT = 0x782,
149 MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT = 0x783,
150 MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT = 0x784,
151 MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT = 0x785,
152 MLX5_CMD_OP_CREATE_QOS_PARA_VPORT = 0x786,
153 MLX5_CMD_OP_DESTROY_QOS_PARA_VPORT = 0x787,
148 MLX5_CMD_OP_ALLOC_PD = 0x800, 154 MLX5_CMD_OP_ALLOC_PD = 0x800,
149 MLX5_CMD_OP_DEALLOC_PD = 0x801, 155 MLX5_CMD_OP_DEALLOC_PD = 0x801,
150 MLX5_CMD_OP_ALLOC_UAR = 0x802, 156 MLX5_CMD_OP_ALLOC_UAR = 0x802,
@@ -537,13 +543,27 @@ struct mlx5_ifc_e_switch_cap_bits {
537 543
538struct mlx5_ifc_qos_cap_bits { 544struct mlx5_ifc_qos_cap_bits {
539 u8 packet_pacing[0x1]; 545 u8 packet_pacing[0x1];
540 u8 reserved_0[0x1f]; 546 u8 esw_scheduling[0x1];
541 u8 reserved_1[0x20]; 547 u8 reserved_at_2[0x1e];
548
549 u8 reserved_at_20[0x20];
550
542 u8 packet_pacing_max_rate[0x20]; 551 u8 packet_pacing_max_rate[0x20];
552
543 u8 packet_pacing_min_rate[0x20]; 553 u8 packet_pacing_min_rate[0x20];
544 u8 reserved_2[0x10]; 554
555 u8 reserved_at_80[0x10];
545 u8 packet_pacing_rate_table_size[0x10]; 556 u8 packet_pacing_rate_table_size[0x10];
546 u8 reserved_3[0x760]; 557
558 u8 esw_element_type[0x10];
559 u8 esw_tsar_type[0x10];
560
561 u8 reserved_at_c0[0x10];
562 u8 max_qos_para_vport[0x10];
563
564 u8 max_tsar_bw_share[0x20];
565
566 u8 reserved_at_100[0x700];
547}; 567};
548 568
549struct mlx5_ifc_per_protocol_networking_offload_caps_bits { 569struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
@@ -2333,6 +2353,30 @@ struct mlx5_ifc_sqc_bits {
2333 struct mlx5_ifc_wq_bits wq; 2353 struct mlx5_ifc_wq_bits wq;
2334}; 2354};
2335 2355
2356enum {
2357 SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR = 0x0,
2358 SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT = 0x1,
2359 SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT_TC = 0x2,
2360 SCHEDULING_CONTEXT_ELEMENT_TYPE_PARA_VPORT_TC = 0x3,
2361};
2362
2363struct mlx5_ifc_scheduling_context_bits {
2364 u8 element_type[0x8];
2365 u8 reserved_at_8[0x18];
2366
2367 u8 element_attributes[0x20];
2368
2369 u8 parent_element_id[0x20];
2370
2371 u8 reserved_at_60[0x40];
2372
2373 u8 bw_share[0x20];
2374
2375 u8 max_average_bw[0x20];
2376
2377 u8 reserved_at_e0[0x120];
2378};
2379
2336struct mlx5_ifc_rqtc_bits { 2380struct mlx5_ifc_rqtc_bits {
2337 u8 reserved_at_0[0xa0]; 2381 u8 reserved_at_0[0xa0];
2338 2382
@@ -2920,6 +2964,29 @@ struct mlx5_ifc_register_loopback_control_bits {
2920 u8 reserved_at_20[0x60]; 2964 u8 reserved_at_20[0x60];
2921}; 2965};
2922 2966
2967struct mlx5_ifc_vport_tc_element_bits {
2968 u8 traffic_class[0x4];
2969 u8 reserved_at_4[0xc];
2970 u8 vport_number[0x10];
2971};
2972
2973struct mlx5_ifc_vport_element_bits {
2974 u8 reserved_at_0[0x10];
2975 u8 vport_number[0x10];
2976};
2977
2978enum {
2979 TSAR_ELEMENT_TSAR_TYPE_DWRR = 0x0,
2980 TSAR_ELEMENT_TSAR_TYPE_ROUND_ROBIN = 0x1,
2981 TSAR_ELEMENT_TSAR_TYPE_ETS = 0x2,
2982};
2983
2984struct mlx5_ifc_tsar_element_bits {
2985 u8 reserved_at_0[0x8];
2986 u8 tsar_type[0x8];
2987 u8 reserved_at_10[0x10];
2988};
2989
2923struct mlx5_ifc_teardown_hca_out_bits { 2990struct mlx5_ifc_teardown_hca_out_bits {
2924 u8 status[0x8]; 2991 u8 status[0x8];
2925 u8 reserved_at_8[0x18]; 2992 u8 reserved_at_8[0x18];
@@ -3540,6 +3607,39 @@ struct mlx5_ifc_query_special_contexts_in_bits {
3540 u8 reserved_at_40[0x40]; 3607 u8 reserved_at_40[0x40];
3541}; 3608};
3542 3609
3610struct mlx5_ifc_query_scheduling_element_out_bits {
3611 u8 opcode[0x10];
3612 u8 reserved_at_10[0x10];
3613
3614 u8 reserved_at_20[0x10];
3615 u8 op_mod[0x10];
3616
3617 u8 reserved_at_40[0xc0];
3618
3619 struct mlx5_ifc_scheduling_context_bits scheduling_context;
3620
3621 u8 reserved_at_300[0x100];
3622};
3623
3624enum {
3625 SCHEDULING_HIERARCHY_E_SWITCH = 0x2,
3626};
3627
3628struct mlx5_ifc_query_scheduling_element_in_bits {
3629 u8 opcode[0x10];
3630 u8 reserved_at_10[0x10];
3631
3632 u8 reserved_at_20[0x10];
3633 u8 op_mod[0x10];
3634
3635 u8 scheduling_hierarchy[0x8];
3636 u8 reserved_at_48[0x18];
3637
3638 u8 scheduling_element_id[0x20];
3639
3640 u8 reserved_at_80[0x180];
3641};
3642
3543struct mlx5_ifc_query_rqt_out_bits { 3643struct mlx5_ifc_query_rqt_out_bits {
3544 u8 status[0x8]; 3644 u8 status[0x8];
3545 u8 reserved_at_8[0x18]; 3645 u8 reserved_at_8[0x18];
@@ -4725,6 +4825,43 @@ struct mlx5_ifc_modify_sq_in_bits {
4725 struct mlx5_ifc_sqc_bits ctx; 4825 struct mlx5_ifc_sqc_bits ctx;
4726}; 4826};
4727 4827
4828struct mlx5_ifc_modify_scheduling_element_out_bits {
4829 u8 status[0x8];
4830 u8 reserved_at_8[0x18];
4831
4832 u8 syndrome[0x20];
4833
4834 u8 reserved_at_40[0x1c0];
4835};
4836
4837enum {
4838 MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_BW_SHARE = 0x1,
4839 MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW = 0x2,
4840};
4841
4842struct mlx5_ifc_modify_scheduling_element_in_bits {
4843 u8 opcode[0x10];
4844 u8 reserved_at_10[0x10];
4845
4846 u8 reserved_at_20[0x10];
4847 u8 op_mod[0x10];
4848
4849 u8 scheduling_hierarchy[0x8];
4850 u8 reserved_at_48[0x18];
4851
4852 u8 scheduling_element_id[0x20];
4853
4854 u8 reserved_at_80[0x20];
4855
4856 u8 modify_bitmask[0x20];
4857
4858 u8 reserved_at_c0[0x40];
4859
4860 struct mlx5_ifc_scheduling_context_bits scheduling_context;
4861
4862 u8 reserved_at_300[0x100];
4863};
4864
4728struct mlx5_ifc_modify_rqt_out_bits { 4865struct mlx5_ifc_modify_rqt_out_bits {
4729 u8 status[0x8]; 4866 u8 status[0x8];
4730 u8 reserved_at_8[0x18]; 4867 u8 reserved_at_8[0x18];
@@ -5390,6 +5527,30 @@ struct mlx5_ifc_destroy_sq_in_bits {
5390 u8 reserved_at_60[0x20]; 5527 u8 reserved_at_60[0x20];
5391}; 5528};
5392 5529
5530struct mlx5_ifc_destroy_scheduling_element_out_bits {
5531 u8 status[0x8];
5532 u8 reserved_at_8[0x18];
5533
5534 u8 syndrome[0x20];
5535
5536 u8 reserved_at_40[0x1c0];
5537};
5538
5539struct mlx5_ifc_destroy_scheduling_element_in_bits {
5540 u8 opcode[0x10];
5541 u8 reserved_at_10[0x10];
5542
5543 u8 reserved_at_20[0x10];
5544 u8 op_mod[0x10];
5545
5546 u8 scheduling_hierarchy[0x8];
5547 u8 reserved_at_48[0x18];
5548
5549 u8 scheduling_element_id[0x20];
5550
5551 u8 reserved_at_80[0x180];
5552};
5553
5393struct mlx5_ifc_destroy_rqt_out_bits { 5554struct mlx5_ifc_destroy_rqt_out_bits {
5394 u8 status[0x8]; 5555 u8 status[0x8];
5395 u8 reserved_at_8[0x18]; 5556 u8 reserved_at_8[0x18];
@@ -6017,6 +6178,36 @@ struct mlx5_ifc_create_sq_in_bits {
6017 struct mlx5_ifc_sqc_bits ctx; 6178 struct mlx5_ifc_sqc_bits ctx;
6018}; 6179};
6019 6180
6181struct mlx5_ifc_create_scheduling_element_out_bits {
6182 u8 status[0x8];
6183 u8 reserved_at_8[0x18];
6184
6185 u8 syndrome[0x20];
6186
6187 u8 reserved_at_40[0x40];
6188
6189 u8 scheduling_element_id[0x20];
6190
6191 u8 reserved_at_a0[0x160];
6192};
6193
6194struct mlx5_ifc_create_scheduling_element_in_bits {
6195 u8 opcode[0x10];
6196 u8 reserved_at_10[0x10];
6197
6198 u8 reserved_at_20[0x10];
6199 u8 op_mod[0x10];
6200
6201 u8 scheduling_hierarchy[0x8];
6202 u8 reserved_at_48[0x18];
6203
6204 u8 reserved_at_60[0xa0];
6205
6206 struct mlx5_ifc_scheduling_context_bits scheduling_context;
6207
6208 u8 reserved_at_300[0x100];
6209};
6210
6020struct mlx5_ifc_create_rqt_out_bits { 6211struct mlx5_ifc_create_rqt_out_bits {
6021 u8 status[0x8]; 6212 u8 status[0x8];
6022 u8 reserved_at_8[0x18]; 6213 u8 reserved_at_8[0x18];