Merge branch 'master' of git://git.denx.de/u-boot-net
This commit is contained in:
commit
0eb4cf9c14
12
README
12
README
|
@ -5454,10 +5454,10 @@ List of environment variables (most likely not complete):
|
||||||
unset, then it will be made silent if the U-Boot console
|
unset, then it will be made silent if the U-Boot console
|
||||||
is silent.
|
is silent.
|
||||||
|
|
||||||
tftpsrcport - If this is set, the value is used for TFTP's
|
tftpsrcp - If this is set, the value is used for TFTP's
|
||||||
UDP source port.
|
UDP source port.
|
||||||
|
|
||||||
tftpdstport - If this is set, the value is used for TFTP's UDP
|
tftpdstp - If this is set, the value is used for TFTP's UDP
|
||||||
destination port instead of the Well Know Port 69.
|
destination port instead of the Well Know Port 69.
|
||||||
|
|
||||||
tftpblocksize - Block size to use for TFTP transfers; if not set,
|
tftpblocksize - Block size to use for TFTP transfers; if not set,
|
||||||
|
@ -5471,6 +5471,14 @@ List of environment variables (most likely not complete):
|
||||||
faster in networks with high packet loss rates or
|
faster in networks with high packet loss rates or
|
||||||
with unreliable TFTP servers.
|
with unreliable TFTP servers.
|
||||||
|
|
||||||
|
tftptimeoutcountmax - maximum count of TFTP timeouts (no
|
||||||
|
unit, minimum value = 0). Defines how many timeouts
|
||||||
|
can happen during a single file transfer before that
|
||||||
|
transfer is aborted. The default is 10, and 0 means
|
||||||
|
'no timeouts allowed'. Increasing this value may help
|
||||||
|
downloads succeed with high packet loss rates, or with
|
||||||
|
unreliable TFTP servers or client hardware.
|
||||||
|
|
||||||
vlan - When set to a value < 4095 the traffic over
|
vlan - When set to a value < 4095 the traffic over
|
||||||
Ethernet is encapsulated/received over 802.1q
|
Ethernet is encapsulated/received over 802.1q
|
||||||
VLAN tagged frames.
|
VLAN tagged frames.
|
||||||
|
|
|
@ -152,6 +152,11 @@ struct mii_dev *mdio_alloc(void)
|
||||||
return bus;
|
return bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mdio_free(struct mii_dev *bus)
|
||||||
|
{
|
||||||
|
free(bus);
|
||||||
|
}
|
||||||
|
|
||||||
int mdio_register(struct mii_dev *bus)
|
int mdio_register(struct mii_dev *bus)
|
||||||
{
|
{
|
||||||
if (!bus || !bus->name || !bus->read || !bus->write)
|
if (!bus || !bus->name || !bus->read || !bus->write)
|
||||||
|
@ -173,6 +178,20 @@ int mdio_register(struct mii_dev *bus)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mdio_unregister(struct mii_dev *bus)
|
||||||
|
{
|
||||||
|
if (!bus)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* delete it from the list */
|
||||||
|
list_del(&bus->link);
|
||||||
|
|
||||||
|
if (current_mii == bus)
|
||||||
|
current_mii = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void mdio_list_devices(void)
|
void mdio_list_devices(void)
|
||||||
{
|
{
|
||||||
struct list_head *entry;
|
struct list_head *entry;
|
||||||
|
|
|
@ -4,3 +4,4 @@ CONFIG_TARGET_BF527_EZKIT=y
|
||||||
CONFIG_NET_RANDOM_ETHADDR=y
|
CONFIG_NET_RANDOM_ETHADDR=y
|
||||||
CONFIG_SPI_FLASH=y
|
CONFIG_SPI_FLASH=y
|
||||||
CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y
|
CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y
|
||||||
|
CONFIG_NET_TFTP_VARS=n
|
||||||
|
|
|
@ -523,22 +523,15 @@ int uclass_post_probe_device(struct udevice *dev)
|
||||||
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
|
||||||
int uclass_pre_remove_device(struct udevice *dev)
|
int uclass_pre_remove_device(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct uclass_driver *uc_drv;
|
|
||||||
struct uclass *uc;
|
struct uclass *uc;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
uc = dev->uclass;
|
uc = dev->uclass;
|
||||||
uc_drv = uc->uc_drv;
|
|
||||||
if (uc->uc_drv->pre_remove) {
|
if (uc->uc_drv->pre_remove) {
|
||||||
ret = uc->uc_drv->pre_remove(dev);
|
ret = uc->uc_drv->pre_remove(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (uc_drv->per_device_auto_alloc_size) {
|
|
||||||
free(dev->uclass_priv);
|
|
||||||
dev->uclass_priv = NULL;
|
|
||||||
}
|
|
||||||
dev->seq = -1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -613,6 +613,17 @@ static int designware_eth_probe(struct udevice *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int designware_eth_remove(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct dw_eth_dev *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
free(priv->phydev);
|
||||||
|
mdio_unregister(priv->bus);
|
||||||
|
mdio_free(priv->bus);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct eth_ops designware_eth_ops = {
|
static const struct eth_ops designware_eth_ops = {
|
||||||
.start = designware_eth_start,
|
.start = designware_eth_start,
|
||||||
.send = designware_eth_send,
|
.send = designware_eth_send,
|
||||||
|
@ -653,6 +664,7 @@ U_BOOT_DRIVER(eth_designware) = {
|
||||||
.ofdata_to_platdata = designware_eth_ofdata_to_platdata,
|
.ofdata_to_platdata = designware_eth_ofdata_to_platdata,
|
||||||
.bind = designware_eth_bind,
|
.bind = designware_eth_bind,
|
||||||
.probe = designware_eth_probe,
|
.probe = designware_eth_probe,
|
||||||
|
.remove = designware_eth_remove,
|
||||||
.ops = &designware_eth_ops,
|
.ops = &designware_eth_ops,
|
||||||
.priv_auto_alloc_size = sizeof(struct dw_eth_dev),
|
.priv_auto_alloc_size = sizeof(struct dw_eth_dev),
|
||||||
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
|
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
|
||||||
|
|
|
@ -452,6 +452,17 @@ int pch_gbe_probe(struct udevice *dev)
|
||||||
return pch_gbe_phy_init(dev);
|
return pch_gbe_phy_init(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pch_gbe_remove(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct pch_gbe_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
free(priv->phydev);
|
||||||
|
mdio_unregister(priv->bus);
|
||||||
|
mdio_free(priv->bus);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct eth_ops pch_gbe_ops = {
|
static const struct eth_ops pch_gbe_ops = {
|
||||||
.start = pch_gbe_start,
|
.start = pch_gbe_start,
|
||||||
.send = pch_gbe_send,
|
.send = pch_gbe_send,
|
||||||
|
@ -470,6 +481,7 @@ U_BOOT_DRIVER(eth_pch_gbe) = {
|
||||||
.id = UCLASS_ETH,
|
.id = UCLASS_ETH,
|
||||||
.of_match = pch_gbe_ids,
|
.of_match = pch_gbe_ids,
|
||||||
.probe = pch_gbe_probe,
|
.probe = pch_gbe_probe,
|
||||||
|
.remove = pch_gbe_remove,
|
||||||
.ops = &pch_gbe_ops,
|
.ops = &pch_gbe_ops,
|
||||||
.priv_auto_alloc_size = sizeof(struct pch_gbe_priv),
|
.priv_auto_alloc_size = sizeof(struct pch_gbe_priv),
|
||||||
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
|
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
|
||||||
|
|
|
@ -22,6 +22,44 @@ static struct phy_driver KSZ804_driver = {
|
||||||
.shutdown = &genphy_shutdown,
|
.shutdown = &genphy_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct phy_driver KSZ8031_driver = {
|
||||||
|
.name = "Micrel KSZ8021/KSZ8031",
|
||||||
|
.uid = 0x221550,
|
||||||
|
.mask = 0xfffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &genphy_config,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KSZ8051
|
||||||
|
*/
|
||||||
|
#define MII_KSZ8051_PHY_OMSO 0x16
|
||||||
|
#define MII_KSZ8051_PHY_OMSO_NAND_TREE_ON (1 << 5)
|
||||||
|
|
||||||
|
static int ksz8051_config(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
unsigned val;
|
||||||
|
|
||||||
|
/* Disable NAND-tree */
|
||||||
|
val = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO);
|
||||||
|
val &= ~MII_KSZ8051_PHY_OMSO_NAND_TREE_ON;
|
||||||
|
phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO, val);
|
||||||
|
|
||||||
|
return genphy_config(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct phy_driver KSZ8051_driver = {
|
||||||
|
.name = "Micrel KSZ8051",
|
||||||
|
.uid = 0x221550,
|
||||||
|
.mask = 0xfffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &ksz8051_config,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
static struct phy_driver KSZ8081_driver = {
|
static struct phy_driver KSZ8081_driver = {
|
||||||
.name = "Micrel KSZ8081",
|
.name = "Micrel KSZ8081",
|
||||||
.uid = 0x221560,
|
.uid = 0x221560,
|
||||||
|
@ -282,6 +320,8 @@ static struct phy_driver ksz9031_driver = {
|
||||||
int phy_micrel_init(void)
|
int phy_micrel_init(void)
|
||||||
{
|
{
|
||||||
phy_register(&KSZ804_driver);
|
phy_register(&KSZ804_driver);
|
||||||
|
phy_register(&KSZ8031_driver);
|
||||||
|
phy_register(&KSZ8051_driver);
|
||||||
phy_register(&KSZ8081_driver);
|
phy_register(&KSZ8081_driver);
|
||||||
#ifdef CONFIG_PHY_MICREL_KSZ9021
|
#ifdef CONFIG_PHY_MICREL_KSZ9021
|
||||||
phy_register(&ksz9021_driver);
|
phy_register(&ksz9021_driver);
|
||||||
|
|
|
@ -671,8 +671,16 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
|
||||||
if (phydev)
|
if (phydev)
|
||||||
return phydev;
|
return phydev;
|
||||||
}
|
}
|
||||||
printf("Phy %d not found\n", ffs(phy_mask) - 1);
|
|
||||||
return phy_device_create(bus, ffs(phy_mask) - 1, 0xffffffff, interface);
|
debug("\n%s PHY: ", bus->name);
|
||||||
|
while (phy_mask) {
|
||||||
|
int addr = ffs(phy_mask) - 1;
|
||||||
|
debug("%d ", addr);
|
||||||
|
phy_mask &= ~(1 << addr);
|
||||||
|
}
|
||||||
|
debug("not found\n");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -781,7 +789,7 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
|
||||||
{
|
{
|
||||||
/* Soft Reset the PHY */
|
/* Soft Reset the PHY */
|
||||||
phy_reset(phydev);
|
phy_reset(phydev);
|
||||||
if (phydev->dev) {
|
if (phydev->dev && phydev->dev != dev) {
|
||||||
printf("%s:%d is connected to %s. Reconnecting to %s\n",
|
printf("%s:%d is connected to %s. Reconnecting to %s\n",
|
||||||
phydev->bus->name, phydev->addr,
|
phydev->bus->name, phydev->addr,
|
||||||
phydev->dev->name, dev->name);
|
phydev->dev->name, dev->name);
|
||||||
|
|
|
@ -581,7 +581,8 @@ int rtl8169_eth_recv(struct udevice *dev, int flags, uchar **packetp)
|
||||||
#else
|
#else
|
||||||
static int rtl_recv(struct eth_device *dev)
|
static int rtl_recv(struct eth_device *dev)
|
||||||
{
|
{
|
||||||
return rtl_recv_common((pci_dev_t)dev->priv, dev->iobase, NULL);
|
return rtl_recv_common((pci_dev_t)(unsigned long)dev->priv,
|
||||||
|
dev->iobase, NULL);
|
||||||
}
|
}
|
||||||
#endif /* nCONFIG_DM_ETH */
|
#endif /* nCONFIG_DM_ETH */
|
||||||
|
|
||||||
|
@ -666,8 +667,8 @@ int rtl8169_eth_send(struct udevice *dev, void *packet, int length)
|
||||||
#else
|
#else
|
||||||
static int rtl_send(struct eth_device *dev, void *packet, int length)
|
static int rtl_send(struct eth_device *dev, void *packet, int length)
|
||||||
{
|
{
|
||||||
return rtl_send_common((pci_dev_t)dev->priv, dev->iobase, packet,
|
return rtl_send_common((pci_dev_t)(unsigned long)dev->priv,
|
||||||
length);
|
dev->iobase, packet, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -846,7 +847,8 @@ RESET - Finish setting up the ethernet interface
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static int rtl_reset(struct eth_device *dev, bd_t *bis)
|
static int rtl_reset(struct eth_device *dev, bd_t *bis)
|
||||||
{
|
{
|
||||||
rtl8169_common_start((pci_dev_t)dev->priv, dev->enetaddr);
|
rtl8169_common_start((pci_dev_t)(unsigned long)dev->priv,
|
||||||
|
dev->enetaddr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,8 +120,9 @@
|
||||||
/* Some extra defines */
|
/* Some extra defines */
|
||||||
#define HS_USB_PKT_SIZE 512
|
#define HS_USB_PKT_SIZE 512
|
||||||
#define FS_USB_PKT_SIZE 64
|
#define FS_USB_PKT_SIZE 64
|
||||||
#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
|
/* 5/33 is lower limit for BURST_CAP to work */
|
||||||
#define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE)
|
#define DEFAULT_HS_BURST_CAP_SIZE (5 * HS_USB_PKT_SIZE)
|
||||||
|
#define DEFAULT_FS_BURST_CAP_SIZE (33 * FS_USB_PKT_SIZE)
|
||||||
#define DEFAULT_BULK_IN_DELAY 0x00002000
|
#define DEFAULT_BULK_IN_DELAY 0x00002000
|
||||||
#define MAX_SINGLE_PACKET_SIZE 2048
|
#define MAX_SINGLE_PACKET_SIZE 2048
|
||||||
#define EEPROM_MAC_OFFSET 0x01
|
#define EEPROM_MAC_OFFSET 0x01
|
||||||
|
@ -135,7 +136,7 @@
|
||||||
#define USB_BULK_SEND_TIMEOUT 5000
|
#define USB_BULK_SEND_TIMEOUT 5000
|
||||||
#define USB_BULK_RECV_TIMEOUT 5000
|
#define USB_BULK_RECV_TIMEOUT 5000
|
||||||
|
|
||||||
#define RX_URB_SIZE 2048
|
#define RX_URB_SIZE DEFAULT_HS_BURST_CAP_SIZE
|
||||||
#define PHY_CONNECT_TIMEOUT 5000
|
#define PHY_CONNECT_TIMEOUT 5000
|
||||||
|
|
||||||
#define TURBO_MODE
|
#define TURBO_MODE
|
||||||
|
@ -529,22 +530,6 @@ static int smsc95xx_init_common(struct usb_device *udev, struct ueth_data *dev,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = smsc95xx_read_reg(udev, HW_CFG, &read_buf);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
debug("Read Value from HW_CFG : 0x%08x\n", read_buf);
|
|
||||||
|
|
||||||
read_buf |= HW_CFG_BIR_;
|
|
||||||
ret = smsc95xx_write_reg(udev, HW_CFG, read_buf);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = smsc95xx_read_reg(udev, HW_CFG, &read_buf);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
debug("Read Value from HW_CFG after writing "
|
|
||||||
"HW_CFG_BIR_: 0x%08x\n", read_buf);
|
|
||||||
|
|
||||||
#ifdef TURBO_MODE
|
#ifdef TURBO_MODE
|
||||||
if (dev->pusb_dev->speed == USB_SPEED_HIGH) {
|
if (dev->pusb_dev->speed == USB_SPEED_HIGH) {
|
||||||
burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
|
burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
|
||||||
|
|
|
@ -59,7 +59,9 @@ struct phy_device *mdio_phydev_for_ethname(const char *devname);
|
||||||
void miiphy_listdev(void);
|
void miiphy_listdev(void);
|
||||||
|
|
||||||
struct mii_dev *mdio_alloc(void);
|
struct mii_dev *mdio_alloc(void);
|
||||||
|
void mdio_free(struct mii_dev *bus);
|
||||||
int mdio_register(struct mii_dev *bus);
|
int mdio_register(struct mii_dev *bus);
|
||||||
|
int mdio_unregister(struct mii_dev *bus);
|
||||||
void mdio_list_devices(void);
|
void mdio_list_devices(void);
|
||||||
|
|
||||||
#ifdef CONFIG_BITBANGMII
|
#ifdef CONFIG_BITBANGMII
|
||||||
|
|
|
@ -233,8 +233,8 @@ void eth_set_current(void); /* set nterface to ethcur var */
|
||||||
|
|
||||||
int eth_get_dev_index(void); /* get the device index */
|
int eth_get_dev_index(void); /* get the device index */
|
||||||
void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
|
void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
|
||||||
int eth_getenv_enetaddr(char *name, uchar *enetaddr);
|
int eth_getenv_enetaddr(const char *name, uchar *enetaddr);
|
||||||
int eth_setenv_enetaddr(char *name, const uchar *enetaddr);
|
int eth_setenv_enetaddr(const char *name, const uchar *enetaddr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the hardware address for an ethernet interface .
|
* Get the hardware address for an ethernet interface .
|
||||||
|
@ -516,7 +516,7 @@ enum proto_t {
|
||||||
TFTPSRV, TFTPPUT, LINKLOCAL
|
TFTPSRV, TFTPPUT, LINKLOCAL
|
||||||
};
|
};
|
||||||
|
|
||||||
extern char net_boot_file_name[128];/* Boot File name */
|
extern char net_boot_file_name[1024];/* Boot File name */
|
||||||
/* The actual transferred size of the bootfile (in bytes) */
|
/* The actual transferred size of the bootfile (in bytes) */
|
||||||
extern u32 net_boot_file_size;
|
extern u32 net_boot_file_size;
|
||||||
/* Boot file size in blocks as reported by the DHCP server */
|
/* Boot file size in blocks as reported by the DHCP server */
|
||||||
|
|
10
net/Kconfig
10
net/Kconfig
|
@ -22,4 +22,14 @@ config NETCONSOLE
|
||||||
Support the 'nc' input/output device for networked console.
|
Support the 'nc' input/output device for networked console.
|
||||||
See README.NetConsole for details.
|
See README.NetConsole for details.
|
||||||
|
|
||||||
|
config NET_TFTP_VARS
|
||||||
|
bool "Control TFTP timeout and count through environment"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
If set, allows controlling the TFTP timeout through the
|
||||||
|
environment variable tftptimeout, and the TFTP maximum
|
||||||
|
timeout count through the variable tftptimeoutcountmax.
|
||||||
|
If unset, timeout and maximum are hard-defined as 1 second
|
||||||
|
and 10 timouts per TFTP transfer.
|
||||||
|
|
||||||
endif # if NET
|
endif # if NET
|
||||||
|
|
|
@ -96,12 +96,12 @@ void arp_request(void)
|
||||||
arp_raw_request(net_ip, net_null_ethaddr, net_arp_wait_reply_ip);
|
arp_raw_request(net_ip, net_null_ethaddr, net_arp_wait_reply_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arp_timeout_check(void)
|
int arp_timeout_check(void)
|
||||||
{
|
{
|
||||||
ulong t;
|
ulong t;
|
||||||
|
|
||||||
if (!net_arp_wait_packet_ip.s_addr)
|
if (!net_arp_wait_packet_ip.s_addr)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
t = get_timer(0);
|
t = get_timer(0);
|
||||||
|
|
||||||
|
@ -112,12 +112,13 @@ void arp_timeout_check(void)
|
||||||
if (arp_wait_try >= ARP_TIMEOUT_COUNT) {
|
if (arp_wait_try >= ARP_TIMEOUT_COUNT) {
|
||||||
puts("\nARP Retry count exceeded; starting again\n");
|
puts("\nARP Retry count exceeded; starting again\n");
|
||||||
arp_wait_try = 0;
|
arp_wait_try = 0;
|
||||||
net_start_again();
|
net_set_state(NETLOOP_FAIL);
|
||||||
} else {
|
} else {
|
||||||
arp_wait_timer_start = t;
|
arp_wait_timer_start = t;
|
||||||
arp_request();
|
arp_request();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
|
void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
|
||||||
|
|
|
@ -25,7 +25,7 @@ void arp_init(void);
|
||||||
void arp_request(void);
|
void arp_request(void);
|
||||||
void arp_raw_request(struct in_addr source_ip, const uchar *targetEther,
|
void arp_raw_request(struct in_addr source_ip, const uchar *targetEther,
|
||||||
struct in_addr target_ip);
|
struct in_addr target_ip);
|
||||||
void arp_timeout_check(void);
|
int arp_timeout_check(void);
|
||||||
void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len);
|
void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len);
|
||||||
|
|
||||||
#endif /* __ARP_H__ */
|
#endif /* __ARP_H__ */
|
||||||
|
|
123
net/bootp.c
123
net/bootp.c
|
@ -64,6 +64,9 @@ char net_root_path[64] = {0,}; /* Our bootpath */
|
||||||
static dhcp_state_t dhcp_state = INIT;
|
static dhcp_state_t dhcp_state = INIT;
|
||||||
static u32 dhcp_leasetime;
|
static u32 dhcp_leasetime;
|
||||||
static struct in_addr dhcp_server_ip;
|
static struct in_addr dhcp_server_ip;
|
||||||
|
static u8 dhcp_option_overload;
|
||||||
|
#define OVERLOAD_FILE 1
|
||||||
|
#define OVERLOAD_SNAME 2
|
||||||
static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||||
unsigned src, unsigned len);
|
unsigned src, unsigned len);
|
||||||
|
|
||||||
|
@ -109,7 +112,8 @@ static bool bootp_match_id(ulong id)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len)
|
static int check_reply_packet(uchar *pkt, unsigned dest, unsigned src,
|
||||||
|
unsigned len)
|
||||||
{
|
{
|
||||||
struct bootp_hdr *bp = (struct bootp_hdr *)pkt;
|
struct bootp_hdr *bp = (struct bootp_hdr *)pkt;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
@ -118,11 +122,7 @@ static int check_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
else if (len < sizeof(struct bootp_hdr) - OPT_FIELD_SIZE)
|
else if (len < sizeof(struct bootp_hdr) - OPT_FIELD_SIZE)
|
||||||
retval = -2;
|
retval = -2;
|
||||||
else if (bp->bp_op != OP_BOOTREQUEST &&
|
else if (bp->bp_op != OP_BOOTREPLY)
|
||||||
bp->bp_op != OP_BOOTREPLY &&
|
|
||||||
bp->bp_op != DHCP_OFFER &&
|
|
||||||
bp->bp_op != DHCP_ACK &&
|
|
||||||
bp->bp_op != DHCP_NAK)
|
|
||||||
retval = -3;
|
retval = -3;
|
||||||
else if (bp->bp_htype != HWT_ETHER)
|
else if (bp->bp_htype != HWT_ETHER)
|
||||||
retval = -4;
|
retval = -4;
|
||||||
|
@ -149,9 +149,14 @@ static void store_net_params(struct bootp_hdr *bp)
|
||||||
net_copy_ip(&net_server_ip, &bp->bp_siaddr);
|
net_copy_ip(&net_server_ip, &bp->bp_siaddr);
|
||||||
memcpy(net_server_ethaddr,
|
memcpy(net_server_ethaddr,
|
||||||
((struct ethernet_hdr *)net_rx_packet)->et_src, 6);
|
((struct ethernet_hdr *)net_rx_packet)->et_src, 6);
|
||||||
if (strlen(bp->bp_file) > 0)
|
if (
|
||||||
|
#if defined(CONFIG_CMD_DHCP)
|
||||||
|
!(dhcp_option_overload & OVERLOAD_FILE) &&
|
||||||
|
#endif
|
||||||
|
(strlen(bp->bp_file) > 0)) {
|
||||||
copy_filename(net_boot_file_name, bp->bp_file,
|
copy_filename(net_boot_file_name, bp->bp_file,
|
||||||
sizeof(net_boot_file_name));
|
sizeof(net_boot_file_name));
|
||||||
|
}
|
||||||
|
|
||||||
debug("net_boot_file_name: %s\n", net_boot_file_name);
|
debug("net_boot_file_name: %s\n", net_boot_file_name);
|
||||||
|
|
||||||
|
@ -343,13 +348,13 @@ static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||||
bp = (struct bootp_hdr *)pkt;
|
bp = (struct bootp_hdr *)pkt;
|
||||||
|
|
||||||
/* Filter out pkts we don't want */
|
/* Filter out pkts we don't want */
|
||||||
if (check_packet(pkt, dest, src, len))
|
if (check_reply_packet(pkt, dest, src, len))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Got a good BOOTP reply. Copy the data into our variables.
|
* Got a good BOOTP reply. Copy the data into our variables.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_STATUS_LED
|
#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
|
||||||
status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
|
status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -498,7 +503,9 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_BOOTP_VCI_STRING
|
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING)
|
||||||
|
put_vci(e, CONFIG_SPL_NET_VCI_STRING);
|
||||||
|
#elif defined(CONFIG_BOOTP_VCI_STRING)
|
||||||
put_vci(e, CONFIG_BOOTP_VCI_STRING);
|
put_vci(e, CONFIG_BOOTP_VCI_STRING);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -712,7 +719,11 @@ void bootp_request(void)
|
||||||
bp->bp_htype = HWT_ETHER;
|
bp->bp_htype = HWT_ETHER;
|
||||||
bp->bp_hlen = HWL_ETHER;
|
bp->bp_hlen = HWL_ETHER;
|
||||||
bp->bp_hops = 0;
|
bp->bp_hops = 0;
|
||||||
bp->bp_secs = htons(get_timer(0) / 1000);
|
/*
|
||||||
|
* according to RFC1542, should be 0 on first request, secs since
|
||||||
|
* first request otherwise
|
||||||
|
*/
|
||||||
|
bp->bp_secs = htons(get_timer(bootp_start) / 1000);
|
||||||
zero_ip.s_addr = 0;
|
zero_ip.s_addr = 0;
|
||||||
net_write_ip(&bp->bp_ciaddr, zero_ip);
|
net_write_ip(&bp->bp_ciaddr, zero_ip);
|
||||||
net_write_ip(&bp->bp_yiaddr, zero_ip);
|
net_write_ip(&bp->bp_yiaddr, zero_ip);
|
||||||
|
@ -762,9 +773,8 @@ void bootp_request(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_DHCP)
|
#if defined(CONFIG_CMD_DHCP)
|
||||||
static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
|
static void dhcp_process_options(uchar *popt, uchar *end)
|
||||||
{
|
{
|
||||||
uchar *end = popt + BOOTP_HDR_SIZE;
|
|
||||||
int oplen, size;
|
int oplen, size;
|
||||||
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
|
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
|
||||||
int *to_ptr;
|
int *to_ptr;
|
||||||
|
@ -773,6 +783,9 @@ static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
|
||||||
while (popt < end && *popt != 0xff) {
|
while (popt < end && *popt != 0xff) {
|
||||||
oplen = *(popt + 1);
|
oplen = *(popt + 1);
|
||||||
switch (*popt) {
|
switch (*popt) {
|
||||||
|
case 0:
|
||||||
|
oplen = -1; /* Pad omits len byte */
|
||||||
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
net_copy_ip(&net_netmask, (popt + 2));
|
net_copy_ip(&net_netmask, (popt + 2));
|
||||||
break;
|
break;
|
||||||
|
@ -817,6 +830,9 @@ static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
|
||||||
case 51:
|
case 51:
|
||||||
net_copy_u32(&dhcp_leasetime, (u32 *)(popt + 2));
|
net_copy_u32(&dhcp_leasetime, (u32 *)(popt + 2));
|
||||||
break;
|
break;
|
||||||
|
case 52:
|
||||||
|
dhcp_option_overload = popt[2];
|
||||||
|
break;
|
||||||
case 53: /* Ignore Message Type Option */
|
case 53: /* Ignore Message Type Option */
|
||||||
break;
|
break;
|
||||||
case 54:
|
case 54:
|
||||||
|
@ -828,31 +844,11 @@ static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
|
||||||
break;
|
break;
|
||||||
case 66: /* Ignore TFTP server name */
|
case 66: /* Ignore TFTP server name */
|
||||||
break;
|
break;
|
||||||
case 67: /* vendor opt bootfile */
|
case 67: /* Bootfile option */
|
||||||
/*
|
size = truncate_sz("Bootfile",
|
||||||
* I can't use dhcp_vendorex_proc here because I need
|
sizeof(net_boot_file_name), oplen);
|
||||||
* to write into the bootp packet - even then I had to
|
memcpy(&net_boot_file_name, popt + 2, size);
|
||||||
* pass the bootp packet pointer into here as the
|
net_boot_file_name[size] = 0;
|
||||||
* second arg
|
|
||||||
*/
|
|
||||||
size = truncate_sz("Opt Boot File",
|
|
||||||
sizeof(bp->bp_file),
|
|
||||||
oplen);
|
|
||||||
if (bp->bp_file[0] == '\0' && size > 0) {
|
|
||||||
/*
|
|
||||||
* only use vendor boot file if we didn't
|
|
||||||
* receive a boot file in the main non-vendor
|
|
||||||
* part of the packet - god only knows why
|
|
||||||
* some vendors chose not to use this perfectly
|
|
||||||
* good spot to store the boot file (join on
|
|
||||||
* Tru64 Unix) it seems mind bogglingly crazy
|
|
||||||
* to me
|
|
||||||
*/
|
|
||||||
printf("*** WARNING: using vendor "
|
|
||||||
"optional boot file\n");
|
|
||||||
memcpy(bp->bp_file, popt + 2, size);
|
|
||||||
bp->bp_file[size] = '\0';
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#if defined(CONFIG_BOOTP_VENDOREX)
|
#if defined(CONFIG_BOOTP_VENDOREX)
|
||||||
|
@ -867,6 +863,35 @@ static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dhcp_packet_process_options(struct bootp_hdr *bp)
|
||||||
|
{
|
||||||
|
uchar *popt = (uchar *)&bp->bp_vend[4];
|
||||||
|
uchar *end = popt + BOOTP_HDR_SIZE;
|
||||||
|
|
||||||
|
if (net_read_u32((u32 *)&bp->bp_vend[0]) != htonl(BOOTP_VENDOR_MAGIC))
|
||||||
|
return;
|
||||||
|
|
||||||
|
dhcp_option_overload = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 'options' field MUST be interpreted first, 'file' next,
|
||||||
|
* 'sname' last.
|
||||||
|
*/
|
||||||
|
dhcp_process_options(popt, end);
|
||||||
|
|
||||||
|
if (dhcp_option_overload & OVERLOAD_FILE) {
|
||||||
|
popt = (uchar *)bp->bp_file;
|
||||||
|
end = popt + sizeof(bp->bp_file);
|
||||||
|
dhcp_process_options(popt, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dhcp_option_overload & OVERLOAD_SNAME) {
|
||||||
|
popt = (uchar *)bp->bp_sname;
|
||||||
|
end = popt + sizeof(bp->bp_sname);
|
||||||
|
dhcp_process_options(popt, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int dhcp_message_type(unsigned char *popt)
|
static int dhcp_message_type(unsigned char *popt)
|
||||||
{
|
{
|
||||||
if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
|
if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
|
||||||
|
@ -876,7 +901,13 @@ static int dhcp_message_type(unsigned char *popt)
|
||||||
while (*popt != 0xff) {
|
while (*popt != 0xff) {
|
||||||
if (*popt == 53) /* DHCP Message Type */
|
if (*popt == 53) /* DHCP Message Type */
|
||||||
return *(popt + 2);
|
return *(popt + 2);
|
||||||
popt += *(popt + 1) + 2; /* Scan through all options */
|
if (*popt == 0) {
|
||||||
|
/* Pad */
|
||||||
|
popt += 1;
|
||||||
|
} else {
|
||||||
|
/* Scan through all options */
|
||||||
|
popt += *(popt + 1) + 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -906,7 +937,7 @@ static void dhcp_send_request_packet(struct bootp_hdr *bp_offer)
|
||||||
bp->bp_htype = HWT_ETHER;
|
bp->bp_htype = HWT_ETHER;
|
||||||
bp->bp_hlen = HWL_ETHER;
|
bp->bp_hlen = HWL_ETHER;
|
||||||
bp->bp_hops = 0;
|
bp->bp_hops = 0;
|
||||||
bp->bp_secs = htons(get_timer(0) / 1000);
|
bp->bp_secs = htons(get_timer(bootp_start) / 1000);
|
||||||
/* Do not set the client IP, your IP, or server IP yet, since it
|
/* Do not set the client IP, your IP, or server IP yet, since it
|
||||||
* hasn't been ACK'ed by the server yet */
|
* hasn't been ACK'ed by the server yet */
|
||||||
|
|
||||||
|
@ -958,7 +989,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||||
src, dest, len, dhcp_state);
|
src, dest, len, dhcp_state);
|
||||||
|
|
||||||
/* Filter out pkts we don't want */
|
/* Filter out pkts we don't want */
|
||||||
if (check_packet(pkt, dest, src, len))
|
if (check_reply_packet(pkt, dest, src, len))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: "
|
debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: "
|
||||||
|
@ -978,14 +1009,11 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||||
CONFIG_SYS_BOOTFILE_PREFIX,
|
CONFIG_SYS_BOOTFILE_PREFIX,
|
||||||
strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
|
strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
|
||||||
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
|
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
|
||||||
|
dhcp_packet_process_options(bp);
|
||||||
|
|
||||||
debug("TRANSITIONING TO REQUESTING STATE\n");
|
debug("TRANSITIONING TO REQUESTING STATE\n");
|
||||||
dhcp_state = REQUESTING;
|
dhcp_state = REQUESTING;
|
||||||
|
|
||||||
if (net_read_u32((u32 *)&bp->bp_vend[0]) ==
|
|
||||||
htonl(BOOTP_VENDOR_MAGIC))
|
|
||||||
dhcp_process_options((u8 *)&bp->bp_vend[4], bp);
|
|
||||||
|
|
||||||
net_set_timeout_handler(5000, bootp_timeout_handler);
|
net_set_timeout_handler(5000, bootp_timeout_handler);
|
||||||
dhcp_send_request_packet(bp);
|
dhcp_send_request_packet(bp);
|
||||||
#ifdef CONFIG_SYS_BOOTFILE_PREFIX
|
#ifdef CONFIG_SYS_BOOTFILE_PREFIX
|
||||||
|
@ -998,14 +1026,13 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||||
debug("DHCP State: REQUESTING\n");
|
debug("DHCP State: REQUESTING\n");
|
||||||
|
|
||||||
if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
|
if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
|
||||||
if (net_read_u32((u32 *)&bp->bp_vend[0]) ==
|
dhcp_packet_process_options(bp);
|
||||||
htonl(BOOTP_VENDOR_MAGIC))
|
|
||||||
dhcp_process_options((u8 *)&bp->bp_vend[4], bp);
|
|
||||||
/* Store net params from reply */
|
/* Store net params from reply */
|
||||||
store_net_params(bp);
|
store_net_params(bp);
|
||||||
dhcp_state = BOUND;
|
dhcp_state = BOUND;
|
||||||
printf("DHCP client bound to address %pI4 (%lu ms)\n",
|
printf("DHCP client bound to address %pI4 (%lu ms)\n",
|
||||||
&net_ip, get_timer(bootp_start));
|
&net_ip, get_timer(bootp_start));
|
||||||
|
net_set_timeout_handler(0, (thand_f *)0);
|
||||||
bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
|
bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
|
||||||
"bootp_stop");
|
"bootp_stop");
|
||||||
|
|
||||||
|
|
27
net/eth.c
27
net/eth.c
|
@ -31,13 +31,13 @@ void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int eth_getenv_enetaddr(char *name, uchar *enetaddr)
|
int eth_getenv_enetaddr(const char *name, uchar *enetaddr)
|
||||||
{
|
{
|
||||||
eth_parse_enetaddr(getenv(name), enetaddr);
|
eth_parse_enetaddr(getenv(name), enetaddr);
|
||||||
return is_valid_ethaddr(enetaddr);
|
return is_valid_ethaddr(enetaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int eth_setenv_enetaddr(char *name, const uchar *enetaddr)
|
int eth_setenv_enetaddr(const char *name, const uchar *enetaddr)
|
||||||
{
|
{
|
||||||
char buf[20];
|
char buf[20];
|
||||||
|
|
||||||
|
@ -179,8 +179,12 @@ struct udevice *eth_get_dev(void)
|
||||||
*/
|
*/
|
||||||
static void eth_set_dev(struct udevice *dev)
|
static void eth_set_dev(struct udevice *dev)
|
||||||
{
|
{
|
||||||
if (dev && !device_active(dev))
|
if (dev && !device_active(dev)) {
|
||||||
eth_errno = device_probe(dev);
|
eth_errno = device_probe(dev);
|
||||||
|
if (eth_errno)
|
||||||
|
dev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
eth_get_uclass_priv()->current = dev;
|
eth_get_uclass_priv()->current = dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,10 +217,9 @@ struct udevice *eth_get_dev_by_name(const char *devname)
|
||||||
* match an alias or it will match a literal name and we'll pick
|
* match an alias or it will match a literal name and we'll pick
|
||||||
* up the error when we try to probe again in eth_set_dev().
|
* up the error when we try to probe again in eth_set_dev().
|
||||||
*/
|
*/
|
||||||
device_probe(it);
|
if (device_probe(it))
|
||||||
/*
|
continue;
|
||||||
* Check for the name or the sequence number to match
|
/* Check for the name or the sequence number to match */
|
||||||
*/
|
|
||||||
if (strcmp(it->name, devname) == 0 ||
|
if (strcmp(it->name, devname) == 0 ||
|
||||||
(endp > startp && it->seq == seq))
|
(endp > startp && it->seq == seq))
|
||||||
return it;
|
return it;
|
||||||
|
@ -346,6 +349,7 @@ int eth_init(void)
|
||||||
|
|
||||||
old_current = current;
|
old_current = current;
|
||||||
do {
|
do {
|
||||||
|
if (current) {
|
||||||
debug("Trying %s\n", current->name);
|
debug("Trying %s\n", current->name);
|
||||||
|
|
||||||
if (device_active(current)) {
|
if (device_active(current)) {
|
||||||
|
@ -362,6 +366,9 @@ int eth_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("FAIL\n");
|
debug("FAIL\n");
|
||||||
|
} else {
|
||||||
|
debug("PROBE FAIL\n");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If ethrotate is enabled, this will change "current",
|
* If ethrotate is enabled, this will change "current",
|
||||||
|
@ -575,8 +582,13 @@ static int eth_post_probe(struct udevice *dev)
|
||||||
|
|
||||||
static int eth_pre_remove(struct udevice *dev)
|
static int eth_pre_remove(struct udevice *dev)
|
||||||
{
|
{
|
||||||
|
struct eth_pdata *pdata = dev->platdata;
|
||||||
|
|
||||||
eth_get_ops(dev)->stop(dev);
|
eth_get_ops(dev)->stop(dev);
|
||||||
|
|
||||||
|
/* clear the MAC address */
|
||||||
|
memset(pdata->enetaddr, 0, 6);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,6 +703,7 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op,
|
||||||
memset(dev->enetaddr, 0, 6);
|
memset(dev->enetaddr, 0, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dev = dev->next;
|
||||||
} while (dev != eth_devices);
|
} while (dev != eth_devices);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -164,7 +164,7 @@ ushort net_our_vlan = 0xFFFF;
|
||||||
ushort net_native_vlan = 0xFFFF;
|
ushort net_native_vlan = 0xFFFF;
|
||||||
|
|
||||||
/* Boot File name */
|
/* Boot File name */
|
||||||
char net_boot_file_name[128];
|
char net_boot_file_name[1024];
|
||||||
/* The actual transferred size of the bootfile (in bytes) */
|
/* The actual transferred size of the bootfile (in bytes) */
|
||||||
u32 net_boot_file_size;
|
u32 net_boot_file_size;
|
||||||
/* Boot file size in blocks as reported by the DHCP server */
|
/* Boot file size in blocks as reported by the DHCP server */
|
||||||
|
@ -569,7 +569,9 @@ restart:
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
arp_timeout_check();
|
if (arp_timeout_check() > 0) {
|
||||||
|
time_start = get_timer(0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for a timeout, and run the timeout handler
|
* Check for a timeout, and run the timeout handler
|
||||||
|
|
17
net/tftp.c
17
net/tftp.c
|
@ -602,7 +602,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||||
}
|
}
|
||||||
|
|
||||||
tftp_prev_block = tftp_cur_block;
|
tftp_prev_block = tftp_cur_block;
|
||||||
timeout_count_max = TIMEOUT_COUNT;
|
timeout_count_max = tftp_timeout_count_max;
|
||||||
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
|
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
|
||||||
|
|
||||||
store_block(tftp_cur_block - 1, pkt + 2, len);
|
store_block(tftp_cur_block - 1, pkt + 2, len);
|
||||||
|
@ -697,12 +697,14 @@ static void tftp_timeout_handler(void)
|
||||||
|
|
||||||
void tftp_start(enum proto_t protocol)
|
void tftp_start(enum proto_t protocol)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_NET_TFTP_VARS
|
||||||
char *ep; /* Environment pointer */
|
char *ep; /* Environment pointer */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow the user to choose TFTP blocksize and timeout.
|
* Allow the user to choose TFTP blocksize and timeout.
|
||||||
* TFTP protocol has a minimal timeout of 1 second.
|
* TFTP protocol has a minimal timeout of 1 second.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ep = getenv("tftpblocksize");
|
ep = getenv("tftpblocksize");
|
||||||
if (ep != NULL)
|
if (ep != NULL)
|
||||||
tftp_block_size_option = simple_strtol(ep, NULL, 10);
|
tftp_block_size_option = simple_strtol(ep, NULL, 10);
|
||||||
|
@ -717,6 +719,17 @@ void tftp_start(enum proto_t protocol)
|
||||||
timeout_ms = 1000;
|
timeout_ms = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ep = getenv("tftptimeoutcountmax");
|
||||||
|
if (ep != NULL)
|
||||||
|
tftp_timeout_count_max = simple_strtol(ep, NULL, 10);
|
||||||
|
|
||||||
|
if (tftp_timeout_count_max < 0) {
|
||||||
|
printf("TFTP timeout count max (%d ms) negative, set to 0\n",
|
||||||
|
tftp_timeout_count_max);
|
||||||
|
tftp_timeout_count_max = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
debug("TFTP blocksize = %i, timeout = %ld ms\n",
|
debug("TFTP blocksize = %i, timeout = %ld ms\n",
|
||||||
tftp_block_size_option, timeout_ms);
|
tftp_block_size_option, timeout_ms);
|
||||||
|
|
||||||
|
@ -842,7 +855,7 @@ void tftp_start_server(void)
|
||||||
|
|
||||||
puts("Loading: *\b");
|
puts("Loading: *\b");
|
||||||
|
|
||||||
timeout_count_max = TIMEOUT_COUNT;
|
timeout_count_max = tftp_timeout_count_max;
|
||||||
timeout_count = 0;
|
timeout_count = 0;
|
||||||
timeout_ms = TIMEOUT;
|
timeout_ms = TIMEOUT;
|
||||||
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
|
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
|
||||||
|
|
|
@ -13,11 +13,15 @@
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <dm/test.h>
|
#include <dm/test.h>
|
||||||
|
#include <dm/device-internal.h>
|
||||||
|
#include <dm/uclass-internal.h>
|
||||||
#include <asm/eth.h>
|
#include <asm/eth.h>
|
||||||
#include <test/ut.h>
|
#include <test/ut.h>
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
#define DM_TEST_ETH_NUM 4
|
||||||
|
|
||||||
static int dm_test_eth(struct unit_test_state *uts)
|
static int dm_test_eth(struct unit_test_state *uts)
|
||||||
{
|
{
|
||||||
net_ping_ip = string_to_ip("1.1.2.2");
|
net_ping_ip = string_to_ip("1.1.2.2");
|
||||||
|
@ -82,6 +86,66 @@ static int dm_test_eth_prime(struct unit_test_state *uts)
|
||||||
}
|
}
|
||||||
DM_TEST(dm_test_eth_prime, DM_TESTF_SCAN_FDT);
|
DM_TEST(dm_test_eth_prime, DM_TESTF_SCAN_FDT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test case is trying to test the following scenario:
|
||||||
|
* - All ethernet devices are not probed
|
||||||
|
* - "ethaddr" for all ethernet devices are not set
|
||||||
|
* - "ethact" is set to a valid ethernet device name
|
||||||
|
*
|
||||||
|
* With Sandbox default test configuration, all ethernet devices are
|
||||||
|
* probed after power-up, so we have to manually create such scenario:
|
||||||
|
* - Remove all ethernet devices
|
||||||
|
* - Remove all "ethaddr" environment variables
|
||||||
|
* - Set "ethact" to the first ethernet device
|
||||||
|
*
|
||||||
|
* Do a ping test to see if anything goes wrong.
|
||||||
|
*/
|
||||||
|
static int dm_test_eth_act(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct udevice *dev[DM_TEST_ETH_NUM];
|
||||||
|
const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
|
||||||
|
"sbe5", "eth@10004000"};
|
||||||
|
const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
|
||||||
|
"eth3addr", "eth1addr"};
|
||||||
|
char ethaddr[DM_TEST_ETH_NUM][18];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
net_ping_ip = string_to_ip("1.1.2.2");
|
||||||
|
|
||||||
|
/* Prepare the test scenario */
|
||||||
|
for (i = 0; i < DM_TEST_ETH_NUM; i++) {
|
||||||
|
ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
|
||||||
|
ethname[i], &dev[i]));
|
||||||
|
ut_assertok(device_remove(dev[i]));
|
||||||
|
|
||||||
|
/* Invalidate MAC address */
|
||||||
|
strcpy(ethaddr[i], getenv(addrname[i]));
|
||||||
|
/* Must disable access protection for ethaddr before clearing */
|
||||||
|
setenv(".flags", addrname[i]);
|
||||||
|
setenv(addrname[i], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set ethact to "eth@10002000" */
|
||||||
|
setenv("ethact", ethname[0]);
|
||||||
|
|
||||||
|
/* Segment fault might happen if something is wrong */
|
||||||
|
ut_asserteq(-ENODEV, net_loop(PING));
|
||||||
|
|
||||||
|
for (i = 0; i < DM_TEST_ETH_NUM; i++) {
|
||||||
|
/* Restore the env */
|
||||||
|
setenv(".flags", addrname[i]);
|
||||||
|
setenv(addrname[i], ethaddr[i]);
|
||||||
|
|
||||||
|
/* Probe the device again */
|
||||||
|
ut_assertok(device_probe(dev[i]));
|
||||||
|
}
|
||||||
|
setenv(".flags", NULL);
|
||||||
|
setenv("ethact", NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_eth_act, DM_TESTF_SCAN_FDT);
|
||||||
|
|
||||||
/* The asserts include a return on fail; cleanup in the caller */
|
/* The asserts include a return on fail; cleanup in the caller */
|
||||||
static int _dm_test_eth_rotate1(struct unit_test_state *uts)
|
static int _dm_test_eth_rotate1(struct unit_test_state *uts)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue