Procházet zdrojové kódy

Multicast join now works.

tags/v0.9.3
Michael Brown před 17 roky
rodič
revize
3c6a6bdc5d

+ 21
- 4
src/drivers/net/mlx_ipoib/arbel.h Zobrazit soubor

@@ -33,6 +33,9 @@
33 33
 #define ARBEL_HCR_INIT2RTR_QPEE		0x001a
34 34
 #define ARBEL_HCR_RTR2RTS_QPEE		0x001b
35 35
 #define ARBEL_HCR_2RST_QPEE		0x0021
36
+#define ARBEL_HCR_READ_MGM		0x0025
37
+#define ARBEL_HCR_WRITE_MGM		0x0026
38
+#define ARBEL_HCR_MGID_HASH		0x0027
36 39
 
37 40
 /* Service types */
38 41
 #define ARBEL_ST_UD			0x03
@@ -42,6 +45,17 @@
42 45
 
43 46
 #define ARBEL_INVALID_LKEY		0x00000100UL
44 47
 
48
+/*
49
+ * Datatypes that seem to be missing from the autogenerated documentation
50
+ *
51
+ */
52
+struct arbelprm_mgm_hash_st {
53
+	pseudo_bit_t reserved0[0x00020];
54
+/* -------------- */
55
+	pseudo_bit_t hash[0x00010];
56
+	pseudo_bit_t reserved1[0x00010];
57
+};
58
+
45 59
 /*
46 60
  * Wrapper structures for hardware datatypes
47 61
  *
@@ -53,6 +67,8 @@ struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
53 67
 struct MLX_DECLARE_STRUCT ( arbelprm_cq_arm_db_record );
54 68
 struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
55 69
 struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
70
+struct MLX_DECLARE_STRUCT ( arbelprm_mgm_entry );
71
+struct MLX_DECLARE_STRUCT ( arbelprm_mgm_hash );
56 72
 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
57 73
 struct MLX_DECLARE_STRUCT ( arbelprm_qp_ee_state_transitions );
58 74
 struct MLX_DECLARE_STRUCT ( arbelprm_query_dev_lim );
@@ -266,7 +282,8 @@ struct arbel {
266 282
 #define ARBEL_HCR_OUT_LEN( _command )	( ( (_command) >> 21 ) & 0x7fc )
267 283
 
268 284
 /** Build HCR command from component parts */
269
-#define ARBEL_HCR_CMD( _opcode, _in_mbox, _in_len, _out_mbox, _out_len )     \
285
+#define ARBEL_HCR_INOUT_CMD( _opcode, _in_mbox, _in_len,		     \
286
+			     _out_mbox, _out_len )			     \
270 287
 	( (_opcode) |							     \
271 288
 	  ( (_in_mbox) ? ARBEL_HCR_IN_MBOX : 0 ) |			     \
272 289
 	  ( ( (_in_len) / 4 ) << 14 ) |					     \
@@ -274,13 +291,13 @@ struct arbel {
274 291
 	  ( ( (_out_len) / 4 ) << 23 ) )
275 292
 
276 293
 #define ARBEL_HCR_IN_CMD( _opcode, _in_mbox, _in_len )			     \
277
-	ARBEL_HCR_CMD ( _opcode, _in_mbox, _in_len, 0, 0 )
294
+	ARBEL_HCR_INOUT_CMD ( _opcode, _in_mbox, _in_len, 0, 0 )
278 295
 
279 296
 #define ARBEL_HCR_OUT_CMD( _opcode, _out_mbox, _out_len )		     \
280
-	ARBEL_HCR_CMD ( _opcode, 0, 0, _out_mbox, _out_len )
297
+	ARBEL_HCR_INOUT_CMD ( _opcode, 0, 0, _out_mbox, _out_len )
281 298
 
282 299
 #define ARBEL_HCR_VOID_CMD( _opcode )					     \
283
-	ARBEL_HCR_CMD ( _opcode, 0, 0, 0, 0 )
300
+	ARBEL_HCR_INOUT_CMD ( _opcode, 0, 0, 0, 0 )
284 301
 
285 302
 /*
286 303
  * Doorbell record allocation

+ 136
- 0
src/drivers/net/mlx_ipoib/mt25218.c Zobrazit soubor

@@ -549,6 +549,34 @@ arbel_cmd_2rst_qpee ( struct arbel *arbel, unsigned long qpn ) {
549 549
 			   0x03, NULL, qpn, NULL );
550 550
 }
551 551
 
552
+static inline int
553
+arbel_cmd_read_mgm ( struct arbel *arbel, unsigned int index,
554
+		     struct arbelprm_mgm_entry *mgm ) {
555
+	return arbel_cmd ( arbel,
556
+			   ARBEL_HCR_OUT_CMD ( ARBEL_HCR_READ_MGM,
557
+					       1, sizeof ( *mgm ) ),
558
+			   0, NULL, index, mgm );
559
+}
560
+
561
+static inline int
562
+arbel_cmd_write_mgm ( struct arbel *arbel, unsigned int index,
563
+		      const struct arbelprm_mgm_entry *mgm ) {
564
+	return arbel_cmd ( arbel,
565
+			   ARBEL_HCR_IN_CMD ( ARBEL_HCR_WRITE_MGM,
566
+					      1, sizeof ( *mgm ) ),
567
+			   0, mgm, index, NULL );
568
+}
569
+
570
+static inline int
571
+arbel_cmd_mgid_hash ( struct arbel *arbel, const struct ib_gid *gid,
572
+		      struct arbelprm_mgm_hash *hash ) {
573
+	return arbel_cmd ( arbel,
574
+			   ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MGID_HASH,
575
+						 1, sizeof ( *gid ),
576
+						 0, sizeof ( *hash ) ),
577
+			   0, gid, 0, hash );
578
+}
579
+
552 580
 /***************************************************************************
553 581
  *
554 582
  * Completion queue operations
@@ -1253,6 +1281,104 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
1253 1281
 	}
1254 1282
 }
1255 1283
 
1284
+/***************************************************************************
1285
+ *
1286
+ * Multicast group operations
1287
+ *
1288
+ ***************************************************************************
1289
+ */
1290
+
1291
+/**
1292
+ * Attach to multicast group
1293
+ *
1294
+ * @v ibdev		Infiniband device
1295
+ * @v qp		Queue pair
1296
+ * @v gid		Multicast GID
1297
+ * @ret rc		Return status code
1298
+ */
1299
+static int arbel_mcast_attach ( struct ib_device *ibdev,
1300
+				struct ib_queue_pair *qp,
1301
+				struct ib_gid *gid ) {
1302
+	struct arbel *arbel = ibdev->dev_priv;
1303
+	struct arbelprm_mgm_hash hash;
1304
+	struct arbelprm_mgm_entry mgm;
1305
+	unsigned int index;
1306
+	int rc;
1307
+
1308
+	/* Generate hash table index */
1309
+	if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
1310
+		DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
1311
+		       arbel, strerror ( rc ) );
1312
+		return rc;
1313
+	}
1314
+	index = MLX_GET ( &hash, hash );
1315
+
1316
+	/* Check for existing hash table entry */
1317
+	if ( ( rc = arbel_cmd_read_mgm ( arbel, index, &mgm ) ) != 0 ) {
1318
+		DBGC ( arbel, "Arbel %p could not read MGM %#x: %s\n",
1319
+		       arbel, index, strerror ( rc ) );
1320
+		return rc;
1321
+	}
1322
+	if ( MLX_GET ( &mgm, mgmqp_0.qi ) != 0 ) {
1323
+		/* FIXME: this implementation allows only a single QP
1324
+		 * per multicast group, and doesn't handle hash
1325
+		 * collisions.  Sufficient for IPoIB but may need to
1326
+		 * be extended in future.
1327
+		 */
1328
+		DBGC ( arbel, "Arbel %p MGID index %#x already in use\n",
1329
+		       arbel, index );
1330
+		return -EBUSY;
1331
+	}
1332
+
1333
+	/* Update hash table entry */
1334
+	MLX_FILL_2 ( &mgm, 8,
1335
+		     mgmqp_0.qpn_i, qp->qpn,
1336
+		     mgmqp_0.qi, 1 );
1337
+	memcpy ( &mgm.u.dwords[4], gid, sizeof ( *gid ) );
1338
+	if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
1339
+		DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
1340
+		       arbel, index, strerror ( rc ) );
1341
+		return rc;
1342
+	}
1343
+
1344
+	return 0;
1345
+}
1346
+
1347
+/**
1348
+ * Detach from multicast group
1349
+ *
1350
+ * @v ibdev		Infiniband device
1351
+ * @v qp		Queue pair
1352
+ * @v gid		Multicast GID
1353
+ */
1354
+static void arbel_mcast_detach ( struct ib_device *ibdev,
1355
+				 struct ib_queue_pair *qp __unused,
1356
+				 struct ib_gid *gid ) {
1357
+	struct arbel *arbel = ibdev->dev_priv;
1358
+	struct arbelprm_mgm_hash hash;
1359
+	struct arbelprm_mgm_entry mgm;
1360
+	unsigned int index;
1361
+	int rc;
1362
+
1363
+	/* Generate hash table index */
1364
+	if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
1365
+		DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
1366
+		       arbel, strerror ( rc ) );
1367
+		return;
1368
+	}
1369
+	index = MLX_GET ( &hash, hash );
1370
+
1371
+	/* Clear hash table entry */
1372
+	memset ( &mgm, 0, sizeof ( mgm ) );
1373
+	if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
1374
+		DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
1375
+		       arbel, index, strerror ( rc ) );
1376
+		return;
1377
+	}
1378
+}
1379
+
1380
+
1381
+
1256 1382
 /** Arbel Infiniband operations */
1257 1383
 static struct ib_device_operations arbel_ib_operations = {
1258 1384
 	.create_cq	= arbel_create_cq,
@@ -1262,6 +1388,8 @@ static struct ib_device_operations arbel_ib_operations = {
1262 1388
 	.post_send	= arbel_post_send,
1263 1389
 	.post_recv	= arbel_post_recv,
1264 1390
 	.poll_cq	= arbel_poll_cq,
1391
+	.mcast_attach	= arbel_mcast_attach,
1392
+	.mcast_detach	= arbel_mcast_detach,
1265 1393
 };
1266 1394
 
1267 1395
 /**
@@ -1379,6 +1507,14 @@ static int arbel_probe ( struct pci_device *pci,
1379 1507
 		return -EIO;
1380 1508
 	}
1381 1509
 	mlx->own_qp->owner_priv = netdev;
1510
+	struct ib_gid *bcast_gid = ( struct ib_gid * ) &ib_data.bcast_gid;
1511
+	if ( ( rc = ib_mcast_attach ( ibdev, mlx->own_qp,
1512
+				      bcast_gid ) ) != 0 ) {
1513
+		DBG ( "Could not attach to broadcast GID: %s\n",
1514
+		      strerror ( rc ) );
1515
+		return rc;
1516
+	}
1517
+				      
1382 1518
 
1383 1519
 	mac = ( ( struct ib_mac * ) netdev->ll_addr );
1384 1520
 	mac->qpn = htonl ( mlx->own_qp->qpn );

+ 47
- 0
src/include/gpxe/infiniband.h Zobrazit soubor

@@ -252,6 +252,27 @@ struct ib_device_operations {
252 252
 			     struct ib_completion_queue *cq,
253 253
 			     ib_completer_t complete_send,
254 254
 			     ib_completer_t complete_recv );
255
+	/**
256
+	 * Attach to multicast group
257
+	 *
258
+	 * @v ibdev		Infiniband device
259
+	 * @v qp		Queue pair
260
+	 * @v gid		Multicast GID
261
+	 * @ret rc		Return status code
262
+	 */
263
+	int ( * mcast_attach ) ( struct ib_device *ibdev,
264
+				 struct ib_queue_pair *qp,
265
+				 struct ib_gid *gid );
266
+	/**
267
+	 * Detach from multicast group
268
+	 *
269
+	 * @v ibdev		Infiniband device
270
+	 * @v qp		Queue pair
271
+	 * @v gid		Multicast GID
272
+	 */
273
+	void ( * mcast_detach ) ( struct ib_device *ibdev,
274
+				  struct ib_queue_pair *qp,
275
+				  struct ib_gid *gid );
255 276
 };
256 277
 
257 278
 /** An Infiniband device */
@@ -275,6 +296,32 @@ extern void ib_destroy_qp ( struct ib_device *ibdev,
275 296
 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
276 297
 					   unsigned long qpn, int is_send );
277 298
 
299
+/**
300
+ * Attach to multicast group
301
+ *
302
+ * @v ibdev		Infiniband device
303
+ * @v qp		Queue pair
304
+ * @v gid		Multicast GID
305
+ * @ret rc		Return status code
306
+ */
307
+static inline __attribute__ (( always_inline )) int
308
+ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
309
+		  struct ib_gid *gid ) {
310
+	return ibdev->op->mcast_attach ( ibdev, qp, gid );
311
+}
312
+
313
+/**
314
+ * Detach from multicast group
315
+ *
316
+ * @v ibdev		Infiniband device
317
+ * @v qp		Queue pair
318
+ * @v gid		Multicast GID
319
+ */
320
+static inline __attribute__ (( always_inline )) void
321
+ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
322
+		  struct ib_gid *gid ) {
323
+	ibdev->op->mcast_detach ( ibdev, qp, gid );
324
+}
278 325
 
279 326
 
280 327
 extern struct ll_protocol infiniband_protocol;

Načítá se…
Zrušit
Uložit