summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/infiniband/hermon.c40
-rw-r--r--src/drivers/infiniband/hermon.h8
2 files changed, 37 insertions, 11 deletions
diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c
index 5db49427..f074386f 100644
--- a/src/drivers/infiniband/hermon.c
+++ b/src/drivers/infiniband/hermon.c
@@ -770,6 +770,15 @@ static int hermon_create_cq ( struct ib_device *ibdev,
goto err_hermon_cq;
}
+ /* Allocate doorbell */
+ hermon_cq->doorbell = malloc_dma ( sizeof ( hermon_cq->doorbell[0] ),
+ sizeof ( hermon_cq->doorbell[0] ) );
+ if ( ! hermon_cq->doorbell ) {
+ rc = -ENOMEM;
+ goto err_doorbell;
+ }
+ memset ( hermon_cq->doorbell, 0, sizeof ( hermon_cq->doorbell[0] ) );
+
/* Allocate completion queue itself */
hermon_cq->cqe_size = ( cq->num_cqes * sizeof ( hermon_cq->cqe[0] ) );
hermon_cq->cqe = malloc_dma ( hermon_cq->cqe_size,
@@ -802,7 +811,7 @@ static int hermon_create_cq ( struct ib_device *ibdev,
MLX_FILL_1 ( &cqctx, 7, mtt_base_addr_l,
( hermon_cq->mtt.mtt_base_addr >> 3 ) );
MLX_FILL_1 ( &cqctx, 15, db_record_addr_l,
- ( virt_to_phys ( &hermon_cq->doorbell ) >> 3 ) );
+ ( virt_to_phys ( hermon_cq->doorbell ) >> 3 ) );
if ( ( rc = hermon_cmd_sw2hw_cq ( hermon, cq->cqn, &cqctx ) ) != 0 ) {
DBGC ( hermon, "Hermon %p CQN %#lx SW2HW_CQ failed: %s\n",
hermon, cq->cqn, strerror ( rc ) );
@@ -812,7 +821,7 @@ static int hermon_create_cq ( struct ib_device *ibdev,
DBGC ( hermon, "Hermon %p CQN %#lx ring [%08lx,%08lx), doorbell "
"%08lx\n", hermon, cq->cqn, virt_to_phys ( hermon_cq->cqe ),
( virt_to_phys ( hermon_cq->cqe ) + hermon_cq->cqe_size ),
- virt_to_phys ( &hermon_cq->doorbell ) );
+ virt_to_phys ( hermon_cq->doorbell ) );
ib_cq_set_drvdata ( cq, hermon_cq );
return 0;
@@ -821,6 +830,8 @@ static int hermon_create_cq ( struct ib_device *ibdev,
err_alloc_mtt:
free_dma ( hermon_cq->cqe, hermon_cq->cqe_size );
err_cqe:
+ free_dma ( hermon_cq->doorbell, sizeof ( hermon_cq->doorbell[0] ) );
+ err_doorbell:
free ( hermon_cq );
err_hermon_cq:
hermon_bitmask_free ( hermon->cq_inuse, cqn_offset, 1 );
@@ -855,6 +866,7 @@ static void hermon_destroy_cq ( struct ib_device *ibdev,
/* Free memory */
free_dma ( hermon_cq->cqe, hermon_cq->cqe_size );
+ free_dma ( hermon_cq->doorbell, sizeof ( hermon_cq->doorbell[0] ) );
free ( hermon_cq );
/* Mark queue number as free */
@@ -1013,7 +1025,16 @@ static int hermon_create_qp ( struct ib_device *ibdev,
goto err_hermon_qp;
}
- /* Calculate doorbell address */
+ /* Allocate doorbells */
+ hermon_qp->recv.doorbell =
+ malloc_dma ( sizeof ( hermon_qp->recv.doorbell[0] ),
+ sizeof ( hermon_qp->recv.doorbell[0] ) );
+ if ( ! hermon_qp->recv.doorbell ) {
+ rc = -ENOMEM;
+ goto err_recv_doorbell;
+ }
+ memset ( hermon_qp->recv.doorbell, 0,
+ sizeof ( hermon_qp->recv.doorbell[0] ) );
hermon_qp->send.doorbell =
( hermon->uar + HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE +
HERMON_DB_POST_SND_OFFSET );
@@ -1072,7 +1093,7 @@ static int hermon_create_qp ( struct ib_device *ibdev,
( hermon_qp->mtt.page_offset >> 6 ) );
MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.db_record_addr_l,
- ( virt_to_phys ( &hermon_qp->recv.doorbell ) >> 2 ) );
+ ( virt_to_phys ( hermon_qp->recv.doorbell ) >> 2 ) );
MLX_FILL_1 ( &qpctx, 53, qpc_eec_data.mtt_base_addr_l,
( hermon_qp->mtt.mtt_base_addr >> 3 ) );
if ( ( rc = hermon_cmd_rst2init_qp ( hermon, qp->qpn,
@@ -1094,7 +1115,7 @@ static int hermon_create_qp ( struct ib_device *ibdev,
virt_to_phys ( hermon_qp->recv.wqe ),
( virt_to_phys ( hermon_qp->recv.wqe ) +
hermon_qp->recv.wqe_size ),
- virt_to_phys ( &hermon_qp->recv.doorbell ) );
+ virt_to_phys ( hermon_qp->recv.doorbell ) );
DBGC ( hermon, "Hermon %p QPN %#lx send CQN %#lx receive CQN %#lx\n",
hermon, qp->qpn, qp->send.cq->cqn, qp->recv.cq->cqn );
ib_qp_set_drvdata ( qp, hermon_qp );
@@ -1106,6 +1127,9 @@ static int hermon_create_qp ( struct ib_device *ibdev,
err_alloc_mtt:
free_dma ( hermon_qp->wqe, hermon_qp->wqe_size );
err_alloc_wqe:
+ free_dma ( hermon_qp->recv.doorbell,
+ sizeof ( hermon_qp->recv.doorbell[0] ) );
+ err_recv_doorbell:
free ( hermon_qp );
err_hermon_qp:
hermon_free_qpn ( ibdev, qp );
@@ -1215,6 +1239,8 @@ static void hermon_destroy_qp ( struct ib_device *ibdev,
/* Free memory */
free_dma ( hermon_qp->wqe, hermon_qp->wqe_size );
+ free_dma ( hermon_qp->recv.doorbell,
+ sizeof ( hermon_qp->recv.doorbell[0] ) );
free ( hermon_qp );
/* Mark queue number as free */
@@ -1482,7 +1508,7 @@ static int hermon_post_recv ( struct ib_device *ibdev,
/* Update doorbell record */
barrier();
- MLX_FILL_1 ( &hermon_recv_wq->doorbell, 0, receive_wqe_counter,
+ MLX_FILL_1 ( hermon_recv_wq->doorbell, 0, receive_wqe_counter,
( wq->next_idx & 0xffff ) );
return 0;
@@ -1631,7 +1657,7 @@ static void hermon_poll_cq ( struct ib_device *ibdev,
cq->next_idx++;
/* Update doorbell record */
- MLX_FILL_1 ( &hermon_cq->doorbell, 0, update_ci,
+ MLX_FILL_1 ( hermon_cq->doorbell, 0, update_ci,
( cq->next_idx & 0x00ffffffUL ) );
}
}
diff --git a/src/drivers/infiniband/hermon.h b/src/drivers/infiniband/hermon.h
index 84b08a03..e29e50b9 100644
--- a/src/drivers/infiniband/hermon.h
+++ b/src/drivers/infiniband/hermon.h
@@ -408,8 +408,8 @@ struct hermon_recv_work_queue {
union hermon_recv_wqe *wqe;
/** Size of work queue */
size_t wqe_size;
- /** Doorbell */
- struct hermonprm_qp_db_record doorbell __attribute__ (( aligned (4) ));
+ /** Doorbell record */
+ struct hermonprm_qp_db_record *doorbell;
};
/** Number of special queue pairs */
@@ -469,8 +469,8 @@ struct hermon_completion_queue {
size_t cqe_size;
/** MTT descriptor */
struct hermon_mtt mtt;
- /** Doorbell */
- struct hermonprm_cq_db_record doorbell __attribute__ (( aligned (8) ));
+ /** Doorbell record */
+ struct hermonprm_cq_db_record *doorbell;
};
/** Maximum number of allocatable event queues