3ffd5e665f646ecfff2c240a2d502dceb180fb86
[people/sha0/gpxe.git] / src / include / gpxe / infiniband.h
1 #ifndef _GPXE_INFINIBAND_H
2 #define _GPXE_INFINIBAND_H
3
4 /** @file
5  *
6  * Infiniband protocol
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER );
11
12 #include <stdint.h>
13 #include <gpxe/refcnt.h>
14 #include <gpxe/device.h>
15 #include <gpxe/ib_packet.h>
16 #include <gpxe/ib_mad.h>
17 #include <gpxe/ib_gma.h>
18
19 /** Subnet management QPN */
20 #define IB_QPN_SMA 0
21
22 /** Subnet management queue key */
23 #define IB_QKEY_SMA 0
24
25 /** General management QPN */
26 #define IB_QPN_GMA 1
27
28 /** General management queue key */
29 #define IB_QKEY_GMA 0x80010000UL
30
31 /** Broadcast QPN */
32 #define IB_QPN_BROADCAST 0xffffffUL
33
34 /** Default Infiniband partition key */
35 #define IB_PKEY_NONE 0xffff
36
37 /**
38  * Maximum payload size
39  *
40  * This is currently hard-coded in various places (drivers, subnet
41  * management agent, etc.) to 2048.
42  */
43 #define IB_MAX_PAYLOAD_SIZE 2048
44
45 struct ib_device;
46 struct ib_queue_pair;
47 struct ib_address_vector;
48 struct ib_completion_queue;
49
50 /** An Infiniband Work Queue */
51 struct ib_work_queue {
52         /** Containing queue pair */
53         struct ib_queue_pair *qp;
54         /** "Is a send queue" flag */
55         int is_send;
56         /** Associated completion queue */
57         struct ib_completion_queue *cq;
58         /** List of work queues on this completion queue */
59         struct list_head list;
60         /** Number of work queue entries */
61         unsigned int num_wqes;
62         /** Number of occupied work queue entries */
63         unsigned int fill;
64         /** Next work queue entry index
65          *
66          * This is the index of the next entry to be filled (i.e. the
67          * first empty entry).  This value is not bounded by num_wqes;
68          * users must logical-AND with (num_wqes-1) to generate an
69          * array index.
70          */
71         unsigned long next_idx;
72         /** I/O buffers assigned to work queue */
73         struct io_buffer **iobufs;
74         /** Driver private data */
75         void *drv_priv;
76 };
77
78 /** An Infiniband multicast GID */
79 struct ib_multicast_gid {
80         /** List of multicast GIDs on this QP */
81         struct list_head list;
82         /** Multicast GID */
83         struct ib_gid gid;
84 };
85
86 /** An Infiniband Queue Pair */
87 struct ib_queue_pair {
88         /** Containing Infiniband device */
89         struct ib_device *ibdev;
90         /** List of queue pairs on this Infiniband device */
91         struct list_head list;
92         /** Queue Pair Number */
93         unsigned long qpn;
94         /** Queue key */
95         unsigned long qkey;
96         /** Send queue */
97         struct ib_work_queue send;
98         /** Receive queue */
99         struct ib_work_queue recv;
100         /** List of multicast GIDs */
101         struct list_head mgids;
102         /** Driver private data */
103         void *drv_priv;
104         /** Queue owner private data */
105         void *owner_priv;
106 };
107
108 /** Infiniband queue pair modification flags */
109 enum ib_queue_pair_mods {
110         IB_MODIFY_QKEY = 0x0001,
111 };
112
113 /** An Infiniband Address Vector */
114 struct ib_address_vector {
115         /** Queue Pair Number */
116         unsigned long qpn;
117         /** Queue key
118          *
119          * Not specified for received packets.
120          */
121         unsigned long qkey;
122         /** Local ID */
123         unsigned int lid;
124         /** Rate
125          *
126          * Not specified for received packets.
127          */
128         unsigned int rate;
129         /** Service level */
130         unsigned int sl;
131         /** GID is present */
132         unsigned int gid_present;
133         /** GID, if present */
134         struct ib_gid gid;
135 };
136
137 /** Infiniband transmission rates */
138 enum ib_rate {
139         IB_RATE_2_5 = 2,
140         IB_RATE_10 = 3,
141         IB_RATE_30 = 4,
142         IB_RATE_5 = 5,
143         IB_RATE_20 = 6,
144         IB_RATE_40 = 7,
145         IB_RATE_60 = 8,
146         IB_RATE_80 = 9,
147         IB_RATE_120 = 10,
148 };
149
150 /** Infiniband completion queue operations */
151 struct ib_completion_queue_operations {
152         /**
153          * Complete Send WQE
154          *
155          * @v ibdev             Infiniband device
156          * @v qp                Queue pair
157          * @v iobuf             I/O buffer
158          * @v rc                Completion status code
159          */
160         void ( * complete_send ) ( struct ib_device *ibdev,
161                                    struct ib_queue_pair *qp,
162                                    struct io_buffer *iobuf, int rc );
163         /**
164          * Complete Receive WQE
165          *
166          * @v ibdev             Infiniband device
167          * @v qp                Queue pair
168          * @v av                Address vector, or NULL
169          * @v iobuf             I/O buffer
170          * @v rc                Completion status code
171          */
172         void ( * complete_recv ) ( struct ib_device *ibdev,
173                                    struct ib_queue_pair *qp,
174                                    struct ib_address_vector *av,
175                                    struct io_buffer *iobuf, int rc );
176 };
177
178 /** An Infiniband Completion Queue */
179 struct ib_completion_queue {
180         /** Containing Infiniband device */
181         struct ib_device *ibdev;
182         /** List of completion queues on this Infiniband device */
183         struct list_head list;
184         /** Completion queue number */
185         unsigned long cqn;
186         /** Number of completion queue entries */
187         unsigned int num_cqes;
188         /** Next completion queue entry index
189          *
190          * This is the index of the next entry to be filled (i.e. the
191          * first empty entry).  This value is not bounded by num_wqes;
192          * users must logical-AND with (num_wqes-1) to generate an
193          * array index.
194          */
195         unsigned long next_idx;
196         /** List of work queues completing to this queue */
197         struct list_head work_queues;
198         /** Completion queue operations */
199         struct ib_completion_queue_operations *op;
200         /** Driver private data */
201         void *drv_priv;
202 };
203
204 /**
205  * Infiniband device operations
206  *
207  * These represent a subset of the Infiniband Verbs.
208  */
209 struct ib_device_operations {
210         /** Create completion queue
211          *
212          * @v ibdev             Infiniband device
213          * @v cq                Completion queue
214          * @ret rc              Return status code
215          */
216         int ( * create_cq ) ( struct ib_device *ibdev,
217                               struct ib_completion_queue *cq );
218         /** Destroy completion queue
219          *
220          * @v ibdev             Infiniband device
221          * @v cq                Completion queue
222          */
223         void ( * destroy_cq ) ( struct ib_device *ibdev,
224                                 struct ib_completion_queue *cq );
225         /** Create queue pair
226          *
227          * @v ibdev             Infiniband device
228          * @v qp                Queue pair
229          * @ret rc              Return status code
230          */
231         int ( * create_qp ) ( struct ib_device *ibdev,
232                               struct ib_queue_pair *qp );
233         /** Modify queue pair
234          *
235          * @v ibdev             Infiniband device
236          * @v qp                Queue pair
237          * @v mod_list          Modification list
238          * @ret rc              Return status code
239          */
240         int ( * modify_qp ) ( struct ib_device *ibdev,
241                               struct ib_queue_pair *qp,
242                               unsigned long mod_list );
243         /** Destroy queue pair
244          *
245          * @v ibdev             Infiniband device
246          * @v qp                Queue pair
247          */
248         void ( * destroy_qp ) ( struct ib_device *ibdev,
249                                 struct ib_queue_pair *qp );
250         /** Post send work queue entry
251          *
252          * @v ibdev             Infiniband device
253          * @v qp                Queue pair
254          * @v av                Address vector
255          * @v iobuf             I/O buffer
256          * @ret rc              Return status code
257          *
258          * If this method returns success, the I/O buffer remains
259          * owned by the queue pair.  If this method returns failure,
260          * the I/O buffer is immediately released; the failure is
261          * interpreted as "failure to enqueue buffer".
262          */
263         int ( * post_send ) ( struct ib_device *ibdev,
264                               struct ib_queue_pair *qp,
265                               struct ib_address_vector *av,
266                               struct io_buffer *iobuf );
267         /** Post receive work queue entry
268          *
269          * @v ibdev             Infiniband device
270          * @v qp                Queue pair
271          * @v iobuf             I/O buffer
272          * @ret rc              Return status code
273          *
274          * If this method returns success, the I/O buffer remains
275          * owned by the queue pair.  If this method returns failure,
276          * the I/O buffer is immediately released; the failure is
277          * interpreted as "failure to enqueue buffer".
278          */
279         int ( * post_recv ) ( struct ib_device *ibdev,
280                               struct ib_queue_pair *qp,
281                               struct io_buffer *iobuf );
282         /** Poll completion queue
283          *
284          * @v ibdev             Infiniband device
285          * @v cq                Completion queue
286          *
287          * The relevant completion handler (specified at completion
288          * queue creation time) takes ownership of the I/O buffer.
289          */
290         void ( * poll_cq ) ( struct ib_device *ibdev,
291                              struct ib_completion_queue *cq );
292         /**
293          * Poll event queue
294          *
295          * @v ibdev             Infiniband device
296          */
297         void ( * poll_eq ) ( struct ib_device *ibdev );
298         /**
299          * Open port
300          *
301          * @v ibdev             Infiniband device
302          * @ret rc              Return status code
303          */
304         int ( * open ) ( struct ib_device *ibdev );
305         /**
306          * Close port
307          *
308          * @v ibdev             Infiniband device
309          */
310         void ( * close ) ( struct ib_device *ibdev );
311         /** Attach to multicast group
312          *
313          * @v ibdev             Infiniband device
314          * @v qp                Queue pair
315          * @v gid               Multicast GID
316          * @ret rc              Return status code
317          */
318         int ( * mcast_attach ) ( struct ib_device *ibdev,
319                                  struct ib_queue_pair *qp,
320                                  struct ib_gid *gid );
321         /** Detach from multicast group
322          *
323          * @v ibdev             Infiniband device
324          * @v qp                Queue pair
325          * @v gid               Multicast GID
326          */
327         void ( * mcast_detach ) ( struct ib_device *ibdev,
328                                   struct ib_queue_pair *qp,
329                                   struct ib_gid *gid );
330 };
331
332 /** An Infiniband device */
333 struct ib_device {
334         /** Reference counter */
335         struct refcnt refcnt;
336         /** List of Infiniband devices */
337         struct list_head list;
338         /** Underlying device */
339         struct device *dev;
340         /** List of completion queues */
341         struct list_head cqs;
342         /** List of queue pairs */
343         struct list_head qps;
344         /** Infiniband operations */
345         struct ib_device_operations *op;
346         /** Port number */
347         unsigned int port;
348         /** Port open request counter */
349         unsigned int open_count;
350
351         /** Port state */
352         uint8_t port_state;
353         /** Link width */
354         uint8_t link_width;
355         /** Link speed */
356         uint8_t link_speed;
357         /** Port GID */
358         struct ib_gid gid;
359         /** Port LID */
360         uint16_t lid;
361         /** Subnet manager LID */
362         uint16_t sm_lid;
363         /** Subnet manager SL */
364         uint8_t sm_sl;
365         /** Partition key */
366         uint16_t pkey;
367
368         /** Outbound packet sequence number */
369         uint32_t psn;
370
371         /** General management agent */
372         struct ib_gma gma;
373
374         /** Driver private data */
375         void *drv_priv;
376         /** Owner private data */
377         void *owner_priv;
378 };
379
380 extern struct ib_completion_queue *
381 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
382                struct ib_completion_queue_operations *op );
383 extern void ib_destroy_cq ( struct ib_device *ibdev,
384                             struct ib_completion_queue *cq );
385 extern void ib_poll_cq ( struct ib_device *ibdev,
386                          struct ib_completion_queue *cq );
387 extern struct ib_queue_pair *
388 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
389                struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
390                struct ib_completion_queue *recv_cq, unsigned long qkey );
391 extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
392                           unsigned long mod_list, unsigned long qkey );
393 extern void ib_destroy_qp ( struct ib_device *ibdev,
394                             struct ib_queue_pair *qp );
395 extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
396                                                unsigned long qpn );
397 extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
398                                                 struct ib_gid *gid );
399 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
400                                            unsigned long qpn, int is_send );
401 extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
402                           struct ib_address_vector *av,
403                           struct io_buffer *iobuf );
404 extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
405                           struct io_buffer *iobuf );
406 extern void ib_complete_send ( struct ib_device *ibdev,
407                                struct ib_queue_pair *qp,
408                                struct io_buffer *iobuf, int rc );
409 extern void ib_complete_recv ( struct ib_device *ibdev,
410                                struct ib_queue_pair *qp,
411                                struct ib_address_vector *av,
412                                struct io_buffer *iobuf, int rc );
413 extern void ib_refill_recv ( struct ib_device *ibdev,
414                              struct ib_queue_pair *qp );
415 extern int ib_open ( struct ib_device *ibdev );
416 extern void ib_close ( struct ib_device *ibdev );
417 extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
418                              struct ib_gid *gid );
419 extern void ib_mcast_detach ( struct ib_device *ibdev,
420                               struct ib_queue_pair *qp, struct ib_gid *gid );
421 extern int ib_get_hca_info ( struct ib_device *ibdev,
422                              struct ib_gid_half *hca_guid );
423 extern struct ib_device * alloc_ibdev ( size_t priv_size );
424 extern int register_ibdev ( struct ib_device *ibdev );
425 extern void unregister_ibdev ( struct ib_device *ibdev );
426 extern void ib_link_state_changed ( struct ib_device *ibdev );
427 extern void ib_poll_eq ( struct ib_device *ibdev );
428 extern struct list_head ib_devices;
429
430 /** Iterate over all network devices */
431 #define for_each_ibdev( ibdev ) \
432         list_for_each_entry ( (ibdev), &ib_devices, list )
433
434 /**
435  * Check link state
436  *
437  * @v ibdev             Infiniband device
438  * @ret link_up         Link is up
439  */
440 static inline __always_inline int
441 ib_link_ok ( struct ib_device *ibdev ) {
442         return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
443 }
444
445 /**
446  * Get reference to Infiniband device
447  *
448  * @v ibdev             Infiniband device
449  * @ret ibdev           Infiniband device
450  */
451 static inline __always_inline struct ib_device *
452 ibdev_get ( struct ib_device *ibdev ) {
453         ref_get ( &ibdev->refcnt );
454         return ibdev;
455 }
456
457 /**
458  * Drop reference to Infiniband device
459  *
460  * @v ibdev             Infiniband device
461  */
462 static inline __always_inline void
463 ibdev_put ( struct ib_device *ibdev ) {
464         ref_put ( &ibdev->refcnt );
465 }
466
467 /**
468  * Set Infiniband work queue driver-private data
469  *
470  * @v wq                Work queue
471  * @v priv              Private data
472  */
473 static inline __always_inline void
474 ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
475         wq->drv_priv = priv;
476 }
477
478 /**
479  * Get Infiniband work queue driver-private data
480  *
481  * @v wq                Work queue
482  * @ret priv            Private data
483  */
484 static inline __always_inline void *
485 ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
486         return wq->drv_priv;
487 }
488
489 /**
490  * Set Infiniband queue pair driver-private data
491  *
492  * @v qp                Queue pair
493  * @v priv              Private data
494  */
495 static inline __always_inline void
496 ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
497         qp->drv_priv = priv;
498 }
499
500 /**
501  * Get Infiniband queue pair driver-private data
502  *
503  * @v qp                Queue pair
504  * @ret priv            Private data
505  */
506 static inline __always_inline void *
507 ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
508         return qp->drv_priv;
509 }
510
511 /**
512  * Set Infiniband queue pair owner-private data
513  *
514  * @v qp                Queue pair
515  * @v priv              Private data
516  */
517 static inline __always_inline void
518 ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
519         qp->owner_priv = priv;
520 }
521
522 /**
523  * Get Infiniband queue pair owner-private data
524  *
525  * @v qp                Queue pair
526  * @ret priv            Private data
527  */
528 static inline __always_inline void *
529 ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
530         return qp->owner_priv;
531 }
532
533 /**
534  * Set Infiniband completion queue driver-private data
535  *
536  * @v cq                Completion queue
537  * @v priv              Private data
538  */
539 static inline __always_inline void
540 ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
541         cq->drv_priv = priv;
542 }
543
544 /**
545  * Get Infiniband completion queue driver-private data
546  *
547  * @v cq                Completion queue
548  * @ret priv            Private data
549  */
550 static inline __always_inline void *
551 ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
552         return cq->drv_priv;
553 }
554
555 /**
556  * Set Infiniband device driver-private data
557  *
558  * @v ibdev             Infiniband device
559  * @v priv              Private data
560  */
561 static inline __always_inline void
562 ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
563         ibdev->drv_priv = priv;
564 }
565
566 /**
567  * Get Infiniband device driver-private data
568  *
569  * @v ibdev             Infiniband device
570  * @ret priv            Private data
571  */
572 static inline __always_inline void *
573 ib_get_drvdata ( struct ib_device *ibdev ) {
574         return ibdev->drv_priv;
575 }
576
577 /**
578  * Set Infiniband device owner-private data
579  *
580  * @v ibdev             Infiniband device
581  * @v priv              Private data
582  */
583 static inline __always_inline void
584 ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
585         ibdev->owner_priv = priv;
586 }
587
588 /**
589  * Get Infiniband device owner-private data
590  *
591  * @v ibdev             Infiniband device
592  * @ret priv            Private data
593  */
594 static inline __always_inline void *
595 ib_get_ownerdata ( struct ib_device *ibdev ) {
596         return ibdev->owner_priv;
597 }
598
599 #endif /* _GPXE_INFINIBAND_H */