The current polling code unconditionally waits 30us, which was sized for a ~25us Clause 22 transaction, and then polls MDIO_CMD with a sleep of up to 2ms between samples. Adding Clause 45 support means that every access becomes two back to back transactions (an ADDR cycle followed by a READ/WRITE cycle), so a fixed delay sized for a single C22 transaction is no longer meaningful, and a sleep of up to 2ms between samples can add significant latency to each access when the transaction has not completed at the first sample. Instead, poll the MDIO_START_BUSY bit every microsecond so that the completion is noticed as soon as it happens, regardless of the type of transaction. This turns the wait into a busy wait, which is bounded by a timeout reduced from 100ms to 1ms: a 64 bit MDIO frame takes about 33us at the lowest MDIO clock the driver can program from a 250MHz reference clock, so even a two frame C45 access completes well within that. Signed-off-by: Florian Fainelli Co-developed-by: Carlos Soto Signed-off-by: Carlos Soto --- drivers/net/mdio/mdio-bcm-unimac.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/mdio/mdio-bcm-unimac.c b/drivers/net/mdio/mdio-bcm-unimac.c index 6df824aba75e..15a9880c3573 100644 --- a/drivers/net/mdio/mdio-bcm-unimac.c +++ b/drivers/net/mdio/mdio-bcm-unimac.c @@ -6,8 +6,8 @@ */ #include -#include #include +#include #include #include #include @@ -36,6 +36,13 @@ #define MDIO_CLK_DIV_MASK 0x3F #define MDIO_SUPP_PREAMBLE (1 << 12) +/* A 64 bit MDIO frame takes ~25us at 2.5MHz and ~33us at the lowest MDIO + * clock the driver can program from a 250MHz reference clock. A C45 access is + * two frames, so a 1ms timeout leaves a wide margin. + */ +#define MDIO_POLL_DELAY_US 1 +#define MDIO_POLL_TIMEOUT_US 1000 + struct unimac_mdio_priv { struct mii_bus *mii_bus; void __iomem *base; @@ -79,14 +86,14 @@ static int unimac_mdio_poll(void *wait_func_data) struct unimac_mdio_priv *priv = wait_func_data; u32 val; - /* - * C22 transactions should take ~25 usec, will need to adjust - * if C45 support is added. + /* C22 transactions should take ~25 usec, C45 transactions take about + * twice as long since they need an address and a data cycle. */ - udelay(30); - - return read_poll_timeout(unimac_mdio_readl, val, !(val & MDIO_START_BUSY), - 2000, 100000, false, priv, MDIO_CMD); + return read_poll_timeout_atomic(unimac_mdio_readl, val, + !(val & MDIO_START_BUSY), + MDIO_POLL_DELAY_US, + MDIO_POLL_TIMEOUT_US, false, priv, + MDIO_CMD); } static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg) -- 2.34.1