1 #ifndef _GPXE_INFINIBAND_H
2 #define _GPXE_INFINIBAND_H
10 FILE_LICENCE ( GPL2_OR_LATER );
13 #include <gpxe/refcnt.h>
14 #include <gpxe/device.h>
15 #include <gpxe/ib_packet.h>
16 #include <gpxe/ib_mad.h>
18 /** Subnet management QPN */
21 /** Subnet management queue key */
24 /** General management QPN */
27 /** General management queue key */
28 #define IB_QKEY_GMA 0x80010000UL
31 #define IB_QPN_BROADCAST 0xffffffUL
33 /** Default Infiniband partition key */
34 #define IB_PKEY_NONE 0xffff
37 * Maximum payload size
39 * This is currently hard-coded in various places (drivers, subnet
40 * management agent, etc.) to 2048.
42 #define IB_MAX_PAYLOAD_SIZE 2048
46 struct ib_address_vector;
47 struct ib_completion_queue;
49 /** An Infiniband Work Queue */
50 struct ib_work_queue {
51 /** Containing queue pair */
52 struct ib_queue_pair *qp;
53 /** "Is a send queue" flag */
55 /** Associated completion queue */
56 struct ib_completion_queue *cq;
57 /** List of work queues on this completion queue */
58 struct list_head list;
59 /** Number of work queue entries */
60 unsigned int num_wqes;
61 /** Number of occupied work queue entries */
63 /** Next work queue entry index
65 * This is the index of the next entry to be filled (i.e. the
66 * first empty entry). This value is not bounded by num_wqes;
67 * users must logical-AND with (num_wqes-1) to generate an
70 unsigned long next_idx;
71 /** I/O buffers assigned to work queue */
72 struct io_buffer **iobufs;
73 /** Driver private data */
77 /** An Infiniband multicast GID */
78 struct ib_multicast_gid {
79 /** List of multicast GIDs on this QP */
80 struct list_head list;
85 /** An Infiniband Queue Pair */
86 struct ib_queue_pair {
87 /** Containing Infiniband device */
88 struct ib_device *ibdev;
89 /** List of queue pairs on this Infiniband device */
90 struct list_head list;
91 /** Queue Pair Number */
96 struct ib_work_queue send;
98 struct ib_work_queue recv;
99 /** List of multicast GIDs */
100 struct list_head mgids;
101 /** Driver private data */
103 /** Queue owner private data */
107 /** Infiniband queue pair modification flags */
108 enum ib_queue_pair_mods {
109 IB_MODIFY_QKEY = 0x0001,
112 /** An Infiniband Address Vector */
113 struct ib_address_vector {
114 /** Queue Pair Number */
118 * Not specified for received packets.
125 * Not specified for received packets.
130 /** GID is present */
131 unsigned int gid_present;
132 /** GID, if present */
136 /** Infiniband completion queue operations */
137 struct ib_completion_queue_operations {
141 * @v ibdev Infiniband device
143 * @v iobuf I/O buffer
144 * @v rc Completion status code
146 void ( * complete_send ) ( struct ib_device *ibdev,
147 struct ib_queue_pair *qp,
148 struct io_buffer *iobuf, int rc );
150 * Complete Receive WQE
152 * @v ibdev Infiniband device
154 * @v av Address vector, or NULL
155 * @v iobuf I/O buffer
156 * @v rc Completion status code
158 void ( * complete_recv ) ( struct ib_device *ibdev,
159 struct ib_queue_pair *qp,
160 struct ib_address_vector *av,
161 struct io_buffer *iobuf, int rc );
164 /** An Infiniband Completion Queue */
165 struct ib_completion_queue {
166 /** Containing Infiniband device */
167 struct ib_device *ibdev;
168 /** List of completion queues on this Infiniband device */
169 struct list_head list;
170 /** Completion queue number */
172 /** Number of completion queue entries */
173 unsigned int num_cqes;
174 /** Next completion queue entry index
176 * This is the index of the next entry to be filled (i.e. the
177 * first empty entry). This value is not bounded by num_wqes;
178 * users must logical-AND with (num_wqes-1) to generate an
181 unsigned long next_idx;
182 /** List of work queues completing to this queue */
183 struct list_head work_queues;
184 /** Completion queue operations */
185 struct ib_completion_queue_operations *op;
186 /** Driver private data */
191 * Infiniband device operations
193 * These represent a subset of the Infiniband Verbs.
195 struct ib_device_operations {
196 /** Create completion queue
198 * @v ibdev Infiniband device
199 * @v cq Completion queue
200 * @ret rc Return status code
202 int ( * create_cq ) ( struct ib_device *ibdev,
203 struct ib_completion_queue *cq );
204 /** Destroy completion queue
206 * @v ibdev Infiniband device
207 * @v cq Completion queue
209 void ( * destroy_cq ) ( struct ib_device *ibdev,
210 struct ib_completion_queue *cq );
211 /** Create queue pair
213 * @v ibdev Infiniband device
215 * @ret rc Return status code
217 int ( * create_qp ) ( struct ib_device *ibdev,
218 struct ib_queue_pair *qp );
219 /** Modify queue pair
221 * @v ibdev Infiniband device
223 * @v mod_list Modification list
224 * @ret rc Return status code
226 int ( * modify_qp ) ( struct ib_device *ibdev,
227 struct ib_queue_pair *qp,
228 unsigned long mod_list );
229 /** Destroy queue pair
231 * @v ibdev Infiniband device
234 void ( * destroy_qp ) ( struct ib_device *ibdev,
235 struct ib_queue_pair *qp );
236 /** Post send work queue entry
238 * @v ibdev Infiniband device
240 * @v av Address vector
241 * @v iobuf I/O buffer
242 * @ret rc Return status code
244 * If this method returns success, the I/O buffer remains
245 * owned by the queue pair. If this method returns failure,
246 * the I/O buffer is immediately released; the failure is
247 * interpreted as "failure to enqueue buffer".
249 int ( * post_send ) ( struct ib_device *ibdev,
250 struct ib_queue_pair *qp,
251 struct ib_address_vector *av,
252 struct io_buffer *iobuf );
253 /** Post receive work queue entry
255 * @v ibdev Infiniband device
257 * @v iobuf I/O buffer
258 * @ret rc Return status code
260 * If this method returns success, the I/O buffer remains
261 * owned by the queue pair. If this method returns failure,
262 * the I/O buffer is immediately released; the failure is
263 * interpreted as "failure to enqueue buffer".
265 int ( * post_recv ) ( struct ib_device *ibdev,
266 struct ib_queue_pair *qp,
267 struct io_buffer *iobuf );
268 /** Poll completion queue
270 * @v ibdev Infiniband device
271 * @v cq Completion queue
273 * The relevant completion handler (specified at completion
274 * queue creation time) takes ownership of the I/O buffer.
276 void ( * poll_cq ) ( struct ib_device *ibdev,
277 struct ib_completion_queue *cq );
281 * @v ibdev Infiniband device
283 void ( * poll_eq ) ( struct ib_device *ibdev );
287 * @v ibdev Infiniband device
288 * @ret rc Return status code
290 int ( * open ) ( struct ib_device *ibdev );
294 * @v ibdev Infiniband device
296 void ( * close ) ( struct ib_device *ibdev );
297 /** Attach to multicast group
299 * @v ibdev Infiniband device
301 * @v gid Multicast GID
302 * @ret rc Return status code
304 int ( * mcast_attach ) ( struct ib_device *ibdev,
305 struct ib_queue_pair *qp,
306 struct ib_gid *gid );
307 /** Detach from multicast group
309 * @v ibdev Infiniband device
311 * @v gid Multicast GID
313 void ( * mcast_detach ) ( struct ib_device *ibdev,
314 struct ib_queue_pair *qp,
315 struct ib_gid *gid );
318 /** An Infiniband device */
320 /** Reference counter */
321 struct refcnt refcnt;
322 /** List of Infiniband devices */
323 struct list_head list;
324 /** Underlying device */
326 /** List of completion queues */
327 struct list_head cqs;
328 /** List of queue pairs */
329 struct list_head qps;
330 /** Infiniband operations */
331 struct ib_device_operations *op;
334 /** Port open request counter */
335 unsigned int open_count;
347 /** Subnet manager LID */
349 /** Subnet manager SL */
354 /** Outbound packet sequence number */
357 /** Driver private data */
359 /** Owner private data */
363 extern struct ib_completion_queue *
364 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
365 struct ib_completion_queue_operations *op );
366 extern void ib_destroy_cq ( struct ib_device *ibdev,
367 struct ib_completion_queue *cq );
368 extern void ib_poll_cq ( struct ib_device *ibdev,
369 struct ib_completion_queue *cq );
370 extern struct ib_queue_pair *
371 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
372 struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
373 struct ib_completion_queue *recv_cq, unsigned long qkey );
374 extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
375 unsigned long mod_list, unsigned long qkey );
376 extern void ib_destroy_qp ( struct ib_device *ibdev,
377 struct ib_queue_pair *qp );
378 extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
380 extern struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
381 struct ib_gid *gid );
382 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
383 unsigned long qpn, int is_send );
384 extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
385 struct ib_address_vector *av,
386 struct io_buffer *iobuf );
387 extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
388 struct io_buffer *iobuf );
389 extern void ib_complete_send ( struct ib_device *ibdev,
390 struct ib_queue_pair *qp,
391 struct io_buffer *iobuf, int rc );
392 extern void ib_complete_recv ( struct ib_device *ibdev,
393 struct ib_queue_pair *qp,
394 struct ib_address_vector *av,
395 struct io_buffer *iobuf, int rc );
396 extern void ib_refill_recv ( struct ib_device *ibdev,
397 struct ib_queue_pair *qp );
398 extern int ib_open ( struct ib_device *ibdev );
399 extern void ib_close ( struct ib_device *ibdev );
400 extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
401 struct ib_gid *gid );
402 extern void ib_mcast_detach ( struct ib_device *ibdev,
403 struct ib_queue_pair *qp, struct ib_gid *gid );
404 extern int ib_get_hca_info ( struct ib_device *ibdev,
405 struct ib_gid_half *hca_guid );
406 extern struct ib_device * alloc_ibdev ( size_t priv_size );
407 extern int register_ibdev ( struct ib_device *ibdev );
408 extern void unregister_ibdev ( struct ib_device *ibdev );
409 extern void ib_link_state_changed ( struct ib_device *ibdev );
410 extern void ib_poll_eq ( struct ib_device *ibdev );
411 extern struct list_head ib_devices;
413 /** Iterate over all network devices */
414 #define for_each_ibdev( ibdev ) \
415 list_for_each_entry ( (ibdev), &ib_devices, list )
420 * @v ibdev Infiniband device
421 * @ret link_up Link is up
423 static inline __always_inline int
424 ib_link_ok ( struct ib_device *ibdev ) {
425 return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
429 * Get reference to Infiniband device
431 * @v ibdev Infiniband device
432 * @ret ibdev Infiniband device
434 static inline __always_inline struct ib_device *
435 ibdev_get ( struct ib_device *ibdev ) {
436 ref_get ( &ibdev->refcnt );
441 * Drop reference to Infiniband device
443 * @v ibdev Infiniband device
445 static inline __always_inline void
446 ibdev_put ( struct ib_device *ibdev ) {
447 ref_put ( &ibdev->refcnt );
451 * Set Infiniband work queue driver-private data
454 * @v priv Private data
456 static inline __always_inline void
457 ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
462 * Get Infiniband work queue driver-private data
465 * @ret priv Private data
467 static inline __always_inline void *
468 ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
473 * Set Infiniband queue pair driver-private data
476 * @v priv Private data
478 static inline __always_inline void
479 ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
484 * Get Infiniband queue pair driver-private data
487 * @ret priv Private data
489 static inline __always_inline void *
490 ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
495 * Set Infiniband queue pair owner-private data
498 * @v priv Private data
500 static inline __always_inline void
501 ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
502 qp->owner_priv = priv;
506 * Get Infiniband queue pair owner-private data
509 * @ret priv Private data
511 static inline __always_inline void *
512 ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
513 return qp->owner_priv;
517 * Set Infiniband completion queue driver-private data
519 * @v cq Completion queue
520 * @v priv Private data
522 static inline __always_inline void
523 ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
528 * Get Infiniband completion queue driver-private data
530 * @v cq Completion queue
531 * @ret priv Private data
533 static inline __always_inline void *
534 ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
539 * Set Infiniband device driver-private data
541 * @v ibdev Infiniband device
542 * @v priv Private data
544 static inline __always_inline void
545 ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
546 ibdev->drv_priv = priv;
550 * Get Infiniband device driver-private data
552 * @v ibdev Infiniband device
553 * @ret priv Private data
555 static inline __always_inline void *
556 ib_get_drvdata ( struct ib_device *ibdev ) {
557 return ibdev->drv_priv;
561 * Set Infiniband device owner-private data
563 * @v ibdev Infiniband device
564 * @v priv Private data
566 static inline __always_inline void
567 ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
568 ibdev->owner_priv = priv;
572 * Get Infiniband device owner-private data
574 * @v ibdev Infiniband device
575 * @ret priv Private data
577 static inline __always_inline void *
578 ib_get_ownerdata ( struct ib_device *ibdev ) {
579 return ibdev->owner_priv;
582 #endif /* _GPXE_INFINIBAND_H */