Date: Fri, 20 Nov 2020 11:31:25 +0000 (UTC) From: Emmanuel Vadot <manu@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367888 - head/sys/dev/dwc Message-ID: <202011201131.0AKBVPqG093741@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: manu Date: Fri Nov 20 11:31:25 2020 New Revision: 367888 URL: https://svnweb.freebsd.org/changeset/base/367888 Log: if_dwc: Add checksum offloading support Modified: head/sys/dev/dwc/if_dwc.c Modified: head/sys/dev/dwc/if_dwc.c ============================================================================== --- head/sys/dev/dwc/if_dwc.c Fri Nov 20 11:31:04 2020 (r367887) +++ head/sys/dev/dwc/if_dwc.c Fri Nov 20 11:31:25 2020 (r367888) @@ -155,7 +155,6 @@ __FBSDID("$FreeBSD$"); #define RDESC0_FS (1U << 9) /* First Descriptor */ #define RDESC0_LS (1U << 8) /* Last Descriptor */ #define RDESC0_ICE (1U << 7) /* IPC Checksum Error */ -#define RDESC0_GF (1U << 7) /* Giant Frame */ #define RDESC0_LC (1U << 6) /* Late Collision */ #define RDESC0_FT (1U << 5) /* Frame Type */ #define RDESC0_RWT (1U << 4) /* Receive Watchdog Timeout */ @@ -628,7 +627,7 @@ dwc_get1paddr(void *arg, bus_dma_segment_t *segs, int inline static void dwc_setup_txdesc(struct dwc_softc *sc, int idx, bus_addr_t paddr, - uint32_t len) + uint32_t len, uint32_t flags) { uint32_t desc0, desc1; @@ -641,10 +640,10 @@ dwc_setup_txdesc(struct dwc_softc *sc, int idx, bus_ad if (sc->mactype != DWC_GMAC_EXT_DESC) { desc0 = 0; desc1 = NTDESC1_TCH | NTDESC1_FS | NTDESC1_LS | - NTDESC1_IC | len; + NTDESC1_IC | len | flags; } else { desc0 = ETDESC0_TCH | ETDESC0_FS | ETDESC0_LS | - ETDESC0_IC; + ETDESC0_IC | flags; desc1 = len; } ++sc->txcount; @@ -667,6 +666,7 @@ dwc_setup_txbuf(struct dwc_softc *sc, int idx, struct struct bus_dma_segment seg; int error, nsegs; struct mbuf * m; + uint32_t flags = 0; if ((m = m_defrag(*mp, M_NOWAIT)) == NULL) return (ENOMEM); @@ -685,8 +685,22 @@ dwc_setup_txbuf(struct dwc_softc *sc, int idx, struct sc->txbuf_map[idx].mbuf = m; - dwc_setup_txdesc(sc, idx, seg.ds_addr, seg.ds_len); + if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) { + if ((m->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP)) != 0) { + if (sc->mactype != DWC_GMAC_EXT_DESC) + flags = NTDESC1_CIC_FULL; + else + flags = ETDESC0_CIC_FULL; + } else { + if (sc->mactype != DWC_GMAC_EXT_DESC) + flags = NTDESC1_CIC_HDR; + else + flags = ETDESC0_CIC_HDR; + } + } + dwc_setup_txdesc(sc, idx, seg.ds_addr, seg.ds_len, flags); + return (0); } @@ -807,6 +821,18 @@ dwc_rxfinish_one(struct dwc_softc *sc, struct dwc_hwde m->m_len = len; if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); + if ((if_getcapenable(ifp) & IFCAP_RXCSUM) != 0 && + (rdesc0 & RDESC0_FT) != 0) { + m->m_pkthdr.csum_flags = CSUM_IP_CHECKED; + if ((rdesc0 & RDESC0_ICE) == 0) + m->m_pkthdr.csum_flags |= CSUM_IP_VALID; + if ((rdesc0 & RDESC0_PCE) == 0) { + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + } + /* Remove trailing FCS */ m_adj(m, -ETHER_CRC_LEN); @@ -893,7 +919,7 @@ setup_dma(struct dwc_softc *sc) "could not create TX buffer DMA map.\n"); goto out; } - dwc_setup_txdesc(sc, idx, 0, 0); + dwc_setup_txdesc(sc, idx, 0, 0, 0); } /* @@ -1139,6 +1165,14 @@ dwc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* No work to do except acknowledge the change took */ if_togglecapenable(ifp, IFCAP_VLAN_MTU); } + if (mask & IFCAP_RXCSUM) + if_togglecapenable(ifp, IFCAP_RXCSUM); + if (mask & IFCAP_TXCSUM) + if_togglecapenable(ifp, IFCAP_TXCSUM); + if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0) + if_sethwassistbits(ifp, CSUM_IP | CSUM_UDP | CSUM_TCP, 0); + else + if_sethwassistbits(ifp, 0, CSUM_IP | CSUM_UDP | CSUM_TCP); break; default: @@ -1173,7 +1207,7 @@ dwc_txfinish_locked(struct dwc_softc *sc) bus_dmamap_unload(sc->txbuf_tag, bmap->map); m_freem(bmap->mbuf); bmap->mbuf = NULL; - dwc_setup_txdesc(sc, sc->tx_idx_tail, 0, 0); + dwc_setup_txdesc(sc, sc->tx_idx_tail, 0, 0, 0); sc->tx_idx_tail = next_txidx(sc, sc->tx_idx_tail); if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE); if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); @@ -1212,6 +1246,7 @@ dwc_rxfinish_locked(struct dwc_softc *sc) if (error != 0) panic("dwc_setup_rxbuf failed: error %d\n", error); + } sc->rx_idx = next_rxidx(sc, sc->rx_idx); } @@ -1561,7 +1596,8 @@ dwc_attach(device_t dev) if_setinitfn(ifp, dwc_init); if_setsendqlen(ifp, TX_DESC_COUNT - 1); if_setsendqready(sc->ifp); - if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU); + if_sethwassist(sc->ifp, CSUM_IP | CSUM_UDP | CSUM_TCP); + if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM); if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp)); /* Attach the mii driver. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011201131.0AKBVPqG093741>