opcode, opcode,
opcode_modifier, op_mod,
go, 1 );
- DBGC2_HD ( arbel, &hcr, sizeof ( hcr ) );
- if ( in_len ) {
- DBGC2 ( arbel, "Input:\n" );
- DBGC2_HD ( arbel, in, ( ( in_len < 512 ) ? in_len : 512 ) );
+ DBGC ( arbel, "Arbel %p issuing command %04x\n", arbel, opcode );
+ DBGC2_HDA ( arbel, virt_to_phys ( arbel->config + ARBEL_HCR_BASE ),
+ &hcr, sizeof ( hcr ) );
+ if ( in_len && ( command & ARBEL_HCR_IN_MBOX ) ) {
+ DBGC2 ( arbel, "Input mailbox:\n" );
+ DBGC2_HDA ( arbel, virt_to_phys ( in_buffer ), in_buffer,
+ ( ( in_len < 512 ) ? in_len : 512 ) );
}
/* Issue command */
hcr.u.dwords[4] = readl ( arbel->config + ARBEL_HCR_REG ( 4 ) );
memcpy ( out, out_buffer, out_len );
if ( out_len ) {
- DBGC2 ( arbel, "Output:\n" );
- DBGC2_HD ( arbel, out, ( ( out_len < 512 ) ? out_len : 512 ) );
+ DBGC2 ( arbel, "Output%s:\n",
+ ( command & ARBEL_HCR_OUT_MBOX ) ? " mailbox" : "" );
+ DBGC2_HDA ( arbel, virt_to_phys ( out_buffer ), out_buffer,
+ ( ( out_len < 512 ) ? out_len : 512 ) );
}
return 0;
0, NULL, cqn, cqctx );
}
+static inline int
+arbel_cmd_query_cq ( struct arbel *arbel, unsigned long cqn,
+ struct arbelprm_completion_queue_context *cqctx ) {
+ return arbel_cmd ( arbel,
+ ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_CQ,
+ 1, sizeof ( *cqctx ) ),
+ 0, NULL, cqn, cqctx );
+}
+
static inline int
arbel_cmd_rst2init_qpee ( struct arbel *arbel, unsigned long qpn,
const struct arbelprm_qp_ee_state_transitions *ctx ){
}
static inline int
-arbel_cmd_rts2rts_qp ( struct arbel *arbel, unsigned long qpn,
- const struct arbelprm_qp_ee_state_transitions *ctx ) {
+arbel_cmd_rts2rts_qpee ( struct arbel *arbel, unsigned long qpn,
+ const struct arbelprm_qp_ee_state_transitions *ctx ) {
return arbel_cmd ( arbel,
ARBEL_HCR_IN_CMD ( ARBEL_HCR_RTS2RTS_QPEE,
1, sizeof ( *ctx ) ),
0x03, NULL, qpn, NULL );
}
+static inline int
+arbel_cmd_query_qpee ( struct arbel *arbel, unsigned long qpn,
+ struct arbelprm_qp_ee_state_transitions *ctx ) {
+ return arbel_cmd ( arbel,
+ ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_QPEE,
+ 1, sizeof ( *ctx ) ),
+ 0, NULL, qpn, ctx );
+}
+
static inline int
arbel_cmd_conf_special_qp ( struct arbel *arbel, unsigned int qp_type,
unsigned long base_qpn ) {
/* Issue MAD */
if ( ( rc = arbel_cmd_mad_ifc ( arbel, ibdev->port,
&mad_ifc ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p could not issue MAD IFC: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p port %d could not issue MAD IFC: %s\n",
+ arbel, ibdev->port, strerror ( rc ) );
return rc;
}
memcpy ( mad, &mad_ifc.mad, sizeof ( *mad ) );
if ( mad->hdr.status != 0 ) {
- DBGC ( arbel, "Arbel %p MAD IFC status %04x\n",
- arbel, ntohs ( mad->hdr.status ) );
+ DBGC ( arbel, "Arbel %p port %d MAD IFC status %04x\n",
+ arbel, ibdev->port, ntohs ( mad->hdr.status ) );
return -EIO;
}
return 0;
***************************************************************************
*/
+/**
+ * Dump completion queue context (for debugging only)
+ *
+ * @v arbel Arbel device
+ * @v cq Completion queue
+ * @ret rc Return status code
+ */
+static __attribute__ (( unused )) int
+arbel_dump_cqctx ( struct arbel *arbel, struct ib_completion_queue *cq ) {
+ struct arbelprm_completion_queue_context cqctx;
+ int rc;
+
+ memset ( &cqctx, 0, sizeof ( cqctx ) );
+ if ( ( rc = arbel_cmd_query_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
+ DBGC ( arbel, "Arbel %p CQN %#lx QUERY_CQ failed: %s\n",
+ arbel, cq->cqn, strerror ( rc ) );
+ return rc;
+ }
+ DBGC ( arbel, "Arbel %p CQN %#lx context:\n", arbel, cq->cqn );
+ DBGC_HDA ( arbel, 0, &cqctx, sizeof ( cqctx ) );
+
+ return 0;
+}
+
/**
* Create completion queue
*
MLX_FILL_1 ( &cqctx, 14,
cq_state_db_record, arbel_cq->arm_doorbell_idx );
if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p CQN %#lx SW2HW_CQ failed: %s\n",
+ arbel, cq->cqn, strerror ( rc ) );
goto err_sw2hw_cq;
}
- DBGC ( arbel, "Arbel %p CQN %#lx ring at [%p,%p)\n",
- arbel, cq->cqn, arbel_cq->cqe,
- ( ( ( void * ) arbel_cq->cqe ) + arbel_cq->cqe_size ) );
+ DBGC ( arbel, "Arbel %p CQN %#lx ring [%08lx,%08lx), doorbell %08lx\n",
+ arbel, cq->cqn, virt_to_phys ( arbel_cq->cqe ),
+ ( virt_to_phys ( arbel_cq->cqe ) + arbel_cq->cqe_size ),
+ virt_to_phys ( ci_db_rec ) );
ib_cq_set_drvdata ( cq, arbel_cq );
return 0;
/* Take ownership back from hardware */
if ( ( rc = arbel_cmd_hw2sw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p FATAL HW2SW_CQ failed on CQN %#lx: "
+ DBGC ( arbel, "Arbel %p CQN %#lx FATAL HW2SW_CQ failed: "
"%s\n", arbel, cq->cqn, strerror ( rc ) );
/* Leak memory and return; at least we avoid corruption */
return;
arbel_bitmask_free ( arbel->qp_inuse, qpn_offset );
}
+/**
+ * Dump queue pair context (for debugging only)
+ *
+ * @v arbel Arbel device
+ * @v qp Queue pair
+ * @ret rc Return status code
+ */
+static __attribute__ (( unused )) int
+arbel_dump_qpctx ( struct arbel *arbel, struct ib_queue_pair *qp ) {
+ struct arbelprm_qp_ee_state_transitions qpctx;
+ int rc;
+
+ memset ( &qpctx, 0, sizeof ( qpctx ) );
+ if ( ( rc = arbel_cmd_query_qpee ( arbel, qp->qpn, &qpctx ) ) != 0 ) {
+ DBGC ( arbel, "Arbel %p QPN %#lx QUERY_QPEE failed: %s\n",
+ arbel, qp->qpn, strerror ( rc ) );
+ return rc;
+ }
+ DBGC ( arbel, "Arbel %p QPN %#lx context:\n", arbel, qp->qpn );
+ DBGC_HDA ( arbel, 0, &qpctx.u.dwords[2], ( sizeof ( qpctx ) - 8 ) );
+
+ return 0;
+}
+
/**
* Create send work queue
*
MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.rcv_db_record_index,
arbel_qp->recv.doorbell_idx );
if ( ( rc = arbel_cmd_rst2init_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
- DBGC ( arbel, "Arbel %p RST2INIT_QPEE failed: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p QPN %#lx RST2INIT_QPEE failed: %s\n",
+ arbel, qp->qpn, strerror ( rc ) );
goto err_rst2init_qpee;
}
memset ( &qpctx, 0, sizeof ( qpctx ) );
qpc_eec_data.mtu, ARBEL_MTU_2048,
qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
- DBGC ( arbel, "Arbel %p INIT2RTR_QPEE failed: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p QPN %#lx INIT2RTR_QPEE failed: %s\n",
+ arbel, qp->qpn, strerror ( rc ) );
goto err_init2rtr_qpee;
}
memset ( &qpctx, 0, sizeof ( qpctx ) );
if ( ( rc = arbel_cmd_rtr2rts_qpee ( arbel, qp->qpn, &qpctx ) ) != 0 ){
- DBGC ( arbel, "Arbel %p RTR2RTS_QPEE failed: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p QPN %#lx RTR2RTS_QPEE failed: %s\n",
+ arbel, qp->qpn, strerror ( rc ) );
goto err_rtr2rts_qpee;
}
- DBGC ( arbel, "Arbel %p QPN %#lx send ring at [%p,%p)\n",
- arbel, qp->qpn, arbel_qp->send.wqe,
- ( ( (void *) arbel_qp->send.wqe ) + arbel_qp->send.wqe_size ) );
- DBGC ( arbel, "Arbel %p QPN %#lx receive ring at [%p,%p)\n",
- arbel, qp->qpn, arbel_qp->recv.wqe,
- ( ( (void *) arbel_qp->recv.wqe ) + arbel_qp->recv.wqe_size ) );
+ DBGC ( arbel, "Arbel %p QPN %#lx send ring [%08lx,%08lx), doorbell "
+ "%08lx\n", arbel, qp->qpn, virt_to_phys ( arbel_qp->send.wqe ),
+ ( virt_to_phys ( arbel_qp->send.wqe ) +
+ arbel_qp->send.wqe_size ),
+ virt_to_phys ( send_db_rec ) );
+ DBGC ( arbel, "Arbel %p QPN %#lx receive ring [%08lx,%08lx), doorbell "
+ "%08lx\n", arbel, qp->qpn, virt_to_phys ( arbel_qp->recv.wqe ),
+ ( virt_to_phys ( arbel_qp->recv.wqe ) +
+ arbel_qp->recv.wqe_size ),
+ virt_to_phys ( recv_db_rec ) );
+ DBGC ( arbel, "Arbel %p QPN %#lx send CQN %#lx receive CQN %#lx\n",
+ arbel, qp->qpn, qp->send.cq->cqn, qp->recv.cq->cqn );
ib_qp_set_drvdata ( qp, arbel_qp );
return 0;
struct arbelprm_qp_ee_state_transitions qpctx;
int rc;
- /* Issue RTS2RTS_QP */
+ /* Issue RTS2RTS_QPEE */
memset ( &qpctx, 0, sizeof ( qpctx ) );
MLX_FILL_1 ( &qpctx, 0, opt_param_mask, ARBEL_QPEE_OPT_PARAM_QKEY );
MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
- if ( ( rc = arbel_cmd_rts2rts_qp ( arbel, qp->qpn, &qpctx ) ) != 0 ){
- DBGC ( arbel, "Arbel %p RTS2RTS_QP failed: %s\n",
- arbel, strerror ( rc ) );
+ if ( ( rc = arbel_cmd_rts2rts_qpee ( arbel, qp->qpn, &qpctx ) ) != 0 ){
+ DBGC ( arbel, "Arbel %p QPN %#lx RTS2RTS_QPEE failed: %s\n",
+ arbel, qp->qpn, strerror ( rc ) );
return rc;
}
/* Take ownership back from hardware */
if ( ( rc = arbel_cmd_2rst_qpee ( arbel, qp->qpn ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p FATAL 2RST_QPEE failed on QPN %#lx: "
+ DBGC ( arbel, "Arbel %p QPN %#lx FATAL 2RST_QPEE failed: "
"%s\n", arbel, qp->qpn, strerror ( rc ) );
/* Leak memory and return; at least we avoid corruption */
return;
union arbel_send_wqe *wqe;
struct arbelprm_qp_db_record *qp_db_rec;
union arbelprm_doorbell_register db_reg;
- unsigned int wqe_idx_mask;
+ unsigned long wqe_idx_mask;
size_t nds;
/* Allocate work queue entry */
wqe_idx_mask = ( wq->num_wqes - 1 );
if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
- DBGC ( arbel, "Arbel %p send queue full", arbel );
+ DBGC ( arbel, "Arbel %p QPN %#lx send queue full",
+ arbel, qp->qpn );
return -ENOBUFS;
}
wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
sizeof ( arbel_fill_send_wqe[0] ) ) );
assert ( arbel_fill_send_wqe[qp->type] != NULL );
nds = arbel_fill_send_wqe[qp->type] ( ibdev, qp, av, iobuf, wqe );
+ DBGCP ( arbel, "Arbel %p QPN %#lx posting send WQE %#lx:\n",
+ arbel, qp->qpn, ( wq->next_idx & wqe_idx_mask ) );
+ DBGCP_HDA ( arbel, virt_to_phys ( wqe ), wqe, sizeof ( *wqe ) );
/* Update previous work queue entry's "next" field */
MLX_SET ( &prev_wqe->next, nopcode, ARBEL_OPCODE_SEND );
/* Allocate work queue entry */
wqe_idx_mask = ( wq->num_wqes - 1 );
if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
- DBGC ( arbel, "Arbel %p receive queue full", arbel );
+ DBGC ( arbel, "Arbel %p QPN %#lx receive queue full\n",
+ arbel, qp->qpn );
return -ENOBUFS;
}
wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
unsigned long qpn;
int is_send;
unsigned long wqe_adr;
- unsigned int wqe_idx;
+ unsigned long wqe_idx;
size_t len;
int rc = 0;
if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
/* "s" field is not valid for error opcodes */
is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR );
- DBGC ( arbel, "Arbel %p CPN %lx syndrome %x vendor %x\n",
+ DBGC ( arbel, "Arbel %p CQN %#lx syndrome %x vendor %x\n",
arbel, cq->cqn, MLX_GET ( &cqe->error, syndrome ),
MLX_GET ( &cqe->error, vendor_code ) );
rc = -EIO;
/* Identify work queue */
wq = ib_find_wq ( cq, qpn, is_send );
if ( ! wq ) {
- DBGC ( arbel, "Arbel %p CQN %lx unknown %s QPN %lx\n",
+ DBGC ( arbel, "Arbel %p CQN %#lx unknown %s QPN %#lx\n",
arbel, cq->cqn, ( is_send ? "send" : "recv" ), qpn );
return -EIO;
}
sizeof ( arbel_recv_wq->wqe[0] ) );
assert ( wqe_idx < qp->recv.num_wqes );
}
+ DBGCP ( arbel, "Arbel %p CQN %#lx QPN %#lx %s WQE %#lx completed:\n",
+ arbel, cq->cqn, qp->qpn, ( is_send ? "send" : "recv" ),
+ wqe_idx );
+ DBGCP_HDA ( arbel, virt_to_phys ( cqe ), cqe, sizeof ( *cqe ) );
/* Identify I/O buffer */
iobuf = wq->iobufs[wqe_idx];
if ( ! iobuf ) {
- DBGC ( arbel, "Arbel %p CQN %lx QPN %lx empty WQE %x\n",
- arbel, cq->cqn, qp->qpn, wqe_idx );
+ DBGC ( arbel, "Arbel %p CQN %#lx QPN %#lx empty %s WQE %#lx\n",
+ arbel, cq->cqn, qp->qpn, ( is_send ? "send" : "recv" ),
+ wqe_idx );
return -EIO;
}
wq->iobufs[wqe_idx] = NULL;
/* Handle completion */
if ( ( rc = arbel_complete ( ibdev, cq, cqe ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p failed to complete: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p CQN %#lx failed to complete: "
+ "%s\n", arbel, cq->cqn, strerror ( rc ) );
DBGC_HD ( arbel, cqe, sizeof ( *cqe ) );
}
MLX_FILL_1 ( &eqctx, 7, lkey, arbel->reserved_lkey );
if ( ( rc = arbel_cmd_sw2hw_eq ( arbel, arbel_eq->eqn,
&eqctx ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p SW2HW_EQ failed: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p EQN %#lx SW2HW_EQ failed: %s\n",
+ arbel, arbel_eq->eqn, strerror ( rc ) );
goto err_sw2hw_eq;
}
if ( ( rc = arbel_cmd_map_eq ( arbel,
( ARBEL_MAP_EQ | arbel_eq->eqn ),
&mask ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p MAP_EQ failed: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p EQN %#lx MAP_EQ failed: %s\n",
+ arbel, arbel_eq->eqn, strerror ( rc ) );
goto err_map_eq;
}
- DBGC ( arbel, "Arbel %p EQN %#lx ring at [%p,%p])\n",
- arbel, arbel_eq->eqn, arbel_eq->eqe,
- ( ( ( void * ) arbel_eq->eqe ) + arbel_eq->eqe_size ) );
+ DBGC ( arbel, "Arbel %p EQN %#lx ring [%08lx,%08lx), doorbell %08lx\n",
+ arbel, arbel_eq->eqn, virt_to_phys ( arbel_eq->eqe ),
+ ( virt_to_phys ( arbel_eq->eqe ) + arbel_eq->eqe_size ),
+ virt_to_phys ( arbel_eq->doorbell ) );
return 0;
err_map_eq:
if ( ( rc = arbel_cmd_map_eq ( arbel,
( ARBEL_UNMAP_EQ | arbel_eq->eqn ),
&mask ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p FATAL MAP_EQ failed to unmap: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p EQN %#lx FATAL MAP_EQ failed to "
+ "unmap: %s\n", arbel, arbel_eq->eqn, strerror ( rc ) );
/* Continue; HCA may die but system should survive */
}
/* Take ownership back from hardware */
if ( ( rc = arbel_cmd_hw2sw_eq ( arbel, arbel_eq->eqn,
&eqctx ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p FATAL HW2SW_EQ failed: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p EQN %#lx FATAL HW2SW_EQ failed: %s\n",
+ arbel, arbel_eq->eqn, strerror ( rc ) );
/* Leak memory and return; at least we avoid corruption */
return;
}
/* Entry still owned by hardware; end of poll */
break;
}
- DBGCP ( arbel, "Arbel %p event:\n", arbel );
- DBGCP_HD ( arbel, eqe, sizeof ( *eqe ) );
+ DBGCP ( arbel, "Arbel %p EQN %#lx event:\n",
+ arbel, arbel_eq->eqn );
+ DBGCP_HDA ( arbel, virt_to_phys ( eqe ),
+ eqe, sizeof ( *eqe ) );
/* Handle event */
event_type = MLX_GET ( &eqe->generic, event_type );
arbel_event_port_state_change ( arbel, eqe );
break;
default:
- DBGC ( arbel, "Arbel %p unrecognised event type "
- "%#x:\n", arbel, event_type );
- DBGC_HD ( arbel, eqe, sizeof ( *eqe ) );
+ DBGC ( arbel, "Arbel %p EQN %#lx unrecognised event "
+ "type %#x:\n",
+ arbel, arbel_eq->eqn, event_type );
+ DBGC_HDA ( arbel, virt_to_phys ( eqe ),
+ eqe, sizeof ( *eqe ) );
break;
}
/* Ring doorbell */
MLX_FILL_1 ( &db_reg.ci, 0, ci, arbel_eq->next_idx );
- DBGCP ( arbel, "Ringing doorbell %08lx with %08x\n",
- virt_to_phys ( arbel_eq->doorbell ),
- db_reg.dword[0] );
writel ( db_reg.dword[0], arbel_eq->doorbell );
}
}
MLX_FILL_1 ( &init_ib, 2, max_pkey, 64 );
if ( ( rc = arbel_cmd_init_ib ( arbel, ibdev->port,
&init_ib ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p could not intialise IB: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p port %d could not intialise IB: %s\n",
+ arbel, ibdev->port, strerror ( rc ) );
return rc;
}
int rc;
if ( ( rc = arbel_cmd_close_ib ( arbel, ibdev->port ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p could not close IB: %s\n",
- arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p port %d could not close IB: %s\n",
+ arbel, ibdev->port, strerror ( rc ) );
/* Nothing we can do about this */
}
}
}
fw_base = ( user_to_phys ( arbel->firmware_area, fw_size ) &
~( fw_size - 1 ) );
- DBGC ( arbel, "Arbel %p firmware area at physical [%lx,%lx)\n",
+ DBGC ( arbel, "Arbel %p firmware area at [%08lx,%08lx)\n",
arbel, fw_base, ( fw_base + fw_size ) );
memset ( &map_fa, 0, sizeof ( map_fa ) );
MLX_FILL_2 ( &map_fa, 3,
/* Register Infiniband devices */
for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) {
if ( ( rc = register_ibdev ( arbel->ibdev[i] ) ) != 0 ) {
- DBGC ( arbel, "Arbel %p could not register IB "
- "device: %s\n", arbel, strerror ( rc ) );
+ DBGC ( arbel, "Arbel %p port %d could not register IB "
+ "device: %s\n", arbel,
+ arbel->ibdev[i]->port, strerror ( rc ) );
goto err_register_ibdev;
}
}