[PATCH 08/15] net-lwip: import net command from cmd/net.c

Add support for "net list" and "net stats" to net-lwip/ by copying the code from cmd/net.c.
Signed-off-by: Jerome Forissier jerome.forissier@linaro.org --- cmd/net-lwip.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++ include/net-lwip.h | 50 +++++++++++++++++++++++ 2 files changed, 148 insertions(+)
diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c index 2926399bd0..20d0d61176 100644 --- a/cmd/net-lwip.c +++ b/cmd/net-lwip.c @@ -2,6 +2,10 @@ /* Copyright (C) 2024 Linaro Ltd. */
#include <command.h> +#include <dm/device.h> +#include <dm/uclass.h> +#include <linux/compat.h> +#include <linux/ethtool.h> #include <net-lwip.h>
#if defined(CONFIG_CMD_DHCP_LWIP) @@ -43,3 +47,97 @@ U_BOOT_CMD( "[loadAddress] URL" ); #endif + +static int do_net_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + const struct udevice *current = eth_get_dev(); + unsigned char env_enetaddr[ARP_HLEN]; + const struct udevice *dev; + struct uclass *uc; + + uclass_id_foreach_dev(UCLASS_ETH, dev, uc) { + eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr); + printf("eth%d : %s %pM %s\n", dev_seq(dev), dev->name, env_enetaddr, + current == dev ? "active" : ""); + } + return CMD_RET_SUCCESS; +} + +static int do_net_stats(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + int nstats, err, i, off; + struct udevice *dev; + u64 *values; + u8 *strings; + + if (argc < 2) + return CMD_RET_USAGE; + + err = uclass_get_device_by_name(UCLASS_ETH, argv[1], &dev); + if (err) { + printf("Could not find device %s\n", argv[1]); + return CMD_RET_FAILURE; + } + + if (!eth_get_ops(dev)->get_sset_count || + !eth_get_ops(dev)->get_strings || + !eth_get_ops(dev)->get_stats) { + printf("Driver does not implement stats dump!\n"); + return CMD_RET_FAILURE; + } + + nstats = eth_get_ops(dev)->get_sset_count(dev); + strings = kcalloc(nstats, ETH_GSTRING_LEN, GFP_KERNEL); + if (!strings) + return CMD_RET_FAILURE; + + values = kcalloc(nstats, sizeof(u64), GFP_KERNEL); + if (!values) + goto err_free_strings; + + eth_get_ops(dev)->get_strings(dev, strings); + eth_get_ops(dev)->get_stats(dev, values); + + off = 0; + for (i = 0; i < nstats; i++) { + printf(" %s: %llu\n", &strings[off], values[i]); + off += ETH_GSTRING_LEN; + }; + + return CMD_RET_SUCCESS; + +err_free_strings: + kfree(strings); + + return CMD_RET_FAILURE; +} + +static struct cmd_tbl cmd_net[] = { + U_BOOT_CMD_MKENT(list, 1, 0, do_net_list, "", ""), + U_BOOT_CMD_MKENT(stats, 2, 0, do_net_stats, "", ""), +}; + +static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + struct cmd_tbl *cp; + + cp = find_cmd_tbl(argv[1], cmd_net, ARRAY_SIZE(cmd_net)); + + /* Drop the net command */ + argc--; + argv++; + + if (!cp || argc > cp->maxargs) + return CMD_RET_USAGE; + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) + return CMD_RET_SUCCESS; + + return cp->cmd(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD( + net, 3, 1, do_net, + "NET sub-system", + "list - list available devices\n" + "stats <device> - dump statistics for specified device\n" +); diff --git a/include/net-lwip.h b/include/net-lwip.h index 23ad70fc09..6fda940fec 100644 --- a/include/net-lwip.h +++ b/include/net-lwip.h @@ -51,6 +51,56 @@ int eth_env_get_enetaddr_by_index(const char *base_name, int index, int eth_init(void); /* Initialize the device */ int eth_send(void *packet, int length); /* Send a packet */ int eth_rx(void); + +/** + * struct eth_ops - functions of Ethernet MAC controllers + * + * start: Prepare the hardware to send and receive packets + * send: Send the bytes passed in "packet" as a packet on the wire + * recv: Check if the hardware received a packet. If so, set the pointer to the + * packet buffer in the packetp parameter. If not, return an error or 0 to + * indicate that the hardware receive FIFO is empty. If 0 is returned, the + * network stack will not process the empty packet, but free_pkt() will be + * called if supplied + * free_pkt: Give the driver an opportunity to manage its packet buffer memory + * when the network stack is finished processing it. This will only be + * called when no error was returned from recv - optional + * stop: Stop the hardware from looking for packets - may be called even if + * state == PASSIVE + * mcast: Join or leave a multicast group (for TFTP) - optional + * write_hwaddr: Write a MAC address to the hardware (used to pass it to Linux + * on some platforms like ARM). This function expects the + * eth_pdata::enetaddr field to be populated. The method can + * return -ENOSYS to indicate that this is not implemented for + this hardware - optional. + * read_rom_hwaddr: Some devices have a backup of the MAC address stored in a + * ROM on the board. This is how the driver should expose it + * to the network stack. This function should fill in the + * eth_pdata::enetaddr field - optional + * set_promisc: Enable or Disable promiscuous mode + * get_sset_count: Number of statistics counters + * get_string: Names of the statistic counters + * get_stats: The values of the statistic counters + */ +struct eth_ops { + int (*start)(struct udevice *dev); + int (*send)(struct udevice *dev, void *packet, int length); + int (*recv)(struct udevice *dev, int flags, uchar **packetp); + int (*free_pkt)(struct udevice *dev, uchar *packet, int length); + void (*stop)(struct udevice *dev); + int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join); + int (*write_hwaddr)(struct udevice *dev); + int (*read_rom_hwaddr)(struct udevice *dev); + int (*set_promisc)(struct udevice *dev, bool enable); + int (*get_sset_count)(struct udevice *dev); + void (*get_strings)(struct udevice *dev, u8 *data); + void (*get_stats)(struct udevice *dev, u64 *data); +}; + +#define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops) + +struct udevice *eth_get_dev(void); /* get the current device */ +int eth_get_dev_index(void); const char *eth_get_name(void); int eth_get_dev_index(void); int eth_init_state_only(void); /* Set active state */

On Wed, 22 May 2024 at 19:04, Jerome Forissier jerome.forissier@linaro.org wrote:
Add support for "net list" and "net stats" to net-lwip/ by copying the code from cmd/net.c.
Signed-off-by: Jerome Forissier jerome.forissier@linaro.org
cmd/net-lwip.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++ include/net-lwip.h | 50 +++++++++++++++++++++++ 2 files changed, 148 insertions(+)
diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c index 2926399bd0..20d0d61176 100644 --- a/cmd/net-lwip.c +++ b/cmd/net-lwip.c @@ -2,6 +2,10 @@ /* Copyright (C) 2024 Linaro Ltd. */
#include <command.h> +#include <dm/device.h> +#include <dm/uclass.h> +#include <linux/compat.h> +#include <linux/ethtool.h> #include <net-lwip.h>
#if defined(CONFIG_CMD_DHCP_LWIP) @@ -43,3 +47,97 @@ U_BOOT_CMD( "[loadAddress] URL" ); #endif
+static int do_net_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{
const struct udevice *current = eth_get_dev();
unsigned char env_enetaddr[ARP_HLEN];
const struct udevice *dev;
struct uclass *uc;
uclass_id_foreach_dev(UCLASS_ETH, dev, uc) {
eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr);
printf("eth%d : %s %pM %s\n", dev_seq(dev), dev->name, env_enetaddr,
current == dev ? "active" : "");
}
return CMD_RET_SUCCESS;
+}
Some of these functions seem to be a c/p from cmd/net.c Carve the common ones out in cmd/net-common.c and reuse them please
[...]
Cheers /Ilias

On 5/24/24 11:38, Ilias Apalodimas wrote:
On Wed, 22 May 2024 at 19:04, Jerome Forissier jerome.forissier@linaro.org wrote:
Add support for "net list" and "net stats" to net-lwip/ by copying the code from cmd/net.c.
Signed-off-by: Jerome Forissier jerome.forissier@linaro.org
cmd/net-lwip.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++ include/net-lwip.h | 50 +++++++++++++++++++++++ 2 files changed, 148 insertions(+)
diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c index 2926399bd0..20d0d61176 100644 --- a/cmd/net-lwip.c +++ b/cmd/net-lwip.c @@ -2,6 +2,10 @@ /* Copyright (C) 2024 Linaro Ltd. */
#include <command.h> +#include <dm/device.h> +#include <dm/uclass.h> +#include <linux/compat.h> +#include <linux/ethtool.h> #include <net-lwip.h>
#if defined(CONFIG_CMD_DHCP_LWIP) @@ -43,3 +47,97 @@ U_BOOT_CMD( "[loadAddress] URL" ); #endif
+static int do_net_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{
const struct udevice *current = eth_get_dev();
unsigned char env_enetaddr[ARP_HLEN];
const struct udevice *dev;
struct uclass *uc;
uclass_id_foreach_dev(UCLASS_ETH, dev, uc) {
eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr);
printf("eth%d : %s %pM %s\n", dev_seq(dev), dev->name, env_enetaddr,
current == dev ? "active" : "");
}
return CMD_RET_SUCCESS;
+}
Some of these functions seem to be a c/p from cmd/net.c Carve the common ones out in cmd/net-common.c and reuse them please
Totally makes sense. Done in upcoming v2.
participants (2)
-
Ilias Apalodimas
-
Jerome Forissier