[infiniband] Flush uncompleted work queue entries at QP teardown
[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
14 /** Subnet administrator QPN */
15 #define IB_SA_QPN 1
16
17 /** Broadcast QPN */
18 #define IB_BROADCAST_QPN 0xffffffUL
19
20 /** Subnet administrator queue key */
21 #define IB_GLOBAL_QKEY 0x80010000UL
22
23 /** An Infiniband Global Identifier */
24 struct ib_gid {
25         union {
26                 uint8_t bytes[16];
27                 uint16_t words[8];
28                 uint32_t dwords[4];
29         } u;
30 };
31
32 /** An Infiniband Global Route Header */
33 struct ib_global_route_header {
34         /** IP version, traffic class, and flow label
35          *
36          *  4 bits : Version of the GRH
37          *  8 bits : Traffic class
38          * 20 bits : Flow label
39          */
40         uint32_t ipver_tclass_flowlabel;
41         /** Payload length */
42         uint16_t paylen;
43         /** Next header */
44         uint8_t nxthdr;
45         /** Hop limit */
46         uint8_t hoplmt;
47         /** Source GID */
48         struct ib_gid sgid;
49         /** Destiniation GID */
50         struct ib_gid dgid;
51 } __attribute__ (( packed ));
52
53 struct ib_device;
54 struct ib_queue_pair;
55 struct ib_completion_queue;
56
57 /** An Infiniband Work Queue */
58 struct ib_work_queue {
59         /** Containing queue pair */
60         struct ib_queue_pair *qp;
61         /** "Is a send queue" flag */
62         int is_send;
63         /** Associated completion queue */
64         struct ib_completion_queue *cq;
65         /** List of work queues on this completion queue */
66         struct list_head list;
67         /** Number of work queue entries */
68         unsigned int num_wqes;
69         /** Next work queue entry index
70          *
71          * This is the index of the next entry to be filled (i.e. the
72          * first empty entry).  This value is not bounded by num_wqes;
73          * users must logical-AND with (num_wqes-1) to generate an
74          * array index.
75          */
76         unsigned long next_idx;
77         /** I/O buffers assigned to work queue */
78         struct io_buffer **iobufs;
79         /** Driver private data */
80         void *drv_priv;
81 };
82
83 /** An Infiniband Queue Pair */
84 struct ib_queue_pair {
85         /** Queue Pair Number */
86         unsigned long qpn;
87         /** Queue key */
88         unsigned long qkey;
89         /** Send queue */
90         struct ib_work_queue send;
91         /** Receive queue */
92         struct ib_work_queue recv;
93         /** Driver private data */
94         void *drv_priv;
95         /** Queue owner private data */
96         void *owner_priv;
97 };
98
99 /** Infiniband queue pair modification flags */
100 enum ib_queue_pair_mods {
101         IB_MODIFY_QKEY = 0x0001,
102 };
103
104 /** An Infiniband completion */
105 struct ib_completion {
106         /** Syndrome
107          *
108          * If non-zero, then the completion is in error.
109          */
110         unsigned int syndrome;
111         /** Length */
112         size_t len;
113 };
114
115 /** Infiniband completion syndromes */
116 enum ib_syndrome {
117         IB_SYN_NONE = 0,
118         IB_SYN_LOCAL_LENGTH = 1,
119         IB_SYN_LOCAL_QP = 2,
120         IB_SYN_LOCAL_PROT = 4,
121 };
122
123 /** An Infiniband completion handler
124  *
125  * @v ibdev             Infiniband device
126  * @v qp                Queue pair
127  * @v completion        Completion
128  * @v iobuf             I/O buffer
129  */
130 typedef void ( * ib_completer_t ) ( struct ib_device *ibdev,
131                                     struct ib_queue_pair *qp,
132                                     struct ib_completion *completion,
133                                     struct io_buffer *iobuf );
134
135 /** An Infiniband Completion Queue */
136 struct ib_completion_queue {
137         /** Completion queue number */
138         unsigned long cqn;
139         /** Number of completion queue entries */
140         unsigned int num_cqes;
141         /** Next completion queue entry index
142          *
143          * This is the index of the next entry to be filled (i.e. the
144          * first empty entry).  This value is not bounded by num_wqes;
145          * users must logical-AND with (num_wqes-1) to generate an
146          * array index.
147          */
148         unsigned long next_idx;
149         /** List of work queues completing to this queue */
150         struct list_head work_queues;
151         /** Send completion handler */
152         ib_completer_t complete_send;
153         /** Receive completion handler */
154         ib_completer_t complete_recv;
155         /** Driver private data */
156         void *drv_priv;
157 };
158
159 /** An Infiniband Address Vector */
160 struct ib_address_vector {
161         /** Destination Queue Pair */
162         unsigned int dest_qp;
163         /** Queue key */
164         unsigned long qkey;
165         /** Destination Local ID */
166         unsigned int dlid;
167         /** Rate */
168         unsigned int rate;
169         /** Service level */
170         unsigned int sl;
171         /** GID is present */
172         unsigned int gid_present;
173         /** GID */
174         struct ib_gid gid;
175 };
176
177 struct ib_mad_hdr;
178
179 /**
180  * Infiniband device operations
181  *
182  * These represent a subset of the Infiniband Verbs.
183  */
184 struct ib_device_operations {
185         /** Create completion queue
186          *
187          * @v ibdev             Infiniband device
188          * @v cq                Completion queue
189          * @ret rc              Return status code
190          */
191         int ( * create_cq ) ( struct ib_device *ibdev,
192                               struct ib_completion_queue *cq );
193         /** Destroy completion queue
194          *
195          * @v ibdev             Infiniband device
196          * @v cq                Completion queue
197          */
198         void ( * destroy_cq ) ( struct ib_device *ibdev,
199                                 struct ib_completion_queue *cq );
200         /** Create queue pair
201          *
202          * @v ibdev             Infiniband device
203          * @v qp                Queue pair
204          * @ret rc              Return status code
205          */
206         int ( * create_qp ) ( struct ib_device *ibdev,
207                               struct ib_queue_pair *qp );
208         /** Modify queue pair
209          *
210          * @v ibdev             Infiniband device
211          * @v qp                Queue pair
212          * @v mod_list          Modification list
213          * @ret rc              Return status code
214          */
215         int ( * modify_qp ) ( struct ib_device *ibdev,
216                               struct ib_queue_pair *qp,
217                               unsigned long mod_list );
218         /** Destroy queue pair
219          *
220          * @v ibdev             Infiniband device
221          * @v qp                Queue pair
222          */
223         void ( * destroy_qp ) ( struct ib_device *ibdev,
224                                 struct ib_queue_pair *qp );
225         /** Post send work queue entry
226          *
227          * @v ibdev             Infiniband device
228          * @v qp                Queue pair
229          * @v av                Address vector
230          * @v iobuf             I/O buffer
231          * @ret rc              Return status code
232          *
233          * If this method returns success, the I/O buffer remains
234          * owned by the queue pair.  If this method returns failure,
235          * the I/O buffer is immediately released; the failure is
236          * interpreted as "failure to enqueue buffer".
237          */
238         int ( * post_send ) ( struct ib_device *ibdev,
239                               struct ib_queue_pair *qp,
240                               struct ib_address_vector *av,
241                               struct io_buffer *iobuf );
242         /** Post receive work queue entry
243          *
244          * @v ibdev             Infiniband device
245          * @v qp                Queue pair
246          * @v iobuf             I/O buffer
247          * @ret rc              Return status code
248          *
249          * If this method returns success, the I/O buffer remains
250          * owned by the queue pair.  If this method returns failure,
251          * the I/O buffer is immediately released; the failure is
252          * interpreted as "failure to enqueue buffer".
253          */
254         int ( * post_recv ) ( struct ib_device *ibdev,
255                               struct ib_queue_pair *qp,
256                               struct io_buffer *iobuf );
257         /** Poll completion queue
258          *
259          * @v ibdev             Infiniband device
260          * @v cq                Completion queue
261          *
262          * The relevant completion handler (specified at completion
263          * queue creation time) takes ownership of the I/O buffer.
264          */
265         void ( * poll_cq ) ( struct ib_device *ibdev,
266                              struct ib_completion_queue *cq );
267         /**
268          * Poll event queue
269          *
270          * @v ibdev             Infiniband device
271          */
272         void ( * poll_eq ) ( struct ib_device *ibdev );
273         /**
274          * Open port
275          *
276          * @v ibdev             Infiniband device
277          * @ret rc              Return status code
278          */
279         int ( * open ) ( struct ib_device *ibdev );
280         /**
281          * Close port
282          *
283          * @v ibdev             Infiniband device
284          */
285         void ( * close ) ( struct ib_device *ibdev );
286         /** Attach to multicast group
287          *
288          * @v ibdev             Infiniband device
289          * @v qp                Queue pair
290          * @v gid               Multicast GID
291          * @ret rc              Return status code
292          */
293         int ( * mcast_attach ) ( struct ib_device *ibdev,
294                                  struct ib_queue_pair *qp,
295                                  struct ib_gid *gid );
296         /** Detach from multicast group
297          *
298          * @v ibdev             Infiniband device
299          * @v qp                Queue pair
300          * @v gid               Multicast GID
301          */
302         void ( * mcast_detach ) ( struct ib_device *ibdev,
303                                   struct ib_queue_pair *qp,
304                                   struct ib_gid *gid );
305         /**
306          * Issue management datagram
307          *
308          * @v ibdev             Infiniband device
309          * @v mad               Management datagram
310          * @v len               Length of management datagram
311          * @ret rc              Return status code
312          */
313         int ( * mad ) ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
314                         size_t len );
315 };
316
317 /** An Infiniband device */
318 struct ib_device {
319         /** Reference counter */
320         struct refcnt refcnt;
321         /** List of Infiniband devices */
322         struct list_head list;
323         /** Underlying device */
324         struct device *dev;
325         /** Infiniband operations */
326         struct ib_device_operations *op;
327         /** Port number */
328         unsigned int port;
329         /** Link state */
330         int link_up;
331         /** Port GID */
332         struct ib_gid port_gid;
333         /** Subnet manager LID */
334         unsigned long sm_lid;
335         /** Partition key */
336         unsigned int pkey;
337         /** Driver private data */
338         void *drv_priv;
339         /** Owner private data */
340         void *owner_priv;
341 };
342
343 extern struct ib_completion_queue *
344 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
345                ib_completer_t complete_send, ib_completer_t complete_recv );
346 extern void ib_destroy_cq ( struct ib_device *ibdev,
347                             struct ib_completion_queue *cq );
348 extern struct ib_queue_pair *
349 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
350                struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
351                struct ib_completion_queue *recv_cq, unsigned long qkey );
352 extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
353                           unsigned long mod_list, unsigned long qkey );
354 extern void ib_destroy_qp ( struct ib_device *ibdev,
355                             struct ib_queue_pair *qp );
356 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
357                                            unsigned long qpn, int is_send );
358 extern struct ib_device * alloc_ibdev ( size_t priv_size );
359 extern int register_ibdev ( struct ib_device *ibdev );
360 extern void unregister_ibdev ( struct ib_device *ibdev );
361 extern void ib_link_state_changed ( struct ib_device *ibdev );
362
363 /**
364  * Post send work queue entry
365  *
366  * @v ibdev             Infiniband device
367  * @v qp                Queue pair
368  * @v av                Address vector
369  * @v iobuf             I/O buffer
370  * @ret rc              Return status code
371  */
372 static inline __attribute__ (( always_inline )) int
373 ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
374                struct ib_address_vector *av, struct io_buffer *iobuf ) {
375         return ibdev->op->post_send ( ibdev, qp, av, iobuf );
376 }
377
378 /**
379  * Post receive work queue entry
380  *
381  * @v ibdev             Infiniband device
382  * @v qp                Queue pair
383  * @v iobuf             I/O buffer
384  * @ret rc              Return status code
385  */
386 static inline __attribute__ (( always_inline )) int
387 ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
388                struct io_buffer *iobuf ) {
389         return ibdev->op->post_recv ( ibdev, qp, iobuf );
390 }
391
392 /**
393  * Complete send work queue entry
394  *
395  * @v ibdev             Infiniband device
396  * @v qp                Queue pair
397  * @v completion        Completion
398  * @v iobuf             I/O buffer
399  */
400 static inline __attribute__ (( always_inline )) void
401 ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
402                    struct ib_completion *completion,
403                    struct io_buffer *iobuf ) {
404         return qp->send.cq->complete_send ( ibdev, qp, completion, iobuf );
405 }
406
407 /**
408  * Complete receive work queue entry
409  *
410  * @v ibdev             Infiniband device
411  * @v qp                Queue pair
412  * @v completion        Completion
413  * @v iobuf             I/O buffer
414  */
415 static inline __attribute__ (( always_inline )) void
416 ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
417                    struct ib_completion *completion,
418                    struct io_buffer *iobuf ) {
419         return qp->recv.cq->complete_recv ( ibdev, qp, completion, iobuf );
420 }
421
422 /**
423  * Poll completion queue
424  *
425  * @v ibdev             Infiniband device
426  * @v cq                Completion queue
427  */
428 static inline __attribute__ (( always_inline )) void
429 ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ) {
430         ibdev->op->poll_cq ( ibdev, cq );
431 }
432
433 /**
434  * Open port
435  *
436  * @v ibdev             Infiniband device
437  * @ret rc              Return status code
438  */
439 static inline __attribute__ (( always_inline )) int
440 ib_open ( struct ib_device *ibdev ) {
441         return ibdev->op->open ( ibdev );
442 }
443
444 /**
445  * Close port
446  *
447  * @v ibdev             Infiniband device
448  */
449 static inline __attribute__ (( always_inline )) void
450 ib_close ( struct ib_device *ibdev ) {
451         ibdev->op->close ( ibdev );
452 }
453
454 /**
455  * Attach to multicast group
456  *
457  * @v ibdev             Infiniband device
458  * @v qp                Queue pair
459  * @v gid               Multicast GID
460  * @ret rc              Return status code
461  */
462 static inline __attribute__ (( always_inline )) int
463 ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
464                   struct ib_gid *gid ) {
465         return ibdev->op->mcast_attach ( ibdev, qp, gid );
466 }
467
468 /**
469  * Detach from multicast group
470  *
471  * @v ibdev             Infiniband device
472  * @v qp                Queue pair
473  * @v gid               Multicast GID
474  */
475 static inline __attribute__ (( always_inline )) void
476 ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
477                   struct ib_gid *gid ) {
478         ibdev->op->mcast_detach ( ibdev, qp, gid );
479 }
480
481 /**
482  * Issue management datagram
483  *
484  * @v ibdev             Infiniband device
485  * @v mad               Management datagram
486  * @v len               Length of management datagram
487  * @ret rc              Return status code
488  */
489 static inline __attribute__ (( always_inline )) int
490 ib_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad, size_t len ) {
491         return ibdev->op->mad ( ibdev, mad, len );
492 }
493
494 /**
495  * Get reference to Infiniband device
496  *
497  * @v ibdev             Infiniband device
498  * @ret ibdev           Infiniband device
499  */
500 static inline __attribute__ (( always_inline )) struct ib_device *
501 ibdev_get ( struct ib_device *ibdev ) {
502         ref_get ( &ibdev->refcnt );
503         return ibdev;
504 }
505
506 /**
507  * Drop reference to Infiniband device
508  *
509  * @v ibdev             Infiniband device
510  */
511 static inline __attribute__ (( always_inline )) void
512 ibdev_put ( struct ib_device *ibdev ) {
513         ref_put ( &ibdev->refcnt );
514 }
515
516 /**
517  * Set Infiniband work queue driver-private data
518  *
519  * @v wq                Work queue
520  * @v priv              Private data
521  */
522 static inline __attribute__ (( always_inline )) void
523 ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
524         wq->drv_priv = priv;
525 }
526
527 /**
528  * Get Infiniband work queue driver-private data
529  *
530  * @v wq                Work queue
531  * @ret priv            Private data
532  */
533 static inline __attribute__ (( always_inline )) void *
534 ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
535         return wq->drv_priv;
536 }
537
538 /**
539  * Set Infiniband queue pair driver-private data
540  *
541  * @v qp                Queue pair
542  * @v priv              Private data
543  */
544 static inline __attribute__ (( always_inline )) void
545 ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
546         qp->drv_priv = priv;
547 }
548
549 /**
550  * Get Infiniband queue pair driver-private data
551  *
552  * @v qp                Queue pair
553  * @ret priv            Private data
554  */
555 static inline __attribute__ (( always_inline )) void *
556 ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
557         return qp->drv_priv;
558 }
559
560 /**
561  * Set Infiniband queue pair owner-private data
562  *
563  * @v qp                Queue pair
564  * @v priv              Private data
565  */
566 static inline __attribute__ (( always_inline )) void
567 ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
568         qp->owner_priv = priv;
569 }
570
571 /**
572  * Get Infiniband queue pair owner-private data
573  *
574  * @v qp                Queue pair
575  * @ret priv            Private data
576  */
577 static inline __attribute__ (( always_inline )) void *
578 ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
579         return qp->owner_priv;
580 }
581
582 /**
583  * Set Infiniband completion queue driver-private data
584  *
585  * @v cq                Completion queue
586  * @v priv              Private data
587  */
588 static inline __attribute__ (( always_inline )) void
589 ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
590         cq->drv_priv = priv;
591 }
592
593 /**
594  * Get Infiniband completion queue driver-private data
595  *
596  * @v cq                Completion queue
597  * @ret priv            Private data
598  */
599 static inline __attribute__ (( always_inline )) void *
600 ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
601         return cq->drv_priv;
602 }
603
604 /**
605  * Set Infiniband device driver-private data
606  *
607  * @v ibdev             Infiniband device
608  * @v priv              Private data
609  */
610 static inline __attribute__ (( always_inline )) void
611 ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
612         ibdev->drv_priv = priv;
613 }
614
615 /**
616  * Get Infiniband device driver-private data
617  *
618  * @v ibdev             Infiniband device
619  * @ret priv            Private data
620  */
621 static inline __attribute__ (( always_inline )) void *
622 ib_get_drvdata ( struct ib_device *ibdev ) {
623         return ibdev->drv_priv;
624 }
625
626 /**
627  * Set Infiniband device owner-private data
628  *
629  * @v ibdev             Infiniband device
630  * @v priv              Private data
631  */
632 static inline __attribute__ (( always_inline )) void
633 ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
634         ibdev->owner_priv = priv;
635 }
636
637 /**
638  * Get Infiniband device owner-private data
639  *
640  * @v ibdev             Infiniband device
641  * @ret priv            Private data
642  */
643 static inline __attribute__ (( always_inline )) void *
644 ib_get_ownerdata ( struct ib_device *ibdev ) {
645         return ibdev->owner_priv;
646 }
647
648 /*****************************************************************************
649  *
650  * Management datagrams
651  *
652  * Portions Copyright (c) 2004 Mellanox Technologies Ltd.  All rights
653  * reserved.
654  *
655  */
656
657 /* Management base version */
658 #define IB_MGMT_BASE_VERSION                    1
659
660 /* Management classes */
661 #define IB_MGMT_CLASS_SUBN_LID_ROUTED           0x01
662 #define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE       0x81
663 #define IB_MGMT_CLASS_SUBN_ADM                  0x03
664 #define IB_MGMT_CLASS_PERF_MGMT                 0x04
665 #define IB_MGMT_CLASS_BM                        0x05
666 #define IB_MGMT_CLASS_DEVICE_MGMT               0x06
667 #define IB_MGMT_CLASS_CM                        0x07
668 #define IB_MGMT_CLASS_SNMP                      0x08
669 #define IB_MGMT_CLASS_VENDOR_RANGE2_START       0x30
670 #define IB_MGMT_CLASS_VENDOR_RANGE2_END         0x4F
671
672 /* Management methods */
673 #define IB_MGMT_METHOD_GET                      0x01
674 #define IB_MGMT_METHOD_SET                      0x02
675 #define IB_MGMT_METHOD_GET_RESP                 0x81
676 #define IB_MGMT_METHOD_SEND                     0x03
677 #define IB_MGMT_METHOD_TRAP                     0x05
678 #define IB_MGMT_METHOD_REPORT                   0x06
679 #define IB_MGMT_METHOD_REPORT_RESP              0x86
680 #define IB_MGMT_METHOD_TRAP_REPRESS             0x07
681 #define IB_MGMT_METHOD_DELETE                   0x15
682 #define IB_MGMT_METHOD_RESP                     0x80
683
684 /* Subnet management attributes */
685 #define IB_SMP_ATTR_NOTICE                      0x0002
686 #define IB_SMP_ATTR_NODE_DESC                   0x0010
687 #define IB_SMP_ATTR_NODE_INFO                   0x0011
688 #define IB_SMP_ATTR_SWITCH_INFO                 0x0012
689 #define IB_SMP_ATTR_GUID_INFO                   0x0014
690 #define IB_SMP_ATTR_PORT_INFO                   0x0015
691 #define IB_SMP_ATTR_PKEY_TABLE                  0x0016
692 #define IB_SMP_ATTR_SL_TO_VL_TABLE              0x0017
693 #define IB_SMP_ATTR_VL_ARB_TABLE                0x0018
694 #define IB_SMP_ATTR_LINEAR_FORWARD_TABLE        0x0019
695 #define IB_SMP_ATTR_RANDOM_FORWARD_TABLE        0x001A
696 #define IB_SMP_ATTR_MCAST_FORWARD_TABLE         0x001B
697 #define IB_SMP_ATTR_SM_INFO                     0x0020
698 #define IB_SMP_ATTR_VENDOR_DIAG                 0x0030
699 #define IB_SMP_ATTR_LED_INFO                    0x0031
700 #define IB_SMP_ATTR_VENDOR_MASK                 0xFF00
701
702 #define IB_SA_ATTR_MC_MEMBER_REC                0x38
703 #define IB_SA_ATTR_PATH_REC                     0x35
704
705 #define IB_SA_MCMEMBER_REC_MGID                 (1<<0)
706 #define IB_SA_MCMEMBER_REC_PORT_GID             (1<<1)
707 #define IB_SA_MCMEMBER_REC_QKEY                 (1<<2)
708 #define IB_SA_MCMEMBER_REC_MLID                 (1<<3)
709 #define IB_SA_MCMEMBER_REC_MTU_SELECTOR         (1<<4)
710 #define IB_SA_MCMEMBER_REC_MTU                  (1<<5)
711 #define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS        (1<<6)
712 #define IB_SA_MCMEMBER_REC_PKEY                 (1<<7)
713 #define IB_SA_MCMEMBER_REC_RATE_SELECTOR        (1<<8)
714 #define IB_SA_MCMEMBER_REC_RATE                 (1<<9)
715 #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR    (1<<10)
716 #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME     (1<<11)
717 #define IB_SA_MCMEMBER_REC_SL                   (1<<12)
718 #define IB_SA_MCMEMBER_REC_FLOW_LABEL           (1<<13)
719 #define IB_SA_MCMEMBER_REC_HOP_LIMIT            (1<<14)
720 #define IB_SA_MCMEMBER_REC_SCOPE                (1<<15)
721 #define IB_SA_MCMEMBER_REC_JOIN_STATE           (1<<16)
722 #define IB_SA_MCMEMBER_REC_PROXY_JOIN           (1<<17)
723
724 #define IB_SA_PATH_REC_DGID                     (1<<2)
725 #define IB_SA_PATH_REC_SGID                     (1<<3)
726
727 struct ib_mad_hdr {
728         uint8_t base_version;
729         uint8_t mgmt_class;
730         uint8_t class_version;
731         uint8_t method;
732         uint16_t status;
733         uint16_t class_specific;
734         uint32_t tid[2];
735         uint16_t attr_id;
736         uint16_t resv;
737         uint32_t attr_mod;
738 } __attribute__ (( packed ));
739
740 struct ib_sa_hdr {
741         uint32_t sm_key[2];
742         uint16_t reserved;
743         uint16_t attrib_offset;
744         uint32_t comp_mask[2];
745 } __attribute__ (( packed ));
746
747 struct ib_rmpp_hdr {
748         uint32_t raw[3];
749 } __attribute__ (( packed ));
750
751 struct ib_mad_data {
752         struct ib_mad_hdr mad_hdr;
753         uint8_t data[232];
754 } __attribute__ (( packed ));
755
756 struct ib_mad_guid_info {
757         struct ib_mad_hdr mad_hdr;
758         uint32_t mkey[2];
759         uint32_t reserved[8];
760         uint8_t gid_local[8];
761 } __attribute__ (( packed ));
762
763 struct ib_mad_port_info {
764         struct ib_mad_hdr mad_hdr;
765         uint32_t mkey[2];
766         uint32_t reserved[8];
767         uint32_t mkey2[2];
768         uint8_t gid_prefix[8];
769         uint16_t lid;
770         uint16_t mastersm_lid;
771         uint32_t cap_mask;
772         uint16_t diag_code;
773         uint16_t mkey_lease_period;
774         uint8_t local_port_num;
775         uint8_t link_width_enabled;
776         uint8_t link_width_supported;
777         uint8_t link_width_active;
778         uint8_t port_state__link_speed_supported;
779         uint8_t link_down_def_state__port_phys_state;
780         uint8_t lmc__r1__mkey_prot_bits;
781         uint8_t link_speed_enabled__link_speed_active;
782 } __attribute__ (( packed ));
783
784 struct ib_mad_pkey_table {
785         struct ib_mad_hdr mad_hdr;
786         uint32_t mkey[2];
787         uint32_t reserved[8];
788         uint16_t pkey[16][2];
789 } __attribute__ (( packed ));
790
791 struct ib_mad_path_record {
792         struct ib_mad_hdr mad_hdr;
793         struct ib_rmpp_hdr rmpp_hdr;
794         struct ib_sa_hdr sa_hdr;
795         uint32_t reserved0[2];
796         struct ib_gid dgid;
797         struct ib_gid sgid;
798         uint16_t dlid;
799         uint16_t slid;
800         uint32_t hop_limit__flow_label__raw_traffic;
801         uint32_t pkey__numb_path__reversible__tclass;
802         uint8_t reserved1;
803         uint8_t reserved__sl;
804         uint8_t mtu_selector__mtu;
805         uint8_t rate_selector__rate;
806         uint32_t preference__packet_lifetime__packet_lifetime_selector;
807         uint32_t reserved2[35];
808 } __attribute__ (( packed ));
809
810 struct ib_mad_mc_member_record {
811         struct ib_mad_hdr mad_hdr;
812         struct ib_rmpp_hdr rmpp_hdr;
813         struct ib_sa_hdr sa_hdr;
814         struct ib_gid mgid;
815         struct ib_gid port_gid;
816         uint32_t qkey;
817         uint16_t mlid;
818         uint8_t mtu_selector__mtu;
819         uint8_t tclass;
820         uint16_t pkey;
821         uint8_t rate_selector__rate;
822         uint8_t packet_lifetime_selector__packet_lifetime;
823         uint32_t sl__flow_label__hop_limit;
824         uint8_t scope__join_state;
825         uint8_t proxy_join__reserved;
826         uint16_t reserved0;
827         uint32_t reserved1[37];
828 } __attribute__ (( packed ));
829
830 union ib_mad {
831         struct ib_mad_hdr mad_hdr;
832         struct ib_mad_data data;
833         struct ib_mad_guid_info guid_info;
834         struct ib_mad_port_info port_info;
835         struct ib_mad_pkey_table pkey_table;
836         struct ib_mad_path_record path_record;
837         struct ib_mad_mc_member_record mc_member_record;
838 } __attribute__ (( packed ));
839
840 #endif /* _GPXE_INFINIBAND_H */