Merge branch 'master' of https://gitlab.denx.de/u-boot/custodians/u-boot-net
authorTom Rini <trini@konsulko.com>
Wed, 4 Sep 2019 20:02:03 +0000 (16:02 -0400)
committerTom Rini <trini@konsulko.com>
Wed, 4 Sep 2019 20:02:03 +0000 (16:02 -0400)
- Assorted CVE fixes
- Other fixes

39 files changed:
Makefile
arch/arm/cpu/armv8/fsl-layerscape/Kconfig
arch/arm/dts/armada-cp110-master.dtsi
arch/arm/dts/armada-cp110-slave.dtsi
board/st/stm32mp1/stm32mp1.c
cmd/Kconfig
cmd/Makefile
cmd/mdio.c
cmd/pcap.c [new file with mode: 0644]
configs/sandbox_defconfig
doc/README.pcap [new file with mode: 0644]
doc/device-tree-bindings/net/marvell-mdio.txt [new file with mode: 0644]
doc/device-tree-bindings/net/mdio.txt [new file with mode: 0644]
doc/driver-model/migration.rst
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/designware.c
drivers/net/dwc_eth_qos.c
drivers/net/fsl-mc/Kconfig [new file with mode: 0644]
drivers/net/fsl_enetc_mdio.c
drivers/net/macb.c
drivers/net/mdio_mux_i2creg.c [new file with mode: 0644]
drivers/net/mdio_sandbox.c
drivers/net/mvmdio.c [new file with mode: 0644]
drivers/net/mvpp2.c
drivers/net/pfe_eth/pfe_mdio.c
include/env_callback.h
include/env_flags.h
include/net.h
include/net/pcap.h [new file with mode: 0644]
include/netdev.h
net/Makefile
net/eth-uclass.c
net/eth_legacy.c
net/mdio-uclass.c
net/net.c
net/nfs.c
net/nfs.h
net/pcap.c [new file with mode: 0644]

index c02accfc265368cc75f334eaad956c0606d61734..ae56e47b2c0bfb89e4547badb51a3f451bec3809 100644 (file)
--- 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
index 42d31fdab0a0d94cd84fb3423522914909f91083..54d03ae622d59f27c77c1ef67a1ef5077981a7a4 100644 (file)
@@ -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
 
index 551d00d7746485f736d08f488c2900be712cb028..e4c17e9f4b634f0a08ba78df61aff324a44b118f 100644 (file)
@@ -96,6 +96,7 @@
                                #size-cells = <0>;
                                compatible = "marvell,orion-mdio";
                                reg = <0x12a200 0x10>;
+                               device-name = "cpm-mdio";
                        };
 
                        cpm_syscon0: system-controller@440000 {
index 2ea9004f1d4962683b2f0335468e23c3d7985bee..2fbd7b5514ee023a1b2e34814e78a00d601e584d 100644 (file)
@@ -96,6 +96,7 @@
                                #size-cells = <0>;
                                compatible = "marvell,orion-mdio";
                                reg = <0x12a200 0x10>;
+                               device-name = "cps-mdio";
                        };
 
                        cps_syscon0: system-controller@440000 {
index fc14ad375c8f9d262b0b40467a44b194ce23c27f..18f9b848765576fcad82661b461e938df53af35a 100644 (file)
@@ -17,6 +17,7 @@
 #include <misc.h>
 #include <mtd.h>
 #include <mtd_node.h>
+#include <netdev.h>
 #include <phy.h>
 #include <remoteproc.h>
 #include <reset.h>
@@ -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);
 
index 05872fa0d7f4dce561079555d7e77729c9c7e00e..98647f58b7acaf8fa3c5b7a31010f260b93d481a 100644 (file)
@@ -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
index 58827b567986b31340abe47583e5f6880a90424b..ac843b4b16addd52925c8fee88c27562bc37060e 100644 (file)
@@ -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
index add6440813f6f4f759c0d966eb0c8e78d7f818c7..22c8fbe856f37f482eb87f823f7baa03db22aaff 100644 (file)
@@ -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,
                                              &reglo, &reghi))
                                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,
diff --git a/cmd/pcap.c b/cmd/pcap.c
new file mode 100644 (file)
index 0000000..980603f
--- /dev/null
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Ramon Fried <rfried.dev@gmail.com>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <net/pcap.h>
+
+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<addr> <max_size>\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<addr>: user address to which pcap will be stored (hexedcimal)\n"
+       "\t<max_size>: 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),
+);
index 7355e3aa1ef0cadaf605414671006dfa1addaf9c..968ffdab61b3e3dc25ee13183b904e68bef69261 100644 (file)
@@ -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
diff --git a/doc/README.pcap b/doc/README.pcap
new file mode 100644 (file)
index 0000000..97b3e55
--- /dev/null
@@ -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
+
diff --git a/doc/device-tree-bindings/net/marvell-mdio.txt b/doc/device-tree-bindings/net/marvell-mdio.txt
new file mode 100644 (file)
index 0000000..e2038e2
--- /dev/null
@@ -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/doc/device-tree-bindings/net/mdio.txt b/doc/device-tree-bindings/net/mdio.txt
new file mode 100644 (file)
index 0000000..1595325
--- /dev/null
@@ -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>;
+       };
+};
+
index a26e7ab7e1aaec7cddda5b20dcb76db6ab8411d1..75b85235ef38a6250ea395fa78c7b04c5ada510e 100644 (file)
@@ -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.
index 084e09522919b1c46e7627a4d7d992895fdbc48a..2ce3092db0bc1eeaf2adbd6e8fbd505d42cff0c6 100644 (file)
@@ -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"
@@ -603,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
index 71c0889355c8087894e51208fd5819cc01adc2eb..30991834ecf61bb20836c0748dea9d3aaa36e266 100644 (file)
@@ -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
index c4fe40b19aa92e0266d3665e29671a10fc1a7a6f..145eeac45fd44fc4c84ef787cacddb44734c06ea 100644 (file)
@@ -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" },
index 07b36675a748ba5a65e63ab7ab84da307d23ab3f..455709338cea5d90a51e9db6db78dca7d5e9ee17 100644 (file)
@@ -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;
@@ -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/drivers/net/fsl-mc/Kconfig b/drivers/net/fsl-mc/Kconfig
new file mode 100644 (file)
index 0000000..25a2cb8
--- /dev/null
@@ -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
index 60d21537b807f0105ed97c99102b7faa26a470ff..b4463a58a5761c1b61fbc6e243ebd1f140f92201 100644 (file)
@@ -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);
index c99cf663a4162d3fdfa50f1b6ec13a30e1b2aedc..377188e361c4f9fe98f423f64018b9945f94c7fe 100644 (file)
@@ -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)
@@ -643,7 +645,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)) {
diff --git a/drivers/net/mdio_mux_i2creg.c b/drivers/net/mdio_mux_i2creg.c
new file mode 100644 (file)
index 0000000..3e82898
--- /dev/null
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Alex Marginean, NXP
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <miiphy.h>
+#include <i2c.h>
+
+/*
+ * 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),
+};
index df053f5381422aeb692d5ef6c64590d345be365e..b731f60a98a132380d8d93d69ac8e27a897f0b03 100644 (file)
@@ -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;
diff --git a/drivers/net/mvmdio.c b/drivers/net/mvmdio.c
new file mode 100644 (file)
index 0000000..ec6805e
--- /dev/null
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ * Author: Ken Ma<make@marvell.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <asm/io.h>
+#include <wait_bit.h>
+
+#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),
+};
+
index bcc6fe92a9f9de9d24c557ff5b33d54e2330f5af..bd89725e777cf9415394356e4d7cf154b13d1d95 100644 (file)
@@ -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 = {
index 2dde9e7ac87d315b7f594328649a5c8a3be4575e..62309670fabf3591d3babb20ae3a875b7532cf36 100644 (file)
@@ -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)
index 982c07854d07c8893b30a854d2f6a419169605e6..74da20eec3087143c239134dbac9e9524d1288cd 100644 (file)
@@ -42,7 +42,7 @@
 #define DNS_CALLBACK
 #endif
 
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
 #define NET_CALLBACKS \
        "bootfile:bootfile," \
        "ipaddr:ipaddr," \
index e5380f2948456639df47f9b17ab09f9241025bd8..725841a891d7577dc9cd42414552fef69525a460 100644 (file)
@@ -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
index a54d5eeac5fc95232089ac2f577ec0ffec667e23..75a16e4c8f8f51478f5ff7c2b53a0b764c27967e 100644 (file)
@@ -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);
diff --git a/include/net/pcap.h b/include/net/pcap.h
new file mode 100644 (file)
index 0000000..512ba98
--- /dev/null
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2019
+ * Ramon Fried <rfried.dev@gmail.com>
+ */
+
+/**
+ * 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);
index a40c4adaadd7a19339abd28dbbc906c3fc1948a4..68a3fceab663415ca4c51318cd4a92a54ae490ce 100644 (file)
@@ -10,6 +10,7 @@
 
 #ifndef _NETDEV_H_
 #define _NETDEV_H_
+#include <phy_interface.h>
 
 /*
  * 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 */
index 826544f05f912567652766aef9c680437280b87d..2a700c8401c4c1e84f45dafa17b08db80a7709e7 100644 (file)
@@ -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
index 1d5d2f03b7d946f989dadfcb852d6d62576c4693..3bd98b01ad32ac097754c5c3ff78b1b485a32cfb 100644 (file)
@@ -11,6 +11,7 @@
 #include <net.h>
 #include <dm/device-internal.h>
 #include <dm/uclass-internal.h>
+#include <net/pcap.h>
 #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;
 }
 
index 850f362d873e2930da2d0e42bf77f5412c5b64cc..41f52635266280360a6e848f752556c7aed011f6 100644 (file)
@@ -11,6 +11,7 @@
 #include <net.h>
 #include <phy.h>
 #include <linux/errno.h>
+#include <net/pcap.h>
 #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)
index 36a404ff449a5beddc2611fe167bd32663273efb..6f922e80b6fb2ff0d0411b6cb9b01961c4d46aca 100644 (file)
@@ -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
@@ -75,7 +86,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);
 }
index 40511db645dff85b255d735fccc737c007c93470..ded86e7456715ebfc39ce1f52cdd5fd954870963 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -96,6 +96,9 @@
 #include <net.h>
 #include <net/fastboot.h>
 #include <net/tftp.h>
+#if defined(CONFIG_CMD_PCAP)
+#include <net/pcap.h>
+#endif
 #if defined(CONFIG_LED_STATUS)
 #include <miiphy.h>
 #include <status_led.h>
@@ -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;
@@ -1253,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);
index d6a7f8e827a1ce47712daca250f45c1ccc24c531..aca0ca55f3f76749c8ff3d663b5d05eb68517b7e 100644 (file)
--- 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;
 
@@ -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);
        }
 
@@ -579,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 :
@@ -634,6 +638,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;
 
@@ -701,6 +708,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;
 
@@ -732,6 +742,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;
 
index a377c90088388b94e77cf23226e38a47ffd2021b..68ada0efeb9ba370e69740438cb27087e9ac8deb 100644 (file)
--- 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 */
 
 
diff --git a/net/pcap.c b/net/pcap.c
new file mode 100644 (file)
index 0000000..4036d8a
--- /dev/null
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Ramon Fried <rfried.dev@gmail.com>
+ */
+
+#include <common.h>
+#include <net.h>
+#include <net/pcap.h>
+#include <time.h>
+#include <asm/io.h>
+
+#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;
+}