|
@@ -331,6 +331,49 @@ arbel_cmd_run_fw ( struct arbel *arbel ) {
|
331
|
331
|
0, NULL, 0, NULL );
|
332
|
332
|
}
|
333
|
333
|
|
|
334
|
+static inline int
|
|
335
|
+arbel_cmd_unmap_icm ( struct arbel *arbel, unsigned int page_count ) {
|
|
336
|
+ return arbel_cmd ( arbel,
|
|
337
|
+ ARBEL_HCR_VOID_CMD ( ARBEL_HCR_UNMAP_ICM ),
|
|
338
|
+ 0, NULL, page_count, NULL );
|
|
339
|
+}
|
|
340
|
+
|
|
341
|
+static inline int
|
|
342
|
+arbel_cmd_map_icm ( struct arbel *arbel,
|
|
343
|
+ const struct arbelprm_virtual_physical_mapping *map ) {
|
|
344
|
+ return arbel_cmd ( arbel,
|
|
345
|
+ ARBEL_HCR_IN_CMD ( ARBEL_HCR_MAP_ICM,
|
|
346
|
+ 1, sizeof ( *map ) ),
|
|
347
|
+ 0, map, 1, NULL );
|
|
348
|
+}
|
|
349
|
+
|
|
350
|
+static inline int
|
|
351
|
+arbel_cmd_unmap_icm_aux ( struct arbel *arbel ) {
|
|
352
|
+ return arbel_cmd ( arbel,
|
|
353
|
+ ARBEL_HCR_VOID_CMD ( ARBEL_HCR_UNMAP_ICM_AUX ),
|
|
354
|
+ 0, NULL, 0, NULL );
|
|
355
|
+}
|
|
356
|
+
|
|
357
|
+static inline int
|
|
358
|
+arbel_cmd_map_icm_aux ( struct arbel *arbel,
|
|
359
|
+ const struct arbelprm_virtual_physical_mapping *map ) {
|
|
360
|
+ return arbel_cmd ( arbel,
|
|
361
|
+ ARBEL_HCR_IN_CMD ( ARBEL_HCR_MAP_ICM_AUX,
|
|
362
|
+ 1, sizeof ( *map ) ),
|
|
363
|
+ 0, map, 1, NULL );
|
|
364
|
+}
|
|
365
|
+
|
|
366
|
+static inline int
|
|
367
|
+arbel_cmd_set_icm_size ( struct arbel *arbel,
|
|
368
|
+ const struct arbelprm_scalar_parameter *icm_size,
|
|
369
|
+ struct arbelprm_scalar_parameter *icm_aux_size ) {
|
|
370
|
+ return arbel_cmd ( arbel,
|
|
371
|
+ ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_SET_ICM_SIZE,
|
|
372
|
+ 0, sizeof ( *icm_size ),
|
|
373
|
+ 0, sizeof ( *icm_aux_size ) ),
|
|
374
|
+ 0, icm_size, 0, icm_aux_size );
|
|
375
|
+}
|
|
376
|
+
|
334
|
377
|
static inline int
|
335
|
378
|
arbel_cmd_unmap_fa ( struct arbel *arbel ) {
|
336
|
379
|
return arbel_cmd ( arbel,
|
|
@@ -340,11 +383,11 @@ arbel_cmd_unmap_fa ( struct arbel *arbel ) {
|
340
|
383
|
|
341
|
384
|
static inline int
|
342
|
385
|
arbel_cmd_map_fa ( struct arbel *arbel,
|
343
|
|
- const struct arbelprm_virtual_physical_mapping *map_fa ) {
|
|
386
|
+ const struct arbelprm_virtual_physical_mapping *map ) {
|
344
|
387
|
return arbel_cmd ( arbel,
|
345
|
388
|
ARBEL_HCR_IN_CMD ( ARBEL_HCR_MAP_FA,
|
346
|
|
- 1, sizeof ( *map_fa ) ),
|
347
|
|
- 0, map_fa, 1, NULL );
|
|
389
|
+ 1, sizeof ( *map ) ),
|
|
390
|
+ 0, map, 1, NULL );
|
348
|
391
|
}
|
349
|
392
|
|
350
|
393
|
/***************************************************************************
|
|
@@ -1536,23 +1579,28 @@ static size_t icm_usage ( unsigned int log_num_entries, size_t entry_size ) {
|
1536
|
1579
|
}
|
1537
|
1580
|
|
1538
|
1581
|
/**
|
1539
|
|
- * Partition ICM
|
|
1582
|
+ * Allocate ICM
|
1540
|
1583
|
*
|
1541
|
1584
|
* @v arbel Arbel device
|
|
1585
|
+ * @v init_hca INIT_HCA structure to fill in
|
1542
|
1586
|
* @ret rc Return status code
|
1543
|
1587
|
*/
|
1544
|
|
-static int arbel_alloc_icm ( struct arbel *arbel ) {
|
1545
|
|
- struct arbelprm_init_hca init_hca;
|
|
1588
|
+static int arbel_alloc_icm ( struct arbel *arbel,
|
|
1589
|
+ struct arbelprm_init_hca *init_hca ) {
|
|
1590
|
+ struct arbelprm_scalar_parameter icm_size;
|
|
1591
|
+ struct arbelprm_scalar_parameter icm_aux_size;
|
|
1592
|
+ struct arbelprm_virtual_physical_mapping map_icm_aux;
|
|
1593
|
+ struct arbelprm_virtual_physical_mapping map_icm;
|
1546
|
1594
|
size_t icm_offset = 0;
|
1547
|
1595
|
unsigned int log_num_qps, log_num_srqs, log_num_ees, log_num_cqs;
|
1548
|
1596
|
unsigned int log_num_mtts, log_num_mpts, log_num_rdbs, log_num_eqs;
|
|
1597
|
+ int rc;
|
1549
|
1598
|
|
1550
|
|
- memset ( &init_hca, 0, sizeof ( init_hca ) );
|
1551
|
1599
|
icm_offset = ( ( arbel->limits.reserved_uars + 1 ) << 12 );
|
1552
|
1600
|
|
1553
|
1601
|
/* Queue pair contexts */
|
1554
|
1602
|
log_num_qps = fls ( arbel->limits.reserved_qps + ARBEL_MAX_QPS - 1 );
|
1555
|
|
- MLX_FILL_2 ( &init_hca, 13,
|
|
1603
|
+ MLX_FILL_2 ( init_hca, 13,
|
1556
|
1604
|
qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_l,
|
1557
|
1605
|
( icm_offset >> 7 ),
|
1558
|
1606
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp,
|
|
@@ -1560,14 +1608,14 @@ static int arbel_alloc_icm ( struct arbel *arbel ) {
|
1560
|
1608
|
icm_offset += icm_usage ( log_num_qps, arbel->limits.qpc_entry_size );
|
1561
|
1609
|
|
1562
|
1610
|
/* Extended queue pair contexts */
|
1563
|
|
- MLX_FILL_1 ( &init_hca, 25,
|
|
1611
|
+ MLX_FILL_1 ( init_hca, 25,
|
1564
|
1612
|
qpc_eec_cqc_eqc_rdb_parameters.eqpc_base_addr_l,
|
1565
|
1613
|
icm_offset );
|
1566
|
1614
|
icm_offset += icm_usage ( log_num_qps, arbel->limits.eqpc_entry_size );
|
1567
|
1615
|
|
1568
|
1616
|
/* Shared receive queue contexts */
|
1569
|
1617
|
log_num_srqs = fls ( arbel->limits.reserved_srqs - 1 );
|
1570
|
|
- MLX_FILL_2 ( &init_hca, 19,
|
|
1618
|
+ MLX_FILL_2 ( init_hca, 19,
|
1571
|
1619
|
qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_l,
|
1572
|
1620
|
( icm_offset >> 5 ),
|
1573
|
1621
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
|
|
@@ -1576,7 +1624,7 @@ static int arbel_alloc_icm ( struct arbel *arbel ) {
|
1576
|
1624
|
|
1577
|
1625
|
/* End-to-end contexts */
|
1578
|
1626
|
log_num_ees = fls ( arbel->limits.reserved_ees - 1 );
|
1579
|
|
- MLX_FILL_2 ( &init_hca, 17,
|
|
1627
|
+ MLX_FILL_2 ( init_hca, 17,
|
1580
|
1628
|
qpc_eec_cqc_eqc_rdb_parameters.eec_base_addr_l,
|
1581
|
1629
|
( icm_offset >> 7 ),
|
1582
|
1630
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_ee,
|
|
@@ -1584,14 +1632,14 @@ static int arbel_alloc_icm ( struct arbel *arbel ) {
|
1584
|
1632
|
icm_offset += icm_usage ( log_num_ees, arbel->limits.eec_entry_size );
|
1585
|
1633
|
|
1586
|
1634
|
/* Extended end-to-end contexts */
|
1587
|
|
- MLX_FILL_1 ( &init_hca, 29,
|
|
1635
|
+ MLX_FILL_1 ( init_hca, 29,
|
1588
|
1636
|
qpc_eec_cqc_eqc_rdb_parameters.eeec_base_addr_l,
|
1589
|
1637
|
icm_offset );
|
1590
|
1638
|
icm_offset += icm_usage ( log_num_ees, arbel->limits.eeec_entry_size );
|
1591
|
1639
|
|
1592
|
1640
|
/* Completion queue contexts */
|
1593
|
1641
|
log_num_cqs = fls ( arbel->limits.reserved_cqs + ARBEL_MAX_CQS - 1 );
|
1594
|
|
- MLX_FILL_2 ( &init_hca, 21,
|
|
1642
|
+ MLX_FILL_2 ( init_hca, 21,
|
1595
|
1643
|
qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_l,
|
1596
|
1644
|
( icm_offset >> 6 ),
|
1597
|
1645
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq,
|
|
@@ -1600,28 +1648,28 @@ static int arbel_alloc_icm ( struct arbel *arbel ) {
|
1600
|
1648
|
|
1601
|
1649
|
/* Memory translation table */
|
1602
|
1650
|
log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
|
1603
|
|
- MLX_FILL_1 ( &init_hca, 65,
|
|
1651
|
+ MLX_FILL_1 ( init_hca, 65,
|
1604
|
1652
|
tpt_parameters.mtt_base_addr_l, icm_offset );
|
1605
|
1653
|
icm_offset += icm_usage ( log_num_mtts, arbel->limits.mtt_entry_size );
|
1606
|
1654
|
|
1607
|
1655
|
/* Memory protection table */
|
1608
|
1656
|
log_num_mpts = fls ( arbel->limits.reserved_mrws - 1 );
|
1609
|
|
- MLX_FILL_1 ( &init_hca, 61,
|
|
1657
|
+ MLX_FILL_1 ( init_hca, 61,
|
1610
|
1658
|
tpt_parameters.mpt_base_adr_l, icm_offset );
|
1611
|
|
- MLX_FILL_1 ( &init_hca, 62,
|
|
1659
|
+ MLX_FILL_1 ( init_hca, 62,
|
1612
|
1660
|
tpt_parameters.log_mpt_sz, log_num_mpts );
|
1613
|
1661
|
icm_offset += icm_usage ( log_num_mpts, arbel->limits.mpt_entry_size );
|
1614
|
1662
|
|
1615
|
1663
|
/* RDMA something or other */
|
1616
|
1664
|
log_num_rdbs = fls ( arbel->limits.reserved_rdbs - 1 );
|
1617
|
|
- MLX_FILL_1 ( &init_hca, 37,
|
|
1665
|
+ MLX_FILL_1 ( init_hca, 37,
|
1618
|
1666
|
qpc_eec_cqc_eqc_rdb_parameters.rdb_base_addr_l,
|
1619
|
1667
|
icm_offset );
|
1620
|
1668
|
icm_offset += icm_usage ( log_num_rdbs, 32 );
|
1621
|
1669
|
|
1622
|
1670
|
/* Event queue contexts */
|
1623
|
1671
|
log_num_eqs = 6;
|
1624
|
|
- MLX_FILL_2 ( &init_hca, 33,
|
|
1672
|
+ MLX_FILL_2 ( init_hca, 33,
|
1625
|
1673
|
qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_l,
|
1626
|
1674
|
( icm_offset >> 6 ),
|
1627
|
1675
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_eq,
|
|
@@ -1629,18 +1677,87 @@ static int arbel_alloc_icm ( struct arbel *arbel ) {
|
1629
|
1677
|
icm_offset += ( ( 1 << log_num_eqs ) * arbel->limits.eqc_entry_size );
|
1630
|
1678
|
|
1631
|
1679
|
/* Multicast table */
|
1632
|
|
- MLX_FILL_1 ( &init_hca, 49,
|
|
1680
|
+ MLX_FILL_1 ( init_hca, 49,
|
1633
|
1681
|
multicast_parameters.mc_base_addr_l, icm_offset );
|
1634
|
|
- MLX_FILL_1 ( &init_hca, 52,
|
|
1682
|
+ MLX_FILL_1 ( init_hca, 52,
|
1635
|
1683
|
multicast_parameters.log_mc_table_entry_sz,
|
1636
|
1684
|
fls ( sizeof ( struct arbelprm_mgm_entry ) - 1 ) );
|
1637
|
|
- MLX_FILL_1 ( &init_hca, 53,
|
|
1685
|
+ MLX_FILL_1 ( init_hca, 53,
|
1638
|
1686
|
multicast_parameters.mc_table_hash_sz, 8 );
|
1639
|
|
- MLX_FILL_1 ( &init_hca, 54,
|
|
1687
|
+ MLX_FILL_1 ( init_hca, 54,
|
1640
|
1688
|
multicast_parameters.log_mc_table_sz, 3 );
|
1641
|
1689
|
icm_offset += ( 8 * sizeof ( struct arbelprm_mgm_entry ) );
|
1642
|
1690
|
|
|
1691
|
+ arbel->icm_len = icm_offset;
|
|
1692
|
+ arbel->icm_len = ( ( arbel->icm_len + 4095 ) & ~4095 );
|
|
1693
|
+
|
|
1694
|
+ /* Get ICM auxiliary area size */
|
|
1695
|
+ memset ( &icm_size, 0, sizeof ( icm_size ) );
|
|
1696
|
+ MLX_FILL_1 ( &icm_size, 1, value, arbel->icm_len );
|
|
1697
|
+ if ( ( rc = arbel_cmd_set_icm_size ( arbel, &icm_size,
|
|
1698
|
+ &icm_aux_size ) ) != 0 ) {
|
|
1699
|
+ DBGC ( arbel, "Arbel %p could not set ICM size: %s\n",
|
|
1700
|
+ arbel, strerror ( rc ) );
|
|
1701
|
+ goto err_set_icm_size;
|
|
1702
|
+ }
|
|
1703
|
+ arbel->icm_aux_len = MLX_GET ( &icm_aux_size, value );
|
|
1704
|
+
|
|
1705
|
+ /* Allocate ICM data and auxiliary area */
|
|
1706
|
+ arbel->icm_aux_len = ( ( arbel->icm_aux_len + 4095 ) & ~4095 );
|
|
1707
|
+ DBGC ( arbel, "Arbel %p requires %zd kB ICM and %zd kB AUX ICM\n",
|
|
1708
|
+ arbel, ( arbel->icm_len / 1024 ),
|
|
1709
|
+ ( arbel->icm_aux_len / 1024 ) );
|
|
1710
|
+ arbel->icm = umalloc ( arbel->icm_len + arbel->icm_aux_len );
|
|
1711
|
+ if ( ! arbel->icm ) {
|
|
1712
|
+ rc = -ENOMEM;
|
|
1713
|
+ goto err_alloc;
|
|
1714
|
+ }
|
|
1715
|
+
|
|
1716
|
+ /* Map ICM auxiliary area */
|
|
1717
|
+ memset ( &map_icm_aux, 0, sizeof ( map_icm_aux ) );
|
|
1718
|
+ MLX_FILL_2 ( &map_icm_aux, 3,
|
|
1719
|
+ log2size, fls ( ( arbel->icm_aux_len / 4096 ) - 1 ),
|
|
1720
|
+ pa_l, user_to_phys ( arbel->icm, arbel->icm_len ) );
|
|
1721
|
+ if ( ( rc = arbel_cmd_map_icm_aux ( arbel, &map_icm_aux ) ) != 0 ) {
|
|
1722
|
+ DBGC ( arbel, "Arbel %p could not map AUX ICM: %s\n",
|
|
1723
|
+ arbel, strerror ( rc ) );
|
|
1724
|
+ goto err_map_icm_aux;
|
|
1725
|
+ }
|
|
1726
|
+
|
|
1727
|
+ /* MAP ICM area */
|
|
1728
|
+ memset ( &map_icm, 0, sizeof ( map_icm ) );
|
|
1729
|
+ MLX_FILL_2 ( &map_icm, 3,
|
|
1730
|
+ log2size, fls ( ( arbel->icm_len / 4096 ) - 1 ),
|
|
1731
|
+ pa_l, user_to_phys ( arbel->icm, 0 ) );
|
|
1732
|
+ if ( ( rc = arbel_cmd_map_icm ( arbel, &map_icm ) ) != 0 ) {
|
|
1733
|
+ DBGC ( arbel, "Arbel %p could not map ICM: %s\n",
|
|
1734
|
+ arbel, strerror ( rc ) );
|
|
1735
|
+ goto err_map_icm;
|
|
1736
|
+ }
|
|
1737
|
+
|
1643
|
1738
|
return 0;
|
|
1739
|
+
|
|
1740
|
+ arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / 4096 ) );
|
|
1741
|
+ err_map_icm:
|
|
1742
|
+ arbel_cmd_unmap_icm_aux ( arbel );
|
|
1743
|
+ err_map_icm_aux:
|
|
1744
|
+ ufree ( arbel->icm );
|
|
1745
|
+ arbel->icm = UNULL;
|
|
1746
|
+ err_alloc:
|
|
1747
|
+ err_set_icm_size:
|
|
1748
|
+ return rc;
|
|
1749
|
+}
|
|
1750
|
+
|
|
1751
|
+/**
|
|
1752
|
+ * Free ICM
|
|
1753
|
+ *
|
|
1754
|
+ * @v arbel Arbel device
|
|
1755
|
+ */
|
|
1756
|
+static void arbel_free_icm ( struct arbel *arbel ) {
|
|
1757
|
+ arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / 4096 ) );
|
|
1758
|
+ arbel_cmd_unmap_icm_aux ( arbel );
|
|
1759
|
+ ufree ( arbel->icm );
|
|
1760
|
+ arbel->icm = UNULL;
|
1644
|
1761
|
}
|
1645
|
1762
|
|
1646
|
1763
|
/***************************************************************************
|
|
@@ -1661,6 +1778,7 @@ static int arbel_probe ( struct pci_device *pci,
|
1661
|
1778
|
const struct pci_device_id *id __unused ) {
|
1662
|
1779
|
struct ib_device *ibdev;
|
1663
|
1780
|
struct arbel *arbel;
|
|
1781
|
+ struct arbelprm_init_hca init_hca;
|
1664
|
1782
|
int rc;
|
1665
|
1783
|
|
1666
|
1784
|
/* Allocate Infiniband device */
|
|
@@ -1697,23 +1815,41 @@ static int arbel_probe ( struct pci_device *pci,
|
1697
|
1815
|
goto err_mailbox_out;
|
1698
|
1816
|
}
|
1699
|
1817
|
|
|
1818
|
+#define SELF_INIT 0
|
|
1819
|
+
|
|
1820
|
+#if SELF_INIT
|
1700
|
1821
|
/* Start firmware */
|
1701
|
1822
|
if ( ( rc = arbel_start_firmware ( arbel ) ) != 0 )
|
1702
|
1823
|
goto err_start_firmware;
|
|
1824
|
+#else
|
|
1825
|
+ /* Initialise hardware */
|
|
1826
|
+ udqp_t qph;
|
|
1827
|
+ if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
|
|
1828
|
+ goto err_ib_driver_init;
|
|
1829
|
+#endif
|
1703
|
1830
|
|
1704
|
1831
|
/* Get device limits */
|
1705
|
1832
|
if ( ( rc = arbel_get_limits ( arbel ) ) != 0 )
|
1706
|
1833
|
goto err_get_limits;
|
1707
|
1834
|
|
1708
|
|
- while ( 1 ) {}
|
|
1835
|
+#if SELF_INIT
|
|
1836
|
+ /* Allocate ICM */
|
|
1837
|
+ memset ( &init_hca, 0, sizeof ( init_hca ) );
|
|
1838
|
+ if ( ( rc = arbel_alloc_icm ( arbel, &init_hca ) ) != 0 )
|
|
1839
|
+ goto err_alloc_icm;
|
1709
|
1840
|
|
1710
|
|
-#if 0
|
1711
|
|
- /* Initialise hardware */
|
1712
|
|
- if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
|
1713
|
|
- goto err_ib_driver_init;
|
|
1841
|
+ /* Initialise HCA */
|
|
1842
|
+ if ( ( rc = arbel_cmd_init_hca ( arbel, &init_hca ) ) != 0 ) {
|
|
1843
|
+ DBGC ( arbel, "Arbel %p could not initialise HCA: %s\n",
|
|
1844
|
+ arbel, strerror ( rc ) );
|
|
1845
|
+ goto err_init_hca;
|
|
1846
|
+ }
|
|
1847
|
+#endif
|
1714
|
1848
|
|
1715
|
|
- /* Hack up IB structures */
|
1716
|
1849
|
|
|
1850
|
+
|
|
1851
|
+ /* Hack up IB structures */
|
|
1852
|
+#if 0
|
1717
|
1853
|
arbel->config = memfree_pci_dev.cr_space;
|
1718
|
1854
|
arbel->uar = memfree_pci_dev.uar;
|
1719
|
1855
|
arbel->mailbox_in = dev_buffers_p->inprm_buf;
|
|
@@ -1728,7 +1864,6 @@ static int arbel_probe ( struct pci_device *pci,
|
1728
|
1864
|
if ( ( rc = arbel_get_mad_params ( ibdev ) ) != 0 )
|
1729
|
1865
|
goto err_get_mad_params;
|
1730
|
1866
|
|
1731
|
|
-
|
1732
|
1867
|
/* Add IPoIB device */
|
1733
|
1868
|
if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
|
1734
|
1869
|
DBGC ( arbel, "Arbel %p could not add IPoIB device: %s\n",
|
|
@@ -1743,7 +1878,10 @@ static int arbel_probe ( struct pci_device *pci,
|
1743
|
1878
|
ib_driver_close ( 0 );
|
1744
|
1879
|
err_ib_driver_init:
|
1745
|
1880
|
|
1746
|
|
-
|
|
1881
|
+
|
|
1882
|
+ err_init_hca:
|
|
1883
|
+ arbel_free_icm ( arbel );
|
|
1884
|
+ err_alloc_icm:
|
1747
|
1885
|
err_get_limits:
|
1748
|
1886
|
arbel_stop_firmware ( arbel );
|
1749
|
1887
|
err_start_firmware:
|