Skip to content

Commit ffe8a49

Browse files
danish-tikuba-moo
authored andcommitted
net: ti: icssg-prueth: Read firmware-names from device tree
Refactor the way firmware names are handled for the ICSSG PRUETH driver. Instead of using hardcoded firmware name arrays for different modes (EMAC, SWITCH, HSR), the driver now reads the firmware names from the device tree property "firmware-name". Only the EMAC firmware names are specified in the device tree property. The firmware names for all other supported modes are generated dynamically based on the EMAC firmware names by replacing substrings (e.g., "eth" with "sw" or "hsr") as appropriate. Example: Below are the firmwares used currently for PRU0 core EMAC: ti-pruss/am65x-sr2-pru0-prueth-fw.elf SW : ti-pruss/am65x-sr2-pru0-prusw-fw.elf HSR : ti-pruss/am65x-sr2-pru0-pruhsr-fw.elf All three firmware names are same except for the operating mode. In general for PRU0 core, firmware name is, ti-pruss/am65x-sr2-pru0-pru<mode>-fw.elf Since the EMAC firmware names are defined in DT, driver will read those directly and for other modes swap the mode name. i.e. eth -> sw or eth -> hsr. This preserves backwards compatibility as ICSSG driver is supported only by AM65x and AM64x. Both of these have "firmware-name" property populated in their device tree. Signed-off-by: MD Danish Anwar <danishanwar@ti.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20250613064547.44394-1-danishanwar@ti.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent c969149 commit ffe8a49

File tree

2 files changed

+102
-45
lines changed

2 files changed

+102
-45
lines changed

drivers/net/ethernet/ti/icssg/icssg_prueth.c

Lines changed: 93 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -125,45 +125,6 @@ static irqreturn_t prueth_tx_ts_irq(int irq, void *dev_id)
125125
return IRQ_HANDLED;
126126
}
127127

128-
static struct icssg_firmwares icssg_hsr_firmwares[] = {
129-
{
130-
.pru = "ti-pruss/am65x-sr2-pru0-pruhsr-fw.elf",
131-
.rtu = "ti-pruss/am65x-sr2-rtu0-pruhsr-fw.elf",
132-
.txpru = "ti-pruss/am65x-sr2-txpru0-pruhsr-fw.elf",
133-
},
134-
{
135-
.pru = "ti-pruss/am65x-sr2-pru1-pruhsr-fw.elf",
136-
.rtu = "ti-pruss/am65x-sr2-rtu1-pruhsr-fw.elf",
137-
.txpru = "ti-pruss/am65x-sr2-txpru1-pruhsr-fw.elf",
138-
}
139-
};
140-
141-
static struct icssg_firmwares icssg_switch_firmwares[] = {
142-
{
143-
.pru = "ti-pruss/am65x-sr2-pru0-prusw-fw.elf",
144-
.rtu = "ti-pruss/am65x-sr2-rtu0-prusw-fw.elf",
145-
.txpru = "ti-pruss/am65x-sr2-txpru0-prusw-fw.elf",
146-
},
147-
{
148-
.pru = "ti-pruss/am65x-sr2-pru1-prusw-fw.elf",
149-
.rtu = "ti-pruss/am65x-sr2-rtu1-prusw-fw.elf",
150-
.txpru = "ti-pruss/am65x-sr2-txpru1-prusw-fw.elf",
151-
}
152-
};
153-
154-
static struct icssg_firmwares icssg_emac_firmwares[] = {
155-
{
156-
.pru = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
157-
.rtu = "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
158-
.txpru = "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
159-
},
160-
{
161-
.pru = "ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
162-
.rtu = "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
163-
.txpru = "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
164-
}
165-
};
166-
167128
static int prueth_start(struct rproc *rproc, const char *fw_name)
168129
{
169130
int ret;
@@ -186,11 +147,11 @@ static int prueth_emac_start(struct prueth *prueth)
186147
int ret, slice;
187148

188149
if (prueth->is_switch_mode)
189-
firmwares = icssg_switch_firmwares;
150+
firmwares = prueth->icssg_switch_firmwares;
190151
else if (prueth->is_hsr_offload_mode)
191-
firmwares = icssg_hsr_firmwares;
152+
firmwares = prueth->icssg_hsr_firmwares;
192153
else
193-
firmwares = icssg_emac_firmwares;
154+
firmwares = prueth->icssg_emac_firmwares;
194155

195156
for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
196157
ret = prueth_start(prueth->pru[slice], firmwares[slice].pru);
@@ -1632,6 +1593,87 @@ static void prueth_unregister_notifiers(struct prueth *prueth)
16321593
unregister_netdevice_notifier(&prueth->prueth_netdevice_nb);
16331594
}
16341595

1596+
static void icssg_read_firmware_names(struct device_node *np,
1597+
struct icssg_firmwares *fw)
1598+
{
1599+
int i;
1600+
1601+
for (i = 0; i < PRUETH_NUM_MACS; i++) {
1602+
of_property_read_string_index(np, "firmware-name", i * 3 + 0,
1603+
&fw[i].pru);
1604+
of_property_read_string_index(np, "firmware-name", i * 3 + 1,
1605+
&fw[i].rtu);
1606+
of_property_read_string_index(np, "firmware-name", i * 3 + 2,
1607+
&fw[i].txpru);
1608+
}
1609+
}
1610+
1611+
/* icssg_firmware_name_replace - Replace a substring in firmware name
1612+
* @dev: device pointer for memory allocation
1613+
* @src: source firmware name string
1614+
* @from: substring to replace
1615+
* @to: replacement substring
1616+
*
1617+
* Return: a newly allocated string with the replacement, or the original
1618+
* string if replacement is not possible.
1619+
*/
1620+
static const char *icssg_firmware_name_replace(struct device *dev,
1621+
const char *src,
1622+
const char *from,
1623+
const char *to)
1624+
{
1625+
size_t prefix, from_len, to_len, total;
1626+
const char *p = strstr(src, from);
1627+
char *buf;
1628+
1629+
if (!p)
1630+
return src; /* fallback: no replacement, use original */
1631+
1632+
prefix = p - src;
1633+
from_len = strlen(from);
1634+
to_len = strlen(to);
1635+
total = strlen(src) - from_len + to_len + 1;
1636+
1637+
buf = devm_kzalloc(dev, total, GFP_KERNEL);
1638+
if (!buf)
1639+
return src; /* fallback: allocation failed, use original */
1640+
1641+
strscpy(buf, src, prefix + 1);
1642+
strscpy(buf + prefix, to, to_len + 1);
1643+
strscpy(buf + prefix + to_len, p + from_len, total - prefix - to_len);
1644+
1645+
return buf;
1646+
}
1647+
1648+
/**
1649+
* icssg_mode_firmware_names - Generate firmware names for a specific mode
1650+
* @dev: device pointer for logging and context
1651+
* @src: source array of firmware name structures
1652+
* @dst: destination array to store updated firmware name structures
1653+
* @from: substring in firmware names to be replaced
1654+
* @to: substring to replace @from in firmware names
1655+
*
1656+
* Iterates over all MACs and replaces occurrences of the @from substring
1657+
* with @to in the firmware names (pru, rtu, txpru) for each MAC. The
1658+
* updated firmware names are stored in the @dst array.
1659+
*/
1660+
static void icssg_mode_firmware_names(struct device *dev,
1661+
struct icssg_firmwares *src,
1662+
struct icssg_firmwares *dst,
1663+
const char *from, const char *to)
1664+
{
1665+
int i;
1666+
1667+
for (i = 0; i < PRUETH_NUM_MACS; i++) {
1668+
dst[i].pru = icssg_firmware_name_replace(dev, src[i].pru,
1669+
from, to);
1670+
dst[i].rtu = icssg_firmware_name_replace(dev, src[i].rtu,
1671+
from, to);
1672+
dst[i].txpru = icssg_firmware_name_replace(dev, src[i].txpru,
1673+
from, to);
1674+
}
1675+
}
1676+
16351677
static int prueth_probe(struct platform_device *pdev)
16361678
{
16371679
struct device_node *eth_node, *eth_ports_node;
@@ -1808,6 +1850,15 @@ static int prueth_probe(struct platform_device *pdev)
18081850
icss_iep_init_fw(prueth->iep1);
18091851
}
18101852

1853+
/* Read EMAC firmware names from device tree */
1854+
icssg_read_firmware_names(np, prueth->icssg_emac_firmwares);
1855+
1856+
/* Generate other mode firmware names based on EMAC firmware names */
1857+
icssg_mode_firmware_names(dev, prueth->icssg_emac_firmwares,
1858+
prueth->icssg_switch_firmwares, "eth", "sw");
1859+
icssg_mode_firmware_names(dev, prueth->icssg_emac_firmwares,
1860+
prueth->icssg_hsr_firmwares, "eth", "hsr");
1861+
18111862
spin_lock_init(&prueth->vtbl_lock);
18121863
spin_lock_init(&prueth->stats_lock);
18131864
/* setup netdev interfaces */

drivers/net/ethernet/ti/icssg/icssg_prueth.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,9 @@ struct prueth_pdata {
259259
};
260260

261261
struct icssg_firmwares {
262-
char *pru;
263-
char *rtu;
264-
char *txpru;
262+
const char *pru;
263+
const char *rtu;
264+
const char *txpru;
265265
};
266266

267267
/**
@@ -300,6 +300,9 @@ struct icssg_firmwares {
300300
* @is_switchmode_supported: indicates platform support for switch mode
301301
* @switch_id: ID for mapping switch ports to bridge
302302
* @default_vlan: Default VLAN for host
303+
* @icssg_emac_firmwares: Firmware names for EMAC mode, indexed per MAC
304+
* @icssg_switch_firmwares: Firmware names for SWITCH mode, indexed per MAC
305+
* @icssg_hsr_firmwares: Firmware names for HSR mode, indexed per MAC
303306
*/
304307
struct prueth {
305308
struct device *dev;
@@ -343,6 +346,9 @@ struct prueth {
343346
spinlock_t vtbl_lock;
344347
/** @stats_lock: Lock for reading icssg stats */
345348
spinlock_t stats_lock;
349+
struct icssg_firmwares icssg_emac_firmwares[PRUETH_NUM_MACS];
350+
struct icssg_firmwares icssg_switch_firmwares[PRUETH_NUM_MACS];
351+
struct icssg_firmwares icssg_hsr_firmwares[PRUETH_NUM_MACS];
346352
};
347353

348354
struct emac_tx_ts_response {

0 commit comments

Comments
 (0)