diff options
author | Steve Hodgson <shodgson@solarflare.com> | 2010-09-10 08:42:22 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-10 21:27:33 +0200 |
commit | ecc910f520ba8f22848982ee816ad75c449b805d (patch) | |
tree | e934380209532b831b7e7e334ddc33d75db7eef5 /drivers/net/sfc/efx.c | |
parent | sfc: Allocate each channel separately, along with its RX and TX queues (diff) | |
download | linux-ecc910f520ba8f22848982ee816ad75c449b805d.tar.xz linux-ecc910f520ba8f22848982ee816ad75c449b805d.zip |
sfc: Make the dmaq size a run-time setting (rather than compile-time)
- Allow the ring size to be specified in non
power-of-two sizes (for instance to limit
the amount of receive buffers).
- Automatically size the event queue.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r-- | drivers/net/sfc/efx.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 4b42e61e3c7d..6166e2207160 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -348,7 +348,7 @@ void efx_process_channel_now(struct efx_channel *channel) napi_disable(&channel->napi_str); /* Poll the channel */ - efx_process_channel(channel, EFX_EVQ_SIZE); + efx_process_channel(channel, channel->eventq_mask + 1); /* Ack the eventq. This may cause an interrupt to be generated * when they are reenabled */ @@ -365,9 +365,18 @@ void efx_process_channel_now(struct efx_channel *channel) */ static int efx_probe_eventq(struct efx_channel *channel) { + struct efx_nic *efx = channel->efx; + unsigned long entries; + netif_dbg(channel->efx, probe, channel->efx->net_dev, "chan %d create event queue\n", channel->channel); + /* Build an event queue with room for one event per tx and rx buffer, + * plus some extra for link state events and MCDI completions. */ + entries = roundup_pow_of_two(efx->rxq_entries + efx->txq_entries + 128); + EFX_BUG_ON_PARANOID(entries > EFX_MAX_EVQ_SIZE); + channel->eventq_mask = max(entries, EFX_MIN_EVQ_SIZE) - 1; + return efx_nic_probe_eventq(channel); } @@ -1191,6 +1200,7 @@ static int efx_probe_all(struct efx_nic *efx) } /* Create channels */ + efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; efx_for_each_channel(channel, efx) { rc = efx_probe_channel(channel); if (rc) { @@ -2101,9 +2111,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, efx->type = type; - /* As close as we can get to guaranteeing that we don't overflow */ - 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! */ |