aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2010-06-25 07:05:33 +0000
committerDavid S. Miller <davem@davemloft.net>2010-06-25 21:03:30 -0700
commit604f6049ba2af86fe361d4cc320443d35b232df1 (patch)
tree21c5cc57e19fb477f86b67170c0eb1c0ff0fe1cf /drivers/net/sfc
parent29046f9b1e36f6e3332ce2d8e366005fd177b37a (diff)
sfc: Fix reading of inserted hash
The hash appears immediately before the packet data, not at the beginning of the buffer. This means we can easily use negative offsets from the start of packet data, so adjust the data and length at the top of __efx_rx_packet() instead of wherever we consume the hash. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/rx.c11
-rw-r--r--drivers/net/sfc/selftest.c3
2 files changed, 6 insertions, 8 deletions
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 0fb98355a09..799c461ce7b 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -104,9 +104,9 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
static inline u32 efx_rx_buf_hash(struct efx_rx_buffer *buf)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) || NET_IP_ALIGN % 4 == 0
- return __le32_to_cpup((const __le32 *)buf->data);
+ return __le32_to_cpup((const __le32 *)(buf->data - 4));
#else
- const u8 *data = (const u8 *)buf->data;
+ const u8 *data = (const u8 *)(buf->data - 4);
return ((u32)data[0] |
(u32)data[1] << 8 |
(u32)data[2] << 16 |
@@ -469,8 +469,6 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
if (efx->net_dev->features & NETIF_F_RXHASH)
skb->rxhash = efx_rx_buf_hash(rx_buf);
- rx_buf->data += efx->type->rx_buffer_hash_size;
- rx_buf->len -= efx->type->rx_buffer_hash_size;
skb_shinfo(skb)->frags[0].page = page;
skb_shinfo(skb)->frags[0].page_offset =
@@ -577,6 +575,9 @@ void __efx_rx_packet(struct efx_channel *channel,
struct efx_nic *efx = channel->efx;
struct sk_buff *skb;
+ rx_buf->data += efx->type->rx_buffer_hash_size;
+ rx_buf->len -= efx->type->rx_buffer_hash_size;
+
/* If we're in loopback test, then pass the packet directly to the
* loopback layer, and free the rx_buf here
*/
@@ -589,11 +590,11 @@ void __efx_rx_packet(struct efx_channel *channel,
if (rx_buf->skb) {
prefetch(skb_shinfo(rx_buf->skb));
+ skb_reserve(rx_buf->skb, efx->type->rx_buffer_hash_size);
skb_put(rx_buf->skb, rx_buf->len);
if (efx->net_dev->features & NETIF_F_RXHASH)
rx_buf->skb->rxhash = efx_rx_buf_hash(rx_buf);
- skb_pull(rx_buf->skb, efx->type->rx_buffer_hash_size);
/* Move past the ethernet header. rx_buf->data still points
* at the ethernet header */
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 0399be21c12..85f015f005d 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -258,9 +258,6 @@ void efx_loopback_rx_packet(struct efx_nic *efx,
payload = &state->payload;
- buf_ptr += efx->type->rx_buffer_hash_size;
- pkt_len -= efx->type->rx_buffer_hash_size;
-
received = (struct efx_loopback_payload *) buf_ptr;
received->ip.saddr = payload->ip.saddr;
if (state->offload_csum)