Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 May 2012 01:21:58 +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: r234906 - head/sys/mips/atheros
Message-ID:  <201205020121.q421LwFU056899@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed May  2 01:21:57 2012
New Revision: 234906
URL: http://svn.freebsd.org/changeset/base/234906

Log:
  MII related infrastructure changes.
  
  * Add a new method to set the MII mode - GMII, RGMII, RMII, MII.
    + arge0 supports all four (two for non-Gige interfaces.)
    + arge1 only supports two (one for non-gige interfaces.)
  * Set the MII clock speed when changing the MAC PLL speed.
    + Needed for AR91xx and AR71xx; not needed for AR724x.
  
  Tested:
  
  * AR71xx only, I'll do AR913x testing tonight and fix whichever issues
    creep up.
  
  TODO:
  
  * Implement the missing AR7242 arge0 PLL configuration, but don't
    adjust the MII speed accordingly.
  * .. the AR7240/AR7241 don't require this, so make sure it's not set
    accidentally.
  
  Bugs (not fixed here):
  
  * Statically configured arge speeds are still broken - investigate why
    that is on the AP96 board.  Autonegotiate is working fine, but there
    still seems to be an occasionally heavy packet loss issue.
  
  Obtained from: Linux/Atheros/OpenWRT

Modified:
  head/sys/mips/atheros/ar71xx_chip.c
  head/sys/mips/atheros/ar71xx_chip.h
  head/sys/mips/atheros/ar71xx_cpudef.h
  head/sys/mips/atheros/ar724x_chip.c
  head/sys/mips/atheros/ar91xx_chip.c

Modified: head/sys/mips/atheros/ar71xx_chip.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_chip.c	Wed May  2 01:14:15 2012	(r234905)
+++ head/sys/mips/atheros/ar71xx_chip.c	Wed May  2 01:21:57 2012	(r234906)
@@ -176,6 +176,50 @@ ar71xx_chip_set_mii_speed(uint32_t unit,
 	ATH_WRITE_REG(reg, val);
 }
 
+void
+ar71xx_chip_set_mii_if(uint32_t unit, uint32_t mii_mode)
+{
+	uint32_t val, reg, mii_if;
+
+	switch (unit) {
+	case 0:
+		reg = AR71XX_MII0_CTRL;
+		if (mii_mode == AR71XX_MII_MODE_GMII)
+			mii_if = MII0_CTRL_IF_GMII;
+		else if (mii_mode == AR71XX_MII_MODE_MII)
+			mii_if = MII0_CTRL_IF_MII;
+		else if (mii_mode == AR71XX_MII_MODE_RGMII)
+			mii_if = MII0_CTRL_IF_RGMII;
+		else if (mii_mode == AR71XX_MII_MODE_RMII)
+			mii_if = MII0_CTRL_IF_RMII;
+		else
+			printf("%s: invalid MII mode (%d) for unit %d\n",
+			    __func__, mii_mode, unit);
+			return;
+		break;
+	case 1:
+		reg = AR71XX_MII1_CTRL;
+		if (mii_mode == AR71XX_MII_MODE_RGMII)
+			mii_if = MII1_CTRL_IF_RGMII;
+		if (mii_mode == AR71XX_MII_MODE_RMII)
+			mii_if = MII1_CTRL_IF_RMII;
+		else
+			printf("%s: invalid MII mode (%d) for unit %d\n",
+			    __func__, mii_mode, unit);
+			return;
+		break;
+	default:
+		printf("%s: invalid MII unit set for arge unit: %d\n",
+		    __func__, unit);
+		return;
+	}
+
+	val = ATH_READ_REG(reg);
+	val &= ~(MII_CTRL_IF_MASK << MII_CTRL_IF_SHIFT);
+	val |= (mii_if & MII_CTRL_IF_MASK) << MII_CTRL_IF_SHIFT;
+	ATH_WRITE_REG(reg, val);
+}
+
 /* Speed is either 10, 100 or 1000 */
 static void
 ar71xx_chip_set_pll_ge(int unit, int speed)
@@ -197,6 +241,7 @@ ar71xx_chip_set_pll_ge(int unit, int spe
 		    __func__, unit, speed);
 		return;
 	}
+
 	switch (unit) {
 	case 0:
 		ar71xx_write_pll(AR71XX_PLL_SEC_CONFIG,
@@ -213,6 +258,12 @@ ar71xx_chip_set_pll_ge(int unit, int spe
 		    __func__, unit);
 		return;
 	}
+
+	/*
+	 * AR71xx and AR913x require this; AR724x doesn't require
+	 * an MII clock change at all.
+	 */
+	ar71xx_chip_set_mii_speed(unit, speed);
 }
 
 static void
@@ -278,6 +329,7 @@ struct ar71xx_cpu_def ar71xx_chip_def = 
 	&ar71xx_chip_device_stopped,
 	&ar71xx_chip_set_pll_ge,
 	&ar71xx_chip_set_mii_speed,
+	&ar71xx_chip_set_mii_if,
 	&ar71xx_chip_ddr_flush_ge,
 	&ar71xx_chip_get_eth_pll,
 	&ar71xx_chip_ddr_flush_ip2,

Modified: head/sys/mips/atheros/ar71xx_chip.h
==============================================================================
--- head/sys/mips/atheros/ar71xx_chip.h	Wed May  2 01:14:15 2012	(r234905)
+++ head/sys/mips/atheros/ar71xx_chip.h	Wed May  2 01:21:57 2012	(r234906)
@@ -31,5 +31,6 @@
 
 extern struct ar71xx_cpu_def ar71xx_chip_def;
 extern void ar71xx_chip_set_mii_speed(uint32_t unit, uint32_t speed);
+extern void ar71xx_chip_set_mii_if(uint32_t unit, uint32_t mii_if);
 
 #endif

Modified: head/sys/mips/atheros/ar71xx_cpudef.h
==============================================================================
--- head/sys/mips/atheros/ar71xx_cpudef.h	Wed May  2 01:14:15 2012	(r234905)
+++ head/sys/mips/atheros/ar71xx_cpudef.h	Wed May  2 01:21:57 2012	(r234906)
@@ -37,6 +37,7 @@ struct ar71xx_cpu_def {
 	int (* ar71xx_chip_device_stopped) (uint32_t);
 	void (* ar71xx_chip_set_pll_ge) (int, int);
 	void (* ar71xx_chip_set_mii_speed) (uint32_t, uint32_t);
+	void (* ar71xx_chip_set_mii_if) (uint32_t, ar71xx_mii_mode);
 	void (* ar71xx_chip_ddr_flush_ge) (int);
 	uint32_t (* ar71xx_chip_get_eth_pll) (unsigned int, int);
 
@@ -90,6 +91,11 @@ static inline void ar71xx_device_set_mii
 	ar71xx_cpu_ops->ar71xx_chip_set_mii_speed(unit, speed);
 }
 
+static inline void ar71xx_device_set_mii_if(int unit, ar71xx_mii_mode mii_cfg)
+{
+	ar71xx_cpu_ops->ar71xx_chip_set_mii_if(unit, mii_cfg);
+}
+
 static inline void ar71xx_device_flush_ddr_ge(int unit)
 {
 	ar71xx_cpu_ops->ar71xx_chip_ddr_flush_ge(unit);

Modified: head/sys/mips/atheros/ar724x_chip.c
==============================================================================
--- head/sys/mips/atheros/ar724x_chip.c	Wed May  2 01:14:15 2012	(r234905)
+++ head/sys/mips/atheros/ar724x_chip.c	Wed May  2 01:21:57 2012	(r234906)
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
 
 #include <mips/atheros/ar71xx_cpudef.h>
 #include <mips/atheros/ar71xx_setup.h>
+#include <mips/atheros/ar71xx_chip.h>
 #include <mips/atheros/ar724x_chip.h>
 
 #include <mips/sentry5/s5reg.h>
@@ -130,6 +131,13 @@ ar724x_chip_set_mii_speed(uint32_t unit,
 	return;
 }
 
+/*
+ * XXX TODO: set the PLL for arge0 only on AR7242.
+ * The PLL/clock requirements are different.
+ *
+ * Otherwise, it's a NULL function for AR7240, AR7241 and
+ * AR7242 arge1.
+ */
 static void
 ar724x_chip_set_pll_ge(int unit, int speed)
 {
@@ -229,6 +237,7 @@ struct ar71xx_cpu_def ar724x_chip_def = 
 	&ar724x_chip_device_stopped,
 	&ar724x_chip_set_pll_ge,
 	&ar724x_chip_set_mii_speed,
+	&ar71xx_chip_set_mii_if,
 	&ar724x_chip_ddr_flush_ge,
 	&ar724x_chip_get_eth_pll,
 	&ar724x_chip_ddr_flush_ip2,

Modified: head/sys/mips/atheros/ar91xx_chip.c
==============================================================================
--- head/sys/mips/atheros/ar91xx_chip.c	Wed May  2 01:14:15 2012	(r234905)
+++ head/sys/mips/atheros/ar91xx_chip.c	Wed May  2 01:21:57 2012	(r234906)
@@ -147,6 +147,7 @@ ar91xx_chip_set_pll_ge(int unit, int spe
 		    __func__, unit);
 		return;
 	}
+	ar71xx_chip_set_mii_speed(unit, speed);
 }
 
 static void
@@ -211,6 +212,7 @@ struct ar71xx_cpu_def ar91xx_chip_def = 
 	&ar91xx_chip_device_stopped,
 	&ar91xx_chip_set_pll_ge,
 	&ar71xx_chip_set_mii_speed,
+	&ar71xx_chip_set_mii_if,
 	&ar91xx_chip_ddr_flush_ge,
 	&ar91xx_chip_get_eth_pll,
 	&ar91xx_chip_ddr_flush_ip2,



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