It's now possible to have the DW XPCS device defined as a standard
platform device for instance in the platform DT-file. Although that
functionality is useless unless there is a way to have the device found by
the client drivers (STMMAC/DW *MAC, NXP SJA1105 Eth Switch, etc). Provide
such ability by means of the xpcs_create_fwnode() method. It needs to be
called with the device DW XPCS fwnode instance passed. That node will be
then used to find the MDIO-device instance in order to create the DW XPCS
descriptor.
Note the method semantics and name is similar to what has been recently
introduced in the Lynx PCS driver.
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
---
Changelog v2:
- Use the function name and semantics similar to the Lynx PCS driver.
- Add kdoc describing the DW XPCS create functions.
---
drivers/net/pcs/pcs-xpcs.c | 50 ++++++++++++++++++++++++++++++++++++
include/linux/pcs/pcs-xpcs.h | 3 +++
2 files changed, 53 insertions(+)
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 8f7e3af64fcc..d45fa6514884 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -10,7 +10,9 @@
#include <linux/delay.h>
#include <linux/pcs/pcs-xpcs.h>
#include <linux/mdio.h>
+#include <linux/phy.h>
#include <linux/phylink.h>
+#include <linux/property.h>
#include "pcs-xpcs.h"
@@ -1505,6 +1507,16 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
return ERR_PTR(ret);
}
+/**
+ * xpcs_create_mdiodev() - create a DW xPCS instance with the MDIO @addr
+ * @bus: pointer to the MDIO-bus descriptor for the device to be looked at
+ * @addr: device MDIO-bus ID
+ * @requested PHY interface
+ *
+ * If successful, returns a pointer to the DW XPCS handle. Otherwise returns
+ * -ENODEV if device couldn't be found on the bus, other negative errno related
+ * to the data allocation and MDIO-bus communications.
+ */
struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
phy_interface_t interface)
{
@@ -1529,6 +1541,44 @@ struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
}
EXPORT_SYMBOL_GPL(xpcs_create_mdiodev);
+/**
+ * xpcs_create_fwnode() - Create a DW xPCS instance from @fwnode
+ * @node: fwnode handle poining to the DW XPCS device
+ * @interface: requested PHY interface
+ *
+ * If successful, returns a pointer to the DW XPCS handle. Otherwise returns
+ * -ENODEV if the fwnode is marked unavailable or device couldn't be found on
+ * the bus, -EPROBE_DEFER if the respective MDIO-device instance couldn't be
+ * found, other negative errno related to the data allocations and MDIO-bus
+ * communications.
+ */
+struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode,
+ phy_interface_t interface)
+{
+ struct mdio_device *mdiodev;
+ struct dw_xpcs *xpcs;
+
+ if (!fwnode_device_is_available(fwnode))
+ return ERR_PTR(-ENODEV);
+
+ mdiodev = fwnode_mdio_find_device(fwnode);
+ if (!mdiodev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ xpcs = xpcs_create(mdiodev, interface);
+
+ /* xpcs_create() has taken a refcount on the mdiodev if it was
+ * successful. If xpcs_create() fails, this will free the mdio
+ * device here. In any case, we don't need to hold our reference
+ * anymore, and putting it here will allow mdio_device_put() in
+ * xpcs_destroy() to automatically free the mdio device.
+ */
+ mdio_device_put(mdiodev);
+
+ return xpcs;
+}
+EXPORT_SYMBOL_GPL(xpcs_create_fwnode);
+
void xpcs_destroy(struct dw_xpcs *xpcs)
{
if (!xpcs)
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index 813be644647f..b4a4eb6c8866 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -8,6 +8,7 @@
#define __LINUX_PCS_XPCS_H
#include <linux/clk.h>
+#include <linux/fwnode.h>
#include <linux/mdio.h>
#include <linux/phy.h>
#include <linux/phylink.h>
@@ -72,6 +73,8 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
int enable);
struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
phy_interface_t interface);
+struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode,
+ phy_interface_t interface);
void xpcs_destroy(struct dw_xpcs *xpcs);
#endif /* __LINUX_PCS_XPCS_H */
--
2.43.0
On Sun, Jun 02, 2024 at 05:36:22PM +0300, Serge Semin wrote:
> It's now possible to have the DW XPCS device defined as a standard
> platform device for instance in the platform DT-file. Although that
> functionality is useless unless there is a way to have the device found by
> the client drivers (STMMAC/DW *MAC, NXP SJA1105 Eth Switch, etc). Provide
> such ability by means of the xpcs_create_fwnode() method. It needs to be
> called with the device DW XPCS fwnode instance passed. That node will be
> then used to find the MDIO-device instance in order to create the DW XPCS
> descriptor.
>
> Note the method semantics and name is similar to what has been recently
> introduced in the Lynx PCS driver.
>
> Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
Hi Serge,
Some minor nits from my side flagged by kernel-doc -none -Wall
...
> diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
...
> @@ -1505,6 +1507,16 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> return ERR_PTR(ret);
> }
>
> +/**
> + * xpcs_create_mdiodev() - create a DW xPCS instance with the MDIO @addr
> + * @bus: pointer to the MDIO-bus descriptor for the device to be looked at
> + * @addr: device MDIO-bus ID
> + * @requested PHY interface
An entry for @interface should go here.
> + *
> + * If successful, returns a pointer to the DW XPCS handle. Otherwise returns
> + * -ENODEV if device couldn't be found on the bus, other negative errno related
> + * to the data allocation and MDIO-bus communications.
Please consider including this information as a Return: section of the
Kernel doc. Likewise for xpcs_create_fwnode().
> + */
> struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
> phy_interface_t interface)
> {
> @@ -1529,6 +1541,44 @@ struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
> }
> EXPORT_SYMBOL_GPL(xpcs_create_mdiodev);
>
> +/**
> + * xpcs_create_fwnode() - Create a DW xPCS instance from @fwnode
> + * @node: fwnode handle poining to the DW XPCS device
s/@node/@fwnode/
> + * @interface: requested PHY interface
> + *
> + * If successful, returns a pointer to the DW XPCS handle. Otherwise returns
> + * -ENODEV if the fwnode is marked unavailable or device couldn't be found on
> + * the bus, -EPROBE_DEFER if the respective MDIO-device instance couldn't be
> + * found, other negative errno related to the data allocations and MDIO-bus
> + * communications.
> + */
> +struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode,
> + phy_interface_t interface)
...
Hi Simon
On Wed, Jun 05, 2024 at 06:49:20PM +0100, Simon Horman wrote:
> On Sun, Jun 02, 2024 at 05:36:22PM +0300, Serge Semin wrote:
> > It's now possible to have the DW XPCS device defined as a standard
> > platform device for instance in the platform DT-file. Although that
> > functionality is useless unless there is a way to have the device found by
> > the client drivers (STMMAC/DW *MAC, NXP SJA1105 Eth Switch, etc). Provide
> > such ability by means of the xpcs_create_fwnode() method. It needs to be
> > called with the device DW XPCS fwnode instance passed. That node will be
> > then used to find the MDIO-device instance in order to create the DW XPCS
> > descriptor.
> >
> > Note the method semantics and name is similar to what has been recently
> > introduced in the Lynx PCS driver.
> >
> > Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
>
> Hi Serge,
>
> Some minor nits from my side flagged by kernel-doc -none -Wall
>
> ...
>
> > diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
>
> ...
>
> > @@ -1505,6 +1507,16 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> > return ERR_PTR(ret);
> > }
> >
> > +/**
> > + * xpcs_create_mdiodev() - create a DW xPCS instance with the MDIO @addr
> > + * @bus: pointer to the MDIO-bus descriptor for the device to be looked at
> > + * @addr: device MDIO-bus ID
> > + * @requested PHY interface
>
> An entry for @interface should go here.
Right.
>
> > + *
> > + * If successful, returns a pointer to the DW XPCS handle. Otherwise returns
> > + * -ENODEV if device couldn't be found on the bus, other negative errno related
> > + * to the data allocation and MDIO-bus communications.
>
> Please consider including this information as a Return: section of the
> Kernel doc. Likewise for xpcs_create_fwnode().
Sure.
>
> > + */
> > struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
> > phy_interface_t interface)
> > {
> > @@ -1529,6 +1541,44 @@ struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
> > }
> > EXPORT_SYMBOL_GPL(xpcs_create_mdiodev);
> >
> > +/**
> > + * xpcs_create_fwnode() - Create a DW xPCS instance from @fwnode
> > + * @node: fwnode handle poining to the DW XPCS device
>
> s/@node/@fwnode/
Holy mother, so many typos in the kdoc part. I should have been more
attentive. I'll fix all of them in v2. Thanks.
* Special thanks for mentioning the scripts/kernel-doc I'll be using
it from now on.
-Serge(y)
>
> > + * @interface: requested PHY interface
> > + *
> > + * If successful, returns a pointer to the DW XPCS handle. Otherwise returns
> > + * -ENODEV if the fwnode is marked unavailable or device couldn't be found on
> > + * the bus, -EPROBE_DEFER if the respective MDIO-device instance couldn't be
> > + * found, other negative errno related to the data allocations and MDIO-bus
> > + * communications.
> > + */
> > +struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode,
> > + phy_interface_t interface)
>
> ...
© 2016 - 2026 Red Hat, Inc.