|
@@ -44,15 +44,24 @@ extern struct ib_address_vector hack_ipoib_bcast_av;
|
44
|
44
|
/** IPoIB MTU */
|
45
|
45
|
#define IPOIB_MTU 2048
|
46
|
46
|
|
47
|
|
-/** Number of IPoIB send work queue entries */
|
|
47
|
+/** Number of IPoIB data send work queue entries */
|
48
|
48
|
#define IPOIB_DATA_NUM_SEND_WQES 4
|
49
|
49
|
|
50
|
|
-/** Number of IPoIB receive work queue entries */
|
51
|
|
-#define IPOIB_DATA_NUM_RECV_WQES 8
|
|
50
|
+/** Number of IPoIB data receive work queue entries */
|
|
51
|
+#define IPOIB_DATA_NUM_RECV_WQES 4
|
52
|
52
|
|
53
|
|
-/** Number of IPoIB completion entries */
|
|
53
|
+/** Number of IPoIB data completion entries */
|
54
|
54
|
#define IPOIB_DATA_NUM_CQES 8
|
55
|
55
|
|
|
56
|
+/** Number of IPoIB metadata send work queue entries */
|
|
57
|
+#define IPOIB_META_NUM_SEND_WQES 4
|
|
58
|
+
|
|
59
|
+/** Number of IPoIB metadata receive work queue entries */
|
|
60
|
+#define IPOIB_META_NUM_RECV_WQES 4
|
|
61
|
+
|
|
62
|
+/** Number of IPoIB metadata completion entries */
|
|
63
|
+#define IPOIB_META_NUM_CQES 8
|
|
64
|
+
|
56
|
65
|
/** An IPoIB queue set */
|
57
|
66
|
struct ipoib_queue_set {
|
58
|
67
|
/** Completion queue */
|
|
@@ -84,10 +93,15 @@ struct ipoib_device {
|
84
|
93
|
****************************************************************************
|
85
|
94
|
*/
|
86
|
95
|
|
|
96
|
+/** Broadcast QPN used in IPoIB MAC addresses
|
|
97
|
+ *
|
|
98
|
+ * This is a guaranteed invalid real QPN
|
|
99
|
+ */
|
|
100
|
+#define IPOIB_BROADCAST_QPN 0xffffffffUL
|
|
101
|
+
|
87
|
102
|
/** Broadcast IPoIB address */
|
88
|
103
|
static struct ipoib_mac ipoib_broadcast = {
|
89
|
|
- .gid = { { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
|
90
|
|
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff } },
|
|
104
|
+ .qpn = ntohl ( IPOIB_BROADCAST_QPN ),
|
91
|
105
|
};
|
92
|
106
|
|
93
|
107
|
/**
|
|
@@ -244,6 +258,73 @@ static int ipoib_create_qset ( struct ipoib_device *ipoib,
|
244
|
258
|
return rc;
|
245
|
259
|
}
|
246
|
260
|
|
|
261
|
+/**
|
|
262
|
+ * Transmit path record request
|
|
263
|
+ *
|
|
264
|
+ * @v ipoib IPoIB device
|
|
265
|
+ * @v gid Destination GID
|
|
266
|
+ * @ret rc Return status code
|
|
267
|
+ */
|
|
268
|
+static int ipoib_get_path_record ( struct ipoib_device *ipoib,
|
|
269
|
+ struct ib_gid *gid ) {
|
|
270
|
+ struct ib_device *ibdev = ipoib->ibdev;
|
|
271
|
+ struct io_buffer *iobuf;
|
|
272
|
+ struct ib_mad_path_record *path_record;
|
|
273
|
+ struct ib_address_vector av;
|
|
274
|
+ static uint32_t tid = 0;
|
|
275
|
+ int rc;
|
|
276
|
+
|
|
277
|
+ DBG ( "get_path_record():\n" );
|
|
278
|
+ int get_path_record(struct ib_gid *dgid, uint16_t *dlid_p,
|
|
279
|
+ uint8_t *sl_p, uint8_t *rate_p);
|
|
280
|
+ uint16_t tmp_dlid;
|
|
281
|
+ uint8_t tmp_sl;
|
|
282
|
+ uint8_t tmp_rate;
|
|
283
|
+ get_path_record ( gid, &tmp_dlid, &tmp_sl, &tmp_rate );
|
|
284
|
+
|
|
285
|
+ DBG ( "ipoib_get_path_record():\n" );
|
|
286
|
+
|
|
287
|
+ /* Allocate I/O buffer */
|
|
288
|
+ iobuf = alloc_iob ( sizeof ( *path_record ) );
|
|
289
|
+ if ( ! iobuf )
|
|
290
|
+ return -ENOMEM;
|
|
291
|
+ iob_put ( iobuf, sizeof ( *path_record ) );
|
|
292
|
+ path_record = iobuf->data;
|
|
293
|
+ memset ( path_record, 0, sizeof ( *path_record ) );
|
|
294
|
+
|
|
295
|
+ /* Construct path record request */
|
|
296
|
+ path_record->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
|
|
297
|
+ path_record->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
|
|
298
|
+ path_record->mad_hdr.class_version = 2;
|
|
299
|
+ path_record->mad_hdr.method = IB_MGMT_METHOD_GET;
|
|
300
|
+ path_record->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
|
|
301
|
+ path_record->mad_hdr.tid = tid++;
|
|
302
|
+ path_record->sa_hdr.comp_mask[1] =
|
|
303
|
+ htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
|
|
304
|
+ memcpy ( &path_record->dgid, gid, sizeof ( path_record->dgid ) );
|
|
305
|
+ memcpy ( &path_record->sgid, &ibdev->port_gid,
|
|
306
|
+ sizeof ( path_record->sgid ) );
|
|
307
|
+
|
|
308
|
+ DBG_HD ( path_record, sizeof ( *path_record ) );
|
|
309
|
+
|
|
310
|
+ /* Construct address vector */
|
|
311
|
+ memset ( &av, 0, sizeof ( av ) );
|
|
312
|
+ av.dlid = ibdev->sm_lid;
|
|
313
|
+ av.dest_qp = IB_SA_QPN;
|
|
314
|
+ av.qkey = IB_SA_QKEY;
|
|
315
|
+
|
|
316
|
+ /* Post send request */
|
|
317
|
+ if ( ( rc = ib_post_send ( ibdev, ipoib->meta.qp, &av,
|
|
318
|
+ iobuf ) ) != 0 ) {
|
|
319
|
+ DBGC ( ipoib, "IPoIB %p could not send get path record: %s\n",
|
|
320
|
+ ipoib, strerror ( rc ) );
|
|
321
|
+ free_iob ( iobuf );
|
|
322
|
+ return rc;
|
|
323
|
+ }
|
|
324
|
+
|
|
325
|
+ return 0;
|
|
326
|
+}
|
|
327
|
+
|
247
|
328
|
/**
|
248
|
329
|
* Transmit packet via IPoIB network device
|
249
|
330
|
*
|
|
@@ -256,19 +337,29 @@ static int ipoib_transmit ( struct net_device *netdev,
|
256
|
337
|
struct ipoib_device *ipoib = netdev->priv;
|
257
|
338
|
struct ib_device *ibdev = ipoib->ibdev;
|
258
|
339
|
struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
|
|
340
|
+ int rc;
|
259
|
341
|
|
260
|
342
|
if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
|
261
|
343
|
DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
|
262
|
344
|
return -EINVAL;
|
263
|
345
|
}
|
264
|
346
|
|
|
347
|
+ DBG ( "TX pseudo-header:\n" );
|
|
348
|
+ DBG_HD ( ipoib_pshdr, sizeof ( *ipoib_pshdr ) );
|
|
349
|
+ if ( ipoib_pshdr->peer.qpn != htonl ( IPOIB_BROADCAST_QPN ) ) {
|
|
350
|
+ DBG ( "Get path record\n" );
|
|
351
|
+ rc = ipoib_get_path_record ( ipoib, &ipoib_pshdr->peer.gid );
|
|
352
|
+ free_iob ( iobuf );
|
|
353
|
+ return 0;
|
|
354
|
+ }
|
|
355
|
+
|
265
|
356
|
iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
|
266
|
357
|
return ib_post_send ( ibdev, ipoib->data.qp,
|
267
|
358
|
&hack_ipoib_bcast_av, iobuf );
|
268
|
359
|
}
|
269
|
360
|
|
270
|
361
|
/**
|
271
|
|
- * Handle IPoIB send completion
|
|
362
|
+ * Handle IPoIB data send completion
|
272
|
363
|
*
|
273
|
364
|
* @v ibdev Infiniband device
|
274
|
365
|
* @v qp Queue pair
|
|
@@ -286,7 +377,7 @@ static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
|
286
|
377
|
}
|
287
|
378
|
|
288
|
379
|
/**
|
289
|
|
- * Handle IPoIB receive completion
|
|
380
|
+ * Handle IPoIB data receive completion
|
290
|
381
|
*
|
291
|
382
|
* @v ibdev Infiniband device
|
292
|
383
|
* @v qp Queue pair
|
|
@@ -315,6 +406,61 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
315
|
406
|
ipoib->data.recv_fill--;
|
316
|
407
|
}
|
317
|
408
|
|
|
409
|
+/**
|
|
410
|
+ * Handle IPoIB metadata send completion
|
|
411
|
+ *
|
|
412
|
+ * @v ibdev Infiniband device
|
|
413
|
+ * @v qp Queue pair
|
|
414
|
+ * @v completion Completion
|
|
415
|
+ * @v iobuf I/O buffer
|
|
416
|
+ */
|
|
417
|
+static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
|
|
418
|
+ struct ib_queue_pair *qp,
|
|
419
|
+ struct ib_completion *completion,
|
|
420
|
+ struct io_buffer *iobuf ) {
|
|
421
|
+ struct net_device *netdev = qp->owner_priv;
|
|
422
|
+ struct ipoib_device *ipoib = netdev->priv;
|
|
423
|
+
|
|
424
|
+ DBG ( "Woohoo! METADATA TX completion\n" );
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+ if ( completion->syndrome ) {
|
|
428
|
+ DBGC ( ipoib, "IPoIB %p metadata TX completion error %x\n",
|
|
429
|
+ ipoib, completion->syndrome );
|
|
430
|
+ }
|
|
431
|
+ free_iob ( iobuf );
|
|
432
|
+}
|
|
433
|
+
|
|
434
|
+/**
|
|
435
|
+ * Handle IPoIB metadata receive completion
|
|
436
|
+ *
|
|
437
|
+ * @v ibdev Infiniband device
|
|
438
|
+ * @v qp Queue pair
|
|
439
|
+ * @v completion Completion
|
|
440
|
+ * @v iobuf I/O buffer
|
|
441
|
+ */
|
|
442
|
+static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
|
|
443
|
+ struct ib_queue_pair *qp,
|
|
444
|
+ struct ib_completion *completion,
|
|
445
|
+ struct io_buffer *iobuf ) {
|
|
446
|
+ struct net_device *netdev = qp->owner_priv;
|
|
447
|
+ struct ipoib_device *ipoib = netdev->priv;
|
|
448
|
+
|
|
449
|
+ DBG ( "***************** META TX!!!!!! ********\n" );
|
|
450
|
+
|
|
451
|
+ if ( completion->syndrome ) {
|
|
452
|
+ DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
|
|
453
|
+ ipoib, completion->syndrome );
|
|
454
|
+ } else {
|
|
455
|
+ iob_put ( iobuf, completion->len );
|
|
456
|
+ DBG ( "Metadata RX:\n" );
|
|
457
|
+ DBG_HD ( iobuf->data, iob_len ( iobuf ) );
|
|
458
|
+ }
|
|
459
|
+
|
|
460
|
+ ipoib->meta.recv_fill--;
|
|
461
|
+ free_iob ( iobuf );
|
|
462
|
+}
|
|
463
|
+
|
318
|
464
|
/**
|
319
|
465
|
* Refill IPoIB receive ring
|
320
|
466
|
*
|
|
@@ -349,6 +495,9 @@ static void ipoib_poll ( struct net_device *netdev ) {
|
349
|
495
|
|
350
|
496
|
ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
|
351
|
497
|
ipoib_data_complete_recv );
|
|
498
|
+ ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
|
|
499
|
+ ipoib_meta_complete_recv );
|
|
500
|
+ ipoib_refill_recv ( ipoib, &ipoib->meta );
|
352
|
501
|
ipoib_refill_recv ( ipoib, &ipoib->data );
|
353
|
502
|
}
|
354
|
503
|
|
|
@@ -382,7 +531,8 @@ static int ipoib_open ( struct net_device *netdev ) {
|
382
|
531
|
return rc;
|
383
|
532
|
}
|
384
|
533
|
|
385
|
|
- /* Fill receive ring */
|
|
534
|
+ /* Fill receive rings */
|
|
535
|
+ ipoib_refill_recv ( ipoib, &ipoib->meta );
|
386
|
536
|
ipoib_refill_recv ( ipoib, &ipoib->data );
|
387
|
537
|
|
388
|
538
|
return 0;
|
|
@@ -436,6 +586,17 @@ int ipoib_probe ( struct ib_device *ibdev ) {
|
436
|
586
|
ipoib->netdev = netdev;
|
437
|
587
|
ipoib->ibdev = ibdev;
|
438
|
588
|
|
|
589
|
+ /* Allocate metadata queue set */
|
|
590
|
+ if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
|
|
591
|
+ IPOIB_META_NUM_CQES,
|
|
592
|
+ IPOIB_META_NUM_SEND_WQES,
|
|
593
|
+ IPOIB_META_NUM_RECV_WQES,
|
|
594
|
+ IB_SA_QKEY ) ) != 0 ) {
|
|
595
|
+ DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
|
|
596
|
+ ipoib, strerror ( rc ) );
|
|
597
|
+ goto err_create_meta_qset;
|
|
598
|
+ }
|
|
599
|
+
|
439
|
600
|
/* Allocate data queue set */
|
440
|
601
|
if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
|
441
|
602
|
IPOIB_DATA_NUM_CQES,
|
|
@@ -461,6 +622,8 @@ int ipoib_probe ( struct ib_device *ibdev ) {
|
461
|
622
|
err_register_netdev:
|
462
|
623
|
ipoib_destroy_qset ( ipoib, &ipoib->data );
|
463
|
624
|
err_create_data_qset:
|
|
625
|
+ ipoib_destroy_qset ( ipoib, &ipoib->meta );
|
|
626
|
+ err_create_meta_qset:
|
464
|
627
|
netdev_nullify ( netdev );
|
465
|
628
|
netdev_put ( netdev );
|
466
|
629
|
return rc;
|