4c924d1def0e261c014ba2042fe665b463ae478d
[people/sha0/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 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <byteswap.h>
26 #include <errno.h>
27 #include <gpxe/if_arp.h>
28 #include <gpxe/iobuf.h>
29 #include <gpxe/netdevice.h>
30 #include <gpxe/infiniband.h>
31 #include <gpxe/ib_pathrec.h>
32 #include <gpxe/ib_mcast.h>
33 #include <gpxe/ipoib.h>
34
35 /** @file
36  *
37  * IP over Infiniband
38  */
39
40 /** Number of IPoIB send work queue entries */
41 #define IPOIB_NUM_SEND_WQES 2
42
43 /** Number of IPoIB receive work queue entries */
44 #define IPOIB_NUM_RECV_WQES 4
45
46 /** Number of IPoIB completion entries */
47 #define IPOIB_NUM_CQES 8
48
49 /** An IPoIB device */
50 struct ipoib_device {
51         /** Network device */
52         struct net_device *netdev;
53         /** Underlying Infiniband device */
54         struct ib_device *ibdev;
55         /** Completion queue */
56         struct ib_completion_queue *cq;
57         /** Queue pair */
58         struct ib_queue_pair *qp;
59         /** Broadcast MAC */
60         struct ipoib_mac broadcast;
61         /** Joined to multicast group
62          *
63          * This flag indicates whether or not we have initiated the
64          * join to the IPv4 multicast group.
65          */
66         int broadcast_joined;
67 };
68
69 /** Broadcast IPoIB address */
70 static struct ipoib_mac ipoib_broadcast = {
71         .qpn = htonl ( IB_QPN_BROADCAST ),
72         .gid.u.bytes =  { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
73                           0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff },
74 };
75
76 /****************************************************************************
77  *
78  * IPoIB peer cache
79  *
80  ****************************************************************************
81  */
82
83 /**
84  * IPoIB peer address
85  *
86  * The IPoIB link-layer header is only four bytes long and so does not
87  * have sufficient room to store IPoIB MAC address(es).  We therefore
88  * maintain a cache of MAC addresses identified by a single-byte key,
89  * and abuse the spare two bytes within the link-layer header to
90  * communicate these MAC addresses between the link-layer code and the
91  * netdevice driver.
92  */
93 struct ipoib_peer {
94         /** Key */
95         uint8_t key;
96         /** MAC address */
97         struct ipoib_mac mac;
98 };
99
100 /** Number of IPoIB peer cache entries
101  *
102  * Must be a power of two.
103  */
104 #define IPOIB_NUM_CACHED_PEERS 4
105
106 /** IPoIB peer address cache */
107 static struct ipoib_peer ipoib_peer_cache[IPOIB_NUM_CACHED_PEERS];
108
109 /** Oldest IPoIB peer cache entry index */
110 static unsigned int ipoib_peer_cache_idx = 1;
111
112 /**
113  * Look up cached peer by key
114  *
115  * @v key               Peer cache key
116  * @ret peer            Peer cache entry, or NULL
117  */
118 static struct ipoib_peer * ipoib_lookup_peer_by_key ( unsigned int key ) {
119         struct ipoib_peer *peer;
120         unsigned int i;
121
122         for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) {
123                 peer = &ipoib_peer_cache[i];
124                 if ( peer->key == key )
125                         return peer;
126         }
127
128         if ( key != 0 ) {
129                 DBG ( "IPoIB warning: peer cache lost track of key %x while "
130                       "still in use\n", key );
131         }
132         return NULL;
133 }
134
135 /**
136  * Store GID and QPN in peer cache
137  *
138  * @v gid               Peer GID
139  * @v qpn               Peer QPN
140  * @ret peer            Peer cache entry
141  */
142 static struct ipoib_peer * ipoib_cache_peer ( const struct ipoib_mac *mac ) {
143         struct ipoib_peer *peer;
144         unsigned int key;
145         unsigned int i;
146
147         /* Look for existing cache entry */
148         for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) {
149                 peer = &ipoib_peer_cache[i];
150                 if ( memcmp ( &peer->mac, mac, sizeof ( peer->mac ) ) == 0 )
151                         return peer;
152         }
153
154         /* No entry found: create a new one */
155         key = ipoib_peer_cache_idx++;
156         peer = &ipoib_peer_cache[ key % IPOIB_NUM_CACHED_PEERS ];
157         if ( peer->key )
158                 DBG ( "IPoIB peer %x evicted from cache\n", peer->key );
159
160         memset ( peer, 0, sizeof ( *peer ) );
161         peer->key = key;
162         memcpy ( &peer->mac, mac, sizeof ( peer->mac ) );
163         DBG ( "IPoIB peer %x has MAC %s\n",
164               peer->key, ipoib_ntoa ( &peer->mac ) );
165         return peer;
166 }
167
168 /****************************************************************************
169  *
170  * IPoIB link layer
171  *
172  ****************************************************************************
173  */
174
175 /**
176  * Add IPoIB link-layer header
177  *
178  * @v netdev            Network device
179  * @v iobuf             I/O buffer
180  * @v ll_dest           Link-layer destination address
181  * @v ll_source         Source link-layer address
182  * @v net_proto         Network-layer protocol, in network-byte order
183  * @ret rc              Return status code
184  */
185 static int ipoib_push ( struct net_device *netdev __unused,
186                         struct io_buffer *iobuf, const void *ll_dest,
187                         const void *ll_source __unused, uint16_t net_proto ) {
188         struct ipoib_hdr *ipoib_hdr =
189                 iob_push ( iobuf, sizeof ( *ipoib_hdr ) );
190         const struct ipoib_mac *dest_mac = ll_dest;
191         const struct ipoib_mac *src_mac = ll_source;
192         struct ipoib_peer *dest;
193         struct ipoib_peer *src;
194
195         /* Add link-layer addresses to cache */
196         dest = ipoib_cache_peer ( dest_mac );
197         src = ipoib_cache_peer ( src_mac );
198
199         /* Build IPoIB header */
200         ipoib_hdr->proto = net_proto;
201         ipoib_hdr->u.peer.dest = dest->key;
202         ipoib_hdr->u.peer.src = src->key;
203
204         return 0;
205 }
206
207 /**
208  * Remove IPoIB link-layer header
209  *
210  * @v netdev            Network device
211  * @v iobuf             I/O buffer
212  * @ret ll_dest         Link-layer destination address
213  * @ret ll_source       Source link-layer address
214  * @ret net_proto       Network-layer protocol, in network-byte order
215  * @ret rc              Return status code
216  */
217 static int ipoib_pull ( struct net_device *netdev,
218                         struct io_buffer *iobuf, const void **ll_dest,
219                         const void **ll_source, uint16_t *net_proto ) {
220         struct ipoib_device *ipoib = netdev->priv;
221         struct ipoib_hdr *ipoib_hdr = iobuf->data;
222         struct ipoib_peer *dest;
223         struct ipoib_peer *source;
224
225         /* Sanity check */
226         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
227                 DBG ( "IPoIB packet too short for link-layer header\n" );
228                 DBG_HD ( iobuf->data, iob_len ( iobuf ) );
229                 return -EINVAL;
230         }
231
232         /* Strip off IPoIB header */
233         iob_pull ( iobuf, sizeof ( *ipoib_hdr ) );
234
235         /* Identify source and destination addresses, and clear
236          * reserved word in IPoIB header
237          */
238         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
239         source = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.src );
240         ipoib_hdr->u.reserved = 0;
241
242         /* Fill in required fields */
243         *ll_dest = ( dest ? &dest->mac : &ipoib->broadcast );
244         *ll_source = ( source ? &source->mac : &ipoib->broadcast );
245         *net_proto = ipoib_hdr->proto;
246
247         return 0;
248 }
249
250 /**
251  * Transcribe IPoIB address
252  *
253  * @v ll_addr   Link-layer address
254  * @ret string  Link-layer address in human-readable format
255  */
256 const char * ipoib_ntoa ( const void *ll_addr ) {
257         static char buf[45];
258         const struct ipoib_mac *mac = ll_addr;
259
260         snprintf ( buf, sizeof ( buf ), "%08x:%08x:%08x:%08x:%08x",
261                    htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
262                    htonl ( mac->gid.u.dwords[1] ),
263                    htonl ( mac->gid.u.dwords[2] ),
264                    htonl ( mac->gid.u.dwords[3] ) );
265         return buf;
266 }
267
268 /**
269  * Hash multicast address
270  *
271  * @v af                Address family
272  * @v net_addr          Network-layer address
273  * @v ll_addr           Link-layer address to fill in
274  * @ret rc              Return status code
275  */
276 static int ipoib_mc_hash ( unsigned int af __unused,
277                            const void *net_addr __unused,
278                            void *ll_addr __unused ) {
279
280         return -ENOTSUP;
281 }
282
283 /** IPoIB protocol */
284 struct ll_protocol ipoib_protocol __ll_protocol = {
285         .name           = "IPoIB",
286         .ll_proto       = htons ( ARPHRD_INFINIBAND ),
287         .ll_addr_len    = IPOIB_ALEN,
288         .ll_header_len  = IPOIB_HLEN,
289         .push           = ipoib_push,
290         .pull           = ipoib_pull,
291         .ntoa           = ipoib_ntoa,
292         .mc_hash        = ipoib_mc_hash,
293 };
294
295 /**
296  * Allocate IPoIB device
297  *
298  * @v priv_size         Size of driver private data
299  * @ret netdev          Network device, or NULL
300  */
301 struct net_device * alloc_ipoibdev ( size_t priv_size ) {
302         struct net_device *netdev;
303
304         netdev = alloc_netdev ( priv_size );
305         if ( netdev ) {
306                 netdev->ll_protocol = &ipoib_protocol;
307                 netdev->ll_broadcast = ( uint8_t * ) &ipoib_broadcast;
308                 netdev->max_pkt_len = IB_MAX_PAYLOAD_SIZE;
309         }
310         return netdev;
311 }
312
313 /****************************************************************************
314  *
315  * IPoIB network device
316  *
317  ****************************************************************************
318  */
319
320 /**
321  * Transmit packet via IPoIB network device
322  *
323  * @v netdev            Network device
324  * @v iobuf             I/O buffer
325  * @ret rc              Return status code
326  */
327 static int ipoib_transmit ( struct net_device *netdev,
328                             struct io_buffer *iobuf ) {
329         struct ipoib_device *ipoib = netdev->priv;
330         struct ib_device *ibdev = ipoib->ibdev;
331         struct ipoib_hdr *ipoib_hdr;
332         struct ipoib_peer *dest;
333         struct ib_address_vector av;
334         int rc;
335
336         /* Sanity check */
337         if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
338                 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
339                 return -EINVAL;
340         }
341         ipoib_hdr = iobuf->data;
342
343         /* Attempting transmission while link is down will put the
344          * queue pair into an error state, so don't try it.
345          */
346         if ( ! ib_link_ok ( ibdev ) )
347                 return -ENETUNREACH;
348
349         /* Identify destination address */
350         dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest );
351         if ( ! dest )
352                 return -ENXIO;
353         ipoib_hdr->u.reserved = 0;
354
355         /* Construct address vector */
356         memset ( &av, 0, sizeof ( av ) );
357         av.qpn = ntohl ( dest->mac.qpn );
358         av.gid_present = 1;
359         memcpy ( &av.gid, &dest->mac.gid, sizeof ( av.gid ) );
360         if ( ( rc = ib_resolve_path ( ibdev, &av ) ) != 0 ) {
361                 /* Path not resolved yet */
362                 return rc;
363         }
364
365         return ib_post_send ( ibdev, ipoib->qp, &av, iobuf );
366 }
367
368 /**
369  * Handle IPoIB send completion
370  *
371  * @v ibdev             Infiniband device
372  * @v qp                Queue pair
373  * @v iobuf             I/O buffer
374  * @v rc                Completion status code
375  */
376 static void ipoib_complete_send ( struct ib_device *ibdev __unused,
377                                   struct ib_queue_pair *qp,
378                                   struct io_buffer *iobuf, int rc ) {
379         struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp );
380
381         netdev_tx_complete_err ( ipoib->netdev, iobuf, rc );
382 }
383
384 /**
385  * Handle IPoIB receive completion
386  *
387  * @v ibdev             Infiniband device
388  * @v qp                Queue pair
389  * @v av                Address vector, or NULL
390  * @v iobuf             I/O buffer
391  * @v rc                Completion status code
392  */
393 static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
394                                   struct ib_queue_pair *qp,
395                                   struct ib_address_vector *av,
396                                   struct io_buffer *iobuf, int rc ) {
397         struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp );
398         struct net_device *netdev = ipoib->netdev;
399         struct ipoib_hdr *ipoib_hdr;
400         struct ipoib_mac ll_src;
401         struct ipoib_peer *src;
402
403         if ( rc != 0 ) {
404                 netdev_rx_err ( netdev, iobuf, rc );
405                 return;
406         }
407
408         /* Sanity check */
409         if ( iob_len ( iobuf ) < sizeof ( struct ipoib_hdr ) ) {
410                 DBGC ( ipoib, "IPoIB %p received packet too short to "
411                        "contain IPoIB header\n", ipoib );
412                 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
413                 netdev_rx_err ( netdev, iobuf, -EIO );
414                 return;
415         }
416         ipoib_hdr = iobuf->data;
417
418         /* Parse source address */
419         if ( av->gid_present ) {
420                 ll_src.qpn = htonl ( av->qpn );
421                 memcpy ( &ll_src.gid, &av->gid, sizeof ( ll_src.gid ) );
422                 src = ipoib_cache_peer ( &ll_src );
423                 ipoib_hdr->u.peer.src = src->key;
424         }
425
426         /* Hand off to network layer */
427         netdev_rx ( netdev, iobuf );
428 }
429
430 /** IPoIB completion operations */
431 static struct ib_completion_queue_operations ipoib_cq_op = {
432         .complete_send = ipoib_complete_send,
433         .complete_recv = ipoib_complete_recv,
434 };
435
436 /**
437  * Poll IPoIB network device
438  *
439  * @v netdev            Network device
440  */
441 static void ipoib_poll ( struct net_device *netdev ) {
442         struct ipoib_device *ipoib = netdev->priv;
443         struct ib_device *ibdev = ipoib->ibdev;
444
445         ib_poll_eq ( ibdev );
446 }
447
448 /**
449  * Enable/disable interrupts on IPoIB network device
450  *
451  * @v netdev            Network device
452  * @v enable            Interrupts should be enabled
453  */
454 static void ipoib_irq ( struct net_device *netdev __unused,
455                         int enable __unused ) {
456         /* No implementation */
457 }
458
459 /**
460  * Join IPv4 broadcast multicast group
461  *
462  * @v ipoib             IPoIB device
463  * @ret rc              Return status code
464  */
465 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
466         int rc;
467
468         if ( ( rc = ib_mcast_join ( ipoib->ibdev, ipoib->qp,
469                                     &ipoib->broadcast.gid ) ) != 0 ) {
470                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
471                        ipoib, strerror ( rc ) );
472                 return rc;
473         }
474         ipoib->broadcast_joined = 1;
475
476         return 0;
477 }
478
479 /**
480  * Leave IPv4 broadcast multicast group
481  *
482  * @v ipoib             IPoIB device
483  */
484 static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
485
486         if ( ipoib->broadcast_joined ) {
487                 ib_mcast_leave ( ipoib->ibdev, ipoib->qp,
488                                  &ipoib->broadcast.gid );
489                 ipoib->broadcast_joined = 0;
490         }
491 }
492
493 /**
494  * Open IPoIB network device
495  *
496  * @v netdev            Network device
497  * @ret rc              Return status code
498  */
499 static int ipoib_open ( struct net_device *netdev ) {
500         struct ipoib_device *ipoib = netdev->priv;
501         struct ib_device *ibdev = ipoib->ibdev;
502         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
503         int rc;
504
505         /* Open IB device */
506         if ( ( rc = ib_open ( ibdev ) ) != 0 ) {
507                 DBGC ( ipoib, "IPoIB %p could not open device: %s\n",
508                        ipoib, strerror ( rc ) );
509                 goto err_ib_open;
510         }
511
512         /* Allocate completion queue */
513         ipoib->cq = ib_create_cq ( ibdev, IPOIB_NUM_CQES, &ipoib_cq_op );
514         if ( ! ipoib->cq ) {
515                 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
516                        ipoib );
517                 rc = -ENOMEM;
518                 goto err_create_cq;
519         }
520
521         /* Allocate queue pair */
522         ipoib->qp = ib_create_qp ( ibdev, IPOIB_NUM_SEND_WQES, ipoib->cq,
523                                    IPOIB_NUM_RECV_WQES, ipoib->cq, 0 );
524         if ( ! ipoib->qp ) {
525                 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
526                        ipoib );
527                 rc = -ENOMEM;
528                 goto err_create_qp;
529         }
530         ib_qp_set_ownerdata ( ipoib->qp, ipoib );
531
532         /* Update MAC address with QPN */
533         mac->qpn = htonl ( ipoib->qp->qpn );
534
535         /* Fill receive rings */
536         ib_refill_recv ( ibdev, ipoib->qp );
537
538         /* Join broadcast group */
539         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
540                 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
541                        ipoib, strerror ( rc ) );
542                 goto err_join_broadcast;
543         }
544
545         return 0;
546
547         ipoib_leave_broadcast_group ( ipoib );
548  err_join_broadcast:
549         ib_destroy_qp ( ibdev, ipoib->qp );
550  err_create_qp:
551         ib_destroy_cq ( ibdev, ipoib->cq );
552  err_create_cq:
553         ib_close ( ibdev );
554  err_ib_open:
555         return rc;
556 }
557
558 /**
559  * Close IPoIB network device
560  *
561  * @v netdev            Network device
562  */
563 static void ipoib_close ( struct net_device *netdev ) {
564         struct ipoib_device *ipoib = netdev->priv;
565         struct ib_device *ibdev = ipoib->ibdev;
566         struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
567
568         /* Leave broadcast group */
569         ipoib_leave_broadcast_group ( ipoib );
570
571         /* Remove QPN from MAC address */
572         mac->qpn = 0;
573
574         /* Tear down the queues */
575         ib_destroy_qp ( ibdev, ipoib->qp );
576         ib_destroy_cq ( ibdev, ipoib->cq );
577
578         /* Close IB device */
579         ib_close ( ibdev );
580 }
581
582 /** IPoIB network device operations */
583 static struct net_device_operations ipoib_operations = {
584         .open           = ipoib_open,
585         .close          = ipoib_close,
586         .transmit       = ipoib_transmit,
587         .poll           = ipoib_poll,
588         .irq            = ipoib_irq,
589 };
590
591 /**
592  * Update IPoIB dynamic Infiniband parameters
593  *
594  * @v ipoib             IPoIB device
595  *
596  * The Infiniband port GID and partition key will change at runtime,
597  * when the link is established (or lost).  The MAC address is based
598  * on the port GID, and the broadcast GID is based on the partition
599  * key.  This function recalculates these IPoIB device parameters.
600  */
601 static void ipoib_set_ib_params ( struct ipoib_device *ipoib ) {
602         struct ib_device *ibdev = ipoib->ibdev;
603         struct net_device *netdev = ipoib->netdev;
604         struct ipoib_mac *mac;
605
606         /* Calculate GID portion of MAC address based on port GID */
607         mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
608         memcpy ( &mac->gid, &ibdev->gid, sizeof ( mac->gid ) );
609
610         /* Calculate broadcast GID based on partition key */
611         memcpy ( &ipoib->broadcast, &ipoib_broadcast,
612                  sizeof ( ipoib->broadcast ) );
613         ipoib->broadcast.gid.u.words[2] = htons ( ibdev->pkey );
614
615         /* Set net device link state to reflect Infiniband link state */
616         if ( ib_link_ok ( ibdev ) ) {
617                 netdev_link_up ( netdev );
618         } else {
619                 netdev_link_down ( netdev );
620         }
621 }
622
623 /**
624  * Handle link status change
625  *
626  * @v ibdev             Infiniband device
627  */
628 void ipoib_link_state_changed ( struct ib_device *ibdev ) {
629         struct net_device *netdev = ib_get_ownerdata ( ibdev );
630         struct ipoib_device *ipoib = netdev->priv;
631         int rc;
632
633         /* Leave existing broadcast group */
634         ipoib_leave_broadcast_group ( ipoib );
635
636         /* Update MAC address and broadcast GID based on new port GID
637          * and partition key.
638          */
639         ipoib_set_ib_params ( ipoib );
640
641         /* Join new broadcast group */
642         if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
643                 DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
644                        "%s\n", ipoib, strerror ( rc ) );
645                 return;
646         }
647 }
648
649 /**
650  * Probe IPoIB device
651  *
652  * @v ibdev             Infiniband device
653  * @ret rc              Return status code
654  */
655 int ipoib_probe ( struct ib_device *ibdev ) {
656         struct net_device *netdev;
657         struct ipoib_device *ipoib;
658         int rc;
659
660         /* Allocate network device */
661         netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
662         if ( ! netdev )
663                 return -ENOMEM;
664         netdev_init ( netdev, &ipoib_operations );
665         ipoib = netdev->priv;
666         ib_set_ownerdata ( ibdev, netdev );
667         netdev->dev = ibdev->dev;
668         netdev->ll_broadcast = ( ( uint8_t * ) &ipoib->broadcast );
669         memset ( ipoib, 0, sizeof ( *ipoib ) );
670         ipoib->netdev = netdev;
671         ipoib->ibdev = ibdev;
672
673         /* Calculate as much of the broadcast GID and the MAC address
674          * as we can.  We won't know either of these in full until we
675          * have link-up.
676          */
677         ipoib_set_ib_params ( ipoib );
678
679         /* Register network device */
680         if ( ( rc = register_netdev ( netdev ) ) != 0 )
681                 goto err_register_netdev;
682
683         return 0;
684
685  err_register_netdev:
686         netdev_nullify ( netdev );
687         netdev_put ( netdev );
688         return rc;
689 }
690
691 /**
692  * Remove IPoIB device
693  *
694  * @v ibdev             Infiniband device
695  */
696 void ipoib_remove ( struct ib_device *ibdev ) {
697         struct net_device *netdev = ib_get_ownerdata ( ibdev );
698
699         unregister_netdev ( netdev );
700         netdev_nullify ( netdev );
701         netdev_put ( netdev );
702 }