aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2015-03-18 08:57:34 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-18 14:55:19 -0400
commitfc31e2560a2443410fe45c27116fae736541a7b5 (patch)
tree6b2d25803b612cb1fcb2038d069d4063a843a4eb
parent822b3b2ebfff8e9b3d006086c527738a7ca00cd0 (diff)
net/mlx4_core: Add basic support for QP max-rate limiting
Add the low-level device commands and definitions used for QP max-rate limiting. This is done through the following elements: - read rate-limit device caps in QUERY_DEV_CAP: number of different rates and the min/max rates in Kbs/Mbs/Gbs units - enhance the QP context struct to contain rate limit units and value - allow to do run time rate-limit setting to QPs through the update-qp firmware command - QP rate-limiting is disallowed for VFs Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c33
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c6
-rw-r--r--include/linux/mlx4/device.h17
-rw-r--r--include/linux/mlx4/qp.h14
7 files changed, 72 insertions, 6 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 242bcee5d774..4a471f5d1b56 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -144,7 +144,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
144 [19] = "Performance optimized for limited rule configuration flow steering support", 144 [19] = "Performance optimized for limited rule configuration flow steering support",
145 [20] = "Recoverable error events support", 145 [20] = "Recoverable error events support",
146 [21] = "Port Remap support", 146 [21] = "Port Remap support",
147 [22] = "QCN support" 147 [22] = "QCN support",
148 [23] = "QP rate limiting support"
148 }; 149 };
149 int i; 150 int i;
150 151
@@ -697,6 +698,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
697#define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 698#define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0
698#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8 699#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8
699#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac 700#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac
701#define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc
702#define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0
703#define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2
704
700 705
701 dev_cap->flags2 = 0; 706 dev_cap->flags2 = 0;
702 mailbox = mlx4_alloc_cmd_mailbox(dev); 707 mailbox = mlx4_alloc_cmd_mailbox(dev);
@@ -904,6 +909,18 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
904 QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET); 909 QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET);
905 dev_cap->dmfs_high_rate_qpn_range &= MGM_QPN_MASK; 910 dev_cap->dmfs_high_rate_qpn_range &= MGM_QPN_MASK;
906 911
912 MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET);
913 dev_cap->rl_caps.num_rates = size;
914 if (dev_cap->rl_caps.num_rates) {
915 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT;
916 MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET);
917 dev_cap->rl_caps.max_val = size & 0xfff;
918 dev_cap->rl_caps.max_unit = size >> 14;
919 MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET);
920 dev_cap->rl_caps.min_val = size & 0xfff;
921 dev_cap->rl_caps.min_unit = size >> 14;
922 }
923
907 MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 924 MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
908 if (field32 & (1 << 16)) 925 if (field32 & (1 << 16))
909 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; 926 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP;
@@ -979,6 +996,15 @@ void mlx4_dev_cap_dump(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
979 dev_cap->dmfs_high_rate_qpn_base); 996 dev_cap->dmfs_high_rate_qpn_base);
980 mlx4_dbg(dev, "DMFS high rate steer QPn range: %d\n", 997 mlx4_dbg(dev, "DMFS high rate steer QPn range: %d\n",
981 dev_cap->dmfs_high_rate_qpn_range); 998 dev_cap->dmfs_high_rate_qpn_range);
999
1000 if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT) {
1001 struct mlx4_rate_limit_caps *rl_caps = &dev_cap->rl_caps;
1002
1003 mlx4_dbg(dev, "QP Rate-Limit: #rates %d, unit/val max %d/%d, min %d/%d\n",
1004 rl_caps->num_rates, rl_caps->max_unit, rl_caps->max_val,
1005 rl_caps->min_unit, rl_caps->min_val);
1006 }
1007
982 dump_dev_cap_flags(dev, dev_cap->flags); 1008 dump_dev_cap_flags(dev, dev_cap->flags);
983 dump_dev_cap_flags2(dev, dev_cap->flags2); 1009 dump_dev_cap_flags2(dev, dev_cap->flags2);
984} 1010}
@@ -1075,6 +1101,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
1075 u64 flags; 1101 u64 flags;
1076 int err = 0; 1102 int err = 0;
1077 u8 field; 1103 u8 field;
1104 u16 field16;
1078 u32 bmme_flags, field32; 1105 u32 bmme_flags, field32;
1079 int real_port; 1106 int real_port;
1080 int slave_port; 1107 int slave_port;
@@ -1158,6 +1185,10 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
1158 field &= 0xfe; 1185 field &= 0xfe;
1159 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET); 1186 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET);
1160 1187
1188 /* turn off QP max-rate limiting for guests */
1189 field16 = 0;
1190 MLX4_PUT(outbox->buf, field16, QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET);
1191
1161 return 0; 1192 return 0;
1162} 1193}
1163 1194
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h
index f44f7f6017ed..863655bd3947 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -127,6 +127,7 @@ struct mlx4_dev_cap {
127 u32 max_counters; 127 u32 max_counters;
128 u32 dmfs_high_rate_qpn_base; 128 u32 dmfs_high_rate_qpn_base;
129 u32 dmfs_high_rate_qpn_range; 129 u32 dmfs_high_rate_qpn_range;
130 struct mlx4_rate_limit_caps rl_caps;
130 struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1]; 131 struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1];
131}; 132};
132 133
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 7e487223489a..43aa76775b5f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -489,6 +489,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
489 dev->caps.dmfs_high_rate_qpn_range = MLX4_A0_STEERING_TABLE_SIZE; 489 dev->caps.dmfs_high_rate_qpn_range = MLX4_A0_STEERING_TABLE_SIZE;
490 } 490 }
491 491
492 dev->caps.rl_caps = dev_cap->rl_caps;
493
492 dev->caps.reserved_qps_cnt[MLX4_QP_REGION_RSS_RAW_ETH] = 494 dev->caps.reserved_qps_cnt[MLX4_QP_REGION_RSS_RAW_ETH] =
493 dev->caps.dmfs_high_rate_qpn_range; 495 dev->caps.dmfs_high_rate_qpn_range;
494 496
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index eda29dbbfcd2..69e4462e4ee4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -442,6 +442,11 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
442 cmd->qp_context.param3 |= cpu_to_be32(MLX4_STRIP_VLAN); 442 cmd->qp_context.param3 |= cpu_to_be32(MLX4_STRIP_VLAN);
443 } 443 }
444 444
445 if (attr & MLX4_UPDATE_QP_RATE_LIMIT) {
446 qp_mask |= 1ULL << MLX4_UPD_QP_MASK_RATE_LIMIT;
447 cmd->qp_context.rate_limit_params = cpu_to_be16((params->rate_unit << 14) | params->rate_val);
448 }
449
445 cmd->primary_addr_path_mask = cpu_to_be64(pri_addr_path_mask); 450 cmd->primary_addr_path_mask = cpu_to_be64(pri_addr_path_mask);
446 cmd->qp_mask = cpu_to_be64(qp_mask); 451 cmd->qp_mask = cpu_to_be64(qp_mask);
447 452
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index d43e25914d19..c258f8625aac 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -2947,8 +2947,12 @@ static int verify_qp_parameters(struct mlx4_dev *dev,
2947 qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff; 2947 qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
2948 optpar = be32_to_cpu(*(__be32 *) inbox->buf); 2948 optpar = be32_to_cpu(*(__be32 *) inbox->buf);
2949 2949
2950 if (slave != mlx4_master_func_num(dev)) 2950 if (slave != mlx4_master_func_num(dev)) {
2951 qp_ctx->params2 &= ~MLX4_QP_BIT_FPP; 2951 qp_ctx->params2 &= ~MLX4_QP_BIT_FPP;
2952 /* setting QP rate-limit is disallowed for VFs */
2953 if (qp_ctx->rate_limit_params)
2954 return -EPERM;
2955 }
2952 2956
2953 switch (qp_type) { 2957 switch (qp_type) {
2954 case MLX4_QP_ST_RC: 2958 case MLX4_QP_ST_RC:
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 1cc54822b931..4550c67b92e4 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -205,6 +205,7 @@ enum {
205 MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT = 1LL << 20, 205 MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT = 1LL << 20,
206 MLX4_DEV_CAP_FLAG2_PORT_REMAP = 1LL << 21, 206 MLX4_DEV_CAP_FLAG2_PORT_REMAP = 1LL << 21,
207 MLX4_DEV_CAP_FLAG2_QCN = 1LL << 22, 207 MLX4_DEV_CAP_FLAG2_QCN = 1LL << 22,
208 MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT = 1LL << 23
208}; 209};
209 210
210enum { 211enum {
@@ -450,6 +451,21 @@ enum mlx4_module_id {
450 MLX4_MODULE_ID_QSFP28 = 0x11, 451 MLX4_MODULE_ID_QSFP28 = 0x11,
451}; 452};
452 453
454enum { /* rl */
455 MLX4_QP_RATE_LIMIT_NONE = 0,
456 MLX4_QP_RATE_LIMIT_KBS = 1,
457 MLX4_QP_RATE_LIMIT_MBS = 2,
458 MLX4_QP_RATE_LIMIT_GBS = 3
459};
460
461struct mlx4_rate_limit_caps {
462 u16 num_rates; /* Number of different rates */
463 u8 min_unit;
464 u16 min_val;
465 u8 max_unit;
466 u16 max_val;
467};
468
453static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor) 469static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor)
454{ 470{
455 return (major << 32) | (minor << 16) | subminor; 471 return (major << 32) | (minor << 16) | subminor;
@@ -565,6 +581,7 @@ struct mlx4_caps {
565 u32 dmfs_high_rate_qpn_base; 581 u32 dmfs_high_rate_qpn_base;
566 u32 dmfs_high_rate_qpn_range; 582 u32 dmfs_high_rate_qpn_range;
567 u32 vf_caps; 583 u32 vf_caps;
584 struct mlx4_rate_limit_caps rl_caps;
568}; 585};
569 586
570struct mlx4_buf_list { 587struct mlx4_buf_list {
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 551f85456c11..1023ebe035b7 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -207,14 +207,16 @@ struct mlx4_qp_context {
207 __be32 msn; 207 __be32 msn;
208 __be16 rq_wqe_counter; 208 __be16 rq_wqe_counter;
209 __be16 sq_wqe_counter; 209 __be16 sq_wqe_counter;
210 u32 reserved3[2]; 210 u32 reserved3;
211 __be16 rate_limit_params;
212 __be16 reserved4;
211 __be32 param3; 213 __be32 param3;
212 __be32 nummmcpeers_basemkey; 214 __be32 nummmcpeers_basemkey;
213 u8 log_page_size; 215 u8 log_page_size;
214 u8 reserved4[2]; 216 u8 reserved5[2];
215 u8 mtt_base_addr_h; 217 u8 mtt_base_addr_h;
216 __be32 mtt_base_addr_l; 218 __be32 mtt_base_addr_l;
217 u32 reserved5[10]; 219 u32 reserved6[10];
218}; 220};
219 221
220struct mlx4_update_qp_context { 222struct mlx4_update_qp_context {
@@ -229,6 +231,7 @@ struct mlx4_update_qp_context {
229enum { 231enum {
230 MLX4_UPD_QP_MASK_PM_STATE = 32, 232 MLX4_UPD_QP_MASK_PM_STATE = 32,
231 MLX4_UPD_QP_MASK_VSD = 33, 233 MLX4_UPD_QP_MASK_VSD = 33,
234 MLX4_UPD_QP_MASK_RATE_LIMIT = 35,
232}; 235};
233 236
234enum { 237enum {
@@ -428,7 +431,8 @@ struct mlx4_wqe_inline_seg {
428enum mlx4_update_qp_attr { 431enum mlx4_update_qp_attr {
429 MLX4_UPDATE_QP_SMAC = 1 << 0, 432 MLX4_UPDATE_QP_SMAC = 1 << 0,
430 MLX4_UPDATE_QP_VSD = 1 << 1, 433 MLX4_UPDATE_QP_VSD = 1 << 1,
431 MLX4_UPDATE_QP_SUPPORTED_ATTRS = (1 << 2) - 1 434 MLX4_UPDATE_QP_RATE_LIMIT = 1 << 2,
435 MLX4_UPDATE_QP_SUPPORTED_ATTRS = (1 << 3) - 1
432}; 436};
433 437
434enum mlx4_update_qp_params_flags { 438enum mlx4_update_qp_params_flags {
@@ -438,6 +442,8 @@ enum mlx4_update_qp_params_flags {
438struct mlx4_update_qp_params { 442struct mlx4_update_qp_params {
439 u8 smac_index; 443 u8 smac_index;
440 u32 flags; 444 u32 flags;
445 u16 rate_unit;
446 u16 rate_val;
441}; 447};
442 448
443int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn, 449int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,