Skip to content

Commit

Permalink
enc28j60: Fix sporadic packet loss (corrected again)
Browse files Browse the repository at this point in the history
Packet data read from the RX buffer the when the RSV is at the end of the RX
buffer does not warp around. This causes packet loss, as the actual data is
never read. Fix this by calculating the right packet data location.

Thanks to Shachar Shemesh for suggesting the fix.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Acked-by: Claudio Lanconelli <lanconelli.claudio@eptar.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Baruch Siach authored and David S. Miller committed Dec 4, 2008
1 parent bd09141 commit 5176da7
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions drivers/net/enc28j60.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,17 @@ static u16 erxrdpt_workaround(u16 next_packet_ptr, u16 start, u16 end)
return erxrdpt;
}

/*
* Calculate wrap around when reading beyond the end of the RX buffer
*/
static u16 rx_packet_start(u16 ptr)
{
if (ptr + RSV_SIZE > RXEND_INIT)
return (ptr + RSV_SIZE) - (RXEND_INIT - RXSTART_INIT + 1);
else
return ptr + RSV_SIZE;
}

static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
{
u16 erxrdpt;
Expand Down Expand Up @@ -938,8 +949,9 @@ static void enc28j60_hw_rx(struct net_device *ndev)
skb->dev = ndev;
skb_reserve(skb, NET_IP_ALIGN);
/* copy the packet from the receive buffer */
enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv),
len, skb_put(skb, len));
enc28j60_mem_read(priv,
rx_packet_start(priv->next_pk_ptr),
len, skb_put(skb, len));
if (netif_msg_pktdata(priv))
dump_packet(__func__, skb->len, skb->data);
skb->protocol = eth_type_trans(skb, ndev);
Expand Down

0 comments on commit 5176da7

Please sign in to comment.