Added an almost obscene amount of debugging and assertion code while
[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 2
51
52 /** Number of IPoIB data receive work queue entries */
53 #define IPOIB_DATA_NUM_RECV_WQES 2
54
55 /** Number of IPoIB data completion entries */
56 #define IPOIB_DATA_NUM_CQES 32
57
58 /** Number of IPoIB metadata send work queue entries */
59 #define IPOIB_META_NUM_SEND_WQES 2
60
61 /** Number of IPoIB metadata receive work queue entries */
62 #define IPOIB_META_NUM_RECV_WQES 2
63
64 /** Number of IPoIB metadata completion entries */
65 #define IPOIB_META_NUM_CQES 32
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         int len = iob_len ( iobuf );
209         DBG ( "WTF iob_len = %zd\n", len );
210         if ( len < 0 ) {
211                 DBG_HD ( iobuf, sizeof ( *iobuf ) );
212                 DBG ( "locking\n" );
213                 while ( 1 ) {}
214         }
215
216         iob_pull ( iobuf, sizeof ( *ipoib_hdr ) );
217
218         /* Hand off to network-layer protocol */
219         return net_rx ( iobuf, netdev, ipoib_hdr->real.proto,
220                         &ipoib_hdr->pseudo.peer );
221 }
222
223 /**
224  * Transcribe IPoIB address
225  *
226  * @v ll_addr   Link-layer address
227  * @ret string  Link-layer address in human-readable format
228  */
229 const char * ipoib_ntoa ( const void *ll_addr ) {
230         static char buf[45];
231         const struct ipoib_mac *mac = ll_addr;
232
233         snprintf ( buf, sizeof ( buf ), "%08lx:%08lx:%08lx:%08lx:%08lx",
234                    htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
235                    htonl ( mac->gid.u.dwords[1] ),
236                    htonl ( mac->gid.u.dwords[2] ),
237                    htonl ( mac->gid.u.dwords[3] ) );
238         return buf;
239 }
240
241 /** IPoIB protocol */
242 struct ll_protocol ipoib_protocol __ll_protocol = {
243         .name           = "IPoIB",
244         .ll_proto       = htons ( ARPHRD_INFINIBAND ),
245         .ll_addr_len    = IPOIB_ALEN,
246         .ll_header_len  = IPOIB_HLEN,
247         .ll_broadcast   = ( uint8_t * ) &ipoib_broadcast,
248         .tx             = ipoib_tx,
249         .rx             = ipoib_rx,
250         .ntoa           = ipoib_ntoa,
251 };
252
253 /****************************************************************************
254  *
255  * IPoIB network device
256  *
257  ****************************************************************************
258  */
259
260 /**
261  * Destroy queue set
262  *
263  * @v ipoib             IPoIB device
264  * @v qset              Queue set
265  */
266 static void ipoib_destroy_qset ( struct ipoib_device *ipoib,
267                                  struct ipoib_queue_set *qset ) {
268         struct ib_device *ibdev = ipoib->ibdev;
269
270         if ( qset->qp )
271                 ib_destroy_qp ( ibdev, qset->qp );
272         if ( qset->cq )
273                 ib_destroy_cq ( ibdev, qset->cq );
274         memset ( qset, 0, sizeof ( *qset ) );
275 }
276
277 /**
278  * Create queue set
279  *
280  * @v ipoib             IPoIB device
281  * @v qset              Queue set
282  * @ret rc              Return status code
283  */
284 static int ipoib_create_qset ( struct ipoib_device *ipoib,
285                                struct ipoib_queue_set *qset,
286                                unsigned int num_cqes,
287                                unsigned int num_send_wqes,
288                                unsigned int num_recv_wqes,
289                                unsigned long qkey ) {
290         struct ib_device *ibdev = ipoib->ibdev;
291         int rc;
292
293         /* Store queue parameters */
294         qset->recv_max_fill = num_recv_wqes;
295
296         /* Allocate completion queue */
297         qset->cq = ib_create_cq ( ibdev, num_cqes );
298         if ( ! qset->cq ) {
299                 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
300                        ipoib );
301                 rc = -ENOMEM;
302                 goto err;
303         }
304
305         /* Allocate queue pair */
306         qset->qp = ib_create_qp ( ibdev, num_send_wqes, qset->cq,
307                                   num_recv_wqes, qset->cq, qkey );
308         if ( ! qset->qp ) {
309                 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
310                        ipoib );
311                 rc = -ENOMEM;
312                 goto err;
313         }
314         qset->qp->owner_priv = ipoib->netdev;
315
316         return 0;
317
318  err:
319         ipoib_destroy_qset ( ipoib, qset );
320         return rc;
321 }
322
323 /**
324  * Find path cache entry by GID
325  *
326  * @v gid               GID
327  * @ret entry           Path cache entry, or NULL
328  */
329 static struct ipoib_cached_path *
330 ipoib_find_cached_path ( struct ib_gid *gid ) {
331         struct ipoib_cached_path *path;
332         unsigned int i;
333
334         for ( i = 0 ; i < IPOIB_NUM_CACHED_PATHS ; i++ ) {
335                 path = &ipoib_path_cache[i];
336                 if ( memcmp ( &path->gid, gid, sizeof ( *gid ) ) == 0 )
337                         return path;
338         }
339         DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx cache miss\n",
340               htonl ( gid->u.dwords[0] ), htonl ( gid->u.dwords[1] ),
341               htonl ( gid->u.dwords[2] ), htonl ( gid->u.dwords[3] ) );
342         return NULL;
343 }
344
345 /**
346  * Transmit path record request
347  *
348  * @v ipoib             IPoIB device
349  * @v gid               Destination GID
350  * @ret rc              Return status code
351  */
352 static int ipoib_get_path_record ( struct ipoib_device *ipoib,
353                                    struct ib_gid *gid ) {
354         struct ib_device *ibdev = ipoib->ibdev;
355         struct io_buffer *iobuf;
356         struct ib_mad_path_record *path_record;
357         struct ib_address_vector av;
358         int rc;
359
360         /* Allocate I/O buffer */
361         iobuf = alloc_iob ( sizeof ( *path_record ) );
362         if ( ! iobuf )
363                 return -ENOMEM;
364         iob_put ( iobuf, sizeof ( *path_record ) );
365         path_record = iobuf->data;
366         memset ( path_record, 0, sizeof ( *path_record ) );
367
368         /* Construct path record request */
369         path_record->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
370         path_record->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
371         path_record->mad_hdr.class_version = 2;
372         path_record->mad_hdr.method = IB_MGMT_METHOD_GET;
373         path_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
374         path_record->mad_hdr.tid[0] = IPOIB_TID_GET_PATH_REC;
375         path_record->mad_hdr.tid[1] = ipoib_meta_tid++;
376         path_record->sa_hdr.comp_mask[1] =
377                 htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
378         memcpy ( &path_record->dgid, gid, sizeof ( path_record->dgid ) );
379         memcpy ( &path_record->sgid, &ibdev->port_gid,
380                  sizeof ( path_record->sgid ) );
381
382         /* Construct address vector */
383         memset ( &av, 0, sizeof ( av ) );
384         av.dlid = ibdev->sm_lid;
385         av.dest_qp = IB_SA_QPN;
386         av.qkey = IB_GLOBAL_QKEY;
387
388         /* Post send request */
389         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
390                                    iobuf ) ) != 0 ) {
391                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
392                        ipoib, strerror ( rc ) );
393                 free_iob ( iobuf );
394                 return rc;
395         }
396
397         return 0;
398 }
399
400 /**
401  * Transmit multicast group membership request
402  *
403  * @v ipoib             IPoIB device
404  * @v gid               Multicast GID
405  * @v join              Join (rather than leave) group
406  * @ret rc              Return status code
407  */
408 static int ipoib_mc_member_record ( struct ipoib_device *ipoib,
409                                     struct ib_gid *gid, int join ) {
410         struct ib_device *ibdev = ipoib->ibdev;
411         struct io_buffer *iobuf;
412         struct ib_mad_mc_member_record *mc_member_record;
413         struct ib_address_vector av;
414         int rc;
415
416         /* Allocate I/O buffer */
417         iobuf = alloc_iob ( sizeof ( *mc_member_record ) );
418         if ( ! iobuf )
419                 return -ENOMEM;
420         iob_put ( iobuf, sizeof ( *mc_member_record ) );
421         mc_member_record = iobuf->data;
422         memset ( mc_member_record, 0, sizeof ( *mc_member_record ) );
423
424         /* Construct path record request */
425         mc_member_record->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
426         mc_member_record->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
427         mc_member_record->mad_hdr.class_version = 2;
428         mc_member_record->mad_hdr.method = 
429                 ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
430         mc_member_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
431         mc_member_record->mad_hdr.tid[0] = IPOIB_TID_MC_MEMBER_REC;
432         mc_member_record->mad_hdr.tid[1] = ipoib_meta_tid++;
433         mc_member_record->sa_hdr.comp_mask[1] =
434                 htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
435                         IB_SA_MCMEMBER_REC_JOIN_STATE );
436         mc_member_record->scope__join_state = 1;
437         memcpy ( &mc_member_record->mgid, gid,
438                  sizeof ( mc_member_record->mgid ) );
439         memcpy ( &mc_member_record->port_gid, &ibdev->port_gid,
440                  sizeof ( mc_member_record->port_gid ) );
441
442         /* Construct address vector */
443         memset ( &av, 0, sizeof ( av ) );
444         av.dlid = ibdev->sm_lid;
445         av.dest_qp = IB_SA_QPN;
446         av.qkey = IB_GLOBAL_QKEY;
447
448         /* Post send request */
449         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
450                                    iobuf ) ) != 0 ) {
451                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
452                        ipoib, strerror ( rc ) );
453                 free_iob ( iobuf );
454                 return rc;
455         }
456
457         return 0;
458 }
459
460 /**
461  * Transmit packet via IPoIB network device
462  *
463  * @v netdev            Network device
464  * @v iobuf             I/O buffer
465  * @ret rc              Return status code
466  */
467 static int ipoib_transmit ( struct net_device *netdev,
468                             struct io_buffer *iobuf ) {
469         struct ipoib_device *ipoib = netdev->priv;
470         struct ib_device *ibdev = ipoib->ibdev;
471         struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
472         struct ib_address_vector av;
473         struct ib_gid *gid;
474         struct ipoib_cached_path *path;
475         int rc;
476
477         /* Sanity check */
478         if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
479                 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
480                 return -EINVAL;
481         }
482         iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
483
484         /* Construct address vector */
485         memset ( &av, 0, sizeof ( av ) );
486         av.qkey = IB_GLOBAL_QKEY;
487         av.gid_present = 1;
488         if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
489                 /* Broadcast address */
490 #if 0
491                 memcpy ( &av, &hack_ipoib_bcast_av, sizeof ( av ) );
492 #endif
493                 av.dest_qp = IB_BROADCAST_QPN;
494                 av.dlid = ipoib->broadcast_lid;
495                 gid = &ipoib->broadcast_gid;
496         } else {
497                 /* Unicast - look in path cache */
498                 path = ipoib_find_cached_path ( &ipoib_pshdr->peer.gid );
499                 if ( ! path ) {
500                         /* No path entry - get path record */
501                         rc = ipoib_get_path_record ( ipoib,
502                                                      &ipoib_pshdr->peer.gid );
503                         netdev_tx_complete ( netdev, iobuf );
504                         return rc;
505                 }
506                 av.dest_qp = ntohl ( ipoib_pshdr->peer.qpn );
507                 av.dlid = path->dlid;
508                 av.rate = path->rate;
509                 av.sl = path->sl;
510                 gid = &ipoib_pshdr->peer.gid;
511         }
512         memcpy ( &av.gid, gid, sizeof ( av.gid ) );
513
514         return ib_post_send ( ibdev, ipoib->data.qp, &av, iobuf );
515 }
516
517 /**
518  * Handle IPoIB data send completion
519  *
520  * @v ibdev             Infiniband device
521  * @v qp                Queue pair
522  * @v completion        Completion
523  * @v iobuf             I/O buffer
524  */
525 static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
526                                        struct ib_queue_pair *qp,
527                                        struct ib_completion *completion,
528                                        struct io_buffer *iobuf ) {
529         struct net_device *netdev = qp->owner_priv;
530
531         netdev_tx_complete_err ( netdev, iobuf,
532                                  ( completion->syndrome ? -EIO : 0 ) );
533 }
534
535 /**
536  * Handle IPoIB data receive completion
537  *
538  * @v ibdev             Infiniband device
539  * @v qp                Queue pair
540  * @v completion        Completion
541  * @v iobuf             I/O buffer
542  */
543 static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
544                                        struct ib_queue_pair *qp,
545                                        struct ib_completion *completion,
546                                        struct io_buffer *iobuf ) {
547         struct net_device *netdev = qp->owner_priv;
548         struct ipoib_device *ipoib = netdev->priv;
549         struct ipoib_pseudo_hdr *ipoib_pshdr;
550
551         if ( completion->syndrome ) {
552                 netdev_rx_err ( netdev, iobuf, -EIO );
553                 goto done;
554         }
555
556         iob_put ( iobuf, completion->len );
557         if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
558                 DBGC ( ipoib, "IPoIB %p received data packet too short to "
559                        "contain GRH\n", ipoib );
560                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
561                 netdev_rx_err ( netdev, iobuf, -EIO );
562                 goto done;
563         }
564         iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
565
566         if ( iob_len ( iobuf ) < sizeof ( struct ipoib_real_hdr ) ) {
567                 DBGC ( ipoib, "IPoIB %p received data packet too short to "
568                        "contain IPoIB header\n", ipoib );
569                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
570                 netdev_rx_err ( netdev, iobuf, -EIO );
571                 goto done;
572         }
573
574         ipoib_pshdr = iob_push ( iobuf, sizeof ( *ipoib_pshdr ) );
575         /* FIXME: fill in a MAC address for the sake of AoE! */
576
577         netdev_rx ( netdev, iobuf );
578
579  done:
580         ipoib->data.recv_fill--;
581 }
582
583 /**
584  * Handle IPoIB metadata send completion
585  *
586  * @v ibdev             Infiniband device
587  * @v qp                Queue pair
588  * @v completion        Completion
589  * @v iobuf             I/O buffer
590  */
591 static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
592                                        struct ib_queue_pair *qp,
593                                        struct ib_completion *completion,
594                                        struct io_buffer *iobuf ) {
595         struct net_device *netdev = qp->owner_priv;
596         struct ipoib_device *ipoib = netdev->priv;
597
598         if ( completion->syndrome ) {
599                 DBGC ( ipoib, "IPoIB %p metadata TX completion error %x\n",
600                        ipoib, completion->syndrome );
601         }
602         free_iob ( iobuf );
603 }
604
605 /**
606  * Handle received IPoIB path record
607  *
608  * @v ipoib             IPoIB device
609  * @v path_record       Path record
610  */
611 static void ipoib_recv_path_record ( struct ipoib_device *ipoib __unused,
612                                      struct ib_mad_path_record *path_record ) {
613         struct ipoib_cached_path *path;
614
615         /* Update path cache entry */
616         path = &ipoib_path_cache[ipoib_path_cache_idx];
617         memcpy ( &path->gid, &path_record->dgid, sizeof ( path->gid ) );
618         path->dlid = ntohs ( path_record->dlid );
619         path->sl = ( path_record->reserved__sl & 0x0f );
620         path->rate = ( path_record->rate_selector__rate & 0x3f );
621
622         DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx dlid %x sl %x rate %x\n",
623               htonl ( path->gid.u.dwords[0] ), htonl ( path->gid.u.dwords[1] ),
624               htonl ( path->gid.u.dwords[2] ), htonl ( path->gid.u.dwords[3] ),
625               path->dlid, path->sl, path->rate );
626         
627         /* Update path cache index */
628         ipoib_path_cache_idx++;
629         if ( ipoib_path_cache_idx == IPOIB_NUM_CACHED_PATHS )
630                 ipoib_path_cache_idx = 0;
631 }
632
633 /**
634  * Handle received IPoIB multicast membership record
635  *
636  * @v ipoib             IPoIB device
637  * @v mc_member_record  Multicast membership record
638  */
639 static void ipoib_recv_mc_member_record ( struct ipoib_device *ipoib,
640                           struct ib_mad_mc_member_record *mc_member_record ) {
641         /* Record parameters */
642         ipoib->broadcast_joined =
643                 ( mc_member_record->scope__join_state & 0x0f );
644         ipoib->data_qkey = ntohl ( mc_member_record->qkey );
645         ipoib->broadcast_lid = ntohs ( mc_member_record->mlid );
646         DBGC ( ipoib, "IPoIB %p %s broadcast group: qkey %lx mlid %x\n",
647                ipoib, ( ipoib->broadcast_joined ? "joined" : "left" ),
648                ipoib->data_qkey, ipoib->broadcast_lid );
649 }
650
651 /**
652  * Handle IPoIB metadata receive completion
653  *
654  * @v ibdev             Infiniband device
655  * @v qp                Queue pair
656  * @v completion        Completion
657  * @v iobuf             I/O buffer
658  */
659 static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
660                                        struct ib_queue_pair *qp,
661                                        struct ib_completion *completion,
662                                        struct io_buffer *iobuf ) {
663         struct net_device *netdev = qp->owner_priv;
664         struct ipoib_device *ipoib = netdev->priv;
665         union ib_mad *mad;
666
667         if ( completion->syndrome ) {
668                 DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
669                        ipoib, completion->syndrome );
670                 goto done;
671         }
672
673         iob_put ( iobuf, completion->len );
674         if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
675                 DBGC ( ipoib, "IPoIB %p received metadata packet too short "
676                        "to contain GRH\n", ipoib );
677                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
678                 goto done;
679         }
680         iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
681         if ( iob_len ( iobuf ) < sizeof ( *mad ) ) {
682                 DBGC ( ipoib, "IPoIB %p received metadata packet too short "
683                        "to contain reply\n", ipoib );
684                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
685                 goto done;
686         }
687         mad = iobuf->data;
688
689         if ( mad->mad_hdr.status != 0 ) {
690                 DBGC ( ipoib, "IPoIB %p metadata RX err status %04x\n",
691                        ipoib, ntohs ( mad->mad_hdr.status ) );
692                 goto done;
693         }
694
695         switch ( mad->mad_hdr.tid[0] ) {
696         case IPOIB_TID_GET_PATH_REC:
697                 ipoib_recv_path_record ( ipoib, &mad->path_record );
698                 break;
699         case IPOIB_TID_MC_MEMBER_REC:
700                 ipoib_recv_mc_member_record ( ipoib, &mad->mc_member_record );
701                 break;
702         default:
703                 DBGC ( ipoib, "IPoIB %p unwanted response:\n",
704                        ipoib );
705                 DBGC_HD ( ipoib, mad, sizeof ( *mad ) );
706                 break;
707         }
708
709  done:
710         ipoib->meta.recv_fill--;
711         free_iob ( iobuf );
712 }
713
714 /**
715  * Refill IPoIB receive ring
716  *
717  * @v ipoib             IPoIB device
718  */
719 static void ipoib_refill_recv ( struct ipoib_device *ipoib,
720                                 struct ipoib_queue_set *qset ) {
721         struct ib_device *ibdev = ipoib->ibdev;
722         struct io_buffer *iobuf;
723         int rc;
724
725         while ( qset->recv_fill < qset->recv_max_fill ) {
726                 iobuf = alloc_iob ( IPOIB_MTU );
727                 if ( ! iobuf )
728                         break;
729                 if ( ( rc = ib_post_recv ( ibdev, qset->qp, iobuf ) ) != 0 ) {
730                         free_iob ( iobuf );
731                         break;
732                 }
733                 qset->recv_fill++;
734         }
735 }
736
737 /**
738  * Poll IPoIB network device
739  *
740  * @v netdev            Network device
741  */
742 static void ipoib_poll ( struct net_device *netdev ) {
743         struct ipoib_device *ipoib = netdev->priv;
744         struct ib_device *ibdev = ipoib->ibdev;
745
746         ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
747                      ipoib_meta_complete_recv );
748         ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
749                      ipoib_data_complete_recv );
750         ipoib_refill_recv ( ipoib, &ipoib->meta );
751         ipoib_refill_recv ( ipoib, &ipoib->data );
752 }
753
754 /**
755  * Enable/disable interrupts on IPoIB network device
756  *
757  * @v netdev            Network device
758  * @v enable            Interrupts should be enabled
759  */
760 static void ipoib_irq ( struct net_device *netdev __unused,
761                         int enable __unused ) {
762         /* No implementation */
763 }
764
765 /**
766  * Open IPoIB network device
767  *
768  * @v netdev            Network device
769  * @ret rc              Return status code
770  */
771 static int ipoib_open ( struct net_device *netdev ) {
772         struct ipoib_device *ipoib = netdev->priv;
773         struct ib_device *ibdev = ipoib->ibdev;
774         int rc;
775
776         /* Attach to broadcast multicast GID */
777         if ( ( rc = ib_mcast_attach ( ibdev, ipoib->data.qp,
778                                       &ipoib->broadcast_gid ) ) != 0 ) {
779                 DBG ( "Could not attach to broadcast GID: %s\n",
780                       strerror ( rc ) );
781                 return rc;
782         }
783
784         /* Fill receive rings */
785         ipoib_refill_recv ( ipoib, &ipoib->meta );
786         ipoib_refill_recv ( ipoib, &ipoib->data );
787
788         return 0;
789 }
790
791 /**
792  * Close IPoIB network device
793  *
794  * @v netdev            Network device
795  */
796 static void ipoib_close ( struct net_device *netdev ) {
797         struct ipoib_device *ipoib = netdev->priv;
798         struct ib_device *ibdev = ipoib->ibdev;
799
800         /* Detach from broadcast multicast GID */
801         ib_mcast_detach ( ibdev, ipoib->data.qp, &ipoib_broadcast.gid );
802
803         /* FIXME: should probably flush the receive ring */
804 }
805
806 /** IPoIB network device operations */
807 static struct net_device_operations ipoib_operations = {
808         .open           = ipoib_open,
809         .close          = ipoib_close,
810         .transmit       = ipoib_transmit,
811         .poll           = ipoib_poll,
812         .irq            = ipoib_irq,
813 };
814
815 /**
816  * Join IPoIB broadcast group
817  *
818  * @v ipoib             IPoIB device
819  * @ret rc              Return status code
820  */
821 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
822         struct ib_device *ibdev = ipoib->ibdev;
823         unsigned int delay_ms;
824         int rc;
825
826         /* Make sure we have some receive descriptors */
827         ipoib_refill_recv ( ipoib, &ipoib->meta );
828
829         /* Send join request */
830         if ( ( rc = ipoib_mc_member_record ( ipoib, &ipoib->broadcast_gid,
831                                              1 ) ) != 0 ) {
832                 DBGC ( ipoib, "IPoIB %p could not send broadcast join: %s\n",
833                        ipoib, strerror ( rc ) );
834                 return rc;
835         }
836
837         /* Wait for join to complete.  Ideally we wouldn't delay for
838          * this long, but we need the queue key before we can set up
839          * the data queue pair, which we need before we can know the
840          * MAC address.
841          */
842         for ( delay_ms = IPOIB_JOIN_MAX_DELAY_MS ; delay_ms ; delay_ms-- ) {
843                 mdelay ( 1 );
844                 ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
845                              ipoib_meta_complete_recv );
846                 ipoib_refill_recv ( ipoib, &ipoib->meta );
847                 if ( ipoib->broadcast_joined )
848                         return 0;
849         }
850         DBGC ( ipoib, "IPoIB %p timed out waiting for broadcast join\n",
851                ipoib );
852
853         return -ETIMEDOUT;
854 }
855
856 /**
857  * Probe IPoIB device
858  *
859  * @v ibdev             Infiniband device
860  * @ret rc              Return status code
861  */
862 int ipoib_probe ( struct ib_device *ibdev ) {
863         struct net_device *netdev;
864         struct ipoib_device *ipoib;
865         struct ipoib_mac *mac;
866         int rc;
867
868         /* Allocate network device */
869         netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
870         if ( ! netdev )
871                 return -ENOMEM;
872         netdev_init ( netdev, &ipoib_operations );
873         ipoib = netdev->priv;
874         ib_set_ownerdata ( ibdev, netdev );
875         netdev->dev = ibdev->dev;
876         memset ( ipoib, 0, sizeof ( *ipoib ) );
877         ipoib->netdev = netdev;
878         ipoib->ibdev = ibdev;
879
880         /* Calculate broadcast GID */
881         memcpy ( &ipoib->broadcast_gid, &ipv4_broadcast_gid,
882                  sizeof ( ipoib->broadcast_gid ) );
883         ipoib->broadcast_gid.u.words[2] = htons ( ibdev->pkey );
884
885         /* Allocate metadata queue set */
886         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
887                                         IPOIB_META_NUM_CQES,
888                                         IPOIB_META_NUM_SEND_WQES,
889                                         IPOIB_META_NUM_RECV_WQES,
890                                         IB_GLOBAL_QKEY ) ) != 0 ) {
891                 DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
892                        ipoib, strerror ( rc ) );
893                 goto err_create_meta_qset;
894         }
895
896 #if 0
897         ipoib->data_qkey = hack_ipoib_qkey;
898 #endif
899
900         /* Join broadcast group */
901         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
902                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
903                        ipoib, strerror ( rc ) );
904                 goto err_join_broadcast_group;
905         }
906
907         /* Allocate data queue set */
908         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
909                                         IPOIB_DATA_NUM_CQES,
910                                         IPOIB_DATA_NUM_SEND_WQES,
911                                         IPOIB_DATA_NUM_RECV_WQES,
912                                         ipoib->data_qkey ) ) != 0 ) {
913                 DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
914                        ipoib, strerror ( rc ) );
915                 goto err_create_data_qset;
916         }
917
918         /* Construct MAC address */
919         mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
920         mac->qpn = htonl ( ipoib->data.qp->qpn );
921         memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) );
922
923         /* Register network device */
924         if ( ( rc = register_netdev ( netdev ) ) != 0 )
925                 goto err_register_netdev;
926
927         return 0;
928
929  err_register_netdev:
930         ipoib_destroy_qset ( ipoib, &ipoib->data );
931  err_join_broadcast_group:
932  err_create_data_qset:
933         ipoib_destroy_qset ( ipoib, &ipoib->meta );
934  err_create_meta_qset:
935         netdev_nullify ( netdev );
936         netdev_put ( netdev );
937         return rc;
938 }
939
940 /**
941  * Remove IPoIB device
942  *
943  * @v ibdev             Infiniband device
944  */
945 void ipoib_remove ( struct ib_device *ibdev ) {
946         struct net_device *netdev = ib_get_ownerdata ( ibdev );
947         struct ipoib_device *ipoib = netdev->priv;
948
949         unregister_netdev ( netdev );
950         ipoib_destroy_qset ( ipoib, &ipoib->data );
951         ipoib_destroy_qset ( ipoib, &ipoib->meta );
952         netdev_nullify ( netdev );
953         netdev_put ( netdev );
954 }