@@ -314,9 +314,14 @@ struct mlx5_rss_caps {
__u8 reserved[7];
};
+enum mlx5_ib_packet_pacing_cap_flags {
+ MLX5_IB_PP_SUPPORT_BURST = 1 << 0,
+};
+
struct mlx5_packet_pacing_caps {
struct ibv_packet_pacing_caps caps;
- __u32 reserved;
+ __u8 cap_flags; /* enum mlx5_ib_packet_pacing_cap_flags */
+ __u8 reserved[3];
};
enum mlx5_mpw_caps {
@@ -357,4 +362,16 @@ struct mlx5_modify_qp_resp_ex {
__u32 dctn;
};
+struct mlx5_ib_burst_info {
+ __u32 max_burst_sz;
+ __u16 typical_pkt_sz;
+};
+
+struct mlx5_ib_modify_qp {
+ struct ibv_modify_qp_ex ibv_cmd;
+ __u32 comp_mask;
+ struct mlx5_ib_burst_info burst_info;
+ __u8 reserved[6];
+};
+
#endif /* MLX5_ABI_H */
@@ -129,6 +129,7 @@ static const struct verbs_context_ops mlx5_ctx_common_ops = {
.destroy_wq = mlx5_destroy_wq,
.get_srq_num = mlx5_get_srq_num,
.modify_cq = mlx5_modify_cq,
+ .modify_qp_rate_limit = mlx5_modify_qp_rate_limit,
.modify_wq = mlx5_modify_wq,
.open_xrcd = mlx5_open_xrcd,
.post_srq_ops = mlx5_post_srq_ops,
@@ -298,6 +298,7 @@ struct mlx5_context {
struct mlx5dv_sw_parsing_caps sw_parsing_caps;
struct mlx5dv_striding_rq_caps striding_rq_caps;
uint32_t tunnel_offloads_caps;
+ struct mlx5_packet_pacing_caps packet_pacing_caps;
pthread_mutex_t dyn_bfregs_mutex; /* protects the dynamic bfregs allocation */
uint32_t num_dyn_bfregs;
uint32_t *count_dyn_bfregs;
@@ -751,6 +752,8 @@ int mlx5_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
struct ibv_qp_init_attr *init_attr);
int mlx5_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
int attr_mask);
+int mlx5_modify_qp_rate_limit(struct ibv_qp *qp,
+ struct ibv_qp_rate_limit_attr *attr);
int mlx5_destroy_qp(struct ibv_qp *qp);
void mlx5_init_qp_indices(struct mlx5_qp *qp);
void mlx5_init_rwq_indices(struct mlx5_rwq *rwq);
@@ -2131,6 +2131,38 @@ int mlx5_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
return ret;
}
+int mlx5_modify_qp_rate_limit(struct ibv_qp *qp,
+ struct ibv_qp_rate_limit_attr *attr)
+{
+ struct ibv_qp_attr qp_attr = {};
+ struct ib_uverbs_ex_modify_qp_resp resp = {};
+ struct mlx5_ib_modify_qp cmd = {};
+ struct mlx5_context *mctx = to_mctx(qp->context);
+ int ret;
+
+ if (attr->comp_mask)
+ return EINVAL;
+
+ if ((attr->max_burst_sz ||
+ attr->typical_pkt_sz) &&
+ (!attr->rate_limit ||
+ !(mctx->packet_pacing_caps.cap_flags &
+ MLX5_IB_PP_SUPPORT_BURST)))
+ return EINVAL;
+
+ cmd.burst_info.max_burst_sz = attr->max_burst_sz;
+ cmd.burst_info.typical_pkt_sz = attr->typical_pkt_sz;
+ qp_attr.rate_limit = attr->rate_limit;
+
+ ret = ibv_cmd_modify_qp_ex(qp, &qp_attr, IBV_QP_RATE_LIMIT,
+ &cmd.ibv_cmd,
+ sizeof(cmd.ibv_cmd), sizeof(cmd),
+ &resp,
+ sizeof(resp), sizeof(resp));
+
+ return ret;
+}
+
#define RROCE_UDP_SPORT_MIN 0xC000
#define RROCE_UDP_SPORT_MAX 0xFFFF
struct ibv_ah *mlx5_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
@@ -2603,6 +2635,7 @@ int mlx5_query_device_ex(struct ibv_context *context,
mctx->sw_parsing_caps = resp.sw_parsing_caps;
mctx->striding_rq_caps = resp.striding_rq_caps.caps;
mctx->tunnel_offloads_caps = resp.tunnel_offloads_caps;
+ mctx->packet_pacing_caps = resp.packet_pacing_caps;
if (resp.flags & MLX5_QUERY_DEV_RESP_FLAGS_CQE_128B_COMP)
mctx->vendor_cap_flags |= MLX5_VENDOR_CAP_FLAGS_CQE_128B_COMP;