sandbox: eth-raw: Add a SIMPLE_BUS to enumerate host interfaces

Ask the OS for each of its interfaces and for each one, bind a U-Boot
device and then probe it. This will allocate the priv data structure
that is then populated.

Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Joe Hershberger 2018-07-02 14:47:54 -05:00
parent b96ced9cdb
commit f40a31e695
6 changed files with 98 additions and 26 deletions

View File

@ -23,6 +23,16 @@
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
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 sandbox_eth_raw_os_is_local(const char *ifname)
{ {
int fd = socket(AF_INET, SOCK_DGRAM, 0); int fd = socket(AF_INET, SOCK_DGRAM, 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

@ -34,6 +34,17 @@ struct eth_sandbox_raw_priv {
unsigned short local_bind_udp_port; unsigned short local_bind_udp_port;
}; };
/* 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. * Check if the interface named "ifname" is a localhost interface or not.
* ifname - the interface name on the host to check * ifname - the interface name on the host to check

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

@ -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,
};