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>
18
#include <ipxe/if_ether.h>
20
/** Subnet management interface QPN */
23
/** Subnet management interface queue key */
26
/** General service interface QPN */
29
/** General service interface queue key */
30
#define IB_QKEY_GSI 0x80010000UL
33
#define IB_QPN_BROADCAST 0xffffffUL
36
#define IB_QPN_MASK 0xffffffUL
38
/** Default Infiniband partition key */
39
#define IB_PKEY_DEFAULT 0xffff
41
/** Infiniband partition key full membership flag */
42
#define IB_PKEY_FULL 0x8000
45
* Maximum payload size
47
* This is currently hard-coded in various places (drivers, subnet
48
* management agent, etc.) to 2048.
50
#define IB_MAX_PAYLOAD_SIZE 2048
54
struct ib_address_vector;
55
struct ib_completion_queue;
56
struct ib_mad_interface;
58
/** Infiniband transmission rates */
71
/** An Infiniband Address Vector */
72
struct ib_address_vector {
73
/** Queue Pair Number */
77
* Not specified for received packets.
84
* Not specified for received packets.
90
unsigned int gid_present;
91
/** GID, if present */
93
/** VLAN is present */
94
unsigned int vlan_present;
95
/** VLAN, if present */
99
/** An Infiniband Work Queue */
100
struct ib_work_queue {
101
/** Containing queue pair */
102
struct ib_queue_pair *qp;
103
/** "Is a send queue" flag */
105
/** Associated completion queue */
106
struct ib_completion_queue *cq;
107
/** List of work queues on this completion queue */
108
struct list_head list;
109
/** Packet sequence number */
111
/** Number of work queue entries */
112
unsigned int num_wqes;
113
/** Number of occupied work queue entries */
115
/** Next work queue entry index
117
* This is the index of the next entry to be filled (i.e. the
118
* first empty entry). This value is not bounded by num_wqes;
119
* users must logical-AND with (num_wqes-1) to generate an
122
unsigned long next_idx;
123
/** I/O buffers assigned to work queue */
124
struct io_buffer **iobufs;
125
/** Driver private data */
129
/** An Infiniband multicast GID */
130
struct ib_multicast_gid {
131
/** List of multicast GIDs on this QP */
132
struct list_head list;
137
/** An Infiniband queue pair type */
138
enum ib_queue_pair_type {
146
/** Infiniband queue pair operations */
147
struct ib_queue_pair_operations {
148
/** Allocate receive I/O buffer
150
* @v len Maximum receive length
151
* @ret iobuf I/O buffer (or NULL if out of memory)
153
struct io_buffer * ( * alloc_iob ) ( size_t len );
156
/** An Infiniband Queue Pair */
157
struct ib_queue_pair {
158
/** Containing Infiniband device */
159
struct ib_device *ibdev;
160
/** List of queue pairs on this Infiniband device */
161
struct list_head list;
162
/** Queue pair name */
164
/** Queue pair number */
166
/** Externally-visible queue pair number
168
* This may differ from the real queue pair number (e.g. when
169
* the HCA cannot use the management QPNs 0 and 1 as hardware
170
* QPNs and needs to remap them).
172
unsigned long ext_qpn;
173
/** Queue pair type */
174
enum ib_queue_pair_type type;
178
struct ib_work_queue send;
180
struct ib_work_queue recv;
181
/** List of multicast GIDs */
182
struct list_head mgids;
183
/** Address vector */
184
struct ib_address_vector av;
185
/** Queue pair operations */
186
struct ib_queue_pair_operations *op;
187
/** Driver private data */
189
/** Queue owner private data */
193
/** Infiniband completion queue operations */
194
struct ib_completion_queue_operations {
198
* @v ibdev Infiniband device
200
* @v iobuf I/O buffer
201
* @v rc Completion status code
203
void ( * complete_send ) ( struct ib_device *ibdev,
204
struct ib_queue_pair *qp,
205
struct io_buffer *iobuf, int rc );
207
* Complete Receive WQE
209
* @v ibdev Infiniband device
211
* @v dest Destination address vector, or NULL
212
* @v source Source address vector, or NULL
213
* @v iobuf I/O buffer
214
* @v rc Completion status code
216
void ( * complete_recv ) ( struct ib_device *ibdev,
217
struct ib_queue_pair *qp,
218
struct ib_address_vector *dest,
219
struct ib_address_vector *source,
220
struct io_buffer *iobuf, int rc );
223
/** An Infiniband Completion Queue */
224
struct ib_completion_queue {
225
/** Containing Infiniband device */
226
struct ib_device *ibdev;
227
/** List of completion queues on this Infiniband device */
228
struct list_head list;
229
/** Completion queue number */
231
/** Number of completion queue entries */
232
unsigned int num_cqes;
233
/** Next completion queue entry index
235
* This is the index of the next entry to be filled (i.e. the
236
* first empty entry). This value is not bounded by num_wqes;
237
* users must logical-AND with (num_wqes-1) to generate an
240
unsigned long next_idx;
241
/** List of work queues completing to this queue */
242
struct list_head work_queues;
243
/** Completion queue operations */
244
struct ib_completion_queue_operations *op;
245
/** Driver private data */
250
* Infiniband device operations
252
* These represent a subset of the Infiniband Verbs.
254
struct ib_device_operations {
255
/** Create completion queue
257
* @v ibdev Infiniband device
258
* @v cq Completion queue
259
* @ret rc Return status code
261
int ( * create_cq ) ( struct ib_device *ibdev,
262
struct ib_completion_queue *cq );
263
/** Destroy completion queue
265
* @v ibdev Infiniband device
266
* @v cq Completion queue
268
void ( * destroy_cq ) ( struct ib_device *ibdev,
269
struct ib_completion_queue *cq );
270
/** Create queue pair
272
* @v ibdev Infiniband device
274
* @ret rc Return status code
276
int ( * create_qp ) ( struct ib_device *ibdev,
277
struct ib_queue_pair *qp );
278
/** Modify queue pair
280
* @v ibdev Infiniband device
282
* @ret rc Return status code
284
int ( * modify_qp ) ( struct ib_device *ibdev,
285
struct ib_queue_pair *qp );
286
/** Destroy queue pair
288
* @v ibdev Infiniband device
291
void ( * destroy_qp ) ( struct ib_device *ibdev,
292
struct ib_queue_pair *qp );
293
/** Post send work queue entry
295
* @v ibdev Infiniband device
297
* @v dest Destination address vector
298
* @v iobuf I/O buffer
299
* @ret rc Return status code
301
* If this method returns success, the I/O buffer remains
302
* owned by the queue pair. If this method returns failure,
303
* the I/O buffer is immediately released; the failure is
304
* interpreted as "failure to enqueue buffer".
306
int ( * post_send ) ( struct ib_device *ibdev,
307
struct ib_queue_pair *qp,
308
struct ib_address_vector *dest,
309
struct io_buffer *iobuf );
310
/** Post receive work queue entry
312
* @v ibdev Infiniband device
314
* @v iobuf I/O buffer
315
* @ret rc Return status code
317
* If this method returns success, the I/O buffer remains
318
* owned by the queue pair. If this method returns failure,
319
* the I/O buffer is immediately released; the failure is
320
* interpreted as "failure to enqueue buffer".
322
int ( * post_recv ) ( struct ib_device *ibdev,
323
struct ib_queue_pair *qp,
324
struct io_buffer *iobuf );
325
/** Poll completion queue
327
* @v ibdev Infiniband device
328
* @v cq Completion queue
330
* The relevant completion handler (specified at completion
331
* queue creation time) takes ownership of the I/O buffer.
333
void ( * poll_cq ) ( struct ib_device *ibdev,
334
struct ib_completion_queue *cq );
338
* @v ibdev Infiniband device
340
void ( * poll_eq ) ( struct ib_device *ibdev );
344
* @v ibdev Infiniband device
345
* @ret rc Return status code
347
int ( * open ) ( struct ib_device *ibdev );
351
* @v ibdev Infiniband device
353
void ( * close ) ( struct ib_device *ibdev );
354
/** Attach to multicast group
356
* @v ibdev Infiniband device
358
* @v gid Multicast GID
359
* @ret rc Return status code
361
int ( * mcast_attach ) ( struct ib_device *ibdev,
362
struct ib_queue_pair *qp,
364
/** Detach from multicast group
366
* @v ibdev Infiniband device
368
* @v gid Multicast GID
370
void ( * mcast_detach ) ( struct ib_device *ibdev,
371
struct ib_queue_pair *qp,
373
/** Set port information
375
* @v ibdev Infiniband device
376
* @v mad Set port information MAD
378
* This method is required only by adapters that do not have
381
int ( * set_port_info ) ( struct ib_device *ibdev, union ib_mad *mad );
382
/** Set partition key table
384
* @v ibdev Infiniband device
385
* @v mad Set partition key table MAD
387
* This method is required only by adapters that do not have
390
int ( * set_pkey_table ) ( struct ib_device *ibdev,
394
/** Maximum length of an Infiniband device name */
395
#define IBDEV_NAME_LEN 8
397
/** An Infiniband device */
399
/** Reference counter */
400
struct refcnt refcnt;
401
/** List of Infiniband devices */
402
struct list_head list;
403
/** List of open Infiniband devices */
404
struct list_head open_list;
405
/** Index of this Infiniband device */
407
/** Name of this Infiniband device */
408
char name[IBDEV_NAME_LEN];
409
/** Underlying device */
411
/** List of completion queues */
412
struct list_head cqs;
413
/** List of queue pairs */
414
struct list_head qps;
415
/** Infiniband operations */
416
struct ib_device_operations *op;
419
/** Port open request counter */
420
unsigned int open_count;
424
/** Link width supported */
425
uint8_t link_width_supported;
426
/** Link width enabled */
427
uint8_t link_width_enabled;
428
/** Link width active */
429
uint8_t link_width_active;
430
/** Link speed supported */
431
uint8_t link_speed_supported;
432
/** Link speed enabled */
433
uint8_t link_speed_enabled;
434
/** Link speed active */
435
uint8_t link_speed_active;
437
union ib_guid node_guid;
438
/** Port GID (comprising GID prefix and port GUID) */
442
/** Subnet manager LID */
444
/** Subnet manager SL */
451
* This is a single key allowing unrestricted access to
456
/** Subnet management interface */
457
struct ib_mad_interface *smi;
458
/** General services interface */
459
struct ib_mad_interface *gsi;
461
/** IPoIB LEMAC (if non-default) */
462
uint8_t lemac[ETH_ALEN];
464
/** Driver private data */
468
/** An Infiniband upper-layer driver */
474
* @v ibdev Infiniband device
475
* @ret rc Return status code
477
int ( * probe ) ( struct ib_device *ibdev );
478
/** Notify of device or link state change
480
* @v ibdev Infiniband device
482
void ( * notify ) ( struct ib_device *ibdev );
485
* @v ibdev Infiniband device
487
void ( * remove ) ( struct ib_device *ibdev );
490
/** Infiniband driver table */
491
#define IB_DRIVERS __table ( struct ib_driver, "ib_drivers" )
493
/** Declare an Infiniband driver */
494
#define __ib_driver __table_entry ( IB_DRIVERS, 01 )
496
extern struct ib_completion_queue *
497
ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
498
struct ib_completion_queue_operations *op );
499
extern void ib_destroy_cq ( struct ib_device *ibdev,
500
struct ib_completion_queue *cq );
501
extern void ib_poll_cq ( struct ib_device *ibdev,
502
struct ib_completion_queue *cq );
503
extern struct ib_queue_pair *
504
ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type,
505
unsigned int num_send_wqes, struct ib_completion_queue *send_cq,
506
unsigned int num_recv_wqes, struct ib_completion_queue *recv_cq,
507
struct ib_queue_pair_operations *op, const char *name );
508
extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp );
509
extern void ib_destroy_qp ( struct ib_device *ibdev,
510
struct ib_queue_pair *qp );
511
extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
513
extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
515
extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
516
unsigned long qpn, int is_send );
517
extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
518
struct ib_address_vector *dest,
519
struct io_buffer *iobuf );
520
extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
521
struct io_buffer *iobuf );
522
extern void ib_complete_send ( struct ib_device *ibdev,
523
struct ib_queue_pair *qp,
524
struct io_buffer *iobuf, int rc );
525
extern void ib_complete_recv ( struct ib_device *ibdev,
526
struct ib_queue_pair *qp,
527
struct ib_address_vector *dest,
528
struct ib_address_vector *source,
529
struct io_buffer *iobuf, int rc );
530
extern void ib_refill_recv ( struct ib_device *ibdev,
531
struct ib_queue_pair *qp );
532
extern int ib_open ( struct ib_device *ibdev );
533
extern void ib_close ( struct ib_device *ibdev );
534
extern int ib_link_rc ( struct ib_device *ibdev );
535
extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
537
extern void ib_mcast_detach ( struct ib_device *ibdev,
538
struct ib_queue_pair *qp, union ib_gid *gid );
539
extern int ib_count_ports ( struct ib_device *ibdev );
540
extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad );
541
extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad );
542
extern struct ib_device * alloc_ibdev ( size_t priv_size );
543
extern int register_ibdev ( struct ib_device *ibdev );
544
extern void unregister_ibdev ( struct ib_device *ibdev );
545
extern struct ib_device * find_ibdev ( union ib_gid *gid );
546
extern struct ib_device * last_opened_ibdev ( void );
547
extern void ib_link_state_changed ( struct ib_device *ibdev );
548
extern void ib_poll_eq ( struct ib_device *ibdev );
549
extern struct list_head ib_devices;
551
/** Iterate over all network devices */
552
#define for_each_ibdev( ibdev ) \
553
list_for_each_entry ( (ibdev), &ib_devices, list )
556
* Check link state of Infiniband device
558
* @v ibdev Infiniband device
559
* @ret link_up Link is up
561
static inline __always_inline int
562
ib_link_ok ( struct ib_device *ibdev ) {
563
return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
567
* Check whether or not Infiniband device is open
569
* @v ibdev Infiniband device
570
* @v is_open Infiniband device is open
572
static inline __attribute__ (( always_inline )) int
573
ib_is_open ( struct ib_device *ibdev ) {
574
return ( ibdev->open_count > 0 );
578
* Get reference to Infiniband device
580
* @v ibdev Infiniband device
581
* @ret ibdev Infiniband device
583
static inline __always_inline struct ib_device *
584
ibdev_get ( struct ib_device *ibdev ) {
585
ref_get ( &ibdev->refcnt );
590
* Drop reference to Infiniband device
592
* @v ibdev Infiniband device
594
static inline __always_inline void
595
ibdev_put ( struct ib_device *ibdev ) {
596
ref_put ( &ibdev->refcnt );
600
* Set Infiniband work queue driver-private data
603
* @v priv Private data
605
static inline __always_inline void
606
ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
611
* Get Infiniband work queue driver-private data
614
* @ret priv Private data
616
static inline __always_inline void *
617
ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
622
* Set Infiniband queue pair driver-private data
625
* @v priv Private data
627
static inline __always_inline void
628
ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
633
* Get Infiniband queue pair driver-private data
636
* @ret priv Private data
638
static inline __always_inline void *
639
ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
644
* Set Infiniband queue pair owner-private data
647
* @v priv Private data
649
static inline __always_inline void
650
ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
651
qp->owner_priv = priv;
655
* Get Infiniband queue pair owner-private data
658
* @ret priv Private data
660
static inline __always_inline void *
661
ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
662
return qp->owner_priv;
666
* Set Infiniband completion queue driver-private data
668
* @v cq Completion queue
669
* @v priv Private data
671
static inline __always_inline void
672
ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
677
* Get Infiniband completion queue driver-private data
679
* @v cq Completion queue
680
* @ret priv Private data
682
static inline __always_inline void *
683
ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
688
* Set Infiniband device driver-private data
690
* @v ibdev Infiniband device
691
* @v priv Private data
693
static inline __always_inline void
694
ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
695
ibdev->drv_priv = priv;
699
* Get Infiniband device driver-private data
701
* @v ibdev Infiniband device
702
* @ret priv Private data
704
static inline __always_inline void *
705
ib_get_drvdata ( struct ib_device *ibdev ) {
706
return ibdev->drv_priv;
709
#endif /* _IPXE_INFINIBAND_H */