Date: Fri, 20 Nov 2009 20:33:59 +0000 (UTC) From: Pyun YongHyeon <yongari@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r199611 - head/sys/dev/et Message-ID: <200911202033.nAKKXx58055723@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: yongari Date: Fri Nov 20 20:33:59 2009 New Revision: 199611 URL: http://svn.freebsd.org/changeset/base/199611 Log: Add IPv4/TCP/UDP Tx checksum offloading support. It seems the controller also has support for IP/TCP checksum offloading for Rx path. But I failed to find to way to enable Rx MAC to compute the checksum of received frames. Modified: head/sys/dev/et/if_et.c head/sys/dev/et/if_etvar.h Modified: head/sys/dev/et/if_et.c ============================================================================== --- head/sys/dev/et/if_et.c Fri Nov 20 20:25:21 2009 (r199610) +++ head/sys/dev/et/if_et.c Fri Nov 20 20:33:59 2009 (r199611) @@ -80,6 +80,8 @@ MODULE_DEPEND(et, miibus, 1, 1, 1); static int msi_disable = 0; TUNABLE_INT("hw.et.msi_disable", &msi_disable); +#define ET_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) + static int et_probe(device_t); static int et_attach(device_t); static int et_detach(device_t); @@ -332,7 +334,7 @@ et_attach(device_t dev) ifp->if_ioctl = et_ioctl; ifp->if_start = et_start; ifp->if_mtu = ETHERMTU; - ifp->if_capabilities = IFCAP_VLAN_MTU; + ifp->if_capabilities = /*IFCAP_TXCSUM*/IFCAP_HWCSUM | IFCAP_VLAN_MTU; ifp->if_capenable = ifp->if_capabilities; IFQ_SET_MAXLEN(&ifp->if_snd, ET_TX_NDESC); IFQ_SET_READY(&ifp->if_snd); @@ -1175,7 +1177,7 @@ et_ioctl(struct ifnet *ifp, u_long cmd, struct et_softc *sc = ifp->if_softc; struct mii_data *mii = device_get_softc(sc->sc_miibus); struct ifreq *ifr = (struct ifreq *)data; - int error = 0, max_framelen; + int error = 0, mask, max_framelen; /* XXX LOCKSUSED */ switch (cmd) { @@ -1232,6 +1234,20 @@ et_ioctl(struct ifnet *ifp, u_long cmd, } break; + case SIOCSIFCAP: + ET_LOCK(sc); + mask = ifr->ifr_reqcap ^ ifp->if_capenable; + if ((mask & IFCAP_TXCSUM) != 0 && + (IFCAP_TXCSUM & ifp->if_capabilities) != 0) { + ifp->if_capenable ^= IFCAP_TXCSUM; + if ((IFCAP_TXCSUM & ifp->if_capenable) != 0) + ifp->if_hwassist |= ET_CSUM_FEATURES; + else + ifp->if_hwassist &= ~ET_CSUM_FEATURES; + } + ET_UNLOCK(sc); + break; + default: error = ether_ioctl(ifp, cmd, data); break; @@ -2026,7 +2042,7 @@ et_encap(struct et_softc *sc, struct mbu struct et_txdesc *td; bus_dmamap_t map; int error, maxsegs, first_idx, last_idx, i; - uint32_t tx_ready_pos, last_td_ctrl2; + uint32_t csum_flags, tx_ready_pos, last_td_ctrl2; maxsegs = ET_TX_NDESC - tbd->tbd_used; if (maxsegs > ET_NSEG_MAX) @@ -2088,6 +2104,15 @@ et_encap(struct et_softc *sc, struct mbu last_td_ctrl2 |= ET_TDCTRL2_INTR; } + csum_flags = 0; + if ((m->m_pkthdr.csum_flags & ET_CSUM_FEATURES) != 0) { + if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) + csum_flags |= ET_TDCTRL2_CSUM_IP; + if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0) + csum_flags |= ET_TDCTRL2_CSUM_UDP; + else if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0) + csum_flags |= ET_TDCTRL2_CSUM_TCP; + } last_idx = -1; for (i = 0; i < ctx.nsegs; ++i) { int idx; @@ -2097,11 +2122,11 @@ et_encap(struct et_softc *sc, struct mbu td->td_addr_hi = htole32(ET_ADDR_HI(segs[i].ds_addr)); td->td_addr_lo = htole32(ET_ADDR_LO(segs[i].ds_addr)); td->td_ctrl1 = htole32(segs[i].ds_len & ET_TDCTRL1_LEN_MASK); - if (i == ctx.nsegs - 1) { /* Last frag */ - td->td_ctrl2 = htole32(last_td_ctrl2); + td->td_ctrl2 = htole32(last_td_ctrl2 | csum_flags); last_idx = idx; - } + } else + td->td_ctrl2 = htole32(csum_flags); MPASS(tx_ring->tr_ready_index < ET_TX_NDESC); if (++tx_ring->tr_ready_index == ET_TX_NDESC) { Modified: head/sys/dev/et/if_etvar.h ============================================================================== --- head/sys/dev/et/if_etvar.h Fri Nov 20 20:25:21 2009 (r199610) +++ head/sys/dev/et/if_etvar.h Fri Nov 20 20:33:59 2009 (r199611) @@ -111,6 +111,18 @@ struct et_txdesc { #define ET_TDCTRL2_LAST_FRAG 0x00000001 #define ET_TDCTRL2_FIRST_FRAG 0x00000002 #define ET_TDCTRL2_INTR 0x00000004 +#define ET_TDCTRL2_CTRL_WORD 0x00000008 +#define ET_TDCTRL2_HDX_BACKP 0x00000010 +#define ET_TDCTRL2_XMIT_PAUSE 0x00000020 +#define ET_TDCTRL2_FRAME_ERR 0x00000040 +#define ET_TDCTRL2_NO_CRC 0x00000080 +#define ET_TDCTRL2_MAC_OVRRD 0x00000100 +#define ET_TDCTRL2_PAD_PACKET 0x00000200 +#define ET_TDCTRL2_JUMBO_PACKET 0x00000400 +#define ET_TDCTRL2_INS_VLAN 0x00000800 +#define ET_TDCTRL2_CSUM_IP 0x00001000 +#define ET_TDCTRL2_CSUM_TCP 0x00002000 +#define ET_TDCTRL2_CSUM_UDP 0x00004000 struct et_rxdesc { uint32_t rd_addr_lo;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911202033.nAKKXx58055723>