All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link.
@ 2016-07-15 10:12 Charles-Antoine Couret
  2016-07-15 14:08 ` Andrew Lunn
  0 siblings, 1 reply; 5+ messages in thread
From: Charles-Antoine Couret @ 2016-07-15 10:12 UTC (permalink / raw)
  To: netdev

>From 5be52efa3f1c034c21f80850b651193d1f51a313 Mon Sep 17 00:00:00 2001
From: Charles-Antoine Couret <charles-antoine.couret@nexvision.fr>
Date: Fri, 15 Jul 2016 11:57:25 +0200
Subject: [PATCH 3/4] Marvell phy: add configuration of autonegociation for
 fiber link.

Signed-off-by: Charles-Antoine Couret <charles-antoine.couret@nexvision.fr>
---
 drivers/net/phy/marvell.c | 111 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 109 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 13a93d8..e05209b 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -493,15 +493,122 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
 	return m88e1121_config_aneg(phydev);
 }
 
+/**
+ * ethtool_adv_to_fiber_adv_t
+ * @ethadv: the ethtool advertisement settings
+ *
+ * A small helper function that translates ethtool advertisement
+ * settings to phy autonegotiation advertisements for the
+ * MII_ADV register for fiber link.
+ */
+static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv)
+{
+	u32 result = 0;
+
+	if (ethadv & ADVERTISED_1000baseT_Half)
+		result |= ADVERTISE_FIBER_1000HALF;
+	if (ethadv & ADVERTISED_1000baseT_Full)
+		result |= ADVERTISE_FIBER_1000FULL;
+
+	if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP))
+		result |= LPA_PAUSE_ASYM_FIBER;
+	else if (ethadv & ADVERTISE_PAUSE_CAP)
+		result |= (ADVERTISE_PAUSE_FIBER
+			   & (~ADVERTISE_PAUSE_ASYM_FIBER));
+
+	return result;
+}
+
+/**
+ * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR
+ * @phydev: target phy_device struct
+ *
+ * Description: If auto-negotiation is enabled, we configure the
+ *   advertising, and then restart auto-negotiation.  If it is not
+ *   enabled, then we write the BMCR. Adapted for fiber link in
+ *   some Marvell's devices.
+ */
+static int marvell_config_aneg_fiber(struct phy_device *phydev)
+{
+	int changed = 0;
+	int err;
+	int adv, oldadv;
+	u32 advertise;
+
+	if (phydev->autoneg != AUTONEG_ENABLE)
+		return genphy_setup_forced(phydev);
+
+	/* Only allow advertising what this PHY supports */
+	phydev->advertising &= phydev->supported;
+	advertise = phydev->advertising;
+
+	/* Setup fiber advertisement */
+	adv = phy_read(phydev, MII_ADVERTISE);
+	if (adv < 0)
+		return adv;
+
+	oldadv = adv;
+	adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL
+		| LPA_PAUSE_FIBER);
+	adv |= ethtool_adv_to_fiber_adv_t(advertise);
+
+	if (adv != oldadv) {
+		err = phy_write(phydev, MII_ADVERTISE, adv);
+		if (err < 0)
+			return err;
+
+		changed = 1;
+	}
+
+	if (changed == 0) {
+		/* Advertisement hasn't changed, but maybe aneg was never on to
+		 * begin with?  Or maybe phy was isolated?
+		 */
+		int ctl = phy_read(phydev, MII_BMCR);
+
+		if (ctl < 0)
+			return ctl;
+
+		if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
+			changed = 1; /* do restart aneg */
+	}
+
+	/* Only restart aneg if we are advertising something different
+	 * than we were before.
+	 */
+	if (changed > 0)
+		changed = genphy_restart_aneg(phydev);
+
+	return changed;
+}
+
 static int m88e1510_config_aneg(struct phy_device *phydev)
 {
 	int err;
 
+	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER);
+	if (err < 0)
+		goto error;
+
+	/* Configure the copper link first */
 	err = m88e1318_config_aneg(phydev);
 	if (err < 0)
-		return err;
+		goto error;
 
-	return 0;
+	/* Then the fiber link */
+	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER);
+	if (err < 0)
+		goto error;
+
+	err = marvell_config_aneg_fiber(phydev);
+	if (err < 0)
+		goto error;
+
+	return phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER);
+
+error:
+	phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER);
+	return err;
 }
 
 static int marvell_config_init(struct phy_device *phydev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link.
  2016-07-15 10:12 [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link Charles-Antoine Couret
@ 2016-07-15 14:08 ` Andrew Lunn
  2016-07-15 14:10   ` Charles-Antoine Couret
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Lunn @ 2016-07-15 14:08 UTC (permalink / raw)
  To: Charles-Antoine Couret; +Cc: netdev

On Fri, Jul 15, 2016 at 12:12:39PM +0200, Charles-Antoine Couret wrote:
> >From 5be52efa3f1c034c21f80850b651193d1f51a313 Mon Sep 17 00:00:00 2001
> From: Charles-Antoine Couret <charles-antoine.couret@nexvision.fr>
> Date: Fri, 15 Jul 2016 11:57:25 +0200
> Subject: [PATCH 3/4] Marvell phy: add configuration of autonegociation for
>  fiber link.

It looks like [4/4] did not make it to the list?

   Andrew

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link.
  2016-07-15 14:08 ` Andrew Lunn
@ 2016-07-15 14:10   ` Charles-Antoine Couret
  0 siblings, 0 replies; 5+ messages in thread
From: Charles-Antoine Couret @ 2016-07-15 14:10 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev

Le 15/07/2016 à 16:08, Andrew Lunn a écrit :
> On Fri, Jul 15, 2016 at 12:12:39PM +0200, Charles-Antoine Couret wrote:
>> >From 5be52efa3f1c034c21f80850b651193d1f51a313 Mon Sep 17 00:00:00 2001
>> From: Charles-Antoine Couret <charles-antoine.couret@nexvision.fr>
>> Date: Fri, 15 Jul 2016 11:57:25 +0200
>> Subject: [PATCH 3/4] Marvell phy: add configuration of autonegociation for
>>  fiber link.
> 
> It looks like [4/4] did not make it to the list?
> 
>    Andrew

It's strange, I sent it with others...

I will resend it.
Thanks for your previous comments.

Regards.
Charles-Antoine Couret

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link.
  2016-07-18  9:03 ` [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link Charles-Antoine Couret
@ 2016-07-18 15:36   ` Andrew Lunn
  0 siblings, 0 replies; 5+ messages in thread
From: Andrew Lunn @ 2016-07-18 15:36 UTC (permalink / raw)
  To: Charles-Antoine Couret; +Cc: cacouret.renault, netdev

On Mon, Jul 18, 2016 at 11:03:42AM +0200, Charles-Antoine Couret wrote:

Hi Charles-Antoine

You really should have some sort of comment here which will go into
the commit log. It can just be the Subject said differently.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link.
  2016-07-18  9:03 [PATCH v5 0/4] Marvell phy: manage fiber link for some phys Charles-Antoine Couret
@ 2016-07-18  9:03 ` Charles-Antoine Couret
  2016-07-18 15:36   ` Andrew Lunn
  0 siblings, 1 reply; 5+ messages in thread
From: Charles-Antoine Couret @ 2016-07-18  9:03 UTC (permalink / raw)
  To: cacouret.renault, netdev; +Cc: Charles-Antoine Couret

Signed-off-by: Charles-Antoine Couret <charles-antoine.couret@nexvision.fr>
---
 drivers/net/phy/marvell.c | 111 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 109 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 13a93d8..e05209b 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -493,15 +493,122 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
 	return m88e1121_config_aneg(phydev);
 }
 
+/**
+ * ethtool_adv_to_fiber_adv_t
+ * @ethadv: the ethtool advertisement settings
+ *
+ * A small helper function that translates ethtool advertisement
+ * settings to phy autonegotiation advertisements for the
+ * MII_ADV register for fiber link.
+ */
+static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv)
+{
+	u32 result = 0;
+
+	if (ethadv & ADVERTISED_1000baseT_Half)
+		result |= ADVERTISE_FIBER_1000HALF;
+	if (ethadv & ADVERTISED_1000baseT_Full)
+		result |= ADVERTISE_FIBER_1000FULL;
+
+	if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP))
+		result |= LPA_PAUSE_ASYM_FIBER;
+	else if (ethadv & ADVERTISE_PAUSE_CAP)
+		result |= (ADVERTISE_PAUSE_FIBER
+			   & (~ADVERTISE_PAUSE_ASYM_FIBER));
+
+	return result;
+}
+
+/**
+ * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR
+ * @phydev: target phy_device struct
+ *
+ * Description: If auto-negotiation is enabled, we configure the
+ *   advertising, and then restart auto-negotiation.  If it is not
+ *   enabled, then we write the BMCR. Adapted for fiber link in
+ *   some Marvell's devices.
+ */
+static int marvell_config_aneg_fiber(struct phy_device *phydev)
+{
+	int changed = 0;
+	int err;
+	int adv, oldadv;
+	u32 advertise;
+
+	if (phydev->autoneg != AUTONEG_ENABLE)
+		return genphy_setup_forced(phydev);
+
+	/* Only allow advertising what this PHY supports */
+	phydev->advertising &= phydev->supported;
+	advertise = phydev->advertising;
+
+	/* Setup fiber advertisement */
+	adv = phy_read(phydev, MII_ADVERTISE);
+	if (adv < 0)
+		return adv;
+
+	oldadv = adv;
+	adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL
+		| LPA_PAUSE_FIBER);
+	adv |= ethtool_adv_to_fiber_adv_t(advertise);
+
+	if (adv != oldadv) {
+		err = phy_write(phydev, MII_ADVERTISE, adv);
+		if (err < 0)
+			return err;
+
+		changed = 1;
+	}
+
+	if (changed == 0) {
+		/* Advertisement hasn't changed, but maybe aneg was never on to
+		 * begin with?  Or maybe phy was isolated?
+		 */
+		int ctl = phy_read(phydev, MII_BMCR);
+
+		if (ctl < 0)
+			return ctl;
+
+		if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
+			changed = 1; /* do restart aneg */
+	}
+
+	/* Only restart aneg if we are advertising something different
+	 * than we were before.
+	 */
+	if (changed > 0)
+		changed = genphy_restart_aneg(phydev);
+
+	return changed;
+}
+
 static int m88e1510_config_aneg(struct phy_device *phydev)
 {
 	int err;
 
+	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER);
+	if (err < 0)
+		goto error;
+
+	/* Configure the copper link first */
 	err = m88e1318_config_aneg(phydev);
 	if (err < 0)
-		return err;
+		goto error;
 
-	return 0;
+	/* Then the fiber link */
+	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER);
+	if (err < 0)
+		goto error;
+
+	err = marvell_config_aneg_fiber(phydev);
+	if (err < 0)
+		goto error;
+
+	return phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER);
+
+error:
+	phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER);
+	return err;
 }
 
 static int marvell_config_init(struct phy_device *phydev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-07-18 15:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-15 10:12 [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link Charles-Antoine Couret
2016-07-15 14:08 ` Andrew Lunn
2016-07-15 14:10   ` Charles-Antoine Couret
2016-07-18  9:03 [PATCH v5 0/4] Marvell phy: manage fiber link for some phys Charles-Antoine Couret
2016-07-18  9:03 ` [PATCH 3/4] Marvell phy: add configuration of autonegociation for fiber link Charles-Antoine Couret
2016-07-18 15:36   ` Andrew Lunn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.