Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Mar 2014 05:48:56 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r262681 - head/sys/dev/etherswitch/arswitch
Message-ID:  <201403020548.s225mupU078678@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403020548.s225mupU078678>