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
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to