All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/2] Full phylink support for mv88e6352
@ 2018-09-02 16:13 Andrew Lunn
  2018-09-02 16:13 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: Fix writing to a PHY page Andrew Lunn
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Andrew Lunn @ 2018-09-02 16:13 UTC (permalink / raw)
  To: David Miller
  Cc: Florian Fainelli, Vivien Didelot, Chris Healy, netdev, Andrew Lunn

These two patches implement full phylink support for the mv88e6352
family, when using an SFP connected to its SERDES interface. This adds
interrupt support to the SERDES, so that we get interrupts on link
up/down, and then make calls phydev_link_change().

The first patch is a minor bug fix, which does not seem to affect any
current features, so i'm not submitting it for stable. It is however
required for configuring SERDES interrupts.

Andrew Lunn (2):
  net: dsa: mv88e6xxx: Fix writing to a PHY page.
  net: dsa: mv88e6xxx: Add SERDES phydev_link_change for 6352

 drivers/net/dsa/mv88e6xxx/chip.c   |   6 ++
 drivers/net/dsa/mv88e6xxx/phy.c    |   3 +
 drivers/net/dsa/mv88e6xxx/serdes.c | 105 +++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/serdes.h |  16 +++++
 4 files changed, 130 insertions(+)

-- 
2.19.0.rc1

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

* [PATCH net-next 1/2] net: dsa: mv88e6xxx: Fix writing to a PHY page.
  2018-09-02 16:13 [PATCH net-next 0/2] Full phylink support for mv88e6352 Andrew Lunn
@ 2018-09-02 16:13 ` Andrew Lunn
  2018-09-02 16:13 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add SERDES phydev_link_change for 6352 Andrew Lunn
  2018-09-02 23:17 ` [PATCH net-next 0/2] Full phylink support for mv88e6352 David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2018-09-02 16:13 UTC (permalink / raw)
  To: David Miller
  Cc: Florian Fainelli, Vivien Didelot, Chris Healy, netdev, Andrew Lunn

After changing to the needed page, actually write the value to the
register!

Fixes: 09cb7dfd3f14 ("net: dsa: mv88e6xxx: describe PHY page and SerDes")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---

It has been broken like this for over 2 years. So i don't think it has
been important until now. So i've decided not to submit it to net,
only net-next, were i do actually need this to work.
---
 drivers/net/dsa/mv88e6xxx/phy.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/dsa/mv88e6xxx/phy.c b/drivers/net/dsa/mv88e6xxx/phy.c
index 46af8052e535..152a65d46e0b 100644
--- a/drivers/net/dsa/mv88e6xxx/phy.c
+++ b/drivers/net/dsa/mv88e6xxx/phy.c
@@ -110,6 +110,9 @@ int mv88e6xxx_phy_page_write(struct mv88e6xxx_chip *chip, int phy,
 	err = mv88e6xxx_phy_page_get(chip, phy, page);
 	if (!err) {
 		err = mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_PAGE, page);
+		if (!err)
+			err = mv88e6xxx_phy_write(chip, phy, reg, val);
+
 		mv88e6xxx_phy_page_put(chip, phy);
 	}
 
-- 
2.19.0.rc1

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

* [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add SERDES phydev_link_change for 6352
  2018-09-02 16:13 [PATCH net-next 0/2] Full phylink support for mv88e6352 Andrew Lunn
  2018-09-02 16:13 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: Fix writing to a PHY page Andrew Lunn
@ 2018-09-02 16:13 ` Andrew Lunn
  2018-09-02 23:17 ` [PATCH net-next 0/2] Full phylink support for mv88e6352 David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2018-09-02 16:13 UTC (permalink / raw)
  To: David Miller
  Cc: Florian Fainelli, Vivien Didelot, Chris Healy, netdev, Andrew Lunn

The 6352 family has one SERDES interface, which can be used by either
port 4 or port 5. Add interrupt support for the SERDES interface, and
report when the link status changes.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c   |   6 ++
 drivers/net/dsa/mv88e6xxx/serdes.c | 105 +++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/serdes.h |  16 +++++
 3 files changed, 127 insertions(+)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 8da3d39e3218..614dcc3e6a8b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3160,6 +3160,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_power = mv88e6352_serdes_power,
+	.serdes_irq_setup = mv88e6352_serdes_irq_setup,
+	.serdes_irq_free = mv88e6352_serdes_irq_free,
 	.gpio_ops = &mv88e6352_gpio_ops,
 	.phylink_validate = mv88e6352_phylink_validate,
 };
@@ -3366,6 +3368,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_power = mv88e6352_serdes_power,
+	.serdes_irq_setup = mv88e6352_serdes_irq_setup,
+	.serdes_irq_free = mv88e6352_serdes_irq_free,
 	.gpio_ops = &mv88e6352_gpio_ops,
 	.avb_ops = &mv88e6352_avb_ops,
 	.ptp_ops = &mv88e6352_ptp_ops,
@@ -3664,6 +3668,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_power = mv88e6352_serdes_power,
+	.serdes_irq_setup = mv88e6352_serdes_irq_setup,
+	.serdes_irq_free = mv88e6352_serdes_irq_free,
 	.gpio_ops = &mv88e6352_gpio_ops,
 	.avb_ops = &mv88e6352_avb_ops,
 	.ptp_ops = &mv88e6352_ptp_ops,
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index e82983975754..bb69650ff772 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -185,6 +185,111 @@ int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
 	return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
 }
 
+static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
+{
+	struct dsa_switch *ds = chip->ds;
+	u16 status;
+	bool up;
+
+	mv88e6352_serdes_read(chip, MII_BMSR, &status);
+
+	/* Status must be read twice in order to give the current link
+	 * status. Otherwise the change in link status since the last
+	 * read of the register is returned.
+	 */
+	mv88e6352_serdes_read(chip, MII_BMSR, &status);
+
+	up = status & BMSR_LSTATUS;
+
+	dsa_port_phylink_mac_change(ds, port, up);
+}
+
+static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id)
+{
+	struct mv88e6xxx_port *port = dev_id;
+	struct mv88e6xxx_chip *chip = port->chip;
+	irqreturn_t ret = IRQ_NONE;
+	u16 status;
+	int err;
+
+	mutex_lock(&chip->reg_lock);
+
+	err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
+	if (err)
+		goto out;
+
+	if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
+		ret = IRQ_HANDLED;
+		mv88e6352_serdes_irq_link(chip, port->port);
+	}
+out:
+	mutex_unlock(&chip->reg_lock);
+
+	return ret;
+}
+
+static int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip)
+{
+	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE,
+				      MV88E6352_SERDES_INT_LINK_CHANGE);
+}
+
+static int mv88e6352_serdes_irq_disable(struct mv88e6xxx_chip *chip)
+{
+	return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, 0);
+}
+
+int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
+{
+	int err;
+
+	if (!mv88e6352_port_has_serdes(chip, port))
+		return 0;
+
+	chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain,
+							MV88E6352_SERDES_IRQ);
+	if (chip->ports[port].serdes_irq < 0) {
+		dev_err(chip->dev, "Unable to map SERDES irq: %d\n",
+			chip->ports[port].serdes_irq);
+		return chip->ports[port].serdes_irq;
+	}
+
+	/* Requesting the IRQ will trigger irq callbacks. So we cannot
+	 * hold the reg_lock.
+	 */
+	mutex_unlock(&chip->reg_lock);
+	err = request_threaded_irq(chip->ports[port].serdes_irq, NULL,
+				   mv88e6352_serdes_thread_fn,
+				   IRQF_ONESHOT, "mv88e6xxx-serdes",
+				   &chip->ports[port]);
+	mutex_lock(&chip->reg_lock);
+
+	if (err) {
+		dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n",
+			err);
+		return err;
+	}
+
+	return mv88e6352_serdes_irq_enable(chip);
+}
+
+void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
+{
+	if (!mv88e6352_port_has_serdes(chip, port))
+		return;
+
+	mv88e6352_serdes_irq_disable(chip);
+
+	/* Freeing the IRQ will trigger irq callbacks. So we cannot
+	 * hold the reg_lock.
+	 */
+	mutex_unlock(&chip->reg_lock);
+	free_irq(chip->ports[port].serdes_irq, &chip->ports[port]);
+	mutex_lock(&chip->reg_lock);
+
+	chip->ports[port].serdes_irq = 0;
+}
+
 /* Return the SERDES lane address a port is using. Only Ports 9 and 10
  * have SERDES lanes. Returns -ENODEV if a port does not have a lane.
  */
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index b1496de9c6fe..7870c5a9ef12 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -18,6 +18,19 @@
 
 #define MV88E6352_ADDR_SERDES		0x0f
 #define MV88E6352_SERDES_PAGE_FIBER	0x01
+#define MV88E6352_SERDES_IRQ		0x0b
+#define MV88E6352_SERDES_INT_ENABLE	0x12
+#define MV88E6352_SERDES_INT_SPEED_CHANGE	BIT(14)
+#define MV88E6352_SERDES_INT_DUPLEX_CHANGE	BIT(13)
+#define MV88E6352_SERDES_INT_PAGE_RX		BIT(12)
+#define MV88E6352_SERDES_INT_AN_COMPLETE	BIT(11)
+#define MV88E6352_SERDES_INT_LINK_CHANGE	BIT(10)
+#define MV88E6352_SERDES_INT_SYMBOL_ERROR	BIT(9)
+#define MV88E6352_SERDES_INT_FALSE_CARRIER	BIT(8)
+#define MV88E6352_SERDES_INT_FIFO_OVER_UNDER	BIT(7)
+#define MV88E6352_SERDES_INT_FIBRE_ENERGY	BIT(4)
+#define MV88E6352_SERDES_INT_STATUS	0x13
+
 
 #define MV88E6341_ADDR_SERDES		0x15
 
@@ -73,5 +86,8 @@ int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
 				int lane);
 int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port,
 				 int lane);
+int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
+void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
+
 
 #endif
-- 
2.19.0.rc1

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

* Re: [PATCH net-next 0/2] Full phylink support for mv88e6352
  2018-09-02 16:13 [PATCH net-next 0/2] Full phylink support for mv88e6352 Andrew Lunn
  2018-09-02 16:13 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: Fix writing to a PHY page Andrew Lunn
  2018-09-02 16:13 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add SERDES phydev_link_change for 6352 Andrew Lunn
@ 2018-09-02 23:17 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2018-09-02 23:17 UTC (permalink / raw)
  To: andrew; +Cc: f.fainelli, vivien.didelot, cphealy, netdev

From: Andrew Lunn <andrew@lunn.ch>
Date: Sun,  2 Sep 2018 18:13:13 +0200

> These two patches implement full phylink support for the mv88e6352
> family, when using an SFP connected to its SERDES interface. This adds
> interrupt support to the SERDES, so that we get interrupts on link
> up/down, and then make calls phydev_link_change().
> 
> The first patch is a minor bug fix, which does not seem to affect any
> current features, so i'm not submitting it for stable. It is however
> required for configuring SERDES interrupts.

Series applied, thanks Andrew.

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

end of thread, other threads:[~2018-09-03  3:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-02 16:13 [PATCH net-next 0/2] Full phylink support for mv88e6352 Andrew Lunn
2018-09-02 16:13 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: Fix writing to a PHY page Andrew Lunn
2018-09-02 16:13 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add SERDES phydev_link_change for 6352 Andrew Lunn
2018-09-02 23:17 ` [PATCH net-next 0/2] Full phylink support for mv88e6352 David Miller

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.