1 #ifndef _IPXE_INFINIBAND_H
2 #define _IPXE_INFINIBAND_H
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
13 #include <ipxe/refcnt.h>
14 #include <ipxe/device.h>
15 #include <ipxe/tables.h>
16 #include <ipxe/ib_packet.h>
17 #include <ipxe/ib_mad.h>
19 /** Subnet management interface QPN */
22 /** Subnet management interface queue key */
25 /** General service interface QPN */
28 /** General service interface queue key */
29 #define IB_QKEY_GSI 0x80010000UL
32 #define IB_QPN_BROADCAST 0xffffffUL
35 #define IB_QPN_MASK 0xffffffUL
37 /** Default Infiniband partition key */
38 #define IB_PKEY_DEFAULT 0xffff
40 /** Infiniband partition key full membership flag */
41 #define IB_PKEY_FULL 0x8000
44 * Maximum payload size
46 * This is currently hard-coded in various places (drivers, subnet
47 * management agent, etc.) to 2048.
49 #define IB_MAX_PAYLOAD_SIZE 2048
53 struct ib_address_vector;
54 struct ib_completion_queue;
55 struct ib_mad_interface;
57 /** Infiniband transmission rates */
70 /** An Infiniband Address Vector */
71 struct ib_address_vector {
72 /** Queue Pair Number */
76 * Not specified for received packets.
83 * Not specified for received packets.
89 unsigned int gid_present;
90 /** GID, if present */
92 /** VLAN is present */
93 unsigned int vlan_present;
94 /** VLAN, if present */
98 /** An Infiniband Work Queue */
99 struct ib_work_queue {
100 /** Containing queue pair */
101 struct ib_queue_pair *qp;
102 /** "Is a send queue" flag */
104 /** Associated completion queue */
105 struct ib_completion_queue *cq;
106 /** List of work queues on this completion queue */
107 struct list_head list;
108 /** Packet sequence number */
110 /** Number of work queue entries */
111 unsigned int num_wqes;
112 /** Number of occupied work queue entries */
114 /** Next work queue entry index
116 * This is the index of the next entry to be filled (i.e. the
117 * first empty entry). This value is not bounded by num_wqes;
118 * users must logical-AND with (num_wqes-1) to generate an
121 unsigned long next_idx;
122 /** I/O buffers assigned to work queue */
123 struct io_buffer **iobufs;
124 /** Driver private data */
128 /** An Infiniband multicast GID */
129 struct ib_multicast_gid {
130 /** List of multicast GIDs on this QP */
131 struct list_head list;
136 /** An Infiniband queue pair type */
137 enum ib_queue_pair_type {
145 /** Infiniband queue pair operations */
146 struct ib_queue_pair_operations {
147 /** Allocate receive I/O buffer
149 * @v len Maximum receive length
150 * @ret iobuf I/O buffer (or NULL if out of memory)
152 struct io_buffer * ( * alloc_iob ) ( size_t len );
155 /** An Infiniband Queue Pair */
156 struct ib_queue_pair {
157 /** Containing Infiniband device */
158 struct ib_device *ibdev;
159 /** List of queue pairs on this Infiniband device */
160 struct list_head list;
161 /** Queue pair number */
163 /** Externally-visible queue pair number
165 * This may differ from the real queue pair number (e.g. when
166 * the HCA cannot use the management QPNs 0 and 1 as hardware
167 * QPNs and needs to remap them).
169 unsigned long ext_qpn;
170 /** Queue pair type */
171 enum ib_queue_pair_type type;
175 struct ib_work_queue send;
177 struct ib_work_queue recv;
178 /** List of multicast GIDs */
179 struct list_head mgids;
180 /** Address vector */
181 struct ib_address_vector av;
182 /** Queue pair operations */
183 struct ib_queue_pair_operations *op;
184 /** Driver private data */
186 /** Queue owner private data */
190 /** Infiniband completion queue operations */
191 struct ib_completion_queue_operations {
195 * @v ibdev Infiniband device
197 * @v iobuf I/O buffer
198 * @v rc Completion status code
200 void ( * complete_send ) ( struct ib_device *ibdev,
201 struct ib_queue_pair *qp,
202 struct io_buffer *iobuf, int rc );
204 * Complete Receive WQE
206 * @v ibdev Infiniband device
208 * @v dest Destination address vector, or NULL
209 * @v source Source address vector, or NULL
210 * @v iobuf I/O buffer
211 * @v rc Completion status code
213 void ( * complete_recv ) ( struct ib_device *ibdev,
214 struct ib_queue_pair *qp,
215 struct ib_address_vector *dest,
216 struct ib_address_vector *source,
217 struct io_buffer *iobuf, int rc );
220 /** An Infiniband Completion Queue */
221 struct ib_completion_queue {
222 /** Containing Infiniband device */
223 struct ib_device *ibdev;
224 /** List of completion queues on this Infiniband device */
225 struct list_head list;
226 /** Completion queue number */
228 /** Number of completion queue entries */
229 unsigned int num_cqes;
230 /** Next completion queue entry index
232 * This is the index of the next entry to be filled (i.e. the
233 * first empty entry). This value is not bounded by num_wqes;
234 * users must logical-AND with (num_wqes-1) to generate an
237 unsigned long next_idx;
238 /** List of work queues completing to this queue */
239 struct list_head work_queues;
240 /** Completion queue operations */
241 struct ib_completion_queue_operations *op;
242 /** Driver private data */
247 * Infiniband device operations
249 * These represent a subset of the Infiniband Verbs.
251 struct ib_device_operations {
252 /** Create completion queue
254 * @v ibdev Infiniband device
255 * @v cq Completion queue
256 * @ret rc Return status code
258 int ( * create_cq ) ( struct ib_device *ibdev,
259 struct ib_completion_queue *cq );
260 /** Destroy completion queue
262 * @v ibdev Infiniband device
263 * @v cq Completion queue
265 void ( * destroy_cq ) ( struct ib_device *ibdev,
266 struct ib_completion_queue *cq );
267 /** Create queue pair
269 * @v ibdev Infiniband device
271 * @ret rc Return status code
273 int ( * create_qp ) ( struct ib_device *ibdev,
274 struct ib_queue_pair *qp );
275 /** Modify queue pair
277 * @v ibdev Infiniband device
279 * @ret rc Return status code
281 int ( * modify_qp ) ( struct ib_device *ibdev,
282 struct ib_queue_pair *qp );
283 /** Destroy queue pair
285 * @v ibdev Infiniband device
288 void ( * destroy_qp ) ( struct ib_device *ibdev,
289 struct ib_queue_pair *qp );
290 /** Post send work queue entry
292 * @v ibdev Infiniband device
294 * @v dest Destination address vector
295 * @v iobuf I/O buffer
296 * @ret rc Return status code
298 * If this method returns success, the I/O buffer remains
299 * owned by the queue pair. If this method returns failure,
300 * the I/O buffer is immediately released; the failure is
301 * interpreted as "failure to enqueue buffer".
303 int ( * post_send ) ( struct ib_device *ibdev,
304 struct ib_queue_pair *qp,
305 struct ib_address_vector *dest,
306 struct io_buffer *iobuf );
307 /** Post receive work queue entry
309 * @v ibdev Infiniband device
311 * @v iobuf I/O buffer
312 * @ret rc Return status code
314 * If this method returns success, the I/O buffer remains
315 * owned by the queue pair. If this method returns failure,
316 * the I/O buffer is immediately released; the failure is
317 * interpreted as "failure to enqueue buffer".
319 int ( * post_recv ) ( struct ib_device *ibdev,
320 struct ib_queue_pair *qp,
321 struct io_buffer *iobuf );
322 /** Poll completion queue
324 * @v ibdev Infiniband device
325 * @v cq Completion queue
327 * The relevant completion handler (specified at completion
328 * queue creation time) takes ownership of the I/O buffer.
330 void ( * poll_cq ) ( struct ib_device *ibdev,
331 struct ib_completion_queue *cq );
335 * @v ibdev Infiniband device
337 void ( * poll_eq ) ( struct ib_device *ibdev );
341 * @v ibdev Infiniband device
342 * @ret rc Return status code
344 int ( * open ) ( struct ib_device *ibdev );
348 * @v ibdev Infiniband device
350 void ( * close ) ( struct ib_device *ibdev );
351 /** Attach to multicast group
353 * @v ibdev Infiniband device
355 * @v gid Multicast GID
356 * @ret rc Return status code
358 int ( * mcast_attach ) ( struct ib_device *ibdev,
359 struct ib_queue_pair *qp,
361 /** Detach from multicast group
363 * @v ibdev Infiniband device
365 * @v gid Multicast GID
367 void ( * mcast_detach ) ( struct ib_device *ibdev,
368 struct ib_queue_pair *qp,
370 /** Set port information
372 * @v ibdev Infiniband device
373 * @v mad Set port information MAD
375 * This method is required only by adapters that do not have
378 int ( * set_port_info ) ( struct ib_device *ibdev, union ib_mad *mad );
379 /** Set partition key table
381 * @v ibdev Infiniband device
382 * @v mad Set partition key table MAD
384 * This method is required only by adapters that do not have
387 int ( * set_pkey_table ) ( struct ib_device *ibdev,
391 /** An Infiniband device */
393 /** Reference counter */
394 struct refcnt refcnt;
395 /** List of Infiniband devices */
396 struct list_head list;
397 /** List of open Infiniband devices */
398 struct list_head open_list;
399 /** Underlying device */
401 /** List of completion queues */
402 struct list_head cqs;
403 /** List of queue pairs */
404 struct list_head qps;
405 /** Infiniband operations */
406 struct ib_device_operations *op;
409 /** Port open request counter */
410 unsigned int open_count;
414 /** Link width supported */
415 uint8_t link_width_supported;
416 /** Link width enabled */
417 uint8_t link_width_enabled;
418 /** Link width active */
419 uint8_t link_width_active;
420 /** Link speed supported */
421 uint8_t link_speed_supported;
422 /** Link speed enabled */
423 uint8_t link_speed_enabled;
424 /** Link speed active */
425 uint8_t link_speed_active;
427 union ib_guid node_guid;
428 /** Port GID (comprising GID prefix and port GUID) */
432 /** Subnet manager LID */
434 /** Subnet manager SL */
441 * This is a single key allowing unrestricted access to
446 /** Subnet management interface */
447 struct ib_mad_interface *smi;
448 /** General services interface */
449 struct ib_mad_interface *gsi;
451 /** Driver private data */
453 /** Owner private data */
457 /** An Infiniband upper-layer driver */
463 * @v ibdev Infiniband device
464 * @ret rc Return status code
466 int ( * probe ) ( struct ib_device *ibdev );
467 /** Notify of device or link state change
469 * @v ibdev Infiniband device
471 void ( * notify ) ( struct ib_device *ibdev );
474 * @v ibdev Infiniband device
476 void ( * remove ) ( struct ib_device *ibdev );
479 /** Infiniband driver table */
480 #define IB_DRIVERS __table ( struct ib_driver, "ib_drivers" )
482 /** Declare an Infiniband driver */
483 #define __ib_driver __table_entry ( IB_DRIVERS, 01 )
485 extern struct ib_completion_queue *
486 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
487 struct ib_completion_queue_operations *op );
488 extern void ib_destroy_cq ( struct ib_device *ibdev,
489 struct ib_completion_queue *cq );
490 extern void ib_poll_cq ( struct ib_device *ibdev,
491 struct ib_completion_queue *cq );
492 extern struct ib_queue_pair *
493 ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type,
494 unsigned int num_send_wqes, struct ib_completion_queue *send_cq,
495 unsigned int num_recv_wqes, struct ib_completion_queue *recv_cq,
496 struct ib_queue_pair_operations *op );
497 extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp );
498 extern void ib_destroy_qp ( struct ib_device *ibdev,
499 struct ib_queue_pair *qp );
500 extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
502 extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
504 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
505 unsigned long qpn, int is_send );
506 extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
507 struct ib_address_vector *dest,
508 struct io_buffer *iobuf );
509 extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
510 struct io_buffer *iobuf );
511 extern void ib_complete_send ( struct ib_device *ibdev,
512 struct ib_queue_pair *qp,
513 struct io_buffer *iobuf, int rc );
514 extern void ib_complete_recv ( struct ib_device *ibdev,
515 struct ib_queue_pair *qp,
516 struct ib_address_vector *dest,
517 struct ib_address_vector *source,
518 struct io_buffer *iobuf, int rc );
519 extern void ib_refill_recv ( struct ib_device *ibdev,
520 struct ib_queue_pair *qp );
521 extern int ib_open ( struct ib_device *ibdev );
522 extern void ib_close ( struct ib_device *ibdev );
523 extern int ib_link_rc ( struct ib_device *ibdev );
524 extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
526 extern void ib_mcast_detach ( struct ib_device *ibdev,
527 struct ib_queue_pair *qp, union ib_gid *gid );
528 extern int ib_count_ports ( struct ib_device *ibdev );
529 extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad );
530 extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad );
531 extern struct ib_device * alloc_ibdev ( size_t priv_size );
532 extern int register_ibdev ( struct ib_device *ibdev );
533 extern void unregister_ibdev ( struct ib_device *ibdev );
534 extern struct ib_device * find_ibdev ( union ib_gid *gid );
535 extern struct ib_device * last_opened_ibdev ( void );
536 extern void ib_link_state_changed ( struct ib_device *ibdev );
537 extern void ib_poll_eq ( struct ib_device *ibdev );
538 extern struct list_head ib_devices;
540 /** Iterate over all network devices */
541 #define for_each_ibdev( ibdev ) \
542 list_for_each_entry ( (ibdev), &ib_devices, list )
545 * Check link state of Infiniband device
547 * @v ibdev Infiniband device
548 * @ret link_up Link is up
550 static inline __always_inline int
551 ib_link_ok ( struct ib_device *ibdev ) {
552 return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
556 * Check whether or not Infiniband device is open
558 * @v ibdev Infiniband device
559 * @v is_open Infiniband device is open
561 static inline __attribute__ (( always_inline )) int
562 ib_is_open ( struct ib_device *ibdev ) {
563 return ( ibdev->open_count > 0 );
567 * Get reference to Infiniband device
569 * @v ibdev Infiniband device
570 * @ret ibdev Infiniband device
572 static inline __always_inline struct ib_device *
573 ibdev_get ( struct ib_device *ibdev ) {
574 ref_get ( &ibdev->refcnt );
579 * Drop reference to Infiniband device
581 * @v ibdev Infiniband device
583 static inline __always_inline void
584 ibdev_put ( struct ib_device *ibdev ) {
585 ref_put ( &ibdev->refcnt );
589 * Set Infiniband work queue driver-private data
592 * @v priv Private data
594 static inline __always_inline void
595 ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
600 * Get Infiniband work queue driver-private data
603 * @ret priv Private data
605 static inline __always_inline void *
606 ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
611 * Set Infiniband queue pair driver-private data
614 * @v priv Private data
616 static inline __always_inline void
617 ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
622 * Get Infiniband queue pair driver-private data
625 * @ret priv Private data
627 static inline __always_inline void *
628 ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
633 * Set Infiniband queue pair owner-private data
636 * @v priv Private data
638 static inline __always_inline void
639 ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
640 qp->owner_priv = priv;
644 * Get Infiniband queue pair owner-private data
647 * @ret priv Private data
649 static inline __always_inline void *
650 ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
651 return qp->owner_priv;
655 * Set Infiniband completion queue driver-private data
657 * @v cq Completion queue
658 * @v priv Private data
660 static inline __always_inline void
661 ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
666 * Get Infiniband completion queue driver-private data
668 * @v cq Completion queue
669 * @ret priv Private data
671 static inline __always_inline void *
672 ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
677 * Set Infiniband device driver-private data
679 * @v ibdev Infiniband device
680 * @v priv Private data
682 static inline __always_inline void
683 ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
684 ibdev->drv_priv = priv;
688 * Get Infiniband device driver-private data
690 * @v ibdev Infiniband device
691 * @ret priv Private data
693 static inline __always_inline void *
694 ib_get_drvdata ( struct ib_device *ibdev ) {
695 return ibdev->drv_priv;
699 * Set Infiniband device owner-private data
701 * @v ibdev Infiniband device
702 * @v priv Private data
704 static inline __always_inline void
705 ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
706 ibdev->owner_priv = priv;
710 * Get Infiniband device owner-private data
712 * @v ibdev Infiniband device
713 * @ret priv Private data
715 static inline __always_inline void *
716 ib_get_ownerdata ( struct ib_device *ibdev ) {
717 return ibdev->owner_priv;
720 #endif /* _IPXE_INFINIBAND_H */