summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/phy/micrel_ksz90x1.c12
-rw-r--r--drivers/net/sh_eth.c183
-rw-r--r--drivers/net/sh_eth.h28
-rw-r--r--drivers/net/ti/icssg_prueth.c54
-rw-r--r--drivers/net/ti/icssg_prueth.h7
5 files changed, 127 insertions, 157 deletions
diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c
index ee8eae1efd9..a02dbe900b8 100644
--- a/drivers/net/phy/micrel_ksz90x1.c
+++ b/drivers/net/phy/micrel_ksz90x1.c
@@ -7,6 +7,7 @@
* (C) 2012 NetModule AG, David Andrey, added KSZ9031
* (C) Copyright 2017 Adaptrum, Inc.
* Written by Alexandru Gagniuc <alex.g@adaptrum.com> for Adaptrum, Inc.
+ * Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include <dm.h>
#include <env.h>
@@ -110,6 +111,7 @@ static int ksz90x1_of_config_group(struct phy_device *phydev,
{
struct udevice *dev = phydev->dev;
struct phy_driver *drv = phydev->drv;
+ struct ofnode_phandle_args phandle;
int val[4];
int i, changed = 0, offset, max;
u16 regval = 0;
@@ -126,8 +128,14 @@ static int ksz90x1_of_config_group(struct phy_device *phydev,
}
if (!ofnode_valid(node)) {
- /* No node found, look in the Ethernet node */
- node = dev_ofnode(dev);
+ if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
+ &phandle)) {
+ /* No phy-handle found, look in the Ethernet node */
+ node = dev_ofnode(dev);
+ } else {
+ /* phy-handle found */
+ node = phandle.node;
+ }
}
for (i = 0; i < ofcfg->grpsz; i++) {
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index f695a3a41d2..1160c1d6cfa 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -29,45 +29,30 @@
#include "sh_eth.h"
-#ifndef CFG_SH_ETHER_USE_PORT
-# error "Please define CFG_SH_ETHER_USE_PORT"
-#endif
-#ifndef CFG_SH_ETHER_PHY_ADDR
-# error "Please define CFG_SH_ETHER_PHY_ADDR"
-#endif
+static void flush_cache_wback(void *addr, unsigned long len)
+{
+ flush_dcache_range((unsigned long)addr,
+ (unsigned long)(addr + ALIGN(len, SH_ETHER_ALIGN_SIZE)));
+}
-#if defined(CFG_SH_ETHER_CACHE_WRITEBACK) && \
- !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
-#define flush_cache_wback(addr, len) \
- flush_dcache_range((unsigned long)addr, \
- (unsigned long)(addr + ALIGN(len, CFG_SH_ETHER_ALIGNE_SIZE)))
-#else
-#define flush_cache_wback(...)
-#endif
+static void invalidate_cache(void *addr, unsigned long len)
+{
+ unsigned long line_size = SH_ETHER_ALIGN_SIZE;
+ unsigned long start, end;
-#if defined(CFG_SH_ETHER_CACHE_INVALIDATE) && defined(CONFIG_ARM)
-#define invalidate_cache(addr, len) \
- { \
- unsigned long line_size = CFG_SH_ETHER_ALIGNE_SIZE; \
- unsigned long start, end; \
- \
- start = (unsigned long)addr; \
- end = start + len; \
- start &= ~(line_size - 1); \
- end = ((end + line_size - 1) & ~(line_size - 1)); \
- \
- invalidate_dcache_range(start, end); \
- }
-#else
-#define invalidate_cache(...)
-#endif
+ start = (unsigned long)addr;
+ end = start + len;
+ start &= ~(line_size - 1);
+ end = (end + line_size - 1) & ~(line_size - 1);
+
+ invalidate_dcache_range(start, end);
+}
#define TIMEOUT_CNT 1000
-static int sh_eth_send_common(struct sh_eth_dev *eth, void *packet, int len)
+static int sh_eth_send_common(struct sh_eth_info *port_info, void *packet, int len)
{
int ret = 0, timeout;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
if (!packet || len > 0xffff) {
printf(SHETHER_NAME ": %s: Invalid argument\n", __func__);
@@ -121,10 +106,8 @@ err:
return ret;
}
-static int sh_eth_recv_start(struct sh_eth_dev *eth)
+static int sh_eth_recv_start(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
/* Check if the rx descriptor is ready */
invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s));
if (port_info->rx_desc_cur->rd0 & RD_RACT)
@@ -137,11 +120,9 @@ static int sh_eth_recv_start(struct sh_eth_dev *eth)
return port_info->rx_desc_cur->rd1 & 0xffff;
}
-static void sh_eth_recv_finish(struct sh_eth_dev *eth)
+static void sh_eth_recv_finish(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
- invalidate_cache(ADDR_TO_P2(port_info->rx_desc_cur->rd2), MAX_BUF_SIZE);
+ invalidate_cache((void *)ADDR_TO_P2((uintptr_t)port_info->rx_desc_cur->rd2), MAX_BUF_SIZE);
/* Make current descriptor available again */
if (port_info->rx_desc_cur->rd0 & RD_RDLE)
@@ -159,9 +140,8 @@ static void sh_eth_recv_finish(struct sh_eth_dev *eth)
port_info->rx_desc_cur = port_info->rx_desc_base;
}
-static int sh_eth_reset(struct sh_eth_dev *eth)
+static int sh_eth_reset(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
int ret = 0, i;
@@ -192,12 +172,11 @@ static int sh_eth_reset(struct sh_eth_dev *eth)
#endif
}
-static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
+static int sh_eth_tx_desc_init(struct sh_eth_info *port_info)
{
- int i, ret = 0;
u32 alloc_desc_size = NUM_TX_DESC * sizeof(struct tx_desc_s);
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
struct tx_desc_s *cur_tx_desc;
+ int i, ret = 0;
/*
* Allocate rx descriptors. They must be aligned to size of struct
@@ -244,11 +223,10 @@ err:
return ret;
}
-static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
+static int sh_eth_rx_desc_init(struct sh_eth_info *port_info)
{
int i, ret = 0;
u32 alloc_desc_size = NUM_RX_DESC * sizeof(struct rx_desc_s);
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
struct rx_desc_s *cur_rx_desc;
u8 *rx_buf;
@@ -318,20 +296,16 @@ err:
return ret;
}
-static void sh_eth_tx_desc_free(struct sh_eth_dev *eth)
+static void sh_eth_tx_desc_free(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
if (port_info->tx_desc_alloc) {
free(port_info->tx_desc_alloc);
port_info->tx_desc_alloc = NULL;
}
}
-static void sh_eth_rx_desc_free(struct sh_eth_dev *eth)
+static void sh_eth_rx_desc_free(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
if (port_info->rx_desc_alloc) {
free(port_info->rx_desc_alloc);
port_info->rx_desc_alloc = NULL;
@@ -343,21 +317,21 @@ static void sh_eth_rx_desc_free(struct sh_eth_dev *eth)
}
}
-static int sh_eth_desc_init(struct sh_eth_dev *eth)
+static int sh_eth_desc_init(struct sh_eth_info *port_info)
{
int ret = 0;
- ret = sh_eth_tx_desc_init(eth);
+ ret = sh_eth_tx_desc_init(port_info);
if (ret)
goto err_tx_init;
- ret = sh_eth_rx_desc_init(eth);
+ ret = sh_eth_rx_desc_init(port_info);
if (ret)
goto err_rx_init;
return ret;
err_rx_init:
- sh_eth_tx_desc_free(eth);
+ sh_eth_tx_desc_free(port_info);
err_tx_init:
return ret;
@@ -375,9 +349,8 @@ static void sh_eth_write_hwaddr(struct sh_eth_info *port_info,
sh_eth_write(port_info, val, MALR);
}
-static void sh_eth_mac_regs_config(struct sh_eth_dev *eth, unsigned char *mac)
+static void sh_eth_mac_regs_config(struct sh_eth_info *port_info, unsigned char *mac)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
unsigned long edmr;
/* Configure e-dmac registers */
@@ -422,9 +395,8 @@ static void sh_eth_mac_regs_config(struct sh_eth_dev *eth, unsigned char *mac)
#endif
}
-static int sh_eth_phy_regs_config(struct sh_eth_dev *eth)
+static int sh_eth_phy_regs_config(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
struct phy_device *phy = port_info->phydev;
int ret = 0;
u32 val = 0;
@@ -470,10 +442,8 @@ static int sh_eth_phy_regs_config(struct sh_eth_dev *eth)
return ret;
}
-static void sh_eth_start(struct sh_eth_dev *eth)
+static void sh_eth_start(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
/*
* Enable the e-dmac receiver only. The transmitter will be enabled when
* we have something to transmit
@@ -481,33 +451,30 @@ static void sh_eth_start(struct sh_eth_dev *eth)
sh_eth_write(port_info, EDRRR_R, EDRRR);
}
-static void sh_eth_stop(struct sh_eth_dev *eth)
+static void sh_eth_stop(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
sh_eth_write(port_info, ~EDRRR_R, EDRRR);
}
-static int sh_eth_init_common(struct sh_eth_dev *eth, unsigned char *mac)
+static int sh_eth_init_common(struct sh_eth_info *port_info, unsigned char *mac)
{
int ret = 0;
- ret = sh_eth_reset(eth);
+ ret = sh_eth_reset(port_info);
if (ret)
return ret;
- ret = sh_eth_desc_init(eth);
+ ret = sh_eth_desc_init(port_info);
if (ret)
return ret;
- sh_eth_mac_regs_config(eth, mac);
+ sh_eth_mac_regs_config(port_info, mac);
return 0;
}
-static int sh_eth_start_common(struct sh_eth_dev *eth)
+static int sh_eth_start_common(struct sh_eth_info *port_info)
{
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
int ret;
ret = phy_startup(port_info->phydev);
@@ -516,17 +483,17 @@ static int sh_eth_start_common(struct sh_eth_dev *eth)
return ret;
}
- ret = sh_eth_phy_regs_config(eth);
+ ret = sh_eth_phy_regs_config(port_info);
if (ret)
return ret;
- sh_eth_start(eth);
+ sh_eth_start(port_info);
return 0;
}
struct sh_ether_priv {
- struct sh_eth_dev shdev;
+ struct sh_eth_info port_info;
struct mii_dev *bus;
phys_addr_t iobase;
@@ -536,20 +503,19 @@ struct sh_ether_priv {
static int sh_ether_send(struct udevice *dev, void *packet, int len)
{
struct sh_ether_priv *priv = dev_get_priv(dev);
- struct sh_eth_dev *eth = &priv->shdev;
+ struct sh_eth_info *port_info = &priv->port_info;
- return sh_eth_send_common(eth, packet, len);
+ return sh_eth_send_common(port_info, packet, len);
}
static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct sh_ether_priv *priv = dev_get_priv(dev);
- struct sh_eth_dev *eth = &priv->shdev;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = &priv->port_info;
uchar *packet = (uchar *)ADDR_TO_P2((uintptr_t)port_info->rx_desc_cur->rd2);
int len;
- len = sh_eth_recv_start(eth);
+ len = sh_eth_recv_start(port_info);
if (len > 0) {
invalidate_cache(packet, len);
*packetp = packet;
@@ -567,10 +533,9 @@ static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp)
static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
{
struct sh_ether_priv *priv = dev_get_priv(dev);
- struct sh_eth_dev *eth = &priv->shdev;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = &priv->port_info;
- sh_eth_recv_finish(eth);
+ sh_eth_recv_finish(port_info);
/* Restart the receiver if disabled */
if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
@@ -582,8 +547,7 @@ static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
static int sh_ether_write_hwaddr(struct udevice *dev)
{
struct sh_ether_priv *priv = dev_get_priv(dev);
- struct sh_eth_dev *eth = &priv->shdev;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = &priv->port_info;
struct eth_pdata *pdata = dev_get_plat(dev);
sh_eth_write_hwaddr(port_info, pdata->enetaddr);
@@ -595,10 +559,9 @@ static int sh_eth_phy_config(struct udevice *dev)
{
struct sh_ether_priv *priv = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_plat(dev);
- struct sh_eth_dev *eth = &priv->shdev;
- int ret = 0;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = &priv->port_info;
struct phy_device *phydev;
+ int ret = 0;
phydev = phy_connect(priv->bus, -1, dev, pdata->phy_interface);
if (!phydev)
@@ -614,40 +577,38 @@ static int sh_ether_start(struct udevice *dev)
{
struct sh_ether_priv *priv = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_plat(dev);
- struct sh_eth_dev *eth = &priv->shdev;
+ struct sh_eth_info *port_info = &priv->port_info;
int ret;
- ret = sh_eth_init_common(eth, pdata->enetaddr);
+ ret = sh_eth_init_common(port_info, pdata->enetaddr);
if (ret)
return ret;
- ret = sh_eth_start_common(eth);
+ ret = sh_eth_start_common(port_info);
if (ret)
goto err_start;
return 0;
err_start:
- sh_eth_tx_desc_free(eth);
- sh_eth_rx_desc_free(eth);
+ sh_eth_tx_desc_free(port_info);
+ sh_eth_rx_desc_free(port_info);
return ret;
}
static void sh_ether_stop(struct udevice *dev)
{
struct sh_ether_priv *priv = dev_get_priv(dev);
- struct sh_eth_dev *eth = &priv->shdev;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = &priv->port_info;
phy_shutdown(port_info->phydev);
- sh_eth_stop(&priv->shdev);
+ sh_eth_stop(port_info);
}
/******* for bb_miiphy *******/
static int sh_eth_bb_mdio_active(struct mii_dev *miidev)
{
- struct sh_eth_dev *eth = miidev->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = miidev->priv;
sh_eth_write(port_info, sh_eth_read(port_info, PIR) | PIR_MMD, PIR);
@@ -656,8 +617,7 @@ static int sh_eth_bb_mdio_active(struct mii_dev *miidev)
static int sh_eth_bb_mdio_tristate(struct mii_dev *miidev)
{
- struct sh_eth_dev *eth = miidev->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = miidev->priv;
sh_eth_write(port_info, sh_eth_read(port_info, PIR) & ~PIR_MMD, PIR);
@@ -666,8 +626,7 @@ static int sh_eth_bb_mdio_tristate(struct mii_dev *miidev)
static int sh_eth_bb_set_mdio(struct mii_dev *miidev, int v)
{
- struct sh_eth_dev *eth = miidev->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = miidev->priv;
if (v)
sh_eth_write(port_info,
@@ -681,8 +640,7 @@ static int sh_eth_bb_set_mdio(struct mii_dev *miidev, int v)
static int sh_eth_bb_get_mdio(struct mii_dev *miidev, int *v)
{
- struct sh_eth_dev *eth = miidev->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = miidev->priv;
*v = (sh_eth_read(port_info, PIR) & PIR_MDI) >> 3;
@@ -691,8 +649,7 @@ static int sh_eth_bb_get_mdio(struct mii_dev *miidev, int *v)
static int sh_eth_bb_set_mdc(struct mii_dev *miidev, int v)
{
- struct sh_eth_dev *eth = miidev->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = miidev->priv;
if (v)
sh_eth_write(port_info,
@@ -738,7 +695,7 @@ static int sh_ether_probe(struct udevice *udev)
{
struct eth_pdata *pdata = dev_get_plat(udev);
struct sh_ether_priv *priv = dev_get_priv(udev);
- struct sh_eth_dev *eth = &priv->shdev;
+ struct sh_eth_info *port_info = &priv->port_info;
struct mii_dev *mdiodev;
int ret;
@@ -757,7 +714,7 @@ static int sh_ether_probe(struct udevice *udev)
mdiodev->read = sh_eth_bb_miiphy_read;
mdiodev->write = sh_eth_bb_miiphy_write;
- mdiodev->priv = eth;
+ mdiodev->priv = port_info;
snprintf(mdiodev->name, sizeof(mdiodev->name), udev->name);
ret = mdio_register(mdiodev);
@@ -766,10 +723,7 @@ static int sh_ether_probe(struct udevice *udev)
priv->bus = mdiodev;
- eth->port = CFG_SH_ETHER_USE_PORT;
- eth->port_info[eth->port].phy_addr = CFG_SH_ETHER_PHY_ADDR;
- eth->port_info[eth->port].iobase =
- (void __iomem *)(uintptr_t)(BASE_IO_ADDR + 0x800 * eth->port);
+ port_info->iobase = (void __iomem *)(uintptr_t)BASE_IO_ADDR;
#if CONFIG_IS_ENABLED(CLK)
ret = clk_enable(&priv->clk);
@@ -777,7 +731,7 @@ static int sh_ether_probe(struct udevice *udev)
goto err_mdio_register;
#endif
- ret = sh_eth_init_common(eth, pdata->enetaddr);
+ ret = sh_eth_init_common(port_info, pdata->enetaddr);
if (ret)
goto err_phy_config;
@@ -801,8 +755,7 @@ err_mdio_register:
static int sh_ether_remove(struct udevice *udev)
{
struct sh_ether_priv *priv = dev_get_priv(udev);
- struct sh_eth_dev *eth = &priv->shdev;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
+ struct sh_eth_info *port_info = &priv->port_info;
#if CONFIG_IS_ENABLED(CLK)
clk_disable(&priv->clk);
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index ecf4a697e27..c395e6e8fc7 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -19,23 +19,17 @@
/* The ethernet controller needs to use physical addresses */
#define ADDR_TO_PHY(addr) ((uintptr_t)(addr) & ~0xe0000000)
+#define SH_ETHER_ALIGN_SIZE 16
#elif defined(CONFIG_ARM)
#ifndef inl
#define inl readl
#define outl writel
+#define SH_ETHER_ALIGN_SIZE 64
#endif
#define ADDR_TO_PHY(addr) ((uintptr_t)(addr))
#define ADDR_TO_P2(addr) (addr)
#endif /* defined(CONFIG_SH) */
-/* base padding size is 16 */
-#ifndef CFG_SH_ETHER_ALIGNE_SIZE
-#define CFG_SH_ETHER_ALIGNE_SIZE 16
-#endif
-
-/* Number of supported ports */
-#define MAX_PORT_NUM 2
-
/* Buffers must be big enough to hold the largest ethernet frame. Also, rx
buffers must be a multiple of 32 bytes */
#define MAX_BUF_SIZE (48 * 32)
@@ -47,7 +41,7 @@
/* The size of the tx descriptor is determined by how much padding is used.
4, 20, or 52 bytes of padding can be used */
-#define TX_DESC_PADDING (CFG_SH_ETHER_ALIGNE_SIZE - 12)
+#define TX_DESC_PADDING (SH_ETHER_ALIGN_SIZE - 12)
/* Tx descriptor. We always use 3 bytes of padding */
struct tx_desc_s {
@@ -62,9 +56,9 @@ struct tx_desc_s {
/* The size of the rx descriptor is determined by how much padding is used.
4, 20, or 52 bytes of padding can be used */
-#define RX_DESC_PADDING (CFG_SH_ETHER_ALIGNE_SIZE - 12)
+#define RX_DESC_PADDING (SH_ETHER_ALIGN_SIZE - 12)
/* aligned cache line size */
-#define RX_BUF_ALIGNE_SIZE (CFG_SH_ETHER_ALIGNE_SIZE > 32 ? 64 : 32)
+#define RX_BUF_ALIGNE_SIZE (SH_ETHER_ALIGN_SIZE > 32 ? 64 : 32)
/* Rx descriptor. We always use 4 bytes of padding */
struct rx_desc_s {
@@ -84,17 +78,11 @@ struct sh_eth_info {
u8 *rx_buf_alloc;
u8 *rx_buf_base;
u8 mac_addr[6];
- u8 phy_addr;
struct eth_device *dev;
struct phy_device *phydev;
void __iomem *iobase;
};
-struct sh_eth_dev {
- int port;
- struct sh_eth_info port_info[MAX_PORT_NUM];
-};
-
/* from linux/drivers/net/ethernet/renesas/sh_eth.h */
enum {
/* E-DMAC registers */
@@ -388,11 +376,11 @@ enum DMAC_M_BIT {
#endif
};
-#if CFG_SH_ETHER_ALIGNE_SIZE == 64
+#if SH_ETHER_ALIGN_SIZE == 64
# define EMDR_DESC EDMR_DL1
-#elif CFG_SH_ETHER_ALIGNE_SIZE == 32
+#elif SH_ETHER_ALIGN_SIZE == 32
# define EMDR_DESC EDMR_DL0
-#elif CFG_SH_ETHER_ALIGNE_SIZE == 16 /* Default */
+#elif SH_ETHER_ALIGN_SIZE == 16 /* Default */
# define EMDR_DESC 0
#endif
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 2639f960631..d8df3c9afb0 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -63,6 +63,7 @@
/* Number of PRU Cores per Slice */
#define ICSSG_NUM_PRU_CORES 3
+#define ICSSG_NUM_FIRMWARES 6
static int icssg_gmii_select(struct prueth_priv *priv)
{
@@ -192,25 +193,6 @@ static int icssg_update_link(struct prueth_priv *priv)
return phy->link;
}
-struct icssg_firmwares {
- char *pru;
- char *rtu;
- char *txpru;
-};
-
-static struct icssg_firmwares icssg_emac_firmwares[] = {
- {
- .pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
- .rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
- .txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
- },
- {
- .pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
- .rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
- .txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
- }
-};
-
static int icssg_start_pru_cores(struct udevice *dev)
{
struct prueth_priv *priv = dev_get_priv(dev);
@@ -223,7 +205,7 @@ static int icssg_start_pru_cores(struct udevice *dev)
slice = priv->port_id;
index = slice * ICSSG_NUM_PRU_CORES;
- firmwares = icssg_emac_firmwares;
+ firmwares = prueth->firmwares;
ofnode_read_u32_index(dev_ofnode(prueth->dev), "ti,prus", index, &phandle);
ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle, &rproc_dev);
@@ -476,6 +458,24 @@ static const struct eth_ops prueth_ops = {
.stop = prueth_stop,
};
+static char *prepend_fw_path(const char *fw_name)
+{
+ static const char fw_dir[] = "/lib/firmware/";
+ char *result;
+ int len;
+
+ if (!fw_name)
+ return NULL;
+
+ len = strlen(fw_dir) + strlen(fw_name) + 1;
+ result = malloc(len);
+ if (!result)
+ return NULL;
+
+ sprintf(result, "%s%s", fw_dir, fw_name);
+ return result;
+}
+
static int icssg_ofdata_parse_phy(struct udevice *dev)
{
struct prueth_priv *priv = dev_get_priv(dev);
@@ -534,6 +534,8 @@ static int prueth_probe(struct udevice *dev)
struct udevice **prussdev = NULL;
ofnode eth_ports_node, eth_node;
struct udevice *port_dev;
+ const char **fw_names;
+ int fw_count, i;
int ret = 0;
prueth->dev = dev;
@@ -659,6 +661,18 @@ static int prueth_probe(struct udevice *dev)
}
}
+ /* Parse firmware-name property from DT */
+ fw_count = dev_read_string_list(dev, "firmware-name", &fw_names);
+ if (fw_count != ICSSG_NUM_FIRMWARES) {
+ dev_err(dev, "Expected %d firmware names, got %d\n", ICSSG_NUM_FIRMWARES, fw_count);
+ return -EINVAL;
+ }
+ for (i = 0; i < 2; i++) {
+ prueth->firmwares[i].pru = prepend_fw_path(fw_names[i * 3 + 0]);
+ prueth->firmwares[i].rtu = prepend_fw_path(fw_names[i * 3 + 1]);
+ prueth->firmwares[i].txpru = prepend_fw_path(fw_names[i * 3 + 2]);
+ }
+
return 0;
out:
clk_disable(&prueth->mdiofck);
diff --git a/drivers/net/ti/icssg_prueth.h b/drivers/net/ti/icssg_prueth.h
index c69cfd4f162..d88b6fa88e7 100644
--- a/drivers/net/ti/icssg_prueth.h
+++ b/drivers/net/ti/icssg_prueth.h
@@ -38,6 +38,12 @@ enum prueth_port {
PRUETH_PORT_MII1, /* physical port MII 1 */
};
+struct icssg_firmwares {
+ char *pru;
+ char *rtu;
+ char *txpru;
+};
+
struct prueth {
struct udevice *dev;
struct udevice *pruss;
@@ -66,6 +72,7 @@ struct prueth {
u8 rtu_core_id;
u8 txpru_core_id;
u8 icssg_hwcmdseq;
+ struct icssg_firmwares firmwares[PRUETH_NUM_MACS];
};
struct prueth_priv {