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;