* [PATCH net-next 0/3] Rework GENET MDIO controller clocking
@ 2024-02-16 18:42 Florian Fainelli
2024-02-16 18:42 ` [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses Florian Fainelli
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Florian Fainelli @ 2024-02-16 18:42 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Doug Berger,
Broadcom internal kernel review list, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
Heiner Kallweit, Russell King, open list, Justin Chen
This patch series reworks the way that we manage the GENET MDIO
controller clocks around I/O accesses. During testing with a fully
modular build where bcmgenet, mdio-bcm-unimac, and the Broadcom PHY
driver (broadcom) are all loaded as modules, with no particular care
being taken to order them to mimize deferred probing the following bus
error was obtained:
[ 4.344831] printk: console [ttyS0] enabled
[ 4.351102] 840d000.serial: ttyS1 at MMIO 0x840d000 (irq = 29, base_baud = 5062500) is a Broadcom BCM7271 UART
[ 4.363110] 840e000.serial: ttyS2 at MMIO 0x840e000 (irq = 30, base_baud = 5062500) is a Broadcom BCM7271 UART
[ 4.387392] iproc-rng200 8402000.rng: hwrng registered
[ 4.398012] Consider using thermal netlink events interface
[ 4.403717] brcmstb_thermal a581500.thermal: registered AVS TMON of-sensor driver
[ 4.440085] bcmgenet 8f00000.ethernet: GENET 5.0 EPHY: 0x0000
[ 4.482526] unimac-mdio unimac-mdio.0: Broadcom UniMAC MDIO bus
[ 4.514019] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[ 4.551304] SError Interrupt on CPU2, code 0x00000000bf000002 -- SError
[ 4.551324] CPU: 2 PID: 8 Comm: kworker/u8:0 Not tainted 6.1.53-0.1pre-g5a26d98e908c #2
[ 4.551330] Hardware name: BCM972180HB_V20 (DT)
[ 4.551336] Workqueue: events_unbound deferred_probe_work_func
[ 4.551363] pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 4.551368] pc : el1_abort+0x2c/0x58
[ 4.551376] lr : el1_abort+0x20/0x58
[ 4.551379] sp : ffffffc00a383960
[ 4.551380] x29: ffffffc00a383960 x28: ffffff80029fd780 x27: 0000000000000000
[ 4.551385] x26: 0000000000000000 x25: ffffff8002839005 x24: ffffffc00a1f9bd0
[ 4.551390] x23: 0000000040000005 x22: ffffffc000a48084 x21: ffffffc00a3dde14
[ 4.551394] x20: 0000000096000210 x19: ffffffc00a3839a0 x18: 0000000000000579
[ 4.551399] x17: 0000000000000000 x16: 0000000100000000 x15: ffffffc00a3838c0
[ 4.551403] x14: 000000000000000a x13: 6e69622f7273752f x12: 3a6e6962732f7273
[ 4.551408] x11: 752f3a6e69622f3a x10: 6e6962732f3d4854 x9 : ffffffc0086466a8
[ 4.551412] x8 : ffffff80049ee100 x7 : ffffff8003231938 x6 : 0000000000000000
[ 4.551416] x5 : 0000002200000000 x4 : ffffffc00a3839a0 x3 : 0000002000000000
[ 4.551420] x2 : 0000000000000025 x1 : 0000000096000210 x0 : 0000000000000000
[ 4.551429] Kernel panic - not syncing: Asynchronous SError Interrupt
[ 4.551432] CPU: 2 PID: 8 Comm: kworker/u8:0 Not tainted 6.1.53-0.1pre-g5a26d98e908c #2
[ 4.551435] Hardware name: BCM972180HB_V20 (DT)
[ 4.551437] Workqueue: events_unbound deferred_probe_work_func
[ 4.551443] Call trace:
[ 4.551445] dump_backtrace+0xe4/0x124
[ 4.551452] show_stack+0x1c/0x28
[ 4.551455] dump_stack_lvl+0x60/0x78
[ 4.551462] dump_stack+0x14/0x2c
[ 4.551467] panic+0x134/0x304
[ 4.551472] nmi_panic+0x50/0x70
[ 4.551480] arm64_serror_panic+0x70/0x7c
[ 4.551484] do_serror+0x2c/0x5c
[ 4.551487] el1h_64_error_handler+0x2c/0x40
[ 4.551491] el1h_64_error+0x64/0x68
[ 4.551496] el1_abort+0x2c/0x58
[ 4.551499] el1h_64_sync_handler+0x8c/0xb4
[ 4.551502] el1h_64_sync+0x64/0x68
[ 4.551505] unimac_mdio_readl.isra.0+0x4/0xc [mdio_bcm_unimac]
[ 4.551519] __mdiobus_read+0x2c/0x88
[ 4.551526] mdiobus_read+0x40/0x60
[ 4.551530] phy_read+0x18/0x20
[ 4.551534] bcm_phy_config_intr+0x20/0x84
[ 4.551537] phy_disable_interrupts+0x2c/0x3c
[ 4.551543] phy_probe+0x80/0x1b0
[ 4.551545] really_probe+0x1b8/0x390
[ 4.551550] __driver_probe_device+0x134/0x14c
[ 4.551554] driver_probe_device+0x40/0xf8
[ 4.551559] __device_attach_driver+0x108/0x11c
[ 4.551563] bus_for_each_drv+0xa4/0xcc
[ 4.551567] __device_attach+0xdc/0x190
[ 4.551571] device_initial_probe+0x18/0x20
[ 4.551575] bus_probe_device+0x34/0x94
[ 4.551579] deferred_probe_work_func+0xd4/0xe8
[ 4.551583] process_one_work+0x1ac/0x25c
[ 4.551590] worker_thread+0x1f4/0x260
[ 4.551595] kthread+0xc0/0xd0
[ 4.551600] ret_from_fork+0x10/0x20
[ 4.551608] SMP: stopping secondary CPUs
[ 4.551617] Kernel Offset: disabled
[ 4.551619] CPU features: 0x00000,00c00080,0000420b
[ 4.551622] Memory Limit: none
[ 4.833838] ---[ end Kernel panic - not syncing: Asynchronous SError Interrupt ]---
The issue here is that we managed to probe the GENET controller, the
mdio-bcm-unimac MDIO controller, but the PHY was still being held in a
probe deferral state because it depended upon a GPIO controller provider
not loaded yet. As soon as that provider is loaded however, the PHY
continues to probe, tries to disable the interrupts, and this causes a
MDIO transaction. That MDIO transaction requires I/O register accesses
within the GENET's larger block, and since its clocks are turned off,
the CPU gets a bus error signaled as a System Error.
The patch series takes the simplest approach of keeping the clocks
enabled just for the duration of the I/O accesses. This is also
beneficial to other drivers like bcmasp2 which make use of the same MDIO
controller driver.
Florian Fainelli (3):
net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses
net: bcmgenet: Pass "main" clock down to the MDIO driver
Revert "net: bcmgenet: Ensure MDIO unregistration has clocks enabled"
drivers/net/ethernet/broadcom/genet/bcmmii.c | 6 +-
drivers/net/mdio/mdio-bcm-unimac.c | 91 ++++++++++---------
include/linux/platform_data/mdio-bcm-unimac.h | 3 +
3 files changed, 55 insertions(+), 45 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses
2024-02-16 18:42 [PATCH net-next 0/3] Rework GENET MDIO controller clocking Florian Fainelli
@ 2024-02-16 18:42 ` Florian Fainelli
2024-02-16 22:37 ` Jacob Keller
2024-02-17 10:43 ` kernel test robot
2024-02-16 18:42 ` [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver Florian Fainelli
2024-02-16 18:42 ` [PATCH net-next 3/3] Revert "net: bcmgenet: Ensure MDIO unregistration has clocks enabled" Florian Fainelli
2 siblings, 2 replies; 11+ messages in thread
From: Florian Fainelli @ 2024-02-16 18:42 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Doug Berger,
Broadcom internal kernel review list, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
Heiner Kallweit, Russell King, open list, Justin Chen
Up until now we have managed not to have the mdio-bcm-unimac manage its
clock except during probe and suspend/resume. This works most of the
time, except where it does not.
With a fully modular build, we can get into a situation whereby the
GENET driver is fully registered, and so is the mdio-bcm-unimac driver,
however the Ethernet PHY driver is not yet, because it depends on a
resource that is not yet available (e.g.: GPIO provider). In that state,
the network device is not usable yet, and so to conserve power, the
GENET driver will have turned off its "main" clock which feeds its MDIO
controller.
When the PHY driver finally probes however, we make an access to the PHY
registers to e.g.: disable interrupts, and this causes a bus error
within the MDIO controller space because the MDIO controller clock(s)
are turned off.
To remedy that, we manage the clock around all of the I/O accesses to
the hardware which are done exclusively during read, write and clock
divider configuration.
This ensures that the register space is accessible, and this also
ensures that there are not unnecessarily elevated reference counts
keeping the clocks active when the network device is administratively
turned off. It would be the case with the previous way of managing the
clock.
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
---
drivers/net/mdio/mdio-bcm-unimac.c | 91 ++++++++++---------
include/linux/platform_data/mdio-bcm-unimac.h | 3 +
2 files changed, 51 insertions(+), 43 deletions(-)
diff --git a/drivers/net/mdio/mdio-bcm-unimac.c b/drivers/net/mdio/mdio-bcm-unimac.c
index 68f8ee0ec8ba..0619e5d596d1 100644
--- a/drivers/net/mdio/mdio-bcm-unimac.c
+++ b/drivers/net/mdio/mdio-bcm-unimac.c
@@ -94,6 +94,10 @@ static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
int ret;
u32 cmd;
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
+
/* Prepare the read operation */
cmd = MDIO_RD | (phy_id << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT);
unimac_mdio_writel(priv, cmd, MDIO_CMD);
@@ -103,7 +107,7 @@ static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
ret = priv->wait_func(priv->wait_func_data);
if (ret)
- return ret;
+ goto out;
cmd = unimac_mdio_readl(priv, MDIO_CMD);
@@ -112,10 +116,15 @@ static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
* that condition here and ignore the MDIO controller read failure
* indication.
*/
- if (!(bus->phy_ignore_ta_mask & 1 << phy_id) && (cmd & MDIO_READ_FAIL))
- return -EIO;
+ if (!(bus->phy_ignore_ta_mask & 1 << phy_id) && (cmd & MDIO_READ_FAIL)) {
+ ret = -EIO;
+ goto out;
+ }
- return cmd & 0xffff;
+ ret = cmd & 0xffff;
+out:
+ clk_disable_unprepare(priv->clk);
+ return ret;
}
static int unimac_mdio_write(struct mii_bus *bus, int phy_id,
@@ -123,6 +132,11 @@ static int unimac_mdio_write(struct mii_bus *bus, int phy_id,
{
struct unimac_mdio_priv *priv = bus->priv;
u32 cmd;
+ int ret;
+
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
/* Prepare the write operation */
cmd = MDIO_WR | (phy_id << MDIO_PMD_SHIFT) |
@@ -131,7 +145,10 @@ static int unimac_mdio_write(struct mii_bus *bus, int phy_id,
unimac_mdio_start(priv);
- return priv->wait_func(priv->wait_func_data);
+ ret = priv->wait_func(priv->wait_func_data);
+ clk_disable_unprepare(priv->clk);
+
+ return ret;
}
/* Workaround for integrated BCM7xxx Gigabit PHYs which have a problem with
@@ -178,14 +195,19 @@ static int unimac_mdio_reset(struct mii_bus *bus)
return 0;
}
-static void unimac_mdio_clk_set(struct unimac_mdio_priv *priv)
+static int unimac_mdio_clk_set(struct unimac_mdio_priv *priv)
{
unsigned long rate;
u32 reg, div;
+ int ret;
/* Keep the hardware default values */
if (!priv->clk_freq)
- return;
+ return 0;
+
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
if (!priv->clk)
rate = 250000000;
@@ -195,7 +217,8 @@ static void unimac_mdio_clk_set(struct unimac_mdio_priv *priv)
div = (rate / (2 * priv->clk_freq)) - 1;
if (div & ~MDIO_CLK_DIV_MASK) {
pr_warn("Incorrect MDIO clock frequency, ignoring\n");
- return;
+ ret = 0;
+ goto out;
}
/* The MDIO clock is the reference clock (typically 250Mhz) divided by
@@ -205,6 +228,9 @@ static void unimac_mdio_clk_set(struct unimac_mdio_priv *priv)
reg &= ~(MDIO_CLK_DIV_MASK << MDIO_CLK_DIV_SHIFT);
reg |= div << MDIO_CLK_DIV_SHIFT;
unimac_mdio_writel(priv, reg, MDIO_CFG);
+out:
+ clk_disable_unprepare(priv->clk);
+ return ret;
}
static int unimac_mdio_probe(struct platform_device *pdev)
@@ -235,24 +261,12 @@ static int unimac_mdio_probe(struct platform_device *pdev)
return -ENOMEM;
}
- priv->clk = devm_clk_get_optional(&pdev->dev, NULL);
- if (IS_ERR(priv->clk))
- return PTR_ERR(priv->clk);
-
- ret = clk_prepare_enable(priv->clk);
- if (ret)
- return ret;
-
if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq))
priv->clk_freq = 0;
- unimac_mdio_clk_set(priv);
-
priv->mii_bus = mdiobus_alloc();
- if (!priv->mii_bus) {
- ret = -ENOMEM;
- goto out_clk_disable;
- }
+ if (!priv->mii_bus)
+ return -ENOMEM;
bus = priv->mii_bus;
bus->priv = priv;
@@ -261,17 +275,27 @@ static int unimac_mdio_probe(struct platform_device *pdev)
priv->wait_func = pdata->wait_func;
priv->wait_func_data = pdata->wait_func_data;
bus->phy_mask = ~pdata->phy_mask;
+ priv->clk = pdata->clk;
} else {
bus->name = "unimac MII bus";
priv->wait_func_data = priv;
priv->wait_func = unimac_mdio_poll;
+ priv->clk = devm_clk_get_optional(&pdev->dev, NULL);
}
+
+ if (IS_ERR(priv->clk))
+ goto out_mdio_free;
+
bus->parent = &pdev->dev;
bus->read = unimac_mdio_read;
bus->write = unimac_mdio_write;
bus->reset = unimac_mdio_reset;
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id);
+ ret = unimac_mdio_clk_set(priv);
+ if (ret)
+ goto out_mdio_free;
+
ret = of_mdiobus_register(bus, np);
if (ret) {
dev_err(&pdev->dev, "MDIO bus registration failed\n");
@@ -286,8 +310,6 @@ static int unimac_mdio_probe(struct platform_device *pdev)
out_mdio_free:
mdiobus_free(bus);
-out_clk_disable:
- clk_disable_unprepare(priv->clk);
return ret;
}
@@ -297,34 +319,17 @@ static void unimac_mdio_remove(struct platform_device *pdev)
mdiobus_unregister(priv->mii_bus);
mdiobus_free(priv->mii_bus);
- clk_disable_unprepare(priv->clk);
-}
-
-static int __maybe_unused unimac_mdio_suspend(struct device *d)
-{
- struct unimac_mdio_priv *priv = dev_get_drvdata(d);
-
- clk_disable_unprepare(priv->clk);
-
- return 0;
}
static int __maybe_unused unimac_mdio_resume(struct device *d)
{
struct unimac_mdio_priv *priv = dev_get_drvdata(d);
- int ret;
- ret = clk_prepare_enable(priv->clk);
- if (ret)
- return ret;
-
- unimac_mdio_clk_set(priv);
-
- return 0;
+ return unimac_mdio_clk_set(priv);
}
static SIMPLE_DEV_PM_OPS(unimac_mdio_pm_ops,
- unimac_mdio_suspend, unimac_mdio_resume);
+ NULL, unimac_mdio_resume);
static const struct of_device_id unimac_mdio_ids[] = {
{ .compatible = "brcm,asp-v2.1-mdio", },
diff --git a/include/linux/platform_data/mdio-bcm-unimac.h b/include/linux/platform_data/mdio-bcm-unimac.h
index 8a5f9f0b2c52..724e1f57b81f 100644
--- a/include/linux/platform_data/mdio-bcm-unimac.h
+++ b/include/linux/platform_data/mdio-bcm-unimac.h
@@ -1,11 +1,14 @@
#ifndef __MDIO_BCM_UNIMAC_PDATA_H
#define __MDIO_BCM_UNIMAC_PDATA_H
+struct clk;
+
struct unimac_mdio_pdata {
u32 phy_mask;
int (*wait_func)(void *data);
void *wait_func_data;
const char *bus_name;
+ struct clk *clk;
};
#define UNIMAC_MDIO_DRV_NAME "unimac-mdio"
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver
2024-02-16 18:42 [PATCH net-next 0/3] Rework GENET MDIO controller clocking Florian Fainelli
2024-02-16 18:42 ` [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses Florian Fainelli
@ 2024-02-16 18:42 ` Florian Fainelli
2024-02-16 22:41 ` Jacob Keller
2024-02-17 15:21 ` Andrew Lunn
2024-02-16 18:42 ` [PATCH net-next 3/3] Revert "net: bcmgenet: Ensure MDIO unregistration has clocks enabled" Florian Fainelli
2 siblings, 2 replies; 11+ messages in thread
From: Florian Fainelli @ 2024-02-16 18:42 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Doug Berger,
Broadcom internal kernel review list, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
Heiner Kallweit, Russell King, open list, Justin Chen
GENET has historically had to create a MDIO platform device for its
controller and pass some auxiliary data to it, like a MDIO completion
callback. Now we also pass the "main" clock to allow for the MDIO bus
controller to manage that clock adequately around I/O accesses.
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
---
drivers/net/ethernet/broadcom/genet/bcmmii.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index cbbe004621bc..7a21950da77c 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -476,6 +476,10 @@ static int bcmgenet_mii_register(struct bcmgenet_priv *priv)
ppd.wait_func = bcmgenet_mii_wait;
ppd.wait_func_data = priv;
ppd.bus_name = "bcmgenet MII bus";
+ /* Pass a reference to our "main" clock which is used for MDIO
+ * transfers
+ */
+ ppd.clk = priv->clk;
/* Unimac MDIO bus controller starts at UniMAC offset + MDIO_CMD
* and is 2 * 32-bits word long, 8 bytes total.
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 3/3] Revert "net: bcmgenet: Ensure MDIO unregistration has clocks enabled"
2024-02-16 18:42 [PATCH net-next 0/3] Rework GENET MDIO controller clocking Florian Fainelli
2024-02-16 18:42 ` [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses Florian Fainelli
2024-02-16 18:42 ` [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver Florian Fainelli
@ 2024-02-16 18:42 ` Florian Fainelli
2024-02-16 22:41 ` Jacob Keller
2 siblings, 1 reply; 11+ messages in thread
From: Florian Fainelli @ 2024-02-16 18:42 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Doug Berger,
Broadcom internal kernel review list, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
Heiner Kallweit, Russell King, open list, Justin Chen
This reverts commit eac0aac07f6af47b8ba57c8064bf04ed6df73d1d ("net:
bcmgenet: Ensure MDIO unregistration has clocks enabled"). This is no
longer necessary now that the MDIO bus controller has a clock that it
can manage around the I/O accesses.
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
---
drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 7a21950da77c..9ada89355747 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -678,7 +678,5 @@ void bcmgenet_mii_exit(struct net_device *dev)
if (of_phy_is_fixed_link(dn))
of_phy_deregister_fixed_link(dn);
of_node_put(priv->phy_dn);
- clk_prepare_enable(priv->clk);
platform_device_unregister(priv->mii_pdev);
- clk_disable_unprepare(priv->clk);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses
2024-02-16 18:42 ` [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses Florian Fainelli
@ 2024-02-16 22:37 ` Jacob Keller
2024-02-17 10:43 ` kernel test robot
1 sibling, 0 replies; 11+ messages in thread
From: Jacob Keller @ 2024-02-16 22:37 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: Doug Berger, Broadcom internal kernel review list,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, Heiner Kallweit, Russell King, open list,
Justin Chen
On 2/16/2024 10:42 AM, Florian Fainelli wrote:
> Up until now we have managed not to have the mdio-bcm-unimac manage its
> clock except during probe and suspend/resume. This works most of the
> time, except where it does not.
>
This made me chuckle :)
> With a fully modular build, we can get into a situation whereby the
> GENET driver is fully registered, and so is the mdio-bcm-unimac driver,
> however the Ethernet PHY driver is not yet, because it depends on a
> resource that is not yet available (e.g.: GPIO provider). In that state,
> the network device is not usable yet, and so to conserve power, the
> GENET driver will have turned off its "main" clock which feeds its MDIO
> controller.
>
> When the PHY driver finally probes however, we make an access to the PHY
> registers to e.g.: disable interrupts, and this causes a bus error
> within the MDIO controller space because the MDIO controller clock(s)
> are turned off.
>
> To remedy that, we manage the clock around all of the I/O accesses to
> the hardware which are done exclusively during read, write and clock
> divider configuration.
>
> This ensures that the register space is accessible, and this also
> ensures that there are not unnecessarily elevated reference counts
> keeping the clocks active when the network device is administratively
> turned off. It would be the case with the previous way of managing the
> clock.
>
Good description of the issues.
> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
> ---
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver
2024-02-16 18:42 ` [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver Florian Fainelli
@ 2024-02-16 22:41 ` Jacob Keller
2024-02-16 22:50 ` Florian Fainelli
2024-02-17 15:21 ` Andrew Lunn
1 sibling, 1 reply; 11+ messages in thread
From: Jacob Keller @ 2024-02-16 22:41 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: Doug Berger, Broadcom internal kernel review list,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, Heiner Kallweit, Russell King, open list,
Justin Chen
On 2/16/2024 10:42 AM, Florian Fainelli wrote:
> GENET has historically had to create a MDIO platform device for its
> controller and pass some auxiliary data to it, like a MDIO completion
> callback. Now we also pass the "main" clock to allow for the MDIO bus
> controller to manage that clock adequately around I/O accesses.
>
> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
> ---
> drivers/net/ethernet/broadcom/genet/bcmmii.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
> index cbbe004621bc..7a21950da77c 100644
> --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
> +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
> @@ -476,6 +476,10 @@ static int bcmgenet_mii_register(struct bcmgenet_priv *priv)
> ppd.wait_func = bcmgenet_mii_wait;
> ppd.wait_func_data = priv;
> ppd.bus_name = "bcmgenet MII bus";
> + /* Pass a reference to our "main" clock which is used for MDIO
> + * transfers
> + */
> + ppd.clk = priv->clk;
>
> /* Unimac MDIO bus controller starts at UniMAC offset + MDIO_CMD
> * and is 2 * 32-bits word long, 8 bytes total.
Is this missing a modification of the header file to add the clk field
to struct unimac_mdio_pdata? I don't see that field in the
include/linux/platform_data/mdio-bcm-unimac.h header currently...
Oh. you included that in the first patch of the series. I see.
It feels like the series would be more natural of this was 1/3 instead
of 2/3, since the current 1/3 patch depends on this clk value being set, no?
The result of the series makes sense tho:
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 3/3] Revert "net: bcmgenet: Ensure MDIO unregistration has clocks enabled"
2024-02-16 18:42 ` [PATCH net-next 3/3] Revert "net: bcmgenet: Ensure MDIO unregistration has clocks enabled" Florian Fainelli
@ 2024-02-16 22:41 ` Jacob Keller
0 siblings, 0 replies; 11+ messages in thread
From: Jacob Keller @ 2024-02-16 22:41 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: Doug Berger, Broadcom internal kernel review list,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, Heiner Kallweit, Russell King, open list,
Justin Chen
On 2/16/2024 10:42 AM, Florian Fainelli wrote:
> This reverts commit eac0aac07f6af47b8ba57c8064bf04ed6df73d1d ("net:
> bcmgenet: Ensure MDIO unregistration has clocks enabled"). This is no
> longer necessary now that the MDIO bus controller has a clock that it
> can manage around the I/O accesses.
>
> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
> ---
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver
2024-02-16 22:41 ` Jacob Keller
@ 2024-02-16 22:50 ` Florian Fainelli
0 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2024-02-16 22:50 UTC (permalink / raw)
To: Jacob Keller, netdev
Cc: Doug Berger, Broadcom internal kernel review list,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, Heiner Kallweit, Russell King, open list,
Justin Chen
[-- Attachment #1: Type: text/plain, Size: 2334 bytes --]
On 2/16/24 14:41, Jacob Keller wrote:
>
>
> On 2/16/2024 10:42 AM, Florian Fainelli wrote:
>> GENET has historically had to create a MDIO platform device for its
>> controller and pass some auxiliary data to it, like a MDIO completion
>> callback. Now we also pass the "main" clock to allow for the MDIO bus
>> controller to manage that clock adequately around I/O accesses.
>>
>> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
>> ---
>> drivers/net/ethernet/broadcom/genet/bcmmii.c | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
>> index cbbe004621bc..7a21950da77c 100644
>> --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
>> +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
>> @@ -476,6 +476,10 @@ static int bcmgenet_mii_register(struct bcmgenet_priv *priv)
>> ppd.wait_func = bcmgenet_mii_wait;
>> ppd.wait_func_data = priv;
>> ppd.bus_name = "bcmgenet MII bus";
>> + /* Pass a reference to our "main" clock which is used for MDIO
>> + * transfers
>> + */
>> + ppd.clk = priv->clk;
>>
>> /* Unimac MDIO bus controller starts at UniMAC offset + MDIO_CMD
>> * and is 2 * 32-bits word long, 8 bytes total.
>
> Is this missing a modification of the header file to add the clk field
> to struct unimac_mdio_pdata? I don't see that field in the
> include/linux/platform_data/mdio-bcm-unimac.h header currently...
>
> Oh. you included that in the first patch of the series. I see.
I suppose I could have included it in patch #1, and have introduced in
patch #2 the hunk that dealt with fetching pdata->clk, but since I was
re-organizing the mdio-bcm-unimac.c driver's probe function, it felt
more natural to arrange it that way.
>
> It feels like the series would be more natural of this was 1/3 instead
> of 2/3, since the current 1/3 patch depends on this clk value being set, no?
I sort of debated that with myself, and ended up going with: put the
plumbing first, wire it later, rather than the opposite. If someone was
to run a bisection there would not be any difference in behavior until
patch #2 regardless of their ordering.
>
> The result of the series makes sense tho:
>
> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Thanks Jacob!
--
Florian
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4221 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses
2024-02-16 18:42 ` [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses Florian Fainelli
2024-02-16 22:37 ` Jacob Keller
@ 2024-02-17 10:43 ` kernel test robot
1 sibling, 0 replies; 11+ messages in thread
From: kernel test robot @ 2024-02-17 10:43 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: llvm, oe-kbuild-all, Florian Fainelli, Doug Berger,
Broadcom internal kernel review list, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Andrew Lunn, Heiner Kallweit,
Russell King, linux-kernel, Justin Chen
Hi Florian,
kernel test robot noticed the following build warnings:
[auto build test WARNING on net-next/main]
url: https://github.com/intel-lab-lkp/linux/commits/Florian-Fainelli/net-mdio-mdio-bcm-unimac-Manage-clock-around-I-O-accesses/20240217-024738
base: net-next/main
patch link: https://lore.kernel.org/r/20240216184237.259954-2-florian.fainelli%40broadcom.com
patch subject: [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses
config: arm-defconfig (https://download.01.org/0day-ci/archive/20240217/202402171801.J560K7Fo-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240217/202402171801.J560K7Fo-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402171801.J560K7Fo-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/net/mdio/mdio-bcm-unimac.c:286:6: warning: variable 'ret' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
if (IS_ERR(priv->clk))
^~~~~~~~~~~~~~~~~
drivers/net/mdio/mdio-bcm-unimac.c:313:9: note: uninitialized use occurs here
return ret;
^~~
drivers/net/mdio/mdio-bcm-unimac.c:286:2: note: remove the 'if' if its condition is always false
if (IS_ERR(priv->clk))
^~~~~~~~~~~~~~~~~~~~~~
drivers/net/mdio/mdio-bcm-unimac.c:243:9: note: initialize the variable 'ret' to silence this warning
int ret;
^
= 0
1 warning generated.
vim +286 drivers/net/mdio/mdio-bcm-unimac.c
235
236 static int unimac_mdio_probe(struct platform_device *pdev)
237 {
238 struct unimac_mdio_pdata *pdata = pdev->dev.platform_data;
239 struct unimac_mdio_priv *priv;
240 struct device_node *np;
241 struct mii_bus *bus;
242 struct resource *r;
243 int ret;
244
245 np = pdev->dev.of_node;
246
247 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
248 if (!priv)
249 return -ENOMEM;
250
251 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
252 if (!r)
253 return -EINVAL;
254
255 /* Just ioremap, as this MDIO block is usually integrated into an
256 * Ethernet MAC controller register range
257 */
258 priv->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
259 if (!priv->base) {
260 dev_err(&pdev->dev, "failed to remap register\n");
261 return -ENOMEM;
262 }
263
264 if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq))
265 priv->clk_freq = 0;
266
267 priv->mii_bus = mdiobus_alloc();
268 if (!priv->mii_bus)
269 return -ENOMEM;
270
271 bus = priv->mii_bus;
272 bus->priv = priv;
273 if (pdata) {
274 bus->name = pdata->bus_name;
275 priv->wait_func = pdata->wait_func;
276 priv->wait_func_data = pdata->wait_func_data;
277 bus->phy_mask = ~pdata->phy_mask;
278 priv->clk = pdata->clk;
279 } else {
280 bus->name = "unimac MII bus";
281 priv->wait_func_data = priv;
282 priv->wait_func = unimac_mdio_poll;
283 priv->clk = devm_clk_get_optional(&pdev->dev, NULL);
284 }
285
> 286 if (IS_ERR(priv->clk))
287 goto out_mdio_free;
288
289 bus->parent = &pdev->dev;
290 bus->read = unimac_mdio_read;
291 bus->write = unimac_mdio_write;
292 bus->reset = unimac_mdio_reset;
293 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id);
294
295 ret = unimac_mdio_clk_set(priv);
296 if (ret)
297 goto out_mdio_free;
298
299 ret = of_mdiobus_register(bus, np);
300 if (ret) {
301 dev_err(&pdev->dev, "MDIO bus registration failed\n");
302 goto out_mdio_free;
303 }
304
305 platform_set_drvdata(pdev, priv);
306
307 dev_info(&pdev->dev, "Broadcom UniMAC MDIO bus\n");
308
309 return 0;
310
311 out_mdio_free:
312 mdiobus_free(bus);
313 return ret;
314 }
315
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver
2024-02-16 18:42 ` [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver Florian Fainelli
2024-02-16 22:41 ` Jacob Keller
@ 2024-02-17 15:21 ` Andrew Lunn
2024-02-17 17:18 ` Florian Fainelli
1 sibling, 1 reply; 11+ messages in thread
From: Andrew Lunn @ 2024-02-17 15:21 UTC (permalink / raw)
To: Florian Fainelli
Cc: netdev, Doug Berger, Broadcom internal kernel review list,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Heiner Kallweit, Russell King, open list, Justin Chen
On Fri, Feb 16, 2024 at 10:42:36AM -0800, Florian Fainelli wrote:
> GENET has historically had to create a MDIO platform device for its
> controller and pass some auxiliary data to it, like a MDIO completion
> callback. Now we also pass the "main" clock to allow for the MDIO bus
> controller to manage that clock adequately around I/O accesses.
I guess this code comes from before the times of DT? I would normally
expect to see a clock added to the DT node for the MDIO bus. But if
there is no node, because it is not in DT....
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver
2024-02-17 15:21 ` Andrew Lunn
@ 2024-02-17 17:18 ` Florian Fainelli
0 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2024-02-17 17:18 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, Doug Berger, Broadcom internal kernel review list,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Heiner Kallweit, Russell King, open list, Justin Chen
[-- Attachment #1: Type: text/plain, Size: 1242 bytes --]
Hi Andrew,
On 2/17/2024 7:21 AM, Andrew Lunn wrote:
> On Fri, Feb 16, 2024 at 10:42:36AM -0800, Florian Fainelli wrote:
>> GENET has historically had to create a MDIO platform device for its
>> controller and pass some auxiliary data to it, like a MDIO completion
>> callback. Now we also pass the "main" clock to allow for the MDIO bus
>> controller to manage that clock adequately around I/O accesses.
>
> I guess this code comes from before the times of DT? I would normally
> expect to see a clock added to the DT node for the MDIO bus. But if
> there is no node, because it is not in DT....
The driver started being DT-only from the get go, however it was also my
group's first attempt at upstreaming a driver and we did not get
everything right in terms of the DT binding. In particular there was no
"mdio" sub-node initially, but we still wanted to be able to split up
the MDIO controller part since we knew it was going to be re-used in
other designs (bcm_sf2 and later asp2). The platform device was the best
we could come up with at the time.
All of our DTBs deployed out there do not have a "clocks" property
within the "mdio" sub-mode of the GENET Ethernet node, so that is why we
are doing this.
Thanks!
--
Florian
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4221 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-02-17 17:18 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-16 18:42 [PATCH net-next 0/3] Rework GENET MDIO controller clocking Florian Fainelli
2024-02-16 18:42 ` [PATCH net-next 1/3] net: mdio: mdio-bcm-unimac: Manage clock around I/O accesses Florian Fainelli
2024-02-16 22:37 ` Jacob Keller
2024-02-17 10:43 ` kernel test robot
2024-02-16 18:42 ` [PATCH net-next 2/3] net: bcmgenet: Pass "main" clock down to the MDIO driver Florian Fainelli
2024-02-16 22:41 ` Jacob Keller
2024-02-16 22:50 ` Florian Fainelli
2024-02-17 15:21 ` Andrew Lunn
2024-02-17 17:18 ` Florian Fainelli
2024-02-16 18:42 ` [PATCH net-next 3/3] Revert "net: bcmgenet: Ensure MDIO unregistration has clocks enabled" Florian Fainelli
2024-02-16 22:41 ` Jacob Keller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).