From: msmulski2@gmail.com
To: andrew@lunn.ch
Cc: f.fainelli@gmail.com, olteanv@gmail.com, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
linux@armlinux.org.uk, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, simon.horman@corigine.com,
kabel@kernel.org, Michal Smulski <michal.smulski@ooma.com>
Subject: [PATCH net-next v6 1/1] net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x
Date: Thu, 1 Jun 2023 17:17:04 -0700 [thread overview]
Message-ID: <20230602001705.2747-2-msmulski2@gmail.com> (raw)
In-Reply-To: <20230602001705.2747-1-msmulski2@gmail.com>
From: Michal Smulski <michal.smulski@ooma.com>
Enable USXGMII mode for mv88e6393x chips. Tested on Marvell 88E6191X.
Signed-off-by: Michal Smulski <michal.smulski@ooma.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 3 +-
drivers/net/dsa/mv88e6xxx/port.c | 3 ++
drivers/net/dsa/mv88e6xxx/serdes.c | 46 ++++++++++++++++++++++++++++--
drivers/net/dsa/mv88e6xxx/serdes.h | 4 +++
4 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 8731af6d79de..5a92ccfd08ea 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -815,8 +815,7 @@ static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
config->mac_capabilities |= MAC_5000FD |
MAC_10000FD;
}
- /* FIXME: USXGMII is not supported yet */
- /* __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); */
+ __set_bit(PHY_INTERFACE_MODE_USXGMII, supported);
}
}
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index e9b4a6ea4d09..dd66ec902d4c 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -566,6 +566,9 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
case PHY_INTERFACE_MODE_10GBASER:
cmode = MV88E6393X_PORT_STS_CMODE_10GBASER;
break;
+ case PHY_INTERFACE_MODE_USXGMII:
+ cmode = MV88E6393X_PORT_STS_CMODE_USXGMII;
+ break;
default:
cmode = 0;
}
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index 72faec8f44dc..504424f59795 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -683,7 +683,8 @@ int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
cmode == MV88E6393X_PORT_STS_CMODE_5GBASER ||
- cmode == MV88E6393X_PORT_STS_CMODE_10GBASER)
+ cmode == MV88E6393X_PORT_STS_CMODE_10GBASER ||
+ cmode == MV88E6393X_PORT_STS_CMODE_USXGMII)
lane = port;
return lane;
@@ -984,7 +985,41 @@ static int mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
state->speed = SPEED_10000;
state->duplex = DUPLEX_FULL;
}
+ return 0;
+}
+
+/* USXGMII registers for Marvell switch 88e639x are undocumented and this function is based
+ * on some educated guesses. It appears that there are no status bits related to
+ * autonegotiation complete or flow control.
+ */
+static int mv88e639x_serdes_pcs_get_state_usxgmii(struct mv88e6xxx_chip *chip,
+ int port, int lane,
+ struct phylink_link_state *state)
+{
+ u16 status, lp_status;
+ int err;
+
+ err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
+ MV88E6390_USXGMII_PHY_STATUS, &status);
+ if (err) {
+ dev_err(chip->dev, "can't read Serdes USXGMII PHY status: %d\n", err);
+ return err;
+ }
+ dev_dbg(chip->dev, "USXGMII PHY status: 0x%x\n", status);
+
+ state->link = !!(status & MDIO_USXGMII_LINK);
+
+ if (state->link) {
+ err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
+ MV88E6390_USXGMII_LP_STATUS, &lp_status);
+ if (err) {
+ dev_err(chip->dev, "can't read Serdes USXGMII LP status: %d\n", err);
+ return err;
+ }
+ dev_dbg(chip->dev, "USXGMII LP status: 0x%x\n", lp_status);
+ phylink_decode_usxgmii_word(state, lp_status);
+ }
return 0;
}
@@ -1020,6 +1055,9 @@ int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
case PHY_INTERFACE_MODE_10GBASER:
return mv88e6393x_serdes_pcs_get_state_10g(chip, port, lane,
state);
+ case PHY_INTERFACE_MODE_USXGMII:
+ return mv88e639x_serdes_pcs_get_state_usxgmii(chip, port, lane,
+ state);
default:
return -EOPNOTSUPP;
@@ -1173,6 +1211,7 @@ int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
case MV88E6393X_PORT_STS_CMODE_5GBASER:
case MV88E6393X_PORT_STS_CMODE_10GBASER:
+ case MV88E6393X_PORT_STS_CMODE_USXGMII:
return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable);
}
@@ -1213,6 +1252,7 @@ irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
break;
case MV88E6393X_PORT_STS_CMODE_5GBASER:
case MV88E6393X_PORT_STS_CMODE_10GBASER:
+ case MV88E6393X_PORT_STS_CMODE_USXGMII:
err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status);
if (err)
return err;
@@ -1477,7 +1517,8 @@ static int mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip *chip, int lane,
* to SERDES operating in 10G mode. These registers only apply to 10G
* operation and have no effect on other speeds.
*/
- if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER)
+ if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER &&
+ cmode != MV88E6393X_PORT_STS_CMODE_USXGMII)
return 0;
for (i = 0; i < ARRAY_SIZE(fixes); ++i) {
@@ -1582,6 +1623,7 @@ int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
break;
case MV88E6393X_PORT_STS_CMODE_5GBASER:
case MV88E6393X_PORT_STS_CMODE_10GBASER:
+ case MV88E6393X_PORT_STS_CMODE_USXGMII:
err = mv88e6390_serdes_power_10g(chip, lane, on);
break;
default:
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index 29bb4e91e2f6..e245687ddb1d 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -48,6 +48,10 @@
#define MV88E6393X_10G_INT_LINK_CHANGE BIT(2)
#define MV88E6393X_10G_INT_STATUS 0x9001
+/* USXGMII */
+#define MV88E6390_USXGMII_LP_STATUS 0xf0a2
+#define MV88E6390_USXGMII_PHY_STATUS 0xf0a6
+
/* 1000BASE-X and SGMII */
#define MV88E6390_SGMII_BMCR (0x2000 + MII_BMCR)
#define MV88E6390_SGMII_BMSR (0x2000 + MII_BMSR)
--
2.34.1
next prev parent reply other threads:[~2023-06-02 0:17 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-02 0:17 [PATCH net-next v6 0/1] net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x msmulski2
2023-06-02 0:17 ` msmulski2 [this message]
2023-06-02 7:53 ` [PATCH net-next v6 1/1] " Marek Behún
2023-06-03 4:32 ` Michal Smulski
2023-06-02 10:30 ` Russell King (Oracle)
2023-06-02 11:28 ` Ioana Ciornei
2023-06-02 13:11 ` Russell King (Oracle)
2023-06-02 14:31 ` Ioana Ciornei
2023-06-03 5:27 ` Michal Smulski
2023-06-03 4:56 ` Michal Smulski
2023-06-02 11:08 ` Russell King (Oracle)
2023-06-03 4:59 ` Michal Smulski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230602001705.2747-2-msmulski2@gmail.com \
--to=msmulski2@gmail.com \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=f.fainelli@gmail.com \
--cc=kabel@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=michal.smulski@ooma.com \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=simon.horman@corigine.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.