0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/mlx5/driver.h>
0034 #include "wq.h"
0035 #include "mlx5_core.h"
0036
0037 int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
0038 void *wqc, struct mlx5_wq_cyc *wq,
0039 struct mlx5_wq_ctrl *wq_ctrl)
0040 {
0041 u8 log_wq_stride = MLX5_GET(wq, wqc, log_wq_stride);
0042 u8 log_wq_sz = MLX5_GET(wq, wqc, log_wq_sz);
0043 struct mlx5_frag_buf_ctrl *fbc = &wq->fbc;
0044 int err;
0045
0046 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
0047 if (err) {
0048 mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);
0049 return err;
0050 }
0051
0052 wq->db = wq_ctrl->db.db;
0053
0054 err = mlx5_frag_buf_alloc_node(mdev, wq_get_byte_sz(log_wq_sz, log_wq_stride),
0055 &wq_ctrl->buf, param->buf_numa_node);
0056 if (err) {
0057 mlx5_core_warn(mdev, "mlx5_frag_buf_alloc_node() failed, %d\n", err);
0058 goto err_db_free;
0059 }
0060
0061 mlx5_init_fbc(wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, fbc);
0062 wq->sz = mlx5_wq_cyc_get_size(wq);
0063
0064 wq_ctrl->mdev = mdev;
0065
0066 return 0;
0067
0068 err_db_free:
0069 mlx5_db_free(mdev, &wq_ctrl->db);
0070
0071 return err;
0072 }
0073
0074 void mlx5_wq_cyc_wqe_dump(struct mlx5_wq_cyc *wq, u16 ix, u8 nstrides)
0075 {
0076 size_t len;
0077 void *wqe;
0078
0079 if (!net_ratelimit())
0080 return;
0081
0082 nstrides = max_t(u8, nstrides, 1);
0083
0084 len = nstrides << wq->fbc.log_stride;
0085 wqe = mlx5_wq_cyc_get_wqe(wq, ix);
0086
0087 pr_info("WQE DUMP: WQ size %d WQ cur size %d, WQE index 0x%x, len: %zu\n",
0088 mlx5_wq_cyc_get_size(wq), wq->cur_sz, ix, len);
0089 print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, wqe, len, false);
0090 }
0091
0092 void mlx5_wq_cyc_reset(struct mlx5_wq_cyc *wq)
0093 {
0094 wq->wqe_ctr = 0;
0095 wq->cur_sz = 0;
0096 mlx5_wq_cyc_update_db_record(wq);
0097 }
0098
0099 int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
0100 void *qpc, struct mlx5_wq_qp *wq,
0101 struct mlx5_wq_ctrl *wq_ctrl)
0102 {
0103 u8 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride) + 4;
0104 u8 log_rq_sz = MLX5_GET(qpc, qpc, log_rq_size);
0105 u8 log_sq_stride = ilog2(MLX5_SEND_WQE_BB);
0106 u8 log_sq_sz = MLX5_GET(qpc, qpc, log_sq_size);
0107
0108 u32 rq_byte_size;
0109 int err;
0110
0111
0112
0113 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
0114 if (err) {
0115 mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);
0116 return err;
0117 }
0118
0119 err = mlx5_frag_buf_alloc_node(mdev,
0120 wq_get_byte_sz(log_rq_sz, log_rq_stride) +
0121 wq_get_byte_sz(log_sq_sz, log_sq_stride),
0122 &wq_ctrl->buf, param->buf_numa_node);
0123 if (err) {
0124 mlx5_core_warn(mdev, "mlx5_frag_buf_alloc_node() failed, %d\n", err);
0125 goto err_db_free;
0126 }
0127
0128 mlx5_init_fbc(wq_ctrl->buf.frags, log_rq_stride, log_rq_sz, &wq->rq.fbc);
0129
0130 rq_byte_size = wq_get_byte_sz(log_rq_sz, log_rq_stride);
0131
0132 if (rq_byte_size < PAGE_SIZE) {
0133
0134 u16 sq_strides_offset = rq_byte_size / MLX5_SEND_WQE_BB;
0135
0136 mlx5_init_fbc_offset(wq_ctrl->buf.frags,
0137 log_sq_stride, log_sq_sz, sq_strides_offset,
0138 &wq->sq.fbc);
0139 } else {
0140 u16 rq_npages = rq_byte_size >> PAGE_SHIFT;
0141
0142 mlx5_init_fbc(wq_ctrl->buf.frags + rq_npages,
0143 log_sq_stride, log_sq_sz, &wq->sq.fbc);
0144 }
0145
0146 wq->rq.db = &wq_ctrl->db.db[MLX5_RCV_DBR];
0147 wq->sq.db = &wq_ctrl->db.db[MLX5_SND_DBR];
0148
0149 wq_ctrl->mdev = mdev;
0150
0151 return 0;
0152
0153 err_db_free:
0154 mlx5_db_free(mdev, &wq_ctrl->db);
0155
0156 return err;
0157 }
0158
0159 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
0160 void *cqc, struct mlx5_cqwq *wq,
0161 struct mlx5_wq_ctrl *wq_ctrl)
0162 {
0163
0164 u8 log_wq_stride = MLX5_GET(cqc, cqc, cqe_sz) == CQE_STRIDE_64 ? 6 : 7;
0165 u8 log_wq_sz = MLX5_GET(cqc, cqc, log_cq_size);
0166 int err;
0167
0168 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
0169 if (err) {
0170 mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);
0171 return err;
0172 }
0173
0174 wq->db = wq_ctrl->db.db;
0175
0176 err = mlx5_frag_buf_alloc_node(mdev, wq_get_byte_sz(log_wq_sz, log_wq_stride),
0177 &wq_ctrl->buf,
0178 param->buf_numa_node);
0179 if (err) {
0180 mlx5_core_warn(mdev, "mlx5_frag_buf_alloc_node() failed, %d\n",
0181 err);
0182 goto err_db_free;
0183 }
0184
0185 mlx5_init_fbc(wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, &wq->fbc);
0186
0187 wq_ctrl->mdev = mdev;
0188
0189 return 0;
0190
0191 err_db_free:
0192 mlx5_db_free(mdev, &wq_ctrl->db);
0193
0194 return err;
0195 }
0196
0197 static void mlx5_wq_ll_init_list(struct mlx5_wq_ll *wq)
0198 {
0199 struct mlx5_wqe_srq_next_seg *next_seg;
0200 int i;
0201
0202 for (i = 0; i < wq->fbc.sz_m1; i++) {
0203 next_seg = mlx5_wq_ll_get_wqe(wq, i);
0204 next_seg->next_wqe_index = cpu_to_be16(i + 1);
0205 }
0206 next_seg = mlx5_wq_ll_get_wqe(wq, i);
0207 wq->tail_next = &next_seg->next_wqe_index;
0208 }
0209
0210 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
0211 void *wqc, struct mlx5_wq_ll *wq,
0212 struct mlx5_wq_ctrl *wq_ctrl)
0213 {
0214 u8 log_wq_stride = MLX5_GET(wq, wqc, log_wq_stride);
0215 u8 log_wq_sz = MLX5_GET(wq, wqc, log_wq_sz);
0216 struct mlx5_frag_buf_ctrl *fbc = &wq->fbc;
0217 int err;
0218
0219 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
0220 if (err) {
0221 mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);
0222 return err;
0223 }
0224
0225 wq->db = wq_ctrl->db.db;
0226
0227 err = mlx5_frag_buf_alloc_node(mdev, wq_get_byte_sz(log_wq_sz, log_wq_stride),
0228 &wq_ctrl->buf, param->buf_numa_node);
0229 if (err) {
0230 mlx5_core_warn(mdev, "mlx5_frag_buf_alloc_node() failed, %d\n", err);
0231 goto err_db_free;
0232 }
0233
0234 mlx5_init_fbc(wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, fbc);
0235
0236 mlx5_wq_ll_init_list(wq);
0237 wq_ctrl->mdev = mdev;
0238
0239 return 0;
0240
0241 err_db_free:
0242 mlx5_db_free(mdev, &wq_ctrl->db);
0243
0244 return err;
0245 }
0246
0247 void mlx5_wq_ll_reset(struct mlx5_wq_ll *wq)
0248 {
0249 wq->head = 0;
0250 wq->wqe_ctr = 0;
0251 wq->cur_sz = 0;
0252 mlx5_wq_ll_init_list(wq);
0253 mlx5_wq_ll_update_db_record(wq);
0254 }
0255
0256 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl)
0257 {
0258 mlx5_frag_buf_free(wq_ctrl->mdev, &wq_ctrl->buf);
0259 mlx5_db_free(wq_ctrl->mdev, &wq_ctrl->db);
0260 }
0261