svn commit: r207712 - stable/8/sys/dev/sge

Pyun YongHyeon yongari at FreeBSD.org
Thu May 6 18:30:46 UTC 2010


Author: yongari
Date: Thu May  6 18:30:46 2010
New Revision: 207712
URL: http://svn.freebsd.org/changeset/base/207712

Log:
  MFC r207379:
    Enable FCS stripping and padding 10 bytes bit of RX MAC control
    register. Due to lack of SiS190 controller, I'm not sure whether
    this is also applicable to SiS190 so this feature is only activated
    on SiS191 controller.
    The controller can pad 10 bytes before DMAing a received frame to
    RX buffer and received bytes include the padded bytes. This padding
    is very useful on strict-alignment architectures because driver
    does not have to copy received frame to align IP header on 4 bytes
    boundary. It also gives better RX performance on non-strict
    alignment architectures. Special thanks to xclin to give me
    valuable register information. Without his enthusiastic trial and
    errors this wouldn't be even possible.
  
    While I'm here tighten validity check of received frame. Controller
    clears RDS_CRCOK bit when it received bad CRC frames. xclin found
    that using loop back testing.
  
    Tested by:	xclin <xclin <> cs dot nctu dot edu dot tw >

Modified:
  stable/8/sys/dev/sge/if_sge.c
  stable/8/sys/dev/sge/if_sgereg.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)
  stable/8/sys/geom/sched/   (props changed)

Modified: stable/8/sys/dev/sge/if_sge.c
==============================================================================
--- stable/8/sys/dev/sge/if_sge.c	Thu May  6 18:26:43 2010	(r207711)
+++ stable/8/sys/dev/sge/if_sge.c	Thu May  6 18:30:46 2010	(r207712)
@@ -1144,7 +1144,8 @@ sge_rxeof(struct sge_softc *sc)
 		if ((rxinfo & RDC_OWN) != 0)
 			break;
 		rxstat = le32toh(cur_rx->sge_sts_size);
-		if (SGE_RX_ERROR(rxstat) != 0 || SGE_RX_NSEGS(rxstat) != 1) {
+		if ((rxstat & RDS_CRCOK) == 0 || SGE_RX_ERROR(rxstat) != 0 ||
+		    SGE_RX_NSEGS(rxstat) != 1) {
 			/* XXX We don't support multi-segment frames yet. */
 #ifdef SGE_SHOW_ERRORS
 			device_printf(sc->sge_dev, "Rx error : 0x%b\n", rxstat,
@@ -1177,11 +1178,23 @@ sge_rxeof(struct sge_softc *sc)
 		/*
 		 * TODO : VLAN hardware tag stripping.
 		 */
-		m->m_pkthdr.len = m->m_len =
-		    SGE_RX_BYTES(rxstat) - ETHER_CRC_LEN;
+		if ((sc->sge_flags & SGE_FLAG_SIS190) == 0) {
+			/*
+			 * Account for 10bytes auto padding which is used
+			 * to align IP header on 32bit boundary.  Also note,
+			 * CRC bytes is automatically removed by the
+			 * hardware.
+			 */
+			m->m_data += SGE_RX_PAD_BYTES;
+			m->m_pkthdr.len = m->m_len = SGE_RX_BYTES(rxstat) -
+			    SGE_RX_PAD_BYTES;
+		} else {
+			m->m_pkthdr.len = m->m_len = SGE_RX_BYTES(rxstat) -
+			    ETHER_CRC_LEN;
 #ifndef __NO_STRICT_ALIGNMENT
-		sge_fixup_rx(m);
+			sge_fixup_rx(m);
 #endif
+		}
 		m->m_pkthdr.rcvif = ifp;
 		ifp->if_ipackets++;
 		SGE_UNLOCK(sc);
@@ -1503,6 +1516,7 @@ sge_init_locked(struct sge_softc *sc)
 {
 	struct ifnet *ifp;
 	struct mii_data *mii;
+	uint16_t rxfilt;
 	int i;
 
 	SGE_LOCK_ASSERT(sc);
@@ -1535,10 +1549,19 @@ sge_init_locked(struct sge_softc *sc)
 	CSR_WRITE_4(sc, RxWakeOnLan, 0);
 	CSR_WRITE_4(sc, RxWakeOnLanData, 0);
 	/* Allow receiving VLAN frames. */
-	CSR_WRITE_2(sc, RxMPSControl, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
+	if ((sc->sge_flags & SGE_FLAG_SIS190) == 0)
+		CSR_WRITE_2(sc, RxMPSControl,
+		    ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN + SGE_RX_PAD_BYTES);
+	else
+		CSR_WRITE_2(sc, RxMPSControl, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
 
 	for (i = 0; i < ETHER_ADDR_LEN; i++)
 		CSR_WRITE_1(sc, RxMacAddr + i, IF_LLADDR(ifp)[i]);
+	/* Configure RX MAC. */
+	rxfilt = 0;
+	if ((sc->sge_flags & SGE_FLAG_SIS190) == 0)
+		rxfilt |= RXMAC_STRIP_FCS | RXMAC_PAD_ENB;
+	CSR_WRITE_2(sc, RxMacControl, rxfilt);
 	sge_rxfilter(sc);
 
 	/* Initialize default speed/duplex information. */

Modified: stable/8/sys/dev/sge/if_sgereg.h
==============================================================================
--- stable/8/sys/dev/sge/if_sgereg.h	Thu May  6 18:26:43 2010	(r207711)
+++ stable/8/sys/dev/sge/if_sgereg.h	Thu May  6 18:30:46 2010	(r207712)
@@ -137,6 +137,10 @@
 #define	AcceptAllPhys		0x0100
 #define	AcceptErr		0x0020
 #define	AcceptRunt		0x0010
+#define	RXMAC_STRIP_FCS		0x0010
+#define	RXMAC_PAD_ENB		0x0004
+
+#define	SGE_RX_PAD_BYTES	10
 
 /* Station control register. */
 #define	SC_LOOPBACK		0x80000000


More information about the svn-src-all mailing list