Skip site navigation (1)Skip section navigation (2)
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>