[hermon] Allow for multiple calls to ib_modify_qp()
This commit is contained in:
parent
7a3a159af5
commit
18bcdfb1cc
|
@ -1033,6 +1033,7 @@ static int hermon_create_qp ( struct ib_device *ibdev,
|
||||||
hermon, strerror ( rc ) );
|
hermon, strerror ( rc ) );
|
||||||
goto err_rst2init_qp;
|
goto err_rst2init_qp;
|
||||||
}
|
}
|
||||||
|
hermon_qp->state = HERMON_QP_ST_INIT;
|
||||||
|
|
||||||
DBGC ( hermon, "Hermon %p QPN %#lx send ring at [%p,%p)\n",
|
DBGC ( hermon, "Hermon %p QPN %#lx send ring at [%p,%p)\n",
|
||||||
hermon, qp->qpn, hermon_qp->send.wqe,
|
hermon, qp->qpn, hermon_qp->send.wqe,
|
||||||
|
@ -1066,44 +1067,66 @@ static int hermon_create_qp ( struct ib_device *ibdev,
|
||||||
static int hermon_modify_qp ( struct ib_device *ibdev,
|
static int hermon_modify_qp ( struct ib_device *ibdev,
|
||||||
struct ib_queue_pair *qp ) {
|
struct ib_queue_pair *qp ) {
|
||||||
struct hermon *hermon = ib_get_drvdata ( ibdev );
|
struct hermon *hermon = ib_get_drvdata ( ibdev );
|
||||||
|
struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
|
||||||
struct hermonprm_qp_ee_state_transitions qpctx;
|
struct hermonprm_qp_ee_state_transitions qpctx;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Transition queue to RTR state */
|
/* Transition queue to RTR state, if applicable */
|
||||||
memset ( &qpctx, 0, sizeof ( qpctx ) );
|
if ( hermon_qp->state < HERMON_QP_ST_RTR ) {
|
||||||
MLX_FILL_1 ( &qpctx, 0, opt_param_mask, HERMON_QP_OPT_PARAM_QKEY );
|
memset ( &qpctx, 0, sizeof ( qpctx ) );
|
||||||
MLX_FILL_2 ( &qpctx, 4,
|
MLX_FILL_2 ( &qpctx, 4,
|
||||||
qpc_eec_data.mtu, HERMON_MTU_2048,
|
qpc_eec_data.mtu, HERMON_MTU_2048,
|
||||||
qpc_eec_data.msg_max, 31 );// 11 /* 2^11 = 2048 */ );
|
qpc_eec_data.msg_max, 31 );
|
||||||
MLX_FILL_1 ( &qpctx, 7, qpc_eec_data.remote_qpn_een, qp->av.qpn );
|
MLX_FILL_1 ( &qpctx, 7,
|
||||||
MLX_FILL_1 ( &qpctx, 9,
|
qpc_eec_data.remote_qpn_een, qp->av.qpn );
|
||||||
qpc_eec_data.primary_address_path.rlid, qp->av.lid );
|
MLX_FILL_1 ( &qpctx, 9,
|
||||||
MLX_FILL_1 ( &qpctx, 10,
|
qpc_eec_data.primary_address_path.rlid,
|
||||||
qpc_eec_data.primary_address_path.max_stat_rate,
|
qp->av.lid );
|
||||||
hermon_rate ( &qp->av ) );
|
MLX_FILL_1 ( &qpctx, 10,
|
||||||
memcpy ( &qpctx.u.dwords[12], &qp->av.gid, sizeof ( qp->av.gid ) );
|
qpc_eec_data.primary_address_path.max_stat_rate,
|
||||||
MLX_FILL_1 ( &qpctx, 16,
|
hermon_rate ( &qp->av ) );
|
||||||
qpc_eec_data.primary_address_path.sched_queue,
|
memcpy ( &qpctx.u.dwords[12], &qp->av.gid,
|
||||||
hermon_sched_queue ( ibdev, qp ) );
|
sizeof ( qp->av.gid ) );
|
||||||
MLX_FILL_1 ( &qpctx, 39, qpc_eec_data.next_rcv_psn, qp->recv.psn );
|
MLX_FILL_1 ( &qpctx, 16,
|
||||||
MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
|
qpc_eec_data.primary_address_path.sched_queue,
|
||||||
if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
|
hermon_sched_queue ( ibdev, qp ) );
|
||||||
&qpctx ) ) != 0 ) {
|
MLX_FILL_1 ( &qpctx, 39,
|
||||||
DBGC ( hermon, "Hermon %p INIT2RTR_QP failed: %s\n",
|
qpc_eec_data.next_rcv_psn, qp->recv.psn );
|
||||||
hermon, strerror ( rc ) );
|
if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
|
||||||
return rc;
|
&qpctx ) ) != 0 ) {
|
||||||
|
DBGC ( hermon, "Hermon %p INIT2RTR_QP failed: %s\n",
|
||||||
|
hermon, strerror ( rc ) );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
hermon_qp->state = HERMON_QP_ST_RTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transition queue to RTS state */
|
/* Transition queue to RTS state */
|
||||||
|
if ( hermon_qp->state < HERMON_QP_ST_RTS ) {
|
||||||
|
memset ( &qpctx, 0, sizeof ( qpctx ) );
|
||||||
|
MLX_FILL_1 ( &qpctx, 10,
|
||||||
|
qpc_eec_data.primary_address_path.ack_timeout,
|
||||||
|
0x13 );
|
||||||
|
MLX_FILL_2 ( &qpctx, 30,
|
||||||
|
qpc_eec_data.retry_count, HERMON_RETRY_MAX,
|
||||||
|
qpc_eec_data.rnr_retry, HERMON_RETRY_MAX );
|
||||||
|
MLX_FILL_1 ( &qpctx, 32,
|
||||||
|
qpc_eec_data.next_send_psn, qp->send.psn );
|
||||||
|
if ( ( rc = hermon_cmd_rtr2rts_qp ( hermon, qp->qpn,
|
||||||
|
&qpctx ) ) != 0 ) {
|
||||||
|
DBGC ( hermon, "Hermon %p RTR2RTS_QP failed: %s\n",
|
||||||
|
hermon, strerror ( rc ) );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
hermon_qp->state = HERMON_QP_ST_RTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update parameters in RTS state */
|
||||||
memset ( &qpctx, 0, sizeof ( qpctx ) );
|
memset ( &qpctx, 0, sizeof ( qpctx ) );
|
||||||
MLX_FILL_1 ( &qpctx, 10,
|
MLX_FILL_1 ( &qpctx, 0, opt_param_mask, HERMON_QP_OPT_PARAM_QKEY );
|
||||||
qpc_eec_data.primary_address_path.ack_timeout, 0x13 );
|
MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
|
||||||
MLX_FILL_2 ( &qpctx, 30,
|
if ( ( rc = hermon_cmd_rts2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){
|
||||||
qpc_eec_data.retry_count, HERMON_RETRY_MAX,
|
DBGC ( hermon, "Hermon %p RTS2RTS_QP failed: %s\n",
|
||||||
qpc_eec_data.rnr_retry, HERMON_RETRY_MAX );
|
|
||||||
MLX_FILL_1 ( &qpctx, 32, qpc_eec_data.next_send_psn, qp->send.psn );
|
|
||||||
if ( ( rc = hermon_cmd_rtr2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){
|
|
||||||
DBGC ( hermon, "Hermon %p RTR2RTS_QP failed: %s\n",
|
|
||||||
hermon, strerror ( rc ) );
|
hermon, strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,6 +425,14 @@ struct hermon_recv_work_queue {
|
||||||
/** Base queue pair number */
|
/** Base queue pair number */
|
||||||
#define HERMON_QPN_BASE 0x550000
|
#define HERMON_QPN_BASE 0x550000
|
||||||
|
|
||||||
|
/** Hermon queue pair state */
|
||||||
|
enum hermon_queue_pair_state {
|
||||||
|
HERMON_QP_ST_RST = 0,
|
||||||
|
HERMON_QP_ST_INIT,
|
||||||
|
HERMON_QP_ST_RTR,
|
||||||
|
HERMON_QP_ST_RTS,
|
||||||
|
};
|
||||||
|
|
||||||
/** A Hermon queue pair */
|
/** A Hermon queue pair */
|
||||||
struct hermon_queue_pair {
|
struct hermon_queue_pair {
|
||||||
/** Work queue buffer */
|
/** Work queue buffer */
|
||||||
|
@ -437,6 +445,8 @@ struct hermon_queue_pair {
|
||||||
struct hermon_send_work_queue send;
|
struct hermon_send_work_queue send;
|
||||||
/** Receive work queue */
|
/** Receive work queue */
|
||||||
struct hermon_recv_work_queue recv;
|
struct hermon_recv_work_queue recv;
|
||||||
|
/** Queue state */
|
||||||
|
enum hermon_queue_pair_state state;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Maximum number of allocatable completion queues
|
/** Maximum number of allocatable completion queues
|
||||||
|
|
Reference in New Issue