diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-02-14 20:58:49 -0500 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2012-02-15 19:25:12 -0500 |
commit | 28e47c498a931200125e299e9d60d22e27b4ab0d (patch) | |
tree | 871e75c4db7e670c2ceaed7b5fd69b9ef9a5f4c4 /drivers/net/ethernet/sfc | |
parent | a9a52506277275b73955504bf4df745502a28b8b (diff) |
sfc: Allocate SRAM between buffer table and descriptor caches at init time
Each port has a block of 64-bit SRAM that is divided between buffer
table and descriptor cache regions at initialisation time. Currently
we use a fixed allocation, but it needs to be changed to support
larger numbers of queues.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc')
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/falcon.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.c | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena.c | 12 |
6 files changed, 50 insertions, 14 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index e943ffbe5e2a..c9c306aef2d9 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -1420,6 +1420,8 @@ static int efx_probe_nic(struct efx_nic *efx) | |||
1420 | if (rc) | 1420 | if (rc) |
1421 | goto fail; | 1421 | goto fail; |
1422 | 1422 | ||
1423 | efx->type->dimension_resources(efx); | ||
1424 | |||
1423 | if (efx->n_channels > 1) | 1425 | if (efx->n_channels > 1) |
1424 | get_random_bytes(&efx->rx_hash_key, sizeof(efx->rx_hash_key)); | 1426 | get_random_bytes(&efx->rx_hash_key, sizeof(efx->rx_hash_key)); |
1425 | for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++) | 1427 | for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++) |
diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 98285115df10..3a1ca2bd1548 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c | |||
@@ -1333,6 +1333,12 @@ out: | |||
1333 | return rc; | 1333 | return rc; |
1334 | } | 1334 | } |
1335 | 1335 | ||
1336 | static void falcon_dimension_resources(struct efx_nic *efx) | ||
1337 | { | ||
1338 | efx->rx_dc_base = 0x20000; | ||
1339 | efx->tx_dc_base = 0x26000; | ||
1340 | } | ||
1341 | |||
1336 | /* Probe all SPI devices on the NIC */ | 1342 | /* Probe all SPI devices on the NIC */ |
1337 | static void falcon_probe_spi_devices(struct efx_nic *efx) | 1343 | static void falcon_probe_spi_devices(struct efx_nic *efx) |
1338 | { | 1344 | { |
@@ -1749,6 +1755,7 @@ const struct efx_nic_type falcon_a1_nic_type = { | |||
1749 | .probe = falcon_probe_nic, | 1755 | .probe = falcon_probe_nic, |
1750 | .remove = falcon_remove_nic, | 1756 | .remove = falcon_remove_nic, |
1751 | .init = falcon_init_nic, | 1757 | .init = falcon_init_nic, |
1758 | .dimension_resources = falcon_dimension_resources, | ||
1752 | .fini = efx_port_dummy_op_void, | 1759 | .fini = efx_port_dummy_op_void, |
1753 | .monitor = falcon_monitor, | 1760 | .monitor = falcon_monitor, |
1754 | .map_reset_reason = falcon_map_reset_reason, | 1761 | .map_reset_reason = falcon_map_reset_reason, |
@@ -1783,8 +1790,6 @@ const struct efx_nic_type falcon_a1_nic_type = { | |||
1783 | .max_interrupt_mode = EFX_INT_MODE_MSI, | 1790 | .max_interrupt_mode = EFX_INT_MODE_MSI, |
1784 | .phys_addr_channels = 4, | 1791 | .phys_addr_channels = 4, |
1785 | .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, | 1792 | .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, |
1786 | .tx_dc_base = 0x130000, | ||
1787 | .rx_dc_base = 0x100000, | ||
1788 | .offload_features = NETIF_F_IP_CSUM, | 1793 | .offload_features = NETIF_F_IP_CSUM, |
1789 | }; | 1794 | }; |
1790 | 1795 | ||
@@ -1792,6 +1797,7 @@ const struct efx_nic_type falcon_b0_nic_type = { | |||
1792 | .probe = falcon_probe_nic, | 1797 | .probe = falcon_probe_nic, |
1793 | .remove = falcon_remove_nic, | 1798 | .remove = falcon_remove_nic, |
1794 | .init = falcon_init_nic, | 1799 | .init = falcon_init_nic, |
1800 | .dimension_resources = falcon_dimension_resources, | ||
1795 | .fini = efx_port_dummy_op_void, | 1801 | .fini = efx_port_dummy_op_void, |
1796 | .monitor = falcon_monitor, | 1802 | .monitor = falcon_monitor, |
1797 | .map_reset_reason = falcon_map_reset_reason, | 1803 | .map_reset_reason = falcon_map_reset_reason, |
@@ -1835,8 +1841,6 @@ const struct efx_nic_type falcon_b0_nic_type = { | |||
1835 | * interrupt handler only supports 32 | 1841 | * interrupt handler only supports 32 |
1836 | * channels */ | 1842 | * channels */ |
1837 | .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, | 1843 | .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, |
1838 | .tx_dc_base = 0x130000, | ||
1839 | .rx_dc_base = 0x100000, | ||
1840 | .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, | 1844 | .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, |
1841 | }; | 1845 | }; |
1842 | 1846 | ||
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 94b0dcab897f..7870cefcb203 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -658,6 +658,9 @@ struct efx_filter_state; | |||
658 | * should be allocated for this NIC | 658 | * should be allocated for this NIC |
659 | * @rxq_entries: Size of receive queues requested by user. | 659 | * @rxq_entries: Size of receive queues requested by user. |
660 | * @txq_entries: Size of transmit queues requested by user. | 660 | * @txq_entries: Size of transmit queues requested by user. |
661 | * @tx_dc_base: Base qword address in SRAM of TX queue descriptor caches | ||
662 | * @rx_dc_base: Base qword address in SRAM of RX queue descriptor caches | ||
663 | * @sram_lim_qw: Qword address limit of SRAM | ||
661 | * @next_buffer_table: First available buffer table id | 664 | * @next_buffer_table: First available buffer table id |
662 | * @n_channels: Number of channels in use | 665 | * @n_channels: Number of channels in use |
663 | * @n_rx_channels: Number of channels used for RX (= number of RX queues) | 666 | * @n_rx_channels: Number of channels used for RX (= number of RX queues) |
@@ -753,6 +756,9 @@ struct efx_nic { | |||
753 | 756 | ||
754 | unsigned rxq_entries; | 757 | unsigned rxq_entries; |
755 | unsigned txq_entries; | 758 | unsigned txq_entries; |
759 | unsigned tx_dc_base; | ||
760 | unsigned rx_dc_base; | ||
761 | unsigned sram_lim_qw; | ||
756 | unsigned next_buffer_table; | 762 | unsigned next_buffer_table; |
757 | unsigned n_channels; | 763 | unsigned n_channels; |
758 | unsigned n_rx_channels; | 764 | unsigned n_rx_channels; |
@@ -839,6 +845,8 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) | |||
839 | * @probe: Probe the controller | 845 | * @probe: Probe the controller |
840 | * @remove: Free resources allocated by probe() | 846 | * @remove: Free resources allocated by probe() |
841 | * @init: Initialise the controller | 847 | * @init: Initialise the controller |
848 | * @dimension_resources: Dimension controller resources (buffer table, | ||
849 | * and VIs once the available interrupt resources are clear) | ||
842 | * @fini: Shut down the controller | 850 | * @fini: Shut down the controller |
843 | * @monitor: Periodic function for polling link state and hardware monitor | 851 | * @monitor: Periodic function for polling link state and hardware monitor |
844 | * @map_reset_reason: Map ethtool reset reason to a reset method | 852 | * @map_reset_reason: Map ethtool reset reason to a reset method |
@@ -878,8 +886,6 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) | |||
878 | * @phys_addr_channels: Number of channels with physically addressed | 886 | * @phys_addr_channels: Number of channels with physically addressed |
879 | * descriptors | 887 | * descriptors |
880 | * @timer_period_max: Maximum period of interrupt timer (in ticks) | 888 | * @timer_period_max: Maximum period of interrupt timer (in ticks) |
881 | * @tx_dc_base: Base address in SRAM of TX queue descriptor caches | ||
882 | * @rx_dc_base: Base address in SRAM of RX queue descriptor caches | ||
883 | * @offload_features: net_device feature flags for protocol offload | 889 | * @offload_features: net_device feature flags for protocol offload |
884 | * features implemented in hardware | 890 | * features implemented in hardware |
885 | */ | 891 | */ |
@@ -887,6 +893,7 @@ struct efx_nic_type { | |||
887 | int (*probe)(struct efx_nic *efx); | 893 | int (*probe)(struct efx_nic *efx); |
888 | void (*remove)(struct efx_nic *efx); | 894 | void (*remove)(struct efx_nic *efx); |
889 | int (*init)(struct efx_nic *efx); | 895 | int (*init)(struct efx_nic *efx); |
896 | void (*dimension_resources)(struct efx_nic *efx); | ||
890 | void (*fini)(struct efx_nic *efx); | 897 | void (*fini)(struct efx_nic *efx); |
891 | void (*monitor)(struct efx_nic *efx); | 898 | void (*monitor)(struct efx_nic *efx); |
892 | enum reset_type (*map_reset_reason)(enum reset_type reason); | 899 | enum reset_type (*map_reset_reason)(enum reset_type reason); |
@@ -923,8 +930,6 @@ struct efx_nic_type { | |||
923 | unsigned int max_interrupt_mode; | 930 | unsigned int max_interrupt_mode; |
924 | unsigned int phys_addr_channels; | 931 | unsigned int phys_addr_channels; |
925 | unsigned int timer_period_max; | 932 | unsigned int timer_period_max; |
926 | unsigned int tx_dc_base; | ||
927 | unsigned int rx_dc_base; | ||
928 | netdev_features_t offload_features; | 933 | netdev_features_t offload_features; |
929 | }; | 934 | }; |
930 | 935 | ||
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index 2bdfb6374ce8..747cf9439164 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c | |||
@@ -1609,6 +1609,23 @@ void efx_nic_fini_interrupt(struct efx_nic *efx) | |||
1609 | free_irq(efx->legacy_irq, efx); | 1609 | free_irq(efx->legacy_irq, efx); |
1610 | } | 1610 | } |
1611 | 1611 | ||
1612 | void efx_nic_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw) | ||
1613 | { | ||
1614 | unsigned vi_count, buftbl_min; | ||
1615 | |||
1616 | /* Account for the buffer table entries backing the datapath channels | ||
1617 | * and the descriptor caches for those channels. | ||
1618 | */ | ||
1619 | buftbl_min = ((efx->n_rx_channels * EFX_MAX_DMAQ_SIZE + | ||
1620 | efx->n_tx_channels * EFX_TXQ_TYPES * EFX_MAX_DMAQ_SIZE + | ||
1621 | efx->n_channels * EFX_MAX_EVQ_SIZE) | ||
1622 | * sizeof(efx_qword_t) / EFX_BUF_SIZE); | ||
1623 | vi_count = max(efx->n_channels, efx->n_tx_channels * EFX_TXQ_TYPES); | ||
1624 | |||
1625 | efx->tx_dc_base = sram_lim_qw - vi_count * TX_DC_ENTRIES; | ||
1626 | efx->rx_dc_base = efx->tx_dc_base - vi_count * RX_DC_ENTRIES; | ||
1627 | } | ||
1628 | |||
1612 | u32 efx_nic_fpga_ver(struct efx_nic *efx) | 1629 | u32 efx_nic_fpga_ver(struct efx_nic *efx) |
1613 | { | 1630 | { |
1614 | efx_oword_t altera_build; | 1631 | efx_oword_t altera_build; |
@@ -1621,11 +1638,9 @@ void efx_nic_init_common(struct efx_nic *efx) | |||
1621 | efx_oword_t temp; | 1638 | efx_oword_t temp; |
1622 | 1639 | ||
1623 | /* Set positions of descriptor caches in SRAM. */ | 1640 | /* Set positions of descriptor caches in SRAM. */ |
1624 | EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, | 1641 | EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, efx->tx_dc_base); |
1625 | efx->type->tx_dc_base / 8); | ||
1626 | efx_writeo(efx, &temp, FR_AZ_SRM_TX_DC_CFG); | 1642 | efx_writeo(efx, &temp, FR_AZ_SRM_TX_DC_CFG); |
1627 | EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR, | 1643 | EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR, efx->rx_dc_base); |
1628 | efx->type->rx_dc_base / 8); | ||
1629 | efx_writeo(efx, &temp, FR_AZ_SRM_RX_DC_CFG); | 1644 | efx_writeo(efx, &temp, FR_AZ_SRM_RX_DC_CFG); |
1630 | 1645 | ||
1631 | /* Set TX descriptor cache size. */ | 1646 | /* Set TX descriptor cache size. */ |
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index 1f53e2c7cfd7..5df7da8b8ebf 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h | |||
@@ -230,6 +230,8 @@ extern void falcon_start_nic_stats(struct efx_nic *efx); | |||
230 | extern void falcon_stop_nic_stats(struct efx_nic *efx); | 230 | extern void falcon_stop_nic_stats(struct efx_nic *efx); |
231 | extern void falcon_setup_xaui(struct efx_nic *efx); | 231 | extern void falcon_setup_xaui(struct efx_nic *efx); |
232 | extern int falcon_reset_xaui(struct efx_nic *efx); | 232 | extern int falcon_reset_xaui(struct efx_nic *efx); |
233 | extern void | ||
234 | efx_nic_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw); | ||
233 | extern void efx_nic_init_common(struct efx_nic *efx); | 235 | extern void efx_nic_init_common(struct efx_nic *efx); |
234 | extern void efx_nic_push_rx_indir_table(struct efx_nic *efx); | 236 | extern void efx_nic_push_rx_indir_table(struct efx_nic *efx); |
235 | 237 | ||
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index d3c4169e2a0b..657f3fa93bcf 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c | |||
@@ -225,6 +225,15 @@ static int siena_probe_nvconfig(struct efx_nic *efx) | |||
225 | return rc; | 225 | return rc; |
226 | } | 226 | } |
227 | 227 | ||
228 | static void siena_dimension_resources(struct efx_nic *efx) | ||
229 | { | ||
230 | /* Each port has a small block of internal SRAM dedicated to | ||
231 | * the buffer table and descriptor caches. In theory we can | ||
232 | * map both blocks to one port, but we don't. | ||
233 | */ | ||
234 | efx_nic_dimension_resources(efx, FR_CZ_BUF_FULL_TBL_ROWS / 2); | ||
235 | } | ||
236 | |||
228 | static int siena_probe_nic(struct efx_nic *efx) | 237 | static int siena_probe_nic(struct efx_nic *efx) |
229 | { | 238 | { |
230 | struct siena_nic_data *nic_data; | 239 | struct siena_nic_data *nic_data; |
@@ -619,6 +628,7 @@ const struct efx_nic_type siena_a0_nic_type = { | |||
619 | .probe = siena_probe_nic, | 628 | .probe = siena_probe_nic, |
620 | .remove = siena_remove_nic, | 629 | .remove = siena_remove_nic, |
621 | .init = siena_init_nic, | 630 | .init = siena_init_nic, |
631 | .dimension_resources = siena_dimension_resources, | ||
622 | .fini = efx_port_dummy_op_void, | 632 | .fini = efx_port_dummy_op_void, |
623 | .monitor = NULL, | 633 | .monitor = NULL, |
624 | .map_reset_reason = siena_map_reset_reason, | 634 | .map_reset_reason = siena_map_reset_reason, |
@@ -657,8 +667,6 @@ const struct efx_nic_type siena_a0_nic_type = { | |||
657 | * interrupt handler only supports 32 | 667 | * interrupt handler only supports 32 |
658 | * channels */ | 668 | * channels */ |
659 | .timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH, | 669 | .timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH, |
660 | .tx_dc_base = 0x88000, | ||
661 | .rx_dc_base = 0x68000, | ||
662 | .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 670 | .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
663 | NETIF_F_RXHASH | NETIF_F_NTUPLE), | 671 | NETIF_F_RXHASH | NETIF_F_NTUPLE), |
664 | }; | 672 | }; |