mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 13:06:59 +02:00
RDMA/erdma: Add erdma_modify_qp_rocev2() interface
The QP state machines in the RoCEv2 and iWARP protocols are different. To handle these differences for the erdma RoCEv2 device, we provide the erdma_modify_qp_rocev2() interface, which transitions the QP state and modifies QP attributes accordingly. Signed-off-by: Boshi Yu <boshiyu@linux.alibaba.com> Link: https://patch.msgid.link/20241211020930.68833-6-boshiyu@linux.alibaba.com Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com> Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
parent
41dcaf48ff
commit
9566cf6a77
|
|
@ -201,3 +201,48 @@ int erdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
|
|||
|
||||
return npolled;
|
||||
}
|
||||
|
||||
void erdma_remove_cqes_of_qp(struct ib_cq *ibcq, u32 qpn)
|
||||
{
|
||||
struct erdma_cq *cq = to_ecq(ibcq);
|
||||
struct erdma_cqe *cqe, *dst_cqe;
|
||||
u32 prev_cq_ci, cur_cq_ci;
|
||||
u32 ncqe = 0, nqp_cqe = 0;
|
||||
unsigned long flags;
|
||||
u8 owner;
|
||||
|
||||
spin_lock_irqsave(&cq->kern_cq.lock, flags);
|
||||
|
||||
prev_cq_ci = cq->kern_cq.ci;
|
||||
|
||||
while (ncqe < cq->depth && (cqe = get_next_valid_cqe(cq)) != NULL) {
|
||||
++cq->kern_cq.ci;
|
||||
++ncqe;
|
||||
}
|
||||
|
||||
while (ncqe > 0) {
|
||||
cur_cq_ci = prev_cq_ci + ncqe - 1;
|
||||
cqe = get_queue_entry(cq->kern_cq.qbuf, cur_cq_ci, cq->depth,
|
||||
CQE_SHIFT);
|
||||
|
||||
if (be32_to_cpu(cqe->qpn) == qpn) {
|
||||
++nqp_cqe;
|
||||
} else if (nqp_cqe) {
|
||||
dst_cqe = get_queue_entry(cq->kern_cq.qbuf,
|
||||
cur_cq_ci + nqp_cqe,
|
||||
cq->depth, CQE_SHIFT);
|
||||
owner = FIELD_GET(ERDMA_CQE_HDR_OWNER_MASK,
|
||||
be32_to_cpu(dst_cqe->hdr));
|
||||
cqe->hdr = cpu_to_be32(
|
||||
(be32_to_cpu(cqe->hdr) &
|
||||
~ERDMA_CQE_HDR_OWNER_MASK) |
|
||||
FIELD_PREP(ERDMA_CQE_HDR_OWNER_MASK, owner));
|
||||
memcpy(dst_cqe, cqe, sizeof(*cqe));
|
||||
}
|
||||
|
||||
--ncqe;
|
||||
}
|
||||
|
||||
cq->kern_cq.ci = prev_cq_ci + nqp_cqe;
|
||||
spin_unlock_irqrestore(&cq->kern_cq.lock, flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,6 +347,20 @@ struct erdma_cmdq_modify_qp_req {
|
|||
u32 recv_nxt;
|
||||
};
|
||||
|
||||
/* modify qp cfg1 for roce device */
|
||||
#define ERDMA_CMD_MODIFY_QP_DQPN_MASK GENMASK(19, 0)
|
||||
|
||||
struct erdma_cmdq_mod_qp_req_rocev2 {
|
||||
u64 hdr;
|
||||
u32 cfg0;
|
||||
u32 cfg1;
|
||||
u32 attr_mask;
|
||||
u32 qkey;
|
||||
u32 rq_psn;
|
||||
u32 sq_psn;
|
||||
struct erdma_av_cfg av_cfg;
|
||||
};
|
||||
|
||||
/* create qp cfg0 */
|
||||
#define ERDMA_CMD_CREATE_QP_SQ_DEPTH_MASK GENMASK(31, 20)
|
||||
#define ERDMA_CMD_CREATE_QP_QPN_MASK GENMASK(19, 0)
|
||||
|
|
|
|||
|
|
@ -486,6 +486,7 @@ static const struct ib_device_ops erdma_device_ops_rocev2 = {
|
|||
.query_pkey = erdma_query_pkey,
|
||||
.create_ah = erdma_create_ah,
|
||||
.destroy_ah = erdma_destroy_ah,
|
||||
.modify_qp = erdma_modify_qp_rocev2,
|
||||
};
|
||||
|
||||
static const struct ib_device_ops erdma_device_ops_iwarp = {
|
||||
|
|
@ -497,6 +498,7 @@ static const struct ib_device_ops erdma_device_ops_iwarp = {
|
|||
.iw_get_qp = erdma_get_ibqp,
|
||||
.iw_reject = erdma_reject,
|
||||
.iw_rem_ref = erdma_qp_put_ref,
|
||||
.modify_qp = erdma_modify_qp,
|
||||
};
|
||||
|
||||
static const struct ib_device_ops erdma_device_ops = {
|
||||
|
|
@ -522,7 +524,6 @@ static const struct ib_device_ops erdma_device_ops = {
|
|||
.map_mr_sg = erdma_map_mr_sg,
|
||||
.mmap = erdma_mmap,
|
||||
.mmap_free = erdma_mmap_free,
|
||||
.modify_qp = erdma_modify_qp,
|
||||
.post_recv = erdma_post_recv,
|
||||
.post_send = erdma_post_send,
|
||||
.poll_cq = erdma_poll_cq,
|
||||
|
|
|
|||
|
|
@ -186,6 +186,98 @@ int erdma_modify_qp_internal(struct erdma_qp *qp, struct erdma_qp_attrs *attrs,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int modify_qp_cmd_rocev2(struct erdma_qp *qp,
|
||||
struct erdma_mod_qp_params_rocev2 *params,
|
||||
enum erdma_qpa_mask_rocev2 attr_mask)
|
||||
{
|
||||
struct erdma_cmdq_mod_qp_req_rocev2 req;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
erdma_cmdq_build_reqhdr(&req.hdr, CMDQ_SUBMOD_RDMA,
|
||||
CMDQ_OPCODE_MODIFY_QP);
|
||||
|
||||
req.cfg0 = FIELD_PREP(ERDMA_CMD_MODIFY_QP_QPN_MASK, QP_ID(qp));
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_STATE)
|
||||
req.cfg0 |= FIELD_PREP(ERDMA_CMD_MODIFY_QP_STATE_MASK,
|
||||
params->state);
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_DST_QPN)
|
||||
req.cfg1 = FIELD_PREP(ERDMA_CMD_MODIFY_QP_DQPN_MASK,
|
||||
params->dst_qpn);
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_QKEY)
|
||||
req.qkey = params->qkey;
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_AV)
|
||||
erdma_set_av_cfg(&req.av_cfg, ¶ms->av);
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_SQ_PSN)
|
||||
req.sq_psn = params->sq_psn;
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_RQ_PSN)
|
||||
req.rq_psn = params->rq_psn;
|
||||
|
||||
req.attr_mask = attr_mask;
|
||||
|
||||
return erdma_post_cmd_wait(&qp->dev->cmdq, &req, sizeof(req), NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void erdma_reset_qp(struct erdma_qp *qp)
|
||||
{
|
||||
qp->kern_qp.sq_pi = 0;
|
||||
qp->kern_qp.sq_ci = 0;
|
||||
qp->kern_qp.rq_pi = 0;
|
||||
qp->kern_qp.rq_ci = 0;
|
||||
memset(qp->kern_qp.swr_tbl, 0, qp->attrs.sq_size * sizeof(u64));
|
||||
memset(qp->kern_qp.rwr_tbl, 0, qp->attrs.rq_size * sizeof(u64));
|
||||
memset(qp->kern_qp.sq_buf, 0, qp->attrs.sq_size << SQEBB_SHIFT);
|
||||
memset(qp->kern_qp.rq_buf, 0, qp->attrs.rq_size << RQE_SHIFT);
|
||||
erdma_remove_cqes_of_qp(&qp->scq->ibcq, QP_ID(qp));
|
||||
if (qp->rcq != qp->scq)
|
||||
erdma_remove_cqes_of_qp(&qp->rcq->ibcq, QP_ID(qp));
|
||||
}
|
||||
|
||||
int erdma_modify_qp_state_rocev2(struct erdma_qp *qp,
|
||||
struct erdma_mod_qp_params_rocev2 *params,
|
||||
int attr_mask)
|
||||
{
|
||||
struct erdma_dev *dev = to_edev(qp->ibqp.device);
|
||||
int ret;
|
||||
|
||||
ret = modify_qp_cmd_rocev2(qp, params, attr_mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_STATE)
|
||||
qp->attrs.rocev2.state = params->state;
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_QKEY)
|
||||
qp->attrs.rocev2.qkey = params->qkey;
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_DST_QPN)
|
||||
qp->attrs.rocev2.dst_qpn = params->dst_qpn;
|
||||
|
||||
if (attr_mask & ERDMA_QPA_ROCEV2_AV)
|
||||
memcpy(&qp->attrs.rocev2.av, ¶ms->av,
|
||||
sizeof(struct erdma_av));
|
||||
|
||||
if (rdma_is_kernel_res(&qp->ibqp.res) &&
|
||||
params->state == ERDMA_QPS_ROCEV2_RESET)
|
||||
erdma_reset_qp(qp);
|
||||
|
||||
if (rdma_is_kernel_res(&qp->ibqp.res) &&
|
||||
params->state == ERDMA_QPS_ROCEV2_ERROR) {
|
||||
qp->flags |= ERDMA_QP_IN_FLUSHING;
|
||||
mod_delayed_work(dev->reflush_wq, &qp->reflush_dwork,
|
||||
usecs_to_jiffies(100));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void erdma_qp_safe_free(struct kref *ref)
|
||||
{
|
||||
struct erdma_qp *qp = container_of(ref, struct erdma_qp, ref);
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ static int create_qp_cmd(struct erdma_ucontext *uctx, struct erdma_qp *qp)
|
|||
|
||||
err = erdma_post_cmd_wait(&dev->cmdq, &req, sizeof(req), &resp0,
|
||||
&resp1);
|
||||
if (!err)
|
||||
if (!err && erdma_device_iwarp(dev))
|
||||
qp->attrs.cookie =
|
||||
FIELD_GET(ERDMA_CMDQ_CREATE_QP_RESP_COOKIE_MASK, resp0);
|
||||
|
||||
|
|
@ -1017,7 +1017,12 @@ int erdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
|
||||
qp->attrs.max_send_sge = attrs->cap.max_send_sge;
|
||||
qp->attrs.max_recv_sge = attrs->cap.max_recv_sge;
|
||||
qp->attrs.state = ERDMA_QP_STATE_IDLE;
|
||||
|
||||
if (erdma_device_iwarp(qp->dev))
|
||||
qp->attrs.state = ERDMA_QP_STATE_IDLE;
|
||||
else
|
||||
qp->attrs.rocev2.state = ERDMA_QPS_ROCEV2_RESET;
|
||||
|
||||
INIT_DELAYED_WORK(&qp->reflush_dwork, erdma_flush_worker);
|
||||
|
||||
ret = create_qp_cmd(uctx, qp);
|
||||
|
|
@ -1291,13 +1296,20 @@ int erdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
|||
struct erdma_dev *dev = to_edev(ibqp->device);
|
||||
struct erdma_ucontext *ctx = rdma_udata_to_drv_context(
|
||||
udata, struct erdma_ucontext, ibucontext);
|
||||
struct erdma_mod_qp_params_rocev2 rocev2_params;
|
||||
struct erdma_qp_attrs qp_attrs;
|
||||
int err;
|
||||
struct erdma_cmdq_destroy_qp_req req;
|
||||
|
||||
down_write(&qp->state_lock);
|
||||
qp_attrs.state = ERDMA_QP_STATE_ERROR;
|
||||
erdma_modify_qp_internal(qp, &qp_attrs, ERDMA_QP_ATTR_STATE);
|
||||
if (erdma_device_iwarp(dev)) {
|
||||
qp_attrs.state = ERDMA_QP_STATE_ERROR;
|
||||
erdma_modify_qp_internal(qp, &qp_attrs, ERDMA_QP_ATTR_STATE);
|
||||
} else {
|
||||
rocev2_params.state = ERDMA_QPS_ROCEV2_ERROR;
|
||||
erdma_modify_qp_state_rocev2(qp, &rocev2_params,
|
||||
ERDMA_QPA_ROCEV2_STATE);
|
||||
}
|
||||
up_write(&qp->state_lock);
|
||||
|
||||
cancel_delayed_work_sync(&qp->reflush_dwork);
|
||||
|
|
@ -1528,6 +1540,29 @@ void erdma_dealloc_ucontext(struct ib_ucontext *ibctx)
|
|||
atomic_dec(&dev->num_ctx);
|
||||
}
|
||||
|
||||
static void erdma_attr_to_av(const struct rdma_ah_attr *ah_attr,
|
||||
struct erdma_av *av, u16 sport)
|
||||
{
|
||||
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
|
||||
|
||||
av->port = rdma_ah_get_port_num(ah_attr);
|
||||
av->sgid_index = grh->sgid_index;
|
||||
av->hop_limit = grh->hop_limit;
|
||||
av->traffic_class = grh->traffic_class;
|
||||
av->sl = rdma_ah_get_sl(ah_attr);
|
||||
|
||||
av->flow_label = grh->flow_label;
|
||||
av->udp_sport = sport;
|
||||
|
||||
ether_addr_copy(av->dmac, ah_attr->roce.dmac);
|
||||
memcpy(av->dgid, grh->dgid.raw, ERDMA_ROCEV2_GID_SIZE);
|
||||
|
||||
if (ipv6_addr_v4mapped((struct in6_addr *)&grh->dgid))
|
||||
av->ntype = ERDMA_NETWORK_TYPE_IPV4;
|
||||
else
|
||||
av->ntype = ERDMA_NETWORK_TYPE_IPV6;
|
||||
}
|
||||
|
||||
static int ib_qp_state_to_erdma_qp_state[IB_QPS_ERR + 1] = {
|
||||
[IB_QPS_RESET] = ERDMA_QP_STATE_IDLE,
|
||||
[IB_QPS_INIT] = ERDMA_QP_STATE_IDLE,
|
||||
|
|
@ -1538,6 +1573,140 @@ static int ib_qp_state_to_erdma_qp_state[IB_QPS_ERR + 1] = {
|
|||
[IB_QPS_ERR] = ERDMA_QP_STATE_ERROR
|
||||
};
|
||||
|
||||
static int ib_qps_to_erdma_qps_rocev2[IB_QPS_ERR + 1] = {
|
||||
[IB_QPS_RESET] = ERDMA_QPS_ROCEV2_RESET,
|
||||
[IB_QPS_INIT] = ERDMA_QPS_ROCEV2_INIT,
|
||||
[IB_QPS_RTR] = ERDMA_QPS_ROCEV2_RTR,
|
||||
[IB_QPS_RTS] = ERDMA_QPS_ROCEV2_RTS,
|
||||
[IB_QPS_SQD] = ERDMA_QPS_ROCEV2_SQD,
|
||||
[IB_QPS_SQE] = ERDMA_QPS_ROCEV2_SQE,
|
||||
[IB_QPS_ERR] = ERDMA_QPS_ROCEV2_ERROR,
|
||||
};
|
||||
|
||||
static int erdma_qps_to_ib_qps_rocev2[ERDMA_QPS_ROCEV2_COUNT] = {
|
||||
[ERDMA_QPS_ROCEV2_RESET] = IB_QPS_RESET,
|
||||
[ERDMA_QPS_ROCEV2_INIT] = IB_QPS_INIT,
|
||||
[ERDMA_QPS_ROCEV2_RTR] = IB_QPS_RTR,
|
||||
[ERDMA_QPS_ROCEV2_RTS] = IB_QPS_RTS,
|
||||
[ERDMA_QPS_ROCEV2_SQD] = IB_QPS_SQD,
|
||||
[ERDMA_QPS_ROCEV2_SQE] = IB_QPS_SQE,
|
||||
[ERDMA_QPS_ROCEV2_ERROR] = IB_QPS_ERR,
|
||||
};
|
||||
|
||||
static int erdma_check_qp_attr_rocev2(struct erdma_qp *qp,
|
||||
struct ib_qp_attr *attr, int attr_mask)
|
||||
{
|
||||
enum ib_qp_state cur_state, nxt_state;
|
||||
struct erdma_dev *dev = qp->dev;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (attr_mask & ~IB_QP_ATTR_STANDARD_BITS) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((attr_mask & IB_QP_PKEY_INDEX) &&
|
||||
attr->pkey_index >= ERDMA_MAX_PKEYS)
|
||||
goto out;
|
||||
|
||||
if ((attr_mask & IB_QP_PORT) &&
|
||||
!rdma_is_port_valid(&dev->ibdev, attr->port_num))
|
||||
goto out;
|
||||
|
||||
cur_state = (attr_mask & IB_QP_CUR_STATE) ?
|
||||
attr->cur_qp_state :
|
||||
erdma_qps_to_ib_qps_rocev2[qp->attrs.rocev2.state];
|
||||
|
||||
nxt_state = (attr_mask & IB_QP_STATE) ? attr->qp_state : cur_state;
|
||||
|
||||
if (!ib_modify_qp_is_ok(cur_state, nxt_state, qp->ibqp.qp_type,
|
||||
attr_mask))
|
||||
goto out;
|
||||
|
||||
if ((attr_mask & IB_QP_AV) &&
|
||||
erdma_check_gid_attr(rdma_ah_read_grh(&attr->ah_attr)->sgid_attr))
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void erdma_init_mod_qp_params_rocev2(
|
||||
struct erdma_qp *qp, struct erdma_mod_qp_params_rocev2 *params,
|
||||
int *erdma_attr_mask, struct ib_qp_attr *attr, int ib_attr_mask)
|
||||
{
|
||||
enum erdma_qpa_mask_rocev2 to_modify_attrs = 0;
|
||||
enum erdma_qps_rocev2 cur_state, nxt_state;
|
||||
u16 udp_sport;
|
||||
|
||||
if (ib_attr_mask & IB_QP_CUR_STATE)
|
||||
cur_state = ib_qps_to_erdma_qps_rocev2[attr->cur_qp_state];
|
||||
else
|
||||
cur_state = qp->attrs.rocev2.state;
|
||||
|
||||
if (ib_attr_mask & IB_QP_STATE)
|
||||
nxt_state = ib_qps_to_erdma_qps_rocev2[attr->qp_state];
|
||||
else
|
||||
nxt_state = cur_state;
|
||||
|
||||
to_modify_attrs |= ERDMA_QPA_ROCEV2_STATE;
|
||||
params->state = nxt_state;
|
||||
|
||||
if (ib_attr_mask & IB_QP_QKEY) {
|
||||
to_modify_attrs |= ERDMA_QPA_ROCEV2_QKEY;
|
||||
params->qkey = attr->qkey;
|
||||
}
|
||||
|
||||
if (ib_attr_mask & IB_QP_SQ_PSN) {
|
||||
to_modify_attrs |= ERDMA_QPA_ROCEV2_SQ_PSN;
|
||||
params->sq_psn = attr->sq_psn;
|
||||
}
|
||||
|
||||
if (ib_attr_mask & IB_QP_RQ_PSN) {
|
||||
to_modify_attrs |= ERDMA_QPA_ROCEV2_RQ_PSN;
|
||||
params->rq_psn = attr->rq_psn;
|
||||
}
|
||||
|
||||
if (ib_attr_mask & IB_QP_DEST_QPN) {
|
||||
to_modify_attrs |= ERDMA_QPA_ROCEV2_DST_QPN;
|
||||
params->dst_qpn = attr->dest_qp_num;
|
||||
}
|
||||
|
||||
if (ib_attr_mask & IB_QP_AV) {
|
||||
to_modify_attrs |= ERDMA_QPA_ROCEV2_AV;
|
||||
udp_sport = rdma_get_udp_sport(attr->ah_attr.grh.flow_label,
|
||||
QP_ID(qp), params->dst_qpn);
|
||||
erdma_attr_to_av(&attr->ah_attr, ¶ms->av, udp_sport);
|
||||
}
|
||||
|
||||
*erdma_attr_mask = to_modify_attrs;
|
||||
}
|
||||
|
||||
int erdma_modify_qp_rocev2(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
int attr_mask, struct ib_udata *udata)
|
||||
{
|
||||
struct erdma_mod_qp_params_rocev2 params;
|
||||
struct erdma_qp *qp = to_eqp(ibqp);
|
||||
int ret = 0, erdma_attr_mask = 0;
|
||||
|
||||
down_write(&qp->state_lock);
|
||||
|
||||
ret = erdma_check_qp_attr_rocev2(qp, attr, attr_mask);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
erdma_init_mod_qp_params_rocev2(qp, ¶ms, &erdma_attr_mask, attr,
|
||||
attr_mask);
|
||||
|
||||
ret = erdma_modify_qp_state_rocev2(qp, ¶ms, erdma_attr_mask);
|
||||
|
||||
out:
|
||||
up_write(&qp->state_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int erdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
|
|
@ -1920,6 +2089,22 @@ int erdma_query_pkey(struct ib_device *ibdev, u32 port, u16 index, u16 *pkey)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void erdma_set_av_cfg(struct erdma_av_cfg *av_cfg, struct erdma_av *av)
|
||||
{
|
||||
av_cfg->cfg0 = FIELD_PREP(ERDMA_CMD_CREATE_AV_FL_MASK, av->flow_label) |
|
||||
FIELD_PREP(ERDMA_CMD_CREATE_AV_NTYPE_MASK, av->ntype);
|
||||
|
||||
av_cfg->traffic_class = av->traffic_class;
|
||||
av_cfg->hop_limit = av->hop_limit;
|
||||
av_cfg->sl = av->sl;
|
||||
|
||||
av_cfg->udp_sport = av->udp_sport;
|
||||
av_cfg->sgid_index = av->sgid_index;
|
||||
|
||||
ether_addr_copy(av_cfg->dmac, av->dmac);
|
||||
memcpy(av_cfg->dgid, av->dgid, ERDMA_ROCEV2_GID_SIZE);
|
||||
}
|
||||
|
||||
int erdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
|
|
@ -1948,38 +2133,14 @@ int erdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
|
|||
udp_sport =
|
||||
IB_ROCE_UDP_ENCAP_VALID_PORT_MIN + (ah->ahn & 0x3FFF);
|
||||
|
||||
ah->av.port = rdma_ah_get_port_num(init_attr->ah_attr);
|
||||
ah->av.sgid_index = grh->sgid_index;
|
||||
ah->av.hop_limit = grh->hop_limit;
|
||||
ah->av.traffic_class = grh->traffic_class;
|
||||
ah->av.sl = rdma_ah_get_sl(init_attr->ah_attr);
|
||||
ah->av.flow_label = grh->flow_label;
|
||||
ah->av.udp_sport = udp_sport;
|
||||
|
||||
ether_addr_copy(ah->av.dmac, init_attr->ah_attr->roce.dmac);
|
||||
memcpy(ah->av.dgid, grh->dgid.raw, ERDMA_ROCEV2_GID_SIZE);
|
||||
|
||||
if (ipv6_addr_v4mapped((struct in6_addr *)&grh->dgid))
|
||||
ah->av.ntype = ERDMA_NETWORK_TYPE_IPV4;
|
||||
else
|
||||
ah->av.ntype = ERDMA_NETWORK_TYPE_IPV6;
|
||||
erdma_attr_to_av(init_attr->ah_attr, &ah->av, udp_sport);
|
||||
|
||||
erdma_cmdq_build_reqhdr(&req.hdr, CMDQ_SUBMOD_RDMA,
|
||||
CMDQ_OPCODE_CREATE_AH);
|
||||
|
||||
req.pdn = pd->pdn;
|
||||
req.ahn = ah->ahn;
|
||||
|
||||
req.av_cfg.cfg0 =
|
||||
FIELD_PREP(ERDMA_CMD_CREATE_AV_FL_MASK, ah->av.flow_label) |
|
||||
FIELD_PREP(ERDMA_CMD_CREATE_AV_NTYPE_MASK, ah->av.ntype);
|
||||
req.av_cfg.traffic_class = ah->av.traffic_class;
|
||||
req.av_cfg.hop_limit = ah->av.hop_limit;
|
||||
req.av_cfg.sl = ah->av.sl;
|
||||
req.av_cfg.udp_sport = ah->av.udp_sport;
|
||||
req.av_cfg.sgid_index = ah->av.sgid_index;
|
||||
ether_addr_copy(req.av_cfg.dmac, ah->av.dmac);
|
||||
memcpy(req.av_cfg.dgid, ah->av.dgid, ERDMA_ROCEV2_GID_SIZE);
|
||||
erdma_set_av_cfg(&req.av_cfg, &ah->av);
|
||||
|
||||
ret = erdma_post_cmd_wait(&dev->cmdq, &req, sizeof(req), NULL, NULL);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -216,10 +216,46 @@ enum erdma_qp_attr_mask {
|
|||
ERDMA_QP_ATTR_MPA = (1 << 7)
|
||||
};
|
||||
|
||||
enum erdma_qps_rocev2 {
|
||||
ERDMA_QPS_ROCEV2_RESET = 0,
|
||||
ERDMA_QPS_ROCEV2_INIT = 1,
|
||||
ERDMA_QPS_ROCEV2_RTR = 2,
|
||||
ERDMA_QPS_ROCEV2_RTS = 3,
|
||||
ERDMA_QPS_ROCEV2_SQD = 4,
|
||||
ERDMA_QPS_ROCEV2_SQE = 5,
|
||||
ERDMA_QPS_ROCEV2_ERROR = 6,
|
||||
ERDMA_QPS_ROCEV2_COUNT = 7,
|
||||
};
|
||||
|
||||
enum erdma_qpa_mask_rocev2 {
|
||||
ERDMA_QPA_ROCEV2_STATE = (1 << 0),
|
||||
ERDMA_QPA_ROCEV2_QKEY = (1 << 1),
|
||||
ERDMA_QPA_ROCEV2_AV = (1 << 2),
|
||||
ERDMA_QPA_ROCEV2_SQ_PSN = (1 << 3),
|
||||
ERDMA_QPA_ROCEV2_RQ_PSN = (1 << 4),
|
||||
ERDMA_QPA_ROCEV2_DST_QPN = (1 << 5),
|
||||
};
|
||||
|
||||
enum erdma_qp_flags {
|
||||
ERDMA_QP_IN_FLUSHING = (1 << 0),
|
||||
};
|
||||
|
||||
struct erdma_mod_qp_params_rocev2 {
|
||||
enum erdma_qps_rocev2 state;
|
||||
u32 qkey;
|
||||
u32 sq_psn;
|
||||
u32 rq_psn;
|
||||
u32 dst_qpn;
|
||||
struct erdma_av av;
|
||||
};
|
||||
|
||||
struct erdma_qp_attrs_rocev2 {
|
||||
enum erdma_qps_rocev2 state;
|
||||
u32 qkey;
|
||||
u32 dst_qpn;
|
||||
struct erdma_av av;
|
||||
};
|
||||
|
||||
struct erdma_qp_attrs {
|
||||
enum erdma_qp_state state;
|
||||
enum erdma_cc_alg cc; /* Congestion control algorithm */
|
||||
|
|
@ -234,6 +270,7 @@ struct erdma_qp_attrs {
|
|||
#define ERDMA_QP_PASSIVE 1
|
||||
u8 qp_type;
|
||||
u8 pd_len;
|
||||
struct erdma_qp_attrs_rocev2 rocev2;
|
||||
};
|
||||
|
||||
struct erdma_qp {
|
||||
|
|
@ -307,6 +344,9 @@ void erdma_qp_get(struct erdma_qp *qp);
|
|||
void erdma_qp_put(struct erdma_qp *qp);
|
||||
int erdma_modify_qp_internal(struct erdma_qp *qp, struct erdma_qp_attrs *attrs,
|
||||
enum erdma_qp_attr_mask mask);
|
||||
int erdma_modify_qp_state_rocev2(struct erdma_qp *qp,
|
||||
struct erdma_mod_qp_params_rocev2 *params,
|
||||
int attr_mask);
|
||||
void erdma_qp_llp_close(struct erdma_qp *qp);
|
||||
void erdma_qp_cm_drop(struct erdma_qp *qp);
|
||||
|
||||
|
|
@ -386,6 +426,8 @@ int erdma_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int mask,
|
|||
struct ib_qp_init_attr *init_attr);
|
||||
int erdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int mask,
|
||||
struct ib_udata *data);
|
||||
int erdma_modify_qp_rocev2(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
int mask, struct ib_udata *udata);
|
||||
int erdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
|
||||
int erdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
void erdma_disassociate_ucontext(struct ib_ucontext *ibcontext);
|
||||
|
|
@ -404,6 +446,7 @@ int erdma_post_send(struct ib_qp *ibqp, const struct ib_send_wr *send_wr,
|
|||
int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,
|
||||
const struct ib_recv_wr **bad_recv_wr);
|
||||
int erdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
|
||||
void erdma_remove_cqes_of_qp(struct ib_cq *ibcq, u32 qpn);
|
||||
struct ib_mr *erdma_ib_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
|
||||
u32 max_num_sg);
|
||||
int erdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
|
||||
|
|
@ -419,6 +462,7 @@ enum rdma_link_layer erdma_get_link_layer(struct ib_device *ibdev,
|
|||
int erdma_add_gid(const struct ib_gid_attr *attr, void **context);
|
||||
int erdma_del_gid(const struct ib_gid_attr *attr, void **context);
|
||||
int erdma_query_pkey(struct ib_device *ibdev, u32 port, u16 index, u16 *pkey);
|
||||
void erdma_set_av_cfg(struct erdma_av_cfg *av_cfg, struct erdma_av *av);
|
||||
int erdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
|
||||
struct ib_udata *udata);
|
||||
int erdma_destroy_ah(struct ib_ah *ibah, u32 flags);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user