diff options
Diffstat (limited to 'src/drivers')
| -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 |
3 files changed, 101 insertions, 104 deletions
diff --git a/src/drivers/infiniband/arbel.c b/src/drivers/infiniband/arbel.c index 2649a4aba..8a31ad8b1 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 a8907634f..db7619ad8 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 551230067..aa68fe388 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 ) ); |
