Module Name:    src
Committed By:   nonaka
Date:           Wed Dec 21 05:19:15 UTC 2022

Modified Files:
        src/sys/dev/pci: if_rge.c if_rgereg.h

Log Message:
Update the Rx descriptor based on the vendor driver for Linux.

This fixes a panic on RTL8125.
Patch from OpenBSD if_rge.c r1.20, if_rgereg.h r1.8.

Tested by msaitoh@n.o.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/pci/if_rge.c
cvs rdiff -u -r1.6 -r1.7 src/sys/dev/pci/if_rgereg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_rge.c
diff -u src/sys/dev/pci/if_rge.c:1.24 src/sys/dev/pci/if_rge.c:1.25
--- src/sys/dev/pci/if_rge.c:1.24	Sat Sep 24 18:12:42 2022
+++ src/sys/dev/pci/if_rge.c	Wed Dec 21 05:19:15 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_rge.c,v 1.24 2022/09/24 18:12:42 thorpej Exp $	*/
+/*	$NetBSD: if_rge.c,v 1.25 2022/12/21 05:19:15 nonaka Exp $	*/
 /*	$OpenBSD: if_rge.c,v 1.9 2020/12/12 11:48:53 jan Exp $	*/
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_rge.c,v 1.24 2022/09/24 18:12:42 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_rge.c,v 1.25 2022/12/21 05:19:15 nonaka Exp $");
 
 #include <sys/types.h>
 
@@ -1132,22 +1132,16 @@ rge_newbuf(struct rge_softc *sc, int idx
 	/* Map the segments into RX descriptors. */
 	r = &sc->rge_ldata.rge_rx_list[idx];
 
-	if (RGE_OWN(r)) {
-		device_printf(sc->sc_dev, "tried to map busy RX descriptor\n");
-		goto out;
-	}
-
 	rxq->rxq_mbuf = m;
 
-	r->rge_extsts = 0;
-	r->rge_addrlo = htole32(RGE_ADDR_LO(rxmap->dm_segs[0].ds_addr));
-	r->rge_addrhi = htole32(RGE_ADDR_HI(rxmap->dm_segs[0].ds_addr));
+	r->hi_qword1.rx_qword4.rge_extsts = 0;
+	r->hi_qword0.rge_addr = htole64(rxmap->dm_segs[0].ds_addr);
 
-	r->rge_cmdsts = htole32(rxmap->dm_segs[0].ds_len);
+	r->hi_qword1.rx_qword4.rge_cmdsts = htole32(rxmap->dm_segs[0].ds_len);
 	if (idx == RGE_RX_LIST_CNT - 1)
-		r->rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
+		r->hi_qword1.rx_qword4.rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
 
-	r->rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
+	r->hi_qword1.rx_qword4.rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
 
 	bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
 	    idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
@@ -1167,11 +1161,11 @@ rge_discard_rxbuf(struct rge_softc *sc, 
 
 	r = &sc->rge_ldata.rge_rx_list[idx];
 
-	r->rge_cmdsts = htole32(RGE_JUMBO_FRAMELEN);
-	r->rge_extsts = 0;
+	r->hi_qword1.rx_qword4.rge_cmdsts = htole32(RGE_JUMBO_FRAMELEN);
+	r->hi_qword1.rx_qword4.rge_extsts = 0;
 	if (idx == RGE_RX_LIST_CNT - 1)
-		r->rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
-	r->rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
+		r->hi_qword1.rx_qword4.rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
+	r->hi_qword1.rx_qword4.rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
 
 	bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
 	    idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
@@ -1235,8 +1229,8 @@ rge_rxeof(struct rge_softc *sc)
 		if (RGE_OWN(cur_rx))
 			break;
 
-		rxstat = letoh32(cur_rx->rge_cmdsts);
-		extsts = letoh32(cur_rx->rge_extsts);
+		rxstat = letoh32(cur_rx->hi_qword1.rx_qword4.rge_cmdsts);
+		extsts = letoh32(cur_rx->hi_qword1.rx_qword4.rge_extsts);
 
 		total_len = RGE_RXBYTES(cur_rx);
 		rxq = &sc->rge_ldata.rge_rxq[i];
@@ -1317,16 +1311,16 @@ rge_rxeof(struct rge_softc *sc)
 
 #if notyet
 		/* Check IP header checksum. */
-		if (!(rxstat & RGE_RDCMDSTS_IPCSUMERR) &&
+		if (!(extsts & RGE_RDEXTSTS_IPCSUMERR) &&
 		    (extsts & RGE_RDEXTSTS_IPV4))
 			m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
 
 		/* Check TCP/UDP checksum. */
 		if ((extsts & (RGE_RDEXTSTS_IPV4 | RGE_RDEXTSTS_IPV6)) &&
-		    (((rxstat & RGE_RDCMDSTS_TCPPKT) &&
-		    !(rxstat & RGE_RDCMDSTS_TCPCSUMERR)) ||
-		    ((rxstat & RGE_RDCMDSTS_UDPPKT) &&
-		    !(rxstat & RGE_RDCMDSTS_UDPCSUMERR))))
+		    (((extsts & RGE_RDEXTSTS_TCPPKT) &&
+		    !(extsts & RGE_RDEXTSTS_TCPCSUMERR)) ||
+		    ((extsts & RGE_RDEXTSTS_UDPPKT) &&
+		    !(extsts & RGE_RDEXTSTS_UDPCSUMERR))))
 			m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
 			    M_UDP_CSUM_IN_OK;
 #endif

Index: src/sys/dev/pci/if_rgereg.h
diff -u src/sys/dev/pci/if_rgereg.h:1.6 src/sys/dev/pci/if_rgereg.h:1.7
--- src/sys/dev/pci/if_rgereg.h:1.6	Sun Aug 28 07:44:23 2022
+++ src/sys/dev/pci/if_rgereg.h	Wed Dec 21 05:19:15 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_rgereg.h,v 1.6 2022/08/28 07:44:23 skrll Exp $	*/
+/*	$NetBSD: if_rgereg.h,v 1.7 2022/12/21 05:19:15 nonaka Exp $	*/
 /*	$OpenBSD: if_rgereg.h,v 1.6 2020/12/24 01:00:00 kevlo Exp $	*/
 
 /*
@@ -188,9 +188,10 @@
 #define RGE_NEXT_RX_DESC(x)	(((x) + 1) % RGE_RX_LIST_CNT)
 #define RGE_ADDR_LO(y)		((uint64_t) (y) & 0xffffffff)
 #define RGE_ADDR_HI(y)		((uint64_t) (y) >> 32)
-#define RGE_OWN(x)		(letoh32((x)->rge_cmdsts) & RGE_RDCMDSTS_OWN)
-#define RGE_RXBYTES(x)          (letoh32((x)->rge_cmdsts) & \
-				RGE_RDCMDSTS_FRAGLEN)
+#define RGE_OWN(x)							\
+        (letoh32((x)->hi_qword1.rx_qword4.rge_cmdsts) & RGE_RDCMDSTS_OWN)
+#define RGE_RXBYTES(x)							\
+        (letoh32((x)->hi_qword1.rx_qword4.rge_cmdsts) & RGE_RDCMDSTS_FRAGLEN)
 
 #define RGE_ADV_2500TFDX	0x0080
 
@@ -218,26 +219,67 @@ struct rge_tx_desc {
 
 /* Rx descriptor */
 struct rge_rx_desc {
-	uint32_t		rge_cmdsts;
-	uint32_t		rge_extsts;
-	uint32_t		rge_addrlo;
-	uint32_t		rge_addrhi;
+	union {
+		struct {
+			uint32_t	rsvd0;
+			uint32_t	rsvd1;
+		} rx_qword0;
+	} lo_qword0;
+
+	union {
+		struct {
+			uint32_t	rss;
+			uint16_t	length;
+			uint16_t	hdr_info;
+		} rx_qword1;
+
+		struct {
+			uint32_t	rsvd2;
+			uint32_t	rsvd3;
+		} rx_qword2;
+	} lo_qword1;
+
+	union {
+		uint64_t		rge_addr;
+
+		struct {
+			uint64_t	timestamp;
+		} rx_timestamp;
+
+		struct {
+			uint32_t	rsvd4;
+			uint32_t	rsvd5;
+		} rx_qword3;
+	} hi_qword0;
+
+	union {
+		struct {
+			uint32_t	rge_extsts;
+			uint32_t	rge_cmdsts;
+		} rx_qword4;
+
+		struct {
+			uint16_t	rsvd6;
+			uint16_t	rsvd7;
+			uint32_t	rsvd8;
+		} rx_ptp;
+	} hi_qword1;
 };
 
-#define RGE_RDCMDSTS_TCPCSUMERR	0x00004000
-#define RGE_RDCMDSTS_UDPCSUMERR	0x00008000
-#define RGE_RDCMDSTS_IPCSUMERR	0x00010000
-#define RGE_RDCMDSTS_TCPPKT	0x00020000
-#define RGE_RDCMDSTS_UDPPKT	0x00040000
-#define RGE_RDCMDSTS_RXERRSUM	0x00200000
-#define RGE_RDCMDSTS_EOF	0x10000000
-#define RGE_RDCMDSTS_SOF	0x20000000
+#define RGE_RDCMDSTS_RXERRSUM	0x00100000
+#define RGE_RDCMDSTS_EOF	0x01000000
+#define RGE_RDCMDSTS_SOF	0x02000000
 #define RGE_RDCMDSTS_EOR	0x40000000
 #define RGE_RDCMDSTS_OWN	0x80000000
 #define RGE_RDCMDSTS_FRAGLEN	0x00003fff
 
 #define RGE_RDEXTSTS_VTAG	0x00010000
 #define RGE_RDEXTSTS_VLAN_MASK	0x0000ffff
+#define RGE_RDEXTSTS_TCPCSUMERR 0x01000000
+#define RGE_RDEXTSTS_UDPCSUMERR 0x02000000
+#define RGE_RDEXTSTS_IPCSUMERR  0x04000000
+#define RGE_RDEXTSTS_TCPPKT     0x10000000
+#define RGE_RDEXTSTS_UDPPKT     0x20000000
 #define RGE_RDEXTSTS_IPV4	0x40000000
 #define RGE_RDEXTSTS_IPV6	0x80000000
 
@@ -296,7 +338,7 @@ enum rge_mac_type {
 	ETHER_VLAN_ENCAP_LEN)
 
 #define RGE_TXCFG_CONFIG	0x03000700
-#define RGE_RXCFG_CONFIG	0x40c00700
+#define RGE_RXCFG_CONFIG	0x41c00700
 
 struct rge_softc {
 	device_t		sc_dev;

Reply via email to