diff options
55 files changed, 615 insertions, 577 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index cb787d32f14..01ab0c11f98 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -350,6 +350,8 @@ stages: sandbox64_clang: TEST_PY_BD: "sandbox64" OVERRIDE: "-O clang-18" + sandbox64_lwip: + TEST_PY_BD: "sandbox64_lwip" sandbox_spl: TEST_PY_BD: "sandbox_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5f3418e482f..145bdad83bf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -290,6 +290,17 @@ sandbox64 with clang test.py: OVERRIDE: "-O clang-18" <<: *buildman_and_testpy_dfn +sandbox64_lwip test.py: + parallel: + matrix: + - HOST: "fast arm64" + - HOST: "fast amd64" + tags: + - ${HOST} + variables: + TEST_PY_BD: "sandbox64_lwip" + <<: *buildman_and_testpy_dfn + sandbox_spl test.py: variables: TEST_PY_BD: "sandbox_spl" @@ -96,7 +96,8 @@ This contributor prefers not to receive mails <noreply@example.com> <pali.rohar@ Padmarao Begari <padmarao.begari@amd.com> <padmarao.begari@microchip.com> Patrice Chotard <patrice.chotard@foss.st.com> <patrice.chotard@st.com> Patrick Delaunay <patrick.delaunay@foss.st.com> <patrick.delaunay@st.com> -Paul Burton <paul.burton@mips.com> <paul.burton@imgtec.com> +Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com> +Paul Burton <paulburton@kernel.org> <paul.burton@mips.com> Philipp Tomsich <philipp.tomsich@vrull.eu> <philipp.tomsich@theobroma-systems.com> Piyush Mehta <piyush.mehta@amd.com> <piyush.mehta@xilinx.com> Prabhakar Kushwaha <prabhakar@freescale.com> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d7065a80e23..a0317011de7 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -146,7 +146,35 @@ config TARGET_BOSTON select SUPPORTS_CPU_MIPS64_R6 select SUPPORT_BIG_ENDIAN select SUPPORT_LITTLE_ENDIAN + imply OF_UPSTREAM + imply BOOTSTD_FULL + imply CLK + imply CLK_BOSTON imply CMD_DM + imply AHCI + imply AHCI_PCI + imply CFI_FLASH + imply MTD_NOR_FLASH + imply MMC + imply MMC_PCI + imply MMC_SDHCI + imply MMC_SDHCI_SDMA + imply PCH_GBE + imply PCI + imply PCI_XILINX + imply PCI_INIT_R + imply SCSI + imply SCSI_AHCI + imply SYS_NS16550 + imply SYSRESET + imply SYSRESET_CMD_POWEROFF + imply SYSRESET_SYSCON + imply USB + imply USB_EHCI_HCD + imply USB_EHCI_PCI + imply USB_XHCI_HCD + imply USB_XHCI_PCI + imply CMD_USB config TARGET_XILFPGA bool "Support Imagination Xilfpga" diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index 752e771514f..7c4ee8b668b 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -3,7 +3,6 @@ dtb-$(CONFIG_TARGET_AP121) += ap121.dtb dtb-$(CONFIG_TARGET_AP143) += ap143.dtb dtb-$(CONFIG_TARGET_AP152) += ap152.dtb -dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb dtb-$(CONFIG_TARGET_XILFPGA) += nexys4ddr.dtb diff --git a/arch/mips/dts/boston-u-boot.dtsi b/arch/mips/dts/boston-u-boot.dtsi new file mode 100644 index 00000000000..1b0c0a28961 --- /dev/null +++ b/arch/mips/dts/boston-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ + +&plat_regs { + compatible = "img,boston-platform-regs", "syscon", "simple-mfd"; + bootph-all; +}; + +&clk_boston { + bootph-all; +}; diff --git a/arch/mips/dts/img,boston.dts b/arch/mips/dts/img,boston.dts deleted file mode 100644 index c1a73963037..00000000000 --- a/arch/mips/dts/img,boston.dts +++ /dev/null @@ -1,222 +0,0 @@ -/dts-v1/; - -#include <dt-bindings/clock/boston-clock.h> -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/interrupt-controller/irq.h> -#include <dt-bindings/interrupt-controller/mips-gic.h> - -/ { - #address-cells = <1>; - #size-cells = <1>; - compatible = "img,boston"; - - chosen { - stdout-path = &uart0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "img,mips"; - reg = <0>; - clocks = <&clk_boston BOSTON_CLK_CPU>; - }; - }; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - gic: interrupt-controller { - compatible = "mti,gic"; - - interrupt-controller; - #interrupt-cells = <3>; - - timer { - compatible = "mti,gic-timer"; - interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>; - clocks = <&clk_boston BOSTON_CLK_CPU>; - }; - }; - - pci0: pci@10000000 { - status = "disabled"; - compatible = "xlnx,axi-pcie-host-1.00.a"; - device_type = "pci"; - reg = <0x10000000 0x2000000>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - interrupt-parent = <&gic>; - interrupts = <GIC_SHARED 2 IRQ_TYPE_LEVEL_HIGH>; - - ranges = <0x02000000 0 0x40000000 - 0x40000000 0 0x40000000>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pci0_intc 0>, - <0 0 0 2 &pci0_intc 1>, - <0 0 0 3 &pci0_intc 2>, - <0 0 0 4 &pci0_intc 3>; - - pci0_intc: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - }; - - pci1: pci@12000000 { - status = "disabled"; - compatible = "xlnx,axi-pcie-host-1.00.a"; - device_type = "pci"; - reg = <0x12000000 0x2000000>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - interrupt-parent = <&gic>; - interrupts = <GIC_SHARED 1 IRQ_TYPE_LEVEL_HIGH>; - - ranges = <0x02000000 0 0x20000000 - 0x20000000 0 0x20000000>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pci1_intc 0>, - <0 0 0 2 &pci1_intc 1>, - <0 0 0 3 &pci1_intc 2>, - <0 0 0 4 &pci1_intc 3>; - - pci1_intc: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - }; - - pci2: pci@14000000 { - compatible = "xlnx,axi-pcie-host-1.00.a"; - device_type = "pci"; - reg = <0x14000000 0x2000000>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - interrupt-parent = <&gic>; - interrupts = <GIC_SHARED 0 IRQ_TYPE_LEVEL_HIGH>; - - ranges = <0x02000000 0 0x16000000 - 0x16000000 0 0x100000>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pci2_intc 0>, - <0 0 0 2 &pci2_intc 1>, - <0 0 0 3 &pci2_intc 2>, - <0 0 0 4 &pci2_intc 3>; - - pci2_intc: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - - pci2_root@0,0,0 { - compatible = "pci10ee,7021"; - reg = <0x00000000 0 0 0 0>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - eg20t_bridge@1,0,0 { - compatible = "pci8086,8800"; - reg = <0x00010000 0 0 0 0>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - eg20t_mac@2,0,1 { - compatible = "pci8086,8802"; - reg = <0x00020100 0 0 0 0>; - phy-reset-gpios = <&eg20t_gpio 6 GPIO_ACTIVE_LOW>; - }; - - eg20t_gpio: eg20t_gpio@2,0,2 { - compatible = "pci8086,8803"; - reg = <0x00020200 0 0 0 0>; - - gpio-controller; - #gpio-cells = <2>; - }; - - eg20t_i2c@2,12,2 { - compatible = "pci8086,8817"; - reg = <0x00026200 0 0 0 0>; - - #address-cells = <1>; - #size-cells = <0>; - - rtc@0x68 { - compatible = "st,m41t81s"; - reg = <0x68>; - }; - }; - }; - }; - }; - - plat_regs: system-controller@17ffd000 { - compatible = "img,boston-platform-regs", "syscon"; - reg = <0x17ffd000 0x1000>; - bootph-all; - }; - - clk_boston: clock { - compatible = "img,boston-clock"; - #clock-cells = <1>; - regmap = <&plat_regs>; - bootph-all; - }; - - reboot: syscon-reboot { - compatible = "syscon-reboot"; - regmap = <&plat_regs>; - offset = <0x10>; - mask = <0x10>; - }; - - uart0: uart@17ffe000 { - compatible = "ns16550a"; - reg = <0x17ffe000 0x1000>; - reg-shift = <2>; - reg-io-width = <4>; - - interrupt-parent = <&gic>; - interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>; - - clocks = <&clk_boston BOSTON_CLK_SYS>; - - bootph-all; - }; - - lcd: lcd@17fff000 { - compatible = "img,boston-lcd"; - reg = <0x17fff000 0x8>; - }; - - flash@18000000 { - compatible = "cfi-flash"; - reg = <0x18000000 0x8000000>; - bank-width = <2>; - }; -}; diff --git a/arch/mips/include/asm/acpi_table.h b/arch/mips/include/asm/acpi_table.h new file mode 100644 index 00000000000..b4139d0ba32 --- /dev/null +++ b/arch/mips/include/asm/acpi_table.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __ASM_ACPI_TABLE_H__ +#define __ASM_ACPI_TABLE_H__ + +/* + * This file is needed by some drivers. + */ + +#endif /* __ASM_ACPI_TABLE_H__ */ diff --git a/board/imgtec/boston/Kconfig b/board/imgtec/boston/Kconfig index 5537788001a..965847d9650 100644 --- a/board/imgtec/boston/Kconfig +++ b/board/imgtec/boston/Kconfig @@ -9,6 +9,10 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "boston" + +config ENV_SOURCE_FILE + default "boston" + config TEXT_BASE default 0x9fc00000 if 32BIT default 0xffffffff9fc00000 if 64BIT diff --git a/board/imgtec/boston/MAINTAINERS b/board/imgtec/boston/MAINTAINERS index 07f6156ffcb..b03a6487db2 100644 --- a/board/imgtec/boston/MAINTAINERS +++ b/board/imgtec/boston/MAINTAINERS @@ -1,6 +1,7 @@ BOSTON BOARD -M: Paul Burton <paul.burton@mips.com> +M: Paul Burton <paulburton@kernel.org> S: Maintained +F: arch/mips/dts/boston-u-boot.dtsi F: board/imgtec/boston/ F: include/configs/boston.h F: configs/boston32r2_defconfig diff --git a/board/imgtec/boston/boston.env b/board/imgtec/boston/boston.env new file mode 100644 index 00000000000..796e0fd6bf9 --- /dev/null +++ b/board/imgtec/boston/boston.env @@ -0,0 +1,9 @@ +#ifdef CONFIG_64BIT +fdt_addr_r=0xffffffff80001000 +kernel_addr_r=0xffffffff88000000 +ramdisk_addr_r=0xffffffff8b000000 +#else +fdt_addr_r=0x80001000 +kernel_addr_r=0x88000000 +ramdisk_addr_r=0x8b000000 +#endif diff --git a/board/imgtec/malta/MAINTAINERS b/board/imgtec/malta/MAINTAINERS index b1cf297f4fa..252c5e45ab5 100644 --- a/board/imgtec/malta/MAINTAINERS +++ b/board/imgtec/malta/MAINTAINERS @@ -1,5 +1,5 @@ MALTA BOARD -M: Paul Burton <paul.burton@mips.com> +M: Paul Burton <paulburton@kernel.org> S: Maintained F: board/imgtec/malta/ F: include/configs/malta.h diff --git a/board/sandbox/sandbox.env b/board/sandbox/sandbox.env index a2c19702d64..29197f56e95 100644 --- a/board/sandbox/sandbox.env +++ b/board/sandbox/sandbox.env @@ -8,6 +8,11 @@ stderr=serial,vidconsole ethaddr=02:00:11:22:33:44 eth6addr=02:00:11:22:33:47 ipaddr=192.0.2.1 +ipaddr2=192.0.2.3 +ipaddr3=192.0.2.4 +ipaddr5=192.0.2.6 +ipaddr6=192.0.2.7 +ipaddr7=192.0.2.8 /* * These are used for distro boot which is not supported. But once bootmethod diff --git a/cmd/net.c b/cmd/net.c index 79525f73a51..eaa1de5295f 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -456,8 +456,7 @@ static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc, } #if defined(CONFIG_CMD_PING) -static int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { if (argc < 2) return CMD_RET_USAGE; diff --git a/cmd/pxe.c b/cmd/pxe.c index 37b8dea6ad6..0f26b3b4219 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -13,7 +13,6 @@ #include "pxe_utils.h" -#ifdef CONFIG_CMD_NET const char *pxe_default_paths[] = { #ifdef CONFIG_SYS_SOC #ifdef CONFIG_SYS_BOARD @@ -331,5 +330,3 @@ U_BOOT_CMD(pxe, 4, 1, do_pxe, "get [" USE_IP6_CMD_PARAM "] - try to retrieve a pxe file using tftp\n" "pxe boot [pxefile_addr_r] [-ipv6] - boot from the pxe file at pxefile_addr_r\n" ); - -#endif /* CONFIG_CMD_NET */ diff --git a/common/board_r.c b/common/board_r.c index 65d74e3c092..bc6fd6448c2 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -509,7 +509,7 @@ static int initr_boot_led_on(void) return 0; } -#if defined(CONFIG_CMD_NET) +#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP) static int initr_net(void) { puts("Net: "); @@ -779,7 +779,7 @@ static void initcall_run_r(void) #if CONFIG_IS_ENABLED(PCI_ENDPOINT) INITCALL(pci_ep_init); #endif -#if CONFIG_IS_ENABLED(CMD_NET) +#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP) WATCHDOG_RESET(); INITCALL(initr_net); #endif diff --git a/configs/boston32r2_defconfig b/configs/boston32r2_defconfig index 6f4dfad5a31..5556148f3cf 100644 --- a/configs/boston32r2_defconfig +++ b/configs/boston32r2_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0x88000000 CONFIG_ENV_ADDR=0xBFFE0000 diff --git a/configs/boston32r2el_defconfig b/configs/boston32r2el_defconfig index cdf13c8332f..d23eb99518e 100644 --- a/configs/boston32r2el_defconfig +++ b/configs/boston32r2el_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0x88000000 CONFIG_ENV_ADDR=0xBFFE0000 diff --git a/configs/boston32r6_defconfig b/configs/boston32r6_defconfig index d8fb956914c..56738e955e3 100644 --- a/configs/boston32r6_defconfig +++ b/configs/boston32r6_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0x88000000 CONFIG_ENV_ADDR=0xBFFE0000 diff --git a/configs/boston32r6el_defconfig b/configs/boston32r6el_defconfig index b6d3102cf2a..ddc6655dd7c 100644 --- a/configs/boston32r6el_defconfig +++ b/configs/boston32r6el_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0x88000000 CONFIG_ENV_ADDR=0xBFFE0000 diff --git a/configs/boston64r2_defconfig b/configs/boston64r2_defconfig index 6b23d180f84..fa234b62305 100644 --- a/configs/boston64r2_defconfig +++ b/configs/boston64r2_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0xffffffff88000000 CONFIG_ENV_ADDR=0xFFFFFFFFBFFE0000 diff --git a/configs/boston64r2el_defconfig b/configs/boston64r2el_defconfig index ff4b52615a6..58bf8817ab6 100644 --- a/configs/boston64r2el_defconfig +++ b/configs/boston64r2el_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0xffffffff88000000 CONFIG_ENV_ADDR=0xFFFFFFFFBFFE0000 diff --git a/configs/boston64r6_defconfig b/configs/boston64r6_defconfig index a7446ec5555..eb3ec0064dc 100644 --- a/configs/boston64r6_defconfig +++ b/configs/boston64r6_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0xffffffff88000000 CONFIG_ENV_ADDR=0xFFFFFFFFBFFE0000 diff --git a/configs/boston64r6el_defconfig b/configs/boston64r6el_defconfig index 0dab8efb875..332c2ba39e9 100644 --- a/configs/boston64r6el_defconfig +++ b/configs/boston64r6el_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0xffffffff88000000 CONFIG_ENV_ADDR=0xFFFFFFFFBFFE0000 diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index b7f4a76ce68..2c69e913394 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -47,6 +47,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_NOR_SUPPORT=y CONFIG_HUSH_PARSER=y CONFIG_CMD_LICENSE=y +CONFIG_SYS_BOOTM_LEN=0x2000000 # CONFIG_CMD_ELF is not set # CONFIG_CMD_XIMG is not set CONFIG_CMD_MEMINFO=y diff --git a/configs/sandbox64_lwip_defconfig b/configs/sandbox64_lwip_defconfig new file mode 100644 index 00000000000..0e92728533f --- /dev/null +++ b/configs/sandbox64_lwip_defconfig @@ -0,0 +1,5 @@ +#include <configs/sandbox64_defconfig> + +CONFIG_SANDBOX=y + +CONFIG_NET_LWIP=y diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b532b3b7339..38e953ee79c 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -420,7 +420,7 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts) { - phys_addr_t pa = virt_to_phys((void *)pp->cmd_tbl); + phys_addr_t pa = virt_to_phys(pp->cmd_tbl); pp->cmd_slot->opts = cpu_to_le32(opts); pp->cmd_slot->status = 0; @@ -449,7 +449,7 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) { struct ahci_ioports *pp = &(uc_priv->port[port]); void __iomem *port_mmio = pp->port_mmio; - u64 dma_addr; + phys_addr_t dma_addr; u32 port_status; void __iomem *mem; @@ -472,34 +472,32 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) * First item in chunk of DMA memory: 32-slot command table, * 32 bytes each in size */ - pp->cmd_slot = - (struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem); - debug("cmd_slot = %p\n", pp->cmd_slot); - mem += (AHCI_CMD_SLOT_SZ + 224); + pp->cmd_slot = (struct ahci_cmd_hdr *)mem; + mem += AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT; /* * Second item: Received-FIS area */ - pp->rx_fis = virt_to_phys((void *)mem); + pp->rx_fis = mem; mem += AHCI_RX_FIS_SZ; /* * Third item: data area for storing a single command * and its scatter-gather table */ - pp->cmd_tbl = virt_to_phys((void *)mem); - debug("cmd_tbl_dma = %lx\n", pp->cmd_tbl); + pp->cmd_tbl = mem; mem += AHCI_CMD_TBL_HDR; - pp->cmd_tbl_sg = - (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem); - - dma_addr = (ulong)pp->cmd_slot; - writel_with_flush(dma_addr, port_mmio + PORT_LST_ADDR); - writel_with_flush(dma_addr >> 32, port_mmio + PORT_LST_ADDR_HI); - dma_addr = (ulong)pp->rx_fis; - writel_with_flush(dma_addr, port_mmio + PORT_FIS_ADDR); - writel_with_flush(dma_addr >> 32, port_mmio + PORT_FIS_ADDR_HI); + pp->cmd_tbl_sg = (struct ahci_sg *)(mem); + + dma_addr = virt_to_phys(pp->cmd_slot); + debug("cmd_slot_dma = 0x%08llx\n", (u64)dma_addr); + writel_with_flush(lower_32_bits(dma_addr), port_mmio + PORT_LST_ADDR); + writel_with_flush(upper_32_bits(dma_addr), port_mmio + PORT_LST_ADDR_HI); + dma_addr = virt_to_phys(pp->rx_fis); + debug("rx_fis_dma = 0x%08llx\n", (u64)dma_addr); + writel_with_flush(lower_32_bits(dma_addr), port_mmio + PORT_FIS_ADDR); + writel_with_flush(upper_32_bits(dma_addr), port_mmio + PORT_FIS_ADDR_HI); #ifdef CONFIG_SUNXI_AHCI sunxi_dma_init(port_mmio); diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 203f98edffc..d225289fe6e 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -7,6 +7,7 @@ #include <ahci.h> #include <blk.h> #include <bootdev.h> +#include <clk.h> #include <cpu_func.h> #include <dm.h> #include <dwc_ahsata.h> @@ -19,9 +20,11 @@ #include <sata.h> #include <asm/cache.h> #include <asm/io.h> +#if IS_ENABLED(CONFIG_ARCH_MX5) || IS_ENABLED(CONFIG_ARCH_MX6) #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> #include <asm/mach-imx/sata.h> +#endif #include <linux/bitops.h> #include <linux/ctype.h> #include <linux/delay.h> @@ -116,13 +119,12 @@ static int ahci_setup_oobr(struct ahci_uc_priv *uc_priv, int clk) return 0; } -static int ahci_host_init(struct ahci_uc_priv *uc_priv) +static int ahci_host_init(struct ahci_uc_priv *uc_priv, int clk) { u32 tmp, cap_save, num_ports; int i, j, timeout = 1000; struct sata_port_regs *port_mmio = NULL; struct sata_host_regs *host_mmio = uc_priv->mmio_base; - int clk = mxc_get_clock(MXC_SATA_CLK); cap_save = readl(&host_mmio->cap); cap_save |= SATA_HOST_CAP_SSS; @@ -330,6 +332,7 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, { struct ahci_ioports *pp = &uc_priv->port[port]; struct ahci_sg *ahci_sg = pp->cmd_tbl_sg; + phys_addr_t pa = virt_to_phys(buf); u32 sg_count, max_bytes; int i; @@ -341,9 +344,8 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, } for (i = 0; i < sg_count; i++) { - ahci_sg->addr = - cpu_to_le32((u32)buf + i * max_bytes); - ahci_sg->addr_hi = 0; + ahci_sg->addr = cpu_to_le32(lower_32_bits(pa)); + ahci_sg->addr_hi = cpu_to_le32(upper_32_bits(pa)); ahci_sg->flags_size = cpu_to_le32(0x3fffff & (buf_len < max_bytes ? (buf_len - 1) @@ -359,14 +361,14 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts) { struct ahci_cmd_hdr *cmd_hdr = (struct ahci_cmd_hdr *)(pp->cmd_slot + AHCI_CMD_SLOT_SZ * cmd_slot); + phys_addr_t pa = virt_to_phys(pp->cmd_tbl); memset(cmd_hdr, 0, AHCI_CMD_SLOT_SZ); cmd_hdr->opts = cpu_to_le32(opts); cmd_hdr->status = 0; - pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff); + pp->cmd_slot->tbl_addr = cpu_to_le32(lower_32_bits(pa)); #ifdef CONFIG_PHYS_64BIT - pp->cmd_slot->tbl_addr_hi = - cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16)); + pp->cmd_slot->tbl_addr_hi = cpu_to_le32(upper_32_bits(pa)); #endif } @@ -404,7 +406,7 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, } ahci_fill_cmd_slot(pp, cmd_slot, opts); - flush_cache((int)(pp->cmd_slot), AHCI_PORT_PRIV_DMA_SZ); + flush_cache((ulong)(pp->cmd_slot), AHCI_PORT_PRIV_DMA_SZ); writel_with_flush(1 << cmd_slot, &port_mmio->ci); if (waiting_for_cmd_completed((u8 *)&port_mmio->ci, 10000, @@ -412,8 +414,8 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, printf("timeout exit!\n"); return -1; } - invalidate_dcache_range((int)(pp->cmd_slot), - (int)(pp->cmd_slot)+AHCI_PORT_PRIV_DMA_SZ); + invalidate_dcache_range((ulong)(pp->cmd_slot), + (ulong)(pp->cmd_slot) + AHCI_PORT_PRIV_DMA_SZ); debug("ahci_exec_ata_cmd: %d byte transferred.\n", pp->cmd_slot->status); if (!is_write) @@ -441,8 +443,9 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) { struct ahci_ioports *pp = &uc_priv->port[port]; struct sata_port_regs *port_mmio = pp->port_mmio; + phys_addr_t dma_addr; u32 port_status; - u32 mem; + void *mem; int timeout = 10000000; debug("Enter start port: %d\n", port); @@ -453,22 +456,20 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) return -1; } - mem = (u32)malloc(AHCI_PORT_PRIV_DMA_SZ + 1024); + mem = memalign(2048, AHCI_PORT_PRIV_DMA_SZ); if (!mem) { printf("No mem for table!\n"); return -ENOMEM; } - mem = (mem + 0x400) & (~0x3ff); /* Aligned to 1024-bytes */ - memset((u8 *)mem, 0, AHCI_PORT_PRIV_DMA_SZ); + memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); /* * First item in chunk of DMA memory: 32-slot command table, * 32 bytes each in size */ pp->cmd_slot = (struct ahci_cmd_hdr *)mem; - debug("cmd_slot = 0x%x\n", (unsigned int) pp->cmd_slot); - mem += (AHCI_CMD_SLOT_SZ * DWC_AHSATA_MAX_CMD_SLOTS); + mem += AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT; /* * Second item: Received-FIS area, 256-Byte aligned @@ -481,14 +482,19 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) * and its scatter-gather table */ pp->cmd_tbl = mem; - debug("cmd_tbl_dma = 0x%lx\n", pp->cmd_tbl); - mem += AHCI_CMD_TBL_HDR; + pp->cmd_tbl_sg = (struct ahci_sg *)mem; writel_with_flush(0x00004444, &port_mmio->dmacr); - pp->cmd_tbl_sg = (struct ahci_sg *)mem; - writel_with_flush((u32)pp->cmd_slot, &port_mmio->clb); - writel_with_flush(pp->rx_fis, &port_mmio->fb); + dma_addr = virt_to_phys(pp->cmd_slot); + debug("cmd_slot_dma = 0x%08llx\n", (u64)dma_addr); + writel_with_flush(lower_32_bits(dma_addr), &port_mmio->clb); + writel_with_flush(upper_32_bits(dma_addr), &port_mmio->clbu); + dma_addr = virt_to_phys(pp->cmd_slot); + debug("rx_fis_slot_dma = 0x%08llx\n", (u64)dma_addr); + writel_with_flush(lower_32_bits(dma_addr), &port_mmio->fb); + writel_with_flush(upper_32_bits(dma_addr), &port_mmio->fbu); + /* Enable FRE */ writel_with_flush((SATA_PORT_CMD_FRE | readl(&port_mmio->cmd)), @@ -910,17 +916,41 @@ int dwc_ahsata_scan(struct udevice *dev) int dwc_ahsata_probe(struct udevice *dev) { struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct clk_bulk clk_bulk __maybe_unused; + struct clk clk __maybe_unused; + int sataclk; int ret; -#if defined(CONFIG_MX6) +#if IS_ENABLED(CONFIG_MX6) setup_sata(); #endif +#if IS_ENABLED(CONFIG_MX5) || IS_ENABLED(CONFIG_MX6) + sataclk = mxc_get_clock(MXC_SATA_CLK); +#else + ret = clk_get_bulk(dev, &clk_bulk); + if (ret) + return ret; + + ret = clk_enable_bulk(&clk_bulk); + if (ret) + return ret; + + ret = clk_get_by_name(dev, "sata", &clk); + if (ret) + return ret; + + sataclk = clk_get_rate(&clk); +#endif + if (IS_ERR_VALUE(sataclk)) { + log_err("Unable to get SATA clock rate\n"); + return -EINVAL; + } uc_priv->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NO_ATAPI; uc_priv->mmio_base = dev_read_addr_ptr(dev); /* initialize adapter */ - ret = ahci_host_init(uc_priv); + ret = ahci_host_init(uc_priv, sataclk); if (ret) return ret; @@ -962,7 +992,6 @@ U_BOOT_DRIVER(dwc_ahsata_blk) = { .ops = &dwc_ahsata_blk_ops, }; -#if CONFIG_IS_ENABLED(DWC_AHSATA_AHCI) struct ahci_ops dwc_ahsata_ahci_ops = { .port_status = dwc_ahsata_port_status, .reset = dwc_ahsata_bus_reset, @@ -970,7 +999,9 @@ struct ahci_ops dwc_ahsata_ahci_ops = { }; static const struct udevice_id dwc_ahsata_ahci_ids[] = { + { .compatible = "fsl,imx53-ahci" }, { .compatible = "fsl,imx6q-ahci" }, + { .compatible = "fsl,imx6qp-ahci" }, { } }; @@ -981,4 +1012,3 @@ U_BOOT_DRIVER(dwc_ahsata_ahci) = { .ops = &dwc_ahsata_ahci_ops, .probe = dwc_ahsata_probe, }; -#endif diff --git a/drivers/ata/dwc_ahsata_priv.h b/drivers/ata/dwc_ahsata_priv.h index 5b0579ae115..0c2cd5446b5 100644 --- a/drivers/ata/dwc_ahsata_priv.h +++ b/drivers/ata/dwc_ahsata_priv.h @@ -7,8 +7,6 @@ #ifndef __DWC_AHSATA_PRIV_H__ #define __DWC_AHSATA_PRIV_H__ -#define DWC_AHSATA_MAX_CMD_SLOTS 32 - /* Max host controller numbers */ #define SATA_HC_MAX_NUM 4 /* Max command queue depth per host controller */ diff --git a/drivers/clk/clk_boston.c b/drivers/clk/clk_boston.c index 030ff7cc58e..71e030f463e 100644 --- a/drivers/clk/clk_boston.c +++ b/drivers/clk/clk_boston.c @@ -58,17 +58,21 @@ const struct clk_ops clk_boston_ops = { .get_rate = clk_boston_get_rate, }; -static int clk_boston_of_to_plat(struct udevice *dev) +static int clk_boston_probe(struct udevice *dev) { struct clk_boston *state = dev_get_plat(dev); struct udevice *syscon; int err; - err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, - "regmap", &syscon); - if (err) { - pr_err("unable to find syscon device\n"); - return err; + if (dev->parent && device_get_uclass_id(dev->parent) == UCLASS_SYSCON) { + syscon = dev->parent; + } else { + err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, + "regmap", &syscon); + if (err) { + pr_err("unable to find syscon device\n"); + return err; + } } state->regmap = syscon_get_regmap(syscon); @@ -91,7 +95,8 @@ U_BOOT_DRIVER(clk_boston) = { .name = "boston_clock", .id = UCLASS_CLK, .of_match = clk_boston_match, - .of_to_plat = clk_boston_of_to_plat, + .probe = clk_boston_probe, .plat_auto = sizeof(struct clk_boston), .ops = &clk_boston_ops, + .flags = DM_FLAG_PRE_RELOC, }; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a0a7890bd26..4434d364777 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -48,7 +48,6 @@ config DM_DSA bool "Enable Driver Model for DSA switches" depends on DM_MDIO depends on PHY_FIXED - depends on !NET_LWIP help Enable driver model for DSA switches @@ -358,7 +357,7 @@ config ESSEDMA config ETH_SANDBOX depends on SANDBOX - depends on NET + depends on NET || NET_LWIP default y bool "Sandbox: Mocked Ethernet driver" help @@ -367,17 +366,6 @@ config ETH_SANDBOX This driver is particularly useful in the test/dm/eth.c tests -config ETH_SANDBOX_LWIP - depends on SANDBOX - depends on NET_LWIP - default y - bool "Sandbox: Mocked Ethernet driver (for NET_LWIP)" - help - This driver is meant as a replacement for ETH_SANDBOX when - the network stack is NET_LWIP rather than NET. It currently - does nothing, i.e. it drops the sent packets and never receives - data. - config ETH_SANDBOX_RAW depends on SANDBOX depends on NET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 3244d39036d..67bba3a8536 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -41,7 +41,6 @@ obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o obj-$(CONFIG_ETH_SANDBOX) += sandbox.o obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw-bus.o obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o -obj-$(CONFIG_ETH_SANDBOX_LWIP) += sandbox-lwip.o obj-$(CONFIG_FEC_MXC) += fec_mxc.o obj-$(CONFIG_FMAN_ENET) += fm/ obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o diff --git a/drivers/net/sandbox-lwip.c b/drivers/net/sandbox-lwip.c deleted file mode 100644 index 3721033c310..00000000000 --- a/drivers/net/sandbox-lwip.c +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2015 National Instruments - * - * (C) Copyright 2015 - * Joe Hershberger <joe.hershberger@ni.com> - */ - -#include <dm.h> -#include <log.h> -#include <malloc.h> -#include <net.h> -#include <asm/eth.h> -#include <asm/global_data.h> -#include <asm/test.h> - -DECLARE_GLOBAL_DATA_PTR; - -static int sb_lwip_eth_start(struct udevice *dev) -{ - debug("eth_sandbox_lwip: Start\n"); - - return 0; -} - -static int sb_lwip_eth_send(struct udevice *dev, void *packet, int length) -{ - debug("eth_sandbox_lwip: Send packet %d\n", length); - - return -ENOTSUPP; -} - -static int sb_lwip_eth_recv(struct udevice *dev, int flags, uchar **packetp) -{ - return -EAGAIN; -} - -static int sb_lwip_eth_free_pkt(struct udevice *dev, uchar *packet, int length) -{ - return 0; -} - -static void sb_lwip_eth_stop(struct udevice *dev) -{ -} - -static int sb_lwip_eth_write_hwaddr(struct udevice *dev) -{ - return 0; -} - -static const struct eth_ops sb_eth_ops = { - .start = sb_lwip_eth_start, - .send = sb_lwip_eth_send, - .recv = sb_lwip_eth_recv, - .free_pkt = sb_lwip_eth_free_pkt, - .stop = sb_lwip_eth_stop, - .write_hwaddr = sb_lwip_eth_write_hwaddr, -}; - -static int sb_lwip_eth_remove(struct udevice *dev) -{ - return 0; -} - -static int sb_lwip_eth_of_to_plat(struct udevice *dev) -{ - return 0; -} - -static const struct udevice_id sb_eth_ids[] = { - { .compatible = "sandbox,eth" }, - { } -}; - -U_BOOT_DRIVER(eth_sandbox) = { - .name = "eth_lwip_sandbox", - .id = UCLASS_ETH, - .of_match = sb_eth_ids, - .of_to_plat = sb_lwip_eth_of_to_plat, - .remove = sb_lwip_eth_remove, - .ops = &sb_eth_ops, - .priv_auto = 0, - .plat_auto = sizeof(struct eth_pdata), -}; diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c index fe3627db6e3..2011fd31f41 100644 --- a/drivers/net/sandbox.c +++ b/drivers/net/sandbox.c @@ -9,13 +9,84 @@ #include <dm.h> #include <log.h> #include <malloc.h> -#include <net.h> #include <asm/eth.h> #include <asm/global_data.h> #include <asm/test.h> +#include <asm/types.h> + +/* + * Structure definitions for network protocols. Since this file is used for + * both NET and NET_LWIP, and given that the two network stacks do have + * conflicting types (for instance struct icmp_hdr), it is on purpose that the + * structures are defined locally with minimal dependencies -- <asm/types.h> is + * included for the bit types and that's it. + */ + +#define ETHADDR_LEN 6 +#define IP4_LEN 4 + +struct ethhdr { + u8 dst[ETHADDR_LEN]; + u8 src[ETHADDR_LEN]; + u16 protlen; +} __attribute__((packed)); + +#define ETHHDR_SIZE (sizeof(struct ethhdr)) + +struct arphdr { + u16 htype; + u16 ptype; + u8 hlen; + u8 plen; + u16 op; +} __attribute__((packed)); + +#define ARPHDR_SIZE (sizeof(struct arphdr)) + +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +struct arpdata { + u8 sha[ETHADDR_LEN]; + u32 spa; + u8 tha[ETHADDR_LEN]; + u32 tpa; +} __attribute__((packed)); + +#define ARPDATA_SIZE (sizeof(struct arpdata)) + +struct iphdr { + u8 hl_v; + u8 tos; + u16 len; + u16 id; + u16 off; + u8 ttl; + u8 prot; + u16 sum; + u32 src; + u32 dst; +} __attribute__((packed)); + +#define IPHDR_SIZE (sizeof(struct iphdr)) + +struct icmphdr { + u8 type; + u8 code; + u16 checksum; + u16 id; + u16 sequence; +} __attribute__((packed)); + +#define ICMPHDR_SIZE (sizeof(struct icmphdr)) + +#define ICMP_ECHO_REQUEST 8 +#define ICMP_ECHO_REPLY 0 +#define IPPROTO_ICMP 1 DECLARE_GLOBAL_DATA_PTR; +static const u8 null_ethaddr[6]; static bool skip_timeout; /* @@ -59,17 +130,19 @@ int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet, unsigned int len) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth = packet; - struct arp_hdr *arp; - struct ethernet_hdr *eth_recv; - struct arp_hdr *arp_recv; - - if (ntohs(eth->et_protlen) != PROT_ARP) + struct ethhdr *eth = packet; + struct arphdr *arp; + struct arpdata *arpd; + struct ethhdr *eth_recv; + struct arphdr *arp_recv; + struct arpdata *arp_recvd; + + if (ntohs(eth->protlen) != PROT_ARP) return -EAGAIN; - arp = packet + ETHER_HDR_SIZE; + arp = packet + ETHHDR_SIZE; - if (ntohs(arp->ar_op) != ARPOP_REQUEST) + if (ntohs(arp->op) != ARP_REQUEST) return -EAGAIN; /* Don't allow the buffer to overrun */ @@ -77,27 +150,29 @@ int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet, return 0; /* store this as the assumed IP of the fake host */ - priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa); + arpd = (struct arpdata *)(arp + 1); + priv->fake_host_ipaddr.s_addr = arpd->tpa; /* Formulate a fake response */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_ARP); - - arp_recv = (void *)eth_recv + ETHER_HDR_SIZE; - arp_recv->ar_hrd = htons(ARP_ETHER); - arp_recv->ar_pro = htons(PROT_IP); - arp_recv->ar_hln = ARP_HLEN; - arp_recv->ar_pln = ARP_PLEN; - arp_recv->ar_op = htons(ARPOP_REPLY); - memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr); - memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN); - net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa); - - priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + ARP_HDR_SIZE; + memcpy(eth_recv->dst, eth->src, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_ARP); + + arp_recv = (void *)eth_recv + ETHHDR_SIZE; + arp_recv->htype = htons(ARP_ETHER); + arp_recv->ptype = htons(PROT_IP); + arp_recv->hlen = ETHADDR_LEN; + arp_recv->plen = IP4_LEN; + arp_recv->op = htons(ARP_REPLY); + arp_recvd = (struct arpdata *)(arp_recv + 1); + memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN); + arp_recvd->spa = priv->fake_host_ipaddr.s_addr; + memcpy(&arp_recvd->tha, &arpd->sha, ETHADDR_LEN); + arp_recvd->tpa = arpd->spa; + + priv->recv_packet_length[priv->recv_packets] = ETHHDR_SIZE + + ARPHDR_SIZE + ARPDATA_SIZE; ++priv->recv_packets; return 0; @@ -114,22 +189,22 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, unsigned int len) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth = packet; - struct ip_udp_hdr *ip; - struct icmp_hdr *icmp; - struct ethernet_hdr *eth_recv; - struct ip_udp_hdr *ipr; - struct icmp_hdr *icmpr; - - if (ntohs(eth->et_protlen) != PROT_IP) + struct ethhdr *eth = packet; + struct iphdr *ip; + struct icmphdr *icmp; + struct ethhdr *eth_recv; + struct iphdr *ipr; + struct icmphdr *icmpr; + + if (ntohs(eth->protlen) != PROT_IP) return -EAGAIN; - ip = packet + ETHER_HDR_SIZE; + ip = packet + ETHHDR_SIZE; - if (ip->ip_p != IPPROTO_ICMP) + if (ip->prot != IPPROTO_ICMP) return -EAGAIN; - icmp = (struct icmp_hdr *)&ip->udp_src; + icmp = (struct icmphdr *)(ip + 1); if (icmp->type != ICMP_ECHO_REQUEST) return -EAGAIN; @@ -141,19 +216,19 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, /* reply to the ping */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; memcpy(eth_recv, packet, len); - ipr = (void *)eth_recv + ETHER_HDR_SIZE; - icmpr = (struct icmp_hdr *)&ipr->udp_src; - memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - ipr->ip_sum = 0; - ipr->ip_off = 0; - net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src); - net_write_ip((void *)&ipr->ip_src, priv->fake_host_ipaddr); - ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE); + ipr = (void *)eth_recv + ETHHDR_SIZE; + icmpr = (struct icmphdr *)(ipr + 1); + memcpy(eth_recv->dst, eth->src, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + ipr->sum = 0; + ipr->off = 0; + ipr->dst = ip->src; + ipr->src = priv->fake_host_ipaddr.s_addr; + ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE); icmpr->type = ICMP_ECHO_REPLY; icmpr->checksum = 0; - icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE); + icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE); priv->recv_packet_length[priv->recv_packets] = len; ++priv->recv_packets; @@ -171,8 +246,9 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, int sandbox_eth_recv_arp_req(struct udevice *dev) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth_recv; - struct arp_hdr *arp_recv; + struct ethhdr *eth_recv; + struct arphdr *arp_recv; + struct arpdata *arp_recvd; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -180,23 +256,24 @@ int sandbox_eth_recv_arp_req(struct udevice *dev) /* Formulate a fake request */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, net_bcast_ethaddr, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_ARP); - - arp_recv = (void *)eth_recv + ETHER_HDR_SIZE; - arp_recv->ar_hrd = htons(ARP_ETHER); - arp_recv->ar_pro = htons(PROT_IP); - arp_recv->ar_hln = ARP_HLEN; - arp_recv->ar_pln = ARP_PLEN; - arp_recv->ar_op = htons(ARPOP_REQUEST); - memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr); - memcpy(&arp_recv->ar_tha, net_null_ethaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_tpa, net_ip); + memcpy(eth_recv->dst, net_bcast_ethaddr, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_ARP); + + arp_recv = (void *)eth_recv + ETHHDR_SIZE; + arp_recv->htype = htons(ARP_ETHER); + arp_recv->ptype = htons(PROT_IP); + arp_recv->hlen = ETHADDR_LEN; + arp_recv->plen = IP4_LEN; + arp_recv->op = htons(ARP_REQUEST); + arp_recvd = (struct arpdata *)(arp_recv + 1); + memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN); + arp_recvd->spa = priv->fake_host_ipaddr.s_addr; + memcpy(&arp_recvd->tha, null_ethaddr, ETHADDR_LEN); + arp_recvd->tpa = net_ip.s_addr; priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + ARP_HDR_SIZE; + ETHHDR_SIZE + ARPHDR_SIZE + ARPDATA_SIZE; ++priv->recv_packets; return 0; @@ -212,9 +289,10 @@ int sandbox_eth_recv_arp_req(struct udevice *dev) int sandbox_eth_recv_ping_req(struct udevice *dev) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth_recv; - struct ip_udp_hdr *ipr; - struct icmp_hdr *icmpr; + struct eth_pdata *pdata = dev_get_plat(dev); + struct ethhdr *eth_recv; + struct iphdr *ipr; + struct icmphdr *icmpr; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -223,31 +301,31 @@ int sandbox_eth_recv_ping_req(struct udevice *dev) /* Formulate a fake ping */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, net_ethaddr, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_IP); + memcpy(eth_recv->dst, pdata->enetaddr, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_IP); - ipr = (void *)eth_recv + ETHER_HDR_SIZE; - ipr->ip_hl_v = 0x45; - ipr->ip_len = htons(IP_ICMP_HDR_SIZE); - ipr->ip_off = htons(IP_FLAGS_DFRAG); - ipr->ip_p = IPPROTO_ICMP; - ipr->ip_sum = 0; - net_write_ip(&ipr->ip_src, priv->fake_host_ipaddr); - net_write_ip(&ipr->ip_dst, net_ip); - ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE); + ipr = (void *)eth_recv + ETHHDR_SIZE; + ipr->hl_v = 0x45; + ipr->len = htons(IPHDR_SIZE + ICMPHDR_SIZE); + ipr->off = htons(IP_FLAGS_DFRAG); + ipr->prot = IPPROTO_ICMP; + ipr->sum = 0; + ipr->src = priv->fake_host_ipaddr.s_addr; + ipr->dst = net_ip.s_addr; + ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE); - icmpr = (struct icmp_hdr *)&ipr->udp_src; + icmpr = (struct icmphdr *)(ipr + 1); icmpr->type = ICMP_ECHO_REQUEST; icmpr->code = 0; icmpr->checksum = 0; - icmpr->un.echo.id = 0; - icmpr->un.echo.sequence = htons(1); - icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE); + icmpr->id = 0; + icmpr->sequence = htons(1); + icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE); priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + IP_ICMP_HDR_SIZE; + ETHHDR_SIZE + IPHDR_SIZE + ICMPHDR_SIZE; ++priv->recv_packets; return 0; @@ -398,7 +476,7 @@ static int sb_eth_write_hwaddr(struct udevice *dev) debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name, pdata->enetaddr); - memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ARP_HLEN); + memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ETHADDR_LEN); return 0; } diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 4f876d39875..409049137cc 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -67,6 +67,7 @@ config PCI_CONFIG_HOST_BRIDGE config PCI_MAP_SYSTEM_MEMORY bool "Map local system memory from a virtual base address" depends on MIPS + default y if !ARCH_MAP_SYSMEM help Say Y if base address of system memory is being used as a virtual address instead of a physical address (e.g. on MIPS). The PCI core will then remap @@ -75,6 +76,15 @@ config PCI_MAP_SYSTEM_MEMORY This should only be required on MIPS where CFG_SYS_SDRAM_BASE is still being used as virtual address. +config PCI_BRIDGE_MEM_ALIGNMENT + hex "Alignment boundary of PCI memory resource allocation" + default 0x10000 if TARGET_BOSTON + default 0x100000 + help + Specify a boundary for alignment of PCI memory resource allocation, + this is normally 0x100000 (1MB) but can be reduced to accommodate + hardware with tight bridge range if hardware allows. + config PCI_SRIOV bool "Enable Single Root I/O Virtualization support for PCI" help diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index e68e31a8227..4a1c782be36 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -373,8 +373,8 @@ void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus) dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, 0xff); if (pci_mem) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_mem, 0x100000); + /* Round memory allocator */ + pciauto_region_align(pci_mem, CONFIG_PCI_BRIDGE_MEM_ALIGNMENT); /* * Set up memory and I/O filter limits, assume 32-bit @@ -388,8 +388,8 @@ void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus) } if (pci_prefetch) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_prefetch, 0x100000); + /* Round memory allocator */ + pciauto_region_align(pci_prefetch, CONFIG_PCI_BRIDGE_MEM_ALIGNMENT); /* * Set up memory and I/O filter limits, assume 32-bit @@ -466,8 +466,8 @@ void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus) dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus - dev_seq(ctlr)); if (pci_mem) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_mem, 0x100000); + /* Round memory allocator */ + pciauto_region_align(pci_mem, CONFIG_PCI_BRIDGE_MEM_ALIGNMENT); dm_pci_write_config16(dev, PCI_MEMORY_LIMIT, ((pci_mem->bus_lower - 1) >> 16) & @@ -481,8 +481,8 @@ void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus) &prefechable_64); prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_prefetch, 0x100000); + /* Round memory allocator */ + pciauto_region_align(pci_prefetch, CONFIG_PCI_BRIDGE_MEM_ALIGNMENT); dm_pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, (((pci_prefetch->bus_lower - 1) >> 16) & diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c index a674ab04bee..63058e8e7c5 100644 --- a/drivers/pci/pcie_xilinx.c +++ b/drivers/pci/pcie_xilinx.c @@ -18,14 +18,19 @@ */ struct xilinx_pcie { void *cfg_base; + pci_size_t size; + int first_busno; }; /* Register definitions */ -#define XILINX_PCIE_REG_PSCR 0x144 -#define XILINX_PCIE_REG_PSCR_LNKUP BIT(11) -#define XILINX_PCIE_REG_RPSC 0x148 -#define XILINX_PCIE_REG_RPSC_BEN BIT(0) - +#define XILINX_PCIE_REG_BRIDGE_INFO 0x130 +#define XILINX_PCIE_REG_BRIDGE_INFO_ECAMSZ_SHIFT 16 +#define XILINX_PCIE_REG_BRIDGE_INFO_ECAMSZ_MASK (0x7 << 16) +#define XILINX_PCIE_REG_INT_MASK 0x13c +#define XILINX_PCIE_REG_PSCR 0x144 +#define XILINX_PCIE_REG_PSCR_LNKUP BIT(11) +#define XILINX_PCIE_REG_RPSC 0x148 +#define XILINX_PCIE_REG_RPSC_BEN BIT(0) /** * pcie_xilinx_link_up() - Check whether the PCIe link is up * @pcie: Pointer to the PCI controller state @@ -61,14 +66,18 @@ static int pcie_xilinx_config_address(const struct udevice *udev, pci_dev_t bdf, uint offset, void **paddress) { struct xilinx_pcie *pcie = dev_get_priv(udev); - unsigned int bus = PCI_BUS(bdf); + unsigned int bus = PCI_BUS(bdf) - pcie->first_busno; unsigned int dev = PCI_DEV(bdf); unsigned int func = PCI_FUNC(bdf); + int num_buses = DIV_ROUND_UP(pcie->size, 1 << 16); void *addr; if ((bus > 0) && !pcie_xilinx_link_up(pcie)) return -ENODEV; + if (bus > num_buses) + return -ENODEV; + /* * Busses 0 (host-PCIe bridge) & 1 (its immediate child) are * limited to a single device each. @@ -142,20 +151,37 @@ static int pcie_xilinx_of_to_plat(struct udevice *dev) struct xilinx_pcie *pcie = dev_get_priv(dev); fdt_addr_t addr; fdt_size_t size; - u32 rpsc; addr = dev_read_addr_size(dev, &size); if (addr == FDT_ADDR_T_NONE) return -EINVAL; - pcie->cfg_base = devm_ioremap(dev, addr, size); - if (IS_ERR(pcie->cfg_base)) - return PTR_ERR(pcie->cfg_base); + pcie->cfg_base = map_physmem(addr, size, MAP_NOCACHE); + if (!pcie->cfg_base) + return -ENOMEM; + pcie->size = size; + return 0; +} - /* Enable the Bridge enable bit */ - rpsc = __raw_readl(pcie->cfg_base + XILINX_PCIE_REG_RPSC); +static int pci_xilinx_probe(struct udevice *dev) +{ + struct xilinx_pcie *pcie = dev_get_priv(dev); + u32 rpsc; + int num_buses = DIV_ROUND_UP(pcie->size, 1 << 16); + + pcie->first_busno = dev_seq(dev); + + /* Disable all interrupts */ + writel(0, pcie->cfg_base + XILINX_PCIE_REG_INT_MASK); + + /* Enable the bridge */ + rpsc = readl(pcie->cfg_base + XILINX_PCIE_REG_RPSC); rpsc |= XILINX_PCIE_REG_RPSC_BEN; - __raw_writel(rpsc, pcie->cfg_base + XILINX_PCIE_REG_RPSC); + writel(rpsc, pcie->cfg_base + XILINX_PCIE_REG_RPSC); + + /* Enable access to all possible subordinate buses */ + writel((0 << 0) | (1 << 8) | (num_buses << 16), + pcie->cfg_base + PCI_PRIMARY_BUS); return 0; } @@ -176,5 +202,6 @@ U_BOOT_DRIVER(pcie_xilinx) = { .of_match = pcie_xilinx_ids, .ops = &pcie_xilinx_ops, .of_to_plat = pcie_xilinx_of_to_plat, + .probe = pci_xilinx_probe, .priv_auto = sizeof(struct xilinx_pcie), }; diff --git a/dts/upstream/src/mips/Makefile b/dts/upstream/src/mips/Makefile new file mode 100644 index 00000000000..9a8f6aa3584 --- /dev/null +++ b/dts/upstream/src/mips/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0+ + +include $(srctree)/scripts/Makefile.dts + +targets += $(dtb-y) + +# Add any required device tree compiler flags here +DTC_FLAGS += -a 0x8 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := */*.dtb */*.dtbo diff --git a/include/ahci.h b/include/ahci.h index d4f0f3ce0e7..eb05cc687f6 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -137,8 +137,8 @@ struct ahci_ioports { void __iomem *port_mmio; struct ahci_cmd_hdr *cmd_slot; struct ahci_sg *cmd_tbl_sg; - ulong cmd_tbl; - u32 rx_fis; + void *cmd_tbl; + void *rx_fis; }; /** diff --git a/include/net-common.h b/include/net-common.h index 30860f5975a..e536968a92b 100644 --- a/include/net-common.h +++ b/include/net-common.h @@ -471,6 +471,9 @@ static inline struct in_addr env_get_ip(char *var) int net_init(void); +/* Called when a network operation fails to know if it should be re-tried */ +int net_start_again(void); + /* NET compatibility */ enum proto_t; int net_loop(enum proto_t protocol); @@ -490,6 +493,18 @@ int net_loop(enum proto_t protocol); */ int dhcp_run(ulong addr, const char *fname, bool autoload); + +/** + * do_ping - Run the ping command + * + * @cmdtp: Unused + * @flag: Command flags (CMD_FLAG_...) + * @argc: Number of arguments + * @argv: List of arguments + * Return: result (see enum command_ret_t) + */ +int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); + /** * do_tftpb - Run the tftpboot command * diff --git a/include/net-legacy.h b/include/net-legacy.h index bc0f0cde9fe..51780999a88 100644 --- a/include/net-legacy.h +++ b/include/net-legacy.h @@ -347,9 +347,6 @@ extern int net_ntp_time_offset; /* offset time from UTC */ int net_loop(enum proto_t); -/* Load failed. Start again. */ -int net_start_again(void); - /* Get size of the ethernet header when we send */ int net_eth_hdr_size(void); diff --git a/include/net-lwip.h b/include/net-lwip.h index 64e5c720560..b762956e8fd 100644 --- a/include/net-lwip.h +++ b/include/net-lwip.h @@ -10,7 +10,14 @@ enum proto_t { TFTPGET }; -void net_lwip_set_current(void); +static inline int eth_is_on_demand_init(void) +{ + return 1; +} + +int eth_init_state_only(void); /* Set active state */ + +int net_lwip_eth_start(void); struct netif *net_lwip_new_netif(struct udevice *udev); struct netif *net_lwip_new_netif_noip(struct udevice *udev); void net_lwip_remove_netif(struct netif *netif); @@ -27,7 +34,6 @@ bool wget_validate_uri(char *uri); int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); -int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]); #endif /* __NET_LWIP_H__ */ diff --git a/include/net6.h b/include/net6.h index 1ed989e584a..2ceeaba0639 100644 --- a/include/net6.h +++ b/include/net6.h @@ -90,6 +90,16 @@ struct udp_hdr { 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x02 } } } +/* + * With IPv6, the broadcast MAC address is not used. Instead, it should use + * the multicast address (see RFC RFC2464 section 7) + */ +#define IPV6_ALL_NODE_ETH_ADDR(_ip6_addr) {0x33, \ + 0x33, \ + _ip6_addr.in6_u.u6_addr8[12], \ + _ip6_addr.in6_u.u6_addr8[13], \ + _ip6_addr.in6_u.u6_addr8[14], \ + _ip6_addr.in6_u.u6_addr8[15]} #define IPV6_LINK_LOCAL_PREFIX 0xfe80 #define IPV6_LINK_LOCAL_MASK 0xffb0 /* The first 10-bit of address mask. */ diff --git a/net/Makefile b/net/Makefile index 41edbacabc9..d63f62b7c8a 100644 --- a/net/Makefile +++ b/net/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_NET) += arp.o obj-$(CONFIG_CMD_BOOTP) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o obj-$(CONFIG_CMD_DNS) += dns.o -obj-$(CONFIG_DM_DSA) += dsa-uclass.o obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o obj-$(CONFIG_IPV6) += ndisc.o obj-$(CONFIG_$(PHASE_)DM_ETH) += net.o @@ -39,6 +38,7 @@ CFLAGS_eth_common.o += -Wno-format-extra-args endif ifeq ($(filter y,$(CONFIG_NET) $(CONFIG_NET_LWIP)),y) +obj-$(CONFIG_DM_DSA) += dsa-uclass.o obj-$(CONFIG_$(PHASE_)DM_ETH) += eth-uclass.o obj-$(CONFIG_$(PHASE_)BOOTDEV_ETH) += eth_bootdev.o obj-$(CONFIG_DM_MDIO) += mdio-uclass.o diff --git a/net/dhcpv6.c b/net/dhcpv6.c index 54619ee6983..0c2de75ba1d 100644 --- a/net/dhcpv6.c +++ b/net/dhcpv6.c @@ -29,6 +29,10 @@ int updated_sol_max_rt_ms = SOL_MAX_RT_MS; /* state machine parameters/variables */ struct dhcp6_sm_params sm_params; +/* DHCPv6 all server IP6 address */ +const struct in6_addr dhcp_mcast_ip6 = DHCP6_MULTICAST_ADDR; +/* IPv6 multicast ethernet address */ +const u8 net_dhcp6_mcast_ethaddr[6] = IPV6_ALL_NODE_ETH_ADDR(dhcp_mcast_ip6); static void dhcp6_state_machine(bool timeout, uchar *rx_pkt, unsigned int len); @@ -171,7 +175,6 @@ static int dhcp6_add_option(int option_id, uchar *pkt) */ static void dhcp6_send_solicit_packet(void) { - struct in6_addr dhcp_bcast_ip6; int len = 0; uchar *pkt; uchar *dhcp_pkt_start_ptr; @@ -200,9 +203,8 @@ static void dhcp6_send_solicit_packet(void) len = pkt - dhcp_pkt_start_ptr; /* send UDP packet to DHCP6 multicast address */ - string_to_ip6(DHCP6_MULTICAST_ADDR, sizeof(DHCP6_MULTICAST_ADDR), &dhcp_bcast_ip6); net_set_udp_handler(dhcp6_handler); - net_send_udp_packet6((uchar *)net_bcast_ethaddr, &dhcp_bcast_ip6, + net_send_udp_packet6((uchar *)net_dhcp6_mcast_ethaddr, (struct in6_addr *)&dhcp_mcast_ip6, PORT_DHCP6_S, PORT_DHCP6_C, len); } @@ -218,7 +220,6 @@ static void dhcp6_send_solicit_packet(void) */ static void dhcp6_send_request_packet(void) { - struct in6_addr dhcp_bcast_ip6; int len = 0; uchar *pkt; uchar *dhcp_pkt_start_ptr; @@ -252,9 +253,8 @@ static void dhcp6_send_request_packet(void) len = pkt - dhcp_pkt_start_ptr; /* send UDP packet to DHCP6 multicast address */ - string_to_ip6(DHCP6_MULTICAST_ADDR, strlen(DHCP6_MULTICAST_ADDR), &dhcp_bcast_ip6); net_set_udp_handler(dhcp6_handler); - net_send_udp_packet6((uchar *)net_bcast_ethaddr, &dhcp_bcast_ip6, + net_send_udp_packet6((uchar *)net_dhcp6_mcast_ethaddr, (struct in6_addr *)&dhcp_mcast_ip6, PORT_DHCP6_S, PORT_DHCP6_C, len); } @@ -473,8 +473,7 @@ static int dhcp6_check_advertise_packet(uchar *rx_pkt, unsigned int len) * server UID, save the new server UID and preference */ if (!sm_params.server_uid.uid_ptr || - (sm_params.server_uid.uid_ptr && - sm_params.server_uid.preference < sm_params.rx_status.preference)) { + sm_params.server_uid.preference < sm_params.rx_status.preference) { rx_uid_size = sm_params.rx_status.server_uid_size; if (sm_params.server_uid.uid_ptr) free(sm_params.server_uid.uid_ptr); diff --git a/net/dhcpv6.h b/net/dhcpv6.h index 65c8e4c71d3..d41a3c30615 100644 --- a/net/dhcpv6.h +++ b/net/dhcpv6.h @@ -40,7 +40,13 @@ /* vendor-class-data to send in vendor clas option */ #define DHCP6_VCI_STRING "U-Boot" -#define DHCP6_MULTICAST_ADDR "ff02::1:2" /* DHCP multicast address */ +/* + * All-DHCPv6 server multicast address + */ +#define DHCP6_MULTICAST_ADDR { { { 0xFF, 0x02, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x01, 0x00, 0x02 } } } /* DHCP6 States supported */ enum dhcp6_state { diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c index 3b7e4700c6e..92bd7067a7f 100644 --- a/net/lwip/dhcp.c +++ b/net/lwip/dhcp.c @@ -115,7 +115,8 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int ret; struct udevice *dev; - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; dev = eth_get_dev(); if (!dev) { diff --git a/net/lwip/dns.c b/net/lwip/dns.c index 149bdb784dc..19172ac959a 100644 --- a/net/lwip/dns.c +++ b/net/lwip/dns.c @@ -121,7 +121,8 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc == 3) var = argv[2]; - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; return dns_loop(eth_get_dev(), name, var); } diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index 6b7b696dbf0..f05c4cd3f64 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -14,6 +14,7 @@ #include <lwip/init.h> #include <lwip/prot/etharp.h> #include <net.h> +#include <timer.h> /* xx:xx:xx:xx:xx:xx\0 */ #define MAC_ADDR_STRLEN 18 @@ -21,6 +22,8 @@ #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER) void (*push_packet)(void *, int len) = 0; #endif +static int net_try_count; +static int net_restarted; int net_restart_wrap; static uchar net_pkt_buf[(PKTBUFSRX) * PKTSIZE_ALIGN + PKTALIGN]; uchar *net_rx_packets[PKTBUFSRX]; @@ -134,18 +137,27 @@ static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip, return 0; } -/* Initialize the lwIP stack and the ethernet devices and set current device */ -void net_lwip_set_current(void) +/* + * Initialize the network stack if needed and start the current device if valid + */ +int net_lwip_eth_start(void) { - static bool init_done; - - if (!init_done) { - eth_init_rings(); - eth_init(); - lwip_init(); - init_done = true; + int ret; + + net_init(); + if (eth_is_on_demand_init()) { + eth_halt(); + eth_set_current(); + ret = eth_init(); + if (ret < 0) { + eth_halt(); + return ret; + } + } else { + eth_init_state_only(); } - eth_set_current(); + + return 0; } static struct netif *new_netif(struct udevice *udev, bool with_ip) @@ -224,11 +236,20 @@ void net_lwip_remove_netif(struct netif *netif) free(netif); } +/* + * Initialize the network buffers, an ethernet device, and the lwIP stack + * (once). + */ int net_init(void) { - eth_set_current(); + static bool init_done; - net_lwip_new_netif(eth_get_dev()); + if (!init_done) { + eth_init_rings(); + eth_init(); + lwip_init(); + init_done = true; + } return 0; } @@ -319,5 +340,48 @@ int net_loop(enum proto_t protocol) u32_t sys_now(void) { +#if CONFIG_IS_ENABLED(SANDBOX_TIMER) + return timer_early_get_count(); +#else return get_timer(0); +#endif +} + +int net_start_again(void) +{ + char *nretry; + int retry_forever = 0; + unsigned long retrycnt = 0; + + nretry = env_get("netretry"); + if (nretry) { + if (!strcmp(nretry, "yes")) + retry_forever = 1; + else if (!strcmp(nretry, "no")) + retrycnt = 0; + else if (!strcmp(nretry, "once")) + retrycnt = 1; + else + retrycnt = simple_strtoul(nretry, NULL, 0); + } else { + retrycnt = 0; + retry_forever = 0; + } + + if ((!retry_forever) && (net_try_count > retrycnt)) { + eth_halt(); + /* + * We don't provide a way for the protocol to return an error, + * but this is almost always the reason. + */ + return -ETIMEDOUT; + } + + net_try_count++; + + eth_halt(); +#if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER) + eth_try_another(!net_restarted); +#endif + return eth_init(); } diff --git a/net/lwip/ping.c b/net/lwip/ping.c index c586a96806d..d8042ceecf9 100644 --- a/net/lwip/ping.c +++ b/net/lwip/ping.c @@ -168,10 +168,13 @@ int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (!ipaddr_aton(argv[1], &addr)) return CMD_RET_USAGE; - net_lwip_set_current(); - - if (ping_loop(eth_get_dev(), &addr) < 0) - return CMD_RET_FAILURE; +restart: + if (net_lwip_eth_start() < 0 || ping_loop(eth_get_dev(), &addr) < 0) { + if (net_start_again() == 0) + goto restart; + else + return CMD_RET_FAILURE; + } return CMD_RET_SUCCESS; } diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index 123d66b5dba..4f9b2049187 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -280,7 +280,10 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) goto out; } - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) { + ret = CMD_RET_FAILURE; + goto out; + } if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0) ret = CMD_RET_FAILURE; diff --git a/net/lwip/wget.c b/net/lwip/wget.c index ec098148835..a3b82908877 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -471,7 +471,11 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) int wget_do_request(ulong dst_addr, char *uri) { - net_lwip_set_current(); + int ret; + + ret = net_lwip_eth_start(); + if (ret < 0) + return ret; if (!wget_info) wget_info = &default_wget_info; diff --git a/test/dm/Makefile b/test/dm/Makefile index 3afcc26ca57..917dafe7d22 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -46,9 +46,7 @@ obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o obj-$(CONFIG_DM_DSA) += dsa.o obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o -ifdef CONFIG_NET obj-$(CONFIG_DM_ETH) += eth.o -endif obj-$(CONFIG_EXTCON) += extcon.o ifneq ($(CONFIG_EFI_PARTITION),) obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o diff --git a/test/dm/dsa.c b/test/dm/dsa.c index c6b4e12a758..9a31ae39d95 100644 --- a/test/dm/dsa.c +++ b/test/dm/dsa.c @@ -63,15 +63,15 @@ DM_TEST(dm_test_dsa_probe, UTF_SCAN_FDT); */ static int dm_test_dsa(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.2.3.5"); + char *argv[] = { "ping", "1.1.2.2" }; env_set("ethact", "eth2"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", "lan0"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", "lan1"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", ""); diff --git a/test/dm/eth.c b/test/dm/eth.c index 467495863e1..1087ae9572d 100644 --- a/test/dm/eth.c +++ b/test/dm/eth.c @@ -171,18 +171,18 @@ DM_TEST(dm_test_ip6_make_lladdr, UTF_SCAN_FDT); static int dm_test_eth(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; env_set("ethact", "eth@10002000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth@10003000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); return 0; @@ -191,22 +191,23 @@ DM_TEST(dm_test_eth, UTF_SCAN_FDT); static int dm_test_eth_alias(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; + env_set("ethact", "eth0"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth6"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); /* Expected to fail since eth1 is not defined in the device tree */ env_set("ethact", "eth1"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); return 0; @@ -215,18 +216,18 @@ DM_TEST(dm_test_eth_alias, UTF_SCAN_FDT); static int dm_test_eth_prime(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; /* Expected to be "eth@10003000" because of ethprime variable */ env_set("ethact", NULL); env_set("ethprime", "eth5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); /* Expected to be "eth@10002000" because it is first */ env_set("ethact", NULL); env_set("ethprime", NULL); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); return 0; @@ -249,6 +250,7 @@ DM_TEST(dm_test_eth_prime, UTF_SCAN_FDT); */ static int dm_test_eth_act(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; struct udevice *dev[DM_TEST_ETH_NUM]; const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000", "sbe5", "eth@10004000"}; @@ -258,7 +260,6 @@ static int dm_test_eth_act(struct unit_test_state *uts) int i; memset(ethaddr, '\0', sizeof(ethaddr)); - net_ping_ip = string_to_ip("1.1.2.2"); /* Prepare the test scenario */ for (i = 0; i < DM_TEST_ETH_NUM; i++) { @@ -281,7 +282,7 @@ static int dm_test_eth_act(struct unit_test_state *uts) env_set("ethact", ethname[0]); /* Segment fault might happen if something is wrong */ - ut_asserteq(-ENODEV, net_loop(PING)); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); for (i = 0; i < DM_TEST_ETH_NUM; i++) { /* Restore the env */ @@ -334,15 +335,17 @@ DM_TEST(dm_test_ethaddr, UTF_SCAN_FDT); /* The asserts include a return on fail; cleanup in the caller */ static int _dm_test_eth_rotate1(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* Make sure that the default is to rotate to the next interface */ env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); /* If ethrotate is no, then we should fail on a bad MAC */ env_set("ethact", "eth@10004000"); env_set("ethrotate", "no"); - ut_asserteq(-EINVAL, net_loop(PING)); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); return 0; @@ -350,14 +353,16 @@ static int _dm_test_eth_rotate1(struct unit_test_state *uts) static int _dm_test_eth_rotate2(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* Make sure we can skip invalid devices */ env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); /* Make sure we can handle device name which is not eth# */ env_set("ethact", "sbe5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("sbe5", env_get("ethact")); return 0; @@ -368,9 +373,6 @@ static int dm_test_eth_rotate(struct unit_test_state *uts) char ethaddr[18]; int retval; - /* Set target IP to mock ping */ - net_ping_ip = string_to_ip("1.1.2.2"); - /* Invalidate eth1's MAC address */ memset(ethaddr, '\0', sizeof(ethaddr)); strncpy(ethaddr, env_get("eth6addr"), 17); @@ -396,6 +398,7 @@ static int dm_test_eth_rotate(struct unit_test_state *uts) /* Restore the env */ env_set("ethaddr", ethaddr); } + /* Restore the env */ env_set(".flags", NULL); @@ -406,26 +409,28 @@ DM_TEST(dm_test_eth_rotate, UTF_SCAN_FDT); /* The asserts include a return on fail; cleanup in the caller */ static int _dm_test_net_retry(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* - * eth1 is disabled and netretry is yes, so the ping should succeed and - * the active device should be eth0 + * eth0 is disabled and netretry is yes, so the ping should succeed and + * the active device should be eth1 */ - sandbox_eth_disable_response(1, true); - env_set("ethact", "lan1"); + sandbox_eth_disable_response(0, true); + env_set("ethact", "eth@10002000"); env_set("netretry", "yes"); sandbox_eth_skip_timeout(); - ut_assertok(net_loop(PING)); - ut_asserteq_str("eth@10002000", env_get("ethact")); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); + ut_asserteq_str("eth@10003000", env_get("ethact")); /* - * eth1 is disabled and netretry is no, so the ping should fail and the - * active device should be eth1 + * eth0 is disabled and netretry is no, so the ping should fail and the + * active device should be eth0 */ - env_set("ethact", "lan1"); + env_set("ethact", "eth@10002000"); env_set("netretry", "no"); sandbox_eth_skip_timeout(); - ut_asserteq(-ENONET, net_loop(PING)); - ut_asserteq_str("lan1", env_get("ethact")); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); + ut_asserteq_str("eth@10002000", env_get("ethact")); return 0; } @@ -434,8 +439,6 @@ static int dm_test_net_retry(struct unit_test_state *uts) { int retval; - net_ping_ip = string_to_ip("1.1.2.2"); - retval = _dm_test_net_retry(uts); /* Restore the env */ @@ -446,6 +449,7 @@ static int dm_test_net_retry(struct unit_test_state *uts) } DM_TEST(dm_test_net_retry, UTF_SCAN_FDT); +#if CONFIG_IS_ENABLED(NET) static int sb_check_arp_reply(struct udevice *dev, void *packet, unsigned int len) { @@ -511,7 +515,9 @@ static int sb_with_async_arp_handler(struct udevice *dev, void *packet, return sb_check_arp_reply(dev, packet, len); } +#endif +#if CONFIG_IS_ENABLED(NET) static int dm_test_eth_async_arp_reply(struct unit_test_state *uts) { net_ping_ip = string_to_ip("1.1.2.2"); @@ -529,7 +535,9 @@ static int dm_test_eth_async_arp_reply(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_eth_async_arp_reply, UTF_SCAN_FDT); +#endif +#if CONFIG_IS_ENABLED(NET) static int sb_check_ping_reply(struct udevice *dev, void *packet, unsigned int len) { @@ -613,6 +621,7 @@ static int dm_test_eth_async_ping_reply(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_eth_async_ping_reply, UTF_SCAN_FDT); +#endif #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY) |