[PATCH net-next v7 5/7] net: stmmac: dwmac-socfpga: use pcs_init/pcs_exit
Hariprasad Kelam
hkelam at marvell.com
Mon May 13 03:10:47 PDT 2024
> From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>
>
> Use the newly introduced pcs_init() and pcs_exit() operations to create and
> destroy the PCS instance at a more appropriate moment during the driver
> lifecycle, thereby avoiding publishing a network device to userspace that has
> not yet finished its PCS initialisation.
>
> There are other similar issues with this driver which remain unaddressed, but
> these are out of scope for this patch.
>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
> [rgantois: removed second parameters of new callbacks]
> Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
> ---
> .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 107 ++++++++++-------
> ----
> 1 file changed, 53 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> index 12b4a80ea3aa1..b3d45f9dfb556 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> @@ -379,6 +379,56 @@ static int socfpga_gen10_set_phy_mode(struct
> socfpga_dwmac *dwmac)
> return 0;
> }
>
> +static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv) {
> + struct socfpga_dwmac *dwmac = priv->plat->bsp_priv;
> + struct regmap_config pcs_regmap_cfg = {
> + .reg_bits = 16,
> + .val_bits = 16,
> + .reg_shift = REGMAP_UPSHIFT(1),
> + };
> + struct mdio_regmap_config mrc;
> + struct regmap *pcs_regmap;
> + struct phylink_pcs *pcs;
> + struct mii_bus *pcs_bus;
> +
> + if (!dwmac->tse_pcs_base)
> + return 0;
> +
> + pcs_regmap = devm_regmap_init_mmio(priv->device, dwmac-
> >tse_pcs_base,
> + &pcs_regmap_cfg);
> + if (IS_ERR(pcs_regmap))
> + return PTR_ERR(pcs_regmap);
> +
> + memset(&mrc, 0, sizeof(mrc));
> + mrc.regmap = pcs_regmap;
> + mrc.parent = priv->device;
> + mrc.valid_addr = 0x0;
> + mrc.autoscan = false;
> +
> + /* Can't use ndev->name here because it will not have been
> initialised,
> + * and in any case, the user can rename network interfaces at
> runtime.
> + */
> + snprintf(mrc.name, MII_BUS_ID_SIZE, "%s-pcs-mii",
> + dev_name(priv->device));
> + pcs_bus = devm_mdio_regmap_register(priv->device, &mrc);
> + if (IS_ERR(pcs_bus))
> + return PTR_ERR(pcs_bus);
> +
> + pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
> + if (IS_ERR(pcs))
> + return PTR_ERR(pcs);
> +
> + priv->hw->phylink_pcs = pcs;
> + return 0;
> +}
> +
> +static void socfpga_dwmac_pcs_exit(struct stmmac_priv *priv) {
> + if (priv->hw->phylink_pcs)
> + lynx_pcs_destroy(priv->hw->phylink_pcs);
> +}
> +
> static int socfpga_dwmac_probe(struct platform_device *pdev) {
> struct plat_stmmacenet_data *plat_dat; @@ -426,6 +476,8 @@ static
> int socfpga_dwmac_probe(struct platform_device *pdev)
> dwmac->ops = ops;
> plat_dat->bsp_priv = dwmac;
> plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
> + plat_dat->pcs_init = socfpga_dwmac_pcs_init;
> + plat_dat->pcs_exit = socfpga_dwmac_pcs_exit;
>
> ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
> if (ret)
> @@ -444,48 +496,6 @@ static int socfpga_dwmac_probe(struct
> platform_device *pdev)
> if (ret)
> goto err_dvr_remove;
>
> - /* Create a regmap for the PCS so that it can be used by the PCS
> driver,
> - * if we have such a PCS
> - */
> - if (dwmac->tse_pcs_base) {
> - struct regmap_config pcs_regmap_cfg;
> - struct mdio_regmap_config mrc;
> - struct regmap *pcs_regmap;
> - struct mii_bus *pcs_bus;
> -
> - memset(&pcs_regmap_cfg, 0, sizeof(pcs_regmap_cfg));
> - memset(&mrc, 0, sizeof(mrc));
> -
> - pcs_regmap_cfg.reg_bits = 16;
> - pcs_regmap_cfg.val_bits = 16;
> - pcs_regmap_cfg.reg_shift = REGMAP_UPSHIFT(1);
> -
> - pcs_regmap = devm_regmap_init_mmio(&pdev->dev,
> dwmac->tse_pcs_base,
> - &pcs_regmap_cfg);
> - if (IS_ERR(pcs_regmap)) {
> - ret = PTR_ERR(pcs_regmap);
> - goto err_dvr_remove;
> - }
> -
> - mrc.regmap = pcs_regmap;
> - mrc.parent = &pdev->dev;
> - mrc.valid_addr = 0x0;
> - mrc.autoscan = false;
> -
> - snprintf(mrc.name, MII_BUS_ID_SIZE, "%s-pcs-mii", ndev-
> >name);
> - pcs_bus = devm_mdio_regmap_register(&pdev->dev, &mrc);
> - if (IS_ERR(pcs_bus)) {
> - ret = PTR_ERR(pcs_bus);
> - goto err_dvr_remove;
> - }
> -
> - stpriv->hw->phylink_pcs = lynx_pcs_create_mdiodev(pcs_bus,
> 0);
> - if (IS_ERR(stpriv->hw->phylink_pcs)) {
> - ret = PTR_ERR(stpriv->hw->phylink_pcs);
> - goto err_dvr_remove;
> - }
> - }
> -
> return 0;
>
> err_dvr_remove:
> @@ -494,17 +504,6 @@ static int socfpga_dwmac_probe(struct
> platform_device *pdev)
> return ret;
> }
>
> -static void socfpga_dwmac_remove(struct platform_device *pdev) -{
> - struct net_device *ndev = platform_get_drvdata(pdev);
> - struct stmmac_priv *priv = netdev_priv(ndev);
> - struct phylink_pcs *pcs = priv->hw->phylink_pcs;
> -
> - stmmac_pltfr_remove(pdev);
> -
> - lynx_pcs_destroy(pcs);
> -}
> -
> #ifdef CONFIG_PM_SLEEP
> static int socfpga_dwmac_resume(struct device *dev) { @@ -576,7 +575,7
> @@ MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
>
> static struct platform_driver socfpga_dwmac_driver = {
> .probe = socfpga_dwmac_probe,
> - .remove_new = socfpga_dwmac_remove,
> + .remove_new = stmmac_pltfr_remove,
> .driver = {
> .name = "socfpga-dwmac",
> .pm = &socfpga_dwmac_pm_ops,
>
> --
> 2.44.0
>
Reviewed-by: Hariprasad Kelam <hkelam at marvell.com>
More information about the linux-arm-kernel
mailing list