From owner-svn-src-all@FreeBSD.ORG Sun Mar 2 05:48:57 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6B756678; Sun, 2 Mar 2014 05:48:57 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4BF6B1D45; Sun, 2 Mar 2014 05:48:57 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s225mvn6078681; Sun, 2 Mar 2014 05:48:57 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s225mupU078678; Sun, 2 Mar 2014 05:48:56 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201403020548.s225mupU078678@svn.freebsd.org> From: Adrian Chadd Date: Sun, 2 Mar 2014 05:48:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r262681 - head/sys/dev/etherswitch/arswitch X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 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: Sun, 02 Mar 2014 05:48:57 -0000 Author: adrian Date: Sun Mar 2 05:48:56 2014 New Revision: 262681 URL: http://svnweb.freebsd.org/changeset/base/262681 Log: Add ATU flush support. The OpenWRT AR8xxx switch support flushes the ATU (address translation unit) after each port link 'up' status change. I've modified this to just flush on any port transition. Whilst here, bump the number of ports on the AR8327 to 6, rather than the default of 5. It's DB120 specific; I'll go and make this configurable later. There's some debugging code in here still; I am still debugging whether this is or isn't working fully. Tested: * DB120, AR9344 + AR8327 switch Obtained from: OpenWRT Modified: head/sys/dev/etherswitch/arswitch/arswitch.c head/sys/dev/etherswitch/arswitch/arswitch_8327.c head/sys/dev/etherswitch/arswitch/arswitchvar.h Modified: head/sys/dev/etherswitch/arswitch/arswitch.c ============================================================================== --- head/sys/dev/etherswitch/arswitch/arswitch.c Sun Mar 2 05:47:05 2014 (r262680) +++ head/sys/dev/etherswitch/arswitch/arswitch.c Sun Mar 2 05:48:56 2014 (r262681) @@ -256,6 +256,28 @@ ar8xxx_port_init(struct arswitch_softc * } static int +ar8xxx_atu_flush(struct arswitch_softc *sc) +{ + int ret; + + ret = arswitch_waitreg(sc->sc_dev, + AR8216_REG_ATU, + AR8216_ATU_ACTIVE, + 0, + 1000); + + if (ret) + device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__); + + if (!ret) + arswitch_writereg(sc->sc_dev, + AR8216_REG_ATU, + AR8216_ATU_OP_FLUSH); + + return (ret); +} + +static int arswitch_attach(device_t dev) { struct arswitch_softc *sc; @@ -280,6 +302,7 @@ arswitch_attach(device_t dev) sc->hal.arswitch_vlan_setvgroup = ar8xxx_setvgroup; sc->hal.arswitch_vlan_get_pvid = ar8xxx_get_pvid; sc->hal.arswitch_vlan_set_pvid = ar8xxx_set_pvid; + sc->hal.arswitch_atu_flush = ar8xxx_atu_flush; /* * Attach switch related functions @@ -469,6 +492,7 @@ arswitch_miipollstat(struct arswitch_sof struct mii_data *mii; struct mii_softc *miisc; int portstatus; + int port_flap = 0; ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); @@ -484,7 +508,6 @@ arswitch_miipollstat(struct arswitch_sof else portstatus = arswitch_readreg(sc->sc_dev, AR8X16_REG_PORT_STS(arswitch_portforphy(i))); - #if 0 DPRINTF(sc->sc_dev, "p[%d]=%b\n", i, @@ -492,6 +515,27 @@ arswitch_miipollstat(struct arswitch_sof "\20\3TXMAC\4RXMAC\5TXFLOW\6RXFLOW\7" "DUPLEX\11LINK_UP\12LINK_AUTO\13LINK_PAUSE"); #endif + /* + * If the current status is down, but we have a link + * status showing up, we need to do an ATU flush. + */ + if ((mii->mii_media_status & IFM_ACTIVE) == 0 && + (portstatus & AR8X16_PORT_STS_LINK_UP) != 0) { + device_printf(sc->sc_dev, "%s: port %d: port -> UP\n", + __func__, + i); + port_flap = 1; + } + /* + * and maybe if a port goes up->down? + */ + if ((mii->mii_media_status & IFM_ACTIVE) != 0 && + (portstatus & AR8X16_PORT_STS_LINK_UP) == 0) { + device_printf(sc->sc_dev, "%s: port %d: port -> DOWN\n", + __func__, + i); + port_flap = 1; + } arswitch_update_ifmedia(portstatus, &mii->mii_media_status, &mii->mii_media_active); LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { @@ -501,6 +545,10 @@ arswitch_miipollstat(struct arswitch_sof mii_phy_update(miisc, MII_POLLSTAT); } } + + /* If a port went from down->up, flush the ATU */ + if (port_flap) + sc->hal.arswitch_atu_flush(sc); } static void Modified: head/sys/dev/etherswitch/arswitch/arswitch_8327.c ============================================================================== --- head/sys/dev/etherswitch/arswitch/arswitch_8327.c Sun Mar 2 05:47:05 2014 (r262680) +++ head/sys/dev/etherswitch/arswitch/arswitch_8327.c Sun Mar 2 05:48:56 2014 (r262681) @@ -637,6 +637,9 @@ ar8327_hw_global_setup(struct arswitch_s arswitch_modifyreg(sc->sc_dev, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB, AR8327_MODULE_EN_MIB); + /* Set the right number of ports */ + sc->info.es_nports = 6; + return (0); } @@ -784,6 +787,28 @@ ar8327_set_pvid(struct arswitch_softc *s return (0); } +static int +ar8327_atu_flush(struct arswitch_softc *sc) +{ + + int ret; + + ret = arswitch_waitreg(sc->sc_dev, + AR8327_REG_ATU_FUNC, + AR8327_ATU_FUNC_BUSY, + 0, + 1000); + + if (ret) + device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__); + + if (!ret) + arswitch_writereg(sc->sc_dev, + AR8327_REG_ATU_FUNC, + AR8327_ATU_FUNC_OP_FLUSH); + return (ret); +} + void ar8327_attach(struct arswitch_softc *sc) { @@ -801,6 +826,8 @@ ar8327_attach(struct arswitch_softc *sc) sc->hal.arswitch_vlan_get_pvid = ar8327_get_pvid; sc->hal.arswitch_vlan_set_pvid = ar8327_set_pvid; + sc->hal.arswitch_atu_flush = ar8327_atu_flush; + /* Set the switch vlan capabilities. */ sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q | ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOUBLE_TAG; Modified: head/sys/dev/etherswitch/arswitch/arswitchvar.h ============================================================================== --- head/sys/dev/etherswitch/arswitch/arswitchvar.h Sun Mar 2 05:47:05 2014 (r262680) +++ head/sys/dev/etherswitch/arswitch/arswitchvar.h Sun Mar 2 05:48:56 2014 (r262681) @@ -81,6 +81,9 @@ struct arswitch_softc { /* Port functions */ void (* arswitch_port_init) (struct arswitch_softc *, int); + /* ATU functions */ + int (* arswitch_atu_flush) (struct arswitch_softc *); + /* VLAN functions */ int (* arswitch_port_vlan_setup) (struct arswitch_softc *, etherswitch_port_t *);