Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Mar 2010 01:09:14 +0000 (UTC)
From:      Juli Mallett <jmallett@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r205109 - user/jmallett/octeon/sys/mips/cavium/dev/rgmii
Message-ID:  <201003130109.o2D19ET6067917@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jmallett
Date: Sat Mar 13 01:09:14 2010
New Revision: 205109
URL: http://svn.freebsd.org/changeset/base/205109

Log:
  o) Do not unconditionally update the last known link status in the softc.  If
     report_link isn't set, when octeon_rgmx_config_speed is called the first
     time it will tell the driver (essentially) that we have already marked the
     interface up.  Likewise, don't change media speed and duplex if only the
     link status is at issue.
  o) Remove manual changing of link state and let octeon_rgmx_config_speed do the
     heavy lifting.
  
  Sponsored by:	Packet Forensics

Modified:
  user/jmallett/octeon/sys/mips/cavium/dev/rgmii/octeon_rgmx.c

Modified: user/jmallett/octeon/sys/mips/cavium/dev/rgmii/octeon_rgmx.c
==============================================================================
--- user/jmallett/octeon/sys/mips/cavium/dev/rgmii/octeon_rgmx.c	Sat Mar 13 00:15:06 2010	(r205108)
+++ user/jmallett/octeon/sys/mips/cavium/dev/rgmii/octeon_rgmx.c	Sat Mar 13 01:09:14 2010	(r205109)
@@ -1813,7 +1813,6 @@ static int octeon_rgmx_ioctl (struct ifn
 static void  octeon_rgmx_init (void *xsc)
 {
 	struct rgmx_softc_dev *sc = xsc;
-	octeon_rgmx_rxx_rx_inbnd_t link_status;
 
         /* Enable interrupts.  */
     	/* For RGMX they are already enabled earlier */
@@ -1834,19 +1833,7 @@ static void  octeon_rgmx_init (void *xsc
         /* Hopefully PKO is running and will pick up packets via the timer  or receive loop */
 
 	/* Set link status.  */
-	octeon_rgmx_config_speed(sc->port, 0);
-
-	RGMX_LOCK(sc);
-	/*
-	 * Parse link status.
-	 */
-	link_status.word64 = sc->link_status;
-
-	if (link_status.bits.status)
-		if_link_state_change(sc->ifp, LINK_STATE_UP);
-	else
-		if_link_state_change(sc->ifp, LINK_STATE_DOWN);
-	RGMX_UNLOCK(sc);
+	octeon_rgmx_config_speed(sc->port, 1);
 }
 
 
@@ -1861,7 +1848,6 @@ static void octeon_rgmx_config_speed (u_
         uint64_t			val64_tx_clk, val64_tx_slot, val64_tx_burst;
         u_int				last_enabled;
 
-
         sc = get_rgmx_softc(port);
         if (!sc) {
             printf(" config_speed didn't find sc int:%u port:%u", iface, port);
@@ -1873,79 +1859,96 @@ static void octeon_rgmx_config_speed (u_
          */
         link_status.word64 = oct_read64(OCTEON_RGMX_RXX_RX_INBND(index, iface));
 
+        RGMX_LOCK(sc);
+
         /*
          * Compre to prev known state. If same then nothing to do.
          */
         if (link_status.word64 == sc->link_status) {
+		RGMX_UNLOCK(sc);
             	return;
         }
-
-        RGMX_LOCK(sc);
-
         old_link_status.word64 = sc->link_status;
 
-        sc->link_status = link_status.word64;
-
-        last_enabled = octeon_rgmx_stop_port(port);
-
-        gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, iface));
-
-        /*
-         * Duplex
-         */
-        gmx_cfg.bits.duplex = 1;
-
-        switch (link_status.bits.speed) {
-        case 0:	/* 10Mbps */
-            gmx_cfg.bits.speed = 0;
-            gmx_cfg.bits.slottime = 0;
-            val64_tx_clk = 50; val64_tx_slot = 0x40; val64_tx_burst = 0;
-            break;
-        case 1:	/* 100Mbps */
-            gmx_cfg.bits.speed = 0;
-            gmx_cfg.bits.slottime = 0;
-            val64_tx_clk = 5; val64_tx_slot = 0x40; val64_tx_burst = 0;
-            break;
-
-        case 2:	/* 1Gbps */
-            gmx_cfg.bits.speed = 1;
-            gmx_cfg.bits.slottime = 1;
-            val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000;
-            break;
-
-        case 3:	/* ?? */
-        default:
-            gmx_cfg.bits.speed = 1;
-            gmx_cfg.bits.slottime = 1;
-            val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000;
-            break;
-        }
-
-        oct_write64(OCTEON_RGMX_TXX_CLK(index, iface), val64_tx_clk);
-        oct_write64(OCTEON_RGMX_TXX_SLOT(index, iface), val64_tx_slot);
-        oct_write64(OCTEON_RGMX_TXX_BURST(index, iface), val64_tx_burst);
-
-        oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64);
+	/*
+	 * Compare to previous state modulo link status.  If only link
+	 * status is different, we don't need to change media.
+	 */
+	if (old_link_status.bits.duplex != link_status.bits.duplex ||
+	    old_link_status.bits.speed != link_status.bits.speed) {
+		last_enabled = octeon_rgmx_stop_port(port);
+		
+		gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, iface));
+
+		/*
+		 * Duplex
+		 * XXX Set based on link_status.bits.duplex?
+		 */
+		gmx_cfg.bits.duplex = 1;
+		
+		switch (link_status.bits.speed) {
+		case 0:	/* 10Mbps */
+			gmx_cfg.bits.speed = 0;
+			gmx_cfg.bits.slottime = 0;
+			val64_tx_clk = 50; val64_tx_slot = 0x40; val64_tx_burst = 0;
+			break;
+
+		case 1:	/* 100Mbps */
+			gmx_cfg.bits.speed = 0;
+			gmx_cfg.bits.slottime = 0;
+			val64_tx_clk = 5; val64_tx_slot = 0x40; val64_tx_burst = 0;
+			break;
+
+		case 2:	/* 1Gbps */
+			gmx_cfg.bits.speed = 1;
+			gmx_cfg.bits.slottime = 1;
+			val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000;
+			break;
+
+		case 3:	/* ?? */
+		default:
+			gmx_cfg.bits.speed = 1;
+			gmx_cfg.bits.slottime = 1;
+			val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000;
+			break;
+		}
+
+		oct_write64(OCTEON_RGMX_TXX_CLK(index, iface), val64_tx_clk);
+		oct_write64(OCTEON_RGMX_TXX_SLOT(index, iface), val64_tx_slot);
+		oct_write64(OCTEON_RGMX_TXX_BURST(index, iface), val64_tx_burst);
+		
+		oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64);
+		
+		if (last_enabled) octeon_rgmx_start_port(port);
+	}
 
-        if (last_enabled) octeon_rgmx_start_port(port);
+	/*
+	 * Now check and possibly change link status.
+	 */
+	if (link_status.bits.status != old_link_status.bits.status) {
+		if (report_link) {
+			if (link_status.bits.status) {
+				if_link_state_change(sc->ifp, LINK_STATE_UP);
+			} else {
+				if_link_state_change(sc->ifp, LINK_STATE_DOWN);
+			}
+		}
+	}
 
-        if (link_status.bits.status != old_link_status.bits.status) {
+	if (report_link) {
+		sc->link_status = link_status.word64;
+	} else {
+		/*
+		 * We can't update link status proper since we can't
+		 * change it in the interface, so keep the old link
+		 * status intact but note the current speed and duplex
+		 * settings.
+		 */
+		link_status.bits.status = old_link_status.bits.status;
+		sc->link_status = link_status.word64;
+	}
 
-//#define DEBUG_LINESTATUS
-            if (link_status.bits.status) {
-#ifdef DEBUG_LINESTATUS
-                printf(" %u/%u: Interface is now alive\n", iface, port);
-#endif
-                if (report_link)  if_link_state_change(sc->ifp, LINK_STATE_UP);
-            } else {
-#ifdef DEBUG_LINESTATUS
-                printf(" %u/%u: Interface went down\n", iface, port);
-#endif
-                if (report_link)  if_link_state_change(sc->ifp, LINK_STATE_DOWN);
-            }
-        }
         RGMX_UNLOCK(sc);
-
 }
 
 
@@ -2165,7 +2168,6 @@ static void octeon_config_rgmii_port (u_
         gmx_cfg.bits.en = 1;
         oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64);
 
-
         octeon_rgmx_config_speed(port, 0);
 
         oct_write64(OCTEON_RGMX_TXX_THRESH(index, iface), 32);



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