diff options
Diffstat (limited to 'src/net')
| -rw-r--r-- | src/net/infiniband.c | 55 | ||||
| -rw-r--r-- | src/net/infiniband/ib_gma.c | 24 | ||||
| -rw-r--r-- | src/net/infiniband/ib_mcast.c | 3 | ||||
| -rw-r--r-- | src/net/infiniband/ib_packet.c | 2 |
4 files changed, 66 insertions, 18 deletions
diff --git a/src/net/infiniband.c b/src/net/infiniband.c index 513e40c9a..96a663c88 100644 --- a/src/net/infiniband.c +++ b/src/net/infiniband.c @@ -149,16 +149,17 @@ void ib_poll_cq ( struct ib_device *ibdev, * @v send_cq Send completion queue * @v num_recv_wqes Number of receive work queue entries * @v recv_cq Receive completion queue - * @v qkey Queue key * @ret qp Queue pair + * + * The queue pair will be left in the INIT state; you must call + * ib_modify_qp() before it is ready to use for sending and receiving. */ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type, unsigned int num_send_wqes, struct ib_completion_queue *send_cq, unsigned int num_recv_wqes, - struct ib_completion_queue *recv_cq, - unsigned long qkey ) { + struct ib_completion_queue *recv_cq ) { struct ib_queue_pair *qp; size_t total_size; int rc; @@ -175,16 +176,17 @@ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev, qp->ibdev = ibdev; list_add ( &qp->list, &ibdev->qps ); qp->type = type; - qp->qkey = qkey; qp->send.qp = qp; qp->send.is_send = 1; qp->send.cq = send_cq; list_add ( &qp->send.list, &send_cq->work_queues ); + qp->send.psn = ( random() & 0xffffffUL ); qp->send.num_wqes = num_send_wqes; qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) ); qp->recv.qp = qp; qp->recv.cq = recv_cq; list_add ( &qp->recv.list, &recv_cq->work_queues ); + qp->recv.psn = ( random() & 0xffffffUL ); qp->recv.num_wqes = num_recv_wqes; qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) + ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) )); @@ -239,20 +241,15 @@ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev, * * @v ibdev Infiniband device * @v qp Queue pair - * @v mod_list Modification list - * @v qkey New queue key, if applicable + * @v av New address vector, if applicable * @ret rc Return status code */ -int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp, - unsigned long mod_list, unsigned long qkey ) { +int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) { int rc; DBGC ( ibdev, "IBDEV %p modifying QPN %#lx\n", ibdev, qp->qpn ); - if ( mod_list & IB_MODIFY_QKEY ) - qp->qkey = qkey; - - if ( ( rc = ibdev->op->modify_qp ( ibdev, qp, mod_list ) ) != 0 ) { + if ( ( rc = ibdev->op->modify_qp ( ibdev, qp ) ) != 0 ) { DBGC ( ibdev, "IBDEV %p could not modify QPN %#lx: %s\n", ibdev, qp->qpn, strerror ( rc ) ); return rc; @@ -372,6 +369,7 @@ struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq, 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_copy; int rc; /* Check queue fill level */ @@ -381,6 +379,14 @@ int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, return -ENOBUFS; } + /* Use default address vector if none specified */ + if ( ! av ) + av = &qp->av; + + /* Make modifiable copy of address vector */ + memcpy ( &av_copy, av, sizeof ( av_copy ) ); + av = &av_copy; + /* Fill in optional parameters in address vector */ if ( ! av->qkey ) av->qkey = qp->qkey; @@ -712,6 +718,31 @@ int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ) { return 0; }; +/** + * Set partition key table + * + * @v ibdev Infiniband device + * @v mad Set partition key table MAD + */ +int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ) { + int rc; + + /* Adapters with embedded SMAs do not need to support this method */ + if ( ! ibdev->op->set_pkey_table ) { + DBGC ( ibdev, "IBDEV %p does not support setting partition " + "key table\n", ibdev ); + return -ENOTSUP; + } + + if ( ( rc = ibdev->op->set_pkey_table ( ibdev, mad ) ) != 0 ) { + DBGC ( ibdev, "IBDEV %p could not set partition key table: " + "%s\n", ibdev, strerror ( rc ) ); + return rc; + } + + return 0; +}; + /*************************************************************************** * * Event queues diff --git a/src/net/infiniband/ib_gma.c b/src/net/infiniband/ib_gma.c index 679de6f11..174b8845a 100644 --- a/src/net/infiniband/ib_gma.c +++ b/src/net/infiniband/ib_gma.c @@ -296,8 +296,17 @@ static union ib_mad * ib_sma_set_pkey_table ( struct ib_gma *gma, union ib_mad *mad ) { struct ib_device *ibdev = gma->ibdev; struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table; + int rc; ibdev->pkey = ntohs ( pkey_table->pkey[0] ); + DBGC ( gma, "GMA %p set pkey %04x\n", gma, ibdev->pkey ); + + if ( ( rc = ib_set_pkey_table ( ibdev, mad ) ) != 0 ) { + DBGC ( gma, "GMA %p could not set pkey table: %s\n", + gma, strerror ( rc ) ); + mad->hdr.status = + htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); + } return ib_sma_get_pkey_table ( gma, mad ); } @@ -618,7 +627,7 @@ int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad, struct ib_gma * ib_create_gma ( struct ib_device *ibdev, enum ib_queue_pair_type type ) { struct ib_gma *gma; - unsigned long qkey; + int rc; /* Allocate and initialise fields */ gma = zalloc ( sizeof ( *gma ) ); @@ -637,21 +646,28 @@ struct ib_gma * ib_create_gma ( struct ib_device *ibdev, } /* Create queue pair */ - qkey = ( ( type == IB_QPT_SMA ) ? IB_QKEY_SMA : IB_QKEY_GMA ); gma->qp = ib_create_qp ( ibdev, type, IB_GMA_NUM_SEND_WQES, gma->cq, - IB_GMA_NUM_RECV_WQES, gma->cq, qkey ); + IB_GMA_NUM_RECV_WQES, gma->cq ); if ( ! gma->qp ) { DBGC ( gma, "GMA %p could not allocate queue pair\n", gma ); goto err_create_qp; } ib_qp_set_ownerdata ( gma->qp, gma ); - DBGC ( gma, "GMA %p running on QPN %#lx\n", gma, gma->qp->qpn ); + /* Set queue key */ + gma->qp->qkey = ( ( type == IB_QPT_SMA ) ? IB_QKEY_SMA : IB_QKEY_GMA ); + if ( ( rc = ib_modify_qp ( ibdev, gma->qp ) ) != 0 ) { + DBGC ( gma, "GMA %p could not set queue key: %s\n", + gma, strerror ( rc ) ); + goto err_modify_qp; + } + /* Fill receive ring */ ib_refill_recv ( ibdev, gma->qp ); return gma; + err_modify_qp: ib_destroy_qp ( ibdev, gma->qp ); err_create_qp: ib_destroy_cq ( ibdev, gma->cq ); diff --git a/src/net/infiniband/ib_mcast.c b/src/net/infiniband/ib_mcast.c index 6e3026e5e..58e555ade 100644 --- a/src/net/infiniband/ib_mcast.c +++ b/src/net/infiniband/ib_mcast.c @@ -178,7 +178,8 @@ static union ib_mad * ib_handle_mc_member_join ( struct ib_gma *gma, ntohl ( gid->u.dwords[3] ), qkey ); /* Set queue key */ - if ( ( rc = ib_modify_qp ( ibdev, qp, IB_MODIFY_QKEY, qkey ) ) != 0 ) { + qp->qkey = qkey; + if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) { DBGC ( gma, "GMA %p QPN %lx could not modify qkey: %s\n", gma, qp->qpn, strerror ( rc ) ); return NULL; diff --git a/src/net/infiniband/ib_packet.c b/src/net/infiniband/ib_packet.c index 689e00dce..42ff3499c 100644 --- a/src/net/infiniband/ib_packet.c +++ b/src/net/infiniband/ib_packet.c @@ -100,7 +100,7 @@ int ib_push ( struct ib_device *ibdev, struct io_buffer *iobuf, bth->se__m__padcnt__tver = ( pad_len << 4 ); bth->pkey = htons ( ibdev->pkey ); bth->dest_qp = htonl ( av->qpn ); - bth->ack__psn = htonl ( ( ibdev->psn++ ) & 0xffffffUL ); + bth->ack__psn = htonl ( ( qp->send.psn++ ) & 0xffffffUL ); /* Construct DETH */ deth->qkey = htonl ( av->qkey ); |
