From 6778948f9de86c3cfaf36725a7c87dcff9ba247f Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 08:20:59 +0000 Subject: [PATCH] kernel_5.10 no rt --- kernel/drivers/net/ethernet/nxp/lpc_eth.c | 183 +++++++++++++++++---------------------------- 1 files changed, 70 insertions(+), 113 deletions(-) diff --git a/kernel/drivers/net/ethernet/nxp/lpc_eth.c b/kernel/drivers/net/ethernet/nxp/lpc_eth.c index 415ac33..a9a9bf2 100644 --- a/kernel/drivers/net/ethernet/nxp/lpc_eth.c +++ b/kernel/drivers/net/ethernet/nxp/lpc_eth.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/net/ethernet/nxp/lpc_eth.c * @@ -5,48 +6,21 @@ * * Copyright (C) 2010 NXP Semiconductors * Copyright (C) 2012 Roland Stigge <stigge@antcom.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/errno.h> -#include <linux/ioport.h> +#include <linux/clk.h> #include <linux/crc32.h> +#include <linux/etherdevice.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_mdio.h> +#include <linux/of_net.h> +#include <linux/phy.h> #include <linux/platform_device.h> #include <linux/spinlock.h> -#include <linux/ethtool.h> -#include <linux/mii.h> -#include <linux/clk.h> -#include <linux/workqueue.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/phy.h> -#include <linux/dma-mapping.h> -#include <linux/of.h> -#include <linux/of_net.h> -#include <linux/types.h> - -#include <linux/io.h> -#include <mach/board.h> -#include <mach/platform.h> -#include <mach/hardware.h> +#include <linux/soc/nxp/lpc32xx-misc.h> #define MODNAME "lpc-eth" #define DRV_VERSION "1.00" @@ -296,7 +270,7 @@ #define LPC_FCCR_MIRRORCOUNTERCURRENT(n) ((n) & 0xFFFF) /* - * rxfliterctrl, rxfilterwolstatus, and rxfilterwolclear shared + * rxfilterctrl, rxfilterwolstatus, and rxfilterwolclear shared * register definitions */ #define LPC_RXFLTRW_ACCEPTUNICAST (1 << 0) @@ -307,7 +281,7 @@ #define LPC_RXFLTRW_ACCEPTPERFECT (1 << 5) /* - * rxfliterctrl register definitions + * rxfilterctrl register definitions */ #define LPC_RXFLTRWSTS_MAGICPACKETENWOL (1 << 12) #define LPC_RXFLTRWSTS_RXFILTERENWOL (1 << 13) @@ -418,6 +392,7 @@ struct netdata_local { struct platform_device *pdev; struct net_device *ndev; + struct device_node *phy_node; spinlock_t lock; void __iomem *net_base; u32 msg_enable; @@ -776,31 +751,32 @@ static int lpc_mii_probe(struct net_device *ndev) { struct netdata_local *pldat = netdev_priv(ndev); - struct phy_device *phydev = phy_find_first(pldat->mii_bus); - - if (!phydev) { - netdev_err(ndev, "no PHY found\n"); - return -ENODEV; - } + struct phy_device *phydev; /* Attach to the PHY */ if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII) netdev_info(ndev, "using MII interface\n"); else netdev_info(ndev, "using RMII interface\n"); + + if (pldat->phy_node) + phydev = of_phy_find_device(pldat->phy_node); + else + phydev = phy_find_first(pldat->mii_bus); + if (!phydev) { + netdev_err(ndev, "no PHY found\n"); + return -ENODEV; + } + phydev = phy_connect(ndev, phydev_name(phydev), &lpc_handle_link_change, lpc_phy_interface_mode(&pldat->pdev->dev)); - if (IS_ERR(phydev)) { netdev_err(ndev, "Could not attach to PHY\n"); return PTR_ERR(phydev); } - /* mask with MAC supported features */ - phydev->supported &= PHY_BASIC_FEATURES; - - phydev->advertising = phydev->supported; + phy_set_max_speed(phydev, SPEED_100); pldat->link = 0; pldat->speed = 0; @@ -813,6 +789,7 @@ static int lpc_mii_init(struct netdata_local *pldat) { + struct device_node *node; int err = -ENXIO; pldat->mii_bus = mdiobus_alloc(); @@ -840,9 +817,10 @@ pldat->mii_bus->priv = pldat; pldat->mii_bus->parent = &pldat->pdev->dev; - platform_set_drvdata(pldat->pdev, pldat->mii_bus); - - if (mdiobus_register(pldat->mii_bus)) + node = of_get_child_by_name(pldat->pdev->dev.of_node, "mdio"); + err = of_mdiobus_register(pldat->mii_bus, node); + of_node_put(node); + if (err) goto err_out_unregister_bus; err = lpc_mii_probe(pldat->ndev); @@ -1051,7 +1029,8 @@ return 0; } -static int lpc_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) +static netdev_tx_t lpc_eth_hard_start_xmit(struct sk_buff *skb, + struct net_device *ndev) { struct netdata_local *pldat = netdev_priv(ndev); u32 len, txidx; @@ -1171,19 +1150,6 @@ spin_unlock_irqrestore(&pldat->lock, flags); } -static int lpc_eth_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) -{ - struct phy_device *phydev = ndev->phydev; - - if (!netif_running(ndev)) - return -EINVAL; - - if (!phydev) - return -ENODEV; - - return phy_mii_ioctl(phydev, req, cmd); -} - static int lpc_eth_open(struct net_device *ndev) { struct netdata_local *pldat = netdev_priv(ndev); @@ -1251,35 +1217,29 @@ .ndo_stop = lpc_eth_close, .ndo_start_xmit = lpc_eth_hard_start_xmit, .ndo_set_rx_mode = lpc_eth_set_multicast_list, - .ndo_do_ioctl = lpc_eth_ioctl, + .ndo_do_ioctl = phy_do_ioctl_running, .ndo_set_mac_address = lpc_set_mac_address, .ndo_validate_addr = eth_validate_addr, }; static int lpc_eth_drv_probe(struct platform_device *pdev) { - struct resource *res; - struct net_device *ndev; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct netdata_local *pldat; - struct phy_device *phydev; + struct net_device *ndev; dma_addr_t dma_handle; + struct resource *res; int irq, ret; - u32 tmp; /* Setup network interface for RMII or MII mode */ - tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); - tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; - if (lpc_phy_interface_mode(&pdev->dev) == PHY_INTERFACE_MODE_MII) - tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS; - else - tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; - __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); + lpc32xx_set_phy_interface_mode(lpc_phy_interface_mode(dev)); /* Get platform resources */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || irq < 0) { - dev_err(&pdev->dev, "error getting resources.\n"); + dev_err(dev, "error getting resources.\n"); ret = -ENXIO; goto err_exit; } @@ -1287,12 +1247,12 @@ /* Allocate net driver data structure */ ndev = alloc_etherdev(sizeof(struct netdata_local)); if (!ndev) { - dev_err(&pdev->dev, "could not allocate device.\n"); + dev_err(dev, "could not allocate device.\n"); ret = -ENOMEM; goto err_exit; } - SET_NETDEV_DEV(ndev, &pdev->dev); + SET_NETDEV_DEV(ndev, dev); pldat = netdev_priv(ndev); pldat->pdev = pdev; @@ -1304,9 +1264,9 @@ ndev->irq = irq; /* Get clock for the device */ - pldat->clk = clk_get(&pdev->dev, NULL); + pldat->clk = clk_get(dev, NULL); if (IS_ERR(pldat->clk)) { - dev_err(&pdev->dev, "error getting clock.\n"); + dev_err(dev, "error getting clock.\n"); ret = PTR_ERR(pldat->clk); goto err_out_free_dev; } @@ -1319,14 +1279,14 @@ /* Map IO space */ pldat->net_base = ioremap(res->start, resource_size(res)); if (!pldat->net_base) { - dev_err(&pdev->dev, "failed to map registers\n"); + dev_err(dev, "failed to map registers\n"); ret = -ENOMEM; goto err_out_disable_clocks; } ret = request_irq(ndev->irq, __lpc_eth_interrupt, 0, ndev->name, ndev); if (ret) { - dev_err(&pdev->dev, "error requesting interrupt.\n"); + dev_err(dev, "error requesting interrupt.\n"); goto err_out_iounmap; } @@ -1338,20 +1298,19 @@ /* Get size of DMA buffers/descriptors region */ pldat->dma_buff_size = (ENET_TX_DESC + ENET_RX_DESC) * (ENET_MAXF_SIZE + sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t)); - pldat->dma_buff_base_v = 0; - if (use_iram_for_net(&pldat->pdev->dev)) { - dma_handle = LPC32XX_IRAM_BASE; - if (pldat->dma_buff_size <= lpc32xx_return_iram_size()) - pldat->dma_buff_base_v = - io_p2v(LPC32XX_IRAM_BASE); - else + if (use_iram_for_net(dev)) { + if (pldat->dma_buff_size > + lpc32xx_return_iram(&pldat->dma_buff_base_v, &dma_handle)) { + pldat->dma_buff_base_v = NULL; + pldat->dma_buff_size = 0; netdev_err(ndev, "IRAM not big enough for net buffers, using SDRAM instead.\n"); + } } - if (pldat->dma_buff_base_v == 0) { - ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (pldat->dma_buff_base_v == NULL) { + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) goto err_out_free_irq; @@ -1360,7 +1319,7 @@ /* Allocate a chunk of memory for the DMA ethernet buffers and descriptors */ pldat->dma_buff_base_v = - dma_alloc_coherent(&pldat->pdev->dev, + dma_alloc_coherent(dev, pldat->dma_buff_size, &dma_handle, GFP_KERNEL); if (pldat->dma_buff_base_v == NULL) { @@ -1382,19 +1341,18 @@ netdev_dbg(ndev, "DMA buffer V address :0x%p\n", pldat->dma_buff_base_v); + pldat->phy_node = of_parse_phandle(np, "phy-handle", 0); + /* Get MAC address from current HW setting (POR state is all zeros) */ __lpc_get_mac(pldat, ndev->dev_addr); if (!is_valid_ether_addr(ndev->dev_addr)) { - const char *macaddr = of_get_mac_address(pdev->dev.of_node); - if (macaddr) - memcpy(ndev->dev_addr, macaddr, ETH_ALEN); + const char *macaddr = of_get_mac_address(np); + if (!IS_ERR(macaddr)) + ether_addr_copy(ndev->dev_addr, macaddr); } if (!is_valid_ether_addr(ndev->dev_addr)) eth_hw_addr_random(ndev); - - /* Reset the ethernet controller */ - __lpc_eth_reset(pldat); /* then shut everything down to save power */ __lpc_eth_shutdown(pldat); @@ -1416,7 +1374,7 @@ ret = register_netdev(ndev); if (ret) { - dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); + dev_err(dev, "Cannot register net device, aborting.\n"); goto err_out_dma_unmap; } platform_set_drvdata(pdev, ndev); @@ -1428,19 +1386,17 @@ netdev_info(ndev, "LPC mac at 0x%08lx irq %d\n", (unsigned long)res->start, ndev->irq); - phydev = ndev->phydev; - - device_init_wakeup(&pdev->dev, 1); - device_set_wakeup_enable(&pdev->dev, 0); + device_init_wakeup(dev, 1); + device_set_wakeup_enable(dev, 0); return 0; err_out_unregister_netdev: unregister_netdev(ndev); err_out_dma_unmap: - if (!use_iram_for_net(&pldat->pdev->dev) || - pldat->dma_buff_size > lpc32xx_return_iram_size()) - dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, + if (!use_iram_for_net(dev) || + pldat->dma_buff_size > lpc32xx_return_iram(NULL, NULL)) + dma_free_coherent(dev, pldat->dma_buff_size, pldat->dma_buff_base_v, pldat->dma_buff_base_p); err_out_free_irq: @@ -1466,7 +1422,7 @@ unregister_netdev(ndev); if (!use_iram_for_net(&pldat->pdev->dev) || - pldat->dma_buff_size > lpc32xx_return_iram_size()) + pldat->dma_buff_size > lpc32xx_return_iram(NULL, NULL)) dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, pldat->dma_buff_base_v, pldat->dma_buff_base_p); @@ -1512,6 +1468,7 @@ { struct net_device *ndev = platform_get_drvdata(pdev); struct netdata_local *pldat; + int ret; if (device_may_wakeup(&pdev->dev)) disable_irq_wake(ndev->irq); @@ -1521,7 +1478,9 @@ pldat = netdev_priv(ndev); /* Enable interface clock */ - clk_enable(pldat->clk); + ret = clk_enable(pldat->clk); + if (ret) + return ret; /* Reset and initialize */ __lpc_eth_reset(pldat); @@ -1535,13 +1494,11 @@ } #endif -#ifdef CONFIG_OF static const struct of_device_id lpc_eth_match[] = { { .compatible = "nxp,lpc-eth" }, { } }; MODULE_DEVICE_TABLE(of, lpc_eth_match); -#endif static struct platform_driver lpc_eth_driver = { .probe = lpc_eth_drv_probe, @@ -1552,7 +1509,7 @@ #endif .driver = { .name = MODNAME, - .of_match_table = of_match_ptr(lpc_eth_match), + .of_match_table = lpc_eth_match, }, }; -- Gitblit v1.6.2