[PATCH net-next v7 2/5] net: spacemit: Add K1 Ethernet MAC
Philipp Zabel
p.zabel at pengutronix.de
Tue Aug 26 01:54:31 PDT 2025
On Di, 2025-08-26 at 14:23 +0800, Vivian Wang wrote:
> The Ethernet MACs found on SpacemiT K1 appears to be a custom design
> that only superficially resembles some other embedded MACs. SpacemiT
> refers to them as "EMAC", so let's just call the driver "k1_emac".
>
> Supports RGMII and RMII interfaces. Includes support for MAC hardware
> statistics counters. PTP support is not implemented.
>
> Tested-by: Junhui Liu <junhui.liu at pigmoral.tech>
> Signed-off-by: Vivian Wang <wangruikang at iscas.ac.cn>
> Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
> Reviewed-by: Vadim Fedorenko <vadim.fedorenko at linux.dev>
> ---
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/spacemit/Kconfig | 29 +
> drivers/net/ethernet/spacemit/Makefile | 6 +
> drivers/net/ethernet/spacemit/k1_emac.c | 2193 +++++++++++++++++++++++++++++++
> drivers/net/ethernet/spacemit/k1_emac.h | 426 ++++++
> 6 files changed, 2656 insertions(+)
>
[...]
> diff --git a/drivers/net/ethernet/spacemit/k1_emac.c b/drivers/net/ethernet/spacemit/k1_emac.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..9e558d5893cfbbda0baa7ad21a7209dadda9487e
> --- /dev/null
> +++ b/drivers/net/ethernet/spacemit/k1_emac.c
> @@ -0,0 +1,2193 @@
[...]
> +static int emac_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct reset_control *reset;
> + struct net_device *ndev;
> + struct emac_priv *priv;
> + int ret;
> +
> + ndev = devm_alloc_etherdev(dev, sizeof(struct emac_priv));
> + if (!ndev)
> + return -ENOMEM;
> +
> + ndev->hw_features = NETIF_F_SG;
> + ndev->features |= ndev->hw_features;
> +
> + ndev->max_mtu = EMAC_RX_BUF_4K - (ETH_HLEN + ETH_FCS_LEN);
> +
> + priv = netdev_priv(ndev);
> + priv->ndev = ndev;
> + priv->pdev = pdev;
> + platform_set_drvdata(pdev, priv);
> +
> + ret = emac_config_dt(pdev, priv);
> + if (ret < 0) {
> + dev_err_probe(dev, ret, "Configuration failed\n");
> + goto err;
I'd just
return dev_err_probe(...);
here.
> + }
> +
> + ndev->watchdog_timeo = 5 * HZ;
> + ndev->base_addr = (unsigned long)priv->iobase;
> + ndev->irq = priv->irq;
> +
> + ndev->ethtool_ops = &emac_ethtool_ops;
> + ndev->netdev_ops = &emac_netdev_ops;
> +
> + devm_pm_runtime_enable(&pdev->dev);
> +
> + priv->bus_clk = devm_clk_get_enabled(&pdev->dev, NULL);
> + if (IS_ERR(priv->bus_clk)) {
> + ret = dev_err_probe(dev, PTR_ERR(priv->bus_clk),
> + "Failed to get clock\n");
> + goto err;
Same here.
> + }
> +
> + reset = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev,
> + NULL);
> + if (IS_ERR(reset)) {
> + ret = dev_err_probe(dev, PTR_ERR(reset),
> + "Failed to get reset\n");
> + goto err;
And here.
> + }
> +
> + emac_sw_init(priv);
> +
> + if (of_phy_is_fixed_link(dev->of_node)) {
> + ret = of_phy_register_fixed_link(dev->of_node);
> + if (ret) {
> + dev_err_probe(dev, ret,
> + "Failed to register fixed-link");
> + goto err_timer_delete;
If you can move this section before emac_sw_init(), this could also
just return.
> + }
Then here a function calling of_phy_deregister_fixed_link() could be
registered with devm_add_action_or_reset(), to avoid duplicated cleanup
in the error path and in emac_remove().
regards
Philipp
More information about the linux-riscv
mailing list