Browse Source

[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 years ago
parent
commit
e55bab3ce3
2 changed files with 60 additions and 24 deletions
  1. 47
    19
      src/drivers/infiniband/hermon.c
  2. 13
    5
      src/drivers/infiniband/hermon.h

+ 47
- 19
src/drivers/infiniband/hermon.c View File

344
 			    1, NULL, index, eqctx );
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
 static inline int
356
 static inline int
348
 hermon_cmd_sw2hw_cq ( struct hermon *hermon, unsigned long cqn,
357
 hermon_cmd_sw2hw_cq ( struct hermon *hermon, unsigned long cqn,
349
 		      const struct hermonprm_completion_queue_context *cqctx ){
358
 		      const struct hermonprm_completion_queue_context *cqctx ){
667
 	MLX_FILL_1 ( &cqctx, 2,
676
 	MLX_FILL_1 ( &cqctx, 2,
668
 		     page_offset, ( hermon_cq->mtt.page_offset >> 5 ) );
677
 		     page_offset, ( hermon_cq->mtt.page_offset >> 5 ) );
669
 	MLX_FILL_2 ( &cqctx, 3,
678
 	MLX_FILL_2 ( &cqctx, 3,
670
-		     usr_page, HERMON_UAR_PAGE,
679
+		     usr_page, HERMON_UAR_NON_EQ_PAGE,
671
 		     log_cq_size, fls ( cq->num_cqes - 1 ) );
680
 		     log_cq_size, fls ( cq->num_cqes - 1 ) );
672
 	MLX_FILL_1 ( &cqctx, 7, mtt_base_addr_l,
681
 	MLX_FILL_1 ( &cqctx, 7, mtt_base_addr_l,
673
 		     ( hermon_cq->mtt.mtt_base_addr >> 3 ) );
682
 		     ( hermon_cq->mtt.mtt_base_addr >> 3 ) );
773
 		goto err_hermon_qp;
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
 	/* Allocate work queue buffer */
790
 	/* Allocate work queue buffer */
777
 	hermon_qp->send.num_wqes = ( qp->send.num_wqes /* headroom */ + 1 +
791
 	hermon_qp->send.num_wqes = ( qp->send.num_wqes /* headroom */ + 1 +
778
 				( 2048 / sizeof ( hermon_qp->send.wqe[0] ) ) );
792
 				( 2048 / sizeof ( hermon_qp->send.wqe[0] ) ) );
817
 		     qpc_eec_data.log_sq_stride,
831
 		     qpc_eec_data.log_sq_stride,
818
 		     ( fls ( sizeof ( hermon_qp->send.wqe[0] ) - 1 ) - 4 ) );
832
 		     ( fls ( sizeof ( hermon_qp->send.wqe[0] ) - 1 ) - 4 ) );
819
 	MLX_FILL_1 ( &qpctx, 5,
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
 	MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
835
 	MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
822
 	MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.page_offset,
836
 	MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.page_offset,
823
 		     ( hermon_qp->mtt.page_offset >> 6 ) );
837
 		     ( hermon_qp->mtt.page_offset >> 6 ) );
1029
 	/* Ring doorbell register */
1043
 	/* Ring doorbell register */
1030
 	MLX_FILL_1 ( &db_reg.send, 0, qn, qp->qpn );
1044
 	MLX_FILL_1 ( &db_reg.send, 0, qn, qp->qpn );
1031
 	DBGCP ( hermon, "Ringing doorbell %08lx with %08lx\n",
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
 	/* Update work queue's index */
1049
 	/* Update work queue's index */
1037
 	wq->next_idx++;
1050
 	wq->next_idx++;
1209
 
1222
 
1210
 		/* Update doorbell record */
1223
 		/* Update doorbell record */
1211
 		MLX_FILL_1 ( &hermon_cq->doorbell, 0, update_ci,
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
 	unsigned int i;
1455
 	unsigned int i;
1443
 	int rc;
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
 	/* Allocate event queue itself */
1467
 	/* Allocate event queue itself */
1446
 	hermon_eq->eqe_size =
1468
 	hermon_eq->eqe_size =
1447
 		( HERMON_NUM_EQES * sizeof ( hermon_eq->eqe[0] ) );
1469
 		( HERMON_NUM_EQES * sizeof ( hermon_eq->eqe[0] ) );
1471
 	MLX_FILL_1 ( &eqctx, 3, log_eq_size, fls ( HERMON_NUM_EQES - 1 ) );
1493
 	MLX_FILL_1 ( &eqctx, 3, log_eq_size, fls ( HERMON_NUM_EQES - 1 ) );
1472
 	MLX_FILL_1 ( &eqctx, 7, mtt_base_addr_l,
1494
 	MLX_FILL_1 ( &eqctx, 7, mtt_base_addr_l,
1473
 		     ( hermon_eq->mtt.mtt_base_addr >> 3 ) );
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
 		DBGC ( hermon, "Hermon %p SW2HW_EQ failed: %s\n",
1498
 		DBGC ( hermon, "Hermon %p SW2HW_EQ failed: %s\n",
1476
 		       hermon, strerror ( rc ) );
1499
 		       hermon, strerror ( rc ) );
1477
 		goto err_sw2hw_eq;
1500
 		goto err_sw2hw_eq;
1480
 	/* Map events to this event queue */
1503
 	/* Map events to this event queue */
1481
 	memset ( &mask, 0, sizeof ( mask ) );
1504
 	memset ( &mask, 0, sizeof ( mask ) );
1482
 	MLX_FILL_1 ( &mask, 1, port_state_change, 1 );
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
 					&mask ) ) != 0 ) {
1508
 					&mask ) ) != 0 ) {
1485
 		DBGC ( hermon, "Hermon %p MAP_EQ failed: %s\n",
1509
 		DBGC ( hermon, "Hermon %p MAP_EQ failed: %s\n",
1486
 		       hermon, strerror ( rc )  );
1510
 		       hermon, strerror ( rc )  );
1487
 		goto err_map_eq;
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
 	return 0;
1517
 	return 0;
1491
 
1518
 
1492
  err_map_eq:
1519
  err_map_eq:
1493
-	hermon_cmd_hw2sw_eq ( hermon, 0, &eqctx );
1520
+	hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn, &eqctx );
1494
  err_sw2hw_eq:
1521
  err_sw2hw_eq:
1495
 	hermon_free_mtt ( hermon, &hermon_eq->mtt );
1522
 	hermon_free_mtt ( hermon, &hermon_eq->mtt );
1496
  err_alloc_mtt:
1523
  err_alloc_mtt:
1514
 	/* Unmap events from event queue */
1541
 	/* Unmap events from event queue */
1515
 	memset ( &mask, 0, sizeof ( mask ) );
1542
 	memset ( &mask, 0, sizeof ( mask ) );
1516
 	MLX_FILL_1 ( &mask, 1, port_state_change, 1 );
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
 					&mask ) ) != 0 ) {
1546
 					&mask ) ) != 0 ) {
1519
 		DBGC ( hermon, "Hermon %p FATAL MAP_EQ failed to unmap: %s\n",
1547
 		DBGC ( hermon, "Hermon %p FATAL MAP_EQ failed to unmap: %s\n",
1520
 		       hermon, strerror ( rc ) );
1548
 		       hermon, strerror ( rc ) );
1522
 	}
1550
 	}
1523
 
1551
 
1524
 	/* Take ownership back from hardware */
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
 		DBGC ( hermon, "Hermon %p FATAL HW2SW_EQ failed: %s\n",
1555
 		DBGC ( hermon, "Hermon %p FATAL HW2SW_EQ failed: %s\n",
1527
 		       hermon, strerror ( rc ) );
1556
 		       hermon, strerror ( rc ) );
1528
 		/* Leak memory and return; at least we avoid corruption */
1557
 		/* Leak memory and return; at least we avoid corruption */
1578
 	unsigned int event_type;
1607
 	unsigned int event_type;
1579
 
1608
 
1580
 	while ( 1 ) {
1609
 	while ( 1 ) {
1610
+		/* Look for event entry */
1581
 		eqe_idx_mask = ( HERMON_NUM_EQES - 1 );
1611
 		eqe_idx_mask = ( HERMON_NUM_EQES - 1 );
1582
 		eqe = &hermon_eq->eqe[hermon_eq->next_idx & eqe_idx_mask];
1612
 		eqe = &hermon_eq->eqe[hermon_eq->next_idx & eqe_idx_mask];
1583
 		if ( MLX_GET ( &eqe->generic, owner ) ^
1613
 		if ( MLX_GET ( &eqe->generic, owner ) ^
1605
 		hermon_eq->next_idx++;
1635
 		hermon_eq->next_idx++;
1606
 
1636
 
1607
 		/* Ring doorbell */
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
 		DBGCP ( hermon, "Ringing doorbell %08lx with %08lx\n",
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
 			db_reg.dword[0] );
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
 	/* Get PCI BARs */
2190
 	/* Get PCI BARs */
2162
 	hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
2191
 	hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
2163
 				   HERMON_PCI_CONFIG_BAR_SIZE );
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
 	/* Allocate space for mailboxes */
2196
 	/* Allocate space for mailboxes */
2169
 	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
2197
 	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,

+ 13
- 5
src/drivers/infiniband/hermon.h View File

44
 #define HERMON_HCR_MAP_EQ		0x0012
44
 #define HERMON_HCR_MAP_EQ		0x0012
45
 #define HERMON_HCR_SW2HW_EQ		0x0013
45
 #define HERMON_HCR_SW2HW_EQ		0x0013
46
 #define HERMON_HCR_HW2SW_EQ		0x0014
46
 #define HERMON_HCR_HW2SW_EQ		0x0014
47
+#define HERMON_HCR_QUERY_EQ		0x0015
47
 #define HERMON_HCR_SW2HW_CQ		0x0016
48
 #define HERMON_HCR_SW2HW_CQ		0x0016
48
 #define HERMON_HCR_HW2SW_CQ		0x0017
49
 #define HERMON_HCR_HW2SW_CQ		0x0017
49
 #define HERMON_HCR_RST2INIT_QP		0x0019
50
 #define HERMON_HCR_RST2INIT_QP		0x0019
77
 #define HERMON_PAGE_SIZE		4096
78
 #define HERMON_PAGE_SIZE		4096
78
 
79
 
79
 #define HERMON_DB_POST_SND_OFFSET	0x14
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
 #define HERMON_QP_OPT_PARAM_QKEY	0x00000020UL
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
 #define HERMON_EV_PORT_STATE_CHANGE	0x09
89
 #define HERMON_EV_PORT_STATE_CHANGE	0x09
88
 
90
 
292
  * Pages 0-127 are reserved for event queue doorbells only, so we use
294
  * Pages 0-127 are reserved for event queue doorbells only, so we use
293
  * page 128.
295
  * page 128.
294
  */
296
  */
295
-#define HERMON_UAR_PAGE		128
297
+#define HERMON_UAR_NON_EQ_PAGE	128
296
 
298
 
297
 /** Maximum number of allocatable MTT entries
299
 /** Maximum number of allocatable MTT entries
298
  *
300
  *
334
 	union hermon_send_wqe *wqe;
336
 	union hermon_send_wqe *wqe;
335
 	/** Size of work queue */
337
 	/** Size of work queue */
336
 	size_t wqe_size;
338
 	size_t wqe_size;
339
+	/** Doorbell register */
340
+	void *doorbell;
337
 };
341
 };
338
 
342
 
339
 /** Alignment of Hermon receive work queue entries */
343
 /** Alignment of Hermon receive work queue entries */
400
  *
404
  *
401
  * This is a policy decision, not a device limit.
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
 /** A Hermon event queue */
409
 /** A Hermon event queue */
406
 struct hermon_event_queue {
410
 struct hermon_event_queue {
410
 	size_t eqe_size;
414
 	size_t eqe_size;
411
 	/** MTT descriptor */
415
 	/** MTT descriptor */
412
 	struct hermon_mtt mtt;
416
 	struct hermon_mtt mtt;
417
+	/** Event queue number */
418
+	unsigned long eqn;
413
 	/** Next event queue entry index */
419
 	/** Next event queue entry index */
414
 	unsigned long next_idx;
420
 	unsigned long next_idx;
421
+	/** Doorbell register */
422
+	void *doorbell;
415
 };
423
 };
416
 
424
 
417
 /** Number of event queue entries
425
 /** Number of event queue entries

Loading…
Cancel
Save