845c4c228197aa2becbd704d57cb88c8c83ceb6f
[people/pcmattman/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/device.h>
12
13 /** Subnet administrator QPN */
14 #define IB_SA_QPN       1
15
16 /** Subnet administrator queue key */
17 #define IB_GLOBAL_QKEY  0x80010000UL
18
19 /** An Infiniband Global Identifier */
20 struct ib_gid {
21         union {
22                 uint8_t bytes[16];
23                 uint32_t dwords[4];
24         } u;
25 };
26
27 /** An Infiniband Global Route Header */
28 struct ib_global_route_header {
29         /** IP version, traffic class, and flow label
30          *
31          *  4 bits : Version of the GRH
32          *  8 bits : Traffic class
33          * 20 bits : Flow label
34          */
35         uint32_t ipver_tclass_flowlabel;
36         /** Payload length */
37         uint16_t paylen;
38         /** Next header */
39         uint8_t nxthdr;
40         /** Hop limit */
41         uint8_t hoplmt;
42         /** Source GID */
43         struct ib_gid sgid;
44         /** Destiniation GID */
45         struct ib_gid dgid;
46 } __attribute__ (( packed ));
47
48 struct ib_device;
49 struct ib_queue_pair;
50 struct ib_completion_queue;
51
52 /** An Infiniband Work Queue */
53 struct ib_work_queue {
54         /** Containing queue pair */
55         struct ib_queue_pair *qp;
56         /** "Is a send queue" flag */
57         int is_send;
58         /** Associated completion queue */
59         struct ib_completion_queue *cq;
60         /** List of work queues on this completion queue */
61         struct list_head list;
62         /** Number of work queue entries */
63         unsigned int num_wqes;
64         /** Next work queue entry index
65          *
66          * This is the index of the next entry to be filled (i.e. the
67          * first empty entry).  This value is not bounded by num_wqes;
68          * users must logical-AND with (num_wqes-1) to generate an
69          * array index.
70          */
71         unsigned long next_idx;
72         /** I/O buffers assigned to work queue */
73         struct io_buffer **iobufs;
74         /** Device private data */
75         void *dev_priv;
76 };
77
78 /** An Infiniband Queue Pair */
79 struct ib_queue_pair {
80         /** Queue Pair Number */
81         unsigned long qpn;
82         /** Queue key */
83         unsigned long qkey;
84         /** Send queue */
85         struct ib_work_queue send;
86         /** Receive queue */
87         struct ib_work_queue recv;
88         /** Device private data */
89         void *dev_priv;
90         /** Queue owner private data */
91         void *owner_priv;
92 };
93
94 /** An Infiniband Completion Queue */
95 struct ib_completion_queue {
96         /** Completion queue number */
97         unsigned long cqn;
98         /** Number of completion queue entries */
99         unsigned int num_cqes;
100         /** Next completion queue entry index
101          *
102          * This is the index of the next entry to be filled (i.e. the
103          * first empty entry).  This value is not bounded by num_wqes;
104          * users must logical-AND with (num_wqes-1) to generate an
105          * array index.
106          */
107         unsigned long next_idx;
108         /** List of work queues completing to this queue */
109         struct list_head work_queues;
110         /** Device private data */
111         void *dev_priv;
112 };
113
114 /** An Infiniband completion */
115 struct ib_completion {
116         /** Syndrome
117          *
118          * If non-zero, then the completion is in error.
119          */
120         unsigned int syndrome;
121         /** Length */
122         size_t len;
123 };
124
125 /** An Infiniband completion handler
126  *
127  * @v ibdev             Infiniband device
128  * @v qp                Queue pair
129  * @v completion        Completion
130  * @v iobuf             I/O buffer
131  */
132 typedef void ( * ib_completer_t ) ( struct ib_device *ibdev,
133                                     struct ib_queue_pair *qp,
134                                     struct ib_completion *completion,
135                                     struct io_buffer *iobuf );
136
137 /** An Infiniband Address Vector */
138 struct ib_address_vector {
139         /** Destination Queue Pair */
140         unsigned int dest_qp;
141         /** Queue key */
142         unsigned long qkey;
143         /** Destination Local ID */
144         unsigned int dlid;
145         /** Rate */
146         unsigned int rate;
147         /** Service level */
148         unsigned int sl;
149         /** GID is present */
150         unsigned int gid_present;
151         /** GID */
152         struct ib_gid gid;
153 };
154
155 /**
156  * Infiniband device operations
157  *
158  * These represent a subset of the Infiniband Verbs.
159  */
160 struct ib_device_operations {
161         /** Create completion queue
162          *
163          * @v ibdev             Infiniband device
164          * @v cq                Completion queue
165          * @ret rc              Return status code
166          */
167         int ( * create_cq ) ( struct ib_device *ibdev,
168                               struct ib_completion_queue *cq );
169         /** Destroy completion queue
170          *
171          * @v ibdev             Infiniband device
172          * @v cq                Completion queue
173          */
174         void ( * destroy_cq ) ( struct ib_device *ibdev,
175                                 struct ib_completion_queue *cq );
176         /** Create queue pair
177          *
178          * @v ibdev             Infiniband device
179          * @v qp                Queue pair
180          * @ret rc              Return status code
181          */
182         int ( * create_qp ) ( struct ib_device *ibdev,
183                               struct ib_queue_pair *qp );
184         /** Destroy queue pair
185          *
186          * @v ibdev             Infiniband device
187          * @v qp                Queue pair
188          */
189         void ( * destroy_qp ) ( struct ib_device *ibdev,
190                                 struct ib_queue_pair *qp );
191         /** Post send work queue entry
192          *
193          * @v ibdev             Infiniband device
194          * @v qp                Queue pair
195          * @v av                Address vector
196          * @v iobuf             I/O buffer
197          * @ret rc              Return status code
198          *
199          * If this method returns success, the I/O buffer remains
200          * owned by the queue pair.  If this method returns failure,
201          * the I/O buffer is immediately released; the failure is
202          * interpreted as "failure to enqueue buffer".
203          */
204         int ( * post_send ) ( struct ib_device *ibdev,
205                               struct ib_queue_pair *qp,
206                               struct ib_address_vector *av,
207                               struct io_buffer *iobuf );
208         /** Post receive work queue entry
209          *
210          * @v ibdev             Infiniband device
211          * @v qp                Queue pair
212          * @v iobuf             I/O buffer
213          * @ret rc              Return status code
214          *
215          * If this method returns success, the I/O buffer remains
216          * owned by the queue pair.  If this method returns failure,
217          * the I/O buffer is immediately released; the failure is
218          * interpreted as "failure to enqueue buffer".
219          */
220         int ( * post_recv ) ( struct ib_device *ibdev,
221                               struct ib_queue_pair *qp,
222                               struct io_buffer *iobuf );
223         /** Poll completion queue
224          *
225          * @v ibdev             Infiniband device
226          * @v cq                Completion queue
227          * @v complete_send     Send completion handler
228          * @v complete_recv     Receive completion handler
229          *
230          * The completion handler takes ownership of the I/O buffer.
231          */
232         void ( * poll_cq ) ( struct ib_device *ibdev,
233                              struct ib_completion_queue *cq,
234                              ib_completer_t complete_send,
235                              ib_completer_t complete_recv );
236         /** Attach to multicast group
237          *
238          * @v ibdev             Infiniband device
239          * @v qp                Queue pair
240          * @v gid               Multicast GID
241          * @ret rc              Return status code
242          */
243         int ( * mcast_attach ) ( struct ib_device *ibdev,
244                                  struct ib_queue_pair *qp,
245                                  struct ib_gid *gid );
246         /** Detach from multicast group
247          *
248          * @v ibdev             Infiniband device
249          * @v qp                Queue pair
250          * @v gid               Multicast GID
251          */
252         void ( * mcast_detach ) ( struct ib_device *ibdev,
253                                   struct ib_queue_pair *qp,
254                                   struct ib_gid *gid );
255 };
256
257 /** An Infiniband device */
258 struct ib_device {
259         /** Port GID */
260         struct ib_gid port_gid;
261         /** Broadcast GID */
262         struct ib_gid broadcast_gid;
263         /** Subnet manager LID */
264         unsigned long sm_lid;
265         /** Underlying device */
266         struct device *dev;
267         /** Infiniband operations */
268         struct ib_device_operations *op;
269         /** Device private data */
270         void *dev_priv;
271         /** Owner private data */
272         void *owner_priv;
273 };
274
275 extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
276                                                    unsigned int num_cqes );
277 extern void ib_destroy_cq ( struct ib_device *ibdev,
278                             struct ib_completion_queue *cq );
279 extern struct ib_queue_pair *
280 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
281                struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
282                struct ib_completion_queue *recv_cq, unsigned long qkey );
283 extern void ib_destroy_qp ( struct ib_device *ibdev,
284                             struct ib_queue_pair *qp );
285 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
286                                            unsigned long qpn, int is_send );
287 extern struct ib_device * alloc_ibdev ( size_t priv_size );
288 extern void free_ibdev ( struct ib_device *ibdev );
289
290 /**
291  * Post send work queue entry
292  *
293  * @v ibdev             Infiniband device
294  * @v qp                Queue pair
295  * @v av                Address vector
296  * @v iobuf             I/O buffer
297  * @ret rc              Return status code
298  */
299 static inline __attribute__ (( always_inline )) int
300 ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
301                struct ib_address_vector *av, struct io_buffer *iobuf ) {
302         return ibdev->op->post_send ( ibdev, qp, av, iobuf );
303 }
304
305 /**
306  * Post receive work queue entry
307  *
308  * @v ibdev             Infiniband device
309  * @v qp                Queue pair
310  * @v iobuf             I/O buffer
311  * @ret rc              Return status code
312  */
313 static inline __attribute__ (( always_inline )) int
314 ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
315                struct io_buffer *iobuf ) {
316         return ibdev->op->post_recv ( ibdev, qp, iobuf );
317 }
318
319 /**
320  * Poll completion queue
321  *
322  * @v ibdev             Infiniband device
323  * @v cq                Completion queue
324  * @v complete_send     Send completion handler
325  * @v complete_recv     Receive completion handler
326  */
327 static inline __attribute__ (( always_inline )) void
328 ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq,
329              ib_completer_t complete_send, ib_completer_t complete_recv ) {
330         ibdev->op->poll_cq ( ibdev, cq, complete_send, complete_recv );
331 }
332
333
334 /**
335  * Attach to multicast group
336  *
337  * @v ibdev             Infiniband device
338  * @v qp                Queue pair
339  * @v gid               Multicast GID
340  * @ret rc              Return status code
341  */
342 static inline __attribute__ (( always_inline )) int
343 ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
344                   struct ib_gid *gid ) {
345         return ibdev->op->mcast_attach ( ibdev, qp, gid );
346 }
347
348 /**
349  * Detach from multicast group
350  *
351  * @v ibdev             Infiniband device
352  * @v qp                Queue pair
353  * @v gid               Multicast GID
354  */
355 static inline __attribute__ (( always_inline )) void
356 ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
357                   struct ib_gid *gid ) {
358         ibdev->op->mcast_detach ( ibdev, qp, gid );
359 }
360
361 /**
362  * Set Infiniband owner-private data
363  *
364  * @v pci               Infiniband device
365  * @v priv              Private data
366  */
367 static inline void ib_set_ownerdata ( struct ib_device *ibdev,
368                                       void *owner_priv ) {
369         ibdev->owner_priv = owner_priv;
370 }
371
372 /**
373  * Get Infiniband owner-private data
374  *
375  * @v pci               Infiniband device
376  * @ret priv            Private data
377  */
378 static inline void * ib_get_ownerdata ( struct ib_device *ibdev ) {
379         return ibdev->owner_priv;
380 }
381
382 /*****************************************************************************
383  *
384  * Management datagrams
385  *
386  * Portions Copyright (c) 2004 Mellanox Technologies Ltd.  All rights
387  * reserved.
388  *
389  */
390
391 /* Management base version */
392 #define IB_MGMT_BASE_VERSION                    1
393
394 /* Management classes */
395 #define IB_MGMT_CLASS_SUBN_LID_ROUTED           0x01
396 #define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE       0x81
397 #define IB_MGMT_CLASS_SUBN_ADM                  0x03
398 #define IB_MGMT_CLASS_PERF_MGMT                 0x04
399 #define IB_MGMT_CLASS_BM                        0x05
400 #define IB_MGMT_CLASS_DEVICE_MGMT               0x06
401 #define IB_MGMT_CLASS_CM                        0x07
402 #define IB_MGMT_CLASS_SNMP                      0x08
403 #define IB_MGMT_CLASS_VENDOR_RANGE2_START       0x30
404 #define IB_MGMT_CLASS_VENDOR_RANGE2_END         0x4F
405
406 /* Management methods */
407 #define IB_MGMT_METHOD_GET                      0x01
408 #define IB_MGMT_METHOD_SET                      0x02
409 #define IB_MGMT_METHOD_GET_RESP                 0x81
410 #define IB_MGMT_METHOD_SEND                     0x03
411 #define IB_MGMT_METHOD_TRAP                     0x05
412 #define IB_MGMT_METHOD_REPORT                   0x06
413 #define IB_MGMT_METHOD_REPORT_RESP              0x86
414 #define IB_MGMT_METHOD_TRAP_REPRESS             0x07
415 #define IB_MGMT_METHOD_DELETE                   0x15
416 #define IB_MGMT_METHOD_RESP                     0x80
417
418 /* Subnet management attributes */
419 #define IB_SMP_ATTR_NOTICE                      0x0002
420 #define IB_SMP_ATTR_NODE_DESC                   0x0010
421 #define IB_SMP_ATTR_NODE_INFO                   0x0011
422 #define IB_SMP_ATTR_SWITCH_INFO                 0x0012
423 #define IB_SMP_ATTR_GUID_INFO                   0x0014
424 #define IB_SMP_ATTR_PORT_INFO                   0x0015
425 #define IB_SMP_ATTR_PKEY_TABLE                  0x0016
426 #define IB_SMP_ATTR_SL_TO_VL_TABLE              0x0017
427 #define IB_SMP_ATTR_VL_ARB_TABLE                0x0018
428 #define IB_SMP_ATTR_LINEAR_FORWARD_TABLE        0x0019
429 #define IB_SMP_ATTR_RANDOM_FORWARD_TABLE        0x001A
430 #define IB_SMP_ATTR_MCAST_FORWARD_TABLE         0x001B
431 #define IB_SMP_ATTR_SM_INFO                     0x0020
432 #define IB_SMP_ATTR_VENDOR_DIAG                 0x0030
433 #define IB_SMP_ATTR_LED_INFO                    0x0031
434 #define IB_SMP_ATTR_VENDOR_MASK                 0xFF00
435
436 #define IB_SA_ATTR_MC_MEMBER_REC                0x38
437 #define IB_SA_ATTR_PATH_REC                     0x35
438
439 #define IB_SA_MCMEMBER_REC_MGID                 (1<<0)
440 #define IB_SA_MCMEMBER_REC_PORT_GID             (1<<1)
441 #define IB_SA_MCMEMBER_REC_QKEY                 (1<<2)
442 #define IB_SA_MCMEMBER_REC_MLID                 (1<<3)
443 #define IB_SA_MCMEMBER_REC_MTU_SELECTOR         (1<<4)
444 #define IB_SA_MCMEMBER_REC_MTU                  (1<<5)
445 #define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS        (1<<6)
446 #define IB_SA_MCMEMBER_REC_PKEY                 (1<<7)
447 #define IB_SA_MCMEMBER_REC_RATE_SELECTOR        (1<<8)
448 #define IB_SA_MCMEMBER_REC_RATE                 (1<<9)
449 #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR    (1<<10)
450 #define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME     (1<<11)
451 #define IB_SA_MCMEMBER_REC_SL                   (1<<12)
452 #define IB_SA_MCMEMBER_REC_FLOW_LABEL           (1<<13)
453 #define IB_SA_MCMEMBER_REC_HOP_LIMIT            (1<<14)
454 #define IB_SA_MCMEMBER_REC_SCOPE                (1<<15)
455 #define IB_SA_MCMEMBER_REC_JOIN_STATE           (1<<16)
456 #define IB_SA_MCMEMBER_REC_PROXY_JOIN           (1<<17)
457
458 #define IB_SA_PATH_REC_DGID                     (1<<2)
459 #define IB_SA_PATH_REC_SGID                     (1<<3)
460
461 struct ib_mad_hdr {
462         uint8_t base_version;
463         uint8_t mgmt_class;
464         uint8_t class_version;
465         uint8_t method;
466         uint16_t status;
467         uint16_t class_specific;
468         uint64_t tid;
469         uint16_t attr_id;
470         uint16_t resv;
471         uint32_t attr_mod;
472 } __attribute__ (( packed ));
473
474 struct ib_sa_hdr {
475         uint32_t sm_key[2];
476         uint16_t reserved;
477         uint16_t attrib_offset;
478         uint32_t comp_mask[2];
479 } __attribute__ (( packed ));
480
481 struct ib_rmpp_hdr {
482         uint32_t raw[3];
483 } __attribute__ (( packed ));
484
485 struct ib_mad_data {
486         struct ib_mad_hdr mad_hdr;
487         uint8_t data[232];
488 } __attribute__ (( packed ));
489
490 struct ib_mad_guid_info {
491         struct ib_mad_hdr mad_hdr;
492         uint32_t mkey[2];
493         uint32_t reserved[8];
494         uint8_t gid_local[8];
495 } __attribute__ (( packed ));
496
497 struct ib_mad_port_info {
498         struct ib_mad_hdr mad_hdr;
499         uint32_t mkey[2];
500         uint32_t reserved[8];
501         uint32_t mkey2[2];
502         uint8_t gid_prefix[8];
503         uint16_t lid;
504         uint16_t mastersm_lid;
505         uint32_t cap_mask;
506         uint16_t diag_code;
507         uint16_t mkey_lease_period;
508         uint8_t local_port_num;
509         uint8_t link_width_enabled;
510         uint8_t link_width_supported;
511         uint8_t link_width_active;
512         uint8_t port_state__link_speed_supported;
513         uint8_t link_down_def_state__port_phys_state;
514         uint8_t lmc__r1__mkey_prot_bits;
515         uint8_t link_speed_enabled__link_speed_active;
516 } __attribute__ (( packed ));
517
518 struct ib_mad_pkey_table {
519         struct ib_mad_hdr mad_hdr;
520         uint32_t mkey[2];
521         uint32_t reserved[8];
522         uint16_t pkey[16][2];
523 } __attribute__ (( packed ));
524
525 struct ib_mad_path_record {
526         struct ib_mad_hdr mad_hdr;
527         struct ib_rmpp_hdr rmpp_hdr;
528         struct ib_sa_hdr sa_hdr;
529         uint32_t reserved0[2];
530         struct ib_gid dgid;
531         struct ib_gid sgid;
532         uint16_t dlid;
533         uint16_t slid;
534         uint32_t hop_limit__flow_label__raw_traffic;
535         uint32_t pkey__numb_path__reversible__tclass;
536         uint8_t reserved1;
537         uint8_t reserved__sl;
538         uint8_t mtu_selector__mtu;
539         uint8_t rate_selector__rate;
540         uint32_t preference__packet_lifetime__packet_lifetime_selector;
541         uint32_t reserved2[35];
542 } __attribute__ (( packed ));
543
544 union ib_mad {
545         struct ib_mad_hdr mad_hdr;
546         struct ib_mad_data data;
547         struct ib_mad_guid_info guid_info;
548         struct ib_mad_port_info port_info;
549         struct ib_mad_pkey_table pkey_table;
550         struct ib_mad_path_record path_record;
551 } __attribute__ (( packed ));
552
553 #endif /* _GPXE_INFINIBAND_H */