|
@@ -144,7 +144,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
|
|
|
[19] = "Performance optimized for limited rule configuration flow steering support",
|
|
|
[20] = "Recoverable error events support",
|
|
|
[21] = "Port Remap support",
|
|
|
- [22] = "QCN support"
|
|
|
+ [22] = "QCN support",
|
|
|
+ [23] = "QP rate limiting support"
|
|
|
};
|
|
|
int i;
|
|
|
|
|
@@ -697,6 +698,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
|
|
#define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0
|
|
|
#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8
|
|
|
#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac
|
|
|
+#define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc
|
|
|
+#define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0
|
|
|
+#define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2
|
|
|
+
|
|
|
|
|
|
dev_cap->flags2 = 0;
|
|
|
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)
|
|
|
QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET);
|
|
|
dev_cap->dmfs_high_rate_qpn_range &= MGM_QPN_MASK;
|
|
|
|
|
|
+ MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET);
|
|
|
+ dev_cap->rl_caps.num_rates = size;
|
|
|
+ if (dev_cap->rl_caps.num_rates) {
|
|
|
+ dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT;
|
|
|
+ MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET);
|
|
|
+ dev_cap->rl_caps.max_val = size & 0xfff;
|
|
|
+ dev_cap->rl_caps.max_unit = size >> 14;
|
|
|
+ MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET);
|
|
|
+ dev_cap->rl_caps.min_val = size & 0xfff;
|
|
|
+ dev_cap->rl_caps.min_unit = size >> 14;
|
|
|
+ }
|
|
|
+
|
|
|
MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
|
|
|
if (field32 & (1 << 16))
|
|
|
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)
|
|
|
dev_cap->dmfs_high_rate_qpn_base);
|
|
|
mlx4_dbg(dev, "DMFS high rate steer QPn range: %d\n",
|
|
|
dev_cap->dmfs_high_rate_qpn_range);
|
|
|
+
|
|
|
+ if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT) {
|
|
|
+ struct mlx4_rate_limit_caps *rl_caps = &dev_cap->rl_caps;
|
|
|
+
|
|
|
+ mlx4_dbg(dev, "QP Rate-Limit: #rates %d, unit/val max %d/%d, min %d/%d\n",
|
|
|
+ rl_caps->num_rates, rl_caps->max_unit, rl_caps->max_val,
|
|
|
+ rl_caps->min_unit, rl_caps->min_val);
|
|
|
+ }
|
|
|
+
|
|
|
dump_dev_cap_flags(dev, dev_cap->flags);
|
|
|
dump_dev_cap_flags2(dev, dev_cap->flags2);
|
|
|
}
|
|
@@ -1075,6 +1101,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
|
|
|
u64 flags;
|
|
|
int err = 0;
|
|
|
u8 field;
|
|
|
+ u16 field16;
|
|
|
u32 bmme_flags, field32;
|
|
|
int real_port;
|
|
|
int slave_port;
|
|
@@ -1158,6 +1185,10 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
|
|
|
field &= 0xfe;
|
|
|
MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET);
|
|
|
|
|
|
+ /* turn off QP max-rate limiting for guests */
|
|
|
+ field16 = 0;
|
|
|
+ MLX4_PUT(outbox->buf, field16, QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|