4868f71749cc1ea67ab72c1124f856358eee1176
[people/andreif/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/netdevice.h>
12
13 /** An Infiniband Global Identifier */
14 struct ib_gid {
15         uint8_t bytes[16];
16 };
17
18 /** An Infiniband Global Route Header */
19 struct ib_global_route_header {
20         /** IP version, traffic class, and flow label
21          *
22          *  4 bits : Version of the GRH
23          *  8 bits : Traffic class
24          * 20 bits : Flow label
25          */
26         uint32_t ipver_tclass_flowlabel;
27         /** Payload length */
28         uint16_t paylen;
29         /** Next header */
30         uint8_t nxthdr;
31         /** Hop limit */
32         uint8_t hoplmt;
33         /** Source GID */
34         struct ib_gid sgid;
35         /** Destiniation GID */
36         struct ib_gid dgid;
37 } __attribute__ (( packed ));
38
39 /** Infiniband MAC address length */
40 #define IB_ALEN 20
41
42 /** An Infiniband MAC address */
43 struct ib_mac {
44         /** Queue pair number
45          *
46          * MSB must be zero; QPNs are only 24-bit.
47          */
48         uint32_t qpn;
49         /** Port GID */
50         struct ib_gid gid;
51 } __attribute__ (( packed ));
52
53 /** Infiniband link-layer header length */
54 #define IB_HLEN 4
55
56 /** An Infiniband link-layer header */
57 struct ibhdr {
58         /** Network-layer protocol */
59         uint16_t proto;
60         /** Reserved, must be zero */
61         uint16_t reserved;
62 } __attribute__ (( packed ));
63
64
65
66 struct ib_device;
67 struct ib_queue_pair;
68 struct ib_completion_queue;
69
70 /** An Infiniband Work Queue */
71 struct ib_work_queue {
72         /** Containing queue pair */
73         struct ib_queue_pair *qp;
74         /** "Is a send queue" flag */
75         int is_send;
76         /** Associated completion queue */
77         struct ib_completion_queue *cq;
78         /** List of work queues on this completion queue */
79         struct list_head list;
80         /** Number of work queue entries */
81         unsigned int num_wqes;
82         /** Next work queue entry index
83          *
84          * This is the index of the next entry to be filled (i.e. the
85          * first empty entry).  This value is not bounded by num_wqes;
86          * users must logical-AND with (num_wqes-1) to generate an
87          * array index.
88          */
89         unsigned long next_idx;
90         /** I/O buffers assigned to work queue */
91         struct io_buffer **iobufs;
92         /** Device private data */
93         void *dev_priv;
94 };
95
96 /** An Infiniband Queue Pair */
97 struct ib_queue_pair {
98         /** Queue Pair Number */
99         unsigned long qpn;
100         /** Send queue */
101         struct ib_work_queue send;
102         /** Receive queue */
103         struct ib_work_queue recv;
104         /** Device private data */
105         void *dev_priv;
106         /** Queue owner private data */
107         void *owner_priv;
108 };
109
110 /** An Infiniband Completion Queue */
111 struct ib_completion_queue {
112         /** Completion queue number */
113         unsigned long cqn;
114         /** Number of completion queue entries */
115         unsigned int num_cqes;
116         /** Next completion queue entry index
117          *
118          * This is the index of the next entry to be filled (i.e. the
119          * first empty entry).  This value is not bounded by num_wqes;
120          * users must logical-AND with (num_wqes-1) to generate an
121          * array index.
122          */
123         unsigned long next_idx;
124         /** List of work queues completing to this queue */
125         struct list_head work_queues;
126         /** Device private data */
127         void *dev_priv;
128 };
129
130 /** An Infiniband completion */
131 struct ib_completion {
132         /** Syndrome
133          *
134          * If non-zero, then the completion is in error.
135          */
136         unsigned int syndrome;
137         /** Length */
138         size_t len;
139 };
140
141 /** An Infiniband completion handler
142  *
143  * @v ibdev             Infiniband device
144  * @v qp                Queue pair
145  * @v completion        Completion
146  * @v iobuf             I/O buffer
147  */
148 typedef void ( * ib_completer_t ) ( struct ib_device *ibdev,
149                                     struct ib_queue_pair *qp,
150                                     struct ib_completion *completion,
151                                     struct io_buffer *iobuf );
152
153 /** An Infiniband Address Vector */
154 struct ib_address_vector {
155         /** Destination Queue Pair */
156         unsigned int dest_qp;
157         /** Queue key */
158         unsigned int qkey;
159         /** Destination Local ID */
160         unsigned int dlid;
161         /** Rate */
162         unsigned int rate;
163         /** Service level */
164         unsigned int sl;
165         /** GID is present */
166         unsigned int gid_present;
167         /** GID */
168         struct ib_gid gid;
169 };
170
171 /**
172  * Infiniband device operations
173  *
174  * These represent a subset of the Infiniband Verbs.
175  */
176 struct ib_device_operations {
177         /** Create completion queue
178          *
179          * @v ibdev             Infiniband device
180          * @v cq                Completion queue
181          * @ret rc              Return status code
182          */
183         int ( * create_cq ) ( struct ib_device *ibdev,
184                               struct ib_completion_queue *cq );
185         /** Destroy completion queue
186          *
187          * @v ibdev             Infiniband device
188          * @v cq                Completion queue
189          */
190         void ( * destroy_cq ) ( struct ib_device *ibdev,
191                                 struct ib_completion_queue *cq );
192         /** Create queue pair
193          *
194          * @v ibdev             Infiniband device
195          * @v qp                Queue pair
196          * @ret rc              Return status code
197          */
198         int ( * create_qp ) ( struct ib_device *ibdev,
199                               struct ib_queue_pair *qp );
200         /** Destroy queue pair
201          *
202          * @v ibdev             Infiniband device
203          * @v qp                Queue pair
204          */
205         void ( * destroy_qp ) ( struct ib_device *ibdev,
206                                 struct ib_queue_pair *qp );
207         /** Post send work queue entry
208          *
209          * @v ibdev             Infiniband device
210          * @v qp                Queue pair
211          * @v av                Address vector
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_send ) ( struct ib_device *ibdev,
221                               struct ib_queue_pair *qp,
222                               struct ib_address_vector *av,
223                               struct io_buffer *iobuf );
224         /**
225          * Post receive work queue entry
226          *
227          * @v ibdev             Infiniband device
228          * @v qp                Queue pair
229          * @v iobuf             I/O buffer
230          * @ret rc              Return status code
231          *
232          * If this method returns success, the I/O buffer remains
233          * owned by the queue pair.  If this method returns failure,
234          * the I/O buffer is immediately released; the failure is
235          * interpreted as "failure to enqueue buffer".
236          */
237         int ( * post_recv ) ( struct ib_device *ibdev,
238                               struct ib_queue_pair *qp,
239                               struct io_buffer *iobuf );
240         /** Poll completion queue
241          *
242          * @v ibdev             Infiniband device
243          * @v cq                Completion queue
244          * @v complete_send     Send completion handler
245          * @v complete_recv     Receive completion handler
246          *
247          * The completion handler takes ownership of the I/O buffer.
248          */
249         void ( * poll_cq ) ( struct ib_device *ibdev,
250                              struct ib_completion_queue *cq,
251                              ib_completer_t complete_send,
252                              ib_completer_t complete_recv );
253 };
254
255 /** An Infiniband device */
256 struct ib_device {      
257         /** Infiniband operations */
258         struct ib_device_operations *op;
259         /** Device private data */
260         void *dev_priv;
261 };
262
263 extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
264                                                    unsigned int num_cqes );
265 extern void ib_destroy_cq ( struct ib_device *ibdev,
266                             struct ib_completion_queue *cq );
267 extern struct ib_queue_pair *
268 ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
269                struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
270                struct ib_completion_queue *recv_cq );
271 extern void ib_destroy_qp ( struct ib_device *ibdev,
272                             struct ib_queue_pair *qp );
273 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
274                                            unsigned long qpn, int is_send );
275
276
277
278 extern struct ll_protocol infiniband_protocol;
279
280 extern const char * ib_ntoa ( const void *ll_addr );
281
282 /**
283  * Allocate Infiniband device
284  *
285  * @v priv_size         Size of driver private data
286  * @ret netdev          Network device, or NULL
287  */
288 static inline struct net_device * alloc_ibdev ( size_t priv_size ) {
289         struct net_device *netdev;
290
291         netdev = alloc_netdev ( priv_size );
292         if ( netdev ) {
293                 netdev->ll_protocol = &infiniband_protocol;
294         }
295         return netdev;
296 }
297
298 #endif /* _GPXE_INFINIBAND_H */