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