summaryrefslogtreecommitdiffstats
path: root/src/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/infiniband')
-rw-r--r--src/drivers/infiniband/hermon.c53
-rw-r--r--src/drivers/infiniband/hermon.h6
2 files changed, 47 insertions, 12 deletions
diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c
index 606d35473..99a54a146 100644
--- a/src/drivers/infiniband/hermon.c
+++ b/src/drivers/infiniband/hermon.c
@@ -1111,6 +1111,8 @@ static int hermon_create_qp ( struct ib_device *ibdev,
struct hermon *hermon = ib_get_drvdata ( ibdev );
struct hermon_queue_pair *hermon_qp;
struct hermonprm_qp_ee_state_transitions qpctx;
+ struct hermonprm_wqe_segment_data_ptr *data;
+ unsigned int i;
int rc;
/* Calculate queue pair number */
@@ -1147,8 +1149,14 @@ static int hermon_create_qp ( struct ib_device *ibdev,
sizeof ( hermon_qp->send.wqe[0] ) );
hermon_qp->recv.wqe_size = ( qp->recv.num_wqes *
sizeof ( hermon_qp->recv.wqe[0] ) );
+ if ( ( qp->type == IB_QPT_SMI ) || ( qp->type == IB_QPT_GSI ) ||
+ ( qp->type == IB_QPT_UD ) ) {
+ hermon_qp->recv.grh_size = ( qp->recv.num_wqes *
+ sizeof ( hermon_qp->recv.grh[0] ));
+ }
hermon_qp->wqe_size = ( hermon_qp->send.wqe_size +
- hermon_qp->recv.wqe_size );
+ hermon_qp->recv.wqe_size +
+ hermon_qp->recv.grh_size );
hermon_qp->wqe = malloc_dma ( hermon_qp->wqe_size,
sizeof ( hermon_qp->send.wqe[0] ) );
if ( ! hermon_qp->wqe ) {
@@ -1156,9 +1164,21 @@ static int hermon_create_qp ( struct ib_device *ibdev,
goto err_alloc_wqe;
}
hermon_qp->send.wqe = hermon_qp->wqe;
- memset ( hermon_qp->send.wqe, 0xff, hermon_qp->send.wqe_size );
hermon_qp->recv.wqe = ( hermon_qp->wqe + hermon_qp->send.wqe_size );
+ if ( hermon_qp->recv.grh_size ) {
+ hermon_qp->recv.grh = ( hermon_qp->wqe +
+ hermon_qp->send.wqe_size +
+ hermon_qp->recv.wqe_size );
+ }
+
+ /* Initialise work queue entries */
+ memset ( hermon_qp->send.wqe, 0xff, hermon_qp->send.wqe_size );
memset ( hermon_qp->recv.wqe, 0, hermon_qp->recv.wqe_size );
+ data = &hermon_qp->recv.wqe[0].recv.data[0];
+ for ( i = 0 ; i < ( hermon_qp->recv.wqe_size / sizeof ( *data ) ); i++){
+ MLX_FILL_1 ( data, 1, l_key, HERMON_INVALID_LKEY );
+ data++;
+ }
/* Allocate MTT entries */
if ( ( rc = hermon_alloc_mtt ( hermon, hermon_qp->wqe,
@@ -1633,6 +1653,8 @@ static int hermon_post_recv ( struct ib_device *ibdev,
struct ib_work_queue *wq = &qp->recv;
struct hermon_recv_work_queue *hermon_recv_wq = &hermon_qp->recv;
struct hermonprm_recv_wqe *wqe;
+ struct hermonprm_wqe_segment_data_ptr *data;
+ struct ib_global_route_header *grh;
unsigned int wqe_idx_mask;
/* Allocate work queue entry */
@@ -1646,12 +1668,19 @@ static int hermon_post_recv ( struct ib_device *ibdev,
wqe = &hermon_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv;
/* Construct work queue entry */
- MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
- MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->lkey );
- MLX_FILL_H ( &wqe->data[0], 2,
- local_address_h, virt_to_bus ( iobuf->data ) );
- MLX_FILL_1 ( &wqe->data[0], 3,
- local_address_l, virt_to_bus ( iobuf->data ) );
+ data = &wqe->data[0];
+ if ( hermon_qp->recv.grh ) {
+ grh = &hermon_qp->recv.grh[wq->next_idx & wqe_idx_mask];
+ MLX_FILL_1 ( data, 0, byte_count, sizeof ( *grh ) );
+ MLX_FILL_1 ( data, 1, l_key, hermon->lkey );
+ MLX_FILL_H ( data, 2, local_address_h, virt_to_bus ( grh ) );
+ MLX_FILL_1 ( data, 3, local_address_l, virt_to_bus ( grh ) );
+ data++;
+ }
+ MLX_FILL_1 ( data, 0, byte_count, iob_tailroom ( iobuf ) );
+ MLX_FILL_1 ( data, 1, l_key, hermon->lkey );
+ MLX_FILL_H ( data, 2, local_address_h, virt_to_bus ( iobuf->data ) );
+ MLX_FILL_1 ( data, 3, local_address_l, virt_to_bus ( iobuf->data ) );
/* Update work queue's index */
wq->next_idx++;
@@ -1676,6 +1705,7 @@ static int hermon_complete ( struct ib_device *ibdev,
struct ib_completion_queue *cq,
union hermonprm_completion_entry *cqe ) {
struct hermon *hermon = ib_get_drvdata ( ibdev );
+ struct hermon_queue_pair *hermon_qp;
struct ib_work_queue *wq;
struct ib_queue_pair *qp;
struct io_buffer *iobuf;
@@ -1713,6 +1743,7 @@ static int hermon_complete ( struct ib_device *ibdev,
return -EIO;
}
qp = wq->qp;
+ hermon_qp = ib_qp_get_drvdata ( qp );
/* Identify work queue entry */
wqe_idx = MLX_GET ( &cqe->normal, wqe_counter );
@@ -1747,9 +1778,9 @@ static int hermon_complete ( struct ib_device *ibdev,
case IB_QPT_SMI:
case IB_QPT_GSI:
case IB_QPT_UD:
- assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
- grh = iobuf->data;
- iob_pull ( iobuf, sizeof ( *grh ) );
+ /* Locate corresponding GRH */
+ assert ( hermon_qp->recv.grh != NULL );
+ grh = &hermon_qp->recv.grh[ wqe_idx & wqe_idx_mask ];
/* Construct address vector */
source = &recv_source;
source->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
diff --git a/src/drivers/infiniband/hermon.h b/src/drivers/infiniband/hermon.h
index e0b028f26..61e285781 100644
--- a/src/drivers/infiniband/hermon.h
+++ b/src/drivers/infiniband/hermon.h
@@ -515,7 +515,7 @@ struct hermonprm_eth_send_wqe {
struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER];
} __attribute__ (( packed ));
-#define HERMON_MAX_SCATTER 1
+#define HERMON_MAX_SCATTER 2
struct hermonprm_recv_wqe {
struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_SCATTER];
@@ -686,6 +686,10 @@ struct hermon_recv_work_queue {
union hermon_recv_wqe *wqe;
/** Size of work queue */
size_t wqe_size;
+ /** GRH buffers (if applicable) */
+ struct ib_global_route_header *grh;
+ /** Size of GRH buffers */
+ size_t grh_size;
/** Doorbell record */
struct hermonprm_qp_db_record *doorbell;
};