diff options
| author | sekiya <sekiya@NetBSD.org> | 2022-08-05 21:03:43 +0000 |
|---|---|---|
| committer | sekiya <sekiya@NetBSD.org> | 2022-08-05 21:03:43 +0000 |
| commit | 57741bed1335aa6350c2c75babef71da80905871 (patch) | |
| tree | 98e5f0572563cf91de0dfaad8ddf51763edf6c4a /sys/dev/ic | |
| parent | fa2619154a4625c91f1c2e5501503f55625d01fa (diff) | |
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).
Diffstat (limited to 'sys/dev/ic')
| -rw-r--r-- | sys/dev/ic/dwc_gmac.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/sys/dev/ic/dwc_gmac.c b/sys/dev/ic/dwc_gmac.c index e16b5971735..5a40b61afa6 100644 --- a/sys/dev/ic/dwc_gmac.c +++ b/sys/dev/ic/dwc_gmac.c @@ -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 *sc) 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 *sc) /* 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: |
