mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: mike.marciniszyn@gmail.com
To: Alexander Duyck <alexanderduyck@fb.com>,
	Jakub Kicinski <kuba@kernel.org>,
	kernel-team@meta.com, Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Paolo Abeni <pabeni@redhat.com>,
	Jiawen Wu <jiawenwu@trustnetic.com>,
	Mengyuan Lou <mengyuanlou@net-swift.com>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	Mohsin Bashir <mohsin.bashr@gmail.com>,
	Kees Cook <kees@kernel.org>, Andrew Lunn <andrew@lunn.ch>
Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH net-next v3 1/4] net: pcs: xpcs: Expand mdiodev member as an array
Date: Tue, 26 May 2026 20:09:55 -0400	[thread overview]
Message-ID: <20260527000958.81108-2-mike.marciniszyn@gmail.com> (raw)
In-Reply-To: <20260527000958.81108-1-mike.marciniszyn@gmail.com>

From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@gmail.com>

This allows for support of 50GR2 and 100GR2 by extending the
current singleton mdiodev to an array.

DW XPCS can support 25GR1 and 50GR1 using just a single group
channel.   To operate at 50R2 or 100R2 we need both halves
of the channel combined into one group channel device.

Adjust current use of singleton mdiodev to use the 0th element.

Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Mike Marciniszyn (Meta) <mike.marciniszyn@gmail.com>
---
v3:
  - new to series
  - Added DW XPCS details to commit message
  - change mdiodev to an array in dw_xpcs
  - adjust singleton use case to use mdiodev[0]

 drivers/net/pcs/pcs-xpcs-wx.c |  4 ++--
 drivers/net/pcs/pcs-xpcs.c    | 42 +++++++++++++++++------------------
 drivers/net/pcs/pcs-xpcs.h    |  5 ++++-
 3 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/drivers/net/pcs/pcs-xpcs-wx.c b/drivers/net/pcs/pcs-xpcs-wx.c
index fc52f7aa5f59..38c980f974b4 100644
--- a/drivers/net/pcs/pcs-xpcs-wx.c
+++ b/drivers/net/pcs/pcs-xpcs-wx.c
@@ -123,7 +123,7 @@ static int txgbe_pcs_poll_power_up(struct dw_xpcs *xpcs)
 				10000, 1000000, false,
 				xpcs, DW_VR_XS_PCS_DIG_STS);
 	if (ret < 0)
-		dev_err(&xpcs->mdiodev->dev, "xpcs power-up timeout\n");
+		dev_err(&xpcs->mdiodev[0]->dev, "xpcs power-up timeout\n");
 
 	return ret;
 }
@@ -139,7 +139,7 @@ static int txgbe_pma_init_done(struct dw_xpcs *xpcs)
 				100000, 10000000, false,
 				xpcs, DW_VR_XS_PCS_DIG_CTRL1);
 	if (ret < 0)
-		dev_err(&xpcs->mdiodev->dev, "xpcs pma initialization timeout\n");
+		dev_err(&xpcs->mdiodev[0]->dev, "xpcs pma initialization timeout\n");
 
 	return ret;
 }
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index e69fa2f0a0e8..3c11c9552b60 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -211,23 +211,23 @@ static bool __xpcs_linkmode_supported(const struct dw_xpcs_compat *compat,
 
 int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg)
 {
-	return mdiodev_c45_read(xpcs->mdiodev, dev, reg);
+	return mdiodev_c45_read(xpcs->mdiodev[0], dev, reg);
 }
 
 int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val)
 {
-	return mdiodev_c45_write(xpcs->mdiodev, dev, reg, val);
+	return mdiodev_c45_write(xpcs->mdiodev[0], dev, reg, val);
 }
 
 int xpcs_modify(struct dw_xpcs *xpcs, int dev, u32 reg, u16 mask, u16 set)
 {
-	return mdiodev_c45_modify(xpcs->mdiodev, dev, reg, mask, set);
+	return mdiodev_c45_modify(xpcs->mdiodev[0], dev, reg, mask, set);
 }
 
 static int xpcs_modify_changed(struct dw_xpcs *xpcs, int dev, u32 reg,
 			       u16 mask, u16 set)
 {
-	return mdiodev_c45_modify_changed(xpcs->mdiodev, dev, reg, mask, set);
+	return mdiodev_c45_modify_changed(xpcs->mdiodev[0], dev, reg, mask, set);
 }
 
 static int xpcs_read_vendor(struct dw_xpcs *xpcs, int dev, u32 reg)
@@ -304,7 +304,7 @@ static int xpcs_soft_reset(struct dw_xpcs *xpcs,
 #define xpcs_warn(__xpcs, __state, __args...) \
 ({ \
 	if ((__state)->link) \
-		dev_warn(&(__xpcs)->mdiodev->dev, ##__args); \
+		dev_warn(&(__xpcs)->mdiodev[0]->dev, ##__args); \
 })
 
 static int xpcs_read_fault_c73(struct dw_xpcs *xpcs,
@@ -400,7 +400,7 @@ static void xpcs_link_up_usxgmii(struct dw_xpcs *xpcs, int speed)
 	return;
 
 out:
-	dev_err(&xpcs->mdiodev->dev, "%s: XPCS access returned %pe\n",
+	dev_err(&xpcs->mdiodev[0]->dev, "%s: XPCS access returned %pe\n",
 		__func__, ERR_PTR(ret));
 }
 
@@ -726,7 +726,7 @@ static void xpcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface)
 
 	ret = xpcs_switch_interface_mode(xpcs, interface);
 	if (ret)
-		dev_err(&xpcs->mdiodev->dev, "switch interface failed: %pe\n",
+		dev_err(&xpcs->mdiodev[0]->dev, "switch interface failed: %pe\n",
 			ERR_PTR(ret));
 
 	if (!xpcs->need_reset)
@@ -734,14 +734,14 @@ static void xpcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface)
 
 	compat = xpcs_find_compat(xpcs, interface);
 	if (!compat) {
-		dev_err(&xpcs->mdiodev->dev, "unsupported interface %s\n",
+		dev_err(&xpcs->mdiodev[0]->dev, "unsupported interface %s\n",
 			phy_modes(interface));
 		return;
 	}
 
 	ret = xpcs_soft_reset(xpcs, compat);
 	if (ret)
-		dev_err(&xpcs->mdiodev->dev, "soft reset failed: %pe\n",
+		dev_err(&xpcs->mdiodev[0]->dev, "soft reset failed: %pe\n",
 			ERR_PTR(ret));
 
 	xpcs->need_reset = false;
@@ -1189,30 +1189,30 @@ static void xpcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,
 
 	switch (compat->an_mode) {
 	case DW_10GBASER:
-		phylink_mii_c45_pcs_get_state(xpcs->mdiodev, state);
+		phylink_mii_c45_pcs_get_state(xpcs->mdiodev[0], state);
 		break;
 	case DW_AN_C73:
 		ret = xpcs_get_state_c73(xpcs, state, compat);
 		if (ret)
-			dev_err(&xpcs->mdiodev->dev, "%s returned %pe\n",
+			dev_err(&xpcs->mdiodev[0]->dev, "%s returned %pe\n",
 				"xpcs_get_state_c73", ERR_PTR(ret));
 		break;
 	case DW_AN_C37_SGMII:
 		ret = xpcs_get_state_c37_sgmii(xpcs, state);
 		if (ret)
-			dev_err(&xpcs->mdiodev->dev, "%s returned %pe\n",
+			dev_err(&xpcs->mdiodev[0]->dev, "%s returned %pe\n",
 				"xpcs_get_state_c37_sgmii", ERR_PTR(ret));
 		break;
 	case DW_AN_C37_1000BASEX:
 		ret = xpcs_get_state_c37_1000basex(xpcs, neg_mode, state);
 		if (ret)
-			dev_err(&xpcs->mdiodev->dev, "%s returned %pe\n",
+			dev_err(&xpcs->mdiodev[0]->dev, "%s returned %pe\n",
 				"xpcs_get_state_c37_1000basex", ERR_PTR(ret));
 		break;
 	case DW_2500BASEX:
 		ret = xpcs_get_state_2500basex(xpcs, state);
 		if (ret)
-			dev_err(&xpcs->mdiodev->dev, "%s returned %pe\n",
+			dev_err(&xpcs->mdiodev[0]->dev, "%s returned %pe\n",
 				"xpcs_get_state_2500basex", ERR_PTR(ret));
 		break;
 	default:
@@ -1232,14 +1232,14 @@ static void xpcs_link_up_sgmii_1000basex(struct dw_xpcs *xpcs,
 
 	if (interface == PHY_INTERFACE_MODE_1000BASEX) {
 		if (speed != SPEED_1000) {
-			dev_err(&xpcs->mdiodev->dev,
+			dev_err(&xpcs->mdiodev[0]->dev,
 				"%s: speed %dMbps not supported\n",
 				__func__, speed);
 			return;
 		}
 
 		if (duplex != DUPLEX_FULL)
-			dev_err(&xpcs->mdiodev->dev,
+			dev_err(&xpcs->mdiodev[0]->dev,
 				"%s: half duplex not supported\n",
 				__func__);
 	}
@@ -1247,7 +1247,7 @@ static void xpcs_link_up_sgmii_1000basex(struct dw_xpcs *xpcs,
 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MII_BMCR,
 			 mii_bmcr_encode_fixed(speed, duplex));
 	if (ret)
-		dev_err(&xpcs->mdiodev->dev, "%s: xpcs_write returned %pe\n",
+		dev_err(&xpcs->mdiodev[0]->dev, "%s: xpcs_write returned %pe\n",
 			__func__, ERR_PTR(ret));
 }
 
@@ -1533,7 +1533,7 @@ static struct dw_xpcs *xpcs_create_data(struct mdio_device *mdiodev)
 		return ERR_PTR(-ENOMEM);
 
 	mdio_device_get(mdiodev);
-	xpcs->mdiodev = mdiodev;
+	xpcs->mdiodev[0] = mdiodev;
 	xpcs->pcs.ops = &xpcs_phylink_ops;
 	xpcs->pcs.poll = true;
 
@@ -1542,7 +1542,7 @@ static struct dw_xpcs *xpcs_create_data(struct mdio_device *mdiodev)
 
 static void xpcs_free_data(struct dw_xpcs *xpcs)
 {
-	mdio_device_put(xpcs->mdiodev);
+	mdio_device_put(xpcs->mdiodev[0]);
 	kfree(xpcs);
 }
 
@@ -1552,7 +1552,7 @@ static int xpcs_init_clks(struct dw_xpcs *xpcs)
 		[DW_XPCS_CORE_CLK] = "core",
 		[DW_XPCS_PAD_CLK] = "pad",
 	};
-	struct device *dev = &xpcs->mdiodev->dev;
+	struct device *dev = &xpcs->mdiodev[0]->dev;
 	int ret, i;
 
 	for (i = 0; i < DW_XPCS_NUM_CLKS; ++i)
@@ -1580,7 +1580,7 @@ static int xpcs_init_id(struct dw_xpcs *xpcs)
 {
 	const struct dw_xpcs_info *info;
 
-	info = dev_get_platdata(&xpcs->mdiodev->dev);
+	info = dev_get_platdata(&xpcs->mdiodev[0]->dev);
 	if (!info) {
 		xpcs->info.pcs = DW_XPCS_ID_NATIVE;
 		xpcs->info.pma = DW_XPCS_PMA_ID_NATIVE;
diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h
index 929fa238445e..5c804cfd47d3 100644
--- a/drivers/net/pcs/pcs-xpcs.h
+++ b/drivers/net/pcs/pcs-xpcs.h
@@ -105,10 +105,13 @@ enum dw_xpcs_clock {
 	DW_XPCS_NUM_CLKS,
 };
 
+/* 2 channels per group DW PCS devices */
+#define DW_XPCS_MAX_CHANNELS 2
+
 struct dw_xpcs {
 	struct dw_xpcs_info info;
 	const struct dw_xpcs_desc *desc;
-	struct mdio_device *mdiodev;
+	struct mdio_device *mdiodev[DW_XPCS_MAX_CHANNELS];
 	struct clk_bulk_data clks[DW_XPCS_NUM_CLKS];
 	struct phylink_pcs pcs;
 	phy_interface_t interface;
-- 
2.43.0


  reply	other threads:[~2026-05-27  0:10 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-27  0:09 [PATCH net-next v3 0/4] second series for xpcs based rsfec configuratio mike.marciniszyn
2026-05-27  0:09 ` mike.marciniszyn [this message]
2026-05-27  0:09 ` [PATCH net-next v3 2/4] net: pcs: xpcs: Allow for multiple addr in creation mike.marciniszyn
2026-05-27  0:09 ` [PATCH net-next v3 3/4] net: pcs: xpcs: Add hooks for xpcs configuration of rsfec mike.marciniszyn
2026-05-27  0:09 ` [PATCH net-next v3 4/4] net: pcs: xpcs: Add handling for 4 channel rsfec device mike.marciniszyn
2026-06-02 14:20 ` [PATCH net-next v3 0/4] second series for xpcs based rsfec configuratio Simon Horman

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=20260527000958.81108-2-mike.marciniszyn@gmail.com \
    --to=mike.marciniszyn@gmail.com \
    --cc=alexanderduyck@fb.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=hkallweit1@gmail.com \
    --cc=jiawenwu@trustnetic.com \
    --cc=kees@kernel.org \
    --cc=kernel-team@meta.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=mengyuanlou@net-swift.com \
    --cc=mohsin.bashr@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®