#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_queue * | ib_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_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) |
| 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_pair * | ib_find_qp_qpn (struct ib_device *ibdev, unsigned long qpn) |
| Find queue pair by QPN. | |
| struct ib_queue_pair * | ib_find_qp_mgid (struct ib_device *ibdev, struct ib_gid *gid) |
| Find queue pair by multicast GID. | |
| struct ib_work_queue * | ib_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_device * | alloc_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_device * | find_ibdev (struct ib_gid *gid) |
| Find Infiniband device by GID. | |
| struct ib_device * | last_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. | |
Definition in file infiniband.c.
| #define EINPROGRESS_INIT ( EINPROGRESS | EUNIQ_01 ) |
| #define EINPROGRESS_ARMED ( EINPROGRESS | EUNIQ_02 ) |
| 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.
| ibdev | Infiniband device | |
| num_cqes | Number of completion queue entries | |
| op | Completion queue operations |
| 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.
| 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.
| 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.
| 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 |
| qp | Queue pair |
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.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| av | New address vector, if applicable |
| 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.
| 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.
| ibdev | Infiniband device | |
| qpn | Queue pair number |
| 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.
| ibdev | Infiniband device | |
| gid | Multicast GID |
| 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.
| cq | Completion queue | |
| qpn | Queue pair number | |
| is_send | Find send work queue (rather than receive) |
| 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.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| av | Address vector | |
| iobuf | I/O buffer |
| 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.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| iobuf | I/O buffer |
| 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.
| 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.
| 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.
| 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.
| ibdev | Infiniband device |
| 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.
| 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.
| ibdev | Infiniband device |
| 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.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| gid | Multicast GID |
| rc | Return status code |
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.
| 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.
| ibdev | Infiniband device |
| 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 }
Set port information.
| 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 };
Set partition key table.
| 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.
| 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.
| 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 }
Single-step the Infiniband event queue.
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 }
Allocate Infiniband device.
| priv_size | Size of driver private data area |
| 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.
| ibdev | Infiniband device |
| 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.
| 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 }
Find Infiniband device by GID.
| gid | GID |
| 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.
| 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 }
| struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices ) |
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" },
}
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,
}
Definition at line 838 of file infiniband.c.
1.5.7.1