Browse Source

Unicasts seem to be working. :)

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
ab191e45db
3 changed files with 129 additions and 42 deletions
  1. 111
    30
      src/drivers/net/ipoib.c
  2. 7
    7
      src/drivers/net/mlx_ipoib/mt25218.c
  3. 11
    5
      src/include/gpxe/infiniband.h

+ 111
- 30
src/drivers/net/ipoib.c View File

86
 	struct ipoib_queue_set meta;
86
 	struct ipoib_queue_set meta;
87
 };
87
 };
88
 
88
 
89
+/**
90
+ * IPoIB path cache entry
91
+ *
92
+ * This serves a similar role to the ARP cache for Ethernet.  (ARP
93
+ * *is* used on IPoIB; we have two caches to maintain.)
94
+ */
95
+struct ipoib_cached_path {
96
+	/** Destination GID */
97
+	struct ib_gid gid;
98
+	/** Destination LID */
99
+	unsigned int dlid;
100
+	/** Service level */
101
+	unsigned int sl;
102
+	/** Rate */
103
+	unsigned int rate;
104
+};
105
+
106
+/** Number of IPoIB path cache entries */
107
+#define IPOIB_NUM_CACHED_PATHS 2
108
+
109
+/** IPoIB path cache */
110
+static struct ipoib_cached_path ipoib_path_cache[IPOIB_NUM_CACHED_PATHS];
111
+
112
+/** Oldest IPoIB path cache entry index */
113
+static unsigned int ipoib_path_cache_idx = 0;
114
+
89
 /****************************************************************************
115
 /****************************************************************************
90
  *
116
  *
91
  * IPoIB link layer
117
  * IPoIB link layer
165
  * @ret string	Link-layer address in human-readable format
191
  * @ret string	Link-layer address in human-readable format
166
  */
192
  */
167
 const char * ipoib_ntoa ( const void *ll_addr ) {
193
 const char * ipoib_ntoa ( const void *ll_addr ) {
168
-	static char buf[61];
169
-	const uint8_t *ipoib_addr = ll_addr;
170
-	unsigned int i;
171
-	char *p = buf;
172
-
173
-	for ( i = 0 ; i < IPOIB_ALEN ; i++ ) {
174
-		p += sprintf ( p, ":%02x", ipoib_addr[i] );
175
-	}
176
-	return ( buf + 1 );
194
+	static char buf[45];
195
+	const struct ipoib_mac *mac = ll_addr;
196
+
197
+	snprintf ( buf, sizeof ( buf ), "%08lx:%08lx:%08lx:%08lx:%08lx",
198
+		   htonl ( mac->qpn ), htonl ( mac->gid.u.dwords[0] ),
199
+		   htonl ( mac->gid.u.dwords[1] ),
200
+		   htonl ( mac->gid.u.dwords[2] ),
201
+		   htonl ( mac->gid.u.dwords[3] ) );
202
+	return buf;
177
 }
203
 }
178
 
204
 
179
 /** IPoIB protocol */
205
 /** IPoIB protocol */
258
 	return rc;
284
 	return rc;
259
 }
285
 }
260
 
286
 
287
+/**
288
+ * Find path cache entry by GID
289
+ *
290
+ * @v gid		GID
291
+ * @ret entry		Path cache entry, or NULL
292
+ */
293
+static struct ipoib_cached_path *
294
+ipoib_find_cached_path ( struct ib_gid *gid ) {
295
+	struct ipoib_cached_path *path;
296
+	unsigned int i;
297
+
298
+	for ( i = 0 ; i < IPOIB_NUM_CACHED_PATHS ; i++ ) {
299
+		path = &ipoib_path_cache[i];
300
+		if ( memcmp ( &path->gid, gid, sizeof ( *gid ) ) == 0 )
301
+			return path;
302
+	}
303
+	DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx cache miss\n",
304
+	      htonl ( gid->u.dwords[0] ), htonl ( gid->u.dwords[1] ),
305
+	      htonl ( gid->u.dwords[2] ), htonl ( gid->u.dwords[3] ) );
306
+	return NULL;
307
+}
308
+
261
 /**
309
 /**
262
  * Transmit path record request
310
  * Transmit path record request
263
  *
311
  *
274
  	static uint32_t tid = 0;
322
  	static uint32_t tid = 0;
275
 	int rc;
323
 	int rc;
276
 
324
 
277
-#if 0
278
-	DBG ( "get_path_record():\n" );
279
 	int get_path_record(struct ib_gid *dgid, uint16_t *dlid_p,
325
 	int get_path_record(struct ib_gid *dgid, uint16_t *dlid_p,
280
 			    uint8_t *sl_p, uint8_t *rate_p);
326
 			    uint8_t *sl_p, uint8_t *rate_p);
281
 	uint16_t tmp_dlid;
327
 	uint16_t tmp_dlid;
282
 	uint8_t tmp_sl;
328
 	uint8_t tmp_sl;
283
 	uint8_t tmp_rate;
329
 	uint8_t tmp_rate;
284
 	get_path_record ( gid, &tmp_dlid, &tmp_sl, &tmp_rate );
330
 	get_path_record ( gid, &tmp_dlid, &tmp_sl, &tmp_rate );
331
+	DBG ( "get_path_record() gives dlid = %04x, sl = %02x, rate = %02x\n",
332
+	      tmp_dlid, tmp_sl, tmp_rate );
285
 
333
 
286
-	DBG ( "ipoib_get_path_record():\n" );
287
-#endif
288
 
334
 
289
 	/* Allocate I/O buffer */
335
 	/* Allocate I/O buffer */
290
 	iobuf = alloc_iob ( sizeof ( *path_record ) );
336
 	iobuf = alloc_iob ( sizeof ( *path_record ) );
307
 	memcpy ( &path_record->sgid, &ibdev->port_gid,
353
 	memcpy ( &path_record->sgid, &ibdev->port_gid,
308
 		 sizeof ( path_record->sgid ) );
354
 		 sizeof ( path_record->sgid ) );
309
 
355
 
310
-	//	DBG_HD ( path_record, sizeof ( *path_record ) );
311
-
312
 	/* Construct address vector */
356
 	/* Construct address vector */
313
 	memset ( &av, 0, sizeof ( av ) );
357
 	memset ( &av, 0, sizeof ( av ) );
314
 	av.dlid = ibdev->sm_lid;
358
 	av.dlid = ibdev->sm_lid;
315
 	av.dest_qp = IB_SA_QPN;
359
 	av.dest_qp = IB_SA_QPN;
316
-	av.qkey = IB_SA_QKEY;
360
+	av.qkey = IB_GLOBAL_QKEY;
317
 
361
 
318
 	/* Post send request */
362
 	/* Post send request */
319
 	if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
363
 	if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
339
 	struct ipoib_device *ipoib = netdev->priv;
383
 	struct ipoib_device *ipoib = netdev->priv;
340
 	struct ib_device *ibdev = ipoib->ibdev;
384
 	struct ib_device *ibdev = ipoib->ibdev;
341
 	struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
385
 	struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
386
+	struct ib_address_vector av;
387
+	struct ipoib_cached_path *path;
342
 	int rc;
388
 	int rc;
343
 
389
 
344
 	if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
390
 	if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
346
 		return -EINVAL;
392
 		return -EINVAL;
347
 	}
393
 	}
348
 
394
 
349
-	DBG ( "TX pseudo-header:\n" );
350
-	DBG_HD ( ipoib_pshdr, sizeof ( *ipoib_pshdr ) );
351
-	if ( ipoib_pshdr->peer.qpn != htonl ( IPOIB_BROADCAST_QPN ) ) {
352
-		DBG ( "Get path record\n" );
353
-		rc = ipoib_get_path_record ( ipoib, &ipoib_pshdr->peer.gid );
354
-		free_iob ( iobuf );
355
-		return 0;
395
+	/* Construct address vector */
396
+	memset ( &av, 0, sizeof ( av ) );
397
+	if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
398
+		/* Broadcast address */
399
+		memcpy ( &av, &hack_ipoib_bcast_av, sizeof ( av ) );
400
+	} else {
401
+		/* Unicast - look in path cache */
402
+		path = ipoib_find_cached_path ( &ipoib_pshdr->peer.gid );
403
+		if ( ! path ) {
404
+			/* No path entry - get path record */
405
+			rc = ipoib_get_path_record ( ipoib,
406
+						     &ipoib_pshdr->peer.gid );
407
+			free_iob ( iobuf );
408
+			return rc;
409
+		}
410
+		av.dest_qp = ntohl ( ipoib_pshdr->peer.qpn );
411
+		av.qkey = IB_GLOBAL_QKEY;
412
+		av.dlid = path->dlid;
413
+		av.rate = path->rate;
414
+		av.sl = path->sl;
415
+		av.gid_present = 1;
416
+		memcpy ( &av.gid, &ipoib_pshdr->peer.gid, sizeof ( av.gid ) );
356
 	}
417
 	}
357
 
418
 
358
 	iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
419
 	iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
359
-	return ib_post_send ( ibdev, ipoib->data.qp,
360
-			      &hack_ipoib_bcast_av, iobuf );
420
+	return ib_post_send ( ibdev, ipoib->data.qp, &av, iobuf );
361
 }
421
 }
362
 
422
 
363
 /**
423
 /**
392
 				       struct io_buffer *iobuf ) {
452
 				       struct io_buffer *iobuf ) {
393
 	struct net_device *netdev = qp->owner_priv;
453
 	struct net_device *netdev = qp->owner_priv;
394
 	struct ipoib_device *ipoib = netdev->priv;
454
 	struct ipoib_device *ipoib = netdev->priv;
395
-	struct ib_global_route_header *grh = iobuf->data;
396
 	struct ipoib_pseudo_hdr *ipoib_pshdr;
455
 	struct ipoib_pseudo_hdr *ipoib_pshdr;
397
 
456
 
398
 	if ( completion->syndrome ) {
457
 	if ( completion->syndrome ) {
399
 		netdev_rx_err ( netdev, iobuf, -EIO );
458
 		netdev_rx_err ( netdev, iobuf, -EIO );
400
 	} else {
459
 	} else {
401
 		iob_put ( iobuf, completion->len );
460
 		iob_put ( iobuf, completion->len );
402
-		iob_pull ( iobuf, ( sizeof ( *grh ) -
461
+		iob_pull ( iobuf, ( sizeof ( struct ib_global_route_header ) -
403
 				    sizeof ( *ipoib_pshdr ) ) );
462
 				    sizeof ( *ipoib_pshdr ) ) );
404
 		/* FIXME: fill in a MAC address for the sake of AoE! */
463
 		/* FIXME: fill in a MAC address for the sake of AoE! */
405
 		netdev_rx ( netdev, iobuf );
464
 		netdev_rx ( netdev, iobuf );
444
 				       struct io_buffer *iobuf ) {
503
 				       struct io_buffer *iobuf ) {
445
 	struct net_device *netdev = qp->owner_priv;
504
 	struct net_device *netdev = qp->owner_priv;
446
 	struct ipoib_device *ipoib = netdev->priv;
505
 	struct ipoib_device *ipoib = netdev->priv;
447
-
448
-	DBG ( "***************** META RX!!!!!! ********\n" );
506
+	struct ib_mad_path_record *path_record;
507
+	struct ipoib_cached_path *path;
449
 
508
 
450
 	if ( completion->syndrome ) {
509
 	if ( completion->syndrome ) {
451
 		DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
510
 		DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
452
 		       ipoib, completion->syndrome );
511
 		       ipoib, completion->syndrome );
453
 	} else {
512
 	} else {
513
+		/* Update path cache */
454
 		iob_put ( iobuf, completion->len );
514
 		iob_put ( iobuf, completion->len );
515
+		iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
516
+
455
 		DBG ( "Metadata RX:\n" );
517
 		DBG ( "Metadata RX:\n" );
456
 		DBG_HD ( iobuf->data, iob_len ( iobuf ) );
518
 		DBG_HD ( iobuf->data, iob_len ( iobuf ) );
519
+
520
+		path_record = iobuf->data;
521
+		path = &ipoib_path_cache[ipoib_path_cache_idx];
522
+		memcpy ( &path->gid, &path_record->dgid,
523
+			 sizeof ( path->gid ) );
524
+		path->dlid = ntohs ( path_record->dlid );
525
+		path->sl = ( path_record->reserved__sl & 0x0f );
526
+		path->rate = ( path_record->rate_selector__rate & 0x3f );
527
+		DBG ( "IPoIB %08lx:%08lx:%08lx:%08lx dlid %x sl %x rate %x\n",
528
+		      htonl ( path->gid.u.dwords[0] ),
529
+		      htonl ( path->gid.u.dwords[1] ),
530
+		      htonl ( path->gid.u.dwords[2] ),
531
+		      htonl ( path->gid.u.dwords[3] ),
532
+		      path->dlid, path->sl, path->rate );
533
+
534
+		/* Update path cache index */
535
+		ipoib_path_cache_idx++;
536
+		if ( ipoib_path_cache_idx == IPOIB_NUM_CACHED_PATHS )
537
+			ipoib_path_cache_idx = 0;
457
 	}
538
 	}
458
 
539
 
459
 	ipoib->meta.recv_fill--;
540
 	ipoib->meta.recv_fill--;
590
 					IPOIB_META_NUM_CQES,
671
 					IPOIB_META_NUM_CQES,
591
 					IPOIB_META_NUM_SEND_WQES,
672
 					IPOIB_META_NUM_SEND_WQES,
592
 					IPOIB_META_NUM_RECV_WQES,
673
 					IPOIB_META_NUM_RECV_WQES,
593
-					IB_SA_QKEY ) ) != 0 ) {
674
+					IB_GLOBAL_QKEY ) ) != 0 ) {
594
 		DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
675
 		DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
595
 		       ipoib, strerror ( rc ) );
676
 		       ipoib, strerror ( rc ) );
596
 		goto err_create_meta_qset;
677
 		goto err_create_meta_qset;

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

749
 
749
 
750
 /** GID used for GID-less send work queue entries */
750
 /** GID used for GID-less send work queue entries */
751
 static const struct ib_gid arbel_no_gid = {
751
 static const struct ib_gid arbel_no_gid = {
752
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }
752
+	{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 } }
753
 };
753
 };
754
 
754
 
755
 /**
755
 /**
1238
 	/* Port info gives us the first half of the port GID */
1238
 	/* Port info gives us the first half of the port GID */
1239
 	if ( ( rc = arbel_get_port_info ( arbel, &u.port_info ) ) != 0 )
1239
 	if ( ( rc = arbel_get_port_info ( arbel, &u.port_info ) ) != 0 )
1240
 		return rc;
1240
 		return rc;
1241
-	memcpy ( &port_gid->bytes[0], u.port_info.gid_prefix, 8 );
1242
-
1241
+	memcpy ( &port_gid->u.bytes[0], u.port_info.gid_prefix, 8 );
1242
+	
1243
 	/* GUID info gives us the second half of the port GID */
1243
 	/* GUID info gives us the second half of the port GID */
1244
 	if ( ( rc = arbel_get_guid_info ( arbel, &u.guid_info ) ) != 0 )
1244
 	if ( ( rc = arbel_get_guid_info ( arbel, &u.guid_info ) ) != 0 )
1245
 		return rc;
1245
 		return rc;
1246
-	memcpy ( &port_gid->bytes[8], u.guid_info.gid_local, 8 );
1246
+	memcpy ( &port_gid->u.bytes[8], u.guid_info.gid_local, 8 );
1247
 
1247
 
1248
 	return 0;
1248
 	return 0;
1249
 }
1249
 }
1262
 static int arbel_get_broadcast_gid ( struct arbel *arbel,
1262
 static int arbel_get_broadcast_gid ( struct arbel *arbel,
1263
 				     struct ib_gid *broadcast_gid ) {
1263
 				     struct ib_gid *broadcast_gid ) {
1264
 	static const struct ib_gid ipv4_broadcast_gid = {
1264
 	static const struct ib_gid ipv4_broadcast_gid = {
1265
-		{ 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
1266
-		  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }
1265
+		{ { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
1266
+		    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff } }
1267
 	};
1267
 	};
1268
 	struct ib_mad_pkey_table pkey_table;
1268
 	struct ib_mad_pkey_table pkey_table;
1269
 	int rc;
1269
 	int rc;
1275
 	/* Add partition key */
1275
 	/* Add partition key */
1276
 	if ( ( rc = arbel_get_pkey_table ( arbel, &pkey_table ) ) != 0 )
1276
 	if ( ( rc = arbel_get_pkey_table ( arbel, &pkey_table ) ) != 0 )
1277
 		return rc;
1277
 		return rc;
1278
-	memcpy ( &broadcast_gid->bytes[4], &pkey_table.pkey[0][0],
1278
+	memcpy ( &broadcast_gid->u.bytes[4], &pkey_table.pkey[0][0],
1279
 		 sizeof ( pkey_table.pkey[0][0] ) );
1279
 		 sizeof ( pkey_table.pkey[0][0] ) );
1280
 
1280
 
1281
 	return 0;
1281
 	return 0;

+ 11
- 5
src/include/gpxe/infiniband.h View File

14
 #define IB_SA_QPN	1
14
 #define IB_SA_QPN	1
15
 
15
 
16
 /** Subnet administrator queue key */
16
 /** Subnet administrator queue key */
17
-#define IB_SA_QKEY	0x80010000UL
17
+#define IB_GLOBAL_QKEY	0x80010000UL
18
 
18
 
19
 /** An Infiniband Global Identifier */
19
 /** An Infiniband Global Identifier */
20
 struct ib_gid {
20
 struct ib_gid {
21
-	uint8_t bytes[16];
21
+	union {
22
+		uint8_t bytes[16];
23
+		uint32_t dwords[4];
24
+	} u;
22
 };
25
 };
23
 
26
 
24
 /** An Infiniband Global Route Header */
27
 /** An Infiniband Global Route Header */
136
 	/** Destination Queue Pair */
139
 	/** Destination Queue Pair */
137
 	unsigned int dest_qp;
140
 	unsigned int dest_qp;
138
 	/** Queue key */
141
 	/** Queue key */
139
-	unsigned int qkey;
142
+	unsigned long qkey;
140
 	/** Destination Local ID */
143
 	/** Destination Local ID */
141
 	unsigned int dlid;
144
 	unsigned int dlid;
142
 	/** Rate */
145
 	/** Rate */
530
 	uint16_t slid;
533
 	uint16_t slid;
531
 	uint32_t hop_limit__flow_label__raw_traffic;
534
 	uint32_t hop_limit__flow_label__raw_traffic;
532
 	uint32_t pkey__numb_path__reversible__tclass;
535
 	uint32_t pkey__numb_path__reversible__tclass;
533
-	uint32_t rate__rate_selector__mtu__mtu_selector__sl__reserved;
536
+	uint8_t reserved1;
537
+	uint8_t reserved__sl;
538
+	uint8_t mtu_selector__mtu;
539
+	uint8_t rate_selector__rate;
534
 	uint32_t preference__packet_lifetime__packet_lifetime_selector;
540
 	uint32_t preference__packet_lifetime__packet_lifetime_selector;
535
-	uint32_t reserved1[35];
541
+	uint32_t reserved2[35];
536
 } __attribute__ (( packed ));
542
 } __attribute__ (( packed ));
537
 
543
 
538
 union ib_mad {
544
 union ib_mad {

Loading…
Cancel
Save