Module Name: src Committed By: christos Date: Mon Aug 12 18:55:01 UTC 2024
Modified Files: src/sys/dev/ic: rtl8169.c rtl81x9reg.h rtl81x9var.h Log Message: PR/58588: Christos Zoulas: Avoid crashes when exiting promiscuous mode (^C tcpdump) by disabling RX in re_stop. Also add some earlyoff stuff while here. >From FreeBSD. To generate a diff of this commit: cvs rdiff -u -r1.177 -r1.178 src/sys/dev/ic/rtl8169.c cvs rdiff -u -r1.54 -r1.55 src/sys/dev/ic/rtl81x9reg.h cvs rdiff -u -r1.58 -r1.59 src/sys/dev/ic/rtl81x9var.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/ic/rtl8169.c diff -u src/sys/dev/ic/rtl8169.c:1.177 src/sys/dev/ic/rtl8169.c:1.178 --- src/sys/dev/ic/rtl8169.c:1.177 Fri Jul 5 00:31:51 2024 +++ src/sys/dev/ic/rtl8169.c Mon Aug 12 14:55:01 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: rtl8169.c,v 1.177 2024/07/05 04:31:51 rin Exp $ */ +/* $NetBSD: rtl8169.c,v 1.178 2024/08/12 18:55:01 christos Exp $ */ /* * Copyright (c) 1997, 1998-2003 @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.177 2024/07/05 04:31:51 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.178 2024/08/12 18:55:01 christos Exp $"); /* $FreeBSD: /repoman/r/ncvs/src/sys/dev/re/if_re.c,v 1.20 2004/04/11 20:34:08 ru Exp $ */ /* @@ -669,6 +669,8 @@ re_attach(struct rtk_softc *sc) break; case RTK_HWREV_8168E_VL: case RTK_HWREV_8168F: + sc->sc_quirk |= RTKQ_EARLYOFF; + /*FALLTHROUGH*/ case RTK_HWREV_8411: sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD | RTKQ_MACSTAT | RTKQ_CMDSTOP | RTKQ_NOJUMBO; @@ -1969,6 +1971,10 @@ re_init(struct ifnet *ifp) /* Set the individual bit to receive frames for this host only. */ rxcfg = CSR_READ_4(sc, RTK_RXCFG); rxcfg |= RTK_RXCFG_RX_INDIV; + if (sc->sc_quirk & RTKQ_EARLYOFF) + rxcfg |= RTK_RXCFG_EARLYOFF; + else if (sc->sc_quirk & RTKQ_RXDV_GATED) + rxcfg |= RTK_RXCFG_EARLYOFFV2; /* If we want promiscuous mode, set the allframes bit. */ if (ifp->if_flags & IFF_PROMISC) @@ -2173,6 +2179,21 @@ re_stop(struct ifnet *ifp, int disable) mii_down(&sc->mii); + /* + * Disable accepting frames to put RX MAC into idle state. + * Otherwise it's possible to get frames while stop command + * execution is in progress and controller can DMA the frame + * to already freed RX buffer during that period. + */ + CSR_WRITE_4(sc, RTK_RXCFG, CSR_READ_4(sc, RTK_RXCFG) & + ~(RTK_RXCFG_RX_ALLPHYS | RTK_RXCFG_RX_INDIV | RTK_RXCFG_RX_MULTI | + RTK_RXCFG_RX_BROAD)); + + if (sc->sc_quirk & RTKQ_RXDV_GATED) { + CSR_WRITE_4(sc, RTK_MISC, + CSR_READ_4(sc, RTK_MISC) | RTK_MISC_RXDV_GATED_EN); + } + if ((sc->sc_quirk & RTKQ_CMDSTOP) != 0) CSR_WRITE_1(sc, RTK_COMMAND, RTK_CMD_STOPREQ | RTK_CMD_TX_ENB | RTK_CMD_RX_ENB); Index: src/sys/dev/ic/rtl81x9reg.h diff -u src/sys/dev/ic/rtl81x9reg.h:1.54 src/sys/dev/ic/rtl81x9reg.h:1.55 --- src/sys/dev/ic/rtl81x9reg.h:1.54 Mon Sep 21 02:57:00 2020 +++ src/sys/dev/ic/rtl81x9reg.h Mon Aug 12 14:55:01 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: rtl81x9reg.h,v 1.54 2020/09/21 06:57:00 msaitoh Exp $ */ +/* $NetBSD: rtl81x9reg.h,v 1.55 2024/08/12 18:55:01 christos Exp $ */ /* * Copyright (c) 1997, 1998 @@ -291,8 +291,10 @@ #define RTK_RXCFG_RX_RUNT 0x00000010 #define RTK_RXCFG_RX_ERRPKT 0x00000020 #define RTK_RXCFG_WRAP 0x00000080 +#define RTK_RXCFG_EARLYOFFV2 0x00000800 #define RTK_RXCFG_MAXDMA 0x00000700 #define RTK_RXCFG_BUFSZ 0x00001800 +#define RTK_RXCFG_EARLYOFF 0x00003800 #define RTK_RXCFG_FIFOTHRESH 0x0000E000 #define RTK_RXCFG_EARLYTHRESH 0x07000000 Index: src/sys/dev/ic/rtl81x9var.h diff -u src/sys/dev/ic/rtl81x9var.h:1.58 src/sys/dev/ic/rtl81x9var.h:1.59 --- src/sys/dev/ic/rtl81x9var.h:1.58 Mon Sep 21 02:57:00 2020 +++ src/sys/dev/ic/rtl81x9var.h Mon Aug 12 14:55:01 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: rtl81x9var.h,v 1.58 2020/09/21 06:57:00 msaitoh Exp $ */ +/* $NetBSD: rtl81x9var.h,v 1.59 2024/08/12 18:55:01 christos Exp $ */ /* * Copyright (c) 1997, 1998 @@ -196,6 +196,7 @@ struct rtk_softc { #define RTKQ_RXDV_GATED 0x00000800 #define RTKQ_IM_HW 0x00001000 /* HW interrupt mitigation */ #define RTKQ_TXRXEN_LATER 0x00002000 /* TX/RX enable timing */ +#define RTKQ_EARLYOFF 0x00004000 /* Enable early receive? */ bus_dma_tag_t sc_dmat;