|
@@ -84,6 +84,8 @@ struct ipoib_device {
|
84
|
84
|
struct ipoib_queue_set data;
|
85
|
85
|
/** Data queue set */
|
86
|
86
|
struct ipoib_queue_set meta;
|
|
87
|
+ /** Broadcast GID */
|
|
88
|
+ struct ib_gid broadcast_gid;
|
87
|
89
|
};
|
88
|
90
|
|
89
|
91
|
/**
|
|
@@ -112,6 +114,15 @@ static struct ipoib_cached_path ipoib_path_cache[IPOIB_NUM_CACHED_PATHS];
|
112
|
114
|
/** Oldest IPoIB path cache entry index */
|
113
|
115
|
static unsigned int ipoib_path_cache_idx = 0;
|
114
|
116
|
|
|
117
|
+/** IPoIB metadata TID */
|
|
118
|
+static uint32_t ipoib_meta_tid = 0;
|
|
119
|
+
|
|
120
|
+/** IPv4 broadcast GID */
|
|
121
|
+static const struct ib_gid ipv4_broadcast_gid = {
|
|
122
|
+ { { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
|
|
123
|
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff } }
|
|
124
|
+};
|
|
125
|
+
|
115
|
126
|
/****************************************************************************
|
116
|
127
|
*
|
117
|
128
|
* IPoIB link layer
|
|
@@ -319,7 +330,6 @@ static int ipoib_get_path_record ( struct ipoib_device *ipoib,
|
319
|
330
|
struct io_buffer *iobuf;
|
320
|
331
|
struct ib_mad_path_record *path_record;
|
321
|
332
|
struct ib_address_vector av;
|
322
|
|
- static uint32_t tid = 0;
|
323
|
333
|
int rc;
|
324
|
334
|
|
325
|
335
|
/* Allocate I/O buffer */
|
|
@@ -336,7 +346,7 @@ static int ipoib_get_path_record ( struct ipoib_device *ipoib,
|
336
|
346
|
path_record->mad_hdr.class_version = 2;
|
337
|
347
|
path_record->mad_hdr.method = IB_MGMT_METHOD_GET;
|
338
|
348
|
path_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
|
339
|
|
- path_record->mad_hdr.tid = tid++;
|
|
349
|
+ path_record->mad_hdr.tid = ipoib_meta_tid++;
|
340
|
350
|
path_record->sa_hdr.comp_mask[1] =
|
341
|
351
|
htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
|
342
|
352
|
memcpy ( &path_record->dgid, gid, sizeof ( path_record->dgid ) );
|
|
@@ -361,6 +371,65 @@ static int ipoib_get_path_record ( struct ipoib_device *ipoib,
|
361
|
371
|
return 0;
|
362
|
372
|
}
|
363
|
373
|
|
|
374
|
+/**
|
|
375
|
+ * Transmit multicast group membership request
|
|
376
|
+ *
|
|
377
|
+ * @v ipoib IPoIB device
|
|
378
|
+ * @v gid Multicast GID
|
|
379
|
+ * @v join Join (rather than leave) group
|
|
380
|
+ * @ret rc Return status code
|
|
381
|
+ */
|
|
382
|
+static int ipoib_mc_member_record ( struct ipoib_device *ipoib,
|
|
383
|
+ struct ib_gid *gid, int join ) {
|
|
384
|
+ struct ib_device *ibdev = ipoib->ibdev;
|
|
385
|
+ struct io_buffer *iobuf;
|
|
386
|
+ struct ib_mad_mc_member_record *mc_member_record;
|
|
387
|
+ struct ib_address_vector av;
|
|
388
|
+ int rc;
|
|
389
|
+
|
|
390
|
+ /* Allocate I/O buffer */
|
|
391
|
+ iobuf = alloc_iob ( sizeof ( *mc_member_record ) );
|
|
392
|
+ if ( ! iobuf )
|
|
393
|
+ return -ENOMEM;
|
|
394
|
+ iob_put ( iobuf, sizeof ( *mc_member_record ) );
|
|
395
|
+ mc_member_record = iobuf->data;
|
|
396
|
+ memset ( mc_member_record, 0, sizeof ( *mc_member_record ) );
|
|
397
|
+
|
|
398
|
+ /* Construct path record request */
|
|
399
|
+ mc_member_record->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
|
|
400
|
+ mc_member_record->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
|
|
401
|
+ mc_member_record->mad_hdr.class_version = 2;
|
|
402
|
+ mc_member_record->mad_hdr.method =
|
|
403
|
+ ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
|
|
404
|
+ mc_member_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
|
|
405
|
+ mc_member_record->mad_hdr.tid = ipoib_meta_tid++;
|
|
406
|
+ mc_member_record->sa_hdr.comp_mask[1] =
|
|
407
|
+ htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
|
|
408
|
+ IB_SA_MCMEMBER_REC_JOIN_STATE );
|
|
409
|
+ mc_member_record->scope__join_state = 1;
|
|
410
|
+ memcpy ( &mc_member_record->mgid, gid,
|
|
411
|
+ sizeof ( mc_member_record->mgid ) );
|
|
412
|
+ memcpy ( &mc_member_record->port_gid, &ibdev->port_gid,
|
|
413
|
+ sizeof ( mc_member_record->port_gid ) );
|
|
414
|
+
|
|
415
|
+ /* Construct address vector */
|
|
416
|
+ memset ( &av, 0, sizeof ( av ) );
|
|
417
|
+ av.dlid = ibdev->sm_lid;
|
|
418
|
+ av.dest_qp = IB_SA_QPN;
|
|
419
|
+ av.qkey = IB_GLOBAL_QKEY;
|
|
420
|
+
|
|
421
|
+ /* Post send request */
|
|
422
|
+ if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
|
|
423
|
+ iobuf ) ) != 0 ) {
|
|
424
|
+ DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
|
|
425
|
+ ipoib, strerror ( rc ) );
|
|
426
|
+ free_iob ( iobuf );
|
|
427
|
+ return rc;
|
|
428
|
+ }
|
|
429
|
+
|
|
430
|
+ return 0;
|
|
431
|
+}
|
|
432
|
+
|
364
|
433
|
/**
|
365
|
434
|
* Transmit packet via IPoIB network device
|
366
|
435
|
*
|
|
@@ -591,7 +660,7 @@ static int ipoib_open ( struct net_device *netdev ) {
|
591
|
660
|
|
592
|
661
|
/* Attach to broadcast multicast GID */
|
593
|
662
|
if ( ( rc = ib_mcast_attach ( ibdev, ipoib->data.qp,
|
594
|
|
- &ibdev->broadcast_gid ) ) != 0 ) {
|
|
663
|
+ &ipoib->broadcast_gid ) ) != 0 ) {
|
595
|
664
|
DBG ( "Could not attach to broadcast GID: %s\n",
|
596
|
665
|
strerror ( rc ) );
|
597
|
666
|
return rc;
|
|
@@ -628,6 +697,27 @@ static struct net_device_operations ipoib_operations = {
|
628
|
697
|
.irq = ipoib_irq,
|
629
|
698
|
};
|
630
|
699
|
|
|
700
|
+/**
|
|
701
|
+ * Join IPoIB broadcast group
|
|
702
|
+ *
|
|
703
|
+ * @v ipoib IPoIB device
|
|
704
|
+ * @ret rc Return status code
|
|
705
|
+ */
|
|
706
|
+int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
|
|
707
|
+ int rc;
|
|
708
|
+
|
|
709
|
+ /* Send join request */
|
|
710
|
+ if ( ( rc = ipoib_mc_member_record ( ipoib, &ipoib->broadcast_gid,
|
|
711
|
+ 1 ) ) != 0 ) {
|
|
712
|
+ DBGC ( ipoib, "IPoIB %p could not send broadcast join: %s\n",
|
|
713
|
+ ipoib, strerror ( rc ) );
|
|
714
|
+ return rc;
|
|
715
|
+ }
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+ return 0;
|
|
719
|
+}
|
|
720
|
+
|
631
|
721
|
/**
|
632
|
722
|
* Probe IPoIB device
|
633
|
723
|
*
|
|
@@ -652,6 +742,11 @@ int ipoib_probe ( struct ib_device *ibdev ) {
|
652
|
742
|
ipoib->netdev = netdev;
|
653
|
743
|
ipoib->ibdev = ibdev;
|
654
|
744
|
|
|
745
|
+ /* Calculate broadcast GID */
|
|
746
|
+ memcpy ( &ipoib->broadcast_gid, &ipv4_broadcast_gid,
|
|
747
|
+ sizeof ( ipoib->broadcast_gid ) );
|
|
748
|
+ ipoib->broadcast_gid.u.words[2] = htons ( ibdev->pkey );
|
|
749
|
+
|
655
|
750
|
/* Allocate metadata queue set */
|
656
|
751
|
if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
|
657
|
752
|
IPOIB_META_NUM_CQES,
|
|
@@ -663,6 +758,8 @@ int ipoib_probe ( struct ib_device *ibdev ) {
|
663
|
758
|
goto err_create_meta_qset;
|
664
|
759
|
}
|
665
|
760
|
|
|
761
|
+
|
|
762
|
+
|
666
|
763
|
/* Allocate data queue set */
|
667
|
764
|
if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
|
668
|
765
|
IPOIB_DATA_NUM_CQES,
|