Skip to contentSkip to conversation

enc28j60: Fix sporadic packet loss

PATCH In review Baruch Siach 2 participants 2 messages Dec 2, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 enc28j60: Fix sporadic packet loss

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.

---

net/enc28j60.c renamed from net/enc28j60.c-git +14 -2
@@ -568,6 +568,17 @@ static u16 erxrdpt_workaround(u16 next_p
 	return erxrdpt;
 }
 
+/*
+ * Calculate wrap arround 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;
+}
+
 static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
 {
 	u16 erxrdpt;
@@ -938,8 +949,9 @@ static void enc28j60_hw_rx(struct net_de
 			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);
Signature · 3 lines
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - [email protected] - tel: +972.2.679.5364, http://www.tkos.co.il -
Acked-by on v1 1/1
#1 lore raw
Quoted 2 lines · Baruch Siach

+/*
+ * Calculate wrap arround when reading beyond the end of the RX buffer

                      ^

net/enc28j60.c static u16 erxrdpt_workaround(u16 next_p · line 580

Quoted 8 lines

+ */

net/enc28j60.c renamed from net/enc28j60.c-git +7 -0
+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;
+}

should be
...

	else
		return ptr + RSV_SIZE;

With this change you can add the line

Cheers,
Claudio