1f40a31e6SJoe Hershberger // SPDX-License-Identifier: GPL-2.0+
2f40a31e6SJoe Hershberger /*
3f40a31e6SJoe Hershberger * Copyright (c) 2018 National Instruments
4f40a31e6SJoe Hershberger * Copyright (c) 2018 Joe Hershberger <joe.hershberger@ni.com>
5f40a31e6SJoe Hershberger */
6f40a31e6SJoe Hershberger
7f40a31e6SJoe Hershberger #include <common.h>
8f40a31e6SJoe Hershberger #include <asm/eth-raw-os.h>
9f40a31e6SJoe Hershberger #include <dm.h>
10f40a31e6SJoe Hershberger #include <errno.h>
11f40a31e6SJoe Hershberger #include <dm/device-internal.h>
12f40a31e6SJoe Hershberger #include <dm/lists.h>
13f40a31e6SJoe Hershberger
eth_raw_bus_post_bind(struct udevice * dev)14f40a31e6SJoe Hershberger static int eth_raw_bus_post_bind(struct udevice *dev)
15f40a31e6SJoe Hershberger {
16f40a31e6SJoe Hershberger struct sandbox_eth_raw_if_nameindex *ni, *i;
17f40a31e6SJoe Hershberger struct udevice *child;
18f40a31e6SJoe Hershberger struct eth_sandbox_raw_priv *priv;
19f40a31e6SJoe Hershberger char *ub_ifname;
20f40a31e6SJoe Hershberger static const char ub_ifname_pfx[] = "host_";
21f40a31e6SJoe Hershberger u32 skip_localhost = 0;
22f40a31e6SJoe Hershberger
23f40a31e6SJoe Hershberger ni = sandbox_eth_raw_if_nameindex();
24f40a31e6SJoe Hershberger if (!ni)
25f40a31e6SJoe Hershberger return -EINVAL;
26f40a31e6SJoe Hershberger
27f40a31e6SJoe Hershberger dev_read_u32(dev, "skip-localhost", &skip_localhost);
28f40a31e6SJoe Hershberger for (i = ni; !(i->if_index == 0 && !i->if_name); i++) {
29f40a31e6SJoe Hershberger int local = sandbox_eth_raw_os_is_local(i->if_name);
30f40a31e6SJoe Hershberger
31f40a31e6SJoe Hershberger if (local < 0)
32f40a31e6SJoe Hershberger continue;
33f40a31e6SJoe Hershberger if (skip_localhost && local)
34f40a31e6SJoe Hershberger continue;
35f40a31e6SJoe Hershberger
36f40a31e6SJoe Hershberger ub_ifname = calloc(IFNAMSIZ + sizeof(ub_ifname_pfx), 1);
37f40a31e6SJoe Hershberger strcpy(ub_ifname, ub_ifname_pfx);
38f40a31e6SJoe Hershberger strncat(ub_ifname, i->if_name, IFNAMSIZ);
39f40a31e6SJoe Hershberger device_bind_driver(dev, "eth_sandbox_raw", ub_ifname, &child);
40f40a31e6SJoe Hershberger
41f40a31e6SJoe Hershberger device_set_name_alloced(child);
42f40a31e6SJoe Hershberger device_probe(child);
43f40a31e6SJoe Hershberger priv = dev_get_priv(child);
44f40a31e6SJoe Hershberger if (priv) {
45*e628bba7SSimon Glass strcpy(priv->host_ifname, i->if_name);
46f40a31e6SJoe Hershberger priv->host_ifindex = i->if_index;
47f40a31e6SJoe Hershberger priv->local = local;
48f40a31e6SJoe Hershberger }
49f40a31e6SJoe Hershberger }
50f40a31e6SJoe Hershberger
51f40a31e6SJoe Hershberger sandbox_eth_raw_if_freenameindex(ni);
52f40a31e6SJoe Hershberger
53f40a31e6SJoe Hershberger return 0;
54f40a31e6SJoe Hershberger }
55f40a31e6SJoe Hershberger
56f40a31e6SJoe Hershberger static const struct udevice_id sandbox_eth_raw_bus_ids[] = {
57f40a31e6SJoe Hershberger { .compatible = "sandbox,eth-raw-bus" },
58f40a31e6SJoe Hershberger { }
59f40a31e6SJoe Hershberger };
60f40a31e6SJoe Hershberger
61f40a31e6SJoe Hershberger U_BOOT_DRIVER(sandbox_eth_raw_bus) = {
62f40a31e6SJoe Hershberger .name = "sb_eth_raw_bus",
63f40a31e6SJoe Hershberger .id = UCLASS_SIMPLE_BUS,
64f40a31e6SJoe Hershberger .of_match = sandbox_eth_raw_bus_ids,
65f40a31e6SJoe Hershberger .bind = eth_raw_bus_post_bind,
66f40a31e6SJoe Hershberger };
67