diff mbox series

[net-next,v4] net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x

Message ID 20230531174720.7821-1-msmulski2@gmail.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [net-next,v4] net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/apply fail Patch does not apply to net-next

Commit Message

Michal Smulski May 31, 2023, 5:47 p.m. UTC
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 | 70 +++++++++++++++++++++++++++++-
 drivers/net/dsa/mv88e6xxx/serdes.h | 13 ++++++
 4 files changed, 85 insertions(+), 4 deletions(-)

Comments

Jakub Kicinski June 1, 2023, 5:56 a.m. UTC | #1
On Wed, 31 May 2023 10:47:20 -0700 msmulski2@gmail.com wrote:
> From: Michal Smulski <michal.smulski@ooma.com>
> 
> Enable USXGMII mode for mv88e6393x chips. Tested on Marvell 88E6191X.

Doesn't seem to apply to net-next, and the CC list is definitely way
too short. You must CC people who responded to previous version of 
the patch and the maintainers.

Failed to apply patch:
Applying: net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x
Using index info to reconstruct a base tree...
M	drivers/net/dsa/mv88e6xxx/chip.c
M	drivers/net/dsa/mv88e6xxx/port.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/net/dsa/mv88e6xxx/port.c
Auto-merging drivers/net/dsa/mv88e6xxx/chip.c
CONFLICT (content): Merge conflict in drivers/net/dsa/mv88e6xxx/chip.c
Recorded preimage for 'drivers/net/dsa/mv88e6xxx/chip.c'
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Michal Smulski June 1, 2023, 9:47 p.m. UTC | #2
Both of your suggestions are excellent.

It appears that there were a few changes made to chip.c and port.c since I submitted this patch.  I re-generated this patch against latest state of net-next(main) as v5 and will email to all maintainers and anyone who else who commented on this patch.

Regards,
Michal

-----Original Message-----
From: Jakub Kicinski <kuba@kernel.org> 
Sent: Wednesday, May 31, 2023 10:57 PM
To: msmulski2@gmail.com
Cc: netdev@vger.kernel.org; Michal Smulski <michal.smulski@ooma.com>
Subject: Re: [PATCH net-next v4] net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x

CAUTION: This email is originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.


On Wed, 31 May 2023 10:47:20 -0700 msmulski2@gmail.com wrote:
> From: Michal Smulski <michal.smulski@ooma.com>
>
> Enable USXGMII mode for mv88e6393x chips. Tested on Marvell 88E6191X.

Doesn't seem to apply to net-next, and the CC list is definitely way
too short. You must CC people who responded to previous version of
the patch and the maintainers.

Failed to apply patch:
Applying: net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x
Using index info to reconstruct a base tree...
M       drivers/net/dsa/mv88e6xxx/chip.c
M       drivers/net/dsa/mv88e6xxx/port.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/net/dsa/mv88e6xxx/port.c
Auto-merging drivers/net/dsa/mv88e6xxx/chip.c
CONFLICT (content): Merge conflict in drivers/net/dsa/mv88e6xxx/chip.c
Recorded preimage for 'drivers/net/dsa/mv88e6xxx/chip.c'
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 net: dsa: mv88e6xxx: implement USXGMII mode for mv88e6393x
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

--
pw-bot: cr
diff mbox series

Patch

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 5bbe95fa951c..71cee154622f 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -806,8 +806,7 @@  static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 			__set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
 			__set_bit(PHY_INTERFACE_MODE_5GBASER, supported);
 			__set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
-			/* FIXME: USXGMII is not supported yet */
-			/* __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); */
+			__set_bit(PHY_INTERFACE_MODE_USXGMII, supported);
 
 			config->mac_capabilities |= MAC_2500FD | MAC_5000FD |
 				MAC_10000FD;
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index f79cf716c541..8daeeeb66880 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -554,6 +554,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..e4f3dc39bc46 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,6 +985,64 @@  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_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 statsus: 0x%x\n", lp_status);
+
+	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 statsus: 0x%x\n", status);
+
+	state->link = !!(status & MV88E6390_USXGMII_PHY_STATUS_LINK);
+	state->duplex = status &
+		MV88E6390_USXGMII_PHY_STATUS_DUPLEX_FULL ?
+		DUPLEX_FULL : DUPLEX_HALF;
+
+	switch (status & MV88E6390_USXGMII_PHY_STATUS_SPEED_MASK) {
+	case MV88E6390_USXGMII_PHY_STATUS_SPEED_10000:
+		state->speed = SPEED_10000;
+		break;
+	case MV88E6390_USXGMII_PHY_STATUS_SPEED_5000:
+		state->speed = SPEED_5000;
+		break;
+	case MV88E6390_USXGMII_PHY_STATUS_SPEED_2500:
+		state->speed = SPEED_2500;
+		break;
+	case MV88E6390_USXGMII_PHY_STATUS_SPEED_1000:
+		state->speed = SPEED_1000;
+		break;
+	case MV88E6390_USXGMII_PHY_STATUS_SPEED_100:
+		state->speed = SPEED_100;
+		break;
+	case MV88E6390_USXGMII_PHY_STATUS_SPEED_10:
+		state->speed = SPEED_10;
+		break;
+	default:
+		dev_err(chip->dev, "invalid PHY speed\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -1020,6 +1079,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 +1235,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 +1276,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 +1541,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 +1647,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..899b8518113a 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -48,6 +48,19 @@ 
 #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
+#define MV88E6390_USXGMII_PHY_STATUS_SPEED_MASK	GENMASK(11, 9)
+#define MV88E6390_USXGMII_PHY_STATUS_SPEED_5000	0xa00
+#define MV88E6390_USXGMII_PHY_STATUS_SPEED_2500	0x800
+#define MV88E6390_USXGMII_PHY_STATUS_SPEED_10000	0x600
+#define MV88E6390_USXGMII_PHY_STATUS_SPEED_1000	0x400
+#define MV88E6390_USXGMII_PHY_STATUS_SPEED_100	0x200
+#define MV88E6390_USXGMII_PHY_STATUS_SPEED_10	0x000
+#define MV88E6390_USXGMII_PHY_STATUS_DUPLEX_FULL	BIT(12)
+#define MV88E6390_USXGMII_PHY_STATUS_LINK		BIT(15)
+
 /* 1000BASE-X and SGMII */
 #define MV88E6390_SGMII_BMCR		(0x2000 + MII_BMCR)
 #define MV88E6390_SGMII_BMSR		(0x2000 + MII_BMSR)