svn commit: r367888 - head/sys/dev/dwc

Emmanuel Vadot manu at FreeBSD.org
Fri Nov 20 11:31:25 UTC 2020


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. */


More information about the svn-src-head mailing list