From owner-svn-src-all@FreeBSD.ORG Thu Sep 2 18:10:12 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 11A5A1065770; Thu, 2 Sep 2010 18:10:12 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 006A68FC20; Thu, 2 Sep 2010 18:10:12 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o82IABbC014568; Thu, 2 Sep 2010 18:10:11 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o82IABBH014565; Thu, 2 Sep 2010 18:10:11 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201009021810.o82IABBH014565@svn.freebsd.org> From: Pyun YongHyeon Date: Thu, 2 Sep 2010 18:10:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212157 - head/sys/dev/sis X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Sep 2010 18:10:12 -0000 Author: yongari Date: Thu Sep 2 18:10:11 2010 New Revision: 212157 URL: http://svn.freebsd.org/changeset/base/212157 Log: Unlike most other controllers, NS DP83815/DP83816 controllers seem to pad with 0xFF when it encounter short frames. According to RFC 1042 the pad bytes should be 0x00. Because manual padding consumes extra CPU cycles, introduce a new tunable which controls the padding behavior. Turning this tunable on will have driver pad manually but it's disabled by default. Users can enable software padding by setting the following tunable to non-zero value. dev.sis.%d.manual_pad="1" PR: kern/35422 (patch not used) Modified: head/sys/dev/sis/if_sis.c head/sys/dev/sis/if_sisreg.h Modified: head/sys/dev/sis/if_sis.c ============================================================================== --- head/sys/dev/sis/if_sis.c Thu Sep 2 17:51:41 2010 (r212156) +++ head/sys/dev/sis/if_sis.c Thu Sep 2 18:10:11 2010 (r212157) @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -150,6 +151,7 @@ static int sis_rxeof(struct sis_softc *) static void sis_start(struct ifnet *); static void sis_startl(struct ifnet *); static void sis_stop(struct sis_softc *); +static void sis_add_sysctls(struct sis_softc *); static void sis_watchdog(struct sis_softc *); @@ -710,24 +712,24 @@ sis_miibus_statchg(device_t dev) (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - sc->sis_link = 0; + sc->sis_flags &= ~SIS_FLAG_LINK; if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_10_T: - sc->sis_link++; CSR_WRITE_4(sc, SIS_TX_CFG, SIS_TXCFG_10); + sc->sis_flags |= SIS_FLAG_LINK; break; case IFM_100_TX: - sc->sis_link++; CSR_WRITE_4(sc, SIS_TX_CFG, SIS_TXCFG_100); + sc->sis_flags |= SIS_FLAG_LINK; break; default: break; } } - if (sc->sis_link == 0) { + if ((sc->sis_flags & SIS_FLAG_LINK) == 0) { /* * Stopping MACs seem to reset SIS_TX_LISTPTR and * SIS_RX_LISTPTR which in turn requires resetting @@ -1122,6 +1124,8 @@ sis_attach(device_t dev) break; } + sis_add_sysctls(sc); + /* Allocate DMA'able memory. */ if ((error = sis_dma_alloc(sc)) != 0) goto fail; @@ -1698,7 +1702,7 @@ sis_tick(void *xsc) mii = device_get_softc(sc->sis_miibus); mii_tick(mii); sis_watchdog(sc); - if (sc->sis_link == 0) + if ((sc->sis_flags & SIS_FLAG_LINK) == 0) sis_miibus_statchg(sc->sis_dev); callout_reset(&sc->sis_stat_ch, hz, sis_tick, sc); } @@ -1829,9 +1833,41 @@ sis_encap(struct sis_softc *sc, struct m bus_dma_segment_t segs[SIS_MAXTXSEGS]; bus_dmamap_t map; int error, i, frag, nsegs, prod; + int padlen; prod = sc->sis_tx_prod; txd = &sc->sis_txdesc[prod]; + if ((sc->sis_flags & SIS_FLAG_MANUAL_PAD) != 0 && + (*m_head)->m_pkthdr.len < SIS_MIN_FRAMELEN) { + m = *m_head; + padlen = SIS_MIN_FRAMELEN - m->m_pkthdr.len; + if (M_WRITABLE(m) == 0) { + /* Get a writable copy. */ + m = m_dup(*m_head, M_DONTWAIT); + m_freem(*m_head); + if (m == NULL) { + *m_head = NULL; + return (ENOBUFS); + } + *m_head = m; + } + if (m->m_next != NULL || M_TRAILINGSPACE(m) < padlen) { + m = m_defrag(m, M_DONTWAIT); + if (m == NULL) { + m_freem(*m_head); + *m_head = NULL; + return (ENOBUFS); + } + } + /* + * Manually pad short frames, and zero the pad space + * to avoid leaking data. + */ + bzero(mtod(m, char *) + m->m_pkthdr.len, padlen); + m->m_pkthdr.len += padlen; + m->m_len = m->m_pkthdr.len; + *m_head = m; + } error = bus_dmamap_load_mbuf_sg(sc->sis_tx_tag, txd->tx_dmamap, *m_head, segs, &nsegs, 0); if (error == EFBIG) { @@ -1918,7 +1954,7 @@ sis_startl(struct ifnet *ifp) SIS_LOCK_ASSERT(sc); if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || sc->sis_link == 0) + IFF_DRV_RUNNING || (sc->sis_flags & SIS_FLAG_LINK) == 0) return; for (queued = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && @@ -2025,6 +2061,13 @@ sis_initl(struct sis_softc *sc) return; } + if (sc->sis_type == SIS_TYPE_83815 || sc->sis_type == SIS_TYPE_83816) { + if (sc->sis_manual_pad != 0) + sc->sis_flags |= SIS_FLAG_MANUAL_PAD; + else + sc->sis_flags &= ~SIS_FLAG_MANUAL_PAD; + } + /* * Short Cable Receive Errors (MP21.E) * also: Page 78 of the DP83815 data sheet (september 2002 version) @@ -2125,7 +2168,7 @@ sis_initl(struct sis_softc *sc) /* Clear MAC disable. */ SIS_CLRBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE | SIS_CSR_RX_DISABLE); - sc->sis_link = 0; + sc->sis_flags &= ~SIS_FLAG_LINK; mii_mediachg(mii); ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -2148,7 +2191,6 @@ sis_ifmedia_upd(struct ifnet *ifp) SIS_LOCK(sc); mii = device_get_softc(sc->sis_miibus); - sc->sis_link = 0; if (mii->mii_instance) { struct mii_softc *miisc; LIST_FOREACH(miisc, &mii->mii_phys, mii_list) @@ -2304,7 +2346,7 @@ sis_stop(struct sis_softc *sc) CSR_WRITE_4(sc, SIS_TX_LISTPTR, 0); CSR_WRITE_4(sc, SIS_RX_LISTPTR, 0); - sc->sis_link = 0; + sc->sis_flags &= ~SIS_FLAG_LINK; /* * Free data in the RX lists. @@ -2351,6 +2393,32 @@ sis_shutdown(device_t dev) return (0); } +static void +sis_add_sysctls(struct sis_softc *sc) +{ + struct sysctl_ctx_list *ctx; + struct sysctl_oid_list *children; + char tn[32]; + int unit; + + ctx = device_get_sysctl_ctx(sc->sis_dev); + children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sis_dev)); + + unit = device_get_unit(sc->sis_dev); + /* + * Unlike most other controllers, NS DP83815/DP83816 controllers + * seem to pad with 0xFF when it encounter short frames. According + * to RFC 1042 the pad bytes should be 0x00. Turning this tunable + * on will have driver pad manully but it's disabled by default + * because it will consume extra CPU cycles for short frames. + */ + sc->sis_manual_pad = 0; + snprintf(tn, sizeof(tn), "dev.sis.%d.manual_pad", unit); + TUNABLE_INT_FETCH(tn, &sc->sis_manual_pad); + SYSCTL_ADD_INT(ctx, children, OID_AUTO, "manual_pad", + CTLFLAG_RW, &sc->sis_manual_pad, 0, "Manually pad short frames"); +} + static device_method_t sis_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sis_probe), Modified: head/sys/dev/sis/if_sisreg.h ============================================================================== --- head/sys/dev/sis/if_sisreg.h Thu Sep 2 17:51:41 2010 (r212156) +++ head/sys/dev/sis/if_sisreg.h Thu Sep 2 18:10:11 2010 (r212157) @@ -449,7 +449,10 @@ struct sis_softc { device_t sis_miibus; uint8_t sis_type; uint8_t sis_rev; - uint8_t sis_link; + uint32_t sis_flags; +#define SIS_FLAG_MANUAL_PAD 0x0800 +#define SIS_FLAG_LINK 0x8000 + int sis_manual_pad; uint32_t sis_srr; struct sis_desc *sis_rx_list; struct sis_desc *sis_tx_list;