[infiniband] Call ib_open() only when opening the IPoIB net device
[people/mcb30/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         /** Port open request counter */
310         unsigned int open_count;
311
312         /** Port state */
313         uint8_t port_state;
314         /** Link width */
315         uint8_t link_width;
316         /** Link speed */
317         uint8_t link_speed;
318         /** Port GID */
319         struct ib_gid gid;
320         /** Port LID */
321         uint16_t lid;
322         /** Subnet manager LID */
323         uint16_t sm_lid;
324         /** Subnet manager SL */
325         uint8_t sm_sl;
326         /** Partition key */
327         uint16_t pkey;
328
329         /** Outbound packet sequence number */
330         uint32_t psn;
331
332         /** Driver private data */
333         void *drv_priv;
334         /** Owner private data */
335         void *owner_priv;
336 };
337
338 extern struct ib_completion_queue *
339 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
340                struct ib_completion_queue_operations *op );
341 extern void ib_destroy_cq ( struct ib_device *ibdev,
342                             struct ib_completion_queue *cq );
343 extern struct ib_queue_pair *
344 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
345                struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
346                struct ib_completion_queue *recv_cq, unsigned long qkey );
347 extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
348                           unsigned long mod_list, unsigned long qkey );
349 extern void ib_destroy_qp ( struct ib_device *ibdev,
350                             struct ib_queue_pair *qp );
351 extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
352                                                unsigned long qpn );
353 extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
354                                                 struct ib_gid *gid );
355 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
356                                            unsigned long qpn, int is_send );
357 extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
358                           struct ib_address_vector *av,
359                           struct io_buffer *iobuf );
360 extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
361                           struct io_buffer *iobuf );
362 extern void ib_complete_send ( struct ib_device *ibdev,
363                                struct ib_queue_pair *qp,
364                                struct io_buffer *iobuf, int rc );
365 extern void ib_complete_recv ( struct ib_device *ibdev,
366                                struct ib_queue_pair *qp,
367                                struct ib_address_vector *av,
368                                struct io_buffer *iobuf, int rc );
369 extern int ib_open ( struct ib_device *ibdev );
370 extern void ib_close ( struct ib_device *ibdev );
371 extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
372                              struct ib_gid *gid );
373 extern void ib_mcast_detach ( struct ib_device *ibdev,
374                               struct ib_queue_pair *qp, struct ib_gid *gid );
375 extern struct ib_device * alloc_ibdev ( size_t priv_size );
376 extern int register_ibdev ( struct ib_device *ibdev );
377 extern void unregister_ibdev ( struct ib_device *ibdev );
378 extern void ib_link_state_changed ( struct ib_device *ibdev );
379 extern struct list_head ib_devices;
380
381 /** Iterate over all network devices */
382 #define for_each_ibdev( ibdev ) \
383         list_for_each_entry ( (ibdev), &ib_devices, list )
384
385 /**
386  * Poll completion queue
387  *
388  * @v ibdev             Infiniband device
389  * @v cq                Completion queue
390  */
391 static inline __always_inline void
392 ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ) {
393         ibdev->op->poll_cq ( ibdev, cq );
394 }
395
396 /**
397  * Check link state
398  *
399  * @v ibdev             Infiniband device
400  * @ret link_up         Link is up
401  */
402 static inline __always_inline int
403 ib_link_ok ( struct ib_device *ibdev ) {
404         return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
405 }
406
407 /**
408  * Get reference to Infiniband device
409  *
410  * @v ibdev             Infiniband device
411  * @ret ibdev           Infiniband device
412  */
413 static inline __always_inline struct ib_device *
414 ibdev_get ( struct ib_device *ibdev ) {
415         ref_get ( &ibdev->refcnt );
416         return ibdev;
417 }
418
419 /**
420  * Drop reference to Infiniband device
421  *
422  * @v ibdev             Infiniband device
423  */
424 static inline __always_inline void
425 ibdev_put ( struct ib_device *ibdev ) {
426         ref_put ( &ibdev->refcnt );
427 }
428
429 /**
430  * Set Infiniband work queue driver-private data
431  *
432  * @v wq                Work queue
433  * @v priv              Private data
434  */
435 static inline __always_inline void
436 ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
437         wq->drv_priv = priv;
438 }
439
440 /**
441  * Get Infiniband work queue driver-private data
442  *
443  * @v wq                Work queue
444  * @ret priv            Private data
445  */
446 static inline __always_inline void *
447 ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
448         return wq->drv_priv;
449 }
450
451 /**
452  * Set Infiniband queue pair driver-private data
453  *
454  * @v qp                Queue pair
455  * @v priv              Private data
456  */
457 static inline __always_inline void
458 ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
459         qp->drv_priv = priv;
460 }
461
462 /**
463  * Get Infiniband queue pair driver-private data
464  *
465  * @v qp                Queue pair
466  * @ret priv            Private data
467  */
468 static inline __always_inline void *
469 ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
470         return qp->drv_priv;
471 }
472
473 /**
474  * Set Infiniband queue pair owner-private data
475  *
476  * @v qp                Queue pair
477  * @v priv              Private data
478  */
479 static inline __always_inline void
480 ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
481         qp->owner_priv = priv;
482 }
483
484 /**
485  * Get Infiniband queue pair owner-private data
486  *
487  * @v qp                Queue pair
488  * @ret priv            Private data
489  */
490 static inline __always_inline void *
491 ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
492         return qp->owner_priv;
493 }
494
495 /**
496  * Set Infiniband completion queue driver-private data
497  *
498  * @v cq                Completion queue
499  * @v priv              Private data
500  */
501 static inline __always_inline void
502 ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
503         cq->drv_priv = priv;
504 }
505
506 /**
507  * Get Infiniband completion queue driver-private data
508  *
509  * @v cq                Completion queue
510  * @ret priv            Private data
511  */
512 static inline __always_inline void *
513 ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
514         return cq->drv_priv;
515 }
516
517 /**
518  * Set Infiniband device driver-private data
519  *
520  * @v ibdev             Infiniband device
521  * @v priv              Private data
522  */
523 static inline __always_inline void
524 ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
525         ibdev->drv_priv = priv;
526 }
527
528 /**
529  * Get Infiniband device driver-private data
530  *
531  * @v ibdev             Infiniband device
532  * @ret priv            Private data
533  */
534 static inline __always_inline void *
535 ib_get_drvdata ( struct ib_device *ibdev ) {
536         return ibdev->drv_priv;
537 }
538
539 /**
540  * Set Infiniband device owner-private data
541  *
542  * @v ibdev             Infiniband device
543  * @v priv              Private data
544  */
545 static inline __always_inline void
546 ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
547         ibdev->owner_priv = priv;
548 }
549
550 /**
551  * Get Infiniband device owner-private data
552  *
553  * @v ibdev             Infiniband device
554  * @ret priv            Private data
555  */
556 static inline __always_inline void *
557 ib_get_ownerdata ( struct ib_device *ibdev ) {
558         return ibdev->owner_priv;
559 }
560
561 #endif /* _GPXE_INFINIBAND_H */