Переглянути джерело

[Hermon] Fix event queue doorbells.

Event queue doorbells must use UAR pages 0-127 depending on event queue
number; other doorbells must use pages 128+ (and we choose to use page
128).
tags/v0.9.4
Michael Brown 16 роки тому
джерело
коміт
e55bab3ce3
2 змінених файлів з 60 додано та 24 видалено
  1. 47
    19
      src/drivers/infiniband/hermon.c
  2. 13
    5
      src/drivers/infiniband/hermon.h

+ 47
- 19
src/drivers/infiniband/hermon.c Переглянути файл

@@ -344,6 +344,15 @@ hermon_cmd_hw2sw_eq ( struct hermon *hermon, unsigned int index,
344 344
 			    1, NULL, index, eqctx );
345 345
 }
346 346
 
347
+static inline int
348
+hermon_cmd_query_eq ( struct hermon *hermon, unsigned int index,
349
+		      struct hermonprm_eqc *eqctx ) {
350
+	return hermon_cmd ( hermon,
351
+			    HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_EQ,
352
+						 1, sizeof ( *eqctx ) ),
353
+			    0, NULL, index, eqctx );
354
+}
355
+
347 356
 static inline int
348 357
 hermon_cmd_sw2hw_cq ( struct hermon *hermon, unsigned long cqn,
349 358
 		      const struct hermonprm_completion_queue_context *cqctx ){
@@ -667,7 +676,7 @@ static int hermon_create_cq ( struct ib_device *ibdev,
667 676
 	MLX_FILL_1 ( &cqctx, 2,
668 677
 		     page_offset, ( hermon_cq->mtt.page_offset >> 5 ) );
669 678
 	MLX_FILL_2 ( &cqctx, 3,
670
-		     usr_page, HERMON_UAR_PAGE,
679
+		     usr_page, HERMON_UAR_NON_EQ_PAGE,
671 680
 		     log_cq_size, fls ( cq->num_cqes - 1 ) );
672 681
 	MLX_FILL_1 ( &cqctx, 7, mtt_base_addr_l,
673 682
 		     ( hermon_cq->mtt.mtt_base_addr >> 3 ) );
@@ -773,6 +782,11 @@ static int hermon_create_qp ( struct ib_device *ibdev,
773 782
 		goto err_hermon_qp;
774 783
 	}
775 784
 
785
+	/* Calculate doorbell address */
786
+	hermon_qp->send.doorbell =
787
+		( hermon->uar + HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE +
788
+		  HERMON_DB_POST_SND_OFFSET );
789
+
776 790
 	/* Allocate work queue buffer */
777 791
 	hermon_qp->send.num_wqes = ( qp->send.num_wqes /* headroom */ + 1 +
778 792
 				( 2048 / sizeof ( hermon_qp->send.wqe[0] ) ) );
@@ -817,7 +831,7 @@ static int hermon_create_qp ( struct ib_device *ibdev,
817 831
 		     qpc_eec_data.log_sq_stride,
818 832
 		     ( fls ( sizeof ( hermon_qp->send.wqe[0] ) - 1 ) - 4 ) );
819 833
 	MLX_FILL_1 ( &qpctx, 5,
820
-		     qpc_eec_data.usr_page, HERMON_UAR_PAGE );
834
+		     qpc_eec_data.usr_page, HERMON_UAR_NON_EQ_PAGE );
821 835
 	MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
822 836
 	MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.page_offset,
823 837
 		     ( hermon_qp->mtt.page_offset >> 6 ) );
@@ -1029,9 +1043,8 @@ static int hermon_post_send ( struct ib_device *ibdev,
1029 1043
 	/* Ring doorbell register */
1030 1044
 	MLX_FILL_1 ( &db_reg.send, 0, qn, qp->qpn );
1031 1045
 	DBGCP ( hermon, "Ringing doorbell %08lx with %08lx\n",
1032
-		virt_to_phys ( hermon->uar + HERMON_DB_POST_SND_OFFSET ),
1033
-		db_reg.dword[0] );
1034
-	writel ( db_reg.dword[0], ( hermon->uar + HERMON_DB_POST_SND_OFFSET ));
1046
+		virt_to_phys ( hermon_send_wq->doorbell ), db_reg.dword[0] );
1047
+	writel ( db_reg.dword[0], ( hermon_send_wq->doorbell ) );
1035 1048
 
1036 1049
 	/* Update work queue's index */
1037 1050
 	wq->next_idx++;
@@ -1209,7 +1222,7 @@ static void hermon_poll_cq ( struct ib_device *ibdev,
1209 1222
 
1210 1223
 		/* Update doorbell record */
1211 1224
 		MLX_FILL_1 ( &hermon_cq->doorbell, 0, update_ci,
1212
-			     ( cq->next_idx & 0xffffffUL ) );
1225
+			     ( cq->next_idx & 0x00ffffffUL ) );
1213 1226
 	}
1214 1227
 }
1215 1228
 
@@ -1442,6 +1455,15 @@ static int hermon_create_eq ( struct hermon *hermon ) {
1442 1455
 	unsigned int i;
1443 1456
 	int rc;
1444 1457
 
1458
+	/* Select event queue number */
1459
+	hermon_eq->eqn = ( 4 * hermon->cap.reserved_uars );
1460
+	if ( hermon_eq->eqn < hermon->cap.reserved_eqs )
1461
+		hermon_eq->eqn = hermon->cap.reserved_eqs;
1462
+
1463
+	/* Calculate doorbell address */
1464
+	hermon_eq->doorbell =
1465
+		( hermon->uar + HERMON_DB_EQ_OFFSET ( hermon_eq->eqn ) );
1466
+
1445 1467
 	/* Allocate event queue itself */
1446 1468
 	hermon_eq->eqe_size =
1447 1469
 		( HERMON_NUM_EQES * sizeof ( hermon_eq->eqe[0] ) );
@@ -1471,7 +1493,8 @@ static int hermon_create_eq ( struct hermon *hermon ) {
1471 1493
 	MLX_FILL_1 ( &eqctx, 3, log_eq_size, fls ( HERMON_NUM_EQES - 1 ) );
1472 1494
 	MLX_FILL_1 ( &eqctx, 7, mtt_base_addr_l,
1473 1495
 		     ( hermon_eq->mtt.mtt_base_addr >> 3 ) );
1474
-	if ( ( rc = hermon_cmd_sw2hw_eq ( hermon, 0, &eqctx ) ) != 0 ) {
1496
+	if ( ( rc = hermon_cmd_sw2hw_eq ( hermon, hermon_eq->eqn,
1497
+					  &eqctx ) ) != 0 ) {
1475 1498
 		DBGC ( hermon, "Hermon %p SW2HW_EQ failed: %s\n",
1476 1499
 		       hermon, strerror ( rc ) );
1477 1500
 		goto err_sw2hw_eq;
@@ -1480,17 +1503,21 @@ static int hermon_create_eq ( struct hermon *hermon ) {
1480 1503
 	/* Map events to this event queue */
1481 1504
 	memset ( &mask, 0, sizeof ( mask ) );
1482 1505
 	MLX_FILL_1 ( &mask, 1, port_state_change, 1 );
1483
-	if ( ( rc = hermon_cmd_map_eq ( hermon, ( HERMON_MAP_EQ_MAP | 0 ),
1506
+	if ( ( rc = hermon_cmd_map_eq ( hermon,
1507
+					( HERMON_MAP_EQ | hermon_eq->eqn ),
1484 1508
 					&mask ) ) != 0 ) {
1485 1509
 		DBGC ( hermon, "Hermon %p MAP_EQ failed: %s\n",
1486 1510
 		       hermon, strerror ( rc )  );
1487 1511
 		goto err_map_eq;
1488 1512
 	}
1489 1513
 
1514
+	DBGC ( hermon, "Hermon %p EQN %#lx ring at [%p,%p])\n",
1515
+	       hermon, hermon_eq->eqn, hermon_eq->eqe,
1516
+	       ( ( ( void * ) hermon_eq->eqe ) + hermon_eq->eqe_size ) );
1490 1517
 	return 0;
1491 1518
 
1492 1519
  err_map_eq:
1493
-	hermon_cmd_hw2sw_eq ( hermon, 0, &eqctx );
1520
+	hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn, &eqctx );
1494 1521
  err_sw2hw_eq:
1495 1522
 	hermon_free_mtt ( hermon, &hermon_eq->mtt );
1496 1523
  err_alloc_mtt:
@@ -1514,7 +1541,8 @@ static void hermon_destroy_eq ( struct hermon *hermon ) {
1514 1541
 	/* Unmap events from event queue */
1515 1542
 	memset ( &mask, 0, sizeof ( mask ) );
1516 1543
 	MLX_FILL_1 ( &mask, 1, port_state_change, 1 );
1517
-	if ( ( rc = hermon_cmd_map_eq ( hermon, ( HERMON_MAP_EQ_UNMAP | 0 ),
1544
+	if ( ( rc = hermon_cmd_map_eq ( hermon,
1545
+					( HERMON_UNMAP_EQ | hermon_eq->eqn ),
1518 1546
 					&mask ) ) != 0 ) {
1519 1547
 		DBGC ( hermon, "Hermon %p FATAL MAP_EQ failed to unmap: %s\n",
1520 1548
 		       hermon, strerror ( rc ) );
@@ -1522,7 +1550,8 @@ static void hermon_destroy_eq ( struct hermon *hermon ) {
1522 1550
 	}
1523 1551
 
1524 1552
 	/* Take ownership back from hardware */
1525
-	if ( ( rc = hermon_cmd_hw2sw_eq ( hermon, 0, &eqctx ) ) != 0 ) {
1553
+	if ( ( rc = hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn,
1554
+					  &eqctx ) ) != 0 ) {
1526 1555
 		DBGC ( hermon, "Hermon %p FATAL HW2SW_EQ failed: %s\n",
1527 1556
 		       hermon, strerror ( rc ) );
1528 1557
 		/* Leak memory and return; at least we avoid corruption */
@@ -1578,6 +1607,7 @@ static void hermon_poll_eq ( struct hermon *hermon ) {
1578 1607
 	unsigned int event_type;
1579 1608
 
1580 1609
 	while ( 1 ) {
1610
+		/* Look for event entry */
1581 1611
 		eqe_idx_mask = ( HERMON_NUM_EQES - 1 );
1582 1612
 		eqe = &hermon_eq->eqe[hermon_eq->next_idx & eqe_idx_mask];
1583 1613
 		if ( MLX_GET ( &eqe->generic, owner ) ^
@@ -1605,13 +1635,12 @@ static void hermon_poll_eq ( struct hermon *hermon ) {
1605 1635
 		hermon_eq->next_idx++;
1606 1636
 
1607 1637
 		/* Ring doorbell */
1608
-		memset ( &db_reg, 0, sizeof ( db_reg ) );
1609
-		MLX_FILL_1 ( &db_reg.event, 0, ci, hermon_eq->next_idx );
1638
+		MLX_FILL_1 ( &db_reg.event, 0,
1639
+			     ci, ( hermon_eq->next_idx & 0x00ffffffUL ) );
1610 1640
 		DBGCP ( hermon, "Ringing doorbell %08lx with %08lx\n",
1611
-			virt_to_phys ( hermon->uar + HERMON_DB_EQ0_OFFSET ),
1641
+			virt_to_phys ( hermon_eq->doorbell ),
1612 1642
 			db_reg.dword[0] );
1613
-		writel ( db_reg.dword[0],
1614
-			 ( hermon->uar + HERMON_DB_EQ0_OFFSET ) );
1643
+		writel ( db_reg.dword[0], hermon_eq->doorbell );
1615 1644
 	}
1616 1645
 }
1617 1646
 
@@ -2161,9 +2190,8 @@ static int hermon_probe ( struct pci_device *pci,
2161 2190
 	/* Get PCI BARs */
2162 2191
 	hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
2163 2192
 				   HERMON_PCI_CONFIG_BAR_SIZE );
2164
-	hermon->uar = ioremap ( ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ) +
2165
-				  HERMON_UAR_PAGE * HERMON_PAGE_SIZE ),
2166
-				HERMON_PAGE_SIZE );
2193
+	hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
2194
+				HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
2167 2195
 
2168 2196
 	/* Allocate space for mailboxes */
2169 2197
 	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,

+ 13
- 5
src/drivers/infiniband/hermon.h Переглянути файл

@@ -44,6 +44,7 @@
44 44
 #define HERMON_HCR_MAP_EQ		0x0012
45 45
 #define HERMON_HCR_SW2HW_EQ		0x0013
46 46
 #define HERMON_HCR_HW2SW_EQ		0x0014
47
+#define HERMON_HCR_QUERY_EQ		0x0015
47 48
 #define HERMON_HCR_SW2HW_CQ		0x0016
48 49
 #define HERMON_HCR_HW2SW_CQ		0x0017
49 50
 #define HERMON_HCR_RST2INIT_QP		0x0019
@@ -77,12 +78,13 @@
77 78
 #define HERMON_PAGE_SIZE		4096
78 79
 
79 80
 #define HERMON_DB_POST_SND_OFFSET	0x14
80
-#define HERMON_DB_EQ0_OFFSET		0x800
81
+#define HERMON_DB_EQ_OFFSET(_eqn)	\
82
+	( 0x800 + HERMON_PAGE_SIZE * ( (_eqn) / 4 ) + 0x08 * ( (_eqn) % 4 ) )
81 83
 
82 84
 #define HERMON_QP_OPT_PARAM_QKEY	0x00000020UL
83 85
 
84
-#define HERMON_MAP_EQ_MAP		( 0UL << 31 )
85
-#define HERMON_MAP_EQ_UNMAP		( 1UL << 31 )
86
+#define HERMON_MAP_EQ			( 0UL << 31 )
87
+#define HERMON_UNMAP_EQ			( 1UL << 31 )
86 88
 
87 89
 #define HERMON_EV_PORT_STATE_CHANGE	0x09
88 90
 
@@ -292,7 +294,7 @@ enum hermon_icm_map_regions {
292 294
  * Pages 0-127 are reserved for event queue doorbells only, so we use
293 295
  * page 128.
294 296
  */
295
-#define HERMON_UAR_PAGE		128
297
+#define HERMON_UAR_NON_EQ_PAGE	128
296 298
 
297 299
 /** Maximum number of allocatable MTT entries
298 300
  *
@@ -334,6 +336,8 @@ struct hermon_send_work_queue {
334 336
 	union hermon_send_wqe *wqe;
335 337
 	/** Size of work queue */
336 338
 	size_t wqe_size;
339
+	/** Doorbell register */
340
+	void *doorbell;
337 341
 };
338 342
 
339 343
 /** Alignment of Hermon receive work queue entries */
@@ -400,7 +404,7 @@ struct hermon_completion_queue {
400 404
  *
401 405
  * This is a policy decision, not a device limit.
402 406
  */
403
-#define HERMON_MAX_EQS		4
407
+#define HERMON_MAX_EQS		8
404 408
 
405 409
 /** A Hermon event queue */
406 410
 struct hermon_event_queue {
@@ -410,8 +414,12 @@ struct hermon_event_queue {
410 414
 	size_t eqe_size;
411 415
 	/** MTT descriptor */
412 416
 	struct hermon_mtt mtt;
417
+	/** Event queue number */
418
+	unsigned long eqn;
413 419
 	/** Next event queue entry index */
414 420
 	unsigned long next_idx;
421
+	/** Doorbell register */
422
+	void *doorbell;
415 423
 };
416 424
 
417 425
 /** Number of event queue entries

Завантаження…
Відмінити
Зберегти