diff --git a/sys/dev/dwc/if_dwc.h b/sys/dev/dwc/if_dwc.h --- a/sys/dev/dwc/if_dwc.h +++ b/sys/dev/dwc/if_dwc.h @@ -48,6 +48,7 @@ #define CONF_PS (1 << 15) /* GMII/MII */ #define CONF_FES (1 << 14) /* MII speed select */ #define CONF_DM (1 << 11) /* Full Duplex Enable */ +#define CONF_IPC (1 << 10) /* IPC checksum offload */ #define CONF_ACS (1 << 7) #define CONF_TE (1 << 3) #define CONF_RE (1 << 2) diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c --- a/sys/dev/dwc/if_dwc.c +++ b/sys/dev/dwc/if_dwc.c @@ -518,6 +518,20 @@ WRITE4(sc, MAC_CONFIGURATION, reg); } +static void +dwc_enable_csum_offload(struct dwc_softc *sc) +{ + uint32_t reg; + + DWC_ASSERT_LOCKED(sc); + reg = READ4(sc, MAC_CONFIGURATION); + if ((if_getcapenable(sc->ifp) & IFCAP_RXCSUM) != 0) + reg |= CONF_IPC; + else + reg &= ~CONF_IPC; + WRITE4(sc, MAC_CONFIGURATION, reg); +} + static void dwc_get_hwaddr(struct dwc_softc *sc, uint8_t *hwaddr) { @@ -1163,6 +1177,7 @@ dwc_setup_rxfilter(sc); dwc_setup_core(sc); dwc_enable_mac(sc, true); + dwc_enable_csum_offload(sc); dwc_init_dma(sc); if_setdrvflagbits(ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE); @@ -1261,6 +1276,12 @@ if_sethwassistbits(ifp, CSUM_IP | CSUM_UDP | CSUM_TCP, 0); else if_sethwassistbits(ifp, 0, CSUM_IP | CSUM_UDP | CSUM_TCP); + + if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { + DWC_LOCK(sc); + dwc_enable_csum_offload(sc); + DWC_UNLOCK(sc); + } break; default: