From owner-svn-src-stable@FreeBSD.ORG Sun Nov 28 15:59:46 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0E1C61065781; Sun, 28 Nov 2010 15:59:46 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id EF0938FC08; Sun, 28 Nov 2010 15:59:45 +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 oASFxj3f024973; Sun, 28 Nov 2010 15:59:45 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oASFxj46024969; Sun, 28 Nov 2010 15:59:45 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201011281559.oASFxj46024969@svn.freebsd.org> From: Marius Strobl Date: Sun, 28 Nov 2010 15:59:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r216003 - stable/7/sys/dev/fxp X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 28 Nov 2010 15:59:46 -0000 Author: marius Date: Sun Nov 28 15:59:45 2010 New Revision: 216003 URL: http://svn.freebsd.org/changeset/base/216003 Log: MFC: r215906 Fix and implement missing parts of flow control support. This also removes the dev.fxp.%d.noflow tunable as the same effect can now be achieved with ifconfig(8) by setting the flowcontrol media option as desired (besides the tunable never having a chance to actually enable flow control support so far). In joint forces with: yongari Modified: stable/7/sys/dev/fxp/if_fxp.c stable/7/sys/dev/fxp/if_fxpreg.h stable/7/sys/dev/fxp/if_fxpvar.h Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/dev/fxp/if_fxp.c ============================================================================== --- stable/7/sys/dev/fxp/if_fxp.c Sun Nov 28 15:59:39 2010 (r216002) +++ stable/7/sys/dev/fxp/if_fxp.c Sun Nov 28 15:59:45 2010 (r216003) @@ -224,7 +224,7 @@ static void fxp_rxcsum(struct fxp_softc static void fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack, int count); static void fxp_init(void *xsc); -static void fxp_init_body(struct fxp_softc *sc); +static void fxp_init_body(struct fxp_softc *sc, int); static void fxp_tick(void *xsc); static void fxp_start(struct ifnet *ifp); static void fxp_start_body(struct ifnet *ifp); @@ -261,6 +261,7 @@ static void fxp_serial_ifmedia_sts(stru static int fxp_miibus_readreg(device_t dev, int phy, int reg); static void fxp_miibus_writereg(device_t dev, int phy, int reg, int value); +static void fxp_miibus_statchg(device_t dev); static void fxp_load_ucode(struct fxp_softc *sc); static void fxp_update_stats(struct fxp_softc *sc); static void fxp_sysctl_node(struct fxp_softc *sc); @@ -286,6 +287,7 @@ static device_method_t fxp_methods[] = { /* MII interface */ DEVMETHOD(miibus_readreg, fxp_miibus_readreg), DEVMETHOD(miibus_writereg, fxp_miibus_writereg), + DEVMETHOD(miibus_statchg, fxp_miibus_statchg), { 0, 0 } }; @@ -330,8 +332,8 @@ fxp_scb_wait(struct fxp_softc *sc) while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i) DELAY(2); if (i == 0) { - flowctl.b[0] = CSR_READ_1(sc, FXP_CSR_FLOWCONTROL); - flowctl.b[1] = CSR_READ_1(sc, FXP_CSR_FLOWCONTROL + 1); + flowctl.b[0] = CSR_READ_1(sc, FXP_CSR_FC_THRESH); + flowctl.b[1] = CSR_READ_1(sc, FXP_CSR_FC_STATUS); device_printf(sc->dev, "SCB timeout: 0x%x 0x%x 0x%x 0x%x\n", CSR_READ_1(sc, FXP_CSR_SCB_COMMAND), CSR_READ_1(sc, FXP_CSR_SCB_STATACK), @@ -427,8 +429,7 @@ fxp_attach(device_t dev) uint32_t val; uint16_t data, myea[ETHER_ADDR_LEN / 2]; u_char eaddr[ETHER_ADDR_LEN]; - int i, pmc, prefer_iomap; - int error; + int error, flags, i, pmc, prefer_iomap; error = 0; sc = device_get_softc(dev); @@ -808,11 +809,14 @@ fxp_attach(device_t dev) /* * i82557 wedge when isolating all of their PHYs. */ + flags = MIIF_NOISOLATE; + if (sc->revision >= FXP_REV_82558_A4) + flags |= MIIF_DOPAUSE; error = mii_attach(dev, &sc->miibus, ifp, fxp_ifmedia_upd, fxp_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, - MII_OFFSET_ANY, MIIF_NOISOLATE); + MII_OFFSET_ANY, flags); if (error != 0) { - device_printf(dev, "attaching PHYs failed\n"); + device_printf(dev, "attaching PHYs failed\n"); goto fail; } } @@ -895,7 +899,7 @@ fxp_attach(device_t dev) FXP_LOCK(sc); /* Clear wakeup events. */ CSR_WRITE_1(sc, FXP_CSR_PMDR, CSR_READ_1(sc, FXP_CSR_PMDR)); - fxp_init_body(sc); + fxp_init_body(sc, 1); fxp_stop(sc); FXP_UNLOCK(sc); } @@ -1057,7 +1061,7 @@ fxp_suspend(device_t dev) pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; sc->flags |= FXP_FLAG_WOL; /* Reconfigure hardware to accept magic frames. */ - fxp_init_body(sc); + fxp_init_body(sc, 1); } pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2); } @@ -1099,7 +1103,7 @@ fxp_resume(device_t dev) /* reinitialize interface if necessary */ if (ifp->if_flags & IFF_UP) - fxp_init_body(sc); + fxp_init_body(sc, 1); sc->suspended = 0; @@ -2100,7 +2104,7 @@ fxp_tick(void *xsc) if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) { sc->rx_idle_secs = 0; if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - fxp_init_body(sc); + fxp_init_body(sc, 1); return; } /* @@ -2198,7 +2202,7 @@ fxp_watchdog(struct fxp_softc *sc) device_printf(sc->dev, "device timeout\n"); sc->ifp->if_oerrors++; - fxp_init_body(sc); + fxp_init_body(sc, 1); } /* @@ -2212,7 +2216,7 @@ fxp_init(void *xsc) struct fxp_softc *sc = xsc; FXP_LOCK(sc); - fxp_init_body(sc); + fxp_init_body(sc, 1); FXP_UNLOCK(sc); } @@ -2221,9 +2225,10 @@ fxp_init(void *xsc) * softc lock held. */ static void -fxp_init_body(struct fxp_softc *sc) +fxp_init_body(struct fxp_softc *sc, int setmedia) { struct ifnet *ifp = sc->ifp; + struct mii_data *mii; struct fxp_cb_config *cbp; struct fxp_cb_ias *cb_ias; struct fxp_cb_tx *tcbp; @@ -2358,7 +2363,7 @@ fxp_init_body(struct fxp_softc *sc) cbp->vlan_strip_en = ((sc->flags & FXP_FLAG_EXT_RFA) != 0 && (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) ? 1 : 0; - if (sc->tunable_noflow || sc->revision == FXP_REV_82557) { + if (sc->revision == FXP_REV_82557) { /* * The 82557 has no hardware flow control, the values * below are the defaults for the chip. @@ -2372,12 +2377,30 @@ fxp_init_body(struct fxp_softc *sc) cbp->fc_filter = 0; cbp->pri_fc_loc = 1; } else { - cbp->fc_delay_lsb = 0x1f; - cbp->fc_delay_msb = 0x01; + /* Set pause RX FIFO threshold to 1KB. */ + CSR_WRITE_1(sc, FXP_CSR_FC_THRESH, 1); + /* Set pause time. */ + cbp->fc_delay_lsb = 0xff; + cbp->fc_delay_msb = 0xff; cbp->pri_fc_thresh = 3; - cbp->tx_fc_dis = 0; /* enable transmit FC */ - cbp->rx_fc_restop = 1; /* enable FC restop frames */ - cbp->rx_fc_restart = 1; /* enable FC restart frames */ + mii = device_get_softc(sc->miibus); + if ((IFM_OPTIONS(mii->mii_media_active) & + IFM_ETH_TXPAUSE) != 0) + /* enable transmit FC */ + cbp->tx_fc_dis = 0; + else + /* disable transmit FC */ + cbp->tx_fc_dis = 1; + if ((IFM_OPTIONS(mii->mii_media_active) & + IFM_ETH_RXPAUSE) != 0) { + /* enable FC restart/restop frames */ + cbp->rx_fc_restart = 1; + cbp->rx_fc_restop = 1; + } else { + /* disable FC restart/restop frames */ + cbp->rx_fc_restart = 0; + cbp->rx_fc_restop = 0; + } cbp->fc_filter = !prm; /* drop FC frames to host */ cbp->pri_fc_loc = 1; /* FC pri location (byte31) */ } @@ -2476,10 +2499,7 @@ fxp_init_body(struct fxp_softc *sc) CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->fxp_desc.rx_head->rx_addr); fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START); - /* - * Set current media. - */ - if (sc->miibus != NULL) + if (sc->miibus != NULL && setmedia != 0) mii_mediachg(device_get_softc(sc->miibus)); ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -2735,6 +2755,31 @@ fxp_miibus_writereg(device_t dev, int ph device_printf(dev, "fxp_miibus_writereg: timed out\n"); } +static void +fxp_miibus_statchg(device_t dev) +{ + struct fxp_softc *sc; + struct mii_data *mii; + struct ifnet *ifp; + + sc = device_get_softc(dev); + mii = device_get_softc(sc->miibus); + ifp = sc->ifp; + if (mii == NULL || ifp == NULL || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || + (mii->mii_media_status & (IFM_AVALID | IFM_ACTIVE)) != + (IFM_AVALID | IFM_ACTIVE)) + return; + + /* + * Call fxp_init_body in order to adjust the flow control settings. + * Note that the 82557 doesn't support hardware flow control. + */ + if (sc->revision == FXP_REV_82557) + return; + fxp_init_body(sc, 0); +} + static int fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { @@ -2756,9 +2801,9 @@ fxp_ioctl(struct ifnet *ifp, u_long comm if (((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) && ((ifp->if_flags ^ sc->if_flags) & (IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0) - fxp_init_body(sc); + fxp_init_body(sc, 1); else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - fxp_init_body(sc); + fxp_init_body(sc, 1); } else { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) fxp_stop(sc); @@ -2860,7 +2905,7 @@ fxp_ioctl(struct ifnet *ifp, u_long comm reinit++; } if (reinit > 0 && ifp->if_flags & IFF_UP) - fxp_init_body(sc); + fxp_init_body(sc, 1); FXP_UNLOCK(sc); VLAN_CAPABILITIES(ifp); break; @@ -3051,22 +3096,16 @@ fxp_sysctl_node(struct fxp_softc *sc) "FXP driver receive interrupt microcode bundle size limit"); SYSCTL_ADD_INT(ctx, child,OID_AUTO, "rnr", CTLFLAG_RD, &sc->rnr, 0, "FXP RNR events"); - SYSCTL_ADD_INT(ctx, child, - OID_AUTO, "noflow", CTLFLAG_RW, &sc->tunable_noflow, 0, - "FXP flow control disabled"); /* * Pull in device tunables. */ sc->tunable_int_delay = TUNABLE_INT_DELAY; sc->tunable_bundle_max = TUNABLE_BUNDLE_MAX; - sc->tunable_noflow = 1; (void) resource_int_value(device_get_name(sc->dev), device_get_unit(sc->dev), "int_delay", &sc->tunable_int_delay); (void) resource_int_value(device_get_name(sc->dev), device_get_unit(sc->dev), "bundle_max", &sc->tunable_bundle_max); - (void) resource_int_value(device_get_name(sc->dev), - device_get_unit(sc->dev), "noflow", &sc->tunable_noflow); sc->rnr = 0; hsp = &sc->fxp_hwstats; Modified: stable/7/sys/dev/fxp/if_fxpreg.h ============================================================================== --- stable/7/sys/dev/fxp/if_fxpreg.h Sun Nov 28 15:59:39 2010 (r216002) +++ stable/7/sys/dev/fxp/if_fxpreg.h Sun Nov 28 15:59:45 2010 (r216003) @@ -45,7 +45,8 @@ #define FXP_CSR_FLASHCONTROL 12 /* flash control (2 bytes) */ #define FXP_CSR_EEPROMCONTROL 14 /* eeprom control (2 bytes) */ #define FXP_CSR_MDICONTROL 16 /* mdi control (4 bytes) */ -#define FXP_CSR_FLOWCONTROL 0x19 /* flow control (2 bytes) */ +#define FXP_CSR_FC_THRESH 0x19 /* flow control (1 byte) */ +#define FXP_CSR_FC_STATUS 0x1A /* flow control status (1 byte) */ #define FXP_CSR_PMDR 0x1B /* power management driver (1 byte) */ #define FXP_CSR_GENCONTROL 0x1C /* general control (1 byte) */ Modified: stable/7/sys/dev/fxp/if_fxpvar.h ============================================================================== --- stable/7/sys/dev/fxp/if_fxpvar.h Sun Nov 28 15:59:39 2010 (r216002) +++ stable/7/sys/dev/fxp/if_fxpvar.h Sun Nov 28 15:59:45 2010 (r216003) @@ -210,7 +210,6 @@ struct fxp_softc { device_t dev; int tunable_int_delay; /* interrupt delay value for ucode */ int tunable_bundle_max; /* max # frames per interrupt (ucode) */ - int tunable_noflow; /* flow control disabled */ int rnr; /* RNR events */ int eeprom_size; /* size of serial EEPROM */ int suspended; /* 0 = normal 1 = suspended or dead */