Merge branch 'master' of git://git.denx.de/u-boot-net

This commit is contained in:
Tom Rini 2018-07-26 15:55:42 -04:00
commit a57d45db90
44 changed files with 831 additions and 319 deletions

View File

@ -9,6 +9,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/system.h> #include <asm/system.h>
#include <fm_eth.h>
#include <asm/armv8/mmu.h> #include <asm/armv8/mmu.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/fsl_serdes.h> #include <asm/arch/fsl_serdes.h>
@ -18,7 +19,6 @@
#include <fsl_immap.h> #include <fsl_immap.h>
#include <asm/arch/mp.h> #include <asm/arch/mp.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <fm_eth.h>
#include <fsl-mc/fsl_mc.h> #include <fsl-mc/fsl_mc.h>
#ifdef CONFIG_FSL_ESDHC #ifdef CONFIG_FSL_ESDHC
#include <fsl_esdhc.h> #include <fsl_esdhc.h>

View File

@ -1,9 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* /*
* Copyright (c) 2015 National Instruments * Copyright (c) 2015-2018 National Instruments
* * Copyright (c) 2015-2018 Joe Hershberger <joe.hershberger@ni.com>
* (C) Copyright 2015
* Joe Hershberger <joe.hershberger@ni.com>
*/ */
#include <asm/eth-raw-os.h> #include <asm/eth-raw-os.h>
@ -25,8 +23,46 @@
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
static int _raw_packet_start(const char *ifname, unsigned char *ethmac, struct sandbox_eth_raw_if_nameindex *sandbox_eth_raw_if_nameindex(void)
struct eth_sandbox_raw_priv *priv) {
return (struct sandbox_eth_raw_if_nameindex *)if_nameindex();
}
void sandbox_eth_raw_if_freenameindex(struct sandbox_eth_raw_if_nameindex *ptr)
{
if_freenameindex((struct if_nameindex *)ptr);
}
int sandbox_eth_raw_os_is_local(const char *ifname)
{
int fd = socket(AF_INET, SOCK_DGRAM, 0);
struct ifreq ifr;
int ret = 0;
if (fd < 0)
return -errno;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
if (ret < 0) {
ret = -errno;
goto out;
}
ret = !!(ifr.ifr_flags & IFF_LOOPBACK);
out:
close(fd);
return ret;
}
int sandbox_eth_raw_os_idx_to_name(struct eth_sandbox_raw_priv *priv)
{
if (!if_indextoname(priv->host_ifindex, priv->host_ifname))
return -errno;
return 0;
}
static int _raw_packet_start(struct eth_sandbox_raw_priv *priv,
unsigned char *ethmac)
{ {
struct sockaddr_ll *device; struct sockaddr_ll *device;
struct packet_mreq mr; struct packet_mreq mr;
@ -34,12 +70,14 @@ static int _raw_packet_start(const char *ifname, unsigned char *ethmac,
int flags; int flags;
/* Prepare device struct */ /* Prepare device struct */
priv->local_bind_sd = -1;
priv->device = malloc(sizeof(struct sockaddr_ll)); priv->device = malloc(sizeof(struct sockaddr_ll));
if (priv->device == NULL) if (priv->device == NULL)
return -ENOMEM; return -ENOMEM;
device = priv->device; device = priv->device;
memset(device, 0, sizeof(struct sockaddr_ll)); memset(device, 0, sizeof(struct sockaddr_ll));
device->sll_ifindex = if_nametoindex(ifname); device->sll_ifindex = if_nametoindex(priv->host_ifname);
priv->host_ifindex = device->sll_ifindex;
device->sll_family = AF_PACKET; device->sll_family = AF_PACKET;
memcpy(device->sll_addr, ethmac, 6); memcpy(device->sll_addr, ethmac, 6);
device->sll_halen = htons(6); device->sll_halen = htons(6);
@ -52,11 +90,11 @@ static int _raw_packet_start(const char *ifname, unsigned char *ethmac,
return -errno; return -errno;
} }
/* Bind to the specified interface */ /* Bind to the specified interface */
ret = setsockopt(priv->sd, SOL_SOCKET, SO_BINDTODEVICE, ifname, ret = setsockopt(priv->sd, SOL_SOCKET, SO_BINDTODEVICE,
strlen(ifname) + 1); priv->host_ifname, strlen(priv->host_ifname) + 1);
if (ret < 0) { if (ret < 0) {
printf("Failed to bind to '%s': %d %s\n", ifname, errno, printf("Failed to bind to '%s': %d %s\n", priv->host_ifname,
strerror(errno)); errno, strerror(errno));
return -errno; return -errno;
} }
@ -75,11 +113,12 @@ static int _raw_packet_start(const char *ifname, unsigned char *ethmac,
printf("Failed to set promiscuous mode: %d %s\n" printf("Failed to set promiscuous mode: %d %s\n"
"Falling back to the old \"flags\" way...\n", "Falling back to the old \"flags\" way...\n",
errno, strerror(errno)); errno, strerror(errno));
if (strlen(ifname) >= IFNAMSIZ) { if (strlen(priv->host_ifname) >= IFNAMSIZ) {
printf("Interface name %s is too long.\n", ifname); printf("Interface name %s is too long.\n",
priv->host_ifname);
return -EINVAL; return -EINVAL;
} }
strncpy(ifr.ifr_name, ifname, IFNAMSIZ); strncpy(ifr.ifr_name, priv->host_ifname, IFNAMSIZ);
if (ioctl(priv->sd, SIOCGIFFLAGS, &ifr) < 0) { if (ioctl(priv->sd, SIOCGIFFLAGS, &ifr) < 0) {
printf("Failed to read flags: %d %s\n", errno, printf("Failed to read flags: %d %s\n", errno,
strerror(errno)); strerror(errno));
@ -103,6 +142,8 @@ static int _local_inet_start(struct eth_sandbox_raw_priv *priv)
int one = 1; int one = 1;
/* Prepare device struct */ /* Prepare device struct */
priv->local_bind_sd = -1;
priv->local_bind_udp_port = 0;
priv->device = malloc(sizeof(struct sockaddr_in)); priv->device = malloc(sizeof(struct sockaddr_in));
if (priv->device == NULL) if (priv->device == NULL)
return -ENOMEM; return -ENOMEM;
@ -136,18 +177,16 @@ static int _local_inet_start(struct eth_sandbox_raw_priv *priv)
strerror(errno)); strerror(errno));
return -errno; return -errno;
} }
priv->local_bind_sd = -1;
priv->local_bind_udp_port = 0;
return 0; return 0;
} }
int sandbox_eth_raw_os_start(const char *ifname, unsigned char *ethmac, int sandbox_eth_raw_os_start(struct eth_sandbox_raw_priv *priv,
struct eth_sandbox_raw_priv *priv) unsigned char *ethmac)
{ {
if (priv->local) if (priv->local)
return _local_inet_start(priv); return _local_inet_start(priv);
else else
return _raw_packet_start(ifname, ethmac, priv); return _raw_packet_start(priv, ethmac);
} }
int sandbox_eth_raw_os_send(void *packet, int length, int sandbox_eth_raw_os_send(void *packet, int length,
@ -156,7 +195,7 @@ int sandbox_eth_raw_os_send(void *packet, int length,
int retval; int retval;
struct udphdr *udph = packet + sizeof(struct iphdr); struct udphdr *udph = packet + sizeof(struct iphdr);
if (!priv->sd || !priv->device) if (priv->sd < 0 || !priv->device)
return -EINVAL; return -EINVAL;
/* /*
@ -221,7 +260,7 @@ int sandbox_eth_raw_os_recv(void *packet, int *length,
int retval; int retval;
int saddr_size; int saddr_size;
if (!priv->sd || !priv->device) if (priv->sd < 0 || !priv->device)
return -EINVAL; return -EINVAL;
saddr_size = sizeof(struct sockaddr); saddr_size = sizeof(struct sockaddr);
retval = recvfrom(priv->sd, packet, 1536, 0, retval = recvfrom(priv->sd, packet, 1536, 0,

View File

@ -8,7 +8,6 @@
model = "sandbox"; model = "sandbox";
aliases { aliases {
eth5 = "/eth@90000000";
i2c0 = &i2c_0; i2c0 = &i2c_0;
pci0 = &pci; pci0 = &pci;
rtc0 = &rtc_0; rtc0 = &rtc_0;
@ -47,24 +46,17 @@
}; };
}; };
ethrawbus {
compatible = "sandbox,eth-raw-bus";
skip-localhost = <0>;
};
eth@10002000 { eth@10002000 {
compatible = "sandbox,eth"; compatible = "sandbox,eth";
reg = <0x10002000 0x1000>; reg = <0x10002000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 00]; fake-host-hwaddr = [00 00 66 44 22 00];
}; };
eth@80000000 {
compatible = "sandbox,eth-raw";
reg = <0x80000000 0x1000>;
host-raw-interface = "eth0";
};
eth@90000000 {
compatible = "sandbox,eth-raw";
reg = <0x90000000 0x1000>;
host-raw-interface = "lo";
};
gpio_a: gpios@0 { gpio_a: gpios@0 {
gpio-controller; gpio-controller;
compatible = "sandbox,gpio"; compatible = "sandbox,gpio";

View File

@ -8,7 +8,6 @@
model = "sandbox"; model = "sandbox";
aliases { aliases {
eth5 = "/eth@90000000";
i2c0 = &i2c_0; i2c0 = &i2c_0;
pci0 = &pci; pci0 = &pci;
rtc0 = &rtc_0; rtc0 = &rtc_0;
@ -47,24 +46,17 @@
}; };
}; };
ethrawbus {
compatible = "sandbox,eth-raw-bus";
skip-localhost = <1>;
};
eth@10002000 { eth@10002000 {
compatible = "sandbox,eth"; compatible = "sandbox,eth";
reg = <0x0 0x10002000 0x0 0x1000>; reg = <0x0 0x10002000 0x0 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 00]; fake-host-hwaddr = [00 00 66 44 22 00];
}; };
eth@80000000 {
compatible = "sandbox,eth-raw";
reg = <0x0 0x80000000 0x0 0x1000>;
host-raw-interface = "eth0";
};
eth@90000000 {
compatible = "sandbox,eth-raw";
reg = <0x0 0x90000000 0x0 0x1000>;
host-raw-interface = "lo";
};
gpio_a: gpios@0 { gpio_a: gpios@0 {
gpio-controller; gpio-controller;
compatible = "sandbox,gpio"; compatible = "sandbox,gpio";

View File

@ -155,25 +155,25 @@
eth@10002000 { eth@10002000 {
compatible = "sandbox,eth"; compatible = "sandbox,eth";
reg = <0x10002000 0x1000>; reg = <0x10002000 0x1000>;
fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>; fake-host-hwaddr = [00 00 66 44 22 00];
}; };
eth_5: eth@10003000 { eth_5: eth@10003000 {
compatible = "sandbox,eth"; compatible = "sandbox,eth";
reg = <0x10003000 0x1000>; reg = <0x10003000 0x1000>;
fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>; fake-host-hwaddr = [00 00 66 44 22 11];
}; };
eth_3: sbe5 { eth_3: sbe5 {
compatible = "sandbox,eth"; compatible = "sandbox,eth";
reg = <0x10005000 0x1000>; reg = <0x10005000 0x1000>;
fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x33>; fake-host-hwaddr = [00 00 66 44 22 33];
}; };
eth@10004000 { eth@10004000 {
compatible = "sandbox,eth"; compatible = "sandbox,eth";
reg = <0x10004000 0x1000>; reg = <0x10004000 0x1000>;
fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>; fake-host-hwaddr = [00 00 66 44 22 22];
}; };
gpio_a: base-gpios { gpio_a: base-gpios {

View File

@ -9,10 +9,14 @@
#ifndef __ETH_RAW_OS_H #ifndef __ETH_RAW_OS_H
#define __ETH_RAW_OS_H #define __ETH_RAW_OS_H
#define IFNAMSIZ 16
/** /**
* struct eth_sandbox_raw_priv - raw socket session * struct eth_sandbox_raw_priv - raw socket session
* *
* sd: socket descriptor - the open socket during a session * sd: socket descriptor - the open socket during a session
* host_ifname: interface name on the host to use for sending our packets
* host_ifindex: interface index number on the host
* device: struct sockaddr_ll - the host interface packets move to/from * device: struct sockaddr_ll - the host interface packets move to/from
* local: 1 or 0 to select the local interface ('lo') or not * local: 1 or 0 to select the local interface ('lo') or not
* local_bindsd: socket descriptor to prevent the kernel from sending * local_bindsd: socket descriptor to prevent the kernel from sending
@ -22,14 +26,44 @@
*/ */
struct eth_sandbox_raw_priv { struct eth_sandbox_raw_priv {
int sd; int sd;
char host_ifname[IFNAMSIZ];
unsigned int host_ifindex;
void *device; void *device;
int local; int local;
int local_bind_sd; int local_bind_sd;
unsigned short local_bind_udp_port; unsigned short local_bind_udp_port;
}; };
int sandbox_eth_raw_os_start(const char *ifname, unsigned char *ethmac, /* A struct to mimic if_nameindex but that does not depend on Linux headers */
struct eth_sandbox_raw_priv *priv); struct sandbox_eth_raw_if_nameindex {
unsigned int if_index; /* Index of interface (1, 2, ...) */
char *if_name; /* Null-terminated name ("eth0", etc.) */
};
/* Enumerate host network interfaces */
struct sandbox_eth_raw_if_nameindex *sandbox_eth_raw_if_nameindex(void);
/* Free the data structure of enumerated network interfaces */
void sandbox_eth_raw_if_freenameindex(struct sandbox_eth_raw_if_nameindex *ptr);
/*
* Check if the interface named "ifname" is a localhost interface or not.
* ifname - the interface name on the host to check
*
* returns - 0 if real interface, 1 if local, negative if error
*/
int sandbox_eth_raw_os_is_local(const char *ifname);
/*
* Look up the name of the interface based on the ifindex populated in priv.
*
* Overwrite the host_ifname member in priv based on looking up host_ifindex
*
* returns - 0 if success, negative if error
*/
int sandbox_eth_raw_os_idx_to_name(struct eth_sandbox_raw_priv *priv);
int sandbox_eth_raw_os_start(struct eth_sandbox_raw_priv *priv,
unsigned char *ethmac);
int sandbox_eth_raw_os_send(void *packet, int length, int sandbox_eth_raw_os_send(void *packet, int length,
struct eth_sandbox_raw_priv *priv); struct eth_sandbox_raw_priv *priv);
int sandbox_eth_raw_os_recv(void *packet, int *length, int sandbox_eth_raw_os_recv(void *packet, int *length,

View File

@ -192,6 +192,9 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
switch (argc) { switch (argc) {
case 1: case 1:
/* refresh bootfile name from env */
copy_filename(net_boot_file_name, env_get("bootfile"),
sizeof(net_boot_file_name));
break; break;
case 2: /* case 2: /*
@ -203,6 +206,9 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
addr = simple_strtoul(argv[1], &end, 16); addr = simple_strtoul(argv[1], &end, 16);
if (end == (argv[1] + strlen(argv[1]))) { if (end == (argv[1] + strlen(argv[1]))) {
load_addr = addr; load_addr = addr;
/* refresh bootfile name from env */
copy_filename(net_boot_file_name, env_get("bootfile"),
sizeof(net_boot_file_name));
} else { } else {
net_boot_file_name_explicit = true; net_boot_file_name_explicit = true;
copy_filename(net_boot_file_name, argv[1], copy_filename(net_boot_file_name, argv[1],

View File

@ -196,20 +196,21 @@ static int console_tstc(int file)
{ {
int i, ret; int i, ret;
struct stdio_dev *dev; struct stdio_dev *dev;
int prev;
disable_ctrlc(1); prev = disable_ctrlc(1);
for (i = 0; i < cd_count[file]; i++) { for (i = 0; i < cd_count[file]; i++) {
dev = console_devices[file][i]; dev = console_devices[file][i];
if (dev->tstc != NULL) { if (dev->tstc != NULL) {
ret = dev->tstc(dev); ret = dev->tstc(dev);
if (ret > 0) { if (ret > 0) {
tstcdev = dev; tstcdev = dev;
disable_ctrlc(0); disable_ctrlc(prev);
return ret; return ret;
} }
} }
} }
disable_ctrlc(0); disable_ctrlc(prev);
return 0; return 0;
} }
@ -603,7 +604,6 @@ static int ctrlc_disabled = 0; /* see disable_ctrl() */
static int ctrlc_was_pressed = 0; static int ctrlc_was_pressed = 0;
int ctrlc(void) int ctrlc(void)
{ {
#ifndef CONFIG_SANDBOX
if (!ctrlc_disabled && gd->have_console) { if (!ctrlc_disabled && gd->have_console) {
if (tstc()) { if (tstc()) {
switch (getc()) { switch (getc()) {
@ -615,7 +615,6 @@ int ctrlc(void)
} }
} }
} }
#endif
return 0; return 0;
} }

View File

@ -7,8 +7,8 @@ config DM_ETH
help help
Enable driver model for Ethernet. Enable driver model for Ethernet.
The eth_*() interface will be implemented by the UC_ETH class The eth_*() interface will be implemented by the UCLASS_ETH class
This is currently implemented in net/eth.c This is currently implemented in net/eth-uclass.c
Look in include/net.h for details. Look in include/net.h for details.
config DRIVER_TI_CPSW config DRIVER_TI_CPSW
@ -181,6 +181,7 @@ config FTMAC100
config MVGBE config MVGBE
bool "Marvell Orion5x/Kirkwood network interface support" bool "Marvell Orion5x/Kirkwood network interface support"
depends on KIRKWOOD || ORION5X depends on KIRKWOOD || ORION5X
select PHYLIB if DM_ETH
help help
This driver supports the network interface units in the This driver supports the network interface units in the
Marvell Orion5x and Kirkwood SoCs Marvell Orion5x and Kirkwood SoCs

View File

@ -50,6 +50,7 @@ obj-$(CONFIG_RTL8139) += rtl8139.o
obj-$(CONFIG_RTL8169) += rtl8169.o obj-$(CONFIG_RTL8169) += rtl8169.o
obj-$(CONFIG_ETH_SANDBOX) += sandbox.o obj-$(CONFIG_ETH_SANDBOX) += sandbox.o
obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o
obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw-bus.o
obj-$(CONFIG_SH_ETHER) += sh_eth.o obj-$(CONFIG_SH_ETHER) += sh_eth.o
obj-$(CONFIG_RENESAS_RAVB) += ravb.o obj-$(CONFIG_RENESAS_RAVB) += ravb.o
obj-$(CONFIG_SMC91111) += smc91111.o obj-$(CONFIG_SMC91111) += smc91111.o

View File

@ -999,7 +999,7 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
#ifdef CONFIG_DM_ETH #ifdef CONFIG_DM_ETH
if (slave->data->phy_of_handle) if (slave->data->phy_of_handle)
dev_set_of_offset(phydev->dev, slave->data->phy_of_handle); phydev->node = offset_to_ofnode(slave->data->phy_of_handle);
#endif #endif
priv->phydev = phydev; priv->phydev = phydev;

View File

@ -12,6 +12,7 @@
*/ */
#include <common.h> #include <common.h>
#include <dm.h>
#include <net.h> #include <net.h>
#include <malloc.h> #include <malloc.h>
#include <miiphy.h> #include <miiphy.h>
@ -55,20 +56,13 @@ static int smi_wait_ready(struct mvgbe_device *dmvgbe)
return 0; return 0;
} }
/* static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, int phy_adr,
* smi_reg_read - miiphy_read callback function. int devad, int reg_ofs)
*
* Returns 16bit phy register value, or -EFAULT on error
*/
static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs)
{ {
u16 data = 0;
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs; struct mvgbe_registers *regs = dmvgbe->regs;
u32 smi_reg; u32 smi_reg;
u32 timeout; u32 timeout;
u16 data = 0;
/* Phyadr read request */ /* Phyadr read request */
if (phy_adr == MV_PHY_ADR_REQUEST && if (phy_adr == MV_PHY_ADR_REQUEST &&
@ -127,15 +121,26 @@ static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
} }
/* /*
* smi_reg_write - miiphy_write callback function. * smi_reg_read - miiphy_read callback function.
* *
* Returns 0 if write succeed, -EFAULT on error * Returns 16bit phy register value, or -EFAULT on error
*/ */
static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad, static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs, u16 data) int reg_ofs)
{ {
#ifdef CONFIG_DM_ETH
struct mvgbe_device *dmvgbe = bus->priv;
#else
struct eth_device *dev = eth_get_dev_by_name(bus->name); struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct mvgbe_device *dmvgbe = to_mvgbe(dev); struct mvgbe_device *dmvgbe = to_mvgbe(dev);
#endif
return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
}
static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
int devad, int reg_ofs, u16 data)
{
struct mvgbe_registers *regs = dmvgbe->regs; struct mvgbe_registers *regs = dmvgbe->regs;
u32 smi_reg; u32 smi_reg;
@ -171,6 +176,24 @@ static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
return 0; return 0;
} }
/*
* smi_reg_write - miiphy_write callback function.
*
* Returns 0 if write succeed, -EFAULT on error
*/
static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs, u16 data)
{
#ifdef CONFIG_DM_ETH
struct mvgbe_device *dmvgbe = bus->priv;
#else
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
#endif
return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
}
#endif #endif
/* Stop and checks all queues */ /* Stop and checks all queues */
@ -357,8 +380,9 @@ static int port_uc_addr(struct mvgbe_registers *regs, u8 uc_nibble,
/* /*
* port_uc_addr_set - This function Set the port Unicast address. * port_uc_addr_set - This function Set the port Unicast address.
*/ */
static void port_uc_addr_set(struct mvgbe_registers *regs, u8 * p_addr) static void port_uc_addr_set(struct mvgbe_device *dmvgbe, u8 *p_addr)
{ {
struct mvgbe_registers *regs = dmvgbe->regs;
u32 mac_h; u32 mac_h;
u32 mac_l; u32 mac_l;
@ -400,12 +424,13 @@ static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc; dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
} }
static int mvgbe_init(struct eth_device *dev) static int __mvgbe_init(struct mvgbe_device *dmvgbe, u8 *enetaddr,
const char *name)
{ {
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs; struct mvgbe_registers *regs = dmvgbe->regs;
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \ #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
!defined(CONFIG_PHYLIB) && \ !defined(CONFIG_PHYLIB) && \
!defined(CONFIG_DM_ETH) && \
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
int i; int i;
#endif #endif
@ -422,7 +447,7 @@ static int mvgbe_init(struct eth_device *dev)
set_dram_access(regs); set_dram_access(regs);
port_init_mac_tables(regs); port_init_mac_tables(regs);
port_uc_addr_set(regs, dmvgbe->dev.enetaddr); port_uc_addr_set(dmvgbe, enetaddr);
/* Assign port configuration and command. */ /* Assign port configuration and command. */
MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL); MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
@ -459,28 +484,37 @@ static int mvgbe_init(struct eth_device *dev)
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \ #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
!defined(CONFIG_PHYLIB) && \ !defined(CONFIG_PHYLIB) && \
!defined(CONFIG_DM_ETH) && \
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
/* Wait up to 5s for the link status */ /* Wait up to 5s for the link status */
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
u16 phyadr; u16 phyadr;
miiphy_read(dev->name, MV_PHY_ADR_REQUEST, miiphy_read(name, MV_PHY_ADR_REQUEST,
MV_PHY_ADR_REQUEST, &phyadr); MV_PHY_ADR_REQUEST, &phyadr);
/* Return if we get link up */ /* Return if we get link up */
if (miiphy_link(dev->name, phyadr)) if (miiphy_link(name, phyadr))
return 0; return 0;
udelay(1000000); udelay(1000000);
} }
printf("No link on %s\n", dev->name); printf("No link on %s\n", name);
return -1; return -1;
#endif #endif
return 0; return 0;
} }
static int mvgbe_halt(struct eth_device *dev) #ifndef CONFIG_DM_ETH
static int mvgbe_init(struct eth_device *dev)
{ {
struct mvgbe_device *dmvgbe = to_mvgbe(dev); struct mvgbe_device *dmvgbe = to_mvgbe(dev);
return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr, dmvgbe->dev.name);
}
#endif
static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
{
struct mvgbe_registers *regs = dmvgbe->regs; struct mvgbe_registers *regs = dmvgbe->regs;
/* Disable all gigE address decoder */ /* Disable all gigE address decoder */
@ -502,23 +536,42 @@ static int mvgbe_halt(struct eth_device *dev)
MVGBE_REG_WR(regs->ice, 0); MVGBE_REG_WR(regs->ice, 0);
MVGBE_REG_WR(regs->pim, 0); MVGBE_REG_WR(regs->pim, 0);
MVGBE_REG_WR(regs->peim, 0); MVGBE_REG_WR(regs->peim, 0);
}
#ifndef CONFIG_DM_ETH
static int mvgbe_halt(struct eth_device *dev)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
__mvgbe_halt(dmvgbe);
return 0; return 0;
} }
#endif
#ifdef CONFIG_DM_ETH
static int mvgbe_write_hwaddr(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr);
return 0;
}
#else
static int mvgbe_write_hwaddr(struct eth_device *dev) static int mvgbe_write_hwaddr(struct eth_device *dev)
{ {
struct mvgbe_device *dmvgbe = to_mvgbe(dev); struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs;
/* Programs net device MAC address after initialization */ /* Programs net device MAC address after initialization */
port_uc_addr_set(regs, dmvgbe->dev.enetaddr); port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
return 0; return 0;
} }
#endif
static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize) static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
int datasize)
{ {
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs; struct mvgbe_registers *regs = dmvgbe->regs;
struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc; struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc;
void *p = (void *)dataptr; void *p = (void *)dataptr;
@ -571,13 +624,25 @@ static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
return 0; return 0;
} }
static int mvgbe_recv(struct eth_device *dev) #ifndef CONFIG_DM_ETH
static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
{ {
struct mvgbe_device *dmvgbe = to_mvgbe(dev); struct mvgbe_device *dmvgbe = to_mvgbe(dev);
return __mvgbe_send(dmvgbe, dataptr, datasize);
}
#endif
static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
{
struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr; struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr;
u32 cmd_sts; u32 cmd_sts;
u32 timeout = 0; u32 timeout = 0;
u32 rxdesc_curr_addr; u32 rxdesc_curr_addr;
unsigned char *data;
int rx_bytes = 0;
*packetp = NULL;
/* wait untill rx packet available or timeout */ /* wait untill rx packet available or timeout */
do { do {
@ -621,11 +686,11 @@ static int mvgbe_recv(struct eth_device *dev)
" upper layer (net_process_received_packet)\n", " upper layer (net_process_received_packet)\n",
__func__); __func__);
/* let the upper layer handle the packet */ data = (p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET);
net_process_received_packet((p_rxdesc_curr->buf_ptr + rx_bytes = (int)(p_rxdesc_curr->byte_cnt -
RX_BUF_OFFSET), RX_BUF_OFFSET);
(int)(p_rxdesc_curr->byte_cnt -
RX_BUF_OFFSET)); *packetp = data;
} }
/* /*
* free these descriptors and point next in the ring * free these descriptors and point next in the ring
@ -638,10 +703,59 @@ static int mvgbe_recv(struct eth_device *dev)
rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr; rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr;
writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr); writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr);
return 0; return rx_bytes;
} }
#if defined(CONFIG_PHYLIB) #ifndef CONFIG_DM_ETH
static int mvgbe_recv(struct eth_device *dev)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
uchar *packet;
int ret;
ret = __mvgbe_recv(dmvgbe, &packet);
if (ret < 0)
return ret;
net_process_received_packet(packet, ret);
return 0;
}
#endif
#if defined(CONFIG_PHYLIB) || defined(CONFIG_DM_ETH)
#if defined(CONFIG_DM_ETH)
static struct phy_device *__mvgbe_phy_init(struct udevice *dev,
struct mii_dev *bus,
phy_interface_t phy_interface,
int phyid)
#else
static struct phy_device *__mvgbe_phy_init(struct eth_device *dev,
struct mii_dev *bus,
phy_interface_t phy_interface,
int phyid)
#endif
{
struct phy_device *phydev;
/* Set phy address of the port */
miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
phyid);
phydev = phy_connect(bus, phyid, dev, phy_interface);
if (!phydev) {
printf("phy_connect failed\n");
return NULL;
}
phy_config(phydev);
phy_startup(phydev);
return phydev;
}
#endif /* CONFIG_PHYLIB || CONFIG_DM_ETH */
#if defined(CONFIG_PHYLIB) && !defined(CONFIG_DM_ETH)
int mvgbe_phylib_init(struct eth_device *dev, int phyid) int mvgbe_phylib_init(struct eth_device *dev, int phyid)
{ {
struct mii_dev *bus; struct mii_dev *bus;
@ -664,27 +778,53 @@ int mvgbe_phylib_init(struct eth_device *dev, int phyid)
return -ENOMEM; return -ENOMEM;
} }
/* Set phy address of the port */ phydev = __mvgbe_phy_init(dev, bus, PHY_INTERFACE_MODE_RGMII, phyid);
smi_reg_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid); if (!phydev)
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII);
if (!phydev) {
printf("phy_connect failed\n");
return -ENODEV; return -ENODEV;
}
phy_config(phydev);
phy_startup(phydev);
return 0; return 0;
} }
#endif #endif
static int mvgbe_alloc_buffers(struct mvgbe_device *dmvgbe)
{
dmvgbe->p_rxdesc = memalign(PKTALIGN,
MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
if (!dmvgbe->p_rxdesc)
goto error1;
dmvgbe->p_rxbuf = memalign(PKTALIGN,
RINGSZ * PKTSIZE_ALIGN + 1);
if (!dmvgbe->p_rxbuf)
goto error2;
dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
if (!dmvgbe->p_aligned_txbuf)
goto error3;
dmvgbe->p_txdesc = memalign(PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
if (!dmvgbe->p_txdesc)
goto error4;
return 0;
error4:
free(dmvgbe->p_aligned_txbuf);
error3:
free(dmvgbe->p_rxbuf);
error2:
free(dmvgbe->p_rxdesc);
error1:
return -ENOMEM;
}
#ifndef CONFIG_DM_ETH
int mvgbe_initialize(bd_t *bis) int mvgbe_initialize(bd_t *bis)
{ {
struct mvgbe_device *dmvgbe; struct mvgbe_device *dmvgbe;
struct eth_device *dev; struct eth_device *dev;
int devnum; int devnum;
int ret;
u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS; u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) { for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
@ -693,45 +833,16 @@ int mvgbe_initialize(bd_t *bis)
continue; continue;
dmvgbe = malloc(sizeof(struct mvgbe_device)); dmvgbe = malloc(sizeof(struct mvgbe_device));
if (!dmvgbe) if (!dmvgbe)
goto error1; return -ENOMEM;
memset(dmvgbe, 0, sizeof(struct mvgbe_device)); memset(dmvgbe, 0, sizeof(struct mvgbe_device));
ret = mvgbe_alloc_buffers(dmvgbe);
dmvgbe->p_rxdesc = if (ret) {
(struct mvgbe_rxdesc *)memalign(PKTALIGN,
MV_RXQ_DESC_ALIGNED_SIZE*RINGSZ + 1);
if (!dmvgbe->p_rxdesc)
goto error2;
dmvgbe->p_rxbuf = (u8 *) memalign(PKTALIGN,
RINGSZ*PKTSIZE_ALIGN + 1);
if (!dmvgbe->p_rxbuf)
goto error3;
dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
if (!dmvgbe->p_aligned_txbuf)
goto error4;
dmvgbe->p_txdesc = (struct mvgbe_txdesc *) memalign(
PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
if (!dmvgbe->p_txdesc) {
free(dmvgbe->p_aligned_txbuf);
error4:
free(dmvgbe->p_rxbuf);
error3:
free(dmvgbe->p_rxdesc);
error2:
free(dmvgbe);
error1:
printf("Err.. %s Failed to allocate memory\n", printf("Err.. %s Failed to allocate memory\n",
__func__); __func__);
return -1; free(dmvgbe);
return ret;
} }
dev = &dmvgbe->dev; dev = &dmvgbe->dev;
@ -783,3 +894,154 @@ error1:
} }
return 0; return 0;
} }
#endif
#ifdef CONFIG_DM_ETH
static int mvgbe_port_is_fixed_link(struct mvgbe_device *dmvgbe)
{
return dmvgbe->phyaddr > PHY_MAX_ADDR;
}
static int mvgbe_start(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct mvgbe_device *dmvgbe = dev_get_priv(dev);
int ret;
ret = __mvgbe_init(dmvgbe, pdata->enetaddr, dev->name);
if (ret)
return ret;
if (!mvgbe_port_is_fixed_link(dmvgbe)) {
dmvgbe->phydev = __mvgbe_phy_init(dev, dmvgbe->bus,
dmvgbe->phy_interface,
dmvgbe->phyaddr);
if (!dmvgbe->phydev)
return -ENODEV;
}
return 0;
}
static int mvgbe_send(struct udevice *dev, void *packet, int length)
{
struct mvgbe_device *dmvgbe = dev_get_priv(dev);
return __mvgbe_send(dmvgbe, packet, length);
}
static int mvgbe_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct mvgbe_device *dmvgbe = dev_get_priv(dev);
return __mvgbe_recv(dmvgbe, packetp);
}
static void mvgbe_stop(struct udevice *dev)
{
struct mvgbe_device *dmvgbe = dev_get_priv(dev);
__mvgbe_halt(dmvgbe);
}
static int mvgbe_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct mvgbe_device *dmvgbe = dev_get_priv(dev);
struct mii_dev *bus;
int ret;
ret = mvgbe_alloc_buffers(dmvgbe);
if (ret)
return ret;
dmvgbe->regs = (void __iomem *)pdata->iobase;
bus = mdio_alloc();
if (!bus) {
printf("Failed to allocate MDIO bus\n");
return -ENOMEM;
}
bus->read = smi_reg_read;
bus->write = smi_reg_write;
snprintf(bus->name, sizeof(bus->name), dev->name);
bus->priv = dmvgbe;
dmvgbe->bus = bus;
ret = mdio_register(bus);
if (ret < 0)
return ret;
return 0;
}
static const struct eth_ops mvgbe_ops = {
.start = mvgbe_start,
.send = mvgbe_send,
.recv = mvgbe_recv,
.stop = mvgbe_stop,
.write_hwaddr = mvgbe_write_hwaddr,
};
static int mvgbe_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct mvgbe_device *dmvgbe = dev_get_priv(dev);
void *blob = (void *)gd->fdt_blob;
int node = dev_of_offset(dev);
const char *phy_mode;
int fl_node;
int pnode;
unsigned long addr;
pdata->iobase = devfdt_get_addr(dev);
pdata->phy_interface = -1;
pnode = fdt_node_offset_by_compatible(blob, node,
"marvell,kirkwood-eth-port");
/* Get phy-mode / phy_interface from DT */
phy_mode = fdt_getprop(gd->fdt_blob, pnode, "phy-mode", NULL);
if (phy_mode)
pdata->phy_interface = phy_get_interface_by_name(phy_mode);
if (pdata->phy_interface == -1) {
debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
return -EINVAL;
}
dmvgbe->phy_interface = pdata->phy_interface;
/* fetch 'fixed-link' property */
fl_node = fdt_subnode_offset(blob, pnode, "fixed-link");
if (fl_node != -FDT_ERR_NOTFOUND) {
/* set phy_addr to invalid value for fixed link */
dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
} else {
/* Now read phyaddr from DT */
addr = fdtdec_lookup_phandle(blob, pnode, "phy-handle");
if (addr > 0)
dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
}
return 0;
}
static const struct udevice_id mvgbe_ids[] = {
{ .compatible = "marvell,kirkwood-eth" },
{ }
};
U_BOOT_DRIVER(mvgbe) = {
.name = "mvgbe",
.id = UCLASS_ETH,
.of_match = mvgbe_ids,
.ofdata_to_platdata = mvgbe_ofdata_to_platdata,
.probe = mvgbe_probe,
.ops = &mvgbe_ops,
.priv_auto_alloc_size = sizeof(struct mvgbe_device),
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
};
#endif /* CONFIG_DM_ETH */

View File

@ -30,7 +30,9 @@
#define RXUQ 0 /* Used Rx queue */ #define RXUQ 0 /* Used Rx queue */
#define TXUQ 0 /* Used Rx queue */ #define TXUQ 0 /* Used Rx queue */
#ifndef CONFIG_DM_ETH
#define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev) #define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev)
#endif
#define MVGBE_REG_WR(adr, val) writel(val, &adr) #define MVGBE_REG_WR(adr, val) writel(val, &adr)
#define MVGBE_REG_RD(adr) readl(&adr) #define MVGBE_REG_RD(adr) readl(&adr)
#define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr) #define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr)
@ -479,13 +481,27 @@ struct mvgbe_txdesc {
/* port device data struct */ /* port device data struct */
struct mvgbe_device { struct mvgbe_device {
#ifndef CONFIG_DM_ETH
struct eth_device dev; struct eth_device dev;
#endif
struct mvgbe_registers *regs; struct mvgbe_registers *regs;
struct mvgbe_txdesc *p_txdesc; struct mvgbe_txdesc *p_txdesc;
struct mvgbe_rxdesc *p_rxdesc; struct mvgbe_rxdesc *p_rxdesc;
struct mvgbe_rxdesc *p_rxdesc_curr; struct mvgbe_rxdesc *p_rxdesc_curr;
u8 *p_rxbuf; u8 *p_rxbuf;
u8 *p_aligned_txbuf; u8 *p_aligned_txbuf;
#ifdef CONFIG_DM_ETH
phy_interface_t phy_interface;
unsigned int link;
unsigned int duplex;
unsigned int speed;
int init;
int phyaddr;
struct phy_device *phydev;
struct mii_dev *bus;
#endif
}; };
#endif /* __MVGBE_H__ */ #endif /* __MVGBE_H__ */

View File

@ -5,6 +5,7 @@
* Copyright 2011, 2013 Freescale Semiconductor, Inc. * Copyright 2011, 2013 Freescale Semiconductor, Inc.
* author Andy Fleming * author Andy Fleming
*/ */
#include <common.h>
#include <phy.h> #include <phy.h>
#define AR803x_PHY_DEBUG_ADDR_REG 0x1d #define AR803x_PHY_DEBUG_ADDR_REG 0x1d

View File

@ -5,7 +5,6 @@
* Copyright 2010-2011 Freescale Semiconductor, Inc. * Copyright 2010-2011 Freescale Semiconductor, Inc.
* author Andy Fleming * author Andy Fleming
*/ */
#include <config.h>
#include <common.h> #include <common.h>
#include <phy.h> #include <phy.h>

View File

@ -5,6 +5,7 @@
* Copyright 2010-2011 Freescale Semiconductor, Inc. * Copyright 2010-2011 Freescale Semiconductor, Inc.
* author Andy Fleming * author Andy Fleming
*/ */
#include <common.h>
#include <phy.h> #include <phy.h>
#define MIIM_DM9161_SCR 0x10 #define MIIM_DM9161_SCR 0x10

View File

@ -7,8 +7,6 @@
* *
* Based loosely off of Linux's PHY Lib * Based loosely off of Linux's PHY Lib
*/ */
#include <config.h>
#include <common.h> #include <common.h>
#include <miiphy.h> #include <miiphy.h>
#include <phy.h> #include <phy.h>

View File

@ -5,6 +5,7 @@
* Copyright 2010-2011 Freescale Semiconductor, Inc. * Copyright 2010-2011 Freescale Semiconductor, Inc.
* author Andy Fleming * author Andy Fleming
*/ */
#include <common.h>
#include <phy.h> #include <phy.h>
/* LXT971 Status 2 registers */ /* LXT971 Status 2 registers */

View File

@ -5,7 +5,6 @@
* Copyright 2010-2011 Freescale Semiconductor, Inc. * Copyright 2010-2011 Freescale Semiconductor, Inc.
* author Andy Fleming * author Andy Fleming
*/ */
#include <config.h>
#include <common.h> #include <common.h>
#include <errno.h> #include <errno.h>
#include <phy.h> #include <phy.h>

View File

@ -6,7 +6,6 @@
* author Andy Fleming * author Andy Fleming
* (C) 2012 NetModule AG, David Andrey, added KSZ9031 * (C) 2012 NetModule AG, David Andrey, added KSZ9031
*/ */
#include <config.h>
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <errno.h> #include <errno.h>

View File

@ -8,8 +8,6 @@
* (C) Copyright 2017 Adaptrum, Inc. * (C) Copyright 2017 Adaptrum, Inc.
* Written by Alexandru Gagniuc <alex.g@adaptrum.com> for Adaptrum, Inc. * Written by Alexandru Gagniuc <alex.g@adaptrum.com> for Adaptrum, Inc.
*/ */
#include <config.h>
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <errno.h> #include <errno.h>

View File

@ -5,6 +5,7 @@
* Copyright 2010-2011 Freescale Semiconductor, Inc. * Copyright 2010-2011 Freescale Semiconductor, Inc.
* author Andy Fleming * author Andy Fleming
*/ */
#include <common.h>
#include <phy.h> #include <phy.h>
/* NatSemi DP83630 */ /* NatSemi DP83630 */

View File

@ -7,8 +7,6 @@
* *
* Based loosely off of Linux's PHY Lib * Based loosely off of Linux's PHY Lib
*/ */
#include <config.h>
#include <common.h> #include <common.h>
#include <console.h> #include <console.h>
#include <dm.h> #include <dm.h>
@ -644,6 +642,10 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
dev->link = 0; dev->link = 0;
dev->interface = interface; dev->interface = interface;
#ifdef CONFIG_DM_ETH
dev->node = ofnode_null();
#endif
dev->autoneg = AUTONEG_ENABLE; dev->autoneg = AUTONEG_ENABLE;
dev->addr = addr; dev->addr = addr;

View File

@ -6,7 +6,6 @@
* author Andy Fleming * author Andy Fleming
* Copyright 2016 Karsten Merker <merker@debian.org> * Copyright 2016 Karsten Merker <merker@debian.org>
*/ */
#include <config.h>
#include <common.h> #include <common.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <phy.h> #include <phy.h>

View File

@ -9,6 +9,7 @@
* Some code copied from linux kernel * Some code copied from linux kernel
* Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org> * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
*/ */
#include <common.h>
#include <miiphy.h> #include <miiphy.h>
/* This code does not check the partner abilities. */ /* This code does not check the partner abilities. */

View File

@ -5,7 +5,6 @@
* Copyright 2010-2011 Freescale Semiconductor, Inc. * Copyright 2010-2011 Freescale Semiconductor, Inc.
* author Andy Fleming * author Andy Fleming
*/ */
#include <config.h>
#include <common.h> #include <common.h>
#include <phy.h> #include <phy.h>

View File

@ -8,11 +8,9 @@
#include <linux/compat.h> #include <linux/compat.h>
#include <malloc.h> #include <malloc.h>
#include <fdtdec.h>
#include <dm.h> #include <dm.h>
#include <dt-bindings/net/ti-dp83867.h> #include <dt-bindings/net/ti-dp83867.h>
DECLARE_GLOBAL_DATA_PTR;
/* TI DP83867 */ /* TI DP83867 */
#define DP83867_DEVADDR 0x1f #define DP83867_DEVADDR 0x1f
@ -24,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define DP83867_CTRL 0x1f #define DP83867_CTRL 0x1f
/* Extended Registers */ /* Extended Registers */
#define DP83867_CFG4 0x0031
#define DP83867_RGMIICTL 0x0032 #define DP83867_RGMIICTL 0x0032
#define DP83867_RGMIIDCTL 0x0086 #define DP83867_RGMIIDCTL 0x0086
#define DP83867_IO_MUX_CFG 0x0170 #define DP83867_IO_MUX_CFG 0x0170
@ -95,6 +94,7 @@ struct dp83867_private {
int tx_id_delay; int tx_id_delay;
int fifo_depth; int fifo_depth;
int io_impedance; int io_impedance;
bool rxctrl_strap_quirk;
}; };
/** /**
@ -172,25 +172,31 @@ void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
static int dp83867_of_init(struct phy_device *phydev) static int dp83867_of_init(struct phy_device *phydev)
{ {
struct dp83867_private *dp83867 = phydev->priv; struct dp83867_private *dp83867 = phydev->priv;
struct udevice *dev = phydev->dev; ofnode node;
int node = dev_of_offset(dev);
const void *fdt = gd->fdt_blob;
if (fdtdec_get_bool(fdt, node, "ti,max-output-impedance")) node = phy_get_ofnode(phydev);
if (!ofnode_valid(node))
return -EINVAL;
if (ofnode_read_bool(node, "ti,max-output-impedance"))
dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX; dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
else if (fdtdec_get_bool(fdt, node, "ti,min-output-impedance")) else if (ofnode_read_bool(node, "ti,min-output-impedance"))
dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN; dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN;
else else
dp83867->io_impedance = -EINVAL; dp83867->io_impedance = -EINVAL;
dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), if (ofnode_read_bool(node, "ti,dp83867-rxctrl-strap-quirk"))
"ti,rx-internal-delay", -1); dp83867->rxctrl_strap_quirk = true;
dp83867->rx_id_delay = ofnode_read_u32_default(node,
"ti,rx-internal-delay",
-1);
dp83867->tx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), dp83867->tx_id_delay = ofnode_read_u32_default(node,
"ti,tx-internal-delay", -1); "ti,tx-internal-delay",
-1);
dp83867->fifo_depth = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), dp83867->fifo_depth = ofnode_read_u32_default(node, "ti,fifo-depth",
"ti,fifo-depth", -1); -1);
return 0; return 0;
} }
@ -232,6 +238,15 @@ static int dp83867_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL, phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL,
val | DP83867_SW_RESTART); val | DP83867_SW_RESTART);
/* Mode 1 or 2 workaround */
if (dp83867->rxctrl_strap_quirk) {
val = phy_read_mmd_indirect(phydev, DP83867_CFG4,
DP83867_DEVADDR, phydev->addr);
val &= ~BIT(7);
phy_write_mmd_indirect(phydev, DP83867_CFG4,
DP83867_DEVADDR, phydev->addr, val);
}
if (phy_interface_is_rgmii(phydev)) { if (phy_interface_is_rgmii(phydev)) {
ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL, ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
(DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) | (DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) |

View File

@ -6,6 +6,7 @@
* Original Author: Andy Fleming * Original Author: Andy Fleming
* Add vsc8662 phy support - Priyanka Jain * Add vsc8662 phy support - Priyanka Jain
*/ */
#include <common.h>
#include <miiphy.h> #include <miiphy.h>
/* Cicada Auxiliary Control/Status Register */ /* Cicada Auxiliary Control/Status Register */

View File

@ -10,8 +10,6 @@
#include <phy.h> #include <phy.h>
#include <dm.h> #include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
#define MII_PHY_STATUS_SPD_MASK 0x0C00 #define MII_PHY_STATUS_SPD_MASK 0x0C00
#define MII_PHY_STATUS_FULLDUPLEX 0x1000 #define MII_PHY_STATUS_FULLDUPLEX 0x1000
#define MII_PHY_STATUS_1000 0x0800 #define MII_PHY_STATUS_1000 0x0800
@ -101,10 +99,14 @@ static int xilinxphy_startup(struct phy_device *phydev)
static int xilinxphy_of_init(struct phy_device *phydev) static int xilinxphy_of_init(struct phy_device *phydev)
{ {
u32 phytype; u32 phytype;
ofnode node;
debug("%s\n", __func__); debug("%s\n", __func__);
phytype = fdtdec_get_int(gd->fdt_blob, dev_of_offset(phydev->dev), node = phy_get_ofnode(phydev);
"xlnx,phy-type", -1); if (!ofnode_valid(node))
return -EINVAL;
phytype = ofnode_read_u32_default(node, "xlnx,phy-type", -1);
if (phytype == XAE_PHY_TYPE_1000BASE_X) if (phytype == XAE_PHY_TYPE_1000BASE_X)
phydev->flags |= XAE_PHY_TYPE_1000BASE_X; phydev->flags |= XAE_PHY_TYPE_1000BASE_X;

View File

@ -0,0 +1,66 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2018 National Instruments
* Copyright (c) 2018 Joe Hershberger <joe.hershberger@ni.com>
*/
#include <common.h>
#include <asm/eth-raw-os.h>
#include <dm.h>
#include <errno.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
static int eth_raw_bus_post_bind(struct udevice *dev)
{
struct sandbox_eth_raw_if_nameindex *ni, *i;
struct udevice *child;
struct eth_sandbox_raw_priv *priv;
char *ub_ifname;
static const char ub_ifname_pfx[] = "host_";
u32 skip_localhost = 0;
ni = sandbox_eth_raw_if_nameindex();
if (!ni)
return -EINVAL;
dev_read_u32(dev, "skip-localhost", &skip_localhost);
for (i = ni; !(i->if_index == 0 && !i->if_name); i++) {
int local = sandbox_eth_raw_os_is_local(i->if_name);
if (local < 0)
continue;
if (skip_localhost && local)
continue;
ub_ifname = calloc(IFNAMSIZ + sizeof(ub_ifname_pfx), 1);
strcpy(ub_ifname, ub_ifname_pfx);
strncat(ub_ifname, i->if_name, IFNAMSIZ);
device_bind_driver(dev, "eth_sandbox_raw", ub_ifname, &child);
device_set_name_alloced(child);
device_probe(child);
priv = dev_get_priv(child);
if (priv) {
memcpy(priv->host_ifname, i->if_name, IFNAMSIZ);
priv->host_ifindex = i->if_index;
priv->local = local;
}
}
sandbox_eth_raw_if_freenameindex(ni);
return 0;
}
static const struct udevice_id sandbox_eth_raw_bus_ids[] = {
{ .compatible = "sandbox,eth-raw-bus" },
{ }
};
U_BOOT_DRIVER(sandbox_eth_raw_bus) = {
.name = "sb_eth_raw_bus",
.id = UCLASS_SIMPLE_BUS,
.of_match = sandbox_eth_raw_bus_ids,
.bind = eth_raw_bus_post_bind,
};

View File

@ -21,21 +21,18 @@ static int sb_eth_raw_start(struct udevice *dev)
{ {
struct eth_sandbox_raw_priv *priv = dev_get_priv(dev); struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev); struct eth_pdata *pdata = dev_get_platdata(dev);
const char *interface; int ret;
debug("eth_sandbox_raw: Start\n"); debug("eth_sandbox_raw: Start\n");
interface = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), ret = sandbox_eth_raw_os_start(priv, pdata->enetaddr);
"host-raw-interface", NULL); if (priv->local) {
if (interface == NULL)
return -EINVAL;
if (strcmp(interface, "lo") == 0) {
priv->local = 1;
env_set("ipaddr", "127.0.0.1"); env_set("ipaddr", "127.0.0.1");
env_set("serverip", "127.0.0.1"); env_set("serverip", "127.0.0.1");
net_ip = string_to_ip("127.0.0.1");
net_server_ip = net_ip;
} }
return sandbox_eth_raw_os_start(interface, pdata->enetaddr, priv); return ret;
} }
static int sb_eth_raw_send(struct udevice *dev, void *packet, int length) static int sb_eth_raw_send(struct udevice *dev, void *packet, int length)
@ -133,18 +130,54 @@ static void sb_eth_raw_stop(struct udevice *dev)
sandbox_eth_raw_os_stop(priv); sandbox_eth_raw_os_stop(priv);
} }
static int sb_eth_raw_read_rom_hwaddr(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
net_random_ethaddr(pdata->enetaddr);
return 0;
}
static const struct eth_ops sb_eth_raw_ops = { static const struct eth_ops sb_eth_raw_ops = {
.start = sb_eth_raw_start, .start = sb_eth_raw_start,
.send = sb_eth_raw_send, .send = sb_eth_raw_send,
.recv = sb_eth_raw_recv, .recv = sb_eth_raw_recv,
.stop = sb_eth_raw_stop, .stop = sb_eth_raw_stop,
.read_rom_hwaddr = sb_eth_raw_read_rom_hwaddr,
}; };
static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev) static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev)
{ {
struct eth_pdata *pdata = dev_get_platdata(dev); struct eth_pdata *pdata = dev_get_platdata(dev);
struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
const char *ifname;
u32 local;
int ret;
pdata->iobase = dev_read_addr(dev);
ifname = dev_read_string(dev, "host-raw-interface");
if (ifname) {
strncpy(priv->host_ifname, ifname, IFNAMSIZ);
printf(": Using %s from DT\n", priv->host_ifname);
}
if (dev_read_u32(dev, "host-raw-interface-idx",
&priv->host_ifindex) < 0) {
priv->host_ifindex = 0;
} else {
ret = sandbox_eth_raw_os_idx_to_name(priv);
if (ret < 0)
return ret;
printf(": Using interface index %d from DT (%s)\n",
priv->host_ifindex, priv->host_ifname);
}
local = sandbox_eth_raw_os_is_local(priv->host_ifname);
if (local < 0)
return local;
priv->local = local;
pdata->iobase = devfdt_get_addr(dev);
return 0; return 0;
} }

View File

@ -59,10 +59,8 @@ static int sb_eth_start(struct udevice *dev)
debug("eth_sandbox: Start\n"); debug("eth_sandbox: Start\n");
fdtdec_get_byte_array(gd->fdt_blob, dev_of_offset(dev),
"fake-host-hwaddr", priv->fake_host_hwaddr,
ARP_HLEN);
priv->recv_packet_buffer = net_rx_packets[0]; priv->recv_packet_buffer = net_rx_packets[0];
return 0; return 0;
} }
@ -203,8 +201,18 @@ static int sb_eth_remove(struct udevice *dev)
static int sb_eth_ofdata_to_platdata(struct udevice *dev) static int sb_eth_ofdata_to_platdata(struct udevice *dev)
{ {
struct eth_pdata *pdata = dev_get_platdata(dev); struct eth_pdata *pdata = dev_get_platdata(dev);
struct eth_sandbox_priv *priv = dev_get_priv(dev);
const u8 *mac;
pdata->iobase = dev_read_addr(dev);
mac = dev_read_u8_array_ptr(dev, "fake-host-hwaddr", ARP_HLEN);
if (!mac) {
printf("'fake-host-hwaddr' is missing from the DT\n");
return -EINVAL;
}
memcpy(priv->fake_host_hwaddr, mac, ARP_HLEN);
pdata->iobase = devfdt_get_addr(dev);
return 0; return 0;
} }

View File

@ -178,7 +178,7 @@ struct zynq_gem_priv {
struct zynq_gem_regs *iobase; struct zynq_gem_regs *iobase;
phy_interface_t interface; phy_interface_t interface;
struct phy_device *phydev; struct phy_device *phydev;
int phy_of_handle; ofnode phy_of_node;
struct mii_dev *bus; struct mii_dev *bus;
struct clk clk; struct clk clk;
u32 max_speed; u32 max_speed;
@ -348,9 +348,7 @@ static int zynq_phy_init(struct udevice *dev)
} }
priv->phydev->advertising = priv->phydev->supported; priv->phydev->advertising = priv->phydev->supported;
priv->phydev->node = priv->phy_of_node;
if (priv->phy_of_handle > 0)
dev_set_of_offset(priv->phydev->dev, priv->phy_of_handle);
return phy_config(priv->phydev); return phy_config(priv->phydev);
} }
@ -693,21 +691,23 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
{ {
struct eth_pdata *pdata = dev_get_platdata(dev); struct eth_pdata *pdata = dev_get_platdata(dev);
struct zynq_gem_priv *priv = dev_get_priv(dev); struct zynq_gem_priv *priv = dev_get_priv(dev);
int node = dev_of_offset(dev); struct ofnode_phandle_args phandle_args;
const char *phy_mode; const char *phy_mode;
pdata->iobase = (phys_addr_t)devfdt_get_addr(dev); pdata->iobase = (phys_addr_t)dev_read_addr(dev);
priv->iobase = (struct zynq_gem_regs *)pdata->iobase; priv->iobase = (struct zynq_gem_regs *)pdata->iobase;
/* Hardcode for now */ /* Hardcode for now */
priv->phyaddr = -1; priv->phyaddr = -1;
priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob, node, if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
"phy-handle"); &phandle_args)) {
if (priv->phy_of_handle > 0) debug("phy-handle does not exist %s\n", dev->name);
priv->phyaddr = fdtdec_get_int(gd->fdt_blob, return -ENOENT;
priv->phy_of_handle, "reg", -1); }
phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL); priv->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1);
priv->phy_of_node = phandle_args.node;
phy_mode = dev_read_prop(dev, "phy-mode", NULL);
if (phy_mode) if (phy_mode)
pdata->phy_interface = phy_get_interface_by_name(phy_mode); pdata->phy_interface = phy_get_interface_by_name(phy_mode);
if (pdata->phy_interface == -1) { if (pdata->phy_interface == -1) {
@ -716,10 +716,8 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
} }
priv->interface = pdata->phy_interface; priv->interface = pdata->phy_interface;
priv->max_speed = fdtdec_get_uint(gd->fdt_blob, priv->phy_of_handle, priv->max_speed = dev_read_u32_default(dev, "max-speed", SPEED_1000);
"max-speed", SPEED_1000); priv->int_pcs = dev_read_bool(dev, "is-internal-pcspma");
priv->int_pcs = fdtdec_get_bool(gd->fdt_blob, node,
"is-internal-pcspma");
printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase, printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase,
priv->phyaddr, phy_string_for_interface(priv->interface)); priv->phyaddr, phy_string_for_interface(priv->interface));

View File

@ -10,6 +10,7 @@
*/ */
#include <common.h> #include <common.h>
#include <console.h>
#include <dm.h> #include <dm.h>
#include <fdtdec.h> #include <fdtdec.h>
#include <lcd.h> #include <lcd.h>
@ -69,6 +70,9 @@ static int sandbox_serial_probe(struct udevice *dev)
os_tty_raw(0, state->term_raw == STATE_TERM_RAW_WITH_SIGS); os_tty_raw(0, state->term_raw == STATE_TERM_RAW_WITH_SIGS);
priv->start_of_line = 0; priv->start_of_line = 0;
if (state->term_raw != STATE_TERM_RAW)
disable_ctrlc(1);
return 0; return 0;
} }

View File

@ -3,8 +3,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#ifdef CONFIG_PHY_AQUANTIA #ifdef CONFIG_PHY_AQUANTIA
#include <miiphy.h> #include <phy_interface.h>
#include <phy.h>
#endif #endif
struct spi_slave; struct spi_slave;

View File

@ -839,6 +839,20 @@ ushort env_get_vlan(char *);
/* copy a filename (allow for "..." notation, limit length) */ /* copy a filename (allow for "..." notation, limit length) */
void copy_filename(char *dst, const char *src, int size); void copy_filename(char *dst, const char *src, int size);
/* check if serverip is specified in filename from the command line */
int is_serverip_in_cmd(void);
/**
* net_parse_bootfile - Parse the bootfile env var / cmd line param
*
* @param ipaddr - a pointer to the ipaddr to populate if included in bootfile
* @param filename - a pointer to the string to save the filename part
* @param max_len - The longest - 1 that the filename part can be
*
* return 1 if parsed, 0 if bootfile is empty
*/
int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len);
/* get a random source port */ /* get a random source port */
unsigned int random_port(void); unsigned int random_port(void);

View File

@ -9,10 +9,12 @@
#ifndef _PHY_H #ifndef _PHY_H
#define _PHY_H #define _PHY_H
#include <dm.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/mdio.h> #include <linux/mdio.h>
#include <phy_interface.h>
#define PHY_FIXED_ID 0xa5a55a5a #define PHY_FIXED_ID 0xa5a55a5a
@ -48,60 +50,6 @@
#endif #endif
typedef enum {
PHY_INTERFACE_MODE_MII,
PHY_INTERFACE_MODE_GMII,
PHY_INTERFACE_MODE_SGMII,
PHY_INTERFACE_MODE_SGMII_2500,
PHY_INTERFACE_MODE_QSGMII,
PHY_INTERFACE_MODE_TBI,
PHY_INTERFACE_MODE_RMII,
PHY_INTERFACE_MODE_RGMII,
PHY_INTERFACE_MODE_RGMII_ID,
PHY_INTERFACE_MODE_RGMII_RXID,
PHY_INTERFACE_MODE_RGMII_TXID,
PHY_INTERFACE_MODE_RTBI,
PHY_INTERFACE_MODE_XGMII,
PHY_INTERFACE_MODE_XAUI,
PHY_INTERFACE_MODE_RXAUI,
PHY_INTERFACE_MODE_SFI,
PHY_INTERFACE_MODE_INTERNAL,
PHY_INTERFACE_MODE_NONE, /* Must be last */
PHY_INTERFACE_MODE_COUNT,
} phy_interface_t;
static const char *phy_interface_strings[] = {
[PHY_INTERFACE_MODE_MII] = "mii",
[PHY_INTERFACE_MODE_GMII] = "gmii",
[PHY_INTERFACE_MODE_SGMII] = "sgmii",
[PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500",
[PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
[PHY_INTERFACE_MODE_TBI] = "tbi",
[PHY_INTERFACE_MODE_RMII] = "rmii",
[PHY_INTERFACE_MODE_RGMII] = "rgmii",
[PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
[PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
[PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
[PHY_INTERFACE_MODE_RTBI] = "rtbi",
[PHY_INTERFACE_MODE_XGMII] = "xgmii",
[PHY_INTERFACE_MODE_XAUI] = "xaui",
[PHY_INTERFACE_MODE_RXAUI] = "rxaui",
[PHY_INTERFACE_MODE_SFI] = "sfi",
[PHY_INTERFACE_MODE_INTERNAL] = "internal",
[PHY_INTERFACE_MODE_NONE] = "",
};
static inline const char *phy_string_for_interface(phy_interface_t i)
{
/* Default to unknown */
if (i > PHY_INTERFACE_MODE_NONE)
i = PHY_INTERFACE_MODE_NONE;
return phy_interface_strings[i];
}
struct phy_device; struct phy_device;
#define MDIO_NAME_LEN 32 #define MDIO_NAME_LEN 32
@ -165,6 +113,7 @@ struct phy_device {
#ifdef CONFIG_DM_ETH #ifdef CONFIG_DM_ETH
struct udevice *dev; struct udevice *dev;
ofnode node;
#else #else
struct eth_device *dev; struct eth_device *dev;
#endif #endif
@ -235,11 +184,22 @@ void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
struct phy_device *phy_connect(struct mii_dev *bus, int addr, struct phy_device *phy_connect(struct mii_dev *bus, int addr,
struct udevice *dev, struct udevice *dev,
phy_interface_t interface); phy_interface_t interface);
static inline ofnode phy_get_ofnode(struct phy_device *phydev)
{
if (ofnode_valid(phydev->node))
return phydev->node;
else
return dev_ofnode(phydev->dev);
}
#else #else
void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev); void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
struct phy_device *phy_connect(struct mii_dev *bus, int addr, struct phy_device *phy_connect(struct mii_dev *bus, int addr,
struct eth_device *dev, struct eth_device *dev,
phy_interface_t interface); phy_interface_t interface);
static inline ofnode phy_get_ofnode(struct phy_device *phydev)
{
return ofnode_null();
}
#endif #endif
int phy_startup(struct phy_device *phydev); int phy_startup(struct phy_device *phydev);
int phy_config(struct phy_device *phydev); int phy_config(struct phy_device *phydev);

65
include/phy_interface.h Normal file
View File

@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Andy Fleming <afleming@gmail.com>
*
* This file pretty much stolen from Linux's mii.h/ethtool.h/phy.h
*/
#ifndef _PHY_INTERFACE_H
#define _PHY_INTERFACE_H
typedef enum {
PHY_INTERFACE_MODE_MII,
PHY_INTERFACE_MODE_GMII,
PHY_INTERFACE_MODE_SGMII,
PHY_INTERFACE_MODE_SGMII_2500,
PHY_INTERFACE_MODE_QSGMII,
PHY_INTERFACE_MODE_TBI,
PHY_INTERFACE_MODE_RMII,
PHY_INTERFACE_MODE_RGMII,
PHY_INTERFACE_MODE_RGMII_ID,
PHY_INTERFACE_MODE_RGMII_RXID,
PHY_INTERFACE_MODE_RGMII_TXID,
PHY_INTERFACE_MODE_RTBI,
PHY_INTERFACE_MODE_XGMII,
PHY_INTERFACE_MODE_XAUI,
PHY_INTERFACE_MODE_RXAUI,
PHY_INTERFACE_MODE_SFI,
PHY_INTERFACE_MODE_INTERNAL,
PHY_INTERFACE_MODE_NONE, /* Must be last */
PHY_INTERFACE_MODE_COUNT,
} phy_interface_t;
static const char * const phy_interface_strings[] = {
[PHY_INTERFACE_MODE_MII] = "mii",
[PHY_INTERFACE_MODE_GMII] = "gmii",
[PHY_INTERFACE_MODE_SGMII] = "sgmii",
[PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500",
[PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
[PHY_INTERFACE_MODE_TBI] = "tbi",
[PHY_INTERFACE_MODE_RMII] = "rmii",
[PHY_INTERFACE_MODE_RGMII] = "rgmii",
[PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
[PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
[PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
[PHY_INTERFACE_MODE_RTBI] = "rtbi",
[PHY_INTERFACE_MODE_XGMII] = "xgmii",
[PHY_INTERFACE_MODE_XAUI] = "xaui",
[PHY_INTERFACE_MODE_RXAUI] = "rxaui",
[PHY_INTERFACE_MODE_SFI] = "sfi",
[PHY_INTERFACE_MODE_INTERNAL] = "internal",
[PHY_INTERFACE_MODE_NONE] = "",
};
static inline const char *phy_string_for_interface(phy_interface_t i)
{
/* Default to unknown */
if (i > PHY_INTERFACE_MODE_NONE)
i = PHY_INTERFACE_MODE_NONE;
return phy_interface_strings[i];
}
#endif /* _PHY_INTERFACE_H */

View File

@ -361,6 +361,7 @@ efi_status_t efi_net_register(void)
memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6); memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
netobj->net_mode.hwaddr_size = ARP_HLEN; netobj->net_mode.hwaddr_size = ARP_HLEN;
netobj->net_mode.max_packet_size = PKTSIZE; netobj->net_mode.max_packet_size = PKTSIZE;
netobj->net_mode.if_type = ARP_ETHER;
netobj->pxe.mode = &netobj->pxe_mode; netobj->pxe.mode = &netobj->pxe_mode;
if (dhcp_ack) if (dhcp_ack)

View File

@ -307,7 +307,7 @@ void eth_halt(void)
struct eth_device_priv *priv; struct eth_device_priv *priv;
current = eth_get_dev(); current = eth_get_dev();
if (!current || !device_active(current)) if (!current || !eth_is_active(current))
return; return;
eth_get_ops(current)->stop(current); eth_get_ops(current)->stop(current);

View File

@ -216,26 +216,6 @@ int __maybe_unused net_busy_flag;
/**********************************************************************/ /**********************************************************************/
static int on_bootfile(const char *name, const char *value, enum env_op op,
int flags)
{
if (flags & H_PROGRAMMATIC)
return 0;
switch (op) {
case env_op_create:
case env_op_overwrite:
copy_filename(net_boot_file_name, value,
sizeof(net_boot_file_name));
break;
default:
break;
}
return 0;
}
U_BOOT_ENV_CALLBACK(bootfile, on_bootfile);
static int on_ipaddr(const char *name, const char *value, enum env_op op, static int on_ipaddr(const char *name, const char *value, enum env_op op,
int flags) int flags)
{ {
@ -332,6 +312,16 @@ void net_auto_load(void)
const char *s = env_get("autoload"); const char *s = env_get("autoload");
if (s != NULL && strcmp(s, "NFS") == 0) { if (s != NULL && strcmp(s, "NFS") == 0) {
if (net_check_prereq(NFS)) {
/* We aren't expecting to get a serverip, so just accept the assigned IP */
#ifdef CONFIG_BOOTP_SERVERIP
net_set_state(NETLOOP_SUCCESS);
#else
printf("Cannot autoload with NFS\n");
net_set_state(NETLOOP_FAIL);
#endif
return;
}
/* /*
* Use NFS to load the bootfile. * Use NFS to load the bootfile.
*/ */
@ -347,6 +337,16 @@ void net_auto_load(void)
net_set_state(NETLOOP_SUCCESS); net_set_state(NETLOOP_SUCCESS);
return; return;
} }
if (net_check_prereq(TFTPGET)) {
/* We aren't expecting to get a serverip, so just accept the assigned IP */
#ifdef CONFIG_BOOTP_SERVERIP
net_set_state(NETLOOP_SUCCESS);
#else
printf("Cannot autoload with TFTPGET\n");
net_set_state(NETLOOP_FAIL);
#endif
return;
}
tftp_start(TFTPGET); tftp_start(TFTPGET);
} }
@ -1341,7 +1341,7 @@ static int net_check_prereq(enum proto_t protocol)
/* Fall through */ /* Fall through */
case TFTPGET: case TFTPGET:
case TFTPPUT: case TFTPPUT:
if (net_server_ip.s_addr == 0) { if (net_server_ip.s_addr == 0 && !is_serverip_in_cmd()) {
puts("*** ERROR: `serverip' not set\n"); puts("*** ERROR: `serverip' not set\n");
return 1; return 1;
} }
@ -1502,16 +1502,41 @@ void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
void copy_filename(char *dst, const char *src, int size) void copy_filename(char *dst, const char *src, int size)
{ {
if (*src && (*src == '"')) { if (src && *src && (*src == '"')) {
++src; ++src;
--size; --size;
} }
while ((--size > 0) && *src && (*src != '"')) while ((--size > 0) && src && *src && (*src != '"'))
*dst++ = *src++; *dst++ = *src++;
*dst = '\0'; *dst = '\0';
} }
int is_serverip_in_cmd(void)
{
return !!strchr(net_boot_file_name, ':');
}
int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len)
{
char *colon;
if (net_boot_file_name[0] == '\0')
return 0;
colon = strchr(net_boot_file_name, ':');
if (colon) {
if (ipaddr)
*ipaddr = string_to_ip(net_boot_file_name);
strncpy(filename, colon + 1, max_len);
} else {
strncpy(filename, net_boot_file_name, max_len);
}
filename[max_len - 1] = '\0';
return 1;
}
#if defined(CONFIG_CMD_NFS) || \ #if defined(CONFIG_CMD_NFS) || \
defined(CONFIG_CMD_SNTP) || \ defined(CONFIG_CMD_SNTP) || \
defined(CONFIG_CMD_DNS) defined(CONFIG_CMD_DNS)

View File

@ -533,7 +533,7 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
switch (ntohl(rpc_pkt.u.reply.data[0])) { switch (ntohl(rpc_pkt.u.reply.data[0])) {
/* Minimal supported NFS version */ /* Minimal supported NFS version */
case 3: case 3:
debug("*** Waring: NFS version not supported: Requested: V%d, accepted: min V%d - max V%d\n", debug("*** Warning: NFS version not supported: Requested: V%d, accepted: min V%d - max V%d\n",
(supported_nfs_versions & NFSV2_FLAG) ? (supported_nfs_versions & NFSV2_FLAG) ?
2 : 3, 2 : 3,
ntohl(rpc_pkt.u.reply.data[0]), ntohl(rpc_pkt.u.reply.data[0]),
@ -855,40 +855,29 @@ void nfs_start(void)
if (nfs_path == NULL) { if (nfs_path == NULL) {
net_set_state(NETLOOP_FAIL); net_set_state(NETLOOP_FAIL);
debug("*** ERROR: Fail allocate memory\n"); printf("*** ERROR: Fail allocate memory\n");
return; return;
} }
if (net_boot_file_name[0] == '\0') { if (!net_parse_bootfile(&nfs_server_ip, nfs_path,
sizeof(nfs_path_buff))) {
sprintf(nfs_path, "/nfsroot/%02X%02X%02X%02X.img", sprintf(nfs_path, "/nfsroot/%02X%02X%02X%02X.img",
net_ip.s_addr & 0xFF, net_ip.s_addr & 0xFF,
(net_ip.s_addr >> 8) & 0xFF, (net_ip.s_addr >> 8) & 0xFF,
(net_ip.s_addr >> 16) & 0xFF, (net_ip.s_addr >> 16) & 0xFF,
(net_ip.s_addr >> 24) & 0xFF); (net_ip.s_addr >> 24) & 0xFF);
debug("*** Warning: no boot file name; using '%s'\n", printf("*** Warning: no boot file name; using '%s'\n",
nfs_path); nfs_path);
} else {
char *p = net_boot_file_name;
p = strchr(p, ':');
if (p != NULL) {
nfs_server_ip = string_to_ip(net_boot_file_name);
++p;
strcpy(nfs_path, p);
} else {
strcpy(nfs_path, net_boot_file_name);
}
} }
nfs_filename = basename(nfs_path); nfs_filename = basename(nfs_path);
nfs_path = dirname(nfs_path); nfs_path = dirname(nfs_path);
debug("Using %s device\n", eth_get_name()); printf("Using %s device\n", eth_get_name());
debug("File transfer via NFS from server %pI4; our IP address is %pI4", printf("File transfer via NFS from server %pI4; our IP address is %pI4",
&nfs_server_ip, &net_ip); &nfs_server_ip, &net_ip);
/* Check if we need to send across this subnet */ /* Check if we need to send across this subnet */
if (net_gateway.s_addr && net_netmask.s_addr) { if (net_gateway.s_addr && net_netmask.s_addr) {
@ -896,19 +885,19 @@ void nfs_start(void)
struct in_addr server_net; struct in_addr server_net;
our_net.s_addr = net_ip.s_addr & net_netmask.s_addr; our_net.s_addr = net_ip.s_addr & net_netmask.s_addr;
server_net.s_addr = net_server_ip.s_addr & net_netmask.s_addr; server_net.s_addr = nfs_server_ip.s_addr & net_netmask.s_addr;
if (our_net.s_addr != server_net.s_addr) if (our_net.s_addr != server_net.s_addr)
debug("; sending through gateway %pI4", printf("; sending through gateway %pI4",
&net_gateway); &net_gateway);
} }
debug("\nFilename '%s/%s'.", nfs_path, nfs_filename); printf("\nFilename '%s/%s'.", nfs_path, nfs_filename);
if (net_boot_file_expected_size_in_blocks) { if (net_boot_file_expected_size_in_blocks) {
debug(" Size is 0x%x Bytes = ", printf(" Size is 0x%x Bytes = ",
net_boot_file_expected_size_in_blocks << 9); net_boot_file_expected_size_in_blocks << 9);
print_size(net_boot_file_expected_size_in_blocks << 9, ""); print_size(net_boot_file_expected_size_in_blocks << 9, "");
} }
debug("\nLoad address: 0x%lx\nLoading: *\b", load_addr); printf("\nLoad address: 0x%lx\nLoading: *\b", load_addr);
net_set_timeout_handler(nfs_timeout, nfs_timeout_handler); net_set_timeout_handler(nfs_timeout, nfs_timeout_handler);
net_set_udp_handler(nfs_handler); net_set_udp_handler(nfs_handler);

View File

@ -42,6 +42,7 @@
* case, most NFS servers are optimized for a power of 2. * case, most NFS servers are optimized for a power of 2.
*/ */
#define NFS_READ_SIZE 1024 /* biggest power of two that fits Ether frame */ #define NFS_READ_SIZE 1024 /* biggest power of two that fits Ether frame */
#define NFS_MAX_ATTRS 26
/* Values for Accept State flag on RPC answers (See: rfc1831) */ /* Values for Accept State flag on RPC answers (See: rfc1831) */
enum rpc_accept_stat { enum rpc_accept_stat {
@ -55,7 +56,8 @@ enum rpc_accept_stat {
struct rpc_t { struct rpc_t {
union { union {
uint8_t data[2048]; uint8_t data[NFS_READ_SIZE + (6 + NFS_MAX_ATTRS) *
sizeof(uint32_t)];
struct { struct {
uint32_t id; uint32_t id;
uint32_t type; uint32_t type;
@ -72,7 +74,8 @@ struct rpc_t {
uint32_t verifier; uint32_t verifier;
uint32_t v2; uint32_t v2;
uint32_t astatus; uint32_t astatus;
uint32_t data[NFS_READ_SIZE]; uint32_t data[NFS_READ_SIZE / sizeof(uint32_t) +
NFS_MAX_ATTRS];
} reply; } reply;
} u; } u;
} __attribute__((packed)); } __attribute__((packed));

View File

@ -735,7 +735,7 @@ void tftp_start(enum proto_t protocol)
tftp_block_size_option, timeout_ms); tftp_block_size_option, timeout_ms);
tftp_remote_ip = net_server_ip; tftp_remote_ip = net_server_ip;
if (net_boot_file_name[0] == '\0') { if (!net_parse_bootfile(&tftp_remote_ip, tftp_filename, MAX_LEN)) {
sprintf(default_filename, "%02X%02X%02X%02X.img", sprintf(default_filename, "%02X%02X%02X%02X.img",
net_ip.s_addr & 0xFF, net_ip.s_addr & 0xFF,
(net_ip.s_addr >> 8) & 0xFF, (net_ip.s_addr >> 8) & 0xFF,
@ -747,17 +747,6 @@ void tftp_start(enum proto_t protocol)
printf("*** Warning: no boot file name; using '%s'\n", printf("*** Warning: no boot file name; using '%s'\n",
tftp_filename); tftp_filename);
} else {
char *p = strchr(net_boot_file_name, ':');
if (p == NULL) {
strncpy(tftp_filename, net_boot_file_name, MAX_LEN);
tftp_filename[MAX_LEN - 1] = 0;
} else {
tftp_remote_ip = string_to_ip(net_boot_file_name);
strncpy(tftp_filename, p + 1, MAX_LEN);
tftp_filename[MAX_LEN - 1] = 0;
}
} }
printf("Using %s device\n", eth_get_name()); printf("Using %s device\n", eth_get_name());