infiniband.c File Reference

Infiniband protocol. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <byteswap.h>
#include <errno.h>
#include <assert.h>
#include <gpxe/list.h>
#include <gpxe/errortab.h>
#include <gpxe/if_arp.h>
#include <gpxe/netdevice.h>
#include <gpxe/iobuf.h>
#include <gpxe/ipoib.h>
#include <gpxe/process.h>
#include <gpxe/infiniband.h>
#include <gpxe/ib_mi.h>
#include <gpxe/ib_sma.h>

Go to the source code of this file.

Defines

#define EINPROGRESS_INIT   ( EINPROGRESS | EUNIQ_01 )
#define EINPROGRESS_ARMED   ( EINPROGRESS | EUNIQ_02 )

Functions

 FILE_LICENCE (GPL2_OR_LATER)
struct ib_completion_queueib_create_cq (struct ib_device *ibdev, unsigned int num_cqes, struct ib_completion_queue_operations *op)
 Create completion queue.
void ib_destroy_cq (struct ib_device *ibdev, struct ib_completion_queue *cq)
 Destroy completion queue.
void ib_poll_cq (struct ib_device *ibdev, struct ib_completion_queue *cq)
 Poll completion queue.
struct ib_queue_pairib_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)
 Create queue pair.
int ib_modify_qp (struct ib_device *ibdev, struct ib_queue_pair *qp)
 Modify queue pair.
void ib_destroy_qp (struct ib_device *ibdev, struct ib_queue_pair *qp)
 Destroy queue pair.
struct ib_queue_pairib_find_qp_qpn (struct ib_device *ibdev, unsigned long qpn)
 Find queue pair by QPN.
struct ib_queue_pairib_find_qp_mgid (struct ib_device *ibdev, struct ib_gid *gid)
 Find queue pair by multicast GID.
struct ib_work_queueib_find_wq (struct ib_completion_queue *cq, unsigned long qpn, int is_send)
 Find work queue belonging to completion queue.
int ib_post_send (struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf)
 Post send work queue entry.
int ib_post_recv (struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf)
 Post receive work queue entry.
void ib_complete_send (struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc)
 Complete send work queue entry.
void ib_complete_recv (struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, int rc)
 Complete receive work queue entry.
void ib_refill_recv (struct ib_device *ibdev, struct ib_queue_pair *qp)
 Refill receive work queue.
int ib_open (struct ib_device *ibdev)
 Open port.
void ib_close (struct ib_device *ibdev)
 Close port.
int ib_link_rc (struct ib_device *ibdev)
 Get link state.
int ib_mcast_attach (struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid)
 Attach to multicast group.
void ib_mcast_detach (struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid)
 Detach from multicast group.
int ib_get_hca_info (struct ib_device *ibdev, struct ib_gid_half *hca_guid)
 Get Infiniband HCA information.
int ib_set_port_info (struct ib_device *ibdev, union ib_mad *mad)
 Set port information.
int ib_set_pkey_table (struct ib_device *ibdev, union ib_mad *mad)
 Set partition key table.
void ib_link_state_changed (struct ib_device *ibdev)
 Handle Infiniband link state change.
void ib_poll_eq (struct ib_device *ibdev)
 Poll event queue.
static void ib_step (struct process *process __unused)
 Single-step the Infiniband event queue.
struct ib_devicealloc_ibdev (size_t priv_size)
 Allocate Infiniband device.
int register_ibdev (struct ib_device *ibdev)
 Register Infiniband device.
void unregister_ibdev (struct ib_device *ibdev)
 Unregister Infiniband device.
struct ib_devicefind_ibdev (struct ib_gid *gid)
 Find Infiniband device by GID.
struct ib_devicelast_opened_ibdev (void)
 Get most recently opened Infiniband device.

Variables

struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices )
 List of Infiniband devices.
static struct list_head open_ib_devices = LIST_HEAD_INIT ( open_ib_devices )
 List of open Infiniband devices, in reverse order of opening.
struct errortab infiniband_errors[] __errortab
 Human-readable message for the link statuses.
struct process ib_process __permanent_process
 Infiniband event queue process.


Detailed Description

Infiniband protocol.

Definition in file infiniband.c.


Define Documentation

#define EINPROGRESS_INIT   ( EINPROGRESS | EUNIQ_01 )

Definition at line 53 of file infiniband.c.

Referenced by ib_link_rc().

#define EINPROGRESS_ARMED   ( EINPROGRESS | EUNIQ_02 )

Definition at line 54 of file infiniband.c.

Referenced by ib_link_rc().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

struct ib_completion_queue* ib_create_cq ( struct ib_device ibdev,
unsigned int  num_cqes,
struct ib_completion_queue_operations op 
) [read]

Create completion queue.

Parameters:
ibdev Infiniband device
num_cqes Number of completion queue entries
op Completion queue operations
Return values:
cq New completion queue

Definition at line 78 of file infiniband.c.

References ib_completion_queue::cqn, ib_device::cqs, ib_device_operations::create_cq, DBGC, ib_device_operations::destroy_cq, free(), ib_cq_get_drvdata(), ib_completion_queue::ibdev, INIT_LIST_HEAD, ib_completion_queue::list, list_add, list_del, NULL, ib_completion_queue::num_cqes, ib_device::op, ib_completion_queue::op, strerror(), ib_completion_queue::work_queues, and zalloc().

Referenced by ib_cmrc_open(), ib_create_mi(), and ipoib_open().

00079                                                            {
00080         struct ib_completion_queue *cq;
00081         int rc;
00082 
00083         DBGC ( ibdev, "IBDEV %p creating completion queue\n", ibdev );
00084 
00085         /* Allocate and initialise data structure */
00086         cq = zalloc ( sizeof ( *cq ) );
00087         if ( ! cq )
00088                 goto err_alloc_cq;
00089         cq->ibdev = ibdev;
00090         list_add ( &cq->list, &ibdev->cqs );
00091         cq->num_cqes = num_cqes;
00092         INIT_LIST_HEAD ( &cq->work_queues );
00093         cq->op = op;
00094 
00095         /* Perform device-specific initialisation and get CQN */
00096         if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
00097                 DBGC ( ibdev, "IBDEV %p could not initialise completion "
00098                        "queue: %s\n", ibdev, strerror ( rc ) );
00099                 goto err_dev_create_cq;
00100         }
00101 
00102         DBGC ( ibdev, "IBDEV %p created %d-entry completion queue %p (%p) "
00103                "with CQN %#lx\n", ibdev, num_cqes, cq,
00104                ib_cq_get_drvdata ( cq ), cq->cqn );
00105         return cq;
00106 
00107         ibdev->op->destroy_cq ( ibdev, cq );
00108  err_dev_create_cq:
00109         list_del ( &cq->list );
00110         free ( cq );
00111  err_alloc_cq:
00112         return NULL;
00113 }

void ib_destroy_cq ( struct ib_device ibdev,
struct ib_completion_queue cq 
)

Destroy completion queue.

Parameters:
ibdev Infiniband device
cq Completion queue

Definition at line 121 of file infiniband.c.

References assert, ib_completion_queue::cqn, DBGC, ib_device_operations::destroy_cq, free(), ib_completion_queue::list, list_del, list_empty(), ib_device::op, and ib_completion_queue::work_queues.

Referenced by ib_cmrc_open(), ib_cmrc_shutdown(), ib_create_mi(), ib_destroy_mi(), ipoib_close(), and ipoib_open().

00122                                                       {
00123         DBGC ( ibdev, "IBDEV %p destroying completion queue %#lx\n",
00124                ibdev, cq->cqn );
00125         assert ( list_empty ( &cq->work_queues ) );
00126         ibdev->op->destroy_cq ( ibdev, cq );
00127         list_del ( &cq->list );
00128         free ( cq );
00129 }

void ib_poll_cq ( struct ib_device ibdev,
struct ib_completion_queue cq 
)

Poll completion queue.

Parameters:
ibdev Infiniband device
cq Completion queue

Definition at line 137 of file infiniband.c.

References ib_refill_recv(), ib_work_queue::is_send, ib_work_queue::list, list_for_each_entry, ib_device::op, ib_device_operations::poll_cq, ib_work_queue::qp, and ib_completion_queue::work_queues.

Referenced by ib_poll_eq().

00138                                                    {
00139         struct ib_work_queue *wq;
00140 
00141         /* Poll completion queue */
00142         ibdev->op->poll_cq ( ibdev, cq );
00143 
00144         /* Refill receive work queues */
00145         list_for_each_entry ( wq, &cq->work_queues, list ) {
00146                 if ( ! wq->is_send )
00147                         ib_refill_recv ( ibdev, wq->qp );
00148         }
00149 }

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 
) [read]

Create queue pair.

Parameters:
ibdev Infiniband device
type Queue pair type
num_send_wqes Number of send work queue entries
send_cq Send completion queue
num_recv_wqes Number of receive work queue entries
recv_cq Receive completion queue
Return values:
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.

Definition at line 172 of file infiniband.c.

References ib_work_queue::cq, ib_device_operations::create_qp, DBGC, ib_device_operations::destroy_qp, free(), ib_qp_get_drvdata(), IB_QPN_GSI, IB_QPN_SMI, IB_QPT_GSI, IB_QPT_SMI, ib_queue_pair::ibdev, INIT_LIST_HEAD, ib_work_queue::iobufs, ib_work_queue::is_send, ib_work_queue::list, ib_queue_pair::list, list_add, list_del, ib_queue_pair::mgids, NULL, ib_work_queue::num_wqes, ib_device::op, ib_work_queue::psn, ib_work_queue::qp, ib_queue_pair::qpn, ib_device::qps, random(), ib_queue_pair::recv, ib_queue_pair::send, strerror(), ib_queue_pair::type, ib_completion_queue::work_queues, and zalloc().

Referenced by ib_cmrc_open(), ib_create_mi(), and ipoib_open().

00177                                                                             {
00178         struct ib_queue_pair *qp;
00179         size_t total_size;
00180         int rc;
00181 
00182         DBGC ( ibdev, "IBDEV %p creating queue pair\n", ibdev );
00183 
00184         /* Allocate and initialise data structure */
00185         total_size = ( sizeof ( *qp ) +
00186                        ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ) +
00187                        ( num_recv_wqes * sizeof ( qp->recv.iobufs[0] ) ) );
00188         qp = zalloc ( total_size );
00189         if ( ! qp )
00190                 goto err_alloc_qp;
00191         qp->ibdev = ibdev;
00192         list_add ( &qp->list, &ibdev->qps );
00193         qp->type = type;
00194         qp->send.qp = qp;
00195         qp->send.is_send = 1;
00196         qp->send.cq = send_cq;
00197         list_add ( &qp->send.list, &send_cq->work_queues );
00198         qp->send.psn = ( random() & 0xffffffUL );
00199         qp->send.num_wqes = num_send_wqes;
00200         qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) );
00201         qp->recv.qp = qp;
00202         qp->recv.cq = recv_cq;
00203         list_add ( &qp->recv.list, &recv_cq->work_queues );
00204         qp->recv.psn = ( random() & 0xffffffUL );
00205         qp->recv.num_wqes = num_recv_wqes;
00206         qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) +
00207                             ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ));
00208         INIT_LIST_HEAD ( &qp->mgids );
00209 
00210         /* Perform device-specific initialisation and get QPN */
00211         if ( ( rc = ibdev->op->create_qp ( ibdev, qp ) ) != 0 ) {
00212                 DBGC ( ibdev, "IBDEV %p could not initialise queue pair: "
00213                        "%s\n", ibdev, strerror ( rc ) );
00214                 goto err_dev_create_qp;
00215         }
00216         DBGC ( ibdev, "IBDEV %p created queue pair %p (%p) with QPN %#lx\n",
00217                ibdev, qp, ib_qp_get_drvdata ( qp ), qp->qpn );
00218         DBGC ( ibdev, "IBDEV %p QPN %#lx has %d send entries at [%p,%p)\n",
00219                ibdev, qp->qpn, num_send_wqes, qp->send.iobufs,
00220                qp->recv.iobufs );
00221         DBGC ( ibdev, "IBDEV %p QPN %#lx has %d receive entries at [%p,%p)\n",
00222                ibdev, qp->qpn, num_recv_wqes, qp->recv.iobufs,
00223                ( ( ( void * ) qp ) + total_size ) );
00224 
00225         /* Calculate externally-visible QPN */
00226         switch ( type ) {
00227         case IB_QPT_SMI:
00228                 qp->ext_qpn = IB_QPN_SMI;
00229                 break;
00230         case IB_QPT_GSI:
00231                 qp->ext_qpn = IB_QPN_GSI;
00232                 break;
00233         default:
00234                 qp->ext_qpn = qp->qpn;
00235                 break;
00236         }
00237         if ( qp->ext_qpn != qp->qpn ) {
00238                 DBGC ( ibdev, "IBDEV %p QPN %#lx has external QPN %#lx\n",
00239                        ibdev, qp->qpn, qp->ext_qpn );
00240         }
00241 
00242         return qp;
00243 
00244         ibdev->op->destroy_qp ( ibdev, qp );
00245  err_dev_create_qp:
00246         list_del ( &qp->send.list );
00247         list_del ( &qp->recv.list );
00248         list_del ( &qp->list );
00249         free ( qp );
00250  err_alloc_qp:
00251         return NULL;
00252 }

int ib_modify_qp ( struct ib_device ibdev,
struct ib_queue_pair qp 
)

Modify queue pair.

Parameters:
ibdev Infiniband device
qp Queue pair
av New address vector, if applicable
Return values:
rc Return status code

Definition at line 262 of file infiniband.c.

References DBGC, ib_device_operations::modify_qp, ib_device::op, ib_queue_pair::qpn, and strerror().

Referenced by ib_cm_req_complete(), ib_create_mi(), and ib_mcast_complete().

00262                                                                        {
00263         int rc;
00264 
00265         DBGC ( ibdev, "IBDEV %p modifying QPN %#lx\n", ibdev, qp->qpn );
00266 
00267         if ( ( rc = ibdev->op->modify_qp ( ibdev, qp ) ) != 0 ) {
00268                 DBGC ( ibdev, "IBDEV %p could not modify QPN %#lx: %s\n",
00269                        ibdev, qp->qpn, strerror ( rc ) );
00270                 return rc;
00271         }
00272 
00273         return 0;
00274 }

void ib_destroy_qp ( struct ib_device ibdev,
struct ib_queue_pair qp 
)

Destroy queue pair.

Parameters:
ibdev Infiniband device
qp Queue pair

Definition at line 282 of file infiniband.c.

References assert, DBGC, ib_device_operations::destroy_qp, ECANCELED, free(), ib_complete_recv(), ib_complete_send(), ib_work_queue::iobufs, ib_queue_pair::list, ib_work_queue::list, list_del, list_empty(), ib_queue_pair::mgids, NULL, ib_work_queue::num_wqes, ib_device::op, ib_queue_pair::qpn, ib_queue_pair::recv, and ib_queue_pair::send.

Referenced by ib_cmrc_open(), ib_cmrc_shutdown(), ib_create_mi(), ib_destroy_mi(), ipoib_close(), and ipoib_open().

00282                                                                          {
00283         struct io_buffer *iobuf;
00284         unsigned int i;
00285 
00286         DBGC ( ibdev, "IBDEV %p destroying QPN %#lx\n",
00287                ibdev, qp->qpn );
00288 
00289         assert ( list_empty ( &qp->mgids ) );
00290 
00291         /* Perform device-specific destruction */
00292         ibdev->op->destroy_qp ( ibdev, qp );
00293 
00294         /* Complete any remaining I/O buffers with errors */
00295         for ( i = 0 ; i < qp->send.num_wqes ; i++ ) {
00296                 if ( ( iobuf = qp->send.iobufs[i] ) != NULL )
00297                         ib_complete_send ( ibdev, qp, iobuf, -ECANCELED );
00298         }
00299         for ( i = 0 ; i < qp->recv.num_wqes ; i++ ) {
00300                 if ( ( iobuf = qp->recv.iobufs[i] ) != NULL ) {
00301                         ib_complete_recv ( ibdev, qp, NULL, iobuf,
00302                                            -ECANCELED );
00303                 }
00304         }
00305 
00306         /* Remove work queues from completion queue */
00307         list_del ( &qp->send.list );
00308         list_del ( &qp->recv.list );
00309 
00310         /* Free QP */
00311         list_del ( &qp->list );
00312         free ( qp );
00313 }

struct ib_queue_pair* ib_find_qp_qpn ( struct ib_device ibdev,
unsigned long  qpn 
) [read]

Find queue pair by QPN.

Parameters:
ibdev Infiniband device
qpn Queue pair number
Return values:
qp Queue pair, or NULL

Definition at line 322 of file infiniband.c.

References ib_queue_pair::ext_qpn, ib_queue_pair::list, list_for_each_entry, NULL, ib_queue_pair::qpn, and ib_device::qps.

Referenced by ib_pull().

00323                                                             {
00324         struct ib_queue_pair *qp;
00325 
00326         list_for_each_entry ( qp, &ibdev->qps, list ) {
00327                 if ( ( qpn == qp->qpn ) || ( qpn == qp->ext_qpn ) )
00328                         return qp;
00329         }
00330         return NULL;
00331 }

struct ib_queue_pair* ib_find_qp_mgid ( struct ib_device ibdev,
struct ib_gid gid 
) [read]

Find queue pair by multicast GID.

Parameters:
ibdev Infiniband device
gid Multicast GID
Return values:
qp Queue pair, or NULL

Definition at line 340 of file infiniband.c.

References ib_multicast_gid::gid, ib_multicast_gid::list, list_for_each_entry, memcmp(), ib_queue_pair::mgids, NULL, and ib_device::qps.

Referenced by ib_pull().

00341                                                               {
00342         struct ib_queue_pair *qp;
00343         struct ib_multicast_gid *mgid;
00344 
00345         list_for_each_entry ( qp, &ibdev->qps, list ) {
00346                 list_for_each_entry ( mgid, &qp->mgids, list ) {
00347                         if ( memcmp ( &mgid->gid, gid,
00348                                       sizeof ( mgid->gid ) ) == 0 ) {
00349                                 return qp;
00350                         }
00351                 }
00352         }
00353         return NULL;
00354 }

struct ib_work_queue* ib_find_wq ( struct ib_completion_queue cq,
unsigned long  qpn,
int  is_send 
) [read]

Find work queue belonging to completion queue.

Parameters:
cq Completion queue
qpn Queue pair number
is_send Find send work queue (rather than receive)
Return values:
wq Work queue, or NULL if not found

Definition at line 364 of file infiniband.c.

References ib_work_queue::is_send, ib_work_queue::list, list_for_each_entry, NULL, ib_work_queue::qp, ib_queue_pair::qpn, and ib_completion_queue::work_queues.

Referenced by arbel_complete(), and hermon_complete().

00365                                                                      {
00366         struct ib_work_queue *wq;
00367 
00368         list_for_each_entry ( wq, &cq->work_queues, list ) {
00369                 if ( ( wq->qp->qpn == qpn ) && ( wq->is_send == is_send ) )
00370                         return wq;
00371         }
00372         return NULL;
00373 }

int ib_post_send ( struct ib_device ibdev,
struct ib_queue_pair qp,
struct ib_address_vector av,
struct io_buffer iobuf 
)

Post send work queue entry.

Parameters:
ibdev Infiniband device
qp Queue pair
av Address vector
iobuf I/O buffer
Return values:
rc Return status code

Definition at line 384 of file infiniband.c.

References ib_queue_pair::av, DBGC, ENOBUFS, ib_work_queue::fill, IB_RATE_2_5, memcpy, ib_work_queue::num_wqes, ib_device::op, ib_device_operations::post_send, ib_queue_pair::qkey, ib_address_vector::qkey, ib_queue_pair::qpn, ib_address_vector::rate, ib_queue_pair::send, and strerror().

Referenced by ib_cmrc_xfer_deliver_iob(), ib_mi_send(), and ipoib_transmit().

00386                                              {
00387         struct ib_address_vector av_copy;
00388         int rc;
00389 
00390         /* Check queue fill level */
00391         if ( qp->send.fill >= qp->send.num_wqes ) {
00392                 DBGC ( ibdev, "IBDEV %p QPN %#lx send queue full\n",
00393                        ibdev, qp->qpn );
00394                 return -ENOBUFS;
00395         }
00396 
00397         /* Use default address vector if none specified */
00398         if ( ! av )
00399                 av = &qp->av;
00400 
00401         /* Make modifiable copy of address vector */
00402         memcpy ( &av_copy, av, sizeof ( av_copy ) );
00403         av = &av_copy;
00404 
00405         /* Fill in optional parameters in address vector */
00406         if ( ! av->qkey )
00407                 av->qkey = qp->qkey;
00408         if ( ! av->rate )
00409                 av->rate = IB_RATE_2_5;
00410 
00411         /* Post to hardware */
00412         if ( ( rc = ibdev->op->post_send ( ibdev, qp, av, iobuf ) ) != 0 ) {
00413                 DBGC ( ibdev, "IBDEV %p QPN %#lx could not post send WQE: "
00414                        "%s\n", ibdev, qp->qpn, strerror ( rc ) );
00415                 return rc;
00416         }
00417 
00418         qp->send.fill++;
00419         return 0;
00420 }

int ib_post_recv ( struct ib_device ibdev,
struct ib_queue_pair qp,
struct io_buffer iobuf 
)

Post receive work queue entry.

Parameters:
ibdev Infiniband device
qp Queue pair
iobuf I/O buffer
Return values:
rc Return status code

Definition at line 430 of file infiniband.c.

References DBGC, EINVAL, ENOBUFS, ib_work_queue::fill, IB_MAX_PAYLOAD_SIZE, iob_tailroom(), ib_work_queue::num_wqes, ib_device::op, ib_device_operations::post_recv, ib_queue_pair::qpn, ib_queue_pair::recv, and strerror().

Referenced by ib_refill_recv().

00431                                              {
00432         int rc;
00433 
00434         /* Check packet length */
00435         if ( iob_tailroom ( iobuf ) < IB_MAX_PAYLOAD_SIZE ) {
00436                 DBGC ( ibdev, "IBDEV %p QPN %#lx wrong RX buffer size (%zd)\n",
00437                        ibdev, qp->qpn, iob_tailroom ( iobuf ) );
00438                 return -EINVAL;
00439         }
00440 
00441         /* Check queue fill level */
00442         if ( qp->recv.fill >= qp->recv.num_wqes ) {
00443                 DBGC ( ibdev, "IBDEV %p QPN %#lx receive queue full\n",
00444                        ibdev, qp->qpn );
00445                 return -ENOBUFS;
00446         }
00447 
00448         /* Post to hardware */
00449         if ( ( rc = ibdev->op->post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
00450                 DBGC ( ibdev, "IBDEV %p QPN %#lx could not post receive WQE: "
00451                        "%s\n", ibdev, qp->qpn, strerror ( rc ) );
00452                 return rc;
00453         }
00454 
00455         qp->recv.fill++;
00456         return 0;
00457 }

void ib_complete_send ( struct ib_device ibdev,
struct ib_queue_pair qp,
struct io_buffer iobuf,
int  rc 
)

Complete send work queue entry.

Parameters:
ibdev Infiniband device
qp Queue pair
iobuf I/O buffer
rc Completion status code

Definition at line 467 of file infiniband.c.

References ib_completion_queue_operations::complete_send, ib_work_queue::cq, ib_work_queue::fill, free_iob(), ib_completion_queue::op, and ib_queue_pair::send.

Referenced by arbel_complete(), hermon_complete(), ib_destroy_qp(), and linda_complete_send().

00468                                                           {
00469 
00470         if ( qp->send.cq->op->complete_send ) {
00471                 qp->send.cq->op->complete_send ( ibdev, qp, iobuf, rc );
00472         } else {
00473                 free_iob ( iobuf );
00474         }
00475         qp->send.fill--;
00476 }

void ib_complete_recv ( struct ib_device ibdev,
struct ib_queue_pair qp,
struct ib_address_vector av,
struct io_buffer iobuf,
int  rc 
)

Complete receive work queue entry.

Parameters:
ibdev Infiniband device
qp Queue pair
av Address vector
iobuf I/O buffer
rc Completion status code

Definition at line 487 of file infiniband.c.

References ib_completion_queue_operations::complete_recv, ib_work_queue::cq, ib_work_queue::fill, free_iob(), ib_completion_queue::op, and ib_queue_pair::recv.

Referenced by arbel_complete(), hermon_complete(), ib_destroy_qp(), and linda_complete_recv().

00489                                                           {
00490 
00491         if ( qp->recv.cq->op->complete_recv ) {
00492                 qp->recv.cq->op->complete_recv ( ibdev, qp, av, iobuf, rc );
00493         } else {
00494                 free_iob ( iobuf );
00495         }
00496         qp->recv.fill--;
00497 }

void ib_refill_recv ( struct ib_device ibdev,
struct ib_queue_pair qp 
)

Refill receive work queue.

Parameters:
ibdev Infiniband device
qp Queue pair

Definition at line 505 of file infiniband.c.

References alloc_iob(), DBGC, ib_work_queue::fill, free_iob(), IB_MAX_PAYLOAD_SIZE, ib_post_recv(), ib_work_queue::num_wqes, ib_queue_pair::recv, and strerror().

Referenced by ib_create_mi(), ib_poll_cq(), and ipoib_open().

00505                                                                           {
00506         struct io_buffer *iobuf;
00507         int rc;
00508 
00509         /* Keep filling while unfilled entries remain */
00510         while ( qp->recv.fill < qp->recv.num_wqes ) {
00511 
00512                 /* Allocate I/O buffer */
00513                 iobuf = alloc_iob ( IB_MAX_PAYLOAD_SIZE );
00514                 if ( ! iobuf ) {
00515                         /* Non-fatal; we will refill on next attempt */
00516                         return;
00517                 }
00518 
00519                 /* Post I/O buffer */
00520                 if ( ( rc = ib_post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
00521                         DBGC ( ibdev, "IBDEV %p could not refill: %s\n",
00522                                ibdev, strerror ( rc ) );
00523                         free_iob ( iobuf );
00524                         /* Give up */
00525                         return;
00526                 }
00527         }
00528 }

int ib_open ( struct ib_device ibdev  ) 

Open port.

Parameters:
ibdev Infiniband device
Return values:
rc Return status code

Definition at line 543 of file infiniband.c.

References assert, ib_device_operations::close, DBGC, ENOMEM, ib_device::gsi, ib_create_mi(), ib_create_sma(), ib_destroy_mi(), ib_destroy_sma(), IB_QPT_GSI, IB_QPT_SMI, list_add, ib_device::op, ib_device_operations::open, ib_device::open_count, ib_device::open_list, ib_device::smi, and strerror().

Referenced by ib_cmrc_open(), and ipoib_open().

00543                                         {
00544         int rc;
00545 
00546         /* Increment device open request counter */
00547         if ( ibdev->open_count++ > 0 ) {
00548                 /* Device was already open; do nothing */
00549                 return 0;
00550         }
00551 
00552         /* Create subnet management interface */
00553         ibdev->smi = ib_create_mi ( ibdev, IB_QPT_SMI );
00554         if ( ! ibdev->smi ) {
00555                 DBGC ( ibdev, "IBDEV %p could not create SMI\n", ibdev );
00556                 rc = -ENOMEM;
00557                 goto err_create_smi;
00558         }
00559 
00560         /* Create subnet management agent */
00561         if ( ( rc = ib_create_sma ( ibdev, ibdev->smi ) ) != 0 ) {
00562                 DBGC ( ibdev, "IBDEV %p could not create SMA: %s\n",
00563                        ibdev, strerror ( rc ) );
00564                 goto err_create_sma;
00565         }
00566 
00567         /* Create general services interface */
00568         ibdev->gsi = ib_create_mi ( ibdev, IB_QPT_GSI );
00569         if ( ! ibdev->gsi ) {
00570                 DBGC ( ibdev, "IBDEV %p could not create GSI\n", ibdev );
00571                 rc = -ENOMEM;
00572                 goto err_create_gsi;
00573         }
00574 
00575         /* Open device */
00576         if ( ( rc = ibdev->op->open ( ibdev ) ) != 0 ) {
00577                 DBGC ( ibdev, "IBDEV %p could not open: %s\n",
00578                        ibdev, strerror ( rc ) );
00579                 goto err_open;
00580         }
00581 
00582         /* Add to head of open devices list */
00583         list_add ( &ibdev->open_list, &open_ib_devices );
00584 
00585         assert ( ibdev->open_count == 1 );
00586         return 0;
00587 
00588         ibdev->op->close ( ibdev );
00589  err_open:
00590         ib_destroy_mi ( ibdev, ibdev->gsi );
00591  err_create_gsi:
00592         ib_destroy_sma ( ibdev, ibdev->smi );
00593  err_create_sma:
00594         ib_destroy_mi ( ibdev, ibdev->smi );
00595  err_create_smi:
00596         assert ( ibdev->open_count == 1 );
00597         ibdev->open_count = 0;
00598         return rc;
00599 }

void ib_close ( struct ib_device ibdev  ) 

Close port.

Parameters:
ibdev Infiniband device

Definition at line 606 of file infiniband.c.

References ib_device_operations::close, ib_device::gsi, ib_destroy_mi(), ib_destroy_sma(), list_del, ib_device::op, ib_device::open_count, ib_device::open_list, and ib_device::smi.

Referenced by ib_cmrc_open(), ib_cmrc_shutdown(), ipoib_close(), and ipoib_open().

00606                                           {
00607 
00608         /* Decrement device open request counter */
00609         ibdev->open_count--;
00610 
00611         /* Close device if this was the last remaining requested opening */
00612         if ( ibdev->open_count == 0 ) {
00613                 list_del ( &ibdev->open_list );
00614                 ib_destroy_mi ( ibdev, ibdev->gsi );
00615                 ib_destroy_sma ( ibdev, ibdev->smi );
00616                 ib_destroy_mi ( ibdev, ibdev->smi );
00617                 ibdev->op->close ( ibdev );
00618         }
00619 }

int ib_link_rc ( struct ib_device ibdev  ) 

Get link state.

Parameters:
ibdev Infiniband device
Return values:
rc Link status code

Definition at line 627 of file infiniband.c.

References EINPROGRESS_ARMED, EINPROGRESS_INIT, EINVAL, ENOTCONN, IB_PORT_STATE_ACTIVE, IB_PORT_STATE_ARMED, IB_PORT_STATE_DOWN, IB_PORT_STATE_INIT, and ib_device::port_state.

Referenced by ipoib_link_state_changed().

00627                                            {
00628         switch ( ibdev->port_state ) {
00629         case IB_PORT_STATE_DOWN:        return -ENOTCONN;
00630         case IB_PORT_STATE_INIT:        return -EINPROGRESS_INIT;
00631         case IB_PORT_STATE_ARMED:       return -EINPROGRESS_ARMED;
00632         case IB_PORT_STATE_ACTIVE:      return 0;
00633         default:                        return -EINVAL;
00634         }
00635 }

int ib_mcast_attach ( struct ib_device ibdev,
struct ib_queue_pair qp,
struct ib_gid gid 
)

Attach to multicast group.

Parameters:
ibdev Infiniband device
qp Queue pair
gid Multicast GID
Return values:
rc Return status code
Note that this function handles only the local device's attachment to the multicast GID; it does not issue the relevant MADs to join the multicast group on the subnet.

Definition at line 656 of file infiniband.c.

References ENOMEM, free(), ib_multicast_gid::gid, ib_multicast_gid::list, list_add, list_del, ib_device_operations::mcast_attach, memcpy, ib_queue_pair::mgids, ib_device::op, and zalloc().

Referenced by ib_mcast_join().

00657                                            {
00658         struct ib_multicast_gid *mgid;
00659         int rc;
00660 
00661         /* Add to software multicast GID list */
00662         mgid = zalloc ( sizeof ( *mgid ) );
00663         if ( ! mgid ) {
00664                 rc = -ENOMEM;
00665                 goto err_alloc_mgid;
00666         }
00667         memcpy ( &mgid->gid, gid, sizeof ( mgid->gid ) );
00668         list_add ( &mgid->list, &qp->mgids );
00669 
00670         /* Add to hardware multicast GID list */
00671         if ( ( rc = ibdev->op->mcast_attach ( ibdev, qp, gid ) ) != 0 )
00672                 goto err_dev_mcast_attach;
00673 
00674         return 0;
00675 
00676  err_dev_mcast_attach:
00677         list_del ( &mgid->list );
00678         free ( mgid );
00679  err_alloc_mgid:
00680         return rc;
00681 }

void ib_mcast_detach ( struct ib_device ibdev,
struct ib_queue_pair qp,
struct ib_gid gid 
)

Detach from multicast group.

Parameters:
ibdev Infiniband device
qp Queue pair
gid Multicast GID

Definition at line 690 of file infiniband.c.

References free(), ib_multicast_gid::gid, ib_multicast_gid::list, list_del, list_for_each_entry, ib_device_operations::mcast_detach, memcmp(), ib_queue_pair::mgids, and ib_device::op.

Referenced by ib_mcast_join(), and ib_mcast_leave().

00691                                             {
00692         struct ib_multicast_gid *mgid;
00693 
00694         /* Remove from hardware multicast GID list */
00695         ibdev->op->mcast_detach ( ibdev, qp, gid );
00696 
00697         /* Remove from software multicast GID list */
00698         list_for_each_entry ( mgid, &qp->mgids, list ) {
00699                 if ( memcmp ( &mgid->gid, gid, sizeof ( mgid->gid ) ) == 0 ) {
00700                         list_del ( &mgid->list );
00701                         free ( mgid );
00702                         break;
00703                 }
00704         }
00705 }

int ib_get_hca_info ( struct ib_device ibdev,
struct ib_gid_half hca_guid 
)

Get Infiniband HCA information.

Parameters:
ibdev Infiniband device
Return values:
hca_guid HCA GUID
num_ports Number of ports

Definition at line 721 of file infiniband.c.

References ib_device::dev, for_each_ibdev, ib_device::gid, ib_gid::half, memcpy, and ib_gid::u.

Referenced by ib_cm_path_complete(), ib_sma_node_desc(), and ib_sma_node_info().

00722                                                      {
00723         struct ib_device *tmp;
00724         int num_ports = 0;
00725 
00726         /* Search for IB devices with the same physical device to
00727          * identify port count and a suitable Node GUID.
00728          */
00729         for_each_ibdev ( tmp ) {
00730                 if ( tmp->dev != ibdev->dev )
00731                         continue;
00732                 if ( num_ports == 0 ) {
00733                         memcpy ( hca_guid, &tmp->gid.u.half[1],
00734                                  sizeof ( *hca_guid ) );
00735                 }
00736                 num_ports++;
00737         }
00738         return num_ports;
00739 }

int ib_set_port_info ( struct ib_device ibdev,
union ib_mad mad 
)

Set port information.

Parameters:
ibdev Infiniband device
mad Set port information MAD

Definition at line 747 of file infiniband.c.

References DBGC, ENOTSUP, ib_device::op, ib_device_operations::set_port_info, and strerror().

Referenced by ib_sma_set_port_info().

00747                                                                     {
00748         int rc;
00749 
00750         /* Adapters with embedded SMAs do not need to support this method */
00751         if ( ! ibdev->op->set_port_info ) {
00752                 DBGC ( ibdev, "IBDEV %p does not support setting port "
00753                        "information\n", ibdev );
00754                 return -ENOTSUP;
00755         }
00756 
00757         if ( ( rc = ibdev->op->set_port_info ( ibdev, mad ) ) != 0 ) {
00758                 DBGC ( ibdev, "IBDEV %p could not set port information: %s\n",
00759                        ibdev, strerror ( rc ) );
00760                 return rc;
00761         }
00762 
00763         return 0;
00764 };

int ib_set_pkey_table ( struct ib_device ibdev,
union ib_mad mad 
)

Set partition key table.

Parameters:
ibdev Infiniband device
mad Set partition key table MAD

Definition at line 772 of file infiniband.c.

References DBGC, ENOTSUP, ib_device::op, ib_device_operations::set_pkey_table, and strerror().

Referenced by ib_sma_set_pkey_table().

00772                                                                      {
00773         int rc;
00774 
00775         /* Adapters with embedded SMAs do not need to support this method */
00776         if ( ! ibdev->op->set_pkey_table ) {
00777                 DBGC ( ibdev, "IBDEV %p does not support setting partition "
00778                        "key table\n", ibdev );
00779                 return -ENOTSUP;
00780         }
00781 
00782         if ( ( rc = ibdev->op->set_pkey_table ( ibdev, mad ) ) != 0 ) {
00783                 DBGC ( ibdev, "IBDEV %p could not set partition key table: "
00784                        "%s\n", ibdev, strerror ( rc ) );
00785                 return rc;
00786         }
00787 
00788         return 0;
00789 };

void ib_link_state_changed ( struct ib_device ibdev  ) 

Handle Infiniband link state change.

Parameters:
ibdev Infiniband device

Definition at line 803 of file infiniband.c.

References ipoib_link_state_changed().

Referenced by arbel_event_port_state_change(), hermon_event_port_state_change(), and linda_link_state_changed().

00803                                                        {
00804 
00805         /* Notify IPoIB of link state change */
00806         ipoib_link_state_changed ( ibdev );
00807 }

void ib_poll_eq ( struct ib_device ibdev  ) 

Poll event queue.

Parameters:
ibdev Infiniband device

Definition at line 814 of file infiniband.c.

References ib_device::cqs, ib_poll_cq(), ib_completion_queue::list, list_for_each_entry, ib_device::op, and ib_device_operations::poll_eq.

Referenced by ib_step(), and ipoib_poll().

00814                                             {
00815         struct ib_completion_queue *cq;
00816 
00817         /* Poll device's event queue */
00818         ibdev->op->poll_eq ( ibdev );
00819 
00820         /* Poll all completion queues */
00821         list_for_each_entry ( cq, &ibdev->cqs, list )
00822                 ib_poll_cq ( ibdev, cq );
00823 }

static void ib_step ( struct process *process  __unused  )  [static]

Single-step the Infiniband event queue.

Parameters:
process Infiniband event queue process

Definition at line 830 of file infiniband.c.

References for_each_ibdev, and ib_poll_eq().

00830                                                          {
00831         struct ib_device *ibdev;
00832 
00833         for_each_ibdev ( ibdev )
00834                 ib_poll_eq ( ibdev );
00835 }

struct ib_device* alloc_ibdev ( size_t  priv_size  )  [read]

Allocate Infiniband device.

Parameters:
priv_size Size of driver private data area
Return values:
ibdev Infiniband device, or NULL

Definition at line 856 of file infiniband.c.

References ib_device::cqs, ib_device::drv_priv, IB_LID_NONE, IB_PKEY_DEFAULT, IB_PORT_STATE_DOWN, ib_set_drvdata(), INIT_LIST_HEAD, ib_device::lid, ib_device::pkey, ib_device::port_state, ib_device::qps, and zalloc().

Referenced by arbel_probe(), hermon_probe(), and linda_probe().

00856                                                     {
00857         struct ib_device *ibdev;
00858         void *drv_priv;
00859         size_t total_len;
00860 
00861         total_len = ( sizeof ( *ibdev ) + priv_size );
00862         ibdev = zalloc ( total_len );
00863         if ( ibdev ) {
00864                 drv_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) );
00865                 ib_set_drvdata ( ibdev, drv_priv );
00866                 INIT_LIST_HEAD ( &ibdev->cqs );
00867                 INIT_LIST_HEAD ( &ibdev->qps );
00868                 ibdev->port_state = IB_PORT_STATE_DOWN;
00869                 ibdev->lid = IB_LID_NONE;
00870                 ibdev->pkey = IB_PKEY_DEFAULT;
00871         }
00872         return ibdev;
00873 }

int register_ibdev ( struct ib_device ibdev  ) 

Register Infiniband device.

Parameters:
ibdev Infiniband device
Return values:
rc Return status code

Definition at line 881 of file infiniband.c.

References DBGC, ib_device::dev, ibdev_get(), ibdev_put(), ipoib_probe(), ib_device::list, list_add_tail, list_del, device::name, and strerror().

Referenced by arbel_probe(), hermon_probe(), and linda_probe().

00881                                                {
00882         int rc;
00883 
00884         /* Add to device list */
00885         ibdev_get ( ibdev );
00886         list_add_tail ( &ibdev->list, &ib_devices );
00887 
00888         /* Add IPoIB device */
00889         if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
00890                 DBGC ( ibdev, "IBDEV %p could not add IPoIB device: %s\n",
00891                        ibdev, strerror ( rc ) );
00892                 goto err_ipoib_probe;
00893         }
00894 
00895         DBGC ( ibdev, "IBDEV %p registered (phys %s)\n", ibdev,
00896                ibdev->dev->name );
00897         return 0;
00898 
00899  err_ipoib_probe:
00900         list_del ( &ibdev->list );
00901         ibdev_put ( ibdev );
00902         return rc;
00903 }

void unregister_ibdev ( struct ib_device ibdev  ) 

Unregister Infiniband device.

Parameters:
ibdev Infiniband device

Definition at line 910 of file infiniband.c.

References DBGC, ibdev_put(), ipoib_remove(), ib_device::list, and list_del.

Referenced by arbel_probe(), arbel_remove(), hermon_probe(), hermon_remove(), linda_probe(), and linda_remove().

00910                                                   {
00911 
00912         /* Close device */
00913         ipoib_remove ( ibdev );
00914 
00915         /* Remove from device list */
00916         list_del ( &ibdev->list );
00917         ibdev_put ( ibdev );
00918         DBGC ( ibdev, "IBDEV %p unregistered\n", ibdev );
00919 }

struct ib_device* find_ibdev ( struct ib_gid gid  )  [read]

Find Infiniband device by GID.

Parameters:
gid GID
Return values:
ibdev Infiniband device, or NULL

Definition at line 927 of file infiniband.c.

References for_each_ibdev, ib_device::gid, memcmp(), and NULL.

Referenced by ib_srp_connect().

00927                                                      {
00928         struct ib_device *ibdev;
00929 
00930         for_each_ibdev ( ibdev ) {
00931                 if ( memcmp ( gid, &ibdev->gid, sizeof ( *gid ) ) == 0 )
00932                         return ibdev;
00933         }
00934         return NULL;
00935 }

struct ib_device* last_opened_ibdev ( void   )  [read]

Get most recently opened Infiniband device.

Return values:
ibdev Most recently opened Infiniband device, or NULL

Definition at line 942 of file infiniband.c.

References assert, list_for_each_entry, NULL, ib_device::open_count, and ib_device::open_list.

Referenced by ib_srp_parse_sgid().

00942                                               {
00943         struct ib_device *ibdev;
00944 
00945         list_for_each_entry ( ibdev, &open_ib_devices, open_list ) {
00946                 assert ( ibdev->open_count != 0 );
00947                 return ibdev;
00948         }
00949 
00950         return NULL;
00951 }


Variable Documentation

struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices )

List of Infiniband devices.

Definition at line 47 of file infiniband.c.

struct list_head open_ib_devices = LIST_HEAD_INIT ( open_ib_devices ) [static]

List of open Infiniband devices, in reverse order of opening.

Definition at line 50 of file infiniband.c.

struct errortab infiniband_errors [] __errortab

Initial value:

 {
        { EINPROGRESS_INIT, "Initialising" },
        { EINPROGRESS_ARMED, "Armed" },
}
Human-readable message for the link statuses.

Definition at line 57 of file infiniband.c.

struct process ib_process __permanent_process

Initial value:

 {
        .list = LIST_HEAD_INIT ( ib_process.list ),
        .step = ib_step,
}
Infiniband event queue process.

Definition at line 838 of file infiniband.c.


Generated on Tue Apr 6 20:01:55 2010 for gPXE by  doxygen 1.5.7.1