summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/infiniband.c55
-rw-r--r--src/net/infiniband/ib_gma.c24
-rw-r--r--src/net/infiniband/ib_mcast.c3
-rw-r--r--src/net/infiniband/ib_packet.c2
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 );