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