diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 11:47:02 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 11:47:02 -0700 |
commit | 5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch) | |
tree | 7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /drivers/net/sfc/rx.c | |
parent | 02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff) | |
parent | ec37a48d1d16c30b655ac5280209edf52a6775d4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits)
bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL.
vlan: Calling vlan_hwaccel_do_receive() is always valid.
tproxy: use the interface primary IP address as a default value for --on-ip
tproxy: added IPv6 support to the socket match
cxgb3: function namespace cleanup
tproxy: added IPv6 support to the TPROXY target
tproxy: added IPv6 socket lookup function to nf_tproxy_core
be2net: Changes to use only priority codes allowed by f/w
tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
tproxy: added tproxy sockopt interface in the IPV6 layer
tproxy: added udp6_lib_lookup function
tproxy: added const specifiers to udp lookup functions
tproxy: split off ipv6 defragmentation to a separate module
l2tp: small cleanup
nf_nat: restrict ICMP translation for embedded header
can: mcp251x: fix generation of error frames
can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
can-raw: add msg_flags to distinguish local traffic
9p: client code cleanup
rds: make local functions/variables static
...
Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and
drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'drivers/net/sfc/rx.c')
-rw-r--r-- | drivers/net/sfc/rx.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 799c461ce7b8..6d0959b5158e 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -133,7 +133,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) unsigned index, count; for (count = 0; count < EFX_RX_BATCH; ++count) { - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->skb = netdev_alloc_skb(net_dev, skb_len); @@ -208,7 +208,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) dma_addr += sizeof(struct efx_rx_page_state); split: - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->skb = NULL; @@ -285,7 +285,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, * we'd like to insert an additional descriptor whilst leaving * EFX_RXD_HEAD_ROOM for the non-recycle path */ fill_level = (rx_queue->added_count - rx_queue->removed_count + 2); - if (unlikely(fill_level >= EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM)) { + if (unlikely(fill_level > rx_queue->max_fill)) { /* We could place "state" on a list, and drain the list in * efx_fast_push_rx_descriptors(). For now, this will do. */ return; @@ -294,7 +294,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, ++state->refcnt; get_page(rx_buf->page); - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); new_buf->skb = NULL; @@ -311,7 +311,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) { struct efx_nic *efx = channel->efx; - struct efx_rx_queue *rx_queue = &efx->rx_queue[channel->channel]; + struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel); struct efx_rx_buffer *new_buf; unsigned index; @@ -319,7 +319,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, page_count(rx_buf->page) == 1) efx_resurrect_rx_buffer(rx_queue, rx_buf); - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); memcpy(new_buf, rx_buf, sizeof(*new_buf)); @@ -341,13 +341,13 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, */ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) { - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); unsigned fill_level; int space, rc = 0; /* Calculate current fill level, and exit if we don't need to fill */ fill_level = (rx_queue->added_count - rx_queue->removed_count); - EFX_BUG_ON_PARANOID(fill_level > EFX_RXQ_SIZE); + EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries); if (fill_level >= rx_queue->fast_fill_trigger) goto out; @@ -364,7 +364,8 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filling descriptor ring from" " level %d to level %d using %s allocation\n", - rx_queue->queue, fill_level, rx_queue->fast_fill_limit, + efx_rx_queue_index(rx_queue), fill_level, + rx_queue->fast_fill_limit, channel->rx_alloc_push_pages ? "page" : "skb"); do { @@ -382,7 +383,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filled descriptor ring " - "to level %d\n", rx_queue->queue, + "to level %d\n", efx_rx_queue_index(rx_queue), rx_queue->added_count - rx_queue->removed_count); out: @@ -393,7 +394,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) void efx_rx_slow_fill(unsigned long context) { struct efx_rx_queue *rx_queue = (struct efx_rx_queue *)context; - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); /* Post an event to cause NAPI to run and refill the queue */ efx_nic_generate_fill_event(channel); @@ -421,7 +422,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, netif_err(efx, rx_err, efx->net_dev, " RX queue %d seriously overlength " "RX event (0x%x > 0x%x+0x%x). Leaking\n", - rx_queue->queue, len, max_len, + efx_rx_queue_index(rx_queue), len, max_len, efx->type->rx_buffer_padding); /* If this buffer was skb-allocated, then the meta * data at the end of the skb will be trashed. So @@ -434,10 +435,10 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, netif_err(efx, rx_err, efx->net_dev, " RX queue %d overlength RX event " "(0x%x > 0x%x)\n", - rx_queue->queue, len, max_len); + efx_rx_queue_index(rx_queue), len, max_len); } - rx_queue->channel->n_rx_overlength++; + efx_rx_queue_channel(rx_queue)->n_rx_overlength++; } /* Pass a received packet up through the generic LRO stack @@ -507,7 +508,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, unsigned int len, bool checksummed, bool discard) { struct efx_nic *efx = rx_queue->efx; - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_rx_buffer *rx_buf; bool leak_packet = false; @@ -528,7 +529,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, netif_vdbg(efx, rx_status, efx->net_dev, "RX queue %d received id %x at %llx+%x %s%s\n", - rx_queue->queue, index, + efx_rx_queue_index(rx_queue), index, (unsigned long long)rx_buf->dma_addr, len, (checksummed ? " [SUMMED]" : ""), (discard ? " [DISCARD]" : "")); @@ -560,12 +561,11 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, */ rx_buf->len = len; out: - if (rx_queue->channel->rx_pkt) - __efx_rx_packet(rx_queue->channel, - rx_queue->channel->rx_pkt, - rx_queue->channel->rx_pkt_csummed); - rx_queue->channel->rx_pkt = rx_buf; - rx_queue->channel->rx_pkt_csummed = checksummed; + if (channel->rx_pkt) + __efx_rx_packet(channel, + channel->rx_pkt, channel->rx_pkt_csummed); + channel->rx_pkt = rx_buf; + channel->rx_pkt_csummed = checksummed; } /* Handle a received packet. Second half: Touches packet payload. */ @@ -615,7 +615,7 @@ void __efx_rx_packet(struct efx_channel *channel, EFX_BUG_ON_PARANOID(!skb); /* Set the SKB flags */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Pass the packet up */ netif_receive_skb(skb); @@ -650,15 +650,22 @@ void efx_rx_strategy(struct efx_channel *channel) int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; - unsigned int rxq_size; + unsigned int entries; int rc; + /* Create the smallest power-of-two aligned ring */ + entries = max(roundup_pow_of_two(efx->rxq_entries), EFX_MIN_DMAQ_SIZE); + EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE); + rx_queue->ptr_mask = entries - 1; + netif_dbg(efx, probe, efx->net_dev, - "creating RX queue %d\n", rx_queue->queue); + "creating RX queue %d size %#x mask %#x\n", + efx_rx_queue_index(rx_queue), efx->rxq_entries, + rx_queue->ptr_mask); /* Allocate RX buffers */ - rxq_size = EFX_RXQ_SIZE * sizeof(*rx_queue->buffer); - rx_queue->buffer = kzalloc(rxq_size, GFP_KERNEL); + rx_queue->buffer = kzalloc(entries * sizeof(*rx_queue->buffer), + GFP_KERNEL); if (!rx_queue->buffer) return -ENOMEM; @@ -672,20 +679,20 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) void efx_init_rx_queue(struct efx_rx_queue *rx_queue) { + struct efx_nic *efx = rx_queue->efx; unsigned int max_fill, trigger, limit; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "initialising RX queue %d\n", rx_queue->queue); + "initialising RX queue %d\n", efx_rx_queue_index(rx_queue)); /* Initialise ptr fields */ rx_queue->added_count = 0; rx_queue->notified_count = 0; rx_queue->removed_count = 0; rx_queue->min_fill = -1U; - rx_queue->min_overfill = -1U; /* Initialise limit fields */ - max_fill = EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM; + max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM; trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; limit = max_fill * min(rx_refill_limit, 100U) / 100U; @@ -703,14 +710,14 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) struct efx_rx_buffer *rx_buf; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "shutting down RX queue %d\n", rx_queue->queue); + "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue)); del_timer_sync(&rx_queue->slow_fill); efx_nic_fini_rx(rx_queue); /* Release RX buffers NB start at index 0 not current HW ptr */ if (rx_queue->buffer) { - for (i = 0; i <= EFX_RXQ_MASK; i++) { + for (i = 0; i <= rx_queue->ptr_mask; i++) { rx_buf = efx_rx_buffer(rx_queue, i); efx_fini_rx_buffer(rx_queue, rx_buf); } @@ -720,7 +727,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) void efx_remove_rx_queue(struct efx_rx_queue *rx_queue) { netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "destroying RX queue %d\n", rx_queue->queue); + "destroying RX queue %d\n", efx_rx_queue_index(rx_queue)); efx_nic_remove_rx(rx_queue); |