|
@@ -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,
|