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