Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'net-phy-mscc-miim-reduce-waiting-time-between-MDIO-transactions'

Antoine Tenart says:

====================
net: phy: mscc-miim: reduce waiting time between MDIO transactions

This series aims at reducing the waiting time between MDIO transactions
when using the MSCC MIIM MDIO controller.

I'm not sure we need patch 4/4 and we could reasonably drop it from the
series. I'm including the patch as it could help to ensure the system
is functional with a non optimal configuration.

We needed to improve the driver's performances as when using a PHY
requiring lots of registers accesses (such as the VSC85xx family),
delays would add up and ended up to be quite large which would cause
issues such as: a slow initialization of the PHY, and issues when using
timestamping operations (this feature will be sent quite soon to the
mailing lists).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+28 -8
+2 -1
drivers/net/phy/Kconfig
··· 184 184 depends on HAS_IOMEM 185 185 help 186 186 This driver supports the MIIM (MDIO) interface found in the network 187 - switches of the Microsemi SoCs 187 + switches of the Microsemi SoCs; it is recommended to switch on 188 + CONFIG_HIGH_RES_TIMERS 188 189 189 190 config MDIO_MVUSB 190 191 tristate "Marvell USB to MDIO Adapter"
+26 -7
drivers/net/phy/mdio-mscc-miim.c
··· 16 16 #include <linux/of_mdio.h> 17 17 18 18 #define MSCC_MIIM_REG_STATUS 0x0 19 + #define MSCC_MIIM_STATUS_STAT_PENDING BIT(2) 19 20 #define MSCC_MIIM_STATUS_STAT_BUSY BIT(3) 20 21 #define MSCC_MIIM_REG_CMD 0x8 21 22 #define MSCC_MIIM_CMD_OPR_WRITE BIT(1) ··· 39 38 void __iomem *phy_regs; 40 39 }; 41 40 41 + /* When high resolution timers aren't built-in: we can't use usleep_range() as 42 + * we would sleep way too long. Use udelay() instead. 43 + */ 44 + #define mscc_readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \ 45 + ({ \ 46 + if (!IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) \ 47 + readl_poll_timeout_atomic(addr, val, cond, delay_us, \ 48 + timeout_us); \ 49 + readl_poll_timeout(addr, val, cond, delay_us, timeout_us); \ 50 + }) 51 + 42 52 static int mscc_miim_wait_ready(struct mii_bus *bus) 43 53 { 44 54 struct mscc_miim_dev *miim = bus->priv; 45 55 u32 val; 46 56 47 - readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val, 48 - !(val & MSCC_MIIM_STATUS_STAT_BUSY), 100, 250000); 49 - if (val & MSCC_MIIM_STATUS_STAT_BUSY) 50 - return -ETIMEDOUT; 57 + return mscc_readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val, 58 + !(val & MSCC_MIIM_STATUS_STAT_BUSY), 50, 59 + 10000); 60 + } 51 61 52 - return 0; 62 + static int mscc_miim_wait_pending(struct mii_bus *bus) 63 + { 64 + struct mscc_miim_dev *miim = bus->priv; 65 + u32 val; 66 + 67 + return mscc_readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val, 68 + !(val & MSCC_MIIM_STATUS_STAT_PENDING), 69 + 50, 10000); 53 70 } 54 71 55 72 static int mscc_miim_read(struct mii_bus *bus, int mii_id, int regnum) ··· 76 57 u32 val; 77 58 int ret; 78 59 79 - ret = mscc_miim_wait_ready(bus); 60 + ret = mscc_miim_wait_pending(bus); 80 61 if (ret) 81 62 goto out; 82 63 ··· 105 86 struct mscc_miim_dev *miim = bus->priv; 106 87 int ret; 107 88 108 - ret = mscc_miim_wait_ready(bus); 89 + ret = mscc_miim_wait_pending(bus); 109 90 if (ret < 0) 110 91 goto out; 111 92