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 administrator QPN */
22 #define IB_BROADCAST_QPN 0xffffffUL
24 /** Subnet administrator queue key */
25 #define IB_GLOBAL_QKEY 0x80010000UL
28 * Maximum payload size
30 * This is currently hard-coded in various places (drivers, subnet
31 * management agent, etc.) to 2048.
33 #define IB_MAX_PAYLOAD_SIZE 2048
37 struct ib_address_vector;
38 struct ib_completion_queue;
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 */
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 */
54 /** Next work queue entry index
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
61 unsigned long next_idx;
62 /** I/O buffers assigned to work queue */
63 struct io_buffer **iobufs;
64 /** Driver private data */
68 /** An Infiniband multicast GID */
69 struct ib_multicast_gid {
70 /** List of multicast GIDs on this QP */
71 struct list_head list;
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 */
87 struct ib_work_queue send;
89 struct ib_work_queue recv;
90 /** List of multicast GIDs */
91 struct list_head mgids;
92 /** Driver private data */
94 /** Queue owner private data */
98 /** Infiniband queue pair modification flags */
99 enum ib_queue_pair_mods {
100 IB_MODIFY_QKEY = 0x0001,
103 /** An Infiniband Address Vector */
104 struct ib_address_vector {
105 /** Queue Pair Number */
109 * Not specified for received packets.
116 * Not specified for received packets.
121 /** GID is present */
122 unsigned int gid_present;
123 /** GID, if present */
127 /** Infiniband completion queue operations */
128 struct ib_completion_queue_operations {
132 * @v ibdev Infiniband device
134 * @v iobuf I/O buffer
135 * @v rc Completion status code
137 void ( * complete_send ) ( struct ib_device *ibdev,
138 struct ib_queue_pair *qp,
139 struct io_buffer *iobuf, int rc );
141 * Complete Receive WQE
143 * @v ibdev Infiniband device
145 * @v av Address vector, or NULL
146 * @v iobuf I/O buffer
147 * @v rc Completion status code
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 );
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 */
163 /** Number of completion queue entries */
164 unsigned int num_cqes;
165 /** Next completion queue entry index
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
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 */
182 * Infiniband device operations
184 * These represent a subset of the Infiniband Verbs.
186 struct ib_device_operations {
187 /** Create completion queue
189 * @v ibdev Infiniband device
190 * @v cq Completion queue
191 * @ret rc Return status code
193 int ( * create_cq ) ( struct ib_device *ibdev,
194 struct ib_completion_queue *cq );
195 /** Destroy completion queue
197 * @v ibdev Infiniband device
198 * @v cq Completion queue
200 void ( * destroy_cq ) ( struct ib_device *ibdev,
201 struct ib_completion_queue *cq );
202 /** Create queue pair
204 * @v ibdev Infiniband device
206 * @ret rc Return status code
208 int ( * create_qp ) ( struct ib_device *ibdev,
209 struct ib_queue_pair *qp );
210 /** Modify queue pair
212 * @v ibdev Infiniband device
214 * @v mod_list Modification list
215 * @ret rc Return status code
217 int ( * modify_qp ) ( struct ib_device *ibdev,
218 struct ib_queue_pair *qp,
219 unsigned long mod_list );
220 /** Destroy queue pair
222 * @v ibdev Infiniband device
225 void ( * destroy_qp ) ( struct ib_device *ibdev,
226 struct ib_queue_pair *qp );
227 /** Post send work queue entry
229 * @v ibdev Infiniband device
231 * @v av Address vector
232 * @v iobuf I/O buffer
233 * @ret rc Return status code
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".
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
246 * @v ibdev Infiniband device
248 * @v iobuf I/O buffer
249 * @ret rc Return status code
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".
256 int ( * post_recv ) ( struct ib_device *ibdev,
257 struct ib_queue_pair *qp,
258 struct io_buffer *iobuf );
259 /** Poll completion queue
261 * @v ibdev Infiniband device
262 * @v cq Completion queue
264 * The relevant completion handler (specified at completion
265 * queue creation time) takes ownership of the I/O buffer.
267 void ( * poll_cq ) ( struct ib_device *ibdev,
268 struct ib_completion_queue *cq );
272 * @v ibdev Infiniband device
274 void ( * poll_eq ) ( struct ib_device *ibdev );
278 * @v ibdev Infiniband device
279 * @ret rc Return status code
281 int ( * open ) ( struct ib_device *ibdev );
285 * @v ibdev Infiniband device
287 void ( * close ) ( struct ib_device *ibdev );
288 /** Attach to multicast group
290 * @v ibdev Infiniband device
292 * @v gid Multicast GID
293 * @ret rc Return status code
295 int ( * mcast_attach ) ( struct ib_device *ibdev,
296 struct ib_queue_pair *qp,
297 struct ib_gid *gid );
298 /** Detach from multicast group
300 * @v ibdev Infiniband device
302 * @v gid Multicast GID
304 void ( * mcast_detach ) ( struct ib_device *ibdev,
305 struct ib_queue_pair *qp,
306 struct ib_gid *gid );
309 /** An Infiniband device */
311 /** Reference counter */
312 struct refcnt refcnt;
313 /** List of Infiniband devices */
314 struct list_head list;
315 /** Underlying device */
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;
325 /** Port open request counter */
326 unsigned int open_count;
338 /** Subnet manager LID */
340 /** Subnet manager SL */
345 /** Outbound packet sequence number */
348 /** Driver private data */
350 /** Owner private data */
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,
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;
404 /** Iterate over all network devices */
405 #define for_each_ibdev( ibdev ) \
406 list_for_each_entry ( (ibdev), &ib_devices, list )
411 * @v ibdev Infiniband device
412 * @ret link_up Link is up
414 static inline __always_inline int
415 ib_link_ok ( struct ib_device *ibdev ) {
416 return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
420 * Get reference to Infiniband device
422 * @v ibdev Infiniband device
423 * @ret ibdev Infiniband device
425 static inline __always_inline struct ib_device *
426 ibdev_get ( struct ib_device *ibdev ) {
427 ref_get ( &ibdev->refcnt );
432 * Drop reference to Infiniband device
434 * @v ibdev Infiniband device
436 static inline __always_inline void
437 ibdev_put ( struct ib_device *ibdev ) {
438 ref_put ( &ibdev->refcnt );
442 * Set Infiniband work queue driver-private data
445 * @v priv Private data
447 static inline __always_inline void
448 ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
453 * Get Infiniband work queue driver-private data
456 * @ret priv Private data
458 static inline __always_inline void *
459 ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
464 * Set Infiniband queue pair driver-private data
467 * @v priv Private data
469 static inline __always_inline void
470 ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
475 * Get Infiniband queue pair driver-private data
478 * @ret priv Private data
480 static inline __always_inline void *
481 ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
486 * Set Infiniband queue pair owner-private data
489 * @v priv Private data
491 static inline __always_inline void
492 ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
493 qp->owner_priv = priv;
497 * Get Infiniband queue pair owner-private data
500 * @ret priv Private data
502 static inline __always_inline void *
503 ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
504 return qp->owner_priv;
508 * Set Infiniband completion queue driver-private data
510 * @v cq Completion queue
511 * @v priv Private data
513 static inline __always_inline void
514 ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
519 * Get Infiniband completion queue driver-private data
521 * @v cq Completion queue
522 * @ret priv Private data
524 static inline __always_inline void *
525 ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
530 * Set Infiniband device driver-private data
532 * @v ibdev Infiniband device
533 * @v priv Private data
535 static inline __always_inline void
536 ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
537 ibdev->drv_priv = priv;
541 * Get Infiniband device driver-private data
543 * @v ibdev Infiniband device
544 * @ret priv Private data
546 static inline __always_inline void *
547 ib_get_drvdata ( struct ib_device *ibdev ) {
548 return ibdev->drv_priv;
552 * Set Infiniband device owner-private data
554 * @v ibdev Infiniband device
555 * @v priv Private data
557 static inline __always_inline void
558 ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
559 ibdev->owner_priv = priv;
563 * Get Infiniband device owner-private data
565 * @v ibdev Infiniband device
566 * @ret priv Private data
568 static inline __always_inline void *
569 ib_get_ownerdata ( struct ib_device *ibdev ) {
570 return ibdev->owner_priv;
573 #endif /* _GPXE_INFINIBAND_H */