Author: adrian
Date: Sun Mar  8 22:03:54 2015
New Revision: 279791
URL: https://svnweb.freebsd.org/changeset/base/279791

Log:
  Modify the if_arge code to use a /fixed/ media mode when it's configured.
  
  Otherwise, the initial media speed would change if a PHY is hooked up,
  sending PHY speed notifications.  For the AP135 at least, the RGMII
  PHY has a static speed/duplex configured and if the PHY plumbing
  attaches the PHY to the if_arge interface, the first link speed change
  from 1000/full will set the MAC to something that isn't useful.
  
  This shouldn't affect any other platforms - everything I looked at is
  using hard-coded speed/duplex as static, as they're facing a switch
  with no PHY attached.

Modified:
  head/sys/mips/atheros/if_arge.c

Modified: head/sys/mips/atheros/if_arge.c
==============================================================================
--- head/sys/mips/atheros/if_arge.c     Sun Mar  8 21:59:03 2015        
(r279790)
+++ head/sys/mips/atheros/if_arge.c     Sun Mar  8 22:03:54 2015        
(r279791)
@@ -304,6 +304,8 @@ arge_reset_mac(struct arge_softc *sc)
        uint32_t reg;
        uint32_t reset_reg;
 
+       ARGEDEBUG(sc, ARGE_DBG_RESET, "%s called\n", __func__);
+
        /* Step 1. Soft-reset MAC */
        ARGE_SET_BITS(sc, AR71XX_MAC_CFG1, MAC_CFG1_SOFT_RESET);
        DELAY(20);
@@ -649,8 +651,7 @@ arge_attach(device_t dev)
        }
 
        /*
-        *  Get default media & duplex mode, by default its Base100T
-        *  and full duplex
+        * Get default/hard-coded media & duplex mode.
         */
        if (resource_int_value(device_get_name(dev), device_get_unit(dev),
            "media", &hint) != 0)
@@ -658,8 +659,12 @@ arge_attach(device_t dev)
 
        if (hint == 1000)
                sc->arge_media_type = IFM_1000_T;
-       else
+       else if (hint == 100)
                sc->arge_media_type = IFM_100_TX;
+       else if (hint == 10)
+               sc->arge_media_type = IFM_10_T;
+       else
+               sc->arge_media_type = 0;
 
        if (resource_int_value(device_get_name(dev), device_get_unit(dev),
            "fduplex", &hint) != 0)
@@ -847,9 +852,10 @@ arge_attach(device_t dev)
                        }
                }
        }
+
        if (sc->arge_miibus == NULL) {
                /* no PHY, so use hard-coded values */
-               ifmedia_init(&sc->arge_ifmedia, 0, 
+               ifmedia_init(&sc->arge_ifmedia, 0,
                    arge_multiphy_mediachange,
                    arge_multiphy_mediastatus);
                ifmedia_add(&sc->arge_ifmedia,
@@ -1071,6 +1077,25 @@ arge_update_link_locked(struct arge_soft
                return;
        }
 
+       /*
+        * If we have a static media type configured, then
+        * use that.  Some PHY configurations (eg QCA955x -> AR8327)
+        * use a static speed/duplex between the SoC and switch,
+        * even though the front-facing PHY speed changes.
+        */
+       if (sc->arge_media_type != 0) {
+               ARGEDEBUG(sc, ARGE_DBG_MII, "%s: fixed; media=%d, duplex=%d\n",
+                   __func__,
+                   sc->arge_media_type,
+                   sc->arge_duplex_mode);
+               if (mii->mii_media_status & IFM_ACTIVE) {
+                       sc->arge_link_status = 1;
+               } else {
+                       sc->arge_link_status = 0;
+               }
+               arge_set_pll(sc, sc->arge_media_type, sc->arge_duplex_mode);
+       }
+
        if (mii->mii_media_status & IFM_ACTIVE) {
 
                media = IFM_SUBTYPE(mii->mii_media_active);
@@ -1095,6 +1120,12 @@ arge_set_pll(struct arge_softc *sc, int 
        uint32_t                fifo_tx, pll;
        int if_speed;
 
+       /*
+        * XXX Verify - is this valid for all chips?
+        * QCA955x (and likely some of the earlier chips!) define
+        * this as nibble mode and byte mode, and those have to do
+        * with the interface type (MII/SMII versus GMII/RGMII.)
+        */
        ARGEDEBUG(sc, ARGE_DBG_PLL, "set_pll(%04x, %s)\n", media,
            duplex == IFM_FDX ? "full" : "half");
        cfg = ARGE_READ(sc, AR71XX_MAC_CFG2);
@@ -1199,6 +1230,9 @@ arge_set_pll(struct arge_softc *sc, int 
 static void
 arge_reset_dma(struct arge_softc *sc)
 {
+
+       ARGEDEBUG(sc, ARGE_DBG_RESET, "%s: called\n", __func__);
+
        ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, 0);
        ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, 0);
 
@@ -1230,8 +1264,6 @@ arge_reset_dma(struct arge_softc *sc)
        arge_flush_ddr(sc);
 }
 
-
-
 static void
 arge_init(void *xsc)
 {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to