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
This commit is contained in:
Tom Rini 2025-10-22 09:07:56 -06:00
commit 29a96acaa3
31 changed files with 497 additions and 164 deletions

3
README
View File

@ -1216,9 +1216,6 @@ Note: once the monitor has been relocated, then it will complain if
the default environment is used; a new CRC is computed as soon as you
use the "saveenv" command to store a valid environment.
- CONFIG_SYS_FAULT_MII_ADDR:
MII address of the PHY to check for the Ethernet link state.
- CONFIG_DISPLAY_BOARDINFO
Display information about the board that U-Boot is running on
when U-Boot starts up. The board function checkboard() is called

View File

@ -1951,10 +1951,6 @@ config BOOTP_BOOTPATH
Even though the config is called BOOTP_BOOTPATH, it stores the
path in the variable 'rootpath'.
config BOOTP_VENDOREX
bool "Support vendor extensions from BOOTP/DHCP server"
depends on CMD_BOOTP
config BOOTP_BOOTFILESIZE
bool "Request & store 'bootfilesize' from BOOTP/DHCP server"
depends on CMD_BOOTP

View File

@ -134,8 +134,8 @@ U_BOOT_CMD(dhcp6, 3, 1, do_dhcp6,
#endif
#if defined(CONFIG_CMD_DHCP)
static int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
return netboot_common(DHCP, cmdtp, argc, argv);
}
@ -145,38 +145,6 @@ U_BOOT_CMD(
"boot image via network using DHCP/TFTP protocol",
"[loadAddress] [[hostIPaddr:]bootfilename]"
);
int dhcp_run(ulong addr, const char *fname, bool autoload)
{
char *dhcp_argv[] = {"dhcp", NULL, (char *)fname, NULL};
struct cmd_tbl cmdtp = {}; /* dummy */
char file_addr[17];
int old_autoload;
int ret, result;
log_debug("addr=%lx, fname=%s, autoload=%d\n", addr, fname, autoload);
old_autoload = env_get_yesno("autoload");
ret = env_set("autoload", autoload ? "y" : "n");
if (ret)
return log_msg_ret("en1", -EINVAL);
if (autoload) {
sprintf(file_addr, "%lx", addr);
dhcp_argv[1] = file_addr;
}
result = do_dhcp(&cmdtp, 0, !autoload ? 1 : fname ? 3 : 2, dhcp_argv);
ret = env_set("autoload", old_autoload == -1 ? NULL :
old_autoload ? "y" : "n");
if (ret)
return log_msg_ret("en2", -EINVAL);
if (result)
return log_msg_ret("res", -ENOENT);
return 0;
}
#endif
#if defined(CONFIG_CMD_NFS)

View File

@ -43,6 +43,7 @@ CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SYS_RX_ETH_BUFFER=8
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y

View File

@ -42,7 +42,6 @@ CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_IN_NAND=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RETRY_COUNT=20
CONFIG_TFTP_PORT=y
CONFIG_TFTP_TSIZE=y
CONFIG_AT91_GPIO=y
CONFIG_GENERIC_ATMEL_MCI=y

View File

@ -4,7 +4,7 @@ This text describes properties that are applicable to Aquantia PHY nodes in
addition to the bindings in phy.txt.
Aquantia PHYs allow some flexibility in the way they are wired in a system,
they allow MDI pins to be reversed, LEDs linked up in different weays, have an
they allow MDI pins to be reversed, LEDs linked up in different ways, have an
I2C slave interface that can be used for debug. Normally the configuration
corresponding to these is driven by the PHY firmware with the downside that
a custom firmware is needed for each integration of a PHY.

View File

@ -19,9 +19,8 @@ Description
The tftpput command is used to transfer a file to a TFTP server.
By default the destination port is 69 and the source port is pseudo-random.
If CONFIG_TFTP_PORT=y, the environment variable *tftpsrcp* can be used to set
the source port and the environment variable *tftpdstp* can be used to set
the destination port.
The environment variable *tftpsrcp* can be used to set the source port and the
environment variable *tftpdstp* can be used to set the destination port.
address
memory address where the data starts
@ -75,9 +74,6 @@ The command is only available if CONFIG_CMD_TFTPPUT=y.
CONFIG_TFTP_BLOCKSIZE defines the size of the TFTP blocks sent. It defaults
to 1468 matching an ethernet MTU of 1500.
If CONFIG_TFTP_PORT=y, the environment variables *tftpsrcp* and *tftpdstp* can
be used to set the source and the destination ports.
CONFIG_TFTP_WINDOWSIZE can be used to set the TFTP window size of transmits
after which an ACK response is required. The window size defaults to 1.

View File

@ -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

View File

@ -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

View File

@ -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 = &eth->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;
}

View File

@ -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;

View File

@ -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),
};

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -6,6 +6,7 @@
* Author: Mark Lee <mark-mc.lee@mediatek.com>
*/
#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,
};

View File

@ -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"

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -479,6 +479,16 @@ int net_loop(enum proto_t protocol);
*/
int dhcp_run(ulong addr, const char *fname, bool autoload);
/**
* do_dhcp - Run the dhcp command
*
* @cmdtp: Unused
* @flag: Command flags (CMD_FLAG_...)
* @argc: Number of arguments
* @argv: List of arguments
* Return: result (see enum command_ret_t)
*/
int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
/**
* do_ping - Run the ping command

View File

@ -50,7 +50,6 @@ int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip);
*/
bool wget_validate_uri(char *uri);
int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);

View File

@ -123,6 +123,11 @@ struct phy_driver {
int (*write_mmd)(struct phy_device *phydev, int devad, int reg,
u16 val);
/** @read_page: Return the current PHY register page number */
int (*read_page)(struct phy_device *phydev);
/** @write_page: Set the current PHY register page number */
int (*write_page)(struct phy_device *phydev, int page);
/* driver private data */
ulong data;
};
@ -314,6 +319,9 @@ int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
u16 mask, u16 set);
int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
u16 mask, u16 set);
int phy_save_page(struct phy_device *phydev);
int phy_select_page(struct phy_device *phydev, int page);
int phy_restore_page(struct phy_device *phydev, int oldpage, int ret);
int phy_startup(struct phy_device *phydev);
int phy_config(struct phy_device *phydev);

View File

@ -72,7 +72,7 @@ struct uthread_mutex {
#define UTHREAD_MUTEX_INITIALIZER { .state = UTHREAD_MUTEX_UNLOCKED }
#ifdef CONFIG_UTHREAD
#if CONFIG_IS_ENABLED(UTHREAD)
/**
* uthread_create() - Create a uthread object and make it ready for execution
@ -184,5 +184,5 @@ static inline bool uthread_grp_done(unsigned int grp_id)
#define uthread_mutex_trylock(_mutex) ({ 0 })
#define uthread_mutex_unlock(_mutex) ({ 0; })
#endif /* CONFIG_UTHREAD */
#endif /* CONFIG_IS_ENABLED(UTHREAD) */
#endif /* _UTHREAD_H_ */

View File

@ -161,7 +161,7 @@ obj-$(CONFIG_LIB_ELF) += elf.o
obj-$(CONFIG_$(PHASE_)SEMIHOSTING) += semihosting.o
obj-$(CONFIG_UTHREAD) += uthread.o
obj-$(CONFIG_$(PHASE_)UTHREAD) += uthread.o
#
# Build a fast OID lookup registry from include/linux/oid_registry.h

View File

@ -60,23 +60,9 @@ config SYS_FAULT_ECHO_LINK_DOWN
this option is active, then CONFIG_SYS_FAULT_MII_ADDR also needs to
be configured.
config TFTP_PORT
bool "Set TFTP UDP source/destination ports via the environment"
help
If this is defined, the environment variable tftpsrcp is used to
supply the TFTP UDP source port value. If tftpsrcp isn't defined,
the normal pseudo-random port number generator is used.
Also, the environment variable tftpdstp is used to supply the TFTP
UDP destination port value. If tftpdstp isn't defined, the normal
port 69 is used.
The purpose for tftpsrcp is to allow a TFTP server to blindly start
the TFTP transfer using the pre-configured target IP address and UDP
port. This has the effect of "punching through" the (Windows XP)
firewall, allowing the remainder of the TFTP transfer to proceed
normally. A better solution is to properly configure the firewall,
but sometimes that is not allowed.
config SYS_FAULT_MII_ADDR
hex "MII address of the PHY to check for the Ethernet link state"
depends on SYS_FAULT_ECHO_LINK_DOWN && LED_STATUS_RED_ENABLE
config TFTP_WINDOWSIZE
int "TFTP window size"

View File

@ -379,6 +379,14 @@ static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n",
src, dest, len, sizeof(struct bootp_hdr));
/* Check the minimum size of a BOOTP packet is respected.
* A BOOTP packet is between 300 bytes and 576 bytes big
*/
if (len < offsetof(struct bootp_hdr, bp_vend) + 64) {
printf("Error: got an invalid BOOTP packet (len=%u)\n", len);
return;
}
bp = (struct bootp_hdr *)pkt;
/* Filter out pkts we don't want */
@ -396,7 +404,8 @@ static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
/* Retrieve extended information (we must parse the vendor area) */
if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
bootp_process_vendor((uchar *)&bp->bp_vend[4], len);
bootp_process_vendor((uchar *)&bp->bp_vend[4], len -
(offsetof(struct bootp_hdr, bp_vend) + 4));
net_set_timeout_handler(0, (thand_f *)0);
bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop");
@ -491,9 +500,6 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
#endif
int clientarch = -1;
#if defined(CONFIG_BOOTP_VENDOREX)
u8 *x;
#endif
#if defined(CONFIG_BOOTP_SEND_HOSTNAME)
char *hostname;
#endif
@ -584,12 +590,6 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
e = add_vci(e);
#if defined(CONFIG_BOOTP_VENDOREX)
x = dhcp_vendorex_prep(e);
if (x)
return x - start;
#endif
*e++ = 55; /* Parameter Request List */
cnt = e++; /* Pointer to count of requested items */
*cnt = 0;
@ -977,10 +977,6 @@ static void dhcp_process_options(uchar *popt, uchar *end)
}
break;
default:
#if defined(CONFIG_BOOTP_VENDOREX)
if (dhcp_vendorex_proc(popt))
break;
#endif
printf("*** Unhandled DHCP Option in OFFER/ACK:"
" %d\n", *popt);
break;

View File

@ -24,10 +24,6 @@
#if defined(CONFIG_CMD_DHCP)
/* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */
#define OPT_FIELD_SIZE 312
#if defined(CONFIG_BOOTP_VENDOREX)
extern u8 *dhcp_vendorex_prep(u8 *e); /*rtn new e after add own opts. */
extern u8 *dhcp_vendorex_proc(u8 *e); /*rtn next e if mine,else NULL */
#endif
#else
#define OPT_FIELD_SIZE 64
#endif

View File

@ -150,25 +150,3 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
return CMD_RET_SUCCESS;
}
int dhcp_run(ulong addr, const char *fname, bool autoload)
{
char *dhcp_argv[] = {"dhcp", NULL, };
#ifdef CONFIG_CMD_TFTPBOOT
char *tftp_argv[] = {"tftpboot", boot_file_name, NULL, };
#endif
struct cmd_tbl cmdtp = {}; /* dummy */
if (autoload) {
#ifdef CONFIG_CMD_TFTPBOOT
/* Assume DHCP was already performed */
if (boot_file_name[0])
return do_tftpb(&cmdtp, 0, 2, tftp_argv);
return 0;
#else
return -EOPNOTSUPP;
#endif
}
return do_dhcp(&cmdtp, 0, 1, dhcp_argv);
}

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <dm/uclass.h>
#include <env.h>
#include <net-common.h>
#include <linux/time.h>
#include <rtc.h>
@ -48,3 +49,37 @@ void net_sntp_set_rtc(u32 seconds)
tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
#if defined(CONFIG_CMD_DHCP)
int dhcp_run(ulong addr, const char *fname, bool autoload)
{
char *dhcp_argv[] = {"dhcp", NULL, (char *)fname, NULL};
struct cmd_tbl cmdtp = {}; /* dummy */
char file_addr[17];
int old_autoload;
int ret, result;
log_debug("addr=%lx, fname=%s, autoload=%d\n", addr, fname, autoload);
old_autoload = env_get_yesno("autoload");
ret = env_set("autoload", autoload ? "y" : "n");
if (ret)
return log_msg_ret("en1", -EINVAL);
if (autoload) {
sprintf(file_addr, "%lx", addr);
dhcp_argv[1] = file_addr;
}
result = do_dhcp(&cmdtp, 0, !autoload ? 1 : fname ? 3 : 2, dhcp_argv);
ret = env_set("autoload", old_autoload == -1 ? NULL :
old_autoload ? "y" : "n");
if (ret)
return log_msg_ret("en2", -EINVAL);
if (result)
return log_msg_ret("res", -ENOENT);
return 0;
}
#endif

View File

@ -926,14 +926,13 @@ void tftp_start(enum proto_t protocol)
/* Use a pseudo-random port unless a specific port is set */
tftp_our_port = 1024 + (get_timer(0) % 3072);
#ifdef CONFIG_TFTP_PORT
ep = env_get("tftpdstp");
if (ep != NULL)
tftp_remote_port = simple_strtol(ep, NULL, 10);
ep = env_get("tftpsrcp");
if (ep != NULL)
tftp_our_port = simple_strtol(ep, NULL, 10);
#endif
tftp_cur_block = 0;
tftp_windowsize = 1;
tftp_last_nack = 0;