123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711 |
- #ifndef _IPXE_INFINIBAND_H
- #define _IPXE_INFINIBAND_H
-
- /** @file
- *
- * Infiniband protocol
- *
- */
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- #include <stdint.h>
- #include <ipxe/refcnt.h>
- #include <ipxe/device.h>
- #include <ipxe/tables.h>
- #include <ipxe/ib_packet.h>
- #include <ipxe/ib_mad.h>
- #include <ipxe/if_ether.h>
-
- /** Subnet management interface QPN */
- #define IB_QPN_SMI 0
-
- /** Subnet management interface queue key */
- #define IB_QKEY_SMI 0
-
- /** General service interface QPN */
- #define IB_QPN_GSI 1
-
- /** General service interface queue key */
- #define IB_QKEY_GSI 0x80010000UL
-
- /** Broadcast QPN */
- #define IB_QPN_BROADCAST 0xffffffUL
-
- /** QPN mask */
- #define IB_QPN_MASK 0xffffffUL
-
- /** Default Infiniband partition key */
- #define IB_PKEY_DEFAULT 0xffff
-
- /** Infiniband partition key full membership flag */
- #define IB_PKEY_FULL 0x8000
-
- /**
- * Maximum payload size
- *
- * This is currently hard-coded in various places (drivers, subnet
- * management agent, etc.) to 2048.
- */
- #define IB_MAX_PAYLOAD_SIZE 2048
-
- struct ib_device;
- struct ib_queue_pair;
- struct ib_address_vector;
- struct ib_completion_queue;
- struct ib_mad_interface;
-
- /** Infiniband transmission rates */
- enum ib_rate {
- IB_RATE_2_5 = 2,
- IB_RATE_10 = 3,
- IB_RATE_30 = 4,
- IB_RATE_5 = 5,
- IB_RATE_20 = 6,
- IB_RATE_40 = 7,
- IB_RATE_60 = 8,
- IB_RATE_80 = 9,
- IB_RATE_120 = 10,
- };
-
- /** An Infiniband Address Vector */
- struct ib_address_vector {
- /** Queue Pair Number */
- unsigned long qpn;
- /** Queue key
- *
- * Not specified for received packets.
- */
- unsigned long qkey;
- /** Local ID */
- unsigned int lid;
- /** Rate
- *
- * Not specified for received packets.
- */
- enum ib_rate rate;
- /** Service level */
- unsigned int sl;
- /** GID is present */
- unsigned int gid_present;
- /** GID, if present */
- union ib_gid gid;
- /** VLAN is present */
- unsigned int vlan_present;
- /** VLAN, if present */
- unsigned int vlan;
- };
-
- /** An Infiniband Work Queue */
- struct ib_work_queue {
- /** Containing queue pair */
- struct ib_queue_pair *qp;
- /** "Is a send queue" flag */
- int is_send;
- /** Associated completion queue */
- struct ib_completion_queue *cq;
- /** List of work queues on this completion queue */
- struct list_head list;
- /** Packet sequence number */
- uint32_t psn;
- /** Number of work queue entries */
- unsigned int num_wqes;
- /** Number of occupied work queue entries */
- unsigned int fill;
- /** Next work queue entry index
- *
- * This is the index of the next entry to be filled (i.e. the
- * first empty entry). This value is not bounded by num_wqes;
- * users must logical-AND with (num_wqes-1) to generate an
- * array index.
- */
- unsigned long next_idx;
- /** I/O buffers assigned to work queue */
- struct io_buffer **iobufs;
- /** Driver private data */
- void *drv_priv;
- };
-
- /** An Infiniband multicast GID */
- struct ib_multicast_gid {
- /** List of multicast GIDs on this QP */
- struct list_head list;
- /** Multicast GID */
- union ib_gid gid;
- };
-
- /** An Infiniband queue pair type */
- enum ib_queue_pair_type {
- IB_QPT_SMI,
- IB_QPT_GSI,
- IB_QPT_UD,
- IB_QPT_RC,
- IB_QPT_ETH,
- };
-
- /** Infiniband queue pair operations */
- struct ib_queue_pair_operations {
- /** Allocate receive I/O buffer
- *
- * @v len Maximum receive length
- * @ret iobuf I/O buffer (or NULL if out of memory)
- */
- struct io_buffer * ( * alloc_iob ) ( size_t len );
- };
-
- /** An Infiniband Queue Pair */
- struct ib_queue_pair {
- /** Containing Infiniband device */
- struct ib_device *ibdev;
- /** List of queue pairs on this Infiniband device */
- struct list_head list;
- /** Queue pair name */
- const char *name;
- /** Queue pair number */
- unsigned long qpn;
- /** Externally-visible queue pair number
- *
- * This may differ from the real queue pair number (e.g. when
- * the HCA cannot use the management QPNs 0 and 1 as hardware
- * QPNs and needs to remap them).
- */
- unsigned long ext_qpn;
- /** Queue pair type */
- enum ib_queue_pair_type type;
- /** Queue key */
- unsigned long qkey;
- /** Send queue */
- struct ib_work_queue send;
- /** Receive queue */
- struct ib_work_queue recv;
- /** List of multicast GIDs */
- struct list_head mgids;
- /** Address vector */
- struct ib_address_vector av;
- /** Queue pair operations */
- struct ib_queue_pair_operations *op;
- /** Driver private data */
- void *drv_priv;
- /** Queue owner private data */
- void *owner_priv;
- };
-
- /** Infiniband completion queue operations */
- struct ib_completion_queue_operations {
- /**
- * Complete Send WQE
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @v iobuf I/O buffer
- * @v rc Completion status code
- */
- void ( * complete_send ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- struct io_buffer *iobuf, int rc );
- /**
- * Complete Receive WQE
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @v dest Destination address vector, or NULL
- * @v source Source address vector, or NULL
- * @v iobuf I/O buffer
- * @v rc Completion status code
- */
- void ( * complete_recv ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- struct ib_address_vector *dest,
- struct ib_address_vector *source,
- struct io_buffer *iobuf, int rc );
- };
-
- /** An Infiniband Completion Queue */
- struct ib_completion_queue {
- /** Containing Infiniband device */
- struct ib_device *ibdev;
- /** List of completion queues on this Infiniband device */
- struct list_head list;
- /** Completion queue number */
- unsigned long cqn;
- /** Number of completion queue entries */
- unsigned int num_cqes;
- /** Next completion queue entry index
- *
- * This is the index of the next entry to be filled (i.e. the
- * first empty entry). This value is not bounded by num_wqes;
- * users must logical-AND with (num_wqes-1) to generate an
- * array index.
- */
- unsigned long next_idx;
- /** List of work queues completing to this queue */
- struct list_head work_queues;
- /** Completion queue operations */
- struct ib_completion_queue_operations *op;
- /** Driver private data */
- void *drv_priv;
- };
-
- /**
- * Infiniband device operations
- *
- * These represent a subset of the Infiniband Verbs.
- */
- struct ib_device_operations {
- /** Create completion queue
- *
- * @v ibdev Infiniband device
- * @v cq Completion queue
- * @ret rc Return status code
- */
- int ( * create_cq ) ( struct ib_device *ibdev,
- struct ib_completion_queue *cq );
- /** Destroy completion queue
- *
- * @v ibdev Infiniband device
- * @v cq Completion queue
- */
- void ( * destroy_cq ) ( struct ib_device *ibdev,
- struct ib_completion_queue *cq );
- /** Create queue pair
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @ret rc Return status code
- */
- int ( * create_qp ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp );
- /** Modify queue pair
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @ret rc Return status code
- */
- int ( * modify_qp ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp );
- /** Destroy queue pair
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- */
- void ( * destroy_qp ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp );
- /** Post send work queue entry
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @v dest Destination address vector
- * @v iobuf I/O buffer
- * @ret rc Return status code
- *
- * If this method returns success, the I/O buffer remains
- * owned by the queue pair. If this method returns failure,
- * the I/O buffer is immediately released; the failure is
- * interpreted as "failure to enqueue buffer".
- */
- int ( * post_send ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- struct ib_address_vector *dest,
- struct io_buffer *iobuf );
- /** Post receive work queue entry
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @v iobuf I/O buffer
- * @ret rc Return status code
- *
- * If this method returns success, the I/O buffer remains
- * owned by the queue pair. If this method returns failure,
- * the I/O buffer is immediately released; the failure is
- * interpreted as "failure to enqueue buffer".
- */
- int ( * post_recv ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- struct io_buffer *iobuf );
- /** Poll completion queue
- *
- * @v ibdev Infiniband device
- * @v cq Completion queue
- *
- * The relevant completion handler (specified at completion
- * queue creation time) takes ownership of the I/O buffer.
- */
- void ( * poll_cq ) ( struct ib_device *ibdev,
- struct ib_completion_queue *cq );
- /**
- * Poll event queue
- *
- * @v ibdev Infiniband device
- */
- void ( * poll_eq ) ( struct ib_device *ibdev );
- /**
- * Open port
- *
- * @v ibdev Infiniband device
- * @ret rc Return status code
- */
- int ( * open ) ( struct ib_device *ibdev );
- /**
- * Close port
- *
- * @v ibdev Infiniband device
- */
- void ( * close ) ( struct ib_device *ibdev );
- /** Attach to multicast group
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @v gid Multicast GID
- * @ret rc Return status code
- */
- int ( * mcast_attach ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- union ib_gid *gid );
- /** Detach from multicast group
- *
- * @v ibdev Infiniband device
- * @v qp Queue pair
- * @v gid Multicast GID
- */
- void ( * mcast_detach ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- union ib_gid *gid );
- /** Set port information
- *
- * @v ibdev Infiniband device
- * @v mad Set port information MAD
- *
- * This method is required only by adapters that do not have
- * an embedded SMA.
- */
- int ( * set_port_info ) ( struct ib_device *ibdev, union ib_mad *mad );
- /** Set partition key table
- *
- * @v ibdev Infiniband device
- * @v mad Set partition key table MAD
- *
- * This method is required only by adapters that do not have
- * an embedded SMA.
- */
- int ( * set_pkey_table ) ( struct ib_device *ibdev,
- union ib_mad *mad );
- };
-
- /** Maximum length of an Infiniband device name */
- #define IBDEV_NAME_LEN 8
-
- /** An Infiniband device */
- struct ib_device {
- /** Reference counter */
- struct refcnt refcnt;
- /** List of Infiniband devices */
- struct list_head list;
- /** List of open Infiniband devices */
- struct list_head open_list;
- /** Index of this Infiniband device */
- unsigned int index;
- /** Name of this Infiniband device */
- char name[IBDEV_NAME_LEN];
- /** Underlying device */
- struct device *dev;
- /** List of completion queues */
- struct list_head cqs;
- /** List of queue pairs */
- struct list_head qps;
- /** Infiniband operations */
- struct ib_device_operations *op;
- /** Port number */
- unsigned int port;
- /** Port open request counter */
- unsigned int open_count;
-
- /** Port state */
- uint8_t port_state;
- /** Link width supported */
- uint8_t link_width_supported;
- /** Link width enabled */
- uint8_t link_width_enabled;
- /** Link width active */
- uint8_t link_width_active;
- /** Link speed supported */
- uint8_t link_speed_supported;
- /** Link speed enabled */
- uint8_t link_speed_enabled;
- /** Link speed active */
- uint8_t link_speed_active;
- /** Node GUID */
- union ib_guid node_guid;
- /** Port GID (comprising GID prefix and port GUID) */
- union ib_gid gid;
- /** Port LID */
- uint16_t lid;
- /** Subnet manager LID */
- uint16_t sm_lid;
- /** Subnet manager SL */
- uint8_t sm_sl;
- /** Partition key */
- uint16_t pkey;
-
- /** RDMA key
- *
- * This is a single key allowing unrestricted access to
- * memory.
- */
- uint32_t rdma_key;
-
- /** Subnet management interface */
- struct ib_mad_interface *smi;
- /** General services interface */
- struct ib_mad_interface *gsi;
-
- /** IPoIB LEMAC (if non-default) */
- uint8_t lemac[ETH_ALEN];
-
- /** Driver private data */
- void *drv_priv;
- };
-
- /** An Infiniband upper-layer driver */
- struct ib_driver {
- /** Name */
- const char *name;
- /** Probe device
- *
- * @v ibdev Infiniband device
- * @ret rc Return status code
- */
- int ( * probe ) ( struct ib_device *ibdev );
- /** Notify of device or link state change
- *
- * @v ibdev Infiniband device
- */
- void ( * notify ) ( struct ib_device *ibdev );
- /** Remove device
- *
- * @v ibdev Infiniband device
- */
- void ( * remove ) ( struct ib_device *ibdev );
- };
-
- /** Infiniband driver table */
- #define IB_DRIVERS __table ( struct ib_driver, "ib_drivers" )
-
- /** Declare an Infiniband driver */
- #define __ib_driver __table_entry ( IB_DRIVERS, 01 )
-
- extern int ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
- struct ib_completion_queue_operations *op,
- struct ib_completion_queue **new_cq );
- extern void ib_destroy_cq ( struct ib_device *ibdev,
- struct ib_completion_queue *cq );
- extern void ib_poll_cq ( struct ib_device *ibdev,
- struct ib_completion_queue *cq );
- extern int 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,
- struct ib_queue_pair_operations *op,
- const char *name, struct ib_queue_pair **new_qp );
- extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp );
- extern void ib_destroy_qp ( struct ib_device *ibdev,
- struct ib_queue_pair *qp );
- extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
- unsigned long qpn );
- extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
- union ib_gid *gid );
- extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
- unsigned long qpn, int is_send );
- extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
- struct ib_address_vector *dest,
- struct io_buffer *iobuf );
- extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
- struct io_buffer *iobuf );
- extern void ib_complete_send ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- struct io_buffer *iobuf, int rc );
- extern void ib_complete_recv ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- struct ib_address_vector *dest,
- struct ib_address_vector *source,
- struct io_buffer *iobuf, int rc );
- extern void ib_refill_recv ( struct ib_device *ibdev,
- struct ib_queue_pair *qp );
- extern int ib_open ( struct ib_device *ibdev );
- extern void ib_close ( struct ib_device *ibdev );
- extern int ib_link_rc ( struct ib_device *ibdev );
- extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
- union ib_gid *gid );
- extern void ib_mcast_detach ( struct ib_device *ibdev,
- struct ib_queue_pair *qp, union ib_gid *gid );
- extern int ib_count_ports ( struct ib_device *ibdev );
- extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad );
- extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad );
- extern struct ib_device * alloc_ibdev ( size_t priv_size );
- extern int register_ibdev ( struct ib_device *ibdev );
- extern void unregister_ibdev ( struct ib_device *ibdev );
- extern struct ib_device * find_ibdev ( union ib_gid *gid );
- extern struct ib_device * last_opened_ibdev ( void );
- extern void ib_link_state_changed ( struct ib_device *ibdev );
- extern void ib_poll_eq ( struct ib_device *ibdev );
- extern struct list_head ib_devices;
-
- /** Iterate over all network devices */
- #define for_each_ibdev( ibdev ) \
- list_for_each_entry ( (ibdev), &ib_devices, list )
-
- /**
- * Check link state of Infiniband device
- *
- * @v ibdev Infiniband device
- * @ret link_up Link is up
- */
- static inline __always_inline int
- ib_link_ok ( struct ib_device *ibdev ) {
- return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
- }
-
- /**
- * Check whether or not Infiniband device is open
- *
- * @v ibdev Infiniband device
- * @v is_open Infiniband device is open
- */
- static inline __attribute__ (( always_inline )) int
- ib_is_open ( struct ib_device *ibdev ) {
- return ( ibdev->open_count > 0 );
- }
-
- /**
- * Get reference to Infiniband device
- *
- * @v ibdev Infiniband device
- * @ret ibdev Infiniband device
- */
- static inline __always_inline struct ib_device *
- ibdev_get ( struct ib_device *ibdev ) {
- ref_get ( &ibdev->refcnt );
- return ibdev;
- }
-
- /**
- * Drop reference to Infiniband device
- *
- * @v ibdev Infiniband device
- */
- static inline __always_inline void
- ibdev_put ( struct ib_device *ibdev ) {
- ref_put ( &ibdev->refcnt );
- }
-
- /**
- * Set Infiniband work queue driver-private data
- *
- * @v wq Work queue
- * @v priv Private data
- */
- static inline __always_inline void
- ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
- wq->drv_priv = priv;
- }
-
- /**
- * Get Infiniband work queue driver-private data
- *
- * @v wq Work queue
- * @ret priv Private data
- */
- static inline __always_inline void *
- ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
- return wq->drv_priv;
- }
-
- /**
- * Set Infiniband queue pair driver-private data
- *
- * @v qp Queue pair
- * @v priv Private data
- */
- static inline __always_inline void
- ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
- qp->drv_priv = priv;
- }
-
- /**
- * Get Infiniband queue pair driver-private data
- *
- * @v qp Queue pair
- * @ret priv Private data
- */
- static inline __always_inline void *
- ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
- return qp->drv_priv;
- }
-
- /**
- * Set Infiniband queue pair owner-private data
- *
- * @v qp Queue pair
- * @v priv Private data
- */
- static inline __always_inline void
- ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
- qp->owner_priv = priv;
- }
-
- /**
- * Get Infiniband queue pair owner-private data
- *
- * @v qp Queue pair
- * @ret priv Private data
- */
- static inline __always_inline void *
- ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
- return qp->owner_priv;
- }
-
- /**
- * Set Infiniband completion queue driver-private data
- *
- * @v cq Completion queue
- * @v priv Private data
- */
- static inline __always_inline void
- ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
- cq->drv_priv = priv;
- }
-
- /**
- * Get Infiniband completion queue driver-private data
- *
- * @v cq Completion queue
- * @ret priv Private data
- */
- static inline __always_inline void *
- ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
- return cq->drv_priv;
- }
-
- /**
- * Set Infiniband device driver-private data
- *
- * @v ibdev Infiniband device
- * @v priv Private data
- */
- static inline __always_inline void
- ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
- ibdev->drv_priv = priv;
- }
-
- /**
- * Get Infiniband device driver-private data
- *
- * @v ibdev Infiniband device
- * @ret priv Private data
- */
- static inline __always_inline void *
- ib_get_drvdata ( struct ib_device *ibdev ) {
- return ibdev->drv_priv;
- }
-
- #endif /* _IPXE_INFINIBAND_H */
|