Commit 57cda166 authored by Moni Shoua's avatar Moni Shoua Committed by Jason Gunthorpe

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: default avatarMoni Shoua <monis@mellanox.com>
Reviewed-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 8fc12d94
...@@ -417,7 +417,11 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr) ...@@ -417,7 +417,11 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
cqn = be32_to_cpu(eqe->data.comp.cqn) & 0xffffff; cqn = be32_to_cpu(eqe->data.comp.cqn) & 0xffffff;
mlx5_cq_completion(dev, cqn); mlx5_cq_completion(dev, cqn);
break; break;
case MLX5_EVENT_TYPE_DCT_DRAINED:
rsn = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff;
rsn |= (MLX5_RES_DCT << MLX5_USER_INDEX_LEN);
mlx5_rsc_event(dev, rsn, eqe->type);
break;
case MLX5_EVENT_TYPE_PATH_MIG: case MLX5_EVENT_TYPE_PATH_MIG:
case MLX5_EVENT_TYPE_COMM_EST: case MLX5_EVENT_TYPE_COMM_EST:
case MLX5_EVENT_TYPE_SQ_DRAINED: case MLX5_EVENT_TYPE_SQ_DRAINED:
...@@ -715,6 +719,9 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev) ...@@ -715,6 +719,9 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
if (MLX5_CAP_GEN(dev, fpga)) if (MLX5_CAP_GEN(dev, fpga))
async_event_mask |= (1ull << MLX5_EVENT_TYPE_FPGA_ERROR); async_event_mask |= (1ull << MLX5_EVENT_TYPE_FPGA_ERROR);
if (MLX5_CAP_GEN_MAX(dev, dct))
async_event_mask |= (1ull << MLX5_EVENT_TYPE_DCT_DRAINED);
err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD, err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD, MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,
......
...@@ -98,6 +98,11 @@ static u64 sq_allowed_event_types(void) ...@@ -98,6 +98,11 @@ static u64 sq_allowed_event_types(void)
return BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR); return BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR);
} }
static u64 dct_allowed_event_types(void)
{
return BIT(MLX5_EVENT_TYPE_DCT_DRAINED);
}
static bool is_event_type_allowed(int rsc_type, int event_type) static bool is_event_type_allowed(int rsc_type, int event_type)
{ {
switch (rsc_type) { switch (rsc_type) {
...@@ -107,6 +112,8 @@ static bool is_event_type_allowed(int rsc_type, int event_type) ...@@ -107,6 +112,8 @@ static bool is_event_type_allowed(int rsc_type, int event_type)
return BIT(event_type) & rq_allowed_event_types(); return BIT(event_type) & rq_allowed_event_types();
case MLX5_EVENT_QUEUE_TYPE_SQ: case MLX5_EVENT_QUEUE_TYPE_SQ:
return BIT(event_type) & sq_allowed_event_types(); return BIT(event_type) & sq_allowed_event_types();
case MLX5_EVENT_QUEUE_TYPE_DCT:
return BIT(event_type) & dct_allowed_event_types();
default: default:
WARN(1, "Event arrived for unknown resource type"); WARN(1, "Event arrived for unknown resource type");
return false; return false;
...@@ -116,6 +123,7 @@ static bool is_event_type_allowed(int rsc_type, int event_type) ...@@ -116,6 +123,7 @@ static bool is_event_type_allowed(int rsc_type, int event_type)
void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type) void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
{ {
struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn); struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
struct mlx5_core_dct *dct;
struct mlx5_core_qp *qp; struct mlx5_core_qp *qp;
if (!common) if (!common)
...@@ -134,7 +142,11 @@ void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type) ...@@ -134,7 +142,11 @@ void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
qp = (struct mlx5_core_qp *)common; qp = (struct mlx5_core_qp *)common;
qp->event(qp, event_type); qp->event(qp, event_type);
break; break;
case MLX5_RES_DCT:
dct = (struct mlx5_core_dct *)common;
if (event_type == MLX5_EVENT_TYPE_DCT_DRAINED)
complete(&dct->drained);
break;
default: default:
mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn); mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn);
} }
...@@ -142,9 +154,9 @@ void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type) ...@@ -142,9 +154,9 @@ void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
mlx5_core_put_rsc(common); mlx5_core_put_rsc(common);
} }
static int create_qprqsq_common(struct mlx5_core_dev *dev, static int create_resource_common(struct mlx5_core_dev *dev,
struct mlx5_core_qp *qp, struct mlx5_core_qp *qp,
int rsc_type) int rsc_type)
{ {
struct mlx5_qp_table *table = &dev->priv.qp_table; struct mlx5_qp_table *table = &dev->priv.qp_table;
int err; int err;
...@@ -165,8 +177,8 @@ static int create_qprqsq_common(struct mlx5_core_dev *dev, ...@@ -165,8 +177,8 @@ static int create_qprqsq_common(struct mlx5_core_dev *dev,
return 0; return 0;
} }
static void destroy_qprqsq_common(struct mlx5_core_dev *dev, static void destroy_resource_common(struct mlx5_core_dev *dev,
struct mlx5_core_qp *qp) struct mlx5_core_qp *qp)
{ {
struct mlx5_qp_table *table = &dev->priv.qp_table; struct mlx5_qp_table *table = &dev->priv.qp_table;
unsigned long flags; unsigned long flags;
...@@ -179,6 +191,40 @@ static void destroy_qprqsq_common(struct mlx5_core_dev *dev, ...@@ -179,6 +191,40 @@ static void destroy_qprqsq_common(struct mlx5_core_dev *dev,
wait_for_completion(&qp->common.free); wait_for_completion(&qp->common.free);
} }
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
struct mlx5_core_dct *dct,
u32 *in, int inlen)
{
u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {0};
u32 din[MLX5_ST_SZ_DW(destroy_dct_in)] = {0};
u32 dout[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
struct mlx5_core_qp *qp = &dct->mqp;
int err;
init_completion(&dct->drained);
MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT);
err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
if (err) {
mlx5_core_warn(dev, "create DCT failed, ret %d\n", err);
return err;
}
qp->qpn = MLX5_GET(create_dct_out, out, dctn);
err = create_resource_common(dev, qp, MLX5_RES_DCT);
if (err)
goto err_cmd;
return 0;
err_cmd:
MLX5_SET(destroy_dct_in, din, opcode, MLX5_CMD_OP_DESTROY_DCT);
MLX5_SET(destroy_dct_in, din, dctn, qp->qpn);
mlx5_cmd_exec(dev, (void *)&in, sizeof(din),
(void *)&out, sizeof(dout));
return err;
}
EXPORT_SYMBOL_GPL(mlx5_core_create_dct);
int mlx5_core_create_qp(struct mlx5_core_dev *dev, int mlx5_core_create_qp(struct mlx5_core_dev *dev,
struct mlx5_core_qp *qp, struct mlx5_core_qp *qp,
u32 *in, int inlen) u32 *in, int inlen)
...@@ -197,7 +243,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev, ...@@ -197,7 +243,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
qp->qpn = MLX5_GET(create_qp_out, out, qpn); qp->qpn = MLX5_GET(create_qp_out, out, qpn);
mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn); mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
err = create_qprqsq_common(dev, qp, MLX5_RES_QP); err = create_resource_common(dev, qp, MLX5_RES_QP);
if (err) if (err)
goto err_cmd; goto err_cmd;
...@@ -220,6 +266,47 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev, ...@@ -220,6 +266,47 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
} }
EXPORT_SYMBOL_GPL(mlx5_core_create_qp); EXPORT_SYMBOL_GPL(mlx5_core_create_qp);
static int mlx5_core_drain_dct(struct mlx5_core_dev *dev,
struct mlx5_core_dct *dct)
{
u32 out[MLX5_ST_SZ_DW(drain_dct_out)] = {0};
u32 in[MLX5_ST_SZ_DW(drain_dct_in)] = {0};
struct mlx5_core_qp *qp = &dct->mqp;
MLX5_SET(drain_dct_in, in, opcode, MLX5_CMD_OP_DRAIN_DCT);
MLX5_SET(drain_dct_in, in, dctn, qp->qpn);
return mlx5_cmd_exec(dev, (void *)&in, sizeof(in),
(void *)&out, sizeof(out));
}
int mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
struct mlx5_core_dct *dct)
{
u32 out[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
u32 in[MLX5_ST_SZ_DW(destroy_dct_in)] = {0};
struct mlx5_core_qp *qp = &dct->mqp;
int err;
err = mlx5_core_drain_dct(dev, dct);
if (err) {
if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
goto destroy;
} else {
mlx5_core_warn(dev, "failed drain DCT 0x%x with error 0x%x\n", qp->qpn, err);
return err;
}
}
wait_for_completion(&dct->drained);
destroy:
destroy_resource_common(dev, &dct->mqp);
MLX5_SET(destroy_dct_in, in, opcode, MLX5_CMD_OP_DESTROY_DCT);
MLX5_SET(destroy_dct_in, in, dctn, qp->qpn);
err = mlx5_cmd_exec(dev, (void *)&in, sizeof(in),
(void *)&out, sizeof(out));
return err;
}
EXPORT_SYMBOL_GPL(mlx5_core_destroy_dct);
int mlx5_core_destroy_qp(struct mlx5_core_dev *dev, int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
struct mlx5_core_qp *qp) struct mlx5_core_qp *qp)
{ {
...@@ -229,7 +316,7 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev, ...@@ -229,7 +316,7 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
mlx5_debug_qp_remove(dev, qp); mlx5_debug_qp_remove(dev, qp);
destroy_qprqsq_common(dev, qp); destroy_resource_common(dev, qp);
MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP); MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
MLX5_SET(destroy_qp_in, in, qpn, qp->qpn); 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, ...@@ -405,6 +492,20 @@ int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
} }
EXPORT_SYMBOL_GPL(mlx5_core_qp_query); EXPORT_SYMBOL_GPL(mlx5_core_qp_query);
int mlx5_core_dct_query(struct mlx5_core_dev *dev, struct mlx5_core_dct *dct,
u32 *out, int outlen)
{
u32 in[MLX5_ST_SZ_DW(query_dct_in)] = {0};
struct mlx5_core_qp *qp = &dct->mqp;
MLX5_SET(query_dct_in, in, opcode, MLX5_CMD_OP_QUERY_DCT);
MLX5_SET(query_dct_in, in, dctn, qp->qpn);
return mlx5_cmd_exec(dev, (void *)&in, sizeof(in),
(void *)out, outlen);
}
EXPORT_SYMBOL_GPL(mlx5_core_dct_query);
int mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn) int mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn)
{ {
u32 out[MLX5_ST_SZ_DW(alloc_xrcd_out)] = {0}; 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, ...@@ -441,7 +542,7 @@ int mlx5_core_create_rq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
return err; return err;
rq->qpn = rqn; rq->qpn = rqn;
err = create_qprqsq_common(dev, rq, MLX5_RES_RQ); err = create_resource_common(dev, rq, MLX5_RES_RQ);
if (err) if (err)
goto err_destroy_rq; goto err_destroy_rq;
...@@ -457,7 +558,7 @@ EXPORT_SYMBOL(mlx5_core_create_rq_tracked); ...@@ -457,7 +558,7 @@ EXPORT_SYMBOL(mlx5_core_create_rq_tracked);
void mlx5_core_destroy_rq_tracked(struct mlx5_core_dev *dev, void mlx5_core_destroy_rq_tracked(struct mlx5_core_dev *dev,
struct mlx5_core_qp *rq) struct mlx5_core_qp *rq)
{ {
destroy_qprqsq_common(dev, rq); destroy_resource_common(dev, rq);
mlx5_core_destroy_rq(dev, rq->qpn); mlx5_core_destroy_rq(dev, rq->qpn);
} }
EXPORT_SYMBOL(mlx5_core_destroy_rq_tracked); 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, ...@@ -473,7 +574,7 @@ int mlx5_core_create_sq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
return err; return err;
sq->qpn = sqn; sq->qpn = sqn;
err = create_qprqsq_common(dev, sq, MLX5_RES_SQ); err = create_resource_common(dev, sq, MLX5_RES_SQ);
if (err) if (err)
goto err_destroy_sq; goto err_destroy_sq;
...@@ -489,7 +590,7 @@ EXPORT_SYMBOL(mlx5_core_create_sq_tracked); ...@@ -489,7 +590,7 @@ EXPORT_SYMBOL(mlx5_core_create_sq_tracked);
void mlx5_core_destroy_sq_tracked(struct mlx5_core_dev *dev, void mlx5_core_destroy_sq_tracked(struct mlx5_core_dev *dev,
struct mlx5_core_qp *sq) struct mlx5_core_qp *sq)
{ {
destroy_qprqsq_common(dev, sq); destroy_resource_common(dev, sq);
mlx5_core_destroy_sq(dev, sq->qpn); mlx5_core_destroy_sq(dev, sq->qpn);
} }
EXPORT_SYMBOL(mlx5_core_destroy_sq_tracked); EXPORT_SYMBOL(mlx5_core_destroy_sq_tracked);
......
...@@ -286,6 +286,7 @@ enum { ...@@ -286,6 +286,7 @@ enum {
MLX5_EVENT_QUEUE_TYPE_QP = 0, MLX5_EVENT_QUEUE_TYPE_QP = 0,
MLX5_EVENT_QUEUE_TYPE_RQ = 1, MLX5_EVENT_QUEUE_TYPE_RQ = 1,
MLX5_EVENT_QUEUE_TYPE_SQ = 2, MLX5_EVENT_QUEUE_TYPE_SQ = 2,
MLX5_EVENT_QUEUE_TYPE_DCT = 6,
}; };
enum mlx5_event { enum mlx5_event {
...@@ -321,6 +322,8 @@ enum mlx5_event { ...@@ -321,6 +322,8 @@ enum mlx5_event {
MLX5_EVENT_TYPE_PAGE_FAULT = 0xc, MLX5_EVENT_TYPE_PAGE_FAULT = 0xc,
MLX5_EVENT_TYPE_NIC_VPORT_CHANGE = 0xd, MLX5_EVENT_TYPE_NIC_VPORT_CHANGE = 0xd,
MLX5_EVENT_TYPE_DCT_DRAINED = 0x1c,
MLX5_EVENT_TYPE_FPGA_ERROR = 0x20, MLX5_EVENT_TYPE_FPGA_ERROR = 0x20,
}; };
...@@ -613,6 +616,11 @@ struct mlx5_eqe_pps { ...@@ -613,6 +616,11 @@ struct mlx5_eqe_pps {
u8 rsvd2[12]; u8 rsvd2[12];
} __packed; } __packed;
struct mlx5_eqe_dct {
__be32 reserved[6];
__be32 dctn;
};
union ev_data { union ev_data {
__be32 raw[7]; __be32 raw[7];
struct mlx5_eqe_cmd cmd; struct mlx5_eqe_cmd cmd;
...@@ -628,6 +636,7 @@ union ev_data { ...@@ -628,6 +636,7 @@ union ev_data {
struct mlx5_eqe_vport_change vport_change; struct mlx5_eqe_vport_change vport_change;
struct mlx5_eqe_port_module port_module; struct mlx5_eqe_port_module port_module;
struct mlx5_eqe_pps pps; struct mlx5_eqe_pps pps;
struct mlx5_eqe_dct dct;
} __packed; } __packed;
struct mlx5_eqe { struct mlx5_eqe {
......
...@@ -154,6 +154,13 @@ enum mlx5_dcbx_oper_mode { ...@@ -154,6 +154,13 @@ enum mlx5_dcbx_oper_mode {
MLX5E_DCBX_PARAM_VER_OPER_AUTO = 0x3, MLX5E_DCBX_PARAM_VER_OPER_AUTO = 0x3,
}; };
enum mlx5_dct_atomic_mode {
MLX5_ATOMIC_MODE_DCT_OFF = 20,
MLX5_ATOMIC_MODE_DCT_NONE = 0 << MLX5_ATOMIC_MODE_DCT_OFF,
MLX5_ATOMIC_MODE_DCT_IB_COMP = 1 << MLX5_ATOMIC_MODE_DCT_OFF,
MLX5_ATOMIC_MODE_DCT_CX = 2 << MLX5_ATOMIC_MODE_DCT_OFF,
};
enum { enum {
MLX5_ATOMIC_OPS_CMP_SWAP = 1 << 0, MLX5_ATOMIC_OPS_CMP_SWAP = 1 << 0,
MLX5_ATOMIC_OPS_FETCH_ADD = 1 << 1, MLX5_ATOMIC_OPS_FETCH_ADD = 1 << 1,
...@@ -432,6 +439,7 @@ enum mlx5_res_type { ...@@ -432,6 +439,7 @@ enum mlx5_res_type {
MLX5_RES_SRQ = 3, MLX5_RES_SRQ = 3,
MLX5_RES_XSRQ = 4, MLX5_RES_XSRQ = 4,
MLX5_RES_XRQ = 5, MLX5_RES_XRQ = 5,
MLX5_RES_DCT = MLX5_EVENT_QUEUE_TYPE_DCT,
}; };
struct mlx5_core_rsc_common { struct mlx5_core_rsc_common {
......
...@@ -473,6 +473,11 @@ struct mlx5_core_qp { ...@@ -473,6 +473,11 @@ struct mlx5_core_qp {
int pid; int pid;
}; };
struct mlx5_core_dct {
struct mlx5_core_qp mqp;
struct completion drained;
};
struct mlx5_qp_path { struct mlx5_qp_path {
u8 fl_free_ar; u8 fl_free_ar;
u8 rsvd3; u8 rsvd3;
...@@ -549,6 +554,9 @@ static inline struct mlx5_core_mkey *__mlx5_mr_lookup(struct mlx5_core_dev *dev, ...@@ -549,6 +554,9 @@ static inline struct mlx5_core_mkey *__mlx5_mr_lookup(struct mlx5_core_dev *dev,
return radix_tree_lookup(&dev->priv.mkey_table.tree, key); return radix_tree_lookup(&dev->priv.mkey_table.tree, key);
} }
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
struct mlx5_core_dct *qp,
u32 *in, int inlen);
int mlx5_core_create_qp(struct mlx5_core_dev *dev, int mlx5_core_create_qp(struct mlx5_core_dev *dev,
struct mlx5_core_qp *qp, struct mlx5_core_qp *qp,
u32 *in, u32 *in,
...@@ -558,8 +566,12 @@ int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 opcode, ...@@ -558,8 +566,12 @@ int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 opcode,
struct mlx5_core_qp *qp); struct mlx5_core_qp *qp);
int mlx5_core_destroy_qp(struct mlx5_core_dev *dev, int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
struct mlx5_core_qp *qp); struct mlx5_core_qp *qp);
int mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
struct mlx5_core_dct *dct);
int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp, int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
u32 *out, int outlen); u32 *out, int outlen);
int mlx5_core_dct_query(struct mlx5_core_dev *dev, struct mlx5_core_dct *dct,
u32 *out, int outlen);
int mlx5_core_set_delay_drop(struct mlx5_core_dev *dev, int mlx5_core_set_delay_drop(struct mlx5_core_dev *dev,
u32 timeout_usec); u32 timeout_usec);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment