[netdevice] Split multicast hashing out into an mc_hash method
[people/mcb30/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 <gpxe/if_arp.h>
26 #include <gpxe/iobuf.h>
27 #include <gpxe/netdevice.h>
28 #include <gpxe/infiniband.h>
29 #include <gpxe/ipoib.h>
30
31 /** @file
32  *
33  * IP over Infiniband
34  */
35
36 /** Number of IPoIB data send work queue entries */
37 #define IPOIB_DATA_NUM_SEND_WQES 2
38
39 /** Number of IPoIB data receive work queue entries */
40 #define IPOIB_DATA_NUM_RECV_WQES 4
41
42 /** Number of IPoIB data completion entries */
43 #define IPOIB_DATA_NUM_CQES 8
44
45 /** Number of IPoIB metadata send work queue entries */
46 #define IPOIB_META_NUM_SEND_WQES 2
47
48 /** Number of IPoIB metadata receive work queue entries */
49 #define IPOIB_META_NUM_RECV_WQES 2
50
51 /** Number of IPoIB metadata completion entries */
52 #define IPOIB_META_NUM_CQES 8
53
54 /** An IPoIB queue set */
55 struct ipoib_queue_set {
56         /** Completion queue */
57         struct ib_completion_queue *cq;
58         /** Queue pair */
59         struct ib_queue_pair *qp;
60         /** Receive work queue fill level */
61         unsigned int recv_fill;
62         /** Receive work queue maximum fill level */
63         unsigned int recv_max_fill;
64 };
65
66 /** An IPoIB device */
67 struct ipoib_device {
68         /** Network device */
69         struct net_device *netdev;
70         /** Underlying Infiniband device */
71         struct ib_device *ibdev;
72         /** Data queue set */
73         struct ipoib_queue_set data;
74         /** Data queue set */
75         struct ipoib_queue_set meta;
76         /** Broadcast GID */
77         struct ib_gid broadcast_gid;
78         /** Broadcast LID */
79         unsigned int broadcast_lid;
80         /** Data queue key */
81         unsigned long data_qkey;
82         /** Attached to multicast group
83          *
84          * This flag indicates whether or not we have attached our
85          * data queue pair to the broadcast multicast GID.
86          */
87         int broadcast_attached;
88 };
89
90 /**
91  * IPoIB path cache entry
92  *
93  * This serves a similar role to the ARP cache for Ethernet.  (ARP
94  * *is* used on IPoIB; we have two caches to maintain.)
95  */
96 struct ipoib_cached_path {
97         /** Destination GID */
98         struct ib_gid gid;
99         /** Destination LID */
100         unsigned int dlid;
101         /** Service level */
102         unsigned int sl;
103         /** Rate */
104         unsigned int rate;
105 };
106
107 /** Number of IPoIB path cache entries */
108 #define IPOIB_NUM_CACHED_PATHS 2
109
110 /** IPoIB path cache */
111 static struct ipoib_cached_path ipoib_path_cache[IPOIB_NUM_CACHED_PATHS];
112
113 /** Oldest IPoIB path cache entry index */
114 static unsigned int ipoib_path_cache_idx = 0;
115
116 /** TID half used to identify get path record replies */
117 #define IPOIB_TID_GET_PATH_REC 0x11111111UL
118
119 /** TID half used to identify multicast member record replies */
120 #define IPOIB_TID_MC_MEMBER_REC 0x22222222UL
121
122 /** IPoIB metadata TID */
123 static uint32_t ipoib_meta_tid = 0;
124
125 /** IPv4 broadcast GID */
126 static const struct ib_gid ipv4_broadcast_gid = {
127         { { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
128             0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff } }
129 };
130
131 /** Maximum time we will wait for the broadcast join to succeed */
132 #define IPOIB_JOIN_MAX_DELAY_MS 1000
133
134 /****************************************************************************
135  *
136  * IPoIB link layer
137  *
138  ****************************************************************************
139  */
140
141 /** Broadcast QPN used in IPoIB MAC addresses
142  *
143  * This is a guaranteed invalid real QPN
144  */
145 #define IPOIB_BROADCAST_QPN 0xffffffffUL
146
147 /** Broadcast IPoIB address */
148 static struct ipoib_mac ipoib_broadcast = {
149         .qpn = ntohl ( IPOIB_BROADCAST_QPN ),
150 };
151
152 /**
153  * Add IPoIB link-layer header
154  *
155  * @v iobuf             I/O buffer
156  * @v netdev            Network device
157  * @v net_protocol      Network-layer protocol
158  * @v ll_dest           Link-layer destination address
159  */
160 static int ipoib_push ( struct io_buffer *iobuf,
161                         struct net_device *netdev __unused,
162                         struct net_protocol *net_protocol,
163                         const void *ll_dest ) {
164         struct ipoib_hdr *ipoib_hdr =
165                 iob_push ( iobuf, sizeof ( *ipoib_hdr ) );
166
167         /* Build IPoIB header */
168         memcpy ( &ipoib_hdr->pseudo.peer, ll_dest,
169                  sizeof ( ipoib_hdr->pseudo.peer ) );
170         ipoib_hdr->real.proto = net_protocol->net_proto;
171         ipoib_hdr->real.reserved = 0;
172
173         return 0;
174 }
175
176 /**
177  * Remove IPoIB link-layer header
178  *
179  * @v iobuf             I/O buffer
180  * @v netdev            Network device
181  * @v net_proto         Network-layer protocol, in network-byte order
182  * @v ll_source         Source link-layer address
183  * @ret rc              Return status code
184  */
185 static int ipoib_pull ( struct io_buffer *iobuf,
186                         struct net_device *netdev __unused,
187                         uint16_t *net_proto, const void **ll_source ) {
188         struct ipoib_hdr *ipoib_hdr = iobuf->data;
189
190         /* Sanity check */
191         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
192                 DBG ( "IPoIB packet too short for link-layer header\n" );
193                 DBG_HD ( iobuf->data, iob_len ( iobuf ) );
194                 return -EINVAL;
195         }
196
197         /* Strip off IPoIB header */
198         iob_pull ( iobuf, sizeof ( *ipoib_hdr ) );
199
200         /* Fill in required fields */
201         *net_proto = ipoib_hdr->real.proto;
202         *ll_source = &ipoib_hdr->pseudo.peer;
203
204         return 0;
205 }
206
207 /**
208  * Transcribe IPoIB address
209  *
210  * @v ll_addr   Link-layer address
211  * @ret string  Link-layer address in human-readable format
212  */
213 const char * ipoib_ntoa ( const void *ll_addr ) {
214         static char buf[45];
215         const struct ipoib_mac *mac = ll_addr;
216
217         snprintf ( buf, sizeof ( buf ), "%08lx:%08lx:%08lx:%08lx:%08lx",
218                    htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
219                    htonl ( mac->gid.u.dwords[1] ),
220                    htonl ( mac->gid.u.dwords[2] ),
221                    htonl ( mac->gid.u.dwords[3] ) );
222         return buf;
223 }
224
225 /**
226  * Hash multicast address
227  *
228  * @v af                Address family
229  * @v net_addr          Network-layer address
230  * @v ll_addr           Link-layer address to fill in
231  * @ret rc              Return status code
232  */
233 static int ipoib_mc_hash ( unsigned int af __unused,
234                            const void *net_addr __unused,
235                            void *ll_addr __unused ) {
236
237         return -ENOTSUP;
238 }
239
240 /** IPoIB protocol */
241 struct ll_protocol ipoib_protocol __ll_protocol = {
242         .name           = "IPoIB",
243         .ll_proto       = htons ( ARPHRD_INFINIBAND ),
244         .ll_addr_len    = IPOIB_ALEN,
245         .ll_header_len  = IPOIB_HLEN,
246         .ll_broadcast   = ( uint8_t * ) &ipoib_broadcast,
247         .push           = ipoib_push,
248         .pull           = ipoib_pull,
249         .ntoa           = ipoib_ntoa,
250         .mc_hash        = ipoib_mc_hash,
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         /* Sanity check */
294         assert ( qset->cq == NULL );
295         assert ( qset->qp == NULL );
296
297         /* Store queue parameters */
298         qset->recv_max_fill = num_recv_wqes;
299
300         /* Allocate completion queue */
301         qset->cq = ib_create_cq ( ibdev, num_cqes );
302         if ( ! qset->cq ) {
303                 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
304                        ipoib );
305                 rc = -ENOMEM;
306                 goto err;
307         }
308
309         /* Allocate queue pair */
310         qset->qp = ib_create_qp ( ibdev, num_send_wqes, qset->cq,
311                                   num_recv_wqes, qset->cq, qkey );
312         if ( ! qset->qp ) {
313                 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
314                        ipoib );
315                 rc = -ENOMEM;
316                 goto err;
317         }
318         ib_qp_set_ownerdata ( qset->qp, ipoib->netdev );
319
320         return 0;
321
322  err:
323         ipoib_destroy_qset ( ipoib, qset );
324         return rc;
325 }
326
327 /**
328  * Find path cache entry by GID
329  *
330  * @v gid               GID
331  * @ret entry           Path cache entry, or NULL
332  */
333 static struct ipoib_cached_path *
334 ipoib_find_cached_path ( struct ib_gid *gid ) {
335         struct ipoib_cached_path *path;
336         unsigned int i;
337
338         for ( i = 0 ; i < IPOIB_NUM_CACHED_PATHS ; i++ ) {
339                 path = &ipoib_path_cache[i];
340                 if ( memcmp ( &path->gid, gid, sizeof ( *gid ) ) == 0 )
341                         return path;
342         }
343         DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx cache miss\n",
344               htonl ( gid->u.dwords[0] ), htonl ( gid->u.dwords[1] ),
345               htonl ( gid->u.dwords[2] ), htonl ( gid->u.dwords[3] ) );
346         return NULL;
347 }
348
349 /**
350  * Transmit path record request
351  *
352  * @v ipoib             IPoIB device
353  * @v gid               Destination GID
354  * @ret rc              Return status code
355  */
356 static int ipoib_get_path_record ( struct ipoib_device *ipoib,
357                                    struct ib_gid *gid ) {
358         struct ib_device *ibdev = ipoib->ibdev;
359         struct io_buffer *iobuf;
360         struct ib_mad_path_record *path_record;
361         struct ib_address_vector av;
362         int rc;
363
364         /* Allocate I/O buffer */
365         iobuf = alloc_iob ( sizeof ( *path_record ) );
366         if ( ! iobuf )
367                 return -ENOMEM;
368         iob_put ( iobuf, sizeof ( *path_record ) );
369         path_record = iobuf->data;
370         memset ( path_record, 0, sizeof ( *path_record ) );
371
372         /* Construct path record request */
373         path_record->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
374         path_record->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
375         path_record->mad_hdr.class_version = 2;
376         path_record->mad_hdr.method = IB_MGMT_METHOD_GET;
377         path_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
378         path_record->mad_hdr.tid[0] = IPOIB_TID_GET_PATH_REC;
379         path_record->mad_hdr.tid[1] = ipoib_meta_tid++;
380         path_record->sa_hdr.comp_mask[1] =
381                 htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
382         memcpy ( &path_record->dgid, gid, sizeof ( path_record->dgid ) );
383         memcpy ( &path_record->sgid, &ibdev->port_gid,
384                  sizeof ( path_record->sgid ) );
385
386         /* Construct address vector */
387         memset ( &av, 0, sizeof ( av ) );
388         av.dlid = ibdev->sm_lid;
389         av.dest_qp = IB_SA_QPN;
390         av.qkey = IB_GLOBAL_QKEY;
391
392         /* Post send request */
393         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
394                                    iobuf ) ) != 0 ) {
395                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
396                        ipoib, strerror ( rc ) );
397                 free_iob ( iobuf );
398                 return rc;
399         }
400
401         return 0;
402 }
403
404 /**
405  * Transmit multicast group membership request
406  *
407  * @v ipoib             IPoIB device
408  * @v gid               Multicast GID
409  * @v join              Join (rather than leave) group
410  * @ret rc              Return status code
411  */
412 static int ipoib_mc_member_record ( struct ipoib_device *ipoib,
413                                     struct ib_gid *gid, int join ) {
414         struct ib_device *ibdev = ipoib->ibdev;
415         struct io_buffer *iobuf;
416         struct ib_mad_mc_member_record *mc_member_record;
417         struct ib_address_vector av;
418         int rc;
419
420         /* Allocate I/O buffer */
421         iobuf = alloc_iob ( sizeof ( *mc_member_record ) );
422         if ( ! iobuf )
423                 return -ENOMEM;
424         iob_put ( iobuf, sizeof ( *mc_member_record ) );
425         mc_member_record = iobuf->data;
426         memset ( mc_member_record, 0, sizeof ( *mc_member_record ) );
427
428         /* Construct path record request */
429         mc_member_record->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
430         mc_member_record->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
431         mc_member_record->mad_hdr.class_version = 2;
432         mc_member_record->mad_hdr.method = 
433                 ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
434         mc_member_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
435         mc_member_record->mad_hdr.tid[0] = IPOIB_TID_MC_MEMBER_REC;
436         mc_member_record->mad_hdr.tid[1] = ipoib_meta_tid++;
437         mc_member_record->sa_hdr.comp_mask[1] =
438                 htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
439                         IB_SA_MCMEMBER_REC_JOIN_STATE );
440         mc_member_record->scope__join_state = 1;
441         memcpy ( &mc_member_record->mgid, gid,
442                  sizeof ( mc_member_record->mgid ) );
443         memcpy ( &mc_member_record->port_gid, &ibdev->port_gid,
444                  sizeof ( mc_member_record->port_gid ) );
445
446         /* Construct address vector */
447         memset ( &av, 0, sizeof ( av ) );
448         av.dlid = ibdev->sm_lid;
449         av.dest_qp = IB_SA_QPN;
450         av.qkey = IB_GLOBAL_QKEY;
451
452         /* Post send request */
453         if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
454                                    iobuf ) ) != 0 ) {
455                 DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
456                        ipoib, strerror ( rc ) );
457                 free_iob ( iobuf );
458                 return rc;
459         }
460
461         return 0;
462 }
463
464 /**
465  * Transmit packet via IPoIB network device
466  *
467  * @v netdev            Network device
468  * @v iobuf             I/O buffer
469  * @ret rc              Return status code
470  */
471 static int ipoib_transmit ( struct net_device *netdev,
472                             struct io_buffer *iobuf ) {
473         struct ipoib_device *ipoib = netdev->priv;
474         struct ib_device *ibdev = ipoib->ibdev;
475         struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
476         struct ib_address_vector av;
477         struct ib_gid *gid;
478         struct ipoib_cached_path *path;
479         int rc;
480
481         /* Sanity check */
482         if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
483                 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
484                 return -EINVAL;
485         }
486         iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
487
488         /* Attempting transmission while link is down will put the
489          * queue pair into an error state, so don't try it.
490          */
491         if ( ! ibdev->link_up )
492                 return -ENETUNREACH;
493
494         /* Construct address vector */
495         memset ( &av, 0, sizeof ( av ) );
496         av.qkey = IB_GLOBAL_QKEY;
497         av.gid_present = 1;
498         if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
499                 /* Broadcast address */
500                 av.dest_qp = IB_BROADCAST_QPN;
501                 av.dlid = ipoib->broadcast_lid;
502                 gid = &ipoib->broadcast_gid;
503         } else {
504                 /* Unicast - look in path cache */
505                 path = ipoib_find_cached_path ( &ipoib_pshdr->peer.gid );
506                 if ( ! path ) {
507                         /* No path entry - get path record */
508                         rc = ipoib_get_path_record ( ipoib,
509                                                      &ipoib_pshdr->peer.gid );
510                         netdev_tx_complete ( netdev, iobuf );
511                         return rc;
512                 }
513                 av.dest_qp = ntohl ( ipoib_pshdr->peer.qpn );
514                 av.dlid = path->dlid;
515                 av.rate = path->rate;
516                 av.sl = path->sl;
517                 gid = &ipoib_pshdr->peer.gid;
518         }
519         memcpy ( &av.gid, gid, sizeof ( av.gid ) );
520
521         return ib_post_send ( ibdev, ipoib->data.qp, &av, iobuf );
522 }
523
524 /**
525  * Handle IPoIB data send completion
526  *
527  * @v ibdev             Infiniband device
528  * @v qp                Queue pair
529  * @v completion        Completion
530  * @v iobuf             I/O buffer
531  */
532 static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
533                                        struct ib_queue_pair *qp,
534                                        struct ib_completion *completion,
535                                        struct io_buffer *iobuf ) {
536         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
537
538         netdev_tx_complete_err ( netdev, iobuf,
539                                  ( completion->syndrome ? -EIO : 0 ) );
540 }
541
542 /**
543  * Handle IPoIB data receive completion
544  *
545  * @v ibdev             Infiniband device
546  * @v qp                Queue pair
547  * @v completion        Completion
548  * @v iobuf             I/O buffer
549  */
550 static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
551                                        struct ib_queue_pair *qp,
552                                        struct ib_completion *completion,
553                                        struct io_buffer *iobuf ) {
554         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
555         struct ipoib_device *ipoib = netdev->priv;
556         struct ipoib_pseudo_hdr *ipoib_pshdr;
557
558         if ( completion->syndrome ) {
559                 netdev_rx_err ( netdev, iobuf, -EIO );
560                 goto done;
561         }
562
563         iob_put ( iobuf, completion->len );
564         if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
565                 DBGC ( ipoib, "IPoIB %p received data packet too short to "
566                        "contain GRH\n", ipoib );
567                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
568                 netdev_rx_err ( netdev, iobuf, -EIO );
569                 goto done;
570         }
571         iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
572
573         if ( iob_len ( iobuf ) < sizeof ( struct ipoib_real_hdr ) ) {
574                 DBGC ( ipoib, "IPoIB %p received data packet too short to "
575                        "contain IPoIB header\n", ipoib );
576                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
577                 netdev_rx_err ( netdev, iobuf, -EIO );
578                 goto done;
579         }
580
581         ipoib_pshdr = iob_push ( iobuf, sizeof ( *ipoib_pshdr ) );
582         /* FIXME: fill in a MAC address for the sake of AoE! */
583
584         netdev_rx ( netdev, iobuf );
585
586  done:
587         ipoib->data.recv_fill--;
588 }
589
590 /**
591  * Handle IPoIB metadata send completion
592  *
593  * @v ibdev             Infiniband device
594  * @v qp                Queue pair
595  * @v completion        Completion
596  * @v iobuf             I/O buffer
597  */
598 static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
599                                        struct ib_queue_pair *qp,
600                                        struct ib_completion *completion,
601                                        struct io_buffer *iobuf ) {
602         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
603         struct ipoib_device *ipoib = netdev->priv;
604
605         if ( completion->syndrome ) {
606                 DBGC ( ipoib, "IPoIB %p metadata TX completion error %x\n",
607                        ipoib, completion->syndrome );
608         }
609         free_iob ( iobuf );
610 }
611
612 /**
613  * Handle received IPoIB path record
614  *
615  * @v ipoib             IPoIB device
616  * @v path_record       Path record
617  */
618 static void ipoib_recv_path_record ( struct ipoib_device *ipoib __unused,
619                                      struct ib_mad_path_record *path_record ) {
620         struct ipoib_cached_path *path;
621
622         /* Update path cache entry */
623         path = &ipoib_path_cache[ipoib_path_cache_idx];
624         memcpy ( &path->gid, &path_record->dgid, sizeof ( path->gid ) );
625         path->dlid = ntohs ( path_record->dlid );
626         path->sl = ( path_record->reserved__sl & 0x0f );
627         path->rate = ( path_record->rate_selector__rate & 0x3f );
628
629         DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx dlid %x sl %x rate %x\n",
630               htonl ( path->gid.u.dwords[0] ), htonl ( path->gid.u.dwords[1] ),
631               htonl ( path->gid.u.dwords[2] ), htonl ( path->gid.u.dwords[3] ),
632               path->dlid, path->sl, path->rate );
633         
634         /* Update path cache index */
635         ipoib_path_cache_idx++;
636         if ( ipoib_path_cache_idx == IPOIB_NUM_CACHED_PATHS )
637                 ipoib_path_cache_idx = 0;
638 }
639
640 /**
641  * Handle received IPoIB multicast membership record
642  *
643  * @v ipoib             IPoIB device
644  * @v mc_member_record  Multicast membership record
645  */
646 static void ipoib_recv_mc_member_record ( struct ipoib_device *ipoib,
647                           struct ib_mad_mc_member_record *mc_member_record ) {
648         int joined;
649         int rc;
650
651         /* Record parameters */
652         joined = ( mc_member_record->scope__join_state & 0x0f );
653         ipoib->data_qkey = ntohl ( mc_member_record->qkey );
654         ipoib->broadcast_lid = ntohs ( mc_member_record->mlid );
655         DBGC ( ipoib, "IPoIB %p %s broadcast group: qkey %lx mlid %x\n",
656                ipoib, ( joined ? "joined" : "left" ), ipoib->data_qkey,
657                ipoib->broadcast_lid );
658
659         /* Update data queue pair qkey */
660         if ( ( rc = ib_modify_qp ( ipoib->ibdev, ipoib->data.qp,
661                                    IB_MODIFY_QKEY, ipoib->data_qkey ) ) != 0 ){
662                 DBGC ( ipoib, "IPoIB %p could not update data qkey: %s\n",
663                        ipoib, strerror ( rc ) );
664                 return;
665         }
666 }
667
668 /**
669  * Handle IPoIB metadata receive completion
670  *
671  * @v ibdev             Infiniband device
672  * @v qp                Queue pair
673  * @v completion        Completion
674  * @v iobuf             I/O buffer
675  */
676 static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
677                                        struct ib_queue_pair *qp,
678                                        struct ib_completion *completion,
679                                        struct io_buffer *iobuf ) {
680         struct net_device *netdev = ib_qp_get_ownerdata ( qp );
681         struct ipoib_device *ipoib = netdev->priv;
682         union ib_mad *mad;
683
684         if ( completion->syndrome ) {
685                 DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
686                        ipoib, completion->syndrome );
687                 goto done;
688         }
689
690         iob_put ( iobuf, completion->len );
691         if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
692                 DBGC ( ipoib, "IPoIB %p received metadata packet too short "
693                        "to contain GRH\n", ipoib );
694                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
695                 goto done;
696         }
697         iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
698         if ( iob_len ( iobuf ) < sizeof ( *mad ) ) {
699                 DBGC ( ipoib, "IPoIB %p received metadata packet too short "
700                        "to contain reply\n", ipoib );
701                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
702                 goto done;
703         }
704         mad = iobuf->data;
705
706         if ( mad->mad_hdr.status != 0 ) {
707                 DBGC ( ipoib, "IPoIB %p metadata RX err status %04x\n",
708                        ipoib, ntohs ( mad->mad_hdr.status ) );
709                 goto done;
710         }
711
712         switch ( mad->mad_hdr.tid[0] ) {
713         case IPOIB_TID_GET_PATH_REC:
714                 ipoib_recv_path_record ( ipoib, &mad->path_record );
715                 break;
716         case IPOIB_TID_MC_MEMBER_REC:
717                 ipoib_recv_mc_member_record ( ipoib, &mad->mc_member_record );
718                 break;
719         default:
720                 DBGC ( ipoib, "IPoIB %p unwanted response:\n",
721                        ipoib );
722                 DBGC_HD ( ipoib, mad, sizeof ( *mad ) );
723                 break;
724         }
725
726  done:
727         ipoib->meta.recv_fill--;
728         free_iob ( iobuf );
729 }
730
731 /**
732  * Refill IPoIB receive ring
733  *
734  * @v ipoib             IPoIB device
735  */
736 static void ipoib_refill_recv ( struct ipoib_device *ipoib,
737                                 struct ipoib_queue_set *qset ) {
738         struct ib_device *ibdev = ipoib->ibdev;
739         struct io_buffer *iobuf;
740         int rc;
741
742         while ( qset->recv_fill < qset->recv_max_fill ) {
743                 iobuf = alloc_iob ( IPOIB_PKT_LEN );
744                 if ( ! iobuf )
745                         break;
746                 if ( ( rc = ib_post_recv ( ibdev, qset->qp, iobuf ) ) != 0 ) {
747                         free_iob ( iobuf );
748                         break;
749                 }
750                 qset->recv_fill++;
751         }
752 }
753
754 /**
755  * Poll IPoIB network device
756  *
757  * @v netdev            Network device
758  */
759 static void ipoib_poll ( struct net_device *netdev ) {
760         struct ipoib_device *ipoib = netdev->priv;
761         struct ib_device *ibdev = ipoib->ibdev;
762
763         ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
764                      ipoib_meta_complete_recv );
765         ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
766                      ipoib_data_complete_recv );
767         ipoib_refill_recv ( ipoib, &ipoib->meta );
768         ipoib_refill_recv ( ipoib, &ipoib->data );
769 }
770
771 /**
772  * Enable/disable interrupts on IPoIB network device
773  *
774  * @v netdev            Network device
775  * @v enable            Interrupts should be enabled
776  */
777 static void ipoib_irq ( struct net_device *netdev __unused,
778                         int enable __unused ) {
779         /* No implementation */
780 }
781
782 /**
783  * Join IPv4 broadcast multicast group
784  *
785  * @v ipoib             IPoIB device
786  * @ret rc              Return status code
787  */
788 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
789         int rc;
790
791         /* Sanity check */
792         if ( ! ipoib->data.qp )
793                 return 0;
794
795         /* Attach data queue to broadcast multicast GID */
796         assert ( ipoib->broadcast_attached == 0 );
797         if ( ( rc = ib_mcast_attach ( ipoib->ibdev, ipoib->data.qp,
798                                       &ipoib->broadcast_gid ) ) != 0 ){
799                 DBGC ( ipoib, "IPoIB %p could not attach to broadcast GID: "
800                        "%s\n", ipoib, strerror ( rc ) );
801                 return rc;
802         }
803         ipoib->broadcast_attached = 1;
804
805         /* Initiate broadcast group join */
806         if ( ( rc = ipoib_mc_member_record ( ipoib, &ipoib->broadcast_gid,
807                                              1 ) ) != 0 ) {
808                 DBGC ( ipoib, "IPoIB %p could not send broadcast join: %s\n",
809                        ipoib, strerror ( rc ) );
810                 return rc;
811         }
812
813         /* We will set link up on the network device when we receive
814          * the broadcast join response.
815          */
816
817         return 0;
818 }
819
820 /**
821  * Leave IPv4 broadcast multicast group
822  *
823  * @v ipoib             IPoIB device
824  */
825 static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
826
827         /* Detach data queue from broadcast multicast GID */
828         if ( ipoib->broadcast_attached ) {
829                 assert ( ipoib->data.qp != NULL );
830                 ib_mcast_detach ( ipoib->ibdev, ipoib->data.qp,
831                                   &ipoib->broadcast_gid );
832                 ipoib->broadcast_attached = 0;
833         }
834 }
835
836 /**
837  * Open IPoIB network device
838  *
839  * @v netdev            Network device
840  * @ret rc              Return status code
841  */
842 static int ipoib_open ( struct net_device *netdev ) {
843         struct ipoib_device *ipoib = netdev->priv;
844         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
845         int rc;
846
847         /* Allocate metadata queue set */
848         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
849                                         IPOIB_META_NUM_CQES,
850                                         IPOIB_META_NUM_SEND_WQES,
851                                         IPOIB_META_NUM_RECV_WQES,
852                                         IB_GLOBAL_QKEY ) ) != 0 ) {
853                 DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
854                        ipoib, strerror ( rc ) );
855                 goto err_create_meta_qset;
856         }
857
858         /* Allocate data queue set */
859         if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
860                                         IPOIB_DATA_NUM_CQES,
861                                         IPOIB_DATA_NUM_SEND_WQES,
862                                         IPOIB_DATA_NUM_RECV_WQES,
863                                         IB_GLOBAL_QKEY ) ) != 0 ) {
864                 DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
865                        ipoib, strerror ( rc ) );
866                 goto err_create_data_qset;
867         }
868
869         /* Update MAC address with data QPN */
870         mac->qpn = htonl ( ipoib->data.qp->qpn );
871
872         /* Fill receive rings */
873         ipoib_refill_recv ( ipoib, &ipoib->meta );
874         ipoib_refill_recv ( ipoib, &ipoib->data );
875
876         /* Join broadcast group */
877         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
878                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
879                        ipoib, strerror ( rc ) );
880                 goto err_join_broadcast;
881         }
882
883         return 0;
884
885  err_join_broadcast:
886         ipoib_destroy_qset ( ipoib, &ipoib->data );
887  err_create_data_qset:
888         ipoib_destroy_qset ( ipoib, &ipoib->meta );
889  err_create_meta_qset:
890         return rc;
891 }
892
893 /**
894  * Close IPoIB network device
895  *
896  * @v netdev            Network device
897  */
898 static void ipoib_close ( struct net_device *netdev ) {
899         struct ipoib_device *ipoib = netdev->priv;
900         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
901
902         /* Leave broadcast group */
903         ipoib_leave_broadcast_group ( ipoib );
904
905         /* Remove data QPN from MAC address */
906         mac->qpn = 0;
907
908         /* Tear down the queues */
909         ipoib_destroy_qset ( ipoib, &ipoib->data );
910         ipoib_destroy_qset ( ipoib, &ipoib->meta );
911 }
912
913 /** IPoIB network device operations */
914 static struct net_device_operations ipoib_operations = {
915         .open           = ipoib_open,
916         .close          = ipoib_close,
917         .transmit       = ipoib_transmit,
918         .poll           = ipoib_poll,
919         .irq            = ipoib_irq,
920 };
921
922 /**
923  * Update IPoIB dynamic Infiniband parameters
924  *
925  * @v ipoib             IPoIB device
926  *
927  * The Infiniband port GID and partition key will change at runtime,
928  * when the link is established (or lost).  The MAC address is based
929  * on the port GID, and the broadcast GID is based on the partition
930  * key.  This function recalculates these IPoIB device parameters.
931  */
932 static void ipoib_set_ib_params ( struct ipoib_device *ipoib ) {
933         struct ib_device *ibdev = ipoib->ibdev;
934         struct net_device *netdev = ipoib->netdev;
935         struct ipoib_mac *mac;
936
937         /* Calculate GID portion of MAC address based on port GID */
938         mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
939         memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) );
940
941         /* Calculate broadcast GID based on partition key */
942         memcpy ( &ipoib->broadcast_gid, &ipv4_broadcast_gid,
943                  sizeof ( ipoib->broadcast_gid ) );
944         ipoib->broadcast_gid.u.words[2] = htons ( ibdev->pkey );
945
946         /* Set net device link state to reflect Infiniband link state */
947         if ( ibdev->link_up ) {
948                 netdev_link_up ( netdev );
949         } else {
950                 netdev_link_down ( netdev );
951         }
952 }
953
954 /**
955  * Handle link status change
956  *
957  * @v ibdev             Infiniband device
958  */
959 void ipoib_link_state_changed ( struct ib_device *ibdev ) {
960         struct net_device *netdev = ib_get_ownerdata ( ibdev );
961         struct ipoib_device *ipoib = netdev->priv;
962         int rc;
963
964         /* Leave existing broadcast group */
965         ipoib_leave_broadcast_group ( ipoib );
966
967         /* Update MAC address and broadcast GID based on new port GID
968          * and partition key.
969          */
970         ipoib_set_ib_params ( ipoib );
971
972         /* Join new broadcast group */
973         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
974                 DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
975                        "%s\n", ipoib, strerror ( rc ) );
976                 return;
977         }
978 }
979
980 /**
981  * Probe IPoIB device
982  *
983  * @v ibdev             Infiniband device
984  * @ret rc              Return status code
985  */
986 int ipoib_probe ( struct ib_device *ibdev ) {
987         struct net_device *netdev;
988         struct ipoib_device *ipoib;
989         int rc;
990
991         /* Allocate network device */
992         netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
993         if ( ! netdev )
994                 return -ENOMEM;
995         netdev_init ( netdev, &ipoib_operations );
996         ipoib = netdev->priv;
997         ib_set_ownerdata ( ibdev, netdev );
998         netdev->dev = ibdev->dev;
999         memset ( ipoib, 0, sizeof ( *ipoib ) );
1000         ipoib->netdev = netdev;
1001         ipoib->ibdev = ibdev;
1002
1003         /* Calculate as much of the broadcast GID and the MAC address
1004          * as we can.  We won't know either of these in full until we
1005          * have link-up.
1006          */
1007         ipoib_set_ib_params ( ipoib );
1008
1009         /* Register network device */
1010         if ( ( rc = register_netdev ( netdev ) ) != 0 )
1011                 goto err_register_netdev;
1012
1013         return 0;
1014
1015  err_register_netdev:
1016         netdev_nullify ( netdev );
1017         netdev_put ( netdev );
1018         return rc;
1019 }
1020
1021 /**
1022  * Remove IPoIB device
1023  *
1024  * @v ibdev             Infiniband device
1025  */
1026 void ipoib_remove ( struct ib_device *ibdev ) {
1027         struct net_device *netdev = ib_get_ownerdata ( ibdev );
1028
1029         unregister_netdev ( netdev );
1030         netdev_nullify ( netdev );
1031         netdev_put ( netdev );
1032 }