From 398e7512d8d7ea5aac8ba0a72c07a3810ce39f42 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 30 Jul 2019 14:49:56 -0500 Subject: net: Fix Covarity Defect 244093 Don't allow unterminated strings Signed-off-by: Joe Hershberger --- net/mdio-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mdio-uclass.c b/net/mdio-uclass.c index 36a404ff44..1c0d25272a 100644 --- a/net/mdio-uclass.c +++ b/net/mdio-uclass.c @@ -75,7 +75,7 @@ static int dm_mdio_post_probe(struct udevice *dev) pdata->mii_bus->write = mdio_write; pdata->mii_bus->reset = mdio_reset; pdata->mii_bus->priv = dev; - strncpy(pdata->mii_bus->name, dev->name, MDIO_NAME_LEN); + strncpy(pdata->mii_bus->name, dev->name, MDIO_NAME_LEN - 1); return mdio_register(pdata->mii_bus); } -- cgit v1.2.1 From 14a8adebb559ca6dbf563a0246ad8d2241606879 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 30 Jul 2019 16:51:41 -0500 Subject: net: mdio: Clarify code flow Covarity 244085 & 244090 Document that the lack of breaks is intentional. Series-to: u-boot Series-cc: ti Signed-off-by: Joe Hershberger --- cmd/mdio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/mdio.c b/cmd/mdio.c index add6440813..22c8fbe856 100644 --- a/cmd/mdio.c +++ b/cmd/mdio.c @@ -253,12 +253,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) case 'w': if (pos > 1) data = simple_strtoul(argv[pos--], NULL, 16); + /* Intentional fall-through - Get reg for read and write */ case 'r': if (pos > 1) if (extract_reg_range(argv[pos--], &devadlo, &devadhi, ®lo, ®hi)) return CMD_RET_FAILURE; - + /* Intentional fall-through - Get phy for all commands */ default: if (pos > 1) if (extract_phy_range(&argv[2], pos - 1, &bus, -- cgit v1.2.1 From bb53ae38de567e766289f383349879d73600b71c Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 3 Sep 2019 18:14:06 -0500 Subject: Revert "drivers: net: driver for MDIO muxes controlled over I2C" This reverts commit d9a9174fa5687521035b2ec82cce86cdcf4f36e6. --- drivers/net/Kconfig | 8 -------- drivers/net/Makefile | 1 - 2 files changed, 9 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 084e095229..6eb22df528 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -595,12 +595,4 @@ config FSL_ENETC This driver supports the NXP ENETC Ethernet controller found on some of the NXP SoCs. -config MDIO_MUX_I2CREG - bool "MDIO MUX accessed as a register over I2C" - depends on DM_MDIO_MUX && DM_I2C - help - This driver is used for MDIO muxes driven by writing to a register of - an I2C chip. The board it was developed for uses a mux controlled by - on-board FPGA which in turn is accessed as a chip over I2C. - endif # NETDEVICES diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 71c0889355..b6e40df522 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -37,7 +37,6 @@ obj-$(CONFIG_LAN91C96) += lan91c96.o obj-$(CONFIG_LPC32XX_ETH) += lpc32xx_eth.o obj-$(CONFIG_MACB) += macb.o obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o -obj-$(CONFIG_MDIO_MUX_I2CREG) += mdio_mux_i2creg.o obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o obj-$(CONFIG_MT7628_ETH) += mt7628-eth.o -- cgit v1.2.1 From 74dd38386759dfef24a27d6e1b691d31b19aae07 Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Tue, 16 Jul 2019 11:21:17 +0300 Subject: drivers: net: driver for MDIO muxes controlled over I2C This driver is used for MDIO muxes driven over I2C. This is currently used on Freescale LS1028A QDS board, on which the physical MDIO MUX is controlled by an on-board FPGA which in turn is configured through I2C. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger Reviewed-by: Bin Meng --- drivers/net/Kconfig | 8 ++++ drivers/net/Makefile | 1 + drivers/net/mdio_mux_i2creg.c | 108 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 drivers/net/mdio_mux_i2creg.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6eb22df528..084e095229 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -595,4 +595,12 @@ config FSL_ENETC This driver supports the NXP ENETC Ethernet controller found on some of the NXP SoCs. +config MDIO_MUX_I2CREG + bool "MDIO MUX accessed as a register over I2C" + depends on DM_MDIO_MUX && DM_I2C + help + This driver is used for MDIO muxes driven by writing to a register of + an I2C chip. The board it was developed for uses a mux controlled by + on-board FPGA which in turn is accessed as a chip over I2C. + endif # NETDEVICES diff --git a/drivers/net/Makefile b/drivers/net/Makefile index b6e40df522..71c0889355 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_LAN91C96) += lan91c96.o obj-$(CONFIG_LPC32XX_ETH) += lpc32xx_eth.o obj-$(CONFIG_MACB) += macb.o obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o +obj-$(CONFIG_MDIO_MUX_I2CREG) += mdio_mux_i2creg.o obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o obj-$(CONFIG_MT7628_ETH) += mt7628-eth.o diff --git a/drivers/net/mdio_mux_i2creg.c b/drivers/net/mdio_mux_i2creg.c new file mode 100644 index 0000000000..3e82898f46 --- /dev/null +++ b/drivers/net/mdio_mux_i2creg.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019 + * Alex Marginean, NXP + */ + +#include +#include +#include +#include + +/* + * This driver is used for MDIO muxes driven by writing to a register of an I2C + * chip. The board it was developed for uses a mux controlled by on-board FPGA + * which in turn is accessed as a chip over I2C. + */ + +struct mdio_mux_i2creg_priv { + struct udevice *chip; + int reg; + int mask; +}; + +static int mdio_mux_i2creg_select(struct udevice *mux, int cur, int sel) +{ + struct mdio_mux_i2creg_priv *priv = dev_get_priv(mux); + u8 val, val_old; + + /* if last selection didn't change we're good to go */ + if (cur == sel) + return 0; + + val_old = dm_i2c_reg_read(priv->chip, priv->reg); + val = (val_old & ~priv->mask) | (sel & priv->mask); + debug("%s: chip %s, reg %x, val %x => %x\n", __func__, priv->chip->name, + priv->reg, val_old, val); + dm_i2c_reg_write(priv->chip, priv->reg, val); + + return 0; +} + +static const struct mdio_mux_ops mdio_mux_i2creg_ops = { + .select = mdio_mux_i2creg_select, +}; + +static int mdio_mux_i2creg_probe(struct udevice *dev) +{ + struct mdio_mux_i2creg_priv *priv = dev_get_priv(dev); + ofnode chip_node, bus_node; + struct udevice *i2c_bus; + u32 reg_mask[2]; + u32 chip_addr; + int err; + + /* read the register addr/mask pair */ + err = dev_read_u32_array(dev, "mux-reg-masks", reg_mask, 2); + if (err) { + debug("%s: error reading mux-reg-masks property\n", __func__); + return err; + } + + /* parent should be an I2C chip, grandparent should be an I2C bus */ + chip_node = ofnode_get_parent(dev->node); + bus_node = ofnode_get_parent(chip_node); + + err = uclass_get_device_by_ofnode(UCLASS_I2C, bus_node, &i2c_bus); + if (err) { + debug("%s: can't find I2C bus for node %s\n", __func__, + ofnode_get_name(bus_node)); + return err; + } + + err = ofnode_read_u32(chip_node, "reg", &chip_addr); + if (err) { + debug("%s: can't read chip address in %s\n", __func__, + ofnode_get_name(chip_node)); + return err; + } + + err = i2c_get_chip(i2c_bus, (uint)chip_addr, 1, &priv->chip); + if (err) { + debug("%s: can't find i2c chip device for addr %x\n", __func__, + chip_addr); + return err; + } + + priv->reg = (int)reg_mask[0]; + priv->mask = (int)reg_mask[1]; + + debug("%s: chip %s, reg %x, mask %x\n", __func__, priv->chip->name, + priv->reg, priv->mask); + + return 0; +} + +static const struct udevice_id mdio_mux_i2creg_ids[] = { + { .compatible = "mdio-mux-i2creg" }, + { } +}; + +U_BOOT_DRIVER(mdio_mux_i2creg) = { + .name = "mdio_mux_i2creg", + .id = UCLASS_MDIO_MUX, + .of_match = mdio_mux_i2creg_ids, + .probe = mdio_mux_i2creg_probe, + .ops = &mdio_mux_i2creg_ops, + .priv_auto_alloc_size = sizeof(struct mdio_mux_i2creg_priv), +}; -- cgit v1.2.1 From 1bad991205780cd9f7ebdbdeb0d3a7d118f9f247 Mon Sep 17 00:00:00 2001 From: Florinel Iordache Date: Wed, 15 May 2019 09:09:21 +0000 Subject: drivers/fsl-mc: Create Kconfig file to manage driver specific configs better Create drivers/net/fsl-mc/Kconfig and move fsl-mc specific configs from arch/arm/cpu/armv8/fsl-layerscape/Kconfig to this new Kconfig Signed-off-by: Florinel Iordache Acked-by: Joe Hershberger --- arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 17 ----------------- drivers/net/Kconfig | 1 + drivers/net/fsl-mc/Kconfig | 25 +++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 17 deletions(-) create mode 100644 drivers/net/fsl-mc/Kconfig diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index 42d31fdab0..54d03ae622 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -245,14 +245,6 @@ config FSL_LSCH3 config NXP_LSCH3_2 bool -config FSL_MC_ENET - bool "Management Complex network" - depends on ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A - default y - select RESV_RAM - help - Enable Management Complex (MC) network - menu "Layerscape architecture" depends on FSL_LSCH2 || FSL_LSCH3 @@ -593,15 +585,6 @@ config SYS_FSL_HAS_RGMII bool depends on SYS_FSL_EC1 || SYS_FSL_EC2 - -config SYS_MC_RSV_MEM_ALIGN - hex "Management Complex reserved memory alignment" - depends on RESV_RAM - default 0x20000000 if ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A - help - Reserved memory needs to be aligned for MC to use. Default value - is 512MB. - config SPL_LDSCRIPT default "arch/arm/cpu/armv8/u-boot-spl.lds" if ARCH_LS1043A || ARCH_LS1046A || ARCH_LS2080A diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 084e095229..aaf10a2c59 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1,5 +1,6 @@ source "drivers/net/phy/Kconfig" source "drivers/net/pfe_eth/Kconfig" +source "drivers/net/fsl-mc/Kconfig" config DM_ETH bool "Enable Driver Model for Ethernet drivers" diff --git a/drivers/net/fsl-mc/Kconfig b/drivers/net/fsl-mc/Kconfig new file mode 100644 index 0000000000..25a2cb8ffa --- /dev/null +++ b/drivers/net/fsl-mc/Kconfig @@ -0,0 +1,25 @@ +# +# NXP Management Complex +# + +menuconfig FSL_MC_ENET + bool "NXP Management Complex" + depends on ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A + default y + select RESV_RAM + help + Enable Management Complex (MC) network + This is NXP Management Complex menuconfig + that contains all MC related config options + +if FSL_MC_ENET + +config SYS_MC_RSV_MEM_ALIGN + hex "Management Complex reserved memory alignment" + depends on RESV_RAM + default 0x20000000 if ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A + help + Reserved memory needs to be aligned for MC to use. Default value + is 512MB. + +endif # FSL_MC_ENET -- cgit v1.2.1 From 3eaac6307dff1e281f89fece521dc8a14078bf61 Mon Sep 17 00:00:00 2001 From: Ramon Fried Date: Thu, 18 Jul 2019 21:43:30 +0300 Subject: net: introduce packet capture support Add support for capturing ethernet packets and storing them in memory in PCAP(2.4) format, later to be analyzed by any PCAP viewer software (IE. Wireshark) This feature greatly assist debugging network issues such as detecting dropped packets, packet corruption etc. Signed-off-by: Ramon Fried Reviewed-by: Alex Marginean Tested-by: Alex Marginean Acked-by: Joe Hershberger --- cmd/Kconfig | 7 +++ cmd/Makefile | 1 + cmd/pcap.c | 71 ++++++++++++++++++++++++ include/net/pcap.h | 55 +++++++++++++++++++ net/Makefile | 1 + net/eth-uclass.c | 5 ++ net/eth_legacy.c | 10 +++- net/net.c | 11 ++++ net/pcap.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 cmd/pcap.c create mode 100644 include/net/pcap.h create mode 100644 net/pcap.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 05872fa0d7..98647f58b7 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1339,6 +1339,13 @@ config BOOTP_NTPSERVER bool "Request & store 'ntpserverip' from BOOTP/DHCP server" depends on CMD_BOOTP +config CMD_PCAP + bool "pcap capture" + help + Selecting this will allow capturing all Ethernet packets and store + them in physical memory in a PCAP formated file, + later to be analyzed by PCAP reader application (IE. WireShark). + config BOOTP_PXE bool "Send PXE client arch to BOOTP/DHCP server" default y diff --git a/cmd/Makefile b/cmd/Makefile index 58827b5679..ac843b4b16 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -103,6 +103,7 @@ obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o obj-$(CONFIG_CMD_ONENAND) += onenand.o obj-$(CONFIG_CMD_OSD) += osd.o obj-$(CONFIG_CMD_PART) += part.o +obj-$(CONFIG_CMD_PCAP) += pcap.o ifdef CONFIG_PCI obj-$(CONFIG_CMD_PCI) += pci.o endif diff --git a/cmd/pcap.c b/cmd/pcap.c new file mode 100644 index 0000000000..980603f7bd --- /dev/null +++ b/cmd/pcap.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019 + * Ramon Fried + */ + +#include +#include +#include +#include + +static int do_pcap_init(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + phys_addr_t addr; + unsigned int size; + + if (argc != 3) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[1], NULL, 16); + size = simple_strtoul(argv[2], NULL, 10); + + return pcap_init(addr, size) ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +static int do_pcap_start(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return pcap_start_stop(true) ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +static int do_pcap_stop(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return pcap_start_stop(false) ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +static int do_pcap_status(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return pcap_print_status() ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +static int do_pcap_clear(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return pcap_clear() ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +static char pcap_help_text[] = + "- network packet capture\n\n" + "pcap\n" + "pcap init\t\t\t \n" + "pcap start\t\t\tstart capture\n" + "pcap stop\t\t\tstop capture\n" + "pcap status\t\t\tprint status\n" + "pcap clear\t\t\tclear capture buffer\n" + "\n" + "With:\n" + "\t: user address to which pcap will be stored (hexedcimal)\n" + "\t: Maximum size of pcap file (decimal)\n" + "\n"; + +U_BOOT_CMD_WITH_SUBCMDS(pcap, "pcap", pcap_help_text, + U_BOOT_SUBCMD_MKENT(init, 3, 0, do_pcap_init), + U_BOOT_SUBCMD_MKENT(start, 1, 0, do_pcap_start), + U_BOOT_SUBCMD_MKENT(stop, 1, 0, do_pcap_stop), + U_BOOT_SUBCMD_MKENT(status, 1, 0, do_pcap_status), + U_BOOT_SUBCMD_MKENT(clear, 1, 0, do_pcap_clear), +); diff --git a/include/net/pcap.h b/include/net/pcap.h new file mode 100644 index 0000000000..512ba982f1 --- /dev/null +++ b/include/net/pcap.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 + * Ramon Fried + */ + +/** + * pcap_init() - Initialize PCAP memory buffer + * + * @paddr physicaly memory address to store buffer + * @size maximum size of capture file in memory + * + * @return 0 on success, -ERROR on error + */ +int pcap_init(phys_addr_t paddr, unsigned long size); + +/** + * pcap_start_stop() - start / stop pcap capture + * + * @start if true, start capture if false stop capture + * + * @return 0 on success, -ERROR on error + */ +int pcap_start_stop(bool start); + +/** + * pcap_clear() - clear pcap capture buffer and statistics + * + * @return 0 on success, -ERROR on error + */ +int pcap_clear(void); + +/** + * pcap_print_status() - print status of pcap capture + * + * @return 0 on success, -ERROR on error + */ +int pcap_print_status(void); + +/** + * pcap_active() - check if pcap is enabled + * + * @return TRUE if active, FALSE if not. + */ +bool pcap_active(void); + +/** + * pcap_post() - Post a packet to PCAP file + * + * @packet: packet to post + * @len: packet length in bytes + * @outgoing packet direction (outgoing/incoming) + * @return 0 on success, -ERROR on error + */ +int pcap_post(const void *packet, size_t len, bool outgoing); diff --git a/net/Makefile b/net/Makefile index 826544f05f..2a700c8401 100644 --- a/net/Makefile +++ b/net/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o obj-$(CONFIG_NET) += net.o obj-$(CONFIG_CMD_NFS) += nfs.o obj-$(CONFIG_CMD_PING) += ping.o +obj-$(CONFIG_CMD_PCAP) += pcap.o obj-$(CONFIG_CMD_RARP) += rarp.o obj-$(CONFIG_CMD_SNTP) += sntp.o obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 1d5d2f03b7..3bd98b01ad 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "eth_internal.h" DECLARE_GLOBAL_DATA_PTR; @@ -344,6 +345,10 @@ int eth_send(void *packet, int length) /* We cannot completely return the error at present */ debug("%s: send() returned error %d\n", __func__, ret); } +#if defined(CONFIG_CMD_PCAP) + if (ret >= 0) + pcap_post(packet, length, true); +#endif return ret; } diff --git a/net/eth_legacy.c b/net/eth_legacy.c index 850f362d87..41f5263526 100644 --- a/net/eth_legacy.c +++ b/net/eth_legacy.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "eth_internal.h" DECLARE_GLOBAL_DATA_PTR; @@ -352,10 +353,17 @@ int eth_is_active(struct eth_device *dev) int eth_send(void *packet, int length) { + int ret; + if (!eth_current) return -ENODEV; - return eth_current->send(eth_current, packet, length); + ret = eth_current->send(eth_current, packet, length); +#if defined(CONFIG_CMD_PCAP) + if (ret >= 0) + pcap_post(packet, lengeth, true); +#endif + return ret; } int eth_rx(void) diff --git a/net/net.c b/net/net.c index 40511db645..74a8a36b5a 100644 --- a/net/net.c +++ b/net/net.c @@ -96,6 +96,9 @@ #include #include #include +#if defined(CONFIG_CMD_PCAP) +#include +#endif #if defined(CONFIG_LED_STATUS) #include #include @@ -672,6 +675,11 @@ done: net_set_icmp_handler(NULL); #endif net_set_state(prev_net_state); + +#if defined(CONFIG_CMD_PCAP) + if (pcap_active()) + pcap_print_status(); +#endif return ret; } @@ -1084,6 +1092,9 @@ void net_process_received_packet(uchar *in_packet, int len) debug_cond(DEBUG_NET_PKT, "packet received\n"); +#if defined(CONFIG_CMD_PCAP) + pcap_post(in_packet, len, false); +#endif net_rx_packet = in_packet; net_rx_packet_len = len; et = (struct ethernet_hdr *)in_packet; diff --git a/net/pcap.c b/net/pcap.c new file mode 100644 index 0000000000..4036d8a3fa --- /dev/null +++ b/net/pcap.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Ramon Fried + */ + +#include +#include +#include +#include +#include + +#define LINKTYPE_ETHERNET 1 + +static bool initialized; +static bool running; +static bool buffer_full; +static void *buf; +static unsigned int max_size; +static unsigned int pos; + +static unsigned long incoming_count; +static unsigned long outgoing_count; + +struct pcap_header { + u32 magic; + u16 version_major; + u16 version_minor; + s32 thiszone; + u32 sigfigs; + u32 snaplen; + u32 network; +}; + +struct pcap_packet_header { + u32 ts_sec; + u32 ts_usec; + u32 incl_len; + u32 orig_len; +}; + +static struct pcap_header file_header = { + .magic = 0xa1b2c3d4, + .version_major = 2, + .version_minor = 4, + .snaplen = 65535, + .network = LINKTYPE_ETHERNET, +}; + +int pcap_init(phys_addr_t paddr, unsigned long size) +{ + buf = map_physmem(paddr, size, 0); + if (!buf) { + printf("Failed mapping PCAP memory\n"); + return -ENOMEM; + } + + printf("PCAP capture initialized: addr: 0x%lx max length: %lu\n", + (unsigned long)buf, size); + + memcpy(buf, &file_header, sizeof(file_header)); + pos = sizeof(file_header); + max_size = size; + initialized = true; + running = false; + buffer_full = false; + incoming_count = 0; + outgoing_count = 0; + return 0; +} + +int pcap_start_stop(bool start) +{ + if (!initialized) { + printf("error: pcap was not initialized\n"); + return -ENODEV; + } + + running = start; + + return 0; +} + +int pcap_clear(void) +{ + if (!initialized) { + printf("error: pcap was not initialized\n"); + return -ENODEV; + } + + pos = sizeof(file_header); + incoming_count = 0; + outgoing_count = 0; + buffer_full = false; + + printf("pcap capture cleared\n"); + return 0; +} + +int pcap_post(const void *packet, size_t len, bool outgoing) +{ + struct pcap_packet_header header; + u64 cur_time = timer_get_us(); + + if (!initialized || !running || !buf) + return -ENODEV; + + if (buffer_full) + return -ENOMEM; + + if ((pos + len + sizeof(header)) >= max_size) { + buffer_full = true; + printf("\n!!! Buffer is full, consider increasing buffer size !!!\n"); + return -ENOMEM; + } + + header.ts_sec = cur_time / 1000000; + header.ts_usec = cur_time % 1000000; + header.incl_len = len; + header.orig_len = len; + + memcpy(buf + pos, &header, sizeof(header)); + pos += sizeof(header); + memcpy(buf + pos, packet, len); + pos += len; + + if (outgoing) + outgoing_count++; + else + incoming_count++; + + env_set_hex("pcapsize", pos); + + return 0; +} + +int pcap_print_status(void) +{ + if (!initialized) { + printf("pcap was not initialized\n"); + return -ENODEV; + } + printf("PCAP status:\n"); + printf("\tInitialized addr: 0x%lx\tmax length: %u\n", + (unsigned long)buf, max_size); + printf("\tStatus: %s.\t file size: %u\n", running ? "Active" : "Idle", + pos); + printf("\tIncoming packets: %lu Outgoing packets: %lu\n", + incoming_count, outgoing_count); + + return 0; +} + +bool pcap_active(void) +{ + return running; +} -- cgit v1.2.1 From dc625d04d251f7cb5d51daa513f002a83787a58f Mon Sep 17 00:00:00 2001 From: Ramon Fried Date: Thu, 18 Jul 2019 21:43:31 +0300 Subject: doc: pcap: add pcap cmd documentation Add documentation for new "pcap" command. Signed-off-by: Ramon Fried Acked-by: Joe Hershberger --- doc/README.pcap | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 doc/README.pcap diff --git a/doc/README.pcap b/doc/README.pcap new file mode 100644 index 0000000000..97b3e55fd8 --- /dev/null +++ b/doc/README.pcap @@ -0,0 +1,62 @@ +PCAP: + +U-boot supports live Ethernet packet capture in PCAP(2.4) format. +This is enabled by CONFIG_CMD_PCAP. + +The capture is stored on physical memory, and should be copied to +a machine capable of parsing and displaying PCAP files (IE. wireshark) +If networking works properly one can copy the capture file from physical memory +using tftpput, or save it to local storage with (sf write, mmc write, fatwrite, etc) + +the pcap capturing requires maximum buffer size. +when the buffer is full an error message will be displayed and then packets +will silently drop. +the actual capture file size is populate in the environment variable "pcapsize". + +Usage example: + +# Initialize pcap capture to physical address (0x100000) with maximum size of +# 100000 bytes. + +# Start capture +pcap start + +# Initialize network activity +env set ipaddr 10.0.2.15; env set serverip 10.0.2.2; tftp uImage64 + +# Stop capture +pcap stop + +# pcap init 0x100000 100000 +PCAP capture initialized: addr: 0xffffffff80100000 max length: 100000 + +# pcap start +# env set ipaddr 10.0.2.15; env set serverip 10.0.2.2; tftp uImage64 +eth0@10000000: PHY present at 0 +eth0@10000000: link up, 1000Mbps full-duplex (lpa: 0x7c00) +Using eth0@10000000 device +TFTP from server 10.0.2.2; our IP address is 10.0.2.15 +Filename 'uImage64'. +Load address: 0xffffffff88000000 +Loading: ################################################################# + ################################################################# + ################################################################# + ################################################################# +!!! Buffer is full, consider increasing buffer size !!! + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + # + 18.2 MiB/s +done +Bytes transferred = 8359376 (7f8dd0 hex) +PCAP status: + Initialized addr: 0xffffffff80100000 max length: 100000 + Status: Active. file size: 99991 + Incoming packets: 66 Outgoing packets: 67 + +# pcap stop +# tftpput 0xffffffff80100000 $pcapsize 10.0.2.2:capture.pcap + -- cgit v1.2.1 From 259f7223f2f567afe077528539a43b26d0fef876 Mon Sep 17 00:00:00 2001 From: Ramon Fried Date: Thu, 18 Jul 2019 21:43:32 +0300 Subject: configs: sandbox: enable PCAP capture cmd Enable CONFIG_CMD_PCAP for testing PCAP capture. Signed-off-by: Ramon Fried Acked-by: Joe Hershberger --- configs/sandbox_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 7355e3aa1e..968ffdab61 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -49,6 +49,7 @@ CONFIG_CMD_SPI=y CONFIG_CMD_USB=y CONFIG_CMD_AXI=y CONFIG_CMD_AB_SELECT=y +CONFIG_CMD_PCAP=y CONFIG_CMD_TFTPPUT=y CONFIG_CMD_TFTPSRV=y CONFIG_CMD_RARP=y -- cgit v1.2.1 From 6b3abc048228bb4336dd0cc761993353a4efb206 Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Thu, 25 Jul 2019 12:33:17 +0300 Subject: net: mdio-uclass: name MDIO according to device-name property if preset Use the optional property device-name to name the MDIO bus. This works around limitations with using the DT node name on devices such as Armada-8040, which integrates two cp100 cores, both featuring MDIOs at the same relative offsets and with the same DT node names. The concept was originally proposed by Marvell as a custom property called mdio-name specific to Marvell driver. This patch uses the more generic property device-name and moves this into MDIO class code so other can use it as well. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger Reviewed-by: Bin Meng --- net/mdio-uclass.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/mdio-uclass.c b/net/mdio-uclass.c index 1c0d25272a..6f922e80b6 100644 --- a/net/mdio-uclass.c +++ b/net/mdio-uclass.c @@ -23,6 +23,17 @@ void dm_mdio_probe_devices(void) static int dm_mdio_post_bind(struct udevice *dev) { + const char *dt_name; + + /* set a custom name for the MDIO device, if present in DT */ + if (ofnode_valid(dev->node)) { + dt_name = ofnode_read_string(dev->node, "device-name"); + if (dt_name) { + debug("renaming dev %s to %s\n", dev->name, dt_name); + device_set_name(dev, dt_name); + } + } + /* * MDIO command doesn't like spaces in names, don't allow them to keep * it happy -- cgit v1.2.1 From 01c9f047ac104f442cd5d78ee55ee6e02a8110cc Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Thu, 25 Jul 2019 12:33:18 +0300 Subject: doc: bindings: add mdio.txt describing generic MDIO properties Adds a binding document for mdio. A notable deviation from corresponding Linux binding is the introduction of device-name optional property, which can be used to name MDIO buses. Two reset optional properties described by Linux binding are also not present as they don't seem to be used in U-Boot at this time. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger Reviewed-by: Bin Meng Signed-off-by: Alex Marginean Acked-by: Joe Hershberger Reviewed-by: Bin Meng --- doc/device-tree-bindings/net/mdio.txt | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 doc/device-tree-bindings/net/mdio.txt diff --git a/doc/device-tree-bindings/net/mdio.txt b/doc/device-tree-bindings/net/mdio.txt new file mode 100644 index 0000000000..1595325050 --- /dev/null +++ b/doc/device-tree-bindings/net/mdio.txt @@ -0,0 +1,36 @@ +Common MDIO bus properties. + +These are generic properties that can apply to any MDIO bus. + +Optional properties: + - device-name - If present it is used to name the device and MDIO bus. + The name must be unique and must not contain spaces. + +A list of child nodes, one per device on the bus is expected. These could be +PHYs, switches or similar devices and child nodes should follow the specific +binding for the device type. + +Example : +This example shows the structure used for the external MDIO bus on NXP LS1028A +RDB board. Note that this MDIO device is an integrated PCI function and +requires no compatible property for probing. + +/* definition in SoC dtsi file */ + pcie@1f0000000 { + + mdio0: pci@0,3 { + #address-cells=<0>; + #size-cells=<1>; + reg = <0x000300 0 0 0 0>; + status = "disabled"; + device-name = "emdio"; + }; + }; +/* definition of PHYs in RDB dts file */ +&mdio0 { + status = "okay"; + rdb_phy0: phy@2 { + reg = <2>; + }; +}; + -- cgit v1.2.1 From 8bd37ce3cd7bd49a22156765c93ae5f23c480060 Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Thu, 25 Jul 2019 12:33:19 +0300 Subject: drivers: net: add marvell MDIO driver This patch adds a separate driver for the MDIO interface of the Marvell Ethernet controllers based on driver model. There are two reasons to have a separate driver rather than including it inside the MAC driver itself: *) The MDIO interface is shared by all Ethernet ports, so a driver must guarantee non-concurrent accesses to this MDIO interface. The most logical way is to have a separate driver that handles this single MDIO interface, used by all Ethernet ports. *) The MDIO interface is the same between the existing mv643xx_eth driver and the new mvneta/mvpp2 driver. Even though it is for now only used by the mvneta/mvpp2 driver, it will in the future be used by the mv643xx_eth driver as well. This driver supports SMI IEEE for 802.3 Clause 22 and XSMI for IEEE 802.3 Clause 45. This patch also adds device tree binding for marvell MDIO driver. Signed-off-by: Ken Ma Signed-off-by: Alex Marginean Acked-by: Joe Hershberger --- doc/device-tree-bindings/net/marvell-mdio.txt | 15 ++ drivers/net/Kconfig | 10 ++ drivers/net/Makefile | 1 + drivers/net/mvmdio.c | 236 ++++++++++++++++++++++++++ 4 files changed, 262 insertions(+) create mode 100644 doc/device-tree-bindings/net/marvell-mdio.txt create mode 100644 drivers/net/mvmdio.c diff --git a/doc/device-tree-bindings/net/marvell-mdio.txt b/doc/device-tree-bindings/net/marvell-mdio.txt new file mode 100644 index 0000000000..e2038e2145 --- /dev/null +++ b/doc/device-tree-bindings/net/marvell-mdio.txt @@ -0,0 +1,15 @@ +* Marvell MDIO Ethernet Controller interface + +The Ethernet controllers of the Marvel Armada 3700 and Armada 7k/8k +have an identical unit that provides an interface with the MDIO bus. +This driver handles this MDIO interface. + +Mandatory properties: +SoC specific: + - #address-cells: Must be <1>. + - #size-cells: Must be <0>. + - compatible: Should be "marvell,orion-mdio" (for SMI) + "marvell,xmdio" (for XSMI) + - reg: Base address and size SMI/XMSI bus. + +Please refer to "mdio.txt" for generic MDIO bus bindings. diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index aaf10a2c59..2ce3092db0 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -604,4 +604,14 @@ config MDIO_MUX_I2CREG an I2C chip. The board it was developed for uses a mux controlled by on-board FPGA which in turn is accessed as a chip over I2C. +config MVMDIO + bool "Marvell MDIO interface support" + depends on DM_MDIO + help + This driver supports the MDIO interface found in the network + interface units of the Marvell EBU SoCs (Kirkwood, Orion5x, + Dove, Armada 370, Armada XP, Armada 37xx and Armada7K/8K/8KP). + + This driver is used by the MVPP2 and MVNETA drivers. + endif # NETDEVICES diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 71c0889355..30991834ec 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o obj-$(CONFIG_MT7628_ETH) += mt7628-eth.o obj-$(CONFIG_MVGBE) += mvgbe.o +obj-$(CONFIG_MVMDIO) += mvmdio.o obj-$(CONFIG_MVNETA) += mvneta.o obj-$(CONFIG_MVPP2) += mvpp2.o obj-$(CONFIG_NATSEMI) += natsemi.o diff --git a/drivers/net/mvmdio.c b/drivers/net/mvmdio.c new file mode 100644 index 0000000000..ec6805e536 --- /dev/null +++ b/drivers/net/mvmdio.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Marvell International Ltd. + * Author: Ken Ma + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MVMDIO_SMI_DATA_SHIFT 0 +#define MVMDIO_SMI_PHY_ADDR_SHIFT 16 +#define MVMDIO_SMI_PHY_REG_SHIFT 21 +#define MVMDIO_SMI_READ_OPERATION BIT(26) +#define MVMDIO_SMI_WRITE_OPERATION 0 +#define MVMDIO_SMI_READ_VALID BIT(27) +#define MVMDIO_SMI_BUSY BIT(28) + +#define MVMDIO_XSMI_MGNT_REG 0x0 +#define MVMDIO_XSMI_PHYADDR_SHIFT 16 +#define MVMDIO_XSMI_DEVADDR_SHIFT 21 +#define MVMDIO_XSMI_WRITE_OPERATION (0x5 << 26) +#define MVMDIO_XSMI_READ_OPERATION (0x7 << 26) +#define MVMDIO_XSMI_READ_VALID BIT(29) +#define MVMDIO_XSMI_BUSY BIT(30) +#define MVMDIO_XSMI_ADDR_REG 0x8 + +enum mvmdio_bus_type { + BUS_TYPE_SMI, + BUS_TYPE_XSMI +}; + +struct mvmdio_priv { + void *mdio_base; + enum mvmdio_bus_type type; +}; + +static int mvmdio_smi_read(struct udevice *dev, int addr, + int devad, int reg) +{ + struct mvmdio_priv *priv = dev_get_priv(dev); + u32 val; + int ret; + + if (devad != MDIO_DEVAD_NONE) + return -EOPNOTSUPP; + + ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY, + false, CONFIG_SYS_HZ, false); + if (ret < 0) + return ret; + + writel(((addr << MVMDIO_SMI_PHY_ADDR_SHIFT) | + (reg << MVMDIO_SMI_PHY_REG_SHIFT) | + MVMDIO_SMI_READ_OPERATION), + priv->mdio_base); + + ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY, + false, CONFIG_SYS_HZ, false); + if (ret < 0) + return ret; + + val = readl(priv->mdio_base); + if (!(val & MVMDIO_SMI_READ_VALID)) { + pr_err("SMI bus read not valid\n"); + return -ENODEV; + } + + return val & GENMASK(15, 0); +} + +static int mvmdio_smi_write(struct udevice *dev, int addr, int devad, + int reg, u16 value) +{ + struct mvmdio_priv *priv = dev_get_priv(dev); + int ret; + + if (devad != MDIO_DEVAD_NONE) + return -EOPNOTSUPP; + + ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY, + false, CONFIG_SYS_HZ, false); + if (ret < 0) + return ret; + + writel(((addr << MVMDIO_SMI_PHY_ADDR_SHIFT) | + (reg << MVMDIO_SMI_PHY_REG_SHIFT) | + MVMDIO_SMI_WRITE_OPERATION | + (value << MVMDIO_SMI_DATA_SHIFT)), + priv->mdio_base); + + return 0; +} + +static int mvmdio_xsmi_read(struct udevice *dev, int addr, + int devad, int reg) +{ + struct mvmdio_priv *priv = dev_get_priv(dev); + int ret; + + if (devad == MDIO_DEVAD_NONE) + return -EOPNOTSUPP; + + ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY, + false, CONFIG_SYS_HZ, false); + if (ret < 0) + return ret; + + writel(reg & GENMASK(15, 0), priv->mdio_base + MVMDIO_XSMI_ADDR_REG); + writel(((addr << MVMDIO_XSMI_PHYADDR_SHIFT) | + (devad << MVMDIO_XSMI_DEVADDR_SHIFT) | + MVMDIO_XSMI_READ_OPERATION), + priv->mdio_base + MVMDIO_XSMI_MGNT_REG); + + ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY, + false, CONFIG_SYS_HZ, false); + if (ret < 0) + return ret; + + if (!(readl(priv->mdio_base + MVMDIO_XSMI_MGNT_REG) & + MVMDIO_XSMI_READ_VALID)) { + pr_err("XSMI bus read not valid\n"); + return -ENODEV; + } + + return readl(priv->mdio_base + MVMDIO_XSMI_MGNT_REG) & GENMASK(15, 0); +} + +static int mvmdio_xsmi_write(struct udevice *dev, int addr, int devad, + int reg, u16 value) +{ + struct mvmdio_priv *priv = dev_get_priv(dev); + int ret; + + if (devad == MDIO_DEVAD_NONE) + return -EOPNOTSUPP; + + ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY, + false, CONFIG_SYS_HZ, false); + if (ret < 0) + return ret; + + writel(reg & GENMASK(15, 0), priv->mdio_base + MVMDIO_XSMI_ADDR_REG); + writel(((addr << MVMDIO_XSMI_PHYADDR_SHIFT) | + (devad << MVMDIO_XSMI_DEVADDR_SHIFT) | + MVMDIO_XSMI_WRITE_OPERATION | value), + priv->mdio_base + MVMDIO_XSMI_MGNT_REG); + + return 0; +} + +static int mvmdio_read(struct udevice *dev, int addr, int devad, int reg) +{ + struct mvmdio_priv *priv = dev_get_priv(dev); + int err = -ENOTSUPP; + + switch (priv->type) { + case BUS_TYPE_SMI: + err = mvmdio_smi_read(dev, addr, devad, reg); + break; + case BUS_TYPE_XSMI: + err = mvmdio_xsmi_read(dev, addr, devad, reg); + break; + } + + return err; +} + +static int mvmdio_write(struct udevice *dev, int addr, int devad, int reg, + u16 value) +{ + struct mvmdio_priv *priv = dev_get_priv(dev); + int err = -ENOTSUPP; + + switch (priv->type) { + case BUS_TYPE_SMI: + err = mvmdio_smi_write(dev, addr, devad, reg, value); + break; + case BUS_TYPE_XSMI: + err = mvmdio_xsmi_write(dev, addr, devad, reg, value); + break; + } + + return err; +} + +/* + * Name the device, we use the device tree node name. + * This can be overwritten by MDIO class code if device-name property is + * present. + */ +static int mvmdio_bind(struct udevice *dev) +{ + if (ofnode_valid(dev->node)) + device_set_name(dev, ofnode_get_name(dev->node)); + + return 0; +} + +/* Get device base address and type, either C22 SMII or C45 XSMI */ +static int mvmdio_probe(struct udevice *dev) +{ + struct mvmdio_priv *priv = dev_get_priv(dev); + + priv->mdio_base = (void *)dev_read_addr(dev); + priv->type = (enum mvmdio_bus_type)dev_get_driver_data(dev); + + return 0; +} + +static const struct mdio_ops mvmdio_ops = { + .read = mvmdio_read, + .write = mvmdio_write, +}; + +static const struct udevice_id mvmdio_ids[] = { + { .compatible = "marvell,orion-mdio", .data = BUS_TYPE_SMI }, + { .compatible = "marvell,xmdio", .data = BUS_TYPE_XSMI }, + { } +}; + +U_BOOT_DRIVER(mvmdio) = { + .name = "mvmdio", + .id = UCLASS_MDIO, + .of_match = mvmdio_ids, + .bind = mvmdio_bind, + .probe = mvmdio_probe, + .ops = &mvmdio_ops, + .priv_auto_alloc_size = sizeof(struct mvmdio_priv), +}; + -- cgit v1.2.1 From 7660d5c120698a1fb85ea38ad2bed1438ef5ebb1 Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Thu, 25 Jul 2019 12:33:20 +0300 Subject: arm: dts: Set custom names for cp110 master/slave MDIO buses Implicitly Marvell MDIO driver uses DT node names for devices, but in this case that is not unique. Set MDIO device names for master/slave to cpm/cps. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger --- arch/arm/dts/armada-cp110-master.dtsi | 1 + arch/arm/dts/armada-cp110-slave.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/dts/armada-cp110-master.dtsi b/arch/arm/dts/armada-cp110-master.dtsi index 551d00d774..e4c17e9f4b 100644 --- a/arch/arm/dts/armada-cp110-master.dtsi +++ b/arch/arm/dts/armada-cp110-master.dtsi @@ -96,6 +96,7 @@ #size-cells = <0>; compatible = "marvell,orion-mdio"; reg = <0x12a200 0x10>; + device-name = "cpm-mdio"; }; cpm_syscon0: system-controller@440000 { diff --git a/arch/arm/dts/armada-cp110-slave.dtsi b/arch/arm/dts/armada-cp110-slave.dtsi index 2ea9004f1d..2fbd7b5514 100644 --- a/arch/arm/dts/armada-cp110-slave.dtsi +++ b/arch/arm/dts/armada-cp110-slave.dtsi @@ -96,6 +96,7 @@ #size-cells = <0>; compatible = "marvell,orion-mdio"; reg = <0x12a200 0x10>; + device-name = "cps-mdio"; }; cps_syscon0: system-controller@440000 { -- cgit v1.2.1 From a37c082248220a30caacc7804575cae6f885506b Mon Sep 17 00:00:00 2001 From: Matt Pelland Date: Tue, 30 Jul 2019 09:40:24 -0400 Subject: net: mvpp2: support setting hardware addresses from ethernet core mvpp2 already has support for setting MAC addresses but this functionality was not exposed to the ethernet core. This commit exposes this functionality so that MAC address assignments stored in U-Boot's environment are correctly applied before Linux boots. Signed-off-by: Matt Pelland Acked-by: Joe Hershberger --- drivers/net/mvpp2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index bcc6fe92a9..bd89725e77 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -5321,6 +5321,13 @@ static void mvpp2_stop(struct udevice *dev) mvpp2_cleanup_txqs(port); } +static int mvpp2_write_hwaddr(struct udevice *dev) +{ + struct mvpp2_port *port = dev_get_priv(dev); + + return mvpp2_prs_update_mac_da(port, port->dev_addr); +} + static int mvpp22_smi_phy_addr_cfg(struct mvpp2_port *port) { writel(port->phyaddr, port->priv->iface_base + @@ -5525,6 +5532,7 @@ static const struct eth_ops mvpp2_ops = { .send = mvpp2_send, .recv = mvpp2_recv, .stop = mvpp2_stop, + .write_hwaddr = mvpp2_write_hwaddr }; static struct driver mvpp2_driver = { -- cgit v1.2.1 From fd6d88f55baee946d2a1bd16e7344486cf140c94 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 30 Jul 2019 23:49:00 +0200 Subject: test: dm_mdio: avoid out of bounds access SANDBOX_PHY_REG_CNT is not an allowable index for the array u16 reg[SANDBOX_PHY_REG_CNT]. Identified by cppcheck. Fixes: b47edf8069cc ("test: dm_mdio: add a 2nd register to the emulated PHY") Signed-off-by: Heinrich Schuchardt Acked-by: Joe Hershberger --- drivers/net/mdio_sandbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/mdio_sandbox.c b/drivers/net/mdio_sandbox.c index df053f5381..b731f60a98 100644 --- a/drivers/net/mdio_sandbox.c +++ b/drivers/net/mdio_sandbox.c @@ -27,7 +27,7 @@ static int mdio_sandbox_read(struct udevice *dev, int addr, int devad, int reg) return -ENODEV; if (devad != MDIO_DEVAD_NONE) return -ENODEV; - if (reg < 0 || reg > SANDBOX_PHY_REG_CNT) + if (reg < 0 || reg >= SANDBOX_PHY_REG_CNT) return -ENODEV; return priv->reg[reg]; @@ -45,7 +45,7 @@ static int mdio_sandbox_write(struct udevice *dev, int addr, int devad, int reg, return -ENODEV; if (devad != MDIO_DEVAD_NONE) return -ENODEV; - if (reg < 0 || reg > SANDBOX_PHY_REG_CNT) + if (reg < 0 || reg >= SANDBOX_PHY_REG_CNT) return -ENODEV; priv->reg[reg] = val; -- cgit v1.2.1 From 9bbff5478e7b9e66b25da59da85e88924b79eb2e Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 31 Jul 2019 00:00:51 +0200 Subject: drivers: net: pfe_eth: undefined return value Do not use random value from stack as return value of pfe_phy_write(). Indicated by cppcheck. Signed-off-by: Heinrich Schuchardt Acked-by: Joe Hershberger --- drivers/net/pfe_eth/pfe_mdio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/pfe_eth/pfe_mdio.c b/drivers/net/pfe_eth/pfe_mdio.c index 2dde9e7ac8..62309670fa 100644 --- a/drivers/net/pfe_eth/pfe_mdio.c +++ b/drivers/net/pfe_eth/pfe_mdio.c @@ -110,7 +110,6 @@ static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr, u32 phy; u32 reg_data; int timeout = MDIO_TIMEOUT; - int val; if (dev_addr == MDIO_DEVAD_NONE) { reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) << @@ -150,7 +149,7 @@ static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr, debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phy_addr, reg_addr, data); - return val; + return 0; } static void pfe_configure_serdes(struct pfe_eth_dev *priv) -- cgit v1.2.1 From 50d86e55a4e1dd208109877d4cad21ef504736b9 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 1 Aug 2019 11:29:02 +0200 Subject: net: dwc_eth_qos: Change eqos_ops function to static This patch solves many warnings when compiling with W=1: warning: no previous prototype for '....' [-Wmissing-prototypes] Signed-off-by: Patrice Chotard Signed-off-by: Patrick Delaunay Reviewed-By: Ramon Fried Acked-by: Joe Hershberger --- drivers/net/dwc_eth_qos.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 07b36675a7..6df9956724 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -621,7 +621,7 @@ err: return ret; } -void eqos_stop_clks_tegra186(struct udevice *dev) +static void eqos_stop_clks_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -636,7 +636,7 @@ void eqos_stop_clks_tegra186(struct udevice *dev) debug("%s: OK\n", __func__); } -void eqos_stop_clks_stm32(struct udevice *dev) +static void eqos_stop_clks_stm32(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1290,7 +1290,7 @@ err: return ret; } -void eqos_stop(struct udevice *dev) +static void eqos_stop(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int i; @@ -1344,7 +1344,7 @@ void eqos_stop(struct udevice *dev) debug("%s: OK\n", __func__); } -int eqos_send(struct udevice *dev, void *packet, int length) +static int eqos_send(struct udevice *dev, void *packet, int length) { struct eqos_priv *eqos = dev_get_priv(dev); struct eqos_desc *tx_desc; @@ -1385,7 +1385,7 @@ int eqos_send(struct udevice *dev, void *packet, int length) return -ETIMEDOUT; } -int eqos_recv(struct udevice *dev, int flags, uchar **packetp) +static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) { struct eqos_priv *eqos = dev_get_priv(dev); struct eqos_desc *rx_desc; @@ -1409,7 +1409,7 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp) return length; } -int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) +static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) { struct eqos_priv *eqos = dev_get_priv(dev); uchar *packet_expected; -- cgit v1.2.1 From 53e3d52c6cd628c6ff1ebe6695a38014f8241ed6 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 1 Aug 2019 11:29:03 +0200 Subject: net: dwc_et_qos: update weak function board_interface_eth_init Align the board and driver prototype for board_interface_eth_init to avoid execution issue (the interface_type parameter is defined as int or phy_interface_t). To have a generic weak function (it should be reused by other driver) I change the prototype to use directly udevice. This prototype is added in netdev.h to allow compilation check and avoid warning when compiling with W=1 on file board/st/stm32mp1/stm32mp1.c warning: no previous prototype for 'board_interface_eth_init'\ [-Wmissing-prototypes] int board_interface_eth_init(int interface_type, .... ^~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Patrice Chotard Signed-off-by: Patrick Delaunay Acked-by: Joe Hershberger --- board/st/stm32mp1/stm32mp1.c | 16 +++++++++++++--- drivers/net/dwc_eth_qos.c | 16 +++------------- include/netdev.h | 3 +++ 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index fc14ad375c..18f9b84876 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -683,12 +684,21 @@ void board_quiesce_devices(void) #endif } -/* board interface eth init */ -int board_interface_eth_init(phy_interface_t interface_type, - bool eth_clk_sel_reg, bool eth_ref_clk_sel_reg) +/* eth init function : weak called in eqos driver */ +int board_interface_eth_init(struct udevice *dev, + phy_interface_t interface_type) { u8 *syscfg; u32 value; + bool eth_clk_sel_reg = false; + bool eth_ref_clk_sel_reg = false; + + /* Gigabit Ethernet 125MHz clock selection. */ + eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel"); + + /* Ethernet 50Mhz RMII clock selection */ + eth_ref_clk_sel_reg = + dev_read_bool(dev, "st,eth_ref_clk_sel"); syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 6df9956724..455709338c 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1591,8 +1591,8 @@ err_free_reset_eqos: } /* board-specific Ethernet Interface initializations. */ -__weak int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg, - bool eth_ref_clk_sel_reg) +__weak int board_interface_eth_init(struct udevice *dev, + phy_interface_t interface_type) { return 0; } @@ -1602,8 +1602,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev) struct eqos_priv *eqos = dev_get_priv(dev); int ret; phy_interface_t interface; - bool eth_clk_sel_reg = false; - bool eth_ref_clk_sel_reg = false; debug("%s(dev=%p):\n", __func__, dev); @@ -1614,15 +1612,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev) return -EINVAL; } - /* Gigabit Ethernet 125MHz clock selection. */ - eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel"); - - /* Ethernet 50Mhz RMII clock selection */ - eth_ref_clk_sel_reg = - dev_read_bool(dev, "st,eth_ref_clk_sel"); - - ret = board_interface_eth_init(interface, eth_clk_sel_reg, - eth_ref_clk_sel_reg); + ret = board_interface_eth_init(dev, interface); if (ret) return -EINVAL; diff --git a/include/netdev.h b/include/netdev.h index a40c4adaad..68a3fceab6 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -10,6 +10,7 @@ #ifndef _NETDEV_H_ #define _NETDEV_H_ +#include /* * Board and CPU-specific initialization functions @@ -21,6 +22,8 @@ */ int board_eth_init(bd_t *bis); +int board_interface_eth_init(struct udevice *dev, + phy_interface_t interface_type); int cpu_eth_init(bd_t *bis); /* Driver initialization prototypes */ -- cgit v1.2.1 From e3562b3a8e5385c47910bbda2e77822e6ed001ad Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Wed, 7 Aug 2019 19:33:22 +0300 Subject: drivers: net: fsl_enet_mdio: fix missing terminator in PCI ID array It was missing in the original submission and not having it in place causes issues with probing of PCI devices. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger --- drivers/net/fsl_enetc_mdio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/fsl_enetc_mdio.c b/drivers/net/fsl_enetc_mdio.c index 60d21537b8..b4463a58a5 100644 --- a/drivers/net/fsl_enetc_mdio.c +++ b/drivers/net/fsl_enetc_mdio.c @@ -144,6 +144,7 @@ U_BOOT_DRIVER(enetc_mdio) = { static struct pci_device_id enetc_mdio_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_ENETC_MDIO) }, + { } }; U_BOOT_PCI_DEVICE(enetc_mdio, enetc_mdio_ids); -- cgit v1.2.1 From 2e0f3241787ead5087e8fe81095e830c48b29b36 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 10 Aug 2019 00:10:37 +0200 Subject: network: set timeline for CONFIG_DM_ETH conversion The driver model has been supported for network drivers since 2015. It is time to convert the remaining boards. Set July 2020 as a timeline. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass Acked-by: Joe Hershberger --- Makefile | 11 +++++++++++ doc/driver-model/migration.rst | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/Makefile b/Makefile index c02accfc26..ae56e47b2c 100644 --- a/Makefile +++ b/Makefile @@ -1025,6 +1025,17 @@ ifneq ($(CONFIG_WDT),y) @echo >&2 "See doc/driver-model/MIGRATION.txt for more info." @echo >&2 "====================================================" endif +endif +ifneq ($(CONFIG_NET),) +ifneq ($(CONFIG_DM_ETH),y) + @echo >&2 "===================== WARNING ======================" + @echo >&2 "This board does not use CONFIG_DM_ETH (Driver Model" + @echo >&2 "for Ethernet drivers). Please update the board to use" + @echo >&2 "CONFIG_DM_ETH before the v2020.07 release. Failure to" + @echo >&2 "update by the deadline may result in board removal." + @echo >&2 "See doc/driver-model/migration.rst for more info." + @echo >&2 "====================================================" +endif endif @# Check that this build does not use CONFIG options that we do not @# know about unless they are in Kconfig. All the existing CONFIG diff --git a/doc/driver-model/migration.rst b/doc/driver-model/migration.rst index a26e7ab7e1..75b85235ef 100644 --- a/doc/driver-model/migration.rst +++ b/doc/driver-model/migration.rst @@ -97,3 +97,11 @@ Deadline: 2019.07 The video subsystem has supported driver model since early 2016. Maintainers should submit patches switching over to using CONFIG_DM_VIDEO and other base driver model options in time for inclusion in the 2019.07 release. + +CONFIG_DM_ETH +------------- +Deadline: 2020.07 + +The network subsystem has supported the driver model since early 2015. +Maintainers should submit patches switching over to using CONFIG_DM_ETH and +other base driver model options in time for inclusion in the 2020.07 release. -- cgit v1.2.1 From 19f3b78dfbc63c46574e1c2232a8a89fc122405f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 14 Aug 2019 03:29:42 -0700 Subject: Revert "net: macb: Fixed reading MII_LPA register" This reverts commit 1b0c9914cc75d1570359181ebd493cd5746cb0ed. Commit 1b0c9914cc75 ("net: macb: Fixed reading MII_LPA register") causes 100Mbps does not work any more with SiFive FU540 GEM on the HiFive Unleashed board. Revert it. Signed-off-by: Bin Meng Acked-by: Joe Hershberger --- drivers/net/macb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index c99cf663a4..25f79136e0 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -643,7 +643,7 @@ static int macb_phy_init(struct macb_device *macb, const char *name) /* First check for GMAC and that it is GiB capable */ if (gem_is_gigabit_capable(macb)) { - lpa = macb_mdio_read(macb, MII_LPA); + lpa = macb_mdio_read(macb, MII_STAT1000); if (lpa & (LPA_1000FULL | LPA_1000HALF | LPA_1000XFULL | LPA_1000XHALF)) { -- cgit v1.2.1 From 642b80d256e1ba35e0dc8157a588b49c11b177f4 Mon Sep 17 00:00:00 2001 From: Ralph Siemsen Date: Mon, 19 Aug 2019 14:43:13 -0400 Subject: net: designware: drop compatible altr, socfpga-stmmac The same compatible = "altr,socfpga-stmmac" appears in both drivers/net/designware.c and drivers/net/dwmac_socfgpa.c, creating ambiguity in which driver will be bound. For Intel/Altera SoC devices, dwmac_socfpga.c is the correct driver. So drop the compatible string from designware.c. Signed-off-by: Ralph Siemsen Reviewed-by: Simon Goldschmidt Acked-by: Joe Hershberger --- drivers/net/designware.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index c4fe40b19a..145eeac45f 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -847,7 +847,6 @@ int designware_eth_ofdata_to_platdata(struct udevice *dev) static const struct udevice_id designware_eth_ids[] = { { .compatible = "allwinner,sun7i-a20-gmac" }, - { .compatible = "altr,socfpga-stmmac" }, { .compatible = "amlogic,meson6-dwmac" }, { .compatible = "amlogic,meson-gx-dwmac" }, { .compatible = "amlogic,meson-gxbb-dwmac" }, -- cgit v1.2.1 From 5ccd657b6d6cdf2378b98f6b71a2a5a22d8f4d50 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 26 Aug 2019 09:18:11 +0200 Subject: net: macb: Fix rx buffer cache handling With commit c6d07bf440bc ("net/macb: increase RX buffer size for GEM") ethernet support does not work any more with d-cache enabled on the AT91SAM. The reason is, that MACB_RX_BUFFER_SIZE was changed from 4096 to 128 but this change was not refected in the rx_buffer flush and invalidate functions, as these also use this macro. This patch now fixes this by calculating the rx buffer size correctly again in those functions. With this change, ethernet works again reliably on my AT91SAM board. Signed-off-by: Stefan Roese Fixes: c6d07bf440bc ("net/macb: increase RX buffer size for GEM") Cc: Ramon Fried Cc: Eugen Hristev Cc: Anup Patel Cc: Bin Meng Cc: Joe Hershberger Reviewed-by: Bin Meng Tested-by: Bin Meng Acked-by: Joe Hershberger --- drivers/net/macb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 25f79136e0..377188e361 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -296,13 +296,15 @@ static inline void macb_flush_ring_desc(struct macb_device *macb, bool rx) static inline void macb_flush_rx_buffer(struct macb_device *macb) { flush_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma + - ALIGN(MACB_RX_BUFFER_SIZE, PKTALIGN)); + ALIGN(macb->rx_buffer_size * MACB_RX_RING_SIZE, + PKTALIGN)); } static inline void macb_invalidate_rx_buffer(struct macb_device *macb) { invalidate_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma + - ALIGN(MACB_RX_BUFFER_SIZE, PKTALIGN)); + ALIGN(macb->rx_buffer_size * MACB_RX_RING_SIZE, + PKTALIGN)); } #if defined(CONFIG_CMD_NET) -- cgit v1.2.1 From 12c2a310e87d4eacfd669346338e856cb3ad54c2 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Tue, 27 Aug 2019 10:13:52 +0200 Subject: net: make net_random_ethaddr() more random The net_random_ethaddr() tries to get some entropy from different startup times of a board. The seed is initialized with get_timer() which has only a granularity of milliseconds. We can do better if we use get_ticks() which returns the raw timer ticks. Using this we have a higher chance of getting different values at startup. Signed-off-by: Michael Walle Reviewed-by: Bin Meng Acked-by: Joe Hershberger --- include/net.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net.h b/include/net.h index a54d5eeac5..75a16e4c8f 100644 --- a/include/net.h +++ b/include/net.h @@ -816,7 +816,7 @@ static inline int is_valid_ethaddr(const u8 *addr) static inline void net_random_ethaddr(uchar *addr) { int i; - unsigned int seed = get_timer(0); + unsigned int seed = get_ticks(); for (i = 0; i < 6; i++) addr[i] = rand_r(&seed); -- cgit v1.2.1 From fe7288069d2e6659117049f7d27e261b550bb725 Mon Sep 17 00:00:00 2001 From: "liucheng (G)" Date: Thu, 29 Aug 2019 13:47:33 +0000 Subject: CVE: net: fix unbounded memcpy of UDP packet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a check to udp_len to fix unbounded memcpy for CVE-2019-14192, CVE-2019-14193 and CVE-2019-14199. Signed-off-by: Cheng Liu Reviewed-by: Simon Goldschmidt Reported-by: Fermín Serna Acked-by: Joe Hershberger --- net/net.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/net.c b/net/net.c index 74a8a36b5a..ded86e7456 100644 --- a/net/net.c +++ b/net/net.c @@ -1264,6 +1264,9 @@ void net_process_received_packet(uchar *in_packet, int len) return; } + if (ntohs(ip->udp_len) < UDP_HDR_SIZE || ntohs(ip->udp_len) > ntohs(ip->ip_len)) + return; + debug_cond(DEBUG_DEV_PKT, "received UDP (to=%pI4, from=%pI4, len=%d)\n", &dst_ip, &src_ip, len); -- cgit v1.2.1 From 741a8a08ebe5bc3ccfe3cde6c2b44ee53891af21 Mon Sep 17 00:00:00 2001 From: "liucheng (G)" Date: Thu, 29 Aug 2019 13:47:40 +0000 Subject: CVE: nfs: fix stack-based buffer overflow in some nfs_handler reply helper functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a check to nfs_handler to fix buffer overflow for CVE-2019-14197, CVE-2019-14200, CVE-2019-14201, CVE-2019-14202, CVE-2019-14203 and CVE-2019-14204. Signed-off-by: Cheng Liu Reported-by: Fermín Serna Acked-by: Joe Hershberger --- net/nfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/nfs.c b/net/nfs.c index d6a7f8e827..b7cf3b3a18 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -732,6 +732,9 @@ static void nfs_handler(uchar *pkt, unsigned dest, struct in_addr sip, debug("%s\n", __func__); + if (len > sizeof(struct rpc_t)) + return; + if (dest != nfs_our_port) return; -- cgit v1.2.1 From aa207cf3a6d68f39d64cd29057a4fb63943e9078 Mon Sep 17 00:00:00 2001 From: "liucheng (G)" Date: Thu, 29 Aug 2019 13:47:48 +0000 Subject: CVE-2019-14194/CVE-2019-14198: nfs: fix unbounded memcpy with a failed length check at nfs_read_reply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a check to rpc_pkt.u.reply.data at nfs_read_reply. Signed-off-by: Cheng Liu Reported-by: Fermín Serna Acked-by: Joe Hershberger --- net/nfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/nfs.c b/net/nfs.c index b7cf3b3a18..11941fad1a 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -701,6 +701,9 @@ static int nfs_read_reply(uchar *pkt, unsigned len) &(rpc_pkt.u.reply.data[4 + nfsv3_data_offset]); } + if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len) + return -9999; + if (store_block(data_ptr, nfs_offset, rlen)) return -9999; -- cgit v1.2.1 From cf3a4f1e86ecdd24f87b615051b49d8e1968c230 Mon Sep 17 00:00:00 2001 From: "liucheng (G)" Date: Thu, 29 Aug 2019 13:47:54 +0000 Subject: CVE-2019-14195: nfs: fix unbounded memcpy with unvalidated length at nfs_readlink_reply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a check to rpc_pkt.u.reply.data at nfs_readlink_reply. Signed-off-by: Cheng Liu Reported-by: Fermín Serna Acked-by: Joe Hershberger --- net/nfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/nfs.c b/net/nfs.c index 11941fad1a..915acd95cf 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -634,6 +634,9 @@ static int nfs_readlink_reply(uchar *pkt, unsigned len) /* new path length */ rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]); + if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len) + return -NFS_RPC_DROP; + if (*((char *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset])) != '/') { int pathlen; -- cgit v1.2.1 From 5d14ee4e53a81055d34ba280cb8fd90330f22a96 Mon Sep 17 00:00:00 2001 From: "liucheng (G)" Date: Thu, 29 Aug 2019 13:48:02 +0000 Subject: CVE-2019-14196: nfs: fix unbounded memcpy with a failed length check at nfs_lookup_reply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a check to rpc_pkt.u.reply.data at nfs_lookup_reply. Signed-off-by: Cheng Liu Reported-by: Fermín Serna Acked-by: Joe Hershberger --- net/nfs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/nfs.c b/net/nfs.c index 915acd95cf..89952aeb66 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -566,11 +566,15 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len) } if (supported_nfs_versions & NFSV2_FLAG) { + if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + NFS_FHSIZE) > len) + return -NFS_RPC_DROP; memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE); } else { /* NFSV3_FLAG */ filefh3_length = ntohl(rpc_pkt.u.reply.data[1]); if (filefh3_length > NFS3_FHSIZE) filefh3_length = NFS3_FHSIZE; + if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + filefh3_length) > len) + return -NFS_RPC_DROP; memcpy(filefh, rpc_pkt.u.reply.data + 2, filefh3_length); } -- cgit v1.2.1 From cccc05ee3b9f575b567437d4146af0dee40c68ba Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 2 Sep 2019 10:10:34 +0200 Subject: env: net: U_BOOT_ENV_CALLBACKs should not depend on CMD_NET Some environment variables are relevant for networking. For these U_BOOT_ENV_CALLBACKs have been defined. When the corresponding environment variable is updated the callback updates the state of the network sub-system. In the UEFI subsystem we can use the network even if CONFIG_CMD_NET is not defined. Let the usage of the U_BOOT_ENV_CALLBACKs depend on CONFIG_NET and not on CONFIG_CMD_NET. Signed-off-by: Heinrich Schuchardt Acked-by: Joe Hershberger --- include/env_callback.h | 2 +- include/env_flags.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/env_callback.h b/include/env_callback.h index 982c07854d..74da20eec3 100644 --- a/include/env_callback.h +++ b/include/env_callback.h @@ -42,7 +42,7 @@ #define DNS_CALLBACK #endif -#ifdef CONFIG_CMD_NET +#ifdef CONFIG_NET #define NET_CALLBACKS \ "bootfile:bootfile," \ "ipaddr:ipaddr," \ diff --git a/include/env_flags.h b/include/env_flags.h index e5380f2948..725841a891 100644 --- a/include/env_flags.h +++ b/include/env_flags.h @@ -36,7 +36,7 @@ enum env_flags_varaccess { #define CONFIG_ENV_FLAGS_LIST_STATIC "" #endif -#ifdef CONFIG_CMD_NET +#ifdef CONFIG_NET #ifdef CONFIG_REGEX #define ETHADDR_WILDCARD "\\d*" #else -- cgit v1.2.1 From 15eea9a1a8166b4bbab6c02cc426a7cc806ea2ca Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 2 Sep 2019 23:55:32 +0200 Subject: net: nfs: remove superfluous conversions rpc_pkt.u.call.data is an array of uint32_t. There is no need to convert it to uint32_t *. memcpy() expects void * as it 1st and 2nd argument. There is no point in converting pointers to char * before passing them to memcpy(). In ntohl(data[1]) != 0 calling ntohl() is superfluous. If the value is zero, does not depend on the byte order. Signed-off-by: Heinrich Schuchardt Reviewed-by: Bin Meng Acked-by: Joe Hershberger --- net/nfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/nfs.c b/net/nfs.c index 89952aeb66..aca0ca55f3 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -196,10 +196,10 @@ static void rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen) rpc_pkt.u.call.vers = htonl(2); /* portmapper is version 2 */ } rpc_pkt.u.call.proc = htonl(rpc_proc); - p = (uint32_t *)&(rpc_pkt.u.call.data); + p = rpc_pkt.u.call.data; if (datalen) - memcpy((char *)p, (char *)data, datalen*sizeof(uint32_t)); + memcpy(p, data, datalen * sizeof(uint32_t)); pktlen = (char *)p + datalen * sizeof(uint32_t) - (char *)&rpc_pkt; @@ -583,7 +583,7 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len) static int nfs3_get_attributes_offset(uint32_t *data) { - if (ntohl(data[1]) != 0) { + if (data[1]) { /* 'attributes_follow' flag is TRUE, * so we have attributes on 21 dwords */ /* Skip unused values : -- cgit v1.2.1 From 5a5d1def59024dd3225e2a6142f8ee3ee10180a8 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 3 Sep 2019 00:05:05 +0200 Subject: net: nfs: remove superfluous packed attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With GCC 9.2.1 net/nfs.c leads to multiple errors of type address-of-packed-member. net/nfs.c: In function ‘rpc_req’: net/nfs.c:199:18: error: taking address of packed member of ‘struct rpc_t’ may result in an unaligned pointer value [-Werror=address-of-packed-member] 199 | p = (uint32_t *)&(rpc_pkt.u.call.data); | ^~~~~~~~~~~~~~~~~~~~~~ net/nfs.c: In function ‘nfs_readlink_reply’: net/nfs.c:631:46: error: taking address of packed member of ‘struct rpc_t’ may result in an unaligned pointer value [-Werror=address-of-packed-member] 631 | nfs3_get_attributes_offset(rpc_pkt.u.reply.data); | ~~~~~~~~~~~~~~~^~~~~ LD drivers/block/built-in.o net/nfs.c: In function ‘nfs_read_reply’: net/nfs.c:692:46: error: taking address of packed member of ‘struct rpc_t’ may result in an unaligned pointer value [-Werror=address-of-packed-member] 692 | nfs3_get_attributes_offset(rpc_pkt.u.reply.data); | ~~~~~~~~~~~~~~~^~~~~ struct rpc_t is only used as local variable. It is naturally packed. So there is no need for the attribute packed. Signed-off-by: Heinrich Schuchardt Reviewed-by: Bin Meng Acked-by: Joe Hershberger --- net/nfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfs.h b/net/nfs.h index a377c90088..68ada0efeb 100644 --- a/net/nfs.h +++ b/net/nfs.h @@ -78,7 +78,7 @@ struct rpc_t { NFS_MAX_ATTRS]; } reply; } u; -} __attribute__((packed)); +}; void nfs_start(void); /* Begin NFS */ -- cgit v1.2.1