infiniband.h

Go to the documentation of this file.
00001 #ifndef _GPXE_INFINIBAND_H
00002 #define _GPXE_INFINIBAND_H
00003 
00004 /** @file
00005  *
00006  * Infiniband protocol
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER );
00011 
00012 #include <stdint.h>
00013 #include <gpxe/refcnt.h>
00014 #include <gpxe/device.h>
00015 #include <gpxe/ib_packet.h>
00016 #include <gpxe/ib_mad.h>
00017 
00018 /** Subnet management interface QPN */
00019 #define IB_QPN_SMI 0
00020 
00021 /** Subnet management interface queue key */
00022 #define IB_QKEY_SMI 0
00023 
00024 /** General service interface QPN */
00025 #define IB_QPN_GSI 1
00026 
00027 /** General service interface queue key */
00028 #define IB_QKEY_GSI 0x80010000UL
00029 
00030 /** Broadcast QPN */
00031 #define IB_QPN_BROADCAST 0xffffffUL
00032 
00033 /** QPN mask */
00034 #define IB_QPN_MASK 0xffffffUL
00035 
00036 /** Default Infiniband partition key */
00037 #define IB_PKEY_DEFAULT 0xffff
00038 
00039 /** Infiniband partition key full membership flag */
00040 #define IB_PKEY_FULL 0x8000
00041 
00042 /**
00043  * Maximum payload size
00044  *
00045  * This is currently hard-coded in various places (drivers, subnet
00046  * management agent, etc.) to 2048.
00047  */
00048 #define IB_MAX_PAYLOAD_SIZE 2048
00049 
00050 struct ib_device;
00051 struct ib_queue_pair;
00052 struct ib_address_vector;
00053 struct ib_completion_queue;
00054 struct ib_mad_interface;
00055 
00056 /** Infiniband transmission rates */
00057 enum ib_rate {
00058         IB_RATE_2_5 = 2,
00059         IB_RATE_10 = 3,
00060         IB_RATE_30 = 4,
00061         IB_RATE_5 = 5,
00062         IB_RATE_20 = 6,
00063         IB_RATE_40 = 7,
00064         IB_RATE_60 = 8,
00065         IB_RATE_80 = 9,
00066         IB_RATE_120 = 10,
00067 };
00068 
00069 /** An Infiniband Address Vector */
00070 struct ib_address_vector {
00071         /** Queue Pair Number */
00072         unsigned long qpn;
00073         /** Queue key
00074          *
00075          * Not specified for received packets.
00076          */
00077         unsigned long qkey;
00078         /** Local ID */
00079         unsigned int lid;
00080         /** Rate
00081          *
00082          * Not specified for received packets.
00083          */
00084         enum ib_rate rate;
00085         /** Service level */
00086         unsigned int sl;
00087         /** GID is present */
00088         unsigned int gid_present;
00089         /** GID, if present */
00090         struct ib_gid gid;
00091 };
00092 
00093 /** An Infiniband Work Queue */
00094 struct ib_work_queue {
00095         /** Containing queue pair */
00096         struct ib_queue_pair *qp;
00097         /** "Is a send queue" flag */
00098         int is_send;
00099         /** Associated completion queue */
00100         struct ib_completion_queue *cq;
00101         /** List of work queues on this completion queue */
00102         struct list_head list;
00103         /** Packet sequence number */
00104         uint32_t psn;
00105         /** Number of work queue entries */
00106         unsigned int num_wqes;
00107         /** Number of occupied work queue entries */
00108         unsigned int fill;
00109         /** Next work queue entry index
00110          *
00111          * This is the index of the next entry to be filled (i.e. the
00112          * first empty entry).  This value is not bounded by num_wqes;
00113          * users must logical-AND with (num_wqes-1) to generate an
00114          * array index.
00115          */
00116         unsigned long next_idx;
00117         /** I/O buffers assigned to work queue */
00118         struct io_buffer **iobufs;
00119         /** Driver private data */
00120         void *drv_priv;
00121 };
00122 
00123 /** An Infiniband multicast GID */
00124 struct ib_multicast_gid {
00125         /** List of multicast GIDs on this QP */
00126         struct list_head list;
00127         /** Multicast GID */
00128         struct ib_gid gid;
00129 };
00130 
00131 /** An Infiniband queue pair type */
00132 enum ib_queue_pair_type {
00133         IB_QPT_SMI,
00134         IB_QPT_GSI,
00135         IB_QPT_UD,
00136         IB_QPT_RC,
00137 };
00138 
00139 /** An Infiniband Queue Pair */
00140 struct ib_queue_pair {
00141         /** Containing Infiniband device */
00142         struct ib_device *ibdev;
00143         /** List of queue pairs on this Infiniband device */
00144         struct list_head list;
00145         /** Queue pair number */
00146         unsigned long qpn;
00147         /** Externally-visible queue pair number
00148          *
00149          * This may differ from the real queue pair number (e.g. when
00150          * the HCA cannot use the management QPNs 0 and 1 as hardware
00151          * QPNs and needs to remap them).
00152          */
00153         unsigned long ext_qpn;
00154         /** Queue pair type */
00155         enum ib_queue_pair_type type;
00156         /** Queue key */
00157         unsigned long qkey;
00158         /** Send queue */
00159         struct ib_work_queue send;
00160         /** Receive queue */
00161         struct ib_work_queue recv;
00162         /** List of multicast GIDs */
00163         struct list_head mgids;
00164         /** Address vector */
00165         struct ib_address_vector av;
00166         /** Driver private data */
00167         void *drv_priv;
00168         /** Queue owner private data */
00169         void *owner_priv;
00170 };
00171 
00172 /** Infiniband completion queue operations */
00173 struct ib_completion_queue_operations {
00174         /**
00175          * Complete Send WQE
00176          *
00177          * @v ibdev             Infiniband device
00178          * @v qp                Queue pair
00179          * @v iobuf             I/O buffer
00180          * @v rc                Completion status code
00181          */
00182         void ( * complete_send ) ( struct ib_device *ibdev,
00183                                    struct ib_queue_pair *qp,
00184                                    struct io_buffer *iobuf, int rc );
00185         /**
00186          * Complete Receive WQE
00187          *
00188          * @v ibdev             Infiniband device
00189          * @v qp                Queue pair
00190          * @v av                Address vector, or NULL
00191          * @v iobuf             I/O buffer
00192          * @v rc                Completion status code
00193          */
00194         void ( * complete_recv ) ( struct ib_device *ibdev,
00195                                    struct ib_queue_pair *qp,
00196                                    struct ib_address_vector *av,
00197                                    struct io_buffer *iobuf, int rc );
00198 };
00199 
00200 /** An Infiniband Completion Queue */
00201 struct ib_completion_queue {
00202         /** Containing Infiniband device */
00203         struct ib_device *ibdev;
00204         /** List of completion queues on this Infiniband device */
00205         struct list_head list;
00206         /** Completion queue number */
00207         unsigned long cqn;
00208         /** Number of completion queue entries */
00209         unsigned int num_cqes;
00210         /** Next completion queue entry index
00211          *
00212          * This is the index of the next entry to be filled (i.e. the
00213          * first empty entry).  This value is not bounded by num_wqes;
00214          * users must logical-AND with (num_wqes-1) to generate an
00215          * array index.
00216          */
00217         unsigned long next_idx;
00218         /** List of work queues completing to this queue */
00219         struct list_head work_queues;
00220         /** Completion queue operations */
00221         struct ib_completion_queue_operations *op;
00222         /** Driver private data */
00223         void *drv_priv;
00224 };
00225 
00226 /**
00227  * Infiniband device operations
00228  *
00229  * These represent a subset of the Infiniband Verbs.
00230  */
00231 struct ib_device_operations {
00232         /** Create completion queue
00233          *
00234          * @v ibdev             Infiniband device
00235          * @v cq                Completion queue
00236          * @ret rc              Return status code
00237          */
00238         int ( * create_cq ) ( struct ib_device *ibdev,
00239                               struct ib_completion_queue *cq );
00240         /** Destroy completion queue
00241          *
00242          * @v ibdev             Infiniband device
00243          * @v cq                Completion queue
00244          */
00245         void ( * destroy_cq ) ( struct ib_device *ibdev,
00246                                 struct ib_completion_queue *cq );
00247         /** Create queue pair
00248          *
00249          * @v ibdev             Infiniband device
00250          * @v qp                Queue pair
00251          * @ret rc              Return status code
00252          */
00253         int ( * create_qp ) ( struct ib_device *ibdev,
00254                               struct ib_queue_pair *qp );
00255         /** Modify queue pair
00256          *
00257          * @v ibdev             Infiniband device
00258          * @v qp                Queue pair
00259          * @ret rc              Return status code
00260          */
00261         int ( * modify_qp ) ( struct ib_device *ibdev,
00262                               struct ib_queue_pair *qp );
00263         /** Destroy queue pair
00264          *
00265          * @v ibdev             Infiniband device
00266          * @v qp                Queue pair
00267          */
00268         void ( * destroy_qp ) ( struct ib_device *ibdev,
00269                                 struct ib_queue_pair *qp );
00270         /** Post send work queue entry
00271          *
00272          * @v ibdev             Infiniband device
00273          * @v qp                Queue pair
00274          * @v av                Address vector
00275          * @v iobuf             I/O buffer
00276          * @ret rc              Return status code
00277          *
00278          * If this method returns success, the I/O buffer remains
00279          * owned by the queue pair.  If this method returns failure,
00280          * the I/O buffer is immediately released; the failure is
00281          * interpreted as "failure to enqueue buffer".
00282          */
00283         int ( * post_send ) ( struct ib_device *ibdev,
00284                               struct ib_queue_pair *qp,
00285                               struct ib_address_vector *av,
00286                               struct io_buffer *iobuf );
00287         /** Post receive work queue entry
00288          *
00289          * @v ibdev             Infiniband device
00290          * @v qp                Queue pair
00291          * @v iobuf             I/O buffer
00292          * @ret rc              Return status code
00293          *
00294          * If this method returns success, the I/O buffer remains
00295          * owned by the queue pair.  If this method returns failure,
00296          * the I/O buffer is immediately released; the failure is
00297          * interpreted as "failure to enqueue buffer".
00298          */
00299         int ( * post_recv ) ( struct ib_device *ibdev,
00300                               struct ib_queue_pair *qp,
00301                               struct io_buffer *iobuf );
00302         /** Poll completion queue
00303          *
00304          * @v ibdev             Infiniband device
00305          * @v cq                Completion queue
00306          *
00307          * The relevant completion handler (specified at completion
00308          * queue creation time) takes ownership of the I/O buffer.
00309          */
00310         void ( * poll_cq ) ( struct ib_device *ibdev,
00311                              struct ib_completion_queue *cq );
00312         /**
00313          * Poll event queue
00314          *
00315          * @v ibdev             Infiniband device
00316          */
00317         void ( * poll_eq ) ( struct ib_device *ibdev );
00318         /**
00319          * Open port
00320          *
00321          * @v ibdev             Infiniband device
00322          * @ret rc              Return status code
00323          */
00324         int ( * open ) ( struct ib_device *ibdev );
00325         /**
00326          * Close port
00327          *
00328          * @v ibdev             Infiniband device
00329          */
00330         void ( * close ) ( struct ib_device *ibdev );
00331         /** Attach to multicast group
00332          *
00333          * @v ibdev             Infiniband device
00334          * @v qp                Queue pair
00335          * @v gid               Multicast GID
00336          * @ret rc              Return status code
00337          */
00338         int ( * mcast_attach ) ( struct ib_device *ibdev,
00339                                  struct ib_queue_pair *qp,
00340                                  struct ib_gid *gid );
00341         /** Detach from multicast group
00342          *
00343          * @v ibdev             Infiniband device
00344          * @v qp                Queue pair
00345          * @v gid               Multicast GID
00346          */
00347         void ( * mcast_detach ) ( struct ib_device *ibdev,
00348                                   struct ib_queue_pair *qp,
00349                                   struct ib_gid *gid );
00350         /** Set port information
00351          *
00352          * @v ibdev             Infiniband device
00353          * @v mad               Set port information MAD
00354          *
00355          * This method is required only by adapters that do not have
00356          * an embedded SMA.
00357          */
00358         int ( * set_port_info ) ( struct ib_device *ibdev, union ib_mad *mad );
00359         /** Set partition key table
00360          *
00361          * @v ibdev             Infiniband device
00362          * @v mad               Set partition key table MAD
00363          *
00364          * This method is required only by adapters that do not have
00365          * an embedded SMA.
00366          */
00367         int ( * set_pkey_table ) ( struct ib_device *ibdev,
00368                                    union ib_mad *mad );
00369 };
00370 
00371 /** An Infiniband device */
00372 struct ib_device {
00373         /** Reference counter */
00374         struct refcnt refcnt;
00375         /** List of Infiniband devices */
00376         struct list_head list;
00377         /** List of open Infiniband devices */
00378         struct list_head open_list;
00379         /** Underlying device */
00380         struct device *dev;
00381         /** List of completion queues */
00382         struct list_head cqs;
00383         /** List of queue pairs */
00384         struct list_head qps;
00385         /** Infiniband operations */
00386         struct ib_device_operations *op;
00387         /** Port number */
00388         unsigned int port;
00389         /** Port open request counter */
00390         unsigned int open_count;
00391 
00392         /** Port state */
00393         uint8_t port_state;
00394         /** Link width supported */
00395         uint8_t link_width_supported;
00396         /** Link width enabled */
00397         uint8_t link_width_enabled;
00398         /** Link width active */
00399         uint8_t link_width_active;
00400         /** Link speed supported */
00401         uint8_t link_speed_supported;
00402         /** Link speed enabled */
00403         uint8_t link_speed_enabled;
00404         /** Link speed active */
00405         uint8_t link_speed_active;
00406         /** Port GID */
00407         struct ib_gid gid;
00408         /** Port LID */
00409         uint16_t lid;
00410         /** Subnet manager LID */
00411         uint16_t sm_lid;
00412         /** Subnet manager SL */
00413         uint8_t sm_sl;
00414         /** Partition key */
00415         uint16_t pkey;
00416 
00417         /** RDMA key
00418          *
00419          * This is a single key allowing unrestricted access to
00420          * memory.
00421          */
00422         uint32_t rdma_key;
00423 
00424         /** Subnet management interface */
00425         struct ib_mad_interface *smi;
00426         /** General services interface */
00427         struct ib_mad_interface *gsi;
00428 
00429         /** Driver private data */
00430         void *drv_priv;
00431         /** Owner private data */
00432         void *owner_priv;
00433 };
00434 
00435 extern struct ib_completion_queue *
00436 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
00437                struct ib_completion_queue_operations *op );
00438 extern void ib_destroy_cq ( struct ib_device *ibdev,
00439                             struct ib_completion_queue *cq );
00440 extern void ib_poll_cq ( struct ib_device *ibdev,
00441                          struct ib_completion_queue *cq );
00442 extern struct ib_queue_pair *
00443 ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type,
00444                unsigned int num_send_wqes, struct ib_completion_queue *send_cq,
00445                unsigned int num_recv_wqes,
00446                struct ib_completion_queue *recv_cq );
00447 extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp );
00448 extern void ib_destroy_qp ( struct ib_device *ibdev,
00449                             struct ib_queue_pair *qp );
00450 extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
00451                                                unsigned long qpn );
00452 extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
00453                                                 struct ib_gid *gid );
00454 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
00455                                            unsigned long qpn, int is_send );
00456 extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00457                           struct ib_address_vector *av,
00458                           struct io_buffer *iobuf );
00459 extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00460                           struct io_buffer *iobuf );
00461 extern void ib_complete_send ( struct ib_device *ibdev,
00462                                struct ib_queue_pair *qp,
00463                                struct io_buffer *iobuf, int rc );
00464 extern void ib_complete_recv ( struct ib_device *ibdev,
00465                                struct ib_queue_pair *qp,
00466                                struct ib_address_vector *av,
00467                                struct io_buffer *iobuf, int rc );
00468 extern void ib_refill_recv ( struct ib_device *ibdev,
00469                              struct ib_queue_pair *qp );
00470 extern int ib_open ( struct ib_device *ibdev );
00471 extern void ib_close ( struct ib_device *ibdev );
00472 extern int ib_link_rc ( struct ib_device *ibdev );
00473 extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00474                              struct ib_gid *gid );
00475 extern void ib_mcast_detach ( struct ib_device *ibdev,
00476                               struct ib_queue_pair *qp, struct ib_gid *gid );
00477 extern int ib_get_hca_info ( struct ib_device *ibdev,
00478                              struct ib_gid_half *hca_guid );
00479 extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad );
00480 extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad );
00481 extern struct ib_device * alloc_ibdev ( size_t priv_size );
00482 extern int register_ibdev ( struct ib_device *ibdev );
00483 extern void unregister_ibdev ( struct ib_device *ibdev );
00484 extern struct ib_device * find_ibdev ( struct ib_gid *gid );
00485 extern struct ib_device * last_opened_ibdev ( void );
00486 extern void ib_link_state_changed ( struct ib_device *ibdev );
00487 extern void ib_poll_eq ( struct ib_device *ibdev );
00488 extern struct list_head ib_devices;
00489 
00490 /** Iterate over all network devices */
00491 #define for_each_ibdev( ibdev ) \
00492         list_for_each_entry ( (ibdev), &ib_devices, list )
00493 
00494 /**
00495  * Check link state
00496  *
00497  * @v ibdev             Infiniband device
00498  * @ret link_up         Link is up
00499  */
00500 static inline __always_inline int
00501 ib_link_ok ( struct ib_device *ibdev ) {
00502         return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
00503 }
00504 
00505 /**
00506  * Get reference to Infiniband device
00507  *
00508  * @v ibdev             Infiniband device
00509  * @ret ibdev           Infiniband device
00510  */
00511 static inline __always_inline struct ib_device *
00512 ibdev_get ( struct ib_device *ibdev ) {
00513         ref_get ( &ibdev->refcnt );
00514         return ibdev;
00515 }
00516 
00517 /**
00518  * Drop reference to Infiniband device
00519  *
00520  * @v ibdev             Infiniband device
00521  */
00522 static inline __always_inline void
00523 ibdev_put ( struct ib_device *ibdev ) {
00524         ref_put ( &ibdev->refcnt );
00525 }
00526 
00527 /**
00528  * Set Infiniband work queue driver-private data
00529  *
00530  * @v wq                Work queue
00531  * @v priv              Private data
00532  */
00533 static inline __always_inline void
00534 ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
00535         wq->drv_priv = priv;
00536 }
00537 
00538 /**
00539  * Get Infiniband work queue driver-private data
00540  *
00541  * @v wq                Work queue
00542  * @ret priv            Private data
00543  */
00544 static inline __always_inline void *
00545 ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
00546         return wq->drv_priv;
00547 }
00548 
00549 /**
00550  * Set Infiniband queue pair driver-private data
00551  *
00552  * @v qp                Queue pair
00553  * @v priv              Private data
00554  */
00555 static inline __always_inline void
00556 ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
00557         qp->drv_priv = priv;
00558 }
00559 
00560 /**
00561  * Get Infiniband queue pair driver-private data
00562  *
00563  * @v qp                Queue pair
00564  * @ret priv            Private data
00565  */
00566 static inline __always_inline void *
00567 ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
00568         return qp->drv_priv;
00569 }
00570 
00571 /**
00572  * Set Infiniband queue pair owner-private data
00573  *
00574  * @v qp                Queue pair
00575  * @v priv              Private data
00576  */
00577 static inline __always_inline void
00578 ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
00579         qp->owner_priv = priv;
00580 }
00581 
00582 /**
00583  * Get Infiniband queue pair owner-private data
00584  *
00585  * @v qp                Queue pair
00586  * @ret priv            Private data
00587  */
00588 static inline __always_inline void *
00589 ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
00590         return qp->owner_priv;
00591 }
00592 
00593 /**
00594  * Set Infiniband completion queue driver-private data
00595  *
00596  * @v cq                Completion queue
00597  * @v priv              Private data
00598  */
00599 static inline __always_inline void
00600 ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
00601         cq->drv_priv = priv;
00602 }
00603 
00604 /**
00605  * Get Infiniband completion queue driver-private data
00606  *
00607  * @v cq                Completion queue
00608  * @ret priv            Private data
00609  */
00610 static inline __always_inline void *
00611 ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
00612         return cq->drv_priv;
00613 }
00614 
00615 /**
00616  * Set Infiniband device driver-private data
00617  *
00618  * @v ibdev             Infiniband device
00619  * @v priv              Private data
00620  */
00621 static inline __always_inline void
00622 ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
00623         ibdev->drv_priv = priv;
00624 }
00625 
00626 /**
00627  * Get Infiniband device driver-private data
00628  *
00629  * @v ibdev             Infiniband device
00630  * @ret priv            Private data
00631  */
00632 static inline __always_inline void *
00633 ib_get_drvdata ( struct ib_device *ibdev ) {
00634         return ibdev->drv_priv;
00635 }
00636 
00637 /**
00638  * Set Infiniband device owner-private data
00639  *
00640  * @v ibdev             Infiniband device
00641  * @v priv              Private data
00642  */
00643 static inline __always_inline void
00644 ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
00645         ibdev->owner_priv = priv;
00646 }
00647 
00648 /**
00649  * Get Infiniband device owner-private data
00650  *
00651  * @v ibdev             Infiniband device
00652  * @ret priv            Private data
00653  */
00654 static inline __always_inline void *
00655 ib_get_ownerdata ( struct ib_device *ibdev ) {
00656         return ibdev->owner_priv;
00657 }
00658 
00659 #endif /* _GPXE_INFINIBAND_H */

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