diff options
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r-- | drivers/net/sfc/efx.c | 89 |
1 files changed, 38 insertions, 51 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index cc4b2f99989d..0d0243b7ac34 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -228,26 +228,20 @@ static int efx_poll(struct napi_struct *napi, int budget) if (channel->used_flags & EFX_USED_BY_RX && efx->irq_rx_adaptive && unlikely(++channel->irq_count == 1000)) { - unsigned old_irq_moderation = channel->irq_moderation; - if (unlikely(channel->irq_mod_score < irq_adapt_low_thresh)) { - channel->irq_moderation = - max_t(int, - channel->irq_moderation - - FALCON_IRQ_MOD_RESOLUTION, - FALCON_IRQ_MOD_RESOLUTION); + if (channel->irq_moderation > 1) { + channel->irq_moderation -= 1; + falcon_set_int_moderation(channel); + } } else if (unlikely(channel->irq_mod_score > irq_adapt_high_thresh)) { - channel->irq_moderation = - min(channel->irq_moderation + - FALCON_IRQ_MOD_RESOLUTION, - efx->irq_rx_moderation); + if (channel->irq_moderation < + efx->irq_rx_moderation) { + channel->irq_moderation += 1; + falcon_set_int_moderation(channel); + } } - - if (channel->irq_moderation != old_irq_moderation) - falcon_set_int_moderation(channel); - channel->irq_count = 0; channel->irq_mod_score = 0; } @@ -290,7 +284,7 @@ void efx_process_channel_now(struct efx_channel *channel) napi_disable(&channel->napi_str); /* Poll the channel */ - efx_process_channel(channel, efx->type->evq_size); + efx_process_channel(channel, EFX_EVQ_SIZE); /* Ack the eventq. This may cause an interrupt to be generated * when they are reenabled */ @@ -824,9 +818,8 @@ static int efx_init_io(struct efx_nic *efx) goto fail2; } - efx->membase_phys = pci_resource_start(efx->pci_dev, - efx->type->mem_bar); - rc = pci_request_region(pci_dev, efx->type->mem_bar, "sfc"); + efx->membase_phys = pci_resource_start(efx->pci_dev, EFX_MEM_BAR); + rc = pci_request_region(pci_dev, EFX_MEM_BAR, "sfc"); if (rc) { EFX_ERR(efx, "request for memory BAR failed\n"); rc = -EIO; @@ -835,21 +828,20 @@ static int efx_init_io(struct efx_nic *efx) efx->membase = ioremap_nocache(efx->membase_phys, efx->type->mem_map_size); if (!efx->membase) { - EFX_ERR(efx, "could not map memory BAR %d at %llx+%x\n", - efx->type->mem_bar, + EFX_ERR(efx, "could not map memory BAR at %llx+%x\n", (unsigned long long)efx->membase_phys, efx->type->mem_map_size); rc = -ENOMEM; goto fail4; } - EFX_LOG(efx, "memory BAR %u at %llx+%x (virtual %p)\n", - efx->type->mem_bar, (unsigned long long)efx->membase_phys, + EFX_LOG(efx, "memory BAR at %llx+%x (virtual %p)\n", + (unsigned long long)efx->membase_phys, efx->type->mem_map_size, efx->membase); return 0; fail4: - pci_release_region(efx->pci_dev, efx->type->mem_bar); + pci_release_region(efx->pci_dev, EFX_MEM_BAR); fail3: efx->membase_phys = 0; fail2: @@ -868,7 +860,7 @@ static void efx_fini_io(struct efx_nic *efx) } if (efx->membase_phys) { - pci_release_region(efx->pci_dev, efx->type->mem_bar); + pci_release_region(efx->pci_dev, EFX_MEM_BAR); efx->membase_phys = 0; } @@ -1220,22 +1212,33 @@ void efx_flush_queues(struct efx_nic *efx) * **************************************************************************/ +static unsigned irq_mod_ticks(int usecs, int resolution) +{ + if (usecs <= 0) + return 0; /* cannot receive interrupts ahead of time :-) */ + if (usecs < resolution) + return 1; /* never round down to 0 */ + return usecs / resolution; +} + /* Set interrupt moderation parameters */ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, bool rx_adaptive) { struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; + unsigned tx_ticks = irq_mod_ticks(tx_usecs, FALCON_IRQ_MOD_RESOLUTION); + unsigned rx_ticks = irq_mod_ticks(rx_usecs, FALCON_IRQ_MOD_RESOLUTION); EFX_ASSERT_RESET_SERIALISED(efx); efx_for_each_tx_queue(tx_queue, efx) - tx_queue->channel->irq_moderation = tx_usecs; + tx_queue->channel->irq_moderation = tx_ticks; efx->irq_rx_adaptive = rx_adaptive; - efx->irq_rx_moderation = rx_usecs; + efx->irq_rx_moderation = rx_ticks; efx_for_each_rx_queue(rx_queue, efx) - rx_queue->channel->irq_moderation = rx_usecs; + rx_queue->channel->irq_moderation = rx_ticks; } /************************************************************************** @@ -1981,17 +1984,9 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, efx->type = type; - /* Sanity-check NIC type */ - EFX_BUG_ON_PARANOID(efx->type->txd_ring_mask & - (efx->type->txd_ring_mask + 1)); - EFX_BUG_ON_PARANOID(efx->type->rxd_ring_mask & - (efx->type->rxd_ring_mask + 1)); - EFX_BUG_ON_PARANOID(efx->type->evq_size & - (efx->type->evq_size - 1)); /* As close as we can get to guaranteeing that we don't overflow */ - EFX_BUG_ON_PARANOID(efx->type->evq_size < - (efx->type->txd_ring_mask + 1 + - efx->type->rxd_ring_mask + 1)); + BUILD_BUG_ON(EFX_EVQ_SIZE < EFX_TXQ_SIZE + EFX_RXQ_SIZE); + EFX_BUG_ON_PARANOID(efx->type->phys_addr_channels > EFX_MAX_CHANNELS); /* Higher numbered interrupt modes are less capable! */ @@ -2027,18 +2022,12 @@ static void efx_fini_struct(struct efx_nic *efx) */ static void efx_pci_remove_main(struct efx_nic *efx) { - EFX_ASSERT_RESET_SERIALISED(efx); - - /* Skip everything if we never obtained a valid membase */ - if (!efx->membase) - return; - + falcon_fini_interrupt(efx); efx_fini_channels(efx); efx_fini_port(efx); /* Shutdown the board, then the NIC and board state */ efx->board_info.fini(efx); - falcon_fini_interrupt(efx); efx_fini_napi(efx); efx_remove_all(efx); @@ -2063,9 +2052,6 @@ static void efx_pci_remove(struct pci_dev *pci_dev) /* Allow any queued efx_resets() to complete */ rtnl_unlock(); - if (efx->membase == NULL) - goto out; - efx_unregister_netdev(efx); efx_mtd_remove(efx); @@ -2078,7 +2064,6 @@ static void efx_pci_remove(struct pci_dev *pci_dev) efx_pci_remove_main(efx); -out: efx_fini_io(efx); EFX_LOG(efx, "shutdown successful\n"); @@ -2224,13 +2209,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, * MAC stats succeeds. */ efx->state = STATE_RUNNING; - efx_mtd_probe(efx); /* allowed to fail */ - rc = efx_register_netdev(efx); if (rc) goto fail5; EFX_LOG(efx, "initialisation successful\n"); + + rtnl_lock(); + efx_mtd_probe(efx); /* allowed to fail */ + rtnl_unlock(); return 0; fail5: |