[OpenWrt-Devel] ar8216 patch series

Heiner Kallweit hkallweit1 at gmail.com
Sat Nov 8 18:19:34 EST 2014


Am 08.11.2014 um 13:49 schrieb Dirk Neukirchen:
> On 31.10.2014 21:46, Heiner Kallweit wrote:
>> Patch series adds more abstraction to the driver, adds smaller improvements
>> and fixes an issue with kernels >= 3.14.
>> Ticket 17800: With kernel 3.14 sometimes ports operate at 10/half only
>>
>> This patch series works for me on:
>> TP-LINK TL-WDR4300 ( ar71xx + AR8327v2)
>> TP-LINK TL-WDR4900 (mpc85xx + AR8327v4)
>>
>> I'd appreciate if others with non-AR8327 switches supported by the
>> ar8216 driver test this patch series.
>>
>> Rgds, Heiner
> 
> I was testing this series on a TP-LINK TL-WDR3600 ( ar71xx + AR8327v2)
> but with default kernel (3.10.58). - as I understand this is supposed to work too
> 
> I encountered an error: WAN (eth0.2) does not work. (LAN seems fine)
> The dmesg seems to be identical between patched+unpatched. Both list
> 
> switch0: Atheros AR8327 rev. 2 switch registered on ag71xx-mdio.0
> ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:00 [uid=004dd033, driver=Atheros AR8216/AR8236/AR8316]
> eth0: Atheros AG71xx at 0xb9000000, irq 4, mode:RGMII
Dirk,
here come updated versions of patches 3-5 from the series. I'd appreciate if you could test the updated series.
changes:
patch 3|4: keep phy_fixup callback closer to the original fixup code
patch 5: less intrusive, doesn't touch advertising

Regards, Heiner


patch 3
---
 target/linux/generic/files/drivers/net/phy/ar8216.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index ffc5dcf..a0bf10a 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -80,6 +80,7 @@ struct ar8xxx_chip {
 	int (*atu_flush)(struct ar8xxx_priv *priv);
 	void (*vtu_flush)(struct ar8xxx_priv *priv);
 	void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32 vid, u32 port_mask);
+	void (*phy_fixup)(struct ar8xxx_priv *priv, int phy);
 
 	const struct ar8xxx_mib_desc *mib_decs;
 	unsigned num_mibs;
@@ -1636,7 +1637,7 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
 
 	bus = priv->mii_bus;
 	for (i = 0; i < AR8XXX_NUM_PHYS; i++) {
-		ar8327_phy_fixup(priv, i);
+		priv->chip->phy_fixup(priv, i);
 
 		/* start aneg on the PHY */
 		mdiobus_write(bus, i, MII_ADVERTISE, ADVERTISE_ALL |
@@ -1825,6 +1826,7 @@ static const struct ar8xxx_chip ar8327_chip = {
 	.atu_flush = ar8327_atu_flush,
 	.vtu_flush = ar8327_vtu_flush,
 	.vtu_load_vlan = ar8327_vtu_load_vlan,
+	.phy_fixup = ar8327_phy_fixup,
 
 	.num_mibs = ARRAY_SIZE(ar8236_mibs),
 	.mib_decs = ar8236_mibs,
-- 
2.1.3


patch4
---
 .../linux/generic/files/drivers/net/phy/ar8216.c   | 66 ++++++++--------------
 1 file changed, 25 insertions(+), 41 deletions(-)

diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index a0bf10a..02abfe8 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -340,6 +340,28 @@ ar8xxx_phy_poll_reset(struct mii_bus *bus)
         return -ETIMEDOUT;
 }
 
+static void
+ar8xxx_phy_init(struct ar8xxx_priv *priv)
+{
+	int i;
+	struct mii_bus *bus;
+
+	bus = priv->mii_bus;
+	for (i = 0; i < AR8XXX_NUM_PHYS; i++) {
+		if (priv->chip->phy_fixup)
+			priv->chip->phy_fixup(priv, i);
+
+		/* initialize the port itself */
+		mdiobus_write(bus, i, MII_ADVERTISE,
+			ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
+		if (ar8xxx_has_gige(priv))
+			mdiobus_write(bus, i, MII_CTRL1000, ADVERTISE_1000FULL);
+		mdiobus_write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
+	}
+
+	ar8xxx_phy_poll_reset(bus);
+}
+
 static u32
 ar8xxx_mii_read(struct ar8xxx_priv *priv, int reg)
 {
@@ -886,22 +908,10 @@ ar8236_setup_port(struct ar8xxx_priv *priv, int port, u32 members)
 static int
 ar8236_hw_init(struct ar8xxx_priv *priv)
 {
-	int i;
-	struct mii_bus *bus;
-
 	if (priv->initialized)
 		return 0;
 
-	/* Initialize the PHYs */
-	bus = priv->mii_bus;
-	for (i = 0; i < AR8XXX_NUM_PHYS; i++) {
-		mdiobus_write(bus, i, MII_ADVERTISE,
-			      ADVERTISE_ALL | ADVERTISE_PAUSE_CAP |
-			      ADVERTISE_PAUSE_ASYM);
-		mdiobus_write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
-	}
-
-	ar8xxx_phy_poll_reset(bus);
+	ar8xxx_phy_init(priv);
 
 	priv->initialized = true;
 	return 0;
@@ -938,9 +948,7 @@ static const struct ar8xxx_chip ar8236_chip = {
 static int
 ar8316_hw_init(struct ar8xxx_priv *priv)
 {
-	int i;
 	u32 val, newval;
-	struct mii_bus *bus;
 
 	val = priv->read(priv, AR8316_REG_POSTRIP);
 
@@ -979,17 +987,7 @@ ar8316_hw_init(struct ar8xxx_priv *priv)
 		msleep(1000);
 	}
 
-	/* Initialize the ports */
-	bus = priv->mii_bus;
-	for (i = 0; i < AR8XXX_NUM_PHYS; i++) {
-		/* initialize the port itself */
-		mdiobus_write(bus, i, MII_ADVERTISE,
-			ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-		mdiobus_write(bus, i, MII_CTRL1000, ADVERTISE_1000FULL);
-		mdiobus_write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
-	}
-
-	ar8xxx_phy_poll_reset(bus);
+	ar8xxx_phy_init(priv);
 
 out:
 	priv->initialized = true;
@@ -1620,9 +1618,7 @@ ar8327_hw_config_of(struct ar8xxx_priv *priv, struct device_node *np)
 static int
 ar8327_hw_init(struct ar8xxx_priv *priv)
 {
-	struct mii_bus *bus;
 	int ret;
-	int i;
 
 	if (priv->phy->dev.of_node)
 		ret = ar8327_hw_config_of(priv, priv->phy->dev.of_node);
@@ -1635,19 +1631,7 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
 
 	ar8327_leds_init(priv);
 
-	bus = priv->mii_bus;
-	for (i = 0; i < AR8XXX_NUM_PHYS; i++) {
-		priv->chip->phy_fixup(priv, i);
-
-		/* start aneg on the PHY */
-		mdiobus_write(bus, i, MII_ADVERTISE, ADVERTISE_ALL |
-						     ADVERTISE_PAUSE_CAP |
-						     ADVERTISE_PAUSE_ASYM);
-		mdiobus_write(bus, i, MII_CTRL1000, ADVERTISE_1000FULL);
-		mdiobus_write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
-	}
-
-	ar8xxx_phy_poll_reset(bus);
+	ar8xxx_phy_init(priv);
 
 	return 0;
 }
-- 
2.1.3

patch 5
---
 target/linux/generic/files/drivers/net/phy/ar8216.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 02abfe8..2238064 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -2855,10 +2855,27 @@ ar8xxx_phy_read_status(struct phy_device *phydev)
 static int
 ar8xxx_phy_config_aneg(struct phy_device *phydev)
 {
-	if (phydev->addr == 0)
+	int ctl;
+
+	if (phydev->addr != 0)
+		return genphy_config_aneg(phydev);
+
+	if (AUTONEG_ENABLE != phydev->autoneg)
+		return 0;
+
+	/*
+	 * BMCR_ANENABLE might have been cleared
+	 * by phy_init_hw in certain kernel versions
+	 * therefore check for it
+	 */
+	ctl = phy_read(phydev, MII_BMCR);
+	if (ctl < 0)
+		return ctl;
+	if (ctl & BMCR_ANENABLE)
 		return 0;
 
-	return genphy_config_aneg(phydev);
+	ctl |= BMCR_ANENABLE | BMCR_ANRESTART;
+	return phy_write(phydev, MII_BMCR, ctl);
 }
 
 static const u32 ar8xxx_phy_ids[] = {
-- 
2.1.3
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list