* [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.