Date: Mon, 21 Dec 2009 18:52:39 +0000 (UTC) From: Pyun YongHyeon <yongari@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r200791 - stable/8/sys/dev/et Message-ID: <200912211852.nBLIqdrO037148@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: yongari Date: Mon Dec 21 18:52:38 2009 New Revision: 200791 URL: http://svn.freebsd.org/changeset/base/200791 Log: MFC r199563,199608-199613 r199563: Fix copy & paste error and remove extra space before colon. r199608: Remove unnecessary structure packing. r199609: Add initial endianness support. It seems the controller supports both big-endian and little-endian format in descriptors for Rx path but I couldn't find equivalent feature in Tx path. So just stick to little-endian for now. r199610: Because we know received bytes including CRC there is no reason to call m_adj(9). The controller also seems to have a capability to strip CRC bytes but I failed to activate this feature except for loopback traffic. r199611: 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. r199612: Add __FBSDID. r199613: Only Tx checksum offloading is supported now. Remove experimental code sneaked in r199611. Modified: stable/8/sys/dev/et/if_et.c stable/8/sys/dev/et/if_etvar.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/dev/et/if_et.c ============================================================================== --- stable/8/sys/dev/et/if_et.c Mon Dec 21 18:36:15 2009 (r200790) +++ stable/8/sys/dev/et/if_et.c Mon Dec 21 18:52:38 2009 (r200791) @@ -32,9 +32,11 @@ * SUCH DAMAGE. * * $DragonFly: src/sys/dev/netif/et/if_et.c,v 1.10 2008/05/18 07:47:14 sephe Exp $ - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <sys/param.h> #include <sys/systm.h> #include <sys/endian.h> @@ -78,7 +80,9 @@ MODULE_DEPEND(et, miibus, 1, 1, 1); /* Tunables. */ static int msi_disable = 0; -TUNABLE_INT("hw.re.msi_disable", &msi_disable); +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); @@ -276,7 +280,7 @@ et_attach(device_t dev) sc->sc_flags |= ET_FLAG_PCIE; msic = pci_msi_count(dev); if (bootverbose) - device_printf(dev, "MSI count : %d\n", msic); + device_printf(dev, "MSI count: %d\n", msic); } if (msic > 0 && msi_disable == 0) { msic = 1; @@ -332,7 +336,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_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 +1179,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 +1236,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; @@ -1913,7 +1931,7 @@ et_rxeof(struct et_softc *sc) struct ifnet *ifp; struct et_rxstatus_data *rxsd; struct et_rxstat_ring *rxst_ring; - uint32_t rxs_stat_ring; + uint32_t rxs_stat_ring, rxst_info2; int rxst_wrap, rxst_index; ET_LOCK_ASSERT(sc); @@ -1929,7 +1947,7 @@ et_rxeof(struct et_softc *sc) bus_dmamap_sync(rxst_ring->rsr_dtag, rxst_ring->rsr_dmap, BUS_DMASYNC_POSTREAD); - rxs_stat_ring = rxsd->rxsd_status->rxs_stat_ring; + rxs_stat_ring = le32toh(rxsd->rxsd_status->rxs_stat_ring); rxst_wrap = (rxs_stat_ring & ET_RXS_STATRING_WRAP) ? 1 : 0; rxst_index = (rxs_stat_ring & ET_RXS_STATRING_INDEX_MASK) >> ET_RXS_STATRING_INDEX_SHIFT; @@ -1945,12 +1963,12 @@ et_rxeof(struct et_softc *sc) MPASS(rxst_ring->rsr_index < ET_RX_NSTAT); st = &rxst_ring->rsr_stat[rxst_ring->rsr_index]; - - buflen = (st->rxst_info2 & ET_RXST_INFO2_LEN_MASK) >> + rxst_info2 = le32toh(st->rxst_info2); + buflen = (rxst_info2 & ET_RXST_INFO2_LEN_MASK) >> ET_RXST_INFO2_LEN_SHIFT; - buf_idx = (st->rxst_info2 & ET_RXST_INFO2_BUFIDX_MASK) >> + buf_idx = (rxst_info2 & ET_RXST_INFO2_BUFIDX_MASK) >> ET_RXST_INFO2_BUFIDX_SHIFT; - ring_idx = (st->rxst_info2 & ET_RXST_INFO2_RINGIDX_MASK) >> + ring_idx = (rxst_info2 & ET_RXST_INFO2_RINGIDX_MASK) >> ET_RXST_INFO2_RINGIDX_SHIFT; if (++rxst_ring->rsr_index == ET_RX_NSTAT) { @@ -1982,11 +2000,9 @@ et_rxeof(struct et_softc *sc) m = NULL; ifp->if_ierrors++; } else { - m->m_pkthdr.len = m->m_len = buflen; + m->m_pkthdr.len = m->m_len = + buflen - ETHER_CRC_LEN; m->m_pkthdr.rcvif = ifp; - - m_adj(m, -ETHER_CRC_LEN); - ifp->if_ipackets++; ET_UNLOCK(sc); ifp->if_input(ifp, m); @@ -2028,7 +2044,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) @@ -2090,20 +2106,29 @@ 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; idx = (first_idx + i) % ET_TX_NDESC; td = &tx_ring->tr_desc[idx]; - td->td_addr_hi = ET_ADDR_HI(segs[i].ds_addr); - td->td_addr_lo = ET_ADDR_LO(segs[i].ds_addr); - td->td_ctrl1 = segs[i].ds_len & ET_TDCTRL1_LEN_MASK; - + 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 = 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) { @@ -2112,7 +2137,7 @@ et_encap(struct et_softc *sc, struct mbu } } td = &tx_ring->tr_desc[first_idx]; - td->td_ctrl2 |= ET_TDCTRL2_FIRST_FRAG; /* First frag */ + td->td_ctrl2 |= htole32(ET_TDCTRL2_FIRST_FRAG); /* First frag */ MPASS(last_idx >= 0); tbd->tbd_buf[first_idx].tb_dmap = tbd->tbd_buf[last_idx].tb_dmap; @@ -2424,9 +2449,9 @@ et_setup_rxdesc(struct et_rxbuf_data *rb MPASS(buf_idx < ET_RX_NDESC); desc = &rx_ring->rr_desc[buf_idx]; - desc->rd_addr_hi = ET_ADDR_HI(paddr); - desc->rd_addr_lo = ET_ADDR_LO(paddr); - desc->rd_ctrl = buf_idx & ET_RDCTRL_BUFIDX_MASK; + desc->rd_addr_hi = htole32(ET_ADDR_HI(paddr)); + desc->rd_addr_lo = htole32(ET_ADDR_LO(paddr)); + desc->rd_ctrl = htole32(buf_idx & ET_RDCTRL_BUFIDX_MASK); bus_dmamap_sync(rx_ring->rr_dtag, rx_ring->rr_dmap, BUS_DMASYNC_PREWRITE); Modified: stable/8/sys/dev/et/if_etvar.h ============================================================================== --- stable/8/sys/dev/et/if_etvar.h Mon Dec 21 18:36:15 2009 (r200790) +++ stable/8/sys/dev/et/if_etvar.h Mon Dec 21 18:52:38 2009 (r200791) @@ -104,26 +104,38 @@ struct et_txdesc { uint32_t td_addr_lo; uint32_t td_ctrl1; /* ET_TDCTRL1_ */ uint32_t td_ctrl2; /* ET_TDCTRL2_ */ -} __packed; +}; #define ET_TDCTRL1_LEN_MASK 0x0000FFFF #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; uint32_t rd_addr_hi; uint32_t rd_ctrl; /* ET_RDCTRL_ */ -} __packed; +}; #define ET_RDCTRL_BUFIDX_MASK 0x000003FF struct et_rxstat { uint32_t rxst_info1; uint32_t rxst_info2; /* ET_RXST_INFO2_ */ -} __packed; +}; #define ET_RXST_INFO2_LEN_MASK 0x0000FFFF #define ET_RXST_INFO2_LEN_SHIFT 0 @@ -135,7 +147,7 @@ struct et_rxstat { struct et_rxstatus { uint32_t rxs_ring; uint32_t rxs_stat_ring; /* ET_RXS_STATRING_ */ -} __packed; +}; #define ET_RXS_STATRING_INDEX_MASK 0x0FFF0000 #define ET_RXS_STATRING_INDEX_SHIFT 16
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200912211852.nBLIqdrO037148>