Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Mar 2012 22:44:54 -0700
From:      Adrian Chadd <adrian@freebsd.org>
To:        freebsd-mips@freebsd.org
Subject:   [patch] enable mdio port 1, remove phy mask hard coding
Message-ID:  <CAJ-VmomfLdqv=5_wQmB%2BxNH6mKh6OieTAH4auS232ZFHKeHmzQ@mail.gmail.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hi all,

This patch does a few things:

* it adds mdio port 1 (from MAC1/arge1);
* it removes the hard-coded assumption that arge0/arge1 share the same
mdio bus, which I believe is only relevant for AR71xx;
* it removes phymask from the arge config;
* it introduces a new configuration parameter, "multiphy", which binds
the port to the fake phy. The existing code does this if phymask has
>1 bit set. This makes it absolutely obvious.

Since ar724x CPUs have >1 MDIO bus, we have to do this work to support
the switch phys that ship with these things.


This now raises the issue of how to handle switch PHYs and normal PHYs
on alternate busses. For example, the PB47 reference board has the PHY
for arge1 hang off the only MDIO bus on the board (AR7161) - which is
MDIO 0.

It's about time we fixed this stuff. I want to push in the switch code
from juli/pat/ray/stb now.


adrian

[-- Attachment #2 --]
Index: sys/mips/atheros/if_arge.c
===================================================================
--- sys/mips/atheros/if_arge.c	(revision 233531)
+++ sys/mips/atheros/if_arge.c	(working copy)
@@ -241,9 +241,9 @@
 	uint8_t			eaddr[ETHER_ADDR_LEN];
 	struct ifnet		*ifp;
 	struct arge_softc	*sc;
-	int			error = 0, rid, phymask;
+	int			error = 0, rid;
 	uint32_t		reg, rnd;
-	int			is_base_mac_empty, i, phys_total;
+	int			is_base_mac_empty, i, ret, multiphy = 0;
 	uint32_t		hint;
 	long			eeprom_mac_addr = 0;
 
@@ -276,25 +276,6 @@
 	    ("if_arge: Only MAC0 and MAC1 supported"));
 
 	/*
-	 *  Get which PHY of 5 available we should use for this unit
-	 */
-	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
-	    "phymask", &phymask) != 0) {
-		/*
-		 * Use port 4 (WAN) for GE0. For any other port use
-		 * its PHY the same as its unit number
-		 */
-		if (sc->arge_mac_unit == 0)
-			phymask = (1 << 4);
-		else
-			/* Use all phys up to 4 */
-			phymask = (1 << 4) - 1;
-
-		device_printf(dev, "No PHY specified, using mask %d\n",
-		    phymask);
-	}
-
-	/*
 	 *  Get default media & duplex mode, by default its Base100T
 	 *  and full duplex
 	 */
@@ -316,8 +297,6 @@
 	else
 		sc->arge_duplex_mode = 0;
 
-	sc->arge_phymask = phymask;
-
 	mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
 	    MTX_DEF);
 	callout_init_mtx(&sc->arge_stat_callout, &sc->arge_mtx, 0);
@@ -464,29 +443,15 @@
 	    FIFO_RX_FILTMASK_DEFAULT);
 
 	/*
-	 * Check if we have single-PHY MAC or multi-PHY
+	 * If required, just attach a multi-phy fake PHY.
+	 * Otherwise, attach a normal PHY to it and allow
+	 * a normal probe to occur.
 	 */
-	phys_total = 0;
-	for (i = 0; i < ARGE_NPHY; i++)
-		if (phymask & (1 << i))
-			phys_total ++;
+	ret = resource_int_value(device_get_name(dev), device_get_unit(dev),
+	    "multiphy", &multiphy);
 
-	if (phys_total == 0) {
-		error = EINVAL;
-		goto fail;
-	}
-
-	if (phys_total == 1) {
-		/* Do MII setup. */
-		error = mii_attach(dev, &sc->arge_miibus, ifp,
-		    arge_ifmedia_upd, arge_ifmedia_sts, BMSR_DEFCAPMASK,
-		    MII_PHY_ANY, MII_OFFSET_ANY, 0);
-		if (error != 0) {
-			device_printf(dev, "attaching PHYs failed\n");
-			goto fail;
-		}
-	}
-	else {
+	if (ret == 0 && multiphy == 1) {
+		/* Attach a fake multiphy. */
 		ifmedia_init(&sc->arge_ifmedia, 0,
 		    arge_multiphy_mediachange,
 		    arge_multiphy_mediastatus);
@@ -496,6 +461,15 @@
 		ifmedia_set(&sc->arge_ifmedia,
 		    IFM_ETHER | sc->arge_media_type  | sc->arge_duplex_mode);
 		arge_set_pll(sc, sc->arge_media_type, sc->arge_duplex_mode);
+	} else {
+		/* Do MII setup. */
+		error = mii_attach(dev, &sc->arge_miibus, ifp,
+		    arge_ifmedia_upd, arge_ifmedia_sts, BMSR_DEFCAPMASK,
+		    MII_PHY_ANY, MII_OFFSET_ANY, 0);
+		if (error != 0) {
+			device_printf(dev, "attaching PHYs failed\n");
+			goto fail;
+		}
 	}
 
 	/* Call MI attach routine. */
@@ -606,16 +580,15 @@
 	uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT)
 	    | (reg & MAC_MII_REG_MASK);
 
-	if ((sc->arge_phymask  & (1 << phy)) == 0)
-		return (0);
-
 	mtx_lock(&miibus_mtx);
-	ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE);
-	ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr);
-	ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ);
+	ARGE_MII_WRITE(sc->arge_mac_unit, AR71XX_MAC_MII_CMD,
+	    MAC_MII_CMD_WRITE);
+	ARGE_MII_WRITE(sc->arge_mac_unit, AR71XX_MAC_MII_ADDR, addr);
+	ARGE_MII_WRITE(sc->arge_mac_unit, AR71XX_MAC_MII_CMD,
+	    MAC_MII_CMD_READ);
 
 	i = ARGE_MII_TIMEOUT;
-	while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) &
+	while ((ARGE_MII_READ(sc->arge_mac_unit, AR71XX_MAC_MII_INDICATOR) &
 	    MAC_MII_INDICATOR_BUSY) && (i--))
 		DELAY(5);
 
@@ -626,8 +599,10 @@
 		return (-1);
 	}
 
-	result = ARGE_MII_READ(AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK;
-	ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE);
+	result = ARGE_MII_READ(sc->arge_mac_unit, AR71XX_MAC_MII_STATUS) &
+	    MAC_MII_STATUS_MASK;
+	ARGE_MII_WRITE(sc->arge_mac_unit, AR71XX_MAC_MII_CMD,
+	    MAC_MII_CMD_WRITE);
 	mtx_unlock(&miibus_mtx);
 
 	ARGEDEBUG(sc, ARGE_DBG_MII,
@@ -645,19 +620,15 @@
 	uint32_t addr =
 	    (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK);
 
-
-	if ((sc->arge_phymask  & (1 << phy)) == 0)
-		return (-1);
-
-	ARGEDEBUG(sc, ARGE_DBG_MII, "%s: phy=%d, reg=%02x, value=%04x\n",
+	ARGEDEBUG(sc, ARGE_DBG_MII, "%s: phy=%d, reg=%03x, value=%04x\n",
 	    __func__, phy, reg, data);
 
 	mtx_lock(&miibus_mtx);
-	ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr);
-	ARGE_MII_WRITE(AR71XX_MAC_MII_CONTROL, data);
+	ARGE_MII_WRITE(sc->arge_mac_unit, AR71XX_MAC_MII_ADDR, addr);
+	ARGE_MII_WRITE(sc->arge_mac_unit, AR71XX_MAC_MII_CONTROL, data);
 
 	i = ARGE_MII_TIMEOUT;
-	while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) &
+	while ((ARGE_MII_READ(sc->arge_mac_unit, AR71XX_MAC_MII_INDICATOR) &
 	    MAC_MII_INDICATOR_BUSY) && (i--))
 		DELAY(5);
 
Index: sys/mips/atheros/if_argevar.h
===================================================================
--- sys/mips/atheros/if_argevar.h	(revision 233531)
+++ sys/mips/atheros/if_argevar.h	(working copy)
@@ -70,12 +70,14 @@
 /*
  * MII registers access macros
  */
-#define ARGE_MII_READ(reg) \
-        *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg)))
+#define	ARGE_MII_BASE(unit) \
+	((unit == 0) ? AR71XX_MII0_BASE : AR71XX_MII1_BASE)
 
-#define ARGE_MII_WRITE(reg, val) \
-        *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) = (val)
+#define	ARGE_MII_READ(unit, reg) \
+	*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((ARGE_MII_BASE(unit) + reg)))
 
+#define	ARGE_MII_WRITE(unit, reg, val) \
+	*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((ARGE_MII_BASE(unit) + reg))) = (val)
 
 #define ARGE_DESC_EMPTY		(1 << 31)
 #define ARGE_DESC_MORE		(1 << 24)
@@ -148,7 +150,6 @@
 	int			arge_detach;
 	uint32_t		arge_intr_status;
 	int			arge_mac_unit;
-	int			arge_phymask;
 	int			arge_if_flags;
 	uint32_t		arge_debug;
 	struct {
Index: sys/mips/atheros/ar71xxreg.h
===================================================================
--- sys/mips/atheros/ar71xxreg.h	(revision 233531)
+++ sys/mips/atheros/ar71xxreg.h	(working copy)
@@ -283,11 +283,10 @@
  */
 #define AR71XX_MAC0_BASE	0x19000000
 #define AR71XX_MAC1_BASE	0x1A000000
-/*
- * All 5 PHYs accessible only through MAC0 register space
- */
-#define AR71XX_MII_BASE		0x19000000
 
+#define AR71XX_MII0_BASE		0x19000000
+#define AR71XX_MII1_BASE		0x1A000000
+
 #define		AR71XX_MAC_CFG1			0x00
 #define			MAC_CFG1_SOFT_RESET		(1 << 31)
 #define			MAC_CFG1_SIMUL_RESET		(1 << 30)

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-VmomfLdqv=5_wQmB%2BxNH6mKh6OieTAH4auS232ZFHKeHmzQ>