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