aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2011-12-08 14:51:47 -0500
committerBen Hutchings <bhutchings@solarflare.com>2012-01-26 19:10:50 -0500
commitcc180b69c009ec52f67a56d96b9073b9f774b323 (patch)
tree2d20225099a9a08d3471aeb3cd8ce4295417e5e6
parent6aa9c7f625e8ce07060467051b68fc068118ee64 (diff)
sfc: Correct interrupt timer quantum for Siena (normal and turbo mode)
We currently assume that the timer quantum for Siena is 5 us, the same as for Falcon. This is not correct; timer ticks are generated on a rota which takes a minimum of 768 cycles (each event delivery or other timer change will delay it by 3 cycles). The timer quantum should be 6.144 or 3.072 us depending on whether turbo mode is active. Replace EFX_IRQ_MOD_RESOLUTION with a timer_quantum_ns field in struct efx_nic, initialised by the efx_nic_type::probe function. While we're at it, replace EFX_IRQ_MOD_MAX with a timer_period_max field in struct efx_nic_type. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/efx.c31
-rw-r--r--drivers/net/ethernet/sfc/falcon.c6
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h4
-rw-r--r--drivers/net/ethernet/sfc/nic.h3
-rw-r--r--drivers/net/ethernet/sfc/siena.c13
5 files changed, 40 insertions, 17 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index de162474c3c5..9d4ab5e5e1fa 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1513,13 +1513,13 @@ static void efx_remove_all(struct efx_nic *efx)
1513 * 1513 *
1514 **************************************************************************/ 1514 **************************************************************************/
1515 1515
1516static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int resolution) 1516static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int quantum_ns)
1517{ 1517{
1518 if (usecs == 0) 1518 if (usecs == 0)
1519 return 0; 1519 return 0;
1520 if (usecs < resolution) 1520 if (usecs * 1000 < quantum_ns)
1521 return 1; /* never round down to 0 */ 1521 return 1; /* never round down to 0 */
1522 return usecs / resolution; 1522 return usecs * 1000 / quantum_ns;
1523} 1523}
1524 1524
1525/* Set interrupt moderation parameters */ 1525/* Set interrupt moderation parameters */
@@ -1528,14 +1528,20 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
1528 bool rx_may_override_tx) 1528 bool rx_may_override_tx)
1529{ 1529{
1530 struct efx_channel *channel; 1530 struct efx_channel *channel;
1531 unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION); 1531 unsigned int irq_mod_max = DIV_ROUND_UP(efx->type->timer_period_max *
1532 unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION); 1532 efx->timer_quantum_ns,
1533 1000);
1534 unsigned int tx_ticks;
1535 unsigned int rx_ticks;
1533 1536
1534 EFX_ASSERT_RESET_SERIALISED(efx); 1537 EFX_ASSERT_RESET_SERIALISED(efx);
1535 1538
1536 if (tx_ticks > EFX_IRQ_MOD_MAX || rx_ticks > EFX_IRQ_MOD_MAX) 1539 if (tx_usecs > irq_mod_max || rx_usecs > irq_mod_max)
1537 return -EINVAL; 1540 return -EINVAL;
1538 1541
1542 tx_ticks = irq_mod_ticks(tx_usecs, efx->timer_quantum_ns);
1543 rx_ticks = irq_mod_ticks(rx_usecs, efx->timer_quantum_ns);
1544
1539 if (tx_ticks != rx_ticks && efx->tx_channel_offset == 0 && 1545 if (tx_ticks != rx_ticks && efx->tx_channel_offset == 0 &&
1540 !rx_may_override_tx) { 1546 !rx_may_override_tx) {
1541 netif_err(efx, drv, efx->net_dev, "Channels are shared. " 1547 netif_err(efx, drv, efx->net_dev, "Channels are shared. "
@@ -1558,8 +1564,14 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
1558void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, 1564void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
1559 unsigned int *rx_usecs, bool *rx_adaptive) 1565 unsigned int *rx_usecs, bool *rx_adaptive)
1560{ 1566{
1567 /* We must round up when converting ticks to microseconds
1568 * because we round down when converting the other way.
1569 */
1570
1561 *rx_adaptive = efx->irq_rx_adaptive; 1571 *rx_adaptive = efx->irq_rx_adaptive;
1562 *rx_usecs = efx->irq_rx_moderation * EFX_IRQ_MOD_RESOLUTION; 1572 *rx_usecs = DIV_ROUND_UP(efx->irq_rx_moderation *
1573 efx->timer_quantum_ns,
1574 1000);
1563 1575
1564 /* If channels are shared between RX and TX, so is IRQ 1576 /* If channels are shared between RX and TX, so is IRQ
1565 * moderation. Otherwise, IRQ moderation is the same for all 1577 * moderation. Otherwise, IRQ moderation is the same for all
@@ -1568,9 +1580,10 @@ void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
1568 if (efx->tx_channel_offset == 0) 1580 if (efx->tx_channel_offset == 0)
1569 *tx_usecs = *rx_usecs; 1581 *tx_usecs = *rx_usecs;
1570 else 1582 else
1571 *tx_usecs = 1583 *tx_usecs = DIV_ROUND_UP(
1572 efx->channel[efx->tx_channel_offset]->irq_moderation * 1584 efx->channel[efx->tx_channel_offset]->irq_moderation *
1573 EFX_IRQ_MOD_RESOLUTION; 1585 efx->timer_quantum_ns,
1586 1000);
1574} 1587}
1575 1588
1576/************************************************************************** 1589/**************************************************************************
diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c
index fe21c7e349b6..0b7880b0b8fc 100644
--- a/drivers/net/ethernet/sfc/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon.c
@@ -103,8 +103,6 @@ static void falcon_push_irq_moderation(struct efx_channel *channel)
103 efx_dword_t timer_cmd; 103 efx_dword_t timer_cmd;
104 struct efx_nic *efx = channel->efx; 104 struct efx_nic *efx = channel->efx;
105 105
106 BUILD_BUG_ON(EFX_IRQ_MOD_MAX > (1 << FRF_AB_TC_TIMER_VAL_WIDTH));
107
108 /* Set timer register */ 106 /* Set timer register */
109 if (channel->irq_moderation) { 107 if (channel->irq_moderation) {
110 EFX_POPULATE_DWORD_2(timer_cmd, 108 EFX_POPULATE_DWORD_2(timer_cmd,
@@ -1471,6 +1469,8 @@ static int falcon_probe_nic(struct efx_nic *efx)
1471 goto fail5; 1469 goto fail5;
1472 } 1470 }
1473 1471
1472 efx->timer_quantum_ns = 4968; /* 621 cycles */
1473
1474 /* Initialise I2C adapter */ 1474 /* Initialise I2C adapter */
1475 board = falcon_board(efx); 1475 board = falcon_board(efx);
1476 board->i2c_adap.owner = THIS_MODULE; 1476 board->i2c_adap.owner = THIS_MODULE;
@@ -1785,6 +1785,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
1785 .rx_buffer_padding = 0x24, 1785 .rx_buffer_padding = 0x24,
1786 .max_interrupt_mode = EFX_INT_MODE_MSI, 1786 .max_interrupt_mode = EFX_INT_MODE_MSI,
1787 .phys_addr_channels = 4, 1787 .phys_addr_channels = 4,
1788 .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH,
1788 .tx_dc_base = 0x130000, 1789 .tx_dc_base = 0x130000,
1789 .rx_dc_base = 0x100000, 1790 .rx_dc_base = 0x100000,
1790 .offload_features = NETIF_F_IP_CSUM, 1791 .offload_features = NETIF_F_IP_CSUM,
@@ -1836,6 +1837,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
1836 .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy 1837 .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy
1837 * interrupt handler only supports 32 1838 * interrupt handler only supports 32
1838 * channels */ 1839 * channels */
1840 .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH,
1839 .tx_dc_base = 0x130000, 1841 .tx_dc_base = 0x130000,
1840 .rx_dc_base = 0x100000, 1842 .rx_dc_base = 0x100000,
1841 .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, 1843 .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 4cbd997e378b..8ce4d068bba5 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -624,6 +624,7 @@ struct efx_filter_state;
624 * @membase_phys: Memory BAR value as physical address 624 * @membase_phys: Memory BAR value as physical address
625 * @membase: Memory BAR value 625 * @membase: Memory BAR value
626 * @interrupt_mode: Interrupt mode 626 * @interrupt_mode: Interrupt mode
627 * @timer_quantum_ns: Interrupt timer quantum, in nanoseconds
627 * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues 628 * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
628 * @irq_rx_moderation: IRQ moderation time for RX event queues 629 * @irq_rx_moderation: IRQ moderation time for RX event queues
629 * @msg_enable: Log message enable flags 630 * @msg_enable: Log message enable flags
@@ -706,6 +707,7 @@ struct efx_nic {
706 void __iomem *membase; 707 void __iomem *membase;
707 708
708 enum efx_int_mode interrupt_mode; 709 enum efx_int_mode interrupt_mode;
710 unsigned int timer_quantum_ns;
709 bool irq_rx_adaptive; 711 bool irq_rx_adaptive;
710 unsigned int irq_rx_moderation; 712 unsigned int irq_rx_moderation;
711 u32 msg_enable; 713 u32 msg_enable;
@@ -845,6 +847,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
845 * from &enum efx_init_mode. 847 * from &enum efx_init_mode.
846 * @phys_addr_channels: Number of channels with physically addressed 848 * @phys_addr_channels: Number of channels with physically addressed
847 * descriptors 849 * descriptors
850 * @timer_period_max: Maximum period of interrupt timer (in ticks)
848 * @tx_dc_base: Base address in SRAM of TX queue descriptor caches 851 * @tx_dc_base: Base address in SRAM of TX queue descriptor caches
849 * @rx_dc_base: Base address in SRAM of RX queue descriptor caches 852 * @rx_dc_base: Base address in SRAM of RX queue descriptor caches
850 * @offload_features: net_device feature flags for protocol offload 853 * @offload_features: net_device feature flags for protocol offload
@@ -889,6 +892,7 @@ struct efx_nic_type {
889 unsigned int rx_buffer_padding; 892 unsigned int rx_buffer_padding;
890 unsigned int max_interrupt_mode; 893 unsigned int max_interrupt_mode;
891 unsigned int phys_addr_channels; 894 unsigned int phys_addr_channels;
895 unsigned int timer_period_max;
892 unsigned int tx_dc_base; 896 unsigned int tx_dc_base;
893 unsigned int rx_dc_base; 897 unsigned int rx_dc_base;
894 netdev_features_t offload_features; 898 netdev_features_t offload_features;
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index cfda6ded24fe..a3ccd0b9d78d 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -205,9 +205,6 @@ extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx);
205extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id); 205extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id);
206extern void falcon_irq_ack_a1(struct efx_nic *efx); 206extern void falcon_irq_ack_a1(struct efx_nic *efx);
207 207
208#define EFX_IRQ_MOD_RESOLUTION 5
209#define EFX_IRQ_MOD_MAX 0x1000
210
211/* Global Resources */ 208/* Global Resources */
212extern int efx_nic_flush_queues(struct efx_nic *efx); 209extern int efx_nic_flush_queues(struct efx_nic *efx);
213extern void falcon_start_nic_stats(struct efx_nic *efx); 210extern void falcon_start_nic_stats(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index 65cb5e4f4264..f05425842b31 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -35,8 +35,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel)
35{ 35{
36 efx_dword_t timer_cmd; 36 efx_dword_t timer_cmd;
37 37
38 BUILD_BUG_ON(EFX_IRQ_MOD_MAX > (1 << FRF_CZ_TC_TIMER_VAL_WIDTH));
39
40 if (channel->irq_moderation) 38 if (channel->irq_moderation)
41 EFX_POPULATE_DWORD_2(timer_cmd, 39 EFX_POPULATE_DWORD_2(timer_cmd,
42 FRF_CZ_TC_TIMER_MODE, 40 FRF_CZ_TC_TIMER_MODE,
@@ -216,7 +214,15 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method)
216 214
217static int siena_probe_nvconfig(struct efx_nic *efx) 215static int siena_probe_nvconfig(struct efx_nic *efx)
218{ 216{
219 return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, NULL); 217 u32 caps = 0;
218 int rc;
219
220 rc = efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, &caps);
221
222 efx->timer_quantum_ns =
223 (caps & (1 << MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN)) ?
224 3072 : 6144; /* 768 cycles */
225 return rc;
220} 226}
221 227
222static int siena_probe_nic(struct efx_nic *efx) 228static int siena_probe_nic(struct efx_nic *efx)
@@ -644,6 +650,7 @@ const struct efx_nic_type siena_a0_nic_type = {
644 .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy 650 .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy
645 * interrupt handler only supports 32 651 * interrupt handler only supports 32
646 * channels */ 652 * channels */
653 .timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH,
647 .tx_dc_base = 0x88000, 654 .tx_dc_base = 0x88000,
648 .rx_dc_base = 0x68000, 655 .rx_dc_base = 0x68000,
649 .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 656 .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |