mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-01-06 09:11:27 +01:00
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
This commit is contained in:
commit
29a96acaa3
3
README
3
README
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
36
cmd/net.c
36
cmd/net.c
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
168
drivers/net/mdio-mt7531-mmio.c
Normal file
168
drivers/net/mdio-mt7531-mmio.c
Normal 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),
|
||||
};
|
||||
9
drivers/net/mdio-mt7531-mmio.h
Normal file
9
drivers/net/mdio-mt7531-mmio.h
Normal 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);
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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[]);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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_ */
|
||||
|
||||
@ -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
|
||||
|
||||
20
net/Kconfig
20
net/Kconfig
@ -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"
|
||||
|
||||
24
net/bootp.c
24
net/bootp.c
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user