mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/2] usb: net: ax88179_178a: sync reset and rx with upstream
@ 2025-08-13  7:52 Stefan Kerkmann
  2025-08-13  7:52 ` [PATCH 1/2] net: usb: ax88179_178a: align rx_fixup " Stefan Kerkmann
  2025-08-13  7:52 ` [PATCH 2/2] net: usb: ax88179_178a: align reset " Stefan Kerkmann
  0 siblings, 2 replies; 3+ messages in thread
From: Stefan Kerkmann @ 2025-08-13  7:52 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Stefan Kerkmann

These patches are the result of investigating dropped packages while
working with an AX88179A based UGREEN USB ethernet adapter. The main
improvements are bounds and consistency checking in the RX path. What I
couldn't fix at the moment is that the adapter sometimes stops receiving
packets after a "warm reset" of the device which doesn't power cycle the
device e.g. chain loading barebox via tftp without a power cycle of the
whole USB bus and devices.

I tried the following U-Boot commits, but they didn't fix the issue.

- 9713c15d2e6 ("eth: asix88179: Fix ASIX AX88179A PHY hang")
- 1bd136715a4 ("eth: asix88179: reset during probe")

What helps in the situation is physically re-plugging the ethernet
cable, which triggers a link reset in software. This link reset also
happens while opening the device so I'm suspecting a bug in the
controller itself (or there are still some missing reset instructions).
The Realtek RTL8153 chipsets seem handle this situation better, so it is
adviced to use them in a "warm reset" scenario until this is fixed.

Signed-off-by: Stefan Kerkmann <s.kerkmann@pengutronix.de>
---
Stefan Kerkmann (2):
      net: usb: ax88179_178a: align rx_fixup with upstream
      net: usb: ax88179_178a: align reset with upstream

 drivers/net/usb/ax88179_178a.c | 79 ++++++++++++++++++++++++++++++------------
 1 file changed, 57 insertions(+), 22 deletions(-)
---
base-commit: ed59f724912d0b4a86f88fa318836260c88271d1
change-id: 20250813-fix-ax88179_178a-dropped-packets-39cbcd9f2c87

Best regards,
-- 
Stefan Kerkmann <s.kerkmann@pengutronix.de>




^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] net: usb: ax88179_178a: align rx_fixup with upstream
  2025-08-13  7:52 [PATCH 0/2] usb: net: ax88179_178a: sync reset and rx with upstream Stefan Kerkmann
@ 2025-08-13  7:52 ` Stefan Kerkmann
  2025-08-13  7:52 ` [PATCH 2/2] net: usb: ax88179_178a: align reset " Stefan Kerkmann
  1 sibling, 0 replies; 3+ messages in thread
From: Stefan Kerkmann @ 2025-08-13  7:52 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Stefan Kerkmann

This aligns the ax88179_rx_fixup path with the latest linux upstream
version 61997271a5a7d ("net: usb: asix: ax88772: Increase phy_name
size").

Signed-off-by: Stefan Kerkmann <s.kerkmann@pengutronix.de>
---
 drivers/net/usb/ax88179_178a.c | 73 +++++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 22 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 0cf2635b77f86c9713dd5ed67d8ccf9bc30c45dd..78b5d943a4ecafab025ba3f8cc44293d16f31eb8 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -435,46 +435,75 @@ static void ax88179_unbind(struct usbnet *dev)
 
 static int ax88179_rx_fixup(struct usbnet *dev, void *buf, int len)
 {
-	int pkt_cnt, frame_pos;
-	u32 rx_hdr;
-	u16 hdr_off;
+	u16 hdr_off, pkt_len, pkt_len_plus_padd;
+	u32 rx_hdr, hdr;
+	u8 *pos = buf;
 	u32 *pkt_hdr;
+	int pkt_cnt;
 
 	if (len == dev->rx_urb_size) {
-		dev_err(&dev->udev->dev, "broken package\n");
+		dev_err(&dev->udev->dev, "%s: broken packet\n", __func__);
 		return 0;
 	}
 
-	rx_hdr = get_unaligned_le32(buf + len - 4);
+	if (len < sizeof(rx_hdr)) {
+		dev_err(&dev->udev->dev, "%s: short packet\n", __func__);
+		return 0;
+	}
+
+	rx_hdr = get_unaligned_le32(buf + len - sizeof(rx_hdr));
+	pkt_cnt = lower_16_bits(rx_hdr);
+	hdr_off = upper_16_bits(rx_hdr);
+
+	if (pkt_cnt == 0)
+		return 0;
+
+	if ((pkt_cnt * sizeof(*pkt_hdr) + hdr_off) > (len - sizeof(rx_hdr))) {
+		dev_err(&dev->udev->dev,
+			"%s: malformed metadata: pkt_cnt: %d hdr_off: %d len: %d\n",
+			__func__, pkt_cnt, hdr_off, len);
+		return 0;
+	}
 
-	pkt_cnt = (u16)rx_hdr;
-	hdr_off = (u16)(rx_hdr >> 16);
 	pkt_hdr = (u32 *)(buf + hdr_off);
 
-	frame_pos = 0;
+	/* Packets must not overlap the metadata array */
+	len = hdr_off;
 
-	while (pkt_cnt--) {
-		u16 pkt_len;
-		u32 hdr = le32_to_cpup(pkt_hdr);
+	for (; pkt_cnt > 0; pkt_cnt--, pkt_hdr++) {
+		hdr = le32_to_cpup(pkt_hdr);
+		pkt_len = upper_16_bits(hdr) & GENMASK(12, 0);
+		pkt_len_plus_padd = (pkt_len + 7) & GENMASK(15, 3);
 
-		pkt_len = (hdr >> 16) & 0x1fff;
+		/* Skip dummy header used for alignment */
+		if (pkt_len == 0)
+			continue;
+
+		if (pkt_len_plus_padd > len) {
+			dev_dbg(&dev->udev->dev,
+				"%s: packet too large: %d > %d\n", __func__,
+				pkt_len_plus_padd, len);
+			return 0;
+		}
 
 		/* Check CRC or runt packet */
-		if ((hdr & AX_RXHDR_CRC_ERR) ||
-		    (hdr & AX_RXHDR_DROP_ERR)) {
-			pkt_hdr++;
+		if ((hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) ||
+		    pkt_len < sizeof(u16) + ETH_HLEN) {
+			dev_dbg(&dev->udev->dev,
+				"%s: dropping packet: hdr: 0x%08x len: %d\n",
+				__func__, hdr, pkt_len);
+			pos += pkt_len_plus_padd;
+			len -= pkt_len_plus_padd;
 			continue;
 		}
 
-		frame_pos += 2;
+		dev_dbg(&dev->udev->dev, "%s: loop: frame_pos: %td len: %d\n",
+			__func__, pos - (u8 *)buf, pkt_len);
 
-		dev_dbg(&dev->udev->dev, "%s: loop: frame_pos: %d len: %d\n",
-			__func__, frame_pos, pkt_len);
+		net_receive(&dev->edev, pos + sizeof(u16), pkt_len);
 
-		net_receive(&dev->edev, buf + frame_pos, pkt_len);
-
-		pkt_hdr++;
-		frame_pos += ((pkt_len + 7) & 0xfff8) - 2;
+		pos += pkt_len_plus_padd;
+		len -= pkt_len_plus_padd;
 	}
 
 	return 0;

-- 
2.39.5




^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/2] net: usb: ax88179_178a: align reset with upstream
  2025-08-13  7:52 [PATCH 0/2] usb: net: ax88179_178a: sync reset and rx with upstream Stefan Kerkmann
  2025-08-13  7:52 ` [PATCH 1/2] net: usb: ax88179_178a: align rx_fixup " Stefan Kerkmann
@ 2025-08-13  7:52 ` Stefan Kerkmann
  1 sibling, 0 replies; 3+ messages in thread
From: Stefan Kerkmann @ 2025-08-13  7:52 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Stefan Kerkmann

This aligns the ax88179_reset function with the latest linux upstream
version 61997271a5a7d ("net: usb: asix: ax88772: Increase phy_name
size").

Signed-off-by: Stefan Kerkmann <s.kerkmann@pengutronix.de>
---
 drivers/net/usb/ax88179_178a.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 78b5d943a4ecafab025ba3f8cc44293d16f31eb8..ef413c7973693052ea161487cab15f7ee3f74a0d 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -643,6 +643,12 @@ static int ax88179_reset(struct usbnet *dev)
 	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
 			  2, 2, &tmp16);
 
+	/* Restart auto-negotiation */
+	tmp16 = 0;
+	ax88179_read_cmd(dev, AX_ACCESS_PHY, 0x03, MII_BMCR, 2, &tmp16);
+	tmp16 |= BMCR_ANENABLE | BMCR_ANRESTART;
+	ax88179_write_cmd(dev, AX_ACCESS_PHY, 0x03, MII_BMCR, 2, &tmp16);
+
 	return 0;
 }
 

-- 
2.39.5




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-08-13  8:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-13  7:52 [PATCH 0/2] usb: net: ax88179_178a: sync reset and rx with upstream Stefan Kerkmann
2025-08-13  7:52 ` [PATCH 1/2] net: usb: ax88179_178a: align rx_fixup " Stefan Kerkmann
2025-08-13  7:52 ` [PATCH 2/2] net: usb: ax88179_178a: align reset " Stefan Kerkmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox