Module Name: src Committed By: sekiya Date: Fri Aug 5 21:03:43 UTC 2022
Modified Files: src/sys/dev/ic: dwc_gmac.c Log Message: Do not unilaterally set M_HASFCS; this breaks protocols that lack CRC bytes (such as AppleTalk). Instead, remove/preserve the final four bytes in the packet ourselves on a per- protocol basis, as we do in arch/arm/xscale/ixp425_if_npe.c (and dev/ic/gem.c, and so forth). To generate a diff of this commit: cvs rdiff -u -r1.75 -r1.76 src/sys/dev/ic/dwc_gmac.c 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/dwc_gmac.c diff -u src/sys/dev/ic/dwc_gmac.c:1.75 src/sys/dev/ic/dwc_gmac.c:1.76 --- src/sys/dev/ic/dwc_gmac.c:1.75 Sat Sep 11 20:28:06 2021 +++ src/sys/dev/ic/dwc_gmac.c Fri Aug 5 21:03:43 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac.c,v 1.75 2021/09/11 20:28:06 andvar Exp $ */ +/* $NetBSD: dwc_gmac.c,v 1.76 2022/08/05 21:03:43 sekiya Exp $ */ /*- * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.75 2021/09/11 20:28:06 andvar Exp $"); +__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.76 2022/08/05 21:03:43 sekiya Exp $"); /* #define DWC_GMAC_DEBUG 1 */ @@ -1229,6 +1229,8 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc * struct mbuf *m, *mnew; int i, len, error; + uint16_t etype; + mutex_enter(&sc->sc_rxq.r_mtx); for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) { bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, @@ -1311,8 +1313,29 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc * /* finalize mbuf */ m->m_pkthdr.len = m->m_len = len; m_set_rcvif(m, ifp); - m->m_flags |= M_HASFCS; +#define ETYPE_OFFSET 20 + etype = (m->m_data[ETYPE_OFFSET] << 8) + m->m_data[ETYPE_OFFSET+1]; + + /* + * The hardware doesn't trim the four FCS bytes for us, so + * we need to trim it ourselves. + * Having the upper layer remove it by passing M_HASFCS breaks + * protocols that don't have FCS bytes at the end of the packet + * (AppleTalk, for example), so we do it here instead. + */ + + switch (etype) { + case ETHERTYPE_ATALK: + case ETHERTYPE_AARP: + /* No FCS removal needed */ + break; + default: + /* remove FCS */ + m_adj(m, -ETHER_CRC_LEN); + break; + } + if_percpuq_enqueue(sc->sc_ipq, m); skip: