Skip to content

Commit 57cda16

Browse files
monis410jgunthorpe
authored andcommitted
net/mlx5: Add DCT command interface
Add a missing command interface to work with a DCT. It includes: creating, destroying and get events for. Signed-off-by: Moni Shoua <monis@mellanox.com> Reviewed-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Leon Romanovsky <leon@kernel.org> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
1 parent 8fc12d9 commit 57cda16

File tree

5 files changed

+150
-13
lines changed

5 files changed

+150
-13
lines changed

drivers/net/ethernet/mellanox/mlx5/core/eq.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,11 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
417417
cqn = be32_to_cpu(eqe->data.comp.cqn) & 0xffffff;
418418
mlx5_cq_completion(dev, cqn);
419419
break;
420-
420+
case MLX5_EVENT_TYPE_DCT_DRAINED:
421+
rsn = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff;
422+
rsn |= (MLX5_RES_DCT << MLX5_USER_INDEX_LEN);
423+
mlx5_rsc_event(dev, rsn, eqe->type);
424+
break;
421425
case MLX5_EVENT_TYPE_PATH_MIG:
422426
case MLX5_EVENT_TYPE_COMM_EST:
423427
case MLX5_EVENT_TYPE_SQ_DRAINED:
@@ -715,6 +719,9 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
715719

716720
if (MLX5_CAP_GEN(dev, fpga))
717721
async_event_mask |= (1ull << MLX5_EVENT_TYPE_FPGA_ERROR);
722+
if (MLX5_CAP_GEN_MAX(dev, dct))
723+
async_event_mask |= (1ull << MLX5_EVENT_TYPE_DCT_DRAINED);
724+
718725

719726
err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
720727
MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,

drivers/net/ethernet/mellanox/mlx5/core/qp.c

Lines changed: 113 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ static u64 sq_allowed_event_types(void)
9898
return BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR);
9999
}
100100

101+
static u64 dct_allowed_event_types(void)
102+
{
103+
return BIT(MLX5_EVENT_TYPE_DCT_DRAINED);
104+
}
105+
101106
static bool is_event_type_allowed(int rsc_type, int event_type)
102107
{
103108
switch (rsc_type) {
@@ -107,6 +112,8 @@ static bool is_event_type_allowed(int rsc_type, int event_type)
107112
return BIT(event_type) & rq_allowed_event_types();
108113
case MLX5_EVENT_QUEUE_TYPE_SQ:
109114
return BIT(event_type) & sq_allowed_event_types();
115+
case MLX5_EVENT_QUEUE_TYPE_DCT:
116+
return BIT(event_type) & dct_allowed_event_types();
110117
default:
111118
WARN(1, "Event arrived for unknown resource type");
112119
return false;
@@ -116,6 +123,7 @@ static bool is_event_type_allowed(int rsc_type, int event_type)
116123
void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
117124
{
118125
struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
126+
struct mlx5_core_dct *dct;
119127
struct mlx5_core_qp *qp;
120128

121129
if (!common)
@@ -134,17 +142,21 @@ void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
134142
qp = (struct mlx5_core_qp *)common;
135143
qp->event(qp, event_type);
136144
break;
137-
145+
case MLX5_RES_DCT:
146+
dct = (struct mlx5_core_dct *)common;
147+
if (event_type == MLX5_EVENT_TYPE_DCT_DRAINED)
148+
complete(&dct->drained);
149+
break;
138150
default:
139151
mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn);
140152
}
141153

142154
mlx5_core_put_rsc(common);
143155
}
144156

145-
static int create_qprqsq_common(struct mlx5_core_dev *dev,
146-
struct mlx5_core_qp *qp,
147-
int rsc_type)
157+
static int create_resource_common(struct mlx5_core_dev *dev,
158+
struct mlx5_core_qp *qp,
159+
int rsc_type)
148160
{
149161
struct mlx5_qp_table *table = &dev->priv.qp_table;
150162
int err;
@@ -165,8 +177,8 @@ static int create_qprqsq_common(struct mlx5_core_dev *dev,
165177
return 0;
166178
}
167179

168-
static void destroy_qprqsq_common(struct mlx5_core_dev *dev,
169-
struct mlx5_core_qp *qp)
180+
static void destroy_resource_common(struct mlx5_core_dev *dev,
181+
struct mlx5_core_qp *qp)
170182
{
171183
struct mlx5_qp_table *table = &dev->priv.qp_table;
172184
unsigned long flags;
@@ -179,6 +191,40 @@ static void destroy_qprqsq_common(struct mlx5_core_dev *dev,
179191
wait_for_completion(&qp->common.free);
180192
}
181193

194+
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
195+
struct mlx5_core_dct *dct,
196+
u32 *in, int inlen)
197+
{
198+
u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {0};
199+
u32 din[MLX5_ST_SZ_DW(destroy_dct_in)] = {0};
200+
u32 dout[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
201+
struct mlx5_core_qp *qp = &dct->mqp;
202+
int err;
203+
204+
init_completion(&dct->drained);
205+
MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT);
206+
207+
err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
208+
if (err) {
209+
mlx5_core_warn(dev, "create DCT failed, ret %d\n", err);
210+
return err;
211+
}
212+
213+
qp->qpn = MLX5_GET(create_dct_out, out, dctn);
214+
err = create_resource_common(dev, qp, MLX5_RES_DCT);
215+
if (err)
216+
goto err_cmd;
217+
218+
return 0;
219+
err_cmd:
220+
MLX5_SET(destroy_dct_in, din, opcode, MLX5_CMD_OP_DESTROY_DCT);
221+
MLX5_SET(destroy_dct_in, din, dctn, qp->qpn);
222+
mlx5_cmd_exec(dev, (void *)&in, sizeof(din),
223+
(void *)&out, sizeof(dout));
224+
return err;
225+
}
226+
EXPORT_SYMBOL_GPL(mlx5_core_create_dct);
227+
182228
int mlx5_core_create_qp(struct mlx5_core_dev *dev,
183229
struct mlx5_core_qp *qp,
184230
u32 *in, int inlen)
@@ -197,7 +243,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
197243
qp->qpn = MLX5_GET(create_qp_out, out, qpn);
198244
mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
199245

200-
err = create_qprqsq_common(dev, qp, MLX5_RES_QP);
246+
err = create_resource_common(dev, qp, MLX5_RES_QP);
201247
if (err)
202248
goto err_cmd;
203249

@@ -220,6 +266,47 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
220266
}
221267
EXPORT_SYMBOL_GPL(mlx5_core_create_qp);
222268

269+
static int mlx5_core_drain_dct(struct mlx5_core_dev *dev,
270+
struct mlx5_core_dct *dct)
271+
{
272+
u32 out[MLX5_ST_SZ_DW(drain_dct_out)] = {0};
273+
u32 in[MLX5_ST_SZ_DW(drain_dct_in)] = {0};
274+
struct mlx5_core_qp *qp = &dct->mqp;
275+
276+
MLX5_SET(drain_dct_in, in, opcode, MLX5_CMD_OP_DRAIN_DCT);
277+
MLX5_SET(drain_dct_in, in, dctn, qp->qpn);
278+
return mlx5_cmd_exec(dev, (void *)&in, sizeof(in),
279+
(void *)&out, sizeof(out));
280+
}
281+
282+
int mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
283+
struct mlx5_core_dct *dct)
284+
{
285+
u32 out[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
286+
u32 in[MLX5_ST_SZ_DW(destroy_dct_in)] = {0};
287+
struct mlx5_core_qp *qp = &dct->mqp;
288+
int err;
289+
290+
err = mlx5_core_drain_dct(dev, dct);
291+
if (err) {
292+
if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
293+
goto destroy;
294+
} else {
295+
mlx5_core_warn(dev, "failed drain DCT 0x%x with error 0x%x\n", qp->qpn, err);
296+
return err;
297+
}
298+
}
299+
wait_for_completion(&dct->drained);
300+
destroy:
301+
destroy_resource_common(dev, &dct->mqp);
302+
MLX5_SET(destroy_dct_in, in, opcode, MLX5_CMD_OP_DESTROY_DCT);
303+
MLX5_SET(destroy_dct_in, in, dctn, qp->qpn);
304+
err = mlx5_cmd_exec(dev, (void *)&in, sizeof(in),
305+
(void *)&out, sizeof(out));
306+
return err;
307+
}
308+
EXPORT_SYMBOL_GPL(mlx5_core_destroy_dct);
309+
223310
int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
224311
struct mlx5_core_qp *qp)
225312
{
@@ -229,7 +316,7 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
229316

230317
mlx5_debug_qp_remove(dev, qp);
231318

232-
destroy_qprqsq_common(dev, qp);
319+
destroy_resource_common(dev, qp);
233320

234321
MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
235322
MLX5_SET(destroy_qp_in, in, qpn, qp->qpn);
@@ -405,6 +492,20 @@ int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
405492
}
406493
EXPORT_SYMBOL_GPL(mlx5_core_qp_query);
407494

495+
int mlx5_core_dct_query(struct mlx5_core_dev *dev, struct mlx5_core_dct *dct,
496+
u32 *out, int outlen)
497+
{
498+
u32 in[MLX5_ST_SZ_DW(query_dct_in)] = {0};
499+
struct mlx5_core_qp *qp = &dct->mqp;
500+
501+
MLX5_SET(query_dct_in, in, opcode, MLX5_CMD_OP_QUERY_DCT);
502+
MLX5_SET(query_dct_in, in, dctn, qp->qpn);
503+
504+
return mlx5_cmd_exec(dev, (void *)&in, sizeof(in),
505+
(void *)out, outlen);
506+
}
507+
EXPORT_SYMBOL_GPL(mlx5_core_dct_query);
508+
408509
int mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn)
409510
{
410511
u32 out[MLX5_ST_SZ_DW(alloc_xrcd_out)] = {0};
@@ -441,7 +542,7 @@ int mlx5_core_create_rq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
441542
return err;
442543

443544
rq->qpn = rqn;
444-
err = create_qprqsq_common(dev, rq, MLX5_RES_RQ);
545+
err = create_resource_common(dev, rq, MLX5_RES_RQ);
445546
if (err)
446547
goto err_destroy_rq;
447548

@@ -457,7 +558,7 @@ EXPORT_SYMBOL(mlx5_core_create_rq_tracked);
457558
void mlx5_core_destroy_rq_tracked(struct mlx5_core_dev *dev,
458559
struct mlx5_core_qp *rq)
459560
{
460-
destroy_qprqsq_common(dev, rq);
561+
destroy_resource_common(dev, rq);
461562
mlx5_core_destroy_rq(dev, rq->qpn);
462563
}
463564
EXPORT_SYMBOL(mlx5_core_destroy_rq_tracked);
@@ -473,7 +574,7 @@ int mlx5_core_create_sq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
473574
return err;
474575

475576
sq->qpn = sqn;
476-
err = create_qprqsq_common(dev, sq, MLX5_RES_SQ);
577+
err = create_resource_common(dev, sq, MLX5_RES_SQ);
477578
if (err)
478579
goto err_destroy_sq;
479580

@@ -489,7 +590,7 @@ EXPORT_SYMBOL(mlx5_core_create_sq_tracked);
489590
void mlx5_core_destroy_sq_tracked(struct mlx5_core_dev *dev,
490591
struct mlx5_core_qp *sq)
491592
{
492-
destroy_qprqsq_common(dev, sq);
593+
destroy_resource_common(dev, sq);
493594
mlx5_core_destroy_sq(dev, sq->qpn);
494595
}
495596
EXPORT_SYMBOL(mlx5_core_destroy_sq_tracked);

include/linux/mlx5/device.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ enum {
286286
MLX5_EVENT_QUEUE_TYPE_QP = 0,
287287
MLX5_EVENT_QUEUE_TYPE_RQ = 1,
288288
MLX5_EVENT_QUEUE_TYPE_SQ = 2,
289+
MLX5_EVENT_QUEUE_TYPE_DCT = 6,
289290
};
290291

291292
enum mlx5_event {
@@ -321,6 +322,8 @@ enum mlx5_event {
321322
MLX5_EVENT_TYPE_PAGE_FAULT = 0xc,
322323
MLX5_EVENT_TYPE_NIC_VPORT_CHANGE = 0xd,
323324

325+
MLX5_EVENT_TYPE_DCT_DRAINED = 0x1c,
326+
324327
MLX5_EVENT_TYPE_FPGA_ERROR = 0x20,
325328
};
326329

@@ -613,6 +616,11 @@ struct mlx5_eqe_pps {
613616
u8 rsvd2[12];
614617
} __packed;
615618

619+
struct mlx5_eqe_dct {
620+
__be32 reserved[6];
621+
__be32 dctn;
622+
};
623+
616624
union ev_data {
617625
__be32 raw[7];
618626
struct mlx5_eqe_cmd cmd;
@@ -628,6 +636,7 @@ union ev_data {
628636
struct mlx5_eqe_vport_change vport_change;
629637
struct mlx5_eqe_port_module port_module;
630638
struct mlx5_eqe_pps pps;
639+
struct mlx5_eqe_dct dct;
631640
} __packed;
632641

633642
struct mlx5_eqe {

include/linux/mlx5/driver.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ enum mlx5_dcbx_oper_mode {
154154
MLX5E_DCBX_PARAM_VER_OPER_AUTO = 0x3,
155155
};
156156

157+
enum mlx5_dct_atomic_mode {
158+
MLX5_ATOMIC_MODE_DCT_OFF = 20,
159+
MLX5_ATOMIC_MODE_DCT_NONE = 0 << MLX5_ATOMIC_MODE_DCT_OFF,
160+
MLX5_ATOMIC_MODE_DCT_IB_COMP = 1 << MLX5_ATOMIC_MODE_DCT_OFF,
161+
MLX5_ATOMIC_MODE_DCT_CX = 2 << MLX5_ATOMIC_MODE_DCT_OFF,
162+
};
163+
157164
enum {
158165
MLX5_ATOMIC_OPS_CMP_SWAP = 1 << 0,
159166
MLX5_ATOMIC_OPS_FETCH_ADD = 1 << 1,
@@ -432,6 +439,7 @@ enum mlx5_res_type {
432439
MLX5_RES_SRQ = 3,
433440
MLX5_RES_XSRQ = 4,
434441
MLX5_RES_XRQ = 5,
442+
MLX5_RES_DCT = MLX5_EVENT_QUEUE_TYPE_DCT,
435443
};
436444

437445
struct mlx5_core_rsc_common {

include/linux/mlx5/qp.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ struct mlx5_core_qp {
473473
int pid;
474474
};
475475

476+
struct mlx5_core_dct {
477+
struct mlx5_core_qp mqp;
478+
struct completion drained;
479+
};
480+
476481
struct mlx5_qp_path {
477482
u8 fl_free_ar;
478483
u8 rsvd3;
@@ -549,6 +554,9 @@ static inline struct mlx5_core_mkey *__mlx5_mr_lookup(struct mlx5_core_dev *dev,
549554
return radix_tree_lookup(&dev->priv.mkey_table.tree, key);
550555
}
551556

557+
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
558+
struct mlx5_core_dct *qp,
559+
u32 *in, int inlen);
552560
int mlx5_core_create_qp(struct mlx5_core_dev *dev,
553561
struct mlx5_core_qp *qp,
554562
u32 *in,
@@ -558,8 +566,12 @@ int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 opcode,
558566
struct mlx5_core_qp *qp);
559567
int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
560568
struct mlx5_core_qp *qp);
569+
int mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
570+
struct mlx5_core_dct *dct);
561571
int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
562572
u32 *out, int outlen);
573+
int mlx5_core_dct_query(struct mlx5_core_dev *dev, struct mlx5_core_dct *dct,
574+
u32 *out, int outlen);
563575

564576
int mlx5_core_set_delay_drop(struct mlx5_core_dev *dev,
565577
u32 timeout_usec);

0 commit comments

Comments
 (0)