From owner-p4-projects@FreeBSD.ORG Tue Apr 22 09:53:36 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8F4911065706; Tue, 22 Apr 2008 09:53:36 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 50BD71065702 for ; Tue, 22 Apr 2008 09:53:36 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 346898FC2B for ; Tue, 22 Apr 2008 09:53:36 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m3M9raLa023025 for ; Tue, 22 Apr 2008 09:53:36 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m3M9ran7023023 for perforce@freebsd.org; Tue, 22 Apr 2008 09:53:36 GMT (envelope-from jb@freebsd.org) Date: Tue, 22 Apr 2008 09:53:36 GMT Message-Id: <200804220953.m3M9ran7023023@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 140397 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Apr 2008 09:53:36 -0000 http://perforce.freebsd.org/chv.cgi?CH=140397 Change 140397 by jb@freebsd3 on 2008/04/22 09:52:57 IF7 Affected files ... .. //depot/projects/dtrace7/src/lib/libc/stdlib/strfmon.c#2 integrate .. //depot/projects/dtrace7/src/lib/libthr/thread/thr_mutexattr.c#2 integrate .. //depot/projects/dtrace7/src/share/man/man4/nfe.4#3 integrate .. //depot/projects/dtrace7/src/sys/dev/mii/ip1000phy.c#2 integrate .. //depot/projects/dtrace7/src/sys/dev/mii/ip1000phyreg.h#2 integrate .. //depot/projects/dtrace7/src/sys/dev/mii/miidevs#3 integrate .. //depot/projects/dtrace7/src/sys/dev/mii/rgephy.c#2 integrate .. //depot/projects/dtrace7/src/sys/dev/re/if_re.c#6 integrate .. //depot/projects/dtrace7/src/sys/pci/if_rl.c#5 integrate .. //depot/projects/dtrace7/src/sys/pci/if_rlreg.h#4 integrate Differences ... ==== //depot/projects/dtrace7/src/lib/libc/stdlib/strfmon.c#2 (text+ko) ==== @@ -26,7 +26,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.15 2005/09/12 19:52:42 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.15.2.1 2008/04/22 08:05:38 ru Exp $"); #include #include @@ -67,6 +67,8 @@ while (isdigit((unsigned char)*fmt)) { \ VAR *= 10; \ VAR += *fmt - '0'; \ + if (VAR < 0) \ + goto e2big_error; \ fmt++; \ } \ } while (0) @@ -187,7 +189,7 @@ /* Do we have enough space to put number with * required width ? */ - if (dst + width >= s + maxsize) + if ((unsigned int)width >= maxsize - (dst - s)) goto e2big_error; } @@ -196,6 +198,8 @@ if (!isdigit((unsigned char)*++fmt)) goto format_error; GET_NUMBER(left_prec); + if ((unsigned int)left_prec >= maxsize - (dst - s)) + goto e2big_error; } /* Right precision */ @@ -203,6 +207,9 @@ if (!isdigit((unsigned char)*++fmt)) goto format_error; GET_NUMBER(right_prec); + if ((unsigned int)right_prec >= maxsize - (dst - s) - + left_prec) + goto e2big_error; } /* Conversion Characters */ @@ -218,6 +225,8 @@ goto format_error; } + if (currency_symbol != NULL) + free(currency_symbol); if (flags & USE_INTL_CURRENCY) { currency_symbol = strdup(lc->int_curr_symbol); if (currency_symbol != NULL) @@ -246,6 +255,8 @@ pad_size = 0; } + if (asciivalue != NULL) + free(asciivalue); asciivalue = __format_grouped_double(value, &flags, left_prec, right_prec, pad_char); if (asciivalue == NULL) @@ -535,12 +546,11 @@ /* make sure that we've enough space for result string */ bufsize = strlen(avalue)*2+1; - rslt = malloc(bufsize); + rslt = calloc(1, bufsize); if (rslt == NULL) { free(avalue); return (NULL); } - memset(rslt, 0, bufsize); bufend = rslt + bufsize - 1; /* reserve space for trailing '\0' */ /* skip spaces at beggining */ ==== //depot/projects/dtrace7/src/lib/libthr/thread/thr_mutexattr.c#2 (text+ko) ==== @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libthr/thread/thr_mutexattr.c,v 1.7 2007/01/12 07:26:20 imp Exp $ + * $FreeBSD: src/lib/libthr/thread/thr_mutexattr.c,v 1.7.2.1 2008/04/22 01:28:15 davidxu Exp $ */ /* @@ -132,8 +132,7 @@ { int ret; if (attr == NULL || *attr == NULL || type >= PTHREAD_MUTEX_TYPE_MAX) { - errno = EINVAL; - ret = -1; + ret = EINVAL; } else { (*attr)->m_type = type; ret = 0; ==== //depot/projects/dtrace7/src/share/man/man4/nfe.4#3 (text+ko) ==== @@ -14,9 +14,9 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.\" $FreeBSD: src/share/man/man4/nfe.4,v 1.8.2.1 2007/12/02 08:45:57 remko Exp $ +.\" $FreeBSD: src/share/man/man4/nfe.4,v 1.8.2.2 2008/04/22 06:19:29 yongari Exp $ .\" -.Dd Nov 27, 2007 +.Dd April 16, 2008 .Dt NFE 4 .Os .Sh NAME @@ -43,7 +43,7 @@ driver supports PCI Ethernet adapters based on the NVIDIA nForce Media and Communications Processors (MCP), such as the nForce, nForce 2, nForce 3, CK804, MCP04, MCP51, MCP55, -MCP61, MCP65 and MCP67 Ethernet controller chips. +MCP61, MCP65, MCP67 and MCP73 Ethernet controller chips. .Pp Supported features include (hardware support provided): .Pp @@ -116,6 +116,8 @@ .It NVIDIA nForce MCP67 Networking Adapter .It +NVIDIA nForce MCP73 Networking Adapter +.It NVIDIA nForce2 MCP2 Networking Adapter .It NVIDIA nForce2 400 MCP4 Networking Adapter ==== //depot/projects/dtrace7/src/sys/dev/mii/ip1000phy.c#2 (text+ko) ==== @@ -27,10 +27,10 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/mii/ip1000phy.c,v 1.2 2006/12/02 15:32:33 marius Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/mii/ip1000phy.c,v 1.2.2.1 2008/04/22 06:35:37 yongari Exp $"); /* - * Driver for the IC Plus IP1000A 10/100/1000 PHY. + * Driver for the IC Plus IP1000A/IP1001 10/100/1000 PHY. */ #include @@ -57,6 +57,12 @@ static int ip1000phy_probe(device_t); static int ip1000phy_attach(device_t); +struct ip1000phy_softc { + struct mii_softc mii_sc; + int model; + int revision; +}; + static device_method_t ip1000phy_methods[] = { /* device interface */ DEVMETHOD(device_probe, ip1000phy_probe), @@ -82,6 +88,7 @@ static const struct mii_phydesc ip1000phys[] = { MII_PHY_DESC(ICPLUS, IP1000A), + MII_PHY_DESC(ICPLUS, IP1001), MII_PHY_END }; @@ -95,11 +102,13 @@ static int ip1000phy_attach(device_t dev) { + struct ip1000phy_softc *isc; struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; - sc = device_get_softc(dev); + isc = device_get_softc(dev); + sc = &isc->mii_sc; ma = device_get_ivars(dev); sc->mii_dev = device_get_parent(dev); mii = device_get_softc(sc->mii_dev); @@ -114,6 +123,9 @@ mii->mii_instance++; + isc->model = MII_MODEL(ma->mii_id2); + isc->revision = MII_REV(ma->mii_id2); + device_printf(dev, " "); #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) @@ -302,10 +314,13 @@ static void ip1000phy_status(struct mii_softc *sc) { + struct ip1000phy_softc *isc; struct mii_data *mii = sc->mii_pdata; uint32_t bmsr, bmcr, stat; uint32_t ar, lpar; + isc = (struct ip1000phy_softc *)sc; + mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER; @@ -326,25 +341,44 @@ } } - stat = PHY_READ(sc, STGE_PhyCtrl); - switch (PC_LinkSpeed(stat)) { - case PC_LinkSpeed_Down: - mii->mii_media_active |= IFM_NONE; - return; - case PC_LinkSpeed_10: - mii->mii_media_active |= IFM_10_T; - break; - case PC_LinkSpeed_100: - mii->mii_media_active |= IFM_100_TX; - break; - case PC_LinkSpeed_1000: - mii->mii_media_active |= IFM_1000_T; - break; + if (isc->model == MII_MODEL_ICPLUS_IP1001) { + stat = PHY_READ(sc, IP1000PHY_LSR); + switch (stat & IP1000PHY_LSR_SPEED_MASK) { + case IP1000PHY_LSR_SPEED_10: + mii->mii_media_active |= IFM_10_T; + break; + case IP1000PHY_LSR_SPEED_100: + mii->mii_media_active |= IFM_100_TX; + break; + case IP1000PHY_LSR_SPEED_1000: + mii->mii_media_active |= IFM_1000_T; + break; + } + if ((stat & IP1000PHY_LSR_FULL_DUPLEX) != 0) + mii->mii_media_active |= IFM_FDX; + else + mii->mii_media_active |= IFM_HDX; + } else { + stat = PHY_READ(sc, STGE_PhyCtrl); + switch (PC_LinkSpeed(stat)) { + case PC_LinkSpeed_Down: + mii->mii_media_active |= IFM_NONE; + return; + case PC_LinkSpeed_10: + mii->mii_media_active |= IFM_10_T; + break; + case PC_LinkSpeed_100: + mii->mii_media_active |= IFM_100_TX; + break; + case PC_LinkSpeed_1000: + mii->mii_media_active |= IFM_1000_T; + break; + } + if ((stat & PC_PhyDuplexStatus) != 0) + mii->mii_media_active |= IFM_FDX; + else + mii->mii_media_active |= IFM_HDX; } - if ((stat & PC_PhyDuplexStatus) != 0) - mii->mii_media_active |= IFM_FDX; - else - mii->mii_media_active |= IFM_HDX; ar = PHY_READ(sc, IP1000PHY_MII_ANAR); lpar = PHY_READ(sc, IP1000PHY_MII_ANLPAR); @@ -410,10 +444,12 @@ static void ip1000phy_reset(struct mii_softc *sc) { + struct ip1000phy_softc *isc; struct stge_softc *stge_sc; struct mii_data *mii; uint32_t reg; + isc = (struct ip1000phy_softc *)sc; mii_phy_reset(sc); /* clear autoneg/full-duplex as we don't want it after reset */ @@ -426,7 +462,8 @@ * XXX There should be more general way to pass PHY specific * data via mii interface. */ - if (strcmp(mii->mii_ifp->if_dname, "stge") == 0) { + if (isc->model == MII_MODEL_ICPLUS_IP1000A && + strcmp(mii->mii_ifp->if_dname, "stge") == 0) { stge_sc = mii->mii_ifp->if_softc; if (stge_sc->sc_rev >= 0x40 && stge_sc->sc_rev <= 0x4e) ip1000phy_load_dspcode(sc); ==== //depot/projects/dtrace7/src/sys/dev/mii/ip1000phyreg.h#2 (text+ko) ==== @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/mii/ip1000phyreg.h,v 1.1 2006/07/25 00:16:09 yongari Exp $ + * $FreeBSD: src/sys/dev/mii/ip1000phyreg.h,v 1.1.4.1 2008/04/22 06:35:37 yongari Exp $ */ #ifndef _DEV_MII_IP1000PHYREG_H_ @@ -138,4 +138,49 @@ #define IP1000PHY_EXTSTS_1000X 0x4000 #define IP1000PHY_EXTSTS_1000X_FDX 0x8000 +/* PHY specific control & status register. IP1001 only. */ +#define IP1000PHY_SCSR 0x10 +#define IP1000PHY_SCSR_RXPHASE_SEL 0x0001 +#define IP1000PHY_SCSR_TXPHASE_SEL 0x0002 +#define IP1000PHY_SCSR_REPEATOR_MODE 0x0004 +#define IP1000PHY_SCSR_RESERVED1_DEF 0x0008 +#define IP1000PHY_SCSR_RXCLK_DRV_MASK 0x0060 +#define IP1000PHY_SCSR_RXCLK_DRV_DEF 0x0040 +#define IP1000PHY_SCSR_RXD_DRV_MASK 0x0180 +#define IP1000PHY_SCSR_RXD_DRV_DEF 0x0100 +#define IP1000PHY_SCSR_JABBER_ENB 0x0200 +#define IP1000PHY_SCSR_HEART_BEAT_ENB 0x0400 +#define IP1000PHY_SCSR_DOWNSHIFT_ENB 0x0800 +#define IP1000PHY_SCSR_RESERVED2_DEF 0x1000 +#define IP1000PHY_SCSR_LED_DRV_4MA 0x0000 +#define IP1000PHY_SCSR_LED_DRV_8MA 0x2000 +#define IP1000PHY_SCSR_LED_MODE_MASK 0xC000 +#define IP1000PHY_SCSR_LED_MODE_DEF 0x0000 + +/* PHY link status register. IP1001 only. */ +#define IP1000PHY_LSR 0x11 +#define IP1000PHY_LSR_JABBER_DET 0x0200 +#define IP1000PHY_LSR_APS_SLEEP 0x0400 +#define IP1000PHY_LSR_MDIX 0x0800 +#define IP1000PHY_LSR_FULL_DUPLEX 0x1000 +#define IP1000PHY_LSR_SPEED_10 0x0000 +#define IP1000PHY_LSR_SPEED_100 0x2000 +#define IP1000PHY_LSR_SPEED_1000 0x4000 +#define IP1000PHY_LSR_SPEED_MASK 0x6000 +#define IP1000PHY_LSR_LINKUP 0x8000 + +/* PHY specific control register 2. IP1001 only. */ +#define IP1000PHY_SCR +#define IP1000PHY_SCR_SEW_RATE_MASK 0x0003 +#define IP1000PHY_SCR_SEW_RATE_DEF 0x0003 +#define IP1000PHY_SCR_AUTO_XOVER 0x0004 +#define IP1000PHY_SCR_SPEED_10_100_ENB 0x0040 +#define IP1000PHY_SCR_FIFO_LATENCY_2 0x0000 +#define IP1000PHY_SCR_FIFO_LATENCY_3 0x0080 +#define IP1000PHY_SCR_FIFO_LATENCY_4 0x0100 +#define IP1000PHY_SCR_FIFO_LATENCY_5 0x0180 +#define IP1000PHY_SCR_MDIX_ENB 0x0200 +#define IP1000PHY_SCR_RESERVED_DEF 0x0400 +#define IP1000PHY_SCR_APS_ON 0x0800 + #endif /* _DEV_MII_IP1000PHYREG_H_ */ ==== //depot/projects/dtrace7/src/sys/dev/mii/miidevs#3 (text+ko) ==== @@ -1,4 +1,4 @@ -$FreeBSD: src/sys/dev/mii/miidevs,v 1.46.2.3 2008/03/17 18:23:44 jhb Exp $ +$FreeBSD: src/sys/dev/mii/miidevs,v 1.46.2.4 2008/04/22 06:35:37 yongari Exp $ /*$NetBSD: miidevs,v 1.6 1999/05/14 11:37:30 drochner Exp $*/ /*- @@ -156,6 +156,7 @@ /* IC Plus Corp. PHYs */ model ICPLUS IP101 0x0005 IC Plus 10/100 PHY model ICPLUS IP1000A 0x0008 IC Plus 10/100/1000 media interface +model ICPLUS IP1001 0x0019 IC Plus IP1001 10/100/1000 media interface /* Intel PHYs */ model xxINTEL I82553AB 0x0000 i83553 10/100 media interface ==== //depot/projects/dtrace7/src/sys/dev/mii/rgephy.c#2 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/mii/rgephy.c,v 1.15.2.2 2007/11/05 01:39:25 yongari Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/mii/rgephy.c,v 1.15.2.3 2008/04/22 06:25:11 yongari Exp $"); /* * Driver for the RealTek 8169S/8110S/8211B internal 10/100/1000 PHY. @@ -367,6 +367,11 @@ bmsr = PHY_READ(sc, RGEPHY_MII_BMSR); bmcr = PHY_READ(sc, RGEPHY_MII_BMCR); + if (bmcr & RGEPHY_BMCR_ISO) { + mii->mii_media_active |= IFM_NONE; + mii->mii_media_status = 0; + return; + } if (bmcr & RGEPHY_BMCR_LOOP) mii->mii_media_active |= IFM_LOOP; ==== //depot/projects/dtrace7/src/sys/dev/re/if_re.c#6 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.95.2.5 2008/03/13 07:50:47 yongari Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.95.2.18 2008/04/22 06:14:56 yongari Exp $"); /* * RealTek 8139C+/8169/8169S/8110S/8168/8111/8101E PCI NIC driver @@ -146,6 +146,8 @@ #include #include +#include + MODULE_DEPEND(re, pci, 1, 1, 1); MODULE_DEPEND(re, ether, 1, 1, 1); MODULE_DEPEND(re, miibus, 1, 1, 1); @@ -158,10 +160,8 @@ */ #define RE_USEIOSPACE -#include - /* Tunables. */ -static int msi_disable = 0; +static int msi_disable = 1; TUNABLE_INT("hw.re.msi_disable", &msi_disable); #define RE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) @@ -201,8 +201,7 @@ { LINKSYS_VENDORID, LINKSYS_DEVICEID_EG1032, RL_HWREV_8169S, "Linksys EG1032 (RTL8169S) Gigabit Ethernet" }, { USR_VENDORID, USR_DEVICEID_997902, RL_HWREV_8169S, - "US Robotics 997902 (RTL8169S) Gigabit Ethernet" }, - { 0, 0, 0, NULL } + "US Robotics 997902 (RTL8169S) Gigabit Ethernet" } }; static struct rl_hwrev re_hwrevs[] = { @@ -233,13 +232,13 @@ static int re_attach (device_t); static int re_detach (device_t); -static int re_encap (struct rl_softc *, struct mbuf **, int *); +static int re_encap (struct rl_softc *, struct mbuf **); static void re_dma_map_addr (void *, bus_dma_segment_t *, int, int); -static void re_dma_map_desc (void *, bus_dma_segment_t *, int, - bus_size_t, int); static int re_allocmem (device_t, struct rl_softc *); -static int re_newbuf (struct rl_softc *, int, struct mbuf *); +static __inline void re_discard_rxbuf + (struct rl_softc *, int); +static int re_newbuf (struct rl_softc *, int); static int re_rx_list_init (struct rl_softc *); static int re_tx_list_init (struct rl_softc *); #ifdef RE_FIXUP_RX @@ -280,6 +279,8 @@ static void re_setmulti (struct rl_softc *); static void re_reset (struct rl_softc *); +static void re_setwol (struct rl_softc *); +static void re_clrwol (struct rl_softc *); #ifdef RE_DIAG static int re_diag (struct rl_softc *); @@ -849,14 +850,14 @@ bus_dmamap_sync(sc->rl_ldata.rl_rx_list_tag, sc->rl_ldata.rl_rx_list_map, BUS_DMASYNC_POSTREAD); - bus_dmamap_sync(sc->rl_ldata.rl_mtag, - sc->rl_ldata.rl_rx_dmamap[0], - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->rl_ldata.rl_mtag, - sc->rl_ldata.rl_rx_dmamap[0]); + bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag, + sc->rl_ldata.rl_rx_desc[0].rx_dmamap, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->rl_ldata.rl_rx_mtag, + sc->rl_ldata.rl_rx_desc[0].rx_dmamap); - m0 = sc->rl_ldata.rl_rx_mbuf[0]; - sc->rl_ldata.rl_rx_mbuf[0] = NULL; + m0 = sc->rl_ldata.rl_rx_desc[0].rx_m; + sc->rl_ldata.rl_rx_desc[0].rx_m = NULL; eh = mtod(m0, struct ether_header *); cur_rx = &sc->rl_ldata.rl_rx_list[0]; @@ -916,133 +917,41 @@ device_t dev; { struct rl_type *t; - struct rl_softc *sc; - int rid; - u_int32_t hwrev; + uint16_t devid, vendor; + uint16_t revid, sdevid; + int i; + + vendor = pci_get_vendor(dev); + devid = pci_get_device(dev); + revid = pci_get_revid(dev); + sdevid = pci_get_subdevice(dev); - t = re_devs; - sc = device_get_softc(dev); - - while (t->rl_name != NULL) { - if ((pci_get_vendor(dev) == t->rl_vid) && - (pci_get_device(dev) == t->rl_did)) { + if (vendor == LINKSYS_VENDORID && devid == LINKSYS_DEVICEID_EG1032) { + if (sdevid != LINKSYS_SUBDEVICE_EG1032_REV3) { /* * Only attach to rev. 3 of the Linksys EG1032 adapter. - * Rev. 2 i supported by sk(4). + * Rev. 2 is supported by sk(4). */ - if ((t->rl_vid == LINKSYS_VENDORID) && - (t->rl_did == LINKSYS_DEVICEID_EG1032) && - (pci_get_subdevice(dev) != - LINKSYS_SUBDEVICE_EG1032_REV3)) { - t++; - continue; - } - - /* - * Temporarily map the I/O space - * so we can read the chip ID register. - */ - rid = RL_RID; - sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, - RF_ACTIVE); - if (sc->rl_res == NULL) { - device_printf(dev, - "couldn't map ports/memory\n"); - return (ENXIO); - } - sc->rl_btag = rman_get_bustag(sc->rl_res); - sc->rl_bhandle = rman_get_bushandle(sc->rl_res); - hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV; - bus_release_resource(dev, RL_RES, - RL_RID, sc->rl_res); - if (t->rl_basetype == hwrev) { - device_set_desc(dev, t->rl_name); - return (BUS_PROBE_DEFAULT); - } + return (ENXIO); } - t++; } - return (ENXIO); -} - -/* - * This routine takes the segment list provided as the result of - * a bus_dma_map_load() operation and assigns the addresses/lengths - * to RealTek DMA descriptors. This can be called either by the RX - * code or the TX code. In the RX case, we'll probably wind up mapping - * at most one segment. For the TX case, there could be any number of - * segments since TX packets may span multiple mbufs. In either case, - * if the number of segments is larger than the rl_maxsegs limit - * specified by the caller, we abort the mapping operation. Sadly, - * whoever designed the buffer mapping API did not provide a way to - * return an error from here, so we have to fake it a bit. - */ - -static void -re_dma_map_desc(arg, segs, nseg, mapsize, error) - void *arg; - bus_dma_segment_t *segs; - int nseg; - bus_size_t mapsize; - int error; -{ - struct rl_dmaload_arg *ctx; - struct rl_desc *d = NULL; - int i = 0, idx; - u_int32_t cmdstat; - int totlen = 0; - - if (error) - return; - - ctx = arg; - - /* Signal error to caller if there's too many segments */ - if (nseg > ctx->rl_maxsegs) { - ctx->rl_maxsegs = 0; - return; + if (vendor == RT_VENDORID && devid == RT_DEVICEID_8139) { + if (revid != 0x20) { + /* 8139, let rl(4) take care of this device. */ + return (ENXIO); + } } - /* - * Map the segment array into descriptors. Note that we set the - * start-of-frame and end-of-frame markers for either TX or RX, but - * they really only have meaning in the TX case. (In the RX case, - * it's the chip that tells us where packets begin and end.) - * We also keep track of the end of the ring and set the - * end-of-ring bits as needed, and we set the ownership bits - * in all except the very first descriptor. (The caller will - * set this descriptor later when it start transmission or - * reception.) - */ - idx = ctx->rl_idx; - for (;;) { - d = &ctx->rl_ring[idx]; - if (le32toh(d->rl_cmdstat) & RL_RDESC_STAT_OWN) { - ctx->rl_maxsegs = 0; - return; + t = re_devs; + for (i = 0; i < sizeof(re_devs) / sizeof(re_devs[0]); i++, t++) { + if (vendor == t->rl_vid && devid == t->rl_did) { + device_set_desc(dev, t->rl_name); + return (BUS_PROBE_DEFAULT); } - cmdstat = segs[i].ds_len; - totlen += segs[i].ds_len; - d->rl_vlanctl = 0; - d->rl_bufaddr_lo = htole32(RL_ADDR_LO(segs[i].ds_addr)); - d->rl_bufaddr_hi = htole32(RL_ADDR_HI(segs[i].ds_addr)); - if (i == 0) - cmdstat |= RL_TDESC_CMD_SOF; - else - cmdstat |= RL_TDESC_CMD_OWN; - if (idx == (RL_RX_DESC_CNT - 1)) - cmdstat |= RL_TDESC_CMD_EOR; - d->rl_cmdstat = htole32(cmdstat | ctx->rl_flags); - i++; - if (i == nseg) - break; - RL_DESC_INC(idx); } - d->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF); - ctx->rl_maxsegs = nseg; - ctx->rl_idx = idx; + return (ENXIO); } /* @@ -1071,21 +980,52 @@ device_t dev; struct rl_softc *sc; { + bus_size_t rx_list_size, tx_list_size; int error; - int nseg; int i; + rx_list_size = sc->rl_ldata.rl_rx_desc_cnt * sizeof(struct rl_desc); + tx_list_size = sc->rl_ldata.rl_tx_desc_cnt * sizeof(struct rl_desc); + + /* + * Allocate the parent bus DMA tag appropriate for PCI. + * In order to use DAC, RL_CPLUSCMD_PCI_DAC bit of RL_CPLUS_CMD + * register should be set. However some RealTek chips are known + * to be buggy on DAC handling, therefore disable DAC by limiting + * DMA address space to 32bit. PCIe variants of RealTek chips + * may not have the limitation but I took safer path. + */ + error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, + NULL, NULL, &sc->rl_parent_tag); + if (error) { + device_printf(dev, "could not allocate parent DMA tag\n"); + return (error); + } + /* + * Allocate map for TX mbufs. + */ + error = bus_dma_tag_create(sc->rl_parent_tag, 1, 0, + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, + NULL, MCLBYTES * RL_NTXSEGS, RL_NTXSEGS, 4096, 0, + NULL, NULL, &sc->rl_ldata.rl_tx_mtag); + if (error) { + device_printf(dev, "could not allocate TX DMA tag\n"); + return (error); + } + + /* * Allocate map for RX mbufs. */ - nseg = 32; - error = bus_dma_tag_create(sc->rl_parent_tag, ETHER_ALIGN, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, - NULL, MCLBYTES * nseg, nseg, MCLBYTES, BUS_DMA_ALLOCNOW, - NULL, NULL, &sc->rl_ldata.rl_mtag); + + error = bus_dma_tag_create(sc->rl_parent_tag, sizeof(uint64_t), 0, + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, + MCLBYTES, 1, MCLBYTES, 0, NULL, NULL, &sc->rl_ldata.rl_rx_mtag); if (error) { - device_printf(dev, "could not allocate dma tag\n"); - return (ENOMEM); + device_printf(dev, "could not allocate RX DMA tag\n"); + return (error); } /* @@ -1093,36 +1033,44 @@ */ error = bus_dma_tag_create(sc->rl_parent_tag, RL_RING_ALIGN, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, - NULL, RL_TX_LIST_SZ, 1, RL_TX_LIST_SZ, 0, + NULL, tx_list_size, 1, tx_list_size, 0, NULL, NULL, &sc->rl_ldata.rl_tx_list_tag); if (error) { - device_printf(dev, "could not allocate dma tag\n"); - return (ENOMEM); + device_printf(dev, "could not allocate TX DMA ring tag\n"); + return (error); } /* Allocate DMA'able memory for the TX ring */ error = bus_dmamem_alloc(sc->rl_ldata.rl_tx_list_tag, - (void **)&sc->rl_ldata.rl_tx_list, BUS_DMA_NOWAIT | BUS_DMA_ZERO, + (void **)&sc->rl_ldata.rl_tx_list, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->rl_ldata.rl_tx_list_map); - if (error) - return (ENOMEM); + if (error) { + device_printf(dev, "could not allocate TX DMA ring\n"); + return (error); + } /* Load the map for the TX ring. */ + sc->rl_ldata.rl_tx_list_addr = 0; error = bus_dmamap_load(sc->rl_ldata.rl_tx_list_tag, sc->rl_ldata.rl_tx_list_map, sc->rl_ldata.rl_tx_list, - RL_TX_LIST_SZ, re_dma_map_addr, + tx_list_size, re_dma_map_addr, &sc->rl_ldata.rl_tx_list_addr, BUS_DMA_NOWAIT); + if (error != 0 || sc->rl_ldata.rl_tx_list_addr == 0) { + device_printf(dev, "could not load TX DMA ring\n"); + return (ENOMEM); + } /* Create DMA maps for TX buffers */ - for (i = 0; i < RL_TX_DESC_CNT; i++) { - error = bus_dmamap_create(sc->rl_ldata.rl_mtag, 0, - &sc->rl_ldata.rl_tx_dmamap[i]); + for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++) { + error = bus_dmamap_create(sc->rl_ldata.rl_tx_mtag, 0, + &sc->rl_ldata.rl_tx_desc[i].tx_dmamap); if (error) { - device_printf(dev, "can't create DMA map for TX\n"); - return (ENOMEM); + device_printf(dev, "could not create DMA map for TX\n"); + return (error); } } @@ -1131,36 +1079,50 @@ */ error = bus_dma_tag_create(sc->rl_parent_tag, RL_RING_ALIGN, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, - NULL, RL_RX_LIST_SZ, 1, RL_RX_LIST_SZ, 0, + NULL, rx_list_size, 1, rx_list_size, 0, NULL, NULL, &sc->rl_ldata.rl_rx_list_tag); if (error) { - device_printf(dev, "could not allocate dma tag\n"); - return (ENOMEM); + device_printf(dev, "could not create RX DMA ring tag\n"); + return (error); } /* Allocate DMA'able memory for the RX ring */ error = bus_dmamem_alloc(sc->rl_ldata.rl_rx_list_tag, - (void **)&sc->rl_ldata.rl_rx_list, BUS_DMA_NOWAIT | BUS_DMA_ZERO, + (void **)&sc->rl_ldata.rl_rx_list, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->rl_ldata.rl_rx_list_map); - if (error) - return (ENOMEM); + if (error) { + device_printf(dev, "could not allocate RX DMA ring\n"); + return (error); + } /* Load the map for the RX ring. */ + sc->rl_ldata.rl_rx_list_addr = 0; error = bus_dmamap_load(sc->rl_ldata.rl_rx_list_tag, sc->rl_ldata.rl_rx_list_map, sc->rl_ldata.rl_rx_list, - RL_RX_LIST_SZ, re_dma_map_addr, + rx_list_size, re_dma_map_addr, &sc->rl_ldata.rl_rx_list_addr, BUS_DMA_NOWAIT); + if (error != 0 || sc->rl_ldata.rl_rx_list_addr == 0) { + device_printf(dev, "could not load RX DMA ring\n"); + return (ENOMEM); + } /* Create DMA maps for RX buffers */ - for (i = 0; i < RL_RX_DESC_CNT; i++) { - error = bus_dmamap_create(sc->rl_ldata.rl_mtag, 0, - &sc->rl_ldata.rl_rx_dmamap[i]); + error = bus_dmamap_create(sc->rl_ldata.rl_rx_mtag, 0, + &sc->rl_ldata.rl_rx_sparemap); + if (error) { + device_printf(dev, "could not create spare DMA map for RX\n"); + return (error); + } + for (i = 0; i < sc->rl_ldata.rl_rx_desc_cnt; i++) { + error = bus_dmamap_create(sc->rl_ldata.rl_rx_mtag, 0, + &sc->rl_ldata.rl_rx_desc[i].rx_dmamap); if (error) { - device_printf(dev, "can't create DMA map for RX\n"); - return (ENOMEM); + device_printf(dev, "could not create DMA map for RX\n"); + return (error); } } @@ -1184,6 +1146,7 @@ u_int16_t re_did = 0; int error = 0, rid, i; int msic, reg; + uint8_t cfg; sc = device_get_softc(dev); sc->rl_dev = dev; @@ -1222,6 +1185,12 @@ device_printf(dev, "Using %d MSI messages\n", msic); sc->rl_msi = 1; + /* Explicitly set MSI enable bit. */ + CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE); + cfg = CSR_READ_1(sc, RL_CFG2); + cfg |= RL_CFG2_MSI; + CSR_WRITE_1(sc, RL_CFG2, cfg); + CSR_WRITE_1(sc, RL_EECMD, 0); } else pci_release_msi(dev); } @@ -1265,6 +1234,11 @@ } hw_rev++; } + if (hw_rev->rl_desc == NULL) { + device_printf(dev, "Unknown H/W revision: %08x\n", hwrev); + error = ENXIO; + goto fail; + } sc->rl_eewidth = RL_9356_ADDR_LEN; re_read_eeprom(sc, (caddr_t)&re_did, 0, 1); @@ -1280,28 +1254,25 @@ bcopy(as, eaddr, sizeof(eaddr)); if (sc->rl_type == RL_8169) { - /* Set RX length mask */ + /* Set RX length mask and number of descriptors. */ sc->rl_rxlenmask = RL_RDESC_STAT_GFRAGLEN; sc->rl_txstart = RL_GTXSTART; + sc->rl_ldata.rl_tx_desc_cnt = RL_8169_TX_DESC_CNT; + sc->rl_ldata.rl_rx_desc_cnt = RL_8169_RX_DESC_CNT; } else { - /* Set RX length mask */ + /* Set RX length mask and number of descriptors. */ sc->rl_rxlenmask = RL_RDESC_STAT_FRAGLEN; sc->rl_txstart = RL_TXSTART; + sc->rl_ldata.rl_tx_desc_cnt = RL_8139_TX_DESC_CNT; + sc->rl_ldata.rl_rx_desc_cnt = RL_8139_RX_DESC_CNT; } - - /* - * Allocate the parent bus DMA tag appropriate for PCI. - */ -#define RL_NSEG_NEW 32 - error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - MAXBSIZE, RL_NSEG_NEW, BUS_SPACE_MAXSIZE_32BIT, 0, - NULL, NULL, &sc->rl_parent_tag); - if (error) + if (hw_rev->rl_desc == NULL) { + device_printf(dev, "Unsupported revision : 0x%08x\n", hwrev); + error = ENXIO; goto fail; + } error = re_allocmem(dev, sc); - if (error) goto fail; @@ -1348,8 +1319,8 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = re_ioctl; ifp->if_start = re_start; - ifp->if_hwassist = RE_CSUM_FEATURES; - ifp->if_capabilities = IFCAP_HWCSUM; + ifp->if_hwassist = RE_CSUM_FEATURES | CSUM_TSO; + ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4; ifp->if_capenable = ifp->if_capabilities; ifp->if_init = re_init; IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN); @@ -1368,6 +1339,9 @@ ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING; if (ifp->if_capabilities & IFCAP_HWCSUM) ifp->if_capabilities |= IFCAP_VLAN_HWCSUM; + /* Enable WOL if PM is supported. */ + if (pci_find_extcap(sc->rl_dev, PCIY_PMG, ®) == 0) + ifp->if_capabilities |= IFCAP_WOL; ifp->if_capenable = ifp->if_capabilities; #ifdef DEVICE_POLLING ifp->if_capabilities |= IFCAP_POLLING; @@ -1534,14 +1508,20 @@ /* Destroy all the RX and TX buffer maps */ - if (sc->rl_ldata.rl_mtag) { - for (i = 0; i < RL_TX_DESC_CNT; i++) - bus_dmamap_destroy(sc->rl_ldata.rl_mtag, - sc->rl_ldata.rl_tx_dmamap[i]); - for (i = 0; i < RL_RX_DESC_CNT; i++) - bus_dmamap_destroy(sc->rl_ldata.rl_mtag, - sc->rl_ldata.rl_rx_dmamap[i]); - bus_dma_tag_destroy(sc->rl_ldata.rl_mtag); + if (sc->rl_ldata.rl_tx_mtag) { + for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++) + bus_dmamap_destroy(sc->rl_ldata.rl_tx_mtag, + sc->rl_ldata.rl_tx_desc[i].tx_dmamap); + bus_dma_tag_destroy(sc->rl_ldata.rl_tx_mtag); + } + if (sc->rl_ldata.rl_rx_mtag) { + for (i = 0; i < sc->rl_ldata.rl_rx_desc_cnt; i++) + bus_dmamap_destroy(sc->rl_ldata.rl_rx_mtag, + sc->rl_ldata.rl_rx_desc[i].rx_dmamap); + if (sc->rl_ldata.rl_rx_sparemap) + bus_dmamap_destroy(sc->rl_ldata.rl_rx_mtag, + sc->rl_ldata.rl_rx_sparemap); + bus_dma_tag_destroy(sc->rl_ldata.rl_rx_mtag); } /* Unload and free the stats buffer and map */ @@ -1563,23 +1543,40 @@ return (0); } +static __inline void +re_discard_rxbuf(sc, idx) + struct rl_softc *sc; + int idx; +{ + struct rl_desc *desc; + struct rl_rxdesc *rxd; + uint32_t cmdstat; + + rxd = &sc->rl_ldata.rl_rx_desc[idx]; + desc = &sc->rl_ldata.rl_rx_list[idx]; + desc->rl_vlanctl = 0; + cmdstat = rxd->rx_size; + if (idx == sc->rl_ldata.rl_rx_desc_cnt - 1) + cmdstat |= RL_RDESC_CMD_EOR; + desc->rl_cmdstat = htole32(cmdstat | RL_RDESC_CMD_OWN); +} + static int -re_newbuf(sc, idx, m) +re_newbuf(sc, idx) struct rl_softc *sc; int idx; +{ struct mbuf *m; >>> TRUNCATED FOR MAIL (1000 lines) <<<