Browse Source

Some interesting packet corruption happening now.

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
bdac591726
3 changed files with 188 additions and 46 deletions
  1. 180
    43
      src/drivers/net/ipoib.c
  2. 1
    0
      src/drivers/net/mlx_ipoib/mt25218.c
  3. 7
    3
      src/include/gpxe/infiniband.h

+ 180
- 43
src/drivers/net/ipoib.c View File

@@ -18,9 +18,11 @@
18 18
 
19 19
 #include <stdint.h>
20 20
 #include <stdio.h>
21
+#include <unistd.h>
21 22
 #include <string.h>
22 23
 #include <byteswap.h>
23 24
 #include <errno.h>
25
+#include "timer.h"
24 26
 #include <gpxe/if_arp.h>
25 27
 #include <gpxe/iobuf.h>
26 28
 #include <gpxe/netdevice.h>
@@ -86,6 +88,12 @@ struct ipoib_device {
86 88
 	struct ipoib_queue_set meta;
87 89
 	/** Broadcast GID */
88 90
 	struct ib_gid broadcast_gid;
91
+	/** Broadcast LID */
92
+	unsigned int broadcast_lid;
93
+	/** Joined to broadcast group */
94
+	int broadcast_joined;
95
+	/** Data queue key */
96
+	unsigned long data_qkey;
89 97
 };
90 98
 
91 99
 /**
@@ -114,6 +122,12 @@ static struct ipoib_cached_path ipoib_path_cache[IPOIB_NUM_CACHED_PATHS];
114 122
 /** Oldest IPoIB path cache entry index */
115 123
 static unsigned int ipoib_path_cache_idx = 0;
116 124
 
125
+/** TID half used to identify get path record replies */
126
+#define IPOIB_TID_GET_PATH_REC 0x11111111UL
127
+
128
+/** TID half used to identify multicast member record replies */
129
+#define IPOIB_TID_MC_MEMBER_REC 0x22222222UL
130
+
117 131
 /** IPoIB metadata TID */
118 132
 static uint32_t ipoib_meta_tid = 0;
119 133
 
@@ -123,6 +137,9 @@ static const struct ib_gid ipv4_broadcast_gid = {
123 137
 	    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff } }
124 138
 };
125 139
 
140
+/** Maximum time we will wait for the broadcast join to succeed */
141
+#define IPOIB_JOIN_MAX_DELAY_MS 1000
142
+
126 143
 /****************************************************************************
127 144
  *
128 145
  * IPoIB link layer
@@ -181,8 +198,8 @@ static int ipoib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
181 198
 
182 199
 	/* Sanity check */
183 200
 	if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
184
-		DBG ( "IPoIB packet too short (%d bytes)\n",
185
-		      iob_len ( iobuf ) );
201
+		DBG ( "IPoIB packet too short for link-layer header\n" );
202
+		DBG_HD ( iobuf->data, iob_len ( iobuf ) );
186 203
 		free_iob ( iobuf );
187 204
 		return -EINVAL;
188 205
 	}
@@ -346,7 +363,8 @@ static int ipoib_get_path_record ( struct ipoib_device *ipoib,
346 363
 	path_record->mad_hdr.class_version = 2;
347 364
 	path_record->mad_hdr.method = IB_MGMT_METHOD_GET;
348 365
 	path_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
349
-	path_record->mad_hdr.tid = ipoib_meta_tid++;
366
+	path_record->mad_hdr.tid[0] = IPOIB_TID_GET_PATH_REC;
367
+	path_record->mad_hdr.tid[1] = ipoib_meta_tid++;
350 368
 	path_record->sa_hdr.comp_mask[1] =
351 369
 		htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
352 370
 	memcpy ( &path_record->dgid, gid, sizeof ( path_record->dgid ) );
@@ -402,7 +420,8 @@ static int ipoib_mc_member_record ( struct ipoib_device *ipoib,
402 420
 	mc_member_record->mad_hdr.method = 
403 421
 		( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
404 422
 	mc_member_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
405
-	mc_member_record->mad_hdr.tid = ipoib_meta_tid++;
423
+	mc_member_record->mad_hdr.tid[0] = IPOIB_TID_MC_MEMBER_REC;
424
+	mc_member_record->mad_hdr.tid[1] = ipoib_meta_tid++;
406 425
 	mc_member_record->sa_hdr.comp_mask[1] =
407 426
 		htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
408 427
 			IB_SA_MCMEMBER_REC_JOIN_STATE );
@@ -443,19 +462,29 @@ static int ipoib_transmit ( struct net_device *netdev,
443 462
 	struct ib_device *ibdev = ipoib->ibdev;
444 463
 	struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
445 464
 	struct ib_address_vector av;
465
+	struct ib_gid *gid;
446 466
 	struct ipoib_cached_path *path;
447 467
 	int rc;
448 468
 
469
+	/* Sanity check */
449 470
 	if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
450 471
 		DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
451 472
 		return -EINVAL;
452 473
 	}
474
+	iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
453 475
 
454 476
 	/* Construct address vector */
455 477
 	memset ( &av, 0, sizeof ( av ) );
478
+	av.qkey = IB_GLOBAL_QKEY;
479
+	av.gid_present = 1;
456 480
 	if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
457 481
 		/* Broadcast address */
482
+#if 0
458 483
 		memcpy ( &av, &hack_ipoib_bcast_av, sizeof ( av ) );
484
+#endif
485
+		av.dest_qp = IB_BROADCAST_QPN;
486
+		av.dlid = ipoib->broadcast_lid;
487
+		gid = &ipoib->broadcast_gid;
459 488
 	} else {
460 489
 		/* Unicast - look in path cache */
461 490
 		path = ipoib_find_cached_path ( &ipoib_pshdr->peer.gid );
@@ -467,15 +496,13 @@ static int ipoib_transmit ( struct net_device *netdev,
467 496
 			return rc;
468 497
 		}
469 498
 		av.dest_qp = ntohl ( ipoib_pshdr->peer.qpn );
470
-		av.qkey = IB_GLOBAL_QKEY;
471 499
 		av.dlid = path->dlid;
472 500
 		av.rate = path->rate;
473 501
 		av.sl = path->sl;
474
-		av.gid_present = 1;
475
-		memcpy ( &av.gid, &ipoib_pshdr->peer.gid, sizeof ( av.gid ) );
502
+		gid = &ipoib_pshdr->peer.gid;
476 503
 	}
504
+	memcpy ( &av.gid, gid, sizeof ( av.gid ) );
477 505
 
478
-	iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
479 506
 	return ib_post_send ( ibdev, ipoib->data.qp, &av, iobuf );
480 507
 }
481 508
 
@@ -515,14 +542,33 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
515 542
 
516 543
 	if ( completion->syndrome ) {
517 544
 		netdev_rx_err ( netdev, iobuf, -EIO );
518
-	} else {
519
-		iob_put ( iobuf, completion->len );
520
-		iob_pull ( iobuf, ( sizeof ( struct ib_global_route_header ) -
521
-				    sizeof ( *ipoib_pshdr ) ) );
522
-		/* FIXME: fill in a MAC address for the sake of AoE! */
523
-		netdev_rx ( netdev, iobuf );
545
+		goto done;
546
+	}
547
+
548
+	iob_put ( iobuf, completion->len );
549
+	if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
550
+		DBGC ( ipoib, "IPoIB %p received data packet too short to "
551
+		       "contain GRH\n", ipoib );
552
+		DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
553
+		netdev_rx_err ( netdev, iobuf, -EIO );
554
+		goto done;
555
+	}
556
+	iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
557
+
558
+	if ( iob_len ( iobuf ) < sizeof ( struct ipoib_real_hdr ) ) {
559
+		DBGC ( ipoib, "IPoIB %p received data packet too short to "
560
+		       "contain IPoIB header\n", ipoib );
561
+		DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
562
+		netdev_rx_err ( netdev, iobuf, -EIO );
563
+		goto done;
524 564
 	}
525 565
 
566
+	ipoib_pshdr = iob_push ( iobuf, sizeof ( *ipoib_pshdr ) );
567
+	/* FIXME: fill in a MAC address for the sake of AoE! */
568
+
569
+	netdev_rx ( netdev, iobuf );
570
+
571
+ done:
526 572
 	ipoib->data.recv_fill--;
527 573
 }
528 574
 
@@ -548,6 +594,52 @@ static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
548 594
 	free_iob ( iobuf );
549 595
 }
550 596
 
597
+/**
598
+ * Handle received IPoIB path record
599
+ *
600
+ * @v ipoib		IPoIB device
601
+ * @v path_record	Path record
602
+ */
603
+static void ipoib_recv_path_record ( struct ipoib_device *ipoib __unused,
604
+				     struct ib_mad_path_record *path_record ) {
605
+	struct ipoib_cached_path *path;
606
+
607
+	/* Update path cache entry */
608
+	path = &ipoib_path_cache[ipoib_path_cache_idx];
609
+	memcpy ( &path->gid, &path_record->dgid, sizeof ( path->gid ) );
610
+	path->dlid = ntohs ( path_record->dlid );
611
+	path->sl = ( path_record->reserved__sl & 0x0f );
612
+	path->rate = ( path_record->rate_selector__rate & 0x3f );
613
+
614
+	DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx dlid %x sl %x rate %x\n",
615
+	      htonl ( path->gid.u.dwords[0] ), htonl ( path->gid.u.dwords[1] ),
616
+	      htonl ( path->gid.u.dwords[2] ), htonl ( path->gid.u.dwords[3] ),
617
+	      path->dlid, path->sl, path->rate );
618
+	
619
+	/* Update path cache index */
620
+	ipoib_path_cache_idx++;
621
+	if ( ipoib_path_cache_idx == IPOIB_NUM_CACHED_PATHS )
622
+		ipoib_path_cache_idx = 0;
623
+}
624
+
625
+/**
626
+ * Handle received IPoIB multicast membership record
627
+ *
628
+ * @v ipoib		IPoIB device
629
+ * @v mc_member_record	Multicast membership record
630
+ */
631
+static void ipoib_recv_mc_member_record ( struct ipoib_device *ipoib,
632
+			  struct ib_mad_mc_member_record *mc_member_record ) {
633
+	/* Record parameters */
634
+	ipoib->broadcast_joined =
635
+		( mc_member_record->scope__join_state & 0x0f );
636
+	ipoib->data_qkey = ntohl ( mc_member_record->qkey );
637
+	ipoib->broadcast_lid = ntohs ( mc_member_record->mlid );
638
+	DBGC ( ipoib, "IPoIB %p %s broadcast group: qkey %lx mlid %x\n",
639
+	       ipoib, ( ipoib->broadcast_joined ? "joined" : "left" ),
640
+	       ipoib->data_qkey, ipoib->broadcast_lid );
641
+}
642
+
551 643
 /**
552 644
  * Handle IPoIB metadata receive completion
553 645
  *
@@ -562,36 +654,51 @@ static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
562 654
 				       struct io_buffer *iobuf ) {
563 655
 	struct net_device *netdev = qp->owner_priv;
564 656
 	struct ipoib_device *ipoib = netdev->priv;
565
-	struct ib_mad_path_record *path_record;
566
-	struct ipoib_cached_path *path;
657
+	union ib_mad *mad;
567 658
 
568 659
 	if ( completion->syndrome ) {
569 660
 		DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
570 661
 		       ipoib, completion->syndrome );
571
-	} else {
572
-		/* Update path cache */
573
-		iob_put ( iobuf, completion->len );
574
-		iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
575
-		path_record = iobuf->data;
576
-		path = &ipoib_path_cache[ipoib_path_cache_idx];
577
-		memcpy ( &path->gid, &path_record->dgid,
578
-			 sizeof ( path->gid ) );
579
-		path->dlid = ntohs ( path_record->dlid );
580
-		path->sl = ( path_record->reserved__sl & 0x0f );
581
-		path->rate = ( path_record->rate_selector__rate & 0x3f );
582
-		DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx dlid %x sl %x rate %x\n",
583
-		      htonl ( path->gid.u.dwords[0] ),
584
-		      htonl ( path->gid.u.dwords[1] ),
585
-		      htonl ( path->gid.u.dwords[2] ),
586
-		      htonl ( path->gid.u.dwords[3] ),
587
-		      path->dlid, path->sl, path->rate );
588
-
589
-		/* Update path cache index */
590
-		ipoib_path_cache_idx++;
591
-		if ( ipoib_path_cache_idx == IPOIB_NUM_CACHED_PATHS )
592
-			ipoib_path_cache_idx = 0;
662
+		goto done;
663
+	}
664
+
665
+	iob_put ( iobuf, completion->len );
666
+	if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
667
+		DBGC ( ipoib, "IPoIB %p received metadata packet too short "
668
+		       "to contain GRH\n", ipoib );
669
+		DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
670
+		goto done;
671
+	}
672
+	iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
673
+	if ( iob_len ( iobuf ) < sizeof ( *mad ) ) {
674
+		DBGC ( ipoib, "IPoIB %p received metadata packet too short "
675
+		       "to contain reply\n", ipoib );
676
+		DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
677
+		goto done;
678
+	}
679
+	mad = iobuf->data;
680
+
681
+	if ( mad->mad_hdr.status != 0 ) {
682
+		DBGC ( ipoib, "IPoIB %p metadata RX err status %04x\n",
683
+		       ipoib, ntohs ( mad->mad_hdr.status ) );
684
+		goto done;
685
+	}
686
+
687
+	switch ( mad->mad_hdr.tid[0] ) {
688
+	case IPOIB_TID_GET_PATH_REC:
689
+		ipoib_recv_path_record ( ipoib, &mad->path_record );
690
+		break;
691
+	case IPOIB_TID_MC_MEMBER_REC:
692
+		ipoib_recv_mc_member_record ( ipoib, &mad->mc_member_record );
693
+		break;
694
+	default:
695
+		DBGC ( ipoib, "IPoIB %p unwanted response:\n",
696
+		       ipoib );
697
+		DBGC_HD ( ipoib, mad, sizeof ( *mad ) );
698
+		break;
593 699
 	}
594 700
 
701
+ done:
595 702
 	ipoib->meta.recv_fill--;
596 703
 	free_iob ( iobuf );
597 704
 }
@@ -628,10 +735,10 @@ static void ipoib_poll ( struct net_device *netdev ) {
628 735
 	struct ipoib_device *ipoib = netdev->priv;
629 736
 	struct ib_device *ibdev = ipoib->ibdev;
630 737
 
631
-	ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
632
-		     ipoib_data_complete_recv );
633 738
 	ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
634 739
 		     ipoib_meta_complete_recv );
740
+	ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
741
+		     ipoib_data_complete_recv );
635 742
 	ipoib_refill_recv ( ipoib, &ipoib->meta );
636 743
 	ipoib_refill_recv ( ipoib, &ipoib->data );
637 744
 }
@@ -703,9 +810,14 @@ static struct net_device_operations ipoib_operations = {
703 810
  * @v ipoib		IPoIB device
704 811
  * @ret rc		Return status code
705 812
  */
706
-int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
813
+static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
814
+	struct ib_device *ibdev = ipoib->ibdev;
815
+	unsigned int delay_ms;
707 816
 	int rc;
708 817
 
818
+	/* Make sure we have some receive descriptors */
819
+	ipoib_refill_recv ( ipoib, &ipoib->meta );
820
+
709 821
 	/* Send join request */
710 822
 	if ( ( rc = ipoib_mc_member_record ( ipoib, &ipoib->broadcast_gid,
711 823
 					     1 ) ) != 0 ) {
@@ -714,8 +826,23 @@ int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
714 826
 		return rc;
715 827
 	}
716 828
 
829
+	/* Wait for join to complete.  Ideally we wouldn't delay for
830
+	 * this long, but we need the queue key before we can set up
831
+	 * the data queue pair, which we need before we can know the
832
+	 * MAC address.
833
+	 */
834
+	for ( delay_ms = IPOIB_JOIN_MAX_DELAY_MS ; delay_ms ; delay_ms-- ) {
835
+		mdelay ( 1 );
836
+		ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
837
+			     ipoib_meta_complete_recv );
838
+		ipoib_refill_recv ( ipoib, &ipoib->meta );
839
+		if ( ipoib->broadcast_joined )
840
+			return 0;
841
+	}
842
+	DBGC ( ipoib, "IPoIB %p timed out waiting for broadcast join\n",
843
+	       ipoib );
717 844
 
718
-	return 0;
845
+	return -ETIMEDOUT;
719 846
 }
720 847
 
721 848
 /**
@@ -758,14 +885,23 @@ int ipoib_probe ( struct ib_device *ibdev ) {
758 885
 		goto err_create_meta_qset;
759 886
 	}
760 887
 
888
+#if 0
889
+	ipoib->data_qkey = hack_ipoib_qkey;
890
+#endif
761 891
 
892
+	/* Join broadcast group */
893
+	if ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) {
894
+		DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
895
+		       ipoib, strerror ( rc ) );
896
+		goto err_join_broadcast_group;
897
+	}
762 898
 
763 899
 	/* Allocate data queue set */
764 900
 	if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
765 901
 					IPOIB_DATA_NUM_CQES,
766 902
 					IPOIB_DATA_NUM_SEND_WQES,
767 903
 					IPOIB_DATA_NUM_RECV_WQES,
768
-					hack_ipoib_qkey ) ) != 0 ) {
904
+					ipoib->data_qkey ) ) != 0 ) {
769 905
 		DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
770 906
 		       ipoib, strerror ( rc ) );
771 907
 		goto err_create_data_qset;
@@ -784,6 +920,7 @@ int ipoib_probe ( struct ib_device *ibdev ) {
784 920
 
785 921
  err_register_netdev:
786 922
 	ipoib_destroy_qset ( ipoib, &ipoib->data );
923
+ err_join_broadcast_group:
787 924
  err_create_data_qset:
788 925
 	ipoib_destroy_qset ( ipoib, &ipoib->meta );
789 926
  err_create_meta_qset:

+ 1
- 0
src/drivers/net/mlx_ipoib/mt25218.c View File

@@ -975,6 +975,7 @@ static int arbel_complete ( struct ib_device *ibdev,
975 975
  */
976 976
 static void arbel_drain_eq ( struct arbel *arbel ) {
977 977
 #warning "drain the event queue"
978
+	drain_eq();
978 979
 }
979 980
 
980 981
 /**

+ 7
- 3
src/include/gpxe/infiniband.h View File

@@ -11,10 +11,13 @@
11 11
 #include <gpxe/device.h>
12 12
 
13 13
 /** Subnet administrator QPN */
14
-#define IB_SA_QPN	1
14
+#define IB_SA_QPN 1
15
+
16
+/** Broadcast QPN */
17
+#define IB_BROADCAST_QPN 0xffffffUL
15 18
 
16 19
 /** Subnet administrator queue key */
17
-#define IB_GLOBAL_QKEY	0x80010000UL
20
+#define IB_GLOBAL_QKEY 0x80010000UL
18 21
 
19 22
 /** An Infiniband Global Identifier */
20 23
 struct ib_gid {
@@ -466,7 +469,7 @@ struct ib_mad_hdr {
466 469
 	uint8_t method;
467 470
 	uint16_t status;
468 471
 	uint16_t class_specific;
469
-	uint64_t tid;
472
+	uint32_t tid[2];
470 473
 	uint16_t attr_id;
471 474
 	uint16_t resv;
472 475
 	uint32_t attr_mod;
@@ -569,6 +572,7 @@ union ib_mad {
569 572
 	struct ib_mad_port_info port_info;
570 573
 	struct ib_mad_pkey_table pkey_table;
571 574
 	struct ib_mad_path_record path_record;
575
+	struct ib_mad_mc_member_record mc_member_record;
572 576
 } __attribute__ (( packed ));
573 577
 
574 578
 #endif /* _GPXE_INFINIBAND_H */

Loading…
Cancel
Save