From owner-svn-src-head@freebsd.org Fri Oct 30 23:59:54 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E4CAEA22704; Fri, 30 Oct 2015 23:59:53 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B8CC61302; Fri, 30 Oct 2015 23:59:53 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t9UNxq6u014022; Fri, 30 Oct 2015 23:59:52 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t9UNxqJ0014021; Fri, 30 Oct 2015 23:59:52 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201510302359.t9UNxqJ0014021@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Fri, 30 Oct 2015 23:59:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r290217 - head/sys/mips/atheros X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Oct 2015 23:59:54 -0000 Author: adrian Date: Fri Oct 30 23:59:52 2015 New Revision: 290217 URL: https://svnweb.freebsd.org/changeset/base/290217 Log: arge_mdio: fix barriers; correctly check MII indicator register. * use barriers in a slightly better fashion. You can blame this glass of whiskey on putting barriers in the wrong spot. Grr adrian. * steal/rewrite the mdio busy check from ag7100 from openwrt and refactor the existing code out. This is .. more correct. This seems to fix the boot-to-boot variation that I've been seeing and it quietens the switch port status flapping. Tested: * QCA9558 SoC (AP135.) Obtained from: Linux OpenWRT Modified: head/sys/mips/atheros/if_arge.c Modified: head/sys/mips/atheros/if_arge.c ============================================================================== --- head/sys/mips/atheros/if_arge.c Fri Oct 30 23:57:20 2015 (r290216) +++ head/sys/mips/atheros/if_arge.c Fri Oct 30 23:59:52 2015 (r290217) @@ -1067,34 +1067,47 @@ arge_hinted_child(device_t bus, const ch } static int +arge_mdio_busy(struct arge_softc *sc) +{ + int i,result; + + for (i = 0; i < ARGE_MII_TIMEOUT; i++) { + DELAY(5); + ARGE_MDIO_BARRIER_READ(sc); + result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR); + if (! result) + return (0); + DELAY(5); + } + return (-1); +} + +static int arge_miibus_readreg(device_t dev, int phy, int reg) { struct arge_softc * sc = device_get_softc(dev); - int i, result; + int result; uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); mtx_lock(&miibus_mtx); + ARGE_MDIO_BARRIER_RW(sc); ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + ARGE_MDIO_BARRIER_WRITE(sc); ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_MDIO_BARRIER_WRITE(sc); ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); - i = ARGE_MII_TIMEOUT; - while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) & - MAC_MII_INDICATOR_BUSY) && (i--)) { - ARGE_MDIO_BARRIER_READ(sc); - DELAY(5); - } - - if (i < 0) { + if (arge_mdio_busy(sc) != 0) { mtx_unlock(&miibus_mtx); ARGEDEBUG(sc, ARGE_DBG_MII, "%s timedout\n", __func__); /* XXX: return ERRNO istead? */ return (-1); } - result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; ARGE_MDIO_BARRIER_READ(sc); + result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; + ARGE_MDIO_BARRIER_RW(sc); ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); mtx_unlock(&miibus_mtx); @@ -1109,7 +1122,6 @@ static int arge_miibus_writereg(device_t dev, int phy, int reg, int data) { struct arge_softc * sc = device_get_softc(dev); - int i; uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); @@ -1117,24 +1129,20 @@ arge_miibus_writereg(device_t dev, int p phy, reg, data); mtx_lock(&miibus_mtx); + ARGE_MDIO_BARRIER_RW(sc); ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_MDIO_BARRIER_WRITE(sc); ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CONTROL, data); + ARGE_MDIO_BARRIER_WRITE(sc); - i = ARGE_MII_TIMEOUT; - while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) & - MAC_MII_INDICATOR_BUSY) && (i--)) { - ARGE_MDIO_BARRIER_READ(sc); - DELAY(5); - } - - mtx_unlock(&miibus_mtx); - - if (i < 0) { + if (arge_mdio_busy(sc) != 0) { + mtx_unlock(&miibus_mtx); ARGEDEBUG(sc, ARGE_DBG_MII, "%s timedout\n", __func__); /* XXX: return ERRNO istead? */ return (-1); } + mtx_unlock(&miibus_mtx); return (0); }