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