[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