diff options
| author | Tom Rini <[email protected]> | 2025-10-22 09:07:56 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-10-22 09:07:56 -0600 |
| commit | 29a96acaa3a84c68264d8dcf2182000bce71175e (patch) | |
| tree | abd59b96eeb5783eb0ec7bb43423c3910a328502 /drivers | |
| parent | b21ba014a9e51ae33916ec17786fdb03587ed9b6 (diff) | |
| parent | ed6ec8d1ca0658d811df1cc78d06fec4f7f69fc9 (diff) | |
Merge tag 'net-20251022' of https://source.denx.de/u-boot/custodians/u-boot-net
Pull request net-20251022
net:
- airoha: improvements
- Tighten a few more driver dependencies
- designware: fix bitbang init error
- phy: Make driver overloading get_phy_id depend on !COMPILE_TEST
- phy: add paged PHY register accessors
- make dhcp_run() common for NET and NET_LWIP
- dwc_eth_ops: Correct check for FDT_64BIT
- mediatek: mt7988: various fixup + MDIO detach
- phy: aquantia: switch to use phy_get_ofnode(), fix bindings typo
net-legacy:
- bootp: Prevent buffer overflow to avoid leaking the RAM content
- tftp: make TFTP ports unconditionally configurable
misc:
- uthreads: Make use of CONFIG_IS_ENABLED consistently
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/net/Makefile | 1 | ||||
| -rw-r--r-- | drivers/net/airoha_eth.c | 40 | ||||
| -rw-r--r-- | drivers/net/designware.c | 12 | ||||
| -rw-r--r-- | drivers/net/mdio-mt7531-mmio.c | 168 | ||||
| -rw-r--r-- | drivers/net/mdio-mt7531-mmio.h | 9 | ||||
| -rw-r--r-- | drivers/net/mtk_eth/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/net/mtk_eth/mt7531.c | 20 | ||||
| -rw-r--r-- | drivers/net/mtk_eth/mt7988.c | 92 | ||||
| -rw-r--r-- | drivers/net/phy/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/net/phy/aquantia.c | 2 | ||||
| -rw-r--r-- | drivers/net/phy/phy.c | 113 | ||||
| -rw-r--r-- | drivers/power/domain/Kconfig | 2 |
13 files changed, 421 insertions, 52 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7ae28c4e0d5..c9b35b5a2ff 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -179,7 +179,7 @@ config CALXEDA_XGMAC machines. config DWC_ETH_XGMAC - bool "Synopsys DWC Ethernet XGMAC device support" + bool select PHYLIB help This driver supports the Synopsys Designware Ethernet XGMAC (10G @@ -190,7 +190,8 @@ config DWC_ETH_XGMAC_SOCFPGA bool "Synopsys DWC Ethernet XGMAC device support for SOCFPGA" select REGMAP select SYSCON - depends on DWC_ETH_XGMAC + select DWC_ETH_XGMAC + depends on ARCH_SOCFPGA default y if TARGET_SOCFPGA_AGILEX5 help The Synopsys Designware Ethernet XGMAC IP block with specific @@ -376,7 +377,7 @@ config ETH_DESIGNWARE_SOCFPGA select SYSCON select DW_ALTDESCRIPTOR bool "Altera SoCFPGA extras for Synopsys Designware Ethernet MAC" - depends on ETH_DESIGNWARE + depends on ARCH_SOCFPGA && ETH_DESIGNWARE help The Altera SoCFPGA requires additional configuration of the Altera system manager to correctly interface with the PHY. @@ -966,6 +967,9 @@ config TSEC_ENET This driver implements support for the (Enhanced) Three-Speed Ethernet Controller found on Freescale SoCs. +config MDIO_MT7531_MMIO + bool + source "drivers/net/mtk_eth/Kconfig" config HIFEMAC_ETH diff --git a/drivers/net/Makefile b/drivers/net/Makefile index f8f9a71f815..a3c3420898c 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_MACB) += macb.o obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o obj-$(CONFIG_MDIO_GPIO_BITBANG) += mdio_gpio.o +obj-$(CONFIG_MDIO_MT7531_MMIO) += mdio-mt7531-mmio.o obj-$(CONFIG_MDIO_MUX_I2CREG) += mdio_mux_i2creg.o obj-$(CONFIG_MDIO_MUX_MESON_G12A) += mdio_mux_meson_g12a.o obj-$(CONFIG_MDIO_MUX_MESON_GXL) += mdio_mux_meson_gxl.o diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c index 6588eb3a806..19c3d60044c 100644 --- a/drivers/net/airoha_eth.c +++ b/drivers/net/airoha_eth.c @@ -449,14 +449,10 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q, RX_RING_SIZE_MASK, FIELD_PREP(RX_RING_SIZE_MASK, ndesc)); - /* - * See arht_eth_free_pkt() for the reasons used to fill - * REG_RX_CPU_IDX(qid) register. - */ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK, FIELD_PREP(RX_RING_THR_MASK, 0)); airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK, - FIELD_PREP(RX_RING_CPU_IDX_MASK, q->ndesc - 3)); + FIELD_PREP(RX_RING_CPU_IDX_MASK, q->ndesc - 1)); airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); @@ -920,7 +916,6 @@ static int arht_eth_free_pkt(struct udevice *dev, uchar *packet, int length) struct airoha_qdma *qdma = ð->qdma[0]; struct airoha_queue *q; int qid; - u16 prev, pprev; if (!packet) return 0; @@ -930,22 +925,29 @@ static int arht_eth_free_pkt(struct udevice *dev, uchar *packet, int length) /* * Due to cpu cache issue the airoha_qdma_reset_rx_desc() function - * will always touch 2 descriptors: - * - if current descriptor is even, then the previous and the one - * before previous descriptors will be touched (previous cacheline) - * - if current descriptor is odd, then only current and previous - * descriptors will be touched (current cacheline) + * will always touch 2 descriptors placed on the same cacheline: + * - if current descriptor is even, then current and next + * descriptors will be touched + * - if current descriptor is odd, then current and previous + * descriptors will be touched * - * Thus, to prevent possible destroying of rx queue, only (q->ndesc - 2) - * descriptors might be used for packet receiving. + * Thus, to prevent possible destroying of rx queue, we should: + * - do nothing in the even descriptor case, + * - utilize 2 descriptors (current and previous one) in the + * odd descriptor case. + * + * WARNING: Observations shows that PKTBUFSRX must be even and + * larger than 7 for reliable driver operations. */ - prev = (q->head + q->ndesc - 1) % q->ndesc; - pprev = (q->head + q->ndesc - 2) % q->ndesc; - q->head = (q->head + 1) % q->ndesc; + if (q->head & 0x01) { + airoha_qdma_reset_rx_desc(q, q->head - 1); + airoha_qdma_reset_rx_desc(q, q->head); - airoha_qdma_reset_rx_desc(q, prev); - airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK, - FIELD_PREP(RX_RING_CPU_IDX_MASK, pprev)); + airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK, + FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); + } + + q->head = (q->head + 1) % q->ndesc; return 0; } diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 2fd92cf16bb..6ed9c6d538a 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -125,6 +125,16 @@ static int dw_mdio_reset(struct mii_dev *bus) return __dw_mdio_reset(dev); } + +#if IS_ENABLED(CONFIG_BITBANGMII) +static int dw_bb_mdio_reset(struct mii_dev *bus) +{ + struct dw_eth_dev *priv = bus->priv; + + return __dw_mdio_reset(priv->dev); +} +#endif + #endif #if IS_ENABLED(CONFIG_DM_MDIO) @@ -348,7 +358,7 @@ static int dw_bb_mdio_init(const char *name, struct udevice *dev) bus->read = dw_bb_miiphy_read; bus->write = dw_bb_miiphy_write; #if CONFIG_IS_ENABLED(DM_GPIO) - bus->reset = dw_mdio_reset; + bus->reset = dw_bb_mdio_reset; #endif bus->priv = dwpriv; diff --git a/drivers/net/mdio-mt7531-mmio.c b/drivers/net/mdio-mt7531-mmio.c new file mode 100644 index 00000000000..3e325ca58da --- /dev/null +++ b/drivers/net/mdio-mt7531-mmio.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <asm/io.h> +#include <dm.h> +#include <linux/bitfield.h> +#include <linux/iopoll.h> +#include <miiphy.h> + +#define MT7531_PHY_IAC 0x701c +#define MT7531_PHY_ACS_ST BIT(31) +#define MT7531_MDIO_REG_ADDR_CL22 GENMASK(29, 25) +#define MT7531_MDIO_DEV_ADDR MT7531_MDIO_REG_ADDR_CL22 +#define MT7531_MDIO_PHY_ADDR GENMASK(24, 20) +#define MT7531_MDIO_CMD GENMASK(19, 18) +#define MT7531_MDIO_CMD_READ_CL45 FIELD_PREP_CONST(MT7531_MDIO_CMD, 0x3) +#define MT7531_MDIO_CMD_READ_CL22 FIELD_PREP_CONST(MT7531_MDIO_CMD, 0x2) +#define MT7531_MDIO_CMD_WRITE FIELD_PREP_CONST(MT7531_MDIO_CMD, 0x1) +#define MT7531_MDIO_CMD_ADDR FIELD_PREP_CONST(MT7531_MDIO_CMD, 0x0) +#define MT7531_MDIO_ST GENMASK(17, 16) +#define MT7531_MDIO_ST_CL22 FIELD_PREP_CONST(MT7531_MDIO_ST, 0x1) +#define MT7531_MDIO_ST_CL45 FIELD_PREP_CONST(MT7531_MDIO_ST, 0x0) +#define MT7531_MDIO_RW_DATA GENMASK(15, 0) +#define MT7531_MDIO_REG_ADDR_CL45 MT7531_MDIO_RW_DATA + +#define MT7531_MDIO_TIMEOUT 100000 +#define MT7531_MDIO_SLEEP 20 + +struct mt7531_mdio_priv { + phys_addr_t switch_regs; +}; + +static int mt7531_mdio_wait_busy(struct mt7531_mdio_priv *priv) +{ + unsigned int busy; + + return readl_poll_sleep_timeout(priv->switch_regs + MT7531_PHY_IAC, + busy, (busy & MT7531_PHY_ACS_ST) == 0, + MT7531_MDIO_SLEEP, MT7531_MDIO_TIMEOUT); +} + +static int mt7531_mdio_read(struct mt7531_mdio_priv *priv, int addr, int devad, int reg) +{ + u32 val; + + if (devad != MDIO_DEVAD_NONE) { + if (mt7531_mdio_wait_busy(priv)) + return -ETIMEDOUT; + + val = MT7531_PHY_ACS_ST | + MT7531_MDIO_ST_CL45 | MT7531_MDIO_CMD_ADDR | + FIELD_PREP(MT7531_MDIO_PHY_ADDR, addr) | + FIELD_PREP(MT7531_MDIO_DEV_ADDR, devad) | + FIELD_PREP(MT7531_MDIO_REG_ADDR_CL45, reg); + + writel(val, priv->switch_regs + MT7531_PHY_IAC); + } + + if (mt7531_mdio_wait_busy(priv)) + return -ETIMEDOUT; + + val = MT7531_PHY_ACS_ST | FIELD_PREP(MT7531_MDIO_PHY_ADDR, addr); + if (devad != MDIO_DEVAD_NONE) + val |= MT7531_MDIO_ST_CL45 | MT7531_MDIO_CMD_READ_CL45 | + FIELD_PREP(MT7531_MDIO_DEV_ADDR, devad); + else + val |= MT7531_MDIO_ST_CL22 | MT7531_MDIO_CMD_READ_CL22 | + FIELD_PREP(MT7531_MDIO_REG_ADDR_CL22, reg); + + writel(val, priv->switch_regs + MT7531_PHY_IAC); + + if (mt7531_mdio_wait_busy(priv)) + return -ETIMEDOUT; + + val = readl(priv->switch_regs + MT7531_PHY_IAC); + return val & MT7531_MDIO_RW_DATA; +} + +static int mt7531_mdio_write(struct mt7531_mdio_priv *priv, int addr, int devad, + int reg, u16 value) +{ + u32 val; + + if (devad != MDIO_DEVAD_NONE) { + if (mt7531_mdio_wait_busy(priv)) + return -ETIMEDOUT; + + val = MT7531_PHY_ACS_ST | + MT7531_MDIO_ST_CL45 | MT7531_MDIO_CMD_ADDR | + FIELD_PREP(MT7531_MDIO_PHY_ADDR, addr) | + FIELD_PREP(MT7531_MDIO_DEV_ADDR, devad) | + FIELD_PREP(MT7531_MDIO_REG_ADDR_CL45, reg); + + writel(val, priv->switch_regs + MT7531_PHY_IAC); + } + + if (mt7531_mdio_wait_busy(priv)) + return -ETIMEDOUT; + + val = MT7531_PHY_ACS_ST | FIELD_PREP(MT7531_MDIO_PHY_ADDR, addr) | + MT7531_MDIO_CMD_WRITE | FIELD_PREP(MT7531_MDIO_RW_DATA, value); + if (devad != MDIO_DEVAD_NONE) + val |= MT7531_MDIO_ST_CL45 | + FIELD_PREP(MT7531_MDIO_DEV_ADDR, devad); + else + val |= MT7531_MDIO_ST_CL22 | + FIELD_PREP(MT7531_MDIO_REG_ADDR_CL22, reg); + + writel(val, priv->switch_regs + MT7531_PHY_IAC); + + if (mt7531_mdio_wait_busy(priv)) + return -ETIMEDOUT; + + return 0; +} + +int mt7531_mdio_mmio_read(struct mii_dev *bus, int addr, int devad, int reg) +{ + struct mt7531_mdio_priv *priv = bus->priv; + + return mt7531_mdio_read(priv, addr, devad, reg); +} + +int mt7531_mdio_mmio_write(struct mii_dev *bus, int addr, int devad, + int reg, u16 value) +{ + struct mt7531_mdio_priv *priv = bus->priv; + + return mt7531_mdio_write(priv, addr, devad, reg, value); +} + +static int dm_mt7531_mdio_read(struct udevice *dev, int addr, int devad, int reg) +{ + struct mt7531_mdio_priv *priv = dev_get_priv(dev); + + return mt7531_mdio_read(priv, addr, devad, reg); +} + +static int dm_mt7531_mdio_write(struct udevice *dev, int addr, int devad, + int reg, u16 value) +{ + struct mt7531_mdio_priv *priv = dev_get_priv(dev); + + return mt7531_mdio_write(priv, addr, devad, reg, value); +} + +static const struct mdio_ops mt7531_mdio_ops = { + .read = dm_mt7531_mdio_read, + .write = dm_mt7531_mdio_write, +}; + +static int mt7531_mdio_probe(struct udevice *dev) +{ + struct mt7531_mdio_priv *priv = dev_get_priv(dev); + + priv->switch_regs = dev_read_addr(dev); + if (priv->switch_regs == FDT_ADDR_T_NONE) + return -EINVAL; + + return 0; +} + +U_BOOT_DRIVER(mt7531_mdio) = { + .name = "mt7531-mdio-mmio", + .id = UCLASS_MDIO, + .probe = mt7531_mdio_probe, + .ops = &mt7531_mdio_ops, + .priv_auto = sizeof(struct mt7531_mdio_priv), +}; diff --git a/drivers/net/mdio-mt7531-mmio.h b/drivers/net/mdio-mt7531-mmio.h new file mode 100644 index 00000000000..f98102cb939 --- /dev/null +++ b/drivers/net/mdio-mt7531-mmio.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +struct mt7531_mdio_mmio_priv { + phys_addr_t switch_regs; +}; + +int mt7531_mdio_mmio_read(struct mii_dev *bus, int addr, int devad, int reg); +int mt7531_mdio_mmio_write(struct mii_dev *bus, int addr, int devad, + int reg, u16 value); diff --git a/drivers/net/mtk_eth/Kconfig b/drivers/net/mtk_eth/Kconfig index e8cdf408237..5d4e54ab90e 100644 --- a/drivers/net/mtk_eth/Kconfig +++ b/drivers/net/mtk_eth/Kconfig @@ -1,6 +1,7 @@ config MEDIATEK_ETH bool "MediaTek Ethernet GMAC Driver" + depends on ARCH_MEDIATEK || ARCH_MTMIPS select PHYLIB select DM_GPIO select DM_RESET @@ -30,6 +31,7 @@ config MTK_ETH_SWITCH_MT7531 config MTK_ETH_SWITCH_MT7988 bool "Support for MediaTek MT7988 built-in ethernet switch" depends on TARGET_MT7988 + select MDIO_MT7531_MMIO default y config MTK_ETH_SWITCH_AN8855 diff --git a/drivers/net/mtk_eth/mt7531.c b/drivers/net/mtk_eth/mt7531.c index 32d6bebbbdb..965bc3cb7e9 100644 --- a/drivers/net/mtk_eth/mt7531.c +++ b/drivers/net/mtk_eth/mt7531.c @@ -22,17 +22,13 @@ static int mt7531_core_reg_read(struct mt753x_switch_priv *priv, u32 reg) { - u8 phy_addr = MT753X_PHY_ADDR(priv->phy_base, 0); - - return mt7531_mmd_read(priv, phy_addr, 0x1f, reg); + return mt7531_mmd_read(priv, 0, 0x1f, reg); } static void mt7531_core_reg_write(struct mt753x_switch_priv *priv, u32 reg, u32 val) { - u8 phy_addr = MT753X_PHY_ADDR(priv->phy_base, 0); - - mt7531_mmd_write(priv, phy_addr, 0x1f, reg, val); + mt7531_mmd_write(priv, 0, 0x1f, reg, val); } static void mt7531_core_pll_setup(struct mt753x_switch_priv *priv) @@ -171,7 +167,7 @@ static int mt7531_setup(struct mtk_eth_switch_priv *swpriv) { struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv; u32 i, val, pmcr, port5_sgmii; - u16 phy_addr, phy_val; + u16 phy_val; priv->smi_addr = MT753X_DFL_SMI_ADDR; priv->phy_base = (priv->smi_addr + 1) & MT753X_SMI_ADDR_MASK; @@ -180,10 +176,9 @@ static int mt7531_setup(struct mtk_eth_switch_priv *swpriv) /* Turn off PHYs */ for (i = 0; i < MT753X_NUM_PHYS; i++) { - phy_addr = MT753X_PHY_ADDR(priv->phy_base, i); - phy_val = mt7531_mii_read(priv, phy_addr, MII_BMCR); + phy_val = mt7531_mii_read(priv, i, MII_BMCR); phy_val |= BMCR_PDOWN; - mt7531_mii_write(priv, phy_addr, MII_BMCR, phy_val); + mt7531_mii_write(priv, i, MII_BMCR, phy_val); } /* Force MAC link down before reset */ @@ -239,10 +234,9 @@ static int mt7531_setup(struct mtk_eth_switch_priv *swpriv) /* Turn on PHYs */ for (i = 0; i < MT753X_NUM_PHYS; i++) { - phy_addr = MT753X_PHY_ADDR(priv->phy_base, i); - phy_val = mt7531_mii_read(priv, phy_addr, MII_BMCR); + phy_val = mt7531_mii_read(priv, i, MII_BMCR); phy_val &= ~BMCR_PDOWN; - mt7531_mii_write(priv, phy_addr, MII_BMCR, phy_val); + mt7531_mii_write(priv, i, MII_BMCR, phy_val); } mt7531_phy_setting(priv); diff --git a/drivers/net/mtk_eth/mt7988.c b/drivers/net/mtk_eth/mt7988.c index a416d87840c..29b6363cbd7 100644 --- a/drivers/net/mtk_eth/mt7988.c +++ b/drivers/net/mtk_eth/mt7988.c @@ -6,6 +6,7 @@ * Author: Mark Lee <[email protected]> */ +#include <malloc.h> #include <miiphy.h> #include <linux/delay.h> #include <linux/mdio.h> @@ -14,6 +15,8 @@ #include "mtk_eth.h" #include "mt753x.h" +#include "../mdio-mt7531-mmio.h" + static int mt7988_reg_read(struct mt753x_switch_priv *priv, u32 reg, u32 *data) { *data = readl(priv->epriv.ethsys_base + GSW_BASE + reg); @@ -30,20 +33,34 @@ static int mt7988_reg_write(struct mt753x_switch_priv *priv, u32 reg, u32 data) static void mt7988_phy_setting(struct mt753x_switch_priv *priv) { + struct mii_dev *mdio_bus = priv->mdio_bus; u16 val; u32 i; for (i = 0; i < MT753X_NUM_PHYS; i++) { + u16 addr = MT753X_PHY_ADDR(priv->phy_base, i); + + /* Set PHY to PHY page 1 */ + mt7531_mdio_mmio_write(mdio_bus, addr, MDIO_DEVAD_NONE, + 0x1f, 0x1); + /* Enable HW auto downshift */ - mt7531_mii_write(priv, i, 0x1f, 0x1); - val = mt7531_mii_read(priv, i, PHY_EXT_REG_14); + val = mt7531_mdio_mmio_read(mdio_bus, addr, MDIO_DEVAD_NONE, + PHY_EXT_REG_14); val |= PHY_EN_DOWN_SHFIT; - mt7531_mii_write(priv, i, PHY_EXT_REG_14, val); + mt7531_mdio_mmio_write(mdio_bus, addr, MDIO_DEVAD_NONE, + PHY_EXT_REG_14, val); /* PHY link down power saving enable */ - val = mt7531_mii_read(priv, i, PHY_EXT_REG_17); + val = mt7531_mdio_mmio_read(mdio_bus, addr, MDIO_DEVAD_NONE, + PHY_EXT_REG_17); val |= PHY_LINKDOWN_POWER_SAVING_EN; - mt7531_mii_write(priv, i, PHY_EXT_REG_17, val); + mt7531_mdio_mmio_write(mdio_bus, addr, MDIO_DEVAD_NONE, + PHY_EXT_REG_17, val); + + /* Restore PHY to PHY page 0 */ + mt7531_mdio_mmio_write(mdio_bus, addr, MDIO_DEVAD_NONE, + 0x1f, 0x0); } } @@ -58,24 +75,66 @@ static void mt7988_mac_control(struct mtk_eth_switch_priv *swpriv, bool enable) mt7988_reg_write(priv, PMCR_REG(6), pmcr); } +static int mt7988_mdio_register(struct mt753x_switch_priv *priv) +{ + struct mt7531_mdio_mmio_priv *mdio_priv; + struct mii_dev *mdio_bus = mdio_alloc(); + int ret; + + if (!mdio_bus) + return -ENOMEM; + + mdio_priv = malloc(sizeof(*mdio_priv)); + if (!mdio_priv) + return -ENOMEM; + + mdio_priv->switch_regs = (phys_addr_t)priv->epriv.ethsys_base + GSW_BASE; + + mdio_bus->read = mt7531_mdio_mmio_read; + mdio_bus->write = mt7531_mdio_mmio_write; + snprintf(mdio_bus->name, sizeof(mdio_bus->name), priv->epriv.sw->name); + + mdio_bus->priv = mdio_priv; + + ret = mdio_register(mdio_bus); + if (ret) { + free(mdio_bus->priv); + mdio_free(mdio_bus); + return ret; + } + + priv->mdio_bus = mdio_bus; + + return 0; +} + static int mt7988_setup(struct mtk_eth_switch_priv *swpriv) { struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv; + struct mii_dev *mdio_bus; u16 phy_addr, phy_val; + int ret, i; u32 pmcr; - int i; priv->smi_addr = MT753X_DFL_SMI_ADDR; priv->phy_base = (priv->smi_addr + 1) & MT753X_SMI_ADDR_MASK; priv->reg_read = mt7988_reg_read; priv->reg_write = mt7988_reg_write; + ret = mt7988_mdio_register(priv); + if (ret) + return ret; + + mdio_bus = priv->mdio_bus; + /* Turn off PHYs */ for (i = 0; i < MT753X_NUM_PHYS; i++) { phy_addr = MT753X_PHY_ADDR(priv->phy_base, i); - phy_val = mt7531_mii_read(priv, phy_addr, MII_BMCR); + phy_val = mt7531_mdio_mmio_read(mdio_bus, phy_addr, + MDIO_DEVAD_NONE, MII_BMCR); phy_val |= BMCR_PDOWN; - mt7531_mii_write(priv, phy_addr, MII_BMCR, phy_val); + mt7531_mdio_mmio_write(mdio_bus, phy_addr, MDIO_DEVAD_NONE, + MII_BMCR, phy_val); } switch (priv->epriv.phy_interface) { @@ -129,21 +188,26 @@ static int mt7988_setup(struct mtk_eth_switch_priv *swpriv) /* Turn on PHYs */ for (i = 0; i < MT753X_NUM_PHYS; i++) { phy_addr = MT753X_PHY_ADDR(priv->phy_base, i); - phy_val = mt7531_mii_read(priv, phy_addr, MII_BMCR); + phy_val = mt7531_mdio_mmio_read(mdio_bus, phy_addr, + MDIO_DEVAD_NONE, MII_BMCR); phy_val &= ~BMCR_PDOWN; - mt7531_mii_write(priv, phy_addr, MII_BMCR, phy_val); + mt7531_mdio_mmio_write(mdio_bus, phy_addr, MDIO_DEVAD_NONE, + MII_BMCR, phy_val); } mt7988_phy_setting(priv); - return mt7531_mdio_register(priv); + return 0; } -static int mt7531_cleanup(struct mtk_eth_switch_priv *swpriv) +static int mt7988_cleanup(struct mtk_eth_switch_priv *swpriv) { struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv; + struct mii_dev *mdio_bus = priv->mdio_bus; - mdio_unregister(priv->mdio_bus); + mdio_unregister(mdio_bus); + free(mdio_bus->priv); + mdio_free(mdio_bus); return 0; } @@ -155,6 +219,6 @@ MTK_ETH_SWITCH(mt7988) = { .reset_wait_time = 50, .setup = mt7988_setup, - .cleanup = mt7531_cleanup, + .cleanup = mt7988_cleanup, .mac_control = mt7988_mac_control, }; diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 185c6a3156e..018be98705a 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -56,6 +56,7 @@ endif # B53_SWITCH config MV88E61XX_SWITCH bool "Marvell MV88E61xx Ethernet switch PHY support." + depends on !COMPILE_TEST if MV88E61XX_SWITCH @@ -119,6 +120,7 @@ config PHY_BROADCOM config PHY_CORTINA bool "Cortina Ethernet PHYs support" + depends on !COMPILE_TEST config SYS_CORTINA_NO_FW_UPLOAD bool "Cortina firmware loading support" diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c index f63a13824ca..903fcd667f6 100644 --- a/drivers/net/phy/aquantia.c +++ b/drivers/net/phy/aquantia.c @@ -338,7 +338,7 @@ static int aquantia_set_proto(struct phy_device *phydev, static int aquantia_dts_config(struct phy_device *phydev) { - ofnode node = phydev->node; + ofnode node = phy_get_ofnode(phydev); u32 prop; u16 reg; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 9702d042296..b58283fe3d5 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1250,3 +1250,116 @@ bool phy_interface_is_ncsi(void) return 0; #endif } + +/** + * __phy_read_page() - read the current page + * @phydev: a pointer to a &struct phy_device + * + * Returns page index or < 0 on error + */ +static int __phy_read_page(struct phy_device *phydev) +{ + struct phy_driver *drv = phydev->drv; + + if (!drv->read_page) { + debug("read_page callback not available, PHY driver not loaded?\n"); + return -EOPNOTSUPP; + } + + return drv->read_page(phydev); +} + +/** + * __phy_write_page() - Write a new page + * @phydev: a pointer to a &struct phy_device + * @page: page index to select + * + * Returns 0 or < 0 on error. + */ +static int __phy_write_page(struct phy_device *phydev, int page) +{ + struct phy_driver *drv = phydev->drv; + + if (!drv->write_page) { + debug("write_page callback not available, PHY driver not loaded?\n"); + return -EOPNOTSUPP; + } + + return drv->write_page(phydev, page); +} + +/** + * phy_save_page() - save the current page + * @phydev: a pointer to a &struct phy_device + * + * Return the current page number. On error, + * returns a negative errno. phy_restore_page() must always be called + * after this, irrespective of success or failure of this call. + */ +int phy_save_page(struct phy_device *phydev) +{ + return __phy_read_page(phydev); +} + +/** + * phy_select_page - Switch to a PHY page and return the previous page + * @phydev: a pointer to a &struct phy_device + * @page: desired page + * + * NOTE: Save the current PHY page, and set the current page. + * On error, returns a negative errno, otherwise returns the previous page number. + * phy_restore_page() must always be called after this, irrespective + * of success or failure of this call. + */ +int phy_select_page(struct phy_device *phydev, int page) +{ + int ret, oldpage; + + oldpage = ret = phy_save_page(phydev); + if (ret < 0) + return ret; + + if (oldpage != page) { + ret = __phy_write_page(phydev, page); + if (ret < 0) + return ret; + } + + return oldpage; +} + +/** + * phy_restore_page - Restore a previously saved page and propagate status + * @phydev: a pointer to a &struct phy_device + * @oldpage: the old page, return value from phy_save_page() or phy_select_page() + * @ret: operation's return code + * + * Restoring @oldpage if it is a valid page. + * This function propagates the earliest error code from the group of + * operations. + * + * Returns: + * @oldpage if it was a negative value, otherwise + * @ret if it was a negative errno value, otherwise + * phy_write_page()'s negative value if it were in error, otherwise + * @ret. + */ +int phy_restore_page(struct phy_device *phydev, int oldpage, int ret) +{ + int r; + + if (oldpage >= 0) { + r = __phy_write_page(phydev, oldpage); + + /* Propagate the operation return code if the page write + * was successful. + */ + if (ret >= 0 && r < 0) + ret = r; + } else { + /* Propagate the phy page selection error code */ + ret = oldpage; + } + + return ret; +}
\ No newline at end of file diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig index ebf5d828cb0..0ad885c9e8b 100644 --- a/drivers/power/domain/Kconfig +++ b/drivers/power/domain/Kconfig @@ -20,7 +20,7 @@ config APPLE_PMGR_POWER_DOMAIN config AGILEX5_PMGR_POWER_DOMAIN bool "Enable the Agilex5 PMGR power domain driver" - depends on SPL_POWER_DOMAIN + depends on SPL_POWER_DOMAIN && TARGET_SOCFPGA_SOC64 help Enable support for power gating peripherals' SRAM specified in the handoff data values obtained from the bitstream to reduce |
