[PATCH net-next 07/16] net: pcs: xpcs: Split up xpcs_create() content to sub-functions

From: Serge Semin
Date: Tue Dec 05 2023 - 05:36:35 EST


As a final preparation before adding the DW XPCS MDIO-device driver
support let's split the xpcs_create() function code up to a set of small
sub-functions. Thus the method implementation will get to look simpler and
turn to be more coherent. Further updates will just touch the new methods
a bit: add platform-specific device info, add device reference clock
getting and enabling.

This update implies the xpcs_create() to call the next static methods:
xpcs_create_data() - create the DW XPCS device descriptor,
xpcs_init_id() - find XPCS ID instance and save it in the device
descriptor,
xpcs_init_iface() - find MAC/PCS interface descriptor and perform
basice initialization specific to it: soft-reset, disable polling.

The update doesn't cause any semantic change but merely makes the code
better looking and ready for adding new features support.

Note in addition to that the xpcs_destroy() is moved to be below the
xpcs_create_mdiodev() function as the driver now implies having the
protagonist-then-antagonist functions definition order.

Signed-off-by: Serge Semin <fancer.lancer@xxxxxxxxx>
---
drivers/net/pcs/pcs-xpcs.c | 102 +++++++++++++++++++++++++------------
1 file changed, 70 insertions(+), 32 deletions(-)

diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index a53376472394..ea6f56339595 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1365,70 +1365,97 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = {
.pcs_link_up = xpcs_link_up,
};

-static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
- phy_interface_t interface)
+static struct dw_xpcs *xpcs_create_data(struct mdio_device *mdiodev)
{
struct dw_xpcs *xpcs;
- u32 xpcs_id;
- int i, ret;

xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
if (!xpcs)
return ERR_PTR(-ENOMEM);

xpcs->mdiodev = mdiodev;
+ xpcs->pcs.ops = &xpcs_phylink_ops;
+ xpcs->pcs.neg_mode = true;
+ xpcs->pcs.poll = true;
+
+ return xpcs;
+}
+
+static void xpcs_free_data(struct dw_xpcs *xpcs)
+{
+ kfree(xpcs);
+}
+
+static int xpcs_init_id(struct dw_xpcs *xpcs)
+{
+ u32 xpcs_id;
+ int i, ret;

xpcs_id = xpcs_get_id(xpcs);

for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
const struct xpcs_id *entry = &xpcs_id_list[i];
- const struct xpcs_compat *compat;

if ((xpcs_id & entry->mask) != entry->id)
continue;

xpcs->id = entry;

- compat = xpcs_find_compat(entry, interface);
- if (!compat) {
- ret = -ENODEV;
- goto out;
- }
+ break;
+ }

- ret = xpcs_dev_flag(xpcs);
- if (ret)
- goto out;
+ if (!xpcs->id)
+ return -ENODEV;

- xpcs->pcs.ops = &xpcs_phylink_ops;
- xpcs->pcs.neg_mode = true;
+ ret = xpcs_dev_flag(xpcs);
+ if (ret < 0)
+ return ret;

- if (xpcs->dev_flag != DW_DEV_TXGBE) {
- xpcs->pcs.poll = true;
+ return 0;
+}

- ret = xpcs_soft_reset(xpcs, compat);
- if (ret)
- goto out;
- }
+static int xpcs_init_iface(struct dw_xpcs *xpcs, phy_interface_t interface)
+{
+ const struct xpcs_compat *compat;

- return xpcs;
+ compat = xpcs_find_compat(xpcs->id, interface);
+ if (!compat)
+ return -EINVAL;
+
+ if (xpcs->dev_flag == DW_DEV_TXGBE) {
+ xpcs->pcs.poll = false;
+ return 0;
}

- ret = -ENODEV;
+ return xpcs_soft_reset(xpcs, compat);
+}
+
+static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
+ phy_interface_t interface)
+{
+ struct dw_xpcs *xpcs;
+ int ret;
+
+ xpcs = xpcs_create_data(mdiodev);
+ if (IS_ERR(xpcs))
+ return xpcs;
+
+ ret = xpcs_init_id(xpcs);
+ if (ret)
+ goto out;
+
+ ret = xpcs_init_iface(xpcs, interface);
+ if (ret)
+ goto out;
+
+ return xpcs;

out:
- kfree(xpcs);
+ xpcs_free_data(xpcs);

return ERR_PTR(ret);
}

-void xpcs_destroy(struct dw_xpcs *xpcs)
-{
- if (xpcs)
- mdio_device_put(xpcs->mdiodev);
- kfree(xpcs);
-}
-EXPORT_SYMBOL_GPL(xpcs_destroy);
-
struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
phy_interface_t interface)
{
@@ -1455,4 +1482,15 @@ struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
}
EXPORT_SYMBOL_GPL(xpcs_create_mdiodev);

+void xpcs_destroy(struct dw_xpcs *xpcs)
+{
+ if (!xpcs)
+ return;
+
+ mdio_device_put(xpcs->mdiodev);
+
+ xpcs_free_data(xpcs);
+}
+EXPORT_SYMBOL_GPL(xpcs_destroy);
+
MODULE_LICENSE("GPL v2");
--
2.42.1