Merge branch '2020-09-30-assorted-network-improvements' into next

- Generic UDP framework
- TFTP fixes
- dwc_eth_qos, smc911x, smc911x and mscc phy fixes
This commit is contained in:
Tom Rini 2020-10-01 09:46:10 -04:00
commit 26acc6395f
22 changed files with 494 additions and 72 deletions

View File

@ -1645,6 +1645,7 @@ config CMD_CDP
config CMD_SNTP
bool "sntp"
select PROT_UDP
help
Synchronize RTC via network

View File

@ -13,6 +13,8 @@
#include <env.h>
#include <image.h>
#include <net.h>
#include <net/udp.h>
#include <net/sntp.h>
static int netboot_common(enum proto_t, struct cmd_tbl *, int, char * const []);
@ -356,6 +358,12 @@ U_BOOT_CMD(
#endif
#if defined(CONFIG_CMD_SNTP)
static struct udp_ops sntp_ops = {
.prereq = sntp_prereq,
.start = sntp_start,
.data = NULL,
};
int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
char *toff;
@ -380,7 +388,7 @@ int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
else
net_ntp_time_offset = simple_strtol(toff, NULL, 10);
if (net_loop(SNTP) < 0) {
if (udp_loop(&sntp_ops) < 0) {
printf("SNTP failed: host %pI4 not responding\n",
&net_ntp_server);
return CMD_RET_FAILURE;

View File

@ -102,6 +102,7 @@ CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_EXT4=y
CONFIG_ENV_EXT4_INTERFACE="host"
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
CONFIG_PROT_UDP=y
CONFIG_BOOTP_SEND_HOSTNAME=y
CONFIG_NETCONSOLE=y
CONFIG_IP_DEFRAG=y

35
doc/README.udp Normal file
View File

@ -0,0 +1,35 @@
Udp framework
The udp framework is build on top of network framework and is designed
to define new protocol or new command based on udp without modifying
the network framework.
The udp framework define a function udp_loop that take as argument
a structure udp_ops (defined in include/net/udp.h) :
struct udp_ops {
int (*prereq)(void *data);
int (*start)(void *data);
void *data;
};
The callback prereq define if all the requirements are
valid before running the network/udp loop.
The callback start define the first step in the network/udp loop,
and it may also be used to configure a timemout and udp handler.
The pointer data is used to store private data that
could be used by both callback.
A simple example to use this framework:
static struct udp_ops udp_ops = {
.prereq = wmp_prereq,
.start = wmp_start,
.data = NULL,
};
...
err = udp_loop(&udp_ops);

View File

@ -26,6 +26,7 @@
* supports a single RGMII PHY. This configuration also has SW control over
* all clock and reset signals to the HW block.
*/
#include <common.h>
#include <clk.h>
#include <cpu_func.h>
@ -1893,8 +1894,7 @@ static phy_interface_t eqos_get_interface_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
NULL);
phy_mode = dev_read_prop(dev, "phy-mode", NULL);
if (phy_mode)
interface = phy_get_interface_by_name(phy_mode);
@ -1931,8 +1931,7 @@ static phy_interface_t eqos_get_interface_imx(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
NULL);
phy_mode = dev_read_prop(dev, "phy-mode", NULL);
if (phy_mode)
interface = phy_get_interface_by_name(phy_mode);

View File

@ -551,6 +551,10 @@ static int ftgmac100_probe(struct udevice *dev)
priv->max_speed = pdata->max_speed;
priv->phy_addr = 0;
#ifdef CONFIG_PHY_ADDR
priv->phy_addr = CONFIG_PHY_ADDR;
#endif
ret = clk_enable_bulk(&priv->clks);
if (ret)
goto out;

View File

@ -157,6 +157,14 @@
#define INT_MEM_DATA_M GENMASK(7, 0)
#define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x))
/* Extended page GPIO register 13G */
#define MSCC_CLKOUT_CNTL 13
#define CLKOUT_ENABLE BIT(15)
#define CLKOUT_FREQ_MASK GENMASK(14, 13)
#define CLKOUT_FREQ_25M (0x0 << 13)
#define CLKOUT_FREQ_50M (0x1 << 13)
#define CLKOUT_FREQ_125M (0x2 << 13)
/* Extended page GPIO register 18G */
#define MSCC_PHY_PROC_CMD 18
#define PROC_CMD_NCOMPLETED BIT(15)
@ -1168,6 +1176,9 @@ static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
rx_clk_out = RX_CLK_OUT_NORMAL;
break;
case PHY_INTERFACE_MODE_RGMII_TXID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII:
/* Set Reg23.12:11=2 */
mac_if = MAC_IF_SELECTION_RGMII;
@ -1210,13 +1221,84 @@ static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
return 0;
}
static int vsc8531_vsc8541_clkout_config(struct phy_device *phydev)
{
struct ofnode_phandle_args phandle_args;
u32 clkout_rate = 0;
u16 reg_val;
int retval;
retval = dev_read_phandle_with_args(phydev->dev, "phy-handle", NULL,
0, 0, &phandle_args);
if (!retval)
clkout_rate = ofnode_read_u32_default(phandle_args.node,
"vsc8531,clk-out-frequency", 0);
switch (clkout_rate) {
case 0:
reg_val = 0;
break;
case 25000000:
reg_val = CLKOUT_FREQ_25M | CLKOUT_ENABLE;
break;
case 50000000:
reg_val = CLKOUT_FREQ_50M | CLKOUT_ENABLE;
break;
case 125000000:
reg_val = CLKOUT_FREQ_125M | CLKOUT_ENABLE;
break;
default:
printf("PHY 8530/31 invalid clkout rate %u\n",
clkout_rate);
return -EINVAL;
}
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_GPIO);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_CLKOUT_CNTL, reg_val);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
return 0;
}
static int vsc8531_vsc8541_clk_skew_config(struct phy_device *phydev)
{
enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_200_PS;
enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_200_PS;
u16 reg_val;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
rx_clk_skew = VSC_PHY_RGMII_DELAY_2000_PS;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
tx_clk_skew = VSC_PHY_RGMII_DELAY_2000_PS;
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_EXT2);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
/* Reg20E2 - Update RGMII RX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
/* Reg20E2 - Update RGMII TX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
return 0;
}
static int vsc8531_config(struct phy_device *phydev)
{
int retval = -EINVAL;
u16 reg_val;
u16 rmii_clk_out;
enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
/* For VSC8530/31 and VSC8540/41 the init scripts are the same */
@ -1226,6 +1308,9 @@ static int vsc8531_config(struct phy_device *phydev)
switch (phydev->interface) {
case PHY_INTERFACE_MODE_RMII:
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_TXID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_ID:
retval = vsc8531_vsc8541_mac_config(phydev);
if (retval != 0)
return retval;
@ -1242,19 +1327,12 @@ static int vsc8531_config(struct phy_device *phydev)
/* Default RMII Clk Output to 0=OFF/1=ON */
rmii_clk_out = 0;
retval = vsc8531_vsc8541_clk_skew_config(phydev);
if (retval != 0)
return retval;
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_EXT2);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
/* Reg20E2 - Update RGMII RX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
/* Reg20E2 - Update RGMII TX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
/* Reg27E2 - Update Clk Slew Rate. */
reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
@ -1267,6 +1345,11 @@ static int vsc8531_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
/* Configure the clk output */
retval = vsc8531_vsc8541_clkout_config(phydev);
if (retval != 0)
return retval;
return genphy_config_aneg(phydev);
}
@ -1275,8 +1358,6 @@ static int vsc8541_config(struct phy_device *phydev)
int retval = -EINVAL;
u16 reg_val;
u16 rmii_clk_out;
enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
/* For VSC8530/31 and VSC8540/41 the init scripts are the same */
@ -1304,17 +1385,12 @@ static int vsc8541_config(struct phy_device *phydev)
/* Default RMII Clk Output to 0=OFF/1=ON */
rmii_clk_out = 0;
retval = vsc8531_vsc8541_clk_skew_config(phydev);
if (retval != 0)
return retval;
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_EXT2);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
/* Reg20E2 - Update RGMII RX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
/* Reg20E2 - Update RGMII TX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
/* Reg27E2 - Update Clk Slew Rate. */
reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
@ -1327,6 +1403,11 @@ static int vsc8541_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
/* Configure the clk output */
retval = vsc8531_vsc8541_clkout_config(phydev);
if (retval != 0)
return retval;
return genphy_config_aneg(phydev);
}

View File

@ -6,6 +6,7 @@
*/
#include <common.h>
#include <env.h>
#include <command.h>
#include <malloc.h>
#include <net.h>
@ -185,6 +186,8 @@ static void smc911x_handle_mac_address(struct smc911x_priv *priv)
smc911x_set_mac_csr(priv, ADDRH, addrh);
printf(DRIVERNAME ": MAC %pM\n", m);
if (!env_get("ethaddr"))
env_set("ethaddr", (const char *)m);
}
static bool smc911x_read_mac_address(struct smc911x_priv *priv)

View File

@ -84,6 +84,13 @@ config BCM6368_USBH_PHY
help
Support for the Broadcom MIPS BCM6368 USBH PHY.
config BCM_SR_PCIE_PHY
bool "Broadcom Stingray PCIe PHY driver"
depends on PHY
help
Enable this to support the Broadcom Stingray PCIe PHY
If unsure, say N.
config PHY_DA8XX_USB
tristate "TI DA8xx USB PHY Driver"
depends on PHY && ARCH_DAVINCI

View File

@ -9,6 +9,7 @@ obj-$(CONFIG_BCM6318_USBH_PHY) += bcm6318-usbh-phy.o
obj-$(CONFIG_BCM6348_USBH_PHY) += bcm6348-usbh-phy.o
obj-$(CONFIG_BCM6358_USBH_PHY) += bcm6358-usbh-phy.o
obj-$(CONFIG_BCM6368_USBH_PHY) += bcm6368-usbh-phy.o
obj-$(CONFIG_BCM_SR_PCIE_PHY) += phy-bcm-sr-pcie.o
obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
obj-$(CONFIG_AM654_PHY) += phy-ti-am654.o

View File

@ -0,0 +1,177 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Broadcom
*/
#include <common.h>
#include <dm.h>
#include <generic-phy.h>
#include <asm/io.h>
#include <linux/bitops.h>
/* we have up to 8 PAXB based RC. The 9th one is always PAXC */
#define SR_NR_PCIE_PHYS 8
#define PCIE_PIPEMUX_CFG_OFFSET 0x10c
#define PCIE_PIPEMUX_SELECT_STRAP GENMASK(3, 0)
#define CDRU_STRAP_DATA_LSW_OFFSET 0x5c
#define PCIE_PIPEMUX_SHIFT 19
#define PCIE_PIPEMUX_MASK GENMASK(3, 0)
/**
* struct sr_pcie_phy_core - Stingray PCIe PHY core control
*
* @dev: pointer to device
* @base: base register of PCIe SS
* @cdru: CDRU base address
* @pipemux: pipemuex strap
*/
struct sr_pcie_phy_core {
struct udevice *dev;
void __iomem *base;
void __iomem *cdru;
u32 pipemux;
};
/*
* PCIe PIPEMUX lookup table
*
* Each array index represents a PIPEMUX strap setting
* The array element represents a bitmap where a set bit means the PCIe
* core and associated serdes has been enabled as RC and is available for use
*/
static const u8 pipemux_table[] = {
/* PIPEMUX = 0, EP 1x16 */
0x00,
/* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
0x80,
/* PIPEMUX = 2, EP 4x4 */
0x00,
/* PIPEMUX = 3, RC 2x8, cores 0, 7 */
0x81,
/* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
0xc3,
/* PIPEMUX = 5, RC 8x2, all 8 cores */
0xff,
/* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
0xcd,
/* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
0xfd,
/* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
0xf0,
/* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
0xc0,
/* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
0x42,
/* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
0x3c,
/* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
0xfc,
/* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
0x4c,
};
/*
* Return true if the strap setting is valid
*/
static bool pipemux_strap_is_valid(u32 pipemux)
{
return !!(pipemux < ARRAY_SIZE(pipemux_table));
}
/*
* Read the PCIe PIPEMUX from strap
*/
static u32 pipemux_strap_read(struct sr_pcie_phy_core *core)
{
u32 pipemux;
/*
* Read PIPEMUX configuration register to determine the pipemux setting
*
* In the case when the value indicates using HW strap, fall back to
* use HW strap
*/
pipemux = readl(core->base + PCIE_PIPEMUX_CFG_OFFSET);
pipemux &= PCIE_PIPEMUX_MASK;
if (pipemux == PCIE_PIPEMUX_SELECT_STRAP) {
pipemux = readl(core->cdru + CDRU_STRAP_DATA_LSW_OFFSET);
pipemux >>= PCIE_PIPEMUX_SHIFT;
pipemux &= PCIE_PIPEMUX_MASK;
}
return pipemux;
}
static int sr_pcie_phy_init(struct phy *phy)
{
struct sr_pcie_phy_core *core = dev_get_priv(phy->dev);
unsigned int core_idx = phy->id;
debug("%s %lx\n", __func__, phy->id);
/*
* Check whether this PHY is for root complex or not. If yes, return
* zero so the host driver can proceed to enumeration. If not, return
* an error and that will force the host driver to bail out
*/
if (!!((pipemux_table[core->pipemux] >> core_idx) & 0x1))
return 0;
return -ENODEV;
}
static int sr_pcie_phy_xlate(struct phy *phy, struct ofnode_phandle_args *args)
{
debug("%s %d\n", __func__, args->args[0]);
if (args->args_count && args->args[0] < SR_NR_PCIE_PHYS)
phy->id = args->args[0];
else
return -ENODEV;
return 0;
}
static const struct phy_ops sr_pcie_phy_ops = {
.of_xlate = sr_pcie_phy_xlate,
.init = sr_pcie_phy_init,
};
static int sr_pcie_phy_probe(struct udevice *dev)
{
struct sr_pcie_phy_core *core = dev_get_priv(dev);
core->dev = dev;
core->base = (void __iomem *)devfdt_get_addr_name(dev, "reg_base");
core->cdru = (void __iomem *)devfdt_get_addr_name(dev, "cdru_base");
debug("ip base %p\n", core->base);
debug("cdru base %p\n", core->cdru);
/* read the PCIe PIPEMUX strap setting */
core->pipemux = pipemux_strap_read(core);
if (!pipemux_strap_is_valid(core->pipemux)) {
pr_err("invalid PCIe PIPEMUX strap %u\n", core->pipemux);
return -EIO;
}
debug("%s %#x\n", __func__, core->pipemux);
pr_info("Stingray PCIe PHY driver initialized\n");
return 0;
}
static const struct udevice_id sr_pcie_phy_match_table[] = {
{ .compatible = "brcm,sr-pcie-phy" },
{ }
};
U_BOOT_DRIVER(sr_pcie_phy) = {
.name = "sr-pcie-phy",
.id = UCLASS_PHY,
.probe = sr_pcie_phy_probe,
.of_match = sr_pcie_phy_match_table,
.ops = &sr_pcie_phy_ops,
.platdata_auto_alloc_size = sizeof(struct sr_pcie_phy_core),
.priv_auto_alloc_size = sizeof(struct sr_pcie_phy_core),
};

View File

@ -551,7 +551,7 @@ extern int net_restart_wrap; /* Tried all network devices */
enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL
TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
};
extern char net_boot_file_name[1024];/* Boot File name */

View File

@ -52,6 +52,7 @@ struct sntp_pkt_t {
unsigned long long transmit_timestamp;
} __attribute__((packed));
void sntp_start(void); /* Begin SNTP */
int sntp_prereq(void *data);
int sntp_start(void *data); /* Begin SNTP */
#endif /* __SNTP_H__ */

41
include/net/udp.h Normal file
View File

@ -0,0 +1,41 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com>
*/
#ifndef __UDP
#define __UDP
/**
* struct udp_ops - function to handle udp packet
*
* This structure provides the function to handle udp packet in
* the network loop.
*
* @prereq: callback called to check the requirement
* @start: callback called to start the protocol/feature
* @data: pointer to store private data (used by prereq and start)
*/
struct udp_ops {
int (*prereq)(void *data);
int (*start)(void *data);
void *data;
};
int udp_prereq(void);
int udp_start(void);
/**
* udp_loop() - network loop for udp protocol
*
* Launch a network loop for udp protocol and use callbacks
* provided in parameter @ops to initialize the loop, and then
* to handle udp packet.
*
* @ops: udp callback
* @return: 0 if success, otherwise < 0 on error
*/
int udp_loop(struct udp_ops *ops);
#endif

View File

@ -8,6 +8,12 @@ menuconfig NET
if NET
config PROT_UDP
bool "Enable generic udp framework"
help
Enable a generic udp framework that allows defining a custom
handler for udp protocol.
config BOOTP_SEND_HOSTNAME
bool "Send hostname to DNS server"
help

View File

@ -27,6 +27,7 @@ obj-$(CONFIG_CMD_SNTP) += sntp.o
obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
obj-$(CONFIG_UDP_FUNCTION_FASTBOOT) += fastboot.o
obj-$(CONFIG_CMD_WOL) += wol.o
obj-$(CONFIG_PROT_UDP) += udp.o
# Disable this warning as it is triggered by:
# sprintf(buf, index ? "foo%d" : "foo", index)

View File

@ -273,7 +273,7 @@ int eth_init(void)
if (!current) {
current = eth_get_dev();
if (!current) {
printf("No ethernet found.\n");
log_err("No ethernet found.\n");
return -ENODEV;
}
}
@ -414,7 +414,7 @@ int eth_initialize(void)
*/
uclass_first_device_check(UCLASS_ETH, &dev);
if (!dev) {
printf("No ethernet found.\n");
log_err("No ethernet found.\n");
bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
} else {
char *ethprime = env_get("ethprime");
@ -449,7 +449,7 @@ int eth_initialize(void)
} while (dev);
if (!num_devices)
printf("No ethernet found.\n");
log_err("No ethernet found.\n");
putc('\n');
}

View File

@ -261,7 +261,7 @@ int eth_initialize(void)
}
if (!eth_devices) {
puts("No ethernet found.\n");
log_err("No ethernet found.\n");
bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
} else {
struct eth_device *dev = eth_devices;
@ -319,7 +319,7 @@ int eth_init(void)
struct eth_device *old_current;
if (!eth_current) {
puts("No ethernet found.\n");
log_err("No ethernet found.\n");
return -ENODEV;
}

View File

@ -72,12 +72,6 @@
* We want: - load the boot file
* Next step: none
*
* SNTP:
*
* Prerequisites: - own ethernet address
* - own IP address
* We want: - network time
* Next step: none
*
* WOL:
*
@ -102,6 +96,7 @@
#if defined(CONFIG_CMD_PCAP)
#include <net/pcap.h>
#endif
#include <net/udp.h>
#if defined(CONFIG_LED_STATUS)
#include <miiphy.h>
#include <status_led.h>
@ -118,9 +113,6 @@
#include "nfs.h"
#include "ping.h"
#include "rarp.h"
#if defined(CONFIG_CMD_SNTP)
#include "sntp.h"
#endif
#if defined(CONFIG_CMD_WOL)
#include "wol.h"
#endif
@ -184,13 +176,6 @@ u32 net_boot_file_size;
/* Boot file size in blocks as reported by the DHCP server */
u32 net_boot_file_expected_size_in_blocks;
#if defined(CONFIG_CMD_SNTP)
/* NTP server IP address */
struct in_addr net_ntp_server;
/* offset time from UTC */
int net_ntp_time_offset;
#endif
static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
/* Receive packets */
uchar *net_rx_packets[PKTBUFSRX];
@ -520,11 +505,6 @@ restart:
nc_start();
break;
#endif
#if defined(CONFIG_CMD_SNTP)
case SNTP:
sntp_start();
break;
#endif
#if defined(CONFIG_CMD_DNS)
case DNS:
dns_start();
@ -544,6 +524,9 @@ restart:
break;
}
if (IS_ENABLED(CONFIG_PROT_UDP) && protocol == UDP)
udp_start();
break;
}
@ -1348,14 +1331,6 @@ static int net_check_prereq(enum proto_t protocol)
}
goto common;
#endif
#if defined(CONFIG_CMD_SNTP)
case SNTP:
if (net_ntp_server.s_addr == 0) {
puts("*** ERROR: NTP server address not given\n");
return 1;
}
goto common;
#endif
#if defined(CONFIG_CMD_DNS)
case DNS:
if (net_dns_server.s_addr == 0) {
@ -1364,6 +1339,13 @@ static int net_check_prereq(enum proto_t protocol)
}
goto common;
#endif
#if defined(CONFIG_PROT_UDP)
case UDP:
if (udp_prereq())
return 1;
goto common;
#endif
#if defined(CONFIG_CMD_NFS)
case NFS:
#endif
@ -1374,8 +1356,8 @@ static int net_check_prereq(enum proto_t protocol)
puts("*** ERROR: `serverip' not set\n");
return 1;
}
#if defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
defined(CONFIG_CMD_DNS)
#if defined(CONFIG_CMD_PING) || \
defined(CONFIG_CMD_DNS) || defined(CONFIG_PROT_UDP)
common:
#endif
/* Fall through */

View File

@ -12,12 +12,17 @@
#include <net.h>
#include <rtc.h>
#include "sntp.h"
#include <net/sntp.h>
#define SNTP_TIMEOUT 10000UL
static int sntp_our_port;
/* NTP server IP address */
struct in_addr net_ntp_server;
/* offset time from UTC */
int net_ntp_time_offset;
static void sntp_send(void)
{
struct sntp_pkt_t pkt;
@ -93,7 +98,25 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
net_set_state(NETLOOP_SUCCESS);
}
void sntp_start(void)
/*
* SNTP:
*
* Prerequisites: - own ethernet address
* - own IP address
* We want: - network time
* Next step: none
*/
int sntp_prereq(void *data)
{
if (net_ntp_server.s_addr == 0) {
puts("*** ERROR: NTP server address not given\n");
return 1;
}
return 0;
}
int sntp_start(void *data)
{
debug("%s\n", __func__);
@ -102,4 +125,6 @@ void sntp_start(void)
memset(net_server_ethaddr, 0, sizeof(net_server_ethaddr));
sntp_send();
return 0;
}

View File

@ -159,7 +159,8 @@ static unsigned short tftp_window_size_option = TFTP_WINDOWSIZE;
static inline int store_block(int block, uchar *src, unsigned int len)
{
ulong offset = block * tftp_block_size + tftp_block_wrap_offset;
ulong offset = block * tftp_block_size + tftp_block_wrap_offset -
tftp_block_size;
ulong newsize = offset + len;
ulong store_addr = tftp_load_addr + offset;
#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
@ -233,7 +234,8 @@ static void new_transfer(void)
static int load_block(unsigned block, uchar *dst, unsigned len)
{
/* We may want to get the final block from the previous set */
ulong offset = ((int)block - 1) * len + tftp_block_wrap_offset;
ulong offset = block * tftp_block_size + tftp_block_wrap_offset -
tftp_block_size;
ulong tosend = len;
tosend = min(net_boot_file_size - offset, tosend);
@ -502,6 +504,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
int block = ntohs(*s);
int ack_ok = (tftp_cur_block == block);
tftp_prev_block = tftp_cur_block;
tftp_cur_block = (unsigned short)(block + 1);
update_block_number();
if (ack_ok)
@ -651,7 +654,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
timeout_count_max = tftp_timeout_count_max;
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
if (store_block(tftp_cur_block - 1, pkt + 2, len)) {
if (store_block(tftp_cur_block, pkt + 2, len)) {
eth_halt();
net_set_state(NETLOOP_FAIL);
break;

46
net/udp.c Normal file
View File

@ -0,0 +1,46 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com>
*/
#include <common.h>
#include <net.h>
#include <net/udp.h>
static struct udp_ops *udp_ops;
int udp_prereq(void)
{
int ret = 0;
if (udp_ops->prereq)
ret = udp_ops->prereq(udp_ops->data);
return ret;
}
int udp_start(void)
{
return udp_ops->start(udp_ops->data);
}
int udp_loop(struct udp_ops *ops)
{
int ret = -1;
if (!ops) {
printf("%s: ops should not be null\n", __func__);
goto out;
}
if (!ops->start) {
printf("%s: no start function defined\n", __func__);
goto out;
}
udp_ops = ops;
ret = net_loop(UDP);
out:
return ret;
}