Merge branch 'master' of git://git.denx.de/u-boot-net
This commit is contained in:
commit
a57d45db90
@ -9,6 +9,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/system.h>
|
||||
#include <fm_eth.h>
|
||||
#include <asm/armv8/mmu.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
@ -18,7 +19,6 @@
|
||||
#include <fsl_immap.h>
|
||||
#include <asm/arch/mp.h>
|
||||
#include <efi_loader.h>
|
||||
#include <fm_eth.h>
|
||||
#include <fsl-mc/fsl_mc.h>
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
#include <fsl_esdhc.h>
|
||||
|
@ -1,9 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2015 National Instruments
|
||||
*
|
||||
* (C) Copyright 2015
|
||||
* Joe Hershberger <joe.hershberger@ni.com>
|
||||
* Copyright (c) 2015-2018 National Instruments
|
||||
* Copyright (c) 2015-2018 Joe Hershberger <joe.hershberger@ni.com>
|
||||
*/
|
||||
|
||||
#include <asm/eth-raw-os.h>
|
||||
@ -25,8 +23,46 @@
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
static int _raw_packet_start(const char *ifname, unsigned char *ethmac,
|
||||
struct eth_sandbox_raw_priv *priv)
|
||||
struct sandbox_eth_raw_if_nameindex *sandbox_eth_raw_if_nameindex(void)
|
||||
{
|
||||
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 packet_mreq mr;
|
||||
@ -34,12 +70,14 @@ static int _raw_packet_start(const char *ifname, unsigned char *ethmac,
|
||||
int flags;
|
||||
|
||||
/* Prepare device struct */
|
||||
priv->local_bind_sd = -1;
|
||||
priv->device = malloc(sizeof(struct sockaddr_ll));
|
||||
if (priv->device == NULL)
|
||||
return -ENOMEM;
|
||||
device = priv->device;
|
||||
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;
|
||||
memcpy(device->sll_addr, ethmac, 6);
|
||||
device->sll_halen = htons(6);
|
||||
@ -52,11 +90,11 @@ static int _raw_packet_start(const char *ifname, unsigned char *ethmac,
|
||||
return -errno;
|
||||
}
|
||||
/* Bind to the specified interface */
|
||||
ret = setsockopt(priv->sd, SOL_SOCKET, SO_BINDTODEVICE, ifname,
|
||||
strlen(ifname) + 1);
|
||||
ret = setsockopt(priv->sd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
priv->host_ifname, strlen(priv->host_ifname) + 1);
|
||||
if (ret < 0) {
|
||||
printf("Failed to bind to '%s': %d %s\n", ifname, errno,
|
||||
strerror(errno));
|
||||
printf("Failed to bind to '%s': %d %s\n", priv->host_ifname,
|
||||
errno, strerror(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"
|
||||
"Falling back to the old \"flags\" way...\n",
|
||||
errno, strerror(errno));
|
||||
if (strlen(ifname) >= IFNAMSIZ) {
|
||||
printf("Interface name %s is too long.\n", ifname);
|
||||
if (strlen(priv->host_ifname) >= IFNAMSIZ) {
|
||||
printf("Interface name %s is too long.\n",
|
||||
priv->host_ifname);
|
||||
return -EINVAL;
|
||||
}
|
||||
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
strncpy(ifr.ifr_name, priv->host_ifname, IFNAMSIZ);
|
||||
if (ioctl(priv->sd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||
printf("Failed to read flags: %d %s\n", errno,
|
||||
strerror(errno));
|
||||
@ -103,6 +142,8 @@ static int _local_inet_start(struct eth_sandbox_raw_priv *priv)
|
||||
int one = 1;
|
||||
|
||||
/* Prepare device struct */
|
||||
priv->local_bind_sd = -1;
|
||||
priv->local_bind_udp_port = 0;
|
||||
priv->device = malloc(sizeof(struct sockaddr_in));
|
||||
if (priv->device == NULL)
|
||||
return -ENOMEM;
|
||||
@ -136,18 +177,16 @@ static int _local_inet_start(struct eth_sandbox_raw_priv *priv)
|
||||
strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
priv->local_bind_sd = -1;
|
||||
priv->local_bind_udp_port = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sandbox_eth_raw_os_start(const char *ifname, unsigned char *ethmac,
|
||||
struct eth_sandbox_raw_priv *priv)
|
||||
int sandbox_eth_raw_os_start(struct eth_sandbox_raw_priv *priv,
|
||||
unsigned char *ethmac)
|
||||
{
|
||||
if (priv->local)
|
||||
return _local_inet_start(priv);
|
||||
else
|
||||
return _raw_packet_start(ifname, ethmac, priv);
|
||||
return _raw_packet_start(priv, ethmac);
|
||||
}
|
||||
|
||||
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;
|
||||
struct udphdr *udph = packet + sizeof(struct iphdr);
|
||||
|
||||
if (!priv->sd || !priv->device)
|
||||
if (priv->sd < 0 || !priv->device)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
@ -221,7 +260,7 @@ int sandbox_eth_raw_os_recv(void *packet, int *length,
|
||||
int retval;
|
||||
int saddr_size;
|
||||
|
||||
if (!priv->sd || !priv->device)
|
||||
if (priv->sd < 0 || !priv->device)
|
||||
return -EINVAL;
|
||||
saddr_size = sizeof(struct sockaddr);
|
||||
retval = recvfrom(priv->sd, packet, 1536, 0,
|
||||
|
@ -8,7 +8,6 @@
|
||||
model = "sandbox";
|
||||
|
||||
aliases {
|
||||
eth5 = "/eth@90000000";
|
||||
i2c0 = &i2c_0;
|
||||
pci0 = &pci;
|
||||
rtc0 = &rtc_0;
|
||||
@ -47,24 +46,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
ethrawbus {
|
||||
compatible = "sandbox,eth-raw-bus";
|
||||
skip-localhost = <0>;
|
||||
};
|
||||
|
||||
eth@10002000 {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x10002000 0x1000>;
|
||||
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-controller;
|
||||
compatible = "sandbox,gpio";
|
||||
|
@ -8,7 +8,6 @@
|
||||
model = "sandbox";
|
||||
|
||||
aliases {
|
||||
eth5 = "/eth@90000000";
|
||||
i2c0 = &i2c_0;
|
||||
pci0 = &pci;
|
||||
rtc0 = &rtc_0;
|
||||
@ -47,24 +46,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
ethrawbus {
|
||||
compatible = "sandbox,eth-raw-bus";
|
||||
skip-localhost = <1>;
|
||||
};
|
||||
|
||||
eth@10002000 {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x0 0x10002000 0x0 0x1000>;
|
||||
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-controller;
|
||||
compatible = "sandbox,gpio";
|
||||
|
@ -155,25 +155,25 @@
|
||||
eth@10002000 {
|
||||
compatible = "sandbox,eth";
|
||||
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 {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x10003000 0x1000>;
|
||||
fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>;
|
||||
fake-host-hwaddr = [00 00 66 44 22 11];
|
||||
};
|
||||
|
||||
eth_3: sbe5 {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x10005000 0x1000>;
|
||||
fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x33>;
|
||||
fake-host-hwaddr = [00 00 66 44 22 33];
|
||||
};
|
||||
|
||||
eth@10004000 {
|
||||
compatible = "sandbox,eth";
|
||||
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 {
|
||||
|
@ -9,10 +9,14 @@
|
||||
#ifndef __ETH_RAW_OS_H
|
||||
#define __ETH_RAW_OS_H
|
||||
|
||||
#define IFNAMSIZ 16
|
||||
|
||||
/**
|
||||
* struct eth_sandbox_raw_priv - raw socket 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
|
||||
* local: 1 or 0 to select the local interface ('lo') or not
|
||||
* local_bindsd: socket descriptor to prevent the kernel from sending
|
||||
@ -22,14 +26,44 @@
|
||||
*/
|
||||
struct eth_sandbox_raw_priv {
|
||||
int sd;
|
||||
char host_ifname[IFNAMSIZ];
|
||||
unsigned int host_ifindex;
|
||||
void *device;
|
||||
int local;
|
||||
int local_bind_sd;
|
||||
unsigned short local_bind_udp_port;
|
||||
};
|
||||
|
||||
int sandbox_eth_raw_os_start(const char *ifname, unsigned char *ethmac,
|
||||
struct eth_sandbox_raw_priv *priv);
|
||||
/* A struct to mimic if_nameindex but that does not depend on Linux headers */
|
||||
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,
|
||||
struct eth_sandbox_raw_priv *priv);
|
||||
int sandbox_eth_raw_os_recv(void *packet, int *length,
|
||||
|
@ -192,6 +192,9 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
|
||||
|
||||
switch (argc) {
|
||||
case 1:
|
||||
/* refresh bootfile name from env */
|
||||
copy_filename(net_boot_file_name, env_get("bootfile"),
|
||||
sizeof(net_boot_file_name));
|
||||
break;
|
||||
|
||||
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);
|
||||
if (end == (argv[1] + strlen(argv[1]))) {
|
||||
load_addr = addr;
|
||||
/* refresh bootfile name from env */
|
||||
copy_filename(net_boot_file_name, env_get("bootfile"),
|
||||
sizeof(net_boot_file_name));
|
||||
} else {
|
||||
net_boot_file_name_explicit = true;
|
||||
copy_filename(net_boot_file_name, argv[1],
|
||||
|
@ -196,20 +196,21 @@ static int console_tstc(int file)
|
||||
{
|
||||
int i, ret;
|
||||
struct stdio_dev *dev;
|
||||
int prev;
|
||||
|
||||
disable_ctrlc(1);
|
||||
prev = disable_ctrlc(1);
|
||||
for (i = 0; i < cd_count[file]; i++) {
|
||||
dev = console_devices[file][i];
|
||||
if (dev->tstc != NULL) {
|
||||
ret = dev->tstc(dev);
|
||||
if (ret > 0) {
|
||||
tstcdev = dev;
|
||||
disable_ctrlc(0);
|
||||
disable_ctrlc(prev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
disable_ctrlc(0);
|
||||
disable_ctrlc(prev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -603,7 +604,6 @@ static int ctrlc_disabled = 0; /* see disable_ctrl() */
|
||||
static int ctrlc_was_pressed = 0;
|
||||
int ctrlc(void)
|
||||
{
|
||||
#ifndef CONFIG_SANDBOX
|
||||
if (!ctrlc_disabled && gd->have_console) {
|
||||
if (tstc()) {
|
||||
switch (getc()) {
|
||||
@ -615,7 +615,6 @@ int ctrlc(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ config DM_ETH
|
||||
help
|
||||
Enable driver model for Ethernet.
|
||||
|
||||
The eth_*() interface will be implemented by the UC_ETH class
|
||||
This is currently implemented in net/eth.c
|
||||
The eth_*() interface will be implemented by the UCLASS_ETH class
|
||||
This is currently implemented in net/eth-uclass.c
|
||||
Look in include/net.h for details.
|
||||
|
||||
config DRIVER_TI_CPSW
|
||||
@ -181,6 +181,7 @@ config FTMAC100
|
||||
config MVGBE
|
||||
bool "Marvell Orion5x/Kirkwood network interface support"
|
||||
depends on KIRKWOOD || ORION5X
|
||||
select PHYLIB if DM_ETH
|
||||
help
|
||||
This driver supports the network interface units in the
|
||||
Marvell Orion5x and Kirkwood SoCs
|
||||
|
@ -50,6 +50,7 @@ obj-$(CONFIG_RTL8139) += rtl8139.o
|
||||
obj-$(CONFIG_RTL8169) += rtl8169.o
|
||||
obj-$(CONFIG_ETH_SANDBOX) += sandbox.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_RENESAS_RAVB) += ravb.o
|
||||
obj-$(CONFIG_SMC91111) += smc91111.o
|
||||
|
@ -999,7 +999,7 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
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
|
||||
|
||||
priv->phydev = phydev;
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <net.h>
|
||||
#include <malloc.h>
|
||||
#include <miiphy.h>
|
||||
@ -55,20 +56,13 @@ static int smi_wait_ready(struct mvgbe_device *dmvgbe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* smi_reg_read - miiphy_read callback function.
|
||||
*
|
||||
* 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)
|
||||
static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, 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;
|
||||
u32 smi_reg;
|
||||
u32 timeout;
|
||||
u16 data = 0;
|
||||
|
||||
/* Phyadr read 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,
|
||||
int reg_ofs, u16 data)
|
||||
static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
|
||||
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 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;
|
||||
u32 smi_reg;
|
||||
|
||||
@ -171,6 +176,24 @@ static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
|
||||
|
||||
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
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
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_l;
|
||||
|
||||
@ -400,12 +424,13 @@ static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
|
||||
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;
|
||||
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
|
||||
!defined(CONFIG_PHYLIB) && \
|
||||
!defined(CONFIG_DM_ETH) && \
|
||||
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
|
||||
int i;
|
||||
#endif
|
||||
@ -422,7 +447,7 @@ static int mvgbe_init(struct eth_device *dev)
|
||||
|
||||
set_dram_access(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. */
|
||||
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)) && \
|
||||
!defined(CONFIG_PHYLIB) && \
|
||||
!defined(CONFIG_DM_ETH) && \
|
||||
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
|
||||
/* Wait up to 5s for the link status */
|
||||
for (i = 0; i < 5; i++) {
|
||||
u16 phyadr;
|
||||
|
||||
miiphy_read(dev->name, MV_PHY_ADR_REQUEST,
|
||||
miiphy_read(name, MV_PHY_ADR_REQUEST,
|
||||
MV_PHY_ADR_REQUEST, &phyadr);
|
||||
/* Return if we get link up */
|
||||
if (miiphy_link(dev->name, phyadr))
|
||||
if (miiphy_link(name, phyadr))
|
||||
return 0;
|
||||
udelay(1000000);
|
||||
}
|
||||
|
||||
printf("No link on %s\n", dev->name);
|
||||
printf("No link on %s\n", name);
|
||||
return -1;
|
||||
#endif
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
/* 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->pim, 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;
|
||||
}
|
||||
#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)
|
||||
{
|
||||
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
||||
struct mvgbe_registers *regs = dmvgbe->regs;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
#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_txdesc *p_txdesc = dmvgbe->p_txdesc;
|
||||
void *p = (void *)dataptr;
|
||||
@ -571,13 +624,25 @@ static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
|
||||
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);
|
||||
|
||||
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;
|
||||
u32 cmd_sts;
|
||||
u32 timeout = 0;
|
||||
u32 rxdesc_curr_addr;
|
||||
unsigned char *data;
|
||||
int rx_bytes = 0;
|
||||
|
||||
*packetp = NULL;
|
||||
|
||||
/* wait untill rx packet available or timeout */
|
||||
do {
|
||||
@ -621,11 +686,11 @@ static int mvgbe_recv(struct eth_device *dev)
|
||||
" upper layer (net_process_received_packet)\n",
|
||||
__func__);
|
||||
|
||||
/* let the upper layer handle the packet */
|
||||
net_process_received_packet((p_rxdesc_curr->buf_ptr +
|
||||
RX_BUF_OFFSET),
|
||||
(int)(p_rxdesc_curr->byte_cnt -
|
||||
RX_BUF_OFFSET));
|
||||
data = (p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET);
|
||||
rx_bytes = (int)(p_rxdesc_curr->byte_cnt -
|
||||
RX_BUF_OFFSET);
|
||||
|
||||
*packetp = data;
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
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)
|
||||
{
|
||||
struct mii_dev *bus;
|
||||
@ -664,27 +778,53 @@ int mvgbe_phylib_init(struct eth_device *dev, int phyid)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Set phy address of the port */
|
||||
smi_reg_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid);
|
||||
|
||||
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII);
|
||||
if (!phydev) {
|
||||
printf("phy_connect failed\n");
|
||||
phydev = __mvgbe_phy_init(dev, bus, PHY_INTERFACE_MODE_RGMII, phyid);
|
||||
if (!phydev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
phy_config(phydev);
|
||||
phy_startup(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#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)
|
||||
{
|
||||
struct mvgbe_device *dmvgbe;
|
||||
struct eth_device *dev;
|
||||
int devnum;
|
||||
int ret;
|
||||
u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
|
||||
|
||||
for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
|
||||
@ -693,45 +833,16 @@ int mvgbe_initialize(bd_t *bis)
|
||||
continue;
|
||||
|
||||
dmvgbe = malloc(sizeof(struct mvgbe_device));
|
||||
|
||||
if (!dmvgbe)
|
||||
goto error1;
|
||||
return -ENOMEM;
|
||||
|
||||
memset(dmvgbe, 0, sizeof(struct mvgbe_device));
|
||||
|
||||
dmvgbe->p_rxdesc =
|
||||
(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:
|
||||
ret = mvgbe_alloc_buffers(dmvgbe);
|
||||
if (ret) {
|
||||
printf("Err.. %s Failed to allocate memory\n",
|
||||
__func__);
|
||||
return -1;
|
||||
free(dmvgbe);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev = &dmvgbe->dev;
|
||||
@ -783,3 +894,154 @@ error1:
|
||||
}
|
||||
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 */
|
||||
|
@ -30,7 +30,9 @@
|
||||
#define RXUQ 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)
|
||||
#endif
|
||||
#define MVGBE_REG_WR(adr, val) writel(val, &adr)
|
||||
#define MVGBE_REG_RD(adr) readl(&adr)
|
||||
#define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr)
|
||||
@ -479,13 +481,27 @@ struct mvgbe_txdesc {
|
||||
|
||||
/* port device data struct */
|
||||
struct mvgbe_device {
|
||||
#ifndef CONFIG_DM_ETH
|
||||
struct eth_device dev;
|
||||
#endif
|
||||
struct mvgbe_registers *regs;
|
||||
struct mvgbe_txdesc *p_txdesc;
|
||||
struct mvgbe_rxdesc *p_rxdesc;
|
||||
struct mvgbe_rxdesc *p_rxdesc_curr;
|
||||
u8 *p_rxbuf;
|
||||
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__ */
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Copyright 2011, 2013 Freescale Semiconductor, Inc.
|
||||
* author Andy Fleming
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <phy.h>
|
||||
|
||||
#define AR803x_PHY_DEBUG_ADDR_REG 0x1d
|
||||
|
@ -5,7 +5,6 @@
|
||||
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||
* author Andy Fleming
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <phy.h>
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||
* author Andy Fleming
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <phy.h>
|
||||
|
||||
#define MIIM_DM9161_SCR 0x10
|
||||
|
@ -7,8 +7,6 @@
|
||||
*
|
||||
* Based loosely off of Linux's PHY Lib
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <miiphy.h>
|
||||
#include <phy.h>
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||
* author Andy Fleming
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <phy.h>
|
||||
|
||||
/* LXT971 Status 2 registers */
|
||||
|
@ -5,7 +5,6 @@
|
||||
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||
* author Andy Fleming
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <phy.h>
|
||||
|
@ -6,7 +6,6 @@
|
||||
* author Andy Fleming
|
||||
* (C) 2012 NetModule AG, David Andrey, added KSZ9031
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
|
@ -8,8 +8,6 @@
|
||||
* (C) Copyright 2017 Adaptrum, Inc.
|
||||
* Written by Alexandru Gagniuc <alex.g@adaptrum.com> for Adaptrum, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||
* author Andy Fleming
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <phy.h>
|
||||
|
||||
/* NatSemi DP83630 */
|
||||
|
@ -7,8 +7,6 @@
|
||||
*
|
||||
* Based loosely off of Linux's PHY Lib
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <console.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->interface = interface;
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
dev->node = ofnode_null();
|
||||
#endif
|
||||
|
||||
dev->autoneg = AUTONEG_ENABLE;
|
||||
|
||||
dev->addr = addr;
|
||||
|
@ -6,7 +6,6 @@
|
||||
* author Andy Fleming
|
||||
* Copyright 2016 Karsten Merker <merker@debian.org>
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <phy.h>
|
||||
|
@ -9,6 +9,7 @@
|
||||
* Some code copied from linux kernel
|
||||
* Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <miiphy.h>
|
||||
|
||||
/* This code does not check the partner abilities. */
|
||||
|
@ -5,7 +5,6 @@
|
||||
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||
* author Andy Fleming
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <phy.h>
|
||||
|
||||
|
@ -8,11 +8,9 @@
|
||||
#include <linux/compat.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <fdtdec.h>
|
||||
#include <dm.h>
|
||||
#include <dt-bindings/net/ti-dp83867.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* TI DP83867 */
|
||||
#define DP83867_DEVADDR 0x1f
|
||||
@ -24,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define DP83867_CTRL 0x1f
|
||||
|
||||
/* Extended Registers */
|
||||
#define DP83867_CFG4 0x0031
|
||||
#define DP83867_RGMIICTL 0x0032
|
||||
#define DP83867_RGMIIDCTL 0x0086
|
||||
#define DP83867_IO_MUX_CFG 0x0170
|
||||
@ -95,6 +94,7 @@ struct dp83867_private {
|
||||
int tx_id_delay;
|
||||
int fifo_depth;
|
||||
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)
|
||||
{
|
||||
struct dp83867_private *dp83867 = phydev->priv;
|
||||
struct udevice *dev = phydev->dev;
|
||||
int node = dev_of_offset(dev);
|
||||
const void *fdt = gd->fdt_blob;
|
||||
ofnode node;
|
||||
|
||||
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;
|
||||
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;
|
||||
else
|
||||
dp83867->io_impedance = -EINVAL;
|
||||
|
||||
dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
|
||||
"ti,rx-internal-delay", -1);
|
||||
if (ofnode_read_bool(node, "ti,dp83867-rxctrl-strap-quirk"))
|
||||
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),
|
||||
"ti,tx-internal-delay", -1);
|
||||
dp83867->tx_id_delay = ofnode_read_u32_default(node,
|
||||
"ti,tx-internal-delay",
|
||||
-1);
|
||||
|
||||
dp83867->fifo_depth = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
|
||||
"ti,fifo-depth", -1);
|
||||
dp83867->fifo_depth = ofnode_read_u32_default(node, "ti,fifo-depth",
|
||||
-1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -232,6 +238,15 @@ static int dp83867_config(struct phy_device *phydev)
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL,
|
||||
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)) {
|
||||
ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
|
||||
(DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) |
|
||||
|
@ -6,6 +6,7 @@
|
||||
* Original Author: Andy Fleming
|
||||
* Add vsc8662 phy support - Priyanka Jain
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <miiphy.h>
|
||||
|
||||
/* Cicada Auxiliary Control/Status Register */
|
||||
|
@ -10,8 +10,6 @@
|
||||
#include <phy.h>
|
||||
#include <dm.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define MII_PHY_STATUS_SPD_MASK 0x0C00
|
||||
#define MII_PHY_STATUS_FULLDUPLEX 0x1000
|
||||
#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)
|
||||
{
|
||||
u32 phytype;
|
||||
ofnode node;
|
||||
|
||||
debug("%s\n", __func__);
|
||||
phytype = fdtdec_get_int(gd->fdt_blob, dev_of_offset(phydev->dev),
|
||||
"xlnx,phy-type", -1);
|
||||
node = phy_get_ofnode(phydev);
|
||||
if (!ofnode_valid(node))
|
||||
return -EINVAL;
|
||||
|
||||
phytype = ofnode_read_u32_default(node, "xlnx,phy-type", -1);
|
||||
if (phytype == XAE_PHY_TYPE_1000BASE_X)
|
||||
phydev->flags |= XAE_PHY_TYPE_1000BASE_X;
|
||||
|
||||
|
66
drivers/net/sandbox-raw-bus.c
Normal file
66
drivers/net/sandbox-raw-bus.c
Normal 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,
|
||||
};
|
@ -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_pdata *pdata = dev_get_platdata(dev);
|
||||
const char *interface;
|
||||
int ret;
|
||||
|
||||
debug("eth_sandbox_raw: Start\n");
|
||||
|
||||
interface = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
|
||||
"host-raw-interface", NULL);
|
||||
if (interface == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (strcmp(interface, "lo") == 0) {
|
||||
priv->local = 1;
|
||||
ret = sandbox_eth_raw_os_start(priv, pdata->enetaddr);
|
||||
if (priv->local) {
|
||||
env_set("ipaddr", "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)
|
||||
@ -133,18 +130,54 @@ static void sb_eth_raw_stop(struct udevice *dev)
|
||||
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 = {
|
||||
.start = sb_eth_raw_start,
|
||||
.send = sb_eth_raw_send,
|
||||
.recv = sb_eth_raw_recv,
|
||||
.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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,8 @@ static int sb_eth_start(struct udevice *dev)
|
||||
|
||||
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];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -203,8 +201,18 @@ static int sb_eth_remove(struct udevice *dev)
|
||||
static int sb_eth_ofdata_to_platdata(struct udevice *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;
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ struct zynq_gem_priv {
|
||||
struct zynq_gem_regs *iobase;
|
||||
phy_interface_t interface;
|
||||
struct phy_device *phydev;
|
||||
int phy_of_handle;
|
||||
ofnode phy_of_node;
|
||||
struct mii_dev *bus;
|
||||
struct clk clk;
|
||||
u32 max_speed;
|
||||
@ -348,9 +348,7 @@ static int zynq_phy_init(struct udevice *dev)
|
||||
}
|
||||
|
||||
priv->phydev->advertising = priv->phydev->supported;
|
||||
|
||||
if (priv->phy_of_handle > 0)
|
||||
dev_set_of_offset(priv->phydev->dev, priv->phy_of_handle);
|
||||
priv->phydev->node = priv->phy_of_node;
|
||||
|
||||
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 zynq_gem_priv *priv = dev_get_priv(dev);
|
||||
int node = dev_of_offset(dev);
|
||||
struct ofnode_phandle_args phandle_args;
|
||||
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;
|
||||
/* Hardcode for now */
|
||||
priv->phyaddr = -1;
|
||||
|
||||
priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob, node,
|
||||
"phy-handle");
|
||||
if (priv->phy_of_handle > 0)
|
||||
priv->phyaddr = fdtdec_get_int(gd->fdt_blob,
|
||||
priv->phy_of_handle, "reg", -1);
|
||||
if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
|
||||
&phandle_args)) {
|
||||
debug("phy-handle does not exist %s\n", dev->name);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
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)
|
||||
pdata->phy_interface = phy_get_interface_by_name(phy_mode);
|
||||
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->max_speed = fdtdec_get_uint(gd->fdt_blob, priv->phy_of_handle,
|
||||
"max-speed", SPEED_1000);
|
||||
priv->int_pcs = fdtdec_get_bool(gd->fdt_blob, node,
|
||||
"is-internal-pcspma");
|
||||
priv->max_speed = dev_read_u32_default(dev, "max-speed", SPEED_1000);
|
||||
priv->int_pcs = dev_read_bool(dev, "is-internal-pcspma");
|
||||
|
||||
printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase,
|
||||
priv->phyaddr, phy_string_for_interface(priv->interface));
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <console.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.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);
|
||||
priv->start_of_line = 0;
|
||||
|
||||
if (state->term_raw != STATE_TERM_RAW)
|
||||
disable_ctrlc(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,7 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef CONFIG_PHY_AQUANTIA
|
||||
#include <miiphy.h>
|
||||
#include <phy.h>
|
||||
#include <phy_interface.h>
|
||||
#endif
|
||||
|
||||
struct spi_slave;
|
||||
|
@ -839,6 +839,20 @@ ushort env_get_vlan(char *);
|
||||
/* copy a filename (allow for "..." notation, limit length) */
|
||||
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 */
|
||||
unsigned int random_port(void);
|
||||
|
||||
|
@ -9,10 +9,12 @@
|
||||
#ifndef _PHY_H
|
||||
#define _PHY_H
|
||||
|
||||
#include <dm.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <phy_interface.h>
|
||||
|
||||
#define PHY_FIXED_ID 0xa5a55a5a
|
||||
|
||||
@ -48,60 +50,6 @@
|
||||
#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;
|
||||
|
||||
#define MDIO_NAME_LEN 32
|
||||
@ -165,6 +113,7 @@ struct phy_device {
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
struct udevice *dev;
|
||||
ofnode node;
|
||||
#else
|
||||
struct eth_device *dev;
|
||||
#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 udevice *dev,
|
||||
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
|
||||
void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
|
||||
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
|
||||
struct eth_device *dev,
|
||||
phy_interface_t interface);
|
||||
static inline ofnode phy_get_ofnode(struct phy_device *phydev)
|
||||
{
|
||||
return ofnode_null();
|
||||
}
|
||||
#endif
|
||||
int phy_startup(struct phy_device *phydev);
|
||||
int phy_config(struct phy_device *phydev);
|
||||
|
65
include/phy_interface.h
Normal file
65
include/phy_interface.h
Normal 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 */
|
@ -361,6 +361,7 @@ efi_status_t efi_net_register(void)
|
||||
memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
|
||||
netobj->net_mode.hwaddr_size = ARP_HLEN;
|
||||
netobj->net_mode.max_packet_size = PKTSIZE;
|
||||
netobj->net_mode.if_type = ARP_ETHER;
|
||||
|
||||
netobj->pxe.mode = &netobj->pxe_mode;
|
||||
if (dhcp_ack)
|
||||
|
@ -307,7 +307,7 @@ void eth_halt(void)
|
||||
struct eth_device_priv *priv;
|
||||
|
||||
current = eth_get_dev();
|
||||
if (!current || !device_active(current))
|
||||
if (!current || !eth_is_active(current))
|
||||
return;
|
||||
|
||||
eth_get_ops(current)->stop(current);
|
||||
|
71
net/net.c
71
net/net.c
@ -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,
|
||||
int flags)
|
||||
{
|
||||
@ -332,6 +312,16 @@ void net_auto_load(void)
|
||||
const char *s = env_get("autoload");
|
||||
|
||||
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.
|
||||
*/
|
||||
@ -347,6 +337,16 @@ void net_auto_load(void)
|
||||
net_set_state(NETLOOP_SUCCESS);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1341,7 +1341,7 @@ static int net_check_prereq(enum proto_t protocol)
|
||||
/* Fall through */
|
||||
case TFTPGET:
|
||||
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");
|
||||
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)
|
||||
{
|
||||
if (*src && (*src == '"')) {
|
||||
if (src && *src && (*src == '"')) {
|
||||
++src;
|
||||
--size;
|
||||
}
|
||||
|
||||
while ((--size > 0) && *src && (*src != '"'))
|
||||
while ((--size > 0) && src && *src && (*src != '"'))
|
||||
*dst++ = *src++;
|
||||
*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) || \
|
||||
defined(CONFIG_CMD_SNTP) || \
|
||||
defined(CONFIG_CMD_DNS)
|
||||
|
43
net/nfs.c
43
net/nfs.c
@ -533,7 +533,7 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
|
||||
switch (ntohl(rpc_pkt.u.reply.data[0])) {
|
||||
/* Minimal supported NFS version */
|
||||
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) ?
|
||||
2 : 3,
|
||||
ntohl(rpc_pkt.u.reply.data[0]),
|
||||
@ -855,40 +855,29 @@ void nfs_start(void)
|
||||
|
||||
if (nfs_path == NULL) {
|
||||
net_set_state(NETLOOP_FAIL);
|
||||
debug("*** ERROR: Fail allocate memory\n");
|
||||
printf("*** ERROR: Fail allocate memory\n");
|
||||
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",
|
||||
net_ip.s_addr & 0xFF,
|
||||
(net_ip.s_addr >> 8) & 0xFF,
|
||||
(net_ip.s_addr >> 16) & 0xFF,
|
||||
(net_ip.s_addr >> 24) & 0xFF);
|
||||
|
||||
debug("*** Warning: no boot file name; using '%s'\n",
|
||||
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);
|
||||
}
|
||||
printf("*** Warning: no boot file name; using '%s'\n",
|
||||
nfs_path);
|
||||
}
|
||||
|
||||
nfs_filename = basename(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",
|
||||
&nfs_server_ip, &net_ip);
|
||||
printf("File transfer via NFS from server %pI4; our IP address is %pI4",
|
||||
&nfs_server_ip, &net_ip);
|
||||
|
||||
/* Check if we need to send across this subnet */
|
||||
if (net_gateway.s_addr && net_netmask.s_addr) {
|
||||
@ -896,19 +885,19 @@ void nfs_start(void)
|
||||
struct in_addr server_net;
|
||||
|
||||
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)
|
||||
debug("; sending through gateway %pI4",
|
||||
&net_gateway);
|
||||
printf("; sending through gateway %pI4",
|
||||
&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) {
|
||||
debug(" Size is 0x%x Bytes = ",
|
||||
net_boot_file_expected_size_in_blocks << 9);
|
||||
printf(" Size is 0x%x Bytes = ",
|
||||
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_udp_handler(nfs_handler);
|
||||
|
@ -42,6 +42,7 @@
|
||||
* 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_MAX_ATTRS 26
|
||||
|
||||
/* Values for Accept State flag on RPC answers (See: rfc1831) */
|
||||
enum rpc_accept_stat {
|
||||
@ -55,7 +56,8 @@ enum rpc_accept_stat {
|
||||
|
||||
struct rpc_t {
|
||||
union {
|
||||
uint8_t data[2048];
|
||||
uint8_t data[NFS_READ_SIZE + (6 + NFS_MAX_ATTRS) *
|
||||
sizeof(uint32_t)];
|
||||
struct {
|
||||
uint32_t id;
|
||||
uint32_t type;
|
||||
@ -72,7 +74,8 @@ struct rpc_t {
|
||||
uint32_t verifier;
|
||||
uint32_t v2;
|
||||
uint32_t astatus;
|
||||
uint32_t data[NFS_READ_SIZE];
|
||||
uint32_t data[NFS_READ_SIZE / sizeof(uint32_t) +
|
||||
NFS_MAX_ATTRS];
|
||||
} reply;
|
||||
} u;
|
||||
} __attribute__((packed));
|
||||
|
13
net/tftp.c
13
net/tftp.c
@ -735,7 +735,7 @@ void tftp_start(enum proto_t protocol)
|
||||
tftp_block_size_option, timeout_ms);
|
||||
|
||||
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",
|
||||
net_ip.s_addr & 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",
|
||||
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());
|
||||
|
Loading…
Reference in New Issue
Block a user