077912b309f267c1d424b5b533bd0e6b1852d90d
[people/pcmattman/gpxe.git] / src / drivers / net / ipoib.c
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <byteswap.h>
24 #include <errno.h>
25 #include "timer.h"
26 #include <gpxe/if_arp.h>
27 #include <gpxe/iobuf.h>
28 #include <gpxe/netdevice.h>
29 #include <gpxe/infiniband.h>
30 #include <gpxe/ipoib.h>
31
32 /** @file
33  *
34  * IP over Infiniband
35  */
36
37
38
39
40
41 extern unsigned long hack_ipoib_qkey;
42 extern struct ib_address_vector hack_ipoib_bcast_av;
43
44
45
46 /** IPoIB MTU */
47 #define IPOIB_MTU 2048
48
49 /** Number of IPoIB data send work queue entries */
50 #define IPOIB_DATA_NUM_SEND_WQES 4
51
52 /** Number of IPoIB data receive work queue entries */
53 #define IPOIB_DATA_NUM_RECV_WQES 4
54
55 /** Number of IPoIB data completion entries */
56 #define IPOIB_DATA_NUM_CQES 8
57
58 /** Number of IPoIB metadata send work queue entries */
59 #define IPOIB_META_NUM_SEND_WQES 4
60
61 /** Number of IPoIB metadata receive work queue entries */
62 #define IPOIB_META_NUM_RECV_WQES 4
63
64 /** Number of IPoIB metadata completion entries */
65 #define IPOIB_META_NUM_CQES 8
66
67 /** An IPoIB queue set */
68 struct ipoib_queue_set {
69         /** Completion queue */
70         struct ib_completion_queue *cq;
71         /** Queue pair */
72         struct ib_queue_pair *qp;
73         /** Receive work queue fill level */
74         unsigned int recv_fill;
75         /** Receive work queue maximum fill level */
76         unsigned int recv_max_fill;
77 };
78
79 /** An IPoIB device */
80 struct ipoib_device {
81         /** Network device */
82         struct net_device *netdev;
83         /** Underlying Infiniband device */
84         struct ib_device *ibdev;
85         /** Data queue set */
86         struct ipoib_queue_set data;
87         /** Data queue set */
88         struct ipoib_queue_set meta;
89         /** Broadcast GID */
90         struct ib_gid broadcast_gid;
91         /** Broadcast LID */
92         unsigned int broadcast_lid;
93         /** Joined to broadcast group */
94         int broadcast_joined;
95         /** Data queue key */
96         unsigned long data_qkey;
97 };
98
99 /**
100  * IPoIB path cache entry
101  *
102  * This serves a similar role to the ARP cache for Ethernet.  (ARP
103  * *is* used on IPoIB; we have two caches to maintain.)
104  */
105 struct ipoib_cached_path {
106         /** Destination GID */
107         struct ib_gid gid;
108         /** Destination LID */
109         unsigned int dlid;
110         /** Service level */
111         unsigned int sl;
112         /** Rate */
113         unsigned int rate;
114 };
115
116 /** Number of IPoIB path cache entries */
117 #define IPOIB_NUM_CACHED_PATHS 2
118
119 /** IPoIB path cache */
120 static struct ipoib_cached_path ipoib_path_cache[IPOIB_NUM_CACHED_PATHS];
121
122 /** Oldest IPoIB path cache entry index */
123 static unsigned int ipoib_path_cache_idx = 0;
124
125 /** TID half used to identify get path record replies */
126 #define IPOIB_TID_GET_PATH_REC 0x11111111UL
127
128 /** TID half used to identify multicast member record replies */
129 #define IPOIB_TID_MC_MEMBER_REC 0x22222222UL
130
131 /** IPoIB metadata TID */
132 static uint32_t ipoib_meta_tid = 0;
133
134 /** IPv4 broadcast GID */
135 static const struct ib_gid ipv4_broadcast_gid = {
136         { { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
137             0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff } }
138 };
139
140 /** Maximum time we will wait for the broadcast join to succeed */
141 #define IPOIB_JOIN_MAX_DELAY_MS 1000
142
143 /****************************************************************************
144  *
145  * IPoIB link layer
146  *
147  ****************************************************************************
148  */
149
150 /** Broadcast QPN used in IPoIB MAC addresses
151  *
152  * This is a guaranteed invalid real QPN
153  */
154 #define IPOIB_BROADCAST_QPN 0xffffffffUL
155
156 /** Broadcast IPoIB address */
157 static struct ipoib_mac ipoib_broadcast = {
158         .qpn = ntohl ( IPOIB_BROADCAST_QPN ),
159 };
160
161 /**
162  * Transmit IPoIB packet
163  *
164  * @v iobuf             I/O buffer
165  * @v netdev            Network device
166  * @v net_protocol      Network-layer protocol
167  * @v ll_dest           Link-layer destination address
168  *
169  * Prepends the IPoIB link-layer header and transmits the packet.
170  */
171 static int ipoib_tx ( struct io_buffer *iobuf, struct net_device *netdev,
172                       struct net_protocol *net_protocol,
173                       const void *ll_dest ) {
174         struct ipoib_hdr *ipoib_hdr =
175                 iob_push ( iobuf, sizeof ( *ipoib_hdr ) );
176
177         /* Build IPoIB header */
178         memcpy ( &ipoib_hdr->pseudo.peer, ll_dest,
179                  sizeof ( ipoib_hdr->pseudo.peer ) );
180         ipoib_hdr->real.proto = net_protocol->net_proto;
181         ipoib_hdr->real.reserved = 0;
182
183         /* Hand off to network device */
184         return netdev_tx ( netdev, iobuf );
185 }
186
187 /**
188  * Process received IPoIB packet
189  *
190  * @v iobuf     I/O buffer
191  * @v netdev    Network device
192  *
193  * Strips off the IPoIB link-layer header and passes up to the
194  * network-layer protocol.
195  */
196 static int ipoib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
197         struct ipoib_hdr *ipoib_hdr = iobuf->data;
198
199         /* Sanity check */
200         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
201                 DBG ( "IPoIB packet too short for link-layer header\n" );
202                 DBG_HD ( iobuf->data, iob_len ( iobuf ) );
203                 free_iob ( iobuf );
204                 return -EINVAL;
205         }
206
207         /* Strip off IPoIB header */
208         iob_pull ( iobuf, sizeof ( *ipoib_hdr ) );
209
210         /* Hand off to network-layer protocol */
211         return net_rx ( iobuf, netdev, ipoib_hdr->real.proto,
212                         &ipoib_hdr->pseudo.peer );
213 }
214
215 /**
216  * Transcribe IPoIB address
217  *
218  * @v ll_addr   Link-layer address
219  * @ret string  Link-layer address in human-readable format
220  */
221 const char * ipoib_ntoa ( const void *ll_addr ) {
222         static char buf[45];
223         const struct ipoib_mac *mac = ll_addr;
224
225         snprintf ( buf, sizeof ( buf ), "%08lx:%08lx:%08lx:%08lx:%08lx",
226                    htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
227                    htonl ( mac->gid.u.dwords[1] ),
228                    htonl ( mac->gid.u.dwords[2] ),
229                    htonl ( mac->gid.u.dwords[3] ) );
230         return buf;
231 }
232
233 /** IPoIB protocol */
234 struct ll_protocol ipoib_protocol __ll_protocol = {
235         .name           = "IPoIB",
236         .ll_proto       = htons ( ARPHRD_INFINIBAND ),
237         .ll_addr_len    = IPOIB_ALEN,
238         .ll_header_len  = IPOIB_HLEN,
239         .ll_broadcast   = ( uint8_t * ) &ipoib_broadcast,
240         .tx             = ipoib_tx,
241         .rx             = ipoib_rx,
242         .ntoa           = ipoib_ntoa,
243 };
244
245 /****************************************************************************
246  *
247  * IPoIB network device
248  *
249  ****************************************************************************
250  */
251
252 /**
253  * Destroy queue set
254  *
255  * @v ipoib             IPoIB device
256  * @v qset              Queue set
257  */
258 static void ipoib_destroy_qset ( struct ipoib_device *ipoib,
259                                  struct ipoib_queue_set *qset ) {
260         struct ib_device *ibdev = ipoib->ibdev;
261
262         if ( qset->qp )
263                 ib_destroy_qp ( ibdev, qset->qp );
264         if ( qset->cq )
265                 ib_destroy_cq ( ibdev, qset->cq );
266         memset ( qset, 0, sizeof ( *qset ) );
267 }
268
269 /**
270  * Create queue set
271  *
272  * @v ipoib             IPoIB device
273  * @v qset              Queue set
274  * @ret rc              Return status code
275  */
276 static int ipoib_create_qset ( struct ipoib_device *ipoib,
277                                struct ipoib_queue_set *qset,
278                                unsigned int num_cqes,
279                                unsigned int num_send_wqes,
280                                unsigned int num_recv_wqes,
281                                unsigned long qkey ) {
282         struct ib_device *ibdev = ipoib->ibdev;
283         int rc;
284
285         /* Store queue parameters */
286         qset->recv_max_fill = num_recv_wqes;
287
288         /* Allocate completion queue */
289         qset->cq = ib_create_cq ( ibdev, num_cqes );
290         if ( ! qset->cq ) {
291                 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
292                        ipoib );
293                 rc = -ENOMEM;
294                 goto err;
295         }
296
297         /* Allocate queue pair */
298         qset->qp = ib_create_qp ( ibdev, num_send_wqes, qset->cq,
299                                   num_recv_wqes, qset->cq, qkey );
300         if ( ! qset->qp ) {
301                 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
302                        ipoib );
303                 rc = -ENOMEM;
304                 goto err;
305         }
306         qset->qp->owner_priv = ipoib->netdev;
307
308         return 0;
309
310  err:
311         ipoib_destroy_qset ( ipoib, qset );
312         return rc;
313 }
314
315 /**
316  * Find path cache entry by GID
317  *
318  * @v gid               GID
319  * @ret entry           Path cache entry, or NULL
320  */
321 static struct ipoib_cached_path *
322 ipoib_find_cached_path ( struct ib_gid *gid ) {
323         struct ipoib_cached_path *path;
324         unsigned int i;
325
326         for ( i = 0 ; i < IPOIB_NUM_CACHED_PATHS ; i++ ) {
327                 path = &ipoib_path_cache[i];
328                 if ( memcmp ( &path->gid, gid, sizeof ( *gid ) ) == 0 )
329                         return path;
330         }
331         DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx cache miss\n",
332               htonl ( gid->u.dwords[0] ), htonl ( gid->u.dwords[1] ),
333               htonl ( gid->u.dwords[2] ), htonl ( gid->u.dwords[3] ) );
334         return NULL;
335 }
336
337 /**
338  * Transmit path record request
339  *
340  * @v ipoib             IPoIB device
341  * @v gid               Destination GID
342  * @ret rc              Return status code
343  */
344 static int ipoib_get_path_record ( struct ipoib_device *ipoib,
345                                    struct ib_gid *gid ) {
346         struct ib_device *ibdev = ipoib->ibdev;
347         struct io_buffer *iobuf;
348         struct ib_mad_path_record *path_record;
349         struct ib_address_vector av;
350         int rc;
351
352         /* Allocate I/O buffer */
353         iobuf = alloc_iob ( sizeof ( *path_record ) );
354         if ( ! iobuf )
355                 return -ENOMEM;
356         iob_put ( iobuf, sizeof ( *path_record ) );
357         path_record = iobuf->data;
358         memset ( path_record, 0, sizeof ( *path_record ) );
359
360         /* Construct path record request */
361         path_record->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
362         path_record->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
363         path_record->mad_hdr.class_version = 2;
364         path_record->mad_hdr.method = IB_MGMT_METHOD_GET;
365         path_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
366         path_record->mad_hdr.tid[0] = IPOIB_TID_GET_PATH_REC;
367         path_record->mad_hdr.tid[1] = ipoib_meta_tid++;
368         path_record->sa_hdr.comp_mask[1] =
369                 htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
370         memcpy ( &path_record->dgid, gid, sizeof ( path_record->dgid ) );
371         memcpy ( &path_record->sgid, &ibdev->port_gid,
372                  sizeof ( path_record->sgid ) );
373
374         /* Construct address vector */
375         memset ( &av, 0, sizeof ( av ) );
376         av.dlid = ibdev->sm_lid;
377         av.dest_qp = IB_SA_QPN;
378         av.qkey = IB_GLOBAL_QKEY;
379
380         /* Post send request */
381         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
382                                    iobuf ) ) != 0 ) {
383                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
384                        ipoib, strerror ( rc ) );
385                 free_iob ( iobuf );
386                 return rc;
387         }
388
389         return 0;
390 }
391
392 /**
393  * Transmit multicast group membership request
394  *
395  * @v ipoib             IPoIB device
396  * @v gid               Multicast GID
397  * @v join              Join (rather than leave) group
398  * @ret rc              Return status code
399  */
400 static int ipoib_mc_member_record ( struct ipoib_device *ipoib,
401                                     struct ib_gid *gid, int join ) {
402         struct ib_device *ibdev = ipoib->ibdev;
403         struct io_buffer *iobuf;
404         struct ib_mad_mc_member_record *mc_member_record;
405         struct ib_address_vector av;
406         int rc;
407
408         /* Allocate I/O buffer */
409         iobuf = alloc_iob ( sizeof ( *mc_member_record ) );
410         if ( ! iobuf )
411                 return -ENOMEM;
412         iob_put ( iobuf, sizeof ( *mc_member_record ) );
413         mc_member_record = iobuf->data;
414         memset ( mc_member_record, 0, sizeof ( *mc_member_record ) );
415
416         /* Construct path record request */
417         mc_member_record->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
418         mc_member_record->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
419         mc_member_record->mad_hdr.class_version = 2;
420         mc_member_record->mad_hdr.method = 
421                 ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
422         mc_member_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
423         mc_member_record->mad_hdr.tid[0] = IPOIB_TID_MC_MEMBER_REC;
424         mc_member_record->mad_hdr.tid[1] = ipoib_meta_tid++;
425         mc_member_record->sa_hdr.comp_mask[1] =
426                 htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
427                         IB_SA_MCMEMBER_REC_JOIN_STATE );
428         mc_member_record->scope__join_state = 1;
429         memcpy ( &mc_member_record->mgid, gid,
430                  sizeof ( mc_member_record->mgid ) );
431         memcpy ( &mc_member_record->port_gid, &ibdev->port_gid,
432                  sizeof ( mc_member_record->port_gid ) );
433
434         /* Construct address vector */
435         memset ( &av, 0, sizeof ( av ) );
436         av.dlid = ibdev->sm_lid;
437         av.dest_qp = IB_SA_QPN;
438         av.qkey = IB_GLOBAL_QKEY;
439
440         /* Post send request */
441         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
442                                    iobuf ) ) != 0 ) {
443                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
444                        ipoib, strerror ( rc ) );
445                 free_iob ( iobuf );
446                 return rc;
447         }
448
449         return 0;
450 }
451
452 /**
453  * Transmit packet via IPoIB network device
454  *
455  * @v netdev            Network device
456  * @v iobuf             I/O buffer
457  * @ret rc              Return status code
458  */
459 static int ipoib_transmit ( struct net_device *netdev,
460                             struct io_buffer *iobuf ) {
461         struct ipoib_device *ipoib = netdev->priv;
462         struct ib_device *ibdev = ipoib->ibdev;
463         struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
464         struct ib_address_vector av;
465         struct ib_gid *gid;
466         struct ipoib_cached_path *path;
467         int rc;
468
469         /* Sanity check */
470         if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
471                 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
472                 return -EINVAL;
473         }
474         iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
475
476         /* Construct address vector */
477         memset ( &av, 0, sizeof ( av ) );
478         av.qkey = IB_GLOBAL_QKEY;
479         av.gid_present = 1;
480         if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
481                 /* Broadcast address */
482 #if 0
483                 memcpy ( &av, &hack_ipoib_bcast_av, sizeof ( av ) );
484 #endif
485                 av.dest_qp = IB_BROADCAST_QPN;
486                 av.dlid = ipoib->broadcast_lid;
487                 gid = &ipoib->broadcast_gid;
488         } else {
489                 /* Unicast - look in path cache */
490                 path = ipoib_find_cached_path ( &ipoib_pshdr->peer.gid );
491                 if ( ! path ) {
492                         /* No path entry - get path record */
493                         rc = ipoib_get_path_record ( ipoib,
494                                                      &ipoib_pshdr->peer.gid );
495                         free_iob ( iobuf );
496                         return rc;
497                 }
498                 av.dest_qp = ntohl ( ipoib_pshdr->peer.qpn );
499                 av.dlid = path->dlid;
500                 av.rate = path->rate;
501                 av.sl = path->sl;
502                 gid = &ipoib_pshdr->peer.gid;
503         }
504         memcpy ( &av.gid, gid, sizeof ( av.gid ) );
505
506         return ib_post_send ( ibdev, ipoib->data.qp, &av, iobuf );
507 }
508
509 /**
510  * Handle IPoIB data send completion
511  *
512  * @v ibdev             Infiniband device
513  * @v qp                Queue pair
514  * @v completion        Completion
515  * @v iobuf             I/O buffer
516  */
517 static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
518                                        struct ib_queue_pair *qp,
519                                        struct ib_completion *completion,
520                                        struct io_buffer *iobuf ) {
521         struct net_device *netdev = qp->owner_priv;
522
523         netdev_tx_complete_err ( netdev, iobuf,
524                                  ( completion->syndrome ? -EIO : 0 ) );
525 }
526
527 /**
528  * Handle IPoIB data receive completion
529  *
530  * @v ibdev             Infiniband device
531  * @v qp                Queue pair
532  * @v completion        Completion
533  * @v iobuf             I/O buffer
534  */
535 static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
536                                        struct ib_queue_pair *qp,
537                                        struct ib_completion *completion,
538                                        struct io_buffer *iobuf ) {
539         struct net_device *netdev = qp->owner_priv;
540         struct ipoib_device *ipoib = netdev->priv;
541         struct ipoib_pseudo_hdr *ipoib_pshdr;
542
543         if ( completion->syndrome ) {
544                 netdev_rx_err ( netdev, iobuf, -EIO );
545                 goto done;
546         }
547
548         iob_put ( iobuf, completion->len );
549         if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
550                 DBGC ( ipoib, "IPoIB %p received data packet too short to "
551                        "contain GRH\n", ipoib );
552                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
553                 netdev_rx_err ( netdev, iobuf, -EIO );
554                 goto done;
555         }
556         iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
557
558         if ( iob_len ( iobuf ) < sizeof ( struct ipoib_real_hdr ) ) {
559                 DBGC ( ipoib, "IPoIB %p received data packet too short to "
560                        "contain IPoIB header\n", ipoib );
561                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
562                 netdev_rx_err ( netdev, iobuf, -EIO );
563                 goto done;
564         }
565
566         ipoib_pshdr = iob_push ( iobuf, sizeof ( *ipoib_pshdr ) );
567         /* FIXME: fill in a MAC address for the sake of AoE! */
568
569         netdev_rx ( netdev, iobuf );
570
571  done:
572         ipoib->data.recv_fill--;
573 }
574
575 /**
576  * Handle IPoIB metadata send completion
577  *
578  * @v ibdev             Infiniband device
579  * @v qp                Queue pair
580  * @v completion        Completion
581  * @v iobuf             I/O buffer
582  */
583 static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
584                                        struct ib_queue_pair *qp,
585                                        struct ib_completion *completion,
586                                        struct io_buffer *iobuf ) {
587         struct net_device *netdev = qp->owner_priv;
588         struct ipoib_device *ipoib = netdev->priv;
589
590         if ( completion->syndrome ) {
591                 DBGC ( ipoib, "IPoIB %p metadata TX completion error %x\n",
592                        ipoib, completion->syndrome );
593         }
594         free_iob ( iobuf );
595 }
596
597 /**
598  * Handle received IPoIB path record
599  *
600  * @v ipoib             IPoIB device
601  * @v path_record       Path record
602  */
603 static void ipoib_recv_path_record ( struct ipoib_device *ipoib __unused,
604                                      struct ib_mad_path_record *path_record ) {
605         struct ipoib_cached_path *path;
606
607         /* Update path cache entry */
608         path = &ipoib_path_cache[ipoib_path_cache_idx];
609         memcpy ( &path->gid, &path_record->dgid, sizeof ( path->gid ) );
610         path->dlid = ntohs ( path_record->dlid );
611         path->sl = ( path_record->reserved__sl & 0x0f );
612         path->rate = ( path_record->rate_selector__rate & 0x3f );
613
614         DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx dlid %x sl %x rate %x\n",
615               htonl ( path->gid.u.dwords[0] ), htonl ( path->gid.u.dwords[1] ),
616               htonl ( path->gid.u.dwords[2] ), htonl ( path->gid.u.dwords[3] ),
617               path->dlid, path->sl, path->rate );
618         
619         /* Update path cache index */
620         ipoib_path_cache_idx++;
621         if ( ipoib_path_cache_idx == IPOIB_NUM_CACHED_PATHS )
622                 ipoib_path_cache_idx = 0;
623 }
624
625 /**
626  * Handle received IPoIB multicast membership record
627  *
628  * @v ipoib             IPoIB device
629  * @v mc_member_record  Multicast membership record
630  */
631 static void ipoib_recv_mc_member_record ( struct ipoib_device *ipoib,
632                           struct ib_mad_mc_member_record *mc_member_record ) {
633         /* Record parameters */
634         ipoib->broadcast_joined =
635                 ( mc_member_record->scope__join_state & 0x0f );
636         ipoib->data_qkey = ntohl ( mc_member_record->qkey );
637         ipoib->broadcast_lid = ntohs ( mc_member_record->mlid );
638         DBGC ( ipoib, "IPoIB %p %s broadcast group: qkey %lx mlid %x\n",
639                ipoib, ( ipoib->broadcast_joined ? "joined" : "left" ),
640                ipoib->data_qkey, ipoib->broadcast_lid );
641 }
642
643 /**
644  * Handle IPoIB metadata receive completion
645  *
646  * @v ibdev             Infiniband device
647  * @v qp                Queue pair
648  * @v completion        Completion
649  * @v iobuf             I/O buffer
650  */
651 static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
652                                        struct ib_queue_pair *qp,
653                                        struct ib_completion *completion,
654                                        struct io_buffer *iobuf ) {
655         struct net_device *netdev = qp->owner_priv;
656         struct ipoib_device *ipoib = netdev->priv;
657         union ib_mad *mad;
658
659         if ( completion->syndrome ) {
660                 DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
661                        ipoib, completion->syndrome );
662                 goto done;
663         }
664
665         iob_put ( iobuf, completion->len );
666         if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
667                 DBGC ( ipoib, "IPoIB %p received metadata packet too short "
668                        "to contain GRH\n", ipoib );
669                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
670                 goto done;
671         }
672         iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
673         if ( iob_len ( iobuf ) < sizeof ( *mad ) ) {
674                 DBGC ( ipoib, "IPoIB %p received metadata packet too short "
675                        "to contain reply\n", ipoib );
676                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
677                 goto done;
678         }
679         mad = iobuf->data;
680
681         if ( mad->mad_hdr.status != 0 ) {
682                 DBGC ( ipoib, "IPoIB %p metadata RX err status %04x\n",
683                        ipoib, ntohs ( mad->mad_hdr.status ) );
684                 goto done;
685         }
686
687         switch ( mad->mad_hdr.tid[0] ) {
688         case IPOIB_TID_GET_PATH_REC:
689                 ipoib_recv_path_record ( ipoib, &mad->path_record );
690                 break;
691         case IPOIB_TID_MC_MEMBER_REC:
692                 ipoib_recv_mc_member_record ( ipoib, &mad->mc_member_record );
693                 break;
694         default:
695                 DBGC ( ipoib, "IPoIB %p unwanted response:\n",
696                        ipoib );
697                 DBGC_HD ( ipoib, mad, sizeof ( *mad ) );
698                 break;
699         }
700
701  done:
702         ipoib->meta.recv_fill--;
703         free_iob ( iobuf );
704 }
705
706 /**
707  * Refill IPoIB receive ring
708  *
709  * @v ipoib             IPoIB device
710  */
711 static void ipoib_refill_recv ( struct ipoib_device *ipoib,
712                                 struct ipoib_queue_set *qset ) {
713         struct ib_device *ibdev = ipoib->ibdev;
714         struct io_buffer *iobuf;
715         int rc;
716
717         while ( qset->recv_fill < qset->recv_max_fill ) {
718                 iobuf = alloc_iob ( IPOIB_MTU );
719                 if ( ! iobuf )
720                         break;
721                 if ( ( rc = ib_post_recv ( ibdev, qset->qp, iobuf ) ) != 0 ) {
722                         free_iob ( iobuf );
723                         break;
724                 }
725                 qset->recv_fill++;
726         }
727 }
728
729 /**
730  * Poll IPoIB network device
731  *
732  * @v netdev            Network device
733  */
734 static void ipoib_poll ( struct net_device *netdev ) {
735         struct ipoib_device *ipoib = netdev->priv;
736         struct ib_device *ibdev = ipoib->ibdev;
737
738         ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
739                      ipoib_meta_complete_recv );
740         ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
741                      ipoib_data_complete_recv );
742         ipoib_refill_recv ( ipoib, &ipoib->meta );
743         ipoib_refill_recv ( ipoib, &ipoib->data );
744 }
745
746 /**
747  * Enable/disable interrupts on IPoIB network device
748  *
749  * @v netdev            Network device
750  * @v enable            Interrupts should be enabled
751  */
752 static void ipoib_irq ( struct net_device *netdev __unused,
753                         int enable __unused ) {
754         /* No implementation */
755 }
756
757 /**
758  * Open IPoIB network device
759  *
760  * @v netdev            Network device
761  * @ret rc              Return status code
762  */
763 static int ipoib_open ( struct net_device *netdev ) {
764         struct ipoib_device *ipoib = netdev->priv;
765         struct ib_device *ibdev = ipoib->ibdev;
766         int rc;
767
768         /* Attach to broadcast multicast GID */
769         if ( ( rc = ib_mcast_attach ( ibdev, ipoib->data.qp,
770                                       &ipoib->broadcast_gid ) ) != 0 ) {
771                 DBG ( "Could not attach to broadcast GID: %s\n",
772                       strerror ( rc ) );
773                 return rc;
774         }
775
776         /* Fill receive rings */
777         ipoib_refill_recv ( ipoib, &ipoib->meta );
778         ipoib_refill_recv ( ipoib, &ipoib->data );
779
780         return 0;
781 }
782
783 /**
784  * Close IPoIB network device
785  *
786  * @v netdev            Network device
787  */
788 static void ipoib_close ( struct net_device *netdev ) {
789         struct ipoib_device *ipoib = netdev->priv;
790         struct ib_device *ibdev = ipoib->ibdev;
791
792         /* Detach from broadcast multicast GID */
793         ib_mcast_detach ( ibdev, ipoib->data.qp, &ipoib_broadcast.gid );
794
795         /* FIXME: should probably flush the receive ring */
796 }
797
798 /** IPoIB network device operations */
799 static struct net_device_operations ipoib_operations = {
800         .open           = ipoib_open,
801         .close          = ipoib_close,
802         .transmit       = ipoib_transmit,
803         .poll           = ipoib_poll,
804         .irq            = ipoib_irq,
805 };
806
807 /**
808  * Join IPoIB broadcast group
809  *
810  * @v ipoib             IPoIB device
811  * @ret rc              Return status code
812  */
813 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
814         struct ib_device *ibdev = ipoib->ibdev;
815         unsigned int delay_ms;
816         int rc;
817
818         /* Make sure we have some receive descriptors */
819         ipoib_refill_recv ( ipoib, &ipoib->meta );
820
821         /* Send join request */
822         if ( ( rc = ipoib_mc_member_record ( ipoib, &ipoib->broadcast_gid,
823                                              1 ) ) != 0 ) {
824                 DBGC ( ipoib, "IPoIB %p could not send broadcast join: %s\n",
825                        ipoib, strerror ( rc ) );
826                 return rc;
827         }
828
829         /* Wait for join to complete.  Ideally we wouldn't delay for
830          * this long, but we need the queue key before we can set up
831          * the data queue pair, which we need before we can know the
832          * MAC address.
833          */
834         for ( delay_ms = IPOIB_JOIN_MAX_DELAY_MS ; delay_ms ; delay_ms-- ) {
835                 mdelay ( 1 );
836                 ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
837                              ipoib_meta_complete_recv );
838                 ipoib_refill_recv ( ipoib, &ipoib->meta );
839                 if ( ipoib->broadcast_joined )
840                         return 0;
841         }
842         DBGC ( ipoib, "IPoIB %p timed out waiting for broadcast join\n",
843                ipoib );
844
845         return -ETIMEDOUT;
846 }
847
848 /**
849  * Probe IPoIB device
850  *
851  * @v ibdev             Infiniband device
852  * @ret rc              Return status code
853  */
854 int ipoib_probe ( struct ib_device *ibdev ) {
855         struct net_device *netdev;
856         struct ipoib_device *ipoib;
857         struct ipoib_mac *mac;
858         int rc;
859
860         /* Allocate network device */
861         netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
862         if ( ! netdev )
863                 return -ENOMEM;
864         netdev_init ( netdev, &ipoib_operations );
865         ipoib = netdev->priv;
866         ib_set_ownerdata ( ibdev, netdev );
867         netdev->dev = ibdev->dev;
868         memset ( ipoib, 0, sizeof ( *ipoib ) );
869         ipoib->netdev = netdev;
870         ipoib->ibdev = ibdev;
871
872         /* Calculate broadcast GID */
873         memcpy ( &ipoib->broadcast_gid, &ipv4_broadcast_gid,
874                  sizeof ( ipoib->broadcast_gid ) );
875         ipoib->broadcast_gid.u.words[2] = htons ( ibdev->pkey );
876
877         /* Allocate metadata queue set */
878         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
879                                         IPOIB_META_NUM_CQES,
880                                         IPOIB_META_NUM_SEND_WQES,
881                                         IPOIB_META_NUM_RECV_WQES,
882                                         IB_GLOBAL_QKEY ) ) != 0 ) {
883                 DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
884                        ipoib, strerror ( rc ) );
885                 goto err_create_meta_qset;
886         }
887
888 #if 0
889         ipoib->data_qkey = hack_ipoib_qkey;
890 #endif
891
892         /* Join broadcast group */
893         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
894                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
895                        ipoib, strerror ( rc ) );
896                 goto err_join_broadcast_group;
897         }
898
899         /* Allocate data queue set */
900         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
901                                         IPOIB_DATA_NUM_CQES,
902                                         IPOIB_DATA_NUM_SEND_WQES,
903                                         IPOIB_DATA_NUM_RECV_WQES,
904                                         ipoib->data_qkey ) ) != 0 ) {
905                 DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
906                        ipoib, strerror ( rc ) );
907                 goto err_create_data_qset;
908         }
909
910         /* Construct MAC address */
911         mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
912         mac->qpn = htonl ( ipoib->data.qp->qpn );
913         memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) );
914
915         /* Register network device */
916         if ( ( rc = register_netdev ( netdev ) ) != 0 )
917                 goto err_register_netdev;
918
919         return 0;
920
921  err_register_netdev:
922         ipoib_destroy_qset ( ipoib, &ipoib->data );
923  err_join_broadcast_group:
924  err_create_data_qset:
925         ipoib_destroy_qset ( ipoib, &ipoib->meta );
926  err_create_meta_qset:
927         netdev_nullify ( netdev );
928         netdev_put ( netdev );
929         return rc;
930 }
931
932 /**
933  * Remove IPoIB device
934  *
935  * @v ibdev             Infiniband device
936  */
937 void ipoib_remove ( struct ib_device *ibdev ) {
938         struct net_device *netdev = ib_get_ownerdata ( ibdev );
939         struct ipoib_device *ipoib = netdev->priv;
940
941         unregister_netdev ( netdev );
942         ipoib_destroy_qset ( ipoib, &ipoib->data );
943         ipoib_destroy_qset ( ipoib, &ipoib->meta );
944         netdev_nullify ( netdev );
945         netdev_put ( netdev );
946 }