diff options
-rw-r--r-- | src/drivers/infiniband/arbel.c | 50 | ||||
-rw-r--r-- | src/drivers/infiniband/hermon.c | 46 | ||||
-rw-r--r-- | src/drivers/net/ipoib.c | 109 | ||||
-rw-r--r-- | src/include/gpxe/infiniband.h | 105 | ||||
-rw-r--r-- | src/net/infiniband.c | 38 |
5 files changed, 172 insertions, 176 deletions
diff --git a/src/drivers/infiniband/arbel.c b/src/drivers/infiniband/arbel.c index 2649a4ab..8a31ad8b 100644 --- a/src/drivers/infiniband/arbel.c +++ b/src/drivers/infiniband/arbel.c @@ -1006,7 +1006,7 @@ static int arbel_post_send ( struct ib_device *ibdev, ud_address_vector.pd, ARBEL_GLOBAL_PD, ud_address_vector.port_number, ibdev->port ); MLX_FILL_2 ( &wqe->ud, 1, - ud_address_vector.rlid, av->dlid, + ud_address_vector.rlid, av->lid, ud_address_vector.g, av->gid_present ); MLX_FILL_2 ( &wqe->ud, 2, ud_address_vector.max_stat_rate, @@ -1015,7 +1015,7 @@ static int arbel_post_send ( struct ib_device *ibdev, MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl ); gid = ( av->gid_present ? &av->gid : &arbel_no_gid ); memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) ); - MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp ); + MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->qpn ); MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey ); MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) ); MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey ); @@ -1112,7 +1112,6 @@ static int arbel_complete ( struct ib_device *ibdev, struct ib_completion_queue *cq, union arbelprm_completion_entry *cqe ) { struct arbel *arbel = ib_get_drvdata ( ibdev ); - struct ib_completion completion; struct ib_work_queue *wq; struct ib_queue_pair *qp; struct arbel_queue_pair *arbel_qp; @@ -1120,15 +1119,17 @@ static int arbel_complete ( struct ib_device *ibdev, struct arbel_recv_work_queue *arbel_recv_wq; struct arbelprm_recv_wqe *recv_wqe; struct io_buffer *iobuf; + struct ib_address_vector av; + struct ib_global_route_header *grh; unsigned int opcode; unsigned long qpn; int is_send; unsigned long wqe_adr; unsigned int wqe_idx; + size_t len; int rc = 0; /* Parse completion */ - memset ( &completion, 0, sizeof ( completion ) ); qpn = MLX_GET ( &cqe->normal, my_qpn ); is_send = MLX_GET ( &cqe->normal, s ); wqe_adr = ( MLX_GET ( &cqe->normal, wqe_adr ) << 6 ); @@ -1136,9 +1137,8 @@ static int arbel_complete ( struct ib_device *ibdev, if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) { /* "s" field is not valid for error opcodes */ is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR ); - completion.syndrome = MLX_GET ( &cqe->error, syndrome ); - DBGC ( arbel, "Arbel %p CPN %lx syndrome %x vendor %lx\n", - arbel, cq->cqn, completion.syndrome, + DBGC ( arbel, "Arbel %p CPN %lx syndrome %lx vendor %lx\n", + arbel, cq->cqn, MLX_GET ( &cqe->error, syndrome ), MLX_GET ( &cqe->error, vendor_code ) ); rc = -EIO; /* Don't return immediately; propagate error to completer */ @@ -1176,9 +1176,12 @@ static int arbel_complete ( struct ib_device *ibdev, } wq->iobufs[wqe_idx] = NULL; - /* Fill in length for received packets */ - if ( ! is_send ) { - completion.len = MLX_GET ( &cqe->normal, byte_cnt ); + if ( is_send ) { + /* Hand off to completion handler */ + ib_complete_send ( ibdev, qp, iobuf, rc ); + } else { + /* Set received length */ + len = MLX_GET ( &cqe->normal, byte_cnt ); recv_wqe = &arbel_recv_wq->wqe[wqe_idx].recv; assert ( MLX_GET ( &recv_wqe->data[0], local_address_l ) == virt_to_bus ( iobuf->data ) ); @@ -1187,19 +1190,20 @@ static int arbel_complete ( struct ib_device *ibdev, MLX_FILL_1 ( &recv_wqe->data[0], 0, byte_count, 0 ); MLX_FILL_1 ( &recv_wqe->data[0], 1, l_key, ARBEL_INVALID_LKEY ); - if ( completion.len > iob_tailroom ( iobuf ) ) { - DBGC ( arbel, "Arbel %p CQN %lx QPN %lx IDX %x " - "overlength received packet length %zd\n", - arbel, cq->cqn, qpn, wqe_idx, completion.len ); - return -EIO; - } - } - - /* Pass off to caller's completion handler */ - if ( is_send ) { - ib_complete_send ( ibdev, qp, &completion, iobuf ); - } else { - ib_complete_recv ( ibdev, qp, &completion, iobuf ); + assert ( len <= iob_tailroom ( iobuf ) ); + iob_put ( iobuf, len ); + assert ( iob_len ( iobuf ) >= sizeof ( *grh ) ); + grh = iobuf->data; + iob_pull ( iobuf, sizeof ( *grh ) ); + /* Construct address vector */ + memset ( &av, 0, sizeof ( av ) ); + av.qpn = MLX_GET ( &cqe->normal, rqpn ); + av.lid = MLX_GET ( &cqe->normal, rlid ); + av.sl = MLX_GET ( &cqe->normal, sl ); + av.gid_present = MLX_GET ( &cqe->normal, g ); + memcpy ( &av.gid, &grh->sgid, sizeof ( av.gid ) ); + /* Hand off to completion handler */ + ib_complete_recv ( ibdev, qp, &av, iobuf, rc ); } return rc; diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c index a8907634..db7619ad 100644 --- a/src/drivers/infiniband/hermon.c +++ b/src/drivers/infiniband/hermon.c @@ -1015,7 +1015,7 @@ static int hermon_post_send ( struct ib_device *ibdev, ud_address_vector.pd, HERMON_GLOBAL_PD, ud_address_vector.port_number, ibdev->port ); MLX_FILL_2 ( &wqe->ud, 1, - ud_address_vector.rlid, av->dlid, + ud_address_vector.rlid, av->lid, ud_address_vector.g, av->gid_present ); MLX_FILL_1 ( &wqe->ud, 2, ud_address_vector.max_stat_rate, @@ -1024,7 +1024,7 @@ static int hermon_post_send ( struct ib_device *ibdev, MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl ); gid = ( av->gid_present ? &av->gid : &hermon_no_gid ); memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) ); - MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp ); + MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->qpn ); MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey ); MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) ); MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->reserved_lkey ); @@ -1107,28 +1107,28 @@ 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 ib_completion completion; struct ib_work_queue *wq; struct ib_queue_pair *qp; struct hermon_queue_pair *hermon_qp; struct io_buffer *iobuf; + struct ib_address_vector av; + struct ib_global_route_header *grh; unsigned int opcode; unsigned long qpn; int is_send; unsigned int wqe_idx; + size_t len; int rc = 0; /* Parse completion */ - memset ( &completion, 0, sizeof ( completion ) ); qpn = MLX_GET ( &cqe->normal, qpn ); is_send = MLX_GET ( &cqe->normal, s_r ); opcode = MLX_GET ( &cqe->normal, opcode ); if ( opcode >= HERMON_OPCODE_RECV_ERROR ) { /* "s" field is not valid for error opcodes */ is_send = ( opcode == HERMON_OPCODE_SEND_ERROR ); - completion.syndrome = MLX_GET ( &cqe->error, syndrome ); - DBGC ( hermon, "Hermon %p CQN %lx syndrome %x vendor %lx\n", - hermon, cq->cqn, completion.syndrome, + DBGC ( hermon, "Hermon %p CQN %lx syndrome %lx vendor %lx\n", + hermon, cq->cqn, MLX_GET ( &cqe->error, syndrome ), MLX_GET ( &cqe->error, vendor_error_syndrome ) ); rc = -EIO; /* Don't return immediately; propagate error to completer */ @@ -1155,22 +1155,26 @@ static int hermon_complete ( struct ib_device *ibdev, } wq->iobufs[wqe_idx] = NULL; - /* Fill in length for received packets */ - if ( ! is_send ) { - completion.len = MLX_GET ( &cqe->normal, byte_cnt ); - if ( completion.len > iob_tailroom ( iobuf ) ) { - DBGC ( hermon, "Hermon %p CQN %lx QPN %lx IDX %x " - "overlength received packet length %zd\n", - hermon, cq->cqn, qpn, wqe_idx, completion.len ); - return -EIO; - } - } - - /* Pass off to caller's completion handler */ if ( is_send ) { - ib_complete_send ( ibdev, qp, &completion, iobuf ); + /* Hand off to completion handler */ + ib_complete_send ( ibdev, qp, iobuf, rc ); } else { - ib_complete_recv ( ibdev, qp, &completion, iobuf ); + /* Set received length */ + len = MLX_GET ( &cqe->normal, byte_cnt ); + assert ( len <= iob_tailroom ( iobuf ) ); + iob_put ( iobuf, len ); + assert ( iob_len ( iobuf ) >= sizeof ( *grh ) ); + grh = iobuf->data; + iob_pull ( iobuf, sizeof ( *grh ) ); + /* Construct address vector */ + memset ( &av, 0, sizeof ( av ) ); + av.qpn = MLX_GET ( &cqe->normal, srq_rqpn ); + av.lid = MLX_GET ( &cqe->normal, slid_smac47_32 ); + av.sl = MLX_GET ( &cqe->normal, sl ); + av.gid_present = MLX_GET ( &cqe->normal, g ); + memcpy ( &av.gid, &grh->sgid, sizeof ( av.gid ) ); + /* Hand off to completion handler */ + ib_complete_recv ( ibdev, qp, &av, iobuf, rc ); } return rc; diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c index 55123006..aa68fe38 100644 --- a/src/drivers/net/ipoib.c +++ b/src/drivers/net/ipoib.c @@ -277,20 +277,18 @@ static void ipoib_destroy_qset ( struct ipoib_device *ipoib, * @v ipoib IPoIB device * @v qset Queue set * @v num_cqes Number of completion queue entries + * @v cq_op Completion queue operations * @v num_send_wqes Number of send work queue entries - * @v complete_send Send completion handler * @v num_recv_wqes Number of receive work queue entries - * @v complete_recv Receive completion handler * @v qkey Queue key * @ret rc Return status code */ static int ipoib_create_qset ( struct ipoib_device *ipoib, struct ipoib_queue_set *qset, unsigned int num_cqes, + struct ib_completion_queue_operations *cq_op, unsigned int num_send_wqes, - ib_completer_t complete_send, unsigned int num_recv_wqes, - ib_completer_t complete_recv, unsigned long qkey ) { struct ib_device *ibdev = ipoib->ibdev; int rc; @@ -303,8 +301,7 @@ static int ipoib_create_qset ( struct ipoib_device *ipoib, qset->recv_max_fill = num_recv_wqes; /* Allocate completion queue */ - qset->cq = ib_create_cq ( ibdev, num_cqes, complete_send, - complete_recv ); + qset->cq = ib_create_cq ( ibdev, num_cqes, cq_op ); if ( ! qset->cq ) { DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n", ipoib ); @@ -391,8 +388,8 @@ static int ipoib_get_path_record ( struct ipoib_device *ipoib, /* Construct address vector */ memset ( &av, 0, sizeof ( av ) ); - av.dlid = ibdev->sm_lid; - av.dest_qp = IB_SA_QPN; + av.lid = ibdev->sm_lid; + av.qpn = IB_SA_QPN; av.qkey = IB_GLOBAL_QKEY; /* Post send request */ @@ -451,8 +448,8 @@ static int ipoib_mc_member_record ( struct ipoib_device *ipoib, /* Construct address vector */ memset ( &av, 0, sizeof ( av ) ); - av.dlid = ibdev->sm_lid; - av.dest_qp = IB_SA_QPN; + av.lid = ibdev->sm_lid; + av.qpn = IB_SA_QPN; av.qkey = IB_GLOBAL_QKEY; /* Post send request */ @@ -503,8 +500,8 @@ static int ipoib_transmit ( struct net_device *netdev, av.gid_present = 1; if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) { /* Broadcast address */ - av.dest_qp = IB_BROADCAST_QPN; - av.dlid = ipoib->broadcast_lid; + av.qpn = IB_BROADCAST_QPN; + av.lid = ipoib->broadcast_lid; gid = &ipoib->broadcast_gid; } else { /* Unicast - look in path cache */ @@ -516,8 +513,8 @@ static int ipoib_transmit ( struct net_device *netdev, netdev_tx_complete ( netdev, iobuf ); return rc; } - av.dest_qp = ntohl ( ipoib_pshdr->peer.qpn ); - av.dlid = path->dlid; + av.qpn = ntohl ( ipoib_pshdr->peer.qpn ); + av.lid = path->dlid; av.rate = path->rate; av.sl = path->sl; gid = &ipoib_pshdr->peer.gid; @@ -532,17 +529,15 @@ static int ipoib_transmit ( struct net_device *netdev, * * @v ibdev Infiniband device * @v qp Queue pair - * @v completion Completion * @v iobuf I/O buffer + * @v rc Completion status code */ static void ipoib_data_complete_send ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ) { + struct io_buffer *iobuf, int rc ) { struct net_device *netdev = ib_qp_get_ownerdata ( qp ); - netdev_tx_complete_err ( netdev, iobuf, - ( completion->syndrome ? -EIO : 0 ) ); + netdev_tx_complete_err ( netdev, iobuf, rc ); } /** @@ -550,32 +545,23 @@ static void ipoib_data_complete_send ( struct ib_device *ibdev __unused, * * @v ibdev Infiniband device * @v qp Queue pair - * @v completion Completion + * @v av Address vector, or NULL * @v iobuf I/O buffer + * @v rc Completion status code */ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ) { + struct ib_address_vector *av __unused, + struct io_buffer *iobuf, int rc ) { struct net_device *netdev = ib_qp_get_ownerdata ( qp ); struct ipoib_device *ipoib = netdev->priv; struct ipoib_pseudo_hdr *ipoib_pshdr; - if ( completion->syndrome ) { - netdev_rx_err ( netdev, iobuf, -EIO ); + if ( rc != 0 ) { + netdev_rx_err ( netdev, iobuf, rc ); return; } - iob_put ( iobuf, completion->len ); - if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) { - DBGC ( ipoib, "IPoIB %p received data packet too short to " - "contain GRH\n", ipoib ); - DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) ); - netdev_rx_err ( netdev, iobuf, -EIO ); - return; - } - iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) ); - if ( iob_len ( iobuf ) < sizeof ( struct ipoib_real_hdr ) ) { DBGC ( ipoib, "IPoIB %p received data packet too short to " "contain IPoIB header\n", ipoib ); @@ -590,24 +576,29 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused, netdev_rx ( netdev, iobuf ); } +/** IPoIB data completion operations */ +static struct ib_completion_queue_operations ipoib_data_cq_op = { + .complete_send = ipoib_data_complete_send, + .complete_recv = ipoib_data_complete_recv, +}; + /** * Handle IPoIB metadata send completion * * @v ibdev Infiniband device * @v qp Queue pair - * @v completion Completion * @v iobuf I/O buffer + * @v rc Completion status code */ static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused, struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ) { + struct io_buffer *iobuf, int rc ) { struct net_device *netdev = ib_qp_get_ownerdata ( qp ); struct ipoib_device *ipoib = netdev->priv; - if ( completion->syndrome ) { - DBGC ( ipoib, "IPoIB %p metadata TX completion error %x\n", - ipoib, completion->syndrome ); + if ( rc != 0 ) { + DBGC ( ipoib, "IPoIB %p metadata TX completion error: %s\n", + ipoib, strerror ( rc ) ); } free_iob ( iobuf ); } @@ -673,31 +664,25 @@ static void ipoib_recv_mc_member_record ( struct ipoib_device *ipoib, * * @v ibdev Infiniband device * @v qp Queue pair - * @v completion Completion + * @v av Address vector, or NULL * @v iobuf I/O buffer + * @v rc Completion status code */ -static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused, - struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ) { +static void +ipoib_meta_complete_recv ( struct ib_device *ibdev __unused, + struct ib_queue_pair *qp, + struct ib_address_vector *av __unused, + struct io_buffer *iobuf, int rc ) { struct net_device *netdev = ib_qp_get_ownerdata ( qp ); struct ipoib_device *ipoib = netdev->priv; union ib_mad *mad; - if ( completion->syndrome ) { - DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n", - ipoib, completion->syndrome ); + if ( rc != 0 ) { + DBGC ( ipoib, "IPoIB %p metadata RX completion error: %s\n", + ipoib, strerror ( rc ) ); goto done; } - iob_put ( iobuf, completion->len ); - if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) { - DBGC ( ipoib, "IPoIB %p received metadata packet too short " - "to contain GRH\n", ipoib ); - DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) ); - goto done; - } - iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) ); if ( iob_len ( iobuf ) < sizeof ( *mad ) ) { DBGC ( ipoib, "IPoIB %p received metadata packet too short " "to contain reply\n", ipoib ); @@ -730,6 +715,12 @@ static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused, free_iob ( iobuf ); } +/** IPoIB metadata completion operations */ +static struct ib_completion_queue_operations ipoib_meta_cq_op = { + .complete_send = ipoib_meta_complete_send, + .complete_recv = ipoib_meta_complete_recv, +}; + /** * Refill IPoIB receive ring * @@ -846,10 +837,9 @@ static int ipoib_open ( struct net_device *netdev ) { /* Allocate metadata queue set */ if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta, IPOIB_META_NUM_CQES, + &ipoib_meta_cq_op, IPOIB_META_NUM_SEND_WQES, - ipoib_meta_complete_send, IPOIB_META_NUM_RECV_WQES, - ipoib_meta_complete_recv, IB_GLOBAL_QKEY ) ) != 0 ) { DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n", ipoib, strerror ( rc ) ); @@ -859,10 +849,9 @@ static int ipoib_open ( struct net_device *netdev ) { /* Allocate data queue set */ if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data, IPOIB_DATA_NUM_CQES, + &ipoib_data_cq_op, IPOIB_DATA_NUM_SEND_WQES, - ipoib_data_complete_send, IPOIB_DATA_NUM_RECV_WQES, - ipoib_data_complete_recv, IB_GLOBAL_QKEY ) ) != 0 ) { DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n", ipoib, strerror ( rc ) ); diff --git a/src/include/gpxe/infiniband.h b/src/include/gpxe/infiniband.h index 36adf234..ed0d1a66 100644 --- a/src/include/gpxe/infiniband.h +++ b/src/include/gpxe/infiniband.h @@ -52,6 +52,7 @@ struct ib_global_route_header { struct ib_device; struct ib_queue_pair; +struct ib_address_vector; struct ib_completion_queue; /** An Infiniband Work Queue */ @@ -103,37 +104,58 @@ enum ib_queue_pair_mods { IB_MODIFY_QKEY = 0x0001, }; -/** An Infiniband completion */ -struct ib_completion { - /** Syndrome +/** An Infiniband Address Vector */ +struct ib_address_vector { + /** Queue Pair Number */ + unsigned long qpn; + /** Queue key * - * If non-zero, then the completion is in error. + * Not specified for received packets. */ - unsigned int syndrome; - /** Length */ - size_t len; + unsigned long qkey; + /** Local ID */ + unsigned int lid; + /** Rate + * + * Not specified for received packets. + */ + unsigned int rate; + /** Service level */ + unsigned int sl; + /** GID is present */ + unsigned int gid_present; + /** GID, if present */ + struct ib_gid gid; }; -/** Infiniband completion syndromes */ -enum ib_syndrome { - IB_SYN_NONE = 0, - IB_SYN_LOCAL_LENGTH = 1, - IB_SYN_LOCAL_QP = 2, - IB_SYN_LOCAL_PROT = 4, +/** Infiniband completion queue operations */ +struct ib_completion_queue_operations { + /** + * Complete Send WQE + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v iobuf I/O buffer + * @v rc Completion status code + */ + void ( * complete_send ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp, + struct io_buffer *iobuf, int rc ); + /** + * Complete Receive WQE + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v av Address vector, or NULL + * @v iobuf I/O buffer + * @v rc Completion status code + */ + void ( * complete_recv ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp, + struct ib_address_vector *av, + struct io_buffer *iobuf, int rc ); }; -/** An Infiniband completion handler - * - * @v ibdev Infiniband device - * @v qp Queue pair - * @v completion Completion - * @v iobuf I/O buffer - */ -typedef void ( * ib_completer_t ) ( struct ib_device *ibdev, - struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ); - /** An Infiniband Completion Queue */ struct ib_completion_queue { /** Completion queue number */ @@ -150,32 +172,12 @@ struct ib_completion_queue { unsigned long next_idx; /** List of work queues completing to this queue */ struct list_head work_queues; - /** Send completion handler */ - ib_completer_t complete_send; - /** Receive completion handler */ - ib_completer_t complete_recv; + /** Completion queue operations */ + struct ib_completion_queue_operations *op; /** Driver private data */ void *drv_priv; }; -/** An Infiniband Address Vector */ -struct ib_address_vector { - /** Destination Queue Pair */ - unsigned int dest_qp; - /** Queue key */ - unsigned long qkey; - /** Destination Local ID */ - unsigned int dlid; - /** Rate */ - unsigned int rate; - /** Service level */ - unsigned int sl; - /** GID is present */ - unsigned int gid_present; - /** GID */ - struct ib_gid gid; -}; - struct ib_mad_hdr; /** @@ -344,7 +346,7 @@ struct ib_device { extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes, - ib_completer_t complete_send, ib_completer_t complete_recv ); + struct ib_completion_queue_operations *op ); extern void ib_destroy_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ); extern struct ib_queue_pair * @@ -364,12 +366,11 @@ extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf ); extern void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ); + struct io_buffer *iobuf, int rc ); extern void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ); + struct ib_address_vector *av, + struct io_buffer *iobuf, int rc ); extern struct ib_device * alloc_ibdev ( size_t priv_size ); extern int register_ibdev ( struct ib_device *ibdev ); extern void unregister_ibdev ( struct ib_device *ibdev ); diff --git a/src/net/infiniband.c b/src/net/infiniband.c index 2db8a0f4..ba7842cf 100644 --- a/src/net/infiniband.c +++ b/src/net/infiniband.c @@ -46,13 +46,12 @@ struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices ); * * @v ibdev Infiniband device * @v num_cqes Number of completion queue entries - * @v complete_send Send completion handler - * @v complete_recv Receive completion handler + * @v op Completion queue operations * @ret cq New completion queue */ struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes, - ib_completer_t complete_send, ib_completer_t complete_recv ) { + struct ib_completion_queue_operations *op ) { struct ib_completion_queue *cq; int rc; @@ -64,8 +63,7 @@ ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes, return NULL; cq->num_cqes = num_cqes; INIT_LIST_HEAD ( &cq->work_queues ); - cq->complete_send = complete_send; - cq->complete_recv = complete_recv; + cq->op = op; /* Perform device-specific initialisation and get CQN */ if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) { @@ -195,9 +193,6 @@ int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp, * @v qp Queue pair */ void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) { - struct ib_completion completion = { - .syndrome = IB_SYN_LOCAL_QP, - }; struct io_buffer *iobuf; unsigned int i; @@ -210,11 +205,13 @@ void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) { /* Complete any remaining I/O buffers with errors */ for ( i = 0 ; i < qp->send.num_wqes ; i++ ) { if ( ( iobuf = qp->send.iobufs[i] ) != NULL ) - ib_complete_send ( ibdev, qp, &completion, iobuf ); + ib_complete_send ( ibdev, qp, iobuf, -ECANCELED ); } for ( i = 0 ; i < qp->recv.num_wqes ; i++ ) { - if ( ( iobuf = qp->recv.iobufs[i] ) != NULL ) - ib_complete_recv ( ibdev, qp, &completion, iobuf ); + if ( ( iobuf = qp->recv.iobufs[i] ) != NULL ) { + ib_complete_recv ( ibdev, qp, NULL, iobuf, + -ECANCELED ); + } } /* Remove work queues from completion queue */ @@ -254,7 +251,8 @@ struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq, * @ret rc Return status code */ int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, - struct ib_address_vector *av, struct io_buffer *iobuf ) { + struct ib_address_vector *av, + struct io_buffer *iobuf ) { int rc; /* Check queue fill level */ @@ -310,13 +308,12 @@ int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, * * @v ibdev Infiniband device * @v qp Queue pair - * @v completion Completion * @v iobuf I/O buffer + * @v rc Completion status code */ void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ) { - qp->send.cq->complete_send ( ibdev, qp, completion, iobuf ); + struct io_buffer *iobuf, int rc ) { + qp->send.cq->op->complete_send ( ibdev, qp, iobuf, rc ); qp->send.fill--; } @@ -325,13 +322,14 @@ void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, * * @v ibdev Infiniband device * @v qp Queue pair - * @v completion Completion + * @v av Address vector * @v iobuf I/O buffer + * @v rc Completion status code */ void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, - struct ib_completion *completion, - struct io_buffer *iobuf ) { - qp->recv.cq->complete_recv ( ibdev, qp, completion, iobuf ); + struct ib_address_vector *av, + struct io_buffer *iobuf, int rc ) { + qp->recv.cq->op->complete_recv ( ibdev, qp, av, iobuf, rc ); qp->recv.fill--; } |