From dd83db25feb4718fab1e06d7737490fbe422b6fe Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 11 Mar 2020 16:01:27 +0100 Subject: [PATCH 01/76] Add kernel 5.4 support --- build.sh | 26 +- root/target/linux/generic/config-5.4 | 6464 +++++ .../generic/hack-5.4/690-mptcp_trunk.patch | 23066 ++++++++++++++++ .../generic/hack-5.4/691-mptcp_ecf.patch | 434 + .../generic/hack-5.4/692-tcp_nanqinlang.patch | 1037 + .../generic/hack-5.4/998-ndpi-netfilter.patch | 116 + .../hack-5.4/999-stop-promiscuous-info.patch | 14 + 7 files changed, 31144 insertions(+), 13 deletions(-) create mode 100644 root/target/linux/generic/config-5.4 create mode 100644 root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch create mode 100644 root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch create mode 100644 root/target/linux/generic/hack-5.4/692-tcp_nanqinlang.patch create mode 100644 root/target/linux/generic/hack-5.4/998-ndpi-netfilter.patch create mode 100644 root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch diff --git a/build.sh b/build.sh index 7fe23ff8..588f6c95 100755 --- a/build.sh +++ b/build.sh @@ -58,9 +58,9 @@ else fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" -_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "a017773a92d624142a78452bc0c00e6bc6523967" -_get_repo feeds/packages https://github.com/openwrt/packages "e0c0c3c3f030c8582c9493ff894ee0528198f2ce" -_get_repo feeds/luci https://github.com/openwrt/luci "0c7f3331aff33567e01e0d9c0c63b9a1a16fbe14" +_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "04a21c26a005ac314b79e6905f51b4789d6d79bd" +_get_repo feeds/packages https://github.com/openwrt/packages "e48af750e169e201feb9618828ed9f77b647d234" +_get_repo feeds/luci https://github.com/openwrt/luci "3fb8e3d6236c2ea418c5a5fd90564d9eb44732f3" if [ -z "$OMR_FEED" ]; then OMR_FEED=feeds/openmptcprouter @@ -183,18 +183,18 @@ echo "Done" #fi #echo "Done" -if [ "$OMR_KERNEL" = "4.19" ]; then - echo "Set to kernel 4.19 for rpi arch" - find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.14%KERNEL_PATCHVER:=4.19%g' {} \; +if [ "$OMR_KERNEL" = "5.4" ]; then + echo "Set to kernel 5.4 for rpi arch" + find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.19%KERNEL_PATCHVER:=5.4%g' {} \; echo "Done" - echo "Set to kernel 4.19 for x86 arch" - find target/linux/x86 -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.14%KERNEL_PATCHVER:=4.19%g' {} \; + echo "Set to kernel 5.4 for x86 arch" + find target/linux/x86 -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.19%KERNEL_PATCHVER:=5.4%g' {} \; echo "Done" - echo "Set to kernel 4.19 for mvebu arch (WRT)" - find target/linux/mvebu -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.14%KERNEL_PATCHVER:=4.19%g' {} \; - echo "Done" - echo "Set to kernel 4.19 for mediatek arch (BPI-R2)" - find target/linux/mediatek -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.14%KERNEL_PATCHVER:=4.19%g' {} \; +# echo "Set to kernel 5.4 for mvebu arch (WRT)" +# find target/linux/mvebu -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.19%KERNEL_PATCHVER:=5.4%g' {} \; +# echo "Done" + echo "Set to kernel 5.4 for mediatek arch (BPI-R2)" + find target/linux/mediatek -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.19%KERNEL_PATCHVER:=5.4%g' {} \; echo "Done" fi diff --git a/root/target/linux/generic/config-5.4 b/root/target/linux/generic/config-5.4 new file mode 100644 index 00000000..91d8268c --- /dev/null +++ b/root/target/linux/generic/config-5.4 @@ -0,0 +1,6464 @@ +# CONFIG_104_QUAD_8 is not set +CONFIG_32BIT=y +CONFIG_64BIT_TIME=y +# CONFIG_6LOWPAN is not set +# CONFIG_6LOWPAN_DEBUGFS is not set +# CONFIG_6PACK is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_9P_FS is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_AB8500_CORE is not set +# CONFIG_ABP060MG is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_ACENIC is not set +# CONFIG_ACERHDF is not set +# CONFIG_ACER_WIRELESS is not set +# CONFIG_ACORN_PARTITION is not set +# CONFIG_ACPI_ALS is not set +# CONFIG_ACPI_APEI is not set +# CONFIG_ACPI_BUTTON is not set +# CONFIG_ACPI_CONFIGFS is not set +# CONFIG_ACPI_CUSTOM_METHOD is not set +# CONFIG_ACPI_EXTLOG is not set +# CONFIG_ACPI_HED is not set +# CONFIG_ACPI_NFIT is not set +# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +# CONFIG_ACPI_TABLE_UPGRADE is not set +# CONFIG_ACPI_VIDEO is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set +# CONFIG_AD2S90 is not set +# CONFIG_AD5064 is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_AD5272 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5449 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5592R is not set +# CONFIG_AD5593R is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5686 is not set +# CONFIG_AD5686_SPI is not set +# CONFIG_AD5696_I2C is not set +# CONFIG_AD5755 is not set +# CONFIG_AD5758 is not set +# CONFIG_AD5761 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD5933 is not set +# CONFIG_AD7124 is not set +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7192 is not set +# CONFIG_AD7266 is not set +# CONFIG_AD7280 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7303 is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7606 is not set +# CONFIG_AD7606_IFACE_PARALLEL is not set +# CONFIG_AD7606_IFACE_SPI is not set +# CONFIG_AD7746 is not set +# CONFIG_AD7766 is not set +# CONFIG_AD7768_1 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7791 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7923 is not set +# CONFIG_AD7949 is not set +# CONFIG_AD799X is not set +# CONFIG_AD8366 is not set +# CONFIG_AD8801 is not set +# CONFIG_AD9523 is not set +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set +# CONFIG_ADF4350 is not set +# CONFIG_ADF4371 is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADIN_PHY is not set +# CONFIG_ADIS16060 is not set +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16136 is not set +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADIS16400 is not set +# CONFIG_ADIS16460 is not set +# CONFIG_ADIS16480 is not set +# CONFIG_ADJD_S311 is not set +# CONFIG_ADM6996_PHY is not set +# CONFIG_ADM8211 is not set +# CONFIG_ADT7316 is not set +CONFIG_ADVISE_SYSCALLS=y +# CONFIG_ADXL345_I2C is not set +# CONFIG_ADXL345_SPI is not set +# CONFIG_ADXL372_I2C is not set +# CONFIG_ADXL372_SPI is not set +# CONFIG_ADXRS450 is not set +CONFIG_AEABI=y +# CONFIG_AFE4403 is not set +# CONFIG_AFE4404 is not set +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_AF_KCM is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_RXRPC_INJECT_LOSS is not set +# CONFIG_AF_RXRPC_IPV6 is not set +# CONFIG_AGP is not set +# CONFIG_AHCI_CEVA is not set +# CONFIG_AHCI_IMX is not set +# CONFIG_AHCI_MVEBU is not set +# CONFIG_AHCI_QORIQ is not set +CONFIG_AIO=y +# CONFIG_AIRO is not set +# CONFIG_AIRO_CS is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_AK09911 is not set +# CONFIG_AK8974 is not set +# CONFIG_AK8975 is not set +# CONFIG_AL3320A is not set +# CONFIG_ALIM7101_WDT is not set +CONFIG_ALLOW_DEV_COREDUMP=y +# CONFIG_ALTERA_MBOX is not set +# CONFIG_ALTERA_MSGDMA is not set +# CONFIG_ALTERA_STAPL is not set +# CONFIG_ALTERA_TSE is not set +# CONFIG_ALX is not set +# CONFIG_AL_FIC is not set +# CONFIG_AM2315 is not set +# CONFIG_AM335X_PHY_USB is not set +# CONFIG_AMBA_PL08X is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_AMD_MEM_ENCRYPT is not set +# CONFIG_AMD_PHY is not set +# CONFIG_AMD_XGBE is not set +# CONFIG_AMD_XGBE_HAVE_ECC is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_AMILO_RFKILL is not set +# CONFIG_ANDROID is not set +CONFIG_ANON_INODES=y +# CONFIG_APDS9300 is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_APDS9960 is not set +# CONFIG_APM8018X is not set +# CONFIG_APM_EMULATION is not set +# CONFIG_ENERGY_MODEL is not set +# CONFIG_APPLE_GMUX is not set +# CONFIG_APPLE_PROPERTIES is not set +# CONFIG_APPLICOM is not set +# CONFIG_AQTION is not set +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_AR5523 is not set +# CONFIG_AR7 is not set +# CONFIG_AR8216_PHY is not set +# CONFIG_AR8216_PHY_LEDS is not set +# CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_ARTPEC is not set +# CONFIG_ARCH_ASPEED is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCM is not set +# CONFIG_ARCH_BCM2835 is not set +# CONFIG_ARCH_BCM_21664 is not set +# CONFIG_ARCH_BCM_23550 is not set +# CONFIG_ARCH_BCM_281XX is not set +# CONFIG_ARCH_BCM_5301X is not set +# CONFIG_ARCH_BCM_53573 is not set +# CONFIG_ARCH_BCM_63XX is not set +# CONFIG_ARCH_BCM_CYGNUS is not set +# CONFIG_ARCH_BCM_IPROC is not set +# CONFIG_ARCH_BCM_NSP is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BRCMSTB is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_DIGICOLOR is not set +# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_EXYNOS is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_GEMINI is not set +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_ARCH_HI3xxx is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_K3 is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_LAYERSCAPE is not set +# CONFIG_ARCH_LG1K is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MILBEAUT is not set +CONFIG_ARCH_MMAP_RND_BITS=8 +CONFIG_ARCH_MMAP_RND_BITS_MAX=16 +CONFIG_ARCH_MMAP_RND_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_MULTIPLATFORM is not set +# CONFIG_ARCH_MULTI_V6 is not set +# CONFIG_ARCH_MULTI_V7 is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_NPCM is not set +# CONFIG_ARCH_NSPIRE is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_OMAP1 is not set +# CONFIG_ARCH_OMAP2 is not set +# CONFIG_ARCH_OMAP2PLUS is not set +# CONFIG_ARCH_OMAP3 is not set +# CONFIG_ARCH_OMAP4 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_OXNAS is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +# CONFIG_ARCH_PICOXCELL is not set +# CONFIG_ARCH_PRIMA2 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_RDA is not set +# CONFIG_ARCH_REALTEK is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SEATTLE is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_SHMOBILE_MULTI is not set +# CONFIG_ARCH_SIRF is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_ARCH_SPRD is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_STM32 is not set +# CONFIG_ARCH_STRATIX10 is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_SYNQUACER is not set +# CONFIG_ARCH_TANGO is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_THUNDER is not set +# CONFIG_ARCH_THUNDER2 is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_VT8500 is not set +# CONFIG_ARCH_VULCAN is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_WANTS_THP_SWAP is not set +# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set +# CONFIG_ARCH_WM8505 is not set +# CONFIG_ARCH_WM8750 is not set +# CONFIG_ARCH_WM8850 is not set +# CONFIG_ARCH_XGENE is not set +# CONFIG_ARCH_ZX is not set +# CONFIG_ARCH_ZYNQ is not set +# CONFIG_ARCH_ZYNQMP is not set +# CONFIG_ARCNET is not set +# CONFIG_ARC_EMAC is not set +# CONFIG_ARC_IRQ_NO_AUTOSAVE is not set +# CONFIG_ARM64_ERRATUM_1024718 is not set +# CONFIG_ARM64_ERRATUM_1463225 is not set +# CONFIG_ARM64_ERRATUM_819472 is not set +# CONFIG_ARM64_ERRATUM_824069 is not set +# CONFIG_ARM64_ERRATUM_826319 is not set +# CONFIG_ARM64_ERRATUM_827319 is not set +# CONFIG_ARM64_ERRATUM_832075 is not set +# CONFIG_ARM64_ERRATUM_834220 is not set +# CONFIG_ARM64_ERRATUM_843419 is not set +# CONFIG_ARM64_ERRATUM_845719 is not set +# CONFIG_ARM64_ERRATUM_858921 is not set +# CONFIG_ARM64_RAS_EXTN is not set +# CONFIG_ARM64_RELOC_TEST is not set +CONFIG_ARM64_SW_TTBR0_PAN=y +# CONFIG_ARM_APPENDED_DTB is not set +# CONFIG_ARM_ARCH_TIMER is not set +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set +# CONFIG_ARM_CCI is not set +# CONFIG_ARM_CCI400_PMU is not set +# CONFIG_ARM_CCI5xx_PMU is not set +# CONFIG_ARM_CCI_PMU is not set +# CONFIG_ARM_CCN is not set +# CONFIG_ARM_CPUIDLE is not set +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_ARM_CRYPTO is not set +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +# CONFIG_ARM_DSU_PMU is not set +# CONFIG_ARM_ERRATA_326103 is not set +# CONFIG_ARM_ERRATA_364296 is not set +# CONFIG_ARM_ERRATA_411920 is not set +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_643719 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_742230 is not set +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_ARM_ERRATA_743622 is not set +# CONFIG_ARM_ERRATA_751472 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_773022 is not set +# CONFIG_ARM_ERRATA_775420 is not set +# CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_818325_852422 is not set +# CONFIG_ARM_ERRATA_821420 is not set +# CONFIG_ARM_ERRATA_825619 is not set +# CONFIG_ARM_ERRATA_857271 is not set +# CONFIG_ARM_ERRATA_852421 is not set +# CONFIG_ARM_ERRATA_852423 is not set +# CONFIG_ARM_ERRATA_857272 is not set +# CONFIG_ARM_ERRATA_814220 is not set +CONFIG_ARM_GIC_MAX_NR=1 +# CONFIG_ARM_KERNMEM_PERMS is not set +# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set +# CONFIG_ARM_KPROBES_TEST is not set +# CONFIG_ARM_MHU is not set +# CONFIG_ARM_MODULE_PLTS is not set +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +# CONFIG_ARM_PSCI is not set +# CONFIG_ARM_PSCI_CHECKER is not set +# CONFIG_ARM_PTDUMP is not set +# CONFIG_ARM_PTDUMP_DEBUGFS is not set +# CONFIG_ARM_SBSA_WATCHDOG is not set +# CONFIG_ARM_SCPI_PROTOCOL is not set +# CONFIG_ARM_SDE_INTERFACE is not set +# CONFIG_ARM_SPE_PMU is not set +# CONFIG_ARM_TIMER_SP804 is not set +# CONFIG_ARM_UNWIND is not set +# CONFIG_ARM_VIRT_EXT is not set +# CONFIG_AS3935 is not set +# CONFIG_ASM9260_TIMER is not set +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_ASUS_WIRELESS is not set +# CONFIG_ASYMMETRIC_KEY_TYPE is not set +# CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is not set +# CONFIG_ASYNC_RAID6_TEST is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_AT76C50X_USB is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_AT91_SAMA5D2_ADC is not set +# CONFIG_ATA is not set +# CONFIG_ATAGS is not set +CONFIG_ATAGS_PROC=y +# CONFIG_ATALK is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_ATA_ACPI is not set +CONFIG_ATA_BMDMA=y +# CONFIG_ATA_GENERIC is not set +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_ATA_PIIX is not set +CONFIG_ATA_SFF=y +# CONFIG_ATA_VERBOSE_ERROR is not set +# CONFIG_ATH10K is not set +# CONFIG_ATH25 is not set +# CONFIG_ATH5K is not set +# CONFIG_ATH6KL is not set +# CONFIG_ATH79 is not set +# CONFIG_ATH9K is not set +# CONFIG_ATH9K_HTC is not set +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1C is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL2 is not set +# CONFIG_ATLAS_PH_SENSOR is not set +# CONFIG_ATM is not set +# CONFIG_ATMEL is not set +# CONFIG_ATMEL_PIT is not set +# CONFIG_ATMEL_SSC is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_BR2684 is not set +CONFIG_ATM_BR2684_IPFILTER=y +# CONFIG_ATM_CLIP is not set +CONFIG_ATM_CLIP_NO_ICMP=y +# CONFIG_ATM_DRIVERS is not set +# CONFIG_ATM_DUMMY is not set +# CONFIG_ATM_ENI is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_FORE200E is not set +# CONFIG_ATM_HE is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_IA is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_LANAI is not set +# CONFIG_ATM_LANE is not set +# CONFIG_ATM_MPOA is not set +# CONFIG_ATM_NICSTAR is not set +# CONFIG_ATM_SOLOS is not set +# CONFIG_ATM_TCP is not set +# CONFIG_ATM_ZATM is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_ATP is not set +# CONFIG_AUDIT is not set +# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set +# CONFIG_AURORA_NB8800 is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTO_ZRELADDR is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_AX25 is not set +# CONFIG_AX25_DAMA_SLAVE is not set +# CONFIG_AX88796 is not set +# CONFIG_AX88796B_PHY is not set +# CONFIG_AXP20X_ADC is not set +# CONFIG_AXP20X_POWER is not set +# CONFIG_AXP288_ADC is not set +# CONFIG_AXP288_FUEL_GAUGE is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_B44 is not set +# CONFIG_B53 is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_APPLE is not set +# CONFIG_BACKLIGHT_ARCXCNN is not set +# CONFIG_BACKLIGHT_BD6107 is not set +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +# CONFIG_BACKLIGHT_GENERIC is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_PANDORA is not set +# CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_PWM is not set +# CONFIG_BACKLIGHT_RPI is not set +# CONFIG_BACKLIGHT_SAHARA is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +# CONFIG_BATMAN_ADV is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_BQ27XXX_HDQ is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_GOLDFISH is not set +# CONFIG_BATTERY_LEGO_EV3 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_MAX1721X is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BAYCOM_EPP is not set +# CONFIG_BAYCOM_PAR is not set +# CONFIG_BAYCOM_SER_FDX is not set +# CONFIG_BAYCOM_SER_HDX is not set +# CONFIG_BCACHE is not set +# CONFIG_BCM47XX is not set +# CONFIG_BCM63XX is not set +# CONFIG_BCM63XX_PHY is not set +# CONFIG_BCM7038_WDT is not set +# CONFIG_BCM7XXX_PHY is not set +# CONFIG_BCM84881_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_BCMA is not set +# CONFIG_BCMA_DRIVER_GPIO is not set +CONFIG_BCMA_POSSIBLE=y +# CONFIG_BCMGENET is not set +# CONFIG_BCM_IPROC_ADC is not set +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_BCM_SBA_RAID is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BE2NET is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_BGMAC is not set +# CONFIG_BH1750 is not set +# CONFIG_BH1780 is not set +# CONFIG_BIG_KEYS is not set +# CONFIG_BIG_LITTLE is not set +# CONFIG_BINARY_PRINTF is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_ELF_FDPIC is not set +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_SCRIPT=y +CONFIG_BITREVERSE=y +# CONFIG_BLK_CGROUP_IOCOST is not set +# CONFIG_BLK_CGROUP_IOLATENCY is not set +# CONFIG_BLK_CMDLINE_PARSER is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEBUG_FS is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_ATIIXP is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CS5535 is not set +# CONFIG_BLK_DEV_CS5536 is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_DELKIN is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_IDEACPI is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_BLK_DEV_IDEPNP is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDE_AU1XXX is not set +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_IT8172 is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_NULL_BLK is not set +# CONFIG_BLK_DEV_NVME is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_PLATFORM is not set +# CONFIG_BLK_DEV_PMEM is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_RSXX is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SD is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SKD is not set +# CONFIG_BLK_DEV_SL82C105 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_TC86C001 is not set +# CONFIG_BLK_DEV_THROTTLING is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_UMC8672 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_ZONED is not set +# CONFIG_BLK_SED_OPAL is not set +# CONFIG_BLK_WBT is not set +CONFIG_BLOCK=y +# CONFIG_BMA180 is not set +# CONFIG_BMA220 is not set +# CONFIG_BMC150_ACCEL is not set +# CONFIG_BMC150_MAGN is not set +# CONFIG_BMC150_MAGN_I2C is not set +# CONFIG_BMC150_MAGN_SPI is not set +# CONFIG_BME680 is not set +# CONFIG_BMG160 is not set +# CONFIG_BMI160_I2C is not set +# CONFIG_BMI160_SPI is not set +# CONFIG_BMIPS_GENERIC is not set +# CONFIG_BMP085 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_BMP280 is not set +# CONFIG_BNA is not set +# CONFIG_BNX2 is not set +# CONFIG_BNX2X is not set +# CONFIG_BNX2X_SRIOV is not set +# CONFIG_BNXT is not set +# CONFIG_BONDING is not set +# CONFIG_BOOKE_WDT is not set +CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BOOT_RAW=y +CONFIG_BPF=y +# CONFIG_BPFILTER is not set +CONFIG_BPF_JIT=y +# CONFIG_BPF_JIT_ALWAYS_ON is not set +# CONFIG_BPF_STREAM_PARSER is not set +CONFIG_BPF_SYSCALL=y +# CONFIG_BPQETHER is not set +CONFIG_BQL=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_BRCMFMAC is not set +# CONFIG_BRCMSMAC is not set +# CONFIG_BRCMSTB_GISB_ARB is not set +CONFIG_BRIDGE=y +# CONFIG_BRIDGE_EBT_802_3 is not set +# CONFIG_BRIDGE_EBT_AMONG is not set +# CONFIG_BRIDGE_EBT_ARP is not set +# CONFIG_BRIDGE_EBT_ARPREPLY is not set +# CONFIG_BRIDGE_EBT_BROUTE is not set +# CONFIG_BRIDGE_EBT_DNAT is not set +# CONFIG_BRIDGE_EBT_IP is not set +# CONFIG_BRIDGE_EBT_IP6 is not set +# CONFIG_BRIDGE_EBT_LIMIT is not set +# CONFIG_BRIDGE_EBT_LOG is not set +# CONFIG_BRIDGE_EBT_MARK is not set +# CONFIG_BRIDGE_EBT_MARK_T is not set +# CONFIG_BRIDGE_EBT_NFLOG is not set +# CONFIG_BRIDGE_EBT_PKTTYPE is not set +# CONFIG_BRIDGE_EBT_REDIRECT is not set +# CONFIG_BRIDGE_EBT_SNAT is not set +# CONFIG_BRIDGE_EBT_STP is not set +# CONFIG_BRIDGE_EBT_T_FILTER is not set +# CONFIG_BRIDGE_EBT_T_NAT is not set +# CONFIG_BRIDGE_EBT_VLAN is not set +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_BRIDGE_NETFILTER is not set +# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_BRIDGE_VLAN_FILTERING=y +# CONFIG_BROADCOM_PHY is not set +CONFIG_BROKEN_ON_SMP=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_BT is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_BTRFS_FS_POSIX_ACL is not set +# CONFIG_BTRFS_FS_REF_VERIFY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BT_ATH3K is not set +# CONFIG_BT_BNEP is not set +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +# CONFIG_BT_BREDR is not set +# CONFIG_BT_CMTP is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIBLUECARD is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBT3C is not set +# CONFIG_BT_HCIBTSDIO is not set +# CONFIG_BT_HCIBTUART is not set +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +# CONFIG_BT_HCIBTUSB_MTK is not set +# CONFIG_BT_HCIBTUSB_RTL is not set +# CONFIG_BT_HCIDTL1 is not set +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIUART_3WIRE is not set +# CONFIG_BT_HCIUART_AG6XX is not set +# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_LL is not set +# CONFIG_BT_HCIUART_MRVL is not set +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_HIDP is not set +# CONFIG_BT_HS is not set +# CONFIG_BT_LE is not set +# CONFIG_BT_LEDS is not set +# CONFIG_BT_MRVL is not set +# CONFIG_BT_MTKSDIO is not set +# CONFIG_BT_MTKUART is not set +# CONFIG_BT_RFCOMM is not set +CONFIG_BT_RFCOMM_TTY=y +# CONFIG_BT_SELFTEST is not set +CONFIG_BUG=y +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +CONFIG_BUILDTIME_EXTABLE_SORT=y +# CONFIG_BUILD_BIN2C is not set +CONFIG_BUILD_SALT="" +# CONFIG_C2PORT is not set +CONFIG_CACHE_L2X0_PMU=y +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_CAIF is not set +# CONFIG_CAN is not set +# CONFIG_CAN_BCM is not set +# CONFIG_CAN_DEBUG_DEVICES is not set +# CONFIG_CAN_DEV is not set +# CONFIG_CAN_GS_USB is not set +# CONFIG_CAN_GW is not set +# CONFIG_CAN_HI311X is not set +# CONFIG_CAN_IFI_CANFD is not set +# CONFIG_CAN_J1939 is not set +# CONFIG_CAN_KVASER_PCIEFD is not set +# CONFIG_CAN_MCBA_USB is not set +# CONFIG_CAN_M_CAN is not set +# CONFIG_CAN_PEAK_PCIEFD is not set +# CONFIG_CAN_RAW is not set +# CONFIG_CAN_RCAR is not set +# CONFIG_CAN_RCAR_CANFD is not set +# CONFIG_CAN_SLCAN is not set +# CONFIG_CAN_SUN4I is not set +# CONFIG_CAN_UCAN is not set +# CONFIG_CAN_VCAN is not set +# CONFIG_CAN_VXCAN is not set +# CONFIG_CAPI_AVM is not set +# CONFIG_CAPI_EICON is not set +# CONFIG_CAPI_TRACE is not set +CONFIG_CARDBUS=y +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_CARL9170 is not set +# CONFIG_CASSINI is not set +# CONFIG_CAVIUM_CPT is not set +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23144 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +# CONFIG_CAVIUM_ERRATUM_30115 is not set +# CONFIG_CAVIUM_OCTEON_SOC is not set +# CONFIG_CAVIUM_PTP is not set +# CONFIG_CB710_CORE is not set +# CONFIG_CC10001_ADC is not set +# CONFIG_CCS811 is not set +CONFIG_CC_CAN_LINK=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +CONFIG_CC_HAS_STACKPROTECTOR_NONE=y +CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_CFG80211 is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +# CONFIG_CGROUPS is not set +# CONFIG_CGROUP_BPF is not set +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_NET_CLASSID is not set +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_RDMA is not set +# CONFIG_CHARGER_ADP5061 is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_DETECTOR_MAX14656 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_LT3651 is not set +# CONFIG_CHARGER_LTC3651 is not set +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_RT9455 is not set +# CONFIG_CHARGER_SBS is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_CHARGER_TWL4030 is not set +# CONFIG_CHARGER_UCS1002 is not set +# CONFIG_CHASH_SELFTEST is not set +# CONFIG_CHASH_STATS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_CIFS is not set +# CONFIG_CIFS_ACL is not set +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_FSCACHE is not set +# CONFIG_CIFS_NFSD_EXPORT is not set +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_SMB2 is not set +CONFIG_CIFS_STATS=y +# CONFIG_CIFS_STATS2 is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIO_DAC is not set +CONFIG_CLANG_VERSION=0 +# CONFIG_CLEANCACHE is not set +# CONFIG_CLKSRC_VERSATILE is not set +# CONFIG_CLK_HSDK is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_CLOCK_THERMAL is not set +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +# CONFIG_CM3605 is not set +# CONFIG_CM36651 is not set +# CONFIG_CMA is not set +CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_CMDLINE_EXTEND is not set +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set +# CONFIG_CMDLINE_PARTITION is not set +# CONFIG_CNIC is not set +# CONFIG_CODA_FS is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_COMEDI is not set +# CONFIG_COMMON_CLK_CDCE706 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_COMMON_CLK_CS2000_CP is not set +# CONFIG_COMMON_CLK_FIXED_MMIO is not set +# CONFIG_COMMON_CLK_IPROC is not set +# CONFIG_COMMON_CLK_MAX9485 is not set +# CONFIG_COMMON_CLK_NXP is not set +# CONFIG_COMMON_CLK_PIC32 is not set +# CONFIG_COMMON_CLK_PWM is not set +# CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_QCOM is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI5341 is not set +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI544 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_COMMON_CLK_VERSATILE is not set +# CONFIG_COMMON_CLK_XGENE is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +CONFIG_COMPACTION=y +# CONFIG_COMPAL_LAPTOP is not set +# CONFIG_COMPAT is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_COMPILE_TEST is not set +# CONFIG_CONFIGFS_FS is not set +# CONFIG_CONFIG_KVM_AMD_SEV is not set +# CONFIG_CONNECTOR is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_CONSTRUCTORS=y +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_COPS is not set +# CONFIG_CORDIC is not set +# CONFIG_COREDUMP is not set +# CONFIG_CORESIGHT is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_CORTINA_PHY is not set +# CONFIG_COUNTER is not set +# CONFIG_CPA_DEBUG is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_IDLE is not set +# CONFIG_CPU_IDLE_GOV_MENU is not set +# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set +# CONFIG_CPU_ISOLATION is not set +# CONFIG_CPU_NO_EFFICIENT_FFS is not set +CONFIG_CPU_SW_DOMAIN_PAN=y +# CONFIG_CRAMFS is not set +CONFIG_CRAMFS_BLOCKDEV=y +# CONFIG_CRAMFS_MTD is not set +CONFIG_CRASHLOG=y +# CONFIG_CRASH_DUMP is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_CRC32_BIT is not set +CONFIG_CRC32_SARWATE=y +# CONFIG_CRC32_SELFTEST is not set +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SLICEBY8 is not set +# CONFIG_CRC4 is not set +# CONFIG_CRC64 is not set +# CONFIG_CRC7 is not set +# CONFIG_CRC8 is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CROSS_COMPILE="" +# CONFIG_CROSS_MEMORY_ATTACH is not set +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_ADIANTUM is not set +# CONFIG_CRYPTO_AEAD is not set +# CONFIG_CRYPTO_AEGIS128 is not set +# CONFIG_CRYPTO_AEGIS128L is not set +# CONFIG_CRYPTO_AEGIS128L_AESNI_SSE2 is not set +# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set +# CONFIG_CRYPTO_AEGIS256 is not set +# CONFIG_CRYPTO_AEGIS256_AESNI_SSE2 is not set +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_AES_586 is not set +# CONFIG_CRYPTO_AES_ARM is not set +# CONFIG_CRYPTO_AES_ARM_BS is not set +# CONFIG_CRYPTO_AES_ARM_CE is not set +# CONFIG_CRYPTO_AES_NI_INTEL is not set +# CONFIG_CRYPTO_AES_TI is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CFB is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +# CONFIG_CRYPTO_CHACHA20_NEON is not set +# CONFIG_CRYPTO_CMAC is not set +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CRC32C_INTEL is not set +# CONFIG_CRYPTO_CRC32_ARM_CE is not set +# CONFIG_CRYPTO_CRCT10DIF is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_DEV_ATMEL_AES is not set +# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set +# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set +# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set +# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set +# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set +# CONFIG_CRYPTO_DEV_CCP is not set +# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set +# CONFIG_CRYPTO_DEV_CCREE is not set +# CONFIG_CRYPTO_DEV_FSL_CAAM is not set +# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_CRYPTO_DEV_HISI_SEC is not set +# CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set +# CONFIG_CRYPTO_DEV_MARVELL_CESA is not set +# CONFIG_CRYPTO_DEV_MV_CESA is not set +# CONFIG_CRYPTO_DEV_MXC_SCC is not set +# CONFIG_CRYPTO_DEV_MXS_DCP is not set +# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set +# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set +# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set +# CONFIG_CRYPTO_DEV_QAT_C62X is not set +# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set +# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set +# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set +# CONFIG_CRYPTO_DEV_QCE is not set +# CONFIG_CRYPTO_DEV_S5P is not set +# CONFIG_CRYPTO_DEV_SAFEXCEL is not set +# CONFIG_CRYPTO_DEV_SAHARA is not set +# CONFIG_CRYPTO_DEV_SP_PSP is not set +# CONFIG_CRYPTO_DEV_TALITOS is not set +# CONFIG_CRYPTO_DEV_VIRTIO is not set +# CONFIG_CRYPTO_DH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_MENU is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_ECDH is not set +# CONFIG_CRYPTO_ECHAINIV is not set +# CONFIG_CRYPTO_ECRDSA is not set +# CONFIG_CRYPTO_ESSIV is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_GHASH_ARM_CE is not set +# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set +# CONFIG_CRYPTO_HASH is not set +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_HW is not set +# CONFIG_CRYPTO_JITTERENTROPY is not set +# CONFIG_CRYPTO_KEYWRAP is not set +# CONFIG_CRYPTO_KHAZAD is not set +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_MCRYPTD is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_MORUS1280 is not set +# CONFIG_CRYPTO_MORUS1280_AVX2 is not set +# CONFIG_CRYPTO_MORUS1280_SSE2 is not set +# CONFIG_CRYPTO_MORUS640 is not set +# CONFIG_CRYPTO_MORUS640_SSE2 is not set +# CONFIG_CRYPTO_NHPOLY1305_NEON is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_OFB is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_PCOMP is not set +# CONFIG_CRYPTO_PCOMP2 is not set +CONFIG_CRYPTO_PCRYPT=y +# CONFIG_CRYPTO_POLY1305 is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_RNG is not set +# CONFIG_CRYPTO_RSA is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SALSA20_586 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA1_ARM is not set +# CONFIG_CRYPTO_SHA1_ARM_CE is not set +# CONFIG_CRYPTO_SHA1_ARM_NEON is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA256_ARM is not set +# CONFIG_CRYPTO_SHA2_ARM_CE is not set +# CONFIG_CRYPTO_SHA3 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_SHA512_ARM is not set +# CONFIG_CRYPTO_SIMD is not set +# CONFIG_CRYPTO_SM3 is not set +# CONFIG_CRYPTO_SM4 is not set +# CONFIG_CRYPTO_SPECK is not set +# CONFIG_CRYPTO_STATS is not set +# CONFIG_CRYPTO_STREEBOG is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_TWOFISH_586 is not set +# CONFIG_CRYPTO_TWOFISH_COMMON is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +# CONFIG_CRYPTO_VMAC is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_XXHASH is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_ZSTD is not set +# CONFIG_CS5535_MFGPT is not set +# CONFIG_CS89x0 is not set +# CONFIG_CUSE is not set +# CONFIG_CW1200 is not set +# CONFIG_CXL_AFU_DRIVER_OPS is not set +# CONFIG_CXL_BASE is not set +# CONFIG_CXL_EEH is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_LIB is not set +# CONFIG_CYPRESS_FIRMWARE is not set +# CONFIG_DA280 is not set +# CONFIG_DA311 is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_DAX is not set +# CONFIG_DCB is not set +# CONFIG_DDR is not set +# CONFIG_DEBUG_ALIGN_RODATA is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_INFO_BTF is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +CONFIG_DEBUG_INFO_REDUCED=y +# CONFIG_DEBUG_INFO_SPLIT is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_KOBJECT_RELEASE is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_LL_UART_8250 is not set +# CONFIG_DEBUG_LL_UART_PL01X is not set +# CONFIG_DEBUG_LOCKDEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_MISC is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_NX_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_PAGE_REF is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_RSEQ is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +# CONFIG_DEBUG_SEMIHOSTING is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_DEBUG_TIMEKEEPING is not set +# CONFIG_DEBUG_UART_8250_PALMCHIP is not set +# CONFIG_DEBUG_UART_BCM63XX is not set +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_WX is not set +# CONFIG_DEBUG_ZBOOT is not set +# CONFIG_DECNET is not set +CONFIG_DEFAULT_CUBIC=y +CONFIG_DEFAULT_DEADLINE=y +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_DEFAULT_NOOP is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_SECURITY="" +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +# CONFIG_DELL_LAPTOP is not set +# CONFIG_DELL_RBTN is not set +# CONFIG_DELL_SMBIOS is not set +# CONFIG_DELL_SMO8800 is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_DEVKMEM is not set +# CONFIG_DEVMEM is not set +CONFIG_DEVPORT=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_DEVTMPFS is not set +# CONFIG_DEVTMPFS_MOUNT is not set +# CONFIG_DEV_DAX is not set +# CONFIG_DGAP is not set +# CONFIG_DGNC is not set +# CONFIG_DHT11 is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set +# CONFIG_DISPLAY_CONNECTOR_DVI is not set +# CONFIG_DISPLAY_CONNECTOR_HDMI is not set +# CONFIG_DISPLAY_ENCODER_TFP410 is not set +# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set +# CONFIG_DISPLAY_PANEL_DPI is not set +# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set +# CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1 is not set +# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set +# CONFIG_DL2K is not set +# CONFIG_DLM is not set +# CONFIG_DM9000 is not set +# CONFIG_DMABUF_SELFTESTS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_DMADEVICES_DEBUG is not set +# CONFIG_DMARD06 is not set +# CONFIG_DMARD09 is not set +# CONFIG_DMARD10 is not set +# CONFIG_DMASCC is not set +# CONFIG_DMATEST is not set +# CONFIG_DMA_API_DEBUG is not set +CONFIG_DMA_DECLARE_COHERENT=y +# CONFIG_DMA_ENGINE is not set +# CONFIG_DMA_FENCE_TRACE is not set +# CONFIG_DMA_JZ4780 is not set +# CONFIG_DMA_NOOP_OPS is not set +# CONFIG_DMA_SHARED_BUFFER is not set +# CONFIG_DMA_VIRT_OPS is not set +# CONFIG_DM_CACHE is not set +# CONFIG_DM_CLONE is not set +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_DUST is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_INTEGRITY is not set +# CONFIG_DM_LOG_USERSPACE is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_DM_MQ_DEFAULT is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_UNSTRIPED is not set +# CONFIG_DM_VERITY is not set +# CONFIG_DM_WRITECACHE is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DNET is not set +# CONFIG_DNOTIFY is not set +# CONFIG_DNS_RESOLVER is not set +CONFIG_DOUBLEFAULT=y +# CONFIG_DP83822_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83TC811_PHY is not set +# CONFIG_DPOT_DAC is not set +# CONFIG_DPS310 is not set +CONFIG_DQL=y +# CONFIG_DRAGONRISE_FF is not set +# CONFIG_DRM is not set +# CONFIG_DRM_AMDGPU is not set +# CONFIG_DRM_AMDGPU_CIK is not set +# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set +# CONFIG_DRM_AMDGPU_SI is not set +# CONFIG_DRM_AMDGPU_USERPTR is not set +# CONFIG_DRM_AMD_ACP is not set +# CONFIG_DRM_AMD_DC_DCN2_0 is not set +# CONFIG_DRM_ANALOGIX_ANX78XX is not set +# CONFIG_DRM_ARCPGU is not set +# CONFIG_DRM_ARMADA is not set +# CONFIG_DRM_AST is not set +# CONFIG_DRM_BOCHS is not set +# CONFIG_DRM_CDNS_DSI is not set +# CONFIG_DRM_CIRRUS_QEMU is not set +# CONFIG_DRM_DEBUG_MM is not set +# CONFIG_DRM_DEBUG_SELFTEST is not set +# CONFIG_DRM_DP_AUX_CHARDEV is not set +# CONFIG_DRM_DP_CEC is not set +# CONFIG_DRM_DUMB_VGA_DAC is not set +# CONFIG_DRM_DW_HDMI_CEC is not set +# CONFIG_DRM_ETNAVIV is not set +# CONFIG_DRM_EXYNOS is not set +# CONFIG_DRM_FBDEV_EMULATION is not set +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set +# CONFIG_DRM_FSL_DCU is not set +# CONFIG_DRM_GM12U320 is not set +# CONFIG_DRM_GMA500 is not set +# CONFIG_DRM_HDLCD is not set +# CONFIG_DRM_HISI_HIBMC is not set +# CONFIG_DRM_HISI_KIRIN is not set +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_NXP_TDA9950 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I915 is not set +# CONFIG_DRM_KOMEDA is not set +# CONFIG_DRM_LEGACY is not set +# CONFIG_DRM_LIB_RANDOM is not set +# CONFIG_DRM_LIMA is not set +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +# CONFIG_DRM_LVDS_ENCODER is not set +# CONFIG_DRM_MALI_DISPLAY is not set +# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_MGAG200 is not set +# CONFIG_DRM_MXSFB is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_OMAP is not set +# CONFIG_DRM_PANEL_ARM_VERSATILE is not set +# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set +# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set +# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set +# CONFIG_DRM_PANEL_LG_LB035Q02 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_LVDS is not set +# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set +# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set +# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set +# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set +# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set +# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set +# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set +# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set +# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set +# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set +# CONFIG_DRM_PANFROST is not set +# CONFIG_DRM_TOSHIBA_TC358764 is not set +# CONFIG_DRM_TI_SN65DSI86 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_PL111 is not set +# CONFIG_DRM_QXL is not set +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_RADEON_USERPTR is not set +# CONFIG_DRM_RCAR_DW_HDMI is not set +# CONFIG_DRM_RCAR_LVDS is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SII9234 is not set +# CONFIG_DRM_SIL_SII8620 is not set +# CONFIG_DRM_STI is not set +# CONFIG_DRM_STM is not set +# CONFIG_DRM_SUN4I is not set +# CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TILCDC is not set +# CONFIG_DRM_TINYDRM is not set +# CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_TOSHIBA_TC358767 is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_VBOXVIDEO is not set +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VIRTIO_GPU is not set +# CONFIG_DRM_VKMS is not set +# CONFIG_DRM_VMWGFX is not set +# CONFIG_DRM_XEN is not set +# CONFIG_DS1682 is not set +# CONFIG_DS1803 is not set +# CONFIG_DS4424 is not set +# CONFIG_DST_CACHE is not set +# CONFIG_DTLK is not set +# CONFIG_DUMMY is not set +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +# CONFIG_DUMMY_IRQ is not set +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set +# CONFIG_DWC_XLGMAC is not set +# CONFIG_DWMAC_IPQ806X is not set +# CONFIG_DWMAC_LPC18XX is not set +# CONFIG_DWMAC_MESON is not set +# CONFIG_DWMAC_ROCKCHIP is not set +# CONFIG_DWMAC_SOCFPGA is not set +# CONFIG_DWMAC_STI is not set +# CONFIG_DW_AXI_DMAC is not set +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set +# CONFIG_DW_EDMA is not set +# CONFIG_DW_EDMA_PCIE is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_E1000E_HWTS is not set +# CONFIG_EARLY_PRINTK_8250 is not set +# CONFIG_EARLY_PRINTK_USB_XDBC is not set +# CONFIG_EBC_C384_WDT is not set +# CONFIG_ECHO is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_EDAC is not set +# CONFIG_EEEPC_LAPTOP is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_DIGSY_MTC_CFG is not set +# CONFIG_EEPROM_EE1004 is not set +# CONFIG_EEPROM_IDT_89HPESX is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EFI is not set +CONFIG_EFI_PARTITION=y +# CONFIG_EFS_FS is not set +CONFIG_ELFCORE=y +# CONFIG_ELF_CORE is not set +# CONFIG_EMAC_ROCKCHIP is not set +CONFIG_EMBEDDED=y +# CONFIG_EM_TIMER_STI is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +# CONFIG_ENA_ETHERNET is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_ENCX24J600 is not set +# CONFIG_ENIC is not set +# CONFIG_ENVELOPE_DETECTOR is not set +# CONFIG_EPAPR_PARAVIRT is not set +# CONFIG_EPIC100 is not set +CONFIG_EPOLL=y +# CONFIG_EQUALIZER is not set +# CONFIG_EROFS_FS is not set +# CONFIG_ET131X is not set +CONFIG_ETHERNET=y +# CONFIG_ETHOC is not set +CONFIG_EVENTFD=y +# CONFIG_EXFAT_FS is not set +CONFIG_EXPERT=y +CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_DEBUG is not set +# CONFIG_EXT4_ENCRYPTION is not set +# CONFIG_EXT4_FS is not set +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +CONFIG_EXT4_USE_FOR_EXT2=y +# CONFIG_EXTCON is not set +# CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_ARIZONA is not set +# CONFIG_EXTCON_AXP288 is not set +# CONFIG_EXTCON_FSA9480 is not set +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_INTEL_INT3496 is not set +# CONFIG_EXTCON_MAX3355 is not set +# CONFIG_EXTCON_PTN5150 is not set +# CONFIG_EXTCON_QCOM_SPMI_MISC is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set +CONFIG_EXTRA_FIRMWARE="" +CONFIG_EXTRA_TARGETS="" +# CONFIG_EXYNOS_ADC is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_F2FS_FAULT_INJECTION is not set +# CONFIG_F2FS_FS is not set +# CONFIG_F2FS_FS_ENCRYPTION is not set +# CONFIG_F2FS_FS_POSIX_ACL is not set +# CONFIG_F2FS_IO_TRACE is not set +# CONFIG_FAILOVER is not set +# CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_FANOTIFY is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_FAT_DEFAULT_UTF8 is not set +# CONFIG_FAT_FS is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_FB is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_BIG_ENDIAN is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_BOTH_ENDIAN is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_DA8XX is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_FLEX is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_GOLDFISH is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_IMX is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_LITTLE_ENDIAN is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_MXS is not set +# CONFIG_FB_N411 is not set +# CONFIG_FB_NEOMAGIC is not set +CONFIG_FB_NOTIFY=y +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_OF is not set +# CONFIG_FB_OMAP2 is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_PS3 is not set +# CONFIG_FB_PXA is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_SM712 is not set +# CONFIG_FB_SM750 is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_SSD1307 is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TFT is not set +# CONFIG_FB_TFT_AGM1264K_FL is not set +# CONFIG_FB_TFT_BD663474 is not set +# CONFIG_FB_TFT_FBTFT_DEVICE is not set +# CONFIG_FB_TFT_HX8340BN is not set +# CONFIG_FB_TFT_HX8347D is not set +# CONFIG_FB_TFT_HX8353D is not set +# CONFIG_FB_TFT_HX8357D is not set +# CONFIG_FB_TFT_ILI9163 is not set +# CONFIG_FB_TFT_ILI9320 is not set +# CONFIG_FB_TFT_ILI9325 is not set +# CONFIG_FB_TFT_ILI9340 is not set +# CONFIG_FB_TFT_ILI9341 is not set +# CONFIG_FB_TFT_ILI9481 is not set +# CONFIG_FB_TFT_ILI9486 is not set +# CONFIG_FB_TFT_PCD8544 is not set +# CONFIG_FB_TFT_RA8875 is not set +# CONFIG_FB_TFT_S6D02A1 is not set +# CONFIG_FB_TFT_S6D1121 is not set +# CONFIG_FB_TFT_SH1106 is not set +# CONFIG_FB_TFT_SSD1289 is not set +# CONFIG_FB_TFT_SSD1305 is not set +# CONFIG_FB_TFT_SSD1306 is not set +# CONFIG_FB_TFT_SSD1325 is not set +# CONFIG_FB_TFT_SSD1331 is not set +# CONFIG_FB_TFT_SSD1351 is not set +# CONFIG_FB_TFT_ST7735R is not set +# CONFIG_FB_TFT_ST7789V is not set +# CONFIG_FB_TFT_TINYLCD is not set +# CONFIG_FB_TFT_TLS8204 is not set +# CONFIG_FB_TFT_UC1611 is not set +# CONFIG_FB_TFT_UC1701 is not set +# CONFIG_FB_TFT_UPD161704 is not set +# CONFIG_FB_TFT_WATTEROTT is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_TMIO is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_XGI is not set +# CONFIG_FCOE is not set +# CONFIG_FCOE_FNIC is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +# CONFIG_FENCE_TRACE is not set +# CONFIG_FHANDLE is not set +CONFIG_FIB_RULES=y +# CONFIG_FIELDBUS_DEV is not set +CONFIG_FILE_LOCKING=y +# CONFIG_FIND_BIT_BENCHMARK is not set +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# CONFIG_FIREWIRE_SERIAL is not set +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_TRUSTED_FOUNDATIONS is not set +# CONFIG_FIXED_PHY is not set +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FM10K is not set +# CONFIG_FMC is not set +# CONFIG_FONT_TER16x32 is not set +# CONFIG_FORCEDETH is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_FORTIFY_SOURCE=y +# CONFIG_FPGA is not set +# CONFIG_FRAMEBUFFER_CONSOLE is not set +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# CONFIG_FRAME_POINTER is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_FREEZER is not set +# CONFIG_FRONTSWAP is not set +# CONFIG_FSCACHE is not set +# CONFIG_FSI is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_FSL_QDMA is not set +# CONFIG_FSL_ERRATUM_A008585 is not set +# CONFIG_FSL_MC_BUS is not set +# CONFIG_FSL_PQ_MDIO is not set +# CONFIG_FSL_XGMAC_MDIO is not set +CONFIG_FSNOTIFY=y +# CONFIG_FS_DAX is not set +# CONFIG_FS_ENCRYPTION is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_FS_VERITY is not set +# CONFIG_FTGMAC100 is not set +# CONFIG_FTL is not set +# CONFIG_FTMAC100 is not set +# CONFIG_FTRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_FTWDT010_WATCHDOG is not set +# CONFIG_FUJITSU_ES is not set +# CONFIG_FUJITSU_LAPTOP is not set +# CONFIG_FUJITSU_TABLET is not set +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_FUSE_FS is not set +# CONFIG_FUSION is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set +# CONFIG_FUSION_SPI is not set +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_FW_LOADER=y +# CONFIG_FW_LOADER_COMPRESS is not set +CONFIG_FW_LOADER_USER_HELPER=y +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y +# CONFIG_FXAS21002C is not set +CONFIG_GACT_PROB=y +# CONFIG_GADGET_UAC1 is not set +# CONFIG_GAMEPORT is not set +# CONFIG_GATEWORKS_GW16083 is not set +# CONFIG_GCC_PLUGINS is not set +# CONFIG_GCOV is not set +# CONFIG_GCOV_KERNEL is not set +# CONFIG_GDB_SCRIPTS is not set +# CONFIG_GEMINI_ETHERNET is not set +# CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_GENERIC_ADC_THERMAL is not set +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_GENERIC_HWEIGHT=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_NET_UTILS=y +# CONFIG_GENERIC_PHY is not set +# CONFIG_GENEVE is not set +# CONFIG_GENWQE is not set +# CONFIG_GFS2_FS is not set +# CONFIG_GIGASET_CAPI is not set +# CONFIG_GIGASET_DEBUG is not set +# CONFIG_GIGASET_DUMMYLL is not set +# CONFIG_GLOB_SELFTEST is not set +# CONFIG_GNSS is not set +# CONFIG_GOLDFISH is not set +# CONFIG_GOOGLE_FIRMWARE is not set +# CONFIG_GP2AP020A00F is not set +# CONFIG_GPD_POCKET_FAN is not set +# CONFIG_GPIOLIB is not set +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +# CONFIG_GPIO_104_DIO_48E is not set +# CONFIG_GPIO_104_IDIO_16 is not set +# CONFIG_GPIO_104_IDI_48 is not set +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_AMD8111 is not set +# CONFIG_GPIO_AMDPT is not set +# CONFIG_GPIO_AMD_FCH is not set +# CONFIG_GPIO_BCM_KONA is not set +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_CADENCE is not set +# CONFIG_GPIO_CS5535 is not set +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_EM is not set +# CONFIG_GPIO_EXAR is not set +# CONFIG_GPIO_F7188X is not set +# CONFIG_GPIO_FTGPIO010 is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_GPIO_MM is not set +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_GW_PLD is not set +# CONFIG_GPIO_HLWD is not set +# CONFIG_GPIO_ICH is not set +# CONFIG_GPIO_IT87 is not set +# CONFIG_GPIO_LYNXPOINT is not set +# CONFIG_GPIO_MAX3191X is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_MB86S7X is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_ML_IOH is not set +# CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_MPC8XXX is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_PCH is not set +# CONFIG_GPIO_PCIE_IDIO_24 is not set +# CONFIG_GPIO_PCI_IDIO_16 is not set +# CONFIG_GPIO_PISOSR is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_RCAR is not set +# CONFIG_GPIO_RDC321X is not set +# CONFIG_GPIO_SAMA5D2_PIOBU is not set +# CONFIG_GPIO_SCH is not set +# CONFIG_GPIO_SCH311X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_SYSCON is not set +# CONFIG_GPIO_SYSFS is not set +# CONFIG_GPIO_TPIC2810 is not set +# CONFIG_GPIO_TS4900 is not set +# CONFIG_GPIO_TS5500 is not set +# CONFIG_GPIO_VX855 is not set +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_GPIO_WINBOND is not set +# CONFIG_GPIO_WS16C48 is not set +# CONFIG_GPIO_XGENE is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_XRA1403 is not set +# CONFIG_GPIO_ZEVIO is not set +# CONFIG_GPIO_ZX is not set +# CONFIG_GREENASIA_FF is not set +# CONFIG_GREYBUS is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_GTP is not set +# CONFIG_GUP_BENCHMARK is not set +# CONFIG_GVE is not set +# CONFIG_HABANA_AI is not set +# CONFIG_HAMACHI is not set +# CONFIG_HAMRADIO is not set +# CONFIG_HAPPYMEAL is not set +CONFIG_HARDENED_USERCOPY=y +# CONFIG_HARDENED_USERCOPY_FALLBACK is not set +# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set +CONFIG_HARDEN_EL2_VECTORS=y +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y +# CONFIG_HAVE_ARCH_HASH is not set +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +# CONFIG_HAVE_ARCH_VMAP_STACK is not set +CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y +# CONFIG_HAVE_ARM_ARCH_TIMER is not set +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_CAT=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_NMI=y +CONFIG_HAVE_STACKPROTECTOR=y +# CONFIG_HCALL_STATS is not set +# CONFIG_HDC100X is not set +# CONFIG_HDLC is not set +# CONFIG_HDLC_CISCO is not set +# CONFIG_HDLC_FR is not set +# CONFIG_HDLC_PPP is not set +# CONFIG_HDLC_RAW is not set +# CONFIG_HDLC_RAW_ETH is not set +# CONFIG_HDMI_LPE_AUDIO is not set +# CONFIG_HDQ_MASTER_OMAP is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_HEADER_TEST is not set +# CONFIG_HERMES is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFS_FS_POSIX_ACL is not set +# CONFIG_HI8435 is not set +# CONFIG_HIBERNATION is not set +# CONFIG_HID is not set +# CONFIG_HIDRAW is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACCUTOUCH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_ACRUX_FF is not set +# CONFIG_HID_ALPS is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_ASUS is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BATTERY_STRENGTH is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_BIGBEN_FF is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CMEDIA is not set +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_COUGAR is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CREATIVE_SB0540 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_ELAN is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GENERIC is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_GOOGLE_HAMMER is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LED is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_LOGITECH_DJ is not set +# CONFIG_HID_LOGITECH_HIDPP is not set +# CONFIG_HID_MACALLY is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MALTRON is not set +# CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTI is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PID is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_REDRAGON is not set +# CONFIG_HID_RETRODE is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEAM is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_U2FZERO is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_UDRAW_PS3 is not set +# CONFIG_HID_VIEWSONIC is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HIGHMEM is not set +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HINIC is not set +# CONFIG_HIP04_ETH is not set +# CONFIG_HIPPI is not set +# CONFIG_HISILICON_ERRATUM_161010101 is not set +# CONFIG_HISILICON_ERRATUM_161600802 is not set +# CONFIG_HISI_FEMAC is not set +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HMC6352 is not set +# CONFIG_HNS is not set +# CONFIG_HNS3 is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +# CONFIG_HOSTAP is not set +# CONFIG_HOSTAP_CS is not set +# CONFIG_HOSTAP_PCI is not set +# CONFIG_HOSTAP_PLX is not set +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HP03 is not set +# CONFIG_HP100 is not set +# CONFIG_HP206C is not set +CONFIG_HPET_MMAP_DEFAULT=y +# CONFIG_HPFS_FS is not set +# CONFIG_HP_ILO is not set +# CONFIG_HP_WIRELESS is not set +# CONFIG_HSA_AMD is not set +# CONFIG_HSI is not set +# CONFIG_HSR is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTS221 is not set +# CONFIG_HTU21 is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_HVC_DCC is not set +# CONFIG_HVC_UDBG is not set +# CONFIG_HWLAT_TRACER is not set +# CONFIG_HWMON is not set +# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON_VID is not set +# CONFIG_HWSPINLOCK is not set +# CONFIG_HWSPINLOCK_OMAP is not set +CONFIG_HW_PERF_EVENTS=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HW_RANDOM_AMD is not set +# CONFIG_HW_RANDOM_ATMEL is not set +# CONFIG_HW_RANDOM_CAVIUM is not set +# CONFIG_HW_RANDOM_EXYNOS is not set +# CONFIG_HW_RANDOM_GEODE is not set +# CONFIG_HW_RANDOM_INTEL is not set +# CONFIG_HW_RANDOM_IPROC_RNG200 is not set +# CONFIG_HW_RANDOM_OMAP is not set +# CONFIG_HW_RANDOM_OMAP3_ROM is not set +# CONFIG_HW_RANDOM_PPC4XX is not set +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_TPM=y +# CONFIG_HW_RANDOM_VIA is not set +# CONFIG_HW_RANDOM_VIRTIO is not set +# CONFIG_HX711 is not set +# CONFIG_HYPERV is not set +# CONFIG_HYPERV_TSCPAGE is not set +# CONFIG_HYSDN is not set +CONFIG_HZ=100 +CONFIG_HZ_100=y +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +# CONFIG_HZ_128 is not set +# CONFIG_HZ_200 is not set +# CONFIG_HZ_24 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_300 is not set +# CONFIG_HZ_48 is not set +# CONFIG_HZ_500 is not set +# CONFIG_HZ_PERIODIC is not set +# CONFIG_I2C is not set +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCA is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_AU1550 is not set +# CONFIG_I2C_BCM2835 is not set +# CONFIG_I2C_BCM_IPROC is not set +# CONFIG_I2C_CADENCE is not set +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_COMPAT is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEMUX_PINCTRL is not set +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_EG20T is not set +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_HID is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_IBM_IIC is not set +# CONFIG_I2C_IMG is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_ISMT is not set +# CONFIG_I2C_JZ4780 is not set +# CONFIG_I2C_MLXCPLD is not set +# CONFIG_I2C_MPC is not set +# CONFIG_I2C_MUX is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set +# CONFIG_I2C_MUX_MLXCPLD is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +# CONFIG_I2C_MV64XXX is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_NVIDIA_GPU is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_OCTEON is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PCA_ISA is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_RCAR is not set +# CONFIG_I2C_RK3X is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_S3C2410 is not set +# CONFIG_I2C_SCMI is not set +# CONFIG_I2C_SH_MOBILE is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_SMBUS is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_THUNDERX is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_I2C_VERSATILE is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_XILINX is not set +# CONFIG_I3C is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_IAQCORE is not set +# CONFIG_IBM_ASM is not set +# CONFIG_IBM_EMAC_DEBUG is not set +# CONFIG_IBM_EMAC_EMAC4 is not set +# CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_EMAC_RGMII is not set +# CONFIG_IBM_EMAC_TAH is not set +# CONFIG_IBM_EMAC_ZMII is not set +# CONFIG_ICE is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_ICS932S401 is not set +# CONFIG_IDE is not set +# CONFIG_IDEAPAD_LAPTOP is not set +# CONFIG_IDE_GD is not set +# CONFIG_IDE_PROC_FS is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +# CONFIG_IEEE802154 is not set +# CONFIG_IEEE802154_ADF7242 is not set +# CONFIG_IEEE802154_ATUSB is not set +# CONFIG_IEEE802154_CA8210 is not set +# CONFIG_IEEE802154_HWSIM is not set +# CONFIG_IEEE802154_MCR20A is not set +# CONFIG_IFB is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IGC is not set +# CONFIG_IIO is not set +# CONFIG_IIO_BUFFER_CB is not set +# CONFIG_IIO_BUFFER_HW_CONSUMER is not set +# CONFIG_IIO_CONFIGFS is not set +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 +# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set +# CONFIG_IIO_INTERRUPT_TRIGGER is not set +# CONFIG_IIO_MUX is not set +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set +# CONFIG_IIO_RESCALE is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set +# CONFIG_IIO_SSP_SENSORHUB is not set +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_IIO_ST_GYRO_3AXIS is not set +# CONFIG_IIO_ST_LSM6DSX is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set +# CONFIG_IIO_ST_PRESS is not set +# CONFIG_IIO_SW_DEVICE is not set +# CONFIG_IIO_SW_TRIGGER is not set +# CONFIG_IIO_SYSFS_TRIGGER is not set +# CONFIG_IKCONFIG is not set +# CONFIG_IKCONFIG_PROC is not set +# CONFIG_IKHEADERS is not set +# CONFIG_IMAGE_CMDLINE_HACK is not set +# CONFIG_IMGPDC_WDT is not set +# CONFIG_IMG_MDC_DMA is not set +# CONFIG_IMX7D_ADC is not set +# CONFIG_IMX_IPUV3_CORE is not set +# CONFIG_IMX_THERMAL is not set +# CONFIG_INA2XX_ADC is not set +# CONFIG_INDIRECT_PIO is not set +CONFIG_INET=y +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_DIAG is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_TCP_DIAG is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INFINIBAND is not set +# CONFIG_INFTL is not set +# CONFIG_INGENIC_ADC is not set +# CONFIG_INGENIC_CGU_JZ4725B is not set +# CONFIG_INGENIC_CGU_JZ4740 is not set +# CONFIG_INGENIC_CGU_JZ4770 is not set +# CONFIG_INGENIC_CGU_JZ4780 is not set +# CONFIG_INGENIC_TCU_CLK is not set +# CONFIG_INGENIC_TCU_IRQ is not set +# CONFIG_INGENIC_TIMER is not set +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_INIT_STACK_NONE=y +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_INOTIFY_USER=y +# CONFIG_INPUT is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_APANEL is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_ATLAS_BTNS is not set +# CONFIG_INPUT_ATMEL_CAPTOUCH is not set +# CONFIG_INPUT_AXP20X_PEK is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_DECODER is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_GPIO_VIBRA is not set +# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_LEDS is not set +# CONFIG_INPUT_MATRIXKMAP is not set +# CONFIG_INPUT_MAX8997_HAPTIC is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_MSM_VIBRATOR is not set +# CONFIG_INPUT_PALMAS_PWRBUTTON is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PCSPKR is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_PWM_VIBRA is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_TPS65218_PWRBUTTON is not set +# CONFIG_INPUT_TWL4030_PWRBUTTON is not set +# CONFIG_INPUT_TWL4030_VIBRA is not set +# CONFIG_INPUT_TWL6040_VIBRA is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_WISTRON_BTNS is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INT340X_THERMAL is not set +# CONFIG_INTEL_ATOMISP2_PM is not set +# CONFIG_INTEL_CHT_INT33FE is not set +# CONFIG_INTEL_HID_EVENT is not set +# CONFIG_INTEL_IDLE is not set +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_INTEL_IOATDMA is not set +# CONFIG_INTEL_ISH_HID is not set +# CONFIG_INTEL_MEI is not set +# CONFIG_INTEL_MEI_ME is not set +# CONFIG_INTEL_MEI_TXE is not set +# CONFIG_INTEL_MIC_CARD is not set +# CONFIG_INTEL_MIC_HOST is not set +# CONFIG_INTEL_MID_PTI is not set +# CONFIG_INTEL_OAKTRAIL is not set +# CONFIG_INTEL_PMC_CORE is not set +# CONFIG_INTEL_PUNIT_IPC is not set +# CONFIG_INTEL_RST is not set +# CONFIG_INTEL_SMARTCONNECT is not set +# CONFIG_INTEL_SOC_PMIC is not set +# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set +# CONFIG_INTEL_SOC_PMIC_CHTWC is not set +# CONFIG_INTEL_TH is not set +# CONFIG_INTEL_VBTN is not set +# CONFIG_INTEL_XWAY_PHY is not set +# CONFIG_INTERCONNECT is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_INV_MPU6050_I2C is not set +# CONFIG_INV_MPU6050_IIO is not set +# CONFIG_INV_MPU6050_SPI is not set +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_IOSCHED_BFQ is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IO_STRICT_DEVMEM=y +# CONFIG_IO_URING is not set +# CONFIG_IP17XX_PHY is not set +# CONFIG_IP6_NF_FILTER is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP6_NF_MANGLE is not set +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_MATCH_SRH is not set +# CONFIG_IP6_NF_NAT is not set +# CONFIG_IP6_NF_RAW is not set +# CONFIG_IP6_NF_SECURITY is not set +# CONFIG_IP6_NF_TARGET_HL is not set +# CONFIG_IP6_NF_TARGET_REJECT is not set +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +# CONFIG_IPACK_BUS is not set +# CONFIG_IPC_NS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPV6 is not set +# CONFIG_IPV6_FOU is not set +# CONFIG_IPV6_FOU_TUNNEL is not set +# CONFIG_IPV6_ILA is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_ROUTE_INFO is not set +# CONFIG_IPV6_SEG6_HMAC is not set +# CONFIG_IPV6_SEG6_LWTUNNEL is not set +# CONFIG_IPV6_SIT is not set +# CONFIG_IPV6_SIT_6RD is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_VTI is not set +# CONFIG_IPVLAN is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2200 is not set +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +# CONFIG_IPW2200_PROMISCUOUS is not set +# CONFIG_IPW2200_QOS is not set +# CONFIG_IPW2200_RADIOTAP is not set +# CONFIG_IPWIRELESS is not set +# CONFIG_IPX is not set +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_DCCP is not set +# CONFIG_IP_FIB_TRIE_STATS is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_NF_ARPFILTER is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_ARP_MANGLE is not set +# CONFIG_IP_NF_FILTER is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_RPFILTER is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_SECURITY is not set +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_MASQUERADE is not set +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_REDIRECT is not set +# CONFIG_IP_NF_TARGET_REJECT is not set +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_SCTP is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_SET_HASH_IPMAC is not set +# CONFIG_IP_VS is not set +# CONFIG_IP_VS_MH is not set +CONFIG_IP_VS_MH_TAB_INDEX=10 +# CONFIG_IRDA is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_IRQ_ALL_CPUS is not set +# CONFIG_IRQ_DOMAIN_DEBUG is not set +# CONFIG_IRQ_POLL is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_IR_GPIO_CIR is not set +# CONFIG_IR_HIX5HD2 is not set +# CONFIG_IR_IGORPLUGUSB is not set +# CONFIG_IR_IGUANA is not set +# CONFIG_IR_IMG is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_TTUSBIR is not set +# CONFIG_ISA_BUS is not set +# CONFIG_ISA_BUS_API is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_ISCSI_TCP is not set +CONFIG_ISDN=y +# CONFIG_ISDN_AUDIO is not set +# CONFIG_ISDN_CAPI is not set +# CONFIG_ISDN_CAPI_CAPIDRV is not set +# CONFIG_ISDN_DIVERSION is not set +# CONFIG_ISDN_DRV_ACT2000 is not set +# CONFIG_ISDN_DRV_GIGASET is not set +# CONFIG_ISDN_DRV_HISAX is not set +# CONFIG_ISDN_DRV_ICN is not set +# CONFIG_ISDN_DRV_LOOP is not set +# CONFIG_ISDN_DRV_PCBIT is not set +# CONFIG_ISDN_DRV_SC is not set +# CONFIG_ISDN_I4L is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_ISL29125 is not set +# CONFIG_ISL29501 is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_ISS4xx is not set +# CONFIG_ITG3200 is not set +# CONFIG_IWL3945 is not set +# CONFIG_IWLWIFI is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_JAILHOUSE_GUEST is not set +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_POSIX_ACL is not set +# CONFIG_JFFS2_FS_SECURITY is not set +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_LZMA=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_ZLIB is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_JME is not set +CONFIG_JOLIET=y +# CONFIG_JSA1212 is not set +# CONFIG_JUMP_LABEL is not set +# CONFIG_KALLSYMS is not set +# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_BASE_RELATIVE=y +# CONFIG_KALLSYMS_UNCOMPRESSED is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_KASAN is not set +CONFIG_KASAN_STACK=1 +# CONFIG_KCOV is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_CAT is not set +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_LZ4 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_KERNEL_MODE_NEON=y +CONFIG_KERNEL_XZ=y +CONFIG_KERNFS=y +# CONFIG_KEXEC is not set +# CONFIG_KEXEC_FILE is not set +# CONFIG_KEYBOARD_ADC is not set +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_APPLESPI is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_BCM is not set +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_DLINK_DIR685 is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_PXA27x is not set +# CONFIG_KEYBOARD_QT1050 is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_SH_KEYSC is not set +# CONFIG_KEYBOARD_SNVS_PWRKEY is not set +# CONFIG_KEYBOARD_STMPE is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_TEGRA is not set +# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set +# CONFIG_KEYBOARD_TWL4030 is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYS is not set +# CONFIG_KEYS_REQUEST_CACHE is not set +# CONFIG_KEY_DH_OPERATIONS is not set +# CONFIG_KGDB is not set +# CONFIG_KMEMCHECK is not set +# CONFIG_KMX61 is not set +# CONFIG_KPROBES is not set +# CONFIG_KPROBES_SANITY_TEST is not set +# CONFIG_KS7010 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSM is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_KUSER_HELPERS=y +# CONFIG_KVM_AMD is not set +# CONFIG_KVM_GUEST is not set +# CONFIG_KVM_INTEL is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_KXSD9 is not set +# CONFIG_L2TP is not set +# CONFIG_L2TP_ETH is not set +# CONFIG_L2TP_IP is not set +# CONFIG_L2TP_V3 is not set +# CONFIG_LAN743X is not set +# CONFIG_LANMEDIA is not set +# CONFIG_LANTIQ is not set +# CONFIG_LAPB is not set +# CONFIG_LASAT is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +CONFIG_LBDAF=y +# CONFIG_LCD_AMS369FG06 is not set +# CONFIG_LCD_CLASS_DEVICE is not set +# CONFIG_LCD_HX8357 is not set +# CONFIG_LCD_ILI922X is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_L4F00242T03 is not set +# CONFIG_LCD_LD9040 is not set +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LMS501KF03 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_OTM3225A is not set +# CONFIG_LCD_S6E63M0 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +CONFIG_LDISC_AUTOLOAD=y +# CONFIG_LDM_PARTITION is not set +CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y +# CONFIG_LEDS_AN30259A is not set +# CONFIG_LEDS_APU is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_BLINKM is not set +CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_CLASS_FLASH is not set +# CONFIG_LEDS_CR0014114 is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_INTEL_SS4200 is not set +# CONFIG_LEDS_IS31FL319X is not set +# CONFIG_LEDS_IS31FL32XX is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3532 is not set +# CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_LM3692X is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_MLXCPLD is not set +# CONFIG_LEDS_MLXREG is not set +# CONFIG_LEDS_NIC78BX is not set +# CONFIG_LEDS_NS2 is not set +# CONFIG_LEDS_OT200 is not set +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_SPI_BYTE is not set +# CONFIG_LEDS_SYSCON is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TI_LMU_COMMON is not set +# CONFIG_LEDS_TLC591XX is not set +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_ACTIVITY is not set +# CONFIG_LEDS_TRIGGER_AUDIO is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +# CONFIG_LEDS_TRIGGER_CPU is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +# CONFIG_LEDS_TRIGGER_DISK is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_IDE_DISK is not set +# CONFIG_LEDS_TRIGGER_MTD is not set +CONFIG_LEDS_TRIGGER_NETDEV=y +# CONFIG_LEDS_TRIGGER_ONESHOT is not set +# CONFIG_LEDS_TRIGGER_PANIC is not set +# CONFIG_LEDS_TRIGGER_PATTERN is not set +CONFIG_LEDS_TRIGGER_TIMER=y +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_USER is not set +# CONFIG_LED_TRIGGER_PHY is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_LGUEST is not set +# CONFIG_LIB80211 is not set +# CONFIG_LIB80211_CRYPT_CCMP is not set +# CONFIG_LIB80211_CRYPT_TKIP is not set +# CONFIG_LIB80211_CRYPT_WEP is not set +# CONFIG_LIB80211_DEBUG is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_LIBERTAS is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_LIBERTAS_USB is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_LIBIPW_DEBUG is not set +# CONFIG_LIBNVDIMM is not set +# CONFIG_LIDAR_LITE_V2 is not set +# CONFIG_LIQUIDIO is not set +# CONFIG_LIQUIDIO_VF is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_LKDTM is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_LMP91000 is not set +# CONFIG_LNET is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_LOCKD is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_LOCK_EVENT_COUNTS is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_LOGFS is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIWHEELS_FF is not set +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +# CONFIG_LOONGSON_MC146818 is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_LP_CONSOLE is not set +# CONFIG_LSI_ET1011C_PHY is not set +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" +# CONFIG_LTC1660 is not set +# CONFIG_LTC2471 is not set +# CONFIG_LTC2485 is not set +# CONFIG_LTC2497 is not set +# CONFIG_LTC2632 is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_LTPC is not set +# CONFIG_LTR501 is not set +# CONFIG_LUSTRE_FS is not set +# CONFIG_LV0104CS is not set +# CONFIG_LWTUNNEL is not set +# CONFIG_LXT_PHY is not set +# CONFIG_LZ4HC_COMPRESS is not set +# CONFIG_LZ4_COMPRESS is not set +# CONFIG_LZ4_DECOMPRESS is not set +CONFIG_LZMA_COMPRESS=y +CONFIG_LZMA_DECOMPRESS=y +# CONFIG_LZO_COMPRESS is not set +# CONFIG_LZO_DECOMPRESS is not set +# CONFIG_M62332 is not set +# CONFIG_MAC80211 is not set +# CONFIG_MAC80211_MESSAGE_TRACING is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +# CONFIG_MACB is not set +# CONFIG_MACH_ASM9260 is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_INGENIC is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_MACH_JZ4740 is not set +# CONFIG_MACH_LOONGSON32 is not set +# CONFIG_MACH_LOONGSON64 is not set +# CONFIG_MACH_PIC32 is not set +# CONFIG_MACH_PISTACHIO is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_MACH_XILFPGA is not set +# CONFIG_MACINTOSH_DRIVERS is not set +# CONFIG_MACSEC is not set +# CONFIG_MACVLAN is not set +# CONFIG_MACVTAP is not set +# CONFIG_MAC_EMUMOUSEBTN is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MAG3110 is not set +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +# CONFIG_MAGIC_SYSRQ_SERIAL is not set +# CONFIG_MAILBOX is not set +# CONFIG_MANAGER_SBS is not set +# CONFIG_MANDATORY_FILE_LOCKING is not set +# CONFIG_MANGLE_BOOTARGS is not set +# CONFIG_MARVELL_10G_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX11100 is not set +# CONFIG_MAX1118 is not set +# CONFIG_MAX1363 is not set +# CONFIG_MAX30100 is not set +# CONFIG_MAX30102 is not set +# CONFIG_MAX31856 is not set +# CONFIG_MAX44000 is not set +# CONFIG_MAX44009 is not set +# CONFIG_MAX517 is not set +# CONFIG_MAX5432 is not set +# CONFIG_MAX5481 is not set +# CONFIG_MAX5487 is not set +# CONFIG_MAX5821 is not set +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_MAX9611 is not set +# CONFIG_MAXIM_THERMOCOUPLE is not set +CONFIG_MAY_USE_DEVLINK=y +# CONFIG_MB1232 is not set +# CONFIG_MC3230 is not set +# CONFIG_MCB is not set +# CONFIG_MCP320X is not set +# CONFIG_MCP3422 is not set +# CONFIG_MCP3911 is not set +# CONFIG_MCP4018 is not set +# CONFIG_MCP41010 is not set +# CONFIG_MCP4131 is not set +# CONFIG_MCP4531 is not set +# CONFIG_MCP4725 is not set +# CONFIG_MCP4922 is not set +# CONFIG_MCPM is not set +# CONFIG_MD is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set +# CONFIG_MDIO_DEVICE is not set +# CONFIG_MDIO_HISI_FEMAC is not set +# CONFIG_MDIO_MSCC_MIIM is not set +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_THUNDER is not set +# CONFIG_MD_FAULTY is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_ATTACH is not set +# CONFIG_MEDIA_CAMERA_SUPPORT is not set +# CONFIG_MEDIA_CEC_SUPPORT is not set +# CONFIG_MEDIA_CONTROLLER is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_PCI_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_RC_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +# CONFIG_MEDIA_SUPPORT is not set +# CONFIG_MEDIA_USB_SUPPORT is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_MELLANOX_PLATFORM is not set +CONFIG_MEMBARRIER=y +# CONFIG_MEMORY is not set +# CONFIG_MEMORY_FAILURE is not set +# CONFIG_MEMSTICK is not set +# CONFIG_MEMTEST is not set +# CONFIG_MEN_A21_WDT is not set +# CONFIG_MESON_SM is not set +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ACT8945A is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_AXP20X is not set +# CONFIG_MFD_AXP20X_I2C is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_CPCAP is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_MFD_CS5535 is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_EXYNOS_LPASS is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_LOCHNAGAR is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_MADERA is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77620 is not set +# CONFIG_MFD_MAX77650 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_OMAP_USB_HOST is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_PM8921_CORE is not set +# CONFIG_MFD_PM8XXX is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_RK808 is not set +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_ROHM_BD70528 is not set +# CONFIG_MFD_ROHM_BD718XX is not set +# CONFIG_MFD_ROHM_BD70528 is not set +# CONFIG_MFD_STPMIC1 is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RTSX_PCI is not set +# CONFIG_MFD_RTSX_USB is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_MFD_STMFX is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_STPMIC1 is not set +# CONFIG_MFD_SYSCON is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS68470 is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_MFD_TQMX86 is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_MFD_LOCHNAGAR is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MG_DISK is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_MICROCHIP_KSZ is not set +# CONFIG_MICROCHIP_PHY is not set +# CONFIG_MICROCHIP_T1_PHY is not set +# CONFIG_MICROSEMI_PHY is not set +# CONFIG_MIGRATION is not set +CONFIG_MII=y +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_MINIX_FS is not set +# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_MIPS_ALCHEMY is not set +# CONFIG_MIPS_CDMM is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MIPS_FPU_EMULATOR is not set +# CONFIG_MIPS_FP_SUPPORT is not set +# CONFIG_MIPS_GENERIC is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_O32_FP64_SUPPORT is not set +# CONFIG_MIPS_PARAVIRT is not set +# CONFIG_MIPS_PLATFORM_DEVICES is not set +# CONFIG_MIPS_SEAD3 is not set +# CONFIG_MISC_ALCOR_PCI is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_MISC_RTSX_PCI is not set +# CONFIG_MISC_RTSX_USB is not set +# CONFIG_MISDN is not set +# CONFIG_MISDN_AVMFRITZ is not set +# CONFIG_MISDN_HFCPCI is not set +# CONFIG_MISDN_HFCUSB is not set +# CONFIG_MISDN_INFINEON is not set +# CONFIG_MISDN_NETJET is not set +# CONFIG_MISDN_SPEEDFAX is not set +# CONFIG_MISDN_W6692 is not set +# CONFIG_MKISS is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX5_CORE is not set +# CONFIG_MLX90614 is not set +# CONFIG_MLX90632 is not set +# CONFIG_MLXFW is not set +# CONFIG_MLXSW_CORE is not set +# CONFIG_MLX_CPLD_PLATFORM is not set +# CONFIG_MLX_PLATFORM is not set +# CONFIG_MMA7455_I2C is not set +# CONFIG_MMA7455_SPI is not set +# CONFIG_MMA7660 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MMC is not set +# CONFIG_MMC35240 is not set +# CONFIG_MMC_ARMMMCI is not set +# CONFIG_MMC_STM32_SDMMC is not set +# CONFIG_MMC_AU1X is not set +# CONFIG_MMC_BLOCK is not set +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_MMC_BLOCK_MINORS=8 +# CONFIG_MMC_CAVIUM_THUNDERX is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_CQHCI is not set +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_DW is not set +# CONFIG_MMC_JZ4740 is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MMC_MVSDIO is not set +# CONFIG_MMC_S3C is not set +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SDHCI_ACPI is not set +# CONFIG_MMC_SDHCI_AM654 is not set +# CONFIG_MMC_SDHCI_BCM_KONA is not set +# CONFIG_MMC_SDHCI_CADENCE is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set +# CONFIG_MMC_SDHCI_IPROC is not set +# CONFIG_MMC_SDHCI_MSM is not set +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_ASPEED is not set +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set +# CONFIG_MMC_SDHCI_OF_ESDHC is not set +# CONFIG_MMC_SDHCI_OF_HLWD is not set +# CONFIG_MMC_SDHCI_OMAP is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_S3C is not set +# CONFIG_MMC_SDHCI_XENON is not set +# CONFIG_MMC_SDRICOH_CS is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_TEST is not set +# CONFIG_MMC_TOSHIBA_PCI is not set +# CONFIG_MMC_USDHI6ROL0 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMIOTRACE is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +# CONFIG_MODULE_COMPRESS is not set +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_MODULE_STRIPPED=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MOST is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_ELAN_I2C is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_PS2_FOCALTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_SYNAPTICS_USB is not set +# CONFIG_MOXTET is not set +# CONFIG_MPL115 is not set +# CONFIG_MPL115_I2C is not set +# CONFIG_MPL115_SPI is not set +# CONFIG_MPL3115 is not set +# CONFIG_MPLS is not set +# CONFIG_MPU3050_I2C is not set +# CONFIG_MQ_IOSCHED_DEADLINE is not set +# CONFIG_MQ_IOSCHED_KYBER is not set +# CONFIG_MS5611 is not set +# CONFIG_MS5637 is not set +# CONFIG_MSCC_OCELOT_SWITCH is not set +# CONFIG_MSDOS_FS is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_MSI_BITMAP_SELFTEST is not set +# CONFIG_MSI_LAPTOP is not set +CONFIG_MTD=y +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_MTD_BLOCK2MTD is not set +CONFIG_MTD_CFI=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_DOCG3 is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_HYPERBUS is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_JEDECPROBE is not set +# CONFIG_MTD_LATCH_ADDR is not set +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_LPDDR2_NVM is not set +# CONFIG_MTD_M25P80 is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MCHP23K256 is not set +# CONFIG_MTD_MT81xx_NOR is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_MYLOADER_PARTS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_NAND_AMS_DELTA is not set +# CONFIG_MTD_NAND_AR934X is not set +# CONFIG_MTD_NAND_AR934X_HW_ECC is not set +# CONFIG_MTD_NAND_ATMEL is not set +# CONFIG_MTD_NAND_AU1550 is not set +# CONFIG_MTD_NAND_BCH is not set +# CONFIG_MTD_NAND_BF5XX is not set +# CONFIG_MTD_NAND_BRCMNAND is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_CM_X270 is not set +# CONFIG_MTD_NAND_CS553X is not set +# CONFIG_MTD_NAND_DAVINCI is not set +# CONFIG_MTD_NAND_DENALI is not set +# CONFIG_MTD_NAND_DENALI_DT is not set +# CONFIG_MTD_NAND_DENALI_PCI is not set +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018 +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_DOCG4 is not set +# CONFIG_MTD_NAND_ECC is not set +# CONFIG_MTD_NAND_ECC_BCH is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_ECC_SW_BCH is not set +# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set +# CONFIG_MTD_NAND_FSL_ELBC is not set +# CONFIG_MTD_NAND_FSL_IFC is not set +# CONFIG_MTD_NAND_FSL_UPM is not set +# CONFIG_MTD_NAND_FSMC is not set +# CONFIG_MTD_NAND_GPIO is not set +# CONFIG_MTD_NAND_GPMI_NAND is not set +# CONFIG_MTD_NAND_HISI504 is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_JZ4740 is not set +# CONFIG_MTD_NAND_MPC5121_NFC is not set +# CONFIG_MTD_NAND_MTK is not set +# CONFIG_MTD_NAND_MXC is not set +# CONFIG_MTD_NAND_MXIC is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_NDFC is not set +# CONFIG_MTD_NAND_NUC900 is not set +# CONFIG_MTD_NAND_OMAP2 is not set +# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set +# CONFIG_MTD_NAND_ORION is not set +# CONFIG_MTD_NAND_PASEMI is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_NAND_PXA3xx is not set +# CONFIG_MTD_NAND_RB4XX is not set +# CONFIG_MTD_NAND_RB750 is not set +# CONFIG_MTD_NAND_RICOH is not set +# CONFIG_MTD_NAND_S3C2410 is not set +# CONFIG_MTD_NAND_SHARPSL is not set +# CONFIG_MTD_NAND_SH_FLCTL is not set +# CONFIG_MTD_NAND_SOCRATES is not set +# CONFIG_MTD_NAND_TMIO is not set +# CONFIG_MTD_NAND_TXX9NDFMC is not set +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_PARTITIONED_MASTER is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_PHYSMAP_GEMINI is not set +# CONFIG_MTD_PHYSMAP_GPIO_ADDR is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set +# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set +# CONFIG_MTD_PHYSMAP_VERSATILE is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_RAW_NAND is not set +# CONFIG_MTD_NAND_ECC_SW_BCH is not set +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_ROM is not set +CONFIG_MTD_ROOTFS_ROOT_DEV=y +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_SPINAND_MT29F is not set +# CONFIG_MTD_SPI_NAND is not set +# CONFIG_MTD_SPI_NOR is not set +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=4096 +CONFIG_MTD_SPLIT=y +# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set +# CONFIG_MTD_SPLIT_EVA_FW is not set +# CONFIG_MTD_SPLIT_FIRMWARE is not set +CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware" +# CONFIG_MTD_SPLIT_FIT_FW is not set +# CONFIG_MTD_SPLIT_JIMAGE_FW is not set +# CONFIG_MTD_SPLIT_LZMA_FW is not set +# CONFIG_MTD_SPLIT_MINOR_FW is not set +# CONFIG_MTD_SPLIT_SEAMA_FW is not set +CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y +CONFIG_MTD_SPLIT_SUPPORT=y +# CONFIG_MTD_SPLIT_TPLINK_FW is not set +# CONFIG_MTD_SPLIT_TRX_FW is not set +# CONFIG_MTD_SPLIT_UIMAGE_FW is not set +# CONFIG_MTD_SPLIT_WRGG_FW is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SWAP is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UIMAGE_SPLIT is not set +# CONFIG_MTD_VIRT_CONCAT is not set +# CONFIG_MTK_MMC is not set +CONFIG_MULTIUSER=y +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_MV643XX_ETH is not set +# CONFIG_MVMDIO is not set +# CONFIG_MVNETA_BM is not set +# CONFIG_MVSW61XX_PHY is not set +# CONFIG_MVSWITCH_PHY is not set +# CONFIG_MV_XOR_V2 is not set +# CONFIG_MWAVE is not set +# CONFIG_MWL8K is not set +# CONFIG_MXC4005 is not set +# CONFIG_MXC6255 is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_NATSEMI is not set +# CONFIG_NAU7802 is not set +# CONFIG_NBPFAXI_DMA is not set +# CONFIG_NCP_FS is not set +# CONFIG_NE2000 is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NEC_MARKEINS is not set +CONFIG_NET=y +# CONFIG_NETCONSOLE is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVSIM is not set +# CONFIG_NETFILTER is not set +# CONFIG_NETFILTER_ADVANCED is not set +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_INGRESS is not set +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NETFILTER_NETLINK_ACCT is not set +# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NETFILTER_NETLINK_OSF is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_XTABLES is not set +# CONFIG_NETFILTER_XT_CONNMARK is not set +# CONFIG_NETFILTER_XT_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ECN is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set +# CONFIG_NETFILTER_XT_MATCH_STATE is not set +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_CT is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_NETLINK_MMAP is not set +# CONFIG_NETPOLL is not set +# CONFIG_NETROM is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NET_9P is not set +# CONFIG_NET_ACT_BPF is not set +# CONFIG_NET_ACT_CSUM is not set +# CONFIG_NET_ACT_CT is not set +# CONFIG_NET_ACT_GACT is not set +# CONFIG_NET_ACT_IFE is not set +# CONFIG_NET_ACT_IPT is not set +# CONFIG_NET_ACT_MIRRED is not set +# CONFIG_NET_ACT_MPLS is not set +# CONFIG_NET_ACT_NAT is not set +# CONFIG_NET_ACT_PEDIT is not set +# CONFIG_NET_ACT_POLICE is not set +# CONFIG_NET_ACT_SAMPLE is not set +# CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set +# CONFIG_NET_ACT_SKBMOD is not set +# CONFIG_NET_ACT_TUNNEL_KEY is not set +# CONFIG_NET_ACT_VLAN is not set +CONFIG_NET_CADENCE=y +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_CLS=y +# CONFIG_NET_CLS_ACT is not set +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_BPF is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_FLOWER is not set +# CONFIG_NET_CLS_FW is not set +CONFIG_NET_CLS_IND=y +# CONFIG_NET_CLS_MATCHALL is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_U32 is not set +CONFIG_NET_CORE=y +# CONFIG_NET_DEVLINK is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_NET_DSA is not set +# CONFIG_NET_DSA_BCM_SF2 is not set +# CONFIG_NET_DSA_LANTIQ_GSWIP is not set +# CONFIG_NET_DSA_LEGACY is not set +# CONFIG_NET_DSA_LOOP is not set +# CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set +# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set +# CONFIG_NET_DSA_MT7530 is not set +# CONFIG_NET_DSA_MV88E6060 is not set +# CONFIG_NET_DSA_MV88E6123_61_65 is not set +# CONFIG_NET_DSA_MV88E6131 is not set +# CONFIG_NET_DSA_MV88E6171 is not set +# CONFIG_NET_DSA_MV88E6352 is not set +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +# CONFIG_NET_DSA_QCA8K is not set +# CONFIG_NET_DSA_REALTEK_SMI is not set +# CONFIG_NET_DSA_SJA1105 is not set +# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set +# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set +# CONFIG_NET_DSA_TAG_8021Q is not set +# CONFIG_NET_DSA_TAG_BRCM is not set +# CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set +# CONFIG_NET_DSA_TAG_DSA is not set +# CONFIG_NET_DSA_TAG_EDSA is not set +# CONFIG_NET_DSA_TAG_GSWIP is not set +# CONFIG_NET_DSA_TAG_KSZ is not set +# CONFIG_NET_DSA_TAG_LAN9303 is not set +# CONFIG_NET_DSA_TAG_MTK is not set +# CONFIG_NET_DSA_TAG_QCA is not set +# CONFIG_NET_DSA_TAG_SJA1105 is not set +# CONFIG_NET_DSA_TAG_TRAILER is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_EMATCH_CANID is not set +# CONFIG_NET_EMATCH_CMP is not set +# CONFIG_NET_EMATCH_IPT is not set +# CONFIG_NET_EMATCH_META is not set +# CONFIG_NET_EMATCH_NBYTE is not set +CONFIG_NET_EMATCH_STACK=32 +# CONFIG_NET_EMATCH_TEXT is not set +# CONFIG_NET_EMATCH_U32 is not set +# CONFIG_NET_FAILOVER is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_FOU is not set +# CONFIG_NET_FOU_IP_TUNNELS is not set +# CONFIG_NET_IFE is not set +# CONFIG_NET_IPGRE is not set +CONFIG_NET_IPGRE_BROADCAST=y +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPVTI is not set +# CONFIG_NET_IP_TUNNEL is not set +# CONFIG_NET_KEY is not set +# CONFIG_NET_KEY_MIGRATE is not set +# CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_NET_MPLS_GSO is not set +# CONFIG_NET_NCSI is not set +# CONFIG_NET_NSH is not set +# CONFIG_NET_PACKET_ENGINE is not set +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_NET_PTP_CLASSIFY is not set +CONFIG_NET_RX_BUSY_POLL=y +# CONFIG_NET_SB1000 is not set +CONFIG_NET_SCHED=y +# CONFIG_NET_SCH_ATM is not set +# CONFIG_NET_SCH_CAKE is not set +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_CBS is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_CODEL is not set +# CONFIG_NET_SCH_DEFAULT is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_ETF is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_NET_SCH_FQ is not set +CONFIG_NET_SCH_FQ_CODEL=y +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_HHF is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_INGRESS is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_PIE is not set +# CONFIG_NET_SCH_PLUG is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_QFQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_SKBPRIO is not set +# CONFIG_NET_SCH_TAPRIO is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCTPPROBE is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_TC_SKB_EXT is not set +# CONFIG_NET_TEAM is not set +# CONFIG_NET_TULIP is not set +# CONFIG_NET_UDP_TUNNEL is not set +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_8390=y +CONFIG_NET_VENDOR_ADAPTEC=y +CONFIG_NET_VENDOR_AGERE=y +CONFIG_NET_VENDOR_ALACRITECH=y +CONFIG_NET_VENDOR_ALTEON=y +CONFIG_NET_VENDOR_AMAZON=y +CONFIG_NET_VENDOR_AMD=y +CONFIG_NET_VENDOR_AQUANTIA=y +CONFIG_NET_VENDOR_ARC=y +CONFIG_NET_VENDOR_ATHEROS=y +CONFIG_NET_VENDOR_AURORA=y +CONFIG_NET_VENDOR_BROADCOM=y +CONFIG_NET_VENDOR_BROCADE=y +CONFIG_NET_VENDOR_CADENCE=y +CONFIG_NET_VENDOR_CAVIUM=y +CONFIG_NET_VENDOR_CHELSIO=y +CONFIG_NET_VENDOR_CIRRUS=y +CONFIG_NET_VENDOR_CISCO=y +CONFIG_NET_VENDOR_CORTINA=y +CONFIG_NET_VENDOR_DEC=y +CONFIG_NET_VENDOR_DLINK=y +CONFIG_NET_VENDOR_EMULEX=y +CONFIG_NET_VENDOR_EXAR=y +CONFIG_NET_VENDOR_EZCHIP=y +CONFIG_NET_VENDOR_FARADAY=y +CONFIG_NET_VENDOR_FREESCALE=y +CONFIG_NET_VENDOR_FUJITSU=y +CONFIG_NET_VENDOR_GOOGLE=y +# CONFIG_GVE is not set +CONFIG_NET_VENDOR_HISILICON=y +CONFIG_NET_VENDOR_HP=y +CONFIG_NET_VENDOR_HUAWEI=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_IBM=y +CONFIG_NET_VENDOR_INTEL=y +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_NET_VENDOR_MELLANOX=y +CONFIG_NET_VENDOR_MICREL=y +CONFIG_NET_VENDOR_MICROCHIP=y +CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_NET_VENDOR_MYRI=y +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NET_VENDOR_NETERION=y +CONFIG_NET_VENDOR_NETRONOME=y +CONFIG_NET_VENDOR_NI=y +CONFIG_NET_VENDOR_NVIDIA=y +CONFIG_NET_VENDOR_OKI=y +CONFIG_NET_VENDOR_PACKET_ENGINES=y +CONFIG_NET_VENDOR_PENSANDO=y +CONFIG_NET_VENDOR_QLOGIC=y +CONFIG_NET_VENDOR_QUALCOMM=y +CONFIG_NET_VENDOR_RDC=y +CONFIG_NET_VENDOR_REALTEK=y +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_NET_VENDOR_SAMSUNG=y +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SILAN=y +CONFIG_NET_VENDOR_SIS=y +CONFIG_NET_VENDOR_SMSC=y +CONFIG_NET_VENDOR_SOCIONEXT=y +CONFIG_NET_VENDOR_SOLARFLARE=y +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_NET_VENDOR_SUN=y +CONFIG_NET_VENDOR_SYNOPSYS=y +CONFIG_NET_VENDOR_TEHUTI=y +CONFIG_NET_VENDOR_TI=y +CONFIG_NET_VENDOR_TOSHIBA=y +CONFIG_NET_VENDOR_VIA=y +CONFIG_NET_VENDOR_WIZNET=y +CONFIG_NET_VENDOR_XILINX=y +CONFIG_NET_VENDOR_XIRCOM=y +# CONFIG_NET_VRF is not set +# CONFIG_NET_XGENE is not set +CONFIG_NEW_LEDS=y +# CONFIG_NFC is not set +# CONFIG_NFP is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V2_ACL is not set +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +# CONFIG_NFS_ACL_SUPPORT is not set +CONFIG_NFS_COMMON=y +# CONFIG_NFS_FS is not set +# CONFIG_NFS_FSCACHE is not set +# CONFIG_NFS_SWAP is not set +# CONFIG_NFS_V2 is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_V4_1 is not set +# CONFIG_NFTL is not set +# CONFIG_NFT_BRIDGE_META is not set +# CONFIG_NFT_BRIDGE_REJECT is not set +# CONFIG_NFT_CONNLIMIT is not set +# CONFIG_NFT_DUP_IPV4 is not set +# CONFIG_NFT_DUP_IPV6 is not set +# CONFIG_NFT_FIB_IPV4 is not set +# CONFIG_NFT_FIB_IPV6 is not set +# CONFIG_NFT_FIB_NETDEV is not set +# CONFIG_NFT_FLOW_OFFLOAD is not set +# CONFIG_NFT_OBJREF is not set +# CONFIG_NFT_OSF is not set +# CONFIG_NFT_RT is not set +# CONFIG_NFT_SET_BITMAP is not set +# CONFIG_NFT_SOCKET is not set +# CONFIG_NFT_SYNPROXY is not set +# CONFIG_NFT_TPROXY is not set +# CONFIG_NFT_TUNNEL is not set +# CONFIG_NFT_XFRM is not set +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +# CONFIG_NF_CONNTRACK_BRIDGE is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_FTP is not set +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IPV4 is not set +# CONFIG_NF_CONNTRACK_IPV6 is not set +# CONFIG_NF_CONNTRACK_IRC is not set +# CONFIG_NF_CONNTRACK_LABELS is not set +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +CONFIG_NF_CONNTRACK_PROCFS=y +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_TFTP is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CONNTRACK_ZONES is not set +# CONFIG_NF_CT_NETLINK is not set +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_GRE is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_DEFRAG_IPV4 is not set +# CONFIG_NF_DUP_IPV4 is not set +# CONFIG_NF_DUP_IPV6 is not set +# CONFIG_NF_FLOW_TABLE is not set +# CONFIG_NF_LOG_ARP is not set +# CONFIG_NF_LOG_BRIDGE is not set +# CONFIG_NF_LOG_IPV4 is not set +# CONFIG_NF_LOG_NETDEV is not set +# CONFIG_NF_NAT is not set +# CONFIG_NF_NAT_AMANDA is not set +# CONFIG_NF_NAT_FTP is not set +# CONFIG_NF_NAT_H323 is not set +# CONFIG_NF_NAT_IPV6 is not set +# CONFIG_NF_NAT_IRC is not set +CONFIG_NF_NAT_MASQUERADE_IPV4=y +CONFIG_NF_NAT_MASQUERADE_IPV6=y +# CONFIG_NF_NAT_NEEDED is not set +# CONFIG_NF_NAT_PPTP is not set +# CONFIG_NF_NAT_PROTO_GRE is not set +# CONFIG_NF_NAT_SIP is not set +# CONFIG_NF_NAT_SNMP_BASIC is not set +# CONFIG_NF_NAT_TFTP is not set +# CONFIG_NF_REJECT_IPV4 is not set +# CONFIG_NF_REJECT_IPV6 is not set +# CONFIG_NF_SOCKET_IPV4 is not set +# CONFIG_NF_SOCKET_IPV6 is not set +# CONFIG_NF_TABLES is not set +CONFIG_NF_TABLES_ARP=y +CONFIG_NF_TABLES_BRIDGE=y +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_IPV4=y +CONFIG_NF_TABLES_IPV6=y +CONFIG_NF_TABLES_NETDEV=y +# CONFIG_NF_TABLES_SET is not set +# CONFIG_NF_TPROXY_IPV4 is not set +# CONFIG_NF_TPROXY_IPV6 is not set +# CONFIG_NI65 is not set +# CONFIG_NI903X_WDT is not set +# CONFIG_NIC7018_WDT is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_NIU is not set +# CONFIG_NI_XGE_MANAGEMENT_ENET is not set +CONFIG_NLATTR=y +# CONFIG_NLMON is not set +# CONFIG_NLM_XLP_BOARD is not set +# CONFIG_NLM_XLR_BOARD is not set +# CONFIG_NLS is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +# CONFIG_NLS_UTF8 is not set +CONFIG_NMI_LOG_BUF_SHIFT=13 +# CONFIG_NOA1305 is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_NORTEL_HERMES is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set +# CONFIG_NOZOMI is not set +# CONFIG_NO_BOOTMEM is not set +# CONFIG_NO_HZ is not set +# CONFIG_NO_HZ_FULL is not set +# CONFIG_NO_HZ_IDLE is not set +# CONFIG_NS83820 is not set +# CONFIG_NTB is not set +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_NTP_PPS is not set +# CONFIG_NULL_TTY is not set +# CONFIG_NVM is not set +# CONFIG_NVMEM is not set +# CONFIG_NVMEM_BCM_OCOTP is not set +# CONFIG_NVMEM_IMX_OCOTP is not set +# CONFIG_NVMEM_SYSFS is not set +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TARGET is not set +# CONFIG_NVRAM is not set +# CONFIG_NV_TCO is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set +# CONFIG_NXP_TJA11XX_PHY is not set +# CONFIG_N_GSM is not set +# CONFIG_OABI_COMPAT is not set +# CONFIG_OBS600 is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_OF_OVERLAY is not set +CONFIG_OF_RESERVED_MEM=y +# CONFIG_OF_UNITTEST is not set +# CONFIG_OMAP2_DSS_DEBUG is not set +# CONFIG_OMAP2_DSS_DEBUGFS is not set +# CONFIG_OMAP2_DSS_SDI is not set +# CONFIG_OMAP_OCP2SCP is not set +# CONFIG_OMAP_USB2 is not set +# CONFIG_OMFS_FS is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_OPROFILE is not set +# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set +# CONFIG_OPT3001 is not set +CONFIG_OPTIMIZE_INLINING=y +# CONFIG_ORANGEFS_FS is not set +# CONFIG_ORION_WATCHDOG is not set +# CONFIG_OSF_PARTITION is not set +CONFIG_OVERLAY_FS=y +# CONFIG_OVERLAY_FS_INDEX is not set +# CONFIG_OVERLAY_FS_METACOPY is not set +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +CONFIG_OVERLAY_FS_XINO_AUTO=y +# CONFIG_OWL_LOADER is not set +# CONFIG_P54_COMMON is not set +# CONFIG_PA12203001 is not set +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +# CONFIG_PACKING is not set +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_32KB is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_64KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PALMAS_GPADC is not set +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_PANEL is not set +CONFIG_PANIC_ON_OOPS=y +CONFIG_PANIC_ON_OOPS_VALUE=1 +CONFIG_PANIC_TIMEOUT=1 +# CONFIG_PANTHERLORD_FF is not set +# CONFIG_PARAVIRT is not set +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +# CONFIG_PARPORT is not set +# CONFIG_PARPORT_1284 is not set +# CONFIG_PARPORT_AX88796 is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_PC is not set +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARASAN_CF is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5535 is not set +# CONFIG_PATA_CS5536 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IMX is not set +# CONFIG_PATA_ISAPNP is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OCTEON_CF is not set +# CONFIG_PATA_OF_PLATFORM is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PCMCIA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_QDI is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_WINBOND_VLB is not set +# CONFIG_PC104 is not set +# CONFIG_PC300TOO is not set +# CONFIG_PCCARD is not set +# CONFIG_PCH_DMA is not set +# CONFIG_PCH_GBE is not set +# CONFIG_PCH_PHUB is not set +# CONFIG_PCI is not set +# CONFIG_PCI200SYN is not set +# CONFIG_PCIEAER_INJECT is not set +# CONFIG_PCIEASPM is not set +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCIE_ALTERA is not set +# CONFIG_PCIE_ARMADA_8K is not set +# CONFIG_PCIE_BW is not set +# CONFIG_PCIE_CADENCE_HOST is not set +# CONFIG_PCIE_DPC is not set +# CONFIG_PCIE_DW_PLAT is not set +# CONFIG_PCIE_DW_PLAT_HOST is not set +# CONFIG_PCIE_ECRC is not set +# CONFIG_PCIE_IPROC is not set +# CONFIG_PCIE_KIRIN is not set +# CONFIG_PCIE_PTM is not set +# CONFIG_PCIE_XILINX is not set +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_PCI_ATMEL is not set +# CONFIG_PCI_CNB20LE_QUIRK is not set +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set +# CONFIG_PCI_ENDPOINT is not set +# CONFIG_PCI_ENDPOINT_TEST is not set +# CONFIG_PCI_FTPCI100 is not set +# CONFIG_PCI_HERMES is not set +# CONFIG_PCI_HISI is not set +# CONFIG_PCI_HOST_GENERIC is not set +# CONFIG_PCI_HOST_THUNDER_ECAM is not set +# CONFIG_PCI_HOST_THUNDER_PEM is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCI_LAYERSCAPE is not set +# CONFIG_PCI_MESON is not set +# CONFIG_PCI_MSI is not set +# CONFIG_PCI_PASID is not set +# CONFIG_PCI_PF_STUB is not set +# CONFIG_PCI_PRI is not set +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_SW_SWITCHTEC is not set +CONFIG_PCI_SYSCALL=y +# CONFIG_PCI_V3_SEMI is not set +# CONFIG_PCI_XGENE is not set +# CONFIG_PCMCIA is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_ATMEL is not set +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_PCMCIA_DEBUG is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_HERMES is not set +# CONFIG_PCMCIA_LOAD_CIS is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_SPECTRUM is not set +# CONFIG_PCMCIA_SYM53C500 is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_XIRCOM is not set +# CONFIG_PCNET32 is not set +# CONFIG_PCSPKR_PLATFORM is not set +# CONFIG_PD6729 is not set +# CONFIG_PDA_POWER is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PERCPU_STATS is not set +# CONFIG_PERCPU_TEST is not set +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_EVENTS_AMD_POWER is not set +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_PHANTOM is not set +# CONFIG_PHONET is not set +# CONFIG_PHYLIB is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +# CONFIG_PHY_CADENCE_DP is not set +# CONFIG_PHY_CADENCE_DPHY is not set +# CONFIG_PHY_CADENCE_SIERRA is not set +# CONFIG_PHY_CPCAP_USB is not set +# CONFIG_PHY_EXYNOS_DP_VIDEO is not set +# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set +# CONFIG_PHY_FSL_IMX8MQ_USB is not set +# CONFIG_PHY_MAPPHONE_MDM6600 is not set +# CONFIG_PHY_MIXEL_MIPI_DPHY is not set +# CONFIG_PHY_OCELOT_SERDES is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_QCOM_DWC3 is not set +# CONFIG_PHY_QCOM_USB_HS is not set +# CONFIG_PHY_QCOM_USB_HSIC is not set +# CONFIG_PHY_SAMSUNG_USB2 is not set +# CONFIG_PHY_TUSB1210 is not set +# CONFIG_PHY_XGENE is not set +# CONFIG_PI433 is not set +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_PID_NS is not set +CONFIG_PINCONF=y +# CONFIG_PINCTRL is not set +# CONFIG_PINCTRL_AMD is not set +# CONFIG_PINCTRL_AXP209 is not set +# CONFIG_PINCTRL_CEDARFORK is not set +# CONFIG_PINCTRL_EXYNOS is not set +# CONFIG_PINCTRL_EXYNOS5440 is not set +# CONFIG_PINCTRL_ICELAKE is not set +# CONFIG_PINCTRL_INGENIC is not set +# CONFIG_PINCTRL_MCP23S08 is not set +# CONFIG_PINCTRL_MSM8X74 is not set +# CONFIG_PINCTRL_OCELOT is not set +CONFIG_PINCTRL_SINGLE=y +# CONFIG_PINCTRL_STMFX is not set +# CONFIG_PINCTRL_SX150X is not set +CONFIG_PINMUX=y +# CONFIG_PKCS7_MESSAGE_PARSER is not set +# CONFIG_PL320_MBOX is not set +# CONFIG_PL330_DMA is not set +# CONFIG_PLATFORM_MHU is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_PLIP is not set +CONFIG_PLUGIN_HOSTCC="" +# CONFIG_PLX_HERMES is not set +# CONFIG_PM is not set +# CONFIG_PMBUS is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_PM_WAKELOCKS is not set +# CONFIG_POSIX_MQUEUE is not set +CONFIG_POSIX_TIMERS=y +# CONFIG_POWERCAP is not set +# CONFIG_POWER_AVS is not set +# CONFIG_POWER_RESET is not set +# CONFIG_POWER_RESET_BRCMKONA is not set +# CONFIG_POWER_RESET_BRCMSTB is not set +# CONFIG_POWER_RESET_GPIO is not set +# CONFIG_POWER_RESET_GPIO_RESTART is not set +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_PIIX4_POWEROFF is not set +# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +# CONFIG_POWER_RESET_VERSATILE is not set +# CONFIG_POWER_RESET_XGENE is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_POWER_SUPPLY_HWMON is not set +# CONFIG_PPC4xx_GPIO is not set +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_256K_PAGES is not set +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_64K_PAGES is not set +# CONFIG_PPC_DISABLE_WERROR is not set +# CONFIG_PPC_EMULATED_STATS is not set +# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set +# CONFIG_PPP is not set +# CONFIG_PPPOATM is not set +# CONFIG_PPPOE is not set +# CONFIG_PPPOL2TP is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_DEFLATE is not set +CONFIG_PPP_FILTER=y +# CONFIG_PPP_MPPE is not set +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPS is not set +# CONFIG_PPS_CLIENT_GPIO is not set +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_PARPORT is not set +# CONFIG_PPS_DEBUG is not set +# CONFIG_PPTP is not set +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_PREEMPTIRQ_EVENTS is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTK=y +# CONFIG_PRINTK_CALLER is not set +CONFIG_PRINTK_NMI=y +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 +# CONFIG_PRINTK_TIME is not set +CONFIG_PRINT_STACK_DEPTH=64 +# CONFIG_PRISM2_USB is not set +# CONFIG_PRISM54 is not set +# CONFIG_PROC_CHILDREN is not set +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_PROC_STRIPPED=y +CONFIG_PROC_SYSCTL=y +# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILING is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_PROVE_RCU is not set +# CONFIG_PROVE_RCU_REPEATEDLY is not set +# CONFIG_PSAMPLE is not set +# CONFIG_PSB6970_PHY is not set +# CONFIG_PSI is not set +# CONFIG_PSTORE is not set +# CONFIG_PTP_1588_CLOCK is not set +# CONFIG_PTP_1588_CLOCK_IXP46X is not set +# CONFIG_PTP_1588_CLOCK_KVM is not set +# CONFIG_PTP_1588_CLOCK_PCH is not set +# CONFIG_PUBLIC_KEY_ALGO_RSA is not set +# CONFIG_PVPANIC is not set +# CONFIG_PWM is not set +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWRSEQ_EMMC=y +# CONFIG_PWRSEQ_SD8787 is not set +CONFIG_PWRSEQ_SIMPLE=y +# CONFIG_QCA7000 is not set +# CONFIG_QCA7000_SPI is not set +# CONFIG_QCA7000_UART is not set +# CONFIG_QCOM_EMAC is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set +# CONFIG_QCOM_HIDMA is not set +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set +# CONFIG_QCOM_SPMI_ADC5 is not set +# CONFIG_QCOM_SPMI_IADC is not set +# CONFIG_QCOM_SPMI_TEMP_ALARM is not set +# CONFIG_QCOM_SPMI_VADC is not set +# CONFIG_QED is not set +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_QORIQ_CPUFREQ is not set +# CONFIG_QORIQ_THERMAL is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_QUEUED_LOCK_STAT is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_QUOTA_DEBUG is not set +# CONFIG_R3964 is not set +# CONFIG_R6040 is not set +# CONFIG_R8169 is not set +# CONFIG_R8188EU is not set +# CONFIG_R8712U is not set +# CONFIG_R8723AU is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set +# CONFIG_RAID6_PQ_BENCHMARK is not set +# CONFIG_RAID_ATTRS is not set +# CONFIG_RALINK is not set +# CONFIG_RANDOM32_SELFTEST is not set +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set +# CONFIG_RANDOM_TRUST_CPU is not set +# CONFIG_RAPIDIO is not set +# CONFIG_RAS is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_RBTREE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_RCU_EXPEDITE_BOOT is not set +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FANOUT=32 +CONFIG_RCU_FANOUT_LEAF=16 +# CONFIG_RCU_FAST_NO_HZ is not set +CONFIG_RCU_KTHREAD_PRIO=0 +# CONFIG_RCU_NOCB_CPU is not set +# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 +# CONFIG_RCU_TRACE is not set +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_RC_CORE is not set +# CONFIG_RC_DECODERS is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_RC_MAP is not set +# CONFIG_RDS is not set +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_GZIP is not set +# CONFIG_RD_LZ4 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_XZ is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_REDWOOD is not set +# CONFIG_REED_SOLOMON_TEST is not set +# CONFIG_REFCOUNT_FULL is not set +# CONFIG_REGMAP is not set +# CONFIG_REGMAP_I2C is not set +# CONFIG_REGMAP_MMIO is not set +# CONFIG_REGMAP_SPI is not set +# CONFIG_REGULATOR is not set +# CONFIG_REGULATOR_88PG86X is not set +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ANATOP is not set +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FAN53555 is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_GPIO is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_LTC3676 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MCP16502 is not set +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set +# CONFIG_REGULATOR_PV88090 is not set +# CONFIG_REGULATOR_PWM is not set +# CONFIG_REGULATOR_SLG51000 is not set +# CONFIG_REGULATOR_SY8106A is not set +# CONFIG_REGULATOR_SY8824X is not set +# CONFIG_REGULATOR_TI_ABB is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_VCTRL is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_FS_POSIX_ACL is not set +# CONFIG_REISERFS_FS_SECURITY is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_RELAY is not set +# CONFIG_RELOCATABLE is not set +# CONFIG_REMOTEPROC is not set +# CONFIG_RENESAS_PHY is not set +# CONFIG_RESET_ATH79 is not set +# CONFIG_RESET_BERLIN is not set +# CONFIG_RESET_CONTROLLER is not set +# CONFIG_RESET_IMX7 is not set +# CONFIG_RESET_LANTIQ is not set +# CONFIG_RESET_LPC18XX is not set +# CONFIG_RESET_MESON is not set +# CONFIG_RESET_PISTACHIO is not set +# CONFIG_RESET_SOCFPGA is not set +# CONFIG_RESET_STM32 is not set +# CONFIG_RESET_SUNXI is not set +# CONFIG_RESET_TEGRA_BPMP is not set +# CONFIG_RESET_TI_SYSCON is not set +# CONFIG_RESET_ZYNQ is not set +# CONFIG_RFD77402 is not set +# CONFIG_RFD_FTL is not set +CONFIG_RFKILL=y +# CONFIG_RFKILL_FULL is not set +# CONFIG_RFKILL_GPIO is not set +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_LEDS is not set +# CONFIG_RFKILL_REGULATOR is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_RMI4_CORE is not set +# CONFIG_RMNET is not set +# CONFIG_ROCKCHIP_PHY is not set +# CONFIG_ROCKER is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_ROSE is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set +# CONFIG_RPMSG_VIRTIO is not set +# CONFIG_RPR0521 is not set +# CONFIG_RSEQ is not set +# CONFIG_RT2X00 is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABEOZ9 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_ARMADA38X is not set +# CONFIG_RTC_DRV_AU1XXX is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_CADENCE is not set +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1302 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1307_CENTURY is not set +# CONFIG_RTC_DRV_DS1307_HWMON is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_EP93XX is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_FTRTC010 is not set +# CONFIG_RTC_DRV_GENERIC is not set +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12026 is not set +# CONFIG_RTC_DRV_ISL12057 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_MCP795 is not set +# CONFIG_RTC_DRV_MOXART is not set +# CONFIG_RTC_DRV_MPC5121 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_OMAP is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_PS3 is not set +# CONFIG_RTC_DRV_PT7C4338 is not set +# CONFIG_RTC_DRV_R7301 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_RTC7301 is not set +# CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RV8803 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_RX6110 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_SD3078 is not set +# CONFIG_RTC_DRV_SNVS is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_SUN6I is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_XGENE is not set +# CONFIG_RTC_DRV_ZYNQMP is not set +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +# CONFIG_RTC_NVMEM is not set +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTL8180 is not set +# CONFIG_RTL8187 is not set +# CONFIG_RTL8192E is not set +# CONFIG_RTL8192U is not set +# CONFIG_RTL8306_PHY is not set +# CONFIG_RTL8366RB_PHY is not set +# CONFIG_RTL8366S_PHY is not set +# CONFIG_RTL8366_SMI is not set +# CONFIG_RTL8366_SMI_DEBUG_FS is not set +# CONFIG_RTL8367B_PHY is not set +# CONFIG_RTL8367_PHY is not set +# CONFIG_RTLLIB is not set +# CONFIG_RTL_CARDS is not set +# CONFIG_RTS5208 is not set +CONFIG_RT_MUTEXES=y +# CONFIG_RUNTIME_DEBUG is not set +CONFIG_RUNTIME_TESTING_MENU=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_RXKAD=y +# CONFIG_S2IO is not set +# CONFIG_SAMPLES is not set +# CONFIG_SAMSUNG_LAPTOP is not set +# CONFIG_SATA_ACARD_AHCI is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_SATA_DWC is not set +# CONFIG_SATA_FSL is not set +# CONFIG_SATA_HIGHBANK is not set +# CONFIG_SATA_INIC162X is not set +CONFIG_SATA_MOBILE_LPM_POLICY=0 +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PMP is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_RCAR is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SBC_FITPC2_WATCHDOG is not set +CONFIG_SBITMAP=y +# CONFIG_SC92031 is not set +# CONFIG_SCA3000 is not set +# CONFIG_SCACHE_DEBUGFS is not set +# CONFIG_SCC is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHED_HRTICK=y +# CONFIG_SCHED_MC is not set +CONFIG_SCHED_OMIT_FRAME_POINTER=y +# CONFIG_SCHED_SMT is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_SCR24X is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_BNX2X_FCOE is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CHELSIO_FCOE is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_FDOMAIN_PCI is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_HISI_SAS is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_ISCI is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +# CONFIG_SCSI_LPFC is not set +CONFIG_SCSI_MOD=y +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +# CONFIG_SCSI_MQ_DEFAULT is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVSAS_DEBUG is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_MYRB is not set +# CONFIG_SCSI_MYRS is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_PMCRAID is not set +CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SCSI_SMARTPQI is not set +# CONFIG_SCSI_SNIC is not set +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_SCSI_VIRTIO is not set +# CONFIG_SCSI_WD719X is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_SDIO_UART is not set +# CONFIG_SD_ADC_MODULATOR is not set +# CONFIG_SECCOMP is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_SECURITY_DMESG_RESTRICT=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_SENSIRION_SGP30 is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_ACPI_POWER is not set +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM1275 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_SENSORS_APPLESMC is not set +# CONFIG_SENSORS_AS370 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ASPEED is not set +# CONFIG_SENSORS_ATK0110 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_CORETEMP is not set +# CONFIG_SENSORS_DELL_SMM is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FAM15H_POWER is not set +# CONFIG_SENSORS_FSCHMD is not set +# CONFIG_SENSORS_FTSTEUTATES is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_GSC is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_HMC5843 is not set +# CONFIG_SENSORS_HMC5843_I2C is not set +# CONFIG_SENSORS_HMC5843_SPI is not set +# CONFIG_SENSORS_HTU21 is not set +# CONFIG_SENSORS_I5500 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_IBM_CFFPS is not set +# CONFIG_SENSORS_IIO_HWMON is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA3221 is not set +# CONFIG_SENSORS_INSPUR_IPSPS is not set +# CONFIG_SENSORS_IR35221 is not set +# CONFIG_SENSORS_IR38064 is not set +# CONFIG_SENSORS_IRPS5401 is not set +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_SENSORS_ISL29028 is not set +# CONFIG_SENSORS_ISL68137 is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_K10TEMP is not set +# CONFIG_SENSORS_K8TEMP is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_SENSORS_LIS3_I2C is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LM25066 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC2978 is not set +# CONFIG_SENSORS_LTC2990 is not set +# CONFIG_SENSORS_LTC3815 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16064 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX20751 is not set +# CONFIG_SENSORS_MAX31722 is not set +# CONFIG_SENSORS_MAX31785 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_MAX34440 is not set +# CONFIG_SENSORS_MAX6621 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX8688 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_NPCM7XX is not set +# CONFIG_SENSORS_OCC_P8_I2C is not set +# CONFIG_SENSORS_NSA320 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_OCC_P8_I2C is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_PMBUS is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_PWM_FAN is not set +# CONFIG_SENSORS_PXE1610 is not set +# CONFIG_SENSORS_RM3100_I2C is not set +# CONFIG_SENSORS_RM3100_SPI is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHT3x is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_STTS751 is not set +# CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP108 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_TPS40422 is not set +# CONFIG_SENSORS_TPS53679 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_SENSORS_UCD9000 is not set +# CONFIG_SENSORS_UCD9200 is not set +# CONFIG_SENSORS_VEXPRESS is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VIA_CPUTEMP is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83773G is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_XGENE is not set +# CONFIG_SENSORS_ZL6100 is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_ASPEED_VUART is not set +# CONFIG_SERIAL_8250_BOCA is not set +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_CS is not set +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_DMA=y +# CONFIG_SERIAL_8250_DW is not set +# CONFIG_SERIAL_8250_EM is not set +# CONFIG_SERIAL_8250_EXAR is not set +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_FINTEK is not set +# CONFIG_SERIAL_8250_FOURPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +# CONFIG_SERIAL_8250_INGENIC is not set +# CONFIG_SERIAL_8250_LPSS is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_MID is not set +# CONFIG_SERIAL_8250_MOXA is not set +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_PCI is not set +# CONFIG_SERIAL_8250_RSA is not set +# CONFIG_SERIAL_8250_RT288X is not set +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_BCM63XX is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_DEV_BUS is not set +CONFIG_SERIAL_EARLYCON=y +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_SERIAL_OF_PLATFORM is not set +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set +# CONFIG_SERIAL_PCH_UART is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SH_SCI is not set +# CONFIG_SERIAL_SIFIVE is not set +# CONFIG_SERIAL_STM32 is not set +# CONFIG_SERIAL_ST_ASC is not set +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_UARTLITE is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIO is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_GPIO_PS2 is not set +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_SUN4I_PS2 is not set +# CONFIG_SFC is not set +# CONFIG_SFC_FALCON is not set +# CONFIG_SFI is not set +# CONFIG_SFP is not set +# CONFIG_SGETMASK_SYSCALL is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_SG_POOL is not set +# CONFIG_SG_SPLIT is not set +CONFIG_SHMEM=y +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set +# CONFIG_SH_ETH is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_SI1133 is not set +# CONFIG_SI1145 is not set +# CONFIG_SI7005 is not set +# CONFIG_SI7020 is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_SWARM is not set +CONFIG_SIGNALFD=y +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set +# CONFIG_SIMPLE_GPIO is not set +# CONFIG_SIMPLE_PM_BUS is not set +# CONFIG_SIOX is not set +# CONFIG_SIS190 is not set +# CONFIG_SIS900 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +# CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SLAB_FREELIST_RANDOM is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLHC is not set +# CONFIG_SLICOSS is not set +# CONFIG_SLIMBUS is not set +# CONFIG_SLIP is not set +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_MEMCG_SYSFS_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_SMARTJOYPLUS_FF is not set +# CONFIG_SMC911X is not set +# CONFIG_SMC9194 is not set +# CONFIG_SMC91X is not set +# CONFIG_SMP is not set +# CONFIG_SMSC911X is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_SM_FTL is not set +# CONFIG_SND is not set +# CONFIG_SND_AC97_POWER_SAVE is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ADLIB is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_ASIHPI is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_ATMEL_AC97C is not set +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AUDIO_GRAPH_CARD is not set +# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BCD2000 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5530 is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_DESIGNWARE_I2S is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_EDMA_SOC is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FIREWIRE is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDA_INTEL_DETECT_DMIC is not set +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDA_PREALLOC_SIZE=64 +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_HWDEP is not set +# CONFIG_SND_I2S_HI6210_I2S is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_ISA is not set +# CONFIG_SND_JZ4740_SOC_I2S is not set +# CONFIG_SND_KIRKWOOD_SOC is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +CONFIG_SND_MAX_CARDS=16 +# CONFIG_SND_MIA is not set +# CONFIG_SND_MIPS is not set +# CONFIG_SND_MIRO is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MPC52xx_SOC_EFIKA is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_MTS64 is not set +# CONFIG_SND_MXS_SOC is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +CONFIG_SND_OSSEMUL=y +# CONFIG_SND_OXYGEN is not set +CONFIG_SND_PCI=y +# CONFIG_SND_PCM is not set +# CONFIG_SND_PCMCIA is not set +# CONFIG_SND_PCM_OSS is not set +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_PCM_TIMER is not set +# CONFIG_SND_PCM_XRUN_DEBUG is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_PDAUDIOCF is not set +# CONFIG_SND_PORTMAN2X4 is not set +# CONFIG_SND_POWERPC_SOC is not set +# CONFIG_SND_PPC is not set +CONFIG_SND_PROC_FS=y +# CONFIG_SND_RAWMIDI is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_RTCTIMER is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_SE6X is not set +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_SIMPLE_CARD is not set +# CONFIG_SND_SIMPLE_SCU_CARD is not set +# CONFIG_SND_SIS7019 is not set +# CONFIG_SND_SOC is not set +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_ADAU1761_I2C is not set +# CONFIG_SND_SOC_ADAU1761_SPI is not set +# CONFIG_SND_SOC_ADAU7002 is not set +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4118 is not set +# CONFIG_SND_SOC_AK4458 is not set +# CONFIG_SND_SOC_AK4554 is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_AK5558 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_AMD_ACP is not set +# CONFIG_SND_SOC_AMD_ACP3x is not set +# CONFIG_SND_SOC_AU1XAUDIO is not set +# CONFIG_SND_SOC_AU1XPSC is not set +# CONFIG_SND_SOC_BD28623 is not set +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS35L33 is not set +# CONFIG_SND_SOC_CS35L34 is not set +# CONFIG_SND_SOC_CS35L35 is not set +# CONFIG_SND_SOC_CS35L36 is not set +# CONFIG_SND_SOC_CS4265 is not set +# CONFIG_SND_SOC_CS4270 is not set +# CONFIG_SND_SOC_CS4271 is not set +# CONFIG_SND_SOC_CS4271_I2C is not set +# CONFIG_SND_SOC_CS4271_SPI is not set +# CONFIG_SND_SOC_CS42L42 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS42XX8_I2C is not set +# CONFIG_SND_SOC_CS43130 is not set +# CONFIG_SND_SOC_CS4341 is not set +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CS53L30 is not set +# CONFIG_SND_SOC_CX2072X is not set +# CONFIG_SND_SOC_DIO2125 is not set +# CONFIG_SND_SOC_ES7134 is not set +# CONFIG_SND_SOC_ES7241 is not set +# CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_ES8328_I2C is not set +# CONFIG_SND_SOC_ES8328_SPI is not set +# CONFIG_SND_SOC_EUKREA_TLV320 is not set +# CONFIG_SND_SOC_FSL_ASOC_CARD is not set +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_AUDMIX is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_FSL_MICFIL is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_ICS43432 is not set +# CONFIG_SND_SOC_IMG is not set +# CONFIG_SND_SOC_IMX_AUDMIX is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_SOC_IMX_ES8328 is not set +# CONFIG_SND_SOC_IMX_SPDIF is not set +# CONFIG_SND_SOC_IMX_WM8962 is not set +# CONFIG_SND_SOC_INNO_RK3036 is not set +# CONFIG_SND_SOC_INTEL_APL is not set +# CONFIG_SND_SOC_INTEL_BAYTRAIL is not set +# CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH is not set +# CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH is not set +# CONFIG_SND_SOC_INTEL_BXT_RT298_MACH is not set +# CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH is not set +# CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH is not set +# CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH is not set +# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set +# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set +# CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH is not set +# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set +# CONFIG_SND_SOC_INTEL_CFL is not set +# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH is not set +# CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH is not set +# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH is not set +# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH is not set +# CONFIG_SND_SOC_INTEL_CML_H is not set +# CONFIG_SND_SOC_INTEL_CML_LP is not set +# CONFIG_SND_SOC_INTEL_CNL is not set +# CONFIG_SND_SOC_INTEL_GLK is not set +# CONFIG_SND_SOC_INTEL_HASWELL is not set +# CONFIG_SND_SOC_INTEL_KBL is not set +# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set +# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set +# CONFIG_SND_SOC_INTEL_SKL is not set +# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH is not set +# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH is not set +# CONFIG_SND_SOC_INTEL_SKL_RT286_MACH is not set +# CONFIG_SND_SOC_INTEL_SKYLAKE is not set +# CONFIG_SND_SOC_INTEL_SST is not set +CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y +# CONFIG_SND_SOC_JZ4725B_CODEC is not set +# CONFIG_SND_SOC_JZ4740_CODEC is not set +# CONFIG_SND_SOC_MAX9759 is not set +# CONFIG_SND_SOC_MAX98088 is not set +# CONFIG_SND_SOC_MAX98357A is not set +# CONFIG_SND_SOC_MAX98373 is not set +# CONFIG_SND_SOC_MAX98504 is not set +# CONFIG_SND_SOC_MAX9860 is not set +# CONFIG_SND_SOC_MAX9867 is not set +# CONFIG_SND_SOC_MAX98927 is not set +# CONFIG_SND_SOC_MEDIATEK is not set +# CONFIG_SND_SOC_MPC5200_AC97 is not set +# CONFIG_SND_SOC_MPC5200_I2S is not set +# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set +# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set +# CONFIG_SND_SOC_MT2701 is not set +# CONFIG_SND_SOC_MT6351 is not set +# CONFIG_SND_SOC_MT6358 is not set +# CONFIG_SND_SOC_MT8173 is not set +# CONFIG_SND_SOC_MTK_BTCVSD is not set +# CONFIG_SND_SOC_NAU8540 is not set +# CONFIG_SND_SOC_NAU8810 is not set +# CONFIG_SND_SOC_NAU8822 is not set +# CONFIG_SND_SOC_NAU8824 is not set +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1789_I2C is not set +# CONFIG_SND_SOC_PCM1792A is not set +# CONFIG_SND_SOC_PCM179X_I2C is not set +# CONFIG_SND_SOC_PCM179X_SPI is not set +# CONFIG_SND_SOC_PCM186X_I2C is not set +# CONFIG_SND_SOC_PCM186X_SPI is not set +# CONFIG_SND_SOC_PCM3060_I2C is not set +# CONFIG_SND_SOC_PCM3060_SPI is not set +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_PCM3168A_SPI is not set +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_QCOM is not set +# CONFIG_SND_SOC_RK3328 is not set +# CONFIG_SND_SOC_RT5616 is not set +# CONFIG_SND_SOC_RT5631 is not set +# CONFIG_SND_SOC_RT5677_SPI is not set +# CONFIG_SND_SOC_SGTL5000 is not set +# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +# CONFIG_SND_SOC_SOF_TOPLEVEL is not set +# CONFIG_SND_SOC_SPDIF is not set +# CONFIG_SND_SOC_SSM2305 is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TAS5720 is not set +# CONFIG_SND_SOC_TAS6424 is not set +# CONFIG_SND_SOC_TDA7419 is not set +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set +# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +# CONFIG_SND_SOC_TPA6130A2 is not set +# CONFIG_SND_SOC_TS3A227E is not set +# CONFIG_SND_SOC_TSCS42XX is not set +# CONFIG_SND_SOC_TSCS454 is not set +# CONFIG_SND_SOC_UDA1334 is not set +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8524 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8782 is not set +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8904 is not set +# CONFIG_SND_SOC_WM8960 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8974 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_WM8985 is not set +# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set +# CONFIG_SND_SOC_XILINX_I2S is not set +# CONFIG_SND_SOC_XILINX_SPDIF is not set +# CONFIG_SND_SOC_XTFPGA_I2S is not set +# CONFIG_SND_SOC_ZX_AUD96P22 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_SSCAPE is not set +# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI is not set +# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set +# CONFIG_SND_SUN4I_CODEC is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_TIMER is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_USB_POD is not set +# CONFIG_SND_USB_PODHD is not set +# CONFIG_SND_USB_TONEPORT is not set +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_US122L is not set +# CONFIG_SND_USB_USX2Y is not set +# CONFIG_SND_USB_VARIAX is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_VXPOCKET is not set +# CONFIG_SND_WAVEFRONT is not set +CONFIG_SND_X86=y +# CONFIG_SND_XEN_FRONTEND is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SNI_RM is not set +# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set +# CONFIG_SOCK_CGROUP_DATA is not set +# CONFIG_SOC_AM33XX is not set +# CONFIG_SOC_AM43XX is not set +# CONFIG_SOC_BRCMSTB is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_SOC_DRA7XX is not set +# CONFIG_SOC_HAS_OMAP2_SDRC is not set +# CONFIG_SOC_OMAP5 is not set +# CONFIG_SOC_TI is not set +# CONFIG_SOFTLOCKUP_DETECTOR is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_SONYPI is not set +# CONFIG_SONY_LAPTOP is not set +# CONFIG_SOUND is not set +# CONFIG_SOUNDWIRE is not set +# CONFIG_SOUND_OSS_CORE is not set +# CONFIG_SOUND_PRIME is not set +# CONFIG_SP5100_TCO is not set +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +# CONFIG_SPARSE_IRQ is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_SPEAKUP is not set +# CONFIG_SPI is not set +# CONFIG_SPINLOCK_TEST is not set +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AU1550 is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +# CONFIG_SPI_BCM2835 is not set +# CONFIG_SPI_BCM_QSPI is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_BUTTERFLY is not set +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_CADENCE_QUADSPI is not set +# CONFIG_SPI_DEBUG is not set +# CONFIG_SPI_DESIGNWARE is not set +# CONFIG_SPI_FSL_DSPI is not set +# CONFIG_SPI_FSL_ESPI is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_GPIO_OLD is not set +# CONFIG_SPI_IMG_SPFI is not set +# CONFIG_SPI_LM70_LLP is not set +# CONFIG_SPI_LOOPBACK_TEST is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_SPI_MEM is not set +# CONFIG_SPI_MPC52xx is not set +# CONFIG_SPI_MPC52xx_PSC is not set +# CONFIG_SPI_MTK_QUADSPI is not set +# CONFIG_SPI_MXIC is not set +# CONFIG_SPI_NXP_FLEXSPI is not set +# CONFIG_SPI_OCTEON is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_ORION is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PPC4xx is not set +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_ROCKCHIP is not set +# CONFIG_SPI_QCOM_QSPI is not set +# CONFIG_SPI_S3C64XX is not set +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_SIFIVE is not set +# CONFIG_SPI_SLAVE is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_THUNDERX is not set +# CONFIG_SPI_TI_QSPI is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_TOPCLIFF_PCH is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_XWAY is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_SPMI is not set +# CONFIG_SPS30 is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +CONFIG_SQUASHFS_EMBEDDED=y +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_SQUASHFS_LZ4 is not set +# CONFIG_SQUASHFS_LZO is not set +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_XZ=y +# CONFIG_SQUASHFS_ZLIB is not set +# CONFIG_SQUASHFS_ZSTD is not set +# CONFIG_SRAM is not set +# CONFIG_SRF04 is not set +# CONFIG_SRF08 is not set +# CONFIG_SSB is not set +# CONFIG_SSB_DEBUG is not set +# CONFIG_SSB_DRIVER_GPIO is not set +# CONFIG_SSB_HOST_SOC is not set +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB_SDIOHOST is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSFDC is not set +# CONFIG_STACKPROTECTOR is not set +# CONFIG_STACKPROTECTOR_STRONG is not set +# CONFIG_STACKTRACE is not set +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_TRACER is not set +# CONFIG_STACK_VALIDATION is not set +CONFIG_STAGING=y +# CONFIG_STAGING_BOARD is not set +# CONFIG_STAGING_GASKET_FRAMEWORK is not set +# CONFIG_STAGING_MEDIA is not set +CONFIG_STANDALONE=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +# CONFIG_STATIC_USERMODEHELPER is not set +CONFIG_STDBINUTILS=y +# CONFIG_STE10XP is not set +# CONFIG_STE_MODEM_RPROC is not set +# CONFIG_STK3310 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set +# CONFIG_STM is not set +# CONFIG_STMMAC_ETH is not set +# CONFIG_STMMAC_PCI is not set +# CONFIG_STMMAC_PLATFORM is not set +# CONFIG_STM_DUMMY is not set +# CONFIG_STM_SOURCE_CONSOLE is not set +CONFIG_STP=y +# CONFIG_STREAM_PARSER is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_STRICT_MODULE_RWX=y +# CONFIG_STRING_SELFTEST is not set +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_STX104 is not set +# CONFIG_ST_UVIS25 is not set +# CONFIG_SUN4I_GPADC is not set +# CONFIG_SUN50I_DE2_BUS is not set +# CONFIG_SUN50I_ERRATUM_UNKNOWN1 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_SUNRPC is not set +# CONFIG_SUNRPC_DEBUG is not set +CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SUNXI_SRAM is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SURFACE_3_BUTTON is not set +# CONFIG_SUSPEND is not set +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_SWAP=y +# CONFIG_SWCONFIG is not set +# CONFIG_SWCONFIG_B53 is not set +# CONFIG_SWCONFIG_B53_MDIO_DRIVER is not set +# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set +# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set +# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set +# CONFIG_SWCONFIG_LEDS is not set +# CONFIG_SW_SYNC is not set +# CONFIG_SX9500 is not set +# CONFIG_SXGBE_ETH is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_SYNC_FILE is not set +# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set +CONFIG_SYN_COOKIES=y +# CONFIG_SYSCON_REBOOT_MODE is not set +# CONFIG_NVMEM_REBOOT_MODE is not set +CONFIG_SYSCTL=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_SYSFS_SYSCALL is not set +# CONFIG_SYSTEMPORT is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +# CONFIG_SYSTEM_DATA_VERIFICATION is not set +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +CONFIG_SYSTEM_TRUSTED_KEYS="" +# CONFIG_SYSV68_PARTITION is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_T5403 is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_TASKS_RCU is not set +# CONFIG_TASK_XACCT is not set +# CONFIG_TC35815 is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_CRB is not set +# CONFIG_TCG_FTPM_TEE is not set +# CONFIG_TCG_INFINEON is not set +# CONFIG_TCG_NSC is not set +# CONFIG_TCG_ST33_I2C is not set +# CONFIG_TCG_TIS is not set +# CONFIG_TCG_TIS_I2C_ATMEL is not set +# CONFIG_TCG_TIS_I2C_INFINEON is not set +# CONFIG_TCG_TIS_I2C_NUVOTON is not set +# CONFIG_TCG_TIS_SPI is not set +# CONFIG_TCG_TIS_ST33ZP24_I2C is not set +# CONFIG_TCG_TIS_ST33ZP24_SPI is not set +# CONFIG_TCG_TPM is not set +# CONFIG_TCG_VTPM_PROXY is not set +# CONFIG_TCG_XEN is not set +# CONFIG_TCIC is not set +CONFIG_TCP_CONG_ADVANCED=y +# CONFIG_TCP_CONG_BBR is not set +# CONFIG_TCP_CONG_BIC is not set +# CONFIG_TCP_CONG_CDG is not set +CONFIG_TCP_CONG_CUBIC=y +# CONFIG_TCP_CONG_DCTCP is not set +# CONFIG_TCP_CONG_HSTCP is not set +# CONFIG_TCP_CONG_HTCP is not set +# CONFIG_TCP_CONG_HYBLA is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +# CONFIG_TCP_CONG_LP is not set +# CONFIG_TCP_CONG_NV is not set +# CONFIG_TCP_CONG_SCALABLE is not set +# CONFIG_TCP_CONG_VEGAS is not set +# CONFIG_TCP_CONG_VENO is not set +# CONFIG_TCP_CONG_WESTWOOD is not set +# CONFIG_TCP_CONG_YEAH is not set +# CONFIG_TCP_MD5SIG is not set +# CONFIG_TCS3414 is not set +# CONFIG_TCS3472 is not set +# CONFIG_TEE is not set +# CONFIG_TEGRA_AHB is not set +# CONFIG_TEGRA_HOST1X is not set +# CONFIG_TEHUTI is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +# CONFIG_TEST_BITFIELD is not set +# CONFIG_TEST_BITMAP is not set +# CONFIG_TEST_BLACKHOLE_DEV is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_HASH is not set +# CONFIG_TEST_HEXDUMP is not set +# CONFIG_TEST_IDA is not set +# CONFIG_TEST_KMOD is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_MEMCAT_P is not set +# CONFIG_TEST_MEMINIT is not set +# CONFIG_TEST_OVERFLOW is not set +# CONFIG_TEST_POWER is not set +# CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_TEST_SORT is not set +# CONFIG_TEST_STACKINIT is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_STRSCPY is not set +# CONFIG_TEST_SYSCTL is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_UUID is not set +# CONFIG_TEST_VMALLOC is not set +# CONFIG_TEST_XARRAY is not set +CONFIG_TEXTSEARCH=y +# CONFIG_TEXTSEARCH_BM is not set +# CONFIG_TEXTSEARCH_FSM is not set +# CONFIG_TEXTSEARCH_KMP is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_THERMAL_MMIO is not set +# CONFIG_THERMAL_STATISTICS is not set +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +# CONFIG_THINKPAD_ACPI is not set +CONFIG_THIN_ARCHIVES=y +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_THUNDERBOLT is not set +# CONFIG_THUNDER_NIC_BGX is not set +# CONFIG_THUNDER_NIC_PF is not set +# CONFIG_THUNDER_NIC_RGX is not set +# CONFIG_THUNDER_NIC_VF is not set +# CONFIG_TICK_CPU_ACCOUNTING is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_TIFM_CORE is not set +# CONFIG_TIGON3 is not set +# CONFIG_TIMB_DMA is not set +CONFIG_TIMERFD=y +# CONFIG_TIMER_STATS is not set +# CONFIG_TINYDRM_HX8357D is not set +# CONFIG_TINYDRM_ILI9225 is not set +# CONFIG_TINYDRM_ILI9341 is not set +# CONFIG_TINYDRM_MI0283QT is not set +# CONFIG_TINYDRM_REPAPER is not set +# CONFIG_TINYDRM_ST7586 is not set +# CONFIG_TINYDRM_ST7735R is not set +CONFIG_TINY_RCU=y +# CONFIG_TIPC is not set +# CONFIG_TI_ADC081C is not set +# CONFIG_TI_ADC0832 is not set +# CONFIG_TI_ADC084S021 is not set +# CONFIG_TI_ADC108S102 is not set +# CONFIG_TI_ADC12138 is not set +# CONFIG_TI_ADC128S052 is not set +# CONFIG_TI_ADC161S626 is not set +# CONFIG_TI_ADS1015 is not set +# CONFIG_TI_ADS124S08 is not set +# CONFIG_TI_ADS7950 is not set +# CONFIG_TI_ADS8344 is not set +# CONFIG_TI_ADS8688 is not set +# CONFIG_TI_AM335X_ADC is not set +# CONFIG_TI_CPSW is not set +# CONFIG_TI_CPSW_ALE is not set +# CONFIG_TI_CPSW_PHY_SEL is not set +# CONFIG_TI_CPTS is not set +# CONFIG_TI_DAC082S085 is not set +# CONFIG_TI_DAC5571 is not set +# CONFIG_TI_DAC7311 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_TI_DAC7612 is not set +# CONFIG_TI_DAVINCI_CPDMA is not set +# CONFIG_TI_DAVINCI_MDIO is not set +# CONFIG_TI_ST is not set +# CONFIG_TI_SYSCON_RESET is not set +# CONFIG_TI_TLC4541 is not set +# CONFIG_TLAN is not set +# CONFIG_TLS is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_TMP006 is not set +# CONFIG_TMP007 is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_TMPFS_XATTR=y +# CONFIG_TOPSTAR_LAPTOP is not set +# CONFIG_TORTURE_TEST is not set +# CONFIG_TOSHIBA_HAPS is not set +# CONFIG_TOUCHSCREEN_88PM860X is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_ADC is not set +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_BU21029 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set +# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set +# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set +# CONFIG_TOUCHSCREEN_DA9034 is not set +# CONFIG_TOUCHSCREEN_DA9052 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set +# CONFIG_TOUCHSCREEN_EKTF2127 is not set +# CONFIG_TOUCHSCREEN_ELAN is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_EXC3000 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_HIDEEP is not set +# CONFIG_TOUCHSCREEN_HP600 is not set +# CONFIG_TOUCHSCREEN_HP7XX is not set +# CONFIG_TOUCHSCREEN_HTCPEN is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set +# CONFIG_TOUCHSCREEN_IPROC is not set +# CONFIG_TOUCHSCREEN_IQS5XX is not set +# CONFIG_TOUCHSCREEN_LPC32XX is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MC13783 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set +# CONFIG_TOUCHSCREEN_MIGOR is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MX25 is not set +# CONFIG_TOUCHSCREEN_MXS_LRADC is not set +# CONFIG_TOUCHSCREEN_PCAP is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_PROPERTIES is not set +# CONFIG_TOUCHSCREEN_RM_TS is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set +# CONFIG_TOUCHSCREEN_S3C2410 is not set +# CONFIG_TOUCHSCREEN_S6SY761 is not set +# CONFIG_TOUCHSCREEN_SILEAD is not set +# CONFIG_TOUCHSCREEN_SIS_I2C is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_STMFTS is not set +# CONFIG_TOUCHSCREEN_STMPE is not set +# CONFIG_TOUCHSCREEN_SUN4I is not set +# CONFIG_TOUCHSCREEN_SUR40 is not set +# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set +# CONFIG_TOUCHSCREEN_SX8654 is not set +# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_TS4800 is not set +# CONFIG_TOUCHSCREEN_TSC2004 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set +# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_3M is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set +# CONFIG_TOUCHSCREEN_USB_E2I is not set +# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set +# CONFIG_TOUCHSCREEN_USB_EGALAX is not set +# CONFIG_TOUCHSCREEN_USB_ELO is not set +# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set +# CONFIG_TOUCHSCREEN_USB_ETURBO is not set +# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set +# CONFIG_TOUCHSCREEN_USB_GOTOP is not set +# CONFIG_TOUCHSCREEN_USB_GUNZE is not set +# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set +# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set +# CONFIG_TOUCHSCREEN_USB_ITM is not set +# CONFIG_TOUCHSCREEN_USB_JASTEC is not set +# CONFIG_TOUCHSCREEN_USB_NEXIO is not set +# CONFIG_TOUCHSCREEN_USB_PANJIT is not set +# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +# CONFIG_TOUCHSCREEN_WM831X is not set +# CONFIG_TOUCHSCREEN_WM9705 is not set +# CONFIG_TOUCHSCREEN_WM9712 is not set +# CONFIG_TOUCHSCREEN_WM9713 is not set +# CONFIG_TOUCHSCREEN_WM97XX is not set +# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set +# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set +# CONFIG_TOUCHSCREEN_ZET6223 is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TPL0102 is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_TRACER_SNAPSHOT is not set +# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_TRACE_EVAL_MAP_FILE is not set +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_TRACE_SINK is not set +# CONFIG_TRACING_EVENTS_GPIO is not set +CONFIG_TRACING_SUPPORT=y +CONFIG_TRAD_SIGNALS=y +# CONFIG_TRANSPARENT_HUGEPAGE is not set +# CONFIG_TREE_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_TRIM_UNUSED_KSYMS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_TSL2583 is not set +# CONFIG_TSL2772 is not set +# CONFIG_TSL2x7x is not set +# CONFIG_TSL4531 is not set +# CONFIG_TSYS01 is not set +# CONFIG_TSYS02D is not set +# CONFIG_TTPCI_EEPROM is not set +CONFIG_TTY=y +# CONFIG_TTY_PRINTK is not set +# CONFIG_TUN is not set +# CONFIG_TUN_VNET_CROSS_LE is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL4030_MADC is not set +# CONFIG_TWL6030_GPADC is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_TYPEC is not set +# CONFIG_TYPEC_TCPM is not set +# CONFIG_TYPEC_UCSI is not set +# CONFIG_TYPHOON is not set +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_UBIFS_ATIME_SUPPORT is not set +# CONFIG_UBIFS_FS_AUTHENTICATION is not set +# CONFIG_UBIFS_FS_ENCRYPTION is not set +CONFIG_UBIFS_FS_FORMAT4=y +# CONFIG_UBIFS_FS_SECURITY is not set +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBSAN is not set +CONFIG_UBSAN_ALIGNMENT=y +# CONFIG_UCB1400_CORE is not set +# CONFIG_UCSI is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDMABUF is not set +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_FS is not set +# CONFIG_UHID is not set +CONFIG_UID16=y +# CONFIG_UIO is not set +# CONFIG_ULTRA is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_UNICODE is not set +# CONFIG_UNISYSSPAR is not set +# CONFIG_UNISYS_VISORBUS is not set +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_UNIX_DIAG is not set +CONFIG_UNIX_SCM=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_UPROBES is not set +# CONFIG_UPROBE_EVENTS is not set +# CONFIG_US5182D is not set +# CONFIG_USB is not set +# CONFIG_USBIP_CORE is not set +CONFIG_USBIP_VHCI_HC_PORTS=8 +CONFIG_USBIP_VHCI_NR_HCS=1 +# CONFIG_USBIP_VUDC is not set +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_ADUTUX is not set +CONFIG_USB_ALI_M5632=y +# CONFIG_USB_AMD5536UDC is not set +CONFIG_USB_AN2720=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_ATM is not set +CONFIG_USB_AUTOSUSPEND_DELAY=2 +# CONFIG_USB_BDC_UDC is not set +CONFIG_USB_BELKIN=y +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_CDNS3 is not set +# CONFIG_USB_CHAOSKEY is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_CONFIGFS is not set +# CONFIG_USB_CONN_GPIO is not set +# CONFIG_USB_CXACRU is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DUMMY_HCD is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_DWC2_DEBUG is not set +# CONFIG_USB_DWC2_DUAL_ROLE is not set +# CONFIG_USB_DWC2_HOST is not set +# CONFIG_USB_DWC2_PERIPHERAL is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_DWC3_EXYNOS is not set +# CONFIG_USB_DWC3_HAPS is not set +# CONFIG_USB_DWC3_KEYSTONE is not set +# CONFIG_USB_DWC3_OF_SIMPLE is not set +# CONFIG_USB_DWC3_PCI is not set +# CONFIG_USB_DWC3_QCOM is not set +# CONFIG_USB_DWC3_ULPI is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_EG20T is not set +# CONFIG_USB_EHCI_ATH79 is not set +# CONFIG_USB_EHCI_HCD_AT91 is not set +# CONFIG_USB_EHCI_HCD_OMAP is not set +# CONFIG_USB_EHCI_HCD_PPC_OF is not set +# CONFIG_USB_EHCI_MSM is not set +# CONFIG_USB_EHCI_MV is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_FOTG210_UDC is not set +# CONFIG_USB_FSL_USB2 is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_GADGET is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +CONFIG_USB_GADGET_VBUS_DRAW=2 +# CONFIG_USB_GADGET_XILINX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_GOKU is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_GSPCA_BENQ is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_CPIA1 is not set +# CONFIG_USB_GSPCA_DTCS033 is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_JEILINJ is not set +# CONFIG_USB_GSPCA_JL2005BCD is not set +# CONFIG_USB_GSPCA_KINECT is not set +# CONFIG_USB_GSPCA_KONICA is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_NW80X is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_OV534_9 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7302 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SE401 is not set +# CONFIG_USB_GSPCA_SN9C2028 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA1528 is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_SQ930X is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_STK1135 is not set +# CONFIG_USB_GSPCA_STV0680 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TOPRO is not set +# CONFIG_USB_GSPCA_TOUPTEK is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_VICAM is not set +# CONFIG_USB_GSPCA_XIRLINK_CIT is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_G_WEBCAM is not set +# CONFIG_USB_HCD_TEST_MODE is not set +# CONFIG_USB_HID is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_HUB_USB251XB is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IMX21_HCD is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_ISP1760 is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_KC2190 is not set +# CONFIG_USB_LAN78XX is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set +# CONFIG_USB_LED_TRIG is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_M5602 is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_MAX3421_HCD is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_MSM_OTG is not set +# CONFIG_USB_MTU3 is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MXS_PHY is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_NET2280 is not set +# CONFIG_USB_NET_AQC111 is not set +# CONFIG_USB_NET_AX88179_178A is not set +# CONFIG_USB_NET_AX8817X is not set +# CONFIG_USB_NET_CDCETHER is not set +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_MBIM is not set +# CONFIG_USB_NET_CDC_NCM is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_CH9200 is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_DRIVERS is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_OHCI_HCD_PCI is not set +# CONFIG_USB_OHCI_HCD_PPC_OF is not set +# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set +# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_PCI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_PHY is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_PWC_INPUT_EVDEV is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_RCAR_PHY is not set +# CONFIG_USB_RENESAS_USBHS is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_ROLE_SWITCH is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +# CONFIG_USB_S2255 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_DEBUG is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_F8153X is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_GARMIN is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MXUPORT is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SAFE is not set +CONFIG_USB_SERIAL_SAFE_PADDED=y +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_UPD78F0730 is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_SNP_UDC_PLAT is not set +# CONFIG_USB_SPEEDTOUCH is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_TMC is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_UAS is not set +# CONFIG_USB_UEAGLEATM is not set +# CONFIG_USB_ULPI is not set +# CONFIG_USB_ULPI_BUS is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set +# CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_VL600 is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set +# CONFIG_USB_XHCI_DBGCAP is not set +# CONFIG_USB_XHCI_HCD is not set +# CONFIG_USB_XHCI_MVEBU is not set +# CONFIG_USB_XUSBATM is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USELIB is not set +# CONFIG_USERFAULTFD is not set +# CONFIG_USE_OF is not set +# CONFIG_UTS_NS is not set +# CONFIG_UWB is not set +# CONFIG_U_SERIAL_CONSOLE is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_VALIDATE_FS_PARSER is not set +# CONFIG_VBOXGUEST is not set +# CONFIG_VCNL4000 is not set +# CONFIG_VCNL4035 is not set +# CONFIG_VDSO is not set +# CONFIG_VEML6070 is not set +# CONFIG_VETH is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_VF610_ADC is not set +# CONFIG_VF610_DAC is not set +# CONFIG_VFAT_FS is not set +# CONFIG_VGASTATE is not set +# CONFIG_VGA_ARB is not set +# CONFIG_VGA_SWITCHEROO is not set +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set +# CONFIG_VHOST_NET is not set +# CONFIG_VHOST_VSOCK is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_ADV7393 is not set +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_ASPEED is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_CADENCE is not set +# CONFIG_VIDEO_CAFE_CCIC is not set +# CONFIG_VIDEO_CS3308 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_CX2341X is not set +# CONFIG_VIDEO_CX25840 is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_VIDEO_DM6446_CCDC is not set +# CONFIG_VIDEO_DT3155 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_GO7007 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_I2C is not set +# CONFIG_VIDEO_IR_I2C is not set +# CONFIG_VIDEO_IVTV is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_ML86V7667 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_MT9M111 is not set +# CONFIG_VIDEO_MT9T112 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_MT9V111 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_NOON010PC30 is not set +# CONFIG_VIDEO_OMAP2_VOUT is not set +# CONFIG_VIDEO_OV2640 is not set +# CONFIG_VIDEO_OV2659 is not set +# CONFIG_VIDEO_OV5695 is not set +# CONFIG_VIDEO_OV6650 is not set +# CONFIG_VIDEO_OV7640 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_OV772X is not set +# CONFIG_VIDEO_OV7740 is not set +# CONFIG_VIDEO_OV9640 is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_RJ54N1 is not set +# CONFIG_VIDEO_SAA6588 is not set +# CONFIG_VIDEO_SAA6752HS is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +# CONFIG_VIDEO_SONY_BTF_MPX is not set +# CONFIG_VIDEO_SR030PC30 is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_THS8200 is not set +# CONFIG_VIDEO_TIMBERDALE is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_TM6000 is not set +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_TW2804 is not set +# CONFIG_VIDEO_TW9903 is not set +# CONFIG_VIDEO_TW9906 is not set +# CONFIG_VIDEO_TW9910 is not set +# CONFIG_VIDEO_UDA1342 is not set +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set +# CONFIG_VIDEO_USBTV is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_VIDEO_V4L2 is not set +# CONFIG_VIDEO_VP27SMPX is not set +# CONFIG_VIDEO_VPX3220 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_BLK_SCSI is not set +# CONFIG_VIRTIO_FS is not set +# CONFIG_VIRTIO_INPUT is not set +CONFIG_VIRTIO_MENU=y +# CONFIG_VIRTIO_MMIO is not set +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTUALIZATION is not set +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRT_TO_BUS=y +# CONFIG_VITESSE_PHY is not set +# CONFIG_VL53L0X_I2C is not set +# CONFIG_VL6180 is not set +CONFIG_VLAN_8021Q=y +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_VLAN_8021Q_MVRP is not set +# CONFIG_VME_BUS is not set +# CONFIG_VMSPLIT_1G is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_2G_OPT is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +# CONFIG_VMWARE_PVSCSI is not set +# CONFIG_VMXNET3 is not set +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_VOP_BUS is not set +# CONFIG_VORTEX is not set +# CONFIG_VSOCKETS is not set +# CONFIG_VSOCKETS_DIAG is not set +# CONFIG_VT is not set +# CONFIG_VT6655 is not set +# CONFIG_VT6656 is not set +# CONFIG_VXFS_FS is not set +# CONFIG_VXGE is not set +# CONFIG_VXLAN is not set +# CONFIG_VZ89X is not set +# CONFIG_W1 is not set +# CONFIG_W1_CON is not set +# CONFIG_W1_MASTER_DS1WM is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_GPIO is not set +# CONFIG_W1_MASTER_MATROX is not set +# CONFIG_W1_MASTER_SGI is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +# CONFIG_W1_SLAVE_DS2405 is not set +# CONFIG_W1_SLAVE_DS2406 is not set +# CONFIG_W1_SLAVE_DS2408 is not set +# CONFIG_W1_SLAVE_DS2413 is not set +# CONFIG_W1_SLAVE_DS2423 is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2438 is not set +# CONFIG_W1_SLAVE_DS250X is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_DS2780 is not set +# CONFIG_W1_SLAVE_DS2781 is not set +# CONFIG_W1_SLAVE_DS2805 is not set +# CONFIG_W1_SLAVE_DS28E04 is not set +# CONFIG_W1_SLAVE_DS28E17 is not set +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_THERM is not set +# CONFIG_W83627HF_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_W83977F_WDT is not set +# CONFIG_WAN is not set +# CONFIG_WANXL is not set +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set +# CONFIG_WATCHDOG_SYSFS is not set +# CONFIG_WD80x3 is not set +# CONFIG_WDAT_WDT is not set +# CONFIG_WDTPCI is not set +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PRIV=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WILINK_PLATFORM_DATA=y +# CONFIG_WIMAX is not set +# CONFIG_WIMAX_GDM72XX is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +# CONFIG_WIRELESS_WDS is not set +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +# CONFIG_WL1251 is not set +# CONFIG_WL12XX is not set +# CONFIG_WL18XX is not set +CONFIG_WLAN=y +# CONFIG_WLAN_VENDOR_ADMTEK is not set +# CONFIG_WLAN_VENDOR_ATH is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +# CONFIG_WLAN_VENDOR_BROADCOM is not set +# CONFIG_WLAN_VENDOR_CISCO is not set +# CONFIG_WLAN_VENDOR_INTEL is not set +# CONFIG_WLAN_VENDOR_INTERSIL is not set +# CONFIG_WLAN_VENDOR_MARVELL is not set +# CONFIG_WLAN_VENDOR_MEDIATEK is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +# CONFIG_WLAN_VENDOR_RALINK is not set +# CONFIG_WLAN_VENDOR_REALTEK is not set +# CONFIG_WLAN_VENDOR_RSI is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +# CONFIG_WLCORE is not set +# CONFIG_WL_MEDIATEK is not set +CONFIG_WL_TI=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +# CONFIG_WQ_WATCHDOG is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_X25 is not set +# CONFIG_X509_CERTIFICATE_PARSER is not set +# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set +# CONFIG_X86_PKG_TEMP_THERMAL is not set +CONFIG_X86_SYSFB=y +# CONFIG_XDP_SOCKETS is not set +# CONFIG_XEN is not set +# CONFIG_XEN_GRANT_DMA_ALLOC is not set +# CONFIG_XEN_PVCALLS_FRONTEND is not set +CONFIG_XEN_SCRUB_PAGES_DEFAULT=y +CONFIG_XFRM=y +# CONFIG_XFRM_INTERFACE is not set +# CONFIG_XFRM_IPCOMP is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_USER is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_ONLINE_SCRUB is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XILINX_AXI_EMAC is not set +# CONFIG_XILINX_DMA is not set +# CONFIG_XILINX_EMACLITE is not set +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_XILINX_LL_TEMAC is not set +# CONFIG_XILINX_SDFEC is not set +# CONFIG_XILINX_VCU is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_XILINX_XADC is not set +# CONFIG_XILINX_ZYNQMP_DMA is not set +# CONFIG_XILLYBUS is not set +# CONFIG_XIL_AXIS_FIFO is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_XMON is not set +CONFIG_XZ_DEC=y +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_BCJ is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_SPARC is not set +# CONFIG_XZ_DEC_TEST is not set +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_YAM is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_YENTA is not set +# CONFIG_YENTA_O2 is not set +# CONFIG_YENTA_RICOH is not set +# CONFIG_YENTA_TI is not set +# CONFIG_YENTA_TOSHIBA is not set +# CONFIG_ZBUD is not set +# CONFIG_ZD1211RW is not set +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +# CONFIG_ZISOFS is not set +# CONFIG_ZLIB_DEFLATE is not set +# CONFIG_ZLIB_INFLATE is not set +CONFIG_ZONE_DMA=y +# CONFIG_ZOPT2201 is not set +# CONFIG_ZPA2326 is not set +# CONFIG_ZPOOL is not set +# CONFIG_ZRAM is not set +# CONFIG_ZRAM_MEMORY_TRACKING is not set +# CONFIG_ZSMALLOC is not set +# CONFIG_ZX_TDM is not set +CONFIG_TCP_CONG_LIA=y +CONFIG_TCP_CONG_OLIA=y +CONFIG_TCP_CONG_WVEGAS=y +CONFIG_TCP_CONG_BALIA=y +CONFIG_TCP_CONG_MCTCPDESYNC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_MPTCP=y +# CONFIG_DEFAULT_BALIA is not set +# CONFIG_DEFAULT_LIA is not set +# CONFIG_DEFAULT_OLIA is not set +# CONFIG_DEFAULT_WVEGAS is not set +# CONFIG_DEFAULT_BBR is not set +# CONFIG_DEFAULT_MCTCPDESYNC is not set +CONFIG_DEFAULT_CUBIC=y +CONFIG_DEFAULT_MPTCP_PM="default" +CONFIG_DEFAULT_MPTCP_SCHED="default" +CONFIG_MPTCP_PM_ADVANCED=y +CONFIG_MPTCP_SCHED_ADVANCED=y +CONFIG_MPTCP_FULLMESH=y +CONFIG_MPTCP_NDIFFPORTS=y +CONFIG_MPTCP_BINDER=y +CONFIG_MPTCP_ROUNDROBIN=y +CONFIG_MPTCP_BLEST=y +CONFIG_MPTCP_REDUNDANT=y +CONFIG_MPTCP_NETLINK=y +CONFIG_MPTCP_ECF=y +CONFIG_DEFAULT_FULLMESH=y +CONFIG_DEFAULT_SCHEDULER=y +# CONFIG_DEFAULT_NDIFFPORTS is not set +# CONFIG_DEFAULT_NETLINK is not set +# CONFIG_DEFAULT_BINDER is not set +# CONFIG_DEFAULT_DUMMY is not set +# CONFIG_DEFAULT_ROUNDROBIN is not set +# CONFIG_DEFAULT_BLEST is not set +# CONFIG_DEFAULT_REDUNDANT is not set +CONFIG_NF_CONNTRACK_CUSTOM=2 diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch new file mode 100644 index 00000000..4d0e692f --- /dev/null +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -0,0 +1,23066 @@ +diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt +--- linux-5.4/Documentation/networking/ip-sysctl.txt 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-02-20 18:07:47.000000000 +0100 +@@ -818,6 +818,18 @@ + + Default: 0 (disabled) + ++MPTCP variables: ++ ++mptcp_enabled - INTEGER ++ Enable or disable Multipath TCP for new connections. ++ Possible values are: ++ ++ 0: Multipath TCP is disabled on all TCP-sockets that are newly created. ++ 1: Multipath TCP is enabled by default on all new TCP-sockets. Note that ++ existing sockets in LISTEN-state will still use regular TCP. ++ 2: Enables Multipath TCP only upon the request of the application ++ throught the socket-option MPTCP_ENABLED. ++ + UDP variables: + + udp_l3mdev_accept - BOOLEAN +diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c +--- linux-5.4/drivers/infiniband/hw/cxgb4/cm.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-02-20 18:07:47.000000000 +0100 +@@ -3946,7 +3946,7 @@ + */ + memset(&tmp_opt, 0, sizeof(tmp_opt)); + tcp_clear_options(&tmp_opt); +- tcp_parse_options(&init_net, skb, &tmp_opt, 0, NULL); ++ tcp_parse_options(&init_net, skb, &tmp_opt, NULL, 0, NULL, NULL); + + req = __skb_push(skb, sizeof(*req)); + memset(req, 0, sizeof(*req)); +diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbuff.h +--- linux-5.4/include/linux/skbuff.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-02-20 18:07:47.000000000 +0100 +@@ -717,7 +717,7 @@ + * want to keep them across layers you have to do a skb_clone() + * first. This is owned by whoever has the skb queued ATM. + */ +- char cb[48] __aligned(8); ++ char cb[80] __aligned(8); + + union { + struct { +diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h +--- linux-5.4/include/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-02-20 18:07:47.000000000 +0100 +@@ -54,7 +54,7 @@ + /* TCP Fast Open */ + #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ + #define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */ +-#define TCP_FASTOPEN_COOKIE_SIZE 8 /* the size employed by this impl. */ ++#define TCP_FASTOPEN_COOKIE_SIZE 4 /* the size employed by this impl. */ + + /* TCP Fast Open Cookie as stored in memory */ + struct tcp_fastopen_cookie { +@@ -74,6 +74,56 @@ + u32 end_seq; + }; + ++struct tcp_out_options { ++ u16 options; /* bit field of OPTION_* */ ++ u16 mss; /* 0 to disable */ ++ u8 ws; /* window scale, 0 to disable */ ++ u8 num_sack_blocks; /* number of SACK blocks to include */ ++ u8 hash_size; /* bytes in hash_location */ ++ __u8 *hash_location; /* temporary pointer, overloaded */ ++ __u32 tsval, tsecr; /* need to include OPTION_TS */ ++ struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ ++#ifdef CONFIG_MPTCP ++ u16 mptcp_options; /* bit field of MPTCP related OPTION_* */ ++ u8 dss_csum:1, /* dss-checksum required? */ ++ add_addr_v4:1, ++ add_addr_v6:1, ++ mptcp_ver:4; ++ ++ union { ++ struct { ++ __u64 sender_key; /* sender's key for mptcp */ ++ __u64 receiver_key; /* receiver's key for mptcp */ ++ } mp_capable; ++ ++ struct { ++ __u64 sender_truncated_mac; ++ __u32 sender_nonce; ++ /* random number of the sender */ ++ __u32 token; /* token for mptcp */ ++ u8 low_prio:1; ++ } mp_join_syns; ++ }; ++ ++ struct { ++ __u64 trunc_mac; ++ struct in_addr addr; ++ u16 port; ++ u8 addr_id; ++ } add_addr4; ++ ++ struct { ++ __u64 trunc_mac; ++ struct in6_addr addr; ++ u16 port; ++ u8 addr_id; ++ } add_addr6; ++ ++ u16 remove_addrs; /* list of address id */ ++ u8 addr_id; /* address id (mp_join or add_address) */ ++#endif /* CONFIG_MPTCP */ ++}; ++ + /*These are used to set the sack_ok field in struct tcp_options_received */ + #define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */ + #define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/ +@@ -97,6 +147,9 @@ + u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ + }; + ++struct mptcp_cb; ++struct mptcp_tcp_sock; ++ + static inline void tcp_clear_options(struct tcp_options_received *rx_opt) + { + rx_opt->tstamp_ok = rx_opt->sack_ok = 0; +@@ -135,6 +188,8 @@ + return (struct tcp_request_sock *)req; + } + ++struct tcp_md5sig_key; ++ + struct tcp_sock { + /* inet_connection_sock has to be the first member of tcp_sock */ + struct inet_connection_sock inet_conn; +@@ -395,6 +450,44 @@ + */ + struct request_sock __rcu *fastopen_rsk; + u32 *saved_syn; ++ ++ /* MPTCP/TCP-specific callbacks */ ++ const struct tcp_sock_ops *ops; ++ ++ struct mptcp_cb *mpcb; ++ struct sock *meta_sk; ++ /* We keep these flags even if CONFIG_MPTCP is not checked, because ++ * it allows checking MPTCP capability just by checking the mpc flag, ++ * rather than adding ifdefs everywhere. ++ */ ++ u32 mpc:1, /* Other end is multipath capable */ ++ inside_tk_table:1, /* Is the tcp_sock inside the token-table? */ ++ send_mp_fclose:1, ++ request_mptcp:1, /* Did we send out an MP_CAPABLE? ++ * (this speeds up mptcp_doit() in tcp_recvmsg) ++ */ ++ pf:1, /* Potentially Failed state: when this flag is set, we ++ * stop using the subflow ++ */ ++ mp_killed:1, /* Killed with a tcp_done in mptcp? */ ++ is_master_sk:1, ++ close_it:1, /* Must close socket in mptcp_data_ready? */ ++ closing:1, ++ mptcp_ver:4, ++ mptcp_sched_setsockopt:1, ++ mptcp_pm_setsockopt:1, ++ record_master_info:1, ++ tcp_disconnect:1; ++ struct mptcp_tcp_sock *mptcp; ++#ifdef CONFIG_MPTCP ++#define MPTCP_SCHED_NAME_MAX 16 ++#define MPTCP_PM_NAME_MAX 16 ++ struct hlist_nulls_node tk_table; ++ u32 mptcp_loc_token; ++ u64 mptcp_loc_key; ++ char mptcp_sched_name[MPTCP_SCHED_NAME_MAX]; ++ char mptcp_pm_name[MPTCP_PM_NAME_MAX]; ++#endif /* CONFIG_MPTCP */ + }; + + enum tsq_enum { +@@ -406,6 +499,8 @@ + TCP_MTU_REDUCED_DEFERRED, /* tcp_v{4|6}_err() could not call + * tcp_v{4|6}_mtu_reduced() + */ ++ MPTCP_PATH_MANAGER_DEFERRED, /* MPTCP deferred creation of new subflows */ ++ MPTCP_SUB_DEFERRED, /* A subflow got deferred - process them */ + }; + + enum tsq_flags { +@@ -415,6 +510,8 @@ + TCPF_WRITE_TIMER_DEFERRED = (1UL << TCP_WRITE_TIMER_DEFERRED), + TCPF_DELACK_TIMER_DEFERRED = (1UL << TCP_DELACK_TIMER_DEFERRED), + TCPF_MTU_REDUCED_DEFERRED = (1UL << TCP_MTU_REDUCED_DEFERRED), ++ TCPF_PATH_MANAGER_DEFERRED = (1UL << MPTCP_PATH_MANAGER_DEFERRED), ++ TCPF_SUB_DEFERRED = (1UL << MPTCP_SUB_DEFERRED), + }; + + static inline struct tcp_sock *tcp_sk(const struct sock *sk) +@@ -438,6 +535,7 @@ + #ifdef CONFIG_TCP_MD5SIG + struct tcp_md5sig_key *tw_md5_key; + #endif ++ struct mptcp_tw *mptcp_tw; + }; + + static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) +diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/inet_common.h +--- linux-5.4/include/net/inet_common.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-02-20 18:07:47.000000000 +0100 +@@ -2,6 +2,7 @@ + #ifndef _INET_COMMON_H + #define _INET_COMMON_H + ++#include + #include + + extern const struct proto_ops inet_stream_ops; +@@ -16,6 +17,8 @@ + struct sockaddr; + struct socket; + ++int inet_create(struct net *net, struct socket *sock, int protocol, int kern); ++int inet6_create(struct net *net, struct socket *sock, int protocol, int kern); + int inet_release(struct socket *sock); + int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, + int addr_len, int flags); +diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/include/net/inet_connection_sock.h +--- linux-5.4/include/net/inet_connection_sock.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-02-20 18:07:47.000000000 +0100 +@@ -25,6 +25,7 @@ + + struct inet_bind_bucket; + struct tcp_congestion_ops; ++struct tcp_options_received; + + /* + * Pointers to address related TCP functions +diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_sock.h +--- linux-5.4/include/net/inet_sock.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-02-20 18:07:47.000000000 +0100 +@@ -79,7 +79,7 @@ + #define ireq_state req.__req_common.skc_state + #define ireq_family req.__req_common.skc_family + +- u16 snd_wscale : 4, ++ u32 snd_wscale : 4, + rcv_wscale : 4, + tstamp_ok : 1, + sack_ok : 1, +@@ -87,6 +87,8 @@ + ecn_ok : 1, + acked : 1, + no_srccheck: 1, ++ mptcp_rqsk : 1, ++ saw_mpc : 1, + smc_ok : 1; + u32 ir_mark; + union { +diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +--- linux-5.4/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,1497 @@ ++/* ++ * MPTCP implementation ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer & Author: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#ifndef _MPTCP_H ++#define _MPTCP_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ #define ntohll(x) be64_to_cpu(x) ++ #define htonll(x) cpu_to_be64(x) ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ #define ntohll(x) (x) ++ #define htonll(x) (x) ++#endif ++ ++struct mptcp_loc4 { ++ u8 loc4_id; ++ u8 low_prio:1; ++ int if_idx; ++ struct in_addr addr; ++}; ++ ++struct mptcp_rem4 { ++ u8 rem4_id; ++ __be16 port; ++ struct in_addr addr; ++}; ++ ++struct mptcp_loc6 { ++ u8 loc6_id; ++ u8 low_prio:1; ++ int if_idx; ++ struct in6_addr addr; ++}; ++ ++struct mptcp_rem6 { ++ u8 rem6_id; ++ __be16 port; ++ struct in6_addr addr; ++}; ++ ++struct mptcp_request_sock { ++ struct tcp_request_sock req; ++ struct hlist_nulls_node hash_entry; ++ ++ union { ++ struct { ++ /* Only on initial subflows */ ++ u64 mptcp_loc_key; ++ u64 mptcp_rem_key; ++ u32 mptcp_loc_token; ++ }; ++ ++ struct { ++ /* Only on additional subflows */ ++ u32 mptcp_rem_nonce; ++ u32 mptcp_loc_nonce; ++ u64 mptcp_hash_tmac; ++ }; ++ }; ++ ++ u8 loc_id; ++ u8 rem_id; /* Address-id in the MP_JOIN */ ++ u8 dss_csum:1, ++ is_sub:1, /* Is this a new subflow? */ ++ low_prio:1, /* Interface set to low-prio? */ ++ rcv_low_prio:1, ++ mptcp_ver:4; ++}; ++ ++struct mptcp_options_received { ++ u16 saw_mpc:1, ++ dss_csum:1, ++ drop_me:1, ++ ++ is_mp_join:1, ++ join_ack:1, ++ ++ saw_low_prio:2, /* 0x1 - low-prio set for this subflow ++ * 0x2 - low-prio set for another subflow ++ */ ++ low_prio:1, ++ ++ saw_add_addr:2, /* Saw at least one add_addr option: ++ * 0x1: IPv4 - 0x2: IPv6 ++ */ ++ more_add_addr:1, /* Saw one more add-addr. */ ++ ++ saw_rem_addr:1, /* Saw at least one rem_addr option */ ++ more_rem_addr:1, /* Saw one more rem-addr. */ ++ ++ mp_fail:1, ++ mp_fclose:1; ++ u8 rem_id; /* Address-id in the MP_JOIN */ ++ u8 prio_addr_id; /* Address-id in the MP_PRIO */ ++ ++ const unsigned char *add_addr_ptr; /* Pointer to add-address option */ ++ const unsigned char *rem_addr_ptr; /* Pointer to rem-address option */ ++ ++ u32 data_ack; ++ u32 data_seq; ++ u16 data_len; ++ ++ u8 mptcp_ver; /* MPTCP version */ ++ ++ /* Key inside the option (from mp_capable or fast_close) */ ++ u64 mptcp_sender_key; ++ u64 mptcp_receiver_key; ++ ++ u32 mptcp_rem_token; /* Remote token */ ++ ++ u32 mptcp_recv_nonce; ++ u64 mptcp_recv_tmac; ++ u8 mptcp_recv_mac[20]; ++}; ++ ++struct mptcp_tcp_sock { ++ struct hlist_node node; ++ struct hlist_node cb_list; ++ struct mptcp_options_received rx_opt; ++ ++ /* Those three fields record the current mapping */ ++ u64 map_data_seq; ++ u32 map_subseq; ++ u16 map_data_len; ++ u16 slave_sk:1, ++ fully_established:1, ++ second_packet:1, ++ attached:1, ++ send_mp_fail:1, ++ include_mpc:1, ++ mapping_present:1, ++ map_data_fin:1, ++ low_prio:1, /* use this socket as backup */ ++ rcv_low_prio:1, /* Peer sent low-prio option to us */ ++ send_mp_prio:1, /* Trigger to send mp_prio on this socket */ ++ pre_established:1; /* State between sending 3rd ACK and ++ * receiving the fourth ack of new subflows. ++ */ ++ ++ /* isn: needed to translate abs to relative subflow seqnums */ ++ u32 snt_isn; ++ u32 rcv_isn; ++ u8 path_index; ++ u8 loc_id; ++ u8 rem_id; ++ u8 sk_err; ++ ++#define MPTCP_SCHED_SIZE 16 ++ u8 mptcp_sched[MPTCP_SCHED_SIZE] __aligned(8); ++ ++ int init_rcv_wnd; ++ u32 infinite_cutoff_seq; ++ struct delayed_work work; ++ u32 mptcp_loc_nonce; ++ struct tcp_sock *tp; ++ u32 last_end_data_seq; ++ ++ /* MP_JOIN subflow: timer for retransmitting the 3rd ack */ ++ struct timer_list mptcp_ack_timer; ++ ++ /* HMAC of the third ack */ ++ char sender_mac[20]; ++}; ++ ++struct mptcp_tw { ++ struct list_head list; ++ u64 loc_key; ++ u64 rcv_nxt; ++ struct mptcp_cb __rcu *mpcb; ++ u8 meta_tw:1, ++ in_list:1; ++}; ++ ++#define MPTCP_PM_NAME_MAX 16 ++struct mptcp_pm_ops { ++ struct list_head list; ++ ++ /* Signal the creation of a new MPTCP-session. */ ++ void (*new_session)(const struct sock *meta_sk); ++ void (*release_sock)(struct sock *meta_sk); ++ void (*fully_established)(struct sock *meta_sk); ++ void (*close_session)(struct sock *meta_sk); ++ void (*new_remote_address)(struct sock *meta_sk); ++ int (*get_local_id)(const struct sock *meta_sk, sa_family_t family, ++ union inet_addr *addr, bool *low_prio); ++ void (*addr_signal)(struct sock *sk, unsigned *size, ++ struct tcp_out_options *opts, struct sk_buff *skb); ++ void (*add_raddr)(struct mptcp_cb *mpcb, const union inet_addr *addr, ++ sa_family_t family, __be16 port, u8 id); ++ void (*rem_raddr)(struct mptcp_cb *mpcb, u8 rem_id); ++ void (*init_subsocket_v4)(struct sock *sk, struct in_addr addr); ++ void (*init_subsocket_v6)(struct sock *sk, struct in6_addr addr); ++ void (*established_subflow)(struct sock *sk); ++ void (*delete_subflow)(struct sock *sk); ++ void (*prio_changed)(struct sock *sk, int low_prio); ++ ++ char name[MPTCP_PM_NAME_MAX]; ++ struct module *owner; ++}; ++ ++#define MPTCP_SCHED_NAME_MAX 16 ++struct mptcp_sched_ops { ++ struct list_head list; ++ ++ struct sock * (*get_subflow)(struct sock *meta_sk, ++ struct sk_buff *skb, ++ bool zero_wnd_test); ++ struct sk_buff * (*next_segment)(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit); ++ void (*init)(struct sock *sk); ++ void (*release)(struct sock *sk); ++ ++ char name[MPTCP_SCHED_NAME_MAX]; ++ struct module *owner; ++}; ++ ++struct mptcp_cb { ++ /* list of sockets in this multipath connection */ ++ struct hlist_head conn_list; ++ /* list of sockets that need a call to release_cb */ ++ struct hlist_head callback_list; ++ ++ /* Lock used for protecting the different rcu-lists of mptcp_cb */ ++ spinlock_t mpcb_list_lock; ++ ++ /* High-order bits of 64-bit sequence numbers */ ++ u32 snd_high_order[2]; ++ u32 rcv_high_order[2]; ++ ++ u16 send_infinite_mapping:1, ++ in_time_wait:1, ++ list_rcvd:1, /* XXX TO REMOVE */ ++ addr_signal:1, /* Path-manager wants us to call addr_signal */ ++ dss_csum:1, ++ server_side:1, ++ infinite_mapping_rcv:1, ++ infinite_mapping_snd:1, ++ dfin_combined:1, /* Was the DFIN combined with subflow-fin? */ ++ passive_close:1, ++ snd_hiseq_index:1, /* Index in snd_high_order of snd_nxt */ ++ rcv_hiseq_index:1, /* Index in rcv_high_order of rcv_nxt */ ++ tcp_ca_explicit_set:1; /* was meta CC set by app? */ ++ ++#define MPTCP_SCHED_DATA_SIZE 8 ++ u8 mptcp_sched[MPTCP_SCHED_DATA_SIZE] __aligned(8); ++ const struct mptcp_sched_ops *sched_ops; ++ ++ struct sk_buff_head reinject_queue; ++ /* First cache-line boundary is here minus 8 bytes. But from the ++ * reinject-queue only the next and prev pointers are regularly ++ * accessed. Thus, the whole data-path is on a single cache-line. ++ */ ++ ++ u64 csum_cutoff_seq; ++ u64 infinite_rcv_seq; ++ ++ /***** Start of fields, used for connection closure */ ++ unsigned char mptw_state; ++ u8 dfin_path_index; ++ ++ struct list_head tw_list; ++ ++ /***** Start of fields, used for subflow establishment and closure */ ++ refcount_t mpcb_refcnt; ++ ++ /* Mutex needed, because otherwise mptcp_close will complain that the ++ * socket is owned by the user. ++ * E.g., mptcp_sub_close_wq is taking the meta-lock. ++ */ ++ struct mutex mpcb_mutex; ++ ++ /***** Start of fields, used for subflow establishment */ ++ struct sock *meta_sk; ++ ++ /* Master socket, also part of the conn_list, this ++ * socket is the one that the application sees. ++ */ ++ struct sock *master_sk; ++ ++ __u64 mptcp_loc_key; ++ __u64 mptcp_rem_key; ++ __u32 mptcp_loc_token; ++ __u32 mptcp_rem_token; ++ ++#define MPTCP_PM_SIZE 608 ++ u8 mptcp_pm[MPTCP_PM_SIZE] __aligned(8); ++ const struct mptcp_pm_ops *pm_ops; ++ ++ unsigned long path_index_bits; ++ ++ __u8 mptcp_ver; ++ ++ /* Original snd/rcvbuf of the initial subflow. ++ * Used for the new subflows on the server-side to allow correct ++ * autotuning ++ */ ++ int orig_sk_rcvbuf; ++ int orig_sk_sndbuf; ++ u32 orig_window_clamp; ++ ++ struct tcp_info *master_info; ++}; ++ ++#define MPTCP_VERSION_0 0 ++#define MPTCP_VERSION_1 1 ++ ++#define MPTCP_SUB_CAPABLE 0 ++#define MPTCP_SUB_LEN_CAPABLE_SYN 12 ++#define MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN 12 ++#define MPTCP_SUB_LEN_CAPABLE_ACK 20 ++#define MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN 20 ++ ++#define MPTCP_SUB_JOIN 1 ++#define MPTCP_SUB_LEN_JOIN_SYN 12 ++#define MPTCP_SUB_LEN_JOIN_SYN_ALIGN 12 ++#define MPTCP_SUB_LEN_JOIN_SYNACK 16 ++#define MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN 16 ++#define MPTCP_SUB_LEN_JOIN_ACK 24 ++#define MPTCP_SUB_LEN_JOIN_ACK_ALIGN 24 ++ ++#define MPTCP_SUB_DSS 2 ++#define MPTCP_SUB_LEN_DSS 4 ++#define MPTCP_SUB_LEN_DSS_ALIGN 4 ++ ++/* Lengths for seq and ack are the ones without the generic MPTCP-option header, ++ * as they are part of the DSS-option. ++ * To get the total length, just add the different options together. ++ */ ++#define MPTCP_SUB_LEN_SEQ 10 ++#define MPTCP_SUB_LEN_SEQ_CSUM 12 ++#define MPTCP_SUB_LEN_SEQ_ALIGN 12 ++ ++#define MPTCP_SUB_LEN_SEQ_64 14 ++#define MPTCP_SUB_LEN_SEQ_CSUM_64 16 ++#define MPTCP_SUB_LEN_SEQ_64_ALIGN 16 ++ ++#define MPTCP_SUB_LEN_ACK 4 ++#define MPTCP_SUB_LEN_ACK_ALIGN 4 ++ ++#define MPTCP_SUB_LEN_ACK_64 8 ++#define MPTCP_SUB_LEN_ACK_64_ALIGN 8 ++ ++/* This is the "default" option-length we will send out most often. ++ * MPTCP DSS-header ++ * 32-bit data sequence number ++ * 32-bit data ack ++ * ++ * It is necessary to calculate the effective MSS we will be using when ++ * sending data. ++ */ ++#define MPTCP_SUB_LEN_DSM_ALIGN (MPTCP_SUB_LEN_DSS_ALIGN + \ ++ MPTCP_SUB_LEN_SEQ_ALIGN + \ ++ MPTCP_SUB_LEN_ACK_ALIGN) ++ ++#define MPTCP_SUB_ADD_ADDR 3 ++#define MPTCP_SUB_LEN_ADD_ADDR4 8 ++#define MPTCP_SUB_LEN_ADD_ADDR4_VER1 16 ++#define MPTCP_SUB_LEN_ADD_ADDR6 20 ++#define MPTCP_SUB_LEN_ADD_ADDR6_VER1 28 ++#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN 8 ++#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 16 ++#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN 20 ++#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 28 ++ ++#define MPTCP_SUB_REMOVE_ADDR 4 ++#define MPTCP_SUB_LEN_REMOVE_ADDR 4 ++ ++#define MPTCP_SUB_PRIO 5 ++#define MPTCP_SUB_LEN_PRIO 3 ++#define MPTCP_SUB_LEN_PRIO_ADDR 4 ++#define MPTCP_SUB_LEN_PRIO_ALIGN 4 ++ ++#define MPTCP_SUB_FAIL 6 ++#define MPTCP_SUB_LEN_FAIL 12 ++#define MPTCP_SUB_LEN_FAIL_ALIGN 12 ++ ++#define MPTCP_SUB_FCLOSE 7 ++#define MPTCP_SUB_LEN_FCLOSE 12 ++#define MPTCP_SUB_LEN_FCLOSE_ALIGN 12 ++ ++ ++#define OPTION_MPTCP (1 << 5) ++ ++/* Max number of fastclose retransmissions */ ++#define MPTCP_FASTCLOSE_RETRIES 3 ++ ++#ifdef CONFIG_MPTCP ++ ++/* Used for checking if the mptcp initialization has been successful */ ++extern bool mptcp_init_failed; ++ ++/* MPTCP options */ ++#define OPTION_TYPE_SYN (1 << 0) ++#define OPTION_TYPE_SYNACK (1 << 1) ++#define OPTION_TYPE_ACK (1 << 2) ++#define OPTION_MP_CAPABLE (1 << 3) ++#define OPTION_DATA_ACK (1 << 4) ++#define OPTION_ADD_ADDR (1 << 5) ++#define OPTION_MP_JOIN (1 << 6) ++#define OPTION_MP_FAIL (1 << 7) ++#define OPTION_MP_FCLOSE (1 << 8) ++#define OPTION_REMOVE_ADDR (1 << 9) ++#define OPTION_MP_PRIO (1 << 10) ++ ++/* MPTCP flags: both TX and RX */ ++#define MPTCPHDR_SEQ 0x01 /* DSS.M option is present */ ++#define MPTCPHDR_FIN 0x02 /* DSS.F option is present */ ++#define MPTCPHDR_SEQ64_INDEX 0x04 /* index of seq in mpcb->snd_high_order */ ++/* MPTCP flags: RX only */ ++#define MPTCPHDR_ACK 0x08 ++#define MPTCPHDR_SEQ64_SET 0x10 /* Did we received a 64-bit seq number? */ ++#define MPTCPHDR_SEQ64_OFO 0x20 /* Is it not in our circular array? */ ++#define MPTCPHDR_DSS_CSUM 0x40 ++/* MPTCP flags: TX only */ ++#define MPTCPHDR_INF 0x08 ++#define MPTCP_REINJECT 0x10 /* Did we reinject this segment? */ ++ ++struct mptcp_option { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u8 ver:4, ++ sub:4; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u8 sub:4, ++ ver:4; ++#else ++#error "Adjust your defines" ++#endif ++}; ++ ++struct mp_capable { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u8 ver:4, ++ sub:4; ++ __u8 h:1, ++ rsv:5, ++ b:1, ++ a:1; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u8 sub:4, ++ ver:4; ++ __u8 a:1, ++ b:1, ++ rsv:5, ++ h:1; ++#else ++#error "Adjust your defines" ++#endif ++ __u64 sender_key; ++ __u64 receiver_key; ++} __attribute__((__packed__)); ++ ++struct mp_join { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u8 b:1, ++ rsv:3, ++ sub:4; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u8 sub:4, ++ rsv:3, ++ b:1; ++#else ++#error "Adjust your defines" ++#endif ++ __u8 addr_id; ++ union { ++ struct { ++ u32 token; ++ u32 nonce; ++ } syn; ++ struct { ++ __u64 mac; ++ u32 nonce; ++ } synack; ++ struct { ++ __u8 mac[20]; ++ } ack; ++ } u; ++} __attribute__((__packed__)); ++ ++struct mp_dss { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u16 rsv1:4, ++ sub:4, ++ A:1, ++ a:1, ++ M:1, ++ m:1, ++ F:1, ++ rsv2:3; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u16 sub:4, ++ rsv1:4, ++ rsv2:3, ++ F:1, ++ m:1, ++ M:1, ++ a:1, ++ A:1; ++#else ++#error "Adjust your defines" ++#endif ++}; ++ ++struct mp_add_addr { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u8 ipver:4, ++ sub:4; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u8 sub:4, ++ ipver:4; ++#else ++#error "Adjust your defines" ++#endif ++ __u8 addr_id; ++ union { ++ struct { ++ struct in_addr addr; ++ __be16 port; ++ __u8 mac[8]; ++ } v4; ++ struct { ++ struct in6_addr addr; ++ __be16 port; ++ __u8 mac[8]; ++ } v6; ++ } u; ++} __attribute__((__packed__)); ++ ++struct mp_remove_addr { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u8 rsv:4, ++ sub:4; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u8 sub:4, ++ rsv:4; ++#else ++#error "Adjust your defines" ++#endif ++ /* list of addr_id */ ++ __u8 addrs_id; ++}; ++ ++struct mp_fail { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u16 rsv1:4, ++ sub:4, ++ rsv2:8; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u16 sub:4, ++ rsv1:4, ++ rsv2:8; ++#else ++#error "Adjust your defines" ++#endif ++ __be64 data_seq; ++} __attribute__((__packed__)); ++ ++struct mp_fclose { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u16 rsv1:4, ++ sub:4, ++ rsv2:8; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u16 sub:4, ++ rsv1:4, ++ rsv2:8; ++#else ++#error "Adjust your defines" ++#endif ++ __u64 key; ++} __attribute__((__packed__)); ++ ++struct mp_prio { ++ __u8 kind; ++ __u8 len; ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ __u8 b:1, ++ rsv:3, ++ sub:4; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++ __u8 sub:4, ++ rsv:3, ++ b:1; ++#else ++#error "Adjust your defines" ++#endif ++ __u8 addr_id; ++} __attribute__((__packed__)); ++ ++static inline int mptcp_sub_len_dss(const struct mp_dss *m, const int csum) ++{ ++ return 4 + m->A * (4 + m->a * 4) + m->M * (10 + m->m * 4 + csum * 2); ++} ++ ++#define MPTCP_SYSCTL 1 ++ ++extern int sysctl_mptcp_enabled; ++extern int sysctl_mptcp_version; ++extern int sysctl_mptcp_checksum; ++extern int sysctl_mptcp_debug; ++extern int sysctl_mptcp_syn_retries; ++ ++extern struct workqueue_struct *mptcp_wq; ++ ++#define mptcp_debug(fmt, args...) \ ++ do { \ ++ if (unlikely(sysctl_mptcp_debug)) \ ++ pr_err(fmt, ##args); \ ++ } while (0) ++ ++static inline struct sock *mptcp_to_sock(const struct mptcp_tcp_sock *mptcp) ++{ ++ return (struct sock *)mptcp->tp; ++} ++ ++#define mptcp_for_each_sub(__mpcb, __mptcp) \ ++ hlist_for_each_entry_rcu(__mptcp, &((__mpcb)->conn_list), node) ++ ++/* Must be called with the appropriate lock held */ ++#define mptcp_for_each_sub_safe(__mpcb, __mptcp, __tmp) \ ++ hlist_for_each_entry_safe(__mptcp, __tmp, &((__mpcb)->conn_list), node) ++ ++/* Iterates over all bit set to 1 in a bitset */ ++#define mptcp_for_each_bit_set(b, i) \ ++ for (i = ffs(b) - 1; i >= 0; i = ffs(b >> (i + 1) << (i + 1)) - 1) ++ ++#define mptcp_for_each_bit_unset(b, i) \ ++ mptcp_for_each_bit_set(~b, i) ++ ++#define MPTCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) ++#define MPTCP_INC_STATS_BH(net, field) __SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) ++ ++enum ++{ ++ MPTCP_MIB_NUM = 0, ++ MPTCP_MIB_MPCAPABLEPASSIVE, /* Received SYN with MP_CAPABLE */ ++ MPTCP_MIB_MPCAPABLEACTIVE, /* Sent SYN with MP_CAPABLE */ ++ MPTCP_MIB_MPCAPABLEACTIVEACK, /* Received SYN/ACK with MP_CAPABLE */ ++ MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */ ++ MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */ ++ MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */ ++ MPTCP_MIB_MPCAPABLERETRANSFALLBACK,/* Client-side stopped sending MP_CAPABLE after too many SYN-retransmissions */ ++ MPTCP_MIB_CSUMENABLED, /* Created MPTCP-connection with DSS-checksum enabled */ ++ MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */ ++ MPTCP_MIB_MPFAILRX, /* Received an MP_FAIL */ ++ MPTCP_MIB_CSUMFAIL, /* Received segment with invalid checksum */ ++ MPTCP_MIB_FASTCLOSERX, /* Recevied a FAST_CLOSE */ ++ MPTCP_MIB_FASTCLOSETX, /* Sent a FAST_CLOSE */ ++ MPTCP_MIB_FBACKSUB, /* Fallback upon ack without data-ack on new subflow */ ++ MPTCP_MIB_FBACKINIT, /* Fallback upon ack without data-ack on initial subflow */ ++ MPTCP_MIB_FBDATASUB, /* Fallback upon data without DSS at the beginning on new subflow */ ++ MPTCP_MIB_FBDATAINIT, /* Fallback upon data without DSS at the beginning on initial subflow */ ++ MPTCP_MIB_REMADDRSUB, /* Remove subflow due to REMOVE_ADDR */ ++ MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */ ++ MPTCP_MIB_JOINFALLBACK, /* Received MP_JOIN on session that has fallen back to reg. TCP */ ++ MPTCP_MIB_JOINSYNTX, /* Sent a SYN + MP_JOIN */ ++ MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */ ++ MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */ ++ MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */ ++ MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */ ++ MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */ ++ MPTCP_MIB_JOINACKFAIL, /* Third ACK on new subflow did not contain an MP_JOIN */ ++ MPTCP_MIB_JOINACKRTO, /* Retransmission timer for third ACK + MP_JOIN timed out */ ++ MPTCP_MIB_JOINACKRXMIT, /* Retransmitted an ACK + MP_JOIN */ ++ MPTCP_MIB_NODSSWINDOW, /* Received too many packets without a DSS-option */ ++ MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */ ++ MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */ ++ MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */ ++ MPTCP_MIB_DSSTRIMHEAD, /* Trimmed segment at the head (coalescing middlebox) */ ++ MPTCP_MIB_DSSSPLITTAIL, /* Trimmed segment at the tail (coalescing middlebox) */ ++ MPTCP_MIB_PURGEOLD, /* Removed old skb from the rcv-queue due to missing DSS-mapping */ ++ MPTCP_MIB_ADDADDRRX, /* Received an ADD_ADDR */ ++ MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */ ++ MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */ ++ MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */ ++ __MPTCP_MIB_MAX ++}; ++ ++#define MPTCP_MIB_MAX __MPTCP_MIB_MAX ++struct mptcp_mib { ++ unsigned long mibs[MPTCP_MIB_MAX]; ++}; ++ ++extern struct lock_class_key meta_key; ++extern char *meta_key_name; ++extern struct lock_class_key meta_slock_key; ++extern char *meta_slock_key_name; ++ ++extern siphash_key_t mptcp_secret; ++ ++/* This is needed to ensure that two subsequent key/nonce-generation result in ++ * different keys/nonces if the IPs and ports are the same. ++ */ ++extern u32 mptcp_seed; ++ ++#define MPTCP_HASH_SIZE 1024 ++ ++extern struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; ++ ++/* Request-sockets can be hashed in the tk_htb for collision-detection or in ++ * the regular htb for join-connections. We need to define different NULLS ++ * values so that we can correctly detect a request-socket that has been ++ * recycled. See also c25eb3bfb9729. ++ */ ++#define MPTCP_REQSK_NULLS_BASE (1U << 29) ++ ++ ++void mptcp_data_ready(struct sock *sk); ++void mptcp_write_space(struct sock *sk); ++ ++void mptcp_add_meta_ofo_queue(const struct sock *meta_sk, struct sk_buff *skb, ++ struct sock *sk); ++void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied); ++int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, ++ gfp_t flags); ++void mptcp_del_sock(struct sock *sk); ++void mptcp_update_metasocket(const struct sock *meta_sk); ++void mptcp_reinject_data(struct sock *orig_sk, int clone_it); ++void mptcp_update_sndbuf(const struct tcp_sock *tp); ++void mptcp_send_fin(struct sock *meta_sk); ++void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority); ++bool mptcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, ++ int push_one, gfp_t gfp); ++void tcp_parse_mptcp_options(const struct sk_buff *skb, ++ struct mptcp_options_received *mopt); ++void mptcp_parse_options(const uint8_t *ptr, int opsize, ++ struct mptcp_options_received *mopt, ++ const struct sk_buff *skb, ++ struct tcp_sock *tp); ++void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, ++ unsigned *remaining); ++void mptcp_synack_options(struct request_sock *req, ++ struct tcp_out_options *opts, ++ unsigned *remaining); ++void mptcp_established_options(struct sock *sk, struct sk_buff *skb, ++ struct tcp_out_options *opts, unsigned *size); ++void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, ++ const struct tcp_out_options *opts, ++ struct sk_buff *skb); ++void mptcp_close(struct sock *meta_sk, long timeout); ++bool mptcp_doit(struct sock *sk); ++int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, ++ __u8 mptcp_ver, u32 window); ++int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req); ++int mptcp_check_req_master(struct sock *sk, struct sock *child, ++ struct request_sock *req, const struct sk_buff *skb, ++ int drop, u32 tsoff); ++struct sock *mptcp_check_req_child(struct sock *meta_sk, ++ struct sock *child, ++ struct request_sock *req, ++ struct sk_buff *skb, ++ const struct mptcp_options_received *mopt); ++u32 __mptcp_select_window(struct sock *sk); ++void mptcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, ++ __u32 *rcv_wnd, __u32 *window_clamp, ++ int wscale_ok, __u8 *rcv_wscale, ++ __u32 init_rcv_wnd); ++unsigned int mptcp_current_mss(struct sock *meta_sk); ++void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, ...); ++void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); ++void mptcp_fin(struct sock *meta_sk); ++void mptcp_meta_retransmit_timer(struct sock *meta_sk); ++void mptcp_sub_retransmit_timer(struct sock *sk); ++int mptcp_write_wakeup(struct sock *meta_sk, int mib); ++void mptcp_sub_close_wq(struct work_struct *work); ++void mptcp_sub_close(struct sock *sk, unsigned long delay); ++struct sock *mptcp_select_ack_sock(const struct sock *meta_sk); ++void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb); ++int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb); ++void mptcp_ack_handler(struct timer_list *t); ++bool mptcp_check_rtt(const struct tcp_sock *tp, int time); ++int mptcp_check_snd_buf(const struct tcp_sock *tp); ++bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, ++ const struct sk_buff *skb); ++void __init mptcp_init(void); ++void mptcp_destroy_sock(struct sock *sk); ++int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, ++ const struct sk_buff *skb, ++ const struct mptcp_options_received *mopt); ++unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, ++ int large_allowed); ++int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw); ++void mptcp_twsk_destructor(struct tcp_timewait_sock *tw); ++void mptcp_time_wait(struct sock *sk, int state, int timeo); ++void mptcp_disconnect(struct sock *meta_sk); ++bool mptcp_should_expand_sndbuf(const struct sock *sk); ++int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb); ++void mptcp_tsq_flags(struct sock *sk); ++void mptcp_tsq_sub_deferred(struct sock *meta_sk); ++struct mp_join *mptcp_find_join(const struct sk_buff *skb); ++void mptcp_hash_remove_bh(struct tcp_sock *meta_tp); ++struct sock *mptcp_hash_find(const struct net *net, const u32 token); ++int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw); ++int mptcp_do_join_short(struct sk_buff *skb, ++ const struct mptcp_options_received *mopt, ++ struct net *net); ++void mptcp_reqsk_destructor(struct request_sock *req); ++void mptcp_connect_init(struct sock *sk); ++void mptcp_sub_force_close(struct sock *sk); ++int mptcp_sub_len_remove_addr_align(u16 bitfield); ++void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, ++ const struct request_sock *req, ++ struct sk_buff *skb); ++void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, bool want_cookie); ++int mptcp_conn_request(struct sock *sk, struct sk_buff *skb); ++void mptcp_enable_sock(struct sock *sk); ++void mptcp_disable_sock(struct sock *sk); ++void mptcp_disable_static_key(void); ++void mptcp_cookies_reqsk_init(struct request_sock *req, ++ struct mptcp_options_received *mopt, ++ struct sk_buff *skb); ++void mptcp_mpcb_put(struct mptcp_cb *mpcb); ++int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb); ++int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen); ++void mptcp_clear_sk(struct sock *sk, int size); ++ ++/* MPTCP-path-manager registration/initialization functions */ ++int mptcp_register_path_manager(struct mptcp_pm_ops *pm); ++void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm); ++void mptcp_init_path_manager(struct mptcp_cb *mpcb); ++void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb); ++void mptcp_fallback_default(struct mptcp_cb *mpcb); ++void mptcp_get_default_path_manager(char *name); ++int mptcp_set_scheduler(struct sock *sk, const char *name); ++int mptcp_set_path_manager(struct sock *sk, const char *name); ++int mptcp_set_default_path_manager(const char *name); ++extern struct mptcp_pm_ops mptcp_pm_default; ++ ++/* MPTCP-scheduler registration/initialization functions */ ++int mptcp_register_scheduler(struct mptcp_sched_ops *sched); ++void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched); ++void mptcp_init_scheduler(struct mptcp_cb *mpcb); ++void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb); ++void mptcp_get_default_scheduler(char *name); ++int mptcp_set_default_scheduler(const char *name); ++bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, ++ bool zero_wnd_test); ++bool mptcp_is_def_unavailable(struct sock *sk); ++bool subflow_is_active(const struct tcp_sock *tp); ++bool subflow_is_backup(const struct tcp_sock *tp); ++struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, ++ bool zero_wnd_test); ++extern struct mptcp_sched_ops mptcp_sched_default; ++ ++/* Initializes function-pointers and MPTCP-flags */ ++static inline void mptcp_init_tcp_sock(struct sock *sk) ++{ ++ if (!mptcp_init_failed && sysctl_mptcp_enabled == MPTCP_SYSCTL) ++ mptcp_enable_sock(sk); ++} ++ ++static inline int mptcp_pi_to_flag(int pi) ++{ ++ return 1 << (pi - 1); ++} ++ ++static inline ++struct mptcp_request_sock *mptcp_rsk(const struct request_sock *req) ++{ ++ return (struct mptcp_request_sock *)req; ++} ++ ++static inline ++struct request_sock *rev_mptcp_rsk(const struct mptcp_request_sock *req) ++{ ++ return (struct request_sock *)req; ++} ++ ++static inline bool mptcp_can_sendpage(struct sock *sk) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ ++ if (tcp_sk(sk)->mpcb->dss_csum) ++ return false; ++ ++ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if (!(sk_it->sk_route_caps & NETIF_F_SG)) ++ return false; ++ } ++ ++ return true; ++} ++ ++static inline void mptcp_push_pending_frames(struct sock *meta_sk) ++{ ++ /* We check packets out and send-head here. TCP only checks the ++ * send-head. But, MPTCP also checks packets_out, as this is an ++ * indication that we might want to do opportunistic reinjection. ++ */ ++ if (tcp_sk(meta_sk)->packets_out || tcp_send_head(meta_sk)) { ++ struct tcp_sock *tp = tcp_sk(meta_sk); ++ ++ /* We don't care about the MSS, because it will be set in ++ * mptcp_write_xmit. ++ */ ++ __tcp_push_pending_frames(meta_sk, 0, tp->nonagle); ++ } ++} ++ ++static inline void mptcp_send_reset(struct sock *sk) ++{ ++ if (tcp_need_reset(sk->sk_state)) ++ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); ++ mptcp_sub_force_close(sk); ++} ++ ++static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, ++ struct sock *except) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if (sk_it != except) ++ mptcp_send_reset(sk_it); ++ } ++} ++ ++static inline bool mptcp_is_data_seq(const struct sk_buff *skb) ++{ ++ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ; ++} ++ ++static inline bool mptcp_is_data_fin(const struct sk_buff *skb) ++{ ++ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_FIN; ++} ++ ++/* Is it a data-fin while in infinite mapping mode? ++ * In infinite mode, a subflow-fin is in fact a data-fin. ++ */ ++static inline bool mptcp_is_data_fin2(const struct sk_buff *skb, ++ const struct tcp_sock *tp) ++{ ++ return mptcp_is_data_fin(skb) || ++ (tp->mpcb->infinite_mapping_rcv && ++ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)); ++} ++ ++static inline u8 mptcp_get_64_bit(u64 data_seq, struct mptcp_cb *mpcb) ++{ ++ u64 data_seq_high = (u32)(data_seq >> 32); ++ ++ if (mpcb->rcv_high_order[0] == data_seq_high) ++ return 0; ++ else if (mpcb->rcv_high_order[1] == data_seq_high) ++ return MPTCPHDR_SEQ64_INDEX; ++ else ++ return MPTCPHDR_SEQ64_OFO; ++} ++ ++/* Sets the data_seq and returns pointer to the in-skb field of the data_seq. ++ * If the packet has a 64-bit dseq, the pointer points to the last 32 bits. ++ */ ++static inline __u32 *mptcp_skb_set_data_seq(const struct sk_buff *skb, ++ u32 *data_seq, ++ struct mptcp_cb *mpcb) ++{ ++ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); ++ ++ if (TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ64_SET) { ++ u64 data_seq64 = get_unaligned_be64(ptr); ++ ++ if (mpcb) ++ TCP_SKB_CB(skb)->mptcp_flags |= mptcp_get_64_bit(data_seq64, mpcb); ++ ++ *data_seq = (u32)data_seq64; ++ ptr++; ++ } else { ++ *data_seq = get_unaligned_be32(ptr); ++ } ++ ++ return ptr; ++} ++ ++static inline struct sock *mptcp_meta_sk(const struct sock *sk) ++{ ++ return tcp_sk(sk)->meta_sk; ++} ++ ++static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) ++{ ++ return tcp_sk(tp->meta_sk); ++} ++ ++static inline int is_meta_tp(const struct tcp_sock *tp) ++{ ++ return tp->mpcb && mptcp_meta_tp(tp) == tp; ++} ++ ++static inline int is_meta_sk(const struct sock *sk) ++{ ++ return sk->sk_state != TCP_NEW_SYN_RECV && ++ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && ++ mptcp(tcp_sk(sk)) && mptcp_meta_sk(sk) == sk; ++} ++ ++static inline int is_master_tp(const struct tcp_sock *tp) ++{ ++ return !mptcp(tp) || (!tp->mptcp->slave_sk && !is_meta_tp(tp)); ++} ++ ++static inline void mptcp_init_mp_opt(struct mptcp_options_received *mopt) ++{ ++ mopt->saw_mpc = 0; ++ mopt->dss_csum = 0; ++ mopt->drop_me = 0; ++ ++ mopt->is_mp_join = 0; ++ mopt->join_ack = 0; ++ ++ mopt->saw_low_prio = 0; ++ mopt->low_prio = 0; ++ ++ mopt->saw_add_addr = 0; ++ mopt->more_add_addr = 0; ++ ++ mopt->saw_rem_addr = 0; ++ mopt->more_rem_addr = 0; ++ ++ mopt->mp_fail = 0; ++ mopt->mp_fclose = 0; ++} ++ ++static inline void mptcp_reset_mopt(struct tcp_sock *tp) ++{ ++ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; ++ ++ mopt->saw_low_prio = 0; ++ mopt->saw_add_addr = 0; ++ mopt->more_add_addr = 0; ++ mopt->saw_rem_addr = 0; ++ mopt->more_rem_addr = 0; ++ mopt->join_ack = 0; ++ mopt->mp_fail = 0; ++ mopt->mp_fclose = 0; ++} ++ ++static inline __be32 mptcp_get_highorder_sndbits(const struct sk_buff *skb, ++ const struct mptcp_cb *mpcb) ++{ ++ return htonl(mpcb->snd_high_order[(TCP_SKB_CB(skb)->mptcp_flags & ++ MPTCPHDR_SEQ64_INDEX) ? 1 : 0]); ++} ++ ++static inline u64 mptcp_get_data_seq_64(const struct mptcp_cb *mpcb, int index, ++ u32 data_seq_32) ++{ ++ return ((u64)mpcb->rcv_high_order[index] << 32) | data_seq_32; ++} ++ ++static inline u64 mptcp_get_rcv_nxt_64(const struct tcp_sock *meta_tp) ++{ ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ return mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, ++ meta_tp->rcv_nxt); ++} ++ ++static inline void mptcp_check_sndseq_wrap(struct tcp_sock *meta_tp, int inc) ++{ ++ if (unlikely(meta_tp->snd_nxt > meta_tp->snd_nxt + inc)) { ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; ++ mpcb->snd_high_order[mpcb->snd_hiseq_index] += 2; ++ } ++} ++ ++static inline void mptcp_check_rcvseq_wrap(struct tcp_sock *meta_tp, ++ u32 old_rcv_nxt) ++{ ++ if (unlikely(old_rcv_nxt > meta_tp->rcv_nxt)) { ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ mpcb->rcv_high_order[mpcb->rcv_hiseq_index] += 2; ++ mpcb->rcv_hiseq_index = mpcb->rcv_hiseq_index ? 0 : 1; ++ } ++} ++ ++static inline int mptcp_sk_can_send(const struct sock *sk) ++{ ++ return tcp_passive_fastopen(sk) || ++ ((1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && ++ !tcp_sk(sk)->mptcp->pre_established); ++} ++ ++static inline int mptcp_sk_can_recv(const struct sock *sk) ++{ ++ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2); ++} ++ ++static inline int mptcp_sk_can_send_ack(const struct sock *sk) ++{ ++ return !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV | ++ TCPF_CLOSE | TCPF_LISTEN)) && ++ !tcp_sk(sk)->mptcp->pre_established; ++} ++ ++static inline bool mptcp_can_sg(const struct sock *meta_sk) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ ++ if (tcp_sk(meta_sk)->mpcb->dss_csum) ++ return false; ++ ++ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if (!mptcp_sk_can_send(sk)) ++ continue; ++ if (!(sk->sk_route_caps & NETIF_F_SG)) ++ return false; ++ } ++ return true; ++} ++ ++static inline void mptcp_set_rto(struct sock *sk) ++{ ++ struct inet_connection_sock *micsk = inet_csk(mptcp_meta_sk(sk)); ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_tcp_sock *mptcp; ++ __u32 max_rto = 0; ++ ++ /* We are in recovery-phase on the MPTCP-level. Do not update the ++ * RTO, because this would kill exponential backoff. ++ */ ++ if (micsk->icsk_retransmits) ++ return; ++ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if ((mptcp_sk_can_send(sk_it) || sk_it->sk_state == TCP_SYN_RECV) && ++ inet_csk(sk_it)->icsk_retransmits == 0 && ++ inet_csk(sk_it)->icsk_backoff == 0 && ++ inet_csk(sk_it)->icsk_rto > max_rto) ++ max_rto = inet_csk(sk_it)->icsk_rto; ++ } ++ if (max_rto) { ++ micsk->icsk_rto = max_rto << 1; ++ ++ /* A successfull rto-measurement - reset backoff counter */ ++ micsk->icsk_backoff = 0; ++ } ++} ++ ++static inline void mptcp_sub_close_passive(struct sock *sk) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(meta_sk); ++ ++ /* Only close, if the app did a send-shutdown (passive close), and we ++ * received the data-ack of the data-fin. ++ */ ++ if (tp->mpcb->passive_close && meta_tp->snd_una == meta_tp->write_seq) ++ mptcp_sub_close(sk, 0); ++} ++ ++static inline void mptcp_fallback_close(struct mptcp_cb *mpcb, ++ struct sock *except) ++{ ++ mptcp_sub_force_close_all(mpcb, except); ++ ++ if (mpcb->pm_ops->close_session) ++ mpcb->pm_ops->close_session(mptcp_meta_sk(except)); ++} ++ ++static inline bool mptcp_fallback_infinite(struct sock *sk, int flag) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_cb *mpcb = tp->mpcb; ++ ++ /* If data has been acknowleged on the meta-level, fully_established ++ * will have been set before and thus we will not fall back to infinite ++ * mapping. ++ */ ++ if (likely(tp->mptcp->fully_established)) ++ return false; ++ ++ if (!(flag & MPTCP_FLAG_DATA_ACKED)) ++ return false; ++ ++ /* Don't fallback twice ;) */ ++ if (mpcb->infinite_mapping_snd) ++ return false; ++ ++ pr_debug("%s %#x will fallback - pi %d, src %pI4:%u dst %pI4:%u rcv_nxt %u from %pS\n", ++ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, ++ &inet_sk(sk)->inet_saddr, ntohs(inet_sk(sk)->inet_sport), ++ &inet_sk(sk)->inet_daddr, ntohs(inet_sk(sk)->inet_dport), ++ tp->rcv_nxt, __builtin_return_address(0)); ++ if (!is_master_tp(tp)) { ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKSUB); ++ return true; ++ } ++ ++ mpcb->infinite_mapping_snd = 1; ++ mpcb->infinite_mapping_rcv = 1; ++ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); ++ tp->mptcp->fully_established = 1; ++ ++ mptcp_fallback_close(mpcb, sk); ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKINIT); ++ ++ return false; ++} ++ ++static inline bool mptcp_v6_is_v4_mapped(const struct sock *sk) ++{ ++ return sk->sk_family == AF_INET6 && ++ ipv6_addr_type(&inet6_sk(sk)->saddr) == IPV6_ADDR_MAPPED; ++} ++ ++/* We are in or are becoming to be in infinite mapping mode */ ++static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) ++{ ++ return mpcb->infinite_mapping_rcv || ++ mpcb->infinite_mapping_snd || ++ mpcb->send_infinite_mapping; ++} ++ ++static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) ++{ ++ /* Has been removed from the tk-table. Thus, no new subflows. ++ * ++ * Check for close-state is necessary, because we may have been closed ++ * without passing by mptcp_close(). ++ * ++ * When falling back, no new subflows are allowed either. ++ */ ++ return meta_sk->sk_state != TCP_CLOSE && ++ tcp_sk(meta_sk)->inside_tk_table && ++ !tcp_sk(meta_sk)->mpcb->infinite_mapping_rcv && ++ !tcp_sk(meta_sk)->mpcb->send_infinite_mapping; ++} ++ ++static inline int mptcp_subflow_count(const struct mptcp_cb *mpcb) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ int i = 0; ++ ++ mptcp_for_each_sub(mpcb, mptcp) ++ i++; ++ ++ return i; ++} ++ ++/* TCP and MPTCP mpc flag-depending functions */ ++u16 mptcp_select_window(struct sock *sk); ++void mptcp_tcp_set_rto(struct sock *sk); ++ ++/* TCP and MPTCP flag-depending functions */ ++bool mptcp_prune_ofo_queue(struct sock *sk); ++ ++#else /* CONFIG_MPTCP */ ++#define mptcp_debug(fmt, args...) \ ++ do { \ ++ } while (0) ++ ++static inline struct sock *mptcp_to_sock(const struct mptcp_tcp_sock *mptcp) ++{ ++ return NULL; ++} ++ ++#define mptcp_for_each_sub(__mpcb, __mptcp) \ ++ if (0) ++ ++#define MPTCP_INC_STATS(net, field) \ ++ do { \ ++ } while(0) ++ ++static inline bool mptcp_is_data_fin(const struct sk_buff *skb) ++{ ++ return false; ++} ++static inline bool mptcp_is_data_seq(const struct sk_buff *skb) ++{ ++ return false; ++} ++static inline struct sock *mptcp_meta_sk(const struct sock *sk) ++{ ++ return NULL; ++} ++static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) ++{ ++ return NULL; ++} ++static inline int is_meta_sk(const struct sock *sk) ++{ ++ return 0; ++} ++static inline int is_master_tp(const struct tcp_sock *tp) ++{ ++ return 0; ++} ++static inline void mptcp_del_sock(const struct sock *sk) {} ++static inline void mptcp_update_metasocket(const struct sock *meta_sk) {} ++static inline void mptcp_reinject_data(struct sock *orig_sk, int clone_it) {} ++static inline void mptcp_update_sndbuf(const struct tcp_sock *tp) {} ++static inline void mptcp_clean_rtx_infinite(const struct sk_buff *skb, ++ const struct sock *sk) {} ++static inline void mptcp_sub_close(struct sock *sk, unsigned long delay) {} ++static inline void mptcp_set_rto(const struct sock *sk) {} ++static inline void mptcp_send_fin(const struct sock *meta_sk) {} ++static inline void mptcp_parse_options(const uint8_t *ptr, const int opsize, ++ struct mptcp_options_received *mopt, ++ const struct sk_buff *skb, ++ const struct tcp_sock *tp) {} ++static inline void mptcp_syn_options(const struct sock *sk, ++ struct tcp_out_options *opts, ++ unsigned *remaining) {} ++static inline void mptcp_synack_options(struct request_sock *req, ++ struct tcp_out_options *opts, ++ unsigned *remaining) {} ++ ++static inline void mptcp_established_options(struct sock *sk, ++ struct sk_buff *skb, ++ struct tcp_out_options *opts, ++ unsigned *size) {} ++static inline void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, ++ const struct tcp_out_options *opts, ++ struct sk_buff *skb) {} ++static inline void mptcp_close(struct sock *meta_sk, long timeout) {} ++static inline bool mptcp_doit(struct sock *sk) ++{ ++ return false; ++} ++static inline int mptcp_check_req_fastopen(struct sock *child, ++ struct request_sock *req) ++{ ++ return 1; ++} ++static inline int mptcp_check_req_master(const struct sock *sk, ++ const struct sock *child, ++ const struct request_sock *req, ++ const struct sk_buff *skb, ++ int drop, ++ u32 tsoff) ++{ ++ return 1; ++} ++static inline struct sock *mptcp_check_req_child(const struct sock *meta_sk, ++ const struct sock *child, ++ const struct request_sock *req, ++ struct sk_buff *skb, ++ const struct mptcp_options_received *mopt) ++{ ++ return NULL; ++} ++static inline unsigned int mptcp_current_mss(struct sock *meta_sk) ++{ ++ return 0; ++} ++static inline void mptcp_sub_close_passive(struct sock *sk) {} ++static inline bool mptcp_fallback_infinite(const struct sock *sk, int flag) ++{ ++ return false; ++} ++static inline void mptcp_init_mp_opt(const struct mptcp_options_received *mopt) {} ++static inline void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) {} ++static inline bool mptcp_check_rtt(const struct tcp_sock *tp, int time) ++{ ++ return false; ++} ++static inline int mptcp_check_snd_buf(const struct tcp_sock *tp) ++{ ++ return 0; ++} ++static inline void mptcp_push_pending_frames(struct sock *meta_sk) {} ++static inline void mptcp_send_reset(const struct sock *sk) {} ++static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, ++ struct sock *except) {} ++static inline bool mptcp_handle_options(struct sock *sk, ++ const struct tcphdr *th, ++ struct sk_buff *skb) ++{ ++ return false; ++} ++static inline void mptcp_reset_mopt(struct tcp_sock *tp) {} ++static inline void __init mptcp_init(void) {} ++static inline bool mptcp_can_sg(const struct sock *meta_sk) ++{ ++ return false; ++} ++static inline unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, ++ u32 mss_now, int large_allowed) ++{ ++ return 0; ++} ++static inline void mptcp_destroy_sock(struct sock *sk) {} ++static inline int mptcp_rcv_synsent_state_process(struct sock *sk, ++ struct sock **skptr, ++ struct sk_buff *skb, ++ const struct mptcp_options_received *mopt) ++{ ++ return 0; ++} ++static inline bool mptcp_can_sendpage(struct sock *sk) ++{ ++ return false; ++} ++static inline int mptcp_init_tw_sock(struct sock *sk, ++ struct tcp_timewait_sock *tw) ++{ ++ return 0; ++} ++static inline void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) {} ++static inline void mptcp_disconnect(struct sock *meta_sk) {} ++static inline void mptcp_tsq_flags(struct sock *sk) {} ++static inline void mptcp_tsq_sub_deferred(struct sock *meta_sk) {} ++static inline void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) {} ++static inline void mptcp_remove_shortcuts(const struct mptcp_cb *mpcb, ++ const struct sk_buff *skb) {} ++static inline void mptcp_init_tcp_sock(struct sock *sk) {} ++static inline void mptcp_disable_static_key(void) {} ++static inline void mptcp_cookies_reqsk_init(struct request_sock *req, ++ struct mptcp_options_received *mopt, ++ struct sk_buff *skb) {} ++static inline void mptcp_mpcb_put(struct mptcp_cb *mpcb) {} ++static inline void mptcp_fin(struct sock *meta_sk) {} ++static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) ++{ ++ return false; ++} ++static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) ++{ ++ return false; ++} ++ ++#endif /* CONFIG_MPTCP */ ++ ++#endif /* _MPTCP_H */ +diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_v4.h +--- linux-5.4/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,76 @@ ++/* ++ * MPTCP implementation ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer & Author: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#ifndef MPTCP_V4_H_ ++#define MPTCP_V4_H_ ++ ++ ++#include ++#include ++#include ++#include ++#include ++ ++extern struct request_sock_ops mptcp_request_sock_ops; ++extern const struct inet_connection_sock_af_ops mptcp_v4_specific; ++extern struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; ++extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; ++ ++#ifdef CONFIG_MPTCP ++ ++int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb); ++struct sock *mptcp_v4_search_req(const __be16 rport, const __be32 raddr, ++ const __be32 laddr, const struct net *net); ++int __mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, ++ __be16 sport, struct mptcp_rem4 *rem, ++ struct sock **subsk); ++int mptcp_pm_v4_init(void); ++void mptcp_pm_v4_undo(void); ++u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport); ++u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, ++ u32 seed); ++ ++static inline int mptcp_init4_subsockets(struct sock *meta_sk, ++ const struct mptcp_loc4 *loc, ++ struct mptcp_rem4 *rem) ++{ ++ return __mptcp_init4_subsockets(meta_sk, loc, 0, rem, NULL); ++} ++ ++#else ++ ++static inline int mptcp_v4_do_rcv(const struct sock *meta_sk, ++ const struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++#endif /* CONFIG_MPTCP */ ++ ++#endif /* MPTCP_V4_H_ */ +diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_v6.h +--- linux-5.4/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,77 @@ ++/* ++ * MPTCP implementation ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer & Author: ++ * Jaakko Korkeaniemi ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#ifndef _MPTCP_V6_H ++#define _MPTCP_V6_H ++ ++#include ++#include ++ ++#include ++ ++ ++#ifdef CONFIG_MPTCP ++extern const struct inet_connection_sock_af_ops mptcp_v6_mapped; ++extern const struct inet_connection_sock_af_ops mptcp_v6_specific; ++extern struct request_sock_ops mptcp6_request_sock_ops; ++extern struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; ++extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; ++ ++int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb); ++struct sock *mptcp_v6_search_req(const __be16 rport, const struct in6_addr *raddr, ++ const struct in6_addr *laddr, const struct net *net); ++int __mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, ++ __be16 sport, struct mptcp_rem6 *rem, ++ struct sock **subsk); ++int mptcp_pm_v6_init(void); ++void mptcp_pm_v6_undo(void); ++__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, ++ __be16 sport, __be16 dport); ++u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, ++ __be16 sport, __be16 dport, u32 seed); ++ ++static inline int mptcp_init6_subsockets(struct sock *meta_sk, ++ const struct mptcp_loc6 *loc, ++ struct mptcp_rem6 *rem) ++{ ++ return __mptcp_init6_subsockets(meta_sk, loc, 0, rem, NULL); ++} ++ ++#else /* CONFIG_MPTCP */ ++ ++#define mptcp_v6_mapped ipv6_mapped ++ ++static inline int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++#endif /* CONFIG_MPTCP */ ++ ++#endif /* _MPTCP_V6_H */ +diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/net_namespace.h +--- linux-5.4/include/net/net_namespace.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-02-20 18:07:47.000000000 +0100 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -123,6 +124,9 @@ + #if IS_ENABLED(CONFIG_IPV6) + struct netns_ipv6 ipv6; + #endif ++#if IS_ENABLED(CONFIG_MPTCP) ++ struct netns_mptcp mptcp; ++#endif + #if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) + struct netns_ieee802154_lowpan ieee802154_lowpan; + #endif +diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/netns/mptcp.h +--- linux-5.4/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,52 @@ ++/* ++ * MPTCP implementation - MPTCP namespace ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#ifndef __NETNS_MPTCP_H__ ++#define __NETNS_MPTCP_H__ ++ ++#include ++ ++enum { ++ MPTCP_PM_FULLMESH = 0, ++ MPTCP_PM_MAX ++}; ++ ++struct mptcp_mib; ++ ++struct netns_mptcp { ++ DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics); ++ ++#ifdef CONFIG_PROC_FS ++ struct proc_dir_entry *proc_net_mptcp; ++#endif ++ ++ void *path_managers[MPTCP_PM_MAX]; ++}; ++ ++#endif /* __NETNS_MPTCP_H__ */ +diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h +--- linux-5.4/include/net/snmp.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/snmp.h 2020-02-20 18:07:47.000000000 +0100 +@@ -86,7 +86,6 @@ + atomic_long_t mibs[ICMP6MSG_MIB_MAX]; + }; + +- + /* TCP */ + #define TCP_MIB_MAX __TCP_MIB_MAX + struct tcp_mib { +diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h +--- linux-5.4/include/net/sock.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/sock.h 2020-02-20 18:07:47.000000000 +0100 +@@ -814,6 +814,7 @@ + SOCK_TXTIME, + SOCK_XDP, /* XDP is attached */ + SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */ ++ SOCK_MPTCP, /* MPTCP set on this socket */ + }; + + #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) +@@ -1122,6 +1123,7 @@ + void (*unhash)(struct sock *sk); + void (*rehash)(struct sock *sk); + int (*get_port)(struct sock *sk, unsigned short snum); ++ void (*clear_sk)(struct sock *sk, int size); + + /* Keeping track of sockets in use */ + #ifdef CONFIG_PROC_FS +diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h +--- linux-5.4/include/net/tcp.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/tcp.h 2020-02-20 18:07:47.000000000 +0100 +@@ -182,6 +182,7 @@ + #define TCPOPT_SACK 5 /* SACK Block */ + #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ + #define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ ++#define TCPOPT_MPTCP 30 + #define TCPOPT_FASTOPEN 34 /* Fast open (RFC7413) */ + #define TCPOPT_EXP 254 /* Experimental */ + /* Magic number to be after the option value for sharing TCP +@@ -238,6 +239,31 @@ + */ + #define TFO_SERVER_WO_SOCKOPT1 0x400 + ++/* Flags from tcp_input.c for tcp_ack */ ++#define FLAG_DATA 0x01 /* Incoming frame contained data. */ ++#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ ++#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ ++#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ ++#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ ++#define FLAG_DATA_SACKED 0x20 /* New SACK. */ ++#define FLAG_ECE 0x40 /* ECE in this ACK */ ++#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ ++#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ ++#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ ++#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ ++#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ ++#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ ++#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ ++#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ ++#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ ++#define FLAG_ACK_MAYBE_DELAYED 0x10000 /* Likely a delayed ACK */ ++ ++#define MPTCP_FLAG_DATA_ACKED 0x20000 ++ ++#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) ++#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) ++#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) ++#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) + + /* sysctl variables for tcp */ + extern int sysctl_tcp_max_orphans; +@@ -310,6 +336,97 @@ + #define TCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mib.tcp_statistics, field) + #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) + ++/**** START - Exports needed for MPTCP ****/ ++extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops; ++extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops; ++ ++struct mptcp_options_received; ++ ++void tcp_cleanup_rbuf(struct sock *sk, int copied); ++void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited); ++int tcp_close_state(struct sock *sk); ++void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, ++ const struct sk_buff *skb); ++int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib); ++void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb); ++int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, ++ gfp_t gfp_mask); ++unsigned int tcp_mss_split_point(const struct sock *sk, ++ const struct sk_buff *skb, ++ unsigned int mss_now, ++ unsigned int max_segs, ++ int nonagle); ++bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, ++ unsigned int cur_mss, int nonagle); ++bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, ++ unsigned int cur_mss); ++unsigned int tcp_cwnd_test(const struct tcp_sock *tp, const struct sk_buff *skb); ++int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now); ++int __pskb_trim_head(struct sk_buff *skb, int len); ++void tcp_queue_skb(struct sock *sk, struct sk_buff *skb); ++void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags); ++void tcp_reset(struct sock *sk); ++bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, ++ const u32 ack_seq, const u32 nwin); ++bool tcp_urg_mode(const struct tcp_sock *tp); ++void tcp_ack_probe(struct sock *sk); ++void tcp_rearm_rto(struct sock *sk); ++int tcp_write_timeout(struct sock *sk); ++bool retransmits_timed_out(struct sock *sk, ++ unsigned int boundary, ++ unsigned int timeout); ++void tcp_write_err(struct sock *sk); ++void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr); ++void tcp_update_skb_after_send(struct sock *sk, struct sk_buff *skb, ++ u64 prior_wstamp); ++void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now); ++ ++void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, ++ struct request_sock *req); ++void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb); ++struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb); ++void tcp_v4_reqsk_destructor(struct request_sock *req); ++ ++void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, ++ struct request_sock *req); ++void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); ++struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb); ++int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); ++int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); ++void tcp_v6_destroy_sock(struct sock *sk); ++void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb); ++void tcp_v6_hash(struct sock *sk); ++struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb); ++struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, ++ struct request_sock *req, ++ struct dst_entry *dst, ++ struct request_sock *req_unhash, ++ bool *own_req); ++void tcp_v6_reqsk_destructor(struct request_sock *req); ++ ++unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, ++ int large_allowed); ++u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb); ++ ++void skb_clone_fraglist(struct sk_buff *skb); ++ ++void inet_twsk_free(struct inet_timewait_sock *tw); ++int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb); ++/* These states need RST on ABORT according to RFC793 */ ++static inline bool tcp_need_reset(int state) ++{ ++ return (1 << state) & ++ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | ++ TCPF_FIN_WAIT2 | TCPF_SYN_RECV); ++} ++ ++int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, ++ bool *fragstolen); ++void tcp_ofo_queue(struct sock *sk); ++void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb); ++int linear_payload_sz(bool first_skb); ++/**** END - Exports needed for MPTCP ****/ ++ + void tcp_tasklet_init(void); + + int tcp_v4_err(struct sk_buff *skb, u32); +@@ -411,7 +528,9 @@ + #endif + void tcp_parse_options(const struct net *net, const struct sk_buff *skb, + struct tcp_options_received *opt_rx, +- int estab, struct tcp_fastopen_cookie *foc); ++ struct mptcp_options_received *mopt_rx, ++ int estab, struct tcp_fastopen_cookie *foc, ++ struct tcp_sock *tp); + const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); + + /* +@@ -430,6 +549,7 @@ + + void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); + void tcp_v4_mtu_reduced(struct sock *sk); ++void tcp_v6_mtu_reduced(struct sock *sk); + void tcp_req_err(struct sock *sk, u32 seq, bool abort); + int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); + struct sock *tcp_create_openreq_child(const struct sock *sk, +@@ -453,6 +573,7 @@ + struct request_sock *req, + struct tcp_fastopen_cookie *foc, + enum tcp_synack_type synack_type); ++void tcp_reset_vars(struct sock *sk); + int tcp_disconnect(struct sock *sk, int flags); + + void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); +@@ -536,7 +657,8 @@ + + u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, + u16 *mssp); +-__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mss); ++__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, __u16 *mss); + u64 cookie_init_timestamp(struct request_sock *req); + bool cookie_timestamp_decode(const struct net *net, + struct tcp_options_received *opt); +@@ -550,7 +672,8 @@ + + u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, + const struct tcphdr *th, u16 *mssp); +-__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss); ++__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, __u16 *mss); + #endif + /* tcp_output.c */ + +@@ -586,10 +709,16 @@ + void tcp_skb_collapse_tstamp(struct sk_buff *skb, + const struct sk_buff *next_skb); + ++u16 tcp_select_window(struct sock *sk); ++bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, ++ int push_one, gfp_t gfp); ++ + /* tcp_input.c */ + void tcp_rearm_rto(struct sock *sk); + void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req); + void tcp_reset(struct sock *sk); ++void tcp_set_rto(struct sock *sk); ++bool tcp_should_expand_sndbuf(const struct sock *sk); + void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); + void tcp_fin(struct sock *sk); + +@@ -633,7 +762,7 @@ + } + + /* tcp.c */ +-void tcp_get_info(struct sock *, struct tcp_info *); ++void tcp_get_info(struct sock *, struct tcp_info *, bool no_lock); + + /* Read 'sendfile()'-style from a TCP socket */ + int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, +@@ -817,6 +946,12 @@ + u16 tcp_gso_size; + }; + }; ++ ++#ifdef CONFIG_MPTCP ++ __u8 mptcp_flags; /* flags for the MPTCP layer */ ++ __u8 dss_off; /* Number of 4-byte words until ++ * seq-number */ ++#endif + __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ + + __u8 sacked; /* State flags for SACK. */ +@@ -835,6 +970,14 @@ + has_rxtstamp:1, /* SKB has a RX timestamp */ + unused:5; + __u32 ack_seq; /* Sequence number ACK'd */ ++ ++#ifdef CONFIG_MPTCP ++ union { /* For MPTCP outgoing frames */ ++ __u32 path_mask; /* paths that tried to send this skb */ ++ __u32 dss[6]; /* DSS options */ ++ }; ++#endif ++ + union { + struct { + /* There is space for up to 24 bytes */ +@@ -1076,6 +1219,8 @@ + int tcp_set_allowed_congestion_control(char *allowed); + int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, + bool reinit, bool cap_net_admin); ++int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, ++ bool reinit, bool cap_net_admin); + u32 tcp_slow_start(struct tcp_sock *tp, u32 acked); + void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked); + +@@ -1377,6 +1522,19 @@ + space - (space>>tcp_adv_win_scale); + } + ++#ifdef CONFIG_MPTCP ++extern struct static_key mptcp_static_key; ++static inline bool mptcp(const struct tcp_sock *tp) ++{ ++ return static_key_false(&mptcp_static_key) && tp->mpc; ++} ++#else ++static inline bool mptcp(const struct tcp_sock *tp) ++{ ++ return 0; ++} ++#endif ++ + /* Note: caller must be prepared to deal with negative returns */ + static inline int tcp_space(const struct sock *sk) + { +@@ -1949,6 +2107,31 @@ + #endif + }; + ++/* TCP/MPTCP-specific functions */ ++struct tcp_sock_ops { ++ u32 (*__select_window)(struct sock *sk); ++ u16 (*select_window)(struct sock *sk); ++ void (*select_initial_window)(const struct sock *sk, int __space, ++ __u32 mss, __u32 *rcv_wnd, ++ __u32 *window_clamp, int wscale_ok, ++ __u8 *rcv_wscale, __u32 init_rcv_wnd); ++ void (*init_buffer_space)(struct sock *sk); ++ void (*set_rto)(struct sock *sk); ++ bool (*should_expand_sndbuf)(const struct sock *sk); ++ void (*send_fin)(struct sock *sk); ++ bool (*write_xmit)(struct sock *sk, unsigned int mss_now, int nonagle, ++ int push_one, gfp_t gfp); ++ void (*send_active_reset)(struct sock *sk, gfp_t priority); ++ int (*write_wakeup)(struct sock *sk, int mib); ++ void (*retransmit_timer)(struct sock *sk); ++ void (*time_wait)(struct sock *sk, int state, int timeo); ++ void (*cleanup_rbuf)(struct sock *sk, int copied); ++ void (*cwnd_validate)(struct sock *sk, bool is_cwnd_limited); ++ int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, ++ bool reinit, bool cap_net_admin); ++}; ++extern const struct tcp_sock_ops tcp_specific; ++ + struct tcp_request_sock_ops { + u16 mss_clamp; + #ifdef CONFIG_TCP_MD5SIG +@@ -1959,12 +2142,13 @@ + const struct sock *sk, + const struct sk_buff *skb); + #endif +- void (*init_req)(struct request_sock *req, +- const struct sock *sk_listener, +- struct sk_buff *skb); ++ int (*init_req)(struct request_sock *req, ++ const struct sock *sk_listener, ++ struct sk_buff *skb, ++ bool want_cookie); + #ifdef CONFIG_SYN_COOKIES +- __u32 (*cookie_init_seq)(const struct sk_buff *skb, +- __u16 *mss); ++ __u32 (*cookie_init_seq)(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, __u16 *mss); + #endif + struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, + const struct request_sock *req); +@@ -1978,15 +2162,17 @@ + + #ifdef CONFIG_SYN_COOKIES + static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, ++ struct request_sock *req, + const struct sock *sk, struct sk_buff *skb, + __u16 *mss) + { + tcp_synq_overflow(sk); + __NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT); +- return ops->cookie_init_seq(skb, mss); ++ return ops->cookie_init_seq(req, sk, skb, mss); + } + #else + static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, ++ struct request_sock *req, + const struct sock *sk, struct sk_buff *skb, + __u16 *mss) + { +diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_states.h +--- linux-5.4/include/net/tcp_states.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-02-20 18:07:47.000000000 +0100 +@@ -22,6 +22,7 @@ + TCP_LISTEN, + TCP_CLOSING, /* Now a valid state */ + TCP_NEW_SYN_RECV, ++ TCP_RST_WAIT, + + TCP_MAX_STATES /* Leave at the end! */ + }; +@@ -43,6 +44,7 @@ + TCPF_LISTEN = (1 << TCP_LISTEN), + TCPF_CLOSING = (1 << TCP_CLOSING), + TCPF_NEW_SYN_RECV = (1 << TCP_NEW_SYN_RECV), ++ TCPF_RST_WAIT = (1 << TCP_RST_WAIT), + }; + + #endif /* _LINUX_TCP_STATES_H */ +diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/transp_v6.h +--- linux-5.4/include/net/transp_v6.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-02-20 18:07:47.000000000 +0100 +@@ -58,6 +58,8 @@ + + /* address family specific functions */ + extern const struct inet_connection_sock_af_ops ipv4_specific; ++extern const struct inet_connection_sock_af_ops ipv6_mapped; ++extern const struct inet_connection_sock_af_ops ipv6_specific; + + void inet6_destroy_sock(struct sock *sk); + +diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/events/tcp.h +--- linux-5.4/include/trace/events/tcp.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-02-20 18:07:47.000000000 +0100 +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + + #define TP_STORE_V4MAPPED(__entry, saddr, daddr) \ +@@ -181,6 +182,13 @@ + TP_ARGS(sk) + ); + ++DEFINE_EVENT(tcp_event_sk_skb, mptcp_retransmit, ++ ++ TP_PROTO(const struct sock *sk, const struct sk_buff *skb), ++ ++ TP_ARGS(sk, skb) ++); ++ + TRACE_EVENT(tcp_retransmit_synack, + + TP_PROTO(const struct sock *sk, const struct request_sock *req), +@@ -248,6 +256,7 @@ + __field(__u32, srtt) + __field(__u32, rcv_wnd) + __field(__u64, sock_cookie) ++ __field(__u8, mptcp) + ), + + TP_fast_assign( +@@ -274,13 +283,15 @@ + __entry->ssthresh = tcp_current_ssthresh(sk); + __entry->srtt = tp->srtt_us >> 3; + __entry->sock_cookie = sock_gen_cookie(sk); ++ __entry->mptcp = mptcp(tp) ? tp->mptcp->path_index : 0; + ), + +- TP_printk("src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx", ++ TP_printk("src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx mptcp=%d", + __entry->saddr, __entry->daddr, __entry->mark, + __entry->data_len, __entry->snd_nxt, __entry->snd_una, + __entry->snd_cwnd, __entry->ssthresh, __entry->snd_wnd, +- __entry->srtt, __entry->rcv_wnd, __entry->sock_cookie) ++ __entry->srtt, __entry->rcv_wnd, __entry->sock_cookie, ++ __entry->mptcp) + ); + + #endif /* _TRACE_TCP_H */ +diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/linux/bpf.h +--- linux-5.4/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-02-20 18:07:47.000000000 +0100 +@@ -3438,6 +3438,7 @@ + BPF_TCP_LISTEN, + BPF_TCP_CLOSING, /* Now a valid state */ + BPF_TCP_NEW_SYN_RECV, ++ BPF_TCP_RST_WAIT, + + BPF_TCP_MAX_STATES /* Leave at the end! */ + }; +diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linux/if.h +--- linux-5.4/include/uapi/linux/if.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-02-20 18:07:47.000000000 +0100 +@@ -132,6 +132,9 @@ + #define IFF_ECHO IFF_ECHO + #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ + ++#define IFF_NOMULTIPATH 0x80000 /* Disable for MPTCP */ ++#define IFF_MPBACKUP 0x100000 /* Use as backup path for MPTCP */ ++ + #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ + IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) + +diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/linux/mptcp.h +--- linux-5.4/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,149 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++/* ++ * Netlink API for Multipath TCP ++ * ++ * Author: Gregory Detal ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#ifndef _LINUX_MPTCP_H ++#define _LINUX_MPTCP_H ++ ++#define MPTCP_GENL_NAME "mptcp" ++#define MPTCP_GENL_EV_GRP_NAME "mptcp_events" ++#define MPTCP_GENL_CMD_GRP_NAME "mptcp_commands" ++#define MPTCP_GENL_VER 0x1 ++ ++/* ++ * ATTR types defined for MPTCP ++ */ ++enum { ++ MPTCP_ATTR_UNSPEC = 0, ++ ++ MPTCP_ATTR_TOKEN, /* u32 */ ++ MPTCP_ATTR_FAMILY, /* u16 */ ++ MPTCP_ATTR_LOC_ID, /* u8 */ ++ MPTCP_ATTR_REM_ID, /* u8 */ ++ MPTCP_ATTR_SADDR4, /* u32 */ ++ MPTCP_ATTR_SADDR6, /* struct in6_addr */ ++ MPTCP_ATTR_DADDR4, /* u32 */ ++ MPTCP_ATTR_DADDR6, /* struct in6_addr */ ++ MPTCP_ATTR_SPORT, /* u16 */ ++ MPTCP_ATTR_DPORT, /* u16 */ ++ MPTCP_ATTR_BACKUP, /* u8 */ ++ MPTCP_ATTR_ERROR, /* u8 */ ++ MPTCP_ATTR_FLAGS, /* u16 */ ++ MPTCP_ATTR_TIMEOUT, /* u32 */ ++ MPTCP_ATTR_IF_IDX, /* s32 */ ++ ++ __MPTCP_ATTR_AFTER_LAST ++}; ++ ++#define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1) ++ ++/* ++ * Events generated by MPTCP: ++ * - MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6, ++ * sport, dport ++ * A new connection has been created. It is the good time to allocate ++ * memory and send ADD_ADDR if needed. Depending on the traffic-patterns ++ * it can take a long time until the MPTCP_EVENT_ESTABLISHED is sent. ++ * ++ * - MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6, ++ * sport, dport ++ * A connection is established (can start new subflows). ++ * ++ * - MPTCP_EVENT_CLOSED: token ++ * A connection has stopped. ++ * ++ * - MPTCP_EVENT_ANNOUNCED: token, rem_id, family, daddr4 | daddr6 [, dport] ++ * A new address has been announced by the peer. ++ * ++ * - MPTCP_EVENT_REMOVED: token, rem_id ++ * An address has been lost by the peer. ++ * ++ * - MPTCP_EVENT_SUB_ESTABLISHED: token, family, saddr4 | saddr6, ++ * daddr4 | daddr6, sport, dport, backup, ++ * if_idx [, error] ++ * A new subflow has been established. 'error' should not be set. ++ * ++ * - MPTCP_EVENT_SUB_CLOSED: token, family, saddr4 | saddr6, daddr4 | daddr6, ++ * sport, dport, backup, if_idx [, error] ++ * A subflow has been closed. An error (copy of sk_err) could be set if an ++ * error has been detected for this subflow. ++ * ++ * - MPTCP_EVENT_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6, ++ * sport, dport, backup, if_idx [, error] ++ * The priority of a subflow has changed. 'error' should not be set. ++ * ++ * Commands for MPTCP: ++ * - MPTCP_CMD_ANNOUNCE: token, loc_id, family, saddr4 | saddr6 [, sport] ++ * Announce a new address to the peer. ++ * ++ * - MPTCP_CMD_REMOVE: token, loc_id ++ * Announce that an address has been lost to the peer. ++ * ++ * - MPTCP_CMD_SUB_CREATE: token, family, loc_id, rem_id, [saddr4 | saddr6, ++ * daddr4 | daddr6, dport [, sport, backup, if_idx]] ++ * Create a new subflow. ++ * ++ * - MPTCP_CMD_SUB_DESTROY: token, family, saddr4 | saddr6, daddr4 | daddr6, ++ * sport, dport ++ * Close a subflow. ++ * ++ * - MPTCP_CMD_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6, ++ * sport, dport, backup ++ * Change the priority of a subflow. ++ * ++ * - MPTCP_CMD_SET_FILTER: flags ++ * Set the filter on events. Set MPTCPF_* flags to only receive specific ++ * events. Default is to receive all events. ++ * ++ * - MPTCP_CMD_EXIST: token ++ * Check if this token is linked to an existing socket. ++ */ ++enum { ++ MPTCP_CMD_UNSPEC = 0, ++ ++ MPTCP_EVENT_CREATED, ++ MPTCP_EVENT_ESTABLISHED, ++ MPTCP_EVENT_CLOSED, ++ ++ MPTCP_CMD_ANNOUNCE, ++ MPTCP_CMD_REMOVE, ++ MPTCP_EVENT_ANNOUNCED, ++ MPTCP_EVENT_REMOVED, ++ ++ MPTCP_CMD_SUB_CREATE, ++ MPTCP_CMD_SUB_DESTROY, ++ MPTCP_EVENT_SUB_ESTABLISHED, ++ MPTCP_EVENT_SUB_CLOSED, ++ ++ MPTCP_CMD_SUB_PRIORITY, ++ MPTCP_EVENT_SUB_PRIORITY, ++ ++ MPTCP_CMD_SET_FILTER, ++ ++ MPTCP_CMD_EXIST, ++ ++ __MPTCP_CMD_AFTER_LAST ++}; ++ ++#define MPTCP_CMD_MAX (__MPTCP_CMD_AFTER_LAST - 1) ++ ++enum { ++ MPTCPF_EVENT_CREATED = (1 << 1), ++ MPTCPF_EVENT_ESTABLISHED = (1 << 2), ++ MPTCPF_EVENT_CLOSED = (1 << 3), ++ MPTCPF_EVENT_ANNOUNCED = (1 << 4), ++ MPTCPF_EVENT_REMOVED = (1 << 5), ++ MPTCPF_EVENT_SUB_ESTABLISHED = (1 << 6), ++ MPTCPF_EVENT_SUB_CLOSED = (1 << 7), ++ MPTCPF_EVENT_SUB_PRIORITY = (1 << 8), ++}; ++ ++#endif /* _LINUX_MPTCP_H */ +diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/linux/tcp.h +--- linux-5.4/include/uapi/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-02-20 18:07:47.000000000 +0100 +@@ -18,9 +18,15 @@ + #ifndef _UAPI_LINUX_TCP_H + #define _UAPI_LINUX_TCP_H + +-#include ++#ifndef __KERNEL__ ++#include ++#endif ++ + #include ++#include ++#include + #include ++#include + + struct tcphdr { + __be16 source; +@@ -134,6 +140,13 @@ + #define TCP_REPAIR_OFF 0 + #define TCP_REPAIR_OFF_NO_WP -1 /* Turn off without window probes */ + ++#define MPTCP_ENABLED 42 ++#define MPTCP_SCHEDULER 43 ++#define MPTCP_PATH_MANAGER 44 ++#define MPTCP_INFO 45 ++ ++#define MPTCP_INFO_FLAG_SAVE_MASTER 0x01 ++ + struct tcp_repair_opt { + __u32 opt_code; + __u32 opt_val; +@@ -305,6 +318,53 @@ + TCP_NLA_SRTT, /* smoothed RTT in usecs */ + }; + ++struct mptcp_meta_info { ++ __u8 mptcpi_state; ++ __u8 mptcpi_retransmits; ++ __u8 mptcpi_probes; ++ __u8 mptcpi_backoff; ++ ++ __u32 mptcpi_rto; ++ __u32 mptcpi_unacked; ++ ++ /* Times. */ ++ __u32 mptcpi_last_data_sent; ++ __u32 mptcpi_last_data_recv; ++ __u32 mptcpi_last_ack_recv; ++ ++ __u32 mptcpi_total_retrans; ++ ++ __u64 mptcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ ++ __u64 mptcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ ++}; ++ ++struct mptcp_sub_info { ++ union { ++ struct sockaddr src; ++ struct sockaddr_in src_v4; ++ struct sockaddr_in6 src_v6; ++ }; ++ ++ union { ++ struct sockaddr dst; ++ struct sockaddr_in dst_v4; ++ struct sockaddr_in6 dst_v6; ++ }; ++}; ++ ++struct mptcp_info { ++ __u32 tcp_info_len; /* Length of each struct tcp_info in subflows pointer */ ++ __u32 sub_len; /* Total length of memory pointed to by subflows pointer */ ++ __u32 meta_len; /* Length of memory pointed to by meta_info */ ++ __u32 sub_info_len; /* Length of each struct mptcp_sub_info in subflow_info pointer */ ++ __u32 total_sub_info_len; /* Total length of memory pointed to by subflow_info */ ++ ++ struct mptcp_meta_info *meta_info; ++ struct tcp_info *initial; ++ struct tcp_info *subflows; /* Pointer to array of tcp_info structs */ ++ struct mptcp_sub_info *subflow_info; ++}; ++ + /* for TCP_MD5SIG socket option */ + #define TCP_MD5SIG_MAXKEYLEN 80 + +diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c +--- linux-5.4/net/core/dev.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/core/dev.c 2020-02-20 18:07:47.000000000 +0100 +@@ -7855,7 +7855,7 @@ + + dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | + IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL | +- IFF_AUTOMEDIA)) | ++ IFF_AUTOMEDIA | IFF_NOMULTIPATH | IFF_MPBACKUP)) | + (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC | + IFF_ALLMULTI)); + +diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces.c +--- linux-5.4/net/core/net-traces.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-02-20 18:07:47.000000000 +0100 +@@ -60,3 +60,5 @@ + EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); + + EXPORT_TRACEPOINT_SYMBOL_GPL(tcp_send_reset); ++ ++EXPORT_TRACEPOINT_SYMBOL_GPL(mptcp_retransmit); +diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c +--- linux-5.4/net/core/skbuff.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-02-20 18:07:47.000000000 +0100 +@@ -573,7 +573,7 @@ + skb_drop_list(&skb_shinfo(skb)->frag_list); + } + +-static void skb_clone_fraglist(struct sk_buff *skb) ++void skb_clone_fraglist(struct sk_buff *skb) + { + struct sk_buff *list; + +diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c +--- linux-5.4/net/core/sock.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/core/sock.c 2020-02-20 18:07:47.000000000 +0100 +@@ -135,6 +135,11 @@ + + #include + ++#ifdef CONFIG_MPTCP ++#include ++#include ++#endif ++ + #include + #include + +@@ -1551,6 +1556,23 @@ + */ + static inline void sock_lock_init(struct sock *sk) + { ++#ifdef CONFIG_MPTCP ++ /* Reclassify the lock-class for subflows */ ++ if (sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP) ++ if (mptcp(tcp_sk(sk)) || tcp_sk(sk)->is_master_sk) { ++ sock_lock_init_class_and_name(sk, meta_slock_key_name, ++ &meta_slock_key, ++ meta_key_name, ++ &meta_key); ++ ++ /* We don't yet have the mptcp-point. ++ * Thus we still need inet_sock_destruct ++ */ ++ sk->sk_destruct = inet_sock_destruct; ++ return; ++ } ++#endif ++ + if (sk->sk_kern_sock) + sock_lock_init_class_and_name( + sk, +@@ -1599,8 +1621,12 @@ + sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); + if (!sk) + return sk; +- if (want_init_on_alloc(priority)) +- sk_prot_clear_nulls(sk, prot->obj_size); ++ if (want_init_on_alloc(priority)) { ++ if (prot->clear_sk) ++ prot->clear_sk(sk, prot->obj_size); ++ else ++ sk_prot_clear_nulls(sk, prot->obj_size); ++ } + } else + sk = kmalloc(prot->obj_size, priority); + +@@ -1832,6 +1858,7 @@ + atomic_set(&newsk->sk_zckey, 0); + + sock_reset_flag(newsk, SOCK_DONE); ++ sock_reset_flag(newsk, SOCK_MPTCP); + mem_cgroup_sk_alloc(newsk); + cgroup_sk_alloc(&newsk->sk_cgrp_data); + +diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c +--- linux-5.4/net/ipv4/af_inet.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-02-20 18:07:47.000000000 +0100 +@@ -100,6 +100,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -150,6 +151,9 @@ + return; + } + ++ if (sock_flag(sk, SOCK_MPTCP)) ++ mptcp_disable_static_key(); ++ + WARN_ON(atomic_read(&sk->sk_rmem_alloc)); + WARN_ON(refcount_read(&sk->sk_wmem_alloc)); + WARN_ON(sk->sk_wmem_queued); +@@ -244,8 +248,7 @@ + * Create an inet socket. + */ + +-static int inet_create(struct net *net, struct socket *sock, int protocol, +- int kern) ++int inet_create(struct net *net, struct socket *sock, int protocol, int kern) + { + struct sock *sk; + struct inet_protosw *answer; +@@ -739,6 +742,24 @@ + lock_sock(sk2); + + sock_rps_record_flow(sk2); ++ ++ if (sk2->sk_protocol == IPPROTO_TCP && mptcp(tcp_sk(sk2))) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(tcp_sk(sk2)->mpcb, mptcp) { ++ sock_rps_record_flow(mptcp_to_sock(mptcp)); ++ } ++ ++ if (tcp_sk(sk2)->mpcb->master_sk) { ++ struct sock *sk_it = tcp_sk(sk2)->mpcb->master_sk; ++ ++ write_lock_bh(&sk_it->sk_callback_lock); ++ rcu_assign_pointer(sk_it->sk_wq, &newsock->wq); ++ sk_it->sk_socket = newsock; ++ write_unlock_bh(&sk_it->sk_callback_lock); ++ } ++ } ++ + WARN_ON(!((1 << sk2->sk_state) & + (TCPF_ESTABLISHED | TCPF_SYN_RECV | + TCPF_CLOSE_WAIT | TCPF_CLOSE))); +@@ -1974,6 +1995,9 @@ + + ip_init(); + ++ /* We must initialize MPTCP before TCP. */ ++ mptcp_init(); ++ + /* Setup TCP slab cache for open requests. */ + tcp_init(); + +diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c +--- linux-5.4/net/ipv4/inet_connection_sock.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-02-20 18:07:47.000000000 +0100 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -693,7 +694,10 @@ + int max_retries, thresh; + u8 defer_accept; + +- if (inet_sk_state_load(sk_listener) != TCP_LISTEN) ++ if (!is_meta_sk(sk_listener) && inet_sk_state_load(sk_listener) != TCP_LISTEN) ++ goto drop; ++ ++ if (is_meta_sk(sk_listener) && !mptcp_can_new_subflow(sk_listener)) + goto drop; + + max_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries; +@@ -782,7 +786,9 @@ + const struct request_sock *req, + const gfp_t priority) + { +- struct sock *newsk = sk_clone_lock(sk, priority); ++ struct sock *newsk; ++ ++ newsk = sk_clone_lock(sk, priority); + + if (newsk) { + struct inet_connection_sock *newicsk = inet_csk(newsk); +@@ -981,7 +987,14 @@ + */ + while ((req = reqsk_queue_remove(queue, sk)) != NULL) { + struct sock *child = req->sk; ++ bool mutex_taken = false; ++ struct mptcp_cb *mpcb = tcp_sk(child)->mpcb; + ++ if (is_meta_sk(child)) { ++ WARN_ON(refcount_inc_not_zero(&mpcb->mpcb_refcnt) == 0); ++ mutex_lock(&mpcb->mpcb_mutex); ++ mutex_taken = true; ++ } + local_bh_disable(); + bh_lock_sock(child); + WARN_ON(sock_owned_by_user(child)); +@@ -991,6 +1004,10 @@ + reqsk_put(req); + bh_unlock_sock(child); + local_bh_enable(); ++ if (mutex_taken) { ++ mutex_unlock(&mpcb->mpcb_mutex); ++ mptcp_mpcb_put(mpcb); ++ } + sock_put(child); + + cond_resched(); +diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c +--- linux-5.4/net/ipv4/ip_sockglue.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-02-20 18:07:47.000000000 +0100 +@@ -44,6 +44,8 @@ + #endif + #include + ++#include ++ + #include + #include + +@@ -657,7 +659,7 @@ + break; + old = rcu_dereference_protected(inet->inet_opt, + lockdep_sock_is_held(sk)); +- if (inet->is_icsk) { ++ if (inet->is_icsk && !is_meta_sk(sk)) { + struct inet_connection_sock *icsk = inet_csk(sk); + #if IS_ENABLED(CONFIG_IPV6) + if (sk->sk_family == PF_INET || +@@ -751,6 +753,20 @@ + inet->tos = val; + sk->sk_priority = rt_tos2priority(val); + sk_dst_reset(sk); ++ /* Update TOS on mptcp subflow */ ++ if (is_meta_sk(sk)) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if (inet_sk(sk_it)->tos != inet_sk(sk)->tos) { ++ inet_sk(sk_it)->tos = inet_sk(sk)->tos; ++ sk_it->sk_priority = sk->sk_priority; ++ sk_dst_reset(sk_it); ++ } ++ } ++ } + } + break; + case IP_TTL: +diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig +--- linux-5.4/net/ipv4/Kconfig 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-02-20 18:07:47.000000000 +0100 +@@ -654,6 +654,51 @@ + bufferbloat, policers, or AQM schemes that do not provide a delay + signal. It requires the fq ("Fair Queue") pacing packet scheduler. + ++config TCP_CONG_LIA ++ tristate "MPTCP Linked Increase" ++ depends on MPTCP ++ default n ++ ---help--- ++ MultiPath TCP Linked Increase Congestion Control ++ To enable it, just put 'lia' in tcp_congestion_control ++ ++config TCP_CONG_OLIA ++ tristate "MPTCP Opportunistic Linked Increase" ++ depends on MPTCP ++ default n ++ ---help--- ++ MultiPath TCP Opportunistic Linked Increase Congestion Control ++ To enable it, just put 'olia' in tcp_congestion_control ++ ++config TCP_CONG_WVEGAS ++ tristate "MPTCP WVEGAS CONGESTION CONTROL" ++ depends on MPTCP ++ default n ++ ---help--- ++ wVegas congestion control for MPTCP ++ To enable it, just put 'wvegas' in tcp_congestion_control ++ ++config TCP_CONG_BALIA ++ tristate "MPTCP BALIA CONGESTION CONTROL" ++ depends on MPTCP ++ default n ++ ---help--- ++ Multipath TCP Balanced Linked Adaptation Congestion Control ++ To enable it, just put 'balia' in tcp_congestion_control ++ ++config TCP_CONG_MCTCPDESYNC ++ tristate "DESYNCHRONIZED MCTCP CONGESTION CONTROL (EXPERIMENTAL)" ++ depends on MPTCP ++ default n ++ ---help--- ++ Desynchronized MultiChannel TCP Congestion Control. This is experimental ++ code that only supports single path and must have set mptcp_ndiffports ++ larger than one. ++ To enable it, just put 'mctcpdesync' in tcp_congestion_control ++ For further details see: ++ http://ieeexplore.ieee.org/abstract/document/6911722/ ++ https://doi.org/10.1016/j.comcom.2015.07.010 ++ + choice + prompt "Default TCP congestion control" + default DEFAULT_CUBIC +@@ -691,6 +736,21 @@ + config DEFAULT_BBR + bool "BBR" if TCP_CONG_BBR=y + ++ config DEFAULT_LIA ++ bool "Lia" if TCP_CONG_LIA=y ++ ++ config DEFAULT_OLIA ++ bool "Olia" if TCP_CONG_OLIA=y ++ ++ config DEFAULT_WVEGAS ++ bool "Wvegas" if TCP_CONG_WVEGAS=y ++ ++ config DEFAULT_BALIA ++ bool "Balia" if TCP_CONG_BALIA=y ++ ++ config DEFAULT_MCTCPDESYNC ++ bool "Mctcpdesync (EXPERIMENTAL)" if TCP_CONG_MCTCPDESYNC=y ++ + config DEFAULT_RENO + bool "Reno" + endchoice +@@ -711,6 +771,10 @@ + default "vegas" if DEFAULT_VEGAS + default "westwood" if DEFAULT_WESTWOOD + default "veno" if DEFAULT_VENO ++ default "lia" if DEFAULT_LIA ++ default "olia" if DEFAULT_OLIA ++ default "wvegas" if DEFAULT_WVEGAS ++ default "balia" if DEFAULT_BALIA + default "reno" if DEFAULT_RENO + default "dctcp" if DEFAULT_DCTCP + default "cdg" if DEFAULT_CDG +diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies.c +--- linux-5.4/net/ipv4/syncookies.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-02-20 18:07:47.000000000 +0100 +@@ -12,6 +12,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -175,7 +177,8 @@ + } + EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence); + +-__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mssp) ++__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, __u16 *mssp) + { + const struct iphdr *iph = ip_hdr(skb); + const struct tcphdr *th = tcp_hdr(skb); +@@ -205,9 +208,27 @@ + struct inet_connection_sock *icsk = inet_csk(sk); + struct sock *child; + bool own_req; ++#ifdef CONFIG_MPTCP ++ int ret; ++#endif + + child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst, + NULL, &own_req); ++ ++#ifdef CONFIG_MPTCP ++ if (!child) ++ goto listen_overflow; ++ ++ ret = mptcp_check_req_master(sk, child, req, skb, 0, tsoff); ++ if (ret < 0) ++ return NULL; ++ ++ if (!ret) ++ return tcp_sk(child)->mpcb->master_sk; ++ ++listen_overflow: ++#endif ++ + if (child) { + refcount_set(&req->rsk_refcnt, 1); + tcp_sk(child)->tsoffset = tsoff; +@@ -284,6 +305,7 @@ + { + struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; + struct tcp_options_received tcp_opt; ++ struct mptcp_options_received mopt; + struct inet_request_sock *ireq; + struct tcp_request_sock *treq; + struct tcp_sock *tp = tcp_sk(sk); +@@ -313,7 +335,8 @@ + + /* check for timestamp cookie support */ + memset(&tcp_opt, 0, sizeof(tcp_opt)); +- tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL); ++ mptcp_init_mp_opt(&mopt); ++ tcp_parse_options(sock_net(sk), skb, &tcp_opt, &mopt, 0, NULL, NULL); + + if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { + tsoff = secure_tcp_ts_off(sock_net(sk), +@@ -326,7 +349,12 @@ + goto out; + + ret = NULL; +- req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ ++#ifdef CONFIG_MPTCP ++ if (mopt.saw_mpc) ++ req = inet_reqsk_alloc(&mptcp_request_sock_ops, sk, false); /* for safety */ ++ else ++#endif ++ req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ + if (!req) + goto out; + +@@ -346,6 +374,8 @@ + ireq->sack_ok = tcp_opt.sack_ok; + ireq->wscale_ok = tcp_opt.wscale_ok; + ireq->tstamp_ok = tcp_opt.saw_tstamp; ++ ireq->mptcp_rqsk = 0; ++ ireq->saw_mpc = 0; + req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; + treq->snt_synack = 0; + treq->tfo_listener = false; +@@ -354,6 +384,9 @@ + + ireq->ir_iif = inet_request_bound_dev_if(sk, skb); + ++ if (mopt.saw_mpc) ++ mptcp_cookies_reqsk_init(req, &mopt, skb); ++ + /* We throwed the options of the initial SYN away, so we hope + * the ACK carries the same options again (see RFC1122 4.2.3.8) + */ +@@ -387,10 +420,10 @@ + /* Try to redo what tcp_v4_send_synack did. */ + req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW); + +- tcp_select_initial_window(sk, tcp_full_space(sk), req->mss, +- &req->rsk_rcv_wnd, &req->rsk_window_clamp, +- ireq->wscale_ok, &rcv_wscale, +- dst_metric(&rt->dst, RTAX_INITRWND)); ++ tp->ops->select_initial_window(sk, tcp_full_space(sk), req->mss, ++ &req->rsk_rcv_wnd, &req->rsk_window_clamp, ++ ireq->wscale_ok, &rcv_wscale, ++ dst_metric(&rt->dst, RTAX_INITRWND)); + + ireq->rcv_wscale = rcv_wscale; + ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); +diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c +--- linux-5.4/net/ipv4/tcp.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-02-20 18:07:47.000000000 +0100 +@@ -270,6 +270,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -400,6 +401,24 @@ + return rate64; + } + ++const struct tcp_sock_ops tcp_specific = { ++ .__select_window = __tcp_select_window, ++ .select_window = tcp_select_window, ++ .select_initial_window = tcp_select_initial_window, ++ .init_buffer_space = tcp_init_buffer_space, ++ .set_rto = tcp_set_rto, ++ .should_expand_sndbuf = tcp_should_expand_sndbuf, ++ .send_fin = tcp_send_fin, ++ .write_xmit = tcp_write_xmit, ++ .send_active_reset = tcp_send_active_reset, ++ .write_wakeup = tcp_write_wakeup, ++ .retransmit_timer = tcp_retransmit_timer, ++ .time_wait = tcp_time_wait, ++ .cleanup_rbuf = tcp_cleanup_rbuf, ++ .cwnd_validate = tcp_cwnd_validate, ++ .set_cong_ctrl = __tcp_set_congestion_control, ++}; ++ + /* Address-family independent initialization for a tcp_sock. + * + * NOTE: A lot of things set to zero explicitly by call to +@@ -453,6 +472,11 @@ + WRITE_ONCE(sk->sk_sndbuf, sock_net(sk)->ipv4.sysctl_tcp_wmem[1]); + WRITE_ONCE(sk->sk_rcvbuf, sock_net(sk)->ipv4.sysctl_tcp_rmem[1]); + ++ tp->ops = &tcp_specific; ++ ++ /* Initialize MPTCP-specific stuff and function-pointers */ ++ mptcp_init_tcp_sock(sk); ++ + sk_sockets_allocated_inc(sk); + sk->sk_route_forced_caps = NETIF_F_GSO; + } +@@ -777,6 +801,7 @@ + int ret; + + sock_rps_record_flow(sk); ++ + /* + * We can't seek on a socket input + */ +@@ -787,6 +812,16 @@ + + lock_sock(sk); + ++#ifdef CONFIG_MPTCP ++ if (mptcp(tcp_sk(sk))) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { ++ sock_rps_record_flow(mptcp_to_sock(mptcp)); ++ } ++ } ++#endif ++ + timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); + while (tss.len) { + ret = __tcp_splice_read(sk, &tss); +@@ -902,8 +937,7 @@ + return NULL; + } + +-static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, +- int large_allowed) ++unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, int large_allowed) + { + struct tcp_sock *tp = tcp_sk(sk); + u32 new_size_goal, size_goal; +@@ -931,8 +965,13 @@ + { + int mss_now; + +- mss_now = tcp_current_mss(sk); +- *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); ++ if (mptcp(tcp_sk(sk))) { ++ mss_now = mptcp_current_mss(sk); ++ *size_goal = mptcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); ++ } else { ++ mss_now = tcp_current_mss(sk); ++ *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); ++ } + + return mss_now; + } +@@ -971,12 +1010,34 @@ + * is fully established. + */ + if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && +- !tcp_passive_fastopen(sk)) { ++ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? ++ tp->mpcb->master_sk : sk)) { + err = sk_stream_wait_connect(sk, &timeo); + if (err != 0) + goto out_err; + } + ++ if (mptcp(tp)) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ /* We must check this with socket-lock hold because we iterate ++ * over the subflows. ++ */ ++ if (!mptcp_can_sendpage(sk)) { ++ ssize_t ret; ++ ++ release_sock(sk); ++ ret = sock_no_sendpage(sk->sk_socket, page, offset, ++ size, flags); ++ lock_sock(sk); ++ return ret; ++ } ++ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ sock_rps_record_flow(mptcp_to_sock(mptcp)); ++ } ++ } ++ + sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); + + mss_now = tcp_send_mss(sk, &size_goal, flags); +@@ -1099,7 +1160,8 @@ + int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, + size_t size, int flags) + { +- if (!(sk->sk_route_caps & NETIF_F_SG)) ++ /* If MPTCP is enabled, we check it later after establishment */ ++ if (!mptcp(tcp_sk(sk)) && !(sk->sk_route_caps & NETIF_F_SG)) + return sock_no_sendpage_locked(sk, page, offset, size, flags); + + tcp_rate_check_app_limited(sk); /* is sending application-limited? */ +@@ -1221,12 +1283,21 @@ + * is fully established. + */ + if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && +- !tcp_passive_fastopen(sk)) { ++ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? ++ tp->mpcb->master_sk : sk)) { + err = sk_stream_wait_connect(sk, &timeo); + if (err != 0) + goto do_error; + } + ++ if (mptcp(tp)) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ sock_rps_record_flow(mptcp_to_sock(mptcp)); ++ } ++ } ++ + if (unlikely(tp->repair)) { + if (tp->repair_queue == TCP_RECV_QUEUE) { + copied = tcp_send_rcvq(sk, msg, size); +@@ -1520,7 +1591,7 @@ + * calculation of whether or not we must ACK for the sake of + * a window update. + */ +-static void tcp_cleanup_rbuf(struct sock *sk, int copied) ++void tcp_cleanup_rbuf(struct sock *sk, int copied) + { + struct tcp_sock *tp = tcp_sk(sk); + bool time_to_ack = false; +@@ -1563,7 +1634,7 @@ + + /* Optimize, __tcp_select_window() is not cheap. */ + if (2*rcv_window_now <= tp->window_clamp) { +- __u32 new_window = __tcp_select_window(sk); ++ __u32 new_window = tp->ops->__select_window(sk); + + /* Send ACK now, if this read freed lots of space + * in our buffer. Certainly, new_window is new window. +@@ -1679,7 +1750,7 @@ + /* Clean up data we have read: This will do ACK frames. */ + if (copied > 0) { + tcp_recv_skb(sk, seq, &offset); +- tcp_cleanup_rbuf(sk, copied); ++ tp->ops->cleanup_rbuf(sk, copied); + } + return copied; + } +@@ -1970,6 +2041,16 @@ + + lock_sock(sk); + ++#ifdef CONFIG_MPTCP ++ if (mptcp(tp)) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ sock_rps_record_flow(mptcp_to_sock(mptcp)); ++ } ++ } ++#endif ++ + err = -ENOTCONN; + if (sk->sk_state == TCP_LISTEN) + goto out; +@@ -2088,7 +2169,7 @@ + } + } + +- tcp_cleanup_rbuf(sk, copied); ++ tp->ops->cleanup_rbuf(sk, copied); + + if (copied >= target) { + /* Do not sleep, just process backlog. */ +@@ -2179,7 +2260,7 @@ + */ + + /* Clean up data we have read: This will do ACK frames. */ +- tcp_cleanup_rbuf(sk, copied); ++ tp->ops->cleanup_rbuf(sk, copied); + + release_sock(sk); + +@@ -2287,7 +2368,7 @@ + [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ + }; + +-static int tcp_close_state(struct sock *sk) ++int tcp_close_state(struct sock *sk) + { + int next = (int)new_state[sk->sk_state]; + int ns = next & TCP_STATE_MASK; +@@ -2317,7 +2398,7 @@ + TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { + /* Clear out any half completed packets. FIN if needed. */ + if (tcp_close_state(sk)) +- tcp_send_fin(sk); ++ tcp_sk(sk)->ops->send_fin(sk); + } + } + EXPORT_SYMBOL(tcp_shutdown); +@@ -2342,6 +2423,17 @@ + int data_was_unread = 0; + int state; + ++ if (is_meta_sk(sk)) { ++ /* TODO: Currently forcing timeout to 0 because ++ * sk_stream_wait_close will complain during lockdep because ++ * of the mpcb_mutex (circular lock dependency through ++ * inet_csk_listen_stop()). ++ * We should find a way to get rid of the mpcb_mutex. ++ */ ++ mptcp_close(sk, 0); ++ return; ++ } ++ + lock_sock(sk); + sk->sk_shutdown = SHUTDOWN_MASK; + +@@ -2386,7 +2478,7 @@ + /* Unread data was tossed, zap the connection. */ + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); + tcp_set_state(sk, TCP_CLOSE); +- tcp_send_active_reset(sk, sk->sk_allocation); ++ tcp_sk(sk)->ops->send_active_reset(sk, sk->sk_allocation); + } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { + /* Check zero linger _after_ checking for unread data. */ + sk->sk_prot->disconnect(sk, 0); +@@ -2460,7 +2552,7 @@ + struct tcp_sock *tp = tcp_sk(sk); + if (tp->linger2 < 0) { + tcp_set_state(sk, TCP_CLOSE); +- tcp_send_active_reset(sk, GFP_ATOMIC); ++ tp->ops->send_active_reset(sk, GFP_ATOMIC); + __NET_INC_STATS(sock_net(sk), + LINUX_MIB_TCPABORTONLINGER); + } else { +@@ -2470,7 +2562,8 @@ + inet_csk_reset_keepalive_timer(sk, + tmo - TCP_TIMEWAIT_LEN); + } else { +- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); ++ tcp_sk(sk)->ops->time_wait(sk, TCP_FIN_WAIT2, ++ tmo); + goto out; + } + } +@@ -2479,7 +2572,7 @@ + sk_mem_reclaim(sk); + if (tcp_check_oom(sk, 0)) { + tcp_set_state(sk, TCP_CLOSE); +- tcp_send_active_reset(sk, GFP_ATOMIC); ++ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); + __NET_INC_STATS(sock_net(sk), + LINUX_MIB_TCPABORTONMEMORY); + } else if (!check_net(sock_net(sk))) { +@@ -2511,15 +2604,6 @@ + } + EXPORT_SYMBOL(tcp_close); + +-/* These states need RST on ABORT according to RFC793 */ +- +-static inline bool tcp_need_reset(int state) +-{ +- return (1 << state) & +- (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | +- TCPF_FIN_WAIT2 | TCPF_SYN_RECV); +-} +- + static void tcp_rtx_queue_purge(struct sock *sk) + { + struct rb_node *p = rb_first(&sk->tcp_rtx_queue); +@@ -2540,6 +2624,10 @@ + { + struct sk_buff *skb; + ++ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk) && ++ !tcp_rtx_and_write_queues_empty(sk)) ++ mptcp_reinject_data(sk, 0); ++ + tcp_chrono_stop(sk, TCP_CHRONO_BUSY); + while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { + tcp_skb_tsorted_anchor_cleanup(skb); +@@ -2558,6 +2646,29 @@ + inet_csk(sk)->icsk_backoff = 0; + } + ++void tcp_reset_vars(struct sock *sk) ++{ ++ struct inet_connection_sock *icsk = inet_csk(sk); ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ tp->srtt_us = 0; ++ tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT); ++ tp->rcv_rtt_last_tsecr = 0; ++ icsk->icsk_rto = TCP_TIMEOUT_INIT; ++ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; ++ tp->snd_cwnd = TCP_INIT_CWND; ++ tp->snd_cwnd_cnt = 0; ++ tp->delivered_ce = 0; ++ tp->is_sack_reneg = 0; ++ tcp_clear_retrans(tp); ++ tp->bytes_sent = 0; ++ tp->bytes_acked = 0; ++ tp->bytes_received = 0; ++ tp->bytes_retrans = 0; ++ /* There's a bubble in the pipe until at least the first ACK. */ ++ tp->app_limited = ~0U; ++} ++ + int tcp_disconnect(struct sock *sk, int flags) + { + struct inet_sock *inet = inet_sk(sk); +@@ -2580,7 +2691,7 @@ + /* The last check adjusts for discrepancy of Linux wrt. RFC + * states + */ +- tcp_send_active_reset(sk, gfp_any()); ++ tp->ops->send_active_reset(sk, gfp_any()); + sk->sk_err = ECONNRESET; + } else if (old_state == TCP_SYN_SENT) + sk->sk_err = ECONNRESET; +@@ -2602,11 +2713,15 @@ + if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) + inet_reset_saddr(sk); + ++ if (is_meta_sk(sk)) { ++ mptcp_disconnect(sk); ++ } else { ++ if (tp->inside_tk_table) ++ mptcp_hash_remove_bh(tp); ++ } ++ + sk->sk_shutdown = 0; + sock_reset_flag(sk, SOCK_DONE); +- tp->srtt_us = 0; +- tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT); +- tp->rcv_rtt_last_tsecr = 0; + + seq = tp->write_seq + tp->max_window + 2; + if (!seq) +@@ -2616,17 +2731,11 @@ + icsk->icsk_backoff = 0; + tp->snd_cwnd = 2; + icsk->icsk_probes_out = 0; +- icsk->icsk_rto = TCP_TIMEOUT_INIT; +- tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; +- tp->snd_cwnd = TCP_INIT_CWND; +- tp->snd_cwnd_cnt = 0; + tp->window_clamp = 0; +- tp->delivered = 0; +- tp->delivered_ce = 0; ++ ++ tcp_reset_vars(sk); ++ + tcp_set_ca_state(sk, TCP_CA_Open); +- tp->is_sack_reneg = 0; +- tcp_clear_retrans(tp); +- tp->total_retrans = 0; + inet_csk_delack_init(sk); + /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 + * issue in __tcp_select_window() +@@ -2636,14 +2747,10 @@ + sk->sk_rx_dst = NULL; + tcp_saved_syn_free(tp); + tp->compressed_ack = 0; + tp->segs_in = 0; + tp->segs_out = 0; +- tp->bytes_sent = 0; +- tp->bytes_acked = 0; +- tp->bytes_received = 0; +- tp->bytes_retrans = 0; + tp->data_segs_in = 0; + tp->data_segs_out = 0; + tp->duplicate_sack[0].start_seq = 0; + tp->duplicate_sack[0].end_seq = 0; + tp->dsack_dups = 0; +@@ -2648,8 +2755,6 @@ + tp->sacked_out = 0; + tp->tlp_high_seq = 0; + tp->last_oow_ack_time = 0; +- /* There's a bubble in the pipe until at least the first ACK. */ +- tp->app_limited = ~0U; + tp->rack.mstamp = 0; + tp->rack.advanced = 0; + tp->rack.reo_wnd_steps = 1; +@@ -2683,7 +2788,7 @@ + static inline bool tcp_can_repair_sock(const struct sock *sk) + { + return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && +- (sk->sk_state != TCP_LISTEN); ++ (sk->sk_state != TCP_LISTEN) && !sock_flag(sk, SOCK_MPTCP); + } + + static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) +@@ -2852,6 +2957,61 @@ + + return tcp_fastopen_reset_cipher(net, sk, key, backup_key); + } ++#ifdef CONFIG_MPTCP ++ case MPTCP_SCHEDULER: { ++ char name[MPTCP_SCHED_NAME_MAX]; ++ ++ if (optlen < 1) ++ return -EINVAL; ++ ++ /* Cannot be used if MPTCP is not used or we already have ++ * established an MPTCP-connection. ++ */ ++ if (mptcp_init_failed || !sysctl_mptcp_enabled || ++ sk->sk_state != TCP_CLOSE) ++ return -EPERM; ++ ++ val = strncpy_from_user(name, optval, ++ min_t(long, MPTCP_SCHED_NAME_MAX - 1, ++ optlen)); ++ ++ if (val < 0) ++ return -EFAULT; ++ name[val] = 0; ++ ++ lock_sock(sk); ++ err = mptcp_set_scheduler(sk, name); ++ release_sock(sk); ++ return err; ++ } ++ ++ case MPTCP_PATH_MANAGER: { ++ char name[MPTCP_PM_NAME_MAX]; ++ ++ if (optlen < 1) ++ return -EINVAL; ++ ++ /* Cannot be used if MPTCP is not used or we already have ++ * established an MPTCP-connection. ++ */ ++ if (mptcp_init_failed || !sysctl_mptcp_enabled || ++ sk->sk_state != TCP_CLOSE) ++ return -EPERM; ++ ++ val = strncpy_from_user(name, optval, ++ min_t(long, MPTCP_PM_NAME_MAX - 1, ++ optlen)); ++ ++ if (val < 0) ++ return -EFAULT; ++ name[val] = 0; ++ ++ lock_sock(sk); ++ err = mptcp_set_path_manager(sk, name); ++ release_sock(sk); ++ return err; ++ } ++#endif + default: + /* fallthru */ + break; +@@ -3032,6 +3192,12 @@ + break; + + case TCP_DEFER_ACCEPT: ++ /* An established MPTCP-connection (mptcp(tp) only returns true ++ * if the socket is established) should not use DEFER on new ++ * subflows. ++ */ ++ if (mptcp(tp)) ++ break; + /* Translate value in seconds to number of retransmits */ + icsk->icsk_accept_queue.rskq_defer_accept = + secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, +@@ -3059,7 +3225,7 @@ + (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && + inet_csk_ack_scheduled(sk)) { + icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; +- tcp_cleanup_rbuf(sk, 1); ++ tp->ops->cleanup_rbuf(sk, 1); + if (!(val & 1)) + inet_csk_enter_pingpong_mode(sk); + } +@@ -3069,7 +3235,7 @@ + #ifdef CONFIG_TCP_MD5SIG + case TCP_MD5SIG: + case TCP_MD5SIG_EXT: +- if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ++ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN) && !sock_flag(sk, SOCK_MPTCP)) + err = tp->af_specific->md5_parse(sk, optname, optval, optlen); + else + err = -EINVAL; +@@ -3128,6 +3294,32 @@ + tp->notsent_lowat = val; + sk->sk_write_space(sk); + break; ++#ifdef CONFIG_MPTCP ++ case MPTCP_ENABLED: ++ if (mptcp_init_failed || !sysctl_mptcp_enabled || ++ sk->sk_state != TCP_CLOSE ++#ifdef CONFIG_TCP_MD5SIG ++ || tp->md5sig_info ++#endif ++ ) { ++ err = -EPERM; ++ break; ++ } ++ ++ if (val) ++ mptcp_enable_sock(sk); ++ else ++ mptcp_disable_sock(sk); ++ break; ++ case MPTCP_INFO: ++ if (mptcp_init_failed || !sysctl_mptcp_enabled) { ++ err = -EPERM; ++ break; ++ } ++ ++ tp->record_master_info = !!(val & MPTCP_INFO_FLAG_SAVE_MASTER); ++ break; ++#endif + case TCP_INQ: + if (val > 1 || val < 0) + err = -EINVAL; +@@ -3192,7 +3384,7 @@ + } + + /* Return information about state of tcp endpoint in API format. */ +-void tcp_get_info(struct sock *sk, struct tcp_info *info) ++void tcp_get_info(struct sock *sk, struct tcp_info *info, bool no_lock) + { + const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ + const struct inet_connection_sock *icsk = inet_csk(sk); +@@ -3229,7 +3421,8 @@ + return; + } + +- slow = lock_sock_fast(sk); ++ if (!no_lock) ++ slow = lock_sock_fast(sk); + + info->tcpi_ca_state = icsk->icsk_ca_state; + info->tcpi_retransmits = icsk->icsk_retransmits; +@@ -3305,7 +3498,9 @@ + info->tcpi_reord_seen = tp->reord_seen; + info->tcpi_rcv_ooopack = tp->rcv_ooopack; + info->tcpi_snd_wnd = tp->snd_wnd; +- unlock_sock_fast(sk, slow); ++ ++ if (!no_lock) ++ unlock_sock_fast(sk, slow); + } + EXPORT_SYMBOL_GPL(tcp_get_info); + +@@ -3452,7 +3647,7 @@ + if (get_user(len, optlen)) + return -EFAULT; + +- tcp_get_info(sk, &info); ++ tcp_get_info(sk, &info, false); + + len = min_t(unsigned int, len, sizeof(info)); + if (put_user(len, optlen)) +@@ -3649,6 +3844,87 @@ + } + return 0; + } ++#ifdef CONFIG_MPTCP ++ case MPTCP_SCHEDULER: ++ if (get_user(len, optlen)) ++ return -EFAULT; ++ len = min_t(unsigned int, len, MPTCP_SCHED_NAME_MAX); ++ if (put_user(len, optlen)) ++ return -EFAULT; ++ ++ lock_sock(sk); ++ if (mptcp(tcp_sk(sk))) { ++ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; ++ ++ if (copy_to_user(optval, mpcb->sched_ops->name, len)) { ++ release_sock(sk); ++ return -EFAULT; ++ } ++ } else { ++ if (copy_to_user(optval, tcp_sk(sk)->mptcp_sched_name, ++ len)) { ++ release_sock(sk); ++ return -EFAULT; ++ } ++ } ++ release_sock(sk); ++ return 0; ++ ++ case MPTCP_PATH_MANAGER: ++ if (get_user(len, optlen)) ++ return -EFAULT; ++ len = min_t(unsigned int, len, MPTCP_PM_NAME_MAX); ++ if (put_user(len, optlen)) ++ return -EFAULT; ++ ++ lock_sock(sk); ++ if (mptcp(tcp_sk(sk))) { ++ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; ++ ++ if (copy_to_user(optval, mpcb->pm_ops->name, len)) { ++ release_sock(sk); ++ return -EFAULT; ++ } ++ } else { ++ if (copy_to_user(optval, tcp_sk(sk)->mptcp_pm_name, ++ len)) { ++ release_sock(sk); ++ return -EFAULT; ++ } ++ } ++ release_sock(sk); ++ return 0; ++ ++ case MPTCP_ENABLED: ++ if (sk->sk_state != TCP_SYN_SENT) ++ val = mptcp(tp) ? 1 : 0; ++ else ++ val = sock_flag(sk, SOCK_MPTCP) ? 1 : 0; ++ break; ++ case MPTCP_INFO: ++ { ++ int ret; ++ ++ if (!mptcp(tp)) ++ return -EINVAL; ++ ++ if (get_user(len, optlen)) ++ return -EFAULT; ++ ++ len = min_t(unsigned int, len, sizeof(struct mptcp_info)); ++ ++ lock_sock(sk); ++ ret = mptcp_get_info(sk, optval, len); ++ release_sock(sk); ++ ++ if (ret) ++ return ret; ++ ++ if (put_user(len, optlen)) ++ return -EFAULT; ++ return 0; ++ } ++#endif + #ifdef CONFIG_MMU + case TCP_ZEROCOPY_RECEIVE: { + struct tcp_zerocopy_receive zc; +@@ -3851,7 +4127,9 @@ + if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) + TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); + ++ WARN_ON(sk->sk_state == TCP_CLOSE); + tcp_set_state(sk, TCP_CLOSE); ++ + tcp_clear_xmit_timers(sk); + if (req) + reqsk_fastopen_remove(sk, req, false); +@@ -3867,6 +4145,8 @@ + + int tcp_abort(struct sock *sk, int err) + { ++ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; ++ + if (!sk_fullsock(sk)) { + if (sk->sk_state == TCP_NEW_SYN_RECV) { + struct request_sock *req = inet_reqsk(sk); +@@ -3880,7 +4160,7 @@ + } + + /* Don't race with userspace socket closes such as tcp_close. */ +- lock_sock(sk); ++ lock_sock(meta_sk); + + if (sk->sk_state == TCP_LISTEN) { + tcp_set_state(sk, TCP_CLOSE); +@@ -3889,7 +4169,7 @@ + + /* Don't race with BH socket closes such as inet_csk_listen_stop. */ + local_bh_disable(); +- bh_lock_sock(sk); ++ bh_lock_sock(meta_sk); + + if (!sock_flag(sk, SOCK_DEAD)) { + sk->sk_err = err; +@@ -3897,14 +4177,14 @@ + smp_wmb(); + sk->sk_error_report(sk); + if (tcp_need_reset(sk->sk_state)) +- tcp_send_active_reset(sk, GFP_ATOMIC); ++ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); + tcp_done(sk); + } + +- bh_unlock_sock(sk); ++ bh_unlock_sock(meta_sk); + local_bh_enable(); + tcp_write_queue_purge(sk); +- release_sock(sk); ++ release_sock(meta_sk); + return 0; + } + EXPORT_SYMBOL_GPL(tcp_abort); +diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c +--- linux-5.4/net/ipv4/tcp_cong.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-02-20 18:07:47.000000000 +0100 +@@ -328,13 +328,19 @@ + return ret; + } + ++int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, ++ bool reinit, bool cap_net_admin) ++{ ++ return tcp_sk(sk)->ops->set_cong_ctrl(sk, name, load, reinit, cap_net_admin); ++} ++ + /* Change congestion control for socket. If load is false, then it is the + * responsibility of the caller to call tcp_init_congestion_control or + * tcp_reinit_congestion_control (if the current congestion control was + * already initialized. + */ +-int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, +- bool reinit, bool cap_net_admin) ++int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, ++ bool reinit, bool cap_net_admin) + { + struct inet_connection_sock *icsk = inet_csk(sk); + const struct tcp_congestion_ops *ca; +diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c +--- linux-5.4/net/ipv4/tcp_diag.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-02-20 18:07:47.000000000 +0100 +@@ -31,7 +31,7 @@ + r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; + } + if (info) +- tcp_get_info(sk, info); ++ tcp_get_info(sk, info, false); + } + + #ifdef CONFIG_TCP_MD5SIG +diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c +--- linux-5.4/net/ipv4/tcp_fastopen.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-02-20 18:07:47.000000000 +0100 +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + void tcp_fastopen_init_key_once(struct net *net) + { +@@ -113,8 +114,6 @@ + const siphash_key_t *key, + struct tcp_fastopen_cookie *foc) + { +- BUILD_BUG_ON(TCP_FASTOPEN_COOKIE_SIZE != sizeof(u64)); +- + if (req->rsk_ops->family == AF_INET) { + const struct iphdr *iph = ip_hdr(syn); + +@@ -235,8 +234,9 @@ + { + struct tcp_sock *tp; + struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; +- struct sock *child; ++ struct sock *child, *meta_sk; + bool own_req; ++ int ret; + + child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, + NULL, &own_req); +@@ -271,15 +271,26 @@ + + refcount_set(&req->rsk_refcnt, 2); + +- /* Now finish processing the fastopen child socket. */ +- tcp_init_transfer(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB); +- + tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; + + tcp_fastopen_add_skb(child, skb); + + tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; + tp->rcv_wup = tp->rcv_nxt; ++ ++ meta_sk = child; ++ ret = mptcp_check_req_fastopen(meta_sk, req); ++ if (ret < 0) ++ return NULL; ++ ++ if (ret == 0) { ++ child = tcp_sk(meta_sk)->mpcb->master_sk; ++ tp = tcp_sk(child); ++ } ++ ++ /* Now finish processing the fastopen child socket. */ ++ tcp_init_transfer(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB); ++ + /* tcp_conn_request() is sending the SYNACK, + * and queues the child into listener accept queue. + */ +diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c +--- linux-5.4/net/ipv4/tcp_input.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-02-20 18:07:47.000000000 +0100 +@@ -76,35 +76,15 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + #include + + int sysctl_tcp_max_orphans __read_mostly = NR_FILE; + +-#define FLAG_DATA 0x01 /* Incoming frame contained data. */ +-#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ +-#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ +-#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ +-#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ +-#define FLAG_DATA_SACKED 0x20 /* New SACK. */ +-#define FLAG_ECE 0x40 /* ECE in this ACK */ +-#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ +-#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ +-#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ +-#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ +-#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ +-#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ +-#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ +-#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ +-#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ +-#define FLAG_ACK_MAYBE_DELAYED 0x10000 /* Likely a delayed ACK */ +- +-#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) +-#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) +-#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) +-#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) +- + #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) + #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) + +@@ -348,8 +328,12 @@ + per_mss = roundup_pow_of_two(per_mss) + + SKB_DATA_ALIGN(sizeof(struct sk_buff)); + +- nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); +- nr_segs = max_t(u32, nr_segs, tp->reordering + 1); ++ if (mptcp(tp)) { ++ nr_segs = mptcp_check_snd_buf(tp); ++ } else { ++ nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); ++ nr_segs = max_t(u32, nr_segs, tp->reordering + 1); ++ } + + /* Fast Recovery (RFC 5681 3.2) : + * Cubic needs 1.7 factor, rounded to 2 to include +@@ -358,9 +342,17 @@ + sndmem = ca_ops->sndbuf_expand ? ca_ops->sndbuf_expand(sk) : 2; + sndmem *= nr_segs * per_mss; + +- if (sk->sk_sndbuf < sndmem) ++ /* MPTCP: after this sndmem is the new contribution of the ++ * current subflow to the aggregated sndbuf */ ++ if (sk->sk_sndbuf < sndmem) { ++ int old_sndbuf = sk->sk_sndbuf; + WRITE_ONCE(sk->sk_sndbuf, + min(sndmem, sock_net(sk)->ipv4.sysctl_tcp_wmem[2])); ++ /* MPTCP: ok, the subflow sndbuf has grown, reflect ++ * this in the aggregate buffer.*/ ++ if (mptcp(tp) && old_sndbuf != sk->sk_sndbuf) ++ mptcp_update_sndbuf(tp); ++ } + } + + /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) +@@ -409,9 +401,14 @@ + static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) + { + struct tcp_sock *tp = tcp_sk(sk); ++ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); + int room; + +- room = min_t(int, tp->window_clamp, tcp_space(sk)) - tp->rcv_ssthresh; ++ if (is_meta_sk(sk)) ++ return; ++ ++ room = min_t(int, meta_tp->window_clamp, tcp_space(meta_sk)) - meta_tp->rcv_ssthresh; + + /* Check #1 */ + if (room > 0 && !tcp_under_memory_pressure(sk)) { +@@ -421,13 +418,13 @@ + * will fit to rcvbuf in future. + */ + if (tcp_win_from_space(sk, skb->truesize) <= skb->len) +- incr = 2 * tp->advmss; ++ incr = 2 * meta_tp->advmss; + else +- incr = __tcp_grow_window(sk, skb); ++ incr = __tcp_grow_window(meta_sk, skb); + + if (incr) { + incr = max_t(int, incr, 2 * skb->len); +- tp->rcv_ssthresh += min(room, incr); ++ meta_tp->rcv_ssthresh += min(room, incr); + inet_csk(sk)->icsk_ack.quick |= 1; + } + } +@@ -610,7 +607,10 @@ + + tcp_mstamp_refresh(tp); + time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); +- if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) ++ if (mptcp(tp)) { ++ if (mptcp_check_rtt(tp, time)) ++ return; ++ } else if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) + return; + + /* Number of bytes copied to user in last RTT */ +@@ -833,7 +833,7 @@ + /* Calculate rto without backoff. This is the second half of Van Jacobson's + * routine referred to above. + */ +-static void tcp_set_rto(struct sock *sk) ++void tcp_set_rto(struct sock *sk) + { + const struct tcp_sock *tp = tcp_sk(sk); + /* Old crap is replaced with new one. 8) +@@ -1404,6 +1404,13 @@ + int len; + int in_sack; + ++ /* For MPTCP we cannot shift skb-data and remove one skb from the ++ * send-queue, because this will make us loose the DSS-option (which ++ * is stored in TCP_SKB_CB(skb)->dss) of the skb we are removing. ++ */ ++ if (mptcp(tp)) ++ goto fallback; ++ + /* Normally R but no L won't result in plain S */ + if (!dup_sack && + (TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_RETRANS)) == TCPCB_SACKED_RETRANS) +@@ -2953,7 +2960,7 @@ + */ + tcp_update_rtt_min(sk, ca_rtt_us, flag); + tcp_rtt_estimator(sk, seq_rtt_us); +- tcp_set_rto(sk); ++ tp->ops->set_rto(sk); + + /* RFC6298: only reset backoff on valid RTT measurement. */ + inet_csk(sk)->icsk_backoff = 0; +@@ -3021,7 +3028,7 @@ + } + + /* If we get here, the whole TSO packet has not been acked. */ +-static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) ++u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) + { + struct tcp_sock *tp = tcp_sk(sk); + u32 packets_acked; +@@ -3147,6 +3154,8 @@ + */ + if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { + flag |= FLAG_DATA_ACKED; ++ if (mptcp(tp) && mptcp_is_data_seq(skb)) ++ flag |= MPTCP_FLAG_DATA_ACKED; + } else { + flag |= FLAG_SYN_ACKED; + tp->retrans_stamp = 0; +@@ -3266,7 +3275,7 @@ + return flag; + } + +-static void tcp_ack_probe(struct sock *sk) ++void tcp_ack_probe(struct sock *sk) + { + struct inet_connection_sock *icsk = inet_csk(sk); + struct sk_buff *head = tcp_send_head(sk); +@@ -3338,9 +3347,8 @@ + /* Check that window update is acceptable. + * The function assumes that snd_una<=ack<=snd_next. + */ +-static inline bool tcp_may_update_window(const struct tcp_sock *tp, +- const u32 ack, const u32 ack_seq, +- const u32 nwin) ++bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, ++ const u32 ack_seq, const u32 nwin) + { + return after(ack, tp->snd_una) || + after(ack_seq, tp->snd_wl1) || +@@ -3577,7 +3585,7 @@ + } + + /* This routine deals with incoming acks, but not outgoing ones. */ +-static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) ++static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) + { + struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); +@@ -3691,6 +3699,16 @@ + + tcp_rack_update_reo_wnd(sk, &rs); + ++ if (mptcp(tp)) { ++ if (mptcp_fallback_infinite(sk, flag)) { ++ pr_debug("%s resetting flow\n", __func__); ++ mptcp_send_reset(sk); ++ return -1; ++ } ++ ++ mptcp_clean_rtx_infinite(skb, sk); ++ } ++ + if (tp->tlp_high_seq) + tcp_process_tlp_ack(sk, ack, flag); + /* If needed, reset TLP/RTO timer; RACK may later override this. */ +@@ -3833,8 +3851,10 @@ + */ + void tcp_parse_options(const struct net *net, + const struct sk_buff *skb, +- struct tcp_options_received *opt_rx, int estab, +- struct tcp_fastopen_cookie *foc) ++ struct tcp_options_received *opt_rx, ++ struct mptcp_options_received *mopt, ++ int estab, struct tcp_fastopen_cookie *foc, ++ struct tcp_sock *tp) + { + const unsigned char *ptr; + const struct tcphdr *th = tcp_hdr(skb); +@@ -3920,6 +3940,10 @@ + */ + break; + #endif ++ case TCPOPT_MPTCP: ++ mptcp_parse_options(ptr - 2, opsize, mopt, skb, tp); ++ break; ++ + case TCPOPT_FASTOPEN: + tcp_parse_fastopen_option( + opsize - TCPOLEN_FASTOPEN_BASE, +@@ -3987,7 +4011,9 @@ + return true; + } + +- tcp_parse_options(net, skb, &tp->rx_opt, 1, NULL); ++ tcp_parse_options(net, skb, &tp->rx_opt, ++ mptcp(tp) ? &tp->mptcp->rx_opt : NULL, 1, NULL, tp); ++ + if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) + tp->rx_opt.rcv_tsecr -= tp->tsoffset; + +@@ -4146,6 +4172,11 @@ + { + struct tcp_sock *tp = tcp_sk(sk); + ++ if (is_meta_sk(sk)) { ++ mptcp_fin(sk); ++ return; ++ } ++ + inet_csk_schedule_ack(sk); + + sk->sk_shutdown |= RCV_SHUTDOWN; +@@ -4156,6 +4187,10 @@ + case TCP_ESTABLISHED: + /* Move to CLOSE_WAIT */ + tcp_set_state(sk, TCP_CLOSE_WAIT); ++ ++ if (mptcp(tp)) ++ mptcp_sub_close_passive(sk); ++ + inet_csk_enter_pingpong_mode(sk); + break; + +@@ -4178,9 +4213,16 @@ + tcp_set_state(sk, TCP_CLOSING); + break; + case TCP_FIN_WAIT2: ++ if (mptcp(tp)) { ++ /* The socket will get closed by mptcp_data_ready. ++ * We first have to process all data-sequences. ++ */ ++ tp->close_it = 1; ++ break; ++ } + /* Received a FIN -- send ACK and enter TIME_WAIT. */ + tcp_send_ack(sk); +- tcp_time_wait(sk, TCP_TIME_WAIT, 0); ++ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); + break; + default: + /* Only TCP_LISTEN and TCP_CLOSE are left, in these +@@ -4202,6 +4244,10 @@ + if (!sock_flag(sk, SOCK_DEAD)) { + sk->sk_state_change(sk); + ++ /* Don't wake up MPTCP-subflows */ ++ if (mptcp(tp)) ++ return; ++ + /* Do not send POLL_HUP for half duplex close. */ + if (sk->sk_shutdown == SHUTDOWN_MASK || + sk->sk_state == TCP_CLOSE) +@@ -4416,6 +4462,9 @@ + + *fragstolen = false; + ++ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk)) ++ return false; ++ + /* Its possible this segment overlaps with prior segment in queue */ + if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq) + return false; +@@ -4470,7 +4519,7 @@ + /* This one checks to see if we can put data from the + * out_of_order queue into the receive_queue. + */ +-static void tcp_ofo_queue(struct sock *sk) ++void tcp_ofo_queue(struct sock *sk) + { + struct tcp_sock *tp = tcp_sk(sk); + __u32 dsack_high = tp->rcv_nxt; +@@ -4493,7 +4542,14 @@ + p = rb_next(p); + rb_erase(&skb->rbnode, &tp->out_of_order_queue); + +- if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))) { ++ /* In case of MPTCP, the segment may be empty if it's a ++ * non-data DATA_FIN. (see beginning of tcp_data_queue) ++ * ++ * But this only holds true for subflows, not for the ++ * meta-socket. ++ */ ++ if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt) && ++ (is_meta_sk(sk) || !mptcp(tp) || TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq))) { + tcp_drop(sk, skb); + continue; + } +@@ -4523,6 +4579,9 @@ + static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, + unsigned int size) + { ++ if (mptcp(tcp_sk(sk))) ++ sk = mptcp_meta_sk(sk); ++ + if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || + !sk_rmem_schedule(sk, skb, size)) { + +@@ -4537,7 +4596,7 @@ + return 0; + } + +-static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) ++void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) + { + struct tcp_sock *tp = tcp_sk(sk); + struct rb_node **p, *parent; +@@ -4604,7 +4663,8 @@ + continue; + } + if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { +- if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { ++ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq) && ++ (is_meta_sk(sk) || !mptcp(tp) || end_seq != seq)) { + /* All the bits are present. Drop. */ + NET_INC_STATS(sock_net(sk), + LINUX_MIB_TCPOFOMERGE); +@@ -4651,6 +4711,11 @@ + end_seq); + break; + } ++ /* MPTCP allows non-data data-fin to be in the ofo-queue */ ++ if (mptcp(tp) && !is_meta_sk(sk) && TCP_SKB_CB(skb1)->seq == TCP_SKB_CB(skb1)->end_seq) { ++ skb = skb1; ++ continue; ++ } + rb_erase(&skb1->rbnode, &tp->out_of_order_queue); + tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, + TCP_SKB_CB(skb1)->end_seq); +@@ -4662,7 +4727,7 @@ + tp->ooo_last_skb = skb; + + add_sack: +- if (tcp_is_sack(tp)) ++ if (tcp_is_sack(tp) && seq != end_seq) + tcp_sack_new_ofo_skb(sk, seq, end_seq); + end: + if (skb) { +@@ -4672,8 +4737,8 @@ + } + } + +-static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, +- bool *fragstolen) ++int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, ++ bool *fragstolen) + { + int eaten; + struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); +@@ -4746,7 +4811,7 @@ + const struct tcp_sock *tp = tcp_sk(sk); + int avail = tp->rcv_nxt - tp->copied_seq; + +- if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE)) ++ if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) + return; + + sk->sk_data_ready(sk); +@@ -4758,10 +4823,14 @@ + bool fragstolen; + int eaten; + +- if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { ++ /* If no data is present, but a data_fin is in the options, we still ++ * have to call mptcp_queue_skb later on. */ ++ if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq && ++ !(mptcp(tp) && mptcp_is_data_fin(skb))) { + __kfree_skb(skb); + return; + } ++ + skb_dst_drop(skb); + __skb_pull(skb, tcp_hdr(skb)->doff * 4); + +@@ -4789,7 +4858,7 @@ + } + + eaten = tcp_queue_rcv(sk, skb, &fragstolen); +- if (skb->len) ++ if (skb->len || mptcp_is_data_fin(skb)) + tcp_event_data_recv(sk, skb); + if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) + tcp_fin(sk); +@@ -4811,7 +4880,11 @@ + + if (eaten > 0) + kfree_skb_partial(skb, fragstolen); +- if (!sock_flag(sk, SOCK_DEAD)) ++ if (!sock_flag(sk, SOCK_DEAD) || mptcp(tp)) ++ /* MPTCP: we always have to call data_ready, because ++ * we may be about to receive a data-fin, which still ++ * must get queued. ++ */ + tcp_data_ready(sk); + return; + } +@@ -5154,7 +5227,7 @@ + return -1; + } + +-static bool tcp_should_expand_sndbuf(const struct sock *sk) ++bool tcp_should_expand_sndbuf(const struct sock *sk) + { + const struct tcp_sock *tp = tcp_sk(sk); + +@@ -5189,7 +5262,7 @@ + { + struct tcp_sock *tp = tcp_sk(sk); + +- if (tcp_should_expand_sndbuf(sk)) { ++ if (tp->ops->should_expand_sndbuf(sk)) { + tcp_sndbuf_expand(sk); + tp->snd_cwnd_stamp = tcp_jiffies32; + } +@@ -5203,10 +5276,11 @@ + sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); + /* pairs with tcp_poll() */ + smp_mb(); +- if (sk->sk_socket && +- test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { ++ if (mptcp(tcp_sk(sk)) || ++ (sk->sk_socket && ++ test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))) { + tcp_new_space(sk); +- if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) ++ if (sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) + tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); + } + } +@@ -5225,6 +5299,8 @@ + { + struct tcp_sock *tp = tcp_sk(sk); + unsigned long rtt, delay; ++ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); + + /* More than one full frame received... */ + if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && +@@ -5233,8 +5309,8 @@ + * If application uses SO_RCVLOWAT, we want send ack now if + * we have not received enough bytes to satisfy the condition. + */ +- (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat || +- __tcp_select_window(sk) >= tp->rcv_wnd)) || ++ (meta_tp->rcv_nxt - meta_tp->copied_seq < meta_sk->sk_rcvlowat || ++ tp->ops->__select_window(sk) >= tp->rcv_wnd)) || + /* We ACK each frame or... */ + tcp_in_quickack_mode(sk) || + /* Protocol state mandates a one-time immediate ACK */ +@@ -5369,6 +5445,10 @@ + { + struct tcp_sock *tp = tcp_sk(sk); + ++ /* MPTCP urgent data is not yet supported */ ++ if (mptcp(tp)) ++ return; ++ + /* Check if we get a new urgent pointer - normally not. */ + if (th->urg) + tcp_check_urg(sk, th); +@@ -5511,9 +5591,15 @@ + goto discard; + } + ++ /* If valid: post process the received MPTCP options. */ ++ if (mptcp(tp) && mptcp_handle_options(sk, th, skb)) ++ goto discard; ++ + return true; + + discard: ++ if (mptcp(tp)) ++ mptcp_reset_mopt(tp); + tcp_drop(sk, skb); + return false; + } +@@ -5570,6 +5656,10 @@ + + tp->rx_opt.saw_tstamp = 0; + ++ /* MPTCP: force slowpath. */ ++ if (mptcp(tp)) ++ goto slow_path; ++ + /* pred_flags is 0xS?10 << 16 + snd_wnd + * if header_prediction is to be made + * 'S' will always be tp->tcp_header_len >> 2 +@@ -5742,7 +5832,7 @@ + + tcp_call_bpf(sk, bpf_op, 0, NULL); + tcp_init_congestion_control(sk); +- tcp_init_buffer_space(sk); ++ tcp_sk(sk)->ops->init_buffer_space(sk); + } + + void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) +@@ -5779,17 +5869,24 @@ + struct tcp_fastopen_cookie *cookie) + { + struct tcp_sock *tp = tcp_sk(sk); +- struct sk_buff *data = tp->syn_data ? tcp_rtx_queue_head(sk) : NULL; ++ struct sk_buff *data = NULL; + u16 mss = tp->rx_opt.mss_clamp, try_exp = 0; + bool syn_drop = false; + ++ if (tp->syn_data) { ++ if (mptcp(tp)) ++ data = tcp_write_queue_head(mptcp_meta_sk(sk)); ++ else ++ data = tcp_rtx_queue_head(sk); ++ } ++ + if (mss == tp->rx_opt.user_mss) { + struct tcp_options_received opt; + + /* Get original SYNACK MSS value if user MSS sets mss_clamp */ + tcp_clear_options(&opt); + opt.user_mss = opt.mss_clamp = 0; +- tcp_parse_options(sock_net(sk), synack, &opt, 0, NULL); ++ tcp_parse_options(sock_net(sk), synack, &opt, NULL, 0, NULL, NULL); + mss = opt.mss_clamp; + } + +@@ -5813,7 +5910,11 @@ + + tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp); + +- if (data) { /* Retransmit unacked data in SYN */ ++ /* In mptcp case, we do not rely on "retransmit", but instead on ++ * "transmit", because if fastopen data is not acked, the retransmission ++ * becomes the first MPTCP data (see mptcp_rcv_synsent_fastopen). ++ */ ++ if (data && !mptcp(tp)) { /* Retransmit unacked data in SYN */ + skb_rbtree_walk_from(data) { + if (__tcp_retransmit_skb(sk, data, 1)) + break; +@@ -5868,9 +5969,13 @@ + struct tcp_sock *tp = tcp_sk(sk); + struct tcp_fastopen_cookie foc = { .len = -1 }; + int saved_clamp = tp->rx_opt.mss_clamp; ++ struct mptcp_options_received mopt; + bool fastopen_fail; + +- tcp_parse_options(sock_net(sk), skb, &tp->rx_opt, 0, &foc); ++ mptcp_init_mp_opt(&mopt); ++ ++ tcp_parse_options(sock_net(sk), skb, &tp->rx_opt, ++ mptcp(tp) ? &tp->mptcp->rx_opt : &mopt, 0, &foc, tp); + if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) + tp->rx_opt.rcv_tsecr -= tp->tsoffset; + +@@ -5931,6 +6036,35 @@ + tcp_try_undo_spurious_syn(sk); + tcp_ack(sk, skb, FLAG_SLOWPATH); + ++ if (tp->request_mptcp || mptcp(tp)) { ++ int ret; ++ ++ rcu_read_lock(); ++ local_bh_disable(); ++ ret = mptcp_rcv_synsent_state_process(sk, &sk, ++ skb, &mopt); ++ local_bh_enable(); ++ rcu_read_unlock(); ++ ++ /* May have changed if we support MPTCP */ ++ tp = tcp_sk(sk); ++ icsk = inet_csk(sk); ++ ++ if (ret == 1) ++ goto reset_and_undo; ++ if (ret == 2) ++ goto discard; ++ } ++ ++ if (mptcp(tp) && !is_master_tp(tp)) { ++ /* Timer for repeating the ACK until an answer ++ * arrives. Used only when establishing an additional ++ * subflow inside of an MPTCP connection. ++ */ ++ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, ++ jiffies + icsk->icsk_rto); ++ } ++ + /* Ok.. it's good. Set up sequence numbers and + * move to established. + */ +@@ -5957,6 +6091,11 @@ + tp->tcp_header_len = sizeof(struct tcphdr); + } + ++ if (mptcp(tp)) { ++ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; ++ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; ++ } ++ + tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); + tcp_initialize_rcv_mss(sk); + +@@ -5980,9 +6119,12 @@ + } + if (fastopen_fail) + return -1; +- if (sk->sk_write_pending || ++ /* With MPTCP we cannot send data on the third ack due to the ++ * lack of option-space to combine with an MP_CAPABLE. ++ */ ++ if (!mptcp(tp) && (sk->sk_write_pending || + icsk->icsk_accept_queue.rskq_defer_accept || +- inet_csk_in_pingpong_mode(sk)) { ++ inet_csk_in_pingpong_mode(sk))) { + /* Save one ACK. Data will be ready after + * several ticks, if write_pending is set. + * +@@ -6021,6 +6163,7 @@ + tcp_paws_reject(&tp->rx_opt, 0)) + goto discard_and_undo; + ++ /* TODO - check this here for MPTCP */ + if (th->syn) { + /* We see SYN without ACK. It is attempt of + * simultaneous connect with crossed SYNs. +@@ -6037,6 +6180,11 @@ + tp->tcp_header_len = sizeof(struct tcphdr); + } + ++ if (mptcp(tp)) { ++ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; ++ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; ++ } ++ + WRITE_ONCE(tp->rcv_nxt, TCP_SKB_CB(skb)->seq + 1); + WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); + tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; +@@ -6123,6 +6271,7 @@ + */ + + int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) ++ __releases(&sk->sk_lock.slock) + { + struct tcp_sock *tp = tcp_sk(sk); + struct inet_connection_sock *icsk = inet_csk(sk); +@@ -6165,6 +6314,16 @@ + tp->rx_opt.saw_tstamp = 0; + tcp_mstamp_refresh(tp); + queued = tcp_rcv_synsent_state_process(sk, skb, th); ++ if (is_meta_sk(sk)) { ++ sk = tcp_sk(sk)->mpcb->master_sk; ++ tp = tcp_sk(sk); ++ ++ /* Need to call it here, because it will announce new ++ * addresses, which can only be done after the third ack ++ * of the 3-way handshake. ++ */ ++ mptcp_update_metasocket(tp->meta_sk); ++ } + if (queued >= 0) + return queued; + +@@ -6237,6 +6396,8 @@ + + if (tp->rx_opt.tstamp_ok) + tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; ++ if (mptcp(tp)) ++ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; + + if (!inet_csk(sk)->icsk_ca_ops->cong_control) + tcp_update_pacing_rate(sk); +@@ -6246,6 +6407,30 @@ + + tcp_initialize_rcv_mss(sk); + tcp_fast_path_on(tp); ++ ++ /* Send an ACK when establishing a new MPTCP subflow, i.e. ++ * using an MP_JOIN subtype. ++ */ ++ if (mptcp(tp)) { ++ if (is_master_tp(tp)) { ++ mptcp_update_metasocket(mptcp_meta_sk(sk)); ++ } else { ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ tcp_send_ack(sk); ++ ++ /* Update RTO as it might be worse/better */ ++ mptcp_set_rto(sk); ++ ++ /* If the new RTO would fire earlier, pull it in! */ ++ if (tcp_sk(meta_sk)->packets_out && ++ icsk->icsk_timeout > inet_csk(meta_sk)->icsk_rto + jiffies) { ++ tcp_rearm_rto(meta_sk); ++ } ++ ++ mptcp_push_pending_frames(mptcp_meta_sk(sk)); ++ } ++ } + break; + + case TCP_FIN_WAIT1: { +@@ -6286,7 +6471,8 @@ + tmo = tcp_fin_time(sk); + if (tmo > TCP_TIMEWAIT_LEN) { + inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); +- } else if (th->fin || sock_owned_by_user(sk)) { ++ } else if (th->fin || mptcp_is_data_fin(skb) || ++ sock_owned_by_user(sk)) { + /* Bad case. We could lose such FIN otherwise. + * It is not a big problem, but it looks confusing + * and not so rare event. We still can lose it now, +@@ -6295,7 +6481,7 @@ + */ + inet_csk_reset_keepalive_timer(sk, tmo); + } else { +- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); ++ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); + goto discard; + } + break; +@@ -6303,7 +6489,7 @@ + + case TCP_CLOSING: + if (tp->snd_una == tp->write_seq) { +- tcp_time_wait(sk, TCP_TIME_WAIT, 0); ++ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); + goto discard; + } + break; +@@ -6315,6 +6501,9 @@ + goto discard; + } + break; ++ case TCP_CLOSE: ++ if (tp->mp_killed) ++ goto discard; + } + + /* step 6: check the URG bit */ +@@ -6336,7 +6525,8 @@ + */ + if (sk->sk_shutdown & RCV_SHUTDOWN) { + if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && +- after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { ++ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && ++ !mptcp(tp)) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); + tcp_reset(sk); + return 1; +@@ -6438,6 +6628,8 @@ + ireq->wscale_ok = rx_opt->wscale_ok; + ireq->acked = 0; + ireq->ecn_ok = 0; ++ ireq->mptcp_rqsk = 0; ++ ireq->saw_mpc = 0; + ireq->ir_rmt_port = tcp_hdr(skb)->source; + ireq->ir_num = ntohs(tcp_hdr(skb)->dest); + ireq->ir_mark = inet_request_mark(sk, skb); +@@ -6563,12 +6755,17 @@ + /* TW buckets are converted to open requests without + * limitations, they conserve resources and peer is + * evidently real one. ++ * ++ * MPTCP: new subflows cannot be established in a stateless manner. + */ +- if ((net->ipv4.sysctl_tcp_syncookies == 2 || ++ if (((!is_meta_sk(sk) && net->ipv4.sysctl_tcp_syncookies == 2) || + inet_csk_reqsk_queue_is_full(sk)) && !isn) { + want_cookie = tcp_syn_flood_action(sk, rsk_ops->slab_name); + if (!want_cookie) + goto drop; ++ ++ if (is_meta_sk(sk)) ++ goto drop; + } + + if (sk_acceptq_is_full(sk)) { +@@ -6586,8 +6783,8 @@ + tcp_clear_options(&tmp_opt); + tmp_opt.mss_clamp = af_ops->mss_clamp; + tmp_opt.user_mss = tp->rx_opt.user_mss; +- tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, +- want_cookie ? NULL : &foc); ++ tcp_parse_options(sock_net(sk), skb, &tmp_opt, NULL, 0, ++ want_cookie ? NULL : &foc, NULL); + + if (want_cookie && !tmp_opt.saw_tstamp) + tcp_clear_options(&tmp_opt); +@@ -6602,7 +6799,8 @@ + /* Note: tcp_v6_init_req() might override ir_iif for link locals */ + inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb); + +- af_ops->init_req(req, sk, skb); ++ if (af_ops->init_req(req, sk, skb, want_cookie)) ++ goto drop_and_free; + + if (security_inet_conn_request(sk, skb, req)) + goto drop_and_free; +@@ -6638,7 +6836,7 @@ + tcp_ecn_create_request(req, skb, sk, dst); + + if (want_cookie) { +- isn = cookie_init_sequence(af_ops, sk, skb, &req->mss); ++ isn = cookie_init_sequence(af_ops, req, sk, skb, &req->mss); + req->cookie_ts = tmp_opt.tstamp_ok; + if (!tmp_opt.tstamp_ok) + inet_rsk(req)->ecn_ok = 0; +@@ -6653,17 +6851,25 @@ + fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst); + } + if (fastopen_sk) { ++ struct sock *meta_sk = fastopen_sk; ++ ++ if (mptcp(tcp_sk(fastopen_sk))) ++ meta_sk = mptcp_meta_sk(fastopen_sk); + af_ops->send_synack(fastopen_sk, dst, &fl, req, + &foc, TCP_SYNACK_FASTOPEN); + /* Add the child socket directly into the accept queue */ +- if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) { ++ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { + reqsk_fastopen_remove(fastopen_sk, req, false); + bh_unlock_sock(fastopen_sk); ++ if (meta_sk != fastopen_sk) ++ bh_unlock_sock(meta_sk); + sock_put(fastopen_sk); + goto drop_and_free; + } + sk->sk_data_ready(sk); + bh_unlock_sock(fastopen_sk); ++ if (meta_sk != fastopen_sk) ++ bh_unlock_sock(meta_sk); + sock_put(fastopen_sk); + } else { + tcp_rsk(req)->tfo_listener = false; +diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c +--- linux-5.4/net/ipv4/tcp_ipv4.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-02-20 18:07:47.000000000 +0100 +@@ -62,6 +62,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -430,7 +432,7 @@ + struct inet_sock *inet; + const int type = icmp_hdr(icmp_skb)->type; + const int code = icmp_hdr(icmp_skb)->code; +- struct sock *sk; ++ struct sock *sk, *meta_sk; + struct sk_buff *skb; + struct request_sock *fastopen; + u32 seq, snd_una; +@@ -460,13 +462,19 @@ + return 0; + } + +- bh_lock_sock(sk); ++ tp = tcp_sk(sk); ++ if (mptcp(tp)) ++ meta_sk = mptcp_meta_sk(sk); ++ else ++ meta_sk = sk; ++ ++ bh_lock_sock(meta_sk); + /* If too many ICMPs get dropped on busy + * servers this needs to be solved differently. + * We do take care of PMTU discovery (RFC1191) special case : + * we can receive locally generated ICMP messages while socket is held. + */ +- if (sock_owned_by_user(sk)) { ++ if (sock_owned_by_user(meta_sk)) { + if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) + __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); + } +@@ -479,7 +487,6 @@ + } + + icsk = inet_csk(sk); +- tp = tcp_sk(sk); + /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ + fastopen = rcu_dereference(tp->fastopen_rsk); + snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; +@@ -513,11 +520,13 @@ + goto out; + + tp->mtu_info = info; +- if (!sock_owned_by_user(sk)) { ++ if (!sock_owned_by_user(meta_sk)) { + tcp_v4_mtu_reduced(sk); + } else { + if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &sk->sk_tsq_flags)) + sock_hold(sk); ++ if (mptcp(tp)) ++ mptcp_tsq_flags(sk); + } + goto out; + } +@@ -531,7 +540,7 @@ + !icsk->icsk_backoff || fastopen) + break; + +- if (sock_owned_by_user(sk)) ++ if (sock_owned_by_user(meta_sk)) + break; + + skb = tcp_rtx_queue_head(sk); +@@ -555,7 +564,7 @@ + } else { + /* RTO revert clocked out retransmission. + * Will retransmit now */ +- tcp_retransmit_timer(sk); ++ tcp_sk(sk)->ops->retransmit_timer(sk); + } + + break; +@@ -575,7 +584,7 @@ + if (fastopen && !fastopen->sk) + break; + +- if (!sock_owned_by_user(sk)) { ++ if (!sock_owned_by_user(meta_sk)) { + sk->sk_err = err; + + sk->sk_error_report(sk); +@@ -604,7 +613,7 @@ + */ + + inet = inet_sk(sk); +- if (!sock_owned_by_user(sk) && inet->recverr) { ++ if (!sock_owned_by_user(meta_sk) && inet->recverr) { + sk->sk_err = err; + sk->sk_error_report(sk); + } else { /* Only an error on timeout */ +@@ -612,7 +621,7 @@ + } + + out: +- bh_unlock_sock(sk); ++ bh_unlock_sock(meta_sk); + sock_put(sk); + return 0; + } +@@ -648,7 +657,7 @@ + * Exception: precedence violation. We do not implement it in any case. + */ + +-static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) ++void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) + { + const struct tcphdr *th = tcp_hdr(skb); + struct { +@@ -800,10 +809,10 @@ + */ + + static void tcp_v4_send_ack(const struct sock *sk, +- struct sk_buff *skb, u32 seq, u32 ack, ++ struct sk_buff *skb, u32 seq, u32 ack, u32 data_ack, + u32 win, u32 tsval, u32 tsecr, int oif, + struct tcp_md5sig_key *key, +- int reply_flags, u8 tos) ++ int reply_flags, u8 tos, int mptcp) + { + const struct tcphdr *th = tcp_hdr(skb); + struct { +@@ -812,6 +821,10 @@ + #ifdef CONFIG_TCP_MD5SIG + + (TCPOLEN_MD5SIG_ALIGNED >> 2) + #endif ++#ifdef CONFIG_MPTCP ++ + ((MPTCP_SUB_LEN_DSS >> 2) + ++ (MPTCP_SUB_LEN_ACK >> 2)) ++#endif + ]; + } rep; + struct net *net = sock_net(sk); +@@ -858,6 +871,21 @@ + ip_hdr(skb)->daddr, &rep.th); + } + #endif ++#ifdef CONFIG_MPTCP ++ if (mptcp) { ++ int offset = (tsecr) ? 3 : 0; ++ /* Construction of 32-bit data_ack */ ++ rep.opt[offset++] = htonl((TCPOPT_MPTCP << 24) | ++ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | ++ (0x20 << 8) | ++ (0x01)); ++ rep.opt[offset] = htonl(data_ack); ++ ++ arg.iov[0].iov_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; ++ rep.th.doff = arg.iov[0].iov_len / 4; ++ } ++#endif /* CONFIG_MPTCP */ ++ + arg.flags = reply_flags; + arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, + ip_hdr(skb)->saddr, /* XXX */ +@@ -889,28 +917,36 @@ + { + struct inet_timewait_sock *tw = inet_twsk(sk); + struct tcp_timewait_sock *tcptw = tcp_twsk(sk); ++ u32 data_ack = 0; ++ int mptcp = 0; ++ ++ if (tcptw->mptcp_tw) { ++ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; ++ mptcp = 1; ++ } + + tcp_v4_send_ack(sk, skb, +- tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, ++ tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, data_ack, + tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, + tcp_time_stamp_raw() + tcptw->tw_ts_offset, + tcptw->tw_ts_recent, + tw->tw_bound_dev_if, + tcp_twsk_md5_key(tcptw), + tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0, +- tw->tw_tos ++ tw->tw_tos, mptcp + ); + + inet_twsk_put(tw); + } + +-static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, +- struct request_sock *req) ++void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, ++ struct request_sock *req) + { + /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV + * sk->sk_state == TCP_SYN_RECV -> for Fast Open. + */ +- u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : ++ u32 seq = (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? ++ tcp_rsk(req)->snt_isn + 1 : + tcp_sk(sk)->snd_nxt; + + /* RFC 7323 2.3 +@@ -919,7 +955,7 @@ + * Rcv.Wind.Shift bits: + */ + tcp_v4_send_ack(sk, skb, seq, +- tcp_rsk(req)->rcv_nxt, ++ tcp_rsk(req)->rcv_nxt, 0, + req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, + tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, + req->ts_recent, +@@ -927,7 +963,7 @@ + tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr, + AF_INET), + inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, +- ip_hdr(skb)->tos); ++ ip_hdr(skb)->tos, 0); + } + + /* +@@ -935,11 +971,11 @@ + * This still operates on a request_sock only, not on a big + * socket. + */ +-static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, +- struct flowi *fl, +- struct request_sock *req, +- struct tcp_fastopen_cookie *foc, +- enum tcp_synack_type synack_type) ++int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, ++ struct flowi *fl, ++ struct request_sock *req, ++ struct tcp_fastopen_cookie *foc, ++ enum tcp_synack_type synack_type) + { + const struct inet_request_sock *ireq = inet_rsk(req); + struct flowi4 fl4; +@@ -969,7 +1005,7 @@ + /* + * IPv4 request_sock destructor. + */ +-static void tcp_v4_reqsk_destructor(struct request_sock *req) ++void tcp_v4_reqsk_destructor(struct request_sock *req) + { + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); + } +@@ -1345,9 +1381,10 @@ + return false; + } + +-static void tcp_v4_init_req(struct request_sock *req, +- const struct sock *sk_listener, +- struct sk_buff *skb) ++static int tcp_v4_init_req(struct request_sock *req, ++ const struct sock *sk_listener, ++ struct sk_buff *skb, ++ bool want_cookie) + { + struct inet_request_sock *ireq = inet_rsk(req); + struct net *net = sock_net(sk_listener); +@@ -1355,6 +1392,8 @@ + sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); + sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); ++ ++ return 0; + } + + static struct dst_entry *tcp_v4_route_req(const struct sock *sk, +@@ -1374,7 +1413,7 @@ + .syn_ack_timeout = tcp_syn_ack_timeout, + }; + +-static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { ++const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { + .mss_clamp = TCP_MSS_DEFAULT, + #ifdef CONFIG_TCP_MD5SIG + .req_md5_lookup = tcp_v4_md5_lookup, +@@ -1511,7 +1550,7 @@ + } + EXPORT_SYMBOL(tcp_v4_syn_recv_sock); + +-static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) ++struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) + { + #ifdef CONFIG_SYN_COOKIES + const struct tcphdr *th = tcp_hdr(skb); +@@ -1549,6 +1588,9 @@ + { + struct sock *rsk; + ++ if (is_meta_sk(sk)) ++ return mptcp_v4_do_rcv(sk, skb); ++ + if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ + struct dst_entry *dst = sk->sk_rx_dst; + +@@ -1793,6 +1835,10 @@ + TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + + skb->len - th->doff * 4); + TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); ++#ifdef CONFIG_MPTCP ++ TCP_SKB_CB(skb)->mptcp_flags = 0; ++ TCP_SKB_CB(skb)->dss_off = 0; ++#endif + TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); + TCP_SKB_CB(skb)->tcp_tw_isn = 0; + TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); +@@ -1812,8 +1858,8 @@ + int sdif = inet_sdif(skb); + const struct iphdr *iph; + const struct tcphdr *th; ++ struct sock *sk, *meta_sk = NULL; + bool refcounted; +- struct sock *sk; + int ret; + + if (skb->pkt_type != PACKET_HOST) +@@ -1867,7 +1913,11 @@ + reqsk_put(req); + goto csum_error; + } +- if (unlikely(sk->sk_state != TCP_LISTEN)) { ++ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { ++ inet_csk_reqsk_queue_drop_and_put(sk, req); ++ goto lookup; ++ } ++ if (unlikely(is_meta_sk(sk) && !mptcp_can_new_subflow(sk))) { + inet_csk_reqsk_queue_drop_and_put(sk, req); + goto lookup; + } +@@ -1876,6 +1926,7 @@ + */ + sock_hold(sk); + refcounted = true; ++ + nsk = NULL; + if (!tcp_filter(sk, skb)) { + th = (const struct tcphdr *)skb->data; +@@ -1936,19 +1987,28 @@ + + sk_incoming_cpu_update(sk); + +- bh_lock_sock_nested(sk); ++ if (mptcp(tcp_sk(sk))) { ++ meta_sk = mptcp_meta_sk(sk); ++ ++ bh_lock_sock_nested(meta_sk); ++ if (sock_owned_by_user(meta_sk)) ++ mptcp_prepare_for_backlog(sk, skb); ++ } else { ++ meta_sk = sk; ++ bh_lock_sock_nested(sk); ++ } + tcp_segs_in(tcp_sk(sk), skb); + ret = 0; +- if (!sock_owned_by_user(sk)) { ++ if (!sock_owned_by_user(meta_sk)) { + skb_to_free = sk->sk_rx_skb_cache; + sk->sk_rx_skb_cache = NULL; + ret = tcp_v4_do_rcv(sk, skb); + } else { +- if (tcp_add_backlog(sk, skb)) ++ if (tcp_add_backlog(meta_sk, skb)) + goto discard_and_relse; + skb_to_free = NULL; + } +- bh_unlock_sock(sk); ++ bh_unlock_sock(meta_sk); + if (skb_to_free) + __kfree_skb(skb_to_free); + +@@ -1964,6 +2024,19 @@ + + tcp_v4_fill_cb(skb, iph, th); + ++#ifdef CONFIG_MPTCP ++ if (!sk && th->syn && !th->ack) { ++ int ret = mptcp_lookup_join(skb, NULL); ++ ++ if (ret < 0) { ++ tcp_v4_send_reset(NULL, skb); ++ goto discard_it; ++ } else if (ret > 0) { ++ return 0; ++ } ++ } ++#endif ++ + if (tcp_checksum_complete(skb)) { + csum_error: + __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); +@@ -2012,6 +2085,18 @@ + refcounted = false; + goto process; + } ++#ifdef CONFIG_MPTCP ++ if (th->syn && !th->ack) { ++ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); ++ ++ if (ret < 0) { ++ tcp_v4_send_reset(NULL, skb); ++ goto discard_it; ++ } else if (ret > 0) { ++ return 0; ++ } ++ } ++#endif + } + /* to ACK */ + /* fall through */ +@@ -2081,7 +2166,12 @@ + + tcp_init_sock(sk); + +- icsk->icsk_af_ops = &ipv4_specific; ++#ifdef CONFIG_MPTCP ++ if (sock_flag(sk, SOCK_MPTCP)) ++ icsk->icsk_af_ops = &mptcp_v4_specific; ++ else ++#endif ++ icsk->icsk_af_ops = &ipv4_specific; + + #ifdef CONFIG_TCP_MD5SIG + tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific; +@@ -2100,6 +2190,11 @@ + + tcp_cleanup_congestion_control(sk); + ++ if (mptcp(tp)) ++ mptcp_destroy_sock(sk); ++ if (tp->inside_tk_table) ++ mptcp_hash_remove_bh(tp); ++ + tcp_cleanup_ulp(sk); + + /* Cleanup up the write buffer. */ +@@ -2603,6 +2698,11 @@ + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), + .max_header = MAX_TCP_HEADER, + .obj_size = sizeof(struct tcp_sock), ++#ifdef CONFIG_MPTCP ++ .useroffset = offsetof(struct tcp_sock, mptcp_sched_name), ++ .usersize = sizeof_field(struct tcp_sock, mptcp_sched_name) + ++ sizeof_field(struct tcp_sock, mptcp_pm_name), ++#endif + .slab_flags = SLAB_TYPESAFE_BY_RCU, + .twsk_prot = &tcp_timewait_sock_ops, + .rsk_prot = &tcp_request_sock_ops, +@@ -2613,6 +2713,9 @@ + .compat_getsockopt = compat_tcp_getsockopt, + #endif + .diag_destroy = tcp_abort, ++#ifdef CONFIG_MPTCP ++ .clear_sk = mptcp_clear_sk, ++#endif + }; + EXPORT_SYMBOL(tcp_prot); + +diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c +--- linux-5.4/net/ipv4/tcp_minisocks.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-02-20 18:07:47.000000000 +0100 +@@ -19,11 +19,13 @@ + * Jorge Cwik, + */ + ++#include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -95,10 +97,14 @@ + struct tcp_options_received tmp_opt; + struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); + bool paws_reject = false; ++ struct mptcp_options_received mopt; + + tmp_opt.saw_tstamp = 0; +- if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { +- tcp_parse_options(twsk_net(tw), skb, &tmp_opt, 0, NULL); ++ if (th->doff > (sizeof(*th) >> 2) && ++ (tcptw->tw_ts_recent_stamp || tcptw->mptcp_tw)) { ++ mptcp_init_mp_opt(&mopt); ++ ++ tcp_parse_options(twsk_net(tw), skb, &tmp_opt, &mopt, 0, NULL, NULL); + + if (tmp_opt.saw_tstamp) { + if (tmp_opt.rcv_tsecr) +@@ -107,6 +113,11 @@ + tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; + paws_reject = tcp_paws_reject(&tmp_opt, th->rst); + } ++ ++ if (unlikely(mopt.mp_fclose) && tcptw->mptcp_tw) { ++ if (mopt.mptcp_sender_key == tcptw->mptcp_tw->loc_key) ++ return TCP_TW_RST; ++ } + } + + if (tw->tw_substate == TCP_FIN_WAIT2) { +@@ -130,6 +141,16 @@ + if (!th->ack || + !after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || + TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { ++ /* If mptcp_is_data_fin() returns true, we are sure that ++ * mopt has been initialized - otherwise it would not ++ * be a DATA_FIN. ++ */ ++ if (tcptw->mptcp_tw && tcptw->mptcp_tw->meta_tw && ++ mptcp_is_data_fin(skb) && ++ TCP_SKB_CB(skb)->seq == tcptw->tw_rcv_nxt && ++ mopt.data_seq + 1 == (u32)tcptw->mptcp_tw->rcv_nxt) ++ return TCP_TW_ACK; ++ + inet_twsk_put(tw); + return TCP_TW_SUCCESS; + } +@@ -275,6 +296,16 @@ + tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp; + tcptw->tw_ts_offset = tp->tsoffset; + tcptw->tw_last_oow_ack_time = 0; ++ ++ if (mptcp(tp)) { ++ if (mptcp_init_tw_sock(sk, tcptw)) { ++ inet_twsk_free(tw); ++ goto exit; ++ } ++ } else { ++ tcptw->mptcp_tw = NULL; ++ } ++ + tcptw->tw_tx_delay = tp->tcp_tx_delay; + #if IS_ENABLED(CONFIG_IPV6) + if (tw->tw_family == PF_INET6) { +@@ -336,6 +367,7 @@ + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); + } + ++exit: + tcp_update_metrics(sk); + tcp_done(sk); + } +@@ -343,6 +375,10 @@ + + void tcp_twsk_destructor(struct sock *sk) + { ++ struct tcp_timewait_sock *twsk = tcp_twsk(sk); ++ ++ if (twsk->mptcp_tw) ++ mptcp_twsk_destructor(twsk); + #ifdef CONFIG_TCP_MD5SIG + if (static_branch_unlikely(&tcp_md5_needed)) { + struct tcp_timewait_sock *twsk = tcp_twsk(sk); +@@ -386,8 +422,9 @@ + full_space = rcv_wnd * mss; + + /* tcp_full_space because it is guaranteed to be the first packet */ +- tcp_select_initial_window(sk_listener, full_space, +- mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), ++ tp->ops->select_initial_window(sk_listener, full_space, ++ mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) - ++ (ireq->saw_mpc ? MPTCP_SUB_LEN_DSM_ALIGN : 0), + &req->rsk_rcv_wnd, + &req->rsk_window_clamp, + ireq->wscale_ok, +@@ -487,6 +524,8 @@ + WRITE_ONCE(newtp->snd_nxt, seq); + newtp->snd_up = seq; + ++ newtp->out_of_order_queue = RB_ROOT; ++ newsk->tcp_rtx_queue = RB_ROOT; + INIT_LIST_HEAD(&newtp->tsq_node); + INIT_LIST_HEAD(&newtp->tsorted_sent_queue); + +@@ -530,6 +569,8 @@ + newtp->rx_opt.ts_recent_stamp = 0; + newtp->tcp_header_len = sizeof(struct tcphdr); + } ++ if (ireq->saw_mpc) ++ newtp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; + if (req->num_timeout) { + newtp->undo_marker = treq->snt_isn; + newtp->retrans_stamp = div_u64(treq->snt_synack, +@@ -547,6 +588,7 @@ + tcp_ecn_openreq_child(newtp, req); + newtp->fastopen_req = NULL; + RCU_INIT_POINTER(newtp->fastopen_rsk, NULL); ++ newtp->inside_tk_table = 0; + + __TCP_INC_STATS(sock_net(sk), TCP_MIB_PASSIVEOPENS); + +@@ -570,6 +612,7 @@ + bool fastopen, bool *req_stolen) + { + struct tcp_options_received tmp_opt; ++ struct mptcp_options_received mopt; + struct sock *child; + const struct tcphdr *th = tcp_hdr(skb); + __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); +@@ -577,8 +620,11 @@ + bool own_req; + + tmp_opt.saw_tstamp = 0; ++ ++ mptcp_init_mp_opt(&mopt); ++ + if (th->doff > (sizeof(struct tcphdr)>>2)) { +- tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL); ++ tcp_parse_options(sock_net(sk), skb, &tmp_opt, &mopt, 0, NULL, NULL); + + if (tmp_opt.saw_tstamp) { + tmp_opt.ts_recent = req->ts_recent; +@@ -619,7 +665,14 @@ + * + * Reset timer after retransmitting SYNACK, similar to + * the idea of fast retransmit in recovery. ++ * ++ * Fall back to TCP if MP_CAPABLE is not set. + */ ++ ++ if (inet_rsk(req)->saw_mpc && !mopt.saw_mpc) ++ inet_rsk(req)->saw_mpc = false; ++ ++ + if (!tcp_oow_rate_limited(sock_net(sk), skb, + LINUX_MIB_TCPACKSKIPPEDSYNRECV, + &tcp_rsk(req)->last_oow_ack_time) && +@@ -767,17 +820,37 @@ + * ESTABLISHED STATE. If it will be dropped after + * socket is created, wait for troubles. + */ ++ if (is_meta_sk(sk)) ++ bh_lock_sock_nested(sk); + child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, + req, &own_req); + if (!child) + goto listen_overflow; + ++ if (own_req && !is_meta_sk(sk)) { ++ int ret = mptcp_check_req_master(sk, child, req, skb, 1, 0); ++ if (ret < 0) ++ goto listen_overflow; ++ ++ /* MPTCP-supported */ ++ if (!ret) ++ return tcp_sk(child)->mpcb->master_sk; ++ } else if (own_req) { ++ return mptcp_check_req_child(sk, child, req, skb, &mopt); ++ } ++ ++ if (is_meta_sk(sk)) ++ bh_unlock_sock(sk); ++ + sock_rps_save_rxhash(child, skb); + tcp_synack_rtt_meas(child, req); + *req_stolen = !own_req; + return inet_csk_complete_hashdance(sk, child, req, own_req); + + listen_overflow: ++ if (is_meta_sk(sk)) ++ bh_unlock_sock(sk); ++ + if (!sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow) { + inet_rsk(req)->acked = 1; + return NULL; +@@ -820,12 +893,13 @@ + { + int ret = 0; + int state = child->sk_state; ++ struct sock *meta_sk = mptcp(tcp_sk(child)) ? mptcp_meta_sk(child) : child; + + /* record NAPI ID of child */ + sk_mark_napi_id(child, skb); + + tcp_segs_in(tcp_sk(child), skb); +- if (!sock_owned_by_user(child)) { ++ if (!sock_owned_by_user(meta_sk)) { + ret = tcp_rcv_state_process(child, skb); + /* Wakeup parent, send SIGIO */ + if (state == TCP_SYN_RECV && child->sk_state != state) +@@ -835,10 +909,14 @@ + * in main socket hash table and lock on listening + * socket does not protect us more. + */ +- __sk_add_backlog(child, skb); ++ if (mptcp(tcp_sk(child))) ++ mptcp_prepare_for_backlog(child, skb); ++ __sk_add_backlog(meta_sk, skb); + } + + bh_unlock_sock(child); ++ if (mptcp(tcp_sk(child))) ++ bh_unlock_sock(meta_sk); + sock_put(child); + return ret; + } +diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output.c +--- linux-5.4/net/ipv4/tcp_output.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-02-20 18:07:47.000000000 +0100 +@@ -37,6 +37,12 @@ + + #define pr_fmt(fmt) "TCP: " fmt + ++#include ++#include ++#if IS_ENABLED(CONFIG_IPV6) ++#include ++#endif ++#include + #include + + #include +@@ -57,11 +63,8 @@ + tp->tcp_mstamp = div_u64(val, NSEC_PER_USEC); + } + +-static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, +- int push_one, gfp_t gfp); +- + /* Account for new data that has been sent to the network. */ +-static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) ++void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) + { + struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); +@@ -252,12 +255,16 @@ + * value can be stuffed directly into th->window for an outgoing + * frame. + */ +-static u16 tcp_select_window(struct sock *sk) ++u16 tcp_select_window(struct sock *sk) + { + struct tcp_sock *tp = tcp_sk(sk); + u32 old_win = tp->rcv_wnd; +- u32 cur_win = tcp_receive_window(tp); +- u32 new_win = __tcp_select_window(sk); ++ /* The window must never shrink at the meta-level. At the subflow we ++ * have to allow this. Otherwise we may announce a window too large ++ * for the current meta-level sk_rcvbuf. ++ */ ++ u32 cur_win = tcp_receive_window(mptcp(tp) ? tcp_sk(mptcp_meta_sk(sk)) : tp); ++ u32 new_win = tp->ops->__select_window(sk); + + /* Never shrink the offered window */ + if (new_win < cur_win) { +@@ -273,6 +280,7 @@ + LINUX_MIB_TCPWANTZEROWINDOWADV); + new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); + } ++ + tp->rcv_wnd = new_win; + tp->rcv_wup = tp->rcv_nxt; + +@@ -385,7 +393,7 @@ + /* Constructs common control bits of non-data skb. If SYN/FIN is present, + * auto increment end seqno. + */ +-static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) ++void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) + { + skb->ip_summed = CHECKSUM_PARTIAL; + +@@ -400,7 +408,7 @@ + TCP_SKB_CB(skb)->end_seq = seq; + } + +-static inline bool tcp_urg_mode(const struct tcp_sock *tp) ++bool tcp_urg_mode(const struct tcp_sock *tp) + { + return tp->snd_una != tp->snd_up; + } +@@ -411,6 +419,7 @@ + #define OPTION_WSCALE (1 << 3) + #define OPTION_FAST_OPEN_COOKIE (1 << 8) + #define OPTION_SMC (1 << 9) ++/* Before adding here - take a look at OPTION_MPTCP in include/net/mptcp.h */ + + static void smc_options_write(__be32 *ptr, u16 *options) + { +@@ -427,17 +436,6 @@ + #endif + } + +-struct tcp_out_options { +- u16 options; /* bit field of OPTION_* */ +- u16 mss; /* 0 to disable */ +- u8 ws; /* window scale, 0 to disable */ +- u8 num_sack_blocks; /* number of SACK blocks to include */ +- u8 hash_size; /* bytes in hash_location */ +- __u8 *hash_location; /* temporary pointer, overloaded */ +- __u32 tsval, tsecr; /* need to include OPTION_TS */ +- struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ +-}; +- + /* Write previously computed TCP options to the packet. + * + * Beware: Something in the Internet is very sensitive to the ordering of +@@ -452,7 +450,7 @@ + * (but it may well be that other scenarios fail similarly). + */ + static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, +- struct tcp_out_options *opts) ++ struct tcp_out_options *opts, struct sk_buff *skb) + { + u16 options = opts->options; /* mungable copy */ + +@@ -546,6 +544,9 @@ + } + + smc_options_write(ptr, &options); ++ ++ if (unlikely(OPTION_MPTCP & opts->options)) ++ mptcp_options_write(ptr, tp, opts, skb); + } + + static void smc_set_option(const struct tcp_sock *tp, +@@ -632,6 +633,8 @@ + if (unlikely(!(OPTION_TS & opts->options))) + remaining -= TCPOLEN_SACKPERM_ALIGNED; + } ++ if (tp->request_mptcp || mptcp(tp)) ++ mptcp_syn_options(sk, opts, &remaining); + + if (fastopen && fastopen->cookie.len >= 0) { + u32 need = fastopen->cookie.len; +@@ -713,6 +716,9 @@ + + smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining); + ++ if (ireq->saw_mpc) ++ mptcp_synack_options(req, opts, &remaining); ++ + return MAX_TCP_OPTION_SPACE - remaining; + } + +@@ -747,17 +753,22 @@ + opts->tsecr = tp->rx_opt.ts_recent; + size += TCPOLEN_TSTAMP_ALIGNED; + } ++ if (mptcp(tp)) ++ mptcp_established_options(sk, skb, opts, &size); + + eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; + if (unlikely(eff_sacks)) { +- const unsigned int remaining = MAX_TCP_OPTION_SPACE - size; +- opts->num_sack_blocks = +- min_t(unsigned int, eff_sacks, +- (remaining - TCPOLEN_SACK_BASE_ALIGNED) / +- TCPOLEN_SACK_PERBLOCK); +- if (likely(opts->num_sack_blocks)) +- size += TCPOLEN_SACK_BASE_ALIGNED + +- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; ++ const unsigned remaining = MAX_TCP_OPTION_SPACE - size; ++ if (remaining < TCPOLEN_SACK_BASE_ALIGNED) ++ opts->num_sack_blocks = 0; ++ else ++ opts->num_sack_blocks = ++ min_t(unsigned int, eff_sacks, ++ (remaining - TCPOLEN_SACK_BASE_ALIGNED) / ++ TCPOLEN_SACK_PERBLOCK); ++ if (likely(opts->num_sack_blocks)) ++ size += TCPOLEN_SACK_BASE_ALIGNED + ++ opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; + } + + return size; +@@ -796,19 +808,31 @@ + tcp_xmit_retransmit_queue(sk); + } + +- tcp_write_xmit(sk, tcp_current_mss(sk), tp->nonagle, +- 0, GFP_ATOMIC); ++ tcp_sk(sk)->ops->write_xmit(sk, tcp_current_mss(sk), ++ tcp_sk(sk)->nonagle, 0, GFP_ATOMIC); + } + } + + static void tcp_tsq_handler(struct sock *sk) + { +- bh_lock_sock(sk); +- if (!sock_owned_by_user(sk)) ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; ++ ++ bh_lock_sock(meta_sk); ++ if (!sock_owned_by_user(meta_sk)) { + tcp_tsq_write(sk); +- else if (!test_and_set_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags)) +- sock_hold(sk); +- bh_unlock_sock(sk); ++ ++ if (mptcp(tp)) ++ tcp_tsq_write(meta_sk); ++ } else { ++ if (!test_and_set_bit(TCP_TSQ_DEFERRED, &meta_sk->sk_tsq_flags)) ++ sock_hold(meta_sk); ++ ++ if ((mptcp(tp)) && (sk->sk_state != TCP_CLOSE)) ++ mptcp_tsq_flags(sk); ++ } ++ ++ bh_unlock_sock(meta_sk); + } + /* + * One tasklet per cpu tries to send more skbs. +@@ -845,7 +869,9 @@ + #define TCP_DEFERRED_ALL (TCPF_TSQ_DEFERRED | \ + TCPF_WRITE_TIMER_DEFERRED | \ + TCPF_DELACK_TIMER_DEFERRED | \ +- TCPF_MTU_REDUCED_DEFERRED) ++ TCPF_MTU_REDUCED_DEFERRED | \ ++ TCPF_PATH_MANAGER_DEFERRED |\ ++ TCPF_SUB_DEFERRED) + /** + * tcp_release_cb - tcp release_sock() callback + * @sk: socket +@@ -868,6 +894,9 @@ + if (flags & TCPF_TSQ_DEFERRED) { + tcp_tsq_write(sk); + __sock_put(sk); ++ ++ if (mptcp(tcp_sk(sk))) ++ tcp_tsq_write(mptcp_meta_sk(sk)); + } + /* Here begins the tricky part : + * We are called from release_sock() with : +@@ -892,6 +921,13 @@ + inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); + __sock_put(sk); + } ++ if (flags & TCPF_PATH_MANAGER_DEFERRED) { ++ if (tcp_sk(sk)->mpcb->pm_ops->release_sock) ++ tcp_sk(sk)->mpcb->pm_ops->release_sock(sk); ++ __sock_put(sk); ++ } ++ if (flags & TCPF_SUB_DEFERRED) ++ mptcp_tsq_sub_deferred(sk); + } + EXPORT_SYMBOL(tcp_release_cb); + +@@ -975,8 +1011,8 @@ + return HRTIMER_NORESTART; + } + +-static void tcp_update_skb_after_send(struct sock *sk, struct sk_buff *skb, +- u64 prior_wstamp) ++void tcp_update_skb_after_send(struct sock *sk, struct sk_buff *skb, ++ u64 prior_wstamp) + { + struct tcp_sock *tp = tcp_sk(sk); + +@@ -1118,10 +1154,10 @@ + } + } + +- tcp_options_write((__be32 *)(th + 1), tp, &opts); ++ tcp_options_write((__be32 *)(th + 1), tp, &opts, skb); + skb_shinfo(skb)->gso_type = sk->sk_gso_type; + if (likely(!(tcb->tcp_flags & TCPHDR_SYN))) { +- th->window = htons(tcp_select_window(sk)); ++ th->window = htons(tp->ops->select_window(sk)); + tcp_ecn_send(sk, skb, th, tcp_header_size); + } else { + /* RFC1323: The window in SYN & SYN/ACK segments +@@ -1179,8 +1215,8 @@ + return err; + } + +-static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, +- gfp_t gfp_mask) ++int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, ++ gfp_t gfp_mask) + { + return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask, + tcp_sk(sk)->rcv_nxt); +@@ -1191,7 +1227,7 @@ + * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, + * otherwise socket can stall. + */ +-static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) ++void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) + { + struct tcp_sock *tp = tcp_sk(sk); + +@@ -1204,7 +1240,7 @@ + } + + /* Initialize TSO segments for a packet. */ +-static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) ++void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) + { + if (skb->len <= mss_now) { + /* Avoid the costly divide in the normal +@@ -1221,7 +1257,7 @@ + /* Pcount in the middle of the write queue got changed, we need to do various + * tweaks to fix counters + */ +-static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) ++void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) + { + struct tcp_sock *tp = tcp_sk(sk); + +@@ -1390,7 +1426,7 @@ + /* This is similar to __pskb_pull_tail(). The difference is that pulled + * data is not copied, but immediately discarded. + */ +-static int __pskb_trim_head(struct sk_buff *skb, int len) ++int __pskb_trim_head(struct sk_buff *skb, int len) + { + struct skb_shared_info *shinfo; + int i, k, eat; +@@ -1612,6 +1648,7 @@ + + return mss_now; + } ++EXPORT_SYMBOL(tcp_current_mss); + + /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. + * As additional protections, we do not touch cwnd in retransmission phases, +@@ -1635,7 +1672,7 @@ + tp->snd_cwnd_stamp = tcp_jiffies32; + } + +-static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) ++void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) + { + const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; + struct tcp_sock *tp = tcp_sk(sk); +@@ -1693,8 +1730,8 @@ + * But we can avoid doing the divide again given we already have + * skb_pcount = skb->len / mss_now + */ +-static void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, +- const struct sk_buff *skb) ++void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, ++ const struct sk_buff *skb) + { + if (skb->len < tcp_skb_pcount(skb) * mss_now) + tp->snd_sml = TCP_SKB_CB(skb)->end_seq; +@@ -1754,11 +1791,11 @@ + } + + /* Returns the portion of skb which can be sent right away */ +-static unsigned int tcp_mss_split_point(const struct sock *sk, +- const struct sk_buff *skb, +- unsigned int mss_now, +- unsigned int max_segs, +- int nonagle) ++unsigned int tcp_mss_split_point(const struct sock *sk, ++ const struct sk_buff *skb, ++ unsigned int mss_now, ++ unsigned int max_segs, ++ int nonagle) + { + const struct tcp_sock *tp = tcp_sk(sk); + u32 partial, needed, window, max_len; +@@ -1788,13 +1825,14 @@ + /* Can at least one segment of SKB be sent right now, according to the + * congestion window rules? If so, return how many segments are allowed. + */ +-static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, +- const struct sk_buff *skb) ++unsigned int tcp_cwnd_test(const struct tcp_sock *tp, ++ const struct sk_buff *skb) + { + u32 in_flight, cwnd, halfcwnd; + + /* Don't be strict about the congestion window for the final FIN. */ +- if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && ++ if (skb && ++ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && + tcp_skb_pcount(skb) == 1) + return 1; + +@@ -1809,12 +1847,13 @@ + halfcwnd = max(cwnd >> 1, 1U); + return min(halfcwnd, cwnd - in_flight); + } ++EXPORT_SYMBOL(tcp_cwnd_test); + + /* Initialize TSO state of a skb. + * This must be invoked the first time we consider transmitting + * SKB onto the wire. + */ +-static int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) ++int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) + { + int tso_segs = tcp_skb_pcount(skb); + +@@ -1829,8 +1868,8 @@ + /* Return true if the Nagle test allows this packet to be + * sent now. + */ +-static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, +- unsigned int cur_mss, int nonagle) ++bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, ++ unsigned int cur_mss, int nonagle) + { + /* Nagle rule does not apply to frames, which sit in the middle of the + * write_queue (they have no chances to get new data). +@@ -1842,7 +1881,8 @@ + return true; + + /* Don't use the nagle rule for urgent data (or for the final FIN). */ +- if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)) ++ if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || ++ mptcp_is_data_fin(skb)) + return true; + + if (!tcp_nagle_check(skb->len < cur_mss, tp, nonagle)) +@@ -1852,9 +1892,8 @@ + } + + /* Does at least the first segment of SKB fit into the send window? */ +-static bool tcp_snd_wnd_test(const struct tcp_sock *tp, +- const struct sk_buff *skb, +- unsigned int cur_mss) ++bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, ++ unsigned int cur_mss) + { + u32 end_seq = TCP_SKB_CB(skb)->end_seq; + +@@ -1863,6 +1902,7 @@ + + return !after(end_seq, tcp_wnd_end(tp)); + } ++EXPORT_SYMBOL(tcp_snd_wnd_test); + + /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet + * which is put after SKB on the list. It is very much like +@@ -2021,7 +2061,8 @@ + + /* If this packet won't get more data, do not wait. */ + if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || +- TCP_SKB_CB(skb)->eor) ++ TCP_SKB_CB(skb)->eor || ++ mptcp_is_data_fin(skb)) + goto send_now; + + return true; +@@ -2354,7 +2395,7 @@ + * Returns true, if no segments are in flight and we have queued segments, + * but cannot send anything now because of SWS or another problem. + */ +-static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, ++bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, + int push_one, gfp_t gfp) + { + struct tcp_sock *tp = tcp_sk(sk); +@@ -2368,7 +2409,12 @@ + sent_pkts = 0; + + tcp_mstamp_refresh(tp); +- if (!push_one) { ++ ++ /* pmtu not yet supported with MPTCP. Should be possible, by early ++ * exiting the loop inside tcp_mtu_probe, making sure that only one ++ * single DSS-mapping gets probed. ++ */ ++ if (!push_one && !mptcp(tp)) { + /* Do MTU probing. */ + result = tcp_mtu_probe(sk); + if (!result) { +@@ -2466,7 +2512,8 @@ + if (push_one != 2) + tcp_schedule_loss_probe(sk, false); + is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); +- tcp_cwnd_validate(sk, is_cwnd_limited); ++ if (tp->ops->cwnd_validate) ++ tp->ops->cwnd_validate(sk, is_cwnd_limited); + return false; + } + return !tp->packets_out && !tcp_write_queue_empty(sk); +@@ -2549,7 +2596,7 @@ + skb = tcp_send_head(sk); + if (skb && tcp_snd_wnd_test(tp, skb, mss)) { + pcount = tp->packets_out; +- tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); ++ tp->ops->write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); + if (tp->packets_out > pcount) + goto probe_sent; + goto rearm_timer; +@@ -2613,8 +2660,8 @@ + if (unlikely(sk->sk_state == TCP_CLOSE)) + return; + +- if (tcp_write_xmit(sk, cur_mss, nonagle, 0, +- sk_gfp_mask(sk, GFP_ATOMIC))) ++ if (tcp_sk(sk)->ops->write_xmit(sk, cur_mss, nonagle, 0, ++ sk_gfp_mask(sk, GFP_ATOMIC))) + tcp_check_probe_timer(sk); + } + +@@ -2627,7 +2674,8 @@ + + BUG_ON(!skb || skb->len < mss_now); + +- tcp_write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, sk->sk_allocation); ++ tcp_sk(sk)->ops->write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, ++ sk->sk_allocation); + } + + /* This function returns the amount that we can raise the +@@ -2849,6 +2897,10 @@ + if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) + return; + ++ /* Currently not supported for MPTCP - but it should be possible */ ++ if (mptcp(tp)) ++ return; ++ + skb_rbtree_walk_from_safe(skb, tmp) { + if (!tcp_can_collapse(sk, skb)) + break; +@@ -3325,7 +3377,7 @@ + + /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ + th->window = htons(min(req->rsk_rcv_wnd, 65535U)); +- tcp_options_write((__be32 *)(th + 1), NULL, &opts); ++ tcp_options_write((__be32 *)(th + 1), NULL, &opts, skb); + th->doff = (tcp_header_size >> 2); + __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); + +@@ -3407,13 +3459,13 @@ + if (rcv_wnd == 0) + rcv_wnd = dst_metric(dst, RTAX_INITRWND); + +- tcp_select_initial_window(sk, tcp_full_space(sk), +- tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), +- &tp->rcv_wnd, +- &tp->window_clamp, +- sock_net(sk)->ipv4.sysctl_tcp_window_scaling, +- &rcv_wscale, +- rcv_wnd); ++ tp->ops->select_initial_window(sk, tcp_full_space(sk), ++ tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), ++ &tp->rcv_wnd, ++ &tp->window_clamp, ++ sock_net(sk)->ipv4.sysctl_tcp_window_scaling, ++ &rcv_wscale, ++ rcv_wnd); + + tp->rx_opt.rcv_wscale = rcv_wscale; + tp->rcv_ssthresh = tp->rcv_wnd; +@@ -3438,6 +3490,36 @@ + inet_csk(sk)->icsk_rto = tcp_timeout_init(sk); + inet_csk(sk)->icsk_retransmits = 0; + tcp_clear_retrans(tp); ++ ++#ifdef CONFIG_MPTCP ++ if (sock_flag(sk, SOCK_MPTCP) && mptcp_doit(sk)) { ++ if (is_master_tp(tp)) { ++ tp->request_mptcp = 1; ++ mptcp_connect_init(sk); ++ } else if (tp->mptcp) { ++ struct inet_sock *inet = inet_sk(sk); ++ ++ tp->mptcp->snt_isn = tp->write_seq; ++ tp->mptcp->init_rcv_wnd = tp->rcv_wnd; ++ ++ /* Set nonce for new subflows */ ++ if (sk->sk_family == AF_INET) ++ tp->mptcp->mptcp_loc_nonce = mptcp_v4_get_nonce( ++ inet->inet_saddr, ++ inet->inet_daddr, ++ inet->inet_sport, ++ inet->inet_dport); ++#if IS_ENABLED(CONFIG_IPV6) ++ else ++ tp->mptcp->mptcp_loc_nonce = mptcp_v6_get_nonce( ++ inet6_sk(sk)->saddr.s6_addr32, ++ sk->sk_v6_daddr.s6_addr32, ++ inet->inet_sport, ++ inet->inet_dport); ++#endif ++ } ++ } ++#endif + } + + static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) +@@ -3701,6 +3783,7 @@ + { + __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt); + } ++EXPORT_SYMBOL_GPL(tcp_send_ack); + + /* This routine sends a packet with an out of date sequence + * number. It assumes the other end will try to ack it. +@@ -3713,7 +3796,7 @@ + * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is + * out-of-date with SND.UNA-1 to probe window. + */ +-static int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) ++int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) + { + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb; +@@ -3800,7 +3883,7 @@ + unsigned long timeout; + int err; + +- err = tcp_write_wakeup(sk, LINUX_MIB_TCPWINPROBE); ++ err = tp->ops->write_wakeup(sk, LINUX_MIB_TCPWINPROBE); + + if (tp->packets_out || tcp_write_queue_empty(sk)) { + /* Cancel probe timer, if it is not required. */ +diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c +--- linux-5.4/net/ipv4/tcp_timer.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-02-20 18:07:47.000000000 +0100 +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include + + static u32 tcp_clamp_rto_to_user_timeout(const struct sock *sk) +@@ -47,7 +48,7 @@ + * Returns: Nothing (void) + */ + +-static void tcp_write_err(struct sock *sk) ++void tcp_write_err(struct sock *sk) + { + sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; + sk->sk_error_report(sk); +@@ -103,7 +104,7 @@ + (!tp->snd_wnd && !tp->packets_out)) + do_reset = true; + if (do_reset) +- tcp_send_active_reset(sk, GFP_ATOMIC); ++ tp->ops->send_active_reset(sk, GFP_ATOMIC); + tcp_done(sk); + __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); + return 1; +@@ -188,9 +189,9 @@ + * after "boundary" unsuccessful, exponentially backed-off + * retransmissions with an initial RTO of TCP_RTO_MIN. + */ +-static bool retransmits_timed_out(struct sock *sk, +- unsigned int boundary, +- unsigned int timeout) ++bool retransmits_timed_out(struct sock *sk, ++ unsigned int boundary, ++ unsigned int timeout) + { + unsigned int start_ts; + +@@ -210,7 +211,7 @@ + } + + /* A write timeout has occurred. Process the after effects. */ +-static int tcp_write_timeout(struct sock *sk) ++int tcp_write_timeout(struct sock *sk) + { + struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); +@@ -225,6 +226,17 @@ + sk_rethink_txhash(sk); + } + retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries; ++ ++#ifdef CONFIG_MPTCP ++ /* Stop retransmitting MP_CAPABLE options in SYN if timed out. */ ++ if (tcp_sk(sk)->request_mptcp && ++ icsk->icsk_retransmits >= sysctl_mptcp_syn_retries) { ++ tcp_sk(sk)->request_mptcp = 0; ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLERETRANSFALLBACK); ++ } ++#endif /* CONFIG_MPTCP */ ++ + expired = icsk->icsk_retransmits >= retry_until; + } else { + if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) { +@@ -320,18 +332,22 @@ + struct inet_connection_sock *icsk = + from_timer(icsk, t, icsk_delack_timer); + struct sock *sk = &icsk->icsk_inet.sk; ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; + +- bh_lock_sock(sk); +- if (!sock_owned_by_user(sk)) { ++ bh_lock_sock(meta_sk); ++ if (!sock_owned_by_user(meta_sk)) { + tcp_delack_timer_handler(sk); + } else { + icsk->icsk_ack.blocked = 1; +- __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); ++ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_DELAYEDACKLOCKED); + /* deleguate our work to tcp_release_cb() */ + if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &sk->sk_tsq_flags)) + sock_hold(sk); ++ if (mptcp(tp)) ++ mptcp_tsq_flags(sk); + } +- bh_unlock_sock(sk); ++ bh_unlock_sock(meta_sk); + sock_put(sk); + } + +@@ -375,7 +391,12 @@ + } + + if (icsk->icsk_probes_out >= max_probes) { +-abort: tcp_write_err(sk); ++abort: ++ tcp_write_err(sk); ++ if (is_meta_sk(sk) && ++ mptcp_in_infinite_mapping_weak(tp->mpcb)) { ++ mptcp_sub_force_close_all(tp->mpcb, NULL); ++ } + } else { + /* Only send another probe if we didn't close things up. */ + tcp_send_probe0(sk); +@@ -596,7 +617,7 @@ + break; + case ICSK_TIME_RETRANS: + icsk->icsk_pending = 0; +- tcp_retransmit_timer(sk); ++ tcp_sk(sk)->ops->retransmit_timer(sk); + break; + case ICSK_TIME_PROBE0: + icsk->icsk_pending = 0; +@@ -613,16 +634,19 @@ + struct inet_connection_sock *icsk = + from_timer(icsk, t, icsk_retransmit_timer); + struct sock *sk = &icsk->icsk_inet.sk; ++ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; + +- bh_lock_sock(sk); +- if (!sock_owned_by_user(sk)) { ++ bh_lock_sock(meta_sk); ++ if (!sock_owned_by_user(meta_sk)) { + tcp_write_timer_handler(sk); + } else { + /* delegate our work to tcp_release_cb() */ + if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &sk->sk_tsq_flags)) + sock_hold(sk); ++ if (mptcp(tcp_sk(sk))) ++ mptcp_tsq_flags(sk); + } +- bh_unlock_sock(sk); ++ bh_unlock_sock(meta_sk); + sock_put(sk); + } + +@@ -652,11 +676,12 @@ + struct sock *sk = from_timer(sk, t, sk_timer); + struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); ++ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; + u32 elapsed; + + /* Only process if socket is not in use. */ +- bh_lock_sock(sk); +- if (sock_owned_by_user(sk)) { ++ bh_lock_sock(meta_sk); ++ if (sock_owned_by_user(meta_sk)) { + /* Try again later. */ + inet_csk_reset_keepalive_timer (sk, HZ/20); + goto out; +@@ -668,16 +693,31 @@ + } + + tcp_mstamp_refresh(tp); ++ ++ if (tp->send_mp_fclose) { ++ if (icsk->icsk_retransmits >= MPTCP_FASTCLOSE_RETRIES) { ++ tcp_write_err(sk); ++ goto out; ++ } ++ ++ tcp_send_ack(sk); ++ icsk->icsk_retransmits++; ++ ++ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); ++ elapsed = icsk->icsk_rto; ++ goto resched; ++ } ++ + if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { + if (tp->linger2 >= 0) { + const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; + + if (tmo > 0) { +- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); ++ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); + goto out; + } + } +- tcp_send_active_reset(sk, GFP_ATOMIC); ++ tp->ops->send_active_reset(sk, GFP_ATOMIC); + goto death; + } + +@@ -702,11 +742,11 @@ + icsk->icsk_probes_out > 0) || + (icsk->icsk_user_timeout == 0 && + icsk->icsk_probes_out >= keepalive_probes(tp))) { +- tcp_send_active_reset(sk, GFP_ATOMIC); ++ tp->ops->send_active_reset(sk, GFP_ATOMIC); + tcp_write_err(sk); + goto out; + } +- if (tcp_write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { ++ if (tp->ops->write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { + icsk->icsk_probes_out++; + elapsed = keepalive_intvl_when(tp); + } else { +@@ -730,7 +770,7 @@ + tcp_done(sk); + + out: +- bh_unlock_sock(sk); ++ bh_unlock_sock(meta_sk); + sock_put(sk); + } + +diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c +--- linux-5.4/net/ipv6/addrconf.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-02-20 18:07:47.000000000 +0100 +@@ -967,6 +967,7 @@ + + kfree_rcu(ifp, rcu); + } ++EXPORT_SYMBOL(inet6_ifa_finish_destroy); + + static void + ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) +diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c +--- linux-5.4/net/ipv6/af_inet6.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-02-20 18:07:47.000000000 +0100 +@@ -104,8 +104,7 @@ + return (struct ipv6_pinfo *)(((u8 *)sk) + offset); + } + +-static int inet6_create(struct net *net, struct socket *sock, int protocol, +- int kern) ++int inet6_create(struct net *net, struct socket *sock, int protocol, int kern) + { + struct inet_sock *inet; + struct ipv6_pinfo *np; +diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c +--- linux-5.4/net/ipv6/ipv6_sockglue.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-02-20 18:07:47.000000000 +0100 +@@ -44,6 +44,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -214,7 +216,12 @@ + sock_prot_inuse_add(net, &tcp_prot, 1); + local_bh_enable(); + sk->sk_prot = &tcp_prot; +- icsk->icsk_af_ops = &ipv4_specific; ++#ifdef CONFIG_MPTCP ++ if (sock_flag(sk, SOCK_MPTCP)) ++ icsk->icsk_af_ops = &mptcp_v4_specific; ++ else ++#endif ++ icsk->icsk_af_ops = &ipv4_specific; + sk->sk_socket->ops = &inet_stream_ops; + sk->sk_family = PF_INET; + tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); +diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies.c +--- linux-5.4/net/ipv6/syncookies.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-02-20 18:07:47.000000000 +0100 +@@ -15,6 +15,8 @@ + #include + #include + #include ++#include ++#include + #include + + #define COOKIEBITS 24 /* Upper bits store count */ +@@ -106,7 +108,8 @@ + } + EXPORT_SYMBOL_GPL(__cookie_v6_init_sequence); + +-__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mssp) ++__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, __u16 *mssp) + { + const struct ipv6hdr *iph = ipv6_hdr(skb); + const struct tcphdr *th = tcp_hdr(skb); +@@ -128,6 +131,7 @@ + struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) + { + struct tcp_options_received tcp_opt; ++ struct mptcp_options_received mopt; + struct inet_request_sock *ireq; + struct tcp_request_sock *treq; + struct ipv6_pinfo *np = inet6_sk(sk); +@@ -157,7 +161,8 @@ + + /* check for timestamp cookie support */ + memset(&tcp_opt, 0, sizeof(tcp_opt)); +- tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL); ++ mptcp_init_mp_opt(&mopt); ++ tcp_parse_options(sock_net(sk), skb, &tcp_opt, &mopt, 0, NULL, NULL); + + if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { + tsoff = secure_tcpv6_ts_off(sock_net(sk), +@@ -170,14 +175,27 @@ + goto out; + + ret = NULL; +- req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); ++#ifdef CONFIG_MPTCP ++ if (mopt.saw_mpc) ++ req = inet_reqsk_alloc(&mptcp6_request_sock_ops, sk, false); ++ else ++#endif ++ req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); + if (!req) + goto out; + + ireq = inet_rsk(req); ++ ireq->mptcp_rqsk = 0; ++ ireq->saw_mpc = 0; + treq = tcp_rsk(req); + treq->tfo_listener = false; + ++ /* Must be done before anything else, as it initializes ++ * hash_entry of the MPTCP request-sock. ++ */ ++ if (mopt.saw_mpc) ++ mptcp_cookies_reqsk_init(req, &mopt, skb); ++ + if (security_inet_conn_request(sk, skb, req)) + goto out_free; + +@@ -241,10 +259,10 @@ + } + + req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); +- tcp_select_initial_window(sk, tcp_full_space(sk), req->mss, +- &req->rsk_rcv_wnd, &req->rsk_window_clamp, +- ireq->wscale_ok, &rcv_wscale, +- dst_metric(dst, RTAX_INITRWND)); ++ tp->ops->select_initial_window(sk, tcp_full_space(sk), req->mss, ++ &req->rsk_rcv_wnd, &req->rsk_window_clamp, ++ ireq->wscale_ok, &rcv_wscale, ++ dst_metric(dst, RTAX_INITRWND)); + + ireq->rcv_wscale = rcv_wscale; + ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); +diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c +--- linux-5.4/net/ipv6/tcp_ipv6.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-02-20 18:07:47.000000000 +0100 +@@ -58,6 +58,8 @@ + #include + #include + #include ++#include ++#include + #include + + #include +@@ -67,15 +69,6 @@ + #include + + #include +- +-static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); +-static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, +- struct request_sock *req); +- +-static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); +- +-static const struct inet_connection_sock_af_ops ipv6_mapped; +-static const struct inet_connection_sock_af_ops ipv6_specific; + #ifdef CONFIG_TCP_MD5SIG + static const struct tcp_sock_af_ops tcp_sock_ipv6_specific; + static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; +@@ -99,7 +92,7 @@ + return (struct ipv6_pinfo *)(((u8 *)sk) + offset); + } + +-static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) ++void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) + { + struct dst_entry *dst = skb_dst(skb); + +@@ -141,7 +134,7 @@ + return BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr); + } + +-static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, ++int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + int addr_len) + { + struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; +@@ -236,7 +229,12 @@ + sin.sin_port = usin->sin6_port; + sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; + +- icsk->icsk_af_ops = &ipv6_mapped; ++#ifdef CONFIG_MPTCP ++ if (sock_flag(sk, SOCK_MPTCP)) ++ icsk->icsk_af_ops = &mptcp_v6_mapped; ++ else ++#endif ++ icsk->icsk_af_ops = &ipv6_mapped; + sk->sk_backlog_rcv = tcp_v4_do_rcv; + #ifdef CONFIG_TCP_MD5SIG + tp->af_specific = &tcp_sock_ipv6_mapped_specific; +@@ -246,7 +244,12 @@ + + if (err) { + icsk->icsk_ext_hdr_len = exthdrlen; +- icsk->icsk_af_ops = &ipv6_specific; ++#ifdef CONFIG_MPTCP ++ if (sock_flag(sk, SOCK_MPTCP)) ++ icsk->icsk_af_ops = &mptcp_v6_specific; ++ else ++#endif ++ icsk->icsk_af_ops = &ipv6_specific; + sk->sk_backlog_rcv = tcp_v6_do_rcv; + #ifdef CONFIG_TCP_MD5SIG + tp->af_specific = &tcp_sock_ipv6_specific; +@@ -340,7 +343,7 @@ + return err; + } + +-static void tcp_v6_mtu_reduced(struct sock *sk) ++void tcp_v6_mtu_reduced(struct sock *sk) + { + struct dst_entry *dst; + +@@ -367,7 +370,7 @@ + struct ipv6_pinfo *np; + struct tcp_sock *tp; + __u32 seq, snd_una; +- struct sock *sk; ++ struct sock *sk, *meta_sk; + bool fatal; + int err; + +@@ -393,8 +396,14 @@ + return 0; + } + +- bh_lock_sock(sk); +- if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG) ++ tp = tcp_sk(sk); ++ if (mptcp(tp)) ++ meta_sk = mptcp_meta_sk(sk); ++ else ++ meta_sk = sk; ++ ++ bh_lock_sock(meta_sk); ++ if (sock_owned_by_user(meta_sk) && type != ICMPV6_PKT_TOOBIG) + __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); + + if (sk->sk_state == TCP_CLOSE) +@@ -405,7 +414,6 @@ + goto out; + } + +- tp = tcp_sk(sk); + /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ + fastopen = rcu_dereference(tp->fastopen_rsk); + snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; +@@ -439,11 +447,15 @@ + goto out; + + tp->mtu_info = ntohl(info); +- if (!sock_owned_by_user(sk)) ++ if (!sock_owned_by_user(meta_sk)) { + tcp_v6_mtu_reduced(sk); +- else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, +- &sk->sk_tsq_flags)) +- sock_hold(sk); ++ } else { ++ if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, ++ &sk->sk_tsq_flags)) ++ sock_hold(sk); ++ if (mptcp(tp)) ++ mptcp_tsq_flags(sk); ++ } + goto out; + } + +@@ -458,7 +470,7 @@ + if (fastopen && !fastopen->sk) + break; + +- if (!sock_owned_by_user(sk)) { ++ if (!sock_owned_by_user(meta_sk)) { + sk->sk_err = err; + sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ + +@@ -468,14 +480,14 @@ + goto out; + } + +- if (!sock_owned_by_user(sk) && np->recverr) { ++ if (!sock_owned_by_user(meta_sk) && np->recverr) { + sk->sk_err = err; + sk->sk_error_report(sk); + } else + sk->sk_err_soft = err; + + out: +- bh_unlock_sock(sk); ++ bh_unlock_sock(meta_sk); + sock_put(sk); + return 0; + } +@@ -523,8 +535,7 @@ + return err; + } + +- +-static void tcp_v6_reqsk_destructor(struct request_sock *req) ++void tcp_v6_reqsk_destructor(struct request_sock *req) + { + kfree(inet_rsk(req)->ipv6_opt); + kfree_skb(inet_rsk(req)->pktopts); +@@ -742,9 +753,10 @@ + return false; + } + +-static void tcp_v6_init_req(struct request_sock *req, +- const struct sock *sk_listener, +- struct sk_buff *skb) ++static int tcp_v6_init_req(struct request_sock *req, ++ const struct sock *sk_listener, ++ struct sk_buff *skb, ++ bool want_cookie) + { + bool l3_slave = ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags); + struct inet_request_sock *ireq = inet_rsk(req); +@@ -766,6 +778,8 @@ + refcount_inc(&skb->users); + ireq->pktopts = skb; + } ++ ++ return 0; + } + + static struct dst_entry *tcp_v6_route_req(const struct sock *sk, +@@ -785,7 +799,7 @@ + .syn_ack_timeout = tcp_syn_ack_timeout, + }; + +-static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { ++const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { + .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - + sizeof(struct ipv6hdr), + #ifdef CONFIG_TCP_MD5SIG +@@ -803,9 +817,9 @@ + }; + + static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq, +- u32 ack, u32 win, u32 tsval, u32 tsecr, ++ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, + int oif, struct tcp_md5sig_key *key, int rst, +- u8 tclass, __be32 label, u32 priority) ++ u8 tclass, __be32 label, u32 priority, int mptcp) + { + const struct tcphdr *th = tcp_hdr(skb); + struct tcphdr *t1; +@@ -824,7 +838,10 @@ + if (key) + tot_len += TCPOLEN_MD5SIG_ALIGNED; + #endif +- ++#ifdef CONFIG_MPTCP ++ if (mptcp) ++ tot_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; ++#endif + buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, + GFP_ATOMIC); + if (!buff) +@@ -862,6 +879,17 @@ + tcp_v6_md5_hash_hdr((__u8 *)topt, key, + &ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, t1); ++ topt += 4; ++ } ++#endif ++#ifdef CONFIG_MPTCP ++ if (mptcp) { ++ /* Construction of 32-bit data_ack */ ++ *topt++ = htonl((TCPOPT_MPTCP << 24) | ++ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | ++ (0x20 << 8) | ++ (0x01)); ++ *topt++ = htonl(data_ack); + } + #endif + +@@ -920,7 +948,7 @@ + kfree_skb(buff); + } + +-static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) ++void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) + { + const struct tcphdr *th = tcp_hdr(skb); + struct ipv6hdr *ipv6h = ipv6_hdr(skb); +@@ -1005,8 +1033,8 @@ + label = ip6_flowlabel(ipv6h); + } + +- tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, +- label, priority); ++ tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, 0, oif, key, 1, 0, ++ label, priority, 0); + + #ifdef CONFIG_TCP_MD5SIG + out: +@@ -1015,30 +1043,37 @@ + } + + static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, +- u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, ++ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, int oif, + struct tcp_md5sig_key *key, u8 tclass, +- __be32 label, u32 priority) ++ __be32 label, u32 priority, int mptcp) + { +- tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0, +- tclass, label, priority); ++ tcp_v6_send_response(sk, skb, seq, ack, data_ack, win, tsval, tsecr, oif, ++ key, 0, tclass, label, priority, mptcp); + } + + static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) + { + struct inet_timewait_sock *tw = inet_twsk(sk); + struct tcp_timewait_sock *tcptw = tcp_twsk(sk); ++ u32 data_ack = 0; ++ int mptcp = 0; + ++ if (tcptw->mptcp_tw) { ++ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; ++ mptcp = 1; ++ } + tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, ++ data_ack, + tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, + tcp_time_stamp_raw() + tcptw->tw_ts_offset, + tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), +- tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority); ++ tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority, mptcp); + + inet_twsk_put(tw); + } + +-static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, +- struct request_sock *req) ++void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, ++ struct request_sock *req) + { + /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV + * sk->sk_state == TCP_SYN_RECV -> for Fast Open. +@@ -1048,18 +1083,18 @@ + * exception of segments, MUST be right-shifted by + * Rcv.Wind.Shift bits: + */ +- tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? ++ tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? + tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, +- tcp_rsk(req)->rcv_nxt, ++ tcp_rsk(req)->rcv_nxt, 0, + req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, + tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, + req->ts_recent, sk->sk_bound_dev_if, + tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), +- 0, 0, sk->sk_priority); ++ 0, 0, sk->sk_priority, 0); + } + + +-static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) ++struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) + { + #ifdef CONFIG_SYN_COOKIES + const struct tcphdr *th = tcp_hdr(skb); +@@ -1085,7 +1120,7 @@ + return mss; + } + +-static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) ++int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + { + if (skb->protocol == htons(ETH_P_IP)) + return tcp_v4_conn_request(sk, skb); +@@ -1111,11 +1146,11 @@ + sizeof(struct inet6_skb_parm)); + } + +-static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, +- struct request_sock *req, +- struct dst_entry *dst, +- struct request_sock *req_unhash, +- bool *own_req) ++struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, ++ struct request_sock *req, ++ struct dst_entry *dst, ++ struct request_sock *req_unhash, ++ bool *own_req) + { + struct inet_request_sock *ireq; + struct ipv6_pinfo *newnp; +@@ -1150,7 +1185,15 @@ + + newnp->saddr = newsk->sk_v6_rcv_saddr; + +- inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; ++#ifdef CONFIG_MPTCP ++ /* We must check on the request-socket because the listener ++ * socket's flag may have been changed halfway through. ++ */ ++ if (!inet_rsk(req)->saw_mpc) ++ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_mapped; ++ else ++#endif ++ inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; + newsk->sk_backlog_rcv = tcp_v4_do_rcv; + #ifdef CONFIG_TCP_MD5SIG + newtp->af_specific = &tcp_sock_ipv6_mapped_specific; +@@ -1197,6 +1240,14 @@ + if (!newsk) + goto out_nonewsk; + ++#ifdef CONFIG_MPTCP ++ /* If the meta_sk is v6-mapped we can end up here with the wrong af_ops. ++ * Just make sure that this subflow is v6. ++ */ ++ if (is_meta_sk(sk)) ++ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_specific; ++#endif ++ + /* + * No need to charge this sock to the relevant IPv6 refcnt debug socks + * count here, tcp_create_openreq_child now does this for us, see the +@@ -1324,7 +1375,7 @@ + * This is because we cannot sleep with the original spinlock + * held. + */ +-static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) ++int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) + { + struct ipv6_pinfo *np = tcp_inet6_sk(sk); + struct sk_buff *opt_skb = NULL; +@@ -1341,6 +1392,9 @@ + if (skb->protocol == htons(ETH_P_IP)) + return tcp_v4_do_rcv(sk, skb); + ++ if (is_meta_sk(sk)) ++ return mptcp_v6_do_rcv(sk, skb); ++ + /* + * socket locking is here for SMP purposes as backlog rcv + * is currently called with bh processing disabled. +@@ -1468,6 +1522,10 @@ + TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + + skb->len - th->doff*4); + TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); ++#ifdef CONFIG_MPTCP ++ TCP_SKB_CB(skb)->mptcp_flags = 0; ++ TCP_SKB_CB(skb)->dss_off = 0; ++#endif + TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); + TCP_SKB_CB(skb)->tcp_tw_isn = 0; + TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); +@@ -1482,8 +1540,8 @@ + int sdif = inet6_sdif(skb); + const struct tcphdr *th; + const struct ipv6hdr *hdr; ++ struct sock *sk, *meta_sk = NULL; + bool refcounted; +- struct sock *sk; + int ret; + struct net *net = dev_net(skb->dev); + +@@ -1537,12 +1595,17 @@ + reqsk_put(req); + goto csum_error; + } +- if (unlikely(sk->sk_state != TCP_LISTEN)) { ++ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { ++ inet_csk_reqsk_queue_drop_and_put(sk, req); ++ goto lookup; ++ } ++ if (unlikely(is_meta_sk(sk) && !mptcp_can_new_subflow(sk))) { + inet_csk_reqsk_queue_drop_and_put(sk, req); + goto lookup; + } + sock_hold(sk); + refcounted = true; ++ + nsk = NULL; + if (!tcp_filter(sk, skb)) { + th = (const struct tcphdr *)skb->data; +@@ -1601,19 +1664,28 @@ + + sk_incoming_cpu_update(sk); + +- bh_lock_sock_nested(sk); ++ if (mptcp(tcp_sk(sk))) { ++ meta_sk = mptcp_meta_sk(sk); ++ ++ bh_lock_sock_nested(meta_sk); ++ if (sock_owned_by_user(meta_sk)) ++ mptcp_prepare_for_backlog(sk, skb); ++ } else { ++ meta_sk = sk; ++ bh_lock_sock_nested(sk); ++ } + tcp_segs_in(tcp_sk(sk), skb); + ret = 0; +- if (!sock_owned_by_user(sk)) { ++ if (!sock_owned_by_user(meta_sk)) { + skb_to_free = sk->sk_rx_skb_cache; + sk->sk_rx_skb_cache = NULL; + ret = tcp_v6_do_rcv(sk, skb); + } else { +- if (tcp_add_backlog(sk, skb)) ++ if (tcp_add_backlog(meta_sk, skb)) + goto discard_and_relse; + skb_to_free = NULL; + } +- bh_unlock_sock(sk); ++ bh_unlock_sock(meta_sk); + if (skb_to_free) + __kfree_skb(skb_to_free); + put_and_return: +@@ -1627,6 +1699,19 @@ + + tcp_v6_fill_cb(skb, hdr, th); + ++#ifdef CONFIG_MPTCP ++ if (!sk && th->syn && !th->ack) { ++ int ret = mptcp_lookup_join(skb, NULL); ++ ++ if (ret < 0) { ++ tcp_v6_send_reset(NULL, skb); ++ goto discard_it; ++ } else if (ret > 0) { ++ return 0; ++ } ++ } ++#endif ++ + if (tcp_checksum_complete(skb)) { + csum_error: + __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); +@@ -1679,6 +1764,18 @@ + refcounted = false; + goto process; + } ++#ifdef CONFIG_MPTCP ++ if (th->syn && !th->ack) { ++ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); ++ ++ if (ret < 0) { ++ tcp_v6_send_reset(NULL, skb); ++ goto discard_it; ++ } else if (ret > 0) { ++ return 0; ++ } ++ } ++#endif + } + /* to ACK */ + /* fall through */ +@@ -1733,13 +1830,13 @@ + } + } + +-static struct timewait_sock_ops tcp6_timewait_sock_ops = { ++struct timewait_sock_ops tcp6_timewait_sock_ops = { + .twsk_obj_size = sizeof(struct tcp6_timewait_sock), + .twsk_unique = tcp_twsk_unique, + .twsk_destructor = tcp_twsk_destructor, + }; + +-static const struct inet_connection_sock_af_ops ipv6_specific = { ++const struct inet_connection_sock_af_ops ipv6_specific = { + .queue_xmit = inet6_csk_xmit, + .send_check = tcp_v6_send_check, + .rebuild_header = inet6_sk_rebuild_header, +@@ -1770,7 +1867,7 @@ + /* + * TCP over IPv4 via INET6 API + */ +-static const struct inet_connection_sock_af_ops ipv6_mapped = { ++const struct inet_connection_sock_af_ops ipv6_mapped = { + .queue_xmit = ip_queue_xmit, + .send_check = tcp_v4_send_check, + .rebuild_header = inet_sk_rebuild_header, +@@ -1806,7 +1903,12 @@ + + tcp_init_sock(sk); + +- icsk->icsk_af_ops = &ipv6_specific; ++#ifdef CONFIG_MPTCP ++ if (sock_flag(sk, SOCK_MPTCP)) ++ icsk->icsk_af_ops = &mptcp_v6_specific; ++ else ++#endif ++ icsk->icsk_af_ops = &ipv6_specific; + + #ifdef CONFIG_TCP_MD5SIG + tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific; +@@ -1815,7 +1917,7 @@ + return 0; + } + +-static void tcp_v6_destroy_sock(struct sock *sk) ++void tcp_v6_destroy_sock(struct sock *sk) + { + tcp_v4_destroy_sock(sk); + inet6_destroy_sock(sk); +@@ -2038,6 +2140,11 @@ + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), + .max_header = MAX_TCP_HEADER, + .obj_size = sizeof(struct tcp6_sock), ++#ifdef CONFIG_MPTCP ++ .useroffset = offsetof(struct tcp_sock, mptcp_sched_name), ++ .usersize = sizeof_field(struct tcp_sock, mptcp_sched_name) + ++ sizeof_field(struct tcp_sock, mptcp_pm_name), ++#endif + .slab_flags = SLAB_TYPESAFE_BY_RCU, + .twsk_prot = &tcp6_timewait_sock_ops, + .rsk_prot = &tcp6_request_sock_ops, +@@ -2048,6 +2155,9 @@ + .compat_getsockopt = compat_tcp_getsockopt, + #endif + .diag_destroy = tcp_abort, ++#ifdef CONFIG_MPTCP ++ .clear_sk = mptcp_clear_sk, ++#endif + }; + + /* thinking of making this const? Don't. +diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig +--- linux-5.4/net/Kconfig 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/Kconfig 2020-02-20 18:07:47.000000000 +0100 +@@ -91,6 +91,7 @@ + source "net/ipv4/Kconfig" + source "net/ipv6/Kconfig" + source "net/netlabel/Kconfig" ++source "net/mptcp/Kconfig" + + endif # if INET + +diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile +--- linux-5.4/net/Makefile 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/Makefile 2020-02-20 18:07:47.000000000 +0100 +@@ -20,6 +20,7 @@ + obj-$(CONFIG_XFRM) += xfrm/ + obj-$(CONFIG_UNIX_SCM) += unix/ + obj-$(CONFIG_NET) += ipv6/ ++obj-$(CONFIG_MPTCP) += mptcp/ + obj-$(CONFIG_BPFILTER) += bpfilter/ + obj-$(CONFIG_PACKET) += packet/ + obj-$(CONFIG_NET_KEY) += key/ +diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig +--- linux-5.4/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,146 @@ ++# ++# MPTCP configuration ++# ++config MPTCP ++ bool "MPTCP protocol" ++ depends on (IPV6=y || IPV6=n) ++ ---help--- ++ This replaces the normal TCP stack with a Multipath TCP stack, ++ able to use several paths at once. ++ ++menuconfig MPTCP_PM_ADVANCED ++ bool "MPTCP: advanced path-manager control" ++ depends on MPTCP=y ++ ---help--- ++ Support for selection of different path-managers. You should choose 'Y' here, ++ because otherwise you will not actively create new MPTCP-subflows. ++ ++if MPTCP_PM_ADVANCED ++ ++config MPTCP_FULLMESH ++ tristate "MPTCP Full-Mesh Path-Manager" ++ depends on MPTCP=y ++ ---help--- ++ This path-management module will create a full-mesh among all IP-addresses. ++ ++config MPTCP_NDIFFPORTS ++ tristate "MPTCP ndiff-ports" ++ depends on MPTCP=y ++ ---help--- ++ This path-management module will create multiple subflows between the same ++ pair of IP-addresses, modifying the source-port. You can set the number ++ of subflows via the mptcp_ndiffports-sysctl. ++ ++config MPTCP_BINDER ++ tristate "MPTCP Binder" ++ depends on (MPTCP=y) ++ ---help--- ++ This path-management module works like ndiffports, and adds the sysctl ++ option to set the gateway (and/or path to) per each additional subflow ++ via Loose Source Routing (IPv4 only). ++ ++config MPTCP_NETLINK ++ tristate "MPTCP Netlink Path-Manager" ++ depends on MPTCP=y ++ ---help--- ++ This path-management module is controlled over a Netlink interface. A userspace ++ module can therefore control the establishment of new subflows and the policy ++ to apply over those new subflows for every connection. ++ ++choice ++ prompt "Default MPTCP Path-Manager" ++ default DEFAULT_DUMMY ++ help ++ Select the Path-Manager of your choice ++ ++ config DEFAULT_FULLMESH ++ bool "Full mesh" if MPTCP_FULLMESH=y ++ ++ config DEFAULT_NDIFFPORTS ++ bool "ndiff-ports" if MPTCP_NDIFFPORTS=y ++ ++ config DEFAULT_BINDER ++ bool "binder" if MPTCP_BINDER=y ++ ++ config DEFAULT_NETLINK ++ bool "Netlink" if MPTCP_NETLINK=y ++ ++ config DEFAULT_DUMMY ++ bool "Default" ++ ++endchoice ++ ++endif ++ ++config DEFAULT_MPTCP_PM ++ string ++ default "default" if DEFAULT_DUMMY ++ default "fullmesh" if DEFAULT_FULLMESH ++ default "ndiffports" if DEFAULT_NDIFFPORTS ++ default "binder" if DEFAULT_BINDER ++ default "default" ++ ++menuconfig MPTCP_SCHED_ADVANCED ++ bool "MPTCP: advanced scheduler control" ++ depends on MPTCP=y ++ ---help--- ++ Support for selection of different schedulers. You should choose 'Y' here, ++ if you want to choose a different scheduler than the default one. ++ ++if MPTCP_SCHED_ADVANCED ++ ++config MPTCP_BLEST ++ tristate "MPTCP BLEST" ++ depends on MPTCP=y ++ ---help--- ++ This is an experimental BLocking ESTimation-based (BLEST) scheduler. ++ ++config MPTCP_ROUNDROBIN ++ tristate "MPTCP Round-Robin" ++ depends on (MPTCP=y) ++ ---help--- ++ This is a very simple round-robin scheduler. Probably has bad performance ++ but might be interesting for researchers. ++ ++config MPTCP_REDUNDANT ++ tristate "MPTCP Redundant" ++ depends on (MPTCP=y) ++ ---help--- ++ This scheduler sends all packets redundantly over all subflows to decreases ++ latency and jitter on the cost of lower throughput. ++ ++choice ++ prompt "Default MPTCP Scheduler" ++ default DEFAULT_SCHEDULER ++ help ++ Select the Scheduler of your choice ++ ++ config DEFAULT_SCHEDULER ++ bool "Default" ++ ---help--- ++ This is the default scheduler, sending first on the subflow ++ with the lowest RTT. ++ ++ config DEFAULT_ROUNDROBIN ++ bool "Round-Robin" if MPTCP_ROUNDROBIN=y ++ ---help--- ++ This is the round-rob scheduler, sending in a round-robin ++ fashion.. ++ ++ config DEFAULT_REDUNDANT ++ bool "Redundant" if MPTCP_REDUNDANT=y ++ ---help--- ++ This is the redundant scheduler, sending packets redundantly over ++ all the subflows. ++ ++endchoice ++endif ++ ++config DEFAULT_MPTCP_SCHED ++ string ++ depends on (MPTCP=y) ++ default "default" if DEFAULT_SCHEDULER ++ default "roundrobin" if DEFAULT_ROUNDROBIN ++ default "redundant" if DEFAULT_REDUNDANT ++ default "default" ++ +diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile +--- linux-5.4/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,24 @@ ++# ++## Makefile for MultiPath TCP support code. ++# ++# ++ ++obj-$(CONFIG_MPTCP) += mptcp.o ++ ++mptcp-y := mptcp_ctrl.o mptcp_ipv4.o mptcp_pm.o \ ++ mptcp_output.o mptcp_input.o mptcp_sched.o ++ ++obj-$(CONFIG_TCP_CONG_LIA) += mptcp_coupled.o ++obj-$(CONFIG_TCP_CONG_OLIA) += mptcp_olia.o ++obj-$(CONFIG_TCP_CONG_WVEGAS) += mptcp_wvegas.o ++obj-$(CONFIG_TCP_CONG_BALIA) += mptcp_balia.o ++obj-$(CONFIG_TCP_CONG_MCTCPDESYNC) += mctcp_desync.o ++obj-$(CONFIG_MPTCP_FULLMESH) += mptcp_fullmesh.o ++obj-$(CONFIG_MPTCP_NDIFFPORTS) += mptcp_ndiffports.o ++obj-$(CONFIG_MPTCP_BINDER) += mptcp_binder.o ++obj-$(CONFIG_MPTCP_NETLINK) += mptcp_netlink.o ++obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o ++obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o ++obj-$(CONFIG_MPTCP_BLEST) += mptcp_blest.o ++ ++mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o +diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c +--- linux-5.4/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,193 @@ ++/* ++ * Desynchronized Multi-Channel TCP Congestion Control Algorithm ++ * ++ * Implementation based on publications of "DMCTCP:Desynchronized Multi-Channel ++ * TCP for high speed access networks with tiny buffers" in 23rd international ++ * conference of Computer Communication and Networks (ICCCN), 2014, and ++ * "Exploring parallelism and desynchronization of TCP over high speed networks ++ * with tiny buffers" in Journal of Computer Communications Elsevier, 2015. ++ * ++ * http://ieeexplore.ieee.org/abstract/document/6911722/ ++ * https://doi.org/10.1016/j.comcom.2015.07.010 ++ * ++ * This prototype is for research purpose and is currently experimental code ++ * that only support a single path. Future support of multi-channel over ++ * multi-path requires channels grouping. ++ * ++ * Initial Design and Implementation: ++ * Cheng Cui ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ */ ++#include ++#include ++#include ++ ++enum { ++ MASTER_CHANNEL = 1, ++ INI_MIN_CWND = 2, ++}; ++ ++/* private congestion control structure: ++ * off_tstamp: the last backoff timestamp for loss synchronization event ++ * off_subfid: the subflow which was backoff on off_tstamp ++ */ ++struct mctcp_desync { ++ u64 off_tstamp; ++ u8 off_subfid; ++}; ++ ++static inline int mctcp_cc_sk_can_send(const struct sock *sk) ++{ ++ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; ++} ++ ++static void mctcp_desync_init(struct sock *sk) ++{ ++ if (mptcp(tcp_sk(sk))) { ++ struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); ++ ca->off_tstamp = 0; ++ ca->off_subfid = 0; ++ } ++ /* If we do not mptcp, behave like reno: return */ ++} ++ ++static void mctcp_desync_cong_avoid(struct sock *sk, u32 ack, u32 acked) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (!mptcp(tp)) { ++ tcp_reno_cong_avoid(sk, ack, acked); ++ return; ++ } else if (!tcp_is_cwnd_limited(sk)) { ++ return; ++ } else { ++ const struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); ++ const u8 subfid = tp->mptcp->path_index; ++ ++ /* current aggregated cwnd */ ++ u32 agg_cwnd = 0; ++ u32 min_cwnd = 0xffffffff; ++ u8 min_cwnd_subfid = 0; ++ ++ /* In "safe" area, increase */ ++ if (tcp_in_slow_start(tp)) { ++ if (ca->off_subfid) { ++ /* passed initial phase, allow slow start */ ++ tcp_slow_start(tp, acked); ++ } else if (MASTER_CHANNEL == tp->mptcp->path_index) { ++ /* master channel is normal slow start in ++ * initial phase */ ++ tcp_slow_start(tp, acked); ++ } else { ++ /* secondary channels increase slowly until ++ * the initial phase passed ++ */ ++ tp->snd_ssthresh = tp->snd_cwnd = INI_MIN_CWND; ++ } ++ return; ++ } else { ++ /* In dangerous area, increase slowly and linearly. */ ++ const struct mptcp_tcp_sock *mptcp; ++ ++ /* get total cwnd and the subflow that has min cwnd */ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ const struct sock *sub_sk = mptcp_to_sock(mptcp); ++ ++ if (mctcp_cc_sk_can_send(sub_sk)) { ++ const struct tcp_sock *sub_tp = ++ tcp_sk(sub_sk); ++ agg_cwnd += sub_tp->snd_cwnd; ++ if(min_cwnd > sub_tp->snd_cwnd) { ++ min_cwnd = sub_tp->snd_cwnd; ++ min_cwnd_subfid = ++ sub_tp->mptcp->path_index; ++ } ++ } ++ } ++ /* the smallest subflow grows faster than others */ ++ if (subfid == min_cwnd_subfid) { ++ tcp_cong_avoid_ai(tp, min_cwnd, acked); ++ } else { ++ tcp_cong_avoid_ai(tp, agg_cwnd - min_cwnd, ++ acked); ++ } ++ } ++ } ++} ++ ++static u32 mctcp_desync_ssthresh(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (!mptcp(tp)) { ++ return max(tp->snd_cwnd >> 1U, 2U); ++ } else { ++ struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); ++ const u8 subfid = tp->mptcp->path_index; ++ const struct mptcp_tcp_sock *mptcp; ++ u32 max_cwnd = 0; ++ u8 max_cwnd_subfid = 0; ++ ++ /* Find the subflow that has the max cwnd. */ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ const struct sock *sub_sk = mptcp_to_sock(mptcp); ++ ++ if (mctcp_cc_sk_can_send(sub_sk)) { ++ const struct tcp_sock *sub_tp = tcp_sk(sub_sk); ++ if (max_cwnd < sub_tp->snd_cwnd) { ++ max_cwnd = sub_tp->snd_cwnd; ++ max_cwnd_subfid = ++ sub_tp->mptcp->path_index; ++ } ++ } ++ } ++ /* Use high resolution clock. */ ++ if (subfid == max_cwnd_subfid) { ++ u64 now = tcp_clock_us(); ++ u32 delta = tcp_stamp_us_delta(now, ca->off_tstamp); ++ ++ if (delta < (tp->srtt_us >> 3)) { ++ /* desynchronize */ ++ return tp->snd_cwnd; ++ } else { ++ ca->off_tstamp = now; ++ ca->off_subfid = subfid; ++ return max(max_cwnd >> 1U, 2U); ++ } ++ } else { ++ return tp->snd_cwnd; ++ } ++ } ++} ++ ++static struct tcp_congestion_ops mctcp_desync = { ++ .init = mctcp_desync_init, ++ .ssthresh = mctcp_desync_ssthresh, ++ .undo_cwnd = tcp_reno_undo_cwnd, ++ .cong_avoid = mctcp_desync_cong_avoid, ++ .owner = THIS_MODULE, ++ .name = "mctcpdesync", ++}; ++ ++static int __init mctcp_desync_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct mctcp_desync) > ICSK_CA_PRIV_SIZE); ++ return tcp_register_congestion_control(&mctcp_desync); ++} ++ ++static void __exit mctcp_desync_unregister(void) ++{ ++ tcp_unregister_congestion_control(&mctcp_desync); ++} ++ ++module_init(mctcp_desync_register); ++module_exit(mctcp_desync_unregister); ++ ++MODULE_AUTHOR("Cheng Cui"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MCTCP: DESYNCHRONIZED MULTICHANNEL TCP CONGESTION CONTROL"); ++MODULE_VERSION("1.0"); +diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c +--- linux-5.4/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,261 @@ ++/* ++ * MPTCP implementation - Balia Congestion Control ++ * (Balanced Linked Adaptation Algorithm) ++ * ++ * Analysis, Design and Implementation: ++ * Qiuyu Peng ++ * Anwar Walid ++ * Jaehyun Hwang ++ * Steven H. Low ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++#include ++ ++/* The variable 'rate' (i.e., x_r) will be scaled ++ * e.g., from B/s to KB/s, MB/s, or GB/s ++ * if max_rate > 2^rate_scale_limit ++ */ ++ ++static int rate_scale_limit = 25; ++static int alpha_scale = 10; ++static int scale_num = 5; ++ ++struct mptcp_balia { ++ u64 ai; ++ u64 md; ++ bool forced_update; ++}; ++ ++static inline int mptcp_balia_sk_can_send(const struct sock *sk) ++{ ++ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; ++} ++ ++static inline u64 mptcp_get_ai(const struct sock *meta_sk) ++{ ++ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai; ++} ++ ++static inline void mptcp_set_ai(const struct sock *meta_sk, u64 ai) ++{ ++ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai = ai; ++} ++ ++static inline u64 mptcp_get_md(const struct sock *meta_sk) ++{ ++ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md; ++} ++ ++static inline void mptcp_set_md(const struct sock *meta_sk, u64 md) ++{ ++ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md = md; ++} ++ ++static inline u64 mptcp_balia_scale(u64 val, int scale) ++{ ++ return (u64) val << scale; ++} ++ ++static inline bool mptcp_get_forced(const struct sock *meta_sk) ++{ ++ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update; ++} ++ ++static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) ++{ ++ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update = force; ++} ++ ++static void mptcp_balia_recalc_ai(const struct sock *sk) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ const struct mptcp_cb *mpcb = tp->mpcb; ++ struct mptcp_tcp_sock *mptcp; ++ u64 max_rate = 0, rate = 0, sum_rate = 0; ++ u64 alpha, ai = tp->snd_cwnd, md = (tp->snd_cwnd >> 1); ++ int num_scale_down = 0; ++ ++ if (!mpcb) ++ return; ++ ++ /* Find max_rate first */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ const struct sock *sub_sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *sub_tp = tcp_sk(sub_sk); ++ u64 tmp; ++ ++ if (!mptcp_balia_sk_can_send(sub_sk)) ++ continue; ++ ++ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd ++ * (USEC_PER_SEC << 3), sub_tp->srtt_us); ++ sum_rate += tmp; ++ ++ if (tp == sub_tp) ++ rate = tmp; ++ ++ if (tmp >= max_rate) ++ max_rate = tmp; ++ } ++ ++ /* At least, the current subflow should be able to send */ ++ if (unlikely(!rate)) ++ goto exit; ++ ++ alpha = div64_u64(max_rate, rate); ++ ++ /* Scale down max_rate if it is too high (e.g., >2^25) */ ++ while (max_rate > mptcp_balia_scale(1, rate_scale_limit)) { ++ max_rate >>= scale_num; ++ num_scale_down++; ++ } ++ ++ if (num_scale_down) { ++ sum_rate = 0; ++ mptcp_for_each_sub(mpcb, mptcp) { ++ const struct sock *sub_sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *sub_tp = tcp_sk(sub_sk); ++ u64 tmp; ++ ++ if (!mptcp_balia_sk_can_send(sub_sk)) ++ continue; ++ ++ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd ++ * (USEC_PER_SEC << 3), sub_tp->srtt_us); ++ tmp >>= (scale_num * num_scale_down); ++ ++ sum_rate += tmp; ++ } ++ rate >>= (scale_num * num_scale_down); ++ } ++ ++ /* (sum_rate)^2 * 10 * w_r ++ * ai = ------------------------------------ ++ * (x_r + max_rate) * (4x_r + max_rate) ++ */ ++ sum_rate *= sum_rate; ++ ++ ai = div64_u64(sum_rate * 10, rate + max_rate); ++ ai = div64_u64(ai * tp->snd_cwnd, (rate << 2) + max_rate); ++ ++ if (unlikely(!ai)) ++ ai = tp->snd_cwnd; ++ ++ md = ((tp->snd_cwnd >> 1) * min(mptcp_balia_scale(alpha, alpha_scale), ++ mptcp_balia_scale(3, alpha_scale) >> 1)) ++ >> alpha_scale; ++ ++exit: ++ mptcp_set_ai(sk, ai); ++ mptcp_set_md(sk, md); ++} ++ ++static void mptcp_balia_init(struct sock *sk) ++{ ++ if (mptcp(tcp_sk(sk))) { ++ mptcp_set_forced(sk, 0); ++ mptcp_set_ai(sk, 0); ++ mptcp_set_md(sk, 0); ++ } ++} ++ ++static void mptcp_balia_cwnd_event(struct sock *sk, enum tcp_ca_event event) ++{ ++ if (event == CA_EVENT_COMPLETE_CWR || event == CA_EVENT_LOSS) ++ mptcp_balia_recalc_ai(sk); ++} ++ ++static void mptcp_balia_set_state(struct sock *sk, u8 ca_state) ++{ ++ if (!mptcp(tcp_sk(sk))) ++ return; ++ ++ mptcp_set_forced(sk, 1); ++} ++ ++static void mptcp_balia_cong_avoid(struct sock *sk, u32 ack, u32 acked) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ int snd_cwnd; ++ ++ if (!mptcp(tp)) { ++ tcp_reno_cong_avoid(sk, ack, acked); ++ return; ++ } ++ ++ if (!tcp_is_cwnd_limited(sk)) ++ return; ++ ++ if (tcp_in_slow_start(tp)) { ++ /* In "safe" area, increase. */ ++ tcp_slow_start(tp, acked); ++ mptcp_balia_recalc_ai(sk); ++ return; ++ } ++ ++ if (mptcp_get_forced(mptcp_meta_sk(sk))) { ++ mptcp_balia_recalc_ai(sk); ++ mptcp_set_forced(sk, 0); ++ } ++ ++ snd_cwnd = (int)mptcp_get_ai(sk); ++ ++ if (tp->snd_cwnd_cnt >= snd_cwnd) { ++ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { ++ tp->snd_cwnd++; ++ mptcp_balia_recalc_ai(sk); ++ } ++ ++ tp->snd_cwnd_cnt = 0; ++ } else { ++ tp->snd_cwnd_cnt++; ++ } ++} ++ ++static u32 mptcp_balia_ssthresh(struct sock *sk) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (unlikely(!mptcp(tp))) ++ return tcp_reno_ssthresh(sk); ++ else ++ return max((u32)(tp->snd_cwnd - mptcp_get_md(sk)), 1U); ++} ++ ++static struct tcp_congestion_ops mptcp_balia = { ++ .init = mptcp_balia_init, ++ .ssthresh = mptcp_balia_ssthresh, ++ .cong_avoid = mptcp_balia_cong_avoid, ++ .undo_cwnd = tcp_reno_undo_cwnd, ++ .cwnd_event = mptcp_balia_cwnd_event, ++ .set_state = mptcp_balia_set_state, ++ .owner = THIS_MODULE, ++ .name = "balia", ++}; ++ ++static int __init mptcp_balia_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct mptcp_balia) > ICSK_CA_PRIV_SIZE); ++ return tcp_register_congestion_control(&mptcp_balia); ++} ++ ++static void __exit mptcp_balia_unregister(void) ++{ ++ tcp_unregister_congestion_control(&mptcp_balia); ++} ++ ++module_init(mptcp_balia_register); ++module_exit(mptcp_balia_unregister); ++ ++MODULE_AUTHOR("Jaehyun Hwang, Anwar Walid, Qiuyu Peng, Steven H. Low"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MPTCP BALIA CONGESTION CONTROL ALGORITHM"); ++MODULE_VERSION("0.1"); +diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c +--- linux-5.4/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,494 @@ ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MPTCP_GW_MAX_LISTS 10 ++#define MPTCP_GW_LIST_MAX_LEN 6 ++#define MPTCP_GW_SYSCTL_MAX_LEN (15 * MPTCP_GW_LIST_MAX_LEN * \ ++ MPTCP_GW_MAX_LISTS) ++ ++struct mptcp_gw_list { ++ struct in_addr list[MPTCP_GW_MAX_LISTS][MPTCP_GW_LIST_MAX_LEN]; ++ u8 len[MPTCP_GW_MAX_LISTS]; ++}; ++ ++struct binder_priv { ++ /* Worker struct for subflow establishment */ ++ struct work_struct subflow_work; ++ ++ struct mptcp_cb *mpcb; ++ ++ /* Prevent multiple sub-sockets concurrently iterating over sockets */ ++ spinlock_t *flow_lock; ++}; ++ ++static struct mptcp_gw_list *mptcp_gws; ++static rwlock_t mptcp_gws_lock; ++ ++static int mptcp_binder_ndiffports __read_mostly = 1; ++ ++static char sysctl_mptcp_binder_gateways[MPTCP_GW_SYSCTL_MAX_LEN] __read_mostly; ++ ++static int mptcp_get_avail_list_ipv4(struct sock *sk) ++{ ++ int i, j, list_taken, opt_ret, opt_len; ++ unsigned char *opt_ptr, *opt_end_ptr, opt[MAX_IPOPTLEN]; ++ ++ for (i = 0; i < MPTCP_GW_MAX_LISTS; ++i) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ if (mptcp_gws->len[i] == 0) ++ goto error; ++ ++ mptcp_debug("mptcp_get_avail_list_ipv4: List %i\n", i); ++ list_taken = 0; ++ ++ /* Loop through all sub-sockets in this connection */ ++ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { ++ sk = mptcp_to_sock(mptcp); ++ ++ mptcp_debug("mptcp_get_avail_list_ipv4: Next sock\n"); ++ ++ /* Reset length and options buffer, then retrieve ++ * from socket ++ */ ++ opt_len = MAX_IPOPTLEN; ++ memset(opt, 0, MAX_IPOPTLEN); ++ opt_ret = ip_getsockopt(sk, IPPROTO_IP, ++ IP_OPTIONS, (char __user *)opt, (int __user *)&opt_len); ++ if (opt_ret < 0) { ++ mptcp_debug("%s: MPTCP subsocket getsockopt() IP_OPTIONS failed, error %d\n", ++ __func__, opt_ret); ++ goto error; ++ } ++ ++ /* If socket has no options, it has no stake in this list */ ++ if (opt_len <= 0) ++ continue; ++ ++ /* Iterate options buffer */ ++ for (opt_ptr = &opt[0]; opt_ptr < &opt[opt_len]; opt_ptr++) { ++ if (*opt_ptr == IPOPT_LSRR) { ++ mptcp_debug("mptcp_get_avail_list_ipv4: LSRR options found\n"); ++ goto sock_lsrr; ++ } ++ } ++ continue; ++ ++sock_lsrr: ++ /* Pointer to the 2nd to last address */ ++ opt_end_ptr = opt_ptr+(*(opt_ptr+1))-4; ++ ++ /* Addresses start 3 bytes after type offset */ ++ opt_ptr += 3; ++ j = 0; ++ ++ /* Different length lists cannot be the same */ ++ if ((opt_end_ptr-opt_ptr)/4 != mptcp_gws->len[i]) ++ continue; ++ ++ /* Iterate if we are still inside options list ++ * and sysctl list ++ */ ++ while (opt_ptr < opt_end_ptr && j < mptcp_gws->len[i]) { ++ /* If there is a different address, this list must ++ * not be set on this socket ++ */ ++ if (memcmp(&mptcp_gws->list[i][j], opt_ptr, 4)) ++ break; ++ ++ /* Jump 4 bytes to next address */ ++ opt_ptr += 4; ++ j++; ++ } ++ ++ /* Reached the end without a differing address, lists ++ * are therefore identical. ++ */ ++ if (j == mptcp_gws->len[i]) { ++ mptcp_debug("mptcp_get_avail_list_ipv4: List already used\n"); ++ list_taken = 1; ++ break; ++ } ++ } ++ ++ /* Free list found if not taken by a socket */ ++ if (!list_taken) { ++ mptcp_debug("mptcp_get_avail_list_ipv4: List free\n"); ++ break; ++ } ++ } ++ ++ if (i >= MPTCP_GW_MAX_LISTS) ++ goto error; ++ ++ return i; ++error: ++ return -1; ++} ++ ++/* The list of addresses is parsed each time a new connection is opened, ++ * to make sure it's up to date. In case of error, all the lists are ++ * marked as unavailable and the subflow's fingerprint is set to 0. ++ */ ++static void mptcp_v4_add_lsrr(struct sock *sk, struct in_addr addr) ++{ ++ int i, j, ret; ++ unsigned char opt[MAX_IPOPTLEN] = {0}; ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct binder_priv *fmp = (struct binder_priv *)&tp->mpcb->mptcp_pm[0]; ++ ++ /* Read lock: multiple sockets can read LSRR addresses at the same ++ * time, but writes are done in mutual exclusion. ++ * Spin lock: must search for free list for one socket at a time, or ++ * multiple sockets could take the same list. ++ */ ++ read_lock(&mptcp_gws_lock); ++ spin_lock(fmp->flow_lock); ++ ++ i = mptcp_get_avail_list_ipv4(sk); ++ ++ /* Execution enters here only if a free path is found. ++ */ ++ if (i >= 0) { ++ opt[0] = IPOPT_NOP; ++ opt[1] = IPOPT_LSRR; ++ opt[2] = sizeof(mptcp_gws->list[i][0].s_addr) * ++ (mptcp_gws->len[i] + 1) + 3; ++ opt[3] = IPOPT_MINOFF; ++ for (j = 0; j < mptcp_gws->len[i]; ++j) ++ memcpy(opt + 4 + ++ (j * sizeof(mptcp_gws->list[i][0].s_addr)), ++ &mptcp_gws->list[i][j].s_addr, ++ sizeof(mptcp_gws->list[i][0].s_addr)); ++ /* Final destination must be part of IP_OPTIONS parameter. */ ++ memcpy(opt + 4 + (j * sizeof(addr.s_addr)), &addr.s_addr, ++ sizeof(addr.s_addr)); ++ ++ /* setsockopt must be inside the lock, otherwise another ++ * subflow could fail to see that we have taken a list. ++ */ ++ ret = ip_setsockopt(sk, IPPROTO_IP, IP_OPTIONS, (char __user *)opt, ++ 4 + sizeof(mptcp_gws->list[i][0].s_addr) * (mptcp_gws->len[i] + 1)); ++ ++ if (ret < 0) { ++ mptcp_debug("%s: MPTCP subsock setsockopt() IP_OPTIONS failed, error %d\n", ++ __func__, ret); ++ } ++ } ++ ++ spin_unlock(fmp->flow_lock); ++ read_unlock(&mptcp_gws_lock); ++ ++ return; ++} ++ ++/* Parses gateways string for a list of paths to different ++ * gateways, and stores them for use with the Loose Source Routing (LSRR) ++ * socket option. Each list must have "," separated addresses, and the lists ++ * themselves must be separated by "-". Returns -1 in case one or more of the ++ * addresses is not a valid ipv4/6 address. ++ */ ++static int mptcp_parse_gateway_ipv4(char *gateways) ++{ ++ int i, j, k, ret; ++ char *tmp_string = NULL; ++ struct in_addr tmp_addr; ++ ++ tmp_string = kzalloc(16, GFP_KERNEL); ++ if (tmp_string == NULL) ++ return -ENOMEM; ++ ++ write_lock(&mptcp_gws_lock); ++ ++ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); ++ ++ /* A TMP string is used since inet_pton needs a null terminated string ++ * but we do not want to modify the sysctl for obvious reasons. ++ * i will iterate over the SYSCTL string, j will iterate over the ++ * temporary string where each IP is copied into, k will iterate over ++ * the IPs in each list. ++ */ ++ for (i = j = k = 0; ++ i < MPTCP_GW_SYSCTL_MAX_LEN && k < MPTCP_GW_MAX_LISTS; ++ ++i) { ++ if (gateways[i] == '-' || gateways[i] == ',' || gateways[i] == '\0') { ++ /* If the temp IP is empty and the current list is ++ * empty, we are done. ++ */ ++ if (j == 0 && mptcp_gws->len[k] == 0) ++ break; ++ ++ /* Terminate the temp IP string, then if it is ++ * non-empty parse the IP and copy it. ++ */ ++ tmp_string[j] = '\0'; ++ if (j > 0) { ++ mptcp_debug("mptcp_parse_gateway_list tmp: %s i: %d\n", tmp_string, i); ++ ++ ret = in4_pton(tmp_string, strlen(tmp_string), ++ (u8 *)&tmp_addr.s_addr, '\0', ++ NULL); ++ ++ if (ret) { ++ mptcp_debug("mptcp_parse_gateway_list ret: %d s_addr: %pI4\n", ++ ret, ++ &tmp_addr.s_addr); ++ memcpy(&mptcp_gws->list[k][mptcp_gws->len[k]].s_addr, ++ &tmp_addr.s_addr, ++ sizeof(tmp_addr.s_addr)); ++ mptcp_gws->len[k]++; ++ j = 0; ++ tmp_string[j] = '\0'; ++ /* Since we can't impose a limit to ++ * what the user can input, make sure ++ * there are not too many IPs in the ++ * SYSCTL string. ++ */ ++ if (mptcp_gws->len[k] > MPTCP_GW_LIST_MAX_LEN) { ++ mptcp_debug("mptcp_parse_gateway_list too many members in list %i: max %i\n", ++ k, ++ MPTCP_GW_LIST_MAX_LEN); ++ goto error; ++ } ++ } else { ++ goto error; ++ } ++ } ++ ++ if (gateways[i] == '-' || gateways[i] == '\0') ++ ++k; ++ } else { ++ tmp_string[j] = gateways[i]; ++ ++j; ++ } ++ } ++ ++ /* Number of flows is number of gateway lists plus master flow */ ++ mptcp_binder_ndiffports = k+1; ++ ++ write_unlock(&mptcp_gws_lock); ++ kfree(tmp_string); ++ ++ return 0; ++ ++error: ++ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); ++ memset(gateways, 0, sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN); ++ write_unlock(&mptcp_gws_lock); ++ kfree(tmp_string); ++ return -1; ++} ++ ++/** ++ * Create all new subflows, by doing calls to mptcp_initX_subsockets ++ * ++ * This function uses a goto next_subflow, to allow releasing the lock between ++ * new subflows and giving other processes a chance to do some work on the ++ * socket and potentially finishing the communication. ++ **/ ++static void create_subflow_worker(struct work_struct *work) ++{ ++ const struct binder_priv *pm_priv = container_of(work, ++ struct binder_priv, ++ subflow_work); ++ struct mptcp_cb *mpcb = pm_priv->mpcb; ++ struct sock *meta_sk = mpcb->meta_sk; ++ int iter = 0; ++ ++next_subflow: ++ if (iter) { ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ ++ cond_resched(); ++ } ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ if (!mptcp(tcp_sk(meta_sk))) ++ goto exit; ++ ++ iter++; ++ ++ if (sock_flag(meta_sk, SOCK_DEAD)) ++ goto exit; ++ ++ if (mpcb->master_sk && ++ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) ++ goto exit; ++ ++ if (mptcp_binder_ndiffports > iter && ++ mptcp_binder_ndiffports > mptcp_subflow_count(mpcb)) { ++ struct mptcp_loc4 loc; ++ struct mptcp_rem4 rem; ++ ++ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; ++ loc.loc4_id = 0; ++ loc.low_prio = 0; ++ ++ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; ++ rem.port = inet_sk(meta_sk)->inet_dport; ++ rem.rem4_id = 0; /* Default 0 */ ++ ++ mptcp_init4_subsockets(meta_sk, &loc, &rem); ++ ++ goto next_subflow; ++ } ++ ++exit: ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ mptcp_mpcb_put(mpcb); ++ sock_put(meta_sk); ++} ++ ++static void binder_new_session(const struct sock *meta_sk) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct binder_priv *fmp = (struct binder_priv *)&mpcb->mptcp_pm[0]; ++ static DEFINE_SPINLOCK(flow_lock); ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ if (meta_sk->sk_family == AF_INET6 && ++ !mptcp_v6_is_v4_mapped(meta_sk)) { ++ mptcp_fallback_default(mpcb); ++ return; ++ } ++#endif ++ ++ /* Initialize workqueue-struct */ ++ INIT_WORK(&fmp->subflow_work, create_subflow_worker); ++ fmp->mpcb = mpcb; ++ ++ fmp->flow_lock = &flow_lock; ++} ++ ++static void binder_create_subflows(struct sock *meta_sk) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct binder_priv *pm_priv = (struct binder_priv *)&mpcb->mptcp_pm[0]; ++ ++ if (mptcp_in_infinite_mapping_weak(mpcb) || ++ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) ++ return; ++ ++ if (!work_pending(&pm_priv->subflow_work)) { ++ sock_hold(meta_sk); ++ refcount_inc(&mpcb->mpcb_refcnt); ++ queue_work(mptcp_wq, &pm_priv->subflow_work); ++ } ++} ++ ++static int binder_get_local_id(const struct sock *meta_sk, sa_family_t family, ++ union inet_addr *addr, bool *low_prio) ++{ ++ return 0; ++} ++ ++/* Callback functions, executed when syctl mptcp.mptcp_gateways is updated. ++ * Inspired from proc_tcp_congestion_control(). ++ */ ++static int proc_mptcp_gateways(struct ctl_table *ctl, int write, ++ void __user *buffer, size_t *lenp, ++ loff_t *ppos) ++{ ++ int ret; ++ struct ctl_table tbl = { ++ .maxlen = MPTCP_GW_SYSCTL_MAX_LEN, ++ }; ++ ++ if (write) { ++ tbl.data = kzalloc(MPTCP_GW_SYSCTL_MAX_LEN, GFP_KERNEL); ++ if (tbl.data == NULL) ++ return -ENOMEM; ++ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); ++ if (ret == 0) { ++ ret = mptcp_parse_gateway_ipv4(tbl.data); ++ memcpy(ctl->data, tbl.data, MPTCP_GW_SYSCTL_MAX_LEN); ++ } ++ kfree(tbl.data); ++ } else { ++ ret = proc_dostring(ctl, write, buffer, lenp, ppos); ++ } ++ ++ ++ return ret; ++} ++ ++static struct mptcp_pm_ops binder __read_mostly = { ++ .new_session = binder_new_session, ++ .fully_established = binder_create_subflows, ++ .get_local_id = binder_get_local_id, ++ .init_subsocket_v4 = mptcp_v4_add_lsrr, ++ .name = "binder", ++ .owner = THIS_MODULE, ++}; ++ ++static struct ctl_table binder_table[] = { ++ { ++ .procname = "mptcp_binder_gateways", ++ .data = &sysctl_mptcp_binder_gateways, ++ .maxlen = sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN, ++ .mode = 0644, ++ .proc_handler = &proc_mptcp_gateways ++ }, ++ { } ++}; ++ ++static struct ctl_table_header *mptcp_sysctl_binder; ++ ++/* General initialization of MPTCP_PM */ ++static int __init binder_register(void) ++{ ++ mptcp_gws = kzalloc(sizeof(*mptcp_gws), GFP_KERNEL); ++ if (!mptcp_gws) ++ return -ENOMEM; ++ ++ rwlock_init(&mptcp_gws_lock); ++ ++ BUILD_BUG_ON(sizeof(struct binder_priv) > MPTCP_PM_SIZE); ++ ++ mptcp_sysctl_binder = register_net_sysctl(&init_net, "net/mptcp", ++ binder_table); ++ if (!mptcp_sysctl_binder) ++ goto sysctl_fail; ++ ++ if (mptcp_register_path_manager(&binder)) ++ goto pm_failed; ++ ++ return 0; ++ ++pm_failed: ++ unregister_net_sysctl_table(mptcp_sysctl_binder); ++sysctl_fail: ++ kfree(mptcp_gws); ++ ++ return -1; ++} ++ ++static void binder_unregister(void) ++{ ++ mptcp_unregister_path_manager(&binder); ++ unregister_net_sysctl_table(mptcp_sysctl_binder); ++ kfree(mptcp_gws); ++} ++ ++module_init(binder_register); ++module_exit(binder_unregister); ++ ++MODULE_AUTHOR("Luca Boccassi, Duncan Eastoe, Christoph Paasch (ndiffports)"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("BINDER MPTCP"); ++MODULE_VERSION("0.1"); +diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c +--- linux-5.4/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,481 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* MPTCP Scheduler to reduce HoL-blocking and spurious retransmissions. ++ * ++ * Algorithm Design: ++ * Simone Ferlin ++ * Ozgu Alay ++ * Olivier Mehani ++ * Roksana Boreli ++ * ++ * Initial Implementation: ++ * Simone Ferlin ++ * ++ * Additional Authors: ++ * Daniel Weber ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++ ++static unsigned char lambda __read_mostly = 12; ++module_param(lambda, byte, 0644); ++MODULE_PARM_DESC(lambda, "Divided by 10 for scaling factor of fast flow rate estimation"); ++ ++static unsigned char max_lambda __read_mostly = 13; ++module_param(max_lambda, byte, 0644); ++MODULE_PARM_DESC(max_lambda, "Divided by 10 for maximum scaling factor of fast flow rate estimation"); ++ ++static unsigned char min_lambda __read_mostly = 10; ++module_param(min_lambda, byte, 0644); ++MODULE_PARM_DESC(min_lambda, "Divided by 10 for minimum scaling factor of fast flow rate estimation"); ++ ++static unsigned char dyn_lambda_good = 10; /* 1% */ ++module_param(dyn_lambda_good, byte, 0644); ++MODULE_PARM_DESC(dyn_lambda_good, "Decrease of lambda in positive case."); ++ ++static unsigned char dyn_lambda_bad = 40; /* 4% */ ++module_param(dyn_lambda_bad, byte, 0644); ++MODULE_PARM_DESC(dyn_lambda_bad, "Increase of lambda in negative case."); ++ ++struct blestsched_priv { ++ u32 last_rbuf_opti; ++ u32 min_srtt_us; ++ u32 max_srtt_us; ++}; ++ ++struct blestsched_cb { ++ bool retrans_flag; ++ s16 lambda_1000; /* values range from min_lambda * 100 to max_lambda * 100 */ ++ u32 last_lambda_update; ++}; ++ ++static struct blestsched_priv *blestsched_get_priv(const struct tcp_sock *tp) ++{ ++ return (struct blestsched_priv *)&tp->mptcp->mptcp_sched[0]; ++} ++ ++static struct blestsched_cb *blestsched_get_cb(const struct tcp_sock *tp) ++{ ++ return (struct blestsched_cb *)&tp->mpcb->mptcp_sched[0]; ++} ++ ++static void blestsched_update_lambda(struct sock *meta_sk, struct sock *sk) ++{ ++ struct blestsched_cb *blest_cb = blestsched_get_cb(tcp_sk(meta_sk)); ++ struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); ++ ++ if (tcp_jiffies32 - blest_cb->last_lambda_update < usecs_to_jiffies(blest_p->min_srtt_us >> 3)) ++ return; ++ ++ /* if there have been retransmissions of packets of the slow flow ++ * during the slow flows last RTT => increase lambda ++ * otherwise decrease ++ */ ++ if (blest_cb->retrans_flag) { ++ /* need to slow down on the slow flow */ ++ blest_cb->lambda_1000 += dyn_lambda_bad; ++ } else { ++ /* use the slow flow more */ ++ blest_cb->lambda_1000 -= dyn_lambda_good; ++ } ++ blest_cb->retrans_flag = false; ++ ++ /* cap lambda_1000 to its value range */ ++ blest_cb->lambda_1000 = min_t(s16, blest_cb->lambda_1000, max_lambda * 100); ++ blest_cb->lambda_1000 = max_t(s16, blest_cb->lambda_1000, min_lambda * 100); ++ ++ blest_cb->last_lambda_update = tcp_jiffies32; ++} ++ ++/* how many bytes will sk send during the rtt of another, slower flow? */ ++static u32 blestsched_estimate_bytes(struct sock *sk, u32 time_8) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct blestsched_priv *blest_p = blestsched_get_priv(tp); ++ struct blestsched_cb *blest_cb = blestsched_get_cb(mptcp_meta_tp(tp)); ++ u32 avg_rtt, num_rtts, ca_cwnd, packets; ++ ++ avg_rtt = (blest_p->min_srtt_us + blest_p->max_srtt_us) / 2; ++ if (avg_rtt == 0) ++ num_rtts = 1; /* sanity */ ++ else ++ num_rtts = (time_8 / avg_rtt) + 1; /* round up */ ++ ++ /* during num_rtts, how many bytes will be sent on the flow? ++ * assumes for simplification that Reno is applied as congestion-control ++ */ ++ if (tp->snd_ssthresh == TCP_INFINITE_SSTHRESH) { ++ /* we are in initial slow start */ ++ if (num_rtts > 16) ++ num_rtts = 16; /* cap for sanity */ ++ packets = tp->snd_cwnd * ((1 << num_rtts) - 1); /* cwnd + 2*cwnd + 4*cwnd */ ++ } else { ++ ca_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh + 1); /* assume we jump to CA already */ ++ packets = (ca_cwnd + (num_rtts - 1) / 2) * num_rtts; ++ } ++ ++ return div_u64(((u64)packets) * tp->mss_cache * blest_cb->lambda_1000, 1000); ++} ++ ++static u32 blestsched_estimate_linger_time(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct blestsched_priv *blest_p = blestsched_get_priv(tp); ++ u32 estimate, slope, inflight, cwnd; ++ ++ inflight = tcp_packets_in_flight(tp) + 1; /* take into account the new one */ ++ cwnd = tp->snd_cwnd; ++ ++ if (inflight >= cwnd) { ++ estimate = blest_p->max_srtt_us; ++ } else { ++ slope = blest_p->max_srtt_us - blest_p->min_srtt_us; ++ if (cwnd == 0) ++ cwnd = 1; /* sanity */ ++ estimate = blest_p->min_srtt_us + (slope * inflight) / cwnd; ++ } ++ ++ return (tp->srtt_us > estimate) ? tp->srtt_us : estimate; ++} ++ ++/* This is the BLEST scheduler. This function decides on which flow to send ++ * a given MSS. If all subflows are found to be busy or the currently best ++ * subflow is estimated to possibly cause HoL-blocking, NULL is returned. ++ */ ++struct sock *blest_get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sock *bestsk, *minsk = NULL; ++ struct tcp_sock *meta_tp, *besttp; ++ struct mptcp_tcp_sock *mptcp; ++ struct blestsched_priv *blest_p; ++ u32 min_srtt = U32_MAX; ++ ++ /* Answer data_fin on same subflow!!! */ ++ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && ++ skb && mptcp_is_data_fin(skb)) { ++ mptcp_for_each_sub(mpcb, mptcp) { ++ bestsk = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(bestsk)->mptcp->path_index == mpcb->dfin_path_index && ++ mptcp_is_available(bestsk, skb, zero_wnd_test)) ++ return bestsk; ++ } ++ } ++ ++ /* First, find the overall best subflow */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ bestsk = mptcp_to_sock(mptcp); ++ besttp = tcp_sk(bestsk); ++ blest_p = blestsched_get_priv(besttp); ++ ++ /* Set of states for which we are allowed to send data */ ++ if (!mptcp_sk_can_send(bestsk)) ++ continue; ++ ++ /* We do not send data on this subflow unless it is ++ * fully established, i.e. the 4th ack has been received. ++ */ ++ if (besttp->mptcp->pre_established) ++ continue; ++ ++ blest_p->min_srtt_us = min(blest_p->min_srtt_us, besttp->srtt_us); ++ blest_p->max_srtt_us = max(blest_p->max_srtt_us, besttp->srtt_us); ++ ++ /* record minimal rtt */ ++ if (besttp->srtt_us < min_srtt) { ++ min_srtt = besttp->srtt_us; ++ minsk = bestsk; ++ } ++ } ++ ++ /* find the current best subflow according to the default scheduler */ ++ bestsk = get_available_subflow(meta_sk, skb, zero_wnd_test); ++ ++ /* if we decided to use a slower flow, we have the option of not using it at all */ ++ if (bestsk && minsk && bestsk != minsk) { ++ u32 slow_linger_time, fast_bytes, slow_inflight_bytes, slow_bytes, avail_space; ++ u32 buffered_bytes = 0; ++ ++ meta_tp = tcp_sk(meta_sk); ++ besttp = tcp_sk(bestsk); ++ ++ blestsched_update_lambda(meta_sk, bestsk); ++ ++ /* if we send this SKB now, it will be acked in besttp->srtt seconds ++ * during this time: how many bytes will we send on the fast flow? ++ */ ++ slow_linger_time = blestsched_estimate_linger_time(bestsk); ++ fast_bytes = blestsched_estimate_bytes(minsk, slow_linger_time); ++ ++ if (skb) ++ buffered_bytes = skb->len; ++ ++ /* is the required space available in the mptcp meta send window? ++ * we assume that all bytes inflight on the slow path will be acked in besttp->srtt seconds ++ * (just like the SKB if it was sent now) -> that means that those inflight bytes will ++ * keep occupying space in the meta window until then ++ */ ++ slow_inflight_bytes = besttp->write_seq - besttp->snd_una; ++ slow_bytes = buffered_bytes + slow_inflight_bytes; // bytes of this SKB plus those in flight already ++ ++ avail_space = (slow_bytes < meta_tp->snd_wnd) ? (meta_tp->snd_wnd - slow_bytes) : 0; ++ ++ if (fast_bytes > avail_space) { ++ /* sending this SKB on the slow flow means ++ * we wouldn't be able to send all the data we'd like to send on the fast flow ++ * so don't do that ++ */ ++ return NULL; ++ } ++ } ++ ++ return bestsk; ++} ++ ++/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ ++static struct sk_buff *mptcp_blest_rcv_buf_optimization(struct sock *sk, int penal) ++{ ++ struct sock *meta_sk; ++ const struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_tcp_sock *mptcp; ++ struct sk_buff *skb_head; ++ struct blestsched_priv *blest_p = blestsched_get_priv(tp); ++ struct blestsched_cb *blest_cb; ++ ++ meta_sk = mptcp_meta_sk(sk); ++ skb_head = tcp_rtx_queue_head(meta_sk); ++ ++ if (!skb_head) ++ return NULL; ++ ++ /* If penalization is optional (coming from mptcp_next_segment() and ++ * We are not send-buffer-limited we do not penalize. The retransmission ++ * is just an optimization to fix the idle-time due to the delay before ++ * we wake up the application. ++ */ ++ if (!penal && sk_stream_memory_free(meta_sk)) ++ goto retrans; ++ ++ /* Record the occurrence of a retransmission to update the lambda value */ ++ blest_cb = blestsched_get_cb(tcp_sk(meta_sk)); ++ blest_cb->retrans_flag = true; ++ ++ /* Only penalize again after an RTT has elapsed */ ++ if (tcp_jiffies32 - blest_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) ++ goto retrans; ++ ++ /* Half the cwnd of the slow flows */ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ struct tcp_sock *tp_it = mptcp->tp; ++ ++ if (tp_it != tp && ++ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { ++ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { ++ u32 prior_cwnd = tp_it->snd_cwnd; ++ ++ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); ++ ++ /* If in slow start, do not reduce the ssthresh */ ++ if (prior_cwnd >= tp_it->snd_ssthresh) ++ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); ++ ++ blest_p->last_rbuf_opti = tcp_jiffies32; ++ } ++ } ++ } ++ ++retrans: ++ ++ /* Segment not yet injected into this path? Take it!!! */ ++ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { ++ bool do_retrans = false; ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ struct tcp_sock *tp_it = mptcp->tp; ++ ++ if (tp_it != tp && ++ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { ++ if (tp_it->snd_cwnd <= 4) { ++ do_retrans = true; ++ break; ++ } ++ ++ if (4 * tp->srtt_us >= tp_it->srtt_us) { ++ do_retrans = false; ++ break; ++ } else { ++ do_retrans = true; ++ } ++ } ++ } ++ ++ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { ++ trace_mptcp_retransmit(sk, skb_head); ++ return skb_head; ++ } ++ } ++ return NULL; ++} ++ ++/* copy from mptcp_sched.c: __mptcp_next_segment */ ++/* Returns the next segment to be sent from the mptcp meta-queue. ++ * (chooses the reinject queue if any segment is waiting in it, otherwise, ++ * chooses the normal write queue). ++ * Sets *@reinject to 1 if the returned segment comes from the ++ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, ++ * and sets it to -1 if it is a meta-level retransmission to optimize the ++ * receive-buffer. ++ */ ++static struct sk_buff *__mptcp_blest_next_segment(struct sock *meta_sk, int *reinject) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sk_buff *skb = NULL; ++ ++ *reinject = 0; ++ ++ /* If we are in fallback-mode, just take from the meta-send-queue */ ++ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) ++ return tcp_send_head(meta_sk); ++ ++ skb = skb_peek(&mpcb->reinject_queue); ++ ++ if (skb) { ++ *reinject = 1; ++ } else { ++ skb = tcp_send_head(meta_sk); ++ ++ if (!skb && meta_sk->sk_socket && ++ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && ++ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { ++ struct sock *subsk = blest_get_available_subflow(meta_sk, NULL, ++ false); ++ if (!subsk) ++ return NULL; ++ ++ skb = mptcp_blest_rcv_buf_optimization(subsk, 0); ++ if (skb) ++ *reinject = -1; ++ } ++ } ++ return skb; ++} ++ ++/* copy from mptcp_sched.c: mptcp_next_segment */ ++static struct sk_buff *mptcp_blest_next_segment(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit) ++{ ++ struct sk_buff *skb = __mptcp_blest_next_segment(meta_sk, reinject); ++ unsigned int mss_now; ++ struct tcp_sock *subtp; ++ u16 gso_max_segs; ++ u32 max_len, max_segs, window, needed; ++ ++ /* As we set it, we have to reset it as well. */ ++ *limit = 0; ++ ++ if (!skb) ++ return NULL; ++ ++ *subsk = blest_get_available_subflow(meta_sk, skb, false); ++ if (!*subsk) ++ return NULL; ++ ++ subtp = tcp_sk(*subsk); ++ mss_now = tcp_current_mss(*subsk); ++ ++ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { ++ skb = mptcp_blest_rcv_buf_optimization(*subsk, 1); ++ if (skb) ++ *reinject = -1; ++ else ++ return NULL; ++ } ++ ++ /* No splitting required, as we will only send one single segment */ ++ if (skb->len <= mss_now) ++ return skb; ++ ++ /* The following is similar to tcp_mss_split_point, but ++ * we do not care about nagle, because we will anyways ++ * use TCP_NAGLE_PUSH, which overrides this. ++ * ++ * So, we first limit according to the cwnd/gso-size and then according ++ * to the subflow's window. ++ */ ++ ++ gso_max_segs = (*subsk)->sk_gso_max_segs; ++ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ ++ gso_max_segs = 1; ++ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); ++ if (!max_segs) ++ return NULL; ++ ++ max_len = mss_now * max_segs; ++ window = tcp_wnd_end(subtp) - subtp->write_seq; ++ ++ needed = min(skb->len, window); ++ if (max_len <= skb->len) ++ /* Take max_win, which is actually the cwnd/gso-size */ ++ *limit = max_len; ++ else ++ /* Or, take the window */ ++ *limit = needed; ++ ++ return skb; ++} ++ ++static void blestsched_init(struct sock *sk) ++{ ++ struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); ++ struct blestsched_cb *blest_cb = blestsched_get_cb(tcp_sk(mptcp_meta_sk(sk))); ++ ++ blest_p->last_rbuf_opti = tcp_jiffies32; ++ blest_p->min_srtt_us = U32_MAX; ++ blest_p->max_srtt_us = 0; ++ ++ if (!blest_cb->lambda_1000) { ++ blest_cb->lambda_1000 = lambda * 100; ++ blest_cb->last_lambda_update = tcp_jiffies32; ++ } ++} ++ ++static struct mptcp_sched_ops mptcp_sched_blest = { ++ .get_subflow = blest_get_available_subflow, ++ .next_segment = mptcp_blest_next_segment, ++ .init = blestsched_init, ++ .name = "blest", ++ .owner = THIS_MODULE, ++}; ++ ++static int __init blest_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct blestsched_priv) > MPTCP_SCHED_SIZE); ++ BUILD_BUG_ON(sizeof(struct blestsched_cb) > MPTCP_SCHED_DATA_SIZE); ++ ++ if (mptcp_register_scheduler(&mptcp_sched_blest)) ++ return -1; ++ ++ return 0; ++} ++ ++static void blest_unregister(void) ++{ ++ mptcp_unregister_scheduler(&mptcp_sched_blest); ++} ++ ++module_init(blest_register); ++module_exit(blest_unregister); ++ ++MODULE_AUTHOR("Simone Ferlin, Daniel Weber"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("BLEST scheduler for MPTCP, based on default minimum RTT scheduler"); ++MODULE_VERSION("0.95"); +diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c +--- linux-5.4/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,262 @@ ++/* ++ * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer & Author: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++#include ++#include ++ ++#include ++ ++/* Scaling is done in the numerator with alpha_scale_num and in the denominator ++ * with alpha_scale_den. ++ * ++ * To downscale, we just need to use alpha_scale. ++ * ++ * We have: alpha_scale = alpha_scale_num / (alpha_scale_den ^ 2) ++ */ ++static int alpha_scale_den = 10; ++static int alpha_scale_num = 32; ++static int alpha_scale = 12; ++ ++struct mptcp_ccc { ++ u64 alpha; ++ bool forced_update; ++}; ++ ++static inline int mptcp_ccc_sk_can_send(const struct sock *sk) ++{ ++ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; ++} ++ ++static inline u64 mptcp_get_alpha(const struct sock *meta_sk) ++{ ++ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha; ++} ++ ++static inline void mptcp_set_alpha(const struct sock *meta_sk, u64 alpha) ++{ ++ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha = alpha; ++} ++ ++static inline u64 mptcp_ccc_scale(u32 val, int scale) ++{ ++ return (u64) val << scale; ++} ++ ++static inline bool mptcp_get_forced(const struct sock *meta_sk) ++{ ++ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update; ++} ++ ++static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) ++{ ++ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update = force; ++} ++ ++static void mptcp_ccc_recalc_alpha(const struct sock *sk) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; ++ const struct mptcp_tcp_sock *mptcp; ++ int best_cwnd = 0, best_rtt = 0, can_send = 0; ++ u64 max_numerator = 0, sum_denominator = 0, alpha = 1; ++ ++ if (!mpcb) ++ return; ++ ++ /* Do regular alpha-calculation for multiple subflows */ ++ ++ /* Find the max numerator of the alpha-calculation */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ const struct sock *sub_sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *sub_tp = tcp_sk(sub_sk); ++ u64 tmp; ++ ++ if (!mptcp_ccc_sk_can_send(sub_sk)) ++ continue; ++ ++ can_send++; ++ ++ /* We need to look for the path, that provides the max-value. ++ * Integer-overflow is not possible here, because ++ * tmp will be in u64. ++ */ ++ tmp = div64_u64(mptcp_ccc_scale(sub_tp->snd_cwnd, ++ alpha_scale_num), (u64)sub_tp->srtt_us * sub_tp->srtt_us); ++ ++ if (tmp >= max_numerator) { ++ max_numerator = tmp; ++ best_cwnd = sub_tp->snd_cwnd; ++ best_rtt = sub_tp->srtt_us; ++ } ++ } ++ ++ /* No subflow is able to send - we don't care anymore */ ++ if (unlikely(!can_send)) ++ goto exit; ++ ++ /* Calculate the denominator */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ const struct sock *sub_sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *sub_tp = tcp_sk(sub_sk); ++ ++ if (!mptcp_ccc_sk_can_send(sub_sk)) ++ continue; ++ ++ sum_denominator += div_u64( ++ mptcp_ccc_scale(sub_tp->snd_cwnd, ++ alpha_scale_den) * best_rtt, ++ sub_tp->srtt_us); ++ } ++ sum_denominator *= sum_denominator; ++ if (unlikely(!sum_denominator)) { ++ pr_err("%s: sum_denominator == 0\n", __func__); ++ mptcp_for_each_sub(mpcb, mptcp) { ++ const struct sock *sub_sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *sub_tp = tcp_sk(sub_sk); ++ pr_err("%s: pi:%d, state:%d\n, rtt:%u, cwnd: %u", ++ __func__, sub_tp->mptcp->path_index, ++ sub_sk->sk_state, sub_tp->srtt_us, ++ sub_tp->snd_cwnd); ++ } ++ } ++ ++ alpha = div64_u64(mptcp_ccc_scale(best_cwnd, alpha_scale_num), sum_denominator); ++ ++ if (unlikely(!alpha)) ++ alpha = 1; ++ ++exit: ++ mptcp_set_alpha(mptcp_meta_sk(sk), alpha); ++} ++ ++static void mptcp_ccc_init(struct sock *sk) ++{ ++ if (mptcp(tcp_sk(sk))) { ++ mptcp_set_forced(mptcp_meta_sk(sk), 0); ++ mptcp_set_alpha(mptcp_meta_sk(sk), 1); ++ } ++ /* If we do not mptcp, behave like reno: return */ ++} ++ ++static void mptcp_ccc_cwnd_event(struct sock *sk, enum tcp_ca_event event) ++{ ++ if (event == CA_EVENT_LOSS) ++ mptcp_ccc_recalc_alpha(sk); ++} ++ ++static void mptcp_ccc_set_state(struct sock *sk, u8 ca_state) ++{ ++ if (!mptcp(tcp_sk(sk))) ++ return; ++ ++ mptcp_set_forced(mptcp_meta_sk(sk), 1); ++} ++ ++static void mptcp_ccc_cong_avoid(struct sock *sk, u32 ack, u32 acked) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ int snd_cwnd; ++ u64 alpha; ++ ++ if (!mptcp(tp)) { ++ tcp_reno_cong_avoid(sk, ack, acked); ++ return; ++ } ++ ++ if (!tcp_is_cwnd_limited(sk)) ++ return; ++ ++ if (tcp_in_slow_start(tp)) { ++ /* In "safe" area, increase. */ ++ tcp_slow_start(tp, acked); ++ mptcp_ccc_recalc_alpha(sk); ++ return; ++ } ++ ++ if (mptcp_get_forced(mptcp_meta_sk(sk))) { ++ mptcp_ccc_recalc_alpha(sk); ++ mptcp_set_forced(mptcp_meta_sk(sk), 0); ++ } ++ ++ alpha = mptcp_get_alpha(mptcp_meta_sk(sk)); ++ ++ /* This may happen, if at the initialization, the mpcb ++ * was not yet attached to the sock, and thus ++ * initializing alpha failed. ++ */ ++ if (unlikely(!alpha)) ++ alpha = 1; ++ ++ snd_cwnd = (int)div_u64((u64)mptcp_ccc_scale(1, alpha_scale), alpha); ++ ++ /* snd_cwnd_cnt >= max (scale * tot_cwnd / alpha, cwnd) ++ * Thus, we select here the max value. ++ */ ++ if (snd_cwnd < tp->snd_cwnd) ++ snd_cwnd = tp->snd_cwnd; ++ ++ if (tp->snd_cwnd_cnt >= snd_cwnd) { ++ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { ++ tp->snd_cwnd++; ++ mptcp_ccc_recalc_alpha(sk); ++ } ++ ++ tp->snd_cwnd_cnt = 0; ++ } else { ++ tp->snd_cwnd_cnt++; ++ } ++} ++ ++static struct tcp_congestion_ops mptcp_ccc = { ++ .init = mptcp_ccc_init, ++ .ssthresh = tcp_reno_ssthresh, ++ .cong_avoid = mptcp_ccc_cong_avoid, ++ .undo_cwnd = tcp_reno_undo_cwnd, ++ .cwnd_event = mptcp_ccc_cwnd_event, ++ .set_state = mptcp_ccc_set_state, ++ .owner = THIS_MODULE, ++ .name = "lia", ++}; ++ ++static int __init mptcp_ccc_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct mptcp_ccc) > ICSK_CA_PRIV_SIZE); ++ return tcp_register_congestion_control(&mptcp_ccc); ++} ++ ++static void __exit mptcp_ccc_unregister(void) ++{ ++ tcp_unregister_congestion_control(&mptcp_ccc); ++} ++ ++module_init(mptcp_ccc_register); ++module_exit(mptcp_ccc_unregister); ++ ++MODULE_AUTHOR("Christoph Paasch, Sébastien Barré"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MPTCP LINKED INCREASE CONGESTION CONTROL ALGORITHM"); ++MODULE_VERSION("0.1"); +diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c +--- linux-5.4/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,3142 @@ ++/* ++ * MPTCP implementation - MPTCP-control ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer & Author: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#if IS_ENABLED(CONFIG_IPV6) ++#include ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct kmem_cache *mptcp_sock_cache __read_mostly; ++static struct kmem_cache *mptcp_cb_cache __read_mostly; ++static struct kmem_cache *mptcp_tw_cache __read_mostly; ++ ++int sysctl_mptcp_enabled __read_mostly = 1; ++int sysctl_mptcp_version __read_mostly = 0; ++static int min_mptcp_version; ++static int max_mptcp_version = 1; ++int sysctl_mptcp_checksum __read_mostly = 1; ++int sysctl_mptcp_debug __read_mostly; ++EXPORT_SYMBOL(sysctl_mptcp_debug); ++int sysctl_mptcp_syn_retries __read_mostly = 3; ++ ++bool mptcp_init_failed __read_mostly; ++ ++struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; ++EXPORT_SYMBOL(mptcp_static_key); ++ ++static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn); ++ ++static int proc_mptcp_path_manager(struct ctl_table *ctl, int write, ++ void __user *buffer, size_t *lenp, ++ loff_t *ppos) ++{ ++ char val[MPTCP_PM_NAME_MAX]; ++ struct ctl_table tbl = { ++ .data = val, ++ .maxlen = MPTCP_PM_NAME_MAX, ++ }; ++ int ret; ++ ++ mptcp_get_default_path_manager(val); ++ ++ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); ++ if (write && ret == 0) ++ ret = mptcp_set_default_path_manager(val); ++ return ret; ++} ++ ++static int proc_mptcp_scheduler(struct ctl_table *ctl, int write, ++ void __user *buffer, size_t *lenp, ++ loff_t *ppos) ++{ ++ char val[MPTCP_SCHED_NAME_MAX]; ++ struct ctl_table tbl = { ++ .data = val, ++ .maxlen = MPTCP_SCHED_NAME_MAX, ++ }; ++ int ret; ++ ++ mptcp_get_default_scheduler(val); ++ ++ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); ++ if (write && ret == 0) ++ ret = mptcp_set_default_scheduler(val); ++ return ret; ++} ++ ++static struct ctl_table mptcp_table[] = { ++ { ++ .procname = "mptcp_enabled", ++ .data = &sysctl_mptcp_enabled, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec ++ }, ++ { ++ .procname = "mptcp_version", ++ .data = &sysctl_mptcp_version, ++ .mode = 0644, ++ .maxlen = sizeof(int), ++ .proc_handler = &proc_dointvec_minmax, ++ .extra1 = &min_mptcp_version, ++ .extra2 = &max_mptcp_version, ++ }, ++ { ++ .procname = "mptcp_checksum", ++ .data = &sysctl_mptcp_checksum, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec ++ }, ++ { ++ .procname = "mptcp_debug", ++ .data = &sysctl_mptcp_debug, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec ++ }, ++ { ++ .procname = "mptcp_syn_retries", ++ .data = &sysctl_mptcp_syn_retries, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec ++ }, ++ { ++ .procname = "mptcp_path_manager", ++ .mode = 0644, ++ .maxlen = MPTCP_PM_NAME_MAX, ++ .proc_handler = proc_mptcp_path_manager, ++ }, ++ { ++ .procname = "mptcp_scheduler", ++ .mode = 0644, ++ .maxlen = MPTCP_SCHED_NAME_MAX, ++ .proc_handler = proc_mptcp_scheduler, ++ }, ++ { } ++}; ++ ++static inline u32 mptcp_hash_tk(u32 token) ++{ ++ return token % MPTCP_HASH_SIZE; ++} ++ ++struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; ++EXPORT_SYMBOL(tk_hashtable); ++ ++/* The following hash table is used to avoid collision of token */ ++static struct hlist_nulls_head mptcp_reqsk_tk_htb[MPTCP_HASH_SIZE]; ++ ++/* Lock, protecting the two hash-tables that hold the token. Namely, ++ * mptcp_reqsk_tk_htb and tk_hashtable ++ */ ++static spinlock_t mptcp_tk_hashlock; ++ ++static bool mptcp_reqsk_find_tk(const u32 token) ++{ ++ const u32 hash = mptcp_hash_tk(token); ++ const struct mptcp_request_sock *mtreqsk; ++ const struct hlist_nulls_node *node; ++ ++begin: ++ hlist_nulls_for_each_entry_rcu(mtreqsk, node, ++ &mptcp_reqsk_tk_htb[hash], hash_entry) { ++ if (token == mtreqsk->mptcp_loc_token) ++ return true; ++ } ++ /* A request-socket is destroyed by RCU. So, it might have been recycled ++ * and put into another hash-table list. So, after the lookup we may ++ * end up in a different list. So, we may need to restart. ++ * ++ * See also the comment in __inet_lookup_established. ++ */ ++ if (get_nulls_value(node) != hash) ++ goto begin; ++ return false; ++} ++ ++static void mptcp_reqsk_insert_tk(struct request_sock *reqsk, const u32 token) ++{ ++ u32 hash = mptcp_hash_tk(token); ++ ++ hlist_nulls_add_head_rcu(&mptcp_rsk(reqsk)->hash_entry, ++ &mptcp_reqsk_tk_htb[hash]); ++} ++ ++static void mptcp_reqsk_remove_tk(const struct request_sock *reqsk) ++{ ++ rcu_read_lock(); ++ local_bh_disable(); ++ spin_lock(&mptcp_tk_hashlock); ++ hlist_nulls_del_init_rcu(&mptcp_rsk(reqsk)->hash_entry); ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++} ++ ++void mptcp_reqsk_destructor(struct request_sock *req) ++{ ++ if (!mptcp_rsk(req)->is_sub) ++ mptcp_reqsk_remove_tk(req); ++} ++ ++static void __mptcp_hash_insert(struct tcp_sock *meta_tp, const u32 token) ++{ ++ u32 hash = mptcp_hash_tk(token); ++ hlist_nulls_add_head_rcu(&meta_tp->tk_table, &tk_hashtable[hash]); ++ meta_tp->inside_tk_table = 1; ++} ++ ++static bool mptcp_find_token(u32 token) ++{ ++ const u32 hash = mptcp_hash_tk(token); ++ const struct tcp_sock *meta_tp; ++ const struct hlist_nulls_node *node; ++ ++begin: ++ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], tk_table) { ++ if (token == meta_tp->mptcp_loc_token) ++ return true; ++ } ++ /* A TCP-socket is destroyed by RCU. So, it might have been recycled ++ * and put into another hash-table list. So, after the lookup we may ++ * end up in a different list. So, we may need to restart. ++ * ++ * See also the comment in __inet_lookup_established. ++ */ ++ if (get_nulls_value(node) != hash) ++ goto begin; ++ return false; ++} ++ ++static void mptcp_set_key_reqsk(struct request_sock *req, ++ const struct sk_buff *skb, ++ u32 seed) ++{ ++ const struct inet_request_sock *ireq = inet_rsk(req); ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ mtreq->mptcp_loc_key = mptcp_v4_get_key(ip_hdr(skb)->saddr, ++ ip_hdr(skb)->daddr, ++ htons(ireq->ir_num), ++ ireq->ir_rmt_port, ++ seed); ++#if IS_ENABLED(CONFIG_IPV6) ++ } else { ++ mtreq->mptcp_loc_key = mptcp_v6_get_key(ipv6_hdr(skb)->saddr.s6_addr32, ++ ipv6_hdr(skb)->daddr.s6_addr32, ++ htons(ireq->ir_num), ++ ireq->ir_rmt_port, ++ seed); ++#endif ++ } ++ ++ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); ++} ++ ++/* New MPTCP-connection request, prepare a new token for the meta-socket that ++ * will be created in mptcp_check_req_master(), and store the received token. ++ */ ++static void mptcp_reqsk_new_mptcp(struct request_sock *req, ++ const struct sock *sk, ++ const struct mptcp_options_received *mopt, ++ const struct sk_buff *skb) ++{ ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ const struct tcp_sock *tp = tcp_sk(sk); ++ ++ inet_rsk(req)->saw_mpc = 1; ++ ++ /* MPTCP version agreement */ ++ if (mopt->mptcp_ver >= tp->mptcp_ver) ++ mtreq->mptcp_ver = tp->mptcp_ver; ++ else ++ mtreq->mptcp_ver = mopt->mptcp_ver; ++ ++ rcu_read_lock(); ++ local_bh_disable(); ++ spin_lock(&mptcp_tk_hashlock); ++ do { ++ mptcp_set_key_reqsk(req, skb, mptcp_seed++); ++ } while (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || ++ mptcp_find_token(mtreq->mptcp_loc_token)); ++ mptcp_reqsk_insert_tk(req, mtreq->mptcp_loc_token); ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++} ++ ++static int mptcp_reqsk_new_cookie(struct request_sock *req, ++ const struct sock *sk, ++ const struct mptcp_options_received *mopt, ++ const struct sk_buff *skb) ++{ ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ ++ /* MPTCP version agreement */ ++ if (mopt->mptcp_ver >= tcp_sk(sk)->mptcp_ver) ++ mtreq->mptcp_ver = tcp_sk(sk)->mptcp_ver; ++ else ++ mtreq->mptcp_ver = mopt->mptcp_ver; ++ ++ rcu_read_lock(); ++ local_bh_disable(); ++ spin_lock(&mptcp_tk_hashlock); ++ ++ mptcp_set_key_reqsk(req, skb, tcp_rsk(req)->snt_isn); ++ ++ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || ++ mptcp_find_token(mtreq->mptcp_loc_token)) { ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++ return false; ++ } ++ ++ inet_rsk(req)->saw_mpc = 1; ++ ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++ ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ ++ return true; ++} ++ ++static void mptcp_set_key_sk(const struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ const struct inet_sock *isk = inet_sk(sk); ++ ++ if (sk->sk_family == AF_INET) ++ tp->mptcp_loc_key = mptcp_v4_get_key(isk->inet_saddr, ++ isk->inet_daddr, ++ isk->inet_sport, ++ isk->inet_dport, ++ mptcp_seed++); ++#if IS_ENABLED(CONFIG_IPV6) ++ else ++ tp->mptcp_loc_key = mptcp_v6_get_key(inet6_sk(sk)->saddr.s6_addr32, ++ sk->sk_v6_daddr.s6_addr32, ++ isk->inet_sport, ++ isk->inet_dport, ++ mptcp_seed++); ++#endif ++ ++ mptcp_key_sha1(tp->mptcp_loc_key, ++ &tp->mptcp_loc_token, NULL); ++} ++ ++#ifdef CONFIG_JUMP_LABEL ++static atomic_t mptcp_needed_deferred; ++static atomic_t mptcp_wanted; ++ ++static void mptcp_clear(struct work_struct *work) ++{ ++ int deferred = atomic_xchg(&mptcp_needed_deferred, 0); ++ int wanted; ++ ++ wanted = atomic_add_return(deferred, &mptcp_wanted); ++ if (wanted > 0) ++ static_key_enable(&mptcp_static_key); ++ else ++ static_key_disable(&mptcp_static_key); ++} ++ ++static DECLARE_WORK(mptcp_work, mptcp_clear); ++#endif ++ ++static void mptcp_enable_static_key_bh(void) ++{ ++#ifdef CONFIG_JUMP_LABEL ++ int wanted; ++ ++ while (1) { ++ wanted = atomic_read(&mptcp_wanted); ++ if (wanted <= 0) ++ break; ++ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted + 1) == wanted) ++ return; ++ } ++ atomic_inc(&mptcp_needed_deferred); ++ schedule_work(&mptcp_work); ++#else ++ static_key_slow_inc(&mptcp_static_key); ++#endif ++} ++ ++static void mptcp_enable_static_key(void) ++{ ++#ifdef CONFIG_JUMP_LABEL ++ atomic_inc(&mptcp_wanted); ++ static_key_enable(&mptcp_static_key); ++#else ++ static_key_slow_inc(&mptcp_static_key); ++#endif ++} ++ ++void mptcp_disable_static_key(void) ++{ ++#ifdef CONFIG_JUMP_LABEL ++ int wanted; ++ ++ while (1) { ++ wanted = atomic_read(&mptcp_wanted); ++ if (wanted <= 1) ++ break; ++ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted - 1) == wanted) ++ return; ++ } ++ atomic_dec(&mptcp_needed_deferred); ++ schedule_work(&mptcp_work); ++#else ++ static_key_slow_dec(&mptcp_static_key); ++#endif ++} ++ ++void mptcp_enable_sock(struct sock *sk) ++{ ++ if (!sock_flag(sk, SOCK_MPTCP)) { ++ sock_set_flag(sk, SOCK_MPTCP); ++ tcp_sk(sk)->mptcp_ver = sysctl_mptcp_version; ++ ++ /* Necessary here, because MPTCP can be enabled/disabled through ++ * a setsockopt. ++ */ ++ if (sk->sk_family == AF_INET) ++ inet_csk(sk)->icsk_af_ops = &mptcp_v4_specific; ++#if IS_ENABLED(CONFIG_IPV6) ++ else if (mptcp_v6_is_v4_mapped(sk)) ++ inet_csk(sk)->icsk_af_ops = &mptcp_v6_mapped; ++ else ++ inet_csk(sk)->icsk_af_ops = &mptcp_v6_specific; ++#endif ++ ++ mptcp_enable_static_key(); ++ } ++} ++ ++void mptcp_disable_sock(struct sock *sk) ++{ ++ if (sock_flag(sk, SOCK_MPTCP)) { ++ sock_reset_flag(sk, SOCK_MPTCP); ++ ++ /* Necessary here, because MPTCP can be enabled/disabled through ++ * a setsockopt. ++ */ ++ if (sk->sk_family == AF_INET) ++ inet_csk(sk)->icsk_af_ops = &ipv4_specific; ++#if IS_ENABLED(CONFIG_IPV6) ++ else if (mptcp_v6_is_v4_mapped(sk)) ++ inet_csk(sk)->icsk_af_ops = &ipv6_mapped; ++ else ++ inet_csk(sk)->icsk_af_ops = &ipv6_specific; ++#endif ++ ++ mptcp_disable_static_key(); ++ } ++} ++ ++void mptcp_connect_init(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ rcu_read_lock(); ++ local_bh_disable(); ++ spin_lock(&mptcp_tk_hashlock); ++ do { ++ mptcp_set_key_sk(sk); ++ } while (mptcp_reqsk_find_tk(tp->mptcp_loc_token) || ++ mptcp_find_token(tp->mptcp_loc_token)); ++ ++ __mptcp_hash_insert(tp, tp->mptcp_loc_token); ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE); ++} ++ ++/** ++ * This function increments the refcount of the mpcb struct. ++ * It is the responsibility of the caller to decrement when releasing ++ * the structure. ++ */ ++struct sock *mptcp_hash_find(const struct net *net, const u32 token) ++{ ++ const u32 hash = mptcp_hash_tk(token); ++ const struct tcp_sock *meta_tp; ++ struct sock *meta_sk = NULL; ++ const struct hlist_nulls_node *node; ++ ++ rcu_read_lock(); ++ local_bh_disable(); ++begin: ++ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], ++ tk_table) { ++ meta_sk = (struct sock *)meta_tp; ++ if (token == meta_tp->mptcp_loc_token && ++ net_eq(net, sock_net(meta_sk))) { ++ if (unlikely(!refcount_inc_not_zero(&meta_sk->sk_refcnt))) ++ goto out; ++ if (unlikely(token != meta_tp->mptcp_loc_token || ++ !net_eq(net, sock_net(meta_sk)))) { ++ sock_gen_put(meta_sk); ++ goto begin; ++ } ++ goto found; ++ } ++ } ++ /* A TCP-socket is destroyed by RCU. So, it might have been recycled ++ * and put into another hash-table list. So, after the lookup we may ++ * end up in a different list. So, we may need to restart. ++ * ++ * See also the comment in __inet_lookup_established. ++ */ ++ if (get_nulls_value(node) != hash) ++ goto begin; ++out: ++ meta_sk = NULL; ++found: ++ local_bh_enable(); ++ rcu_read_unlock(); ++ return meta_sk; ++} ++EXPORT_SYMBOL_GPL(mptcp_hash_find); ++ ++void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) ++{ ++ /* remove from the token hashtable */ ++ rcu_read_lock(); ++ local_bh_disable(); ++ spin_lock(&mptcp_tk_hashlock); ++ hlist_nulls_del_init_rcu(&meta_tp->tk_table); ++ meta_tp->inside_tk_table = 0; ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++} ++ ++struct sock *mptcp_select_ack_sock(const struct sock *meta_sk) ++{ ++ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct sock *rttsk = NULL, *lastsk = NULL; ++ u32 min_time = 0, last_active = 0; ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp = tcp_sk(sk); ++ u32 elapsed; ++ ++ if (!mptcp_sk_can_send_ack(sk) || tp->pf) ++ continue; ++ ++ elapsed = keepalive_time_elapsed(tp); ++ ++ /* We take the one with the lowest RTT within a reasonable ++ * (meta-RTO)-timeframe ++ */ ++ if (elapsed < inet_csk(meta_sk)->icsk_rto) { ++ if (!min_time || tp->srtt_us < min_time) { ++ min_time = tp->srtt_us; ++ rttsk = sk; ++ } ++ continue; ++ } ++ ++ /* Otherwise, we just take the most recent active */ ++ if (!rttsk && (!last_active || elapsed < last_active)) { ++ last_active = elapsed; ++ lastsk = sk; ++ } ++ } ++ ++ if (rttsk) ++ return rttsk; ++ ++ return lastsk; ++} ++EXPORT_SYMBOL(mptcp_select_ack_sock); ++ ++static void mptcp_sock_def_error_report(struct sock *sk) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (!sock_flag(sk, SOCK_DEAD)) { ++ if (tp->send_mp_fclose && sk->sk_err == ETIMEDOUT) { ++ /* Called by the keep alive timer (tcp_write_timeout), ++ * when the limit of fastclose retransmissions has been ++ * reached. Send a TCP RST to clear the status of any ++ * stateful firewall (typically conntrack) which are ++ * not aware of mptcp and cannot understand the ++ * fastclose option. ++ */ ++ tp->ops->send_active_reset(sk, GFP_ATOMIC); ++ } ++ } ++ ++ /* record this info that can be used by PM after the sf close */ ++ tp->mptcp->sk_err = sk->sk_err; ++ ++ if (!tp->tcp_disconnect && mptcp_in_infinite_mapping_weak(mpcb)) { ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ meta_sk->sk_err = sk->sk_err; ++ meta_sk->sk_err_soft = sk->sk_err_soft; ++ ++ if (!sock_flag(meta_sk, SOCK_DEAD)) ++ meta_sk->sk_error_report(meta_sk); ++ ++ WARN(meta_sk->sk_state == TCP_CLOSE, ++ "Meta already closed i_rcv %u i_snd %u send_i %u flags %#lx\n", ++ mpcb->infinite_mapping_rcv, mpcb->infinite_mapping_snd, ++ mpcb->send_infinite_mapping, meta_sk->sk_flags); ++ ++ if (meta_sk->sk_state != TCP_CLOSE) ++ tcp_done(meta_sk); ++ } ++ ++ sk->sk_err = 0; ++ return; ++} ++ ++void mptcp_mpcb_put(struct mptcp_cb *mpcb) ++{ ++ if (refcount_dec_and_test(&mpcb->mpcb_refcnt)) { ++ mptcp_cleanup_path_manager(mpcb); ++ mptcp_cleanup_scheduler(mpcb); ++ kfree(mpcb->master_info); ++ kmem_cache_free(mptcp_cb_cache, mpcb); ++ } ++} ++EXPORT_SYMBOL(mptcp_mpcb_put); ++ ++static void mptcp_mpcb_cleanup(struct mptcp_cb *mpcb) ++{ ++ struct mptcp_tw *mptw; ++ ++ /* The mpcb is disappearing - we can make the final ++ * update to the rcv_nxt of the time-wait-sock and remove ++ * its reference to the mpcb. ++ */ ++ spin_lock_bh(&mpcb->mpcb_list_lock); ++ list_for_each_entry_rcu(mptw, &mpcb->tw_list, list) { ++ list_del_rcu(&mptw->list); ++ mptw->in_list = 0; ++ mptcp_mpcb_put(mpcb); ++ rcu_assign_pointer(mptw->mpcb, NULL); ++ } ++ spin_unlock_bh(&mpcb->mpcb_list_lock); ++ ++ mptcp_mpcb_put(mpcb); ++} ++ ++static void mptcp_sock_destruct(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (!is_meta_sk(sk)) { ++ BUG_ON(!hlist_unhashed(&tp->mptcp->cb_list)); ++ ++ kmem_cache_free(mptcp_sock_cache, tp->mptcp); ++ tp->mptcp = NULL; ++ ++ /* Taken when mpcb pointer was set */ ++ sock_put(mptcp_meta_sk(sk)); ++ mptcp_mpcb_put(tp->mpcb); ++ } else { ++ mptcp_debug("%s destroying meta-sk token %#x\n", __func__, ++ tcp_sk(sk)->mpcb->mptcp_loc_token); ++ ++ mptcp_mpcb_cleanup(tp->mpcb); ++ } ++ ++ WARN_ON(!static_key_false(&mptcp_static_key)); ++ ++ /* Must be called here, because this will decrement the jump-label. */ ++ inet_sock_destruct(sk); ++} ++ ++void mptcp_destroy_sock(struct sock *sk) ++{ ++ if (is_meta_sk(sk)) { ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ __skb_queue_purge(&tcp_sk(sk)->mpcb->reinject_queue); ++ ++ /* We have to close all remaining subflows. Normally, they ++ * should all be about to get closed. But, if the kernel is ++ * forcing a closure (e.g., tcp_write_err), the subflows might ++ * not have been closed properly (as we are waiting for the ++ * DATA_ACK of the DATA_FIN). ++ */ ++ mptcp_for_each_sub_safe(tcp_sk(sk)->mpcb, mptcp, tmp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ /* Already did call tcp_close - waiting for graceful ++ * closure, or if we are retransmitting fast-close on ++ * the subflow. The reset (or timeout) will kill the ++ * subflow.. ++ */ ++ if (tcp_sk(sk_it)->closing || ++ tcp_sk(sk_it)->send_mp_fclose) ++ continue; ++ ++ /* Allow the delayed work first to prevent time-wait state */ ++ if (delayed_work_pending(&tcp_sk(sk_it)->mptcp->work)) ++ continue; ++ ++ mptcp_sub_close(sk_it, 0); ++ } ++ } else { ++ mptcp_del_sock(sk); ++ } ++} ++ ++static void mptcp_set_state(struct sock *sk) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ /* Meta is not yet established - wake up the application */ ++ if ((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV) && ++ sk->sk_state == TCP_ESTABLISHED) { ++ tcp_set_state(meta_sk, TCP_ESTABLISHED); ++ ++ if (!sock_flag(meta_sk, SOCK_DEAD)) { ++ meta_sk->sk_state_change(meta_sk); ++ sk_wake_async(meta_sk, SOCK_WAKE_IO, POLL_OUT); ++ } ++ ++ tcp_sk(meta_sk)->lsndtime = tcp_jiffies32; ++ } ++ ++ if (sk->sk_state == TCP_CLOSE) { ++ if (!sock_flag(sk, SOCK_DEAD)) ++ mptcp_sub_close(sk, 0); ++ } ++} ++ ++static int mptcp_set_congestion_control(struct sock *meta_sk, const char *name, ++ bool load, bool reinit, bool cap_net_admin) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ int err, result = 0; ++ ++ result = __tcp_set_congestion_control(meta_sk, name, load, reinit, cap_net_admin); ++ ++ tcp_sk(meta_sk)->mpcb->tcp_ca_explicit_set = true; ++ ++ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ err = __tcp_set_congestion_control(sk_it, name, load, reinit, cap_net_admin); ++ if (err) ++ result = err; ++ } ++ return result; ++} ++ ++static void mptcp_assign_congestion_control(struct sock *sk) ++{ ++ struct inet_connection_sock *icsk = inet_csk(sk); ++ struct inet_connection_sock *meta_icsk = inet_csk(mptcp_meta_sk(sk)); ++ const struct tcp_congestion_ops *ca = meta_icsk->icsk_ca_ops; ++ ++ /* Congestion control is the same as meta. Thus, it has been ++ * try_module_get'd by tcp_assign_congestion_control. ++ * Congestion control on meta was not explicitly configured by ++ * application, leave default or route based. ++ */ ++ if (icsk->icsk_ca_ops == ca || ++ !tcp_sk(mptcp_meta_sk(sk))->mpcb->tcp_ca_explicit_set) ++ return; ++ ++ /* Use the same congestion control as set on the meta-sk */ ++ if (!try_module_get(ca->owner)) { ++ /* This should never happen. The congestion control is linked ++ * to the meta-socket (through tcp_assign_congestion_control) ++ * who "holds" the refcnt on the module. ++ */ ++ WARN(1, "Could not get the congestion control!"); ++ return; ++ } ++ module_put(icsk->icsk_ca_ops->owner); ++ icsk->icsk_ca_ops = ca; ++ ++ /* Clear out private data before diag gets it and ++ * the ca has not been initialized. ++ */ ++ if (ca->get_info) ++ memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); ++ ++ return; ++} ++ ++siphash_key_t mptcp_secret __read_mostly; ++u32 mptcp_seed = 0; ++ ++static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) ++{ ++ u32 workspace[SHA_WORKSPACE_WORDS]; ++ u32 mptcp_hashed_key[SHA_DIGEST_WORDS]; ++ u8 input[64]; ++ int i; ++ ++ memset(workspace, 0, sizeof(workspace)); ++ ++ /* Initialize input with appropriate padding */ ++ memset(&input[9], 0, sizeof(input) - 10); /* -10, because the last byte ++ * is explicitly set too ++ */ ++ memcpy(input, &key, sizeof(key)); /* Copy key to the msg beginning */ ++ input[8] = 0x80; /* Padding: First bit after message = 1 */ ++ input[63] = 0x40; /* Padding: Length of the message = 64 bits */ ++ ++ sha_init(mptcp_hashed_key); ++ sha_transform(mptcp_hashed_key, input, workspace); ++ ++ for (i = 0; i < 5; i++) ++ mptcp_hashed_key[i] = (__force u32)cpu_to_be32(mptcp_hashed_key[i]); ++ ++ if (token) ++ *token = mptcp_hashed_key[0]; ++ if (idsn) ++ *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[3])); ++} ++ ++void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, ...) ++{ ++ u32 workspace[SHA_WORKSPACE_WORDS]; ++ u8 input[128]; /* 2 512-bit blocks */ ++ int i; ++ int index; ++ int length; ++ u8 *msg; ++ va_list list; ++ ++ memset(workspace, 0, sizeof(workspace)); ++ ++ /* Generate key xored with ipad */ ++ memset(input, 0x36, 64); ++ for (i = 0; i < 8; i++) ++ input[i] ^= key_1[i]; ++ for (i = 0; i < 8; i++) ++ input[i + 8] ^= key_2[i]; ++ ++ va_start(list, arg_num); ++ index = 64; ++ for (i = 0; i < arg_num; i++) { ++ length = va_arg(list, int); ++ msg = va_arg(list, u8 *); ++ BUG_ON(index + length > 125); /* Message is too long */ ++ memcpy(&input[index], msg, length); ++ index += length; ++ } ++ va_end(list); ++ ++ input[index] = 0x80; /* Padding: First bit after message = 1 */ ++ memset(&input[index + 1], 0, (126 - index)); ++ ++ /* Padding: Length of the message = 512 + message length (bits) */ ++ input[126] = 0x02; ++ input[127] = ((index - 64) * 8); /* Message length (bits) */ ++ ++ sha_init(hash_out); ++ sha_transform(hash_out, input, workspace); ++ memset(workspace, 0, sizeof(workspace)); ++ ++ sha_transform(hash_out, &input[64], workspace); ++ memset(workspace, 0, sizeof(workspace)); ++ ++ for (i = 0; i < 5; i++) ++ hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); ++ ++ /* Prepare second part of hmac */ ++ memset(input, 0x5C, 64); ++ for (i = 0; i < 8; i++) ++ input[i] ^= key_1[i]; ++ for (i = 0; i < 8; i++) ++ input[i + 8] ^= key_2[i]; ++ ++ memcpy(&input[64], hash_out, 20); ++ input[84] = 0x80; ++ memset(&input[85], 0, 41); ++ ++ /* Padding: Length of the message = 512 + 160 bits */ ++ input[126] = 0x02; ++ input[127] = 0xA0; ++ ++ sha_init(hash_out); ++ sha_transform(hash_out, input, workspace); ++ memset(workspace, 0, sizeof(workspace)); ++ ++ sha_transform(hash_out, &input[64], workspace); ++ ++ for (i = 0; i < 5; i++) ++ hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); ++} ++EXPORT_SYMBOL(mptcp_hmac_sha1); ++ ++static void mptcp_mpcb_inherit_sockopts(struct sock *meta_sk, struct sock *master_sk) ++{ ++ /* Socket-options handled by sk_clone_lock while creating the meta-sk. ++ * ====== ++ * SO_SNDBUF, SO_SNDBUFFORCE, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVLOWAT, ++ * SO_RCVTIMEO, SO_SNDTIMEO, SO_ATTACH_FILTER, SO_DETACH_FILTER, ++ * TCP_NODELAY, TCP_CORK ++ * ++ * Socket-options handled in this function here ++ * ====== ++ * TCP_DEFER_ACCEPT ++ * SO_KEEPALIVE ++ * ++ * Socket-options on the todo-list ++ * ====== ++ * SO_BINDTODEVICE - should probably prevent creation of new subsocks ++ * across other devices. - what about the api-draft? ++ * SO_DEBUG ++ * SO_REUSEADDR - probably we don't care about this ++ * SO_DONTROUTE, SO_BROADCAST ++ * SO_OOBINLINE ++ * SO_LINGER ++ * SO_TIMESTAMP* - I don't think this is of concern for a SOCK_STREAM ++ * SO_PASSSEC - I don't think this is of concern for a SOCK_STREAM ++ * SO_RXQ_OVFL ++ * TCP_COOKIE_TRANSACTIONS ++ * TCP_MAXSEG ++ * TCP_THIN_* - Handled by sk_clone_lock, but we need to support this ++ * in mptcp_meta_retransmit_timer. AND we need to check ++ * what is about the subsockets. ++ * TCP_LINGER2 ++ * TCP_WINDOW_CLAMP ++ * TCP_USER_TIMEOUT ++ * TCP_MD5SIG ++ * ++ * Socket-options of no concern for the meta-socket (but for the subsocket) ++ * ====== ++ * SO_PRIORITY ++ * SO_MARK ++ * TCP_CONGESTION ++ * TCP_SYNCNT ++ * TCP_QUICKACK ++ */ ++ ++ /* DEFER_ACCEPT should not be set on the meta, as we want to accept new subflows directly */ ++ inet_csk(meta_sk)->icsk_accept_queue.rskq_defer_accept = 0; ++ ++ /* Keepalives are handled entirely at the MPTCP-layer */ ++ if (sock_flag(meta_sk, SOCK_KEEPOPEN)) { ++ inet_csk_reset_keepalive_timer(meta_sk, ++ keepalive_time_when(tcp_sk(meta_sk))); ++ sock_reset_flag(master_sk, SOCK_KEEPOPEN); ++ inet_csk_delete_keepalive_timer(master_sk); ++ } ++ ++ /* Do not propagate subflow-errors up to the MPTCP-layer */ ++ inet_sk(master_sk)->recverr = 0; ++} ++ ++/* Called without holding lock on meta_sk */ ++static void mptcp_sub_inherit_sockopts(const struct sock *meta_sk, struct sock *sub_sk) ++{ ++ __u8 meta_tos; ++ ++ /* IP_TOS also goes to the subflow. */ ++ meta_tos = READ_ONCE(inet_sk(meta_sk)->tos); ++ if (inet_sk(sub_sk)->tos != meta_tos) { ++ inet_sk(sub_sk)->tos = meta_tos; ++ sub_sk->sk_priority = meta_sk->sk_priority; ++ sk_dst_reset(sub_sk); ++ } ++ ++ /* Inherit SO_REUSEADDR */ ++ sub_sk->sk_reuse = meta_sk->sk_reuse; ++ ++ /* Inherit SO_MARK: can be used for routing or filtering */ ++ sub_sk->sk_mark = meta_sk->sk_mark; ++ ++ /* Inherit snd/rcv-buffer locks */ ++ sub_sk->sk_userlocks = meta_sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; ++ ++ /* Nagle/Cork is forced off on the subflows. It is handled at the meta-layer */ ++ tcp_sk(sub_sk)->nonagle = TCP_NAGLE_OFF|TCP_NAGLE_PUSH; ++ ++ /* Keepalives are handled entirely at the MPTCP-layer */ ++ if (sock_flag(sub_sk, SOCK_KEEPOPEN)) { ++ sock_reset_flag(sub_sk, SOCK_KEEPOPEN); ++ inet_csk_delete_keepalive_timer(sub_sk); ++ } ++ ++ /* Do not propagate subflow-errors up to the MPTCP-layer */ ++ inet_sk(sub_sk)->recverr = 0; ++} ++ ++void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) ++{ ++ /* In case of success (in mptcp_backlog_rcv) and error (in kfree_skb) of ++ * sk_add_backlog, we will decrement the sk refcount. ++ */ ++ sock_hold(sk); ++ skb->sk = sk; ++ skb->destructor = sock_efree; ++} ++ ++int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb) ++{ ++ /* skb-sk may be NULL if we receive a packet immediatly after the ++ * SYN/ACK + MP_CAPABLE. ++ */ ++ struct sock *sk = skb->sk ? skb->sk : meta_sk; ++ int ret = 0; ++ ++ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) { ++ kfree_skb(skb); ++ return 0; ++ } ++ ++ /* Decrement sk refcnt when calling the skb destructor. ++ * Refcnt is incremented and skb destructor is set in tcp_v{4,6}_rcv via ++ * mptcp_prepare_for_backlog() here above. ++ */ ++ skb_orphan(skb); ++ ++ if (sk->sk_family == AF_INET) ++ ret = tcp_v4_do_rcv(sk, skb); ++#if IS_ENABLED(CONFIG_IPV6) ++ else ++ ret = tcp_v6_do_rcv(sk, skb); ++#endif ++ ++ sock_put(sk); ++ return ret; ++} ++ ++static void mptcp_init_buffer_space(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ int space; ++ ++ tcp_init_buffer_space(sk); ++ ++ if (is_master_tp(tp)) { ++ meta_tp->rcvq_space.space = meta_tp->rcv_wnd; ++ tcp_mstamp_refresh(meta_tp); ++ meta_tp->rcvq_space.time = meta_tp->tcp_mstamp; ++ meta_tp->rcvq_space.seq = meta_tp->copied_seq; ++ ++ /* If there is only one subflow, we just use regular TCP ++ * autotuning. User-locks are handled already by ++ * tcp_init_buffer_space ++ */ ++ meta_tp->window_clamp = tp->window_clamp; ++ meta_tp->rcv_ssthresh = tp->rcv_ssthresh; ++ meta_sk->sk_rcvbuf = sk->sk_rcvbuf; ++ meta_sk->sk_sndbuf = sk->sk_sndbuf; ++ ++ return; ++ } ++ ++ if (meta_sk->sk_userlocks & SOCK_RCVBUF_LOCK) ++ goto snd_buf; ++ ++ /* Adding a new subflow to the rcv-buffer space. We make a simple ++ * addition, to give some space to allow traffic on the new subflow. ++ * Autotuning will increase it further later on. ++ */ ++ space = min(meta_sk->sk_rcvbuf + sk->sk_rcvbuf, ++ sock_net(meta_sk)->ipv4.sysctl_tcp_rmem[2]); ++ if (space > meta_sk->sk_rcvbuf) { ++ meta_tp->window_clamp += tp->window_clamp; ++ meta_tp->rcv_ssthresh += tp->rcv_ssthresh; ++ meta_sk->sk_rcvbuf = space; ++ } ++ ++snd_buf: ++ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) ++ return; ++ ++ /* Adding a new subflow to the send-buffer space. We make a simple ++ * addition, to give some space to allow traffic on the new subflow. ++ * Autotuning will increase it further later on. ++ */ ++ space = min(meta_sk->sk_sndbuf + sk->sk_sndbuf, ++ sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]); ++ if (space > meta_sk->sk_sndbuf) { ++ meta_sk->sk_sndbuf = space; ++ meta_sk->sk_write_space(meta_sk); ++ } ++} ++ ++struct lock_class_key meta_key; ++char *meta_key_name = "sk_lock-AF_INET-MPTCP"; ++struct lock_class_key meta_slock_key; ++char *meta_slock_key_name = "slock-AF_INET-MPTCP"; ++ ++static const struct tcp_sock_ops mptcp_meta_specific = { ++ .__select_window = __mptcp_select_window, ++ .select_window = mptcp_select_window, ++ .select_initial_window = mptcp_select_initial_window, ++ .init_buffer_space = mptcp_init_buffer_space, ++ .set_rto = mptcp_tcp_set_rto, ++ .should_expand_sndbuf = mptcp_should_expand_sndbuf, ++ .send_fin = mptcp_send_fin, ++ .write_xmit = mptcp_write_xmit, ++ .send_active_reset = mptcp_send_active_reset, ++ .write_wakeup = mptcp_write_wakeup, ++ .retransmit_timer = mptcp_meta_retransmit_timer, ++ .time_wait = mptcp_time_wait, ++ .cleanup_rbuf = mptcp_cleanup_rbuf, ++ .set_cong_ctrl = mptcp_set_congestion_control, ++}; ++ ++static const struct tcp_sock_ops mptcp_sub_specific = { ++ .__select_window = __mptcp_select_window, ++ .select_window = mptcp_select_window, ++ .select_initial_window = mptcp_select_initial_window, ++ .init_buffer_space = mptcp_init_buffer_space, ++ .set_rto = mptcp_tcp_set_rto, ++ .should_expand_sndbuf = mptcp_should_expand_sndbuf, ++ .send_fin = tcp_send_fin, ++ .write_xmit = tcp_write_xmit, ++ .send_active_reset = tcp_send_active_reset, ++ .write_wakeup = tcp_write_wakeup, ++ .retransmit_timer = mptcp_sub_retransmit_timer, ++ .time_wait = tcp_time_wait, ++ .cleanup_rbuf = tcp_cleanup_rbuf, ++ .set_cong_ctrl = __tcp_set_congestion_control, ++}; ++ ++static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, ++ __u8 mptcp_ver, u32 window) ++{ ++ struct mptcp_cb *mpcb; ++ struct sock *master_sk; ++ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); ++ struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk); ++ u64 snd_idsn, rcv_idsn; ++ ++ dst_release(meta_sk->sk_rx_dst); ++ meta_sk->sk_rx_dst = NULL; ++ /* This flag is set to announce sock_lock_init to ++ * reclassify the lock-class of the master socket. ++ */ ++ meta_tp->is_master_sk = 1; ++ master_sk = sk_clone_lock(meta_sk, GFP_ATOMIC | __GFP_ZERO); ++ meta_tp->is_master_sk = 0; ++ if (!master_sk) ++ goto err_alloc_master; ++ ++ master_tp = tcp_sk(master_sk); ++ master_tp->inside_tk_table = 0; ++ ++ mpcb = kmem_cache_zalloc(mptcp_cb_cache, GFP_ATOMIC); ++ if (!mpcb) ++ goto err_alloc_mpcb; ++ ++ /* Store the mptcp version agreed on initial handshake */ ++ mpcb->mptcp_ver = mptcp_ver; ++ ++ /* Store the keys and generate the peer's token */ ++ mpcb->mptcp_loc_key = meta_tp->mptcp_loc_key; ++ mpcb->mptcp_loc_token = meta_tp->mptcp_loc_token; ++ ++ /* Generate Initial data-sequence-numbers */ ++ mptcp_key_sha1(mpcb->mptcp_loc_key, NULL, &snd_idsn); ++ snd_idsn++; ++ mpcb->snd_high_order[0] = snd_idsn >> 32; ++ mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1; ++ ++ mpcb->mptcp_rem_key = remote_key; ++ mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &rcv_idsn); ++ rcv_idsn++; ++ mpcb->rcv_high_order[0] = rcv_idsn >> 32; ++ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; ++ ++ mpcb->meta_sk = meta_sk; ++ mpcb->master_sk = master_sk; ++ ++ skb_queue_head_init(&mpcb->reinject_queue); ++ mutex_init(&mpcb->mpcb_mutex); ++ ++ /* Init time-wait stuff */ ++ INIT_LIST_HEAD(&mpcb->tw_list); ++ ++ INIT_HLIST_HEAD(&mpcb->callback_list); ++ INIT_HLIST_HEAD(&mpcb->conn_list); ++ spin_lock_init(&mpcb->mpcb_list_lock); ++ ++ mpcb->orig_sk_rcvbuf = meta_sk->sk_rcvbuf; ++ mpcb->orig_sk_sndbuf = meta_sk->sk_sndbuf; ++ mpcb->orig_window_clamp = meta_tp->window_clamp; ++ ++ /* The meta is directly linked - set refcnt to 1 */ ++ refcount_set(&mpcb->mpcb_refcnt, 1); ++ ++ if (!meta_tp->inside_tk_table) { ++ /* Adding the meta_tp in the token hashtable - coming from server-side */ ++ rcu_read_lock(); ++ local_bh_disable(); ++ spin_lock(&mptcp_tk_hashlock); ++ ++ /* With lockless listeners, we might process two ACKs at the ++ * same time. With TCP, inet_csk_complete_hashdance takes care ++ * of this. But, for MPTCP this would be too late if we add ++ * this MPTCP-socket in the token table (new subflows might ++ * come in and match on this socket here. ++ * So, we need to check if someone else already added the token ++ * and revert in that case. The other guy won the race... ++ */ ++ if (mptcp_find_token(mpcb->mptcp_loc_token)) { ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++ ++ goto err_insert_token; ++ } ++ __mptcp_hash_insert(meta_tp, mpcb->mptcp_loc_token); ++ ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++ } ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ if (meta_icsk->icsk_af_ops == &mptcp_v6_mapped) { ++ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; ++ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); ++ ++ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; ++ ++ newnp = inet6_sk(master_sk); ++ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); ++ ++ newnp->ipv6_mc_list = NULL; ++ newnp->ipv6_ac_list = NULL; ++ newnp->ipv6_fl_list = NULL; ++ newnp->pktoptions = NULL; ++ newnp->opt = NULL; ++ ++ newnp->rxopt.all = 0; ++ newnp->repflow = 0; ++ np->rxopt.all = 0; ++ np->repflow = 0; ++ } else if (meta_sk->sk_family == AF_INET6) { ++ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; ++ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); ++ struct ipv6_txoptions *opt; ++ ++ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; ++ ++ /* The following heavily inspired from tcp_v6_syn_recv_sock() */ ++ newnp = inet6_sk(master_sk); ++ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); ++ ++ newnp->ipv6_mc_list = NULL; ++ newnp->ipv6_ac_list = NULL; ++ newnp->ipv6_fl_list = NULL; ++ newnp->pktoptions = NULL; ++ newnp->opt = NULL; ++ ++ newnp->rxopt.all = 0; ++ newnp->repflow = 0; ++ np->rxopt.all = 0; ++ np->repflow = 0; ++ ++ opt = rcu_dereference(np->opt); ++ if (opt) { ++ opt = ipv6_dup_options(master_sk, opt); ++ RCU_INIT_POINTER(newnp->opt, opt); ++ } ++ inet_csk(master_sk)->icsk_ext_hdr_len = 0; ++ if (opt) ++ inet_csk(master_sk)->icsk_ext_hdr_len = opt->opt_nflen + ++ opt->opt_flen; ++ } ++#endif ++ ++ meta_tp->mptcp = NULL; ++ ++ meta_tp->write_seq = (u32)snd_idsn; ++ meta_tp->snd_sml = meta_tp->write_seq; ++ meta_tp->snd_una = meta_tp->write_seq; ++ meta_tp->snd_nxt = meta_tp->write_seq; ++ meta_tp->pushed_seq = meta_tp->write_seq; ++ meta_tp->snd_up = meta_tp->write_seq; ++ ++ meta_tp->copied_seq = (u32)rcv_idsn; ++ meta_tp->rcv_nxt = (u32)rcv_idsn; ++ meta_tp->rcv_wup = (u32)rcv_idsn; ++ ++ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; ++ meta_tp->snd_wnd = window; ++ meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */ ++ ++ meta_tp->packets_out = 0; ++ meta_icsk->icsk_probes_out = 0; ++ ++ rcu_assign_pointer(inet_sk(meta_sk)->inet_opt, NULL); ++ ++ /* Set mptcp-pointers */ ++ master_tp->mpcb = mpcb; ++ master_tp->meta_sk = meta_sk; ++ meta_tp->mpcb = mpcb; ++ meta_tp->meta_sk = meta_sk; ++ ++ /* Initialize the queues */ ++ master_tp->out_of_order_queue = RB_ROOT; ++ master_sk->tcp_rtx_queue = RB_ROOT; ++ INIT_LIST_HEAD(&master_tp->tsq_node); ++ INIT_LIST_HEAD(&master_tp->tsorted_sent_queue); ++ ++ master_sk->sk_tsq_flags = 0; ++ /* icsk_bind_hash inherited from the meta, but it will be properly set in ++ * mptcp_create_master_sk. Same operation is done in inet_csk_clone_lock. ++ */ ++ inet_csk(master_sk)->icsk_bind_hash = NULL; ++ ++ /* Init the accept_queue structure, we support a queue of 32 pending ++ * connections, it does not need to be huge, since we only store here ++ * pending subflow creations. ++ */ ++ reqsk_queue_alloc(&meta_icsk->icsk_accept_queue); ++ meta_sk->sk_max_ack_backlog = 32; ++ meta_sk->sk_ack_backlog = 0; ++ ++ if (!sock_flag(meta_sk, SOCK_MPTCP)) { ++ mptcp_enable_static_key_bh(); ++ sock_set_flag(meta_sk, SOCK_MPTCP); ++ } ++ ++ /* Redefine function-pointers as the meta-sk is now fully ready */ ++ meta_tp->mpc = 1; ++ meta_tp->ops = &mptcp_meta_specific; ++ ++ meta_sk->sk_backlog_rcv = mptcp_backlog_rcv; ++ meta_sk->sk_destruct = mptcp_sock_destruct; ++ ++ /* Meta-level retransmit timer */ ++ meta_icsk->icsk_rto *= 2; /* Double of initial - rto */ ++ ++ tcp_init_xmit_timers(master_sk); ++ /* Has been set for sending out the SYN */ ++ inet_csk_clear_xmit_timer(meta_sk, ICSK_TIME_RETRANS); ++ ++ mptcp_mpcb_inherit_sockopts(meta_sk, master_sk); ++ ++ mptcp_init_path_manager(mpcb); ++ mptcp_init_scheduler(mpcb); ++ ++ if (!try_module_get(inet_csk(master_sk)->icsk_ca_ops->owner)) ++ tcp_assign_congestion_control(master_sk); ++ ++ master_tp->saved_syn = NULL; ++ ++ mptcp_debug("%s: created mpcb with token %#x\n", ++ __func__, mpcb->mptcp_loc_token); ++ ++ return 0; ++ ++err_insert_token: ++ kmem_cache_free(mptcp_cb_cache, mpcb); ++ ++err_alloc_mpcb: ++ inet_sk(master_sk)->inet_opt = NULL; ++ master_sk->sk_state = TCP_CLOSE; ++ sock_orphan(master_sk); ++ bh_unlock_sock(master_sk); ++ sk_free(master_sk); ++ ++err_alloc_master: ++ return -ENOBUFS; ++} ++ ++/* Called without holding lock on mpcb */ ++static u8 mptcp_set_new_pathindex(struct mptcp_cb *mpcb) ++{ ++ int i; ++ ++ /* Start at 1, because 0 is reserved for the meta-sk */ ++ for (i = 1; i < sizeof(mpcb->path_index_bits) * 8; i++) { ++ if (!test_and_set_bit(i, &mpcb->path_index_bits)) ++ break; ++ } ++ ++ if (i == sizeof(mpcb->path_index_bits) * 8) ++ return 0; ++ return i; ++} ++ ++/* May be called without holding the meta-level lock */ ++int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, ++ gfp_t flags) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ tp->mptcp = kmem_cache_zalloc(mptcp_sock_cache, flags); ++ if (!tp->mptcp) ++ return -ENOMEM; ++ ++ tp->mptcp->path_index = mptcp_set_new_pathindex(mpcb); ++ /* No more space for more subflows? */ ++ if (!tp->mptcp->path_index) { ++ kmem_cache_free(mptcp_sock_cache, tp->mptcp); ++ return -EPERM; ++ } ++ ++ INIT_HLIST_NODE(&tp->mptcp->cb_list); ++ ++ tp->mptcp->tp = tp; ++ tp->mpcb = mpcb; ++ tp->meta_sk = meta_sk; ++ ++ if (!sock_flag(sk, SOCK_MPTCP)) { ++ mptcp_enable_static_key_bh(); ++ sock_set_flag(sk, SOCK_MPTCP); ++ } ++ ++ tp->mpc = 1; ++ tp->ops = &mptcp_sub_specific; ++ ++ tp->mptcp->loc_id = loc_id; ++ tp->mptcp->rem_id = rem_id; ++ if (mpcb->sched_ops->init) ++ mpcb->sched_ops->init(sk); ++ ++ /* The corresponding sock_put is in mptcp_sock_destruct(). It cannot be ++ * included in mptcp_del_sock(), because the mpcb must remain alive ++ * until the last subsocket is completely destroyed. ++ */ ++ sock_hold(meta_sk); ++ refcount_inc(&mpcb->mpcb_refcnt); ++ ++ spin_lock_bh(&mpcb->mpcb_list_lock); ++ hlist_add_head_rcu(&tp->mptcp->node, &mpcb->conn_list); ++ spin_unlock_bh(&mpcb->mpcb_list_lock); ++ ++ tp->mptcp->attached = 1; ++ ++ mptcp_sub_inherit_sockopts(meta_sk, sk); ++ INIT_DELAYED_WORK(&tp->mptcp->work, mptcp_sub_close_wq); ++ ++ /* Properly inherit CC from the meta-socket */ ++ mptcp_assign_congestion_control(sk); ++ ++ /* As we successfully allocated the mptcp_tcp_sock, we have to ++ * change the function-pointers here (for sk_destruct to work correctly) ++ */ ++ sk->sk_error_report = mptcp_sock_def_error_report; ++ sk->sk_data_ready = mptcp_data_ready; ++ sk->sk_write_space = mptcp_write_space; ++ sk->sk_state_change = mptcp_set_state; ++ sk->sk_destruct = mptcp_sock_destruct; ++ ++ if (sk->sk_family == AF_INET) ++ mptcp_debug("%s: token %#x pi %d, src_addr:%pI4:%d dst_addr:%pI4:%d\n", ++ __func__ , mpcb->mptcp_loc_token, ++ tp->mptcp->path_index, ++ &((struct inet_sock *)tp)->inet_saddr, ++ ntohs(((struct inet_sock *)tp)->inet_sport), ++ &((struct inet_sock *)tp)->inet_daddr, ++ ntohs(((struct inet_sock *)tp)->inet_dport)); ++#if IS_ENABLED(CONFIG_IPV6) ++ else ++ mptcp_debug("%s: token %#x pi %d, src_addr:%pI6:%d dst_addr:%pI6:%d\n", ++ __func__ , mpcb->mptcp_loc_token, ++ tp->mptcp->path_index, &inet6_sk(sk)->saddr, ++ ntohs(((struct inet_sock *)tp)->inet_sport), ++ &sk->sk_v6_daddr, ++ ntohs(((struct inet_sock *)tp)->inet_dport)); ++#endif ++ ++ return 0; ++} ++ ++void mptcp_del_sock(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_cb *mpcb; ++ ++ if (!tp->mptcp || !tp->mptcp->attached) ++ return; ++ ++ mpcb = tp->mpcb; ++ ++ if (mpcb->sched_ops->release) ++ mpcb->sched_ops->release(sk); ++ ++ if (mpcb->pm_ops->delete_subflow) ++ mpcb->pm_ops->delete_subflow(sk); ++ ++ mptcp_debug("%s: Removing subsock tok %#x pi:%d state %d is_meta? %d\n", ++ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, ++ sk->sk_state, is_meta_sk(sk)); ++ ++ spin_lock_bh(&mpcb->mpcb_list_lock); ++ hlist_del_init_rcu(&tp->mptcp->node); ++ spin_unlock_bh(&mpcb->mpcb_list_lock); ++ ++ tp->mptcp->attached = 0; ++ mpcb->path_index_bits &= ~(1 << tp->mptcp->path_index); ++ ++ if (!tcp_write_queue_empty(sk) || !tcp_rtx_queue_empty(sk)) ++ mptcp_reinject_data(sk, 0); ++ ++ if (is_master_tp(tp)) { ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ ++ if (meta_tp->record_master_info && ++ !sock_flag(meta_sk, SOCK_DEAD)) { ++ mpcb->master_info = kmalloc(sizeof(*mpcb->master_info), ++ GFP_ATOMIC); ++ ++ if (mpcb->master_info) ++ tcp_get_info(sk, mpcb->master_info, true); ++ } ++ ++ mpcb->master_sk = NULL; ++ } else if (tp->mptcp->pre_established) { ++ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); ++ } ++} ++ ++/* Updates the MPTCP-session based on path-manager information (e.g., addresses, ++ * low-prio flows,...). ++ */ ++void mptcp_update_metasocket(const struct sock *meta_sk) ++{ ++ if (tcp_sk(meta_sk)->mpcb->pm_ops->new_session) ++ tcp_sk(meta_sk)->mpcb->pm_ops->new_session(meta_sk); ++} ++ ++/* Clean up the receive buffer for full frames taken by the user, ++ * then send an ACK if necessary. COPIED is the number of bytes ++ * tcp_recvmsg has given to the user so far, it speeds up the ++ * calculation of whether or not we must ACK for the sake of ++ * a window update. ++ * (inspired from tcp_cleanup_rbuf()) ++ */ ++void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ bool recheck_rcv_window = false; ++ struct mptcp_tcp_sock *mptcp; ++ __u32 rcv_window_now = 0; ++ ++ if (copied > 0 && !(meta_sk->sk_shutdown & RCV_SHUTDOWN)) { ++ rcv_window_now = tcp_receive_window(meta_tp); ++ ++ /* Optimize, __mptcp_select_window() is not cheap. */ ++ if (2 * rcv_window_now <= meta_tp->window_clamp) ++ recheck_rcv_window = true; ++ } ++ ++ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp = tcp_sk(sk); ++ const struct inet_connection_sock *icsk = inet_csk(sk); ++ ++ if (!mptcp_sk_can_send_ack(sk)) ++ continue; ++ ++ if (!inet_csk_ack_scheduled(sk)) ++ goto second_part; ++ /* Delayed ACKs frequently hit locked sockets during bulk ++ * receive. ++ */ ++ if (icsk->icsk_ack.blocked || ++ /* Once-per-two-segments ACK was not sent by tcp_input.c */ ++ tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss || ++ /* If this read emptied read buffer, we send ACK, if ++ * connection is not bidirectional, user drained ++ * receive buffer and there was a small segment ++ * in queue. ++ */ ++ (copied > 0 && ++ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) || ++ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && ++ !icsk->icsk_ack.pingpong)) && ++ !atomic_read(&meta_sk->sk_rmem_alloc))) { ++ tcp_send_ack(sk); ++ continue; ++ } ++ ++second_part: ++ /* This here is the second part of tcp_cleanup_rbuf */ ++ if (recheck_rcv_window) { ++ __u32 new_window = tp->ops->__select_window(sk); ++ ++ /* Send ACK now, if this read freed lots of space ++ * in our buffer. Certainly, new_window is new window. ++ * We can advertise it now, if it is not less than ++ * current one. ++ * "Lots" means "at least twice" here. ++ */ ++ if (new_window && new_window >= 2 * rcv_window_now) ++ tcp_send_ack(sk); ++ } ++ } ++} ++ ++static int mptcp_sub_send_fin(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct sk_buff *skb = tcp_write_queue_tail(sk); ++ int mss_now; ++ ++ /* Optimization, tack on the FIN if we have a queue of ++ * unsent frames. But be careful about outgoing SACKS ++ * and IP options. ++ */ ++ mss_now = tcp_current_mss(sk); ++ ++ if (tcp_send_head(sk) != NULL) { ++ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; ++ TCP_SKB_CB(skb)->end_seq++; ++ tp->write_seq++; ++ } else { ++ skb = alloc_skb_fclone(MAX_TCP_HEADER, GFP_ATOMIC); ++ if (!skb) ++ return 1; ++ ++ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); ++ skb_reserve(skb, MAX_TCP_HEADER); ++ /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ ++ tcp_init_nondata_skb(skb, tp->write_seq, ++ TCPHDR_ACK | TCPHDR_FIN); ++ tcp_queue_skb(sk, skb); ++ } ++ __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF); ++ ++ return 0; ++} ++ ++static void mptcp_sub_close_doit(struct sock *sk) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (sock_flag(sk, SOCK_DEAD)) ++ return; ++ ++ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) { ++ tp->closing = 1; ++ tcp_close(sk, 0); ++ } else if (tcp_close_state(sk)) { ++ sk->sk_shutdown |= SEND_SHUTDOWN; ++ tcp_send_fin(sk); ++ } ++} ++ ++void mptcp_sub_close_wq(struct work_struct *work) ++{ ++ struct tcp_sock *tp = container_of(work, struct mptcp_tcp_sock, work.work)->tp; ++ struct sock *sk = (struct sock *)tp; ++ struct mptcp_cb *mpcb = tp->mpcb; ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ mptcp_sub_close_doit(sk); ++ ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ mptcp_mpcb_put(mpcb); ++ sock_put(sk); ++} ++ ++void mptcp_sub_close(struct sock *sk, unsigned long delay) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct delayed_work *work = &tcp_sk(sk)->mptcp->work; ++ ++ /* We are already closing - e.g., call from sock_def_error_report upon ++ * tcp_disconnect in tcp_close. ++ */ ++ if (tp->closing) ++ return; ++ ++ /* Work already scheduled ? */ ++ if (work_pending(&work->work)) { ++ /* Work present - who will be first ? */ ++ if (jiffies + delay > work->timer.expires) ++ return; ++ ++ /* Try canceling - if it fails, work will be executed soon */ ++ if (!cancel_delayed_work(work)) ++ return; ++ sock_put(sk); ++ mptcp_mpcb_put(tp->mpcb); ++ } ++ ++ if (!delay) { ++ unsigned char old_state = sk->sk_state; ++ ++ /* We directly send the FIN. Because it may take so a long time, ++ * untile the work-queue will get scheduled... ++ * ++ * If mptcp_sub_send_fin returns 1, it failed and thus we reset ++ * the old state so that tcp_close will finally send the fin ++ * in user-context. ++ */ ++ if (!sk->sk_err && old_state != TCP_CLOSE && ++ tcp_close_state(sk) && mptcp_sub_send_fin(sk)) { ++ if (old_state == TCP_ESTABLISHED) ++ TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); ++ sk->sk_state = old_state; ++ } ++ } ++ ++ sock_hold(sk); ++ refcount_inc(&tp->mpcb->mpcb_refcnt); ++ queue_delayed_work(mptcp_wq, work, delay); ++} ++ ++void mptcp_sub_force_close(struct sock *sk) ++{ ++ /* The below tcp_done may have freed the socket, if he is already dead. ++ * Thus, we are not allowed to access it afterwards. That's why ++ * we have to store the dead-state in this local variable. ++ */ ++ int sock_is_dead = sock_flag(sk, SOCK_DEAD); ++ ++ tcp_sk(sk)->mp_killed = 1; ++ ++ if (sk->sk_state != TCP_CLOSE) ++ tcp_done(sk); ++ ++ if (!sock_is_dead) ++ mptcp_sub_close(sk, 0); ++} ++EXPORT_SYMBOL(mptcp_sub_force_close); ++ ++/* Update the mpcb send window, based on the contributions ++ * of each subflow ++ */ ++void mptcp_update_sndbuf(const struct tcp_sock *tp) ++{ ++ struct sock *meta_sk = tp->meta_sk; ++ int new_sndbuf = 0, old_sndbuf = meta_sk->sk_sndbuf; ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if (!mptcp_sk_can_send(sk)) ++ continue; ++ ++ new_sndbuf += sk->sk_sndbuf; ++ ++ if (new_sndbuf > sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2] || ++ new_sndbuf < 0) { ++ new_sndbuf = sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]; ++ break; ++ } ++ } ++ meta_sk->sk_sndbuf = max(min(new_sndbuf, ++ sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]), ++ meta_sk->sk_sndbuf); ++ ++ /* The subflow's call to sk_write_space in tcp_new_space ends up in ++ * mptcp_write_space. ++ * It has nothing to do with waking up the application. ++ * So, we do it here. ++ */ ++ if (old_sndbuf != meta_sk->sk_sndbuf) ++ meta_sk->sk_write_space(meta_sk); ++} ++ ++/* Similar to: tcp_close */ ++void mptcp_close(struct sock *meta_sk, long timeout) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct mptcp_tcp_sock *mptcp; ++ struct sk_buff *skb; ++ int data_was_unread = 0; ++ int state; ++ ++ mptcp_debug("%s: Close of meta_sk with tok %#x\n", ++ __func__, mpcb->mptcp_loc_token); ++ ++ WARN_ON(refcount_inc_not_zero(&mpcb->mpcb_refcnt) == 0); ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ if (meta_tp->inside_tk_table) ++ /* Detach the mpcb from the token hashtable */ ++ mptcp_hash_remove_bh(meta_tp); ++ ++ meta_sk->sk_shutdown = SHUTDOWN_MASK; ++ /* We need to flush the recv. buffs. We do this only on the ++ * descriptor close, not protocol-sourced closes, because the ++ * reader process may not have drained the data yet! ++ */ ++ while ((skb = __skb_dequeue(&meta_sk->sk_receive_queue)) != NULL) { ++ u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq; ++ ++ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) ++ len--; ++ data_was_unread += len; ++ __kfree_skb(skb); ++ } ++ ++ sk_mem_reclaim(meta_sk); ++ ++ /* If socket has been already reset (e.g. in tcp_reset()) - kill it. */ ++ if (meta_sk->sk_state == TCP_CLOSE) { ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(sk_it)->send_mp_fclose) ++ continue; ++ mptcp_sub_close(sk_it, 0); ++ } ++ goto adjudge_to_death; ++ } ++ ++ if (data_was_unread) { ++ /* Unread data was tossed, zap the connection. */ ++ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONCLOSE); ++ tcp_set_state(meta_sk, TCP_CLOSE); ++ tcp_sk(meta_sk)->ops->send_active_reset(meta_sk, ++ meta_sk->sk_allocation); ++ } else if (sock_flag(meta_sk, SOCK_LINGER) && !meta_sk->sk_lingertime) { ++ /* Check zero linger _after_ checking for unread data. */ ++ meta_sk->sk_prot->disconnect(meta_sk, 0); ++ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); ++ } else if (tcp_close_state(meta_sk)) { ++ mptcp_send_fin(meta_sk); ++ } else if (meta_tp->snd_una == meta_tp->write_seq) { ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ /* The DATA_FIN has been sent and acknowledged ++ * (e.g., by sk_shutdown). Close all the other subflows ++ */ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ unsigned long delay = 0; ++ /* If we are the passive closer, don't trigger ++ * subflow-fin until the subflow has been finned ++ * by the peer. - thus we add a delay ++ */ ++ if (mpcb->passive_close && ++ sk_it->sk_state == TCP_ESTABLISHED) ++ delay = inet_csk(sk_it)->icsk_rto << 3; ++ ++ mptcp_sub_close(sk_it, delay); ++ } ++ } ++ ++ sk_stream_wait_close(meta_sk, timeout); ++ ++adjudge_to_death: ++ state = meta_sk->sk_state; ++ sock_hold(meta_sk); ++ sock_orphan(meta_sk); ++ ++ /* socket will be freed after mptcp_close - we have to prevent ++ * access from the subflows. ++ */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ /* Similar to sock_orphan, but we don't set it DEAD, because ++ * the callbacks are still set and must be called. ++ */ ++ write_lock_bh(&sk_it->sk_callback_lock); ++ sk_set_socket(sk_it, NULL); ++ sk_it->sk_wq = NULL; ++ write_unlock_bh(&sk_it->sk_callback_lock); ++ } ++ ++ if (mpcb->pm_ops->close_session) ++ mpcb->pm_ops->close_session(meta_sk); ++ ++ /* It is the last release_sock in its life. It will remove backlog. */ ++ release_sock(meta_sk); ++ ++ /* Now socket is owned by kernel and we acquire BH lock ++ * to finish close. No need to check for user refs. ++ */ ++ local_bh_disable(); ++ bh_lock_sock(meta_sk); ++ WARN_ON(sock_owned_by_user(meta_sk)); ++ ++ percpu_counter_inc(meta_sk->sk_prot->orphan_count); ++ ++ /* Have we already been destroyed by a softirq or backlog? */ ++ if (state != TCP_CLOSE && meta_sk->sk_state == TCP_CLOSE) ++ goto out; ++ ++ /* This is a (useful) BSD violating of the RFC. There is a ++ * problem with TCP as specified in that the other end could ++ * keep a socket open forever with no application left this end. ++ * We use a 3 minute timeout (about the same as BSD) then kill ++ * our end. If they send after that then tough - BUT: long enough ++ * that we won't make the old 4*rto = almost no time - whoops ++ * reset mistake. ++ * ++ * Nope, it was not mistake. It is really desired behaviour ++ * f.e. on http servers, when such sockets are useless, but ++ * consume significant resources. Let's do it with special ++ * linger2 option. --ANK ++ */ ++ ++ if (meta_sk->sk_state == TCP_FIN_WAIT2) { ++ if (meta_tp->linger2 < 0) { ++ tcp_set_state(meta_sk, TCP_CLOSE); ++ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); ++ __NET_INC_STATS(sock_net(meta_sk), ++ LINUX_MIB_TCPABORTONLINGER); ++ } else { ++ const int tmo = tcp_fin_time(meta_sk); ++ ++ if (tmo > TCP_TIMEWAIT_LEN) { ++ inet_csk_reset_keepalive_timer(meta_sk, ++ tmo - TCP_TIMEWAIT_LEN); ++ } else { ++ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, ++ tmo); ++ goto out; ++ } ++ } ++ } ++ if (meta_sk->sk_state != TCP_CLOSE) { ++ sk_mem_reclaim(meta_sk); ++ if (tcp_check_oom(meta_sk, 0)) { ++ if (net_ratelimit()) ++ pr_info("MPTCP: out of memory: force closing socket\n"); ++ tcp_set_state(meta_sk, TCP_CLOSE); ++ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); ++ __NET_INC_STATS(sock_net(meta_sk), ++ LINUX_MIB_TCPABORTONMEMORY); ++ } ++ } ++ ++ ++ if (meta_sk->sk_state == TCP_CLOSE) ++ inet_csk_destroy_sock(meta_sk); ++ /* Otherwise, socket is reprieved until protocol close. */ ++ ++out: ++ bh_unlock_sock(meta_sk); ++ local_bh_enable(); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ mptcp_mpcb_put(mpcb); ++ sock_put(meta_sk); /* Taken by sock_hold */ ++} ++ ++void mptcp_disconnect(struct sock *meta_sk) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ __skb_queue_purge(&meta_tp->mpcb->reinject_queue); ++ ++ if (meta_tp->inside_tk_table) ++ mptcp_hash_remove_bh(meta_tp); ++ ++ local_bh_disable(); ++ mptcp_for_each_sub_safe(meta_tp->mpcb, mptcp, tmp) { ++ struct sock *subsk = mptcp_to_sock(mptcp); ++ ++ if (spin_is_locked(&subsk->sk_lock.slock)) ++ bh_unlock_sock(subsk); ++ ++ tcp_sk(subsk)->tcp_disconnect = 1; ++ ++ meta_sk->sk_prot->disconnect(subsk, O_NONBLOCK); ++ ++ sock_orphan(subsk); ++ ++ percpu_counter_inc(meta_sk->sk_prot->orphan_count); ++ ++ inet_csk_destroy_sock(subsk); ++ } ++ local_bh_enable(); ++ ++ mptcp_mpcb_cleanup(meta_tp->mpcb); ++ meta_tp->meta_sk = NULL; ++ ++ meta_tp->send_mp_fclose = 0; ++ meta_tp->mpc = 0; ++ meta_tp->ops = &tcp_specific; ++#if IS_ENABLED(CONFIG_IPV6) ++ if (meta_sk->sk_family == AF_INET6) ++ meta_sk->sk_backlog_rcv = tcp_v6_do_rcv; ++ else ++ meta_sk->sk_backlog_rcv = tcp_v4_do_rcv; ++#else ++ meta_sk->sk_backlog_rcv = tcp_v4_do_rcv; ++#endif ++ meta_sk->sk_destruct = inet_sock_destruct; ++} ++ ++ ++/* Returns True if we should enable MPTCP for that socket. */ ++bool mptcp_doit(struct sock *sk) ++{ ++ const struct dst_entry *dst = __sk_dst_get(sk); ++ ++ /* Don't do mptcp over loopback */ ++ if (sk->sk_family == AF_INET && ++ (ipv4_is_loopback(inet_sk(sk)->inet_daddr) || ++ ipv4_is_loopback(inet_sk(sk)->inet_saddr))) ++ return false; ++#if IS_ENABLED(CONFIG_IPV6) ++ if (sk->sk_family == AF_INET6 && ++ (ipv6_addr_loopback(&sk->sk_v6_daddr) || ++ ipv6_addr_loopback(&inet6_sk(sk)->saddr))) ++ return false; ++#endif ++ if (mptcp_v6_is_v4_mapped(sk) && ++ ipv4_is_loopback(inet_sk(sk)->inet_saddr)) ++ return false; ++ ++#ifdef CONFIG_TCP_MD5SIG ++ /* If TCP_MD5SIG is enabled, do not do MPTCP - there is no Option-Space */ ++ if (tcp_sk(sk)->af_specific->md5_lookup(sk, sk)) ++ return false; ++#endif ++ ++ if (dst->dev && (dst->dev->flags & IFF_NOMULTIPATH)) ++ return false; ++ ++ return true; ++} ++ ++int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, ++ __u8 mptcp_ver, u32 window) ++{ ++ struct tcp_sock *master_tp; ++ struct sock *master_sk; ++ ++ if (mptcp_alloc_mpcb(meta_sk, remote_key, mptcp_ver, window)) ++ goto err_alloc_mpcb; ++ ++ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; ++ master_tp = tcp_sk(master_sk); ++ ++ if (mptcp_add_sock(meta_sk, master_sk, 0, 0, GFP_ATOMIC)) ++ goto err_add_sock; ++ ++ if (__inet_inherit_port(meta_sk, master_sk) < 0) ++ goto err_add_sock; ++ ++ meta_sk->sk_prot->unhash(meta_sk); ++ inet_ehash_nolisten(master_sk, NULL); ++ ++ master_tp->mptcp->init_rcv_wnd = master_tp->rcv_wnd; ++ ++ return 0; ++ ++err_add_sock: ++ inet_csk_prepare_forced_close(master_sk); ++ tcp_done(master_sk); ++ ++err_alloc_mpcb: ++ return -ENOBUFS; ++} ++ ++static int __mptcp_check_req_master(struct sock *child, ++ struct request_sock *req) ++{ ++ struct tcp_sock *child_tp = tcp_sk(child); ++ struct sock *meta_sk = child; ++ struct mptcp_cb *mpcb; ++ struct mptcp_request_sock *mtreq; ++ ++ /* Never contained an MP_CAPABLE */ ++ if (!inet_rsk(req)->mptcp_rqsk) ++ return 1; ++ ++ if (!inet_rsk(req)->saw_mpc) { ++ /* Fallback to regular TCP, because we saw one SYN without ++ * MP_CAPABLE. In tcp_check_req we continue the regular path. ++ * But, the socket has been added to the reqsk_tk_htb, so we ++ * must still remove it. ++ */ ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK); ++ mptcp_reqsk_remove_tk(req); ++ return 1; ++ } ++ ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK); ++ ++ /* Just set this values to pass them to mptcp_alloc_mpcb */ ++ mtreq = mptcp_rsk(req); ++ child_tp->mptcp_loc_key = mtreq->mptcp_loc_key; ++ child_tp->mptcp_loc_token = mtreq->mptcp_loc_token; ++ ++ if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, ++ mtreq->mptcp_ver, child_tp->snd_wnd)) { ++ inet_csk_prepare_forced_close(meta_sk); ++ tcp_done(meta_sk); ++ ++ return -ENOBUFS; ++ } ++ ++ child = tcp_sk(child)->mpcb->master_sk; ++ child_tp = tcp_sk(child); ++ mpcb = child_tp->mpcb; ++ ++ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; ++ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; ++ ++ mpcb->dss_csum = mtreq->dss_csum; ++ mpcb->server_side = 1; ++ ++ /* Needs to be done here additionally, because when accepting a ++ * new connection we pass by __reqsk_free and not reqsk_free. ++ */ ++ mptcp_reqsk_remove_tk(req); ++ ++ /* Hold when creating the meta-sk in tcp_vX_syn_recv_sock. */ ++ sock_put(meta_sk); ++ ++ return 0; ++} ++ ++int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req) ++{ ++ struct sock *meta_sk = child, *master_sk; ++ struct sk_buff *skb; ++ u32 new_mapping; ++ int ret; ++ ++ ret = __mptcp_check_req_master(child, req); ++ if (ret) ++ return ret; ++ ++ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; ++ ++ /* We need to rewind copied_seq as it is set to IDSN + 1 and as we have ++ * pre-MPTCP data in the receive queue. ++ */ ++ tcp_sk(meta_sk)->copied_seq -= tcp_sk(master_sk)->rcv_nxt - ++ tcp_rsk(req)->rcv_isn - 1; ++ ++ /* Map subflow sequence number to data sequence numbers. We need to map ++ * these data to [IDSN - len - 1, IDSN[. ++ */ ++ new_mapping = tcp_sk(meta_sk)->copied_seq - tcp_rsk(req)->rcv_isn - 1; ++ ++ /* There should be only one skb: the SYN + data. */ ++ skb_queue_walk(&meta_sk->sk_receive_queue, skb) { ++ TCP_SKB_CB(skb)->seq += new_mapping; ++ TCP_SKB_CB(skb)->end_seq += new_mapping; ++ } ++ ++ /* With fastopen we change the semantics of the relative subflow ++ * sequence numbers to deal with middleboxes that could add/remove ++ * multiple bytes in the SYN. We chose to start counting at rcv_nxt - 1 ++ * instead of the regular TCP ISN. ++ */ ++ tcp_sk(master_sk)->mptcp->rcv_isn = tcp_sk(master_sk)->rcv_nxt - 1; ++ ++ /* We need to update copied_seq of the master_sk to account for the ++ * already moved data to the meta receive queue. ++ */ ++ tcp_sk(master_sk)->copied_seq = tcp_sk(master_sk)->rcv_nxt; ++ ++ /* Handled by the master_sk */ ++ tcp_sk(meta_sk)->fastopen_rsk = NULL; ++ ++ return 0; ++} ++ ++int mptcp_check_req_master(struct sock *sk, struct sock *child, ++ struct request_sock *req, const struct sk_buff *skb, ++ int drop, u32 tsoff) ++{ ++ struct sock *meta_sk = child; ++ int ret; ++ ++ ret = __mptcp_check_req_master(child, req); ++ if (ret) ++ return ret; ++ child = tcp_sk(child)->mpcb->master_sk; ++ ++ sock_rps_save_rxhash(child, skb); ++ ++ /* drop indicates that we come from tcp_check_req and thus need to ++ * handle the request-socket fully. ++ */ ++ if (drop) { ++ tcp_synack_rtt_meas(child, req); ++ ++ inet_csk_reqsk_queue_drop(sk, req); ++ reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); ++ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { ++ bh_unlock_sock(meta_sk); ++ /* No sock_put() of the meta needed. The reference has ++ * already been dropped in __mptcp_check_req_master(). ++ */ ++ sock_put(child); ++ return -1; ++ } ++ } else { ++ /* Thus, we come from syn-cookies */ ++ refcount_set(&req->rsk_refcnt, 1); ++ tcp_sk(meta_sk)->tsoffset = tsoff; ++ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { ++ bh_unlock_sock(meta_sk); ++ /* No sock_put() of the meta needed. The reference has ++ * already been dropped in __mptcp_check_req_master(). ++ */ ++ sock_put(child); ++ reqsk_put(req); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++/* May be called without holding the meta-level lock */ ++struct sock *mptcp_check_req_child(struct sock *meta_sk, ++ struct sock *child, ++ struct request_sock *req, ++ struct sk_buff *skb, ++ const struct mptcp_options_received *mopt) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ struct tcp_sock *child_tp = tcp_sk(child); ++ u8 hash_mac_check[20]; ++ ++ if (!mopt->join_ack) { ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKFAIL); ++ goto teardown; ++ } ++ ++ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)&mpcb->mptcp_loc_key, ++ (u32 *)hash_mac_check, 2, ++ 4, (u8 *)&mtreq->mptcp_rem_nonce, ++ 4, (u8 *)&mtreq->mptcp_loc_nonce); ++ ++ if (memcmp(hash_mac_check, (char *)&mopt->mptcp_recv_mac, 20)) { ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKMAC); ++ goto teardown; ++ } ++ ++ /* Point it to the same struct socket and wq as the meta_sk */ ++ sk_set_socket(child, meta_sk->sk_socket); ++ child->sk_wq = meta_sk->sk_wq; ++ ++ if (mptcp_add_sock(meta_sk, child, mtreq->loc_id, mtreq->rem_id, GFP_ATOMIC)) { ++ /* Has been inherited, but now child_tp->mptcp is NULL */ ++ child_tp->mpc = 0; ++ child_tp->ops = &tcp_specific; ++ ++ /* TODO when we support acking the third ack for new subflows, ++ * we should silently discard this third ack, by returning NULL. ++ * ++ * Maybe, at the retransmission we will have enough memory to ++ * fully add the socket to the meta-sk. ++ */ ++ goto teardown; ++ } ++ ++ /* The child is a clone of the meta socket, we must now reset ++ * some of the fields ++ */ ++ child_tp->mptcp->rcv_low_prio = mtreq->rcv_low_prio; ++ ++ /* We should allow proper increase of the snd/rcv-buffers. Thus, we ++ * use the original values instead of the bloated up ones from the ++ * clone. ++ */ ++ child->sk_sndbuf = mpcb->orig_sk_sndbuf; ++ child->sk_rcvbuf = mpcb->orig_sk_rcvbuf; ++ ++ child_tp->mptcp->slave_sk = 1; ++ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; ++ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; ++ child_tp->mptcp->init_rcv_wnd = req->rsk_rcv_wnd; ++ ++ child->sk_tsq_flags = 0; ++ ++ child_tp->packets_out = 0; ++ ++ tcp_reset_vars(child); ++ ++ sock_rps_save_rxhash(child, skb); ++ tcp_synack_rtt_meas(child, req); ++ ++ if (mpcb->pm_ops->established_subflow) ++ mpcb->pm_ops->established_subflow(child); ++ ++ /* Subflows do not use the accept queue, as they ++ * are attached immediately to the mpcb. ++ */ ++ inet_csk_reqsk_queue_drop(meta_sk, req); ++ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); ++ ++ /* The refcnt is initialized to 2, because regular TCP will put him ++ * in the socket's listener queue. However, we do not have a listener-queue. ++ * So, we need to make sure that this request-sock indeed gets destroyed. ++ */ ++ reqsk_put(req); ++ ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKRX); ++ return child; ++ ++teardown: ++ req->rsk_ops->send_reset(meta_sk, skb); ++ ++ /* Drop this request - sock creation failed. */ ++ inet_csk_reqsk_queue_drop(meta_sk, req); ++ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); ++ inet_csk_prepare_forced_close(child); ++ tcp_done(child); ++ bh_unlock_sock(meta_sk); ++ return meta_sk; ++} ++ ++int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw) ++{ ++ struct mptcp_tw *mptw; ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_cb *mpcb = tp->mpcb; ++ ++ /* A subsocket in tw can only receive data. So, if we are in ++ * infinite-receive, then we should not reply with a data-ack or act ++ * upon general MPTCP-signaling. We prevent this by simply not creating ++ * the mptcp_tw_sock. ++ */ ++ if (mpcb->infinite_mapping_rcv) { ++ tw->mptcp_tw = NULL; ++ return 0; ++ } ++ ++ /* Alloc MPTCP-tw-sock */ ++ mptw = kmem_cache_alloc(mptcp_tw_cache, GFP_ATOMIC); ++ if (!mptw) { ++ tw->mptcp_tw = NULL; ++ return -ENOBUFS; ++ } ++ ++ refcount_inc(&mpcb->mpcb_refcnt); ++ ++ tw->mptcp_tw = mptw; ++ mptw->loc_key = mpcb->mptcp_loc_key; ++ mptw->meta_tw = mpcb->in_time_wait; ++ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); ++ if (mptw->meta_tw && mpcb->mptw_state != TCP_TIME_WAIT) ++ mptw->rcv_nxt++; ++ rcu_assign_pointer(mptw->mpcb, mpcb); ++ ++ spin_lock_bh(&mpcb->mpcb_list_lock); ++ list_add_rcu(&mptw->list, &tp->mpcb->tw_list); ++ mptw->in_list = 1; ++ spin_unlock_bh(&mpcb->mpcb_list_lock); ++ ++ return 0; ++} ++ ++void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) ++{ ++ struct mptcp_cb *mpcb; ++ ++ rcu_read_lock(); ++ local_bh_disable(); ++ mpcb = rcu_dereference(tw->mptcp_tw->mpcb); ++ ++ /* If we are still holding a ref to the mpcb, we have to remove ourself ++ * from the list and drop the ref properly. ++ */ ++ if (mpcb && refcount_inc_not_zero(&mpcb->mpcb_refcnt)) { ++ spin_lock(&mpcb->mpcb_list_lock); ++ if (tw->mptcp_tw->in_list) { ++ list_del_rcu(&tw->mptcp_tw->list); ++ tw->mptcp_tw->in_list = 0; ++ /* Put, because we added it to the list */ ++ mptcp_mpcb_put(mpcb); ++ } ++ spin_unlock(&mpcb->mpcb_list_lock); ++ ++ /* Second time, because we increased it above */ ++ mptcp_mpcb_put(mpcb); ++ } ++ ++ local_bh_enable(); ++ rcu_read_unlock(); ++ ++ kmem_cache_free(mptcp_tw_cache, tw->mptcp_tw); ++} ++ ++/* Updates the rcv_nxt of the time-wait-socks and allows them to ack a ++ * data-fin. ++ */ ++void mptcp_time_wait(struct sock *meta_sk, int state, int timeo) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_tw *mptw; ++ ++ if (mptcp_in_infinite_mapping_weak(meta_tp->mpcb)) { ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ mptcp_for_each_sub_safe(meta_tp->mpcb, mptcp, tmp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if (sk_it->sk_state == TCP_CLOSE) ++ continue; ++ ++ tcp_sk(sk_it)->ops->time_wait(sk_it, state, timeo); ++ } ++ } ++ ++ /* Used for sockets that go into tw after the meta ++ * (see mptcp_init_tw_sock()) ++ */ ++ meta_tp->mpcb->in_time_wait = 1; ++ meta_tp->mpcb->mptw_state = state; ++ ++ /* Update the time-wait-sock's information */ ++ rcu_read_lock(); ++ local_bh_disable(); ++ list_for_each_entry_rcu(mptw, &meta_tp->mpcb->tw_list, list) { ++ mptw->meta_tw = 1; ++ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(meta_tp); ++ ++ /* We want to ack a DATA_FIN, but are yet in FIN_WAIT_2 - ++ * pretend as if the DATA_FIN has already reached us, that way ++ * the checks in tcp_timewait_state_process will be good as the ++ * DATA_FIN comes in. ++ */ ++ if (state != TCP_TIME_WAIT) ++ mptw->rcv_nxt++; ++ } ++ local_bh_enable(); ++ rcu_read_unlock(); ++ ++ if (meta_sk->sk_state != TCP_CLOSE) ++ tcp_done(meta_sk); ++} ++ ++void mptcp_tsq_flags(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ /* It will be handled as a regular deferred-call */ ++ if (is_meta_sk(sk)) ++ return; ++ ++ if (hlist_unhashed(&tp->mptcp->cb_list)) { ++ hlist_add_head(&tp->mptcp->cb_list, &tp->mpcb->callback_list); ++ /* We need to hold it here, as the sock_hold is not assured ++ * by the release_sock as it is done in regular TCP. ++ * ++ * The subsocket may get inet_csk_destroy'd while it is inside ++ * the callback_list. ++ */ ++ sock_hold(sk); ++ } ++ ++ if (!test_and_set_bit(MPTCP_SUB_DEFERRED, &meta_sk->sk_tsq_flags)) ++ sock_hold(meta_sk); ++} ++ ++void mptcp_tsq_sub_deferred(struct sock *meta_sk) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ __sock_put(meta_sk); ++ hlist_for_each_entry_safe(mptcp, tmp, &meta_tp->mpcb->callback_list, cb_list) { ++ struct tcp_sock *tp = mptcp->tp; ++ struct sock *sk = (struct sock *)tp; ++ ++ hlist_del_init(&mptcp->cb_list); ++ sk->sk_prot->release_cb(sk); ++ /* Final sock_put (cfr. mptcp_tsq_flags) */ ++ sock_put(sk); ++ } ++} ++ ++/* May be called without holding the meta-level lock */ ++void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, ++ const struct request_sock *req, ++ struct sk_buff *skb) ++{ ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ struct mptcp_options_received mopt; ++ u8 mptcp_hash_mac[20]; ++ ++ mptcp_init_mp_opt(&mopt); ++ tcp_parse_mptcp_options(skb, &mopt); ++ ++ mtreq->is_sub = 1; ++ inet_rsk(req)->mptcp_rqsk = 1; ++ ++ mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; ++ ++ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)&mpcb->mptcp_rem_key, ++ (u32 *)mptcp_hash_mac, 2, ++ 4, (u8 *)&mtreq->mptcp_loc_nonce, ++ 4, (u8 *)&mtreq->mptcp_rem_nonce); ++ mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; ++ ++ mtreq->rem_id = mopt.rem_id; ++ mtreq->rcv_low_prio = mopt.low_prio; ++ inet_rsk(req)->saw_mpc = 1; ++ ++ MPTCP_INC_STATS(sock_net(mpcb->meta_sk), MPTCP_MIB_JOINSYNRX); ++} ++ ++void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, bool want_cookie) ++{ ++ struct mptcp_options_received mopt; ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ ++ mptcp_init_mp_opt(&mopt); ++ tcp_parse_mptcp_options(skb, &mopt); ++ ++ mtreq->dss_csum = mopt.dss_csum; ++ ++ if (want_cookie) { ++ if (!mptcp_reqsk_new_cookie(req, sk, &mopt, skb)) ++ /* No key available - back to regular TCP */ ++ inet_rsk(req)->mptcp_rqsk = 0; ++ return; ++ } ++ ++ mptcp_reqsk_new_mptcp(req, sk, &mopt, skb); ++} ++ ++void mptcp_cookies_reqsk_init(struct request_sock *req, ++ struct mptcp_options_received *mopt, ++ struct sk_buff *skb) ++{ ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ ++ /* Absolutely need to always initialize this. */ ++ mtreq->hash_entry.pprev = NULL; ++ ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ mtreq->mptcp_loc_key = mopt->mptcp_receiver_key; ++ ++ /* Generate the token */ ++ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); ++ ++ rcu_read_lock(); ++ local_bh_disable(); ++ spin_lock(&mptcp_tk_hashlock); ++ ++ /* Check, if the key is still free */ ++ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || ++ mptcp_find_token(mtreq->mptcp_loc_token)) ++ goto out; ++ ++ inet_rsk(req)->saw_mpc = 1; ++ mtreq->is_sub = 0; ++ inet_rsk(req)->mptcp_rqsk = 1; ++ mtreq->dss_csum = mopt->dss_csum; ++ ++out: ++ spin_unlock(&mptcp_tk_hashlock); ++ local_bh_enable(); ++ rcu_read_unlock(); ++} ++ ++int mptcp_conn_request(struct sock *sk, struct sk_buff *skb) ++{ ++ struct mptcp_options_received mopt; ++ ++ mptcp_init_mp_opt(&mopt); ++ tcp_parse_mptcp_options(skb, &mopt); ++ ++ if (mopt.is_mp_join) ++ return mptcp_do_join_short(skb, &mopt, sock_net(sk)); ++ if (mopt.drop_me) ++ goto drop; ++ ++ if (!sock_flag(sk, SOCK_MPTCP)) ++ mopt.saw_mpc = 0; ++ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ if (mopt.saw_mpc) { ++ if (skb_rtable(skb)->rt_flags & ++ (RTCF_BROADCAST | RTCF_MULTICAST)) ++ goto drop; ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); ++ return tcp_conn_request(&mptcp_request_sock_ops, ++ &mptcp_request_sock_ipv4_ops, ++ sk, skb); ++ } ++ ++ return tcp_v4_conn_request(sk, skb); ++#if IS_ENABLED(CONFIG_IPV6) ++ } else { ++ if (mopt.saw_mpc) { ++ if (!ipv6_unicast_destination(skb)) ++ goto drop; ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); ++ return tcp_conn_request(&mptcp6_request_sock_ops, ++ &mptcp_request_sock_ipv6_ops, ++ sk, skb); ++ } ++ ++ return tcp_v6_conn_request(sk, skb); ++#endif ++ } ++drop: ++ __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); ++ return 0; ++} ++ ++int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb) ++ __releases(&child->sk_lock.slock) ++{ ++ int ret; ++ ++ /* We don't call tcp_child_process here, because we hold ++ * already the meta-sk-lock and are sure that it is not owned ++ * by the user. ++ */ ++ tcp_sk(child)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs); ++ ret = tcp_rcv_state_process(child, skb); ++ bh_unlock_sock(child); ++ sock_put(child); ++ ++ return ret; ++} ++ ++static void __mptcp_get_info(const struct sock *meta_sk, ++ struct mptcp_meta_info *info) ++{ ++ const struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); ++ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ u32 now = tcp_jiffies32; ++ ++ memset(info, 0, sizeof(*info)); ++ ++ info->mptcpi_state = meta_sk->sk_state; ++ info->mptcpi_retransmits = meta_icsk->icsk_retransmits; ++ info->mptcpi_probes = meta_icsk->icsk_probes_out; ++ info->mptcpi_backoff = meta_icsk->icsk_backoff; ++ ++ info->mptcpi_rto = jiffies_to_usecs(meta_icsk->icsk_rto); ++ ++ info->mptcpi_unacked = meta_tp->packets_out; ++ ++ info->mptcpi_last_data_sent = jiffies_to_msecs(now - meta_tp->lsndtime); ++ info->mptcpi_last_data_recv = jiffies_to_msecs(now - meta_icsk->icsk_ack.lrcvtime); ++ info->mptcpi_last_ack_recv = jiffies_to_msecs(now - meta_tp->rcv_tstamp); ++ ++ info->mptcpi_total_retrans = meta_tp->total_retrans; ++ ++ info->mptcpi_bytes_acked = meta_tp->bytes_acked; ++ info->mptcpi_bytes_received = meta_tp->bytes_received; ++} ++ ++static void mptcp_get_sub_info(struct sock *sk, struct mptcp_sub_info *info) ++{ ++ struct inet_sock *inet = inet_sk(sk); ++ ++ memset(info, 0, sizeof(*info)); ++ ++ if (sk->sk_family == AF_INET) { ++ info->src_v4.sin_family = AF_INET; ++ info->src_v4.sin_port = inet->inet_sport; ++ ++ info->src_v4.sin_addr.s_addr = inet->inet_rcv_saddr; ++ if (!info->src_v4.sin_addr.s_addr) ++ info->src_v4.sin_addr.s_addr = inet->inet_saddr; ++ ++ info->dst_v4.sin_family = AF_INET; ++ info->dst_v4.sin_port = inet->inet_dport; ++ info->dst_v4.sin_addr.s_addr = inet->inet_daddr; ++#if IS_ENABLED(CONFIG_IPV6) ++ } else { ++ struct ipv6_pinfo *np = inet6_sk(sk); ++ ++ info->src_v6.sin6_family = AF_INET6; ++ info->src_v6.sin6_port = inet->inet_sport; ++ ++ if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) ++ info->src_v6.sin6_addr = np->saddr; ++ else ++ info->src_v6.sin6_addr = sk->sk_v6_rcv_saddr; ++ ++ info->dst_v6.sin6_family = AF_INET6; ++ info->dst_v6.sin6_port = inet->inet_dport; ++ info->dst_v6.sin6_addr = sk->sk_v6_daddr; ++#endif ++ } ++} ++ ++int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen) ++{ ++ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ ++ struct mptcp_meta_info meta_info; ++ struct mptcp_info m_info; ++ ++ unsigned int info_len; ++ ++ /* Check again with the lock held */ ++ if (!mptcp(meta_tp)) ++ return -EINVAL; ++ ++ if (copy_from_user(&m_info, optval, optlen)) ++ return -EFAULT; ++ ++ if (m_info.meta_info) { ++ unsigned int len; ++ ++ __mptcp_get_info(meta_sk, &meta_info); ++ ++ /* Need to set this, if user thinks that tcp_info is bigger than ours */ ++ len = min_t(unsigned int, m_info.meta_len, sizeof(meta_info)); ++ m_info.meta_len = len; ++ ++ if (copy_to_user((void __user *)m_info.meta_info, &meta_info, len)) ++ return -EFAULT; ++ } ++ ++ /* Need to set this, if user thinks that tcp_info is bigger than ours */ ++ info_len = min_t(unsigned int, m_info.tcp_info_len, sizeof(struct tcp_info)); ++ m_info.tcp_info_len = info_len; ++ ++ if (m_info.initial) { ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ ++ if (mpcb->master_sk) { ++ struct tcp_info info; ++ ++ tcp_get_info(mpcb->master_sk, &info, true); ++ if (copy_to_user((void __user *)m_info.initial, &info, info_len)) ++ return -EFAULT; ++ } else if (meta_tp->record_master_info && mpcb->master_info) { ++ if (copy_to_user((void __user *)m_info.initial, mpcb->master_info, info_len)) ++ return -EFAULT; ++ } else { ++ return meta_tp->record_master_info ? -ENOMEM : -EINVAL; ++ } ++ } ++ ++ if (m_info.subflows) { ++ unsigned int len, sub_len = 0; ++ struct mptcp_tcp_sock *mptcp; ++ char __user *ptr; ++ ++ ptr = (char __user *)m_info.subflows; ++ len = m_info.sub_len; ++ ++ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { ++ struct tcp_info t_info; ++ unsigned int tmp_len; ++ ++ tcp_get_info(mptcp_to_sock(mptcp), &t_info, true); ++ ++ tmp_len = min_t(unsigned int, len, info_len); ++ len -= tmp_len; ++ ++ if (copy_to_user(ptr, &t_info, tmp_len)) ++ return -EFAULT; ++ ++ ptr += tmp_len; ++ sub_len += tmp_len; ++ ++ if (len == 0) ++ break; ++ } ++ ++ m_info.sub_len = sub_len; ++ } ++ ++ if (m_info.subflow_info) { ++ unsigned int len, sub_info_len, total_sub_info_len = 0; ++ struct mptcp_tcp_sock *mptcp; ++ char __user *ptr; ++ ++ ptr = (char __user *)m_info.subflow_info; ++ len = m_info.total_sub_info_len; ++ ++ sub_info_len = min_t(unsigned int, m_info.sub_info_len, ++ sizeof(struct mptcp_sub_info)); ++ m_info.sub_info_len = sub_info_len; ++ ++ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { ++ struct mptcp_sub_info m_sub_info; ++ unsigned int tmp_len; ++ ++ mptcp_get_sub_info(mptcp_to_sock(mptcp), &m_sub_info); ++ ++ tmp_len = min_t(unsigned int, len, sub_info_len); ++ len -= tmp_len; ++ ++ if (copy_to_user(ptr, &m_sub_info, tmp_len)) ++ return -EFAULT; ++ ++ ptr += tmp_len; ++ total_sub_info_len += tmp_len; ++ ++ if (len == 0) ++ break; ++ } ++ ++ m_info.total_sub_info_len = total_sub_info_len; ++ } ++ ++ if (copy_to_user(optval, &m_info, optlen)) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++void mptcp_clear_sk(struct sock *sk, int size) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ /* we do not want to clear tk_table field, because of RCU lookups */ ++ sk_prot_clear_nulls(sk, offsetof(struct tcp_sock, tk_table.next)); ++ ++ size -= offsetof(struct tcp_sock, tk_table.pprev); ++ memset((char *)&tp->tk_table.pprev, 0, size); ++} ++ ++static const struct snmp_mib mptcp_snmp_list[] = { ++ SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE), ++ SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE), ++ SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK), ++ SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK), ++ SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK), ++ SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK), ++ SNMP_MIB_ITEM("MPCapableRetransFallback", MPTCP_MIB_MPCAPABLERETRANSFALLBACK), ++ SNMP_MIB_ITEM("MPTCPCsumEnabled", MPTCP_MIB_CSUMENABLED), ++ SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS), ++ SNMP_MIB_ITEM("MPFailRX", MPTCP_MIB_MPFAILRX), ++ SNMP_MIB_ITEM("MPCsumFail", MPTCP_MIB_CSUMFAIL), ++ SNMP_MIB_ITEM("MPFastcloseRX", MPTCP_MIB_FASTCLOSERX), ++ SNMP_MIB_ITEM("MPFastcloseTX", MPTCP_MIB_FASTCLOSETX), ++ SNMP_MIB_ITEM("MPFallbackAckSub", MPTCP_MIB_FBACKSUB), ++ SNMP_MIB_ITEM("MPFallbackAckInit", MPTCP_MIB_FBACKINIT), ++ SNMP_MIB_ITEM("MPFallbackDataSub", MPTCP_MIB_FBDATASUB), ++ SNMP_MIB_ITEM("MPFallbackDataInit", MPTCP_MIB_FBDATAINIT), ++ SNMP_MIB_ITEM("MPRemoveAddrSubDelete", MPTCP_MIB_REMADDRSUB), ++ SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN), ++ SNMP_MIB_ITEM("MPJoinAlreadyFallenback", MPTCP_MIB_JOINFALLBACK), ++ SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX), ++ SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX), ++ SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX), ++ SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC), ++ SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX), ++ SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC), ++ SNMP_MIB_ITEM("MPJoinAckMissing", MPTCP_MIB_JOINACKFAIL), ++ SNMP_MIB_ITEM("MPJoinAckRTO", MPTCP_MIB_JOINACKRTO), ++ SNMP_MIB_ITEM("MPJoinAckRexmit", MPTCP_MIB_JOINACKRXMIT), ++ SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW), ++ SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH), ++ SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX), ++ SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH), ++ SNMP_MIB_ITEM("DSSTrimHead", MPTCP_MIB_DSSTRIMHEAD), ++ SNMP_MIB_ITEM("DSSSplitTail", MPTCP_MIB_DSSSPLITTAIL), ++ SNMP_MIB_ITEM("DSSPurgeOldSubSegs", MPTCP_MIB_PURGEOLD), ++ SNMP_MIB_ITEM("AddAddrRx", MPTCP_MIB_ADDADDRRX), ++ SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX), ++ SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX), ++ SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX), ++ SNMP_MIB_SENTINEL ++}; ++ ++struct workqueue_struct *mptcp_wq; ++EXPORT_SYMBOL(mptcp_wq); ++ ++/* Output /proc/net/mptcp */ ++static int mptcp_pm_seq_show(struct seq_file *seq, void *v) ++{ ++ struct tcp_sock *meta_tp; ++ const struct net *net = seq->private; ++ int i, n = 0; ++ ++ seq_printf(seq, " sl loc_tok rem_tok v6 local_address remote_address st ns tx_queue rx_queue inode"); ++ seq_putc(seq, '\n'); ++ ++ for (i = 0; i < MPTCP_HASH_SIZE; i++) { ++ struct hlist_nulls_node *node; ++ rcu_read_lock(); ++ local_bh_disable(); ++ hlist_nulls_for_each_entry_rcu(meta_tp, node, ++ &tk_hashtable[i], tk_table) { ++ struct sock *meta_sk = (struct sock *)meta_tp; ++ struct inet_sock *isk = inet_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ ++ if (!mptcp(meta_tp) || !net_eq(net, sock_net(meta_sk))) ++ continue; ++ ++ if (!mpcb) ++ continue; ++ ++ if (capable(CAP_NET_ADMIN)) { ++ seq_printf(seq, "%4d: %04X %04X ", n++, ++ mpcb->mptcp_loc_token, ++ mpcb->mptcp_rem_token); ++ } else { ++ seq_printf(seq, "%4d: %04X %04X ", n++, -1, -1); ++ } ++ if (meta_sk->sk_family == AF_INET || ++ mptcp_v6_is_v4_mapped(meta_sk)) { ++ seq_printf(seq, " 0 %08X:%04X %08X:%04X ", ++ isk->inet_rcv_saddr, ++ ntohs(isk->inet_sport), ++ isk->inet_daddr, ++ ntohs(isk->inet_dport)); ++#if IS_ENABLED(CONFIG_IPV6) ++ } else if (meta_sk->sk_family == AF_INET6) { ++ struct in6_addr *src = &meta_sk->sk_v6_rcv_saddr; ++ struct in6_addr *dst = &meta_sk->sk_v6_daddr; ++ seq_printf(seq, " 1 %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X", ++ src->s6_addr32[0], src->s6_addr32[1], ++ src->s6_addr32[2], src->s6_addr32[3], ++ ntohs(isk->inet_sport), ++ dst->s6_addr32[0], dst->s6_addr32[1], ++ dst->s6_addr32[2], dst->s6_addr32[3], ++ ntohs(isk->inet_dport)); ++#endif ++ } ++ ++ seq_printf(seq, " %02X %02X %08X:%08X %lu", ++ meta_sk->sk_state, mptcp_subflow_count(mpcb), ++ meta_tp->write_seq - meta_tp->snd_una, ++ max_t(int, meta_tp->rcv_nxt - ++ meta_tp->copied_seq, 0), ++ sock_i_ino(meta_sk)); ++ seq_putc(seq, '\n'); ++ } ++ ++ local_bh_enable(); ++ rcu_read_unlock(); ++ } ++ ++ return 0; ++} ++ ++static int mptcp_snmp_seq_show(struct seq_file *seq, void *v) ++{ ++ struct net *net = seq->private; ++ int i; ++ ++ for (i = 0; mptcp_snmp_list[i].name != NULL; i++) ++ seq_printf(seq, "%-32s\t%ld\n", mptcp_snmp_list[i].name, ++ snmp_fold_field(net->mptcp.mptcp_statistics, ++ mptcp_snmp_list[i].entry)); ++ ++ return 0; ++} ++ ++static int mptcp_pm_init_net(struct net *net) ++{ ++ net->mptcp.mptcp_statistics = alloc_percpu(struct mptcp_mib); ++ if (!net->mptcp.mptcp_statistics) ++ goto out_mptcp_mibs; ++ ++#ifdef CONFIG_PROC_FS ++ net->mptcp.proc_net_mptcp = proc_net_mkdir(net, "mptcp_net", net->proc_net); ++ if (!net->mptcp.proc_net_mptcp) ++ goto out_proc_net_mptcp; ++ if (!proc_create_net_single("mptcp", S_IRUGO, net->mptcp.proc_net_mptcp, ++ mptcp_pm_seq_show, NULL)) ++ goto out_mptcp_net_mptcp; ++ if (!proc_create_net_single("snmp", S_IRUGO, net->mptcp.proc_net_mptcp, ++ mptcp_snmp_seq_show, NULL)) ++ goto out_mptcp_net_snmp; ++#endif ++ ++ return 0; ++ ++#ifdef CONFIG_PROC_FS ++out_mptcp_net_snmp: ++ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); ++out_mptcp_net_mptcp: ++ remove_proc_subtree("mptcp_net", net->proc_net); ++ net->mptcp.proc_net_mptcp = NULL; ++out_proc_net_mptcp: ++ free_percpu(net->mptcp.mptcp_statistics); ++#endif ++out_mptcp_mibs: ++ return -ENOMEM; ++} ++ ++static void mptcp_pm_exit_net(struct net *net) ++{ ++ remove_proc_entry("snmp", net->mptcp.proc_net_mptcp); ++ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); ++ remove_proc_subtree("mptcp_net", net->proc_net); ++ free_percpu(net->mptcp.mptcp_statistics); ++} ++ ++static struct pernet_operations mptcp_pm_proc_ops = { ++ .init = mptcp_pm_init_net, ++ .exit = mptcp_pm_exit_net, ++}; ++ ++/* General initialization of mptcp */ ++void __init mptcp_init(void) ++{ ++ int i; ++ struct ctl_table_header *mptcp_sysctl; ++ ++ mptcp_sock_cache = kmem_cache_create("mptcp_sock", ++ sizeof(struct mptcp_tcp_sock), ++ 0, SLAB_HWCACHE_ALIGN, ++ NULL); ++ if (!mptcp_sock_cache) ++ goto mptcp_sock_cache_failed; ++ ++ mptcp_cb_cache = kmem_cache_create("mptcp_cb", sizeof(struct mptcp_cb), ++ 0, SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, ++ NULL); ++ if (!mptcp_cb_cache) ++ goto mptcp_cb_cache_failed; ++ ++ mptcp_tw_cache = kmem_cache_create("mptcp_tw", sizeof(struct mptcp_tw), ++ 0, SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, ++ NULL); ++ if (!mptcp_tw_cache) ++ goto mptcp_tw_cache_failed; ++ ++ get_random_bytes(&mptcp_secret, sizeof(mptcp_secret)); ++ ++ mptcp_wq = alloc_workqueue("mptcp_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 8); ++ if (!mptcp_wq) ++ goto alloc_workqueue_failed; ++ ++ for (i = 0; i < MPTCP_HASH_SIZE; i++) { ++ INIT_HLIST_NULLS_HEAD(&tk_hashtable[i], i); ++ INIT_HLIST_NULLS_HEAD(&mptcp_reqsk_tk_htb[i], i); ++ } ++ ++ spin_lock_init(&mptcp_tk_hashlock); ++ ++ if (register_pernet_subsys(&mptcp_pm_proc_ops)) ++ goto pernet_failed; ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ if (mptcp_pm_v6_init()) ++ goto mptcp_pm_v6_failed; ++#endif ++ if (mptcp_pm_v4_init()) ++ goto mptcp_pm_v4_failed; ++ ++ mptcp_sysctl = register_net_sysctl(&init_net, "net/mptcp", mptcp_table); ++ if (!mptcp_sysctl) ++ goto register_sysctl_failed; ++ ++ if (mptcp_register_path_manager(&mptcp_pm_default)) ++ goto register_pm_failed; ++ ++ if (mptcp_register_scheduler(&mptcp_sched_default)) ++ goto register_sched_failed; ++ ++ pr_info("MPTCP: Unstable branch"); ++ ++ mptcp_init_failed = false; ++ ++ return; ++ ++register_sched_failed: ++ mptcp_unregister_path_manager(&mptcp_pm_default); ++register_pm_failed: ++ unregister_net_sysctl_table(mptcp_sysctl); ++register_sysctl_failed: ++ mptcp_pm_v4_undo(); ++mptcp_pm_v4_failed: ++#if IS_ENABLED(CONFIG_IPV6) ++ mptcp_pm_v6_undo(); ++mptcp_pm_v6_failed: ++#endif ++ unregister_pernet_subsys(&mptcp_pm_proc_ops); ++pernet_failed: ++ destroy_workqueue(mptcp_wq); ++alloc_workqueue_failed: ++ kmem_cache_destroy(mptcp_tw_cache); ++mptcp_tw_cache_failed: ++ kmem_cache_destroy(mptcp_cb_cache); ++mptcp_cb_cache_failed: ++ kmem_cache_destroy(mptcp_sock_cache); ++mptcp_sock_cache_failed: ++ mptcp_init_failed = true; ++} +diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c +--- linux-5.4/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,1943 @@ ++#include ++#include ++ ++#include ++#include ++ ++#if IS_ENABLED(CONFIG_IPV6) ++#include ++#include ++#endif ++ ++enum { ++ MPTCP_EVENT_ADD = 1, ++ MPTCP_EVENT_DEL, ++ MPTCP_EVENT_MOD, ++}; ++ ++#define MPTCP_SUBFLOW_RETRY_DELAY 1000 ++ ++/* Max number of local or remote addresses we can store. ++ * When changing, see the bitfield below in fullmesh_rem4/6. ++ */ ++#define MPTCP_MAX_ADDR 8 ++ ++struct fullmesh_rem4 { ++ u8 rem4_id; ++ u8 bitfield; ++ u8 retry_bitfield; ++ __be16 port; ++ struct in_addr addr; ++}; ++ ++struct fullmesh_rem6 { ++ u8 rem6_id; ++ u8 bitfield; ++ u8 retry_bitfield; ++ __be16 port; ++ struct in6_addr addr; ++}; ++ ++struct mptcp_loc_addr { ++ struct mptcp_loc4 locaddr4[MPTCP_MAX_ADDR]; ++ u8 loc4_bits; ++ u8 next_v4_index; ++ ++ struct mptcp_loc6 locaddr6[MPTCP_MAX_ADDR]; ++ u8 loc6_bits; ++ u8 next_v6_index; ++ struct rcu_head rcu; ++}; ++ ++struct mptcp_addr_event { ++ struct list_head list; ++ unsigned short family; ++ u8 code:7, ++ low_prio:1; ++ int if_idx; ++ union inet_addr addr; ++}; ++ ++struct fullmesh_priv { ++ /* Worker struct for subflow establishment */ ++ struct work_struct subflow_work; ++ /* Delayed worker, when the routing-tables are not yet ready. */ ++ struct delayed_work subflow_retry_work; ++ ++ /* Remote addresses */ ++ struct fullmesh_rem4 remaddr4[MPTCP_MAX_ADDR]; ++ struct fullmesh_rem6 remaddr6[MPTCP_MAX_ADDR]; ++ ++ struct mptcp_cb *mpcb; ++ ++ u16 remove_addrs; /* Addresses to remove */ ++ u8 announced_addrs_v4; /* IPv4 Addresses we did announce */ ++ u8 announced_addrs_v6; /* IPv6 Addresses we did announce */ ++ ++ u8 add_addr; /* Are we sending an add_addr? */ ++ ++ u8 rem4_bits; ++ u8 rem6_bits; ++ ++ /* Have we established the additional subflows for primary pair? */ ++ u8 first_pair:1; ++}; ++ ++struct mptcp_fm_ns { ++ struct mptcp_loc_addr __rcu *local; ++ spinlock_t local_lock; /* Protecting the above pointer */ ++ struct list_head events; ++ struct delayed_work address_worker; ++ ++ struct net *net; ++}; ++ ++static int num_subflows __read_mostly = 1; ++module_param(num_subflows, int, 0644); ++MODULE_PARM_DESC(num_subflows, "choose the number of subflows per pair of IP addresses of MPTCP connection"); ++ ++static int create_on_err __read_mostly; ++module_param(create_on_err, int, 0644); ++MODULE_PARM_DESC(create_on_err, "recreate the subflow upon a timeout"); ++ ++static struct mptcp_pm_ops full_mesh __read_mostly; ++ ++static void full_mesh_create_subflows(struct sock *meta_sk); ++ ++static struct mptcp_fm_ns *fm_get_ns(const struct net *net) ++{ ++ return (struct mptcp_fm_ns *)net->mptcp.path_managers[MPTCP_PM_FULLMESH]; ++} ++ ++static struct fullmesh_priv *fullmesh_get_priv(const struct mptcp_cb *mpcb) ++{ ++ return (struct fullmesh_priv *)&mpcb->mptcp_pm[0]; ++} ++ ++/* Find the first free index in the bitfield */ ++static int __mptcp_find_free_index(u8 bitfield, u8 base) ++{ ++ int i; ++ ++ /* There are anyways no free bits... */ ++ if (bitfield == 0xff) ++ goto exit; ++ ++ i = ffs(~(bitfield >> base)) - 1; ++ if (i < 0) ++ goto exit; ++ ++ /* No free bits when starting at base, try from 0 on */ ++ if (i + base >= sizeof(bitfield) * 8) ++ return __mptcp_find_free_index(bitfield, 0); ++ ++ return i + base; ++exit: ++ return -1; ++} ++ ++static int mptcp_find_free_index(u8 bitfield) ++{ ++ return __mptcp_find_free_index(bitfield, 0); ++} ++ ++static void mptcp_addv4_raddr(struct mptcp_cb *mpcb, ++ const struct in_addr *addr, ++ __be16 port, u8 id) ++{ ++ int i; ++ struct fullmesh_rem4 *rem4; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ ++ mptcp_for_each_bit_set(fmp->rem4_bits, i) { ++ rem4 = &fmp->remaddr4[i]; ++ ++ /* Address is already in the list --- continue */ ++ if (rem4->rem4_id == id && ++ rem4->addr.s_addr == addr->s_addr && rem4->port == port) ++ return; ++ ++ /* This may be the case, when the peer is behind a NAT. He is ++ * trying to JOIN, thus sending the JOIN with a certain ID. ++ * However the src_addr of the IP-packet has been changed. We ++ * update the addr in the list, because this is the address as ++ * OUR BOX sees it. ++ */ ++ if (rem4->rem4_id == id && rem4->addr.s_addr != addr->s_addr) { ++ /* update the address */ ++ mptcp_debug("%s: updating old addr:%pI4 to addr %pI4 with id:%d\n", ++ __func__, &rem4->addr.s_addr, ++ &addr->s_addr, id); ++ rem4->addr.s_addr = addr->s_addr; ++ rem4->port = port; ++ mpcb->list_rcvd = 1; ++ return; ++ } ++ } ++ ++ i = mptcp_find_free_index(fmp->rem4_bits); ++ /* Do we have already the maximum number of local/remote addresses? */ ++ if (i < 0) { ++ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI4\n", ++ __func__, MPTCP_MAX_ADDR, &addr->s_addr); ++ return; ++ } ++ ++ rem4 = &fmp->remaddr4[i]; ++ ++ /* Address is not known yet, store it */ ++ rem4->addr.s_addr = addr->s_addr; ++ rem4->port = port; ++ rem4->bitfield = 0; ++ rem4->retry_bitfield = 0; ++ rem4->rem4_id = id; ++ mpcb->list_rcvd = 1; ++ fmp->rem4_bits |= (1 << i); ++ ++ return; ++} ++ ++static void mptcp_addv6_raddr(struct mptcp_cb *mpcb, ++ const struct in6_addr *addr, ++ __be16 port, u8 id) ++{ ++ int i; ++ struct fullmesh_rem6 *rem6; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ ++ mptcp_for_each_bit_set(fmp->rem6_bits, i) { ++ rem6 = &fmp->remaddr6[i]; ++ ++ /* Address is already in the list --- continue */ ++ if (rem6->rem6_id == id && ++ ipv6_addr_equal(&rem6->addr, addr) && rem6->port == port) ++ return; ++ ++ /* This may be the case, when the peer is behind a NAT. He is ++ * trying to JOIN, thus sending the JOIN with a certain ID. ++ * However the src_addr of the IP-packet has been changed. We ++ * update the addr in the list, because this is the address as ++ * OUR BOX sees it. ++ */ ++ if (rem6->rem6_id == id) { ++ /* update the address */ ++ mptcp_debug("%s: updating old addr: %pI6 to addr %pI6 with id:%d\n", ++ __func__, &rem6->addr, addr, id); ++ rem6->addr = *addr; ++ rem6->port = port; ++ mpcb->list_rcvd = 1; ++ return; ++ } ++ } ++ ++ i = mptcp_find_free_index(fmp->rem6_bits); ++ /* Do we have already the maximum number of local/remote addresses? */ ++ if (i < 0) { ++ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI6\n", ++ __func__, MPTCP_MAX_ADDR, addr); ++ return; ++ } ++ ++ rem6 = &fmp->remaddr6[i]; ++ ++ /* Address is not known yet, store it */ ++ rem6->addr = *addr; ++ rem6->port = port; ++ rem6->bitfield = 0; ++ rem6->retry_bitfield = 0; ++ rem6->rem6_id = id; ++ mpcb->list_rcvd = 1; ++ fmp->rem6_bits |= (1 << i); ++ ++ return; ++} ++ ++static void mptcp_v4_rem_raddress(struct mptcp_cb *mpcb, u8 id) ++{ ++ int i; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ ++ mptcp_for_each_bit_set(fmp->rem4_bits, i) { ++ if (fmp->remaddr4[i].rem4_id == id) { ++ /* remove address from bitfield */ ++ fmp->rem4_bits &= ~(1 << i); ++ ++ break; ++ } ++ } ++} ++ ++static void mptcp_v6_rem_raddress(const struct mptcp_cb *mpcb, u8 id) ++{ ++ int i; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ ++ mptcp_for_each_bit_set(fmp->rem6_bits, i) { ++ if (fmp->remaddr6[i].rem6_id == id) { ++ /* remove address from bitfield */ ++ fmp->rem6_bits &= ~(1 << i); ++ ++ break; ++ } ++ } ++} ++ ++/* Sets the bitfield of the remote-address field */ ++static void mptcp_v4_set_init_addr_bit(const struct mptcp_cb *mpcb, ++ const struct in_addr *addr, u8 index) ++{ ++ int i; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ ++ mptcp_for_each_bit_set(fmp->rem4_bits, i) { ++ if (fmp->remaddr4[i].addr.s_addr == addr->s_addr) { ++ fmp->remaddr4[i].bitfield |= (1 << index); ++ return; ++ } ++ } ++} ++ ++/* Sets the bitfield of the remote-address field */ ++static void mptcp_v6_set_init_addr_bit(struct mptcp_cb *mpcb, ++ const struct in6_addr *addr, u8 index) ++{ ++ int i; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ ++ mptcp_for_each_bit_set(fmp->rem6_bits, i) { ++ if (ipv6_addr_equal(&fmp->remaddr6[i].addr, addr)) { ++ fmp->remaddr6[i].bitfield |= (1 << index); ++ return; ++ } ++ } ++} ++ ++static void mptcp_set_init_addr_bit(struct mptcp_cb *mpcb, ++ const union inet_addr *addr, ++ sa_family_t family, u8 id) ++{ ++ if (family == AF_INET) ++ mptcp_v4_set_init_addr_bit(mpcb, &addr->in, id); ++ else ++ mptcp_v6_set_init_addr_bit(mpcb, &addr->in6, id); ++} ++ ++static void mptcp_v4_subflows(struct sock *meta_sk, ++ const struct mptcp_loc4 *loc, ++ struct mptcp_rem4 *rem) ++{ ++ int i; ++ ++ for (i = 1; i < num_subflows; i++) ++ mptcp_init4_subsockets(meta_sk, loc, rem); ++} ++ ++#if IS_ENABLED(CONFIG_IPV6) ++static void mptcp_v6_subflows(struct sock *meta_sk, ++ const struct mptcp_loc6 *loc, ++ struct mptcp_rem6 *rem) ++{ ++ int i; ++ ++ for (i = 1; i < num_subflows; i++) ++ mptcp_init6_subsockets(meta_sk, loc, rem); ++} ++#endif ++ ++static void retry_subflow_worker(struct work_struct *work) ++{ ++ struct delayed_work *delayed_work = container_of(work, ++ struct delayed_work, ++ work); ++ struct fullmesh_priv *fmp = container_of(delayed_work, ++ struct fullmesh_priv, ++ subflow_retry_work); ++ struct mptcp_cb *mpcb = fmp->mpcb; ++ struct sock *meta_sk = mpcb->meta_sk; ++ struct mptcp_loc_addr *mptcp_local; ++ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); ++ int iter = 0, i; ++ ++ /* We need a local (stable) copy of the address-list. Really, it is not ++ * such a big deal, if the address-list is not 100% up-to-date. ++ */ ++ rcu_read_lock_bh(); ++ mptcp_local = rcu_dereference_bh(fm_ns->local); ++ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); ++ rcu_read_unlock_bh(); ++ ++ if (!mptcp_local) ++ return; ++ ++next_subflow: ++ if (iter) { ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ ++ cond_resched(); ++ } ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ if (!mptcp(tcp_sk(meta_sk))) ++ goto exit; ++ ++ iter++; ++ ++ if (sock_flag(meta_sk, SOCK_DEAD)) ++ goto exit; ++ ++ mptcp_for_each_bit_set(fmp->rem4_bits, i) { ++ struct fullmesh_rem4 *rem = &fmp->remaddr4[i]; ++ /* Do we need to retry establishing a subflow ? */ ++ if (rem->retry_bitfield) { ++ int i = mptcp_find_free_index(~rem->retry_bitfield); ++ struct mptcp_rem4 rem4; ++ ++ rem->bitfield |= (1 << i); ++ rem->retry_bitfield &= ~(1 << i); ++ ++ rem4.addr = rem->addr; ++ rem4.port = rem->port; ++ rem4.rem4_id = rem->rem4_id; ++ ++ mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], &rem4); ++ mptcp_v4_subflows(meta_sk, ++ &mptcp_local->locaddr4[i], ++ &rem4); ++ goto next_subflow; ++ } ++ } ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ mptcp_for_each_bit_set(fmp->rem6_bits, i) { ++ struct fullmesh_rem6 *rem = &fmp->remaddr6[i]; ++ ++ /* Do we need to retry establishing a subflow ? */ ++ if (rem->retry_bitfield) { ++ int i = mptcp_find_free_index(~rem->retry_bitfield); ++ struct mptcp_rem6 rem6; ++ ++ rem->bitfield |= (1 << i); ++ rem->retry_bitfield &= ~(1 << i); ++ ++ rem6.addr = rem->addr; ++ rem6.port = rem->port; ++ rem6.rem6_id = rem->rem6_id; ++ ++ mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], &rem6); ++ mptcp_v6_subflows(meta_sk, ++ &mptcp_local->locaddr6[i], ++ &rem6); ++ goto next_subflow; ++ } ++ } ++#endif ++ ++exit: ++ kfree(mptcp_local); ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ mptcp_mpcb_put(mpcb); ++ sock_put(meta_sk); ++} ++ ++/** ++ * Create all new subflows, by doing calls to mptcp_initX_subsockets ++ * ++ * This function uses a goto next_subflow, to allow releasing the lock between ++ * new subflows and giving other processes a chance to do some work on the ++ * socket and potentially finishing the communication. ++ **/ ++static void create_subflow_worker(struct work_struct *work) ++{ ++ struct fullmesh_priv *fmp = container_of(work, struct fullmesh_priv, ++ subflow_work); ++ struct mptcp_cb *mpcb = fmp->mpcb; ++ struct sock *meta_sk = mpcb->meta_sk; ++ struct mptcp_loc_addr *mptcp_local; ++ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); ++ int iter = 0, retry = 0; ++ int i; ++ ++ /* We need a local (stable) copy of the address-list. Really, it is not ++ * such a big deal, if the address-list is not 100% up-to-date. ++ */ ++ rcu_read_lock_bh(); ++ mptcp_local = rcu_dereference_bh(fm_ns->local); ++ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); ++ rcu_read_unlock_bh(); ++ ++ if (!mptcp_local) ++ return; ++ ++next_subflow: ++ if (iter) { ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ ++ cond_resched(); ++ } ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ if (sock_flag(meta_sk, SOCK_DEAD) || !mptcp(tcp_sk(meta_sk))) ++ goto exit; ++ ++ if (mpcb->master_sk && ++ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) ++ goto exit; ++ ++ /* Create the additional subflows for the first pair */ ++ if (fmp->first_pair == 0 && mpcb->master_sk) { ++ struct mptcp_loc4 loc; ++ struct mptcp_rem4 rem; ++ ++ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; ++ loc.loc4_id = 0; ++ loc.low_prio = 0; ++ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; ++ ++ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; ++ rem.port = inet_sk(meta_sk)->inet_dport; ++ rem.rem4_id = 0; /* Default 0 */ ++ ++ mptcp_v4_subflows(meta_sk, &loc, &rem); ++ ++ fmp->first_pair = 1; ++ } ++ iter++; ++ ++ mptcp_for_each_bit_set(fmp->rem4_bits, i) { ++ struct fullmesh_rem4 *rem; ++ u8 remaining_bits; ++ ++ rem = &fmp->remaddr4[i]; ++ remaining_bits = ~(rem->bitfield) & mptcp_local->loc4_bits; ++ ++ /* Are there still combinations to handle? */ ++ if (remaining_bits) { ++ int i = mptcp_find_free_index(~remaining_bits); ++ struct mptcp_rem4 rem4; ++ ++ rem->bitfield |= (1 << i); ++ ++ rem4.addr = rem->addr; ++ rem4.port = rem->port; ++ rem4.rem4_id = rem->rem4_id; ++ ++ /* If a route is not yet available then retry once */ ++ if (mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], ++ &rem4) == -ENETUNREACH) ++ retry = rem->retry_bitfield |= (1 << i); ++ else ++ mptcp_v4_subflows(meta_sk, ++ &mptcp_local->locaddr4[i], ++ &rem4); ++ goto next_subflow; ++ } ++ } ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ if (fmp->first_pair == 0 && mpcb->master_sk) { ++ struct mptcp_loc6 loc; ++ struct mptcp_rem6 rem; ++ ++ loc.addr = inet6_sk(meta_sk)->saddr; ++ loc.loc6_id = 0; ++ loc.low_prio = 0; ++ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; ++ ++ rem.addr = meta_sk->sk_v6_daddr; ++ rem.port = inet_sk(meta_sk)->inet_dport; ++ rem.rem6_id = 0; /* Default 0 */ ++ ++ mptcp_v6_subflows(meta_sk, &loc, &rem); ++ ++ fmp->first_pair = 1; ++ } ++ mptcp_for_each_bit_set(fmp->rem6_bits, i) { ++ struct fullmesh_rem6 *rem; ++ u8 remaining_bits; ++ ++ rem = &fmp->remaddr6[i]; ++ remaining_bits = ~(rem->bitfield) & mptcp_local->loc6_bits; ++ ++ /* Are there still combinations to handle? */ ++ if (remaining_bits) { ++ int i = mptcp_find_free_index(~remaining_bits); ++ struct mptcp_rem6 rem6; ++ ++ rem->bitfield |= (1 << i); ++ ++ rem6.addr = rem->addr; ++ rem6.port = rem->port; ++ rem6.rem6_id = rem->rem6_id; ++ ++ /* If a route is not yet available then retry once */ ++ if (mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], ++ &rem6) == -ENETUNREACH) ++ retry = rem->retry_bitfield |= (1 << i); ++ else ++ mptcp_v6_subflows(meta_sk, ++ &mptcp_local->locaddr6[i], ++ &rem6); ++ goto next_subflow; ++ } ++ } ++#endif ++ ++ if (retry && !delayed_work_pending(&fmp->subflow_retry_work)) { ++ sock_hold(meta_sk); ++ refcount_inc(&mpcb->mpcb_refcnt); ++ queue_delayed_work(mptcp_wq, &fmp->subflow_retry_work, ++ msecs_to_jiffies(MPTCP_SUBFLOW_RETRY_DELAY)); ++ } ++ ++exit: ++ kfree(mptcp_local); ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ mptcp_mpcb_put(mpcb); ++ sock_put(meta_sk); ++} ++ ++static void announce_remove_addr(u8 addr_id, struct sock *meta_sk) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ struct sock *sk = mptcp_select_ack_sock(meta_sk); ++ ++ fmp->remove_addrs |= (1 << addr_id); ++ mpcb->addr_signal = 1; ++ ++ if (sk) ++ tcp_send_ack(sk); ++} ++ ++static void update_addr_bitfields(struct sock *meta_sk, ++ const struct mptcp_loc_addr *mptcp_local) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ int i; ++ ++ /* The bits in announced_addrs_* always match with loc*_bits. So, a ++ * simple & operation unsets the correct bits, because these go from ++ * announced to non-announced ++ */ ++ fmp->announced_addrs_v4 &= mptcp_local->loc4_bits; ++ ++ mptcp_for_each_bit_set(fmp->rem4_bits, i) { ++ fmp->remaddr4[i].bitfield &= mptcp_local->loc4_bits; ++ fmp->remaddr4[i].retry_bitfield &= mptcp_local->loc4_bits; ++ } ++ ++ fmp->announced_addrs_v6 &= mptcp_local->loc6_bits; ++ ++ mptcp_for_each_bit_set(fmp->rem6_bits, i) { ++ fmp->remaddr6[i].bitfield &= mptcp_local->loc6_bits; ++ fmp->remaddr6[i].retry_bitfield &= mptcp_local->loc6_bits; ++ } ++} ++ ++static int mptcp_find_address(const struct mptcp_loc_addr *mptcp_local, ++ sa_family_t family, const union inet_addr *addr, ++ int if_idx) ++{ ++ int i; ++ u8 loc_bits; ++ bool found = false; ++ ++ if (family == AF_INET) ++ loc_bits = mptcp_local->loc4_bits; ++ else ++ loc_bits = mptcp_local->loc6_bits; ++ ++ mptcp_for_each_bit_set(loc_bits, i) { ++ if (family == AF_INET && ++ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && ++ mptcp_local->locaddr4[i].addr.s_addr == addr->in.s_addr) { ++ found = true; ++ break; ++ } ++ if (family == AF_INET6 && ++ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && ++ ipv6_addr_equal(&mptcp_local->locaddr6[i].addr, ++ &addr->in6)) { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ return -1; ++ ++ return i; ++} ++ ++static int mptcp_find_address_transp(const struct mptcp_loc_addr *mptcp_local, ++ sa_family_t family, int if_idx) ++{ ++ bool found = false; ++ u8 loc_bits; ++ int i; ++ ++ if (family == AF_INET) ++ loc_bits = mptcp_local->loc4_bits; ++ else ++ loc_bits = mptcp_local->loc6_bits; ++ ++ mptcp_for_each_bit_set(loc_bits, i) { ++ if (family == AF_INET && ++ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx)) { ++ found = true; ++ break; ++ } ++ if (family == AF_INET6 && ++ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx)) { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ return -1; ++ ++ return i; ++} ++ ++static void mptcp_address_worker(struct work_struct *work) ++{ ++ const struct delayed_work *delayed_work = container_of(work, ++ struct delayed_work, ++ work); ++ struct mptcp_fm_ns *fm_ns = container_of(delayed_work, ++ struct mptcp_fm_ns, ++ address_worker); ++ struct net *net = fm_ns->net; ++ struct mptcp_addr_event *event = NULL; ++ struct mptcp_loc_addr *mptcp_local, *old; ++ int i, id = -1; /* id is used in the socket-code on a delete-event */ ++ bool success; /* Used to indicate if we succeeded handling the event */ ++ ++next_event: ++ success = false; ++ kfree(event); ++ ++ /* First, let's dequeue an event from our event-list */ ++ rcu_read_lock_bh(); ++ spin_lock(&fm_ns->local_lock); ++ ++ event = list_first_entry_or_null(&fm_ns->events, ++ struct mptcp_addr_event, list); ++ if (!event) { ++ spin_unlock(&fm_ns->local_lock); ++ rcu_read_unlock_bh(); ++ return; ++ } ++ ++ list_del(&event->list); ++ ++ mptcp_local = rcu_dereference_bh(fm_ns->local); ++ ++ if (event->code == MPTCP_EVENT_DEL) { ++ id = mptcp_find_address(mptcp_local, event->family, ++ &event->addr, event->if_idx); ++ ++ /* Not in the list - so we don't care */ ++ if (id < 0) { ++ mptcp_debug("%s could not find id\n", __func__); ++ goto duno; ++ } ++ ++ old = mptcp_local; ++ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), ++ GFP_ATOMIC); ++ if (!mptcp_local) ++ goto duno; ++ ++ if (event->family == AF_INET) ++ mptcp_local->loc4_bits &= ~(1 << id); ++ else ++ mptcp_local->loc6_bits &= ~(1 << id); ++ ++ rcu_assign_pointer(fm_ns->local, mptcp_local); ++ kfree_rcu(old, rcu); ++ } else { ++ int i = mptcp_find_address(mptcp_local, event->family, ++ &event->addr, event->if_idx); ++ int j = i; ++ ++ if (j < 0) { ++ /* Not in the list, so we have to find an empty slot */ ++ if (event->family == AF_INET) ++ i = __mptcp_find_free_index(mptcp_local->loc4_bits, ++ mptcp_local->next_v4_index); ++ if (event->family == AF_INET6) ++ i = __mptcp_find_free_index(mptcp_local->loc6_bits, ++ mptcp_local->next_v6_index); ++ ++ if (i < 0) { ++ mptcp_debug("%s no more space\n", __func__); ++ goto duno; ++ } ++ ++ /* It might have been a MOD-event. */ ++ event->code = MPTCP_EVENT_ADD; ++ } else { ++ /* Let's check if anything changes */ ++ if (event->family == AF_INET && ++ event->low_prio == mptcp_local->locaddr4[i].low_prio) ++ goto duno; ++ ++ if (event->family == AF_INET6 && ++ event->low_prio == mptcp_local->locaddr6[i].low_prio) ++ goto duno; ++ } ++ ++ old = mptcp_local; ++ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), ++ GFP_ATOMIC); ++ if (!mptcp_local) ++ goto duno; ++ ++ if (event->family == AF_INET) { ++ mptcp_local->locaddr4[i].addr.s_addr = event->addr.in.s_addr; ++ mptcp_local->locaddr4[i].loc4_id = i + 1; ++ mptcp_local->locaddr4[i].low_prio = event->low_prio; ++ mptcp_local->locaddr4[i].if_idx = event->if_idx; ++ ++ mptcp_debug("%s updated IP %pI4 on ifidx %u prio %u id %u\n", ++ __func__, &event->addr.in.s_addr, ++ event->if_idx, event->low_prio, i + 1); ++ } else { ++ mptcp_local->locaddr6[i].addr = event->addr.in6; ++ mptcp_local->locaddr6[i].loc6_id = i + MPTCP_MAX_ADDR; ++ mptcp_local->locaddr6[i].low_prio = event->low_prio; ++ mptcp_local->locaddr6[i].if_idx = event->if_idx; ++ ++ mptcp_debug("%s updated IP %pI6 on ifidx %u prio %u id %u\n", ++ __func__, &event->addr.in6, ++ event->if_idx, event->low_prio, i + MPTCP_MAX_ADDR); ++ } ++ ++ if (j < 0) { ++ if (event->family == AF_INET) { ++ mptcp_local->loc4_bits |= (1 << i); ++ mptcp_local->next_v4_index = i + 1; ++ } else { ++ mptcp_local->loc6_bits |= (1 << i); ++ mptcp_local->next_v6_index = i + 1; ++ } ++ } ++ ++ rcu_assign_pointer(fm_ns->local, mptcp_local); ++ kfree_rcu(old, rcu); ++ } ++ success = true; ++ ++duno: ++ spin_unlock(&fm_ns->local_lock); ++ rcu_read_unlock_bh(); ++ ++ if (!success) ++ goto next_event; ++ ++ /* Now we iterate over the MPTCP-sockets and apply the event. */ ++ for (i = 0; i < MPTCP_HASH_SIZE; i++) { ++ const struct hlist_nulls_node *node; ++ struct tcp_sock *meta_tp; ++ ++ rcu_read_lock_bh(); ++ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[i], ++ tk_table) { ++ struct sock *meta_sk = (struct sock *)meta_tp, *sk; ++ bool meta_v4 = meta_sk->sk_family == AF_INET; ++ struct mptcp_cb *mpcb; ++ ++ if (sock_net(meta_sk) != net) ++ continue; ++ ++ if (meta_v4) { ++ /* skip IPv6 events if meta is IPv4 */ ++ if (event->family == AF_INET6) ++ continue; ++ } else if (event->family == AF_INET && meta_sk->sk_ipv6only) { ++ /* skip IPv4 events if IPV6_V6ONLY is set */ ++ continue; ++ } ++ ++ if (unlikely(!refcount_inc_not_zero(&meta_sk->sk_refcnt))) ++ continue; ++ ++ bh_lock_sock(meta_sk); ++ ++ mpcb = meta_tp->mpcb; ++ if (!mpcb) ++ goto next; ++ ++ if (!mptcp(meta_tp) || !is_meta_sk(meta_sk) || ++ mptcp_in_infinite_mapping_weak(mpcb)) ++ goto next; ++ ++ /* May be that the pm has changed in-between */ ++ if (mpcb->pm_ops != &full_mesh) ++ goto next; ++ ++ if (sock_owned_by_user(meta_sk)) { ++ if (!test_and_set_bit(MPTCP_PATH_MANAGER_DEFERRED, ++ &meta_sk->sk_tsq_flags)) ++ sock_hold(meta_sk); ++ ++ goto next; ++ } ++ ++ if (event->code == MPTCP_EVENT_ADD) { ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ ++ fmp->add_addr++; ++ mpcb->addr_signal = 1; ++ ++ sk = mptcp_select_ack_sock(meta_sk); ++ if (sk) ++ tcp_send_ack(sk); ++ ++ full_mesh_create_subflows(meta_sk); ++ } ++ ++ if (event->code == MPTCP_EVENT_DEL) { ++ struct mptcp_tcp_sock *mptcp; ++ struct mptcp_loc_addr *mptcp_local; ++ struct hlist_node *tmp; ++ bool found = false; ++ ++ mptcp_local = rcu_dereference_bh(fm_ns->local); ++ ++ /* In any case, we need to update our bitfields */ ++ if (id >= 0) ++ update_addr_bitfields(meta_sk, mptcp_local); ++ ++ /* Look for the socket and remove him */ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if ((event->family == AF_INET6 && ++ (sk->sk_family == AF_INET || ++ mptcp_v6_is_v4_mapped(sk))) || ++ (event->family == AF_INET && ++ (sk->sk_family == AF_INET6 && ++ !mptcp_v6_is_v4_mapped(sk)))) ++ continue; ++ ++ if (event->family == AF_INET && ++ (sk->sk_family == AF_INET || ++ mptcp_v6_is_v4_mapped(sk)) && ++ inet_sk(sk)->inet_saddr != event->addr.in.s_addr) ++ continue; ++ ++ if (event->family == AF_INET6 && ++ sk->sk_family == AF_INET6 && ++ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) ++ continue; ++ ++ /* Reinject, so that pf = 1 and so we ++ * won't select this one as the ++ * ack-sock. ++ */ ++ mptcp_reinject_data(sk, 0); ++ ++ /* We announce the removal of this id */ ++ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, meta_sk); ++ ++ mptcp_sub_force_close(sk); ++ found = true; ++ } ++ ++ if (found) ++ goto next; ++ ++ /* The id may have been given by the event, ++ * matching on a local address. And it may not ++ * have matched on one of the above sockets, ++ * because the client never created a subflow. ++ * So, we have to finally remove it here. ++ */ ++ if (id >= 0) { ++ u8 loc_id = id ++ + (event->family == AF_INET ? 1 : MPTCP_MAX_ADDR); ++ announce_remove_addr(loc_id, meta_sk); ++ } ++ } ++ ++ if (event->code == MPTCP_EVENT_MOD) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp = tcp_sk(sk); ++ if (event->family == AF_INET && ++ (sk->sk_family == AF_INET || ++ mptcp_v6_is_v4_mapped(sk)) && ++ inet_sk(sk)->inet_saddr == event->addr.in.s_addr) { ++ if (event->low_prio != tp->mptcp->low_prio) { ++ tp->mptcp->send_mp_prio = 1; ++ tp->mptcp->low_prio = event->low_prio; ++ ++ tcp_send_ack(sk); ++ } ++ } ++ ++ if (event->family == AF_INET6 && ++ sk->sk_family == AF_INET6 && ++ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) { ++ if (event->low_prio != tp->mptcp->low_prio) { ++ tp->mptcp->send_mp_prio = 1; ++ tp->mptcp->low_prio = event->low_prio; ++ ++ tcp_send_ack(sk); ++ } ++ } ++ } ++ } ++next: ++ bh_unlock_sock(meta_sk); ++ sock_put(meta_sk); ++ } ++ rcu_read_unlock_bh(); ++ } ++ goto next_event; ++} ++ ++static struct mptcp_addr_event *lookup_similar_event(const struct net *net, ++ const struct mptcp_addr_event *event) ++{ ++ struct mptcp_addr_event *eventq; ++ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); ++ ++ list_for_each_entry(eventq, &fm_ns->events, list) { ++ if (eventq->family != event->family) ++ continue; ++ if (eventq->if_idx != event->if_idx) ++ continue; ++ if (event->family == AF_INET) { ++ if (eventq->addr.in.s_addr == event->addr.in.s_addr) ++ return eventq; ++ } else { ++ if (ipv6_addr_equal(&eventq->addr.in6, &event->addr.in6)) ++ return eventq; ++ } ++ } ++ return NULL; ++} ++ ++/* We already hold the net-namespace MPTCP-lock */ ++static void add_pm_event(struct net *net, const struct mptcp_addr_event *event) ++{ ++ struct mptcp_addr_event *eventq = lookup_similar_event(net, event); ++ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); ++ ++ if (eventq) { ++ switch (event->code) { ++ case MPTCP_EVENT_DEL: ++ mptcp_debug("%s del old_code %u\n", __func__, eventq->code); ++ list_del(&eventq->list); ++ kfree(eventq); ++ break; ++ case MPTCP_EVENT_ADD: ++ mptcp_debug("%s add old_code %u\n", __func__, eventq->code); ++ eventq->low_prio = event->low_prio; ++ eventq->code = MPTCP_EVENT_ADD; ++ return; ++ case MPTCP_EVENT_MOD: ++ mptcp_debug("%s mod old_code %u\n", __func__, eventq->code); ++ eventq->low_prio = event->low_prio; ++ eventq->code = MPTCP_EVENT_MOD; ++ return; ++ } ++ } ++ ++ /* OK, we have to add the new address to the wait queue */ ++ eventq = kmemdup(event, sizeof(struct mptcp_addr_event), GFP_ATOMIC); ++ if (!eventq) ++ return; ++ ++ list_add_tail(&eventq->list, &fm_ns->events); ++ ++ /* Create work-queue */ ++ if (!delayed_work_pending(&fm_ns->address_worker)) ++ queue_delayed_work(mptcp_wq, &fm_ns->address_worker, ++ msecs_to_jiffies(500)); ++} ++ ++static void addr4_event_handler(const struct in_ifaddr *ifa, unsigned long event, ++ struct net *net) ++{ ++ const struct net_device *netdev = ifa->ifa_dev->dev; ++ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); ++ struct mptcp_addr_event mpevent; ++ ++ if (ifa->ifa_scope > RT_SCOPE_LINK || ++ ipv4_is_loopback(ifa->ifa_local)) ++ return; ++ ++ spin_lock_bh(&fm_ns->local_lock); ++ ++ mpevent.family = AF_INET; ++ mpevent.addr.in.s_addr = ifa->ifa_local; ++ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; ++ mpevent.if_idx = netdev->ifindex; ++ ++ if (event == NETDEV_DOWN || !netif_running(netdev) || ++ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) ++ mpevent.code = MPTCP_EVENT_DEL; ++ else if (event == NETDEV_UP) ++ mpevent.code = MPTCP_EVENT_ADD; ++ else if (event == NETDEV_CHANGE) ++ mpevent.code = MPTCP_EVENT_MOD; ++ ++ mptcp_debug("%s created event for %pI4, code %u prio %u idx %u\n", __func__, ++ &ifa->ifa_local, mpevent.code, mpevent.low_prio, mpevent.if_idx); ++ add_pm_event(net, &mpevent); ++ ++ spin_unlock_bh(&fm_ns->local_lock); ++ return; ++} ++ ++/* React on IPv4-addr add/rem-events */ ++static int mptcp_pm_inetaddr_event(struct notifier_block *this, ++ unsigned long event, void *ptr) ++{ ++ const struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; ++ struct net *net = dev_net(ifa->ifa_dev->dev); ++ ++ if (!(event == NETDEV_UP || event == NETDEV_DOWN || ++ event == NETDEV_CHANGE)) ++ return NOTIFY_DONE; ++ ++ addr4_event_handler(ifa, event, net); ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block mptcp_pm_inetaddr_notifier = { ++ .notifier_call = mptcp_pm_inetaddr_event, ++}; ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ ++static int inet6_addr_event(struct notifier_block *this, unsigned long event, ++ void *ptr); ++ ++static void addr6_event_handler(const struct inet6_ifaddr *ifa, unsigned long event, ++ struct net *net) ++{ ++ const struct net_device *netdev = ifa->idev->dev; ++ int addr_type = ipv6_addr_type(&ifa->addr); ++ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); ++ struct mptcp_addr_event mpevent; ++ ++ if (ifa->scope > RT_SCOPE_LINK || ++ addr_type == IPV6_ADDR_ANY || ++ (addr_type & IPV6_ADDR_LOOPBACK) || ++ (addr_type & IPV6_ADDR_LINKLOCAL)) ++ return; ++ ++ spin_lock_bh(&fm_ns->local_lock); ++ ++ mpevent.family = AF_INET6; ++ mpevent.addr.in6 = ifa->addr; ++ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; ++ mpevent.if_idx = netdev->ifindex; ++ ++ if (event == NETDEV_DOWN || !netif_running(netdev) || ++ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) ++ mpevent.code = MPTCP_EVENT_DEL; ++ else if (event == NETDEV_UP) ++ mpevent.code = MPTCP_EVENT_ADD; ++ else if (event == NETDEV_CHANGE) ++ mpevent.code = MPTCP_EVENT_MOD; ++ ++ mptcp_debug("%s created event for %pI6, code %u prio %u idx %u\n", __func__, ++ &ifa->addr, mpevent.code, mpevent.low_prio, mpevent.if_idx); ++ add_pm_event(net, &mpevent); ++ ++ spin_unlock_bh(&fm_ns->local_lock); ++ return; ++} ++ ++/* React on IPv6-addr add/rem-events */ ++static int inet6_addr_event(struct notifier_block *this, unsigned long event, ++ void *ptr) ++{ ++ struct inet6_ifaddr *ifa6 = (struct inet6_ifaddr *)ptr; ++ struct net *net = dev_net(ifa6->idev->dev); ++ ++ if (!(event == NETDEV_UP || event == NETDEV_DOWN || ++ event == NETDEV_CHANGE)) ++ return NOTIFY_DONE; ++ ++ addr6_event_handler(ifa6, event, net); ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block inet6_addr_notifier = { ++ .notifier_call = inet6_addr_event, ++}; ++ ++#endif ++ ++/* React on ifup/down-events */ ++static int netdev_event(struct notifier_block *this, unsigned long event, ++ void *ptr) ++{ ++ const struct net_device *dev = netdev_notifier_info_to_dev(ptr); ++ struct in_device *in_dev; ++#if IS_ENABLED(CONFIG_IPV6) ++ struct inet6_dev *in6_dev; ++#endif ++ ++ if (!(event == NETDEV_UP || event == NETDEV_DOWN || ++ event == NETDEV_CHANGE)) ++ return NOTIFY_DONE; ++ ++ rcu_read_lock(); ++ in_dev = __in_dev_get_rtnl(dev); ++ ++ if (in_dev) { ++ struct in_ifaddr *ifa; ++ ++ in_dev_for_each_ifa_rcu(ifa, in_dev) { ++ mptcp_pm_inetaddr_event(NULL, event, ifa); ++ } ++ } ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ in6_dev = __in6_dev_get(dev); ++ ++ if (in6_dev) { ++ struct inet6_ifaddr *ifa6; ++ list_for_each_entry(ifa6, &in6_dev->addr_list, if_list) ++ inet6_addr_event(NULL, event, ifa6); ++ } ++#endif ++ ++ rcu_read_unlock(); ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block mptcp_pm_netdev_notifier = { ++ .notifier_call = netdev_event, ++}; ++ ++static void full_mesh_add_raddr(struct mptcp_cb *mpcb, ++ const union inet_addr *addr, ++ sa_family_t family, __be16 port, u8 id) ++{ ++ if (family == AF_INET) ++ mptcp_addv4_raddr(mpcb, &addr->in, port, id); ++ else ++ mptcp_addv6_raddr(mpcb, &addr->in6, port, id); ++} ++ ++static void full_mesh_new_session(const struct sock *meta_sk) ++{ ++ struct mptcp_loc_addr *mptcp_local; ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); ++ struct tcp_sock *master_tp = tcp_sk(mpcb->master_sk); ++ int i, index, if_idx = 0; ++ union inet_addr saddr, daddr; ++ sa_family_t family = AF_INET; ++ bool meta_v4 = meta_sk->sk_family == AF_INET; ++ ++ /* Init local variables necessary for the rest */ ++ if (meta_sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(meta_sk)) { ++ saddr.ip = inet_sk(meta_sk)->inet_saddr; ++ daddr.ip = inet_sk(meta_sk)->inet_daddr; ++ if_idx = mpcb->master_sk->sk_bound_dev_if; ++ family = AF_INET; ++#if IS_ENABLED(CONFIG_IPV6) ++ } else { ++ saddr.in6 = inet6_sk(meta_sk)->saddr; ++ daddr.in6 = meta_sk->sk_v6_daddr; ++ if_idx = mpcb->master_sk->sk_bound_dev_if; ++ family = AF_INET6; ++#endif ++ } ++ ++ if (inet_sk(meta_sk)->transparent) ++ if_idx = inet_sk(meta_sk)->rx_dst_ifindex; ++ ++ rcu_read_lock_bh(); ++ mptcp_local = rcu_dereference(fm_ns->local); ++ ++ if (inet_sk(meta_sk)->transparent) ++ index = mptcp_find_address_transp(mptcp_local, family, if_idx); ++ else ++ index = mptcp_find_address(mptcp_local, family, &saddr, if_idx); ++ if (index < 0) ++ goto fallback; ++ ++ if (family == AF_INET) ++ master_tp->mptcp->low_prio = mptcp_local->locaddr4[index].low_prio; ++ else ++ master_tp->mptcp->low_prio = mptcp_local->locaddr6[index].low_prio; ++ master_tp->mptcp->send_mp_prio = master_tp->mptcp->low_prio; ++ ++ full_mesh_add_raddr(mpcb, &daddr, family, 0, 0); ++ mptcp_set_init_addr_bit(mpcb, &daddr, family, index); ++ ++ /* Initialize workqueue-struct */ ++ INIT_WORK(&fmp->subflow_work, create_subflow_worker); ++ INIT_DELAYED_WORK(&fmp->subflow_retry_work, retry_subflow_worker); ++ fmp->mpcb = mpcb; ++ ++ if (!meta_v4 && meta_sk->sk_ipv6only) ++ goto skip_ipv4; ++ ++ /* Look for the address among the local addresses */ ++ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { ++ __be32 ifa_address = mptcp_local->locaddr4[i].addr.s_addr; ++ ++ /* We do not need to announce the initial subflow's address again */ ++ if (family == AF_INET && ++ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && ++ saddr.ip == ifa_address) ++ continue; ++ ++ fmp->add_addr++; ++ mpcb->addr_signal = 1; ++ } ++ ++skip_ipv4: ++#if IS_ENABLED(CONFIG_IPV6) ++ /* skip IPv6 addresses if meta-socket is IPv4 */ ++ if (meta_v4) ++ goto skip_ipv6; ++ ++ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { ++ const struct in6_addr *ifa6 = &mptcp_local->locaddr6[i].addr; ++ ++ /* We do not need to announce the initial subflow's address again */ ++ if (family == AF_INET6 && ++ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && ++ ipv6_addr_equal(&saddr.in6, ifa6)) ++ continue; ++ ++ fmp->add_addr++; ++ mpcb->addr_signal = 1; ++ } ++ ++skip_ipv6: ++#endif ++ ++ rcu_read_unlock_bh(); ++ ++ if (family == AF_INET) ++ fmp->announced_addrs_v4 |= (1 << index); ++ else ++ fmp->announced_addrs_v6 |= (1 << index); ++ ++ for (i = fmp->add_addr; i && fmp->add_addr; i--) ++ tcp_send_ack(mpcb->master_sk); ++ ++ if (master_tp->mptcp->send_mp_prio) ++ tcp_send_ack(mpcb->master_sk); ++ ++ return; ++ ++fallback: ++ rcu_read_unlock_bh(); ++ mptcp_fallback_default(mpcb); ++ return; ++} ++ ++static void full_mesh_create_subflows(struct sock *meta_sk) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ ++ if (mptcp_in_infinite_mapping_weak(mpcb) || ++ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) ++ return; ++ ++ if (mpcb->master_sk && ++ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) ++ return; ++ ++ if (!work_pending(&fmp->subflow_work)) { ++ sock_hold(meta_sk); ++ refcount_inc(&mpcb->mpcb_refcnt); ++ queue_work(mptcp_wq, &fmp->subflow_work); ++ } ++} ++ ++/* Called upon release_sock, if the socket was owned by the user during ++ * a path-management event. ++ */ ++static void full_mesh_release_sock(struct sock *meta_sk) ++{ ++ struct mptcp_loc_addr *mptcp_local; ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); ++ bool meta_v4 = meta_sk->sk_family == AF_INET; ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ int i; ++ ++ rcu_read_lock_bh(); ++ mptcp_local = rcu_dereference(fm_ns->local); ++ ++ if (!meta_v4 && meta_sk->sk_ipv6only) ++ goto skip_ipv4; ++ ++ /* First, detect modifications or additions */ ++ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { ++ struct in_addr ifa = mptcp_local->locaddr4[i].addr; ++ bool found = false; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (sk->sk_family == AF_INET6 && ++ !mptcp_v6_is_v4_mapped(sk)) ++ continue; ++ ++ if (inet_sk(sk)->inet_saddr != ifa.s_addr) ++ continue; ++ ++ found = true; ++ ++ if (mptcp_local->locaddr4[i].low_prio != tp->mptcp->low_prio) { ++ tp->mptcp->send_mp_prio = 1; ++ tp->mptcp->low_prio = mptcp_local->locaddr4[i].low_prio; ++ ++ tcp_send_ack(sk); ++ } ++ } ++ ++ if (!found) { ++ struct sock *sk; ++ ++ fmp->add_addr++; ++ mpcb->addr_signal = 1; ++ ++ sk = mptcp_select_ack_sock(meta_sk); ++ if (sk) ++ tcp_send_ack(sk); ++ full_mesh_create_subflows(meta_sk); ++ } ++ } ++ ++skip_ipv4: ++#if IS_ENABLED(CONFIG_IPV6) ++ /* skip IPv6 addresses if meta-socket is IPv4 */ ++ if (meta_v4) ++ goto removal; ++ ++ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { ++ struct in6_addr ifa = mptcp_local->locaddr6[i].addr; ++ bool found = false; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (sk->sk_family == AF_INET || ++ mptcp_v6_is_v4_mapped(sk)) ++ continue; ++ ++ if (!ipv6_addr_equal(&inet6_sk(sk)->saddr, &ifa)) ++ continue; ++ ++ found = true; ++ ++ if (mptcp_local->locaddr6[i].low_prio != tp->mptcp->low_prio) { ++ tp->mptcp->send_mp_prio = 1; ++ tp->mptcp->low_prio = mptcp_local->locaddr6[i].low_prio; ++ ++ tcp_send_ack(sk); ++ } ++ } ++ ++ if (!found) { ++ struct sock *sk; ++ ++ fmp->add_addr++; ++ mpcb->addr_signal = 1; ++ ++ sk = mptcp_select_ack_sock(meta_sk); ++ if (sk) ++ tcp_send_ack(sk); ++ full_mesh_create_subflows(meta_sk); ++ } ++ } ++ ++removal: ++#endif ++ ++ /* Now, detect address-removals */ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ bool shall_remove = true; ++ ++ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { ++ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { ++ if (inet_sk(sk)->inet_saddr == mptcp_local->locaddr4[i].addr.s_addr) { ++ shall_remove = false; ++ break; ++ } ++ } ++ } else { ++ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { ++ if (ipv6_addr_equal(&inet6_sk(sk)->saddr, &mptcp_local->locaddr6[i].addr)) { ++ shall_remove = false; ++ break; ++ } ++ } ++ } ++ ++ if (shall_remove) { ++ /* Reinject, so that pf = 1 and so we ++ * won't select this one as the ++ * ack-sock. ++ */ ++ mptcp_reinject_data(sk, 0); ++ ++ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, ++ meta_sk); ++ ++ mptcp_sub_force_close(sk); ++ } ++ } ++ ++ /* Just call it optimistically. It actually cannot do any harm */ ++ update_addr_bitfields(meta_sk, mptcp_local); ++ ++ rcu_read_unlock_bh(); ++} ++ ++static int full_mesh_get_local_id(const struct sock *meta_sk, ++ sa_family_t family, union inet_addr *addr, ++ bool *low_prio) ++{ ++ struct mptcp_loc_addr *mptcp_local; ++ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); ++ int index, id = -1; ++ ++ /* Handle the backup-flows */ ++ rcu_read_lock_bh(); ++ mptcp_local = rcu_dereference(fm_ns->local); ++ ++ index = mptcp_find_address(mptcp_local, family, addr, 0); ++ ++ if (index != -1) { ++ if (family == AF_INET) { ++ id = mptcp_local->locaddr4[index].loc4_id; ++ *low_prio = mptcp_local->locaddr4[index].low_prio; ++ } else { ++ id = mptcp_local->locaddr6[index].loc6_id; ++ *low_prio = mptcp_local->locaddr6[index].low_prio; ++ } ++ } ++ ++ ++ rcu_read_unlock_bh(); ++ ++ return id; ++} ++ ++static void full_mesh_addr_signal(struct sock *sk, unsigned *size, ++ struct tcp_out_options *opts, ++ struct sk_buff *skb) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_cb *mpcb = tp->mpcb; ++ struct sock *meta_sk = mpcb->meta_sk; ++ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); ++ struct mptcp_loc_addr *mptcp_local; ++ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); ++ int remove_addr_len; ++ u8 unannouncedv4 = 0, unannouncedv6 = 0; ++ bool meta_v4 = meta_sk->sk_family == AF_INET; ++ ++ mpcb->addr_signal = 0; ++ ++ if (likely(!fmp->add_addr)) ++ goto remove_addr; ++ ++ rcu_read_lock_bh(); ++ mptcp_local = rcu_dereference(fm_ns->local); ++ ++ if (!meta_v4 && meta_sk->sk_ipv6only) ++ goto skip_ipv4; ++ ++ /* IPv4 */ ++ unannouncedv4 = (~fmp->announced_addrs_v4) & mptcp_local->loc4_bits; ++ if (unannouncedv4 && ++ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && ++ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN) || ++ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && ++ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1))) { ++ int ind = mptcp_find_free_index(~unannouncedv4); ++ ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_ADD_ADDR; ++ opts->add_addr4.addr_id = mptcp_local->locaddr4[ind].loc4_id; ++ opts->add_addr4.addr = mptcp_local->locaddr4[ind].addr; ++ opts->add_addr_v4 = 1; ++ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { ++ u8 mptcp_hash_mac[20]; ++ u8 no_key[8]; ++ ++ *(u64 *)no_key = 0; ++ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)no_key, ++ (u32 *)mptcp_hash_mac, 2, ++ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, ++ 4, (u8 *)&opts->add_addr4.addr.s_addr); ++ opts->add_addr4.trunc_mac = *(u64 *)mptcp_hash_mac; ++ } ++ ++ if (skb) { ++ fmp->announced_addrs_v4 |= (1 << ind); ++ fmp->add_addr--; ++ } ++ ++ if (mpcb->mptcp_ver < MPTCP_VERSION_1) ++ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN; ++ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) ++ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1; ++ ++ goto skip_ipv6; ++ } ++ ++ if (meta_v4) ++ goto skip_ipv6; ++skip_ipv4: ++ /* IPv6 */ ++ unannouncedv6 = (~fmp->announced_addrs_v6) & mptcp_local->loc6_bits; ++ if (unannouncedv6 && ++ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && ++ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN) || ++ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && ++ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1))) { ++ int ind = mptcp_find_free_index(~unannouncedv6); ++ ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_ADD_ADDR; ++ opts->add_addr6.addr_id = mptcp_local->locaddr6[ind].loc6_id; ++ opts->add_addr6.addr = mptcp_local->locaddr6[ind].addr; ++ opts->add_addr_v6 = 1; ++ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { ++ u8 mptcp_hash_mac[20]; ++ u8 no_key[8]; ++ ++ *(u64 *)no_key = 0; ++ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)no_key, ++ (u32 *)mptcp_hash_mac, 2, ++ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, ++ 16, (u8 *)&opts->add_addr6.addr.s6_addr); ++ opts->add_addr6.trunc_mac = *(u64 *)mptcp_hash_mac; ++ } ++ ++ if (skb) { ++ fmp->announced_addrs_v6 |= (1 << ind); ++ fmp->add_addr--; ++ } ++ if (mpcb->mptcp_ver < MPTCP_VERSION_1) ++ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN; ++ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) ++ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1; ++ } ++ ++skip_ipv6: ++ rcu_read_unlock_bh(); ++ ++ if (!unannouncedv4 && !unannouncedv6 && skb) ++ fmp->add_addr--; ++ ++remove_addr: ++ if (likely(!fmp->remove_addrs)) ++ goto exit; ++ ++ remove_addr_len = mptcp_sub_len_remove_addr_align(fmp->remove_addrs); ++ if (MAX_TCP_OPTION_SPACE - *size < remove_addr_len) ++ goto exit; ++ ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_REMOVE_ADDR; ++ opts->remove_addrs = fmp->remove_addrs; ++ *size += remove_addr_len; ++ if (skb) ++ fmp->remove_addrs = 0; ++ ++exit: ++ mpcb->addr_signal = !!(fmp->add_addr || fmp->remove_addrs); ++} ++ ++static void full_mesh_rem_raddr(struct mptcp_cb *mpcb, u8 rem_id) ++{ ++ mptcp_v4_rem_raddress(mpcb, rem_id); ++ mptcp_v6_rem_raddress(mpcb, rem_id); ++} ++ ++static void full_mesh_delete_subflow(struct sock *sk) ++{ ++ struct fullmesh_priv *fmp = fullmesh_get_priv(tcp_sk(sk)->mpcb); ++ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct mptcp_loc_addr *mptcp_local; ++ int index, i; ++ ++ if (!create_on_err) ++ return; ++ ++ if (!mptcp_can_new_subflow(meta_sk)) ++ return; ++ ++ rcu_read_lock_bh(); ++ mptcp_local = rcu_dereference_bh(fm_ns->local); ++ ++ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { ++ union inet_addr saddr; ++ ++ saddr.ip = inet_sk(sk)->inet_saddr; ++ index = mptcp_find_address(mptcp_local, AF_INET, &saddr, ++ sk->sk_bound_dev_if); ++ if (index < 0) ++ goto out; ++ ++ mptcp_for_each_bit_set(fmp->rem4_bits, i) { ++ struct fullmesh_rem4 *rem4 = &fmp->remaddr4[i]; ++ ++ if (rem4->addr.s_addr != sk->sk_daddr) ++ continue; ++ ++ if (rem4->port && rem4->port != inet_sk(sk)->inet_dport) ++ continue; ++ ++ rem4->bitfield &= ~(1 << index); ++ } ++#if IS_ENABLED(CONFIG_IPV6) ++ } else { ++ union inet_addr saddr; ++ ++ saddr.in6 = inet6_sk(sk)->saddr; ++ index = mptcp_find_address(mptcp_local, AF_INET6, &saddr, ++ sk->sk_bound_dev_if); ++ if (index < 0) ++ goto out; ++ ++ mptcp_for_each_bit_set(fmp->rem6_bits, i) { ++ struct fullmesh_rem6 *rem6 = &fmp->remaddr6[i]; ++ ++ if (!ipv6_addr_equal(&rem6->addr, &sk->sk_v6_daddr)) ++ continue; ++ ++ if (rem6->port && rem6->port != inet_sk(sk)->inet_dport) ++ continue; ++ ++ rem6->bitfield &= ~(1 << index); ++ } ++#endif ++ } ++ ++out: ++ rcu_read_unlock_bh(); ++ ++ /* re-schedule the creation of failed subflows */ ++ if (tcp_sk(sk)->mptcp->sk_err == ETIMEDOUT || sk->sk_err == ETIMEDOUT) ++ full_mesh_create_subflows(meta_sk); ++} ++ ++/* Output /proc/net/mptcp_fullmesh */ ++static int mptcp_fm_seq_show(struct seq_file *seq, void *v) ++{ ++ const struct net *net = seq->private; ++ struct mptcp_loc_addr *mptcp_local; ++ const struct mptcp_fm_ns *fm_ns = fm_get_ns(net); ++ int i; ++ ++ seq_printf(seq, "Index, Address-ID, Backup, IP-address, if-idx\n"); ++ ++ rcu_read_lock_bh(); ++ mptcp_local = rcu_dereference(fm_ns->local); ++ ++ seq_printf(seq, "IPv4, next v4-index: %u\n", mptcp_local->next_v4_index); ++ ++ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { ++ struct mptcp_loc4 *loc4 = &mptcp_local->locaddr4[i]; ++ ++ seq_printf(seq, "%u, %u, %u, %pI4 %u\n", i, loc4->loc4_id, ++ loc4->low_prio, &loc4->addr, loc4->if_idx); ++ } ++ ++ seq_printf(seq, "IPv6, next v6-index: %u\n", mptcp_local->next_v6_index); ++ ++ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { ++ struct mptcp_loc6 *loc6 = &mptcp_local->locaddr6[i]; ++ ++ seq_printf(seq, "%u, %u, %u, %pI6 %u\n", i, loc6->loc6_id, ++ loc6->low_prio, &loc6->addr, loc6->if_idx); ++ } ++ rcu_read_unlock_bh(); ++ ++ return 0; ++} ++ ++static int mptcp_fm_init_net(struct net *net) ++{ ++ struct mptcp_loc_addr *mptcp_local; ++ struct mptcp_fm_ns *fm_ns; ++ int err = 0; ++ ++ fm_ns = kzalloc(sizeof(*fm_ns), GFP_KERNEL); ++ if (!fm_ns) ++ return -ENOBUFS; ++ ++ mptcp_local = kzalloc(sizeof(*mptcp_local), GFP_KERNEL); ++ if (!mptcp_local) { ++ err = -ENOBUFS; ++ goto err_mptcp_local; ++ } ++ ++ if (!proc_create_net_single("mptcp_fullmesh", S_IRUGO, net->proc_net, ++ mptcp_fm_seq_show, NULL)) { ++ err = -ENOMEM; ++ goto err_seq_fops; ++ } ++ ++ mptcp_local->next_v4_index = 1; ++ ++ rcu_assign_pointer(fm_ns->local, mptcp_local); ++ INIT_DELAYED_WORK(&fm_ns->address_worker, mptcp_address_worker); ++ INIT_LIST_HEAD(&fm_ns->events); ++ spin_lock_init(&fm_ns->local_lock); ++ fm_ns->net = net; ++ net->mptcp.path_managers[MPTCP_PM_FULLMESH] = fm_ns; ++ ++ return 0; ++err_seq_fops: ++ kfree(mptcp_local); ++err_mptcp_local: ++ kfree(fm_ns); ++ return err; ++} ++ ++static void mptcp_fm_exit_net(struct net *net) ++{ ++ struct mptcp_addr_event *eventq, *tmp; ++ struct mptcp_fm_ns *fm_ns; ++ struct mptcp_loc_addr *mptcp_local; ++ ++ fm_ns = fm_get_ns(net); ++ cancel_delayed_work_sync(&fm_ns->address_worker); ++ ++ rcu_read_lock_bh(); ++ ++ mptcp_local = rcu_dereference_bh(fm_ns->local); ++ kfree_rcu(mptcp_local, rcu); ++ ++ spin_lock(&fm_ns->local_lock); ++ list_for_each_entry_safe(eventq, tmp, &fm_ns->events, list) { ++ list_del(&eventq->list); ++ kfree(eventq); ++ } ++ spin_unlock(&fm_ns->local_lock); ++ ++ rcu_read_unlock_bh(); ++ ++ remove_proc_entry("mptcp_fullmesh", net->proc_net); ++ ++ kfree(fm_ns); ++} ++ ++static struct pernet_operations full_mesh_net_ops = { ++ .init = mptcp_fm_init_net, ++ .exit = mptcp_fm_exit_net, ++}; ++ ++static struct mptcp_pm_ops full_mesh __read_mostly = { ++ .new_session = full_mesh_new_session, ++ .release_sock = full_mesh_release_sock, ++ .fully_established = full_mesh_create_subflows, ++ .new_remote_address = full_mesh_create_subflows, ++ .get_local_id = full_mesh_get_local_id, ++ .addr_signal = full_mesh_addr_signal, ++ .add_raddr = full_mesh_add_raddr, ++ .rem_raddr = full_mesh_rem_raddr, ++ .delete_subflow = full_mesh_delete_subflow, ++ .name = "fullmesh", ++ .owner = THIS_MODULE, ++}; ++ ++/* General initialization of MPTCP_PM */ ++static int __init full_mesh_register(void) ++{ ++ int ret; ++ ++ BUILD_BUG_ON(sizeof(struct fullmesh_priv) > MPTCP_PM_SIZE); ++ ++ ret = register_pernet_subsys(&full_mesh_net_ops); ++ if (ret) ++ goto out; ++ ++ ret = register_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); ++ if (ret) ++ goto err_reg_inetaddr; ++ ret = register_netdevice_notifier(&mptcp_pm_netdev_notifier); ++ if (ret) ++ goto err_reg_netdev; ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ ret = register_inet6addr_notifier(&inet6_addr_notifier); ++ if (ret) ++ goto err_reg_inet6addr; ++#endif ++ ++ ret = mptcp_register_path_manager(&full_mesh); ++ if (ret) ++ goto err_reg_pm; ++ ++out: ++ return ret; ++ ++ ++err_reg_pm: ++#if IS_ENABLED(CONFIG_IPV6) ++ unregister_inet6addr_notifier(&inet6_addr_notifier); ++err_reg_inet6addr: ++#endif ++ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); ++err_reg_netdev: ++ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); ++err_reg_inetaddr: ++ unregister_pernet_subsys(&full_mesh_net_ops); ++ goto out; ++} ++ ++static void full_mesh_unregister(void) ++{ ++#if IS_ENABLED(CONFIG_IPV6) ++ unregister_inet6addr_notifier(&inet6_addr_notifier); ++#endif ++ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); ++ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); ++ unregister_pernet_subsys(&full_mesh_net_ops); ++ mptcp_unregister_path_manager(&full_mesh); ++} ++ ++module_init(full_mesh_register); ++module_exit(full_mesh_unregister); ++ ++MODULE_AUTHOR("Christoph Paasch"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Full-Mesh MPTCP"); ++MODULE_VERSION("0.88"); +diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_input.c +--- linux-5.4/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,2436 @@ ++/* ++ * MPTCP implementation - Sending side ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer & Author: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++/* is seq1 < seq2 ? */ ++static inline bool before64(const u64 seq1, const u64 seq2) ++{ ++ return (s64)(seq1 - seq2) < 0; ++} ++ ++/* is seq1 > seq2 ? */ ++#define after64(seq1, seq2) before64(seq2, seq1) ++ ++static inline void mptcp_become_fully_estab(struct sock *sk) ++{ ++ tcp_sk(sk)->mptcp->fully_established = 1; ++ ++ if (is_master_tp(tcp_sk(sk)) && ++ tcp_sk(sk)->mpcb->pm_ops->fully_established) ++ tcp_sk(sk)->mpcb->pm_ops->fully_established(mptcp_meta_sk(sk)); ++} ++ ++/* Similar to tcp_tso_acked without any memory accounting */ ++static inline int mptcp_tso_acked_reinject(const struct sock *meta_sk, ++ struct sk_buff *skb) ++{ ++ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ u32 packets_acked, len, delta_truesize; ++ ++ BUG_ON(!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)); ++ ++ packets_acked = tcp_skb_pcount(skb); ++ ++ if (skb_unclone(skb, GFP_ATOMIC)) ++ return 0; ++ ++ len = meta_tp->snd_una - TCP_SKB_CB(skb)->seq; ++ delta_truesize = __pskb_trim_head(skb, len); ++ ++ TCP_SKB_CB(skb)->seq += len; ++ skb->ip_summed = CHECKSUM_PARTIAL; ++ ++ if (delta_truesize) ++ skb->truesize -= delta_truesize; ++ ++ /* Any change of skb->len requires recalculation of tso factor. */ ++ if (tcp_skb_pcount(skb) > 1) ++ tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb)); ++ packets_acked -= tcp_skb_pcount(skb); ++ ++ if (packets_acked) { ++ BUG_ON(tcp_skb_pcount(skb) == 0); ++ BUG_ON(!before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)); ++ } ++ ++ return packets_acked; ++} ++ ++/* Cleans the meta-socket retransmission queue and the reinject-queue. */ ++static void mptcp_clean_rtx_queue(struct sock *meta_sk, u32 prior_snd_una) ++{ ++ struct sk_buff *skb, *tmp, *next; ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ bool acked = false; ++ u32 acked_pcount; ++ ++ for (skb = skb_rb_first(&meta_sk->tcp_rtx_queue); skb; skb = next) { ++ bool fully_acked = true; ++ ++ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { ++ if (tcp_skb_pcount(skb) == 1 || ++ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) ++ break; ++ ++ acked_pcount = tcp_tso_acked(meta_sk, skb); ++ if (!acked_pcount) ++ break; ++ ++ fully_acked = false; ++ } else { ++ acked_pcount = tcp_skb_pcount(skb); ++ } ++ ++ acked = true; ++ meta_tp->packets_out -= acked_pcount; ++ meta_tp->retrans_stamp = 0; ++ ++ if (!fully_acked) ++ break; ++ ++ next = skb_rb_next(skb); ++ ++ if (mptcp_is_data_fin(skb)) { ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ /* DATA_FIN has been acknowledged - now we can close ++ * the subflows ++ */ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ unsigned long delay = 0; ++ ++ /* If we are the passive closer, don't trigger ++ * subflow-fin until the subflow has been finned ++ * by the peer - thus we add a delay. ++ */ ++ if (mpcb->passive_close && ++ sk_it->sk_state == TCP_ESTABLISHED) ++ delay = inet_csk(sk_it)->icsk_rto << 3; ++ ++ mptcp_sub_close(sk_it, delay); ++ } ++ } ++ tcp_rtx_queue_unlink_and_free(skb, meta_sk); ++ } ++ /* Remove acknowledged data from the reinject queue */ ++ skb_queue_walk_safe(&mpcb->reinject_queue, skb, tmp) { ++ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { ++ if (tcp_skb_pcount(skb) == 1 || ++ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) ++ break; ++ ++ mptcp_tso_acked_reinject(meta_sk, skb); ++ break; ++ } ++ ++ __skb_unlink(skb, &mpcb->reinject_queue); ++ __kfree_skb(skb); ++ } ++ ++ if (likely(between(meta_tp->snd_up, prior_snd_una, meta_tp->snd_una))) ++ meta_tp->snd_up = meta_tp->snd_una; ++ ++ if (acked) { ++ tcp_rearm_rto(meta_sk); ++ /* Normally this is done in tcp_try_undo_loss - but MPTCP ++ * does not call this function. ++ */ ++ inet_csk(meta_sk)->icsk_retransmits = 0; ++ } ++} ++ ++/* Inspired by tcp_rcv_state_process */ ++static int mptcp_rcv_state_process(struct sock *meta_sk, struct sock *sk, ++ const struct sk_buff *skb, u32 data_seq, ++ u16 data_len) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); ++ const struct tcphdr *th = tcp_hdr(skb); ++ ++ /* State-machine handling if FIN has been enqueued and he has ++ * been acked (snd_una == write_seq) - it's important that this ++ * here is after sk_wmem_free_skb because otherwise ++ * sk_forward_alloc is wrong upon inet_csk_destroy_sock() ++ */ ++ switch (meta_sk->sk_state) { ++ case TCP_FIN_WAIT1: { ++ struct dst_entry *dst; ++ int tmo; ++ ++ if (meta_tp->snd_una != meta_tp->write_seq) ++ break; ++ ++ tcp_set_state(meta_sk, TCP_FIN_WAIT2); ++ meta_sk->sk_shutdown |= SEND_SHUTDOWN; ++ ++ dst = __sk_dst_get(sk); ++ if (dst) ++ dst_confirm(dst); ++ ++ if (!sock_flag(meta_sk, SOCK_DEAD)) { ++ /* Wake up lingering close() */ ++ meta_sk->sk_state_change(meta_sk); ++ break; ++ } ++ ++ if (meta_tp->linger2 < 0 || ++ (data_len && ++ after(data_seq + data_len - (mptcp_is_data_fin2(skb, tp) ? 1 : 0), ++ meta_tp->rcv_nxt))) { ++ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); ++ tcp_done(meta_sk); ++ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); ++ return 1; ++ } ++ ++ tmo = tcp_fin_time(meta_sk); ++ if (tmo > TCP_TIMEWAIT_LEN) { ++ inet_csk_reset_keepalive_timer(meta_sk, tmo - TCP_TIMEWAIT_LEN); ++ } else if (mptcp_is_data_fin2(skb, tp) || sock_owned_by_user(meta_sk)) { ++ /* Bad case. We could lose such FIN otherwise. ++ * It is not a big problem, but it looks confusing ++ * and not so rare event. We still can lose it now, ++ * if it spins in bh_lock_sock(), but it is really ++ * marginal case. ++ */ ++ inet_csk_reset_keepalive_timer(meta_sk, tmo); ++ } else { ++ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, tmo); ++ } ++ break; ++ } ++ case TCP_CLOSING: ++ case TCP_LAST_ACK: ++ if (meta_tp->snd_una == meta_tp->write_seq) { ++ tcp_done(meta_sk); ++ return 1; ++ } ++ break; ++ } ++ ++ /* step 7: process the segment text */ ++ switch (meta_sk->sk_state) { ++ case TCP_FIN_WAIT1: ++ case TCP_FIN_WAIT2: ++ /* RFC 793 says to queue data in these states, ++ * RFC 1122 says we MUST send a reset. ++ * BSD 4.4 also does reset. ++ */ ++ if (meta_sk->sk_shutdown & RCV_SHUTDOWN) { ++ if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && ++ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && ++ !mptcp_is_data_fin2(skb, tp)) { ++ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); ++ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); ++ tcp_reset(meta_sk); ++ return 1; ++ } ++ } ++ break; ++ } ++ ++ return 0; ++} ++ ++/** ++ * @return: ++ * i) 1: Everything's fine. ++ * ii) -1: A reset has been sent on the subflow - csum-failure ++ * iii) 0: csum-failure but no reset sent, because it's the last subflow. ++ * Last packet should not be destroyed by the caller because it has ++ * been done here. ++ */ ++static int mptcp_verif_dss_csum(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct sk_buff *tmp, *tmp1, *last = NULL; ++ __wsum csum_tcp = 0; /* cumulative checksum of pld + mptcp-header */ ++ int ans = 1, overflowed = 0, offset = 0, dss_csum_added = 0; ++ int iter = 0; ++ u32 next_seq, offset_seq; ++ ++ skb_queue_walk_safe(&sk->sk_receive_queue, tmp, tmp1) { ++ unsigned int csum_len; ++ ++ /* init next seq in first round */ ++ if (!iter) ++ next_seq = TCP_SKB_CB(tmp)->seq; ++ offset_seq = next_seq - TCP_SKB_CB(tmp)->seq; ++ ++ if (before(tp->mptcp->map_subseq + tp->mptcp->map_data_len, TCP_SKB_CB(tmp)->end_seq)) ++ /* Mapping ends in the middle of the packet - ++ * csum only these bytes ++ */ ++ csum_len = tp->mptcp->map_subseq + tp->mptcp->map_data_len - TCP_SKB_CB(tmp)->seq; ++ else ++ csum_len = tmp->len; ++ ++ csum_len -= offset_seq; ++ offset = 0; ++ if (overflowed) { ++ char first_word[4]; ++ first_word[0] = 0; ++ first_word[1] = 0; ++ first_word[2] = 0; ++ first_word[3] = *(tmp->data + offset_seq); ++ csum_tcp = csum_partial(first_word, 4, csum_tcp); ++ offset = 1; ++ csum_len--; ++ overflowed = 0; ++ } ++ ++ csum_tcp = skb_checksum(tmp, offset + offset_seq, csum_len, ++ csum_tcp); ++ ++ /* Was it on an odd-length? Then we have to merge the next byte ++ * correctly (see above) ++ */ ++ if (csum_len != (csum_len & (~1))) ++ overflowed = 1; ++ ++ if (mptcp_is_data_seq(tmp) && !dss_csum_added) { ++ __be32 data_seq = htonl((u32)(tp->mptcp->map_data_seq >> 32)); ++ ++ /* If a 64-bit dss is present, we increase the offset ++ * by 4 bytes, as the high-order 64-bits will be added ++ * in the final csum_partial-call. ++ */ ++ u32 offset = skb_transport_offset(tmp) + ++ TCP_SKB_CB(tmp)->dss_off; ++ if (TCP_SKB_CB(tmp)->mptcp_flags & MPTCPHDR_SEQ64_SET) ++ offset += 4; ++ ++ csum_tcp = skb_checksum(tmp, offset, ++ MPTCP_SUB_LEN_SEQ_CSUM, ++ csum_tcp); ++ ++ csum_tcp = csum_partial(&data_seq, ++ sizeof(data_seq), csum_tcp); ++ ++ dss_csum_added = 1; /* Just do it once */ ++ } ++ last = tmp; ++ iter++; ++ ++ if (!skb_queue_is_last(&sk->sk_receive_queue, tmp) && ++ !before(TCP_SKB_CB(tmp1)->seq, ++ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) ++ break; ++ next_seq = TCP_SKB_CB(tmp)->end_seq; ++ } ++ ++ /* Now, checksum must be 0 */ ++ if (unlikely(csum_fold(csum_tcp))) { ++ struct mptcp_tcp_sock *mptcp; ++ struct sock *sk_it = NULL; ++ ++ pr_debug("%s csum is wrong: %#x tcp-seq %u dss_csum_added %d overflowed %d iterations %d\n", ++ __func__, csum_fold(csum_tcp), TCP_SKB_CB(last)->seq, ++ dss_csum_added, overflowed, iter); ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMFAIL); ++ tp->mptcp->send_mp_fail = 1; ++ ++ /* map_data_seq is the data-seq number of the ++ * mapping we are currently checking ++ */ ++ tp->mpcb->csum_cutoff_seq = tp->mptcp->map_data_seq; ++ ++ /* Search for another subflow that is fully established */ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ sk_it = mptcp_to_sock(mptcp); ++ ++ if (sk_it != sk && ++ tcp_sk(sk_it)->mptcp->fully_established) ++ break; ++ ++ sk_it = NULL; ++ } ++ ++ if (sk_it) { ++ mptcp_send_reset(sk); ++ ans = -1; ++ } else { ++ tp->mpcb->send_infinite_mapping = 1; ++ ++ /* Need to purge the rcv-queue as it's no more valid */ ++ while ((tmp = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { ++ tp->copied_seq = TCP_SKB_CB(tmp)->end_seq; ++ kfree_skb(tmp); ++ } ++ ++ mptcp_fallback_close(tp->mpcb, sk); ++ ++ ans = 0; ++ } ++ } ++ ++ return ans; ++} ++ ++static inline void mptcp_prepare_skb(struct sk_buff *skb, ++ const struct sock *sk) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); ++ u32 inc = 0, end_seq = tcb->end_seq; ++ ++ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) ++ end_seq--; ++ /* If skb is the end of this mapping (end is always at mapping-boundary ++ * thanks to the splitting/trimming), then we need to increase ++ * data-end-seq by 1 if this here is a data-fin. ++ * ++ * We need to do -1 because end_seq includes the subflow-FIN. ++ */ ++ if (tp->mptcp->map_data_fin && ++ end_seq == tp->mptcp->map_subseq + tp->mptcp->map_data_len) { ++ inc = 1; ++ ++ /* We manually set the fin-flag if it is a data-fin. For easy ++ * processing in tcp_recvmsg. ++ */ ++ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; ++ } else { ++ /* We may have a subflow-fin with data but without data-fin */ ++ TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_FIN; ++ } ++ ++ /* Adapt data-seq's to the packet itself. We kinda transform the ++ * dss-mapping to a per-packet granularity. This is necessary to ++ * correctly handle overlapping mappings coming from different ++ * subflows. Otherwise it would be a complete mess. ++ */ ++ tcb->seq = ((u32)tp->mptcp->map_data_seq) + tcb->seq - tp->mptcp->map_subseq; ++ tcb->end_seq = tcb->seq + skb->len + inc; ++} ++ ++static inline void mptcp_reset_mapping(struct tcp_sock *tp, u32 old_copied_seq) ++{ ++ tp->mptcp->map_data_len = 0; ++ tp->mptcp->map_data_seq = 0; ++ tp->mptcp->map_subseq = 0; ++ tp->mptcp->map_data_fin = 0; ++ tp->mptcp->mapping_present = 0; ++ ++ /* In infinite mapping receiver mode, we have to advance the implied ++ * data-sequence number when we progress the subflow's data. ++ */ ++ if (tp->mpcb->infinite_mapping_rcv) ++ tp->mpcb->infinite_rcv_seq += (tp->copied_seq - old_copied_seq); ++} ++ ++/* The DSS-mapping received on the sk only covers the second half of the skb ++ * (cut at seq). We trim the head from the skb. ++ * Data will be freed upon kfree(). ++ * ++ * Inspired by tcp_trim_head(). ++ */ ++static void mptcp_skb_trim_head(struct sk_buff *skb, struct sock *sk, u32 seq) ++{ ++ int len = seq - TCP_SKB_CB(skb)->seq; ++ u32 new_seq = TCP_SKB_CB(skb)->seq + len; ++ u32 delta_truesize; ++ ++ delta_truesize = __pskb_trim_head(skb, len); ++ ++ TCP_SKB_CB(skb)->seq = new_seq; ++ ++ if (delta_truesize) { ++ skb->truesize -= delta_truesize; ++ atomic_sub(delta_truesize, &sk->sk_rmem_alloc); ++ sk_mem_uncharge(sk, delta_truesize); ++ } ++} ++ ++/* The DSS-mapping received on the sk only covers the first half of the skb ++ * (cut at seq). We create a second skb (@return), and queue it in the rcv-queue ++ * as further packets may resolve the mapping of the second half of data. ++ * ++ * Inspired by tcp_fragment(). ++ */ ++static int mptcp_skb_split_tail(struct sk_buff *skb, struct sock *sk, u32 seq) ++{ ++ struct sk_buff *buff; ++ int nsize; ++ int nlen, len; ++ u8 flags; ++ ++ len = seq - TCP_SKB_CB(skb)->seq; ++ nsize = skb_headlen(skb) - len + tcp_sk(sk)->tcp_header_len; ++ if (nsize < 0) ++ nsize = 0; ++ ++ /* Get a new skb... force flag on. */ ++ buff = alloc_skb(nsize, GFP_ATOMIC); ++ if (buff == NULL) ++ return -ENOMEM; ++ ++ skb_reserve(buff, tcp_sk(sk)->tcp_header_len); ++ skb_reset_transport_header(buff); ++ ++ flags = TCP_SKB_CB(skb)->tcp_flags; ++ TCP_SKB_CB(skb)->tcp_flags = flags & ~(TCPHDR_FIN); ++ TCP_SKB_CB(buff)->tcp_flags = flags; ++ ++ /* We absolutly need to call skb_set_owner_r before refreshing the ++ * truesize of buff, otherwise the moved data will account twice. ++ */ ++ skb_set_owner_r(buff, sk); ++ nlen = skb->len - len - nsize; ++ buff->truesize += nlen; ++ skb->truesize -= nlen; ++ ++ /* Correct the sequence numbers. */ ++ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; ++ TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; ++ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; ++ ++ skb_split(skb, buff, len); ++ ++ __skb_queue_after(&sk->sk_receive_queue, skb, buff); ++ ++ return 0; ++} ++ ++/* @return: 0 everything is fine. Just continue processing ++ * 1 subflow is broken stop everything ++ * -1 this packet was broken - continue with the next one. ++ */ ++static int mptcp_prevalidate_skb(struct sock *sk, struct sk_buff *skb) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_cb *mpcb = tp->mpcb; ++ ++ /* If we are in infinite mode, the subflow-fin is in fact a data-fin. */ ++ if (!skb->len && (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && ++ !mptcp_is_data_fin(skb) && !mpcb->infinite_mapping_rcv) { ++ /* Remove a pure subflow-fin from the queue and increase ++ * copied_seq. ++ */ ++ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; ++ __skb_unlink(skb, &sk->sk_receive_queue); ++ __kfree_skb(skb); ++ return -1; ++ } ++ ++ /* If we are not yet fully established and do not know the mapping for ++ * this segment, this path has to fallback to infinite or be torn down. ++ */ ++ if (!tp->mptcp->fully_established && !mptcp_is_data_seq(skb) && ++ !tp->mptcp->mapping_present && !mpcb->infinite_mapping_rcv) { ++ pr_debug("%s %#x will fallback - pi %d from %pS, seq %u\n", ++ __func__, mpcb->mptcp_loc_token, ++ tp->mptcp->path_index, __builtin_return_address(0), ++ TCP_SKB_CB(skb)->seq); ++ ++ if (!is_master_tp(tp)) { ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATASUB); ++ mptcp_send_reset(sk); ++ return 1; ++ } ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATAINIT); ++ ++ mpcb->infinite_mapping_snd = 1; ++ mpcb->infinite_mapping_rcv = 1; ++ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); ++ ++ mptcp_fallback_close(mpcb, sk); ++ ++ /* We do a seamless fallback and should not send a inf.mapping. */ ++ mpcb->send_infinite_mapping = 0; ++ tp->mptcp->fully_established = 1; ++ } ++ ++ /* Receiver-side becomes fully established when a whole rcv-window has ++ * been received without the need to fallback due to the previous ++ * condition. ++ */ ++ if (!tp->mptcp->fully_established) { ++ tp->mptcp->init_rcv_wnd -= skb->len; ++ if (tp->mptcp->init_rcv_wnd < 0) ++ mptcp_become_fully_estab(sk); ++ } ++ ++ return 0; ++} ++ ++static void mptcp_restart_sending(struct sock *meta_sk) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct sk_buff *wq_head, *skb, *tmp; ++ ++ skb = tcp_rtx_queue_head(meta_sk); ++ ++ /* We resend everything that has not been acknowledged, thus we need ++ * to move it from the rtx-tree to the write-queue. ++ */ ++ wq_head = tcp_write_queue_head(meta_sk); ++ ++ skb_rbtree_walk_from_safe(skb, tmp) { ++ list_del(&skb->tcp_tsorted_anchor); ++ tcp_rtx_queue_unlink(skb, meta_sk); ++ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); ++ ++ if (wq_head) ++ __skb_queue_before(&meta_sk->sk_write_queue, wq_head, skb); ++ else ++ tcp_add_write_queue_tail(meta_sk, skb); ++ } ++ ++ /* We artificially restart the whole send-queue. Thus, ++ * it is as if no packets are in flight ++ */ ++ meta_tp->packets_out = 0; ++ ++ /* If the snd_nxt already wrapped around, we have to ++ * undo the wrapping, as we are restarting from snd_una ++ * on. ++ */ ++ if (meta_tp->snd_nxt < meta_tp->snd_una) { ++ mpcb->snd_high_order[mpcb->snd_hiseq_index] -= 2; ++ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; ++ } ++ meta_tp->snd_nxt = meta_tp->snd_una; ++ ++ /* Trigger a sending on the meta. */ ++ mptcp_push_pending_frames(meta_sk); ++} ++ ++/* @return: 0 everything is fine. Just continue processing ++ * 1 subflow is broken stop everything ++ * -1 this packet was broken - continue with the next one. ++ */ ++static int mptcp_detect_mapping(struct sock *sk, struct sk_buff *skb) ++{ ++ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); ++ struct mptcp_cb *mpcb = tp->mpcb; ++ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); ++ u32 *ptr; ++ u32 data_seq, sub_seq, data_len, tcp_end_seq; ++ bool set_infinite_rcv = false; ++ ++ /* If we are in infinite-mapping-mode, the subflow is guaranteed to be ++ * in-order at the data-level. Thus data-seq-numbers can be inferred ++ * from what is expected at the data-level. ++ */ ++ if (mpcb->infinite_mapping_rcv) { ++ /* copied_seq may be bigger than tcb->seq (e.g., when the peer ++ * retransmits data that actually has already been acknowledged with ++ * newer data, if he did not receive our acks). Thus, we need ++ * to account for this overlap as well. ++ */ ++ tp->mptcp->map_data_seq = mpcb->infinite_rcv_seq - (tp->copied_seq - tcb->seq); ++ tp->mptcp->map_subseq = tcb->seq; ++ tp->mptcp->map_data_len = skb->len; ++ tp->mptcp->map_data_fin = !!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN); ++ tp->mptcp->mapping_present = 1; ++ return 0; ++ } ++ ++ /* No mapping here? Exit - it is either already set or still on its way */ ++ if (!mptcp_is_data_seq(skb)) { ++ /* Too many packets without a mapping - this subflow is broken */ ++ if (!tp->mptcp->mapping_present && ++ tp->rcv_nxt - tp->copied_seq > 65536) { ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); ++ mptcp_send_reset(sk); ++ return 1; ++ } ++ ++ return 0; ++ } ++ ++ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); ++ ptr++; ++ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; ++ ptr++; ++ data_len = get_unaligned_be16(ptr); ++ ++ /* If it's an empty skb with DATA_FIN, sub_seq must get fixed. ++ * The draft sets it to 0, but we really would like to have the ++ * real value, to have an easy handling afterwards here in this ++ * function. ++ */ ++ if (mptcp_is_data_fin(skb) && skb->len == 0) ++ sub_seq = TCP_SKB_CB(skb)->seq; ++ ++ /* If there is already a mapping - we check if it maps with the current ++ * one. If not - we reset. ++ */ ++ if (tp->mptcp->mapping_present && ++ (data_seq != (u32)tp->mptcp->map_data_seq || ++ sub_seq != tp->mptcp->map_subseq || ++ data_len != tp->mptcp->map_data_len + tp->mptcp->map_data_fin || ++ mptcp_is_data_fin(skb) != tp->mptcp->map_data_fin)) { ++ /* Mapping in packet is different from what we want */ ++ pr_debug("%s Mappings do not match!\n", __func__); ++ pr_debug("%s dseq %u mdseq %u, sseq %u msseq %u dlen %u mdlen %u dfin %d mdfin %d\n", ++ __func__, data_seq, (u32)tp->mptcp->map_data_seq, ++ sub_seq, tp->mptcp->map_subseq, data_len, ++ tp->mptcp->map_data_len, mptcp_is_data_fin(skb), ++ tp->mptcp->map_data_fin); ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSNOMATCH); ++ mptcp_send_reset(sk); ++ return 1; ++ } ++ ++ /* If the previous check was good, the current mapping is valid and we exit. */ ++ if (tp->mptcp->mapping_present) ++ return 0; ++ ++ /* Mapping not yet set on this subflow - we set it here! */ ++ ++ if (!data_len) { ++ mpcb->infinite_mapping_rcv = 1; ++ mpcb->send_infinite_mapping = 1; ++ tp->mptcp->fully_established = 1; ++ /* We need to repeat mp_fail's until the sender felt ++ * back to infinite-mapping - here we stop repeating it. ++ */ ++ tp->mptcp->send_mp_fail = 0; ++ ++ /* We have to fixup data_len - it must be the same as skb->len */ ++ data_len = skb->len + (mptcp_is_data_fin(skb) ? 1 : 0); ++ sub_seq = tcb->seq; ++ ++ mptcp_restart_sending(tp->meta_sk); ++ ++ mptcp_fallback_close(mpcb, sk); ++ ++ /* data_seq and so on are set correctly */ ++ ++ /* At this point, the meta-ofo-queue has to be emptied, ++ * as the following data is guaranteed to be in-order at ++ * the data and subflow-level ++ */ ++ skb_rbtree_purge(&meta_tp->out_of_order_queue); ++ ++ set_infinite_rcv = true; ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_INFINITEMAPRX); ++ } ++ ++ /* We are sending mp-fail's and thus are in fallback mode. ++ * Ignore packets which do not announce the fallback and still ++ * want to provide a mapping. ++ */ ++ if (tp->mptcp->send_mp_fail) { ++ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; ++ __skb_unlink(skb, &sk->sk_receive_queue); ++ __kfree_skb(skb); ++ return -1; ++ } ++ ++ /* FIN increased the mapping-length by 1 */ ++ if (mptcp_is_data_fin(skb)) ++ data_len--; ++ ++ /* Subflow-sequences of packet must be ++ * (at least partially) be part of the DSS-mapping's ++ * subflow-sequence-space. ++ * ++ * Basically the mapping is not valid, if either of the ++ * following conditions is true: ++ * ++ * 1. It's not a data_fin and ++ * MPTCP-sub_seq >= TCP-end_seq ++ * ++ * 2. It's a data_fin and TCP-end_seq > TCP-seq and ++ * MPTCP-sub_seq >= TCP-end_seq ++ * ++ * The previous two can be merged into: ++ * TCP-end_seq > TCP-seq and MPTCP-sub_seq >= TCP-end_seq ++ * Because if it's not a data-fin, TCP-end_seq > TCP-seq ++ * ++ * 3. It's a data_fin and skb->len == 0 and ++ * MPTCP-sub_seq > TCP-end_seq ++ * ++ * 4. It's not a data_fin and TCP-end_seq > TCP-seq and ++ * MPTCP-sub_seq + MPTCP-data_len <= TCP-seq ++ */ ++ ++ /* subflow-fin is not part of the mapping - ignore it here ! */ ++ tcp_end_seq = tcb->end_seq; ++ if (tcb->tcp_flags & TCPHDR_FIN) ++ tcp_end_seq--; ++ if ((!before(sub_seq, tcb->end_seq) && after(tcp_end_seq, tcb->seq)) || ++ (mptcp_is_data_fin(skb) && skb->len == 0 && after(sub_seq, tcb->end_seq)) || ++ (!after(sub_seq + data_len, tcb->seq) && after(tcp_end_seq, tcb->seq))) { ++ /* Subflow-sequences of packet is different from what is in the ++ * packet's dss-mapping. The peer is misbehaving - reset ++ */ ++ pr_debug("%s Packet's mapping does not map to the DSS sub_seq %u end_seq %u, tcp_end_seq %u seq %u dfin %u len %u data_len %u copied_seq %u\n", ++ __func__, sub_seq, tcb->end_seq, tcp_end_seq, ++ tcb->seq, mptcp_is_data_fin(skb), ++ skb->len, data_len, tp->copied_seq); ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTCPMISMATCH); ++ mptcp_send_reset(sk); ++ return 1; ++ } ++ ++ /* Does the DSS had 64-bit seqnum's ? */ ++ if (!(tcb->mptcp_flags & MPTCPHDR_SEQ64_SET)) { ++ /* Wrapped around? */ ++ if (unlikely(after(data_seq, meta_tp->rcv_nxt) && data_seq < meta_tp->rcv_nxt)) { ++ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, !mpcb->rcv_hiseq_index, data_seq); ++ } else { ++ /* Else, access the default high-order bits */ ++ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, data_seq); ++ } ++ } else { ++ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, (tcb->mptcp_flags & MPTCPHDR_SEQ64_INDEX) ? 1 : 0, data_seq); ++ ++ if (unlikely(tcb->mptcp_flags & MPTCPHDR_SEQ64_OFO)) { ++ /* We make sure that the data_seq is invalid. ++ * It will be dropped later. ++ */ ++ tp->mptcp->map_data_seq += 0xFFFFFFFF; ++ tp->mptcp->map_data_seq += 0xFFFFFFFF; ++ } ++ } ++ ++ if (set_infinite_rcv) ++ mpcb->infinite_rcv_seq = tp->mptcp->map_data_seq; ++ ++ tp->mptcp->map_data_len = data_len; ++ tp->mptcp->map_subseq = sub_seq; ++ tp->mptcp->map_data_fin = mptcp_is_data_fin(skb) ? 1 : 0; ++ tp->mptcp->mapping_present = 1; ++ ++ return 0; ++} ++ ++/* Similar to tcp_sequence(...) */ ++static inline bool mptcp_sequence(const struct tcp_sock *meta_tp, ++ u64 data_seq, u64 end_data_seq) ++{ ++ const struct mptcp_cb *mpcb = meta_tp->mpcb; ++ u64 rcv_wup64; ++ ++ /* Wrap-around? */ ++ if (meta_tp->rcv_wup > meta_tp->rcv_nxt) { ++ rcv_wup64 = ((u64)(mpcb->rcv_high_order[mpcb->rcv_hiseq_index] - 1) << 32) | ++ meta_tp->rcv_wup; ++ } else { ++ rcv_wup64 = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, ++ meta_tp->rcv_wup); ++ } ++ ++ return !before64(end_data_seq, rcv_wup64) && ++ !after64(data_seq, mptcp_get_rcv_nxt_64(meta_tp) + tcp_receive_window(meta_tp)); ++} ++ ++/* @return: 0 everything is fine. Just continue processing ++ * -1 this packet was broken - continue with the next one. ++ */ ++static int mptcp_validate_mapping(struct sock *sk, struct sk_buff *skb) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct sk_buff *tmp, *tmp1; ++ u32 tcp_end_seq; ++ ++ if (!tp->mptcp->mapping_present) ++ return 0; ++ ++ /* either, the new skb gave us the mapping and the first segment ++ * in the sub-rcv-queue has to be trimmed ... ++ */ ++ tmp = skb_peek(&sk->sk_receive_queue); ++ if (before(TCP_SKB_CB(tmp)->seq, tp->mptcp->map_subseq) && ++ after(TCP_SKB_CB(tmp)->end_seq, tp->mptcp->map_subseq)) { ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTRIMHEAD); ++ mptcp_skb_trim_head(tmp, sk, tp->mptcp->map_subseq); ++ } ++ ++ /* ... or the new skb (tail) has to be split at the end. */ ++ tcp_end_seq = TCP_SKB_CB(skb)->end_seq; ++ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) ++ tcp_end_seq--; ++ if (after(tcp_end_seq, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) { ++ u32 seq = tp->mptcp->map_subseq + tp->mptcp->map_data_len; ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSSPLITTAIL); ++ if (mptcp_skb_split_tail(skb, sk, seq)) { /* Allocation failed */ ++ /* TODO : maybe handle this here better. ++ * We now just force meta-retransmission. ++ */ ++ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; ++ __skb_unlink(skb, &sk->sk_receive_queue); ++ __kfree_skb(skb); ++ return -1; ++ } ++ } ++ ++ /* Now, remove old sk_buff's from the receive-queue. ++ * This may happen if the mapping has been lost for these segments and ++ * the next mapping has already been received. ++ */ ++ if (before(TCP_SKB_CB(skb_peek(&sk->sk_receive_queue))->seq, tp->mptcp->map_subseq)) { ++ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { ++ if (!before(TCP_SKB_CB(tmp1)->seq, tp->mptcp->map_subseq)) ++ break; ++ ++ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; ++ __skb_unlink(tmp1, &sk->sk_receive_queue); ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_PURGEOLD); ++ /* Impossible that we could free skb here, because his ++ * mapping is known to be valid from previous checks ++ */ ++ __kfree_skb(tmp1); ++ } ++ } ++ ++ return 0; ++} ++ ++/* @return: 0 everything is fine. Just continue processing ++ * 1 subflow is broken stop everything ++ * -1 this mapping has been put in the meta-receive-queue ++ * -2 this mapping has been eaten by the application ++ */ ++static int mptcp_queue_skb(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct mptcp_cb *mpcb = tp->mpcb; ++ struct sk_buff *tmp, *tmp1; ++ u64 rcv_nxt64 = mptcp_get_rcv_nxt_64(meta_tp); ++ u32 old_copied_seq = tp->copied_seq; ++ bool data_queued = false; ++ ++ /* Have we not yet received the full mapping? */ ++ if (!tp->mptcp->mapping_present || ++ before(tp->rcv_nxt, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) ++ return 0; ++ ++ /* Is this an overlapping mapping? rcv_nxt >= end_data_seq ++ * OR ++ * This mapping is out of window ++ */ ++ if (!before64(rcv_nxt64, tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin) || ++ !mptcp_sequence(meta_tp, tp->mptcp->map_data_seq, ++ tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin)) { ++ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { ++ __skb_unlink(tmp1, &sk->sk_receive_queue); ++ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; ++ __kfree_skb(tmp1); ++ ++ if (!skb_queue_empty(&sk->sk_receive_queue) && ++ !before(TCP_SKB_CB(tmp)->seq, ++ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) ++ break; ++ } ++ ++ mptcp_reset_mapping(tp, old_copied_seq); ++ ++ return -1; ++ } ++ ++ /* Record it, because we want to send our data_fin on the same path */ ++ if (tp->mptcp->map_data_fin) { ++ mpcb->dfin_path_index = tp->mptcp->path_index; ++ mpcb->dfin_combined = !!(sk->sk_shutdown & RCV_SHUTDOWN); ++ } ++ ++ /* Verify the checksum */ ++ if (mpcb->dss_csum && !mpcb->infinite_mapping_rcv) { ++ int ret = mptcp_verif_dss_csum(sk); ++ ++ if (ret <= 0) { ++ mptcp_reset_mapping(tp, old_copied_seq); ++ return 1; ++ } ++ } ++ ++ if (before64(rcv_nxt64, tp->mptcp->map_data_seq)) { ++ /* Seg's have to go to the meta-ofo-queue */ ++ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { ++ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; ++ mptcp_prepare_skb(tmp1, sk); ++ __skb_unlink(tmp1, &sk->sk_receive_queue); ++ /* MUST be done here, because fragstolen may be true later. ++ * Then, kfree_skb_partial will not account the memory. ++ */ ++ skb_orphan(tmp1); ++ ++ if (!mpcb->in_time_wait) /* In time-wait, do not receive data */ ++ tcp_data_queue_ofo(meta_sk, tmp1); ++ else ++ __kfree_skb(tmp1); ++ ++ if (!skb_queue_empty(&sk->sk_receive_queue) && ++ !before(TCP_SKB_CB(tmp)->seq, ++ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) ++ break; ++ } ++ ++ /* Quick ACK if more 3/4 of the receive window is filled */ ++ if (after64(tp->mptcp->map_data_seq, ++ rcv_nxt64 + 3 * (tcp_receive_window(meta_tp) >> 2))) ++ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); ++ ++ } else { ++ /* Ready for the meta-rcv-queue */ ++ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { ++ int eaten = 0; ++ bool fragstolen = false; ++ u32 old_rcv_nxt = meta_tp->rcv_nxt; ++ ++ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; ++ mptcp_prepare_skb(tmp1, sk); ++ __skb_unlink(tmp1, &sk->sk_receive_queue); ++ /* MUST be done here, because fragstolen may be true. ++ * Then, kfree_skb_partial will not account the memory. ++ */ ++ skb_orphan(tmp1); ++ ++ /* This segment has already been received */ ++ if (!after(TCP_SKB_CB(tmp1)->end_seq, meta_tp->rcv_nxt)) { ++ __kfree_skb(tmp1); ++ goto next; ++ } ++ ++ if (mpcb->in_time_wait) /* In time-wait, do not receive data */ ++ eaten = 1; ++ ++ if (!eaten) ++ eaten = tcp_queue_rcv(meta_sk, tmp1, &fragstolen); ++ ++ meta_tp->rcv_nxt = TCP_SKB_CB(tmp1)->end_seq; ++ ++ if (TCP_SKB_CB(tmp1)->tcp_flags & TCPHDR_FIN) ++ mptcp_fin(meta_sk); ++ ++ /* Check if this fills a gap in the ofo queue */ ++ if (!RB_EMPTY_ROOT(&meta_tp->out_of_order_queue)) ++ tcp_ofo_queue(meta_sk); ++ ++ mptcp_check_rcvseq_wrap(meta_tp, old_rcv_nxt); ++ ++ if (eaten) ++ kfree_skb_partial(tmp1, fragstolen); ++ ++ data_queued = true; ++next: ++ if (!skb_queue_empty(&sk->sk_receive_queue) && ++ !before(TCP_SKB_CB(tmp)->seq, ++ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) ++ break; ++ } ++ } ++ ++ inet_csk(meta_sk)->icsk_ack.lrcvtime = tcp_jiffies32; ++ mptcp_reset_mapping(tp, old_copied_seq); ++ ++ return data_queued ? -1 : -2; ++} ++ ++void mptcp_data_ready(struct sock *sk) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct sk_buff *skb, *tmp; ++ int queued = 0; ++ ++ tcp_mstamp_refresh(tcp_sk(meta_sk)); ++ ++ /* restart before the check, because mptcp_fin might have changed the ++ * state. ++ */ ++restart: ++ /* If the meta cannot receive data, there is no point in pushing data. ++ * If we are in time-wait, we may still be waiting for the final FIN. ++ * So, we should proceed with the processing. ++ */ ++ if (!mptcp_sk_can_recv(meta_sk) && !tcp_sk(sk)->mpcb->in_time_wait) { ++ skb_queue_purge(&sk->sk_receive_queue); ++ tcp_sk(sk)->copied_seq = tcp_sk(sk)->rcv_nxt; ++ goto exit; ++ } ++ ++ /* Iterate over all segments, detect their mapping (if we don't have ++ * one yet), validate them and push everything one level higher. ++ */ ++ skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp) { ++ int ret; ++ /* Pre-validation - e.g., early fallback */ ++ ret = mptcp_prevalidate_skb(sk, skb); ++ if (ret < 0) ++ goto restart; ++ else if (ret > 0) ++ break; ++ ++ /* Set the current mapping */ ++ ret = mptcp_detect_mapping(sk, skb); ++ if (ret < 0) ++ goto restart; ++ else if (ret > 0) ++ break; ++ ++ /* Validation */ ++ if (mptcp_validate_mapping(sk, skb) < 0) ++ goto restart; ++ ++ /* Push a level higher */ ++ ret = mptcp_queue_skb(sk); ++ if (ret < 0) { ++ if (ret == -1) ++ queued = ret; ++ goto restart; ++ } else if (ret == 0) { ++ continue; ++ } else { /* ret == 1 */ ++ break; ++ } ++ } ++ ++exit: ++ if (tcp_sk(sk)->close_it && sk->sk_state == TCP_FIN_WAIT2) { ++ tcp_send_ack(sk); ++ tcp_sk(sk)->ops->time_wait(sk, TCP_TIME_WAIT, 0); ++ } ++ ++ if (queued == -1 && !sock_flag(meta_sk, SOCK_DEAD)) ++ meta_sk->sk_data_ready(meta_sk); ++} ++ ++struct mp_join *mptcp_find_join(const struct sk_buff *skb) ++{ ++ const struct tcphdr *th = tcp_hdr(skb); ++ unsigned char *ptr; ++ int length = (th->doff * 4) - sizeof(struct tcphdr); ++ ++ /* Jump through the options to check whether JOIN is there */ ++ ptr = (unsigned char *)(th + 1); ++ while (length > 0) { ++ int opcode = *ptr++; ++ int opsize; ++ ++ switch (opcode) { ++ case TCPOPT_EOL: ++ return NULL; ++ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ ++ length--; ++ continue; ++ default: ++ opsize = *ptr++; ++ if (opsize < 2) /* "silly options" */ ++ return NULL; ++ if (opsize > length) ++ return NULL; /* don't parse partial options */ ++ if (opcode == TCPOPT_MPTCP && ++ ((struct mptcp_option *)(ptr - 2))->sub == MPTCP_SUB_JOIN) { ++ return (struct mp_join *)(ptr - 2); ++ } ++ ptr += opsize - 2; ++ length -= opsize; ++ } ++ } ++ return NULL; ++} ++ ++int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw) ++{ ++ struct sock *meta_sk; ++ u32 token; ++ bool meta_v4; ++ struct mp_join *join_opt = mptcp_find_join(skb); ++ if (!join_opt) ++ return 0; ++ ++ /* MPTCP structures were not initialized, so return error */ ++ if (mptcp_init_failed) ++ return -1; ++ ++ token = join_opt->u.syn.token; ++ meta_sk = mptcp_hash_find(dev_net(skb_dst(skb)->dev), token); ++ if (!meta_sk) { ++ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); ++ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); ++ return -1; ++ } ++ ++ meta_v4 = meta_sk->sk_family == AF_INET; ++ if (meta_v4) { ++ if (skb->protocol == htons(ETH_P_IPV6)) { ++ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); ++ sock_put(meta_sk); /* Taken by mptcp_hash_find */ ++ return -1; ++ } ++ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { ++ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); ++ sock_put(meta_sk); /* Taken by mptcp_hash_find */ ++ return -1; ++ } ++ ++ /* Coming from time-wait-sock processing in tcp_v4_rcv. ++ * We have to deschedule it before continuing, because otherwise ++ * mptcp_v4_do_rcv will hit again on it inside tcp_v4_hnd_req. ++ */ ++ if (tw) ++ inet_twsk_deschedule_put(tw); ++ ++ /* OK, this is a new syn/join, let's create a new open request and ++ * send syn+ack ++ */ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ tcp_v4_do_rcv(meta_sk, skb); ++#if IS_ENABLED(CONFIG_IPV6) ++ } else { ++ tcp_v6_do_rcv(meta_sk, skb); ++#endif /* CONFIG_IPV6 */ ++ } ++ sock_put(meta_sk); /* Taken by mptcp_hash_find */ ++ return 1; ++} ++ ++int mptcp_do_join_short(struct sk_buff *skb, ++ const struct mptcp_options_received *mopt, ++ struct net *net) ++{ ++ struct sock *meta_sk; ++ u32 token; ++ bool meta_v4; ++ ++ token = mopt->mptcp_rem_token; ++ meta_sk = mptcp_hash_find(net, token); ++ if (!meta_sk) { ++ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); ++ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); ++ return -1; ++ } ++ ++ meta_v4 = meta_sk->sk_family == AF_INET; ++ if (meta_v4) { ++ if (skb->protocol == htons(ETH_P_IPV6)) { ++ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); ++ sock_put(meta_sk); /* Taken by mptcp_hash_find */ ++ return -1; ++ } ++ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { ++ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); ++ sock_put(meta_sk); /* Taken by mptcp_hash_find */ ++ return -1; ++ } ++ ++ /* OK, this is a new syn/join, let's create a new open request and ++ * send syn+ack ++ */ ++ ++ /* mptcp_v4_do_rcv tries to free the skb - we prevent this, as ++ * the skb will finally be freed by tcp_v4_do_rcv (where we are ++ * coming from) ++ */ ++ skb_get(skb); ++ if (skb->protocol == htons(ETH_P_IP)) { ++ tcp_v4_do_rcv(meta_sk, skb); ++#if IS_ENABLED(CONFIG_IPV6) ++ } else { /* IPv6 */ ++ tcp_v6_do_rcv(meta_sk, skb); ++#endif /* CONFIG_IPV6 */ ++ } ++ ++ sock_put(meta_sk); /* Taken by mptcp_hash_find */ ++ return 0; ++} ++ ++/** ++ * Equivalent of tcp_fin() for MPTCP ++ * Can be called only when the FIN is validly part ++ * of the data seqnum space. Not before when we get holes. ++ */ ++void mptcp_fin(struct sock *meta_sk) ++{ ++ struct sock *sk = NULL; ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct mptcp_tcp_sock *mptcp; ++ unsigned char state; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(sk_it)->mptcp->path_index == mpcb->dfin_path_index) { ++ sk = sk_it; ++ break; ++ } ++ } ++ ++ if (!sk || sk->sk_state == TCP_CLOSE) ++ sk = mptcp_select_ack_sock(meta_sk); ++ ++ inet_csk_schedule_ack(sk); ++ ++ if (!mpcb->in_time_wait) { ++ meta_sk->sk_shutdown |= RCV_SHUTDOWN; ++ sock_set_flag(meta_sk, SOCK_DONE); ++ state = meta_sk->sk_state; ++ } else { ++ state = mpcb->mptw_state; ++ } ++ ++ switch (state) { ++ case TCP_SYN_RECV: ++ case TCP_ESTABLISHED: ++ /* Move to CLOSE_WAIT */ ++ tcp_set_state(meta_sk, TCP_CLOSE_WAIT); ++ inet_csk(sk)->icsk_ack.pingpong = 1; ++ break; ++ ++ case TCP_CLOSE_WAIT: ++ case TCP_CLOSING: ++ /* Received a retransmission of the FIN, do ++ * nothing. ++ */ ++ break; ++ case TCP_LAST_ACK: ++ /* RFC793: Remain in the LAST-ACK state. */ ++ break; ++ ++ case TCP_FIN_WAIT1: ++ /* This case occurs when a simultaneous close ++ * happens, we must ack the received FIN and ++ * enter the CLOSING state. ++ */ ++ tcp_send_ack(sk); ++ tcp_set_state(meta_sk, TCP_CLOSING); ++ break; ++ case TCP_FIN_WAIT2: ++ /* Received a FIN -- send ACK and enter TIME_WAIT. */ ++ tcp_send_ack(sk); ++ meta_tp->ops->time_wait(meta_sk, TCP_TIME_WAIT, 0); ++ break; ++ default: ++ /* Only TCP_LISTEN and TCP_CLOSE are left, in these ++ * cases we should never reach this piece of code. ++ */ ++ pr_err("%s: Impossible, meta_sk->sk_state=%d\n", __func__, ++ meta_sk->sk_state); ++ break; ++ } ++ ++ /* It _is_ possible, that we have something out-of-order _after_ FIN. ++ * Probably, we should reset in this case. For now drop them. ++ */ ++ skb_rbtree_purge(&meta_tp->out_of_order_queue); ++ sk_mem_reclaim(meta_sk); ++ ++ if (!sock_flag(meta_sk, SOCK_DEAD)) { ++ meta_sk->sk_state_change(meta_sk); ++ ++ /* Do not send POLL_HUP for half duplex close. */ ++ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || ++ meta_sk->sk_state == TCP_CLOSE) ++ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_HUP); ++ else ++ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_IN); ++ } ++ ++ return; ++} ++ ++/* Similar to tcp_xmit_retransmit_queue */ ++static void mptcp_xmit_retransmit_queue(struct sock *meta_sk) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct sk_buff *skb, *rtx_head; ++ ++ if (!meta_tp->packets_out) ++ return; ++ ++ skb = rtx_head = tcp_rtx_queue_head(meta_sk); ++ skb_rbtree_walk_from(skb) { ++ if (mptcp_retransmit_skb(meta_sk, skb)) ++ return; ++ ++ if (skb == rtx_head) ++ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, ++ inet_csk(meta_sk)->icsk_rto, ++ TCP_RTO_MAX); ++ } ++} ++ ++static void mptcp_snd_una_update(struct tcp_sock *meta_tp, u32 data_ack) ++{ ++ u32 delta = data_ack - meta_tp->snd_una; ++ ++ sock_owned_by_me((struct sock *)meta_tp); ++ meta_tp->bytes_acked += delta; ++ meta_tp->snd_una = data_ack; ++} ++ ++/* Handle the DATA_ACK */ ++static void mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); ++ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); ++ u32 prior_snd_una = meta_tp->snd_una; ++ int prior_packets; ++ u32 nwin, data_ack, data_seq; ++ u16 data_len = 0; ++ ++ /* A valid packet came in - subflow is operational again */ ++ tp->pf = 0; ++ ++ /* Even if there is no data-ack, we stop retransmitting. ++ * Except if this is a SYN/ACK. Then it is just a retransmission ++ */ ++ if (tp->mptcp->pre_established && !tcp_hdr(skb)->syn) { ++ tp->mptcp->pre_established = 0; ++ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); ++ ++ if (meta_tp->mpcb->pm_ops->established_subflow) ++ meta_tp->mpcb->pm_ops->established_subflow(sk); ++ } ++ ++ /* If we are in infinite mapping mode, rx_opt.data_ack has been ++ * set by mptcp_clean_rtx_infinite. ++ */ ++ if (!(tcb->mptcp_flags & MPTCPHDR_ACK) && !tp->mpcb->infinite_mapping_snd) ++ return; ++ ++ if (unlikely(!tp->mptcp->fully_established) && ++ tp->mptcp->snt_isn + 1 != TCP_SKB_CB(skb)->ack_seq) ++ /* As soon as a subflow-data-ack (not acking syn, thus snt_isn + 1) ++ * includes a data-ack, we are fully established ++ */ ++ mptcp_become_fully_estab(sk); ++ ++ /* After we did the subflow-only processing (stopping timer and marking ++ * subflow as established), check if we can proceed with MPTCP-level ++ * processing. ++ */ ++ if (meta_sk->sk_state == TCP_CLOSE) ++ return; ++ ++ /* Get the data_seq */ ++ if (mptcp_is_data_seq(skb)) { ++ data_seq = tp->mptcp->rx_opt.data_seq; ++ data_len = tp->mptcp->rx_opt.data_len; ++ } else { ++ data_seq = meta_tp->snd_wl1; ++ } ++ ++ data_ack = tp->mptcp->rx_opt.data_ack; ++ ++ /* If the ack is older than previous acks ++ * then we can probably ignore it. ++ */ ++ if (before(data_ack, prior_snd_una)) ++ goto exit; ++ ++ /* If the ack includes data we haven't sent yet, discard ++ * this segment (RFC793 Section 3.9). ++ */ ++ if (after(data_ack, meta_tp->snd_nxt)) ++ goto exit; ++ ++ /*** Now, update the window - inspired by tcp_ack_update_window ***/ ++ nwin = ntohs(tcp_hdr(skb)->window); ++ ++ if (likely(!tcp_hdr(skb)->syn)) ++ nwin <<= tp->rx_opt.snd_wscale; ++ ++ if (tcp_may_update_window(meta_tp, data_ack, data_seq, nwin)) { ++ tcp_update_wl(meta_tp, data_seq); ++ ++ /* Draft v09, Section 3.3.5: ++ * [...] It should only update its local receive window values ++ * when the largest sequence number allowed (i.e. DATA_ACK + ++ * receive window) increases. [...] ++ */ ++ if (meta_tp->snd_wnd != nwin && ++ !before(data_ack + nwin, tcp_wnd_end(meta_tp))) { ++ meta_tp->snd_wnd = nwin; ++ ++ if (nwin > meta_tp->max_window) ++ meta_tp->max_window = nwin; ++ } ++ } ++ /*** Done, update the window ***/ ++ ++ /* We passed data and got it acked, remove any soft error ++ * log. Something worked... ++ */ ++ sk->sk_err_soft = 0; ++ inet_csk(meta_sk)->icsk_probes_out = 0; ++ meta_tp->rcv_tstamp = tcp_jiffies32; ++ prior_packets = meta_tp->packets_out; ++ if (!prior_packets) ++ goto no_queue; ++ ++ mptcp_snd_una_update(meta_tp, data_ack); ++ ++ mptcp_clean_rtx_queue(meta_sk, prior_snd_una); ++ ++ /* We are in loss-state, and something got acked, retransmit the whole ++ * queue now! ++ */ ++ if (inet_csk(meta_sk)->icsk_ca_state == TCP_CA_Loss && ++ after(data_ack, prior_snd_una)) { ++ mptcp_xmit_retransmit_queue(meta_sk); ++ inet_csk(meta_sk)->icsk_ca_state = TCP_CA_Open; ++ } ++ ++ /* Simplified version of tcp_new_space, because the snd-buffer ++ * is handled by all the subflows. ++ */ ++ if (sock_flag(meta_sk, SOCK_QUEUE_SHRUNK)) { ++ sock_reset_flag(meta_sk, SOCK_QUEUE_SHRUNK); ++ if (meta_sk->sk_socket && ++ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) ++ meta_sk->sk_write_space(meta_sk); ++ } ++ ++ if (meta_sk->sk_state != TCP_ESTABLISHED && ++ mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len)) ++ return; ++ ++exit: ++ mptcp_push_pending_frames(meta_sk); ++ ++ return; ++ ++no_queue: ++ if (tcp_send_head(meta_sk)) ++ tcp_ack_probe(meta_sk); ++ ++ mptcp_push_pending_frames(meta_sk); ++ ++ return; ++} ++ ++void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(mptcp_meta_sk(sk)); ++ ++ if (!tp->mpcb->infinite_mapping_snd) ++ return; ++ ++ /* The difference between both write_seq's represents the offset between ++ * data-sequence and subflow-sequence. As we are infinite, this must ++ * match. ++ * ++ * Thus, from this difference we can infer the meta snd_una. ++ */ ++ tp->mptcp->rx_opt.data_ack = meta_tp->snd_nxt - tp->snd_nxt + ++ tp->snd_una; ++ ++ mptcp_data_ack(sk, skb); ++} ++ ++/**** static functions used by mptcp_parse_options */ ++ ++static void mptcp_send_reset_rem_id(const struct mptcp_cb *mpcb, u8 rem_id) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(sk_it)->mptcp->rem_id == rem_id) { ++ mptcp_reinject_data(sk_it, 0); ++ mptcp_send_reset(sk_it); ++ } ++ } ++} ++ ++static inline bool is_valid_addropt_opsize(u8 mptcp_ver, ++ struct mp_add_addr *mpadd, ++ int opsize) ++{ ++#if IS_ENABLED(CONFIG_IPV6) ++ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 6) { ++ return opsize == MPTCP_SUB_LEN_ADD_ADDR6 || ++ opsize == MPTCP_SUB_LEN_ADD_ADDR6 + 2; ++ } ++ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 6) ++ return opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 || ++ opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2; ++#endif ++ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 4) { ++ return opsize == MPTCP_SUB_LEN_ADD_ADDR4 || ++ opsize == MPTCP_SUB_LEN_ADD_ADDR4 + 2; ++ } ++ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 4) { ++ return opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || ++ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; ++ } ++ return false; ++} ++ ++void mptcp_parse_options(const uint8_t *ptr, int opsize, ++ struct mptcp_options_received *mopt, ++ const struct sk_buff *skb, ++ struct tcp_sock *tp) ++{ ++ const struct mptcp_option *mp_opt = (struct mptcp_option *)ptr; ++ ++ /* If the socket is mp-capable we would have a mopt. */ ++ if (!mopt) ++ return; ++ ++ switch (mp_opt->sub) { ++ case MPTCP_SUB_CAPABLE: ++ { ++ const struct mp_capable *mpcapable = (struct mp_capable *)ptr; ++ ++ if (opsize != MPTCP_SUB_LEN_CAPABLE_SYN && ++ opsize != MPTCP_SUB_LEN_CAPABLE_ACK) { ++ mptcp_debug("%s: mp_capable: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ /* MPTCP-RFC 6824: ++ * "If receiving a message with the 'B' flag set to 1, and this ++ * is not understood, then this SYN MUST be silently ignored; ++ */ ++ if (mpcapable->b) { ++ mopt->drop_me = 1; ++ break; ++ } ++ ++ /* MPTCP-RFC 6824: ++ * "An implementation that only supports this method MUST set ++ * bit "H" to 1, and bits "C" through "G" to 0." ++ */ ++ if (!mpcapable->h) ++ break; ++ ++ mopt->saw_mpc = 1; ++ mopt->dss_csum = sysctl_mptcp_checksum || mpcapable->a; ++ ++ if (opsize >= MPTCP_SUB_LEN_CAPABLE_SYN) ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) ++ mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ ++ mopt->mptcp_ver = mpcapable->ver; ++ break; ++ } ++ case MPTCP_SUB_JOIN: ++ { ++ const struct mp_join *mpjoin = (struct mp_join *)ptr; ++ ++ if (opsize != MPTCP_SUB_LEN_JOIN_SYN && ++ opsize != MPTCP_SUB_LEN_JOIN_SYNACK && ++ opsize != MPTCP_SUB_LEN_JOIN_ACK) { ++ mptcp_debug("%s: mp_join: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ /* saw_mpc must be set, because in tcp_check_req we assume that ++ * it is set to support falling back to reg. TCP if a rexmitted ++ * SYN has no MP_CAPABLE or MP_JOIN ++ */ ++ switch (opsize) { ++ case MPTCP_SUB_LEN_JOIN_SYN: ++ mopt->is_mp_join = 1; ++ mopt->saw_mpc = 1; ++ mopt->low_prio = mpjoin->b; ++ mopt->rem_id = mpjoin->addr_id; ++ mopt->mptcp_rem_token = mpjoin->u.syn.token; ++ mopt->mptcp_recv_nonce = mpjoin->u.syn.nonce; ++ break; ++ case MPTCP_SUB_LEN_JOIN_SYNACK: ++ mopt->saw_mpc = 1; ++ mopt->low_prio = mpjoin->b; ++ mopt->rem_id = mpjoin->addr_id; ++ mopt->mptcp_recv_tmac = mpjoin->u.synack.mac; ++ mopt->mptcp_recv_nonce = mpjoin->u.synack.nonce; ++ break; ++ case MPTCP_SUB_LEN_JOIN_ACK: ++ mopt->saw_mpc = 1; ++ mopt->join_ack = 1; ++ memcpy(mopt->mptcp_recv_mac, mpjoin->u.ack.mac, 20); ++ break; ++ } ++ break; ++ } ++ case MPTCP_SUB_DSS: ++ { ++ const struct mp_dss *mdss = (struct mp_dss *)ptr; ++ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); ++ ++ /* We check opsize for the csum and non-csum case. We do this, ++ * because the draft says that the csum SHOULD be ignored if ++ * it has not been negotiated in the MP_CAPABLE but still is ++ * present in the data. ++ * ++ * It will get ignored later in mptcp_queue_skb. ++ */ ++ if (opsize != mptcp_sub_len_dss(mdss, 0) && ++ opsize != mptcp_sub_len_dss(mdss, 1)) { ++ mptcp_debug("%s: mp_dss: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ ptr += 4; ++ ++ if (mdss->A) { ++ tcb->mptcp_flags |= MPTCPHDR_ACK; ++ ++ if (mdss->a) { ++ mopt->data_ack = (u32) get_unaligned_be64(ptr); ++ ptr += MPTCP_SUB_LEN_ACK_64; ++ } else { ++ mopt->data_ack = get_unaligned_be32(ptr); ++ ptr += MPTCP_SUB_LEN_ACK; ++ } ++ } ++ ++ tcb->dss_off = (ptr - skb_transport_header(skb)); ++ ++ if (mdss->M) { ++ if (mdss->m) { ++ u64 data_seq64 = get_unaligned_be64(ptr); ++ ++ tcb->mptcp_flags |= MPTCPHDR_SEQ64_SET; ++ mopt->data_seq = (u32) data_seq64; ++ ++ ptr += 12; /* 64-bit dseq + subseq */ ++ } else { ++ mopt->data_seq = get_unaligned_be32(ptr); ++ ptr += 8; /* 32-bit dseq + subseq */ ++ } ++ mopt->data_len = get_unaligned_be16(ptr); ++ ++ tcb->mptcp_flags |= MPTCPHDR_SEQ; ++ ++ /* Is a check-sum present? */ ++ if (opsize == mptcp_sub_len_dss(mdss, 1)) ++ tcb->mptcp_flags |= MPTCPHDR_DSS_CSUM; ++ ++ /* DATA_FIN only possible with DSS-mapping */ ++ if (mdss->F) ++ tcb->mptcp_flags |= MPTCPHDR_FIN; ++ } ++ ++ break; ++ } ++ case MPTCP_SUB_ADD_ADDR: ++ { ++ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; ++ ++ /* If tcp_sock is not available, MPTCP version can't be ++ * retrieved and ADD_ADDR opsize validation is not possible. ++ */ ++ if (!tp || !tp->mpcb) ++ break; ++ ++ if (!is_valid_addropt_opsize(tp->mpcb->mptcp_ver, ++ mpadd, opsize)) { ++ mptcp_debug("%s: mp_add_addr: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ /* We have to manually parse the options if we got two of them. */ ++ if (mopt->saw_add_addr) { ++ mopt->more_add_addr = 1; ++ break; ++ } ++ mopt->saw_add_addr = 1; ++ mopt->add_addr_ptr = ptr; ++ break; ++ } ++ case MPTCP_SUB_REMOVE_ADDR: ++ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) { ++ mptcp_debug("%s: mp_remove_addr: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ if (mopt->saw_rem_addr) { ++ mopt->more_rem_addr = 1; ++ break; ++ } ++ mopt->saw_rem_addr = 1; ++ mopt->rem_addr_ptr = ptr; ++ break; ++ case MPTCP_SUB_PRIO: ++ { ++ const struct mp_prio *mpprio = (struct mp_prio *)ptr; ++ ++ if (opsize != MPTCP_SUB_LEN_PRIO && ++ opsize != MPTCP_SUB_LEN_PRIO_ADDR) { ++ mptcp_debug("%s: mp_prio: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ mopt->saw_low_prio = 1; ++ mopt->low_prio = mpprio->b; ++ ++ if (opsize == MPTCP_SUB_LEN_PRIO_ADDR) { ++ mopt->saw_low_prio = 2; ++ mopt->prio_addr_id = mpprio->addr_id; ++ } ++ break; ++ } ++ case MPTCP_SUB_FAIL: ++ if (opsize != MPTCP_SUB_LEN_FAIL) { ++ mptcp_debug("%s: mp_fail: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ mopt->mp_fail = 1; ++ break; ++ case MPTCP_SUB_FCLOSE: ++ if (opsize != MPTCP_SUB_LEN_FCLOSE) { ++ mptcp_debug("%s: mp_fclose: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ mopt->mp_fclose = 1; ++ mopt->mptcp_sender_key = ((struct mp_fclose *)ptr)->key; ++ ++ break; ++ default: ++ mptcp_debug("%s: Received unkown subtype: %d\n", ++ __func__, mp_opt->sub); ++ break; ++ } ++} ++ ++/** Parse only MPTCP options */ ++void tcp_parse_mptcp_options(const struct sk_buff *skb, ++ struct mptcp_options_received *mopt) ++{ ++ const struct tcphdr *th = tcp_hdr(skb); ++ int length = (th->doff * 4) - sizeof(struct tcphdr); ++ const unsigned char *ptr = (const unsigned char *)(th + 1); ++ ++ while (length > 0) { ++ int opcode = *ptr++; ++ int opsize; ++ ++ switch (opcode) { ++ case TCPOPT_EOL: ++ return; ++ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ ++ length--; ++ continue; ++ default: ++ opsize = *ptr++; ++ if (opsize < 2) /* "silly options" */ ++ return; ++ if (opsize > length) ++ return; /* don't parse partial options */ ++ if (opcode == TCPOPT_MPTCP) ++ mptcp_parse_options(ptr - 2, opsize, mopt, skb, NULL); ++ } ++ ptr += opsize - 2; ++ length -= opsize; ++ } ++} ++ ++bool mptcp_check_rtt(const struct tcp_sock *tp, int time) ++{ ++ struct mptcp_cb *mpcb = tp->mpcb; ++ struct mptcp_tcp_sock *mptcp; ++ u32 rtt_max = 0; ++ ++ /* In MPTCP, we take the max delay across all flows, ++ * in order to take into account meta-reordering buffers. ++ */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if (!mptcp_sk_can_recv(sk)) ++ continue; ++ ++ if (rtt_max < tcp_sk(sk)->rcv_rtt_est.rtt_us) ++ rtt_max = tcp_sk(sk)->rcv_rtt_est.rtt_us; ++ } ++ if (time < (rtt_max >> 3) || !rtt_max) ++ return true; ++ ++ return false; ++} ++ ++static void mptcp_handle_add_addr(const unsigned char *ptr, struct sock *sk) ++{ ++ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; ++ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; ++ __be16 port = 0; ++ union inet_addr addr; ++ sa_family_t family; ++ ++ if (mpadd->ipver == 4) { ++ char *recv_hmac; ++ u8 hash_mac_check[20]; ++ u8 no_key[8]; ++ int msg_parts = 0; ++ ++ if (mpcb->mptcp_ver < MPTCP_VERSION_1) ++ goto skip_hmac_v4; ++ ++ *(u64 *)no_key = 0; ++ recv_hmac = (char *)mpadd->u.v4.mac; ++ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1) { ++ recv_hmac -= sizeof(mpadd->u.v4.port); ++ msg_parts = 2; ++ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { ++ msg_parts = 3; ++ } ++ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)no_key, ++ (u32 *)hash_mac_check, msg_parts, ++ 1, (u8 *)&mpadd->addr_id, ++ 4, (u8 *)&mpadd->u.v4.addr.s_addr, ++ 2, (u8 *)&mpadd->u.v4.port); ++ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) ++ /* ADD_ADDR2 discarded */ ++ return; ++skip_hmac_v4: ++ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && ++ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4 + 2) || ++ (mpcb->mptcp_ver == MPTCP_VERSION_1 && ++ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2)) ++ port = mpadd->u.v4.port; ++ family = AF_INET; ++ addr.in = mpadd->u.v4.addr; ++#if IS_ENABLED(CONFIG_IPV6) ++ } else if (mpadd->ipver == 6) { ++ char *recv_hmac; ++ u8 hash_mac_check[20]; ++ u8 no_key[8]; ++ int msg_parts = 0; ++ ++ if (mpcb->mptcp_ver < MPTCP_VERSION_1) ++ goto skip_hmac_v6; ++ ++ *(u64 *)no_key = 0; ++ recv_hmac = (char *)mpadd->u.v6.mac; ++ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1) { ++ recv_hmac -= sizeof(mpadd->u.v6.port); ++ msg_parts = 2; ++ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { ++ msg_parts = 3; ++ } ++ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)no_key, ++ (u32 *)hash_mac_check, msg_parts, ++ 1, (u8 *)&mpadd->addr_id, ++ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, ++ 2, (u8 *)&mpadd->u.v6.port); ++ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) ++ /* ADD_ADDR2 discarded */ ++ return; ++skip_hmac_v6: ++ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && ++ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6 + 2) || ++ (mpcb->mptcp_ver == MPTCP_VERSION_1 && ++ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2)) ++ port = mpadd->u.v6.port; ++ family = AF_INET6; ++ addr.in6 = mpadd->u.v6.addr; ++#endif /* CONFIG_IPV6 */ ++ } else { ++ return; ++ } ++ ++ if (mpcb->pm_ops->add_raddr) ++ mpcb->pm_ops->add_raddr(mpcb, &addr, family, port, mpadd->addr_id); ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRRX); ++} ++ ++static void mptcp_handle_rem_addr(const unsigned char *ptr, struct sock *sk) ++{ ++ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; ++ int i; ++ u8 rem_id; ++ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; ++ ++ for (i = 0; i <= mprem->len - MPTCP_SUB_LEN_REMOVE_ADDR; i++) { ++ rem_id = (&mprem->addrs_id)[i]; ++ ++ if (mpcb->pm_ops->rem_raddr) ++ mpcb->pm_ops->rem_raddr(mpcb, rem_id); ++ mptcp_send_reset_rem_id(mpcb, rem_id); ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRSUB); ++ } ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRRX); ++} ++ ++static void mptcp_parse_addropt(const struct sk_buff *skb, struct sock *sk) ++{ ++ struct tcphdr *th = tcp_hdr(skb); ++ unsigned char *ptr; ++ int length = (th->doff * 4) - sizeof(struct tcphdr); ++ ++ /* Jump through the options to check whether ADD_ADDR is there */ ++ ptr = (unsigned char *)(th + 1); ++ while (length > 0) { ++ int opcode = *ptr++; ++ int opsize; ++ ++ switch (opcode) { ++ case TCPOPT_EOL: ++ return; ++ case TCPOPT_NOP: ++ length--; ++ continue; ++ default: ++ opsize = *ptr++; ++ if (opsize < 2) ++ return; ++ if (opsize > length) ++ return; /* don't parse partial options */ ++ if (opcode == TCPOPT_MPTCP && ++ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_ADD_ADDR) { ++ u8 mptcp_ver = tcp_sk(sk)->mpcb->mptcp_ver; ++ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; ++ ++ if (!is_valid_addropt_opsize(mptcp_ver, mpadd, ++ opsize)) ++ goto cont; ++ ++ mptcp_handle_add_addr(ptr, sk); ++ } ++ if (opcode == TCPOPT_MPTCP && ++ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_REMOVE_ADDR) { ++ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) ++ goto cont; ++ ++ mptcp_handle_rem_addr(ptr, sk); ++ } ++cont: ++ ptr += opsize - 2; ++ length -= opsize; ++ } ++ } ++ return; ++} ++ ++static bool mptcp_mp_fastclose_rcvd(struct sock *sk) ++{ ++ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; ++ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; ++ ++ if (likely(!mptcp->rx_opt.mp_fclose)) ++ return false; ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FASTCLOSERX); ++ mptcp->rx_opt.mp_fclose = 0; ++ if (mptcp->rx_opt.mptcp_sender_key != mpcb->mptcp_loc_key) ++ return false; ++ ++ mptcp_sub_force_close_all(mpcb, NULL); ++ ++ tcp_reset(mptcp_meta_sk(sk)); ++ ++ return true; ++} ++ ++static void mptcp_mp_fail_rcvd(struct sock *sk, const struct tcphdr *th) ++{ ++ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILRX); ++ mptcp->rx_opt.mp_fail = 0; ++ ++ if (!th->rst && !mpcb->infinite_mapping_snd) { ++ mpcb->send_infinite_mapping = 1; ++ ++ mptcp_restart_sending(meta_sk); ++ ++ mptcp_fallback_close(mpcb, sk); ++ } ++} ++ ++static inline void mptcp_path_array_check(struct sock *meta_sk) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ ++ if (unlikely(mpcb->list_rcvd)) { ++ mpcb->list_rcvd = 0; ++ if (mpcb->pm_ops->new_remote_address) ++ mpcb->pm_ops->new_remote_address(meta_sk); ++ } ++} ++ ++bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, ++ const struct sk_buff *skb) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; ++ struct mptcp_cb *mpcb = tp->mpcb; ++ ++ if (tp->mpcb->infinite_mapping_rcv || tp->mpcb->infinite_mapping_snd) ++ return false; ++ ++ if (mptcp_mp_fastclose_rcvd(sk)) ++ return true; ++ ++ if (sk->sk_state == TCP_RST_WAIT && !th->rst) ++ return true; ++ ++ if (unlikely(mopt->mp_fail)) ++ mptcp_mp_fail_rcvd(sk, th); ++ ++ /* RFC 6824, Section 3.3: ++ * If a checksum is not present when its use has been negotiated, the ++ * receiver MUST close the subflow with a RST as it is considered broken. ++ */ ++ if (mptcp_is_data_seq(skb) && tp->mpcb->dss_csum && ++ !(TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_DSS_CSUM)) { ++ mptcp_send_reset(sk); ++ return true; ++ } ++ ++ /* We have to acknowledge retransmissions of the third ++ * ack. ++ */ ++ if (mopt->join_ack) { ++ tcp_send_delayed_ack(sk); ++ mopt->join_ack = 0; ++ } ++ ++ if (mopt->saw_add_addr || mopt->saw_rem_addr) { ++ if (mopt->more_add_addr || mopt->more_rem_addr) { ++ mptcp_parse_addropt(skb, sk); ++ } else { ++ if (mopt->saw_add_addr) ++ mptcp_handle_add_addr(mopt->add_addr_ptr, sk); ++ if (mopt->saw_rem_addr) ++ mptcp_handle_rem_addr(mopt->rem_addr_ptr, sk); ++ } ++ ++ mopt->more_add_addr = 0; ++ mopt->saw_add_addr = 0; ++ mopt->more_rem_addr = 0; ++ mopt->saw_rem_addr = 0; ++ } ++ if (mopt->saw_low_prio) { ++ if (mopt->saw_low_prio == 1) { ++ tp->mptcp->rcv_low_prio = mopt->low_prio; ++ if (mpcb->pm_ops->prio_changed) ++ mpcb->pm_ops->prio_changed(sk, mopt->low_prio); ++ } else { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ if (mptcp->rem_id == mopt->prio_addr_id) { ++ mptcp->rcv_low_prio = mopt->low_prio; ++ if (mpcb->pm_ops->prio_changed) ++ mpcb->pm_ops->prio_changed(sk, ++ mopt->low_prio); ++ } ++ } ++ } ++ mopt->saw_low_prio = 0; ++ } ++ ++ mptcp_data_ack(sk, skb); ++ ++ mptcp_path_array_check(mptcp_meta_sk(sk)); ++ /* Socket may have been mp_killed by a REMOVE_ADDR */ ++ if (tp->mp_killed) ++ return true; ++ ++ return false; ++} ++ ++static void _mptcp_rcv_synsent_fastopen(struct sock *meta_sk, ++ struct sk_buff *skb, bool rtx_queue) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct tcp_sock *master_tp = tcp_sk(meta_tp->mpcb->master_sk); ++ u32 new_mapping = meta_tp->write_seq - master_tp->snd_una; ++ ++ /* If the server only acknowledges partially the data sent in ++ * the SYN, we need to trim the acknowledged part because ++ * we don't want to retransmit this already received data. ++ * When we reach this point, tcp_ack() has already cleaned up ++ * fully acked segments. However, tcp trims partially acked ++ * segments only when retransmitting. Since MPTCP comes into ++ * play only now, we will fake an initial transmit, and ++ * retransmit_skb() will not be called. The following fragment ++ * comes from __tcp_retransmit_skb(). ++ */ ++ if (before(TCP_SKB_CB(skb)->seq, master_tp->snd_una)) { ++ BUG_ON(before(TCP_SKB_CB(skb)->end_seq, ++ master_tp->snd_una)); ++ /* tcp_trim_head can only returns ENOMEM if skb is ++ * cloned. It is not the case here (see ++ * tcp_send_syn_data). ++ */ ++ BUG_ON(tcp_trim_head(meta_sk, skb, master_tp->snd_una - ++ TCP_SKB_CB(skb)->seq)); ++ } ++ ++ TCP_SKB_CB(skb)->seq += new_mapping; ++ TCP_SKB_CB(skb)->end_seq += new_mapping; ++ TCP_SKB_CB(skb)->sacked = 0; ++ ++ list_del(&skb->tcp_tsorted_anchor); ++ ++ if (rtx_queue) ++ tcp_rtx_queue_unlink(skb, meta_sk); ++ else ++ tcp_unlink_write_queue(skb, meta_sk); ++ ++ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); ++ ++ tcp_add_write_queue_tail(meta_sk, skb); ++} ++ ++/* In case of fastopen, some data can already be in the write queue. ++ * We need to update the sequence number of the segments as they ++ * were initially TCP sequence numbers. ++ */ ++static void mptcp_rcv_synsent_fastopen(struct sock *meta_sk) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct tcp_sock *master_tp = tcp_sk(meta_tp->mpcb->master_sk); ++ struct sk_buff *skb_write_head, *skb_rtx_head, *tmp; ++ ++ skb_write_head = tcp_write_queue_head(meta_sk); ++ skb_rtx_head = tcp_rtx_queue_head(meta_sk); ++ ++ if (!(skb_write_head || skb_rtx_head)) ++ return; ++ ++ /* There should only be one skb in {write, rtx} queue: the data not ++ * acknowledged in the SYN+ACK. In this case, we need to map ++ * this data to data sequence numbers. ++ */ ++ ++ WARN_ON(skb_write_head && skb_rtx_head); ++ ++ if (skb_write_head) { ++ skb_queue_walk_from_safe(&meta_sk->sk_write_queue, ++ skb_write_head, tmp) { ++ _mptcp_rcv_synsent_fastopen(meta_sk, skb_write_head, ++ false); ++ } ++ } ++ ++ if (skb_rtx_head) { ++ skb_rbtree_walk_from_safe(skb_rtx_head, tmp) { ++ _mptcp_rcv_synsent_fastopen(meta_sk, skb_rtx_head, ++ true); ++ } ++ } ++ ++ /* We can advance write_seq by the number of bytes unacknowledged ++ * and that were mapped in the previous loop. ++ */ ++ meta_tp->write_seq += master_tp->write_seq - master_tp->snd_una; ++ ++ /* The packets from the master_sk will be entailed to it later ++ * Until that time, its write queue is empty, and ++ * write_seq must align with snd_una ++ */ ++ master_tp->snd_nxt = master_tp->write_seq = master_tp->snd_una; ++ master_tp->packets_out = 0; ++ tcp_clear_retrans(meta_tp); ++ tcp_clear_retrans(master_tp); ++ tcp_set_ca_state(meta_tp->mpcb->master_sk, TCP_CA_Open); ++ tcp_set_ca_state(meta_sk, TCP_CA_Open); ++} ++ ++/* The skptr is needed, because if we become MPTCP-capable, we have to switch ++ * from meta-socket to master-socket. ++ * ++ * @return: 1 - we want to reset this connection ++ * 2 - we want to discard the received syn/ack ++ * 0 - everything is fine - continue ++ */ ++int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, ++ const struct sk_buff *skb, ++ const struct mptcp_options_received *mopt) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (mptcp(tp)) { ++ u8 hash_mac_check[20]; ++ struct mptcp_cb *mpcb = tp->mpcb; ++ ++ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)&mpcb->mptcp_loc_key, ++ (u32 *)hash_mac_check, 2, ++ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, ++ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); ++ if (memcmp(hash_mac_check, ++ (char *)&tp->mptcp->rx_opt.mptcp_recv_tmac, 8)) { ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); ++ mptcp_sub_force_close(sk); ++ return 1; ++ } ++ ++ /* Set this flag in order to postpone data sending ++ * until the 4th ack arrives. ++ */ ++ tp->mptcp->pre_established = 1; ++ tp->mptcp->rcv_low_prio = tp->mptcp->rx_opt.low_prio; ++ ++ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)&mpcb->mptcp_rem_key, ++ (u32 *)&tp->mptcp->sender_mac[0], 2, ++ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, ++ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); ++ } else if (mopt->saw_mpc) { ++ struct sock *meta_sk = sk; ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEACK); ++ if (mopt->mptcp_ver > tcp_sk(sk)->mptcp_ver) ++ /* TODO Consider adding new MPTCP_INC_STATS entry */ ++ goto fallback; ++ ++ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, ++ mopt->mptcp_ver, ++ ntohs(tcp_hdr(skb)->window))) ++ return 2; ++ ++ sk = tcp_sk(sk)->mpcb->master_sk; ++ *skptr = sk; ++ tp = tcp_sk(sk); ++ ++ /* If fastopen was used data might be in the send queue. We ++ * need to update their sequence number to MPTCP-level seqno. ++ * Note that it can happen in rare cases that fastopen_req is ++ * NULL and syn_data is 0 but fastopen indeed occurred and ++ * data has been queued in the write queue (but not sent). ++ * Example of such rare cases: connect is non-blocking and ++ * TFO is configured to work without cookies. ++ */ ++ mptcp_rcv_synsent_fastopen(meta_sk); ++ ++ /* -1, because the SYN consumed 1 byte. In case of TFO, we ++ * start the subflow-sequence number as if the data of the SYN ++ * is not part of any mapping. ++ */ ++ tp->mptcp->snt_isn = tp->snd_una - 1; ++ tp->mpcb->dss_csum = mopt->dss_csum; ++ if (tp->mpcb->dss_csum) ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMENABLED); ++ ++ tp->mptcp->include_mpc = 1; ++ ++ /* Ensure that fastopen is handled at the meta-level. */ ++ tp->fastopen_req = NULL; ++ ++ sk_set_socket(sk, meta_sk->sk_socket); ++ sk->sk_wq = meta_sk->sk_wq; ++ ++ bh_unlock_sock(sk); ++ /* hold in sk_clone_lock due to initialization to 2 */ ++ sock_put(sk); ++ } else { ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEFALLBACK); ++fallback: ++ tp->request_mptcp = 0; ++ ++ if (tp->inside_tk_table) ++ mptcp_hash_remove_bh(tp); ++ } ++ ++ if (mptcp(tp)) ++ tp->mptcp->rcv_isn = TCP_SKB_CB(skb)->seq; ++ ++ return 0; ++} ++ ++/* Similar to tcp_should_expand_sndbuf */ ++bool mptcp_should_expand_sndbuf(const struct sock *sk) ++{ ++ const struct sock *meta_sk = mptcp_meta_sk(sk); ++ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ const struct mptcp_tcp_sock *mptcp; ++ ++ /* We circumvent this check in tcp_check_space, because we want to ++ * always call sk_write_space. So, we reproduce the check here. ++ */ ++ if (!meta_sk->sk_socket || ++ !test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) ++ return false; ++ ++ /* If the user specified a specific send buffer setting, do ++ * not modify it. ++ */ ++ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) ++ return false; ++ ++ /* If we are under global TCP memory pressure, do not expand. */ ++ if (tcp_under_memory_pressure(meta_sk)) ++ return false; ++ ++ /* If we are under soft global TCP memory pressure, do not expand. */ ++ if (sk_memory_allocated(meta_sk) >= sk_prot_mem_limits(meta_sk, 0)) ++ return false; ++ ++ /* For MPTCP we look for a subsocket that could send data. ++ * If we found one, then we update the send-buffer. ++ */ ++ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { ++ const struct sock *sk_it = mptcp_to_sock(mptcp); ++ const struct tcp_sock *tp_it = tcp_sk(sk_it); ++ ++ if (!mptcp_sk_can_send(sk_it)) ++ continue; ++ ++ if (tcp_packets_in_flight(tp_it) < tp_it->snd_cwnd) ++ return true; ++ } ++ ++ return false; ++} ++ ++void mptcp_tcp_set_rto(struct sock *sk) ++{ ++ tcp_set_rto(sk); ++ mptcp_set_rto(sk); ++} +diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c +--- linux-5.4/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,427 @@ ++/* ++ * MPTCP implementation - IPv4-specific functions ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport) ++{ ++ return siphash_4u32((__force u32)saddr, (__force u32)daddr, ++ (__force u32)sport << 16 | (__force u32)dport, ++ mptcp_seed++, &mptcp_secret); ++} ++ ++u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, ++ u32 seed) ++{ ++ return siphash_2u64((__force u64)saddr << 32 | (__force u64)daddr, ++ (__force u64)seed << 32 | (__force u64)sport << 16 | (__force u64)dport, ++ &mptcp_secret); ++} ++ ++ ++static void mptcp_v4_reqsk_destructor(struct request_sock *req) ++{ ++ mptcp_reqsk_destructor(req); ++ ++ tcp_v4_reqsk_destructor(req); ++} ++ ++static int mptcp_v4_init_req(struct request_sock *req, const struct sock *sk, ++ struct sk_buff *skb, bool want_cookie) ++{ ++ tcp_request_sock_ipv4_ops.init_req(req, sk, skb, want_cookie); ++ ++ mptcp_rsk(req)->hash_entry.pprev = NULL; ++ mptcp_rsk(req)->is_sub = 0; ++ inet_rsk(req)->mptcp_rqsk = 1; ++ ++ /* In case of SYN-cookies, we wait for the isn to be generated - it is ++ * input to the key-generation. ++ */ ++ if (!want_cookie) ++ mptcp_reqsk_init(req, sk, skb, false); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SYN_COOKIES ++static u32 mptcp_v4_cookie_init_seq(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, __u16 *mssp) ++{ ++ __u32 isn = cookie_v4_init_sequence(req, sk, skb, mssp); ++ ++ tcp_rsk(req)->snt_isn = isn; ++ ++ mptcp_reqsk_init(req, sk, skb, true); ++ ++ return isn; ++} ++#endif ++ ++/* May be called without holding the meta-level lock */ ++static int mptcp_v4_join_init_req(struct request_sock *req, const struct sock *meta_sk, ++ struct sk_buff *skb, bool want_cookie) ++{ ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ union inet_addr addr; ++ int loc_id; ++ bool low_prio = false; ++ ++ /* We need to do this as early as possible. Because, if we fail later ++ * (e.g., get_local_id), then reqsk_free tries to remove the ++ * request-socket from the htb in mptcp_hash_request_remove as pprev ++ * may be different from NULL. ++ */ ++ mtreq->hash_entry.pprev = NULL; ++ ++ tcp_request_sock_ipv4_ops.init_req(req, meta_sk, skb, want_cookie); ++ ++ mtreq->mptcp_loc_nonce = mptcp_v4_get_nonce(ip_hdr(skb)->saddr, ++ ip_hdr(skb)->daddr, ++ tcp_hdr(skb)->source, ++ tcp_hdr(skb)->dest); ++ addr.ip = inet_rsk(req)->ir_loc_addr; ++ loc_id = mpcb->pm_ops->get_local_id(meta_sk, AF_INET, &addr, &low_prio); ++ if (loc_id == -1) ++ return -1; ++ mtreq->loc_id = loc_id; ++ mtreq->low_prio = low_prio; ++ ++ mptcp_join_reqsk_init(mpcb, req, skb); ++ ++ return 0; ++} ++ ++/* Similar to tcp_request_sock_ops */ ++struct request_sock_ops mptcp_request_sock_ops __read_mostly = { ++ .family = PF_INET, ++ .obj_size = sizeof(struct mptcp_request_sock), ++ .rtx_syn_ack = tcp_rtx_synack, ++ .send_ack = tcp_v4_reqsk_send_ack, ++ .destructor = mptcp_v4_reqsk_destructor, ++ .send_reset = tcp_v4_send_reset, ++ .syn_ack_timeout = tcp_syn_ack_timeout, ++}; ++ ++/* Similar to: tcp_v4_conn_request ++ * May be called without holding the meta-level lock ++ */ ++static int mptcp_v4_join_request(struct sock *meta_sk, struct sk_buff *skb) ++{ ++ return tcp_conn_request(&mptcp_request_sock_ops, ++ &mptcp_join_request_sock_ipv4_ops, ++ meta_sk, skb); ++} ++ ++/* Similar to: tcp_v4_do_rcv ++ * We only process join requests here. (either the SYN or the final ACK) ++ */ ++int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb) ++{ ++ const struct tcphdr *th = tcp_hdr(skb); ++ const struct iphdr *iph = ip_hdr(skb); ++ struct sock *child, *rsk = NULL, *sk; ++ int ret; ++ ++ sk = inet_lookup_established(sock_net(meta_sk), &tcp_hashinfo, ++ iph->saddr, th->source, iph->daddr, ++ th->dest, inet_iif(skb)); ++ ++ if (!sk) ++ goto new_subflow; ++ ++ if (is_meta_sk(sk)) { ++ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); ++ sock_put(sk); ++ goto discard; ++ } ++ ++ if (sk->sk_state == TCP_TIME_WAIT) { ++ inet_twsk_put(inet_twsk(sk)); ++ goto discard; ++ } ++ ++ if (sk->sk_state == TCP_NEW_SYN_RECV) { ++ struct request_sock *req = inet_reqsk(sk); ++ bool req_stolen; ++ ++ if (!mptcp_can_new_subflow(meta_sk)) ++ goto reset_and_discard; ++ ++ local_bh_disable(); ++ child = tcp_check_req(meta_sk, skb, req, false, &req_stolen); ++ if (!child) { ++ reqsk_put(req); ++ local_bh_enable(); ++ goto discard; ++ } ++ ++ if (child != meta_sk) { ++ ret = mptcp_finish_handshake(child, skb); ++ if (ret) { ++ rsk = child; ++ local_bh_enable(); ++ goto reset_and_discard; ++ } ++ ++ local_bh_enable(); ++ return 0; ++ } ++ ++ /* tcp_check_req failed */ ++ reqsk_put(req); ++ ++ local_bh_enable(); ++ goto discard; ++ } ++ ++ ret = tcp_v4_do_rcv(sk, skb); ++ sock_put(sk); ++ ++ return ret; ++ ++new_subflow: ++ if (!mptcp_can_new_subflow(meta_sk)) ++ goto reset_and_discard; ++ ++ child = tcp_v4_cookie_check(meta_sk, skb); ++ if (!child) ++ goto discard; ++ ++ if (child != meta_sk) { ++ ret = mptcp_finish_handshake(child, skb); ++ if (ret) { ++ rsk = child; ++ goto reset_and_discard; ++ } ++ } ++ ++ if (tcp_hdr(skb)->syn) { ++ local_bh_disable(); ++ mptcp_v4_join_request(meta_sk, skb); ++ local_bh_enable(); ++ } ++ ++discard: ++ kfree_skb(skb); ++ return 0; ++ ++reset_and_discard: ++ tcp_v4_send_reset(rsk, skb); ++ goto discard; ++} ++ ++/* Create a new IPv4 subflow. ++ * ++ * We are in user-context and meta-sock-lock is hold. ++ */ ++int __mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, ++ __be16 sport, struct mptcp_rem4 *rem, ++ struct sock **subsk) ++{ ++ struct tcp_sock *tp; ++ struct sock *sk; ++ struct sockaddr_in loc_in, rem_in; ++ struct socket_alloc sock_full; ++ struct socket *sock = (struct socket *)&sock_full; ++ int ret; ++ ++ /** First, create and prepare the new socket */ ++ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); ++ sock->state = SS_UNCONNECTED; ++ sock->ops = NULL; ++ ++ ret = inet_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); ++ if (unlikely(ret < 0)) { ++ net_err_ratelimited("%s inet_create failed ret: %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ sk = sock->sk; ++ tp = tcp_sk(sk); ++ ++ /* All subsockets need the MPTCP-lock-class */ ++ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); ++ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); ++ ++ ret = mptcp_add_sock(meta_sk, sk, loc->loc4_id, rem->rem4_id, GFP_KERNEL); ++ if (ret) { ++ net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", ++ __func__, ret); ++ goto error; ++ } ++ ++ tp->mptcp->slave_sk = 1; ++ tp->mptcp->low_prio = loc->low_prio; ++ ++ /* Initializing the timer for an MPTCP subflow */ ++ timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); ++ ++ /** Then, connect the socket to the peer */ ++ loc_in.sin_family = AF_INET; ++ rem_in.sin_family = AF_INET; ++ loc_in.sin_port = sport; ++ if (rem->port) ++ rem_in.sin_port = rem->port; ++ else ++ rem_in.sin_port = inet_sk(meta_sk)->inet_dport; ++ loc_in.sin_addr = loc->addr; ++ rem_in.sin_addr = rem->addr; ++ ++ if (loc->if_idx) ++ sk->sk_bound_dev_if = loc->if_idx; ++ ++ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, ++ sizeof(struct sockaddr_in)); ++ if (ret < 0) { ++ net_err_ratelimited("%s: token %#x bind() to %pI4 index %d failed, error %d\n", ++ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, ++ &loc_in.sin_addr, loc->if_idx, ret); ++ goto error; ++ } ++ ++ mptcp_debug("%s: token %#x pi %d src_addr:%pI4:%d dst_addr:%pI4:%d ifidx: %d\n", ++ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, ++ tp->mptcp->path_index, &loc_in.sin_addr, ++ ntohs(loc_in.sin_port), &rem_in.sin_addr, ++ ntohs(rem_in.sin_port), loc->if_idx); ++ ++ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4) ++ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4(sk, rem->addr); ++ ++ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, ++ sizeof(struct sockaddr_in), O_NONBLOCK); ++ if (ret < 0 && ret != -EINPROGRESS) { ++ net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", ++ __func__, ret); ++ goto error; ++ } ++ ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); ++ ++ sk_set_socket(sk, meta_sk->sk_socket); ++ sk->sk_wq = meta_sk->sk_wq; ++ ++ if (subsk) ++ *subsk = sk; ++ ++ return 0; ++ ++error: ++ /* May happen if mptcp_add_sock fails first */ ++ if (!mptcp(tp)) { ++ tcp_close(sk, 0); ++ } else { ++ local_bh_disable(); ++ mptcp_sub_force_close(sk); ++ local_bh_enable(); ++ } ++ return ret; ++} ++EXPORT_SYMBOL(__mptcp_init4_subsockets); ++ ++const struct inet_connection_sock_af_ops mptcp_v4_specific = { ++ .queue_xmit = ip_queue_xmit, ++ .send_check = tcp_v4_send_check, ++ .rebuild_header = inet_sk_rebuild_header, ++ .sk_rx_dst_set = inet_sk_rx_dst_set, ++ .conn_request = mptcp_conn_request, ++ .syn_recv_sock = tcp_v4_syn_recv_sock, ++ .net_header_len = sizeof(struct iphdr), ++ .setsockopt = ip_setsockopt, ++ .getsockopt = ip_getsockopt, ++ .addr2sockaddr = inet_csk_addr2sockaddr, ++ .sockaddr_len = sizeof(struct sockaddr_in), ++#ifdef CONFIG_COMPAT ++ .compat_setsockopt = compat_ip_setsockopt, ++ .compat_getsockopt = compat_ip_getsockopt, ++#endif ++ .mtu_reduced = tcp_v4_mtu_reduced, ++}; ++ ++struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; ++struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; ++ ++/* General initialization of IPv4 for MPTCP */ ++int mptcp_pm_v4_init(void) ++{ ++ int ret = 0; ++ struct request_sock_ops *ops = &mptcp_request_sock_ops; ++ ++ mptcp_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; ++ mptcp_request_sock_ipv4_ops.init_req = mptcp_v4_init_req; ++#ifdef CONFIG_SYN_COOKIES ++ mptcp_request_sock_ipv4_ops.cookie_init_seq = mptcp_v4_cookie_init_seq; ++#endif ++ mptcp_join_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; ++ mptcp_join_request_sock_ipv4_ops.init_req = mptcp_v4_join_init_req; ++ ++ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP"); ++ if (ops->slab_name == NULL) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, ++ SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, ++ NULL); ++ ++ if (ops->slab == NULL) { ++ ret = -ENOMEM; ++ goto err_reqsk_create; ++ } ++ ++out: ++ return ret; ++ ++err_reqsk_create: ++ kfree(ops->slab_name); ++ ops->slab_name = NULL; ++ goto out; ++} ++ ++void mptcp_pm_v4_undo(void) ++{ ++ kmem_cache_destroy(mptcp_request_sock_ops.slab); ++ kfree(mptcp_request_sock_ops.slab_name); ++} +diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c +--- linux-5.4/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,475 @@ ++/* ++ * MPTCP implementation - IPv6-specific functions ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer: ++ * Jaakko Korkeaniemi ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, ++ __be16 sport, __be16 dport) ++{ ++ const struct { ++ struct in6_addr saddr; ++ struct in6_addr daddr; ++ u32 seed; ++ __be16 sport; ++ __be16 dport; ++ } __aligned(SIPHASH_ALIGNMENT) combined = { ++ .saddr = *(struct in6_addr *)saddr, ++ .daddr = *(struct in6_addr *)daddr, ++ .seed = mptcp_seed++, ++ .sport = sport, ++ .dport = dport ++ }; ++ ++ return siphash(&combined, offsetofend(typeof(combined), dport), ++ &mptcp_secret); ++} ++ ++u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, ++ __be16 sport, __be16 dport, u32 seed) ++{ ++ const struct { ++ struct in6_addr saddr; ++ struct in6_addr daddr; ++ u32 seed; ++ __be16 sport; ++ __be16 dport; ++ } __aligned(SIPHASH_ALIGNMENT) combined = { ++ .saddr = *(struct in6_addr *)saddr, ++ .daddr = *(struct in6_addr *)daddr, ++ .seed = seed, ++ .sport = sport, ++ .dport = dport ++ }; ++ ++ return siphash(&combined, offsetofend(typeof(combined), dport), ++ &mptcp_secret); ++} ++ ++static void mptcp_v6_reqsk_destructor(struct request_sock *req) ++{ ++ mptcp_reqsk_destructor(req); ++ ++ tcp_v6_reqsk_destructor(req); ++} ++ ++static int mptcp_v6_init_req(struct request_sock *req, const struct sock *sk, ++ struct sk_buff *skb, bool want_cookie) ++{ ++ tcp_request_sock_ipv6_ops.init_req(req, sk, skb, want_cookie); ++ ++ mptcp_rsk(req)->hash_entry.pprev = NULL; ++ mptcp_rsk(req)->is_sub = 0; ++ inet_rsk(req)->mptcp_rqsk = 1; ++ ++ /* In case of SYN-cookies, we wait for the isn to be generated - it is ++ * input to the key-generation. ++ */ ++ if (!want_cookie) ++ mptcp_reqsk_init(req, sk, skb, false); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SYN_COOKIES ++static u32 mptcp_v6_cookie_init_seq(struct request_sock *req, const struct sock *sk, ++ const struct sk_buff *skb, __u16 *mssp) ++{ ++ __u32 isn = cookie_v6_init_sequence(req, sk, skb, mssp); ++ ++ tcp_rsk(req)->snt_isn = isn; ++ ++ mptcp_reqsk_init(req, sk, skb, true); ++ ++ return isn; ++} ++#endif ++ ++/* May be called without holding the meta-level lock */ ++static int mptcp_v6_join_init_req(struct request_sock *req, const struct sock *meta_sk, ++ struct sk_buff *skb, bool want_cookie) ++{ ++ struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ union inet_addr addr; ++ int loc_id; ++ bool low_prio = false; ++ ++ /* We need to do this as early as possible. Because, if we fail later ++ * (e.g., get_local_id), then reqsk_free tries to remove the ++ * request-socket from the htb in mptcp_hash_request_remove as pprev ++ * may be different from NULL. ++ */ ++ mtreq->hash_entry.pprev = NULL; ++ ++ tcp_request_sock_ipv6_ops.init_req(req, meta_sk, skb, want_cookie); ++ ++ mtreq->mptcp_loc_nonce = mptcp_v6_get_nonce(ipv6_hdr(skb)->saddr.s6_addr32, ++ ipv6_hdr(skb)->daddr.s6_addr32, ++ tcp_hdr(skb)->source, ++ tcp_hdr(skb)->dest); ++ addr.in6 = inet_rsk(req)->ir_v6_loc_addr; ++ loc_id = mpcb->pm_ops->get_local_id(meta_sk, AF_INET6, &addr, &low_prio); ++ if (loc_id == -1) ++ return -1; ++ mtreq->loc_id = loc_id; ++ mtreq->low_prio = low_prio; ++ ++ mptcp_join_reqsk_init(mpcb, req, skb); ++ ++ return 0; ++} ++ ++/* Similar to tcp6_request_sock_ops */ ++struct request_sock_ops mptcp6_request_sock_ops __read_mostly = { ++ .family = AF_INET6, ++ .obj_size = sizeof(struct mptcp_request_sock), ++ .rtx_syn_ack = tcp_rtx_synack, ++ .send_ack = tcp_v6_reqsk_send_ack, ++ .destructor = mptcp_v6_reqsk_destructor, ++ .send_reset = tcp_v6_send_reset, ++ .syn_ack_timeout = tcp_syn_ack_timeout, ++}; ++ ++/* Similar to: tcp_v6_conn_request ++ * May be called without holding the meta-level lock ++ */ ++static int mptcp_v6_join_request(struct sock *meta_sk, struct sk_buff *skb) ++{ ++ return tcp_conn_request(&mptcp6_request_sock_ops, ++ &mptcp_join_request_sock_ipv6_ops, ++ meta_sk, skb); ++} ++ ++int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) ++{ ++ const struct tcphdr *th = tcp_hdr(skb); ++ const struct ipv6hdr *ip6h = ipv6_hdr(skb); ++ struct sock *child, *rsk = NULL, *sk; ++ int ret; ++ ++ sk = __inet6_lookup_established(sock_net(meta_sk), ++ &tcp_hashinfo, ++ &ip6h->saddr, th->source, ++ &ip6h->daddr, ntohs(th->dest), ++ tcp_v6_iif(skb), tcp_v6_sdif(skb)); ++ ++ if (!sk) ++ goto new_subflow; ++ ++ if (is_meta_sk(sk)) { ++ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); ++ sock_put(sk); ++ goto discard; ++ } ++ ++ if (sk->sk_state == TCP_TIME_WAIT) { ++ inet_twsk_put(inet_twsk(sk)); ++ goto discard; ++ } ++ ++ if (sk->sk_state == TCP_NEW_SYN_RECV) { ++ struct request_sock *req = inet_reqsk(sk); ++ bool req_stolen; ++ ++ if (!mptcp_can_new_subflow(meta_sk)) ++ goto reset_and_discard; ++ ++ local_bh_disable(); ++ child = tcp_check_req(meta_sk, skb, req, false, &req_stolen); ++ if (!child) { ++ reqsk_put(req); ++ local_bh_enable(); ++ goto discard; ++ } ++ ++ if (child != meta_sk) { ++ ret = mptcp_finish_handshake(child, skb); ++ if (ret) { ++ rsk = child; ++ local_bh_enable(); ++ goto reset_and_discard; ++ } ++ ++ local_bh_enable(); ++ return 0; ++ } ++ ++ /* tcp_check_req failed */ ++ reqsk_put(req); ++ ++ local_bh_enable(); ++ goto discard; ++ } ++ ++ ret = tcp_v6_do_rcv(sk, skb); ++ sock_put(sk); ++ ++ return ret; ++ ++new_subflow: ++ if (!mptcp_can_new_subflow(meta_sk)) ++ goto reset_and_discard; ++ ++ child = tcp_v6_cookie_check(meta_sk, skb); ++ if (!child) ++ goto discard; ++ ++ if (child != meta_sk) { ++ ret = mptcp_finish_handshake(child, skb); ++ if (ret) { ++ rsk = child; ++ goto reset_and_discard; ++ } ++ } ++ ++ if (tcp_hdr(skb)->syn) { ++ local_bh_disable(); ++ mptcp_v6_join_request(meta_sk, skb); ++ local_bh_enable(); ++ } ++ ++discard: ++ kfree_skb(skb); ++ return 0; ++ ++reset_and_discard: ++ tcp_v6_send_reset(rsk, skb); ++ goto discard; ++} ++ ++/* Create a new IPv6 subflow. ++ * ++ * We are in user-context and meta-sock-lock is hold. ++ */ ++int __mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, ++ __be16 sport, struct mptcp_rem6 *rem, ++ struct sock **subsk) ++{ ++ struct tcp_sock *tp; ++ struct sock *sk; ++ struct sockaddr_in6 loc_in, rem_in; ++ struct socket_alloc sock_full; ++ struct socket *sock = (struct socket *)&sock_full; ++ int ret; ++ ++ /** First, create and prepare the new socket */ ++ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); ++ sock->state = SS_UNCONNECTED; ++ sock->ops = NULL; ++ ++ ret = inet6_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); ++ if (unlikely(ret < 0)) { ++ net_err_ratelimited("%s inet6_create failed ret: %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ sk = sock->sk; ++ tp = tcp_sk(sk); ++ ++ /* All subsockets need the MPTCP-lock-class */ ++ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); ++ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); ++ ++ ret = mptcp_add_sock(meta_sk, sk, loc->loc6_id, rem->rem6_id, GFP_KERNEL); ++ if (ret) { ++ net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", ++ __func__, ret); ++ goto error; ++ } ++ ++ tp->mptcp->slave_sk = 1; ++ tp->mptcp->low_prio = loc->low_prio; ++ ++ /* Initializing the timer for an MPTCP subflow */ ++ timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); ++ ++ /** Then, connect the socket to the peer */ ++ loc_in.sin6_family = AF_INET6; ++ rem_in.sin6_family = AF_INET6; ++ loc_in.sin6_port = sport; ++ if (rem->port) ++ rem_in.sin6_port = rem->port; ++ else ++ rem_in.sin6_port = inet_sk(meta_sk)->inet_dport; ++ loc_in.sin6_addr = loc->addr; ++ rem_in.sin6_addr = rem->addr; ++ ++ if (loc->if_idx) ++ sk->sk_bound_dev_if = loc->if_idx; ++ ++ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, ++ sizeof(struct sockaddr_in6)); ++ if (ret < 0) { ++ net_err_ratelimited("%s: token %#x bind() to %pI6 index %d failed, error %d\n", ++ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, ++ &loc_in.sin6_addr, loc->if_idx, ret); ++ goto error; ++ } ++ ++ mptcp_debug("%s: token %#x pi %d src_addr:%pI6:%d dst_addr:%pI6:%d ifidx: %u\n", ++ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, ++ tp->mptcp->path_index, &loc_in.sin6_addr, ++ ntohs(loc_in.sin6_port), &rem_in.sin6_addr, ++ ntohs(rem_in.sin6_port), loc->if_idx); ++ ++ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6) ++ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6(sk, rem->addr); ++ ++ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, ++ sizeof(struct sockaddr_in6), O_NONBLOCK); ++ if (ret < 0 && ret != -EINPROGRESS) { ++ net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", ++ __func__, ret); ++ goto error; ++ } ++ ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); ++ ++ sk_set_socket(sk, meta_sk->sk_socket); ++ sk->sk_wq = meta_sk->sk_wq; ++ ++ if (subsk) ++ *subsk = sk; ++ ++ return 0; ++ ++error: ++ /* May happen if mptcp_add_sock fails first */ ++ if (!mptcp(tp)) { ++ tcp_close(sk, 0); ++ } else { ++ local_bh_disable(); ++ mptcp_sub_force_close(sk); ++ local_bh_enable(); ++ } ++ return ret; ++} ++EXPORT_SYMBOL(__mptcp_init6_subsockets); ++ ++const struct inet_connection_sock_af_ops mptcp_v6_specific = { ++ .queue_xmit = inet6_csk_xmit, ++ .send_check = tcp_v6_send_check, ++ .rebuild_header = inet6_sk_rebuild_header, ++ .sk_rx_dst_set = inet6_sk_rx_dst_set, ++ .conn_request = mptcp_conn_request, ++ .syn_recv_sock = tcp_v6_syn_recv_sock, ++ .net_header_len = sizeof(struct ipv6hdr), ++ .net_frag_header_len = sizeof(struct frag_hdr), ++ .setsockopt = ipv6_setsockopt, ++ .getsockopt = ipv6_getsockopt, ++ .addr2sockaddr = inet6_csk_addr2sockaddr, ++ .sockaddr_len = sizeof(struct sockaddr_in6), ++#ifdef CONFIG_COMPAT ++ .compat_setsockopt = compat_ipv6_setsockopt, ++ .compat_getsockopt = compat_ipv6_getsockopt, ++#endif ++ .mtu_reduced = tcp_v6_mtu_reduced, ++}; ++ ++const struct inet_connection_sock_af_ops mptcp_v6_mapped = { ++ .queue_xmit = ip_queue_xmit, ++ .send_check = tcp_v4_send_check, ++ .rebuild_header = inet_sk_rebuild_header, ++ .sk_rx_dst_set = inet_sk_rx_dst_set, ++ .conn_request = mptcp_conn_request, ++ .syn_recv_sock = tcp_v6_syn_recv_sock, ++ .net_header_len = sizeof(struct iphdr), ++ .setsockopt = ipv6_setsockopt, ++ .getsockopt = ipv6_getsockopt, ++ .addr2sockaddr = inet6_csk_addr2sockaddr, ++ .sockaddr_len = sizeof(struct sockaddr_in6), ++#ifdef CONFIG_COMPAT ++ .compat_setsockopt = compat_ipv6_setsockopt, ++ .compat_getsockopt = compat_ipv6_getsockopt, ++#endif ++ .mtu_reduced = tcp_v4_mtu_reduced, ++}; ++ ++struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; ++struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; ++ ++int mptcp_pm_v6_init(void) ++{ ++ int ret = 0; ++ struct request_sock_ops *ops = &mptcp6_request_sock_ops; ++ ++ mptcp_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; ++ mptcp_request_sock_ipv6_ops.init_req = mptcp_v6_init_req; ++#ifdef CONFIG_SYN_COOKIES ++ mptcp_request_sock_ipv6_ops.cookie_init_seq = mptcp_v6_cookie_init_seq; ++#endif ++ ++ mptcp_join_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; ++ mptcp_join_request_sock_ipv6_ops.init_req = mptcp_v6_join_init_req; ++ ++ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP6"); ++ if (ops->slab_name == NULL) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, ++ SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, ++ NULL); ++ ++ if (ops->slab == NULL) { ++ ret = -ENOMEM; ++ goto err_reqsk_create; ++ } ++ ++out: ++ return ret; ++ ++err_reqsk_create: ++ kfree(ops->slab_name); ++ ops->slab_name = NULL; ++ goto out; ++} ++ ++void mptcp_pm_v6_undo(void) ++{ ++ kmem_cache_destroy(mptcp6_request_sock_ops.slab); ++ kfree(mptcp6_request_sock_ops.slab_name); ++} +diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c +--- linux-5.4/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,174 @@ ++#include ++ ++#include ++#include ++ ++#if IS_ENABLED(CONFIG_IPV6) ++#include ++#endif ++ ++struct ndiffports_priv { ++ /* Worker struct for subflow establishment */ ++ struct work_struct subflow_work; ++ ++ struct mptcp_cb *mpcb; ++}; ++ ++static int num_subflows __read_mostly = 2; ++module_param(num_subflows, int, 0644); ++MODULE_PARM_DESC(num_subflows, "choose the number of subflows per MPTCP connection"); ++ ++/** ++ * Create all new subflows, by doing calls to mptcp_initX_subsockets ++ * ++ * This function uses a goto next_subflow, to allow releasing the lock between ++ * new subflows and giving other processes a chance to do some work on the ++ * socket and potentially finishing the communication. ++ **/ ++static void create_subflow_worker(struct work_struct *work) ++{ ++ const struct ndiffports_priv *pm_priv = container_of(work, ++ struct ndiffports_priv, ++ subflow_work); ++ struct mptcp_cb *mpcb = pm_priv->mpcb; ++ struct sock *meta_sk = mpcb->meta_sk; ++ int iter = 0; ++ ++next_subflow: ++ if (iter) { ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ ++ cond_resched(); ++ } ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ if (!mptcp(tcp_sk(meta_sk))) ++ goto exit; ++ ++ iter++; ++ ++ if (sock_flag(meta_sk, SOCK_DEAD)) ++ goto exit; ++ ++ if (mpcb->master_sk && ++ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) ++ goto exit; ++ ++ if (num_subflows > iter && num_subflows > mptcp_subflow_count(mpcb)) { ++ if (meta_sk->sk_family == AF_INET || ++ mptcp_v6_is_v4_mapped(meta_sk)) { ++ struct mptcp_loc4 loc; ++ struct mptcp_rem4 rem; ++ ++ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; ++ loc.loc4_id = 0; ++ loc.low_prio = 0; ++ if (mpcb->master_sk) ++ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; ++ else ++ loc.if_idx = 0; ++ ++ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; ++ rem.port = inet_sk(meta_sk)->inet_dport; ++ rem.rem4_id = 0; /* Default 0 */ ++ ++ mptcp_init4_subsockets(meta_sk, &loc, &rem); ++ } else { ++#if IS_ENABLED(CONFIG_IPV6) ++ struct mptcp_loc6 loc; ++ struct mptcp_rem6 rem; ++ ++ loc.addr = inet6_sk(meta_sk)->saddr; ++ loc.loc6_id = 0; ++ loc.low_prio = 0; ++ if (mpcb->master_sk) ++ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; ++ else ++ loc.if_idx = 0; ++ ++ rem.addr = meta_sk->sk_v6_daddr; ++ rem.port = inet_sk(meta_sk)->inet_dport; ++ rem.rem6_id = 0; /* Default 0 */ ++ ++ mptcp_init6_subsockets(meta_sk, &loc, &rem); ++#endif ++ } ++ goto next_subflow; ++ } ++ ++exit: ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ mptcp_mpcb_put(mpcb); ++ sock_put(meta_sk); ++} ++ ++static void ndiffports_new_session(const struct sock *meta_sk) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct ndiffports_priv *fmp = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; ++ ++ /* Initialize workqueue-struct */ ++ INIT_WORK(&fmp->subflow_work, create_subflow_worker); ++ fmp->mpcb = mpcb; ++} ++ ++static void ndiffports_create_subflows(struct sock *meta_sk) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct ndiffports_priv *pm_priv = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; ++ ++ if (mptcp_in_infinite_mapping_weak(mpcb) || ++ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) ++ return; ++ ++ if (!work_pending(&pm_priv->subflow_work)) { ++ sock_hold(meta_sk); ++ refcount_inc(&mpcb->mpcb_refcnt); ++ queue_work(mptcp_wq, &pm_priv->subflow_work); ++ } ++} ++ ++static int ndiffports_get_local_id(const struct sock *meta_sk, ++ sa_family_t family, union inet_addr *addr, ++ bool *low_prio) ++{ ++ return 0; ++} ++ ++static struct mptcp_pm_ops ndiffports __read_mostly = { ++ .new_session = ndiffports_new_session, ++ .fully_established = ndiffports_create_subflows, ++ .get_local_id = ndiffports_get_local_id, ++ .name = "ndiffports", ++ .owner = THIS_MODULE, ++}; ++ ++/* General initialization of MPTCP_PM */ ++static int __init ndiffports_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct ndiffports_priv) > MPTCP_PM_SIZE); ++ ++ if (mptcp_register_path_manager(&ndiffports)) ++ goto exit; ++ ++ return 0; ++ ++exit: ++ return -1; ++} ++ ++static void ndiffports_unregister(void) ++{ ++ mptcp_unregister_path_manager(&ndiffports); ++} ++ ++module_init(ndiffports_register); ++module_exit(ndiffports_unregister); ++ ++MODULE_AUTHOR("Christoph Paasch"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("NDIFF-PORTS MPTCP"); ++MODULE_VERSION("0.88"); +diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c +--- linux-5.4/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,1271 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* MPTCP implementation - Netlink Path Manager ++ * ++ * Analysis, Design and Implementation: ++ * - Gregory Detal ++ * - Sébastien Barré ++ * - Matthieu Baerts ++ * - Pau Espin Pedrol ++ * - Detlev Casanova ++ * - David Verbeiren ++ * - Frank Vanbever ++ * - Antoine Maes ++ * - Tim Froidcoeur ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++#include ++#include ++#include ++#include ++#include ++#if IS_ENABLED(CONFIG_IPV6) ++#include ++#endif ++ ++#define MPTCP_MAX_ADDR 8 ++ ++struct mptcp_nl_priv { ++ /* Unfortunately we need to store this to generate MP_JOINs in case ++ * of the peer generating a subflow (see get_local_id). ++ */ ++ u8 loc4_bits; ++ u8 announced4; ++ struct mptcp_loc4 locaddr4[MPTCP_MAX_ADDR]; ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ u8 loc6_bits; ++ u8 announced6; ++ struct mptcp_loc6 locaddr6[MPTCP_MAX_ADDR]; ++#endif ++ ++ u16 remove_addrs; ++ ++ bool is_closed; ++}; ++ ++static struct genl_family mptcp_genl_family; ++ ++#define MPTCP_GENL_EV_GRP_OFFSET 0 ++#define MPTCP_GENL_CMD_GRP_OFFSET 1 ++ ++static const struct genl_multicast_group mptcp_mcgrps[] = { ++ [MPTCP_GENL_EV_GRP_OFFSET] = { .name = MPTCP_GENL_EV_GRP_NAME, }, ++ [MPTCP_GENL_CMD_GRP_OFFSET] = { .name = MPTCP_GENL_CMD_GRP_NAME, }, ++}; ++ ++static const struct nla_policy mptcp_nl_genl_policy[MPTCP_ATTR_MAX + 1] = { ++ [MPTCP_ATTR_TOKEN] = { .type = NLA_U32, }, ++ [MPTCP_ATTR_FAMILY] = { .type = NLA_U16, }, ++ [MPTCP_ATTR_LOC_ID] = { .type = NLA_U8, }, ++ [MPTCP_ATTR_REM_ID] = { .type = NLA_U8, }, ++ [MPTCP_ATTR_SADDR4] = { .type = NLA_U32, }, ++ [MPTCP_ATTR_SADDR6] = { .type = NLA_BINARY, ++ .len = sizeof(struct in6_addr), }, ++ [MPTCP_ATTR_DADDR4] = { .type = NLA_U32, }, ++ [MPTCP_ATTR_DADDR6] = { .type = NLA_BINARY, ++ .len = sizeof(struct in6_addr), }, ++ [MPTCP_ATTR_SPORT] = { .type = NLA_U16, }, ++ [MPTCP_ATTR_DPORT] = { .type = NLA_U16, }, ++ [MPTCP_ATTR_BACKUP] = { .type = NLA_U8, }, ++ [MPTCP_ATTR_TIMEOUT] = { .type = NLA_U32, }, ++ [MPTCP_ATTR_IF_IDX] = { .type = NLA_S32, }, ++}; ++ ++/* Defines the userspace PM filter on events. Set events are ignored. */ ++static u16 mptcp_nl_event_filter; ++ ++static inline struct mptcp_nl_priv * ++mptcp_nl_priv(const struct sock *meta_sk) ++{ ++ return (struct mptcp_nl_priv *)&tcp_sk(meta_sk)->mpcb->mptcp_pm[0]; ++} ++ ++static inline bool ++mptcp_nl_must_notify(u16 event, const struct sock *meta_sk) ++{ ++ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); ++ ++ /* close_session() can be called before other events because it is ++ * also called when doing a fallback to TCP. We don't want to send ++ * events to the user-space after having sent the CLOSED event. ++ */ ++ if (priv->is_closed) ++ return false; ++ ++ if (event == MPTCPF_EVENT_CLOSED) ++ priv->is_closed = true; ++ ++ if (mptcp_nl_event_filter & event) ++ return false; ++ ++ if (!genl_has_listeners(&mptcp_genl_family, sock_net(meta_sk), 0)) ++ return false; ++ ++ return true; ++} ++ ++/* Find the first free index in the bitfield starting from 0 */ ++static int ++mptcp_nl_find_free_index(u8 bitfield) ++{ ++ int i; ++ ++ /* There are anyways no free bits... */ ++ if (bitfield == 0xff) ++ return -1; ++ ++ i = ffs(~bitfield) - 1; ++ if (i < 0) ++ return -1; ++ ++ return i; ++} ++ ++static inline int ++mptcp_nl_put_subsk(struct sk_buff *msg, struct sock *sk) ++{ ++ struct inet_sock *isk = inet_sk(sk); ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ u8 backup; ++ u8 sk_err; ++ ++ if (nla_put_u16(msg, MPTCP_ATTR_FAMILY, sk->sk_family)) ++ goto nla_put_failure; ++ ++ if (nla_put_u8(msg, MPTCP_ATTR_LOC_ID, tcp_sk(sk)->mptcp->loc_id)) ++ goto nla_put_failure; ++ ++ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, tcp_sk(sk)->mptcp->rem_id)) ++ goto nla_put_failure; ++ ++ switch (sk->sk_family) { ++ case AF_INET: ++ if (nla_put_u32(msg, MPTCP_ATTR_SADDR4, isk->inet_saddr)) ++ goto nla_put_failure; ++ ++ if (nla_put_u32(msg, MPTCP_ATTR_DADDR4, isk->inet_daddr)) ++ goto nla_put_failure; ++ break; ++#if IS_ENABLED(CONFIG_IPV6) ++ case AF_INET6: { ++ struct ipv6_pinfo *np = inet6_sk(sk); ++ ++ if (nla_put(msg, MPTCP_ATTR_SADDR6, sizeof(np->saddr), ++ &np->saddr)) ++ goto nla_put_failure; ++ ++ if (nla_put(msg, MPTCP_ATTR_DADDR6, sizeof(sk->sk_v6_daddr), ++ &sk->sk_v6_daddr)) ++ goto nla_put_failure; ++ break; ++ } ++#endif ++ default: ++ goto nla_put_failure; ++ } ++ ++ if (nla_put_u16(msg, MPTCP_ATTR_SPORT, ntohs(isk->inet_sport))) ++ goto nla_put_failure; ++ ++ if (nla_put_u16(msg, MPTCP_ATTR_DPORT, ntohs(isk->inet_dport))) ++ goto nla_put_failure; ++ ++ backup = !!(tcp_sk(sk)->mptcp->rcv_low_prio || ++ tcp_sk(sk)->mptcp->low_prio); ++ ++ if (nla_put_u8(msg, MPTCP_ATTR_BACKUP, backup)) ++ goto nla_put_failure; ++ ++ if (nla_put_s32(msg, MPTCP_ATTR_IF_IDX, sk->sk_bound_dev_if)) ++ goto nla_put_failure; ++ ++ sk_err = sk->sk_err ? : tcp_sk(sk)->mptcp->sk_err; ++ if (unlikely(sk_err != 0) && meta_sk->sk_state == TCP_ESTABLISHED && ++ nla_put_u8(msg, MPTCP_ATTR_ERROR, sk_err)) ++ goto nla_put_failure; ++ ++ return 0; ++ ++nla_put_failure: ++ return -1; ++} ++ ++static inline struct sk_buff * ++mptcp_nl_mcast_prepare(struct mptcp_cb *mpcb, struct sock *sk, int cmd, ++ void **hdr) ++{ ++ struct sk_buff *msg; ++ ++ /* possible optimisation: use the needed size */ ++ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); ++ if (!msg) ++ return NULL; ++ ++ *hdr = genlmsg_put(msg, 0, 0, &mptcp_genl_family, 0, cmd); ++ if (!*hdr) ++ goto free_msg; ++ ++ if (nla_put_u32(msg, MPTCP_ATTR_TOKEN, mpcb->mptcp_loc_token)) ++ goto nla_put_failure; ++ ++ if (sk && mptcp_nl_put_subsk(msg, sk)) ++ goto nla_put_failure; ++ ++ return msg; ++ ++nla_put_failure: ++ genlmsg_cancel(msg, *hdr); ++free_msg: ++ nlmsg_free(msg); ++ return NULL; ++} ++ ++static inline int ++mptcp_nl_mcast_send(struct mptcp_cb *mpcb, struct sk_buff *msg, void *hdr) ++{ ++ int ret; ++ struct sock *meta_sk = mpcb->meta_sk; ++ ++ genlmsg_end(msg, hdr); ++ ++ ret = genlmsg_multicast_netns(&mptcp_genl_family, sock_net(meta_sk), ++ msg, 0, MPTCP_GENL_EV_GRP_OFFSET, ++ GFP_ATOMIC); ++ if (ret && ret != -ESRCH) ++ pr_err("%s: genlmsg_multicast failed with %d\n", __func__, ret); ++ return ret; ++} ++ ++static inline void ++mptcp_nl_mcast(struct mptcp_cb *mpcb, struct sock *sk, int cmd) ++{ ++ void *hdr; ++ struct sk_buff *msg; ++ ++ msg = mptcp_nl_mcast_prepare(mpcb, sk, cmd, &hdr); ++ if (msg) ++ mptcp_nl_mcast_send(mpcb, msg, hdr); ++ else ++ pr_warn("%s: unable to prepare multicast message\n", __func__); ++} ++ ++static inline void ++mptcp_nl_mcast_fail(struct sk_buff *msg, void *hdr) ++{ ++ genlmsg_cancel(msg, hdr); ++ nlmsg_free(msg); ++} ++ ++static void ++mptcp_nl_new(const struct sock *meta_sk, bool established) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ ++ mptcp_nl_mcast(mpcb, mpcb->master_sk, ++ established ? MPTCP_EVENT_ESTABLISHED ++ : MPTCP_EVENT_CREATED); ++} ++ ++static void ++mptcp_nl_pm_new_session(const struct sock *meta_sk) ++{ ++ if (!mptcp_nl_must_notify(MPTCPF_EVENT_CREATED, meta_sk)) ++ return; ++ ++ mptcp_nl_new(meta_sk, false); ++} ++ ++static inline int ++mptcp_nl_loc_id_to_index_lookup(struct sock *meta_sk, sa_family_t family, ++ u8 addr_id) ++{ ++ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); ++ int i; ++ ++ switch (family) { ++ case AF_INET: ++ mptcp_for_each_bit_set(priv->loc4_bits, i) { ++ if (priv->locaddr4[i].loc4_id == addr_id) ++ return i; ++ } ++ break; ++#if IS_ENABLED(CONFIG_IPV6) ++ case AF_INET6: ++ mptcp_for_each_bit_set(priv->loc6_bits, i) { ++ if (priv->locaddr6[i].loc6_id == addr_id) ++ return i; ++ } ++ break; ++#endif ++ } ++ return -1; ++} ++ ++static inline void ++mptcp_nl_sk_setup_locaddr(struct sock *meta_sk, struct sock *sk) ++{ ++ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); ++ bool backup = !!(tcp_sk(sk)->mptcp->rcv_low_prio || ++ tcp_sk(sk)->mptcp->low_prio); ++ sa_family_t family = mptcp_v6_is_v4_mapped(sk) ? AF_INET ++ : sk->sk_family; ++ u8 addr_id = tcp_sk(sk)->mptcp->loc_id; ++ int idx = mptcp_nl_loc_id_to_index_lookup(meta_sk, family, ++ addr_id); ++ ++ /* Same as in mptcp_fullmesh.c: exception for transparent sockets */ ++ int if_idx = inet_sk(sk)->transparent ? inet_sk(sk)->rx_dst_ifindex : ++ sk->sk_bound_dev_if; ++ ++ switch (family) { ++ case AF_INET: { ++ struct inet_sock *isk = inet_sk(sk); ++ ++ if (idx == -1) ++ idx = mptcp_nl_find_free_index(priv->loc4_bits); ++ if (idx == -1) { ++ pr_warn("No free index for sk loc_id v4\n"); ++ return; ++ } ++ priv->locaddr4[idx].addr.s_addr = isk->inet_saddr; ++ priv->locaddr4[idx].loc4_id = addr_id; ++ priv->locaddr4[idx].low_prio = backup; ++ priv->locaddr4[idx].if_idx = if_idx; ++ priv->loc4_bits |= 1 << idx; ++ priv->announced4 |= 1 << idx; ++ break; ++ } ++#if IS_ENABLED(CONFIG_IPV6) ++ case AF_INET6: { ++ struct ipv6_pinfo *np = inet6_sk(sk); ++ ++ if (idx == -1) ++ idx = mptcp_nl_find_free_index(priv->loc6_bits); ++ if (idx == -1) { ++ pr_warn("No free index for sk loc_id v6\n"); ++ return; ++ } ++ priv->locaddr6[idx].addr = np->saddr; ++ priv->locaddr6[idx].loc6_id = addr_id; ++ priv->locaddr6[idx].low_prio = backup; ++ priv->locaddr6[idx].if_idx = if_idx; ++ priv->loc6_bits |= 1 << idx; ++ priv->announced6 |= 1 << idx; ++ break; ++ } ++#endif ++ } ++} ++ ++static void ++mptcp_nl_pm_fully_established(struct sock *meta_sk) ++{ ++ mptcp_nl_sk_setup_locaddr(meta_sk, tcp_sk(meta_sk)->mpcb->master_sk); ++ ++ if (!mptcp_nl_must_notify(MPTCPF_EVENT_ESTABLISHED, meta_sk)) ++ return; ++ ++ mptcp_nl_new(meta_sk, true); ++} ++ ++static void ++mptcp_nl_pm_close_session(struct sock *meta_sk) ++{ ++ if (!mptcp_nl_must_notify(MPTCPF_EVENT_CLOSED, meta_sk)) ++ return; ++ ++ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, NULL, MPTCP_EVENT_CLOSED); ++} ++ ++static void ++mptcp_nl_pm_established_subflow(struct sock *sk) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ mptcp_nl_sk_setup_locaddr(meta_sk, sk); ++ ++ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_ESTABLISHED, meta_sk)) ++ return; ++ ++ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_ESTABLISHED); ++} ++ ++static void ++mptcp_nl_pm_delete_subflow(struct sock *sk) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_CLOSED, meta_sk)) ++ return; ++ ++ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_CLOSED); ++} ++ ++static void ++mptcp_nl_pm_add_raddr(struct mptcp_cb *mpcb, const union inet_addr *addr, ++ sa_family_t family, __be16 port, u8 id) ++{ ++ struct sk_buff *msg; ++ void *hdr; ++ ++ if (!mptcp_nl_must_notify(MPTCPF_EVENT_ANNOUNCED, mpcb->meta_sk)) ++ return; ++ ++ msg = mptcp_nl_mcast_prepare(mpcb, NULL, MPTCP_EVENT_ANNOUNCED, &hdr); ++ if (!msg) ++ return; ++ ++ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, id)) ++ goto nla_put_failure; ++ ++ if (nla_put_u16(msg, MPTCP_ATTR_FAMILY, family)) ++ goto nla_put_failure; ++ ++ switch (family) { ++ case AF_INET: ++ if (nla_put_u32(msg, MPTCP_ATTR_DADDR4, addr->ip)) ++ goto nla_put_failure; ++ break; ++#if IS_ENABLED(CONFIG_IPV6) ++ case AF_INET6: ++ if (nla_put(msg, MPTCP_ATTR_DADDR6, sizeof(addr->ip6), ++ &addr->ip6)) ++ goto nla_put_failure; ++ break; ++#endif ++ default: ++ goto nla_put_failure; ++ } ++ ++ if (nla_put_u16(msg, MPTCP_ATTR_DPORT, ntohs(port))) ++ goto nla_put_failure; ++ ++ mptcp_nl_mcast_send(mpcb, msg, hdr); ++ ++ return; ++ ++nla_put_failure: ++ mptcp_nl_mcast_fail(msg, hdr); ++} ++ ++static void ++mptcp_nl_pm_rem_raddr(struct mptcp_cb *mpcb, u8 id) ++{ ++ struct sk_buff *msg; ++ void *hdr; ++ ++ if (!mptcp_nl_must_notify(MPTCPF_EVENT_REMOVED, mpcb->meta_sk)) ++ return; ++ ++ msg = mptcp_nl_mcast_prepare(mpcb, NULL, MPTCP_EVENT_REMOVED, &hdr); ++ ++ if (!msg) ++ return; ++ ++ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, id)) ++ goto nla_put_failure; ++ ++ mptcp_nl_mcast_send(mpcb, msg, hdr); ++ ++ return; ++ ++nla_put_failure: ++ mptcp_nl_mcast_fail(msg, hdr); ++} ++ ++static int ++mptcp_nl_pm_get_local_id(const struct sock *meta_sk, sa_family_t family, ++ union inet_addr *addr, bool *low_prio) ++{ ++ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); ++ int i, id = 0; ++ ++ switch (family) { ++ case AF_INET: ++ mptcp_for_each_bit_set(priv->loc4_bits, i) { ++ if (addr->in.s_addr == priv->locaddr4[i].addr.s_addr) { ++ id = priv->locaddr4[i].loc4_id; ++ *low_prio = priv->locaddr4[i].low_prio; ++ goto out; ++ } ++ } ++ break; ++#if IS_ENABLED(CONFIG_IPV6) ++ case AF_INET6: ++ mptcp_for_each_bit_set(priv->loc6_bits, i) { ++ if (ipv6_addr_equal(&addr->in6, ++ &priv->locaddr6[i].addr)) { ++ id = priv->locaddr6[i].loc6_id; ++ *low_prio = priv->locaddr6[i].low_prio; ++ goto out; ++ } ++ } ++ break; ++#endif ++ } ++ return -1; ++ ++out: ++ return id; ++} ++ ++static void ++mptcp_nl_pm_addr_signal(struct sock *sk, unsigned *size, ++ struct tcp_out_options *opts, struct sk_buff *skb) ++{ ++ struct mptcp_nl_priv *priv = mptcp_nl_priv(sk); ++ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; ++ u8 unannounced; ++ int remove_addr_len; ++ ++ unannounced = (~priv->announced4) & priv->loc4_bits; ++ if (unannounced && ++ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN) { ++ int i = mptcp_nl_find_free_index(~unannounced); ++ ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_ADD_ADDR; ++ opts->add_addr4.addr_id = priv->locaddr4[i].loc4_id; ++ opts->add_addr4.addr = priv->locaddr4[i].addr; ++ opts->add_addr_v4 = 1; ++ ++ if (skb) ++ priv->announced4 |= (1 << i); ++ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN; ++ } ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ unannounced = (~priv->announced6) & priv->loc6_bits; ++ if (unannounced && ++ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN) { ++ int i = mptcp_nl_find_free_index(~unannounced); ++ ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_ADD_ADDR; ++ opts->add_addr6.addr_id = priv->locaddr6[i].loc6_id; ++ opts->add_addr6.addr = priv->locaddr6[i].addr; ++ opts->add_addr_v6 = 1; ++ ++ if (skb) ++ priv->announced6 |= (1 << i); ++ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN; ++ } ++#endif ++ ++ if (likely(!priv->remove_addrs)) ++ goto exit; ++ ++ remove_addr_len = mptcp_sub_len_remove_addr_align(priv->remove_addrs); ++ if (MAX_TCP_OPTION_SPACE - *size < remove_addr_len) ++ goto exit; ++ ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_REMOVE_ADDR; ++ opts->remove_addrs = priv->remove_addrs; ++ ++ if (skb) ++ priv->remove_addrs = 0; ++ *size += remove_addr_len; ++ ++exit: ++ mpcb->addr_signal = !!((~priv->announced4) & priv->loc4_bits || ++#if IS_ENABLED(CONFIG_IPV6) ++ (~priv->announced6) & priv->loc6_bits || ++#endif ++ priv->remove_addrs); ++} ++ ++static void ++mptcp_nl_pm_prio_changed(struct sock *sk, int low_prio) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_PRIORITY, meta_sk)) ++ return; ++ ++ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_PRIORITY); ++} ++ ++static int ++mptcp_nl_genl_announce(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct sock *meta_sk, *subsk; ++ struct mptcp_cb *mpcb; ++ struct mptcp_nl_priv *priv; ++ u32 token; ++ u8 addr_id, backup = 0; ++ u16 family; ++ int i, ret = 0; ++ union inet_addr saddr; ++ int if_idx = 0; ++ bool useless; /* unused out parameter "low_prio" */ ++ ++ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_FAMILY] || ++ !info->attrs[MPTCP_ATTR_LOC_ID]) ++ return -EINVAL; ++ ++ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); ++ meta_sk = mptcp_hash_find(genl_info_net(info), token); ++ if (!meta_sk) ++ return -EINVAL; ++ ++ mpcb = tcp_sk(meta_sk)->mpcb; ++ priv = mptcp_nl_priv(meta_sk); ++ family = nla_get_u16(info->attrs[MPTCP_ATTR_FAMILY]); ++ addr_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); ++ ++ if (info->attrs[MPTCP_ATTR_BACKUP]) ++ backup = nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]); ++ ++ if (info->attrs[MPTCP_ATTR_IF_IDX]) ++ if_idx = nla_get_s32(info->attrs[MPTCP_ATTR_IF_IDX]); ++ ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ switch (family) { ++ case AF_INET: ++ if (!info->attrs[MPTCP_ATTR_SADDR4]) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ saddr.in.s_addr = nla_get_u32(info->attrs[MPTCP_ATTR_SADDR4]); ++ i = mptcp_nl_pm_get_local_id(meta_sk, family, ++ &saddr, &useless); ++ if (i < 0) { ++ i = mptcp_nl_find_free_index(priv->loc4_bits); ++ if (i < 0) { ++ ret = -ENOBUFS; ++ goto exit; ++ } ++ } else if (i != addr_id) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ priv->locaddr4[i].addr.s_addr = saddr.in.s_addr; ++ priv->locaddr4[i].loc4_id = addr_id; ++ priv->locaddr4[i].low_prio = !!backup; ++ priv->locaddr4[i].if_idx = if_idx; ++ priv->loc4_bits |= 1 << i; ++ priv->announced4 &= ~(1 << i); ++ break; ++#if IS_ENABLED(CONFIG_IPV6) ++ case AF_INET6: ++ if (!info->attrs[MPTCP_ATTR_SADDR6]) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ saddr.in6 = *(struct in6_addr *) ++ nla_data(info->attrs[MPTCP_ATTR_SADDR6]); ++ i = mptcp_nl_pm_get_local_id(meta_sk, family, &saddr, &useless); ++ if (i < 0) { ++ i = mptcp_nl_find_free_index(priv->loc6_bits); ++ if (i < 0) { ++ ret = -ENOBUFS; ++ goto exit; ++ } ++ } else if (i != addr_id) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ priv->locaddr6[i].addr = saddr.in6; ++ priv->locaddr6[i].loc6_id = addr_id; ++ priv->locaddr6[i].low_prio = !!backup; ++ priv->locaddr6[i].if_idx = if_idx; ++ priv->loc6_bits |= 1 << i; ++ priv->announced6 &= ~(1 << i); ++ break; ++#endif ++ default: ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ mpcb->addr_signal = 1; ++ ++ rcu_read_lock_bh(); ++ subsk = mptcp_select_ack_sock(meta_sk); ++ if (subsk) ++ tcp_send_ack(subsk); ++ rcu_read_unlock_bh(); ++ ++exit: ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ sock_put(meta_sk); ++ return ret; ++} ++ ++static int ++mptcp_nl_genl_remove(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct sock *meta_sk, *subsk; ++ struct mptcp_cb *mpcb; ++ struct mptcp_nl_priv *priv; ++ u32 token; ++ u8 addr_id; ++ int i; ++ int retcode; ++ bool found = false; ++ ++ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_LOC_ID]) ++ return -EINVAL; ++ ++ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); ++ meta_sk = mptcp_hash_find(genl_info_net(info), token); ++ if (!meta_sk) ++ return -EINVAL; ++ ++ mpcb = tcp_sk(meta_sk)->mpcb; ++ priv = mptcp_nl_priv(meta_sk); ++ addr_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); ++ ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ mptcp_for_each_bit_set(priv->loc4_bits, i) { ++ if (priv->locaddr4[i].loc4_id == addr_id) { ++ priv->loc4_bits &= ~(1 << i); ++ found = true; ++ break; ++ } ++ } ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ if (!found) { ++ mptcp_for_each_bit_set(priv->loc6_bits, i) { ++ if (priv->locaddr6[i].loc6_id == addr_id) { ++ priv->loc6_bits &= ~(1 << i); ++ found = true; ++ break; ++ } ++ } ++ } ++#endif ++ ++ if (found) { ++ priv->remove_addrs |= 1 << addr_id; ++ mpcb->addr_signal = 1; ++ ++ rcu_read_lock_bh(); ++ subsk = mptcp_select_ack_sock(meta_sk); ++ if (subsk) ++ tcp_send_ack(subsk); ++ rcu_read_unlock_bh(); ++ retcode = 0; ++ } else { ++ retcode = -EINVAL; ++ } ++ ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ sock_put(meta_sk); ++ return retcode; ++} ++ ++static int ++mptcp_nl_genl_create(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct sock *meta_sk, *subsk = NULL; ++ struct mptcp_cb *mpcb; ++ struct mptcp_nl_priv *priv; ++ u32 token; ++ u16 family, sport; ++ u8 loc_id, rem_id, backup = 0; ++ int i, ret = 0; ++ int if_idx; ++ ++ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_FAMILY] || ++ !info->attrs[MPTCP_ATTR_LOC_ID] || !info->attrs[MPTCP_ATTR_REM_ID]) ++ return -EINVAL; ++ ++ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); ++ meta_sk = mptcp_hash_find(genl_info_net(info), token); ++ if (!meta_sk) ++ /* We use a more specific value than EINVAL here so that ++ * userspace can handle this specific case easily. This is ++ * useful to check the case in which userspace tries to create a ++ * subflow for a connection which was already destroyed recently ++ * in kernelspace, but userspace didn't have time to realize ++ * about it because there is a gap of time between kernel ++ * destroying the connection and userspace receiving the event ++ * through Netlink. It can easily happen for short life-time ++ * conns. ++ */ ++ return -EBADR; ++ ++ mpcb = tcp_sk(meta_sk)->mpcb; ++ ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ if (sock_flag(meta_sk, SOCK_DEAD)) { ++ /* Same as for the EBADR case. In this case, though, we know for ++ * sure the conn owner of the subflow existed at some point (no ++ * invalid token possibility) ++ */ ++ ret = -EOWNERDEAD; ++ goto unlock; ++ } ++ ++ if (!mptcp_can_new_subflow(meta_sk)) { ++ /* Same as for the EBADR and EOWNERDEAD case but here, the MPTCP ++ * session has just been stopped, it is no longer possible to ++ * create new subflows. ++ */ ++ ret = -ENOTCONN; ++ goto unlock; ++ } ++ ++ if (mpcb->master_sk && ++ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) { ++ /* First condition is not only in there for safely purposes, it ++ * can also be triggered in the same scenario as in EBADR and ++ * EOWNERDEAD ++ */ ++ ret = -EAGAIN; ++ goto unlock; ++ } ++ ++ priv = mptcp_nl_priv(meta_sk); ++ ++ family = nla_get_u16(info->attrs[MPTCP_ATTR_FAMILY]); ++ loc_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); ++ rem_id = nla_get_u8(info->attrs[MPTCP_ATTR_REM_ID]); ++ ++ sport = info->attrs[MPTCP_ATTR_SPORT] ++ ? htons(nla_get_u16(info->attrs[MPTCP_ATTR_SPORT])) : 0; ++ backup = info->attrs[MPTCP_ATTR_BACKUP] ++ ? nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]) : 0; ++ if_idx = info->attrs[MPTCP_ATTR_IF_IDX] ++ ? nla_get_s32(info->attrs[MPTCP_ATTR_IF_IDX]) : 0; ++ ++ switch (family) { ++ case AF_INET: { ++ struct mptcp_rem4 rem = { ++ .rem4_id = rem_id, ++ }; ++ struct mptcp_loc4 loc = { ++ .loc4_id = loc_id, ++ }; ++ ++ if (!info->attrs[MPTCP_ATTR_DADDR4] || ++ !info->attrs[MPTCP_ATTR_DPORT]) { ++ goto create_failed; ++ } else { ++ rem.addr.s_addr = ++ nla_get_u32(info->attrs[MPTCP_ATTR_DADDR4]); ++ rem.port = ++ ntohs(nla_get_u16(info->attrs[MPTCP_ATTR_DPORT])); ++ } ++ ++ if (!info->attrs[MPTCP_ATTR_SADDR4]) { ++ bool found = false; ++ ++ mptcp_for_each_bit_set(priv->loc4_bits, i) { ++ if (priv->locaddr4[i].loc4_id == loc_id) { ++ loc.addr = priv->locaddr4[i].addr; ++ loc.low_prio = ++ priv->locaddr4[i].low_prio; ++ loc.if_idx = ++ priv->locaddr4[i].if_idx; ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ goto create_failed; ++ } else { ++ loc.addr.s_addr = ++ nla_get_u32(info->attrs[MPTCP_ATTR_SADDR4]); ++ loc.low_prio = backup; ++ loc.if_idx = if_idx; ++ } ++ ++ ret = __mptcp_init4_subsockets(meta_sk, &loc, sport, &rem, ++ &subsk); ++ if (ret < 0) ++ goto unlock; ++ break; ++ } ++#if IS_ENABLED(CONFIG_IPV6) ++ case AF_INET6: { ++ struct mptcp_rem6 rem = { ++ .rem6_id = rem_id, ++ }; ++ struct mptcp_loc6 loc = { ++ .loc6_id = loc_id, ++ }; ++ ++ if (!info->attrs[MPTCP_ATTR_DADDR6] || ++ !info->attrs[MPTCP_ATTR_DPORT]) { ++ goto create_failed; ++ } else { ++ rem.addr = *(struct in6_addr *) ++ nla_data(info->attrs[MPTCP_ATTR_DADDR6]); ++ rem.port = ++ ntohs(nla_get_u16(info->attrs[MPTCP_ATTR_DPORT])); ++ } ++ ++ if (!info->attrs[MPTCP_ATTR_SADDR6]) { ++ bool found = false; ++ ++ mptcp_for_each_bit_set(priv->loc6_bits, i) { ++ if (priv->locaddr6[i].loc6_id == loc_id) { ++ loc.addr = priv->locaddr6[i].addr; ++ loc.low_prio = ++ priv->locaddr6[i].low_prio; ++ loc.if_idx = ++ priv->locaddr6[i].if_idx; ++ ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ goto create_failed; ++ } else { ++ loc.addr = *(struct in6_addr *) ++ nla_data(info->attrs[MPTCP_ATTR_SADDR6]); ++ loc.low_prio = backup; ++ loc.if_idx = if_idx; ++ } ++ ++ ret = __mptcp_init6_subsockets(meta_sk, &loc, sport, &rem, ++ &subsk); ++ if (ret < 0) ++ goto unlock; ++ break; ++ } ++#endif ++ default: ++ goto create_failed; ++ } ++ ++unlock: ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ sock_put(meta_sk); ++ return ret; ++ ++create_failed: ++ ret = -EINVAL; ++ goto unlock; ++} ++ ++static struct sock * ++mptcp_nl_subsk_lookup(struct mptcp_cb *mpcb, struct nlattr **attrs) ++{ ++ struct sock *sk; ++ struct mptcp_tcp_sock *mptcp; ++ struct hlist_node *tmp; ++ u16 family; ++ __be16 sport, dport; ++ ++ if (!attrs[MPTCP_ATTR_FAMILY] || !attrs[MPTCP_ATTR_SPORT] || ++ !attrs[MPTCP_ATTR_DPORT]) ++ goto exit; ++ ++ family = nla_get_u16(attrs[MPTCP_ATTR_FAMILY]); ++ sport = htons(nla_get_u16(attrs[MPTCP_ATTR_SPORT])); ++ dport = htons(nla_get_u16(attrs[MPTCP_ATTR_DPORT])); ++ ++ switch (family) { ++ case AF_INET: { ++ __be32 saddr, daddr; ++ ++ if (!attrs[MPTCP_ATTR_SADDR4] || !attrs[MPTCP_ATTR_DADDR4]) ++ break; ++ ++ saddr = nla_get_u32(attrs[MPTCP_ATTR_SADDR4]); ++ daddr = nla_get_u32(attrs[MPTCP_ATTR_DADDR4]); ++ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *subsk = mptcp_to_sock(mptcp); ++ struct inet_sock *isk = inet_sk(subsk); ++ ++ if (subsk->sk_family != AF_INET) ++ continue; ++ ++ if (isk->inet_saddr == saddr && ++ isk->inet_daddr == daddr && ++ isk->inet_sport == sport && ++ isk->inet_dport == dport) { ++ sk = subsk; ++ goto found; ++ } ++ } ++ break; ++ } ++#if IS_ENABLED(CONFIG_IPV6) ++ case AF_INET6: { ++ struct in6_addr saddr, daddr; ++ ++ if (!attrs[MPTCP_ATTR_SADDR6] || !attrs[MPTCP_ATTR_DADDR6]) ++ break; ++ ++ saddr = *(struct in6_addr *)nla_data(attrs[MPTCP_ATTR_SADDR6]); ++ daddr = *(struct in6_addr *)nla_data(attrs[MPTCP_ATTR_DADDR6]); ++ ++ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { ++ struct sock *subsk = mptcp_to_sock(mptcp); ++ struct inet_sock *isk = inet_sk(subsk); ++ struct ipv6_pinfo *np; ++ ++ if (subsk->sk_family != AF_INET6) ++ continue; ++ ++ np = inet6_sk(subsk); ++ if (ipv6_addr_equal(&saddr, &np->saddr) && ++ ipv6_addr_equal(&daddr, &subsk->sk_v6_daddr) && ++ isk->inet_sport == sport && ++ isk->inet_dport == dport) { ++ sk = subsk; ++ goto found; ++ } ++ } ++ break; ++ } ++#endif ++ } ++ ++exit: ++ sk = NULL; ++found: ++ return sk; ++} ++ ++static int ++mptcp_nl_genl_destroy(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct sock *meta_sk, *subsk; ++ struct mptcp_cb *mpcb; ++ int ret = 0; ++ u32 token; ++ ++ if (!info->attrs[MPTCP_ATTR_TOKEN]) ++ return -EINVAL; ++ ++ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); ++ ++ meta_sk = mptcp_hash_find(genl_info_net(info), token); ++ if (!meta_sk) ++ return -EINVAL; ++ ++ mpcb = tcp_sk(meta_sk)->mpcb; ++ ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ subsk = mptcp_nl_subsk_lookup(mpcb, info->attrs); ++ if (subsk) { ++ local_bh_disable(); ++ mptcp_reinject_data(subsk, 0); ++ mptcp_send_reset(subsk); ++ local_bh_enable(); ++ } else { ++ ret = -EINVAL; ++ } ++ ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ sock_put(meta_sk); ++ return ret; ++} ++ ++static int ++mptcp_nl_genl_conn_exists(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct sock *meta_sk; ++ u32 token; ++ ++ if (!info->attrs[MPTCP_ATTR_TOKEN]) ++ return -EINVAL; ++ ++ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); ++ ++ meta_sk = mptcp_hash_find(genl_info_net(info), token); ++ if (!meta_sk) ++ return -ENOTCONN; ++ ++ sock_put(meta_sk); ++ return 0; ++} ++ ++static int ++mptcp_nl_genl_priority(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct sock *meta_sk, *subsk; ++ struct mptcp_cb *mpcb; ++ int ret = 0; ++ u32 token; ++ u8 backup = 0; ++ ++ if (!info->attrs[MPTCP_ATTR_TOKEN]) ++ return -EINVAL; ++ ++ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); ++ if (info->attrs[MPTCP_ATTR_BACKUP]) ++ backup = nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]); ++ ++ meta_sk = mptcp_hash_find(genl_info_net(info), token); ++ if (!meta_sk) ++ return -EINVAL; ++ ++ mpcb = tcp_sk(meta_sk)->mpcb; ++ ++ mutex_lock(&mpcb->mpcb_mutex); ++ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); ++ ++ subsk = mptcp_nl_subsk_lookup(mpcb, info->attrs); ++ if (subsk) { ++ tcp_sk(subsk)->mptcp->send_mp_prio = 1; ++ tcp_sk(subsk)->mptcp->low_prio = !!backup; ++ ++ local_bh_disable(); ++ if (mptcp_sk_can_send_ack(subsk)) ++ tcp_send_ack(subsk); ++ else ++ ret = -ENOTCONN; ++ local_bh_enable(); ++ } else { ++ ret = -EINVAL; ++ } ++ ++ release_sock(meta_sk); ++ mutex_unlock(&mpcb->mpcb_mutex); ++ sock_put(meta_sk); ++ return ret; ++} ++ ++static int ++mptcp_nl_genl_set_filter(struct sk_buff *skb, struct genl_info *info) ++{ ++ u16 flags; ++ ++ if (!info->attrs[MPTCP_ATTR_FLAGS]) ++ return -EINVAL; ++ ++ flags = nla_get_u16(info->attrs[MPTCP_ATTR_FLAGS]); ++ ++ /* Only want to receive events that correspond to these flags */ ++ mptcp_nl_event_filter = ~flags; ++ ++ return 0; ++} ++ ++static struct genl_ops mptcp_genl_ops[] = { ++ { ++ .cmd = MPTCP_CMD_ANNOUNCE, ++ .doit = mptcp_nl_genl_announce, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = MPTCP_CMD_REMOVE, ++ .doit = mptcp_nl_genl_remove, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = MPTCP_CMD_SUB_CREATE, ++ .doit = mptcp_nl_genl_create, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = MPTCP_CMD_SUB_DESTROY, ++ .doit = mptcp_nl_genl_destroy, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = MPTCP_CMD_SUB_PRIORITY, ++ .doit = mptcp_nl_genl_priority, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = MPTCP_CMD_SET_FILTER, ++ .doit = mptcp_nl_genl_set_filter, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = MPTCP_CMD_EXIST, ++ .doit = mptcp_nl_genl_conn_exists, ++ .flags = GENL_ADMIN_PERM, ++ }, ++}; ++ ++static struct mptcp_pm_ops mptcp_nl_pm_ops = { ++ .new_session = mptcp_nl_pm_new_session, ++ .close_session = mptcp_nl_pm_close_session, ++ .fully_established = mptcp_nl_pm_fully_established, ++ .established_subflow = mptcp_nl_pm_established_subflow, ++ .delete_subflow = mptcp_nl_pm_delete_subflow, ++ .add_raddr = mptcp_nl_pm_add_raddr, ++ .rem_raddr = mptcp_nl_pm_rem_raddr, ++ .get_local_id = mptcp_nl_pm_get_local_id, ++ .addr_signal = mptcp_nl_pm_addr_signal, ++ .prio_changed = mptcp_nl_pm_prio_changed, ++ .name = "netlink", ++ .owner = THIS_MODULE, ++}; ++ ++static struct genl_family mptcp_genl_family = { ++ .hdrsize = 0, ++ .name = MPTCP_GENL_NAME, ++ .version = MPTCP_GENL_VER, ++ .maxattr = MPTCP_ATTR_MAX, ++ .policy = mptcp_nl_genl_policy, ++ .netnsok = true, ++ .module = THIS_MODULE, ++ .ops = mptcp_genl_ops, ++ .n_ops = ARRAY_SIZE(mptcp_genl_ops), ++ .mcgrps = mptcp_mcgrps, ++ .n_mcgrps = ARRAY_SIZE(mptcp_mcgrps), ++}; ++ ++static int __init ++mptcp_nl_init(void) ++{ ++ int ret; ++ ++ BUILD_BUG_ON(sizeof(struct mptcp_nl_priv) > MPTCP_PM_SIZE); ++ ++ ret = genl_register_family(&mptcp_genl_family); ++ if (ret) ++ goto out_genl; ++ ++ ret = mptcp_register_path_manager(&mptcp_nl_pm_ops); ++ if (ret) ++ goto out_pm; ++ ++ return 0; ++out_pm: ++ genl_unregister_family(&mptcp_genl_family); ++out_genl: ++ return ret; ++} ++ ++static void __exit ++mptcp_nl_exit(void) ++{ ++ mptcp_unregister_path_manager(&mptcp_nl_pm_ops); ++ genl_unregister_family(&mptcp_genl_family); ++} ++ ++module_init(mptcp_nl_init); ++module_exit(mptcp_nl_exit); ++ ++MODULE_AUTHOR("Gregory Detal "); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MPTCP netlink-based path manager"); ++MODULE_ALIAS_GENL_FAMILY(MPTCP_GENL_NAME); +diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c +--- linux-5.4/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,318 @@ ++/* ++ * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: ++ * ++ * Algorithm design: ++ * Ramin Khalili ++ * Nicolas Gast ++ * Jean-Yves Le Boudec ++ * ++ * Implementation: ++ * Ramin Khalili ++ * ++ * Ported to the official MPTCP-kernel: ++ * Christoph Paasch ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++ ++#include ++#include ++ ++#include ++ ++static int scale = 10; ++ ++struct mptcp_olia { ++ u32 mptcp_loss1; ++ u32 mptcp_loss2; ++ u32 mptcp_loss3; ++ int epsilon_num; ++ u32 epsilon_den; ++ int mptcp_snd_cwnd_cnt; ++}; ++ ++static inline int mptcp_olia_sk_can_send(const struct sock *sk) ++{ ++ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; ++} ++ ++static inline u64 mptcp_olia_scale(u64 val, int scale) ++{ ++ return (u64) val << scale; ++} ++ ++/* take care of artificially inflate (see RFC5681) ++ * of cwnd during fast-retransmit phase ++ */ ++static u32 mptcp_get_crt_cwnd(struct sock *sk) ++{ ++ const struct inet_connection_sock *icsk = inet_csk(sk); ++ ++ if (icsk->icsk_ca_state == TCP_CA_Recovery) ++ return tcp_sk(sk)->snd_ssthresh; ++ else ++ return tcp_sk(sk)->snd_cwnd; ++} ++ ++/* return the dominator of the first term of the increasing term */ ++static u64 mptcp_get_rate(const struct mptcp_cb *mpcb , u32 path_rtt) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ u64 rate = 1; /* We have to avoid a zero-rate because it is used as a divisor */ ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp = tcp_sk(sk); ++ u64 scaled_num; ++ u32 tmp_cwnd; ++ ++ if (!mptcp_olia_sk_can_send(sk)) ++ continue; ++ ++ tmp_cwnd = mptcp_get_crt_cwnd(sk); ++ scaled_num = mptcp_olia_scale(tmp_cwnd, scale) * path_rtt; ++ rate += div_u64(scaled_num , tp->srtt_us); ++ } ++ rate *= rate; ++ return rate; ++} ++ ++/* find the maximum cwnd, used to find set M */ ++static u32 mptcp_get_max_cwnd(const struct mptcp_cb *mpcb) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ u32 best_cwnd = 0; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ u32 tmp_cwnd; ++ ++ if (!mptcp_olia_sk_can_send(sk)) ++ continue; ++ ++ tmp_cwnd = mptcp_get_crt_cwnd(sk); ++ if (tmp_cwnd > best_cwnd) ++ best_cwnd = tmp_cwnd; ++ } ++ return best_cwnd; ++} ++ ++static void mptcp_get_epsilon(const struct mptcp_cb *mpcb) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ struct mptcp_olia *ca; ++ struct tcp_sock *tp; ++ struct sock *sk; ++ u64 tmp_int, tmp_rtt, best_int = 0, best_rtt = 1; ++ u32 max_cwnd, tmp_cwnd, established_cnt = 0; ++ u8 M = 0, B_not_M = 0; ++ ++ /* TODO - integrate this in the following loop - we just want to iterate once */ ++ ++ max_cwnd = mptcp_get_max_cwnd(mpcb); ++ ++ /* find the best path */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ sk = mptcp_to_sock(mptcp); ++ tp = tcp_sk(sk); ++ ca = inet_csk_ca(sk); ++ ++ if (!mptcp_olia_sk_can_send(sk)) ++ continue; ++ ++ established_cnt++; ++ ++ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; ++ /* TODO - check here and rename variables */ ++ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, ++ ca->mptcp_loss2 - ca->mptcp_loss1); ++ ++ if ((u64)tmp_int * best_rtt >= (u64)best_int * tmp_rtt) { ++ best_rtt = tmp_rtt; ++ best_int = tmp_int; ++ } ++ } ++ ++ /* TODO - integrate this here in mptcp_get_max_cwnd and in the previous loop */ ++ /* find the size of M and B_not_M */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ sk = mptcp_to_sock(mptcp); ++ tp = tcp_sk(sk); ++ ca = inet_csk_ca(sk); ++ ++ if (!mptcp_olia_sk_can_send(sk)) ++ continue; ++ ++ tmp_cwnd = mptcp_get_crt_cwnd(sk); ++ if (tmp_cwnd == max_cwnd) { ++ M++; ++ } else { ++ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; ++ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, ++ ca->mptcp_loss2 - ca->mptcp_loss1); ++ ++ if ((u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) ++ B_not_M++; ++ } ++ } ++ ++ /* check if the path is in M or B_not_M and set the value of epsilon accordingly */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ sk = mptcp_to_sock(mptcp); ++ tp = tcp_sk(sk); ++ ca = inet_csk_ca(sk); ++ ++ if (!mptcp_olia_sk_can_send(sk)) ++ continue; ++ ++ if (B_not_M == 0) { ++ ca->epsilon_num = 0; ++ ca->epsilon_den = 1; ++ } else { ++ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; ++ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, ++ ca->mptcp_loss2 - ca->mptcp_loss1); ++ tmp_cwnd = mptcp_get_crt_cwnd(sk); ++ ++ if (tmp_cwnd < max_cwnd && ++ (u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) { ++ ca->epsilon_num = 1; ++ ca->epsilon_den = established_cnt * B_not_M; ++ } else if (tmp_cwnd == max_cwnd) { ++ ca->epsilon_num = -1; ++ ca->epsilon_den = established_cnt * M; ++ } else { ++ ca->epsilon_num = 0; ++ ca->epsilon_den = 1; ++ } ++ } ++ } ++} ++ ++/* setting the initial values */ ++static void mptcp_olia_init(struct sock *sk) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_olia *ca = inet_csk_ca(sk); ++ ++ if (mptcp(tp)) { ++ ca->mptcp_loss1 = tp->snd_una; ++ ca->mptcp_loss2 = tp->snd_una; ++ ca->mptcp_loss3 = tp->snd_una; ++ ca->mptcp_snd_cwnd_cnt = 0; ++ ca->epsilon_num = 0; ++ ca->epsilon_den = 1; ++ } ++} ++ ++/* updating inter-loss distance and ssthresh */ ++static void mptcp_olia_set_state(struct sock *sk, u8 new_state) ++{ ++ if (!mptcp(tcp_sk(sk))) ++ return; ++ ++ if (new_state == TCP_CA_Loss || ++ new_state == TCP_CA_Recovery || new_state == TCP_CA_CWR) { ++ struct mptcp_olia *ca = inet_csk_ca(sk); ++ ++ if (ca->mptcp_loss3 != ca->mptcp_loss2 && ++ !inet_csk(sk)->icsk_retransmits) { ++ ca->mptcp_loss1 = ca->mptcp_loss2; ++ ca->mptcp_loss2 = ca->mptcp_loss3; ++ } ++ } ++} ++ ++/* main algorithm */ ++static void mptcp_olia_cong_avoid(struct sock *sk, u32 ack, u32 acked) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_olia *ca = inet_csk_ca(sk); ++ const struct mptcp_cb *mpcb = tp->mpcb; ++ ++ u64 inc_num, inc_den, rate, cwnd_scaled; ++ ++ if (!mptcp(tp)) { ++ tcp_reno_cong_avoid(sk, ack, acked); ++ return; ++ } ++ ++ ca->mptcp_loss3 = tp->snd_una; ++ ++ if (!tcp_is_cwnd_limited(sk)) ++ return; ++ ++ /* slow start if it is in the safe area */ ++ if (tcp_in_slow_start(tp)) { ++ tcp_slow_start(tp, acked); ++ return; ++ } ++ ++ mptcp_get_epsilon(mpcb); ++ rate = mptcp_get_rate(mpcb, tp->srtt_us); ++ cwnd_scaled = mptcp_olia_scale(tp->snd_cwnd, scale); ++ inc_den = ca->epsilon_den * tp->snd_cwnd * rate ? : 1; ++ ++ /* calculate the increasing term, scaling is used to reduce the rounding effect */ ++ if (ca->epsilon_num == -1) { ++ if (ca->epsilon_den * cwnd_scaled * cwnd_scaled < rate) { ++ inc_num = rate - ca->epsilon_den * ++ cwnd_scaled * cwnd_scaled; ++ ca->mptcp_snd_cwnd_cnt -= div64_u64( ++ mptcp_olia_scale(inc_num , scale) , inc_den); ++ } else { ++ inc_num = ca->epsilon_den * ++ cwnd_scaled * cwnd_scaled - rate; ++ ca->mptcp_snd_cwnd_cnt += div64_u64( ++ mptcp_olia_scale(inc_num , scale) , inc_den); ++ } ++ } else { ++ inc_num = ca->epsilon_num * rate + ++ ca->epsilon_den * cwnd_scaled * cwnd_scaled; ++ ca->mptcp_snd_cwnd_cnt += div64_u64( ++ mptcp_olia_scale(inc_num , scale) , inc_den); ++ } ++ ++ ++ if (ca->mptcp_snd_cwnd_cnt >= (1 << scale) - 1) { ++ if (tp->snd_cwnd < tp->snd_cwnd_clamp) ++ tp->snd_cwnd++; ++ ca->mptcp_snd_cwnd_cnt = 0; ++ } else if (ca->mptcp_snd_cwnd_cnt <= 0 - (1 << scale) + 1) { ++ tp->snd_cwnd = max((int) 1 , (int) tp->snd_cwnd - 1); ++ ca->mptcp_snd_cwnd_cnt = 0; ++ } ++} ++ ++static struct tcp_congestion_ops mptcp_olia = { ++ .init = mptcp_olia_init, ++ .ssthresh = tcp_reno_ssthresh, ++ .cong_avoid = mptcp_olia_cong_avoid, ++ .undo_cwnd = tcp_reno_undo_cwnd, ++ .set_state = mptcp_olia_set_state, ++ .owner = THIS_MODULE, ++ .name = "olia", ++}; ++ ++static int __init mptcp_olia_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct mptcp_olia) > ICSK_CA_PRIV_SIZE); ++ return tcp_register_congestion_control(&mptcp_olia); ++} ++ ++static void __exit mptcp_olia_unregister(void) ++{ ++ tcp_unregister_congestion_control(&mptcp_olia); ++} ++ ++module_init(mptcp_olia_register); ++module_exit(mptcp_olia_unregister); ++ ++MODULE_AUTHOR("Ramin Khalili, Nicolas Gast, Jean-Yves Le Boudec"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MPTCP COUPLED CONGESTION CONTROL"); ++MODULE_VERSION("0.1"); +diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_output.c +--- linux-5.4/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,1900 @@ ++/* ++ * MPTCP implementation - Sending side ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer & Author: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++static const int mptcp_dss_len = MPTCP_SUB_LEN_DSS_ALIGN + ++ MPTCP_SUB_LEN_ACK_ALIGN + ++ MPTCP_SUB_LEN_SEQ_ALIGN; ++ ++static inline int mptcp_sub_len_remove_addr(u16 bitfield) ++{ ++ unsigned int c; ++ for (c = 0; bitfield; c++) ++ bitfield &= bitfield - 1; ++ return MPTCP_SUB_LEN_REMOVE_ADDR + c - 1; ++} ++ ++int mptcp_sub_len_remove_addr_align(u16 bitfield) ++{ ++ return ALIGN(mptcp_sub_len_remove_addr(bitfield), 4); ++} ++EXPORT_SYMBOL(mptcp_sub_len_remove_addr_align); ++ ++/* get the data-seq and end-data-seq and store them again in the ++ * tcp_skb_cb ++ */ ++static bool mptcp_reconstruct_mapping(struct sk_buff *skb) ++{ ++ const struct mp_dss *mpdss = (struct mp_dss *)TCP_SKB_CB(skb)->dss; ++ __be32 *p32; ++ __be16 *p16; ++ ++ if (!mptcp_is_data_seq(skb)) ++ return false; ++ ++ if (!mpdss->M) ++ return false; ++ ++ /* Move the pointer to the data-seq */ ++ p32 = (__be32 *)mpdss; ++ p32++; ++ if (mpdss->A) { ++ p32++; ++ if (mpdss->a) ++ p32++; ++ } ++ ++ TCP_SKB_CB(skb)->seq = ntohl(*p32); ++ ++ /* Get the data_len to calculate the end_data_seq */ ++ p32++; ++ p32++; ++ p16 = (__be16 *)p32; ++ TCP_SKB_CB(skb)->end_seq = ntohs(*p16) + TCP_SKB_CB(skb)->seq; ++ ++ return true; ++} ++ ++static bool mptcp_is_reinjected(const struct sk_buff *skb) ++{ ++ return TCP_SKB_CB(skb)->mptcp_flags & MPTCP_REINJECT; ++} ++ ++static void mptcp_find_and_set_pathmask(struct sock *meta_sk, struct sk_buff *skb) ++{ ++ struct rb_node **p = &meta_sk->tcp_rtx_queue.rb_node; ++ struct rb_node *parent; ++ struct sk_buff *skb_it; ++ ++ while (*p) { ++ parent = *p; ++ skb_it = rb_to_skb(parent); ++ if (before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb_it)->seq)) { ++ p = &parent->rb_left; ++ continue; ++ } ++ if (after(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb_it)->seq)) { ++ p = &parent->rb_right; ++ continue; ++ } ++ ++ TCP_SKB_CB(skb)->path_mask = TCP_SKB_CB(skb_it)->path_mask; ++ break; ++ } ++} ++ ++/* Reinject data from one TCP subflow to the meta_sk. If sk == NULL, we are ++ * coming from the meta-retransmit-timer ++ */ ++static void __mptcp_reinject_data(struct sk_buff *orig_skb, struct sock *meta_sk, ++ struct sock *sk, int clone_it, ++ enum tcp_queue tcp_queue) ++{ ++ struct sk_buff *skb, *skb1; ++ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ u32 seq, end_seq; ++ ++ if (clone_it) { ++ /* pskb_copy is necessary here, because the TCP/IP-headers ++ * will be changed when it's going to be reinjected on another ++ * subflow. ++ */ ++ tcp_skb_tsorted_save(orig_skb) { ++ skb = pskb_copy_for_clone(orig_skb, GFP_ATOMIC); ++ } tcp_skb_tsorted_restore(orig_skb); ++ } else { ++ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) { ++ __skb_unlink(orig_skb, &sk->sk_write_queue); ++ } else { ++ list_del(&orig_skb->tcp_tsorted_anchor); ++ tcp_rtx_queue_unlink(orig_skb, sk); ++ INIT_LIST_HEAD(&orig_skb->tcp_tsorted_anchor); ++ } ++ sock_set_flag(sk, SOCK_QUEUE_SHRUNK); ++ sk->sk_wmem_queued -= orig_skb->truesize; ++ sk_mem_uncharge(sk, orig_skb->truesize); ++ skb = orig_skb; ++ } ++ if (unlikely(!skb)) ++ return; ++ ++ /* Make sure that this list is clean */ ++ tcp_skb_tsorted_anchor_cleanup(skb); ++ ++ if (sk && !mptcp_reconstruct_mapping(skb)) { ++ __kfree_skb(skb); ++ return; ++ } ++ ++ skb->sk = meta_sk; ++ ++ /* Reset subflow-specific TCP control-data */ ++ TCP_SKB_CB(skb)->sacked = 0; ++ TCP_SKB_CB(skb)->tcp_flags &= (TCPHDR_ACK | TCPHDR_PSH); ++ ++ /* If it reached already the destination, we don't have to reinject it */ ++ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { ++ __kfree_skb(skb); ++ return; ++ } ++ ++ /* Only reinject segments that are fully covered by the mapping */ ++ if (skb->len + (mptcp_is_data_fin(skb) ? 1 : 0) != ++ TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq) { ++ struct rb_node *parent, **p = &meta_sk->tcp_rtx_queue.rb_node; ++ u32 end_seq = TCP_SKB_CB(skb)->end_seq; ++ u32 seq = TCP_SKB_CB(skb)->seq; ++ ++ __kfree_skb(skb); ++ ++ /* Ok, now we have to look for the full mapping in the meta ++ * send-queue :S ++ */ ++ ++ /* First, find the first skb that covers us */ ++ while (*p) { ++ parent = *p; ++ skb = rb_to_skb(parent); ++ ++ /* Not yet at the mapping? */ ++ if (!after(end_seq, TCP_SKB_CB(skb)->seq)) { ++ p = &parent->rb_left; ++ continue; ++ } ++ ++ if (!before(seq, TCP_SKB_CB(skb)->end_seq)) { ++ p = &parent->rb_right; ++ continue; ++ } ++ ++ break; ++ } ++ ++ if (*p) { ++ /* We found it, now let's reinject everything */ ++ skb = rb_to_skb(*p); ++ ++ skb_rbtree_walk_from(skb) { ++ if (after(TCP_SKB_CB(skb)->end_seq, end_seq)) ++ return; ++ __mptcp_reinject_data(skb, meta_sk, NULL, 1, ++ TCP_FRAG_IN_RTX_QUEUE); ++ } ++ } ++ return; ++ } ++ ++ /* Segment goes back to the MPTCP-layer. So, we need to zero the ++ * path_mask/dss. ++ */ ++ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); ++ ++ /* We need to find out the path-mask from the meta-write-queue ++ * to properly select a subflow. ++ */ ++ mptcp_find_and_set_pathmask(meta_sk, skb); ++ ++ /* If it's empty, just add */ ++ if (skb_queue_empty(&mpcb->reinject_queue)) { ++ skb_queue_head(&mpcb->reinject_queue, skb); ++ return; ++ } ++ ++ /* Find place to insert skb - or even we can 'drop' it, as the ++ * data is already covered by other skb's in the reinject-queue. ++ * ++ * This is inspired by code from tcp_data_queue. ++ */ ++ ++ skb1 = skb_peek_tail(&mpcb->reinject_queue); ++ seq = TCP_SKB_CB(skb)->seq; ++ while (1) { ++ if (!after(TCP_SKB_CB(skb1)->seq, seq)) ++ break; ++ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) { ++ skb1 = NULL; ++ break; ++ } ++ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); ++ } ++ ++ /* Do skb overlap to previous one? */ ++ end_seq = TCP_SKB_CB(skb)->end_seq; ++ if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { ++ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { ++ /* All the bits are present. Don't reinject */ ++ __kfree_skb(skb); ++ return; ++ } ++ if (seq == TCP_SKB_CB(skb1)->seq) { ++ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) ++ skb1 = NULL; ++ else ++ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); ++ } ++ } ++ if (!skb1) ++ __skb_queue_head(&mpcb->reinject_queue, skb); ++ else ++ __skb_queue_after(&mpcb->reinject_queue, skb1, skb); ++ ++ /* And clean segments covered by new one as whole. */ ++ while (!skb_queue_is_last(&mpcb->reinject_queue, skb)) { ++ skb1 = skb_queue_next(&mpcb->reinject_queue, skb); ++ ++ if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) ++ break; ++ ++ if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) ++ break; ++ ++ __skb_unlink(skb1, &mpcb->reinject_queue); ++ __kfree_skb(skb1); ++ } ++ return; ++} ++ ++/* Inserts data into the reinject queue */ ++void mptcp_reinject_data(struct sock *sk, int clone_it) ++{ ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ struct sk_buff *skb_it, *tmp; ++ enum tcp_queue tcp_queue; ++ ++ /* It has already been closed - there is really no point in reinjecting */ ++ if (meta_sk->sk_state == TCP_CLOSE) ++ return; ++ ++ skb_queue_walk_safe(&sk->sk_write_queue, skb_it, tmp) { ++ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it); ++ /* Subflow syn's and fin's are not reinjected. ++ * ++ * As well as empty subflow-fins with a data-fin. ++ * They are reinjected below (without the subflow-fin-flag) ++ */ ++ if (tcb->tcp_flags & TCPHDR_SYN || ++ (tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) || ++ (tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len)) ++ continue; ++ ++ if (mptcp_is_reinjected(skb_it)) ++ continue; ++ ++ tcb->mptcp_flags |= MPTCP_REINJECT; ++ __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it, ++ TCP_FRAG_IN_WRITE_QUEUE); ++ } ++ ++ skb_it = tcp_rtx_queue_head(sk); ++ skb_rbtree_walk_from_safe(skb_it, tmp) { ++ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it); ++ ++ /* Subflow syn's and fin's are not reinjected. ++ * ++ * As well as empty subflow-fins with a data-fin. ++ * They are reinjected below (without the subflow-fin-flag) ++ */ ++ if (tcb->tcp_flags & TCPHDR_SYN || ++ (tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) || ++ (tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len)) ++ continue; ++ ++ if (mptcp_is_reinjected(skb_it)) ++ continue; ++ ++ tcb->mptcp_flags |= MPTCP_REINJECT; ++ __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it, ++ TCP_FRAG_IN_RTX_QUEUE); ++ } ++ ++ skb_it = tcp_write_queue_tail(meta_sk); ++ tcp_queue = TCP_FRAG_IN_WRITE_QUEUE; ++ ++ if (!skb_it) { ++ skb_it = skb_rb_last(&meta_sk->tcp_rtx_queue); ++ tcp_queue = TCP_FRAG_IN_RTX_QUEUE; ++ } ++ ++ /* If sk has sent the empty data-fin, we have to reinject it too. */ ++ if (skb_it && mptcp_is_data_fin(skb_it) && skb_it->len == 0 && ++ TCP_SKB_CB(skb_it)->path_mask & mptcp_pi_to_flag(tcp_sk(sk)->mptcp->path_index)) { ++ __mptcp_reinject_data(skb_it, meta_sk, NULL, 1, tcp_queue); ++ } ++ ++ tcp_sk(sk)->pf = 1; ++ ++ mptcp_push_pending_frames(meta_sk); ++} ++EXPORT_SYMBOL(mptcp_reinject_data); ++ ++static void mptcp_combine_dfin(const struct sk_buff *skb, ++ const struct sock *meta_sk, ++ struct sock *subsk) ++{ ++ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ const struct mptcp_cb *mpcb = meta_tp->mpcb; ++ ++ /* In infinite mapping we always try to combine */ ++ if (mpcb->infinite_mapping_snd) ++ goto combine; ++ ++ /* Don't combine, if they didn't combine when closing - otherwise we end ++ * up in TIME_WAIT, even if our app is smart enough to avoid it. ++ */ ++ if (!mptcp_sk_can_recv(meta_sk) && !mpcb->dfin_combined) ++ return; ++ ++ /* Don't combine if there is still outstanding data that remains to be ++ * DATA_ACKed, because otherwise we may never be able to deliver this. ++ */ ++ if (meta_tp->snd_una != TCP_SKB_CB(skb)->seq) ++ return; ++ ++combine: ++ if (tcp_close_state(subsk)) { ++ subsk->sk_shutdown |= SEND_SHUTDOWN; ++ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; ++ } ++} ++ ++static int mptcp_write_dss_mapping(const struct tcp_sock *tp, const struct sk_buff *skb, ++ __be32 *ptr) ++{ ++ const struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); ++ __be32 *start = ptr; ++ __u16 data_len; ++ ++ *ptr++ = htonl(tcb->seq); /* data_seq */ ++ ++ /* If it's a non-data DATA_FIN, we set subseq to 0 (draft v7) */ ++ if (mptcp_is_data_fin(skb) && skb->len == 0) ++ *ptr++ = 0; /* subseq */ ++ else ++ *ptr++ = htonl(tp->write_seq - tp->mptcp->snt_isn); /* subseq */ ++ ++ if (tcb->mptcp_flags & MPTCPHDR_INF) ++ data_len = 0; ++ else ++ data_len = tcb->end_seq - tcb->seq; ++ ++ if (tp->mpcb->dss_csum && data_len) { ++ __sum16 *p16 = (__sum16 *)ptr; ++ __be32 hdseq = mptcp_get_highorder_sndbits(skb, tp->mpcb); ++ __wsum csum; ++ ++ *ptr = htonl(((data_len) << 16) | ++ (TCPOPT_EOL << 8) | ++ (TCPOPT_EOL)); ++ csum = csum_partial(ptr - 2, 12, skb->csum); ++ p16++; ++ *p16++ = csum_fold(csum_partial(&hdseq, sizeof(hdseq), csum)); ++ } else { ++ *ptr++ = htonl(((data_len) << 16) | ++ (TCPOPT_NOP << 8) | ++ (TCPOPT_NOP)); ++ } ++ ++ return ptr - start; ++} ++ ++static int mptcp_write_dss_data_ack(const struct tcp_sock *tp, const struct sk_buff *skb, ++ __be32 *ptr) ++{ ++ struct mp_dss *mdss = (struct mp_dss *)ptr; ++ __be32 *start = ptr; ++ ++ mdss->kind = TCPOPT_MPTCP; ++ mdss->sub = MPTCP_SUB_DSS; ++ mdss->rsv1 = 0; ++ mdss->rsv2 = 0; ++ mdss->F = mptcp_is_data_fin(skb) ? 1 : 0; ++ mdss->m = 0; ++ mdss->M = mptcp_is_data_seq(skb) ? 1 : 0; ++ mdss->a = 0; ++ mdss->A = 1; ++ mdss->len = mptcp_sub_len_dss(mdss, tp->mpcb->dss_csum); ++ ptr++; ++ ++ *ptr++ = htonl(mptcp_meta_tp(tp)->rcv_nxt); ++ ++ return ptr - start; ++} ++ ++/* RFC6824 states that once a particular subflow mapping has been sent ++ * out it must never be changed. However, packets may be split while ++ * they are in the retransmission queue (due to SACK or ACKs) and that ++ * arguably means that we would change the mapping (e.g. it splits it, ++ * our sends out a subset of the initial mapping). ++ * ++ * Furthermore, the skb checksum is not always preserved across splits ++ * (e.g. mptcp_fragment) which would mean that we need to recompute ++ * the DSS checksum in this case. ++ * ++ * To avoid this we save the initial DSS mapping which allows us to ++ * send the same DSS mapping even for fragmented retransmits. ++ */ ++static void mptcp_save_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb) ++{ ++ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); ++ __be32 *ptr = (__be32 *)tcb->dss; ++ ++ tcb->mptcp_flags |= MPTCPHDR_SEQ; ++ ++ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); ++ ptr += mptcp_write_dss_mapping(tp, skb, ptr); ++} ++ ++/* Write the saved DSS mapping to the header */ ++static int mptcp_write_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb, ++ __be32 *ptr) ++{ ++ __be32 *start = ptr; ++ ++ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); ++ ++ /* update the data_ack */ ++ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); ++ ++ /* dss is in a union with inet_skb_parm and ++ * the IP layer expects zeroed IPCB fields. ++ */ ++ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); ++ ++ return mptcp_dss_len/sizeof(*ptr); ++} ++ ++static bool mptcp_skb_entail(struct sock *sk, struct sk_buff *skb, int reinject) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ const struct sock *meta_sk = mptcp_meta_sk(sk); ++ const struct mptcp_cb *mpcb = tp->mpcb; ++ struct tcp_skb_cb *tcb; ++ struct sk_buff *subskb = NULL; ++ ++ if (!reinject) ++ TCP_SKB_CB(skb)->mptcp_flags |= (mpcb->snd_hiseq_index ? ++ MPTCPHDR_SEQ64_INDEX : 0); ++ ++ tcp_skb_tsorted_save(skb) { ++ subskb = pskb_copy_for_clone(skb, GFP_ATOMIC); ++ } tcp_skb_tsorted_restore(skb); ++ if (!subskb) ++ return false; ++ ++ /* At the subflow-level we need to call again tcp_init_tso_segs. We ++ * force this, by setting pcount to 0. It has been set to 1 prior to ++ * the call to mptcp_skb_entail. ++ */ ++ tcp_skb_pcount_set(subskb, 0); ++ ++ TCP_SKB_CB(skb)->path_mask |= mptcp_pi_to_flag(tp->mptcp->path_index); ++ ++ /* Compute checksum */ ++ if (tp->mpcb->dss_csum) ++ subskb->csum = skb->csum = skb_checksum(skb, 0, skb->len, 0); ++ ++ tcb = TCP_SKB_CB(subskb); ++ ++ if (tp->mpcb->send_infinite_mapping && ++ !tp->mpcb->infinite_mapping_snd && ++ !before(tcb->seq, mptcp_meta_tp(tp)->snd_nxt)) { ++ tp->mptcp->fully_established = 1; ++ tp->mpcb->infinite_mapping_snd = 1; ++ tp->mptcp->infinite_cutoff_seq = tp->write_seq; ++ tcb->mptcp_flags |= MPTCPHDR_INF; ++ } ++ ++ if (mptcp_is_data_fin(subskb)) ++ mptcp_combine_dfin(subskb, meta_sk, sk); ++ ++ mptcp_save_dss_data_seq(tp, subskb); ++ ++ tcb->seq = tp->write_seq; ++ ++ /* Take into account seg len */ ++ tp->write_seq += subskb->len + ((tcb->tcp_flags & TCPHDR_FIN) ? 1 : 0); ++ tcb->end_seq = tp->write_seq; ++ ++ /* If it's a non-payload DATA_FIN (also no subflow-fin), the ++ * segment is not part of the subflow but on a meta-only-level. ++ */ ++ if (!mptcp_is_data_fin(subskb) || tcb->end_seq != tcb->seq) { ++ /* Make sure that this list is clean */ ++ INIT_LIST_HEAD(&subskb->tcp_tsorted_anchor); ++ ++ tcp_add_write_queue_tail(sk, subskb); ++ sk->sk_wmem_queued += subskb->truesize; ++ sk_mem_charge(sk, subskb->truesize); ++ } else { ++ /* Necessary to initialize for tcp_transmit_skb. mss of 1, as ++ * skb->len = 0 will force tso_segs to 1. ++ */ ++ tcp_init_tso_segs(subskb, 1); ++ ++ /* Empty data-fins are sent immediatly on the subflow */ ++ if (tcp_transmit_skb(sk, subskb, 0, GFP_ATOMIC)) ++ return false; ++ } ++ ++ if (!tp->mptcp->fully_established) { ++ tp->mptcp->second_packet = 1; ++ tp->mptcp->last_end_data_seq = TCP_SKB_CB(skb)->end_seq; ++ } ++ ++ return true; ++} ++ ++/* Fragment an skb and update the mptcp meta-data. Due to reinject, we ++ * might need to undo some operations done by tcp_fragment. ++ * ++ * Be careful, the skb may come from 3 different places: ++ * - The send-queue (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) ++ * - The retransmit-queue (tcp_queue == TCP_FRAG_IN_RTX_QUEUE) ++ * - The reinject-queue (reinject == -1) ++ */ ++static int mptcp_fragment(struct sock *meta_sk, enum tcp_queue tcp_queue, ++ struct sk_buff *skb, u32 len, ++ gfp_t gfp, int reinject) ++{ ++ int ret, diff, old_factor; ++ struct sk_buff *buff; ++ u8 flags; ++ ++ if (skb_headlen(skb) < len) ++ diff = skb->len - len; ++ else ++ diff = skb->data_len; ++ old_factor = tcp_skb_pcount(skb); ++ ++ /* The mss_now in tcp_fragment is used to set the tso_segs of the skb. ++ * At the MPTCP-level we do not care about the absolute value. All we ++ * care about is that it is set to 1 for accurate packets_out ++ * accounting. ++ */ ++ ret = tcp_fragment(meta_sk, tcp_queue, skb, len, UINT_MAX, gfp); ++ if (ret) ++ return ret; ++ ++ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) ++ buff = skb->next; ++ else ++ buff = skb_rb_next(skb); ++ ++ flags = TCP_SKB_CB(skb)->mptcp_flags; ++ TCP_SKB_CB(skb)->mptcp_flags = flags & ~(MPTCPHDR_FIN); ++ TCP_SKB_CB(buff)->mptcp_flags = flags; ++ TCP_SKB_CB(buff)->path_mask = TCP_SKB_CB(skb)->path_mask; ++ ++ /* If reinject == 1, the buff will be added to the reinject ++ * queue, which is currently not part of memory accounting. So ++ * undo the changes done by tcp_fragment and update the ++ * reinject queue. Also, undo changes to the packet counters. ++ */ ++ if (reinject == 1) { ++ int undo = buff->truesize - diff; ++ meta_sk->sk_wmem_queued -= undo; ++ sk_mem_uncharge(meta_sk, undo); ++ ++ tcp_sk(meta_sk)->mpcb->reinject_queue.qlen++; ++ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) ++ meta_sk->sk_write_queue.qlen--; ++ ++ if (!before(tcp_sk(meta_sk)->snd_nxt, TCP_SKB_CB(buff)->end_seq)) { ++ undo = old_factor - tcp_skb_pcount(skb) - ++ tcp_skb_pcount(buff); ++ if (undo) ++ tcp_adjust_pcount(meta_sk, skb, -undo); ++ } ++ ++ /* tcp_fragment's call to sk_stream_alloc_skb initializes the ++ * tcp_tsorted_anchor. We need to revert this as it clashes ++ * with the refdst pointer. ++ */ ++ tcp_skb_tsorted_anchor_cleanup(buff); ++ } ++ ++ return 0; ++} ++ ++/* Inspired by tcp_write_wakeup */ ++int mptcp_write_wakeup(struct sock *meta_sk, int mib) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct sk_buff *skb; ++ int ans = 0; ++ ++ if (meta_sk->sk_state == TCP_CLOSE) ++ return -1; ++ ++ skb = tcp_send_head(meta_sk); ++ if (skb && ++ before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(meta_tp))) { ++ unsigned int mss; ++ unsigned int seg_size = tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq; ++ struct sock *subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, true); ++ struct tcp_sock *subtp; ++ ++ WARN_ON(TCP_SKB_CB(skb)->sacked); ++ ++ if (!subsk) ++ goto window_probe; ++ subtp = tcp_sk(subsk); ++ mss = tcp_current_mss(subsk); ++ ++ seg_size = min(tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq, ++ tcp_wnd_end(subtp) - subtp->write_seq); ++ ++ if (before(meta_tp->pushed_seq, TCP_SKB_CB(skb)->end_seq)) ++ meta_tp->pushed_seq = TCP_SKB_CB(skb)->end_seq; ++ ++ /* We are probing the opening of a window ++ * but the window size is != 0 ++ * must have been a result SWS avoidance ( sender ) ++ */ ++ if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq || ++ skb->len > mss) { ++ seg_size = min(seg_size, mss); ++ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; ++ if (mptcp_fragment(meta_sk, TCP_FRAG_IN_WRITE_QUEUE, ++ skb, seg_size, GFP_ATOMIC, 0)) ++ return -1; ++ } else if (!tcp_skb_pcount(skb)) { ++ /* see mptcp_write_xmit on why we use UINT_MAX */ ++ tcp_set_skb_tso_segs(skb, UINT_MAX); ++ } ++ ++ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; ++ if (!mptcp_skb_entail(subsk, skb, 0)) ++ return -1; ++ ++ mptcp_check_sndseq_wrap(meta_tp, TCP_SKB_CB(skb)->end_seq - ++ TCP_SKB_CB(skb)->seq); ++ tcp_event_new_data_sent(meta_sk, skb); ++ ++ __tcp_push_pending_frames(subsk, mss, TCP_NAGLE_PUSH); ++ tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); ++ meta_tp->lsndtime = tcp_jiffies32; ++ ++ return 0; ++ } else { ++ struct mptcp_tcp_sock *mptcp; ++ ++window_probe: ++ if (between(meta_tp->snd_up, meta_tp->snd_una + 1, ++ meta_tp->snd_una + 0xFFFF)) { ++ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ ++ if (mptcp_sk_can_send_ack(sk_it)) ++ tcp_xmit_probe_skb(sk_it, 1, mib); ++ } ++ } ++ ++ /* At least one of the tcp_xmit_probe_skb's has to succeed */ ++ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ int ret; ++ ++ if (!mptcp_sk_can_send_ack(sk_it)) ++ continue; ++ ++ ret = tcp_xmit_probe_skb(sk_it, 0, mib); ++ if (unlikely(ret > 0)) ++ ans = ret; ++ } ++ return ans; ++ } ++} ++ ++bool mptcp_write_xmit(struct sock *meta_sk, unsigned int mss_now, int nonagle, ++ int push_one, gfp_t gfp) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *subtp; ++ struct mptcp_tcp_sock *mptcp; ++ struct sock *subsk = NULL; ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct sk_buff *skb; ++ int reinject = 0; ++ unsigned int sublimit; ++ __u32 path_mask = 0; ++ ++ tcp_mstamp_refresh(meta_tp); ++ ++ if (inet_csk(meta_sk)->icsk_retransmits) { ++ /* If the timer already once fired, retransmit the head of the ++ * queue to unblock us ASAP. ++ */ ++ if (meta_tp->packets_out && !mpcb->infinite_mapping_snd) ++ mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); ++ } ++ ++ while ((skb = mpcb->sched_ops->next_segment(meta_sk, &reinject, &subsk, ++ &sublimit))) { ++ enum tcp_queue tcp_queue = TCP_FRAG_IN_WRITE_QUEUE; ++ unsigned int limit; ++ ++ WARN(TCP_SKB_CB(skb)->sacked, "sacked: %u reinject: %u", ++ TCP_SKB_CB(skb)->sacked, reinject); ++ ++ subtp = tcp_sk(subsk); ++ mss_now = tcp_current_mss(subsk); ++ ++ if (reinject == 1) { ++ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { ++ /* Segment already reached the peer, take the next one */ ++ __skb_unlink(skb, &mpcb->reinject_queue); ++ __kfree_skb(skb); ++ continue; ++ } ++ } else if (reinject == -1) { ++ tcp_queue = TCP_FRAG_IN_RTX_QUEUE; ++ } ++ ++ /* If the segment was cloned (e.g. a meta retransmission), ++ * the header must be expanded/copied so that there is no ++ * corruption of TSO information. ++ */ ++ if (skb_unclone(skb, GFP_ATOMIC)) ++ break; ++ ++ if (unlikely(!tcp_snd_wnd_test(meta_tp, skb, mss_now))) ++ break; ++ ++ /* Force tso_segs to 1 by using UINT_MAX. ++ * We actually don't care about the exact number of segments ++ * emitted on the subflow. We need just to set tso_segs, because ++ * we still need an accurate packets_out count in ++ * tcp_event_new_data_sent. ++ */ ++ tcp_set_skb_tso_segs(skb, UINT_MAX); ++ ++ /* Check for nagle, irregardless of tso_segs. If the segment is ++ * actually larger than mss_now (TSO segment), then ++ * tcp_nagle_check will have partial == false and always trigger ++ * the transmission. ++ * tcp_write_xmit has a TSO-level nagle check which is not ++ * subject to the MPTCP-level. It is based on the properties of ++ * the subflow, not the MPTCP-level. ++ * When the segment is a reinjection or redundant scheduled ++ * segment, nagle check at meta-level may prevent ++ * sending. This could hurt with certain schedulers, as they ++ * to reinjection to recover from a window-stall or reduce latency. ++ * Therefore, Nagle check should be disabled in that case. ++ */ ++ if (!reinject && ++ unlikely(!tcp_nagle_test(meta_tp, skb, mss_now, ++ (tcp_skb_is_last(meta_sk, skb) ? ++ nonagle : TCP_NAGLE_PUSH)))) ++ break; ++ ++ limit = mss_now; ++ /* skb->len > mss_now is the equivalent of tso_segs > 1 in ++ * tcp_write_xmit. Otherwise split-point would return 0. ++ */ ++ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) ++ /* We limit the size of the skb so that it fits into the ++ * window. Call tcp_mss_split_point to avoid duplicating ++ * code. ++ * We really only care about fitting the skb into the ++ * window. That's why we use UINT_MAX. If the skb does ++ * not fit into the cwnd_quota or the NIC's max-segs ++ * limitation, it will be split by the subflow's ++ * tcp_write_xmit which does the appropriate call to ++ * tcp_mss_split_point. ++ */ ++ limit = tcp_mss_split_point(meta_sk, skb, mss_now, ++ UINT_MAX / mss_now, ++ nonagle); ++ ++ if (sublimit) ++ limit = min(limit, sublimit); ++ ++ if (skb->len > limit && ++ unlikely(mptcp_fragment(meta_sk, tcp_queue, ++ skb, limit, gfp, reinject))) ++ break; ++ ++ if (!mptcp_skb_entail(subsk, skb, reinject)) ++ break; ++ /* Nagle is handled at the MPTCP-layer, so ++ * always push on the subflow ++ */ ++ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); ++ if (reinject <= 0) ++ tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); ++ meta_tp->lsndtime = tcp_jiffies32; ++ ++ path_mask |= mptcp_pi_to_flag(subtp->mptcp->path_index); ++ ++ if (!reinject) { ++ mptcp_check_sndseq_wrap(meta_tp, ++ TCP_SKB_CB(skb)->end_seq - ++ TCP_SKB_CB(skb)->seq); ++ tcp_event_new_data_sent(meta_sk, skb); ++ } ++ ++ tcp_minshall_update(meta_tp, mss_now, skb); ++ ++ if (reinject > 0) { ++ __skb_unlink(skb, &mpcb->reinject_queue); ++ kfree_skb(skb); ++ } ++ ++ if (push_one) ++ break; ++ } ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ subsk = mptcp_to_sock(mptcp); ++ subtp = tcp_sk(subsk); ++ ++ if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) ++ continue; ++ ++ /* We have pushed data on this subflow. We ignore the call to ++ * cwnd_validate in tcp_write_xmit as is_cwnd_limited will never ++ * be true (we never push more than what the cwnd can accept). ++ * We need to ensure that we call tcp_cwnd_validate with ++ * is_cwnd_limited set to true if we have filled the cwnd. ++ */ ++ tcp_cwnd_validate(subsk, tcp_packets_in_flight(subtp) >= ++ subtp->snd_cwnd); ++ } ++ ++ return !meta_tp->packets_out && tcp_send_head(meta_sk); ++} ++ ++void mptcp_write_space(struct sock *sk) ++{ ++ mptcp_push_pending_frames(mptcp_meta_sk(sk)); ++} ++ ++u32 __mptcp_select_window(struct sock *sk) ++{ ++ struct inet_connection_sock *icsk = inet_csk(sk); ++ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ int mss, free_space, full_space, window; ++ ++ /* MSS for the peer's data. Previous versions used mss_clamp ++ * here. I don't know if the value based on our guesses ++ * of peer's MSS is better for the performance. It's more correct ++ * but may be worse for the performance because of rcv_mss ++ * fluctuations. --SAW 1998/11/1 ++ */ ++ mss = icsk->icsk_ack.rcv_mss; ++ free_space = tcp_space(meta_sk); ++ full_space = min_t(int, meta_tp->window_clamp, ++ tcp_full_space(meta_sk)); ++ ++ if (mss > full_space) ++ mss = full_space; ++ ++ if (free_space < (full_space >> 1)) { ++ /* If free_space is decreasing due to mostly meta-level ++ * out-of-order packets, don't turn off the quick-ack mode. ++ */ ++ if (meta_tp->rcv_nxt - meta_tp->copied_seq > ((full_space - free_space) >> 1)) ++ icsk->icsk_ack.quick = 0; ++ ++ if (tcp_memory_pressure) ++ /* TODO this has to be adapted when we support different ++ * MSS's among the subflows. ++ */ ++ meta_tp->rcv_ssthresh = min(meta_tp->rcv_ssthresh, ++ 4U * meta_tp->advmss); ++ ++ if (free_space < mss) ++ return 0; ++ } ++ ++ if (free_space > meta_tp->rcv_ssthresh) ++ free_space = meta_tp->rcv_ssthresh; ++ ++ /* Don't do rounding if we are using window scaling, since the ++ * scaled window will not line up with the MSS boundary anyway. ++ */ ++ window = meta_tp->rcv_wnd; ++ if (tp->rx_opt.rcv_wscale) { ++ window = free_space; ++ ++ /* Advertise enough space so that it won't get scaled away. ++ * Import case: prevent zero window announcement if ++ * 1< mss. ++ */ ++ if (((window >> tp->rx_opt.rcv_wscale) << tp-> ++ rx_opt.rcv_wscale) != window) ++ window = (((window >> tp->rx_opt.rcv_wscale) + 1) ++ << tp->rx_opt.rcv_wscale); ++ } else { ++ /* Get the largest window that is a nice multiple of mss. ++ * Window clamp already applied above. ++ * If our current window offering is within 1 mss of the ++ * free space we just keep it. This prevents the divide ++ * and multiply from happening most of the time. ++ * We also don't do any window rounding when the free space ++ * is too small. ++ */ ++ if (window <= free_space - mss || window > free_space) ++ window = (free_space / mss) * mss; ++ else if (mss == full_space && ++ free_space > window + (full_space >> 1)) ++ window = free_space; ++ } ++ ++ return window; ++} ++ ++void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, ++ unsigned *remaining) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ ++ opts->options |= OPTION_MPTCP; ++ if (is_master_tp(tp)) { ++ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYN; ++ opts->mptcp_ver = tcp_sk(sk)->mptcp_ver; ++ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ opts->mp_capable.sender_key = tp->mptcp_loc_key; ++ opts->dss_csum = !!sysctl_mptcp_checksum; ++ } else { ++ const struct mptcp_cb *mpcb = tp->mpcb; ++ ++ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYN; ++ *remaining -= MPTCP_SUB_LEN_JOIN_SYN_ALIGN; ++ opts->mp_join_syns.token = mpcb->mptcp_rem_token; ++ opts->mp_join_syns.low_prio = tp->mptcp->low_prio; ++ opts->addr_id = tp->mptcp->loc_id; ++ opts->mp_join_syns.sender_nonce = tp->mptcp->mptcp_loc_nonce; ++ } ++} ++ ++void mptcp_synack_options(struct request_sock *req, ++ struct tcp_out_options *opts, unsigned *remaining) ++{ ++ struct mptcp_request_sock *mtreq; ++ mtreq = mptcp_rsk(req); ++ ++ opts->options |= OPTION_MPTCP; ++ /* MPCB not yet set - thus it's a new MPTCP-session */ ++ if (!mtreq->is_sub) { ++ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYNACK; ++ opts->mptcp_ver = mtreq->mptcp_ver; ++ opts->mp_capable.sender_key = mtreq->mptcp_loc_key; ++ opts->dss_csum = !!sysctl_mptcp_checksum || mtreq->dss_csum; ++ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ } else { ++ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYNACK; ++ opts->mp_join_syns.sender_truncated_mac = ++ mtreq->mptcp_hash_tmac; ++ opts->mp_join_syns.sender_nonce = mtreq->mptcp_loc_nonce; ++ opts->mp_join_syns.low_prio = mtreq->low_prio; ++ opts->addr_id = mtreq->loc_id; ++ *remaining -= MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN; ++ } ++} ++ ++void mptcp_established_options(struct sock *sk, struct sk_buff *skb, ++ struct tcp_out_options *opts, unsigned *size) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_cb *mpcb = tp->mpcb; ++ const struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; ++ ++ /* We are coming from tcp_current_mss with the meta_sk as an argument. ++ * It does not make sense to check for the options, because when the ++ * segment gets sent, another subflow will be chosen. ++ */ ++ if (!skb && is_meta_sk(sk)) ++ return; ++ ++ if (unlikely(tp->send_mp_fclose)) { ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_MP_FCLOSE; ++ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; ++ *size += MPTCP_SUB_LEN_FCLOSE_ALIGN; ++ return; ++ } ++ ++ /* 1. If we are the sender of the infinite-mapping, we need the ++ * MPTCPHDR_INF-flag, because a retransmission of the ++ * infinite-announcment still needs the mptcp-option. ++ * ++ * We need infinite_cutoff_seq, because retransmissions from before ++ * the infinite-cutoff-moment still need the MPTCP-signalling to stay ++ * consistent. ++ * ++ * 2. If we are the receiver of the infinite-mapping, we always skip ++ * mptcp-options, because acknowledgments from before the ++ * infinite-mapping point have already been sent out. ++ * ++ * I know, the whole infinite-mapping stuff is ugly... ++ * ++ * TODO: Handle wrapped data-sequence numbers ++ * (even if it's very unlikely) ++ */ ++ if (unlikely(mpcb->infinite_mapping_snd) && ++ ((mpcb->send_infinite_mapping && tcb && ++ mptcp_is_data_seq(skb) && ++ !(tcb->mptcp_flags & MPTCPHDR_INF) && ++ !before(tcb->seq, tp->mptcp->infinite_cutoff_seq)) || ++ !mpcb->send_infinite_mapping)) ++ return; ++ ++ if (unlikely(tp->mptcp->include_mpc)) { ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_MP_CAPABLE | ++ OPTION_TYPE_ACK; ++ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; ++ opts->mptcp_ver = mpcb->mptcp_ver; ++ opts->mp_capable.sender_key = mpcb->mptcp_loc_key; ++ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; ++ opts->dss_csum = mpcb->dss_csum; ++ ++ if (skb) ++ tp->mptcp->include_mpc = 0; ++ } ++ if (unlikely(tp->mptcp->pre_established) && ++ (!skb || !(tcb->tcp_flags & (TCPHDR_FIN | TCPHDR_RST)))) { ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_ACK; ++ *size += MPTCP_SUB_LEN_JOIN_ACK_ALIGN; ++ } ++ ++ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && ++ mpcb->mptcp_ver >= MPTCP_VERSION_1 && skb && !mptcp_is_data_seq(skb)) { ++ mpcb->pm_ops->addr_signal(sk, size, opts, skb); ++ ++ if (opts->add_addr_v6) ++ /* Skip subsequent options */ ++ return; ++ } ++ ++ if (!tp->mptcp->include_mpc && !tp->mptcp->pre_established) { ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_DATA_ACK; ++ /* If !skb, we come from tcp_current_mss and thus we always ++ * assume that the DSS-option will be set for the data-packet. ++ */ ++ if (skb && !mptcp_is_data_seq(skb)) { ++ *size += MPTCP_SUB_LEN_ACK_ALIGN; ++ } else { ++ /* Doesn't matter, if csum included or not. It will be ++ * either 10 or 12, and thus aligned = 12 ++ */ ++ *size += MPTCP_SUB_LEN_ACK_ALIGN + ++ MPTCP_SUB_LEN_SEQ_ALIGN; ++ } ++ ++ *size += MPTCP_SUB_LEN_DSS_ALIGN; ++ } ++ ++ /* In fallback mp_fail-mode, we have to repeat it until the fallback ++ * has been done by the sender ++ */ ++ if (unlikely(tp->mptcp->send_mp_fail) && skb && ++ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_FAIL) { ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_MP_FAIL; ++ *size += MPTCP_SUB_LEN_FAIL; ++ } ++ ++ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && ++ mpcb->mptcp_ver < MPTCP_VERSION_1) ++ mpcb->pm_ops->addr_signal(sk, size, opts, skb); ++ ++ if (unlikely(tp->mptcp->send_mp_prio) && ++ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_PRIO_ALIGN) { ++ opts->options |= OPTION_MPTCP; ++ opts->mptcp_options |= OPTION_MP_PRIO; ++ if (skb) ++ tp->mptcp->send_mp_prio = 0; ++ *size += MPTCP_SUB_LEN_PRIO_ALIGN; ++ } ++ ++ return; ++} ++ ++u16 mptcp_select_window(struct sock *sk) ++{ ++ u16 new_win = tcp_select_window(sk); ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct tcp_sock *meta_tp = mptcp_meta_tp(tp); ++ ++ meta_tp->rcv_wnd = tp->rcv_wnd; ++ meta_tp->rcv_wup = meta_tp->rcv_nxt; ++ ++ return new_win; ++} ++ ++void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, ++ const struct tcp_out_options *opts, ++ struct sk_buff *skb) ++{ ++ if (unlikely(OPTION_MP_CAPABLE & opts->mptcp_options)) { ++ struct mp_capable *mpc = (struct mp_capable *)ptr; ++ ++ mpc->kind = TCPOPT_MPTCP; ++ ++ if ((OPTION_TYPE_SYN & opts->mptcp_options) || ++ (OPTION_TYPE_SYNACK & opts->mptcp_options)) { ++ mpc->sender_key = opts->mp_capable.sender_key; ++ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; ++ mpc->ver = opts->mptcp_ver; ++ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; ++ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { ++ mpc->sender_key = opts->mp_capable.sender_key; ++ mpc->receiver_key = opts->mp_capable.receiver_key; ++ mpc->len = MPTCP_SUB_LEN_CAPABLE_ACK; ++ mpc->ver = opts->mptcp_ver; ++ ptr += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN >> 2; ++ } ++ ++ mpc->sub = MPTCP_SUB_CAPABLE; ++ mpc->a = opts->dss_csum; ++ mpc->b = 0; ++ mpc->rsv = 0; ++ mpc->h = 1; ++ } ++ if (unlikely(OPTION_MP_JOIN & opts->mptcp_options)) { ++ struct mp_join *mpj = (struct mp_join *)ptr; ++ ++ mpj->kind = TCPOPT_MPTCP; ++ mpj->sub = MPTCP_SUB_JOIN; ++ mpj->rsv = 0; ++ ++ if (OPTION_TYPE_SYN & opts->mptcp_options) { ++ mpj->len = MPTCP_SUB_LEN_JOIN_SYN; ++ mpj->u.syn.token = opts->mp_join_syns.token; ++ mpj->u.syn.nonce = opts->mp_join_syns.sender_nonce; ++ mpj->b = opts->mp_join_syns.low_prio; ++ mpj->addr_id = opts->addr_id; ++ ptr += MPTCP_SUB_LEN_JOIN_SYN_ALIGN >> 2; ++ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { ++ mpj->len = MPTCP_SUB_LEN_JOIN_SYNACK; ++ mpj->u.synack.mac = ++ opts->mp_join_syns.sender_truncated_mac; ++ mpj->u.synack.nonce = opts->mp_join_syns.sender_nonce; ++ mpj->b = opts->mp_join_syns.low_prio; ++ mpj->addr_id = opts->addr_id; ++ ptr += MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN >> 2; ++ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { ++ mpj->len = MPTCP_SUB_LEN_JOIN_ACK; ++ mpj->addr_id = 0; /* addr_id is rsv (RFC 6824, p. 21) */ ++ memcpy(mpj->u.ack.mac, &tp->mptcp->sender_mac[0], 20); ++ ptr += MPTCP_SUB_LEN_JOIN_ACK_ALIGN >> 2; ++ } ++ } ++ if (unlikely(OPTION_ADD_ADDR & opts->mptcp_options)) { ++ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; ++ struct mptcp_cb *mpcb = tp->mpcb; ++ ++ mpadd->kind = TCPOPT_MPTCP; ++ if (opts->add_addr_v4) { ++ mpadd->sub = MPTCP_SUB_ADD_ADDR; ++ mpadd->ipver = 4; ++ mpadd->addr_id = opts->add_addr4.addr_id; ++ mpadd->u.v4.addr = opts->add_addr4.addr; ++ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { ++ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4; ++ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN >> 2; ++ } else { ++ memcpy((char *)mpadd->u.v4.mac - 2, ++ (char *)&opts->add_addr4.trunc_mac, 8); ++ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4_VER1; ++ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 >> 2; ++ } ++ } else if (opts->add_addr_v6) { ++ mpadd->sub = MPTCP_SUB_ADD_ADDR; ++ mpadd->ipver = 6; ++ mpadd->addr_id = opts->add_addr6.addr_id; ++ memcpy(&mpadd->u.v6.addr, &opts->add_addr6.addr, ++ sizeof(mpadd->u.v6.addr)); ++ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { ++ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6; ++ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN >> 2; ++ } else { ++ memcpy((char *)mpadd->u.v6.mac - 2, ++ (char *)&opts->add_addr6.trunc_mac, 8); ++ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6_VER1; ++ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 >> 2; ++ } ++ } ++ ++ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_ADDADDRTX); ++ } ++ if (unlikely(OPTION_REMOVE_ADDR & opts->mptcp_options)) { ++ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; ++ u8 *addrs_id; ++ int id, len, len_align; ++ ++ len = mptcp_sub_len_remove_addr(opts->remove_addrs); ++ len_align = mptcp_sub_len_remove_addr_align(opts->remove_addrs); ++ ++ mprem->kind = TCPOPT_MPTCP; ++ mprem->len = len; ++ mprem->sub = MPTCP_SUB_REMOVE_ADDR; ++ mprem->rsv = 0; ++ addrs_id = &mprem->addrs_id; ++ ++ mptcp_for_each_bit_set(opts->remove_addrs, id) ++ *(addrs_id++) = id; ++ ++ /* Fill the rest with NOP's */ ++ if (len_align > len) { ++ int i; ++ for (i = 0; i < len_align - len; i++) ++ *(addrs_id++) = TCPOPT_NOP; ++ } ++ ++ ptr += len_align >> 2; ++ ++ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_REMADDRTX); ++ } ++ if (unlikely(OPTION_MP_FAIL & opts->mptcp_options)) { ++ struct mp_fail *mpfail = (struct mp_fail *)ptr; ++ ++ mpfail->kind = TCPOPT_MPTCP; ++ mpfail->len = MPTCP_SUB_LEN_FAIL; ++ mpfail->sub = MPTCP_SUB_FAIL; ++ mpfail->rsv1 = 0; ++ mpfail->rsv2 = 0; ++ mpfail->data_seq = htonll(tp->mpcb->csum_cutoff_seq); ++ ++ ptr += MPTCP_SUB_LEN_FAIL_ALIGN >> 2; ++ } ++ if (unlikely(OPTION_MP_FCLOSE & opts->mptcp_options)) { ++ struct mp_fclose *mpfclose = (struct mp_fclose *)ptr; ++ ++ mpfclose->kind = TCPOPT_MPTCP; ++ mpfclose->len = MPTCP_SUB_LEN_FCLOSE; ++ mpfclose->sub = MPTCP_SUB_FCLOSE; ++ mpfclose->rsv1 = 0; ++ mpfclose->rsv2 = 0; ++ mpfclose->key = opts->mp_capable.receiver_key; ++ ++ ptr += MPTCP_SUB_LEN_FCLOSE_ALIGN >> 2; ++ } ++ ++ if (OPTION_DATA_ACK & opts->mptcp_options) { ++ if (!mptcp_is_data_seq(skb)) ++ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); ++ else ++ ptr += mptcp_write_dss_data_seq(tp, skb, ptr); ++ } ++ if (unlikely(OPTION_MP_PRIO & opts->mptcp_options)) { ++ struct mp_prio *mpprio = (struct mp_prio *)ptr; ++ ++ mpprio->kind = TCPOPT_MPTCP; ++ mpprio->len = MPTCP_SUB_LEN_PRIO; ++ mpprio->sub = MPTCP_SUB_PRIO; ++ mpprio->rsv = 0; ++ mpprio->b = tp->mptcp->low_prio; ++ mpprio->addr_id = TCPOPT_NOP; ++ ++ ptr += MPTCP_SUB_LEN_PRIO_ALIGN >> 2; ++ } ++} ++ ++/* Sends the datafin */ ++void mptcp_send_fin(struct sock *meta_sk) ++{ ++ struct sk_buff *skb, *tskb = tcp_write_queue_tail(meta_sk); ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ int mss_now; ++ ++ if ((1 << meta_sk->sk_state) & (TCPF_CLOSE_WAIT | TCPF_LAST_ACK)) ++ meta_tp->mpcb->passive_close = 1; ++ ++ /* Optimization, tack on the FIN if we have a queue of ++ * unsent frames. But be careful about outgoing SACKS ++ * and IP options. ++ */ ++ mss_now = mptcp_current_mss(meta_sk); ++ ++ if (tskb) { ++ TCP_SKB_CB(tskb)->mptcp_flags |= MPTCPHDR_FIN; ++ TCP_SKB_CB(tskb)->end_seq++; ++ meta_tp->write_seq++; ++ } else { ++ /* Socket is locked, keep trying until memory is available. */ ++ for (;;) { ++ skb = alloc_skb_fclone(MAX_TCP_HEADER, ++ meta_sk->sk_allocation); ++ if (skb) ++ break; ++ yield(); ++ } ++ /* Reserve space for headers and prepare control bits. */ ++ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); ++ skb_reserve(skb, MAX_TCP_HEADER); ++ ++ tcp_init_nondata_skb(skb, meta_tp->write_seq, TCPHDR_ACK); ++ TCP_SKB_CB(skb)->end_seq++; ++ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_FIN; ++ tcp_queue_skb(meta_sk, skb); ++ } ++ __tcp_push_pending_frames(meta_sk, mss_now, TCP_NAGLE_OFF); ++} ++ ++void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct sock *sk; ++ ++ if (hlist_empty(&mpcb->conn_list)) ++ return; ++ ++ WARN_ON(meta_tp->send_mp_fclose); ++ ++ /* First - select a socket */ ++ sk = mptcp_select_ack_sock(meta_sk); ++ ++ /* May happen if no subflow is in an appropriate state, OR ++ * we are in infinite mode or about to go there - just send a reset ++ */ ++ if (!sk || mptcp_in_infinite_mapping_weak(mpcb)) { ++ /* tcp_done must be handled with bh disabled */ ++ if (!in_serving_softirq()) ++ local_bh_disable(); ++ ++ mptcp_sub_force_close_all(mpcb, NULL); ++ ++ if (!in_serving_softirq()) ++ local_bh_enable(); ++ return; ++ } ++ ++ tcp_mstamp_refresh(meta_tp); ++ ++ tcp_sk(sk)->send_mp_fclose = 1; ++ /** Reset all other subflows */ ++ ++ /* tcp_done must be handled with bh disabled */ ++ if (!in_serving_softirq()) ++ local_bh_disable(); ++ ++ mptcp_sub_force_close_all(mpcb, sk); ++ ++ tcp_set_state(sk, TCP_RST_WAIT); ++ ++ if (!in_serving_softirq()) ++ local_bh_enable(); ++ ++ tcp_send_ack(sk); ++ tcp_clear_xmit_timers(sk); ++ inet_csk_reset_keepalive_timer(sk, inet_csk(sk)->icsk_rto); ++ ++ meta_tp->send_mp_fclose = 1; ++ inet_csk(sk)->icsk_retransmits = 0; ++ ++ /* Prevent exp backoff reverting on ICMP dest unreachable */ ++ inet_csk(sk)->icsk_backoff = 0; ++ ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_FASTCLOSETX); ++} ++ ++static void mptcp_ack_retransmit_timer(struct sock *sk) ++{ ++ struct inet_connection_sock *icsk = inet_csk(sk); ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct net *net = sock_net(sk); ++ struct sk_buff *skb; ++ ++ if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) ++ goto out; /* Routing failure or similar */ ++ ++ tcp_mstamp_refresh(tp); ++ ++ if (tcp_write_timeout(sk)) { ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRTO); ++ tp->mptcp->pre_established = 0; ++ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); ++ tp->ops->send_active_reset(sk, GFP_ATOMIC); ++ goto out; ++ } ++ ++ skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC); ++ if (skb == NULL) { ++ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, ++ jiffies + icsk->icsk_rto); ++ return; ++ } ++ ++ /* Reserve space for headers and prepare control bits */ ++ skb_reserve(skb, MAX_TCP_HEADER); ++ tcp_init_nondata_skb(skb, tp->snd_una, TCPHDR_ACK); ++ ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRXMIT); ++ ++ if (tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC) > 0) { ++ /* Retransmission failed because of local congestion, ++ * do not backoff. ++ */ ++ if (!icsk->icsk_retransmits) ++ icsk->icsk_retransmits = 1; ++ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, ++ jiffies + icsk->icsk_rto); ++ return; ++ } ++ ++ if (!tp->retrans_stamp) ++ tp->retrans_stamp = tcp_time_stamp(tp) ? : 1; ++ ++ icsk->icsk_retransmits++; ++ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); ++ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, ++ jiffies + icsk->icsk_rto); ++ if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0)) ++ __sk_dst_reset(sk); ++ ++out:; ++} ++ ++void mptcp_ack_handler(struct timer_list *t) ++{ ++ struct mptcp_tcp_sock *mptcp = from_timer(mptcp, t, mptcp_ack_timer); ++ struct sock *sk = (struct sock *)mptcp->tp; ++ struct sock *meta_sk = mptcp_meta_sk(sk); ++ ++ bh_lock_sock(meta_sk); ++ if (sock_owned_by_user(meta_sk)) { ++ /* Try again later */ ++ sk_reset_timer(sk, &tcp_sk(sk)->mptcp->mptcp_ack_timer, ++ jiffies + (HZ / 20)); ++ goto out_unlock; ++ } ++ ++ if (sk->sk_state == TCP_CLOSE) ++ goto out_unlock; ++ if (!tcp_sk(sk)->mptcp->pre_established) ++ goto out_unlock; ++ ++ mptcp_ack_retransmit_timer(sk); ++ ++ sk_mem_reclaim(sk); ++ ++out_unlock: ++ bh_unlock_sock(meta_sk); ++ sock_put(sk); ++} ++ ++/* Similar to tcp_retransmit_skb ++ * ++ * The diff is that we handle the retransmission-stats (retrans_stamp) at the ++ * meta-level. ++ */ ++int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct sock *subsk; ++ unsigned int limit, mss_now; ++ int err = -1; ++ ++ WARN_ON(TCP_SKB_CB(skb)->sacked); ++ ++ /* Do not sent more than we queued. 1/4 is reserved for possible ++ * copying overhead: fragmentation, tunneling, mangling etc. ++ * ++ * This is a meta-retransmission thus we check on the meta-socket. ++ */ ++ if (refcount_read(&meta_sk->sk_wmem_alloc) > ++ min(meta_sk->sk_wmem_queued + (meta_sk->sk_wmem_queued >> 2), meta_sk->sk_sndbuf)) { ++ return -EAGAIN; ++ } ++ ++ /* We need to make sure that the retransmitted segment can be sent on a ++ * subflow right now. If it is too big, it needs to be fragmented. ++ */ ++ subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, false); ++ if (!subsk) { ++ /* We want to increase icsk_retransmits, thus return 0, so that ++ * mptcp_meta_retransmit_timer enters the desired branch. ++ */ ++ err = 0; ++ goto failed; ++ } ++ mss_now = tcp_current_mss(subsk); ++ ++ /* If the segment was cloned (e.g. a meta retransmission), the header ++ * must be expanded/copied so that there is no corruption of TSO ++ * information. ++ */ ++ if (skb_unclone(skb, GFP_ATOMIC)) { ++ err = -ENOMEM; ++ goto failed; ++ } ++ ++ /* Must have been set by mptcp_write_xmit before */ ++ BUG_ON(!tcp_skb_pcount(skb)); ++ ++ limit = mss_now; ++ /* skb->len > mss_now is the equivalent of tso_segs > 1 in ++ * tcp_write_xmit. Otherwise split-point would return 0. ++ */ ++ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) ++ limit = tcp_mss_split_point(meta_sk, skb, mss_now, ++ UINT_MAX / mss_now, ++ TCP_NAGLE_OFF); ++ ++ limit = min(limit, tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq); ++ ++ if (skb->len > limit && ++ unlikely(mptcp_fragment(meta_sk, TCP_FRAG_IN_RTX_QUEUE, skb, ++ limit, GFP_ATOMIC, 0))) ++ goto failed; ++ ++ if (!mptcp_skb_entail(subsk, skb, -1)) ++ goto failed; ++ ++ /* Update global TCP statistics. */ ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_RETRANSSEGS); ++ ++ /* Diff to tcp_retransmit_skb */ ++ ++ /* Save stamp of the first retransmit. */ ++ if (!meta_tp->retrans_stamp) { ++ tcp_mstamp_refresh(meta_tp); ++ meta_tp->retrans_stamp = tcp_time_stamp(meta_tp); ++ } ++ ++ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); ++ tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); ++ meta_tp->lsndtime = tcp_jiffies32; ++ ++ return 0; ++ ++failed: ++ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPRETRANSFAIL); ++ return err; ++} ++ ++/* Similar to tcp_retransmit_timer ++ * ++ * The diff is that we have to handle retransmissions of the FAST_CLOSE-message ++ * and that we don't have an srtt estimation at the meta-level. ++ */ ++void mptcp_meta_retransmit_timer(struct sock *meta_sk) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); ++ int err; ++ ++ /* In fallback, retransmission is handled at the subflow-level */ ++ if (!meta_tp->packets_out || mpcb->infinite_mapping_snd) ++ return; ++ ++ WARN_ON(tcp_rtx_queue_empty(meta_sk)); ++ ++ if (!meta_tp->snd_wnd && !sock_flag(meta_sk, SOCK_DEAD) && ++ !((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) { ++ /* Receiver dastardly shrinks window. Our retransmits ++ * become zero probes, but we should not timeout this ++ * connection. If the socket is an orphan, time it out, ++ * we cannot allow such beasts to hang infinitely. ++ */ ++ struct inet_sock *meta_inet = inet_sk(meta_sk); ++ if (meta_sk->sk_family == AF_INET) { ++ net_dbg_ratelimited("MPTCP: Peer %pI4:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", ++ &meta_inet->inet_daddr, ++ ntohs(meta_inet->inet_dport), ++ meta_inet->inet_num, meta_tp->snd_una, ++ meta_tp->snd_nxt); ++ } ++#if IS_ENABLED(CONFIG_IPV6) ++ else if (meta_sk->sk_family == AF_INET6) { ++ net_dbg_ratelimited("MPTCP: Peer %pI6:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", ++ &meta_sk->sk_v6_daddr, ++ ntohs(meta_inet->inet_dport), ++ meta_inet->inet_num, meta_tp->snd_una, ++ meta_tp->snd_nxt); ++ } ++#endif ++ if (tcp_jiffies32 - meta_tp->rcv_tstamp > TCP_RTO_MAX) { ++ tcp_write_err(meta_sk); ++ return; ++ } ++ ++ mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); ++ goto out_reset_timer; ++ } ++ ++ if (tcp_write_timeout(meta_sk)) ++ return; ++ ++ if (meta_icsk->icsk_retransmits == 0) ++ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPTIMEOUTS); ++ ++ meta_icsk->icsk_ca_state = TCP_CA_Loss; ++ ++ err = mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); ++ if (err > 0) { ++ /* Retransmission failed because of local congestion, ++ * do not backoff. ++ */ ++ if (!meta_icsk->icsk_retransmits) ++ meta_icsk->icsk_retransmits = 1; ++ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, ++ min(meta_icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL), ++ TCP_RTO_MAX); ++ return; ++ } ++ ++ /* Increase the timeout each time we retransmit. Note that ++ * we do not increase the rtt estimate. rto is initialized ++ * from rtt, but increases here. Jacobson (SIGCOMM 88) suggests ++ * that doubling rto each time is the least we can get away with. ++ * In KA9Q, Karn uses this for the first few times, and then ++ * goes to quadratic. netBSD doubles, but only goes up to *64, ++ * and clamps at 1 to 64 sec afterwards. Note that 120 sec is ++ * defined in the protocol as the maximum possible RTT. I guess ++ * we'll have to use something other than TCP to talk to the ++ * University of Mars. ++ * ++ * PAWS allows us longer timeouts and large windows, so once ++ * implemented ftp to mars will work nicely. We will have to fix ++ * the 120 second clamps though! ++ */ ++ meta_icsk->icsk_backoff++; ++ meta_icsk->icsk_retransmits++; ++ ++out_reset_timer: ++ /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is ++ * used to reset timer, set to 0. Recalculate 'icsk_rto' as this ++ * might be increased if the stream oscillates between thin and thick, ++ * thus the old value might already be too high compared to the value ++ * set by 'tcp_set_rto' in tcp_input.c which resets the rto without ++ * backoff. Limit to TCP_THIN_LINEAR_RETRIES before initiating ++ * exponential backoff behaviour to avoid continue hammering ++ * linear-timeout retransmissions into a black hole ++ */ ++ if (meta_sk->sk_state == TCP_ESTABLISHED && ++ (meta_tp->thin_lto || sock_net(meta_sk)->ipv4.sysctl_tcp_thin_linear_timeouts) && ++ tcp_stream_is_thin(meta_tp) && ++ meta_icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) { ++ meta_icsk->icsk_backoff = 0; ++ /* We cannot do the same as in tcp_write_timer because the ++ * srtt is not set here. ++ */ ++ mptcp_set_rto(meta_sk); ++ } else { ++ /* Use normal (exponential) backoff */ ++ meta_icsk->icsk_rto = min(meta_icsk->icsk_rto << 1, TCP_RTO_MAX); ++ } ++ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, meta_icsk->icsk_rto, TCP_RTO_MAX); ++ ++ return; ++} ++ ++void mptcp_sub_retransmit_timer(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ tcp_retransmit_timer(sk); ++ ++ if (!tp->fastopen_rsk) { ++ mptcp_reinject_data(sk, 1); ++ mptcp_set_rto(sk); ++ } ++} ++ ++/* Modify values to an mptcp-level for the initial window of new subflows */ ++void mptcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, ++ __u32 *rcv_wnd, __u32 *window_clamp, ++ int wscale_ok, __u8 *rcv_wscale, ++ __u32 init_rcv_wnd) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; ++ ++ *window_clamp = mpcb->orig_window_clamp; ++ __space = tcp_win_from_space(sk, mpcb->orig_sk_rcvbuf); ++ ++ tcp_select_initial_window(sk, __space, mss, rcv_wnd, window_clamp, ++ wscale_ok, rcv_wscale, init_rcv_wnd); ++} ++ ++static inline u64 mptcp_calc_rate(const struct sock *meta_sk, unsigned int mss) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ u64 rate = 0; ++ ++ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp = tcp_sk(sk); ++ int this_mss; ++ u64 this_rate; ++ ++ if (!mptcp_sk_can_send(sk)) ++ continue; ++ ++ /* Do not consider subflows without a RTT estimation yet ++ * otherwise this_rate >>> rate. ++ */ ++ if (unlikely(!tp->srtt_us)) ++ continue; ++ ++ this_mss = tcp_current_mss(sk); ++ ++ /* If this_mss is smaller than mss, it means that a segment will ++ * be splitted in two (or more) when pushed on this subflow. If ++ * you consider that mss = 1428 and this_mss = 1420 then two ++ * segments will be generated: a 1420-byte and 8-byte segment. ++ * The latter will introduce a large overhead as for a single ++ * data segment 2 slots will be used in the congestion window. ++ * Therefore reducing by ~2 the potential throughput of this ++ * subflow. Indeed, 1428 will be send while 2840 could have been ++ * sent if mss == 1420 reducing the throughput by 2840 / 1428. ++ * ++ * The following algorithm take into account this overhead ++ * when computing the potential throughput that MPTCP can ++ * achieve when generating mss-byte segments. ++ * ++ * The formulae is the following: ++ * \sum_{\forall sub} ratio * \frac{mss * cwnd_sub}{rtt_sub} ++ * Where ratio is computed as follows: ++ * \frac{mss}{\ceil{mss / mss_sub} * mss_sub} ++ * ++ * ratio gives the reduction factor of the theoretical ++ * throughput a subflow can achieve if MPTCP uses a specific ++ * MSS value. ++ */ ++ this_rate = div64_u64((u64)mss * mss * (USEC_PER_SEC << 3) * ++ max(tp->snd_cwnd, tp->packets_out), ++ (u64)tp->srtt_us * ++ DIV_ROUND_UP(mss, this_mss) * this_mss); ++ rate += this_rate; ++ } ++ ++ return rate; ++} ++ ++static unsigned int __mptcp_current_mss(const struct sock *meta_sk) ++{ ++ struct mptcp_tcp_sock *mptcp; ++ unsigned int mss = 0; ++ u64 rate = 0; ++ ++ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ int this_mss; ++ u64 this_rate; ++ ++ if (!mptcp_sk_can_send(sk)) ++ continue; ++ ++ this_mss = tcp_current_mss(sk); ++ ++ /* Same mss values will produce the same throughput. */ ++ if (this_mss == mss) ++ continue; ++ ++ /* See whether using this mss value can theoretically improve ++ * the performances. ++ */ ++ this_rate = mptcp_calc_rate(meta_sk, this_mss); ++ if (this_rate >= rate) { ++ mss = this_mss; ++ rate = this_rate; ++ } ++ } ++ ++ return mss; ++} ++ ++unsigned int mptcp_current_mss(struct sock *meta_sk) ++{ ++ unsigned int mss = __mptcp_current_mss(meta_sk); ++ ++ /* If no subflow is available, we take a default-mss from the ++ * meta-socket. ++ */ ++ return !mss ? tcp_current_mss(meta_sk) : mss; ++} ++ ++int mptcp_check_snd_buf(const struct tcp_sock *tp) ++{ ++ const struct mptcp_tcp_sock *mptcp; ++ u32 rtt_max = tp->srtt_us; ++ u64 bw_est; ++ ++ if (!tp->srtt_us) ++ return tp->reordering + 1; ++ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ const struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if (!mptcp_sk_can_send(sk)) ++ continue; ++ ++ if (rtt_max < tcp_sk(sk)->srtt_us) ++ rtt_max = tcp_sk(sk)->srtt_us; ++ } ++ ++ bw_est = div64_u64(((u64)tp->snd_cwnd * rtt_max) << 16, ++ (u64)tp->srtt_us); ++ ++ return max_t(unsigned int, (u32)(bw_est >> 16), ++ tp->reordering + 1); ++} ++ ++unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, ++ int large_allowed) ++{ ++ u32 xmit_size_goal = 0; ++ ++ if (large_allowed && !tcp_sk(meta_sk)->mpcb->dss_csum) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ int this_size_goal; ++ ++ if (!mptcp_sk_can_send(sk)) ++ continue; ++ ++ this_size_goal = tcp_xmit_size_goal(sk, mss_now, 1); ++ if (this_size_goal > xmit_size_goal) ++ xmit_size_goal = this_size_goal; ++ } ++ } ++ ++ return max(xmit_size_goal, mss_now); ++} ++ +diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c +--- linux-5.4/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,226 @@ ++/* ++ * MPTCP implementation - MPTCP-subflow-management ++ * ++ * Initial Design & Implementation: ++ * Sébastien Barré ++ * ++ * Current Maintainer & Author: ++ * Christoph Paasch ++ * ++ * Additional authors: ++ * Jaakko Korkeaniemi ++ * Gregory Detal ++ * Fabien Duchêne ++ * Andreas Seelinger ++ * Lavkesh Lahngir ++ * Andreas Ripke ++ * Vlad Dogaru ++ * Octavian Purdila ++ * John Ronan ++ * Catalin Nicutar ++ * Brandon Heller ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++ ++#include ++#include ++ ++static DEFINE_SPINLOCK(mptcp_pm_list_lock); ++static LIST_HEAD(mptcp_pm_list); ++ ++static int mptcp_default_id(const struct sock *meta_sk, sa_family_t family, ++ union inet_addr *addr, bool *low_prio) ++{ ++ return 0; ++} ++ ++struct mptcp_pm_ops mptcp_pm_default = { ++ .get_local_id = mptcp_default_id, /* We do not care */ ++ .name = "default", ++ .owner = THIS_MODULE, ++}; ++ ++static struct mptcp_pm_ops *mptcp_pm_find(const char *name) ++{ ++ struct mptcp_pm_ops *e; ++ ++ list_for_each_entry_rcu(e, &mptcp_pm_list, list) { ++ if (strcmp(e->name, name) == 0) ++ return e; ++ } ++ ++ return NULL; ++} ++ ++int mptcp_register_path_manager(struct mptcp_pm_ops *pm) ++{ ++ int ret = 0; ++ ++ if (!pm->get_local_id) ++ return -EINVAL; ++ ++ spin_lock(&mptcp_pm_list_lock); ++ if (mptcp_pm_find(pm->name)) { ++ pr_notice("%s already registered\n", pm->name); ++ ret = -EEXIST; ++ } else { ++ list_add_tail_rcu(&pm->list, &mptcp_pm_list); ++ pr_info("%s registered\n", pm->name); ++ } ++ spin_unlock(&mptcp_pm_list_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(mptcp_register_path_manager); ++ ++void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm) ++{ ++ spin_lock(&mptcp_pm_list_lock); ++ list_del_rcu(&pm->list); ++ spin_unlock(&mptcp_pm_list_lock); ++ ++ /* Wait for outstanding readers to complete before the ++ * module gets removed entirely. ++ * ++ * A try_module_get() should fail by now as our module is ++ * in "going" state since no refs are held anymore and ++ * module_exit() handler being called. ++ */ ++ synchronize_rcu(); ++} ++EXPORT_SYMBOL_GPL(mptcp_unregister_path_manager); ++ ++void mptcp_get_default_path_manager(char *name) ++{ ++ struct mptcp_pm_ops *pm; ++ ++ BUG_ON(list_empty(&mptcp_pm_list)); ++ ++ rcu_read_lock(); ++ pm = list_entry(mptcp_pm_list.next, struct mptcp_pm_ops, list); ++ strncpy(name, pm->name, MPTCP_PM_NAME_MAX); ++ rcu_read_unlock(); ++} ++ ++int mptcp_set_default_path_manager(const char *name) ++{ ++ struct mptcp_pm_ops *pm; ++ int ret = -ENOENT; ++ ++ spin_lock(&mptcp_pm_list_lock); ++ pm = mptcp_pm_find(name); ++#ifdef CONFIG_MODULES ++ if (!pm && capable(CAP_NET_ADMIN)) { ++ spin_unlock(&mptcp_pm_list_lock); ++ ++ request_module("mptcp_%s", name); ++ spin_lock(&mptcp_pm_list_lock); ++ pm = mptcp_pm_find(name); ++ } ++#endif ++ ++ if (pm) { ++ list_move(&pm->list, &mptcp_pm_list); ++ ret = 0; ++ } else { ++ pr_info("%s is not available\n", name); ++ } ++ spin_unlock(&mptcp_pm_list_lock); ++ ++ return ret; ++} ++ ++static struct mptcp_pm_ops *__mptcp_pm_find_autoload(const char *name) ++{ ++ struct mptcp_pm_ops *pm = mptcp_pm_find(name); ++#ifdef CONFIG_MODULES ++ if (!pm && capable(CAP_NET_ADMIN)) { ++ rcu_read_unlock(); ++ request_module("mptcp_%s", name); ++ rcu_read_lock(); ++ pm = mptcp_pm_find(name); ++ } ++#endif ++ return pm; ++} ++ ++void mptcp_init_path_manager(struct mptcp_cb *mpcb) ++{ ++ struct mptcp_pm_ops *pm; ++ struct sock *meta_sk = mpcb->meta_sk; ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ ++ rcu_read_lock(); ++ /* if path manager was set using socket option */ ++ if (meta_tp->mptcp_pm_setsockopt) { ++ pm = __mptcp_pm_find_autoload(meta_tp->mptcp_pm_name); ++ if (pm && try_module_get(pm->owner)) { ++ mpcb->pm_ops = pm; ++ goto out; ++ } ++ } ++ ++ list_for_each_entry_rcu(pm, &mptcp_pm_list, list) { ++ if (try_module_get(pm->owner)) { ++ mpcb->pm_ops = pm; ++ break; ++ } ++ } ++out: ++ rcu_read_unlock(); ++} ++ ++/* Change path manager for socket */ ++int mptcp_set_path_manager(struct sock *sk, const char *name) ++{ ++ struct mptcp_pm_ops *pm; ++ int err = 0; ++ ++ rcu_read_lock(); ++ pm = __mptcp_pm_find_autoload(name); ++ ++ if (!pm) { ++ err = -ENOENT; ++ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { ++ err = -EPERM; ++ } else { ++ strcpy(tcp_sk(sk)->mptcp_pm_name, name); ++ tcp_sk(sk)->mptcp_pm_setsockopt = 1; ++ } ++ rcu_read_unlock(); ++ ++ return err; ++} ++ ++/* Manage refcounts on socket close. */ ++void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb) ++{ ++ module_put(mpcb->pm_ops->owner); ++} ++ ++/* Fallback to the default path-manager. */ ++void mptcp_fallback_default(struct mptcp_cb *mpcb) ++{ ++ struct mptcp_pm_ops *pm; ++ ++ mptcp_cleanup_path_manager(mpcb); ++ pm = mptcp_pm_find("default"); ++ ++ /* Cannot fail - it's the default module */ ++ try_module_get(pm->owner); ++ mpcb->pm_ops = pm; ++} ++EXPORT_SYMBOL_GPL(mptcp_fallback_default); ++ ++/* Set default value from kernel configuration at bootup */ ++static int __init mptcp_path_manager_default(void) ++{ ++ return mptcp_set_default_path_manager(CONFIG_DEFAULT_MPTCP_PM); ++} ++late_initcall(mptcp_path_manager_default); +diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c +--- linux-5.4/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,389 @@ ++/* ++ * MPTCP Scheduler to reduce latency and jitter. ++ * ++ * This scheduler sends all packets redundantly on all available subflows. ++ * ++ * Initial Design & Implementation: ++ * Tobias Erbshaeusser ++ * Alexander Froemmgen ++ * ++ * Initial corrections & modifications: ++ * Christian Pinedo ++ * Igor Lopez ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++/* Struct to store the data of a single subflow */ ++struct redsched_priv { ++ /* The skb or NULL */ ++ struct sk_buff *skb; ++ /* End sequence number of the skb. This number should be checked ++ * to be valid before the skb field is used ++ */ ++ u32 skb_end_seq; ++}; ++ ++/* Struct to store the data of the control block */ ++struct redsched_cb { ++ /* The next subflow where a skb should be sent or NULL */ ++ struct tcp_sock *next_subflow; ++}; ++ ++/* Returns the socket data from a given subflow socket */ ++static struct redsched_priv *redsched_get_priv(struct tcp_sock *tp) ++{ ++ return (struct redsched_priv *)&tp->mptcp->mptcp_sched[0]; ++} ++ ++/* Returns the control block data from a given meta socket */ ++static struct redsched_cb *redsched_get_cb(struct tcp_sock *tp) ++{ ++ return (struct redsched_cb *)&tp->mpcb->mptcp_sched[0]; ++} ++ ++static bool redsched_get_active_valid_sks(struct sock *meta_sk) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct mptcp_tcp_sock *mptcp; ++ int active_valid_sks = 0; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if (subflow_is_active((struct tcp_sock *)sk) && ++ !mptcp_is_def_unavailable(sk)) ++ active_valid_sks++; ++ } ++ ++ return active_valid_sks; ++} ++ ++static bool redsched_use_subflow(struct sock *meta_sk, ++ int active_valid_sks, ++ struct tcp_sock *tp, ++ struct sk_buff *skb) ++{ ++ if (!skb || !mptcp_is_available((struct sock *)tp, skb, false)) ++ return false; ++ ++ if (TCP_SKB_CB(skb)->path_mask != 0) ++ return subflow_is_active(tp); ++ ++ if (TCP_SKB_CB(skb)->path_mask == 0) { ++ if (active_valid_sks == -1) ++ active_valid_sks = redsched_get_active_valid_sks(meta_sk); ++ ++ if (subflow_is_backup(tp) && active_valid_sks > 0) ++ return false; ++ else ++ return true; ++ } ++ ++ return false; ++} ++ ++#define mptcp_entry_next_rcu(__mptcp) \ ++ hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ ++ &(__mptcp)->node)), struct mptcp_tcp_sock, node) ++ ++static void redsched_update_next_subflow(struct tcp_sock *tp, ++ struct redsched_cb *red_cb) ++{ ++ struct mptcp_tcp_sock *mptcp = mptcp_entry_next_rcu(tp->mptcp); ++ ++ if (mptcp) ++ red_cb->next_subflow = mptcp->tp; ++ else ++ red_cb->next_subflow = NULL; ++} ++ ++static struct sock *red_get_available_subflow(struct sock *meta_sk, ++ struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); ++ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; ++ struct mptcp_tcp_sock *mptcp; ++ int found = 0; ++ ++ /* Answer data_fin on same subflow */ ++ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && ++ skb && mptcp_is_data_fin(skb)) { ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(sk)->mptcp->path_index == ++ mpcb->dfin_path_index && ++ mptcp_is_available(sk, skb, zero_wnd_test)) ++ return sk; ++ } ++ } ++ ++ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { ++ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), ++ struct mptcp_tcp_sock, node)->tp; ++ } ++ tp = first_tp; ++ ++ /* still NULL (no subflow in conn_list?) */ ++ if (!first_tp) ++ return NULL; ++ ++ /* Search for a subflow to send it. ++ * ++ * We want to pick a subflow that is after 'first_tp' in the list of subflows. ++ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up ++ * to the subflow 'tp' and then checks whether any one of the remaining ++ * ones is eligible to send. ++ * The second mptcp_for_each-sub()-loop is then iterating from the ++ * beginning of the list up to 'first_tp'. ++ */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ /* We go up to the subflow 'tp' and start from there */ ++ if (tp == mptcp->tp) ++ found = 1; ++ ++ if (!found) ++ continue; ++ tp = mptcp->tp; ++ ++ if (mptcp_is_available((struct sock *)tp, skb, ++ zero_wnd_test)) { ++ redsched_update_next_subflow(tp, red_cb); ++ return (struct sock *)tp; ++ } ++ } ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ tp = mptcp->tp; ++ ++ if (tp == first_tp) ++ break; ++ ++ if (mptcp_is_available((struct sock *)tp, skb, ++ zero_wnd_test)) { ++ redsched_update_next_subflow(tp, red_cb); ++ return (struct sock *)tp; ++ } ++ } ++ ++ /* No space */ ++ return NULL; ++} ++ ++/* Corrects the stored skb pointers if they are invalid */ ++static void redsched_correct_skb_pointers(struct sock *meta_sk, ++ struct redsched_priv *red_p) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ ++ if (red_p->skb && !after(red_p->skb_end_seq, meta_tp->snd_una)) ++ red_p->skb = NULL; ++} ++ ++/* Returns the next skb from the queue */ ++static struct sk_buff *redsched_next_skb_from_queue(struct sk_buff_head *queue, ++ struct sk_buff *previous, ++ struct sock *meta_sk) ++{ ++ struct sk_buff *skb; ++ ++ if (!previous) ++ return skb_peek(queue); ++ ++ /* sk_data->skb stores the last scheduled packet for this subflow. ++ * If sk_data->skb was scheduled but not sent (e.g., due to nagle), ++ * we have to schedule it again. ++ * ++ * For the redundant scheduler, there are two cases: ++ * 1. sk_data->skb was not sent on another subflow: ++ * we have to schedule it again to ensure that we do not ++ * skip this packet. ++ * 2. sk_data->skb was already sent on another subflow: ++ * with regard to the redundant semantic, we have to ++ * schedule it again. However, we keep it simple and ignore it, ++ * as it was already sent by another subflow. ++ * This might be changed in the future. ++ * ++ * For case 1, send_head is equal previous, as only a single ++ * packet can be skipped. ++ */ ++ if (tcp_send_head(meta_sk) == previous) ++ return tcp_send_head(meta_sk); ++ ++ skb = skb_rb_next(previous); ++ if (skb) ++ return skb; ++ ++ return tcp_send_head(meta_sk); ++} ++ ++static struct sk_buff *mptcp_red_next_segment(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); ++ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; ++ struct mptcp_tcp_sock *mptcp; ++ int active_valid_sks = -1; ++ struct sk_buff *skb; ++ int found = 0; ++ ++ /* As we set it, we have to reset it as well. */ ++ *limit = 0; ++ ++ if (skb_queue_empty(&mpcb->reinject_queue) && ++ skb_queue_empty(&meta_sk->sk_write_queue)) ++ /* Nothing to send */ ++ return NULL; ++ ++ /* First try reinjections */ ++ skb = skb_peek(&mpcb->reinject_queue); ++ if (skb) { ++ *subsk = get_available_subflow(meta_sk, skb, false); ++ if (!*subsk) ++ return NULL; ++ *reinject = 1; ++ return skb; ++ } ++ ++ /* Then try indistinctly redundant and normal skbs */ ++ ++ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { ++ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), ++ struct mptcp_tcp_sock, node)->tp; ++ } ++ ++ /* still NULL (no subflow in conn_list?) */ ++ if (!first_tp) ++ return NULL; ++ ++ tp = first_tp; ++ ++ *reinject = 0; ++ active_valid_sks = redsched_get_active_valid_sks(meta_sk); ++ ++ /* We want to pick a subflow that is after 'first_tp' in the list of subflows. ++ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up ++ * to the subflow 'tp' and then checks whether any one of the remaining ++ * ones can send a segment. ++ * The second mptcp_for_each-sub()-loop is then iterating from the ++ * beginning of the list up to 'first_tp'. ++ */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct redsched_priv *red_p; ++ ++ if (tp == mptcp->tp) ++ found = 1; ++ ++ if (!found) ++ continue; ++ ++ tp = mptcp->tp; ++ ++ /* Correct the skb pointers of the current subflow */ ++ red_p = redsched_get_priv(tp); ++ redsched_correct_skb_pointers(meta_sk, red_p); ++ ++ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, ++ red_p->skb, meta_sk); ++ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, ++ skb)) { ++ red_p->skb = skb; ++ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; ++ redsched_update_next_subflow(tp, red_cb); ++ *subsk = (struct sock *)tp; ++ ++ if (TCP_SKB_CB(skb)->path_mask) ++ *reinject = -1; ++ return skb; ++ } ++ } ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct redsched_priv *red_p; ++ ++ tp = mptcp->tp; ++ ++ if (tp == first_tp) ++ break; ++ ++ /* Correct the skb pointers of the current subflow */ ++ red_p = redsched_get_priv(tp); ++ redsched_correct_skb_pointers(meta_sk, red_p); ++ ++ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, ++ red_p->skb, meta_sk); ++ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, ++ skb)) { ++ red_p->skb = skb; ++ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; ++ redsched_update_next_subflow(tp, red_cb); ++ *subsk = (struct sock *)tp; ++ ++ if (TCP_SKB_CB(skb)->path_mask) ++ *reinject = -1; ++ return skb; ++ } ++ } ++ ++ /* Nothing to send */ ++ return NULL; ++} ++ ++static void redsched_release(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct redsched_cb *red_cb = redsched_get_cb(tp); ++ ++ /* Check if the next subflow would be the released one. If yes correct ++ * the pointer ++ */ ++ if (red_cb->next_subflow == tp) ++ redsched_update_next_subflow(tp, red_cb); ++} ++ ++static struct mptcp_sched_ops mptcp_sched_red = { ++ .get_subflow = red_get_available_subflow, ++ .next_segment = mptcp_red_next_segment, ++ .release = redsched_release, ++ .name = "redundant", ++ .owner = THIS_MODULE, ++}; ++ ++static int __init red_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct redsched_priv) > MPTCP_SCHED_SIZE); ++ BUILD_BUG_ON(sizeof(struct redsched_cb) > MPTCP_SCHED_DATA_SIZE); ++ ++ if (mptcp_register_scheduler(&mptcp_sched_red)) ++ return -1; ++ ++ return 0; ++} ++ ++static void red_unregister(void) ++{ ++ mptcp_unregister_scheduler(&mptcp_sched_red); ++} ++ ++module_init(red_register); ++module_exit(red_unregister); ++ ++MODULE_AUTHOR("Tobias Erbshaeusser, Alexander Froemmgen"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("REDUNDANT MPTCP"); ++MODULE_VERSION("0.90"); +diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c +--- linux-5.4/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,309 @@ ++/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ ++ ++#include ++#include ++ ++static unsigned char num_segments __read_mostly = 1; ++module_param(num_segments, byte, 0644); ++MODULE_PARM_DESC(num_segments, "The number of consecutive segments that are part of a burst"); ++ ++static bool cwnd_limited __read_mostly = 1; ++module_param(cwnd_limited, bool, 0644); ++MODULE_PARM_DESC(cwnd_limited, "if set to 1, the scheduler tries to fill the congestion-window on all subflows"); ++ ++struct rrsched_priv { ++ unsigned char quota; ++}; ++ ++static struct rrsched_priv *rrsched_get_priv(const struct tcp_sock *tp) ++{ ++ return (struct rrsched_priv *)&tp->mptcp->mptcp_sched[0]; ++} ++ ++/* If the sub-socket sk available to send the skb? */ ++static bool mptcp_rr_is_available(const struct sock *sk, const struct sk_buff *skb, ++ bool zero_wnd_test, bool cwnd_test) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ unsigned int space, in_flight; ++ ++ /* Set of states for which we are allowed to send data */ ++ if (!mptcp_sk_can_send(sk)) ++ return false; ++ ++ /* We do not send data on this subflow unless it is ++ * fully established, i.e. the 4th ack has been received. ++ */ ++ if (tp->mptcp->pre_established) ++ return false; ++ ++ if (tp->pf) ++ return false; ++ ++ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { ++ /* If SACK is disabled, and we got a loss, TCP does not exit ++ * the loss-state until something above high_seq has been acked. ++ * (see tcp_try_undo_recovery) ++ * ++ * high_seq is the snd_nxt at the moment of the RTO. As soon ++ * as we have an RTO, we won't push data on the subflow. ++ * Thus, snd_una can never go beyond high_seq. ++ */ ++ if (!tcp_is_reno(tp)) ++ return false; ++ else if (tp->snd_una != tp->high_seq) ++ return false; ++ } ++ ++ if (!tp->mptcp->fully_established) { ++ /* Make sure that we send in-order data */ ++ if (skb && tp->mptcp->second_packet && ++ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) ++ return false; ++ } ++ ++ if (!cwnd_test) ++ goto zero_wnd_test; ++ ++ in_flight = tcp_packets_in_flight(tp); ++ /* Not even a single spot in the cwnd */ ++ if (in_flight >= tp->snd_cwnd) ++ return false; ++ ++ /* Now, check if what is queued in the subflow's send-queue ++ * already fills the cwnd. ++ */ ++ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; ++ ++ if (tp->write_seq - tp->snd_nxt > space) ++ return false; ++ ++zero_wnd_test: ++ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) ++ return false; ++ ++ return true; ++} ++ ++/* Are we not allowed to reinject this skb on tp? */ ++static int mptcp_rr_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) ++{ ++ /* If the skb has already been enqueued in this sk, try to find ++ * another one. ++ */ ++ return skb && ++ /* Has the skb already been enqueued into this subsocket? */ ++ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; ++} ++ ++/* We just look for any subflow that is available */ ++static struct sock *rr_get_available_subflow(struct sock *meta_sk, ++ struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sock *sk = NULL, *bestsk = NULL, *backupsk = NULL; ++ struct mptcp_tcp_sock *mptcp; ++ ++ /* Answer data_fin on same subflow!!! */ ++ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && ++ skb && mptcp_is_data_fin(skb)) { ++ mptcp_for_each_sub(mpcb, mptcp) { ++ sk = mptcp_to_sock(mptcp); ++ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && ++ mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) ++ return sk; ++ } ++ } ++ ++ /* First, find the best subflow */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct tcp_sock *tp; ++ ++ sk = mptcp_to_sock(mptcp); ++ tp = tcp_sk(sk); ++ ++ if (!mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) ++ continue; ++ ++ if (mptcp_rr_dont_reinject_skb(tp, skb)) { ++ backupsk = sk; ++ continue; ++ } ++ ++ bestsk = sk; ++ } ++ ++ if (bestsk) { ++ sk = bestsk; ++ } else if (backupsk) { ++ /* It has been sent on all subflows once - let's give it a ++ * chance again by restarting its pathmask. ++ */ ++ if (skb) ++ TCP_SKB_CB(skb)->path_mask = 0; ++ sk = backupsk; ++ } ++ ++ return sk; ++} ++ ++/* Returns the next segment to be sent from the mptcp meta-queue. ++ * (chooses the reinject queue if any segment is waiting in it, otherwise, ++ * chooses the normal write queue). ++ * Sets *@reinject to 1 if the returned segment comes from the ++ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, ++ * and sets it to -1 if it is a meta-level retransmission to optimize the ++ * receive-buffer. ++ */ ++static struct sk_buff *__mptcp_rr_next_segment(const struct sock *meta_sk, int *reinject) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sk_buff *skb = NULL; ++ ++ *reinject = 0; ++ ++ /* If we are in fallback-mode, just take from the meta-send-queue */ ++ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) ++ return tcp_send_head(meta_sk); ++ ++ skb = skb_peek(&mpcb->reinject_queue); ++ ++ if (skb) ++ *reinject = 1; ++ else ++ skb = tcp_send_head(meta_sk); ++ return skb; ++} ++ ++static struct sk_buff *mptcp_rr_next_segment(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sock *choose_sk = NULL; ++ struct mptcp_tcp_sock *mptcp; ++ struct sk_buff *skb = __mptcp_rr_next_segment(meta_sk, reinject); ++ unsigned char split = num_segments; ++ unsigned char iter = 0, full_subs = 0; ++ ++ /* As we set it, we have to reset it as well. */ ++ *limit = 0; ++ ++ if (!skb) ++ return NULL; ++ ++ if (*reinject) { ++ *subsk = rr_get_available_subflow(meta_sk, skb, false); ++ if (!*subsk) ++ return NULL; ++ ++ return skb; ++ } ++ ++retry: ++ ++ /* First, we look for a subflow who is currently being used */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp_it = tcp_sk(sk_it); ++ struct rrsched_priv *rr_p = rrsched_get_priv(tp_it); ++ ++ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) ++ continue; ++ ++ iter++; ++ ++ /* Is this subflow currently being used? */ ++ if (rr_p->quota > 0 && rr_p->quota < num_segments) { ++ split = num_segments - rr_p->quota; ++ choose_sk = sk_it; ++ goto found; ++ } ++ ++ /* Or, it's totally unused */ ++ if (!rr_p->quota) { ++ split = num_segments; ++ choose_sk = sk_it; ++ } ++ ++ /* Or, it must then be fully used */ ++ if (rr_p->quota >= num_segments) ++ full_subs++; ++ } ++ ++ /* All considered subflows have a full quota, and we considered at ++ * least one. ++ */ ++ if (iter && iter == full_subs) { ++ /* So, we restart this round by setting quota to 0 and retry ++ * to find a subflow. ++ */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk_it = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp_it = tcp_sk(sk_it); ++ struct rrsched_priv *rr_p = rrsched_get_priv(tp_it); ++ ++ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) ++ continue; ++ ++ rr_p->quota = 0; ++ } ++ ++ goto retry; ++ } ++ ++found: ++ if (choose_sk) { ++ unsigned int mss_now; ++ struct tcp_sock *choose_tp = tcp_sk(choose_sk); ++ struct rrsched_priv *rr_p = rrsched_get_priv(choose_tp); ++ ++ if (!mptcp_rr_is_available(choose_sk, skb, false, true)) ++ return NULL; ++ ++ *subsk = choose_sk; ++ mss_now = tcp_current_mss(*subsk); ++ *limit = split * mss_now; ++ ++ if (skb->len > mss_now) ++ rr_p->quota += DIV_ROUND_UP(skb->len, mss_now); ++ else ++ rr_p->quota++; ++ ++ return skb; ++ } ++ ++ return NULL; ++} ++ ++static struct mptcp_sched_ops mptcp_sched_rr = { ++ .get_subflow = rr_get_available_subflow, ++ .next_segment = mptcp_rr_next_segment, ++ .name = "roundrobin", ++ .owner = THIS_MODULE, ++}; ++ ++static int __init rr_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct rrsched_priv) > MPTCP_SCHED_SIZE); ++ ++ if (mptcp_register_scheduler(&mptcp_sched_rr)) ++ return -1; ++ ++ return 0; ++} ++ ++static void rr_unregister(void) ++{ ++ mptcp_unregister_scheduler(&mptcp_sched_rr); ++} ++ ++module_init(rr_register); ++module_exit(rr_unregister); ++ ++MODULE_AUTHOR("Christoph Paasch"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("ROUNDROBIN MPTCP"); ++MODULE_VERSION("0.89"); +diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c +--- linux-5.4/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,634 @@ ++/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ ++ ++#include ++#include ++#include ++ ++static DEFINE_SPINLOCK(mptcp_sched_list_lock); ++static LIST_HEAD(mptcp_sched_list); ++ ++struct defsched_priv { ++ u32 last_rbuf_opti; ++}; ++ ++static struct defsched_priv *defsched_get_priv(const struct tcp_sock *tp) ++{ ++ return (struct defsched_priv *)&tp->mptcp->mptcp_sched[0]; ++} ++ ++bool mptcp_is_def_unavailable(struct sock *sk) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ ++ /* Set of states for which we are allowed to send data */ ++ if (!mptcp_sk_can_send(sk)) ++ return true; ++ ++ /* We do not send data on this subflow unless it is ++ * fully established, i.e. the 4th ack has been received. ++ */ ++ if (tp->mptcp->pre_established) ++ return true; ++ ++ if (tp->pf) ++ return true; ++ ++ return false; ++} ++EXPORT_SYMBOL_GPL(mptcp_is_def_unavailable); ++ ++static bool mptcp_is_temp_unavailable(struct sock *sk, ++ const struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ unsigned int mss_now, space, in_flight; ++ ++ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { ++ /* If SACK is disabled, and we got a loss, TCP does not exit ++ * the loss-state until something above high_seq has been ++ * acked. (see tcp_try_undo_recovery) ++ * ++ * high_seq is the snd_nxt at the moment of the RTO. As soon ++ * as we have an RTO, we won't push data on the subflow. ++ * Thus, snd_una can never go beyond high_seq. ++ */ ++ if (!tcp_is_reno(tp)) ++ return true; ++ else if (tp->snd_una != tp->high_seq) ++ return true; ++ } ++ ++ if (!tp->mptcp->fully_established) { ++ /* Make sure that we send in-order data */ ++ if (skb && tp->mptcp->second_packet && ++ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) ++ return true; ++ } ++ ++ in_flight = tcp_packets_in_flight(tp); ++ /* Not even a single spot in the cwnd */ ++ if (in_flight >= tp->snd_cwnd) ++ return true; ++ ++ /* Now, check if what is queued in the subflow's send-queue ++ * already fills the cwnd. ++ */ ++ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; ++ ++ if (tp->write_seq - tp->snd_nxt > space) ++ return true; ++ ++ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) ++ return true; ++ ++ mss_now = tcp_current_mss(sk); ++ ++ /* Don't send on this subflow if we bypass the allowed send-window at ++ * the per-subflow level. Similar to tcp_snd_wnd_test, but manually ++ * calculated end_seq (because here at this point end_seq is still at ++ * the meta-level). ++ */ ++ if (skb && zero_wnd_test && ++ after(tp->write_seq + min(skb->len, mss_now), tcp_wnd_end(tp))) ++ return true; ++ ++ return false; ++} ++ ++/* Is the sub-socket sk available to send the skb? */ ++bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ return !mptcp_is_def_unavailable(sk) && ++ !mptcp_is_temp_unavailable(sk, skb, zero_wnd_test); ++} ++EXPORT_SYMBOL_GPL(mptcp_is_available); ++ ++/* Are we not allowed to reinject this skb on tp? */ ++static int mptcp_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) ++{ ++ /* If the skb has already been enqueued in this sk, try to find ++ * another one. ++ */ ++ return skb && ++ /* Has the skb already been enqueued into this subsocket? */ ++ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; ++} ++ ++bool subflow_is_backup(const struct tcp_sock *tp) ++{ ++ return tp->mptcp->rcv_low_prio || tp->mptcp->low_prio; ++} ++EXPORT_SYMBOL_GPL(subflow_is_backup); ++ ++bool subflow_is_active(const struct tcp_sock *tp) ++{ ++ return !tp->mptcp->rcv_low_prio && !tp->mptcp->low_prio; ++} ++EXPORT_SYMBOL_GPL(subflow_is_active); ++ ++/* Generic function to iterate over used and unused subflows and to select the ++ * best one ++ */ ++static struct sock ++*get_subflow_from_selectors(struct mptcp_cb *mpcb, struct sk_buff *skb, ++ bool (*selector)(const struct tcp_sock *), ++ bool zero_wnd_test, bool *force) ++{ ++ struct sock *bestsk = NULL; ++ u32 min_srtt = 0xffffffff; ++ bool found_unused = false; ++ bool found_unused_una = false; ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ struct tcp_sock *tp = tcp_sk(sk); ++ bool unused = false; ++ ++ /* First, we choose only the wanted sks */ ++ if (!(*selector)(tp)) ++ continue; ++ ++ if (!mptcp_dont_reinject_skb(tp, skb)) ++ unused = true; ++ else if (found_unused) ++ /* If a unused sk was found previously, we continue - ++ * no need to check used sks anymore. ++ */ ++ continue; ++ ++ if (mptcp_is_def_unavailable(sk)) ++ continue; ++ ++ if (mptcp_is_temp_unavailable(sk, skb, zero_wnd_test)) { ++ if (unused) ++ found_unused_una = true; ++ continue; ++ } ++ ++ if (unused) { ++ if (!found_unused) { ++ /* It's the first time we encounter an unused ++ * sk - thus we reset the bestsk (which might ++ * have been set to a used sk). ++ */ ++ min_srtt = 0xffffffff; ++ bestsk = NULL; ++ } ++ found_unused = true; ++ } ++ ++ if (tp->srtt_us < min_srtt) { ++ min_srtt = tp->srtt_us; ++ bestsk = sk; ++ } ++ } ++ ++ if (bestsk) { ++ /* The force variable is used to mark the returned sk as ++ * previously used or not-used. ++ */ ++ if (found_unused) ++ *force = true; ++ else ++ *force = false; ++ } else { ++ /* The force variable is used to mark if there are temporally ++ * unavailable not-used sks. ++ */ ++ if (found_unused_una) ++ *force = true; ++ else ++ *force = false; ++ } ++ ++ return bestsk; ++} ++ ++/* This is the scheduler. This function decides on which flow to send ++ * a given MSS. If all subflows are found to be busy, NULL is returned ++ * The flow is selected based on the shortest RTT. ++ * If all paths have full cong windows, we simply return NULL. ++ * ++ * Additionally, this function is aware of the backup-subflows. ++ */ ++struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sock *sk; ++ bool looping = false, force; ++ ++ /* Answer data_fin on same subflow!!! */ ++ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && ++ skb && mptcp_is_data_fin(skb)) { ++ struct mptcp_tcp_sock *mptcp; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ sk = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && ++ mptcp_is_available(sk, skb, zero_wnd_test)) ++ return sk; ++ } ++ } ++ ++ /* Find the best subflow */ ++restart: ++ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_active, ++ zero_wnd_test, &force); ++ if (force) ++ /* one unused active sk or one NULL sk when there is at least ++ * one temporally unavailable unused active sk ++ */ ++ return sk; ++ ++ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_backup, ++ zero_wnd_test, &force); ++ if (!force && skb) { ++ /* one used backup sk or one NULL sk where there is no one ++ * temporally unavailable unused backup sk ++ * ++ * the skb passed through all the available active and backups ++ * sks, so clean the path mask ++ */ ++ TCP_SKB_CB(skb)->path_mask = 0; ++ ++ if (!looping) { ++ looping = true; ++ goto restart; ++ } ++ } ++ return sk; ++} ++EXPORT_SYMBOL_GPL(get_available_subflow); ++ ++static struct sk_buff *mptcp_rcv_buf_optimization(struct sock *sk, int penal) ++{ ++ struct sock *meta_sk; ++ const struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_tcp_sock *mptcp; ++ struct sk_buff *skb_head; ++ struct defsched_priv *def_p = defsched_get_priv(tp); ++ ++ meta_sk = mptcp_meta_sk(sk); ++ skb_head = tcp_rtx_queue_head(meta_sk); ++ ++ if (!skb_head) ++ return NULL; ++ ++ /* If penalization is optional (coming from mptcp_next_segment() and ++ * We are not send-buffer-limited we do not penalize. The retransmission ++ * is just an optimization to fix the idle-time due to the delay before ++ * we wake up the application. ++ */ ++ if (!penal && sk_stream_memory_free(meta_sk)) ++ goto retrans; ++ ++ /* Only penalize again after an RTT has elapsed */ ++ if (tcp_jiffies32 - def_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) ++ goto retrans; ++ ++ /* Half the cwnd of the slow flows */ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ struct tcp_sock *tp_it = mptcp->tp; ++ ++ if (tp_it != tp && ++ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { ++ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { ++ u32 prior_cwnd = tp_it->snd_cwnd; ++ ++ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); ++ ++ /* If in slow start, do not reduce the ssthresh */ ++ if (prior_cwnd >= tp_it->snd_ssthresh) ++ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); ++ ++ def_p->last_rbuf_opti = tcp_jiffies32; ++ } ++ } ++ } ++ ++retrans: ++ ++ /* Segment not yet injected into this path? Take it!!! */ ++ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { ++ bool do_retrans = false; ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ struct tcp_sock *tp_it = mptcp->tp; ++ ++ if (tp_it != tp && ++ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { ++ if (tp_it->snd_cwnd <= 4) { ++ do_retrans = true; ++ break; ++ } ++ ++ if (4 * tp->srtt_us >= tp_it->srtt_us) { ++ do_retrans = false; ++ break; ++ } else { ++ do_retrans = true; ++ } ++ } ++ } ++ ++ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { ++ trace_mptcp_retransmit(sk, skb_head); ++ return skb_head; ++ } ++ } ++ return NULL; ++} ++ ++/* Returns the next segment to be sent from the mptcp meta-queue. ++ * (chooses the reinject queue if any segment is waiting in it, otherwise, ++ * chooses the normal write queue). ++ * Sets *@reinject to 1 if the returned segment comes from the ++ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, ++ * and sets it to -1 if it is a meta-level retransmission to optimize the ++ * receive-buffer. ++ */ ++static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sk_buff *skb = NULL; ++ ++ *reinject = 0; ++ ++ /* If we are in fallback-mode, just take from the meta-send-queue */ ++ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) ++ return tcp_send_head(meta_sk); ++ ++ skb = skb_peek(&mpcb->reinject_queue); ++ ++ if (skb) { ++ *reinject = 1; ++ } else { ++ skb = tcp_send_head(meta_sk); ++ ++ if (!skb && meta_sk->sk_socket && ++ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && ++ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { ++ struct sock *subsk = get_available_subflow(meta_sk, NULL, ++ false); ++ if (!subsk) ++ return NULL; ++ ++ skb = mptcp_rcv_buf_optimization(subsk, 0); ++ if (skb) ++ *reinject = -1; ++ } ++ } ++ return skb; ++} ++ ++static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit) ++{ ++ struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); ++ unsigned int mss_now; ++ struct tcp_sock *subtp; ++ u16 gso_max_segs; ++ u32 max_len, max_segs, window, needed; ++ ++ /* As we set it, we have to reset it as well. */ ++ *limit = 0; ++ ++ if (!skb) ++ return NULL; ++ ++ *subsk = get_available_subflow(meta_sk, skb, false); ++ if (!*subsk) ++ return NULL; ++ ++ subtp = tcp_sk(*subsk); ++ mss_now = tcp_current_mss(*subsk); ++ ++ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { ++ skb = mptcp_rcv_buf_optimization(*subsk, 1); ++ if (skb) ++ *reinject = -1; ++ else ++ return NULL; ++ } ++ ++ /* No splitting required, as we will only send one single segment */ ++ if (skb->len <= mss_now) ++ return skb; ++ ++ /* The following is similar to tcp_mss_split_point, but ++ * we do not care about nagle, because we will anyways ++ * use TCP_NAGLE_PUSH, which overrides this. ++ * ++ * So, we first limit according to the cwnd/gso-size and then according ++ * to the subflow's window. ++ */ ++ ++ gso_max_segs = (*subsk)->sk_gso_max_segs; ++ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ ++ gso_max_segs = 1; ++ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); ++ if (!max_segs) ++ return NULL; ++ ++ max_len = mss_now * max_segs; ++ window = tcp_wnd_end(subtp) - subtp->write_seq; ++ ++ needed = min(skb->len, window); ++ if (max_len <= skb->len) ++ /* Take max_win, which is actually the cwnd/gso-size */ ++ *limit = max_len; ++ else ++ /* Or, take the window */ ++ *limit = needed; ++ ++ return skb; ++} ++ ++static void defsched_init(struct sock *sk) ++{ ++ struct defsched_priv *def_p = defsched_get_priv(tcp_sk(sk)); ++ ++ def_p->last_rbuf_opti = tcp_jiffies32; ++} ++ ++struct mptcp_sched_ops mptcp_sched_default = { ++ .get_subflow = get_available_subflow, ++ .next_segment = mptcp_next_segment, ++ .init = defsched_init, ++ .name = "default", ++ .owner = THIS_MODULE, ++}; ++ ++static struct mptcp_sched_ops *mptcp_sched_find(const char *name) ++{ ++ struct mptcp_sched_ops *e; ++ ++ list_for_each_entry_rcu(e, &mptcp_sched_list, list) { ++ if (strcmp(e->name, name) == 0) ++ return e; ++ } ++ ++ return NULL; ++} ++ ++int mptcp_register_scheduler(struct mptcp_sched_ops *sched) ++{ ++ int ret = 0; ++ ++ if (!sched->get_subflow || !sched->next_segment) ++ return -EINVAL; ++ ++ spin_lock(&mptcp_sched_list_lock); ++ if (mptcp_sched_find(sched->name)) { ++ pr_notice("%s already registered\n", sched->name); ++ ret = -EEXIST; ++ } else { ++ list_add_tail_rcu(&sched->list, &mptcp_sched_list); ++ pr_info("%s registered\n", sched->name); ++ } ++ spin_unlock(&mptcp_sched_list_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(mptcp_register_scheduler); ++ ++void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched) ++{ ++ spin_lock(&mptcp_sched_list_lock); ++ list_del_rcu(&sched->list); ++ spin_unlock(&mptcp_sched_list_lock); ++ ++ /* Wait for outstanding readers to complete before the ++ * module gets removed entirely. ++ * ++ * A try_module_get() should fail by now as our module is ++ * in "going" state since no refs are held anymore and ++ * module_exit() handler being called. ++ */ ++ synchronize_rcu(); ++} ++EXPORT_SYMBOL_GPL(mptcp_unregister_scheduler); ++ ++void mptcp_get_default_scheduler(char *name) ++{ ++ struct mptcp_sched_ops *sched; ++ ++ BUG_ON(list_empty(&mptcp_sched_list)); ++ ++ rcu_read_lock(); ++ sched = list_entry(mptcp_sched_list.next, struct mptcp_sched_ops, list); ++ strncpy(name, sched->name, MPTCP_SCHED_NAME_MAX); ++ rcu_read_unlock(); ++} ++ ++int mptcp_set_default_scheduler(const char *name) ++{ ++ struct mptcp_sched_ops *sched; ++ int ret = -ENOENT; ++ ++ spin_lock(&mptcp_sched_list_lock); ++ sched = mptcp_sched_find(name); ++#ifdef CONFIG_MODULES ++ if (!sched && capable(CAP_NET_ADMIN)) { ++ spin_unlock(&mptcp_sched_list_lock); ++ ++ request_module("mptcp_%s", name); ++ spin_lock(&mptcp_sched_list_lock); ++ sched = mptcp_sched_find(name); ++ } ++#endif ++ ++ if (sched) { ++ list_move(&sched->list, &mptcp_sched_list); ++ ret = 0; ++ } else { ++ pr_info("%s is not available\n", name); ++ } ++ spin_unlock(&mptcp_sched_list_lock); ++ ++ return ret; ++} ++ ++/* Must be called with rcu lock held */ ++static struct mptcp_sched_ops *__mptcp_sched_find_autoload(const char *name) ++{ ++ struct mptcp_sched_ops *sched = mptcp_sched_find(name); ++#ifdef CONFIG_MODULES ++ if (!sched && capable(CAP_NET_ADMIN)) { ++ rcu_read_unlock(); ++ request_module("mptcp_%s", name); ++ rcu_read_lock(); ++ sched = mptcp_sched_find(name); ++ } ++#endif ++ return sched; ++} ++ ++void mptcp_init_scheduler(struct mptcp_cb *mpcb) ++{ ++ struct mptcp_sched_ops *sched; ++ struct sock *meta_sk = mpcb->meta_sk; ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ ++ rcu_read_lock(); ++ /* if scheduler was set using socket option */ ++ if (meta_tp->mptcp_sched_setsockopt) { ++ sched = __mptcp_sched_find_autoload(meta_tp->mptcp_sched_name); ++ if (sched && try_module_get(sched->owner)) { ++ mpcb->sched_ops = sched; ++ goto out; ++ } ++ } ++ ++ list_for_each_entry_rcu(sched, &mptcp_sched_list, list) { ++ if (try_module_get(sched->owner)) { ++ mpcb->sched_ops = sched; ++ break; ++ } ++ } ++out: ++ rcu_read_unlock(); ++} ++ ++/* Change scheduler for socket */ ++int mptcp_set_scheduler(struct sock *sk, const char *name) ++{ ++ struct mptcp_sched_ops *sched; ++ int err = 0; ++ ++ rcu_read_lock(); ++ sched = __mptcp_sched_find_autoload(name); ++ ++ if (!sched) { ++ err = -ENOENT; ++ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { ++ err = -EPERM; ++ } else { ++ strcpy(tcp_sk(sk)->mptcp_sched_name, name); ++ tcp_sk(sk)->mptcp_sched_setsockopt = 1; ++ } ++ rcu_read_unlock(); ++ ++ return err; ++} ++ ++/* Manage refcounts on socket close. */ ++void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb) ++{ ++ module_put(mpcb->sched_ops->owner); ++} ++ ++/* Set default value from kernel configuration at bootup */ ++static int __init mptcp_scheduler_default(void) ++{ ++ BUILD_BUG_ON(sizeof(struct defsched_priv) > MPTCP_SCHED_SIZE); ++ ++ return mptcp_set_default_scheduler(CONFIG_DEFAULT_MPTCP_SCHED); ++} ++late_initcall(mptcp_scheduler_default); +diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c +--- linux-5.4/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-02-20 18:07:47.000000000 +0100 +@@ -0,0 +1,271 @@ ++/* ++ * MPTCP implementation - WEIGHTED VEGAS ++ * ++ * Algorithm design: ++ * Yu Cao ++ * Mingwei Xu ++ * Xiaoming Fu ++ * ++ * Implementation: ++ * Yu Cao ++ * Enhuan Dong ++ * ++ * Ported to the official MPTCP-kernel: ++ * Christoph Paasch ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int initial_alpha = 2; ++static int total_alpha = 10; ++static int gamma = 1; ++ ++module_param(initial_alpha, int, 0644); ++MODULE_PARM_DESC(initial_alpha, "initial alpha for all subflows"); ++module_param(total_alpha, int, 0644); ++MODULE_PARM_DESC(total_alpha, "total alpha for all subflows"); ++module_param(gamma, int, 0644); ++MODULE_PARM_DESC(gamma, "limit on increase (scale by 2)"); ++ ++#define MPTCP_WVEGAS_SCALE 16 ++ ++/* wVegas variables */ ++struct wvegas { ++ u32 beg_snd_nxt; /* right edge during last RTT */ ++ u8 doing_wvegas_now;/* if true, do wvegas for this RTT */ ++ ++ u16 cnt_rtt; /* # of RTTs measured within last RTT */ ++ u32 sampled_rtt; /* cumulative RTTs measured within last RTT (in usec) */ ++ u32 base_rtt; /* the min of all wVegas RTT measurements seen (in usec) */ ++ ++ u64 instant_rate; /* cwnd / srtt_us, unit: pkts/us * 2^16 */ ++ u64 weight; /* the ratio of subflow's rate to the total rate, * 2^16 */ ++ int alpha; /* alpha for each subflows */ ++ ++ u32 queue_delay; /* queue delay*/ ++}; ++ ++ ++static inline u64 mptcp_wvegas_scale(u32 val, int scale) ++{ ++ return (u64) val << scale; ++} ++ ++static void wvegas_enable(const struct sock *sk) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ struct wvegas *wvegas = inet_csk_ca(sk); ++ ++ wvegas->doing_wvegas_now = 1; ++ ++ wvegas->beg_snd_nxt = tp->snd_nxt; ++ ++ wvegas->cnt_rtt = 0; ++ wvegas->sampled_rtt = 0; ++ ++ wvegas->instant_rate = 0; ++ wvegas->alpha = initial_alpha; ++ wvegas->weight = mptcp_wvegas_scale(1, MPTCP_WVEGAS_SCALE); ++ ++ wvegas->queue_delay = 0; ++} ++ ++static inline void wvegas_disable(const struct sock *sk) ++{ ++ struct wvegas *wvegas = inet_csk_ca(sk); ++ ++ wvegas->doing_wvegas_now = 0; ++} ++ ++static void mptcp_wvegas_init(struct sock *sk) ++{ ++ struct wvegas *wvegas = inet_csk_ca(sk); ++ ++ wvegas->base_rtt = 0x7fffffff; ++ wvegas_enable(sk); ++} ++ ++static inline u64 mptcp_wvegas_rate(u32 cwnd, u32 rtt_us) ++{ ++ return div_u64(mptcp_wvegas_scale(cwnd, MPTCP_WVEGAS_SCALE), rtt_us); ++} ++ ++static void mptcp_wvegas_pkts_acked(struct sock *sk, ++ const struct ack_sample *sample) ++{ ++ struct wvegas *wvegas = inet_csk_ca(sk); ++ u32 vrtt; ++ ++ if (sample->rtt_us < 0) ++ return; ++ ++ vrtt = sample->rtt_us + 1; ++ ++ if (vrtt < wvegas->base_rtt) ++ wvegas->base_rtt = vrtt; ++ ++ wvegas->sampled_rtt += vrtt; ++ wvegas->cnt_rtt++; ++} ++ ++static void mptcp_wvegas_state(struct sock *sk, u8 ca_state) ++{ ++ if (ca_state == TCP_CA_Open) ++ wvegas_enable(sk); ++ else ++ wvegas_disable(sk); ++} ++ ++static void mptcp_wvegas_cwnd_event(struct sock *sk, enum tcp_ca_event event) ++{ ++ if (event == CA_EVENT_CWND_RESTART) { ++ mptcp_wvegas_init(sk); ++ } else if (event == CA_EVENT_LOSS) { ++ struct wvegas *wvegas = inet_csk_ca(sk); ++ wvegas->instant_rate = 0; ++ } ++} ++ ++static inline u32 mptcp_wvegas_ssthresh(const struct tcp_sock *tp) ++{ ++ return min(tp->snd_ssthresh, tp->snd_cwnd); ++} ++ ++static u64 mptcp_wvegas_weight(const struct mptcp_cb *mpcb, const struct sock *sk) ++{ ++ u64 total_rate = 0; ++ const struct wvegas *wvegas = inet_csk_ca(sk); ++ struct mptcp_tcp_sock *mptcp; ++ ++ if (!mpcb) ++ return wvegas->weight; ++ ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sub_sk = mptcp_to_sock(mptcp); ++ struct wvegas *sub_wvegas = inet_csk_ca(sub_sk); ++ ++ /* sampled_rtt is initialized by 0 */ ++ if (mptcp_sk_can_send(sub_sk) && (sub_wvegas->sampled_rtt > 0)) ++ total_rate += sub_wvegas->instant_rate; ++ } ++ ++ if (total_rate && wvegas->instant_rate) ++ return div64_u64(mptcp_wvegas_scale(wvegas->instant_rate, MPTCP_WVEGAS_SCALE), total_rate); ++ else ++ return wvegas->weight; ++} ++ ++static void mptcp_wvegas_cong_avoid(struct sock *sk, u32 ack, u32 acked) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct wvegas *wvegas = inet_csk_ca(sk); ++ ++ if (!wvegas->doing_wvegas_now) { ++ tcp_reno_cong_avoid(sk, ack, acked); ++ return; ++ } ++ ++ if (after(ack, wvegas->beg_snd_nxt)) { ++ wvegas->beg_snd_nxt = tp->snd_nxt; ++ ++ if (wvegas->cnt_rtt <= 2) { ++ tcp_reno_cong_avoid(sk, ack, acked); ++ } else { ++ u32 rtt, diff, q_delay; ++ u64 target_cwnd; ++ ++ rtt = wvegas->sampled_rtt / wvegas->cnt_rtt; ++ target_cwnd = div_u64(((u64)tp->snd_cwnd * wvegas->base_rtt), rtt); ++ ++ diff = div_u64((u64)tp->snd_cwnd * (rtt - wvegas->base_rtt), rtt); ++ ++ if (diff > gamma && tcp_in_slow_start(tp)) { ++ tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1); ++ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); ++ ++ } else if (tcp_in_slow_start(tp)) { ++ tcp_slow_start(tp, acked); ++ } else { ++ if (diff >= wvegas->alpha) { ++ wvegas->instant_rate = mptcp_wvegas_rate(tp->snd_cwnd, rtt); ++ wvegas->weight = mptcp_wvegas_weight(tp->mpcb, sk); ++ wvegas->alpha = max(2U, (u32)((wvegas->weight * total_alpha) >> MPTCP_WVEGAS_SCALE)); ++ } ++ if (diff > wvegas->alpha) { ++ tp->snd_cwnd--; ++ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); ++ } else if (diff < wvegas->alpha) { ++ tp->snd_cwnd++; ++ } ++ ++ /* Try to drain link queue if needed*/ ++ q_delay = rtt - wvegas->base_rtt; ++ if ((wvegas->queue_delay == 0) || (wvegas->queue_delay > q_delay)) ++ wvegas->queue_delay = q_delay; ++ ++ if (q_delay >= 2 * wvegas->queue_delay) { ++ u32 backoff_factor = div_u64(mptcp_wvegas_scale(wvegas->base_rtt, MPTCP_WVEGAS_SCALE), 2 * rtt); ++ tp->snd_cwnd = ((u64)tp->snd_cwnd * backoff_factor) >> MPTCP_WVEGAS_SCALE; ++ wvegas->queue_delay = 0; ++ } ++ } ++ ++ if (tp->snd_cwnd < 2) ++ tp->snd_cwnd = 2; ++ else if (tp->snd_cwnd > tp->snd_cwnd_clamp) ++ tp->snd_cwnd = tp->snd_cwnd_clamp; ++ ++ tp->snd_ssthresh = tcp_current_ssthresh(sk); ++ } ++ ++ wvegas->cnt_rtt = 0; ++ wvegas->sampled_rtt = 0; ++ } ++ /* Use normal slow start */ ++ else if (tcp_in_slow_start(tp)) ++ tcp_slow_start(tp, acked); ++} ++ ++ ++static struct tcp_congestion_ops mptcp_wvegas __read_mostly = { ++ .init = mptcp_wvegas_init, ++ .ssthresh = tcp_reno_ssthresh, ++ .cong_avoid = mptcp_wvegas_cong_avoid, ++ .undo_cwnd = tcp_reno_undo_cwnd, ++ .pkts_acked = mptcp_wvegas_pkts_acked, ++ .set_state = mptcp_wvegas_state, ++ .cwnd_event = mptcp_wvegas_cwnd_event, ++ ++ .owner = THIS_MODULE, ++ .name = "wvegas", ++}; ++ ++static int __init mptcp_wvegas_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct wvegas) > ICSK_CA_PRIV_SIZE); ++ tcp_register_congestion_control(&mptcp_wvegas); ++ return 0; ++} ++ ++static void __exit mptcp_wvegas_unregister(void) ++{ ++ tcp_unregister_congestion_control(&mptcp_wvegas); ++} ++ ++module_init(mptcp_wvegas_register); ++module_exit(mptcp_wvegas_unregister); ++ ++MODULE_AUTHOR("Yu Cao, Enhuan Dong"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MPTCP wVegas"); ++MODULE_VERSION("0.1"); +diff -aurN linux-5.4/tools/include/uapi/linux/bpf.h mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h +--- linux-5.4/tools/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-02-20 18:07:47.000000000 +0100 +@@ -3438,6 +3438,7 @@ + BPF_TCP_LISTEN, + BPF_TCP_CLOSING, /* Now a valid state */ + BPF_TCP_NEW_SYN_RECV, ++ BPF_TCP_RST_WAIT, + + BPF_TCP_MAX_STATES /* Leave at the end! */ + }; diff --git a/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch b/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch new file mode 100644 index 00000000..d9cf6251 --- /dev/null +++ b/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch @@ -0,0 +1,434 @@ +From 35f41229b58cb8c2611207827aa4f658b82db67e Mon Sep 17 00:00:00 2001 +From: Daniel Weber +Date: Mon, 5 Aug 2019 14:02:30 +0200 +Subject: [PATCH] mptcp: Earliest Completion First (ECF) Scheduler + +This scheduler works much like the default MPTCP scheduler. It always +prefers the subflow with the smallest round-trip-time that is available. + +Signed-off-by: Daniel Weber +--- + net/mptcp/Kconfig | 6 + + net/mptcp/Makefile | 1 + + net/mptcp/mptcp_ecf.c | 384 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 391 insertions(+) + create mode 100644 net/mptcp/mptcp_ecf.c + +diff --git a/net/mptcp/Kconfig b/net/mptcp/Kconfig +index d22b7b47860f..dd1f859f1070 100644 +--- a/net/mptcp/Kconfig ++++ b/net/mptcp/Kconfig +@@ -109,6 +109,12 @@ config MPTCP_REDUNDANT + This scheduler sends all packets redundantly over all subflows to decreases + latency and jitter on the cost of lower throughput. + ++config MPTCP_ECF ++ tristate "MPTCP ECF" ++ depends on (MPTCP=y) ++ ---help--- ++ This is an experimental Earliest Completion First (ECF) scheduler. ++ + choice + prompt "Default MPTCP Scheduler" + default DEFAULT +diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile +index 82a2d4d945ae..369248a2f68e 100644 +--- a/net/mptcp/Makefile ++++ b/net/mptcp/Makefile +@@ -20,5 +20,6 @@ obj-$(CONFIG_MPTCP_NETLINK) += mptcp_netlink.o + obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o + obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o + obj-$(CONFIG_MPTCP_BLEST) += mptcp_blest.o ++obj-$(CONFIG_MPTCP_ECF) += mptcp_ecf.o + + mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o +diff --git a/net/mptcp/mptcp_ecf.c b/net/mptcp/mptcp_ecf.c +new file mode 100644 +index 000000000000..d61f4d2ad375 +--- /dev/null ++++ b/net/mptcp/mptcp_ecf.c +@@ -0,0 +1,384 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* MPTCP ECF Scheduler ++ * ++ * Algorithm Design: ++ * Yeon-sup Lim ++ * Don Towsley ++ * Erich M. Nahum ++ * Richard J. Gibbens ++ * ++ * Initial Implementation: ++ * Yeon-sup Lim ++ * ++ * Additional Authors: ++ * Daniel Weber ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++ ++static unsigned int r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ ++module_param(r_beta, int, 0644); ++MODULE_PARM_DESC(r_beta, "beta for ECF"); ++ ++struct ecfsched_priv { ++ u32 last_rbuf_opti; ++}; ++ ++struct ecfsched_cb { ++ u32 switching_margin; /* this is "waiting" in algorithm description */ ++}; ++ ++static struct ecfsched_priv *ecfsched_get_priv(const struct tcp_sock *tp) ++{ ++ return (struct ecfsched_priv *)&tp->mptcp->mptcp_sched[0]; ++} ++ ++static struct ecfsched_cb *ecfsched_get_cb(const struct tcp_sock *tp) ++{ ++ return (struct ecfsched_cb *)&tp->mpcb->mptcp_sched[0]; ++} ++ ++/* This is the ECF scheduler. This function decides on which flow to send ++ * a given MSS. If all subflows are found to be busy or the currently best ++ * subflow is estimated to be slower than waiting for minsk, NULL is returned. ++ */ ++static struct sock *ecf_get_available_subflow(struct sock *meta_sk, ++ struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sock *bestsk, *minsk = NULL; ++ struct tcp_sock *besttp; ++ struct mptcp_tcp_sock *mptcp; ++ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(meta_sk)); ++ u32 min_srtt = U32_MAX; ++ u32 sub_sndbuf = 0; ++ u32 sub_packets_out = 0; ++ ++ /* Answer data_fin on same subflow!!! */ ++ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && ++ skb && mptcp_is_data_fin(skb)) { ++ mptcp_for_each_sub(mpcb, mptcp) { ++ bestsk = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(bestsk)->mptcp->path_index == mpcb->dfin_path_index && ++ mptcp_is_available(bestsk, skb, zero_wnd_test)) ++ return bestsk; ++ } ++ } ++ ++ /* First, find the overall best (fastest) subflow */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ bestsk = mptcp_to_sock(mptcp); ++ besttp = tcp_sk(bestsk); ++ ++ /* Set of states for which we are allowed to send data */ ++ if (!mptcp_sk_can_send(bestsk)) ++ continue; ++ ++ /* We do not send data on this subflow unless it is ++ * fully established, i.e. the 4th ack has been received. ++ */ ++ if (besttp->mptcp->pre_established) ++ continue; ++ ++ sub_sndbuf += bestsk->sk_wmem_queued; ++ sub_packets_out += besttp->packets_out; ++ ++ /* record minimal rtt */ ++ if (besttp->srtt_us < min_srtt) { ++ min_srtt = besttp->srtt_us; ++ minsk = bestsk; ++ } ++ } ++ ++ /* find the current best subflow according to the default scheduler */ ++ bestsk = get_available_subflow(meta_sk, skb, zero_wnd_test); ++ ++ /* if we decided to use a slower flow, we have the option of not using it at all */ ++ if (bestsk && minsk && bestsk != minsk) { ++ u32 mss = tcp_current_mss(bestsk); /* assuming equal MSS */ ++ u32 sndbuf_meta = meta_sk->sk_wmem_queued; ++ u32 sndbuf_minus = sub_sndbuf; ++ u32 sndbuf = 0; ++ ++ u32 cwnd_f = tcp_sk(minsk)->snd_cwnd; ++ u32 srtt_f = tcp_sk(minsk)->srtt_us >> 3; ++ u32 rttvar_f = tcp_sk(minsk)->rttvar_us >> 1; ++ ++ u32 cwnd_s = tcp_sk(bestsk)->snd_cwnd; ++ u32 srtt_s = tcp_sk(bestsk)->srtt_us >> 3; ++ u32 rttvar_s = tcp_sk(bestsk)->rttvar_us >> 1; ++ ++ u32 delta = max(rttvar_f, rttvar_s); ++ ++ u32 x_f; ++ u64 lhs, rhs; /* to avoid overflow, using u64 */ ++ ++ if (tcp_sk(meta_sk)->packets_out > sub_packets_out) ++ sndbuf_minus += (tcp_sk(meta_sk)->packets_out - sub_packets_out) * mss; ++ ++ if (sndbuf_meta > sndbuf_minus) ++ sndbuf = sndbuf_meta - sndbuf_minus; ++ ++ /* we have something to send. ++ * at least one time tx over fastest subflow is required ++ */ ++ x_f = sndbuf > cwnd_f * mss ? sndbuf : cwnd_f * mss; ++ lhs = srtt_f * (x_f + cwnd_f * mss); ++ rhs = cwnd_f * mss * (srtt_s + delta); ++ ++ if (r_beta * lhs < r_beta * rhs + ecf_cb->switching_margin * rhs) { ++ u32 x_s = sndbuf > cwnd_s * mss ? sndbuf : cwnd_s * mss; ++ u64 lhs_s = srtt_s * x_s; ++ u64 rhs_s = cwnd_s * mss * (2 * srtt_f + delta); ++ ++ if (lhs_s >= rhs_s) { ++ /* too slower than fastest */ ++ ecf_cb->switching_margin = 1; ++ return NULL; ++ } ++ } else { ++ /* use slower one */ ++ ecf_cb->switching_margin = 0; ++ } ++ } ++ ++ return bestsk; ++} ++ ++/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ ++static struct sk_buff *mptcp_ecf_rcv_buf_optimization(struct sock *sk, int penal) ++{ ++ struct sock *meta_sk; ++ const struct tcp_sock *tp = tcp_sk(sk); ++ struct mptcp_tcp_sock *mptcp; ++ struct sk_buff *skb_head; ++ struct ecfsched_priv *ecf_p = ecfsched_get_priv(tp); ++ ++ meta_sk = mptcp_meta_sk(sk); ++ skb_head = tcp_rtx_queue_head(meta_sk); ++ ++ if (!skb_head) ++ return NULL; ++ ++ /* If penalization is optional (coming from mptcp_next_segment() and ++ * We are not send-buffer-limited we do not penalize. The retransmission ++ * is just an optimization to fix the idle-time due to the delay before ++ * we wake up the application. ++ */ ++ if (!penal && sk_stream_memory_free(meta_sk)) ++ goto retrans; ++ ++ /* Only penalize again after an RTT has elapsed */ ++ if (tcp_jiffies32 - ecf_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) ++ goto retrans; ++ ++ /* Half the cwnd of the slow flows */ ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ struct tcp_sock *tp_it = mptcp->tp; ++ ++ if (tp_it != tp && ++ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { ++ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { ++ u32 prior_cwnd = tp_it->snd_cwnd; ++ ++ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); ++ ++ /* If in slow start, do not reduce the ssthresh */ ++ if (prior_cwnd >= tp_it->snd_ssthresh) ++ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); ++ ++ ecf_p->last_rbuf_opti = tcp_jiffies32; ++ } ++ } ++ } ++ ++retrans: ++ ++ /* Segment not yet injected into this path? Take it!!! */ ++ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { ++ bool do_retrans = false; ++ mptcp_for_each_sub(tp->mpcb, mptcp) { ++ struct tcp_sock *tp_it = mptcp->tp; ++ ++ if (tp_it != tp && ++ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { ++ if (tp_it->snd_cwnd <= 4) { ++ do_retrans = true; ++ break; ++ } ++ ++ if (4 * tp->srtt_us >= tp_it->srtt_us) { ++ do_retrans = false; ++ break; ++ } else { ++ do_retrans = true; ++ } ++ } ++ } ++ ++ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { ++ trace_mptcp_retransmit(sk, skb_head); ++ return skb_head; ++ } ++ } ++ return NULL; ++} ++ ++/* copy from mptcp_sched.c: __mptcp_next_segment */ ++/* Returns the next segment to be sent from the mptcp meta-queue. ++ * (chooses the reinject queue if any segment is waiting in it, otherwise, ++ * chooses the normal write queue). ++ * Sets *@reinject to 1 if the returned segment comes from the ++ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, ++ * and sets it to -1 if it is a meta-level retransmission to optimize the ++ * receive-buffer. ++ */ ++static struct sk_buff *__mptcp_ecf_next_segment(struct sock *meta_sk, int *reinject) ++{ ++ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sk_buff *skb = NULL; ++ ++ *reinject = 0; ++ ++ /* If we are in fallback-mode, just take from the meta-send-queue */ ++ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) ++ return tcp_send_head(meta_sk); ++ ++ skb = skb_peek(&mpcb->reinject_queue); ++ ++ if (skb) { ++ *reinject = 1; ++ } else { ++ skb = tcp_send_head(meta_sk); ++ ++ if (!skb && meta_sk->sk_socket && ++ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && ++ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { ++ struct sock *subsk = ecf_get_available_subflow(meta_sk, NULL, ++ false); ++ if (!subsk) ++ return NULL; ++ ++ skb = mptcp_ecf_rcv_buf_optimization(subsk, 0); ++ if (skb) ++ *reinject = -1; ++ } ++ } ++ return skb; ++} ++ ++/* copy from mptcp_sched.c: mptcp_next_segment */ ++static struct sk_buff *mptcp_ecf_next_segment(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit) ++{ ++ struct sk_buff *skb = __mptcp_ecf_next_segment(meta_sk, reinject); ++ unsigned int mss_now; ++ struct tcp_sock *subtp; ++ u16 gso_max_segs; ++ u32 max_len, max_segs, window, needed; ++ ++ /* As we set it, we have to reset it as well. */ ++ *limit = 0; ++ ++ if (!skb) ++ return NULL; ++ ++ *subsk = ecf_get_available_subflow(meta_sk, skb, false); ++ if (!*subsk) ++ return NULL; ++ ++ subtp = tcp_sk(*subsk); ++ mss_now = tcp_current_mss(*subsk); ++ ++ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { ++ skb = mptcp_ecf_rcv_buf_optimization(*subsk, 1); ++ if (skb) ++ *reinject = -1; ++ else ++ return NULL; ++ } ++ ++ /* No splitting required, as we will only send one single segment */ ++ if (skb->len <= mss_now) ++ return skb; ++ ++ /* The following is similar to tcp_mss_split_point, but ++ * we do not care about nagle, because we will anyways ++ * use TCP_NAGLE_PUSH, which overrides this. ++ * ++ * So, we first limit according to the cwnd/gso-size and then according ++ * to the subflow's window. ++ */ ++ ++ gso_max_segs = (*subsk)->sk_gso_max_segs; ++ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ ++ gso_max_segs = 1; ++ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); ++ if (!max_segs) ++ return NULL; ++ ++ max_len = mss_now * max_segs; ++ window = tcp_wnd_end(subtp) - subtp->write_seq; ++ ++ needed = min(skb->len, window); ++ if (max_len <= skb->len) ++ /* Take max_win, which is actually the cwnd/gso-size */ ++ *limit = max_len; ++ else ++ /* Or, take the window */ ++ *limit = needed; ++ ++ return skb; ++} ++ ++static void ecfsched_init(struct sock *sk) ++{ ++ struct ecfsched_priv *ecf_p = ecfsched_get_priv(tcp_sk(sk)); ++ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(mptcp_meta_sk(sk))); ++ ++ ecf_p->last_rbuf_opti = tcp_jiffies32; ++ ecf_cb->switching_margin = 0; ++} ++ ++struct mptcp_sched_ops mptcp_sched_ecf = { ++ .get_subflow = ecf_get_available_subflow, ++ .next_segment = mptcp_ecf_next_segment, ++ .init = ecfsched_init, ++ .name = "ecf", ++ .owner = THIS_MODULE, ++}; ++ ++static int __init ecf_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct ecfsched_priv) > MPTCP_SCHED_SIZE); ++ BUILD_BUG_ON(sizeof(struct ecfsched_cb) > MPTCP_SCHED_DATA_SIZE); ++ ++ if (mptcp_register_scheduler(&mptcp_sched_ecf)) ++ return -1; ++ ++ return 0; ++} ++ ++static void ecf_unregister(void) ++{ ++ mptcp_unregister_scheduler(&mptcp_sched_ecf); ++} ++ ++module_init(ecf_register); ++module_exit(ecf_unregister); ++ ++MODULE_AUTHOR("Yeon-sup Lim, Daniel Weber"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("ECF (Earliest Completion First) scheduler for MPTCP, based on default minimum RTT scheduler"); ++MODULE_VERSION("0.95"); diff --git a/root/target/linux/generic/hack-5.4/692-tcp_nanqinlang.patch b/root/target/linux/generic/hack-5.4/692-tcp_nanqinlang.patch new file mode 100644 index 00000000..56051ae7 --- /dev/null +++ b/root/target/linux/generic/hack-5.4/692-tcp_nanqinlang.patch @@ -0,0 +1,1037 @@ +--- a/net/ipv4/Makefile.anc 2019-11-23 23:01:47.069966970 +0100 ++++ b/net/ipv4/Makefile 2019-11-23 23:03:01.416428035 +0100 +@@ -48,6 +48,7 @@ + obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o + obj-$(CONFIG_INET_RAW_DIAG) += raw_diag.o + obj-$(CONFIG_TCP_CONG_BBR) += tcp_bbr.o ++obj-$(CONFIG_TCP_CONG_NANQINLANG) += tcp_nanqinlang.o + obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o + obj-$(CONFIG_TCP_CONG_CDG) += tcp_cdg.o + obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o +--- a/net/ipv4/Kconfig.anc 2019-11-23 23:01:52.649851417 +0100 ++++ b/net/ipv4/Kconfig 2019-11-23 23:04:21.974762180 +0100 +@@ -681,6 +681,21 @@ + bufferbloat, policers, or AQM schemes that do not provide a delay + signal. It requires the fq ("Fair Queue") pacing packet scheduler. + ++config TCP_CONG_NANQINLANG ++ tristate "NANGINLANG TCP" ++ default n ++ ---help--- ++ ++ BBR (Bottleneck Bandwidth and RTT) TCP congestion control aims to ++ maximize network utilization and minimize queues. It builds an explicit ++ model of the the bottleneck delivery rate and path round-trip ++ propagation delay. It tolerates packet loss and delay unrelated to ++ congestion. It can operate over LAN, WAN, cellular, wifi, or cable ++ modem links. It can coexist with flows that use loss-based congestion ++ control, and can operate with shallow buffers, deep buffers, ++ bufferbloat, policers, or AQM schemes that do not provide a delay ++ signal. It requires the fq ("Fair Queue") pacing packet scheduler. ++ + config TCP_CONG_LIA + tristate "MPTCP Linked Increase" + depends on MPTCP +@@ -763,6 +778,9 @@ + config DEFAULT_BBR + bool "BBR" if TCP_CONG_BBR=y + ++ config DEFAULT_NANQINLANG ++ bool "BBR" if TCP_CONG_NANQINLANG=y ++ + config DEFAULT_LIA + bool "Lia" if TCP_CONG_LIA=y + +@@ -806,6 +824,7 @@ + default "dctcp" if DEFAULT_DCTCP + default "cdg" if DEFAULT_CDG + default "bbr" if DEFAULT_BBR ++ default "nanqinlang" if DEFAULT_NANQINLANG + default "cubic" + + config TCP_MD5SIG +--- /dev/null 2019-11-25 21:13:36.728349757 +0100 ++++ b/net/ipv4/tcp_nanqinlang.c 2019-11-25 21:10:00.392068414 +0100 +@@ -0,0 +1,982 @@ ++/* Bottleneck Bandwidth and RTT (BBR) congestion control ++ * ++ * BBR congestion control computes the sending rate based on the delivery ++ * rate (throughput) estimated from ACKs. In a nutshell: ++ * ++ * On each ACK, update our model of the network path: ++ * bottleneck_bandwidth = windowed_max(delivered / elapsed, 10 round trips) ++ * min_rtt = windowed_min(rtt, 10 seconds) ++ * pacing_rate = pacing_gain * bottleneck_bandwidth ++ * cwnd = max(cwnd_gain * bottleneck_bandwidth * min_rtt, 4) ++ * ++ * The core algorithm does not react directly to packet losses or delays, ++ * although BBR may adjust the size of next send per ACK when loss is ++ * observed, or adjust the sending rate if it estimates there is a ++ * traffic policer, in order to keep the drop rate reasonable. ++ * ++ * Here is a state transition diagram for BBR: ++ * ++ * | ++ * V ++ * +---> STARTUP ----+ ++ * | | | ++ * | V | ++ * | DRAIN ----+ ++ * | | | ++ * | V | ++ * +---> PROBE_BW ----+ ++ * | ^ | | ++ * | | | | ++ * | +----+ | ++ * | | ++ * +---- PROBE_RTT <--+ ++ * ++ * A BBR flow starts in STARTUP, and ramps up its sending rate quickly. ++ * When it estimates the pipe is full, it enters DRAIN to drain the queue. ++ * In steady state a BBR flow only uses PROBE_BW and PROBE_RTT. ++ * A long-lived BBR flow spends the vast majority of its time remaining ++ * (repeatedly) in PROBE_BW, fully probing and utilizing the pipe's bandwidth ++ * in a fair manner, with a small, bounded queue. *If* a flow has been ++ * continuously sending for the entire min_rtt window, and hasn't seen an RTT ++ * sample that matches or decreases its min_rtt estimate for 10 seconds, then ++ * it briefly enters PROBE_RTT to cut inflight to a minimum value to re-probe ++ * the path's two-way propagation delay (min_rtt). When exiting PROBE_RTT, if ++ * we estimated that we reached the full bw of the pipe then we enter PROBE_BW; ++ * otherwise we enter STARTUP to try to fill the pipe. ++ * ++ * BBR is described in detail in: ++ * "BBR: Congestion-Based Congestion Control", ++ * Neal Cardwell, Yuchung Cheng, C. Stephen Gunn, Soheil Hassas Yeganeh, ++ * Van Jacobson. ACM Queue, Vol. 14 No. 5, September-October 2016. ++ * ++ * There is a public e-mail list for discussing BBR development and testing: ++ * https://groups.google.com/forum/#!forum/bbr-dev ++ * ++ * NOTE: BBR might be used with the fq qdisc ("man tc-fq") with pacing enabled, ++ * otherwise TCP stack falls back to an internal pacing using one high ++ * resolution timer per TCP socket and may use more resources. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Scale factor for rate in pkt/uSec unit to avoid truncation in bandwidth ++ * estimation. The rate unit ~= (1500 bytes / 1 usec / 2^24) ~= 715 bps. ++ * This handles bandwidths from 0.06pps (715bps) to 256Mpps (3Tbps) in a u32. ++ * Since the minimum window is >=4 packets, the lower bound isn't ++ * an issue. The upper bound isn't an issue with existing technologies. ++ */ ++#define BW_SCALE 24 ++#define BW_UNIT (1 << BW_SCALE) ++ ++#define BBR_SCALE 8 /* scaling factor for fractions in BBR (e.g. gains) */ ++#define BBR_UNIT (1 << BBR_SCALE) ++ ++/* BBR has the following modes for deciding how fast to send: */ ++enum bbr_mode { ++ BBR_STARTUP, /* ramp up sending rate rapidly to fill pipe */ ++ BBR_DRAIN, /* drain any queue created during startup */ ++ BBR_PROBE_BW, /* discover, share bw: pace around estimated bw */ ++ BBR_PROBE_RTT, /* cut inflight to min to probe min_rtt */ ++}; ++ ++/* BBR congestion control block */ ++struct bbr { ++ u32 min_rtt_us; /* min RTT in min_rtt_win_sec window */ ++ u32 min_rtt_stamp; /* timestamp of min_rtt_us */ ++ u32 probe_rtt_done_stamp; /* end time for BBR_PROBE_RTT mode */ ++ struct minmax bw; /* Max recent delivery rate in pkts/uS << 24 */ ++ u32 rtt_cnt; /* count of packet-timed rounds elapsed */ ++ u32 next_rtt_delivered; /* scb->tx.delivered at end of round */ ++ u64 cycle_mstamp; /* time of this cycle phase start */ ++ u32 mode:3, /* current bbr_mode in state machine */ ++ prev_ca_state:3, /* CA state on previous ACK */ ++ packet_conservation:1, /* use packet conservation? */ ++ round_start:1, /* start of packet-timed tx->ack round? */ ++ idle_restart:1, /* restarting after idle? */ ++ probe_rtt_round_done:1, /* a BBR_PROBE_RTT round at 4 pkts? */ ++ unused:13, ++ lt_is_sampling:1, /* taking long-term ("LT") samples now? */ ++ lt_rtt_cnt:7, /* round trips in long-term interval */ ++ lt_use_bw:1; /* use lt_bw as our bw estimate? */ ++ u32 lt_bw; /* LT est delivery rate in pkts/uS << 24 */ ++ u32 lt_last_delivered; /* LT intvl start: tp->delivered */ ++ u32 lt_last_stamp; /* LT intvl start: tp->delivered_mstamp */ ++ u32 lt_last_lost; /* LT intvl start: tp->lost */ ++ u32 pacing_gain:10, /* current gain for setting pacing rate */ ++ cwnd_gain:10, /* current gain for setting cwnd */ ++ full_bw_reached:1, /* reached full bw in Startup? */ ++ full_bw_cnt:2, /* number of rounds without large bw gains */ ++ cycle_idx:3, /* current index in pacing_gain cycle array */ ++ has_seen_rtt:1, /* have we seen an RTT sample yet? */ ++ unused_b:5; ++ u32 prior_cwnd; /* prior cwnd upon entering loss recovery */ ++ u32 full_bw; /* recent bw, to estimate if pipe is full */ ++}; ++ ++#define CYCLE_LEN 8 /* number of phases in a pacing gain cycle */ ++ ++/* Window length of bw filter (in rounds): */ ++static const int bbr_bw_rtts = CYCLE_LEN + 2; ++/* Window length of min_rtt filter (in sec): */ ++static const u32 bbr_min_rtt_win_sec = 10; ++/* Minimum time (in ms) spent at bbr_cwnd_min_target in BBR_PROBE_RTT mode: */ ++static const u32 bbr_probe_rtt_mode_ms = 100; ++/* Skip TSO below the following bandwidth (bits/sec): */ ++static const int bbr_min_tso_rate = 1200000; ++ ++/* We use a high_gain value of 2/ln(2) because it's the smallest pacing gain ++ * that will allow a smoothly increasing pacing rate that will double each RTT ++ * and send the same number of packets per RTT that an un-paced, slow-starting ++ * Reno or CUBIC flow would: ++ */ ++static const int bbr_high_gain = BBR_UNIT * 3000 / 1000 + 1; ++/* The pacing gain of 1/high_gain in BBR_DRAIN is calculated to typically drain ++ * the queue created in BBR_STARTUP in a single round: ++ */ ++static const int bbr_drain_gain = BBR_UNIT * 1000 / 3000; ++/* The gain for deriving steady-state cwnd tolerates delayed/stretched ACKs: */ ++static const int bbr_cwnd_gain = BBR_UNIT * 2; ++/* The pacing_gain values for the PROBE_BW gain cycle, to discover/share bw: */ ++static const int bbr_pacing_gain[] = { ++ BBR_UNIT * 6 / 4, /* probe for more available bw */ ++ BBR_UNIT * 3 / 4, /* drain queue and/or yield bw to other flows */ ++ BBR_UNIT * 5 / 4, BBR_UNIT * 5 / 4, BBR_UNIT * 5 / 4, /* cruise at 1.0*bw to utilize pipe, */ ++ BBR_UNIT * 6 / 4, BBR_UNIT * 6 / 4, BBR_UNIT * 6 / 4 /* without creating excess queue... */ ++}; ++/* Randomize the starting gain cycling phase over N phases: */ ++static const u32 bbr_cycle_rand = 7; ++ ++/* Try to keep at least this many packets in flight, if things go smoothly. For ++ * smooth functioning, a sliding window protocol ACKing every other packet ++ * needs at least 4 packets in flight: ++ */ ++static const u32 bbr_cwnd_min_target = 4; ++ ++/* To estimate if BBR_STARTUP mode (i.e. high_gain) has filled pipe... */ ++/* If bw has increased significantly (1.25x), there may be more bw available: */ ++static const u32 bbr_full_bw_thresh = BBR_UNIT * 5 / 4; ++/* But after 3 rounds w/o significant bw growth, estimate pipe is full: */ ++static const u32 bbr_full_bw_cnt = 3; ++ ++/* "long-term" ("LT") bandwidth estimator parameters... */ ++/* The minimum number of rounds in an LT bw sampling interval: */ ++static const u32 bbr_lt_intvl_min_rtts = 4; ++/* If lost/delivered ratio > 20%, interval is "lossy" and we may be policed: */ ++static const u32 bbr_lt_loss_thresh = 50; ++/* If 2 intervals have a bw ratio <= 1/8, their bw is "consistent": */ ++static const u32 bbr_lt_bw_ratio = BBR_UNIT / 4; ++/* If 2 intervals have a bw diff <= 4 Kbit/sec their bw is "consistent": */ ++static const u32 bbr_lt_bw_diff = 4000 / 8; ++/* If we estimate we're policed, use lt_bw for this many round trips: */ ++static const u32 bbr_lt_bw_max_rtts = 48; ++ ++static void bbr_check_probe_rtt_done(struct sock *sk); ++ ++/* Do we estimate that STARTUP filled the pipe? */ ++static bool bbr_full_bw_reached(const struct sock *sk) ++{ ++ const struct bbr *bbr = inet_csk_ca(sk); ++ ++ return bbr->full_bw_reached; ++} ++ ++/* Return the windowed max recent bandwidth sample, in pkts/uS << BW_SCALE. */ ++static u32 bbr_max_bw(const struct sock *sk) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ return minmax_get(&bbr->bw); ++} ++ ++/* Return the estimated bandwidth of the path, in pkts/uS << BW_SCALE. */ ++static u32 bbr_bw(const struct sock *sk) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ return bbr->lt_use_bw ? bbr->lt_bw : bbr_max_bw(sk); ++} ++ ++/* Return rate in bytes per second, optionally with a gain. ++ * The order here is chosen carefully to avoid overflow of u64. This should ++ * work for input rates of up to 2.9Tbit/sec and gain of 2.89x. ++ */ ++static u64 bbr_rate_bytes_per_sec(struct sock *sk, u64 rate, int gain) ++{ ++ unsigned int mss = tcp_sk(sk)->mss_cache; ++ ++ if (!tcp_needs_internal_pacing(sk)) ++ mss = tcp_mss_to_mtu(sk, mss); ++ rate *= mss; ++ rate *= gain; ++ rate >>= BBR_SCALE; ++ rate *= USEC_PER_SEC; ++ return rate >> BW_SCALE; ++} ++ ++/* Convert a BBR bw and gain factor to a pacing rate in bytes per second. */ ++static u32 bbr_bw_to_pacing_rate(struct sock *sk, u32 bw, int gain) ++{ ++ u64 rate = bw; ++ ++ rate = bbr_rate_bytes_per_sec(sk, rate, gain); ++ rate = min_t(u64, rate, sk->sk_max_pacing_rate); ++ return rate; ++} ++ ++/* Initialize pacing rate to: high_gain * init_cwnd / RTT. */ ++static void bbr_init_pacing_rate_from_rtt(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ u64 bw; ++ u32 rtt_us; ++ ++ if (tp->srtt_us) { /* any RTT sample yet? */ ++ rtt_us = max(tp->srtt_us >> 3, 1U); ++ bbr->has_seen_rtt = 1; ++ } else { /* no RTT sample yet */ ++ rtt_us = USEC_PER_MSEC; /* use nominal default RTT */ ++ } ++ bw = (u64)tp->snd_cwnd * BW_UNIT; ++ do_div(bw, rtt_us); ++ sk->sk_pacing_rate = bbr_bw_to_pacing_rate(sk, bw, bbr_high_gain); ++} ++ ++/* Pace using current bw estimate and a gain factor. In order to help drive the ++ * network toward lower queues while maintaining high utilization and low ++ * latency, the average pacing rate aims to be slightly (~1%) lower than the ++ * estimated bandwidth. This is an important aspect of the design. In this ++ * implementation this slightly lower pacing rate is achieved implicitly by not ++ * including link-layer headers in the packet size used for the pacing rate. ++ */ ++static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ u32 rate = bbr_bw_to_pacing_rate(sk, bw, gain); ++ ++ if (unlikely(!bbr->has_seen_rtt && tp->srtt_us)) ++ bbr_init_pacing_rate_from_rtt(sk); ++ if (bbr_full_bw_reached(sk) || rate > sk->sk_pacing_rate) ++ sk->sk_pacing_rate = rate; ++} ++ ++/* override sysctl_tcp_min_tso_segs */ ++static u32 bbr_min_tso_segs(struct sock *sk) ++{ ++ return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2; ++} ++ ++static u32 bbr_tso_segs_goal(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ u32 segs, bytes; ++ ++ /* Sort of tcp_tso_autosize() but ignoring ++ * driver provided sk_gso_max_size. ++ */ ++ bytes = min_t(u32, sk->sk_pacing_rate >> sk->sk_pacing_shift, ++ GSO_MAX_SIZE - 1 - MAX_TCP_HEADER); ++ segs = max_t(u32, bytes / tp->mss_cache, bbr_min_tso_segs(sk)); ++ ++ return min(segs, 0x7FU); ++} ++ ++/* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */ ++static void bbr_save_cwnd(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ if (bbr->prev_ca_state < TCP_CA_Recovery && bbr->mode != BBR_PROBE_RTT) ++ bbr->prior_cwnd = tp->snd_cwnd; /* this cwnd is good enough */ ++ else /* loss recovery or BBR_PROBE_RTT have temporarily cut cwnd */ ++ bbr->prior_cwnd = max(bbr->prior_cwnd, tp->snd_cwnd); ++} ++ ++static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ if (event == CA_EVENT_TX_START && tp->app_limited) { ++ bbr->idle_restart = 1; ++ /* Avoid pointless buffer overflows: pace at est. bw if we don't ++ * need more speed (we're restarting from idle and app-limited). ++ */ ++ if (bbr->mode == BBR_PROBE_BW) ++ bbr_set_pacing_rate(sk, bbr_bw(sk), BBR_UNIT); ++ else if (bbr->mode == BBR_PROBE_RTT) ++ bbr_check_probe_rtt_done(sk); ++ } ++} ++ ++/* Find target cwnd. Right-size the cwnd based on min RTT and the ++ * estimated bottleneck bandwidth: ++ * ++ * cwnd = bw * min_rtt * gain = BDP * gain ++ * ++ * The key factor, gain, controls the amount of queue. While a small gain ++ * builds a smaller queue, it becomes more vulnerable to noise in RTT ++ * measurements (e.g., delayed ACKs or other ACK compression effects). This ++ * noise may cause BBR to under-estimate the rate. ++ * ++ * To achieve full performance in high-speed paths, we budget enough cwnd to ++ * fit full-sized skbs in-flight on both end hosts to fully utilize the path: ++ * - one skb in sending host Qdisc, ++ * - one skb in sending host TSO/GSO engine ++ * - one skb being received by receiver host LRO/GRO/delayed-ACK engine ++ * Don't worry, at low rates (bbr_min_tso_rate) this won't bloat cwnd because ++ * in such cases tso_segs_goal is 1. The minimum cwnd is 4 packets, ++ * which allows 2 outstanding 2-packet sequences, to try to keep pipe ++ * full even with ACK-every-other-packet delayed ACKs. ++ */ ++static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ u32 cwnd; ++ u64 w; ++ ++ /* If we've never had a valid RTT sample, cap cwnd at the initial ++ * default. This should only happen when the connection is not using TCP ++ * timestamps and has retransmitted all of the SYN/SYNACK/data packets ++ * ACKed so far. In this case, an RTO can cut cwnd to 1, in which ++ * case we need to slow-start up toward something safe: TCP_INIT_CWND. ++ */ ++ if (unlikely(bbr->min_rtt_us == ~0U)) /* no valid RTT samples yet? */ ++ return TCP_INIT_CWND; /* be safe: cap at default initial cwnd*/ ++ ++ w = (u64)bw * bbr->min_rtt_us; ++ ++ /* Apply a gain to the given value, then remove the BW_SCALE shift. */ ++ cwnd = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT; ++ ++ /* Allow enough full-sized skbs in flight to utilize end systems. */ ++ cwnd += 3 * bbr_tso_segs_goal(sk); ++ ++ /* Reduce delayed ACKs by rounding up cwnd to the next even number. */ ++ cwnd = (cwnd + 1) & ~1U; ++ ++ /* Ensure gain cycling gets inflight above BDP even for small BDPs. */ ++ if (bbr->mode == BBR_PROBE_BW && gain > BBR_UNIT) ++ cwnd += 2; ++ ++ return cwnd; ++} ++ ++/* An optimization in BBR to reduce losses: On the first round of recovery, we ++ * follow the packet conservation principle: send P packets per P packets acked. ++ * After that, we slow-start and send at most 2*P packets per P packets acked. ++ * After recovery finishes, or upon undo, we restore the cwnd we had when ++ * recovery started (capped by the target cwnd based on estimated BDP). ++ * ++ * TODO(ycheng/ncardwell): implement a rate-based approach. ++ */ ++static bool bbr_set_cwnd_to_recover_or_restore( ++ struct sock *sk, const struct rate_sample *rs, u32 acked, u32 *new_cwnd) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ u8 prev_state = bbr->prev_ca_state, state = inet_csk(sk)->icsk_ca_state; ++ u32 cwnd = tp->snd_cwnd; ++ ++ /* An ACK for P pkts should release at most 2*P packets. We do this ++ * in two steps. First, here we deduct the number of lost packets. ++ * Then, in bbr_set_cwnd() we slow start up toward the target cwnd. ++ */ ++ if (rs->losses > 0) ++ cwnd = max_t(s32, cwnd - rs->losses, 1); ++ ++ if (state == TCP_CA_Recovery && prev_state != TCP_CA_Recovery) { ++ /* Starting 1st round of Recovery, so do packet conservation. */ ++ bbr->packet_conservation = 1; ++ bbr->next_rtt_delivered = tp->delivered; /* start round now */ ++ /* Cut unused cwnd from app behavior, TSQ, or TSO deferral: */ ++ cwnd = tcp_packets_in_flight(tp) + acked; ++ } else if (prev_state >= TCP_CA_Recovery && state < TCP_CA_Recovery) { ++ /* Exiting loss recovery; restore cwnd saved before recovery. */ ++ cwnd = max(cwnd, bbr->prior_cwnd); ++ bbr->packet_conservation = 0; ++ } ++ bbr->prev_ca_state = state; ++ ++ if (bbr->packet_conservation) { ++ *new_cwnd = max(cwnd, tcp_packets_in_flight(tp) + acked); ++ return true; /* yes, using packet conservation */ ++ } ++ *new_cwnd = cwnd; ++ return false; ++} ++ ++/* Slow-start up toward target cwnd (if bw estimate is growing, or packet loss ++ * has drawn us down below target), or snap down to target if we're above it. ++ */ ++static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs, ++ u32 acked, u32 bw, int gain) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ u32 cwnd = tp->snd_cwnd, target_cwnd = 0; ++ ++ if (!acked) ++ goto done; /* no packet fully ACKed; just apply caps */ ++ ++ if (bbr_set_cwnd_to_recover_or_restore(sk, rs, acked, &cwnd)) ++ goto done; ++ ++ /* If we're below target cwnd, slow start cwnd toward target cwnd. */ ++ target_cwnd = bbr_target_cwnd(sk, bw, gain); ++ if (bbr_full_bw_reached(sk)) /* only cut cwnd if we filled the pipe */ ++ cwnd = min(cwnd + acked, target_cwnd); ++ else if (cwnd < target_cwnd || tp->delivered < TCP_INIT_CWND) ++ cwnd = cwnd + acked; ++ cwnd = max(cwnd, bbr_cwnd_min_target); ++ ++done: ++ tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp); /* apply global cap */ ++ if (bbr->mode == BBR_PROBE_RTT) /* drain queue, refresh min_rtt */ ++ tp->snd_cwnd = min(tp->snd_cwnd, bbr_cwnd_min_target); ++} ++ ++/* End cycle phase if it's time and/or we hit the phase's in-flight target. */ ++static bool bbr_is_next_cycle_phase(struct sock *sk, ++ const struct rate_sample *rs) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ bool is_full_length = ++ tcp_stamp_us_delta(tp->delivered_mstamp, bbr->cycle_mstamp) > ++ bbr->min_rtt_us; ++ u32 inflight, bw; ++ ++ /* The pacing_gain of 1.0 paces at the estimated bw to try to fully ++ * use the pipe without increasing the queue. ++ */ ++ if (bbr->pacing_gain == BBR_UNIT) ++ return is_full_length; /* just use wall clock time */ ++ ++ inflight = rs->prior_in_flight; /* what was in-flight before ACK? */ ++ bw = bbr_max_bw(sk); ++ ++ /* A pacing_gain > 1.0 probes for bw by trying to raise inflight to at ++ * least pacing_gain*BDP; this may take more than min_rtt if min_rtt is ++ * small (e.g. on a LAN). We do not persist if packets are lost, since ++ * a path with small buffers may not hold that much. ++ */ ++ if (bbr->pacing_gain > BBR_UNIT) ++ return is_full_length && ++ (rs->losses || /* perhaps pacing_gain*BDP won't fit */ ++ inflight >= bbr_target_cwnd(sk, bw, bbr->pacing_gain)); ++ ++ /* A pacing_gain < 1.0 tries to drain extra queue we added if bw ++ * probing didn't find more bw. If inflight falls to match BDP then we ++ * estimate queue is drained; persisting would underutilize the pipe. ++ */ ++ return is_full_length || ++ inflight <= bbr_target_cwnd(sk, bw, BBR_UNIT); ++} ++ ++static void bbr_advance_cycle_phase(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ bbr->cycle_idx = (bbr->cycle_idx + 1) & (CYCLE_LEN - 1); ++ bbr->cycle_mstamp = tp->delivered_mstamp; ++ bbr->pacing_gain = bbr->lt_use_bw ? BBR_UNIT : ++ bbr_pacing_gain[bbr->cycle_idx]; ++} ++ ++/* Gain cycling: cycle pacing gain to converge to fair share of available bw. */ ++static void bbr_update_cycle_phase(struct sock *sk, ++ const struct rate_sample *rs) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ if (bbr->mode == BBR_PROBE_BW && bbr_is_next_cycle_phase(sk, rs)) ++ bbr_advance_cycle_phase(sk); ++} ++ ++static void bbr_reset_startup_mode(struct sock *sk) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ bbr->mode = BBR_STARTUP; ++ bbr->pacing_gain = bbr_high_gain; ++ bbr->cwnd_gain = bbr_high_gain; ++} ++ ++static void bbr_reset_probe_bw_mode(struct sock *sk) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ bbr->mode = BBR_PROBE_BW; ++ bbr->pacing_gain = BBR_UNIT; ++ bbr->cwnd_gain = bbr_cwnd_gain; ++ bbr->cycle_idx = CYCLE_LEN - 1 - prandom_u32_max(bbr_cycle_rand); ++ bbr_advance_cycle_phase(sk); /* flip to next phase of gain cycle */ ++} ++ ++static void bbr_reset_mode(struct sock *sk) ++{ ++ if (!bbr_full_bw_reached(sk)) ++ bbr_reset_startup_mode(sk); ++ else ++ bbr_reset_probe_bw_mode(sk); ++} ++ ++/* Start a new long-term sampling interval. */ ++static void bbr_reset_lt_bw_sampling_interval(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ bbr->lt_last_stamp = div_u64(tp->delivered_mstamp, USEC_PER_MSEC); ++ bbr->lt_last_delivered = tp->delivered; ++ bbr->lt_last_lost = tp->lost; ++ bbr->lt_rtt_cnt = 0; ++} ++ ++/* Completely reset long-term bandwidth sampling. */ ++static void bbr_reset_lt_bw_sampling(struct sock *sk) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ bbr->lt_bw = 0; ++ bbr->lt_use_bw = 0; ++ bbr->lt_is_sampling = false; ++ bbr_reset_lt_bw_sampling_interval(sk); ++} ++ ++/* Long-term bw sampling interval is done. Estimate whether we're policed. */ ++static void bbr_lt_bw_interval_done(struct sock *sk, u32 bw) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ u32 diff; ++ ++ if (bbr->lt_bw) { /* do we have bw from a previous interval? */ ++ /* Is new bw close to the lt_bw from the previous interval? */ ++ diff = abs(bw - bbr->lt_bw); ++ if ((diff * BBR_UNIT <= bbr_lt_bw_ratio * bbr->lt_bw) || ++ (bbr_rate_bytes_per_sec(sk, diff, BBR_UNIT) <= ++ bbr_lt_bw_diff)) { ++ /* All criteria are met; estimate we're policed. */ ++ bbr->lt_bw = (bw + bbr->lt_bw) >> 1; /* avg 2 intvls */ ++ bbr->lt_use_bw = 1; ++ bbr->pacing_gain = BBR_UNIT; /* try to avoid drops */ ++ bbr->lt_rtt_cnt = 0; ++ return; ++ } ++ } ++ bbr->lt_bw = bw; ++ bbr_reset_lt_bw_sampling_interval(sk); ++} ++ ++/* Token-bucket traffic policers are common (see "An Internet-Wide Analysis of ++ * Traffic Policing", SIGCOMM 2016). BBR detects token-bucket policers and ++ * explicitly models their policed rate, to reduce unnecessary losses. We ++ * estimate that we're policed if we see 2 consecutive sampling intervals with ++ * consistent throughput and high packet loss. If we think we're being policed, ++ * set lt_bw to the "long-term" average delivery rate from those 2 intervals. ++ */ ++static void bbr_lt_bw_sampling(struct sock *sk, const struct rate_sample *rs) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ u32 lost, delivered; ++ u64 bw; ++ u32 t; ++ ++ if (bbr->lt_use_bw) { /* already using long-term rate, lt_bw? */ ++ if (bbr->mode == BBR_PROBE_BW && bbr->round_start && ++ ++bbr->lt_rtt_cnt >= bbr_lt_bw_max_rtts) { ++ bbr_reset_lt_bw_sampling(sk); /* stop using lt_bw */ ++ bbr_reset_probe_bw_mode(sk); /* restart gain cycling */ ++ } ++ return; ++ } ++ ++ /* Wait for the first loss before sampling, to let the policer exhaust ++ * its tokens and estimate the steady-state rate allowed by the policer. ++ * Starting samples earlier includes bursts that over-estimate the bw. ++ */ ++ if (!bbr->lt_is_sampling) { ++ if (!rs->losses) ++ return; ++ bbr_reset_lt_bw_sampling_interval(sk); ++ bbr->lt_is_sampling = true; ++ } ++ ++ /* To avoid underestimates, reset sampling if we run out of data. */ ++ if (rs->is_app_limited) { ++ bbr_reset_lt_bw_sampling(sk); ++ return; ++ } ++ ++ if (bbr->round_start) ++ bbr->lt_rtt_cnt++; /* count round trips in this interval */ ++ if (bbr->lt_rtt_cnt < bbr_lt_intvl_min_rtts) ++ return; /* sampling interval needs to be longer */ ++ if (bbr->lt_rtt_cnt > 4 * bbr_lt_intvl_min_rtts) { ++ bbr_reset_lt_bw_sampling(sk); /* interval is too long */ ++ return; ++ } ++ ++ /* End sampling interval when a packet is lost, so we estimate the ++ * policer tokens were exhausted. Stopping the sampling before the ++ * tokens are exhausted under-estimates the policed rate. ++ */ ++ if (!rs->losses) ++ return; ++ ++ /* Calculate packets lost and delivered in sampling interval. */ ++ lost = tp->lost - bbr->lt_last_lost; ++ delivered = tp->delivered - bbr->lt_last_delivered; ++ /* Is loss rate (lost/delivered) >= lt_loss_thresh? If not, wait. */ ++ if (!delivered || (lost << BBR_SCALE) < bbr_lt_loss_thresh * delivered) ++ return; ++ ++ /* Find average delivery rate in this sampling interval. */ ++ t = div_u64(tp->delivered_mstamp, USEC_PER_MSEC) - bbr->lt_last_stamp; ++ if ((s32)t < 1) ++ return; /* interval is less than one ms, so wait */ ++ /* Check if can multiply without overflow */ ++ if (t >= ~0U / USEC_PER_MSEC) { ++ bbr_reset_lt_bw_sampling(sk); /* interval too long; reset */ ++ return; ++ } ++ t *= USEC_PER_MSEC; ++ bw = (u64)delivered * BW_UNIT; ++ do_div(bw, t); ++ bbr_lt_bw_interval_done(sk, bw); ++} ++ ++/* Estimate the bandwidth based on how fast packets are delivered */ ++static void bbr_update_bw(struct sock *sk, const struct rate_sample *rs) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ u64 bw; ++ ++ bbr->round_start = 0; ++ if (rs->delivered < 0 || rs->interval_us <= 0) ++ return; /* Not a valid observation */ ++ ++ /* See if we've reached the next RTT */ ++ if (!before(rs->prior_delivered, bbr->next_rtt_delivered)) { ++ bbr->next_rtt_delivered = tp->delivered; ++ bbr->rtt_cnt++; ++ bbr->round_start = 1; ++ bbr->packet_conservation = 0; ++ } ++ ++ bbr_lt_bw_sampling(sk, rs); ++ ++ /* Divide delivered by the interval to find a (lower bound) bottleneck ++ * bandwidth sample. Delivered is in packets and interval_us in uS and ++ * ratio will be <<1 for most connections. So delivered is first scaled. ++ */ ++ bw = (u64)rs->delivered * BW_UNIT; ++ do_div(bw, rs->interval_us); ++ ++ /* If this sample is application-limited, it is likely to have a very ++ * low delivered count that represents application behavior rather than ++ * the available network rate. Such a sample could drag down estimated ++ * bw, causing needless slow-down. Thus, to continue to send at the ++ * last measured network rate, we filter out app-limited samples unless ++ * they describe the path bw at least as well as our bw model. ++ * ++ * So the goal during app-limited phase is to proceed with the best ++ * network rate no matter how long. We automatically leave this ++ * phase when app writes faster than the network can deliver :) ++ */ ++ if (!rs->is_app_limited || bw >= bbr_max_bw(sk)) { ++ /* Incorporate new sample into our max bw filter. */ ++ minmax_running_max(&bbr->bw, bbr_bw_rtts, bbr->rtt_cnt, bw); ++ } ++} ++ ++/* Estimate when the pipe is full, using the change in delivery rate: BBR ++ * estimates that STARTUP filled the pipe if the estimated bw hasn't changed by ++ * at least bbr_full_bw_thresh (25%) after bbr_full_bw_cnt (3) non-app-limited ++ * rounds. Why 3 rounds: 1: rwin autotuning grows the rwin, 2: we fill the ++ * higher rwin, 3: we get higher delivery rate samples. Or transient ++ * cross-traffic or radio noise can go away. CUBIC Hystart shares a similar ++ * design goal, but uses delay and inter-ACK spacing instead of bandwidth. ++ */ ++static void bbr_check_full_bw_reached(struct sock *sk, ++ const struct rate_sample *rs) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ u32 bw_thresh; ++ ++ if (bbr_full_bw_reached(sk) || !bbr->round_start || rs->is_app_limited) ++ return; ++ ++ bw_thresh = (u64)bbr->full_bw * bbr_full_bw_thresh >> BBR_SCALE; ++ if (bbr_max_bw(sk) >= bw_thresh) { ++ bbr->full_bw = bbr_max_bw(sk); ++ bbr->full_bw_cnt = 0; ++ return; ++ } ++ ++bbr->full_bw_cnt; ++ bbr->full_bw_reached = bbr->full_bw_cnt >= bbr_full_bw_cnt; ++} ++ ++/* If pipe is probably full, drain the queue and then enter steady-state. */ ++static void bbr_check_drain(struct sock *sk, const struct rate_sample *rs) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ if (bbr->mode == BBR_STARTUP && bbr_full_bw_reached(sk)) { ++ bbr->mode = BBR_DRAIN; /* drain queue we created */ ++ bbr->pacing_gain = bbr_drain_gain; /* pace slow to drain */ ++ bbr->cwnd_gain = bbr_high_gain; /* maintain cwnd */ ++ tcp_sk(sk)->snd_ssthresh = ++ bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT); ++ } /* fall through to check if in-flight is already small: */ ++ if (bbr->mode == BBR_DRAIN && ++ tcp_packets_in_flight(tcp_sk(sk)) <= ++ bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT)) ++ bbr_reset_probe_bw_mode(sk); /* we estimate queue is drained */ ++} ++ ++static void bbr_check_probe_rtt_done(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ if (!(bbr->probe_rtt_done_stamp && ++ after(tcp_jiffies32, bbr->probe_rtt_done_stamp))) ++ return; ++ ++ bbr->min_rtt_stamp = tcp_jiffies32; /* wait a while until PROBE_RTT */ ++ tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd); ++ bbr_reset_mode(sk); ++} ++ ++/* The goal of PROBE_RTT mode is to have BBR flows cooperatively and ++ * periodically drain the bottleneck queue, to converge to measure the true ++ * min_rtt (unloaded propagation delay). This allows the flows to keep queues ++ * small (reducing queuing delay and packet loss) and achieve fairness among ++ * BBR flows. ++ * ++ * The min_rtt filter window is 10 seconds. When the min_rtt estimate expires, ++ * we enter PROBE_RTT mode and cap the cwnd at bbr_cwnd_min_target=4 packets. ++ * After at least bbr_probe_rtt_mode_ms=200ms and at least one packet-timed ++ * round trip elapsed with that flight size <= 4, we leave PROBE_RTT mode and ++ * re-enter the previous mode. BBR uses 200ms to approximately bound the ++ * performance penalty of PROBE_RTT's cwnd capping to roughly 2% (200ms/10s). ++ * ++ * Note that flows need only pay 2% if they are busy sending over the last 10 ++ * seconds. Interactive applications (e.g., Web, RPCs, video chunks) often have ++ * natural silences or low-rate periods within 10 seconds where the rate is low ++ * enough for long enough to drain its queue in the bottleneck. We pick up ++ * these min RTT measurements opportunistically with our min_rtt filter. :-) ++ */ ++static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ bool filter_expired; ++ ++ /* Track min RTT seen in the min_rtt_win_sec filter window: */ ++ filter_expired = after(tcp_jiffies32, ++ bbr->min_rtt_stamp + bbr_min_rtt_win_sec * HZ); ++ if (rs->rtt_us >= 0 && ++ (rs->rtt_us <= bbr->min_rtt_us || ++ (filter_expired && !rs->is_ack_delayed))) { ++ bbr->min_rtt_us = rs->rtt_us; ++ bbr->min_rtt_stamp = tcp_jiffies32; ++ } ++ ++ if (bbr_probe_rtt_mode_ms > 0 && filter_expired && ++ !bbr->idle_restart && bbr->mode != BBR_PROBE_RTT) { ++ bbr->mode = BBR_PROBE_RTT; /* dip, drain queue */ ++ bbr->pacing_gain = BBR_UNIT; ++ bbr->cwnd_gain = BBR_UNIT; ++ bbr_save_cwnd(sk); /* note cwnd so we can restore it */ ++ bbr->probe_rtt_done_stamp = 0; ++ } ++ ++ if (bbr->mode == BBR_PROBE_RTT) { ++ /* Ignore low rate samples during this mode. */ ++ tp->app_limited = ++ (tp->delivered + tcp_packets_in_flight(tp)) ? : 1; ++ /* Maintain min packets in flight for max(200 ms, 1 round). */ ++ if (!bbr->probe_rtt_done_stamp && ++ tcp_packets_in_flight(tp) <= bbr_cwnd_min_target) { ++ bbr->probe_rtt_done_stamp = tcp_jiffies32 + ++ msecs_to_jiffies(bbr_probe_rtt_mode_ms); ++ bbr->probe_rtt_round_done = 0; ++ bbr->next_rtt_delivered = tp->delivered; ++ } else if (bbr->probe_rtt_done_stamp) { ++ if (bbr->round_start) ++ bbr->probe_rtt_round_done = 1; ++ if (bbr->probe_rtt_round_done) ++ bbr_check_probe_rtt_done(sk); ++ } ++ } ++ /* Restart after idle ends only once we process a new S/ACK for data */ ++ if (rs->delivered > 0) ++ bbr->idle_restart = 0; ++} ++ ++static void bbr_update_model(struct sock *sk, const struct rate_sample *rs) ++{ ++ bbr_update_bw(sk, rs); ++ bbr_update_cycle_phase(sk, rs); ++ bbr_check_full_bw_reached(sk, rs); ++ bbr_check_drain(sk, rs); ++ bbr_update_min_rtt(sk, rs); ++} ++ ++static void bbr_main(struct sock *sk, const struct rate_sample *rs) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ u32 bw; ++ ++ bbr_update_model(sk, rs); ++ ++ bw = bbr_bw(sk); ++ bbr_set_pacing_rate(sk, bw, bbr->pacing_gain); ++ bbr_set_cwnd(sk, rs, rs->acked_sacked, bw, bbr->cwnd_gain); ++} ++ ++static void bbr_init(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ bbr->prior_cwnd = 0; ++ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; ++ bbr->rtt_cnt = 0; ++ bbr->next_rtt_delivered = 0; ++ bbr->prev_ca_state = TCP_CA_Open; ++ bbr->packet_conservation = 0; ++ ++ bbr->probe_rtt_done_stamp = 0; ++ bbr->probe_rtt_round_done = 0; ++ bbr->min_rtt_us = tcp_min_rtt(tp); ++ bbr->min_rtt_stamp = tcp_jiffies32; ++ ++ minmax_reset(&bbr->bw, bbr->rtt_cnt, 0); /* init max bw to 0 */ ++ ++ bbr->has_seen_rtt = 0; ++ bbr_init_pacing_rate_from_rtt(sk); ++ ++ bbr->round_start = 0; ++ bbr->idle_restart = 0; ++ bbr->full_bw_reached = 0; ++ bbr->full_bw = 0; ++ bbr->full_bw_cnt = 0; ++ bbr->cycle_mstamp = 0; ++ bbr->cycle_idx = 0; ++ bbr_reset_lt_bw_sampling(sk); ++ bbr_reset_startup_mode(sk); ++ ++ cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED); ++} ++ ++static u32 bbr_sndbuf_expand(struct sock *sk) ++{ ++ /* Provision 3 * cwnd since BBR may slow-start even during recovery. */ ++ return 3; ++} ++ ++/* In theory BBR does not need to undo the cwnd since it does not ++ * always reduce cwnd on losses (see bbr_main()). Keep it for now. ++ */ ++static u32 bbr_undo_cwnd(struct sock *sk) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ bbr->full_bw = 0; /* spurious slow-down; reset full pipe detection */ ++ bbr->full_bw_cnt = 0; ++ bbr_reset_lt_bw_sampling(sk); ++ return tcp_sk(sk)->snd_cwnd; ++} ++ ++/* Entering loss recovery, so save cwnd for when we exit or undo recovery. */ ++static u32 bbr_ssthresh(struct sock *sk) ++{ ++ bbr_save_cwnd(sk); ++ return tcp_sk(sk)->snd_ssthresh; ++} ++ ++static size_t bbr_get_info(struct sock *sk, u32 ext, int *attr, ++ union tcp_cc_info *info) ++{ ++ if (ext & (1 << (INET_DIAG_BBRINFO - 1)) || ++ ext & (1 << (INET_DIAG_VEGASINFO - 1))) { ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct bbr *bbr = inet_csk_ca(sk); ++ u64 bw = bbr_bw(sk); ++ ++ bw = bw * tp->mss_cache * USEC_PER_SEC >> BW_SCALE; ++ memset(&info->bbr, 0, sizeof(info->bbr)); ++ info->bbr.bbr_bw_lo = (u32)bw; ++ info->bbr.bbr_bw_hi = (u32)(bw >> 32); ++ info->bbr.bbr_min_rtt = bbr->min_rtt_us; ++ info->bbr.bbr_pacing_gain = bbr->pacing_gain; ++ info->bbr.bbr_cwnd_gain = bbr->cwnd_gain; ++ *attr = INET_DIAG_BBRINFO; ++ return sizeof(info->bbr); ++ } ++ return 0; ++} ++ ++static void bbr_set_state(struct sock *sk, u8 new_state) ++{ ++ struct bbr *bbr = inet_csk_ca(sk); ++ ++ if (new_state == TCP_CA_Loss) { ++ struct rate_sample rs = { .losses = 1 }; ++ ++ bbr->prev_ca_state = TCP_CA_Loss; ++ bbr->full_bw = 0; ++ bbr->round_start = 1; /* treat RTO like end of a round */ ++ bbr_lt_bw_sampling(sk, &rs); ++ } ++} ++ ++static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = { ++ .flags = TCP_CONG_NON_RESTRICTED, ++ .name = "nanqinlang", ++ .owner = THIS_MODULE, ++ .init = bbr_init, ++ .cong_control = bbr_main, ++ .sndbuf_expand = bbr_sndbuf_expand, ++ .undo_cwnd = bbr_undo_cwnd, ++ .cwnd_event = bbr_cwnd_event, ++ .ssthresh = bbr_ssthresh, ++ .min_tso_segs = bbr_min_tso_segs, ++ .get_info = bbr_get_info, ++ .set_state = bbr_set_state, ++}; ++ ++static int __init bbr_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct bbr) > ICSK_CA_PRIV_SIZE); ++ return tcp_register_congestion_control(&tcp_bbr_cong_ops); ++} ++ ++static void __exit bbr_unregister(void) ++{ ++ tcp_unregister_congestion_control(&tcp_bbr_cong_ops); ++} ++ ++module_init(bbr_register); ++module_exit(bbr_unregister); ++ ++MODULE_AUTHOR("Van Jacobson "); ++MODULE_AUTHOR("Neal Cardwell "); ++MODULE_AUTHOR("Yuchung Cheng "); ++MODULE_AUTHOR("Soheil Hassas Yeganeh "); ++MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_DESCRIPTION("TCP BBR (Bottleneck Bandwidth and RTT)"); ++MODULE_AUTHOR("Nanqinlang "); diff --git a/root/target/linux/generic/hack-5.4/998-ndpi-netfilter.patch b/root/target/linux/generic/hack-5.4/998-ndpi-netfilter.patch new file mode 100644 index 00000000..cd8d61a7 --- /dev/null +++ b/root/target/linux/generic/hack-5.4/998-ndpi-netfilter.patch @@ -0,0 +1,116 @@ +diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h +index 21f887c..59980ec 100644 +--- a/include/net/netfilter/nf_conntrack_extend.h ++++ b/include/net/netfilter/nf_conntrack_extend.h +@@ -28,7 +28,8 @@ enum nf_ct_ext_id { + #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) + NF_CT_EXT_SYNPROXY, + #endif +- NF_CT_EXT_NUM, ++ NF_CT_EXT_CUSTOM, ++ NF_CT_EXT_NUM=NF_CT_EXT_CUSTOM+CONFIG_NF_CONNTRACK_CUSTOM, + }; + + #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help +@@ -96,5 +97,6 @@ struct nf_ct_ext_type { + }; + + int nf_ct_extend_register(const struct nf_ct_ext_type *type); ++int nf_ct_extend_custom_register(struct nf_ct_ext_type *type,unsigned long int cid); + void nf_ct_extend_unregister(const struct nf_ct_ext_type *type); + #endif /* _NF_CONNTRACK_EXTEND_H */ +diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig +index 7581e82..30a11eb 100644 +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -85,6 +85,16 @@ config NF_CONNTRACK_SECMARK + + If unsure, say 'N'. + ++config NF_CONNTRACK_CUSTOM ++ int "Number of custom extend" ++ range 0 8 ++ depends on NETFILTER_ADVANCED ++ default "2" ++ help ++ This parameter specifies how many custom extensions can be registered. ++ ++ The default value is 2. ++ + config NF_CONNTRACK_ZONES + bool 'Connection tracking zones' + depends on NETFILTER_ADVANCED +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index 85f643c..44e2fdd 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -1971,7 +1971,7 @@ int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp) + static __always_inline unsigned int total_extension_size(void) + { + /* remember to add new extensions below */ +- BUILD_BUG_ON(NF_CT_EXT_NUM > 9); ++ BUILD_BUG_ON(NF_CT_EXT_NUM > 12); + + return sizeof(struct nf_ct_ext) + + sizeof(struct nf_conn_help) +diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c +index 9fe0ddc..5a9054e 100644 +--- a/net/netfilter/nf_conntrack_extend.c ++++ b/net/netfilter/nf_conntrack_extend.c +@@ -108,11 +108,56 @@ int nf_ct_extend_register(const struct nf_ct_ext_type *type) + } + EXPORT_SYMBOL_GPL(nf_ct_extend_register); + ++static unsigned long int nf_ct_ext_cust_id[CONFIG_NF_CONNTRACK_CUSTOM]; ++static enum nf_ct_ext_id ++nf_ct_extend_get_custom_id(unsigned long int ext_id); ++ ++int nf_ct_extend_custom_register(struct nf_ct_ext_type *type, ++ unsigned long int cid) ++{ ++ int ret; ++ enum nf_ct_ext_id new_id = nf_ct_extend_get_custom_id(cid); ++ if(!new_id) ++ return -EBUSY; ++ type->id = new_id; ++ ret = nf_ct_extend_register(type); ++ if(ret < 0) { ++ mutex_lock(&nf_ct_ext_type_mutex); ++ nf_ct_ext_cust_id[new_id - NF_CT_EXT_CUSTOM] = 0; ++ mutex_unlock(&nf_ct_ext_type_mutex); ++ } ++ return ret; ++} ++EXPORT_SYMBOL_GPL(nf_ct_extend_custom_register); ++ ++static enum nf_ct_ext_id ++nf_ct_extend_get_custom_id(unsigned long int ext_id) ++{ ++ enum nf_ct_ext_id ret = 0; ++ int i; ++ mutex_lock(&nf_ct_ext_type_mutex); ++ for(i = 0; i < CONFIG_NF_CONNTRACK_CUSTOM; i++) { ++ if(!nf_ct_ext_cust_id[i]) { ++ nf_ct_ext_cust_id[i] = ext_id; ++ ret = i+NF_CT_EXT_CUSTOM; ++ break; ++ } ++ if(nf_ct_ext_cust_id[i] == ext_id) { ++ ret = i+NF_CT_EXT_CUSTOM; ++ break; ++ } ++ } ++ mutex_unlock(&nf_ct_ext_type_mutex); ++ return ret; ++} ++ + /* This MUST be called in process context. */ + void nf_ct_extend_unregister(const struct nf_ct_ext_type *type) + { + mutex_lock(&nf_ct_ext_type_mutex); + RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL); ++ if(type->id >= NF_CT_EXT_CUSTOM && type->id < NF_CT_EXT_NUM) ++ nf_ct_ext_cust_id[type->id-NF_CT_EXT_CUSTOM] = 0; + mutex_unlock(&nf_ct_ext_type_mutex); + synchronize_rcu(); + } diff --git a/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch b/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch new file mode 100644 index 00000000..2dc06ee6 --- /dev/null +++ b/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch @@ -0,0 +1,14 @@ +--- a/net/core/dev.c 2018-08-10 10:31:41.199494561 +0200 ++++ b/net/core/dev.c 2018-08-10 10:32:03.635272509 +0200 +@@ -6613,9 +6613,11 @@ + } + } + if (dev->flags != old_flags) { ++ /* + pr_info("device %s %s promiscuous mode\n", + dev->name, + dev->flags & IFF_PROMISC ? "entered" : "left"); ++ */ + if (audit_enabled) { + current_uid_gid(&uid, &gid); + audit_log(current->audit_context, GFP_ATOMIC, From be9efea2b380b8bdd6f2b9b05a812302015bd2ac Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 13 Mar 2020 21:04:22 +0100 Subject: [PATCH 02/76] Fix for ip6tables-nat with kernel 5.4 --- .../package/kernel/linux/modules/netfilter.mk | 1169 +++++++++++++++++ 1 file changed, 1169 insertions(+) create mode 100644 root/package/kernel/linux/modules/netfilter.mk diff --git a/root/package/kernel/linux/modules/netfilter.mk b/root/package/kernel/linux/modules/netfilter.mk new file mode 100644 index 00000000..2060760b --- /dev/null +++ b/root/package/kernel/linux/modules/netfilter.mk @@ -0,0 +1,1169 @@ + +# +# Copyright (C) 2006-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +NF_MENU:=Netfilter Extensions +NF_KMOD:=1 +include $(INCLUDE_DIR)/netfilter.mk + + +define KernelPackage/nf-reject + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter IPv4 reject support + KCONFIG:= \ + CONFIG_NETFILTER=y \ + CONFIG_NETFILTER_ADVANCED=y \ + $(KCONFIG_NF_REJECT) + FILES:=$(foreach mod,$(NF_REJECT-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_REJECT-m))) +endef + +$(eval $(call KernelPackage,nf-reject)) + + +define KernelPackage/nf-reject6 + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter IPv6 reject support + KCONFIG:= \ + CONFIG_NETFILTER=y \ + CONFIG_NETFILTER_ADVANCED=y \ + $(KCONFIG_NF_REJECT6) + DEPENDS:=@IPV6 + FILES:=$(foreach mod,$(NF_REJECT6-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_REJECT6-m))) +endef + +$(eval $(call KernelPackage,nf-reject6)) + + +define KernelPackage/nf-ipt + SUBMENU:=$(NF_MENU) + TITLE:=Iptables core + KCONFIG:=$(KCONFIG_NF_IPT) + FILES:=$(foreach mod,$(NF_IPT-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_IPT-m))) +endef + +$(eval $(call KernelPackage,nf-ipt)) + + +define KernelPackage/nf-ipt6 + SUBMENU:=$(NF_MENU) + TITLE:=Ip6tables core + KCONFIG:=$(KCONFIG_NF_IPT6) + FILES:=$(foreach mod,$(NF_IPT6-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_IPT6-m))) + DEPENDS:=+kmod-nf-ipt +endef + +$(eval $(call KernelPackage,nf-ipt6)) + + + +define KernelPackage/ipt-core + SUBMENU:=$(NF_MENU) + TITLE:=Iptables core + KCONFIG:=$(KCONFIG_IPT_CORE) + FILES:=$(foreach mod,$(IPT_CORE-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CORE-m))) + DEPENDS:=+kmod-nf-reject +kmod-nf-ipt +endef + +define KernelPackage/ipt-core/description + Netfilter core kernel modules + Includes: + - comment + - limit + - LOG + - mac + - multiport + - REJECT + - TCPMSS +endef + +$(eval $(call KernelPackage,ipt-core)) + + +define KernelPackage/nf-conntrack + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter connection tracking + KCONFIG:= \ + CONFIG_NETFILTER=y \ + CONFIG_NETFILTER_ADVANCED=y \ + CONFIG_NF_CONNTRACK_MARK=y \ + CONFIG_NF_CONNTRACK_ZONES=y \ + $(KCONFIG_NF_CONNTRACK) + FILES:=$(foreach mod,$(NF_CONNTRACK-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_CONNTRACK-m))) +endef + +define KernelPackage/nf-conntrack/install + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DATA) ./files/sysctl-nf-conntrack.conf $(1)/etc/sysctl.d/11-nf-conntrack.conf +endef + +$(eval $(call KernelPackage,nf-conntrack)) + + +define KernelPackage/nf-conntrack6 + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter IPv6 connection tracking + KCONFIG:=$(KCONFIG_NF_CONNTRACK6) + DEPENDS:=@IPV6 +kmod-nf-conntrack + FILES:=$(foreach mod,$(NF_CONNTRACK6-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_CONNTRACK6-m))) +endef + +$(eval $(call KernelPackage,nf-conntrack6)) + + +define KernelPackage/nf-nat + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter NAT + KCONFIG:=$(KCONFIG_NF_NAT) + DEPENDS:=+kmod-nf-conntrack + FILES:=$(foreach mod,$(NF_NAT-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NAT-m))) +endef + +$(eval $(call KernelPackage,nf-nat)) + + +define KernelPackage/nf-nat6 + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter IPV6-NAT + KCONFIG:=$(KCONFIG_NF_NAT6) + DEPENDS:=+kmod-nf-conntrack6 +kmod-nf-nat + FILES:=$(foreach mod,$(NF_NAT6-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NAT6-m))) +endef + +$(eval $(call KernelPackage,nf-nat6)) + + +define KernelPackage/nf-flow + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter flowtable support + KCONFIG:= \ + CONFIG_NETFILTER_INGRESS=y \ + CONFIG_NF_FLOW_TABLE \ + CONFIG_NF_FLOW_TABLE_HW + DEPENDS:=+kmod-nf-conntrack + FILES:= \ + $(LINUX_DIR)/net/netfilter/nf_flow_table.ko \ + $(LINUX_DIR)/net/netfilter/nf_flow_table_hw.ko + AUTOLOAD:=$(call AutoProbe,nf_flow_table nf_flow_table_hw) +endef + +$(eval $(call KernelPackage,nf-flow)) + + +define AddDepends/ipt + SUBMENU:=$(NF_MENU) + DEPENDS+= +kmod-ipt-core $(1) +endef + + +define KernelPackage/ipt-conntrack + TITLE:=Basic connection tracking modules + KCONFIG:=$(KCONFIG_IPT_CONNTRACK) + FILES:=$(foreach mod,$(IPT_CONNTRACK-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CONNTRACK-m))) + $(call AddDepends/ipt,+kmod-nf-conntrack) +endef + +define KernelPackage/ipt-conntrack/description + Netfilter (IPv4) kernel modules for connection tracking + Includes: + - conntrack + - defrag + - iptables_raw + - NOTRACK + - state +endef + +$(eval $(call KernelPackage,ipt-conntrack)) + + +define KernelPackage/ipt-conntrack-extra + TITLE:=Extra connection tracking modules + KCONFIG:=$(KCONFIG_IPT_CONNTRACK_EXTRA) + FILES:=$(foreach mod,$(IPT_CONNTRACK_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CONNTRACK_EXTRA-m))) + $(call AddDepends/ipt,+kmod-ipt-conntrack) +endef + +define KernelPackage/ipt-conntrack-extra/description + Netfilter (IPv4) extra kernel modules for connection tracking + Includes: + - connbytes + - connmark/CONNMARK + - conntrack + - helper + - recent +endef + +$(eval $(call KernelPackage,ipt-conntrack-extra)) + +define KernelPackage/ipt-conntrack-label + TITLE:=Module for handling connection tracking labels + KCONFIG:=$(KCONFIG_IPT_CONNTRACK_LABEL) + FILES:=$(foreach mod,$(IPT_CONNTRACK_LABEL-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CONNTRACK_LABEL-m))) + $(call AddDepends/ipt,+kmod-ipt-conntrack) +endef + +define KernelPackage/ipt-conntrack-label/description + Netfilter (IPv4) module for handling connection tracking labels + Includes: + - connlabel +endef + +$(eval $(call KernelPackage,ipt-conntrack-label)) + +define KernelPackage/ipt-filter + TITLE:=Modules for packet content inspection + KCONFIG:=$(KCONFIG_IPT_FILTER) + FILES:=$(foreach mod,$(IPT_FILTER-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_FILTER-m))) + $(call AddDepends/ipt,+kmod-lib-textsearch +kmod-ipt-conntrack) +endef + +define KernelPackage/ipt-filter/description + Netfilter (IPv4) kernel modules for packet content inspection + Includes: + - string + - bpf +endef + +$(eval $(call KernelPackage,ipt-filter)) + + +define KernelPackage/ipt-offload + TITLE:=Netfilter routing/NAT offload support + KCONFIG:=$(KCONFIG_IPT_FLOW) + FILES:=$(foreach mod,$(IPT_FLOW-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_FLOW-m))) + $(call AddDepends/ipt,+kmod-nf-flow) +endef + +$(eval $(call KernelPackage,ipt-offload)) + + +define KernelPackage/ipt-ipopt + TITLE:=Modules for matching/changing IP packet options + KCONFIG:=$(KCONFIG_IPT_IPOPT) + FILES:=$(foreach mod,$(IPT_IPOPT-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPOPT-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-ipopt/description + Netfilter (IPv4) modules for matching/changing IP packet options + Includes: + - CLASSIFY + - dscp/DSCP + - ecn/ECN + - hl/HL + - length + - mark/MARK + - statistic + - tcpmss + - time + - ttl/TTL + - unclean +endef + +$(eval $(call KernelPackage,ipt-ipopt)) + + +define KernelPackage/ipt-ipsec + TITLE:=Modules for matching IPSec packets + KCONFIG:=$(KCONFIG_IPT_IPSEC) + FILES:=$(foreach mod,$(IPT_IPSEC-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPSEC-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-ipsec/description + Netfilter (IPv4) modules for matching IPSec packets + Includes: + - ah + - esp + - policy +endef + +$(eval $(call KernelPackage,ipt-ipsec)) + +IPSET_MODULES:= \ + ipset/ip_set \ + ipset/ip_set_bitmap_ip \ + ipset/ip_set_bitmap_ipmac \ + ipset/ip_set_bitmap_port \ + ipset/ip_set_hash_ip \ + ipset/ip_set_hash_ipmark \ + ipset/ip_set_hash_ipport \ + ipset/ip_set_hash_ipportip \ + ipset/ip_set_hash_ipportnet \ + ipset/ip_set_hash_mac \ + ipset/ip_set_hash_netportnet \ + ipset/ip_set_hash_net \ + ipset/ip_set_hash_netnet \ + ipset/ip_set_hash_netport \ + ipset/ip_set_hash_netiface \ + ipset/ip_set_list_set \ + xt_set + +define KernelPackage/ipt-ipset + SUBMENU:=Netfilter Extensions + TITLE:=IPset netfilter modules + DEPENDS+= +kmod-ipt-core +kmod-nfnetlink + KCONFIG:= \ + CONFIG_IP_SET \ + CONFIG_IP_SET_MAX=256 \ + CONFIG_NETFILTER_XT_SET \ + CONFIG_IP_SET_BITMAP_IP \ + CONFIG_IP_SET_BITMAP_IPMAC \ + CONFIG_IP_SET_BITMAP_PORT \ + CONFIG_IP_SET_HASH_IP \ + CONFIG_IP_SET_HASH_IPMAC \ + CONFIG_IP_SET_HASH_IPMARK \ + CONFIG_IP_SET_HASH_IPPORT \ + CONFIG_IP_SET_HASH_IPPORTIP \ + CONFIG_IP_SET_HASH_IPPORTNET \ + CONFIG_IP_SET_HASH_MAC \ + CONFIG_IP_SET_HASH_NET \ + CONFIG_IP_SET_HASH_NETNET \ + CONFIG_IP_SET_HASH_NETIFACE \ + CONFIG_IP_SET_HASH_NETPORT \ + CONFIG_IP_SET_HASH_NETPORTNET \ + CONFIG_IP_SET_LIST_SET \ + CONFIG_NET_EMATCH_IPSET=n + FILES:=$(foreach mod,$(IPSET_MODULES),$(LINUX_DIR)/net/netfilter/$(mod).ko) + AUTOLOAD:=$(call AutoLoad,49,$(notdir $(IPSET_MODULES))) +endef +$(eval $(call KernelPackage,ipt-ipset)) + + +IPVS_MODULES:= \ + ipvs/ip_vs \ + ipvs/ip_vs_lc \ + ipvs/ip_vs_wlc \ + ipvs/ip_vs_rr \ + ipvs/ip_vs_wrr \ + ipvs/ip_vs_lblc \ + ipvs/ip_vs_lblcr \ + ipvs/ip_vs_dh \ + ipvs/ip_vs_sh \ + ipvs/ip_vs_fo \ + ipvs/ip_vs_ovf \ + ipvs/ip_vs_nq \ + ipvs/ip_vs_sed \ + xt_ipvs + +define KernelPackage/nf-ipvs + SUBMENU:=Netfilter Extensions + TITLE:=IP Virtual Server modules + DEPENDS:=@IPV6 +kmod-lib-crc32c +kmod-ipt-conntrack +kmod-nf-conntrack +LINUX_4_14:kmod-nf-conntrack6 + KCONFIG:= \ + CONFIG_IP_VS \ + CONFIG_IP_VS_IPV6=y \ + CONFIG_IP_VS_DEBUG=n \ + CONFIG_IP_VS_PROTO_TCP=y \ + CONFIG_IP_VS_PROTO_UDP=y \ + CONFIG_IP_VS_PROTO_AH_ESP=y \ + CONFIG_IP_VS_PROTO_ESP=y \ + CONFIG_IP_VS_PROTO_AH=y \ + CONFIG_IP_VS_PROTO_SCTP=y \ + CONFIG_IP_VS_TAB_BITS=12 \ + CONFIG_IP_VS_RR \ + CONFIG_IP_VS_WRR \ + CONFIG_IP_VS_LC \ + CONFIG_IP_VS_WLC \ + CONFIG_IP_VS_FO \ + CONFIG_IP_VS_OVF \ + CONFIG_IP_VS_LBLC \ + CONFIG_IP_VS_LBLCR \ + CONFIG_IP_VS_DH \ + CONFIG_IP_VS_SH \ + CONFIG_IP_VS_SED \ + CONFIG_IP_VS_NQ \ + CONFIG_IP_VS_SH_TAB_BITS=8 \ + CONFIG_IP_VS_NFCT=y \ + CONFIG_NETFILTER_XT_MATCH_IPVS + FILES:=$(foreach mod,$(IPVS_MODULES),$(LINUX_DIR)/net/netfilter/$(mod).ko) + $(call AddDepends/ipt,+kmod-ipt-conntrack,+kmod-nf-conntrack) +endef + +define KernelPackage/nf-ipvs/description + IPVS (IP Virtual Server) implements transport-layer load balancing inside + the Linux kernel so called Layer-4 switching. +endef + +$(eval $(call KernelPackage,nf-ipvs)) + + +define KernelPackage/nf-ipvs-ftp + SUBMENU:=$(NF_MENU) + TITLE:=Virtual Server FTP protocol support + KCONFIG:=CONFIG_IP_VS_FTP + DEPENDS:=kmod-nf-ipvs +kmod-nf-nat +kmod-nf-nathelper + FILES:=$(LINUX_DIR)/net/netfilter/ipvs/ip_vs_ftp.ko +endef + +define KernelPackage/nf-ipvs-ftp/description + In the virtual server via Network Address Translation, + the IP address and port number of real servers cannot be sent to + clients in ftp connections directly, so FTP protocol helper is + required for tracking the connection and mangling it back to that of + virtual service. +endef + +$(eval $(call KernelPackage,nf-ipvs-ftp)) + + +define KernelPackage/nf-ipvs-sip + SUBMENU:=$(NF_MENU) + TITLE:=Virtual Server SIP protocol support + KCONFIG:=CONFIG_IP_VS_PE_SIP + DEPENDS:=kmod-nf-ipvs +kmod-nf-nathelper-extra + FILES:=$(LINUX_DIR)/net/netfilter/ipvs/ip_vs_pe_sip.ko +endef + +define KernelPackage/nf-ipvs-sip/description + Allow persistence based on the SIP Call-ID +endef + +$(eval $(call KernelPackage,nf-ipvs-sip)) + + +define KernelPackage/ipt-nat + TITLE:=Basic NAT targets + KCONFIG:=$(KCONFIG_IPT_NAT) + FILES:=$(foreach mod,$(IPT_NAT-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NAT-m))) + $(call AddDepends/ipt,+kmod-nf-nat) +endef + +define KernelPackage/ipt-nat/description + Netfilter (IPv4) kernel modules for basic NAT targets + Includes: + - MASQUERADE +endef + +$(eval $(call KernelPackage,ipt-nat)) + + +define KernelPackage/ipt-raw + TITLE:=Netfilter IPv4 raw table support + KCONFIG:=CONFIG_IP_NF_RAW + FILES:=$(LINUX_DIR)/net/ipv4/netfilter/iptable_raw.ko + AUTOLOAD:=$(call AutoProbe,iptable_raw) + $(call AddDepends/ipt) +endef + +$(eval $(call KernelPackage,ipt-raw)) + + +define KernelPackage/ipt-raw6 + TITLE:=Netfilter IPv6 raw table support + KCONFIG:=CONFIG_IP6_NF_RAW + FILES:=$(LINUX_DIR)/net/ipv6/netfilter/ip6table_raw.ko + AUTOLOAD:=$(call AutoProbe,ip6table_raw) + $(call AddDepends/ipt,+kmod-ip6tables) +endef + +$(eval $(call KernelPackage,ipt-raw6)) + + +define KernelPackage/ipt-nat6 + TITLE:=IPv6 NAT targets + KCONFIG:=$(KCONFIG_IPT_NAT6) + FILES:= \ + $(LINUX_DIR)/net/ipv6/netfilter/ip6table_nat.ko \ + $(LINUX_DIR)/net/ipv6/netfilter/ip6t_NPT.ko + AUTOLOAD:=$(call AutoLoad,43,$(notdir $(IPT_NAT6-m))) + $(call AddDepends/ipt,+kmod-nf-nat6) + $(call AddDepends/ipt,+kmod-ipt-conntrack) + $(call AddDepends/ipt,+kmod-ipt-nat) + $(call AddDepends/ipt,+kmod-ip6tables) +endef + +define KernelPackage/ipt-nat6/description + Netfilter (IPv6) kernel modules for NAT targets +endef + +$(eval $(call KernelPackage,ipt-nat6)) + + +define KernelPackage/ipt-nat-extra + TITLE:=Extra NAT targets + KCONFIG:=$(KCONFIG_IPT_NAT_EXTRA) + FILES:=$(foreach mod,$(IPT_NAT_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NAT_EXTRA-m))) + $(call AddDepends/ipt,+kmod-ipt-nat) +endef + +define KernelPackage/ipt-nat-extra/description + Netfilter (IPv4) kernel modules for extra NAT targets + Includes: + - NETMAP + - REDIRECT +endef + +$(eval $(call KernelPackage,ipt-nat-extra)) + + +define KernelPackage/nf-nathelper + SUBMENU:=$(NF_MENU) + TITLE:=Basic Conntrack and NAT helpers + KCONFIG:=$(KCONFIG_NF_NATHELPER) + FILES:=$(foreach mod,$(NF_NATHELPER-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NATHELPER-m))) + DEPENDS:=+kmod-nf-nat +endef + +define KernelPackage/nf-nathelper/description + Default Netfilter (IPv4) Conntrack and NAT helpers + Includes: + - ftp +endef + +$(eval $(call KernelPackage,nf-nathelper)) + + +define KernelPackage/nf-nathelper-extra + SUBMENU:=$(NF_MENU) + TITLE:=Extra Conntrack and NAT helpers + KCONFIG:=$(KCONFIG_NF_NATHELPER_EXTRA) + FILES:=$(foreach mod,$(NF_NATHELPER_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NATHELPER_EXTRA-m))) + DEPENDS:=+kmod-nf-nat +kmod-lib-textsearch +kmod-ipt-raw +!LINUX_4_14:kmod-asn1-decoder +endef + +define KernelPackage/nf-nathelper-extra/description + Extra Netfilter (IPv4) Conntrack and NAT helpers + Includes: + - amanda + - h323 + - irc + - mms + - pptp + - proto_gre + - sip + - snmp_basic + - tftp + - broadcast +endef + +$(eval $(call KernelPackage,nf-nathelper-extra)) + + +define KernelPackage/ipt-ulog + TITLE:=Module for user-space packet logging + KCONFIG:=$(KCONFIG_IPT_ULOG) + FILES:=$(foreach mod,$(IPT_ULOG-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_ULOG-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-ulog/description + Netfilter (IPv4) module for user-space packet logging + Includes: + - ULOG +endef + +$(eval $(call KernelPackage,ipt-ulog)) + + +define KernelPackage/ipt-nflog + TITLE:=Module for user-space packet logging + KCONFIG:=$(KCONFIG_IPT_NFLOG) + FILES:=$(foreach mod,$(IPT_NFLOG-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NFLOG-m))) + $(call AddDepends/ipt,+kmod-nfnetlink-log) +endef + +define KernelPackage/ipt-nflog/description + Netfilter module for user-space packet logging + Includes: + - NFLOG +endef + +$(eval $(call KernelPackage,ipt-nflog)) + + +define KernelPackage/ipt-nfqueue + TITLE:=Module for user-space packet queuing + KCONFIG:=$(KCONFIG_IPT_NFQUEUE) + FILES:=$(foreach mod,$(IPT_NFQUEUE-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NFQUEUE-m))) + $(call AddDepends/ipt,+kmod-nfnetlink-queue) +endef + +define KernelPackage/ipt-nfqueue/description + Netfilter module for user-space packet queuing + Includes: + - NFQUEUE +endef + +$(eval $(call KernelPackage,ipt-nfqueue)) + + +define KernelPackage/ipt-debug + TITLE:=Module for debugging/development + KCONFIG:=$(KCONFIG_IPT_DEBUG) + FILES:=$(foreach mod,$(IPT_DEBUG-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_DEBUG-m))) + $(call AddDepends/ipt,+kmod-ipt-raw +IPV6:kmod-ipt-raw6) +endef + +define KernelPackage/ipt-debug/description + Netfilter modules for debugging/development of the firewall + Includes: + - TRACE +endef + +$(eval $(call KernelPackage,ipt-debug)) + + +define KernelPackage/ipt-led + TITLE:=Module to trigger a LED with a Netfilter rule + KCONFIG:=$(KCONFIG_IPT_LED) + FILES:=$(foreach mod,$(IPT_LED-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_LED-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-led/description + Netfilter target to trigger a LED when a network packet is matched. +endef + +$(eval $(call KernelPackage,ipt-led)) + +define KernelPackage/ipt-tproxy + TITLE:=Transparent proxying support + DEPENDS+=+kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +IPV6:kmod-ip6tables + KCONFIG:=$(KCONFIG_IPT_TPROXY) + FILES:=$(foreach mod,$(IPT_TPROXY-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_TPROXY-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-tproxy/description + Kernel modules for Transparent Proxying +endef + +$(eval $(call KernelPackage,ipt-tproxy)) + +define KernelPackage/ipt-tee + TITLE:=TEE support + DEPENDS:=+kmod-ipt-conntrack + KCONFIG:=$(KCONFIG_IPT_TEE) + FILES:=$(foreach mod,$(IPT_TEE-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir nf_tee $(IPT_TEE-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-tee/description + Kernel modules for TEE +endef + +$(eval $(call KernelPackage,ipt-tee)) + + +define KernelPackage/ipt-u32 + TITLE:=U32 support + KCONFIG:=$(KCONFIG_IPT_U32) + FILES:=$(foreach mod,$(IPT_U32-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir nf_tee $(IPT_U32-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-u32/description + Kernel modules for U32 +endef + +$(eval $(call KernelPackage,ipt-u32)) + +define KernelPackage/ipt-checksum + TITLE:=CHECKSUM support + KCONFIG:=$(KCONFIG_IPT_CHECKSUM) + FILES:=$(foreach mod,$(IPT_CHECKSUM-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CHECKSUM-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-checksum/description + Kernel modules for CHECKSUM fillin target +endef + +$(eval $(call KernelPackage,ipt-checksum)) + + +define KernelPackage/ipt-iprange + TITLE:=Module for matching ip ranges + KCONFIG:=$(KCONFIG_IPT_IPRANGE) + FILES:=$(foreach mod,$(IPT_IPRANGE-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPRANGE-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-iprange/description + Netfilter (IPv4) module for matching ip ranges + Includes: + - iprange +endef + +$(eval $(call KernelPackage,ipt-iprange)) + +define KernelPackage/ipt-cluster + TITLE:=Module for matching cluster + KCONFIG:=$(KCONFIG_IPT_CLUSTER) + FILES:=$(foreach mod,$(IPT_CLUSTER-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CLUSTER-m))) + $(call AddDepends/ipt,+kmod-nf-conntrack) +endef + +define KernelPackage/ipt-cluster/description + Netfilter (IPv4/IPv6) module for matching cluster + This option allows you to build work-load-sharing clusters of + network servers/stateful firewalls without having a dedicated + load-balancing router/server/switch. Basically, this match returns + true when the packet must be handled by this cluster node. Thus, + all nodes see all packets and this match decides which node handles + what packets. The work-load sharing algorithm is based on source + address hashing. + + This module is usable for ipv4 and ipv6. + + To use it also enable iptables-mod-cluster + + see `iptables -m cluster --help` for more information. +endef + +$(eval $(call KernelPackage,ipt-cluster)) + +define KernelPackage/ipt-clusterip + TITLE:=Module for CLUSTERIP + KCONFIG:=$(KCONFIG_IPT_CLUSTERIP) + FILES:=$(foreach mod,$(IPT_CLUSTERIP-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CLUSTERIP-m))) + $(call AddDepends/ipt,+kmod-nf-conntrack) +endef + +define KernelPackage/ipt-clusterip/description + Netfilter (IPv4-only) module for CLUSTERIP + The CLUSTERIP target allows you to build load-balancing clusters of + network servers without having a dedicated load-balancing + router/server/switch. + + To use it also enable iptables-mod-clusterip + + see `iptables -j CLUSTERIP --help` for more information. +endef + +$(eval $(call KernelPackage,ipt-clusterip)) + + +define KernelPackage/ipt-extra + TITLE:=Extra modules + KCONFIG:=$(KCONFIG_IPT_EXTRA) + FILES:=$(foreach mod,$(IPT_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_EXTRA-m))) + $(call AddDepends/ipt) +endef + +define KernelPackage/ipt-extra/description + Other Netfilter (IPv4) kernel modules + Includes: + - addrtype + - owner + - pkttype + - quota +endef + +$(eval $(call KernelPackage,ipt-extra)) + + +define KernelPackage/ipt-physdev + TITLE:=physdev module + KCONFIG:=$(KCONFIG_IPT_PHYSDEV) + FILES:=$(foreach mod,$(IPT_PHYSDEV-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_PHYSDEV-m))) + $(call AddDepends/ipt,+kmod-br-netfilter) +endef + +define KernelPackage/ipt-physdev/description + The iptables physdev kernel module +endef + +$(eval $(call KernelPackage,ipt-physdev)) + + +define KernelPackage/ip6tables + SUBMENU:=$(NF_MENU) + TITLE:=IPv6 modules + DEPENDS:=+kmod-nf-reject6 +kmod-nf-ipt6 +kmod-ipt-core + KCONFIG:=$(KCONFIG_IPT_IPV6) + FILES:=$(foreach mod,$(IPT_IPV6-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoLoad,42,$(notdir $(IPT_IPV6-m))) +endef + +define KernelPackage/ip6tables/description + Netfilter IPv6 firewalling support +endef + +$(eval $(call KernelPackage,ip6tables)) + +define KernelPackage/ip6tables-extra + SUBMENU:=$(NF_MENU) + TITLE:=Extra IPv6 modules + DEPENDS:=+kmod-ip6tables + KCONFIG:=$(KCONFIG_IPT_IPV6_EXTRA) + FILES:=$(foreach mod,$(IPT_IPV6_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoLoad,43,$(notdir $(IPT_IPV6_EXTRA-m))) +endef + +define KernelPackage/ip6tables-extra/description + Netfilter IPv6 extra header matching modules +endef + +$(eval $(call KernelPackage,ip6tables-extra)) + +ARP_MODULES = arp_tables arpt_mangle arptable_filter +define KernelPackage/arptables + SUBMENU:=$(NF_MENU) + TITLE:=ARP firewalling modules + DEPENDS:=+kmod-ipt-core + FILES:=$(LINUX_DIR)/net/ipv4/netfilter/arp*.ko + KCONFIG:=CONFIG_IP_NF_ARPTABLES \ + CONFIG_IP_NF_ARPFILTER \ + CONFIG_IP_NF_ARP_MANGLE + AUTOLOAD:=$(call AutoProbe,$(ARP_MODULES)) +endef + +define KernelPackage/arptables/description + Kernel modules for ARP firewalling +endef + +$(eval $(call KernelPackage,arptables)) + + +define KernelPackage/br-netfilter + SUBMENU:=$(NF_MENU) + TITLE:=Bridge netfilter support modules + DEPENDS:=+kmod-ipt-core + FILES:=$(LINUX_DIR)/net/bridge/br_netfilter.ko + KCONFIG:=CONFIG_BRIDGE_NETFILTER + AUTOLOAD:=$(call AutoProbe,br_netfilter) +endef + +define KernelPackage/br-netfilter/install + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DATA) ./files/sysctl-br-netfilter.conf $(1)/etc/sysctl.d/11-br-netfilter.conf +endef + +$(eval $(call KernelPackage,br-netfilter)) + + +define KernelPackage/ebtables + SUBMENU:=$(NF_MENU) + TITLE:=Bridge firewalling modules + DEPENDS:=+kmod-ipt-core + FILES:=$(foreach mod,$(EBTABLES-m),$(LINUX_DIR)/net/$(mod).ko) + KCONFIG:=$(KCONFIG_EBTABLES) + AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES-m))) +endef + +define KernelPackage/ebtables/description + ebtables is a general, extensible frame/packet identification + framework. It provides you to do Ethernet + filtering/NAT/brouting on the Ethernet bridge. +endef + +$(eval $(call KernelPackage,ebtables)) + + +define AddDepends/ebtables + SUBMENU:=$(NF_MENU) + DEPENDS+= +kmod-ebtables $(1) +endef + + +define KernelPackage/ebtables-ipv4 + TITLE:=ebtables: IPv4 support + FILES:=$(foreach mod,$(EBTABLES_IP4-m),$(LINUX_DIR)/net/$(mod).ko) + KCONFIG:=$(KCONFIG_EBTABLES_IP4) + AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_IP4-m))) + $(call AddDepends/ebtables) +endef + +define KernelPackage/ebtables-ipv4/description + This option adds the IPv4 support to ebtables, which allows basic + IPv4 header field filtering, ARP filtering as well as SNAT, DNAT targets. +endef + +$(eval $(call KernelPackage,ebtables-ipv4)) + + +define KernelPackage/ebtables-ipv6 + TITLE:=ebtables: IPv6 support + FILES:=$(foreach mod,$(EBTABLES_IP6-m),$(LINUX_DIR)/net/$(mod).ko) + KCONFIG:=$(KCONFIG_EBTABLES_IP6) + AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_IP6-m))) + $(call AddDepends/ebtables) +endef + +define KernelPackage/ebtables-ipv6/description + This option adds the IPv6 support to ebtables, which allows basic + IPv6 header field filtering and target support. +endef + +$(eval $(call KernelPackage,ebtables-ipv6)) + + +define KernelPackage/ebtables-watchers + TITLE:=ebtables: watchers support + FILES:=$(foreach mod,$(EBTABLES_WATCHERS-m),$(LINUX_DIR)/net/$(mod).ko) + KCONFIG:=$(KCONFIG_EBTABLES_WATCHERS) + AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_WATCHERS-m))) + $(call AddDepends/ebtables) +endef + +define KernelPackage/ebtables-watchers/description + This option adds the log watchers, that you can use in any rule + in any ebtables table. +endef + +$(eval $(call KernelPackage,ebtables-watchers)) + + +define KernelPackage/nfnetlink + SUBMENU:=$(NF_MENU) + TITLE:=Netlink-based userspace interface + FILES:=$(foreach mod,$(NFNETLINK-m),$(LINUX_DIR)/net/$(mod).ko) + KCONFIG:=$(KCONFIG_NFNETLINK) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK-m))) +endef + +define KernelPackage/nfnetlink/description + Kernel modules support for a netlink-based userspace interface +endef + +$(eval $(call KernelPackage,nfnetlink)) + + +define AddDepends/nfnetlink + SUBMENU:=$(NF_MENU) + DEPENDS+=+kmod-nfnetlink $(1) +endef + + +define KernelPackage/nfnetlink-log + TITLE:=Netfilter LOG over NFNETLINK interface + FILES:=$(foreach mod,$(NFNETLINK_LOG-m),$(LINUX_DIR)/net/$(mod).ko) + KCONFIG:=$(KCONFIG_NFNETLINK_LOG) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK_LOG-m))) + $(call AddDepends/nfnetlink) +endef + +define KernelPackage/nfnetlink-log/description + Kernel modules support for logging packets via NFNETLINK + Includes: + - NFLOG +endef + +$(eval $(call KernelPackage,nfnetlink-log)) + + +define KernelPackage/nfnetlink-queue + TITLE:=Netfilter QUEUE over NFNETLINK interface + FILES:=$(foreach mod,$(NFNETLINK_QUEUE-m),$(LINUX_DIR)/net/$(mod).ko) + KCONFIG:=$(KCONFIG_NFNETLINK_QUEUE) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK_QUEUE-m))) + $(call AddDepends/nfnetlink) +endef + +define KernelPackage/nfnetlink-queue/description + Kernel modules support for queueing packets via NFNETLINK + Includes: + - NFQUEUE +endef + +$(eval $(call KernelPackage,nfnetlink-queue)) + + +define KernelPackage/nf-conntrack-netlink + TITLE:=Connection tracking netlink interface + FILES:=$(LINUX_DIR)/net/netfilter/nf_conntrack_netlink.ko + KCONFIG:=CONFIG_NF_CT_NETLINK CONFIG_NF_CONNTRACK_EVENTS=y + AUTOLOAD:=$(call AutoProbe,nf_conntrack_netlink) + $(call AddDepends/nfnetlink,+kmod-ipt-conntrack) +endef + +define KernelPackage/nf-conntrack-netlink/description + Kernel modules support for a netlink-based connection tracking + userspace interface +endef + +$(eval $(call KernelPackage,nf-conntrack-netlink)) + +define KernelPackage/ipt-hashlimit + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter hashlimit match + DEPENDS:=+kmod-ipt-core + KCONFIG:=$(KCONFIG_IPT_HASHLIMIT) + FILES:=$(LINUX_DIR)/net/netfilter/xt_hashlimit.ko + AUTOLOAD:=$(call AutoProbe,xt_hashlimit) + $(call KernelPackage/ipt) +endef + +define KernelPackage/ipt-hashlimit/description + Kernel modules support for the hashlimit bucket match module +endef + +$(eval $(call KernelPackage,ipt-hashlimit)) + +define KernelPackage/ipt-rpfilter + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter rpfilter match + DEPENDS:=+kmod-ipt-core + KCONFIG:=$(KCONFIG_IPT_RPFILTER) + FILES:=$(realpath \ + $(LINUX_DIR)/net/ipv4/netfilter/ipt_rpfilter.ko \ + $(LINUX_DIR)/net/ipv6/netfilter/ip6t_rpfilter.ko) + AUTOLOAD:=$(call AutoProbe,ipt_rpfilter ip6t_rpfilter) + $(call KernelPackage/ipt) +endef + +define KernelPackage/ipt-rpfilter/description + Kernel modules support for the Netfilter rpfilter match +endef + +$(eval $(call KernelPackage,ipt-rpfilter)) + + +define KernelPackage/nft-core + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables support + DEPENDS:=+kmod-nfnetlink +kmod-nf-reject +kmod-nf-reject6 +kmod-nf-conntrack6 +LINUX_5_4:kmod-nf-nat + FILES:=$(foreach mod,$(NFT_CORE-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_CORE-m))) + KCONFIG:= \ + CONFIG_NFT_COMPAT=n \ + CONFIG_NFT_QUEUE=n \ + $(KCONFIG_NFT_CORE) +endef + +define KernelPackage/nft-core/description + Kernel module support for nftables +endef + +$(eval $(call KernelPackage,nft-core)) + + +define KernelPackage/nft-arp + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables ARP table support + DEPENDS:=+kmod-nft-core + FILES:=$(foreach mod,$(NFT_ARP-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_ARP-m))) + KCONFIG:=$(KCONFIG_NFT_ARP) +endef + +$(eval $(call KernelPackage,nft-arp)) + + +define KernelPackage/nft-bridge + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables bridge table support + DEPENDS:=+kmod-nft-core + FILES:=$(foreach mod,$(NFT_BRIDGE-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_BRIDGE-m))) + KCONFIG:= \ + CONFIG_NF_LOG_BRIDGE=n \ + $(KCONFIG_NFT_BRIDGE) +endef + +$(eval $(call KernelPackage,nft-bridge)) + + +define KernelPackage/nft-nat + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables NAT support + DEPENDS:=+kmod-nft-core +kmod-nf-nat + FILES:=$(foreach mod,$(NFT_NAT-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_NAT-m))) + KCONFIG:=$(KCONFIG_NFT_NAT) +endef + +$(eval $(call KernelPackage,nft-nat)) + + +define KernelPackage/nft-offload + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables routing/NAT offload support + DEPENDS:=+kmod-nf-flow +kmod-nft-nat + KCONFIG:= \ + CONFIG_NF_FLOW_TABLE_INET \ + CONFIG_NF_FLOW_TABLE_IPV4 \ + CONFIG_NF_FLOW_TABLE_IPV6 \ + CONFIG_NFT_FLOW_OFFLOAD + FILES:= \ + $(LINUX_DIR)/net/netfilter/nf_flow_table_inet.ko \ + $(LINUX_DIR)/net/ipv4/netfilter/nf_flow_table_ipv4.ko \ + $(LINUX_DIR)/net/ipv6/netfilter/nf_flow_table_ipv6.ko \ + $(LINUX_DIR)/net/netfilter/nft_flow_offload.ko + AUTOLOAD:=$(call AutoProbe,nf_flow_table_inet nf_flow_table_ipv4 nf_flow_table_ipv6 nft_flow_offload) +endef + +$(eval $(call KernelPackage,nft-offload)) + + +define KernelPackage/nft-nat6 + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables IPv6-NAT support + DEPENDS:=+kmod-nft-nat +kmod-nf-nat6 + FILES:=$(foreach mod,$(NFT_NAT6-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_NAT6-m))) + KCONFIG:=$(KCONFIG_NFT_NAT6) +endef + +$(eval $(call KernelPackage,nft-nat6)) + +define KernelPackage/nft-netdev + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables netdev support + DEPENDS:=+kmod-nft-core + KCONFIG:= \ + CONFIG_NETFILTER_INGRESS=y \ + CONFIG_NF_TABLES_NETDEV \ + CONFIG_NF_DUP_NETDEV \ + CONFIG_NFT_DUP_NETDEV \ + CONFIG_NFT_FWD_NETDEV + FILES:= \ + $(LINUX_DIR)/net/netfilter/nf_tables_netdev.ko@lt4.17 \ + $(LINUX_DIR)/net/netfilter/nf_dup_netdev.ko \ + $(LINUX_DIR)/net/netfilter/nft_dup_netdev.ko \ + $(LINUX_DIR)/net/netfilter/nft_fwd_netdev.ko + AUTOLOAD:=$(call AutoProbe,nf_tables_netdev nf_dup_netdev nft_dup_netdev nft_fwd_netdev) +endef + +$(eval $(call KernelPackage,nft-netdev)) + + +define KernelPackage/nft-fib + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables fib support + DEPENDS:=+kmod-nft-core + FILES:=$(foreach mod,$(NFT_FIB-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_FIB-m))) + KCONFIG:=$(KCONFIG_NFT_FIB) +endef + +$(eval $(call KernelPackage,nft-fib)) From d1ecaaeaf8eff35a93334a562697b6bebc917210 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 27 Mar 2020 10:19:22 +0100 Subject: [PATCH 03/76] Update OpenWrt, fix and add mvebu 5.14 support --- build.sh | 32 +- patches/ipt-nat6.patch | 13 + patches/mvebu-5.14.patch | 7720 ++++++++++++++++++++++++++++++++++++++ patches/smsc75xx.patch | 26 + patches/uefi.patch | 856 +++-- 5 files changed, 8264 insertions(+), 383 deletions(-) create mode 100644 patches/ipt-nat6.patch create mode 100644 patches/mvebu-5.14.patch create mode 100644 patches/smsc75xx.patch diff --git a/build.sh b/build.sh index 588f6c95..7082f7bf 100755 --- a/build.sh +++ b/build.sh @@ -29,7 +29,7 @@ OMR_UEFI=${OMR_UEFI:-yes} OMR_ALL_PACKAGES=${OMR_ALL_PACKAGES:-no} OMR_TARGET=${OMR_TARGET:-x86_64} OMR_TARGET_CONFIG="config-$OMR_TARGET" -OMR_KERNEL=${OMR_KERNEL:-4.19} +OMR_KERNEL=${OMR_KERNEL:-5.4} OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" OMR_FEED_SRC="${OMR_FEED_SRC:-develop}" @@ -58,9 +58,9 @@ else fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" -_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "04a21c26a005ac314b79e6905f51b4789d6d79bd" -_get_repo feeds/packages https://github.com/openwrt/packages "e48af750e169e201feb9618828ed9f77b647d234" -_get_repo feeds/luci https://github.com/openwrt/luci "3fb8e3d6236c2ea418c5a5fd90564d9eb44732f3" +_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "dd166960f48580bf6d4a8dde071b96832bfd9e1f" +_get_repo feeds/packages https://github.com/openwrt/packages "ce15a63a9ef2877df1d61429dd6db5432a204d63" +_get_repo feeds/luci https://github.com/openwrt/luci "6efaea2ffb46f9909038b85cf12e7acf4467ae2e" if [ -z "$OMR_FEED" ]; then OMR_FEED=feeds/openmptcprouter @@ -172,6 +172,24 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/nanqinlang.patch; then fi echo "Done" +echo "Checking if smsc75xx patch is set or not" +if ! patch -Rf -N -p1 -s --dry-run < ../../patches/smsc75xx.patch; then + patch -N -p1 -s < ../../patches/smsc75xx.patch +fi +echo "Done" + +echo "Checking if ipt-nat patch is set or not" +if ! patch -Rf -N -p1 -s --dry-run < ../../patches/ipt-nat6.patch; then + patch -N -p1 -s < ../../patches/ipt-nat6.patch +fi +echo "Done" + +echo "Checking if ipt-nat patch is set or not" +if [ ! -d target/linux/mvebu/patches-5.4 ]; then + patch -N -p1 -s < ../../patches/mvebu-5.14.patch +fi +echo "Done" + #echo "Patch protobuf wrong hash" #patch -N -R -p1 -s < ../../patches/protobuf_hash.patch @@ -190,9 +208,9 @@ if [ "$OMR_KERNEL" = "5.4" ]; then echo "Set to kernel 5.4 for x86 arch" find target/linux/x86 -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.19%KERNEL_PATCHVER:=5.4%g' {} \; echo "Done" -# echo "Set to kernel 5.4 for mvebu arch (WRT)" -# find target/linux/mvebu -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.19%KERNEL_PATCHVER:=5.4%g' {} \; -# echo "Done" + echo "Set to kernel 5.4 for mvebu arch (WRT)" + find target/linux/mvebu -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.19%KERNEL_PATCHVER:=5.4%g' {} \; + echo "Done" echo "Set to kernel 5.4 for mediatek arch (BPI-R2)" find target/linux/mediatek -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=4.19%KERNEL_PATCHVER:=5.4%g' {} \; echo "Done" diff --git a/patches/ipt-nat6.patch b/patches/ipt-nat6.patch new file mode 100644 index 00000000..10fc9eaf --- /dev/null +++ b/patches/ipt-nat6.patch @@ -0,0 +1,13 @@ +--- a/package/kernel/linux/modules/netfilter.mk 2020-03-20 15:41:58.620893747 +0100 ++++ b/package/kernel/linux/modules/netfilter.mk 2020-03-20 15:45:34.389015301 +0100 +@@ -483,7 +483,9 @@ + define KernelPackage/ipt-nat6 + TITLE:=IPv6 NAT targets + KCONFIG:=$(KCONFIG_IPT_NAT6) +- FILES:=$(foreach mod,$(IPT_NAT6-m),$(LINUX_DIR)/net/$(mod).ko) ++ FILES:= \ ++ $(LINUX_DIR)/net/ipv6/netfilter/ip6t_NPT.ko \ ++ $(LINUX_DIR)/net/ipv6/netfilter/ip6table_nat.ko + AUTOLOAD:=$(call AutoLoad,43,$(notdir $(IPT_NAT6-m))) + $(call AddDepends/ipt,+kmod-nf-nat6) + $(call AddDepends/ipt,+kmod-ipt-conntrack) diff --git a/patches/mvebu-5.14.patch b/patches/mvebu-5.14.patch new file mode 100644 index 00000000..2d0112c2 --- /dev/null +++ b/patches/mvebu-5.14.patch @@ -0,0 +1,7720 @@ +From 7d933370e999abf6a25624597f3cb1a15a62d3e2 Mon Sep 17 00:00:00 2001 +From: DENG Qingfang +Date: Wed, 4 Mar 2020 20:46:10 +0800 +Subject: [PATCH 1/4] mvebu: copy files and patches to 5.4 + +Signed-off-by: DENG Qingfang +--- + target/linux/mvebu/config-5.4 | 498 +++++++++++ + target/linux/mvebu/cortexa53/config-5.4 | 169 ++++ + target/linux/mvebu/cortexa72/config-5.4 | 176 ++++ + .../arm/boot/dts/armada-385-linksys-venom.dts | 213 +++++ + .../marvell/armada-3720-espressobin-emmc.dts | 28 + + .../armada-3720-espressobin-v7-emmc.dts | 43 + + .../marvell/armada-3720-espressobin-v7.dts | 31 + + .../boot/dts/marvell/armada-3720-uDPU.dts | 162 ++++ + .../patches-5.4/002-add_powertables.patch | 770 ++++++++++++++++++ + .../patches-5.4/003-add_switch_nodes.patch | 40 + + .../004-add_sata_disk_activity_trigger.patch | 39 + + ...5-linksys_hardcode_nand_ecc_settings.patch | 17 + + ...Mangle-bootloader-s-kernel-arguments.patch | 201 +++++ + .../patches-5.4/100-find_active_root.patch | 60 ++ + .../patches-5.4/102-revert_i2c_delay.patch | 15 + + .../205-armada-385-rd-mtd-partitions.patch | 19 + + .../206-ARM-mvebu-385-ap-Add-partitions.patch | 35 + + .../210-clearfog_switch_node.patch | 21 + + .../220-disable-untested-dsa-boards.patch | 30 + + ...-armada-xp-linksys-mamba-broken-idle.patch | 10 + + .../patches-5.4/240-linksys-status-led.patch | 50 ++ + .../300-mvneta-tx-queue-workaround.patch | 35 + + ...dicate-failure-to-enter-deeper-sleep.patch | 40 + + ...-pci-mvebu-time-out-reset-on-link-up.patch | 60 ++ + ...da388-clearfog-emmc-on-clearfog-base.patch | 87 ++ + ...rmada388-clearfog-document-MPP-usage.patch | 124 +++ + ...l-armada37xx-Add-emmc-sdio-pinctrl-d.patch | 40 + + ...l-armada-37xx-Enable-emmc-on-espress.patch | 49 ++ + ...ts-marvell-armada37xx-Add-eth0-alias.patch | 20 + + ...da-3720-espressobin-correct-spi-node.patch | 58 ++ + ...l-armada-3720-espressobin-add-ports-.patch | 26 + + ...rdvark-Convert-to-use-pci_host_probe.patch | 44 + + ...-device-to-the-same-MAX-payload-size.patch | 138 ++++ + ...ardvark-disable-LOS-state-by-default.patch | 55 ++ + ...ark-allow-to-specify-link-capability.patch | 43 + + ...-3720-espressobin-set-max-link-to-ge.patch | 73 ++ + ...vneta-Add-support-for-2500Mbps-SGMII.patch | 104 +++ + .../532-net-mvneta-correct-typo.patch | 33 + + ...net-mvneta-Dont-advertise-2.5G-modes.patch | 55 ++ + ...et-mvneta-remove-redundant-check-for.patch | 30 + + ...-net-marvell-neta-add-comphy-support.patch | 159 ++++ + ...eta-disable-comphy-when-setting-mode.patch | 78 ++ + ...537-net-mvneta-add-2500baset-support.patch | 34 + + .../538-phy-add-QSGMII-and-PCIE-modes.patch | 28 + + .../539-phy-core-add-PHY_MODE_ETHERNET.patch | 24 + + ...fix-build-breakage-add-PHY_MODE_SATA.patch | 45 + + ...phy_set_mode-to-accept-phy-mode-and-.patch | 134 +++ + .../542-phy-add-A3700-COMPHY-support.patch | 381 +++++++++ + ...rvell-armada-37xx-declare-the-COMPHY.patch | 58 ++ + ...rm64-dts-uDPU-fix-comphy-definitions.patch | 35 + + ...-arm64-dts-uDPU-remove-i2c-fast-mode.patch | 30 + + ...ts-uDPU-SFP-cages-support-3W-modules.patch | 33 + + 52 files changed, 4780 insertions(+) + create mode 100644 target/linux/mvebu/config-5.4 + create mode 100644 target/linux/mvebu/cortexa53/config-5.4 + create mode 100644 target/linux/mvebu/cortexa72/config-5.4 + create mode 100644 target/linux/mvebu/files-5.4/arch/arm/boot/dts/armada-385-linksys-venom.dts + create mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts + create mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts + create mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts + create mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts + create mode 100644 target/linux/mvebu/patches-5.4/002-add_powertables.patch + create mode 100644 target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch + create mode 100644 target/linux/mvebu/patches-5.4/004-add_sata_disk_activity_trigger.patch + create mode 100644 target/linux/mvebu/patches-5.4/005-linksys_hardcode_nand_ecc_settings.patch + create mode 100644 target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch + create mode 100644 target/linux/mvebu/patches-5.4/100-find_active_root.patch + create mode 100644 target/linux/mvebu/patches-5.4/102-revert_i2c_delay.patch + create mode 100644 target/linux/mvebu/patches-5.4/205-armada-385-rd-mtd-partitions.patch + create mode 100644 target/linux/mvebu/patches-5.4/206-ARM-mvebu-385-ap-Add-partitions.patch + create mode 100644 target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch + create mode 100644 target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch + create mode 100644 target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch + create mode 100644 target/linux/mvebu/patches-5.4/240-linksys-status-led.patch + create mode 100644 target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch + create mode 100644 target/linux/mvebu/patches-5.4/400-cpuidle-mvebu-indicate-failure-to-enter-deeper-sleep.patch + create mode 100644 target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch + create mode 100644 target/linux/mvebu/patches-5.4/412-ARM-dts-armada388-clearfog-emmc-on-clearfog-base.patch + create mode 100644 target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch + create mode 100644 target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch + create mode 100644 target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch + create mode 100644 target/linux/mvebu/patches-5.4/520-arm64-dts-marvell-armada37xx-Add-eth0-alias.patch + create mode 100644 target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch + create mode 100644 target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch + create mode 100644 target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch + create mode 100644 target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch + create mode 100644 target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch + create mode 100644 target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch + create mode 100644 target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch + create mode 100644 target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch + create mode 100644 target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch + create mode 100644 target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch + create mode 100644 target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch + create mode 100644 target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch + create mode 100644 target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch + create mode 100644 target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch + create mode 100644 target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch + create mode 100644 target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch + create mode 100644 target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch + create mode 100644 target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch + create mode 100644 target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch + create mode 100644 target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch + create mode 100644 target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch + create mode 100644 target/linux/mvebu/patches-5.4/545-arm64-dts-uDPU-remove-i2c-fast-mode.patch + create mode 100644 target/linux/mvebu/patches-5.4/546-arm64-dts-uDPU-SFP-cages-support-3W-modules.patch + +diff --git a/target/linux/mvebu/config-5.4 b/target/linux/mvebu/config-5.4 +new file mode 100644 +index 00000000000..24093fd386a +--- /dev/null ++++ b/target/linux/mvebu/config-5.4 +@@ -0,0 +1,498 @@ ++CONFIG_AHCI_MVEBU=y ++CONFIG_ALIGNMENT_TRAP=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_ARCH_HAS_FORTIFY_SOURCE=y ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_ARCH_HAS_KCOV=y ++CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y ++CONFIG_ARCH_HAS_PHYS_TO_DMA=y ++CONFIG_ARCH_HAS_SET_MEMORY=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y ++CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y ++CONFIG_ARCH_HAS_TICK_BROADCAST=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++CONFIG_ARCH_MULTIPLATFORM=y ++CONFIG_ARCH_MULTI_V6_V7=y ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MVEBU=y ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y ++CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_ARM=y ++CONFIG_ARMADA_370_CLK=y ++CONFIG_ARMADA_370_XP_IRQ=y ++CONFIG_ARMADA_370_XP_TIMER=y ++CONFIG_ARMADA_38X_CLK=y ++CONFIG_ARMADA_THERMAL=y ++CONFIG_ARMADA_XP_CLK=y ++CONFIG_ARM_APPENDED_DTB=y ++# CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARM_CRYPTO=y ++CONFIG_ARM_ERRATA_720789=y ++CONFIG_ARM_ERRATA_764369=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GLOBAL_TIMER=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_ARM_HEAVY_MB=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++# CONFIG_ARM_LPAE is not set ++CONFIG_ARM_MVEBU_V7_CPUIDLE=y ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_UNWIND=y ++CONFIG_ARM_VIRT_EXT=y ++CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y ++CONFIG_ATA=y ++CONFIG_ATAGS=y ++CONFIG_AUTO_ZRELADDR=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_MQ_PCI=y ++CONFIG_BLK_SCSI_REQUEST=y ++CONFIG_BOUNCE=y ++# CONFIG_CACHE_FEROCEON_L2 is not set ++CONFIG_CACHE_L2X0=y ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_COMMON_CLK=y ++CONFIG_CPUFREQ_DT=y ++CONFIG_CPUFREQ_DT_PLATDEV=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++# CONFIG_CPU_BIG_ENDIAN is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y ++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set ++CONFIG_CPU_FREQ_GOV_ATTR_SET=y ++CONFIG_CPU_FREQ_GOV_COMMON=y ++# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set ++# CONFIG_CPU_FREQ_GOV_USERSPACE is not set ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_HAS_ASID=y ++# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++CONFIG_CPU_IDLE=y ++CONFIG_CPU_IDLE_GOV_LADDER=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_PJ4B=y ++CONFIG_CPU_PM=y ++CONFIG_CPU_RMAP=y ++CONFIG_CPU_SPECTRE=y ++CONFIG_CPU_THERMAL=y ++CONFIG_CPU_THUMB_CAPABLE=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_V7=y ++CONFIG_CRC16=y ++CONFIG_CRYPTO_ACOMP2=y ++CONFIG_CRYPTO_AEAD=y ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AES_ARM=y ++CONFIG_CRYPTO_AES_ARM_BS=y ++# CONFIG_CRYPTO_AES_ARM_CE is not set ++# CONFIG_CRYPTO_CHACHA20_NEON is not set ++CONFIG_CRYPTO_CRC32=y ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32_ARM_CE is not set ++CONFIG_CRYPTO_CRYPTD=y ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_DEV_MARVELL_CESA=y ++# CONFIG_CRYPTO_GHASH_ARM_CE is not set ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_HW=y ++CONFIG_CRYPTO_LZO=y ++CONFIG_CRYPTO_MANAGER=y ++CONFIG_CRYPTO_MANAGER2=y ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA1_ARM=y ++# CONFIG_CRYPTO_SHA1_ARM_CE is not set ++CONFIG_CRYPTO_SHA1_ARM_NEON=y ++CONFIG_CRYPTO_SHA256_ARM=y ++# CONFIG_CRYPTO_SHA2_ARM_CE is not set ++CONFIG_CRYPTO_SHA512_ARM=y ++CONFIG_CRYPTO_SIMD=y ++CONFIG_CRYPTO_WORKQUEUE=y ++CONFIG_DCACHE_WORD_ACCESS=y ++CONFIG_DEBUG_ALIGN_RODATA=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_LL=y ++CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" ++CONFIG_DEBUG_MVEBU_UART0=y ++# CONFIG_DEBUG_MVEBU_UART0_ALTERNATE is not set ++# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set ++CONFIG_DEBUG_UART_8250=y ++# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set ++CONFIG_DEBUG_UART_8250_SHIFT=2 ++# CONFIG_DEBUG_UART_8250_WORD is not set ++CONFIG_DEBUG_UART_PHYS=0xd0012000 ++CONFIG_DEBUG_UART_VIRT=0xfec12000 ++CONFIG_DEBUG_UNCOMPRESS=y ++CONFIG_DEBUG_USER=y ++CONFIG_DMADEVICES=y ++CONFIG_DMA_ENGINE=y ++CONFIG_DMA_ENGINE_RAID=y ++CONFIG_DMA_OF=y ++CONFIG_DTC=y ++CONFIG_EARLY_PRINTK=y ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++CONFIG_EXT4_FS=y ++CONFIG_EXTCON=y ++# CONFIG_F2FS_CHECK_FS is not set ++CONFIG_F2FS_FS=y ++# CONFIG_F2FS_FS_SECURITY is not set ++CONFIG_F2FS_FS_XATTR=y ++CONFIG_F2FS_STAT_FS=y ++CONFIG_FIXED_PHY=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_FS_IOMAP=y ++CONFIG_FS_MBCACHE=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_GENERIC_ARCH_TOPOLOGY=y ++CONFIG_GENERIC_BUG=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y ++CONFIG_GENERIC_CPU_AUTOPROBE=y ++CONFIG_GENERIC_EARLY_IOREMAP=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_GENERIC_IRQ_CHIP=y ++CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y ++CONFIG_GENERIC_IRQ_MIGRATION=y ++CONFIG_GENERIC_IRQ_MULTI_HANDLER=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_GENERIC_MSI_IRQ=y ++CONFIG_GENERIC_MSI_IRQ_DOMAIN=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_PHY=y ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GLOB=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIOLIB_IRQCHIP=y ++CONFIG_GPIO_GENERIC=y ++CONFIG_GPIO_GENERIC_PLATFORM=y ++CONFIG_GPIO_MVEBU=y ++CONFIG_GPIO_PCA953X=y ++CONFIG_GPIO_PCA953X_IRQ=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_HARDEN_BRANCH_PREDICTOR=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_HAS_DMA=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_HAVE_ARCH_KGDB=y ++CONFIG_HAVE_ARCH_PFN_VALID=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_ARM_SCU=y ++CONFIG_HAVE_ARM_SMCCC=y ++CONFIG_HAVE_ARM_TWD=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y ++CONFIG_HAVE_EBPF_JIT=y ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_HAVE_IDE=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_HAVE_NET_DSA=y ++CONFIG_HAVE_OPROFILE=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_RSEQ=y ++CONFIG_HAVE_SMP=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_UID16=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HIGHMEM=y ++# CONFIG_HIGHPTE is not set ++CONFIG_HOTPLUG_CPU=y ++CONFIG_HWBM=y ++CONFIG_HWMON=y ++CONFIG_HW_RANDOM=y ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_PERIODIC=y ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MV64XXX=y ++# CONFIG_I2C_PXA is not set ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_IRQCHIP=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_IRQ_WORK=y ++# CONFIG_IWMMXT is not set ++CONFIG_JBD2=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PCA963X=y ++CONFIG_LEDS_TLC591XX=y ++CONFIG_LEDS_TRIGGER_DISK=y ++CONFIG_LIBFDT=y ++CONFIG_LOCK_DEBUGGING_SUPPORT=y ++CONFIG_LOCK_SPIN_ON_OWNER=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_MACH_ARMADA_370=y ++# CONFIG_MACH_ARMADA_375 is not set ++CONFIG_MACH_ARMADA_38X=y ++# CONFIG_MACH_ARMADA_39X is not set ++CONFIG_MACH_ARMADA_XP=y ++# CONFIG_MACH_DOVE is not set ++CONFIG_MACH_MVEBU_ANY=y ++CONFIG_MACH_MVEBU_V7=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_MANGLE_BOOTARGS=y ++CONFIG_MARVELL_PHY=y ++CONFIG_MDIO_BUS=y ++CONFIG_MDIO_DEVICE=y ++CONFIG_MDIO_I2C=y ++CONFIG_MEMFD_CREATE=y ++CONFIG_MEMORY=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_MIGRATION=y ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_MVSDIO=y ++CONFIG_MMC_SDHCI=y ++# CONFIG_MMC_SDHCI_PCI is not set ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_PXAV3=y ++# CONFIG_MMC_TIFM_SD is not set ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_ECC=y ++CONFIG_MTD_NAND_MARVELL=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_SPLIT_FIRMWARE=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++CONFIG_MTD_UBI_BLOCK=y ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MUTEX_SPIN_ON_OWNER=y ++CONFIG_MVEBU_CLK_COMMON=y ++CONFIG_MVEBU_CLK_COREDIV=y ++CONFIG_MVEBU_CLK_CPU=y ++CONFIG_MVEBU_DEVBUS=y ++CONFIG_MVEBU_MBUS=y ++CONFIG_MVMDIO=y ++CONFIG_MVNETA=y ++CONFIG_MVNETA_BM=y ++CONFIG_MVNETA_BM_ENABLE=y ++CONFIG_MVPP2=y ++CONFIG_MVSW61XX_PHY=y ++CONFIG_MV_XOR=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_NEON=y ++CONFIG_NET_DSA=y ++CONFIG_NET_DSA_MV88E6XXX=y ++CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y ++# CONFIG_NET_DSA_MV88E6XXX_PTP is not set ++CONFIG_NET_DSA_TAG_DSA=y ++CONFIG_NET_DSA_TAG_EDSA=y ++CONFIG_NET_FLOW_LIMIT=y ++CONFIG_NET_SWITCHDEV=y ++CONFIG_NLS=y ++CONFIG_NOP_USB_XCEIV=y ++CONFIG_NO_BOOTMEM=y ++CONFIG_NR_CPUS=4 ++CONFIG_NVMEM=y ++CONFIG_OF=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_GPIO=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_KOBJ=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_NET=y ++CONFIG_OF_RESERVED_MEM=y ++CONFIG_OLD_SIGACTION=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_ORION_WATCHDOG=y ++CONFIG_OUTER_CACHE=y ++CONFIG_OUTER_CACHE_SYNC=y ++CONFIG_PADATA=y ++CONFIG_PAGE_OFFSET=0xC0000000 ++CONFIG_PCI=y ++CONFIG_PCI_DOMAINS=y ++CONFIG_PCI_DOMAINS_GENERIC=y ++CONFIG_PCI_MSI=y ++CONFIG_PCI_MSI_IRQ_DOMAIN=y ++CONFIG_PCI_MVEBU=y ++# CONFIG_PCI_V3_SEMI is not set ++CONFIG_PERF_USE_VMALLOC=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_PHYLIB=y ++CONFIG_PHYLINK=y ++# CONFIG_PHY_MVEBU_A3700_COMPHY is not set ++# CONFIG_PHY_MVEBU_CP110_COMPHY is not set ++CONFIG_PINCTRL=y ++CONFIG_PINCTRL_ARMADA_370=y ++CONFIG_PINCTRL_ARMADA_38X=y ++CONFIG_PINCTRL_ARMADA_XP=y ++CONFIG_PINCTRL_MVEBU=y ++# CONFIG_PINCTRL_SINGLE is not set ++CONFIG_PJ4B_ERRATA_4742=y ++# CONFIG_PL310_ERRATA_588369 is not set ++# CONFIG_PL310_ERRATA_727915 is not set ++CONFIG_PL310_ERRATA_753970=y ++# CONFIG_PL310_ERRATA_769419 is not set ++CONFIG_PLAT_ORION=y ++CONFIG_PM_OPP=y ++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=11 ++CONFIG_PWM=y ++CONFIG_PWM_SYSFS=y ++CONFIG_RATIONAL=y ++CONFIG_RCU_NEED_SEGCBLIST=y ++CONFIG_RCU_STALL_COMMON=y ++CONFIG_REFCOUNT_FULL=y ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_RFS_ACCEL=y ++CONFIG_RPS=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_ARMADA38X=y ++CONFIG_RTC_DRV_MV=y ++CONFIG_RTC_I2C_AND_SPI=y ++CONFIG_RTC_MC146818_LIB=y ++CONFIG_RWSEM_SPIN_ON_OWNER=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_SATA_AHCI_PLATFORM=y ++CONFIG_SATA_MV=y ++CONFIG_SATA_PMP=y ++CONFIG_SCSI=y ++CONFIG_SENSORS_PWM_FAN=y ++CONFIG_SENSORS_TMP421=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_8250_FSL=y ++CONFIG_SERIAL_MVEBU_CONSOLE=y ++CONFIG_SERIAL_MVEBU_UART=y ++CONFIG_SFP=y ++CONFIG_SGL_ALLOC=y ++CONFIG_SG_POOL=y ++CONFIG_SMP=y ++CONFIG_SMP_ON_UP=y ++CONFIG_SOC_BUS=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_SPI=y ++# CONFIG_SPI_ARMADA_3700 is not set ++CONFIG_SPI_MASTER=y ++CONFIG_SPI_MEM=y ++CONFIG_SPI_ORION=y ++CONFIG_SRAM=y ++CONFIG_SRAM_EXEC=y ++CONFIG_SRCU=y ++CONFIG_SWCONFIG=y ++CONFIG_SWPHY=y ++CONFIG_SWP_EMULATE=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_THERMAL=y ++CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y ++CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 ++CONFIG_THERMAL_GOV_STEP_WISE=y ++CONFIG_THERMAL_HWMON=y ++CONFIG_THERMAL_OF=y ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_TICK_CPU_ACCOUNTING=y ++CONFIG_TIMER_OF=y ++CONFIG_TIMER_PROBE=y ++CONFIG_TREE_RCU=y ++CONFIG_TREE_SRCU=y ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++CONFIG_USB=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_HCD_ORION=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++CONFIG_USB_LEDS_TRIGGER_USBPORT=y ++CONFIG_USB_PHY=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_MVEBU=y ++CONFIG_USB_XHCI_PLATFORM=y ++CONFIG_USE_OF=y ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_WATCHDOG_CORE=y ++CONFIG_XPS=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_BCJ=y ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_ZLIB_INFLATE=y +diff --git a/target/linux/mvebu/cortexa53/config-5.4 b/target/linux/mvebu/cortexa53/config-5.4 +new file mode 100644 +index 00000000000..7f3c2b21de0 +--- /dev/null ++++ b/target/linux/mvebu/cortexa53/config-5.4 +@@ -0,0 +1,169 @@ ++CONFIG_64BIT=y ++CONFIG_ARCH_DMA_ADDR_T_64BIT=y ++CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y ++CONFIG_ARCH_HAS_FAST_MULTIPLIER=y ++CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y ++CONFIG_ARCH_HAS_PTE_SPECIAL=y ++CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y ++CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y ++CONFIG_ARCH_INLINE_READ_LOCK=y ++CONFIG_ARCH_INLINE_READ_LOCK_BH=y ++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y ++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y ++CONFIG_ARCH_INLINE_READ_UNLOCK=y ++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y ++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y ++CONFIG_ARCH_INLINE_SPIN_LOCK=y ++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y ++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y ++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y ++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y ++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y ++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y ++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y ++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y ++CONFIG_ARCH_INLINE_WRITE_LOCK=y ++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y ++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y ++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y ++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y ++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y ++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y ++CONFIG_ARCH_MMAP_RND_BITS=18 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=24 ++CONFIG_ARCH_MMAP_RND_BITS_MIN=18 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 ++CONFIG_ARCH_PROC_KCORE_TEXT=y ++CONFIG_ARCH_SELECT_MEMORY_MODEL=y ++CONFIG_ARCH_SPARSEMEM_DEFAULT=y ++CONFIG_ARCH_SPARSEMEM_ENABLE=y ++CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y ++CONFIG_ARCH_SUPPORTS_INT128=y ++CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y ++CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y ++CONFIG_ARCH_USE_QUEUED_RWLOCKS=y ++CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y ++CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y ++CONFIG_ARCH_WANT_FRAME_POINTERS=y ++CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y ++CONFIG_ARM64=y ++# CONFIG_ARM64_16K_PAGES is not set ++CONFIG_ARM64_4K_PAGES=y ++# CONFIG_ARM64_64K_PAGES is not set ++CONFIG_ARM64_CONT_SHIFT=4 ++# CONFIG_ARM64_CRYPTO is not set ++# CONFIG_ARM64_HW_AFDBM is not set ++# CONFIG_ARM64_LSE_ATOMICS is not set ++CONFIG_ARM64_PAGE_SHIFT=12 ++# CONFIG_ARM64_PAN is not set ++CONFIG_ARM64_PA_BITS=48 ++CONFIG_ARM64_PA_BITS_48=y ++# CONFIG_ARM64_PMEM is not set ++# CONFIG_ARM64_PTDUMP_DEBUGFS is not set ++# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set ++CONFIG_ARM64_SSBD=y ++CONFIG_ARM64_SVE=y ++# CONFIG_ARM64_UAO is not set ++CONFIG_ARM64_VA_BITS=39 ++CONFIG_ARM64_VA_BITS_39=y ++# CONFIG_ARM64_VA_BITS_48 is not set ++# CONFIG_ARM64_VHE is not set ++CONFIG_ARMADA_37XX_CLK=y ++CONFIG_ARMADA_AP806_SYSCON=y ++CONFIG_ARMADA_CP110_SYSCON=y ++CONFIG_ARM_AMBA=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++CONFIG_ARM_ARMADA_37XX_CPUFREQ=y ++CONFIG_ARM_GIC_V2M=y ++CONFIG_ARM_GIC_V3=y ++CONFIG_ARM_GIC_V3_ITS=y ++CONFIG_ARM_GIC_V3_ITS_PCI=y ++# CONFIG_ARM_PL172_MPMC is not set ++CONFIG_ARM_PSCI_FW=y ++# CONFIG_ARM_SP805_WATCHDOG is not set ++CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y ++# CONFIG_DEBUG_ALIGN_RODATA is not set ++CONFIG_DMA_DIRECT_OPS=y ++# CONFIG_FLATMEM_MANUAL is not set ++CONFIG_FRAME_POINTER=y ++CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y ++CONFIG_GENERIC_CSUM=y ++CONFIG_GENERIC_PINCONF=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y ++CONFIG_HAVE_ARCH_HUGE_VMAP=y ++CONFIG_HAVE_ARCH_KASAN=y ++CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y ++CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y ++CONFIG_HAVE_ARCH_VMAP_STACK=y ++CONFIG_HAVE_CMPXCHG_DOUBLE=y ++CONFIG_HAVE_CMPXCHG_LOCAL=y ++CONFIG_HAVE_DEBUG_BUGVERBOSE=y ++CONFIG_HAVE_GENERIC_GUP=y ++CONFIG_HAVE_MEMORY_PRESENT=y ++CONFIG_HAVE_PATA_PLATFORM=y ++CONFIG_HAVE_RCU_TABLE_FREE=y ++CONFIG_HOLES_IN_ZONE=y ++# CONFIG_HUGETLBFS is not set ++CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 ++CONFIG_INLINE_READ_LOCK=y ++CONFIG_INLINE_READ_LOCK_BH=y ++CONFIG_INLINE_READ_LOCK_IRQ=y ++CONFIG_INLINE_READ_LOCK_IRQSAVE=y ++CONFIG_INLINE_READ_UNLOCK_BH=y ++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y ++CONFIG_INLINE_SPIN_LOCK=y ++CONFIG_INLINE_SPIN_LOCK_BH=y ++CONFIG_INLINE_SPIN_LOCK_IRQ=y ++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y ++CONFIG_INLINE_SPIN_TRYLOCK=y ++CONFIG_INLINE_SPIN_TRYLOCK_BH=y ++CONFIG_INLINE_SPIN_UNLOCK_BH=y ++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y ++CONFIG_INLINE_WRITE_LOCK=y ++CONFIG_INLINE_WRITE_LOCK_BH=y ++CONFIG_INLINE_WRITE_LOCK_IRQ=y ++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y ++CONFIG_INLINE_WRITE_UNLOCK_BH=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y ++CONFIG_MFD_SYSCON=y ++CONFIG_MMC_SDHCI_XENON=y ++CONFIG_MODULES_USE_ELF_RELA=y ++CONFIG_MVEBU_GICP=y ++CONFIG_MVEBU_ICU=y ++CONFIG_MVEBU_ODMI=y ++CONFIG_MVEBU_PIC=y ++CONFIG_NEED_SG_DMA_LENGTH=y ++# CONFIG_NUMA is not set ++CONFIG_PARTITION_PERCPU=y ++CONFIG_PCI_AARDVARK=y ++CONFIG_PGTABLE_LEVELS=3 ++CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_PHY_MVEBU_A3700_COMPHY=y ++CONFIG_PINCTRL_ARMADA_37XX=y ++CONFIG_PINCTRL_ARMADA_AP806=y ++CONFIG_PINCTRL_ARMADA_CP110=y ++CONFIG_POWER_RESET=y ++CONFIG_POWER_SUPPLY=y ++CONFIG_QUEUED_RWLOCKS=y ++CONFIG_QUEUED_SPINLOCKS=y ++# CONFIG_RANDOMIZE_BASE is not set ++CONFIG_REGULATOR_GPIO=y ++# CONFIG_SERIAL_AMBA_PL011 is not set ++CONFIG_SPARSEMEM=y ++CONFIG_SPARSEMEM_EXTREME=y ++CONFIG_SPARSEMEM_MANUAL=y ++CONFIG_SPARSEMEM_VMEMMAP=y ++CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y ++CONFIG_SPI_ARMADA_3700=y ++CONFIG_SWIOTLB=y ++CONFIG_SYSCTL_EXCEPTION_TRACE=y ++CONFIG_SYS_SUPPORTS_HUGETLBFS=y ++CONFIG_THREAD_INFO_IN_TASK=y ++CONFIG_UNMAP_KERNEL_AT_EL0=y ++CONFIG_VMAP_STACK=y ++CONFIG_ZONE_DMA32=y +diff --git a/target/linux/mvebu/cortexa72/config-5.4 b/target/linux/mvebu/cortexa72/config-5.4 +new file mode 100644 +index 00000000000..c78eb843724 +--- /dev/null ++++ b/target/linux/mvebu/cortexa72/config-5.4 +@@ -0,0 +1,176 @@ ++CONFIG_64BIT=y ++CONFIG_ARCH_DMA_ADDR_T_64BIT=y ++CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y ++CONFIG_ARCH_HAS_FAST_MULTIPLIER=y ++CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y ++CONFIG_ARCH_HAS_PTE_SPECIAL=y ++CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y ++CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y ++CONFIG_ARCH_INLINE_READ_LOCK=y ++CONFIG_ARCH_INLINE_READ_LOCK_BH=y ++CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y ++CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y ++CONFIG_ARCH_INLINE_READ_UNLOCK=y ++CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y ++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y ++CONFIG_ARCH_INLINE_SPIN_LOCK=y ++CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y ++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y ++CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y ++CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y ++CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y ++CONFIG_ARCH_INLINE_SPIN_UNLOCK=y ++CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y ++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y ++CONFIG_ARCH_INLINE_WRITE_LOCK=y ++CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y ++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y ++CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y ++CONFIG_ARCH_INLINE_WRITE_UNLOCK=y ++CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y ++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y ++CONFIG_ARCH_MMAP_RND_BITS=18 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=24 ++CONFIG_ARCH_MMAP_RND_BITS_MIN=18 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 ++CONFIG_ARCH_PROC_KCORE_TEXT=y ++CONFIG_ARCH_SELECT_MEMORY_MODEL=y ++CONFIG_ARCH_SPARSEMEM_DEFAULT=y ++CONFIG_ARCH_SPARSEMEM_ENABLE=y ++CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y ++CONFIG_ARCH_SUPPORTS_INT128=y ++CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y ++CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y ++CONFIG_ARCH_USE_QUEUED_RWLOCKS=y ++CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y ++CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y ++CONFIG_ARCH_WANT_FRAME_POINTERS=y ++CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y ++CONFIG_ARM64=y ++# CONFIG_ARM64_16K_PAGES is not set ++CONFIG_ARM64_4K_PAGES=y ++# CONFIG_ARM64_64K_PAGES is not set ++CONFIG_ARM64_CONT_SHIFT=4 ++# CONFIG_ARM64_CRYPTO is not set ++# CONFIG_ARM64_HW_AFDBM is not set ++# CONFIG_ARM64_LSE_ATOMICS is not set ++CONFIG_ARM64_PAGE_SHIFT=12 ++# CONFIG_ARM64_PAN is not set ++CONFIG_ARM64_PA_BITS=48 ++CONFIG_ARM64_PA_BITS_48=y ++# CONFIG_ARM64_PMEM is not set ++# CONFIG_ARM64_PTDUMP_DEBUGFS is not set ++# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set ++CONFIG_ARM64_SSBD=y ++CONFIG_ARM64_SVE=y ++# CONFIG_ARM64_UAO is not set ++CONFIG_ARM64_VA_BITS=39 ++CONFIG_ARM64_VA_BITS_39=y ++# CONFIG_ARM64_VA_BITS_48 is not set ++# CONFIG_ARM64_VHE is not set ++CONFIG_ARMADA_37XX_CLK=y ++CONFIG_ARMADA_AP806_SYSCON=y ++CONFIG_ARMADA_CP110_SYSCON=y ++CONFIG_ARM_AMBA=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++CONFIG_ARM_GIC_V2M=y ++CONFIG_ARM_GIC_V3=y ++CONFIG_ARM_GIC_V3_ITS=y ++CONFIG_ARM_GIC_V3_ITS_PCI=y ++# CONFIG_ARM_PL172_MPMC is not set ++CONFIG_ARM_PSCI_FW=y ++# CONFIG_ARM_SP805_WATCHDOG is not set ++CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y ++# CONFIG_DEBUG_ALIGN_RODATA is not set ++CONFIG_DMA_DIRECT_OPS=y ++# CONFIG_FLATMEM_MANUAL is not set ++CONFIG_FRAME_POINTER=y ++CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y ++CONFIG_GENERIC_CSUM=y ++CONFIG_GENERIC_PINCONF=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y ++CONFIG_HAVE_ARCH_HUGE_VMAP=y ++CONFIG_HAVE_ARCH_KASAN=y ++CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y ++CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y ++CONFIG_HAVE_ARCH_VMAP_STACK=y ++CONFIG_HAVE_CMPXCHG_DOUBLE=y ++CONFIG_HAVE_CMPXCHG_LOCAL=y ++CONFIG_HAVE_DEBUG_BUGVERBOSE=y ++CONFIG_HAVE_GENERIC_GUP=y ++CONFIG_HAVE_MEMORY_PRESENT=y ++CONFIG_HAVE_PATA_PLATFORM=y ++CONFIG_HAVE_RCU_TABLE_FREE=y ++CONFIG_HOLES_IN_ZONE=y ++# CONFIG_HUGETLBFS is not set ++CONFIG_HW_RANDOM_OMAP=y ++CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 ++CONFIG_INLINE_READ_LOCK=y ++CONFIG_INLINE_READ_LOCK_BH=y ++CONFIG_INLINE_READ_LOCK_IRQ=y ++CONFIG_INLINE_READ_LOCK_IRQSAVE=y ++CONFIG_INLINE_READ_UNLOCK_BH=y ++CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y ++CONFIG_INLINE_SPIN_LOCK=y ++CONFIG_INLINE_SPIN_LOCK_BH=y ++CONFIG_INLINE_SPIN_LOCK_IRQ=y ++CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y ++CONFIG_INLINE_SPIN_TRYLOCK=y ++CONFIG_INLINE_SPIN_TRYLOCK_BH=y ++CONFIG_INLINE_SPIN_UNLOCK_BH=y ++CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y ++CONFIG_INLINE_WRITE_LOCK=y ++CONFIG_INLINE_WRITE_LOCK_BH=y ++CONFIG_INLINE_WRITE_LOCK_IRQ=y ++CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y ++CONFIG_INLINE_WRITE_UNLOCK_BH=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y ++CONFIG_MARVELL_10G_PHY=y ++CONFIG_MFD_SYSCON=y ++CONFIG_MMC_SDHCI_XENON=y ++CONFIG_MODULES_USE_ELF_RELA=y ++CONFIG_MVEBU_GICP=y ++CONFIG_MVEBU_ICU=y ++CONFIG_MVEBU_ODMI=y ++CONFIG_MVEBU_PIC=y ++CONFIG_MV_XOR_V2=y ++CONFIG_NEED_SG_DMA_LENGTH=y ++# CONFIG_NUMA is not set ++CONFIG_PARTITION_PERCPU=y ++CONFIG_PCIEAER=y ++CONFIG_PCIEPORTBUS=y ++CONFIG_PCIE_ARMADA_8K=y ++CONFIG_PCIE_DW=y ++CONFIG_PCIE_DW_HOST=y ++# CONFIG_PCI_AARDVARK is not set ++CONFIG_PGTABLE_LEVELS=3 ++CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_PHY_MVEBU_CP110_COMPHY=y ++CONFIG_PINCTRL_ARMADA_37XX=y ++CONFIG_PINCTRL_ARMADA_AP806=y ++CONFIG_PINCTRL_ARMADA_CP110=y ++CONFIG_POWER_RESET=y ++CONFIG_POWER_SUPPLY=y ++CONFIG_QUEUED_RWLOCKS=y ++CONFIG_QUEUED_SPINLOCKS=y ++# CONFIG_RANDOMIZE_BASE is not set ++CONFIG_RAS=y ++CONFIG_REGULATOR_GPIO=y ++# CONFIG_SERIAL_AMBA_PL011 is not set ++CONFIG_SPARSEMEM=y ++CONFIG_SPARSEMEM_EXTREME=y ++CONFIG_SPARSEMEM_MANUAL=y ++CONFIG_SPARSEMEM_VMEMMAP=y ++CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y ++CONFIG_SWIOTLB=y ++CONFIG_SYSCTL_EXCEPTION_TRACE=y ++CONFIG_SYS_SUPPORTS_HUGETLBFS=y ++CONFIG_THREAD_INFO_IN_TASK=y ++CONFIG_UNMAP_KERNEL_AT_EL0=y ++CONFIG_VMAP_STACK=y ++CONFIG_ZONE_DMA32=y +diff --git a/target/linux/mvebu/files-5.4/arch/arm/boot/dts/armada-385-linksys-venom.dts b/target/linux/mvebu/files-5.4/arch/arm/boot/dts/armada-385-linksys-venom.dts +new file mode 100644 +index 00000000000..c152c14c6b9 +--- /dev/null ++++ b/target/linux/mvebu/files-5.4/arch/arm/boot/dts/armada-385-linksys-venom.dts +@@ -0,0 +1,213 @@ ++/* ++ * Device Tree file for the Linksys WRT32X (Venom) ++ * ++ * Copyright (C) 2017 Imre Kaloz ++ * ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without ++ * any warranty of any kind, whether express or implied. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include ++#include ++#include "armada-385-linksys.dtsi" ++ ++/ { ++ model = "Linksys WRT32X"; ++ compatible = "linksys,venom", "linksys,armada385", "marvell,armada385", ++ "marvell,armada380"; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200"; ++ stdout-path = "serial0:115200n8"; ++ append-rootblock = "root=/dev/mtdblock"; ++ }; ++}; ++ ++&expander0 { ++ wan_amber@0 { ++ label = "venom:amber:wan"; ++ reg = <0x0>; ++ }; ++ ++ wan_blue@1 { ++ label = "venom:blue:wan"; ++ reg = <0x1>; ++ }; ++ ++ usb2@5 { ++ label = "venom:blue:usb2"; ++ reg = <0x5>; ++ }; ++ ++ usb3_1@6 { ++ label = "venom:blue:usb3_1"; ++ reg = <0x6>; ++ }; ++ ++ usb3_2@7 { ++ label = "venom:blue:usb3_2"; ++ reg = <0x7>; ++ }; ++ ++ wps_blue@8 { ++ label = "venom:blue:wps"; ++ reg = <0x8>; ++ }; ++ ++ wps_amber@9 { ++ label = "venom:amber:wps"; ++ reg = <0x9>; ++ }; ++}; ++ ++&gpio_leds { ++ power { ++ gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; ++ label = "venom:blue:power"; ++ }; ++ ++ sata { ++ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; ++ label = "venom:blue:sata"; ++ }; ++ ++ wlan_2g { ++ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; ++ label = "venom:blue:wlan_2g"; ++ }; ++ ++ wlan_5g { ++ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; ++ label = "venom:blue:wlan_5g"; ++ }; ++}; ++ ++&gpio_leds_pins { ++ marvell,pins = "mpp21", "mpp45", "mpp46", "mpp56"; ++}; ++ ++&nand { ++ /* Spansion S34ML02G2 256MiB, OEM Layout */ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "u-boot"; ++ reg = <0x0000000 0x200000>; /* 2MB */ ++ read-only; ++ }; ++ ++ partition@200000 { ++ label = "u_env"; ++ reg = <0x200000 0x20000>; /* 128KB */ ++ }; ++ ++ partition@220000 { ++ label = "s_env"; ++ reg = <0x220000 0x40000>; /* 256KB */ ++ }; ++ ++ partition@180000 { ++ label = "unused_area"; ++ reg = <0x260000 0x5c0000>; /* 5.75MB */ ++ }; ++ ++ partition@7e0000 { ++ label = "devinfo"; ++ reg = <0x7e0000 0x40000>; /* 256KB */ ++ read-only; ++ }; ++ ++ /* kernel1 overlaps with rootfs1 by design */ ++ partition@900000 { ++ label = "kernel1"; ++ reg = <0x900000 0x7b00000>; /* 123MB */ ++ }; ++ ++ partition@c00000 { ++ label = "rootfs1"; ++ reg = <0xc00000 0x7800000>; /* 120MB */ ++ }; ++ ++ /* kernel2 overlaps with rootfs2 by design */ ++ partition@8400000 { ++ label = "kernel2"; ++ reg = <0x8400000 0x7b00000>; /* 123MB */ ++ }; ++ ++ partition@8700000 { ++ label = "rootfs2"; ++ reg = <0x8700000 0x7800000>; /* 120MB */ ++ }; ++ ++ /* last MB is for the BBT, not writable */ ++ partition@ff00000 { ++ label = "BBT"; ++ reg = <0xff00000 0x100000>; ++ }; ++ }; ++}; ++ ++ ++&pcie1 { ++ mwlwifi { ++ marvell,chainmask = <4 4>; ++ }; ++}; ++ ++&pcie2 { ++ mwlwifi { ++ marvell,chainmask = <4 4>; ++ }; ++}; ++ ++&sdhci { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhci_pins>; ++ no-1-8-v; ++ non-removable; ++ wp-inverted; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++&usb3_1_vbus { ++ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; ++}; ++ ++&usb3_1_vbus_pins { ++ marvell,pins = "mpp44"; ++}; +diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts +new file mode 100644 +index 00000000000..ef90a1bd387 +--- /dev/null ++++ b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Device Tree file for Globalscale Marvell ESPRESSOBin Board with eMMC ++ * Copyright (C) 2018 Marvell ++ * ++ * Romain Perier ++ * Konstantin Porotchkin ++ * ++ */ ++ ++#include "armada-3720-espressobin.dts" ++ ++/ { ++ model = "Globalscale Marvell ESPRESSOBin Board (eMMC)"; ++ compatible = "globalscale,espressobin-emmc", "globalscale,espressobin", ++ "marvell,armada3720", "marvell,armada3710"; ++}; ++ ++&sdhci0 { ++ status = "okay"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mmccard: mmccard@0 { ++ compatible = "mmc-card"; ++ reg = <0>; ++ }; ++}; +diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts +new file mode 100644 +index 00000000000..2b565ca8d82 +--- /dev/null ++++ b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts +@@ -0,0 +1,43 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Device Tree file for Globalscale Marvell ESPRESSOBin Board V7 with eMMC ++ * Copyright (C) 2018 Marvell ++ * ++ * Romain Perier ++ * Konstantin Porotchkin ++ * ++ */ ++ ++#include "armada-3720-espressobin.dts" ++ ++/ { ++ model = "Globalscale Marvell ESPRESSOBin Board V7 (eMMC)"; ++ compatible = "globalscale,espressobin-v7-emmc", "globalscale,espressobin-v7", ++ "globalscale,espressobin", "marvell,armada3720", ++ "marvell,armada3710"; ++}; ++ ++&ports { ++ port@1 { ++ reg = <1>; ++ label = "lan1"; ++ phy-handle = <&switch0phy0>; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ label = "wan"; ++ phy-handle = <&switch0phy2>; ++ }; ++}; ++ ++&sdhci0 { ++ status = "okay"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mmccard: mmccard@0 { ++ compatible = "mmc-card"; ++ reg = <0>; ++ }; ++}; +diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts +new file mode 100644 +index 00000000000..8a408c3c48f +--- /dev/null ++++ b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts +@@ -0,0 +1,31 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Device Tree file for Globalscale Marvell ESPRESSOBin Board V7 ++ * Copyright (C) 2018 Marvell ++ * ++ * Romain Perier ++ * Konstantin Porotchkin ++ * ++ */ ++ ++#include "armada-3720-espressobin.dts" ++ ++/ { ++ model = "Globalscale Marvell ESPRESSOBin Board V7"; ++ compatible = "globalscale,espressobin-v7", "globalscale,espressobin", ++ "marvell,armada3720", "marvell,armada3710"; ++}; ++ ++&ports { ++ port@1 { ++ reg = <1>; ++ label = "lan1"; ++ phy-handle = <&switch0phy0>; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ label = "wan"; ++ phy-handle = <&switch0phy2>; ++ }; ++}; +diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +new file mode 100644 +index 00000000000..5b722b4f832 +--- /dev/null ++++ b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +@@ -0,0 +1,162 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Device tree for the uDPU board. ++ * Based on Marvell Armada 3720 development board (DB-88F3720-DDR3) ++ * Copyright (C) 2016 Marvell ++ * Copyright (C) 2019 Methode Electronics ++ * Copyright (C) 2019 Telus ++ * ++ * Vladimir Vid ++ */ ++ ++/dts-v1/; ++ ++#include ++#include "armada-372x.dtsi" ++ ++/ { ++ model = "Methode uDPU Board"; ++ compatible = "methode,udpu", "marvell,armada3720"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x00000000 0x00000000 0x00000000 0x20000000>; ++ }; ++ ++ leds { ++ pinctrl-names = "default"; ++ compatible = "gpio-leds"; ++ ++ power1 { ++ label = "udpu:green:power"; ++ gpios = <&gpionb 11 GPIO_ACTIVE_LOW>; ++ }; ++ ++ power2 { ++ label = "udpu:red:power"; ++ gpios = <&gpionb 12 GPIO_ACTIVE_LOW>; ++ }; ++ ++ network1 { ++ label = "udpu:green:network"; ++ gpios = <&gpionb 13 GPIO_ACTIVE_LOW>; ++ }; ++ ++ network2 { ++ label = "udpu:red:network"; ++ gpios = <&gpionb 14 GPIO_ACTIVE_LOW>; ++ }; ++ ++ alarm1 { ++ label = "udpu:green:alarm"; ++ gpios = <&gpionb 15 GPIO_ACTIVE_LOW>; ++ }; ++ ++ alarm2 { ++ label = "udpu:red:alarm"; ++ gpios = <&gpionb 16 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ sfp_eth0: sfp-eth0 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c0>; ++ los-gpio = <&gpiosb 2 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>; ++ tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>; ++ tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ sfp_eth1: sfp-eth1 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c1>; ++ los-gpio = <&gpiosb 7 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>; ++ tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>; ++ tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&sdhci0 { ++ status = "okay"; ++ bus-width = <8>; ++ mmc-ddr-1_8v; ++ mmc-hs400-1_8v; ++ marvell,pad-type = "fixed-1-8v"; ++ non-removable; ++ no-sd; ++ no-sdio; ++}; ++ ++&spi0 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_quad_pins>; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <54000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ /* only bootloader is located on the SPI */ ++ partition@0 { ++ label = "uboot"; ++ reg = <0 0x400000>; ++ }; ++ }; ++ }; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ ++ lm75@48 { ++ status = "okay"; ++ compatible = "lm75"; ++ reg = <0x48>; ++ }; ++ ++ lm75@49 { ++ status = "okay"; ++ compatible = "lm75"; ++ reg = <0x49>; ++ }; ++}; ++ ++ð0 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ managed = "in-band-status"; ++ sfp = <&sfp_eth0>; ++}; ++ ++ð1 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ managed = "in-band-status"; ++ sfp = <&sfp_eth1>; ++}; ++ ++&usb3 { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; +diff --git a/target/linux/mvebu/patches-5.4/002-add_powertables.patch b/target/linux/mvebu/patches-5.4/002-add_powertables.patch +new file mode 100644 +index 00000000000..c2fb748d5d0 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/002-add_powertables.patch +@@ -0,0 +1,770 @@ ++--- a/arch/arm/boot/dts/armada-385-linksys.dtsi +++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi ++@@ -212,11 +212,19 @@ ++ &pcie1 { ++ /* Marvell 88W8864, 5GHz-only */ ++ status = "okay"; +++ +++ mwlwifi { +++ marvell,2ghz = <0>; +++ }; ++ }; ++ ++ &pcie2 { ++ /* Marvell 88W8864, 2GHz-only */ ++ status = "okay"; +++ +++ mwlwifi { +++ marvell,5ghz = <0>; +++ }; ++ }; ++ ++ &pinctrl { ++--- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts +++++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts ++@@ -142,3 +142,205 @@ ++ }; ++ }; ++ }; +++ +++&pcie1 { +++ mwlwifi { +++ marvell,chainmask = <2 2>; +++ marvell,powertable { +++ AU = +++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <100 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <104 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <108 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <112 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <116 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <120 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <124 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <128 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <132 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <136 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <140 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, +++ <149 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>, +++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>, +++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>, +++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>, +++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>; +++ CA = +++ <36 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>, +++ <40 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>, +++ <44 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>, +++ <48 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <149 0 0x1a 0x1a 0x18 0x17 0x19 0x19 0x17 0x15 0x18 0x18 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, +++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, +++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, +++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, +++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>; +++ CN = +++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <100 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <104 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <108 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <112 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <116 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <120 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <124 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <128 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <132 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <136 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <140 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <149 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x11 0x11 0x11 0x11 0 0xf>, +++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>, +++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>, +++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>, +++ <165 0 0x15 0x15 0x15 0x15 0x16 0x16 0x16 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>; +++ ETSI = +++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <100 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <104 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <108 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <112 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <116 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <120 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <124 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <128 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <132 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <136 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <140 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, +++ <149 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>; +++ FCC = +++ <36 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <40 0 0x19 0x19 0x18 0x17 0x19 0x19 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <44 0 0x19 0x19 0x18 0x17 0x19 0x19 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <48 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <149 0 0x1a 0x1a 0x18 0x17 0x19 0x19 0x17 0x15 0x18 0x18 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, +++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, +++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, +++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, +++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>; +++ }; +++ }; +++}; +++ +++&pcie2 { +++ mwlwifi { +++ marvell,chainmask = <2 2>; +++ marvell,powertable { +++ AU = +++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>; +++ CA = +++ <1 0 0x19 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 0 0xf>, +++ <2 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <3 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <4 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <5 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <6 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <7 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <8 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <9 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <10 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, +++ <11 0 0x19 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x00 0x00 0x00 0x00 0 0xf>; +++ CN = +++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <12 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <13 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <14 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>; +++ ETSI = +++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <12 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, +++ <13 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>; +++ FCC = +++ <1 0 0x19 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0x19 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x0 0x0 0x0 0x0 0 0xf>; +++ }; +++ }; +++}; ++--- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts +++++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts ++@@ -142,3 +142,205 @@ ++ }; ++ }; ++ }; +++ +++&pcie1 { +++ mwlwifi { +++ marvell,chainmask = <4 4>; +++ marvell,powertable { +++ AU = +++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <149 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, +++ <153 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, +++ <157 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, +++ <161 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, +++ <165 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>; +++ CA = +++ <36 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <40 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <44 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <48 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>; +++ CN = +++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <149 0 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <165 0 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>; +++ ETSI = +++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <149 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>; +++ FCC = +++ <36 0 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0 0xf>, +++ <40 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, +++ <44 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, +++ <48 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>; +++ }; +++ }; +++}; +++ +++&pcie2 { +++ mwlwifi { +++ marvell,chainmask = <4 4>; +++ marvell,powertable { +++ AU = +++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; +++ CA = +++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>; +++ CN = +++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <14 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; +++ ETSI = +++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; +++ FCC = +++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>; +++ }; +++ }; +++}; ++--- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts +++++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts ++@@ -142,3 +142,205 @@ ++ }; ++ }; ++ }; +++ +++&pcie1 { +++ mwlwifi { +++ marvell,chainmask = <4 4>; +++ marvell,powertable { +++ AU = +++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <149 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, +++ <153 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, +++ <157 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, +++ <161 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, +++ <165 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>; +++ CA = +++ <36 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <40 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <44 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <48 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>; +++ CN = +++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <149 0 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, +++ <165 0 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>; +++ ETSI = +++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, +++ <149 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>; +++ FCC = +++ <36 0 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0 0xf>, +++ <40 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, +++ <44 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, +++ <48 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, +++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, +++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, +++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, +++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>; +++ }; +++ }; +++}; +++ +++&pcie2 { +++ mwlwifi { +++ marvell,chainmask = <4 4>; +++ marvell,powertable { +++ AU = +++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; +++ CA = +++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>; +++ CN = +++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <14 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; +++ ETSI = +++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, +++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; +++ FCC = +++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>; +++ }; +++ }; +++}; ++--- a/arch/arm/boot/dts/armada-385-linksys-rango.dts +++++ b/arch/arm/boot/dts/armada-385-linksys-rango.dts ++@@ -157,6 +157,18 @@ ++ }; ++ }; ++ +++&pcie1 { +++ mwlwifi { +++ marvell,chainmask = <4 4>; +++ }; +++}; +++ +++&pcie2 { +++ mwlwifi { +++ marvell,chainmask = <4 4>; +++ }; +++}; +++ ++ &sdhci { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhci_pins>; ++--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts ++@@ -272,12 +272,100 @@ ++ pcie@2,0 { ++ /* Port 0, Lane 1 */ ++ status = "okay"; +++ +++ mwlwifi { +++ marvell,5ghz = <0>; +++ marvell,chainmask = <4 4>; +++ marvell,powertable { +++ FCC = +++ <1 0 0x17 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>; +++ +++ ETSI = +++ <1 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <2 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <3 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <4 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <5 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <6 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <7 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <8 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <9 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <10 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <11 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <12 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, +++ <13 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>; +++ }; +++ }; ++ }; ++ ++ /* Second mini-PCIe port */ ++ pcie@3,0 { ++ /* Port 0, Lane 3 */ ++ status = "okay"; +++ +++ mwlwifi { +++ marvell,2ghz = <0>; +++ marvell,chainmask = <4 4>; +++ marvell,powertable { +++ FCC = +++ <36 0 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <40 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <44 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <48 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, +++ <52 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>, +++ <56 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>, +++ <60 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>, +++ <64 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>, +++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, +++ <149 0 0x16 0x16 0x16 0x16 0x14 0x14 0x14 0x14 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>, +++ <153 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>, +++ <157 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>, +++ <161 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>, +++ <165 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>; +++ +++ ETSI = +++ <36 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <40 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <44 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <48 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <52 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <56 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <60 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <64 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <100 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <104 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <108 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <112 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <116 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <120 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <124 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <128 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <132 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <136 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <140 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, +++ <149 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>; +++ }; +++ }; ++ }; ++ }; ++ +diff --git a/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch b/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch +new file mode 100644 +index 00000000000..b2086389163 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch +@@ -0,0 +1,40 @@ ++--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts ++@@ -257,6 +257,16 @@ ++ }; ++ }; ++ }; +++ +++ mvsw61xx { +++ compatible = "marvell,88e6172"; +++ status = "okay"; +++ reg = <0x10>; +++ +++ mii-bus = <&mdio>; +++ cpu-port-0 = <5>; +++ cpu-port-1 = <6>; +++ }; ++ }; ++ ++ &pciec { ++--- a/arch/arm/boot/dts/armada-385-linksys.dtsi +++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi ++@@ -82,6 +82,18 @@ ++ linux,default-trigger = "disk-activity"; ++ }; ++ }; +++ +++ mvsw61xx { +++ #address-cells = <1>; +++ #size-cells = <0>; +++ compatible = "marvell,88e6176"; +++ status = "okay"; +++ reg = <0x10>; +++ +++ mii-bus = <&mdio>; +++ cpu-port-0 = <5>; +++ cpu-port-1 = <6>; +++ }; ++ }; ++ ++ &ahci0 { +diff --git a/target/linux/mvebu/patches-5.4/004-add_sata_disk_activity_trigger.patch b/target/linux/mvebu/patches-5.4/004-add_sata_disk_activity_trigger.patch +new file mode 100644 +index 00000000000..2cb8f254906 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/004-add_sata_disk_activity_trigger.patch +@@ -0,0 +1,39 @@ ++From 172230195068703b78ad5733a09492f5d6814c09 Mon Sep 17 00:00:00 2001 ++From: Ansuel Smith ++Date: Tue, 28 Feb 2017 14:15:50 +0100 ++Subject: [PATCH] ARM: dts: armada: Add default trigger for sata led ++ ++In others board we have the sata led set to function ++with the sata led trigger by default. ++This patch makes the same for these board that have sata ++led but get disabled by not associating it to any trigger. ++ ++Signed-off-by: Ansuel Smith ++Acked-by: Jason Cooper ++Signed-off-by: Gregory CLEMENT ++--- ++ arch/arm/boot/dts/armada-385-linksys-caiman.dts | 1 + ++ arch/arm/boot/dts/armada-385-linksys-cobra.dts | 1 + ++ arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 1 + ++ 3 files changed, 3 insertions(+) ++ ++--- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts +++++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts ++@@ -68,6 +68,7 @@ ++ ++ sata { ++ label = "caiman:white:sata"; +++ linux,default-trigger = "disk-activity"; ++ }; ++ }; ++ ++--- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts +++++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts ++@@ -68,6 +68,7 @@ ++ ++ sata { ++ label = "cobra:white:sata"; +++ linux,default-trigger = "disk-activity"; ++ }; ++ }; ++ +diff --git a/target/linux/mvebu/patches-5.4/005-linksys_hardcode_nand_ecc_settings.patch b/target/linux/mvebu/patches-5.4/005-linksys_hardcode_nand_ecc_settings.patch +new file mode 100644 +index 00000000000..dfe13bae7b5 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/005-linksys_hardcode_nand_ecc_settings.patch +@@ -0,0 +1,17 @@ ++Newer Linksys boards might come with a Winbond W29N02GV which can be ++configured in different ways. Make sure we configure it the same way ++as the older chips so everything keeps working. ++ ++Signed-off-by: Imre Kaloz ++ ++--- a/arch/arm/boot/dts/armada-385-linksys.dtsi +++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi ++@@ -160,6 +160,8 @@ ++ reg = <0>; ++ label = "pxa3xx_nand-0"; ++ nand-rb = <0>; +++ nand-ecc-strength = <4>; +++ nand-ecc-step-size = <512>; ++ marvell,nand-keep-config; ++ nand-on-flash-bbt; ++ }; +diff --git a/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch +new file mode 100644 +index 00000000000..0cb9e996027 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch +@@ -0,0 +1,201 @@ ++From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001 ++From: Adrian Panella ++Date: Thu, 9 Mar 2017 09:37:17 +0100 ++Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments ++ ++The command-line arguments provided by the boot loader will be ++appended to a new device tree property: bootloader-args. ++If there is a property "append-rootblock" in DT under /chosen ++and a root= option in bootloaders command line it will be parsed ++and added to DT bootargs with the form: XX. ++Only command line ATAG will be processed, the rest of the ATAGs ++sent by bootloader will be ignored. ++This is usefull in dual boot systems, to get the current root partition ++without afecting the rest of the system. ++ ++Signed-off-by: Adrian Panella ++ ++This patch has been modified to be mvebu specific. The original patch ++did not pass the bootloader cmdline on if no append-rootblock stanza ++was found, resulting in blank cmdline and failure to boot. ++ ++Signed-off-by: Michael Gray ++--- ++ arch/arm/Kconfig | 11 +++++ ++ arch/arm/boot/compressed/atags_to_fdt.c | 72 ++++++++++++++++++++++++++++++++- ++ init/main.c | 16 ++++++++ ++ 3 files changed, 98 insertions(+), 1 deletion(-) ++ ++--- a/arch/arm/Kconfig +++++ b/arch/arm/Kconfig ++@@ -1926,6 +1926,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN ++ The command-line arguments provided by the boot loader will be ++ appended to the the device tree bootargs property. ++ +++config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE +++ bool "Append rootblock parsing bootloader's kernel arguments" +++ help +++ The command-line arguments provided by the boot loader will be +++ appended to a new device tree property: bootloader-args. +++ If there is a property "append-rootblock" in DT under /chosen +++ and a root= option in bootloaders command line it will be parsed +++ and added to DT bootargs with the form: XX. +++ Only command line ATAG will be processed, the rest of the ATAGs +++ sent by bootloader will be ignored. +++ ++ endchoice ++ ++ config CMDLINE ++--- a/arch/arm/boot/compressed/atags_to_fdt.c +++++ b/arch/arm/boot/compressed/atags_to_fdt.c ++@@ -4,6 +4,8 @@ ++ ++ #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND) ++ #define do_extend_cmdline 1 +++#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) +++#define do_extend_cmdline 1 ++ #else ++ #define do_extend_cmdline 0 ++ #endif ++@@ -67,6 +69,65 @@ static uint32_t get_cell_size(const void ++ return cell_size; ++ } ++ +++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) +++ +++static char *append_rootblock(char *dest, const char *str, int len, void *fdt) +++{ +++ char *ptr, *end; +++ char *root="root="; +++ int i, l; +++ const char *rootblock; +++ +++ //ARM doesn't have __HAVE_ARCH_STRSTR, so search manually +++ ptr = str - 1; +++ +++ do { +++ //first find an 'r' at the begining or after a space +++ do { +++ ptr++; +++ ptr = strchr(ptr, 'r'); +++ if(!ptr) return dest; +++ +++ } while (ptr != str && *(ptr-1) != ' '); +++ +++ //then check for the rest +++ for(i = 1; i <= 4; i++) +++ if(*(ptr+i) != *(root+i)) break; +++ +++ } while (i != 5); +++ +++ end = strchr(ptr, ' '); +++ end = end ? (end - 1) : (strchr(ptr, 0) - 1); +++ +++ //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX ) +++ for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++); +++ ptr = end + 1; +++ +++ /* if append-rootblock property is set use it to append to command line */ +++ rootblock = getprop(fdt, "/chosen", "append-rootblock", &l); +++ if(rootblock != NULL) { +++ if(*dest != ' ') { +++ *dest = ' '; +++ dest++; +++ len++; +++ } +++ if (len + l + i <= COMMAND_LINE_SIZE) { +++ memcpy(dest, rootblock, l); +++ dest += l - 1; +++ memcpy(dest, ptr, i); +++ dest += i; +++ } +++ } else { +++ len = strlen(str); +++ if (len + 1 < COMMAND_LINE_SIZE) { +++ memcpy(dest, str, len); +++ dest += len; +++ } +++ } +++ return dest; +++} +++#endif +++ ++ static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) ++ { ++ char cmdline[COMMAND_LINE_SIZE]; ++@@ -86,12 +147,21 @@ static void merge_fdt_bootargs(void *fdt ++ ++ /* and append the ATAG_CMDLINE */ ++ if (fdt_cmdline) { +++ +++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) +++ //save original bootloader args +++ //and append ubi.mtd with root partition number to current cmdline +++ setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline); +++ ptr = append_rootblock(ptr, fdt_cmdline, len, fdt); +++ +++#else ++ len = strlen(fdt_cmdline); ++ if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) { ++ *ptr++ = ' '; ++ memcpy(ptr, fdt_cmdline, len); ++ ptr += len; ++ } +++#endif ++ } ++ *ptr = '\0'; ++ ++@@ -148,7 +218,9 @@ int atags_to_fdt(void *atag_list, void * ++ else ++ setprop_string(fdt, "/chosen", "bootargs", ++ atag->u.cmdline.cmdline); ++- } else if (atag->hdr.tag == ATAG_MEM) { +++ } +++#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE +++ else if (atag->hdr.tag == ATAG_MEM) { ++ if (memcount >= sizeof(mem_reg_property)/4) ++ continue; ++ if (!atag->u.mem.size) ++@@ -187,6 +259,10 @@ int atags_to_fdt(void *atag_list, void * ++ setprop(fdt, "/memory", "reg", mem_reg_property, ++ 4 * memcount * memsize); ++ } +++#else +++ +++ } +++#endif ++ ++ return fdt_pack(fdt); ++ } ++--- a/init/main.c +++++ b/init/main.c ++@@ -102,6 +102,10 @@ ++ #define CREATE_TRACE_POINTS ++ #include ++ +++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) +++#include +++#endif +++ ++ static int kernel_init(void *); ++ ++ extern void init_IRQ(void); ++@@ -591,6 +595,18 @@ asmlinkage __visible void __init start_k ++ page_alloc_init(); ++ ++ pr_notice("Kernel command line: %s\n", boot_command_line); +++ +++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) +++ //Show bootloader's original command line for reference +++ if(of_chosen) { +++ const char *prop = of_get_property(of_chosen, "bootloader-args", NULL); +++ if(prop) +++ pr_notice("Bootloader command line (ignored): %s\n", prop); +++ else +++ pr_notice("Bootloader command line not present\n"); +++ } +++#endif +++ ++ /* parameters may set static keys */ ++ jump_label_init(); ++ parse_early_param(); +diff --git a/target/linux/mvebu/patches-5.4/100-find_active_root.patch b/target/linux/mvebu/patches-5.4/100-find_active_root.patch +new file mode 100644 +index 00000000000..f52a5108b85 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/100-find_active_root.patch +@@ -0,0 +1,60 @@ ++The WRT1900AC among other Linksys routers uses a dual-firmware layout. ++Dynamically rename the active partition to "ubi". ++ ++Signed-off-by: Imre Kaloz ++ ++--- a/drivers/mtd/ofpart.c +++++ b/drivers/mtd/ofpart.c ++@@ -25,6 +25,8 @@ static bool node_has_compatible(struct d ++ return of_get_property(pp, "compatible", NULL); ++ } ++ +++static int mangled_rootblock; +++ ++ static int parse_fixed_partitions(struct mtd_info *master, ++ const struct mtd_partition **pparts, ++ struct mtd_part_parser_data *data) ++@@ -33,6 +35,7 @@ static int parse_fixed_partitions(struct ++ struct device_node *mtd_node; ++ struct device_node *ofpart_node; ++ const char *partname; +++ const char *owrtpart = "ubi"; ++ struct device_node *pp; ++ int nr_parts, i, ret = 0; ++ bool dedicated = true; ++@@ -110,9 +113,13 @@ static int parse_fixed_partitions(struct ++ parts[i].size = of_read_number(reg + a_cells, s_cells); ++ parts[i].of_node = pp; ++ ++- partname = of_get_property(pp, "label", &len); ++- if (!partname) ++- partname = of_get_property(pp, "name", &len); +++ if (mangled_rootblock && (i == mangled_rootblock)) { +++ partname = owrtpart; +++ } else { +++ partname = of_get_property(pp, "label", &len); +++ if (!partname) +++ partname = of_get_property(pp, "name", &len); +++ } ++ parts[i].name = partname; ++ ++ if (of_get_property(pp, "read-only", &len)) ++@@ -219,6 +226,18 @@ static int __init ofpart_parser_init(voi ++ return 0; ++ } ++ +++static int __init active_root(char *str) +++{ +++ get_option(&str, &mangled_rootblock); +++ +++ if (!mangled_rootblock) +++ return 1; +++ +++ return 1; +++} +++ +++__setup("mangled_rootblock=", active_root); +++ ++ static void __exit ofpart_parser_exit(void) ++ { ++ deregister_mtd_parser(&ofpart_parser); +diff --git a/target/linux/mvebu/patches-5.4/102-revert_i2c_delay.patch b/target/linux/mvebu/patches-5.4/102-revert_i2c_delay.patch +new file mode 100644 +index 00000000000..930c0f94942 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/102-revert_i2c_delay.patch +@@ -0,0 +1,15 @@ ++--- a/arch/arm/boot/dts/armada-xp.dtsi +++++ b/arch/arm/boot/dts/armada-xp.dtsi ++@@ -237,12 +237,10 @@ ++ }; ++ ++ &i2c0 { ++- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; ++ reg = <0x11000 0x100>; ++ }; ++ ++ &i2c1 { ++- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; ++ reg = <0x11100 0x100>; ++ }; ++ +diff --git a/target/linux/mvebu/patches-5.4/205-armada-385-rd-mtd-partitions.patch b/target/linux/mvebu/patches-5.4/205-armada-385-rd-mtd-partitions.patch +new file mode 100644 +index 00000000000..31bd53b1f3b +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/205-armada-385-rd-mtd-partitions.patch +@@ -0,0 +1,19 @@ ++--- a/arch/arm/boot/dts/armada-388-rd.dts +++++ b/arch/arm/boot/dts/armada-388-rd.dts ++@@ -103,6 +103,16 @@ ++ compatible = "st,m25p128", "jedec,spi-nor"; ++ reg = <0>; /* Chip select 0 */ ++ spi-max-frequency = <108000000>; +++ +++ partition@0 { +++ label = "uboot"; +++ reg = <0 0x400000>; +++ }; +++ +++ partition@1 { +++ label = "firmware"; +++ reg = <0x400000 0xc00000>; +++ }; ++ }; ++ }; ++ +diff --git a/target/linux/mvebu/patches-5.4/206-ARM-mvebu-385-ap-Add-partitions.patch b/target/linux/mvebu/patches-5.4/206-ARM-mvebu-385-ap-Add-partitions.patch +new file mode 100644 +index 00000000000..2057e31c7e9 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/206-ARM-mvebu-385-ap-Add-partitions.patch +@@ -0,0 +1,35 @@ ++From 9861f93a59142a3131870df2521eb2deb73026d7 Mon Sep 17 00:00:00 2001 ++From: Maxime Ripard ++Date: Tue, 13 Jan 2015 11:14:09 +0100 ++Subject: [PATCH 2/2] ARM: mvebu: 385-ap: Add partitions ++ ++Signed-off-by: Maxime Ripard ++--- ++ arch/arm/boot/dts/armada-385-db-ap.dts | 15 +++++++++++++++ ++ 1 file changed, 15 insertions(+) ++ ++--- a/arch/arm/boot/dts/armada-385-db-ap.dts +++++ b/arch/arm/boot/dts/armada-385-db-ap.dts ++@@ -218,19 +218,19 @@ ++ #size-cells = <1>; ++ ++ partition@0 { ++- label = "U-Boot"; +++ label = "u-boot"; ++ reg = <0x00000000 0x00800000>; ++ read-only; ++ }; ++ ++ partition@800000 { ++- label = "uImage"; +++ label = "kernel"; ++ reg = <0x00800000 0x00400000>; ++ read-only; ++ }; ++ ++ partition@c00000 { ++- label = "Root"; +++ label = "ubi"; ++ reg = <0x00c00000 0x3f400000>; ++ }; ++ }; +diff --git a/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch b/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch +new file mode 100644 +index 00000000000..f9677a82f2e +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch +@@ -0,0 +1,21 @@ ++--- a/arch/arm/boot/dts/armada-388-clearfog.dts +++++ b/arch/arm/boot/dts/armada-388-clearfog.dts ++@@ -88,6 +88,18 @@ ++ }; ++ }; ++ +++ mvsw61xx { +++ #address-cells = <1>; +++ #size-cells = <0>; +++ compatible = "marvell,88e6176"; +++ status = "okay"; +++ reg = <0x4>; +++ is-indirect; +++ +++ mii-bus = <&mdio>; +++ cpu-port-0 = <5>; +++ }; +++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ pinctrl-0 = <&rear_button_pins>; +diff --git a/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch b/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch +new file mode 100644 +index 00000000000..9cc7a113f6c +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch +@@ -0,0 +1,30 @@ ++--- a/arch/arm/boot/dts/armada-385-linksys.dtsi +++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi ++@@ -171,6 +171,7 @@ ++ status = "okay"; ++ ++ switch@0 { +++ status = "disabled"; ++ compatible = "marvell,mv88e6085"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++--- a/arch/arm/boot/dts/armada-388-clearfog.dts +++++ b/arch/arm/boot/dts/armada-388-clearfog.dts ++@@ -161,6 +161,7 @@ ++ status = "okay"; ++ ++ switch@4 { +++ status = "disabled"; ++ compatible = "marvell,mv88e6085"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts ++@@ -413,6 +413,7 @@ ++ status = "okay"; ++ ++ switch@0 { +++ status = "disabled"; ++ compatible = "marvell,mv88e6085"; ++ #address-cells = <1>; ++ #size-cells = <0>; +diff --git a/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch b/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch +new file mode 100644 +index 00000000000..935c8fe0935 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch +@@ -0,0 +1,10 @@ ++--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts ++@@ -543,3 +543,7 @@ ++ }; ++ }; ++ }; +++ +++&coherencyfab { +++ broken-idle; +++}; +diff --git a/target/linux/mvebu/patches-5.4/240-linksys-status-led.patch b/target/linux/mvebu/patches-5.4/240-linksys-status-led.patch +new file mode 100644 +index 00000000000..e5e83572c9e +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/240-linksys-status-led.patch +@@ -0,0 +1,50 @@ ++--- a/arch/arm/boot/dts/armada-385-linksys.dtsi +++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi ++@@ -14,6 +14,13 @@ ++ compatible = "linksys,armada385", "marvell,armada385", ++ "marvell,armada380"; ++ +++ aliases { +++ led-boot = &led_power; +++ led-failsafe = &led_power; +++ led-running = &led_power; +++ led-upgrade = &led_power; +++ }; +++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++@@ -71,7 +78,7 @@ ++ pinctrl-0 = <&gpio_leds_pins>; ++ pinctrl-names = "default"; ++ ++- power { +++ led_power: power { ++ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts ++@@ -26,6 +26,13 @@ ++ compatible = "linksys,mamba", "marvell,armadaxp-mv78230", ++ "marvell,armadaxp", "marvell,armada-370-xp"; ++ +++ aliases { +++ led-boot = &led_power; +++ led-failsafe = &led_power; +++ led-running = &led_power; +++ led-upgrade = &led_power; +++ }; +++ ++ chosen { ++ bootargs = "console=ttyS0,115200"; ++ stdout-path = &uart0; ++@@ -197,7 +204,7 @@ ++ pinctrl-0 = <&power_led_pin>; ++ pinctrl-names = "default"; ++ ++- power { +++ led_power: power { ++ label = "mamba:white:power"; ++ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; +diff --git a/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch b/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch +new file mode 100644 +index 00000000000..4a5ea361449 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch +@@ -0,0 +1,35 @@ ++The hardware queue scheduling is apparently configured with fixed ++priorities, which creates a nasty fairness issue where traffic from one ++CPU can starve traffic from all other CPUs. ++ ++Work around this issue by forcing all tx packets to go through one CPU, ++until this issue is fixed properly. ++ ++Signed-off-by: Felix Fietkau ++--- ++--- a/drivers/net/ethernet/marvell/mvneta.c +++++ b/drivers/net/ethernet/marvell/mvneta.c ++@@ -4272,6 +4272,15 @@ static int mvneta_ethtool_set_eee(struct ++ return phylink_ethtool_set_eee(pp->phylink, eee); ++ } ++ +++static u16 mvneta_select_queue(struct net_device *dev, struct sk_buff *skb, +++ struct net_device *sb_dev, +++ select_queue_fallback_t fallback) +++{ +++ /* XXX: hardware queue scheduling is broken, +++ * use only one queue until it is fixed */ +++ return 0; +++} +++ ++ static const struct net_device_ops mvneta_netdev_ops = { ++ .ndo_open = mvneta_open, ++ .ndo_stop = mvneta_stop, ++@@ -4282,6 +4291,7 @@ static const struct net_device_ops mvnet ++ .ndo_fix_features = mvneta_fix_features, ++ .ndo_get_stats64 = mvneta_get_stats64, ++ .ndo_do_ioctl = mvneta_ioctl, +++ .ndo_select_queue = mvneta_select_queue, ++ }; ++ ++ static const struct ethtool_ops mvneta_eth_tool_ops = { +diff --git a/target/linux/mvebu/patches-5.4/400-cpuidle-mvebu-indicate-failure-to-enter-deeper-sleep.patch b/target/linux/mvebu/patches-5.4/400-cpuidle-mvebu-indicate-failure-to-enter-deeper-sleep.patch +new file mode 100644 +index 00000000000..29f36be460d +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/400-cpuidle-mvebu-indicate-failure-to-enter-deeper-sleep.patch +@@ -0,0 +1,40 @@ ++From c28b2d367da8a471482e6a4aa8337ab6369a80c2 Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Sat, 3 Oct 2015 09:13:05 +0100 ++Subject: cpuidle: mvebu: indicate failure to enter deeper sleep states ++ ++The cpuidle ->enter method expects the return value to be the sleep ++state we entered. Returning negative numbers or other codes is not ++permissible since coupled CPU idle was merged. ++ ++At least some of the mvebu_v7_cpu_suspend() implementations return the ++value from cpu_suspend(), which returns zero if the CPU vectors back ++into the kernel via cpu_resume() (the success case), or the non-zero ++return value of the suspend actor, or one (failure cases). ++ ++We do not want to be returning the failure case value back to CPU idle ++as that indicates that we successfully entered one of the deeper idle ++states. Always return zero instead, indicating that we slept for the ++shortest amount of time. ++ ++Signed-off-by: Russell King ++--- ++ drivers/cpuidle/cpuidle-mvebu-v7.c | 6 +++++- ++ 1 file changed, 5 insertions(+), 1 deletion(-) ++ ++--- a/drivers/cpuidle/cpuidle-mvebu-v7.c +++++ b/drivers/cpuidle/cpuidle-mvebu-v7.c ++@@ -39,8 +39,12 @@ static int mvebu_v7_enter_idle(struct cp ++ ret = mvebu_v7_cpu_suspend(deepidle); ++ cpu_pm_exit(); ++ +++ /* +++ * If we failed to enter the desired state, indicate that we +++ * slept lightly. +++ */ ++ if (ret) ++- return ret; +++ return 0; ++ ++ return index; ++ } +diff --git a/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch b/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch +new file mode 100644 +index 00000000000..2bbb6471538 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch +@@ -0,0 +1,60 @@ ++From 287b9df160b6159f8d385424904f8bac501280c1 Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Sat, 9 Jul 2016 10:58:16 +0100 ++Subject: pci: mvebu: time out reset on link up ++ ++If the port reports that the link is up while we are resetting, there's ++little point in waiting for the full duration. ++ ++Signed-off-by: Russell King ++--- ++ drivers/pci/controller/pci-mvebu.c | 20 ++++++++++++++------ ++ 1 file changed, 14 insertions(+), 6 deletions(-) ++ ++--- a/drivers/pci/controller/pci-mvebu.c +++++ b/drivers/pci/controller/pci-mvebu.c ++@@ -1112,6 +1112,7 @@ static int mvebu_pcie_powerup(struct mve ++ ++ if (port->reset_gpio) { ++ u32 reset_udelay = PCI_PM_D3COLD_WAIT * 1000; +++ unsigned int i; ++ ++ of_property_read_u32(port->dn, "reset-delay-us", ++ &reset_udelay); ++@@ -1119,7 +1120,13 @@ static int mvebu_pcie_powerup(struct mve ++ udelay(100); ++ ++ gpiod_set_value_cansleep(port->reset_gpio, 0); ++- msleep(reset_udelay / 1000); +++ for (i = 0; i < reset_udelay; i += 1000) { +++ if (mvebu_pcie_link_up(port)) +++ break; +++ msleep(1); +++ } +++ +++ printk("%s: reset completed in %dus\n", port->name, i); ++ } ++ ++ return 0; ++@@ -1283,15 +1290,16 @@ static int mvebu_pcie_probe(struct platf ++ if (!child) ++ continue; ++ ++- ret = mvebu_pcie_powerup(port); ++- if (ret < 0) ++- continue; ++- ++ port->base = mvebu_pcie_map_registers(pdev, child, port); ++ if (IS_ERR(port->base)) { ++ dev_err(dev, "%s: cannot map registers\n", port->name); ++ port->base = NULL; ++- mvebu_pcie_powerdown(port); +++ continue; +++ } +++ +++ ret = mvebu_pcie_powerup(port); +++ if (ret < 0) { +++ port->base = NULL; ++ continue; ++ } ++ +diff --git a/target/linux/mvebu/patches-5.4/412-ARM-dts-armada388-clearfog-emmc-on-clearfog-base.patch b/target/linux/mvebu/patches-5.4/412-ARM-dts-armada388-clearfog-emmc-on-clearfog-base.patch +new file mode 100644 +index 00000000000..dd2bef7f632 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/412-ARM-dts-armada388-clearfog-emmc-on-clearfog-base.patch +@@ -0,0 +1,87 @@ ++From 8137da20701c776ad3481115305a5e8e410871ba Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Tue, 29 Nov 2016 10:15:45 +0000 ++Subject: ARM: dts: armada388-clearfog: emmc on clearfog base ++ ++Signed-off-by: Russell King ++--- ++ arch/arm/boot/dts/armada-388-clearfog-base.dts | 1 + ++ .../dts/armada-38x-solidrun-microsom-emmc.dtsi | 62 ++++++++++++++++++++++ ++ 2 files changed, 63 insertions(+) ++ create mode 100644 arch/arm/boot/dts/armada-38x-solidrun-microsom-emmc.dtsi ++ ++--- a/arch/arm/boot/dts/armada-388-clearfog-base.dts +++++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts ++@@ -7,6 +7,7 @@ ++ ++ /dts-v1/; ++ #include "armada-388-clearfog.dtsi" +++#include "armada-38x-solidrun-microsom-emmc.dtsi" ++ ++ / { ++ model = "SolidRun Clearfog Base A1"; ++--- /dev/null +++++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom-emmc.dtsi ++@@ -0,0 +1,62 @@ +++/* +++ * Device Tree file for SolidRun Armada 38x Microsom add-on for eMMC +++ * +++ * Copyright (C) 2015 Russell King +++ * +++ * This board is in development; the contents of this file work with +++ * the A1 rev 2.0 of the board, which does not represent final +++ * production board. Things will change, don't expect this file to +++ * remain compatible info the future. +++ * +++ * This file is dual-licensed: you can use it either under the terms +++ * of the GPL or the X11 license, at your option. Note that this dual +++ * licensing only applies to this file, and not this project as a +++ * whole. +++ * +++ * a) This file is free software; you can redistribute it and/or +++ * modify it under the terms of the GNU General Public License +++ * version 2 as published by the Free Software Foundation. +++ * +++ * This file is distributed in the hope that it will be useful +++ * but WITHOUT ANY WARRANTY; without even the implied warranty of +++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +++ * GNU General Public License for more details. +++ * +++ * Or, alternatively +++ * +++ * b) Permission is hereby granted, free of charge, to any person +++ * obtaining a copy of this software and associated documentation +++ * files (the "Software"), to deal in the Software without +++ * restriction, including without limitation the rights to use +++ * copy, modify, merge, publish, distribute, sublicense, and/or +++ * sell copies of the Software, and to permit persons to whom the +++ * Software is furnished to do so, subject to the following +++ * conditions: +++ * +++ * The above copyright notice and this permission notice shall be +++ * included in all copies or substantial portions of the Software. +++ * +++ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND +++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY +++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +++ * OTHER DEALINGS IN THE SOFTWARE. +++ */ +++/ { +++ soc { +++ internal-regs { +++ sdhci@d8000 { +++ bus-width = <4>; +++ no-1-8-v; +++ non-removable; +++ pinctrl-0 = <µsom_sdhci_pins>; +++ pinctrl-names = "default"; +++ status = "okay"; +++ wp-inverted; +++ }; +++ }; +++ }; +++}; +diff --git a/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch b/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch +new file mode 100644 +index 00000000000..d64bd8084ea +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch +@@ -0,0 +1,124 @@ ++From 09a0122c74ec076e08512f1b00b7ccb8a450282f Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Tue, 29 Nov 2016 10:15:43 +0000 ++Subject: ARM: dts: armada388-clearfog: document MPP usage ++ ++Signed-off-by: Russell King ++--- ++ arch/arm/boot/dts/armada-388-clearfog-base.dts | 51 ++++++++++++++++++++++++++ ++ arch/arm/boot/dts/armada-388-clearfog.dts | 50 +++++++++++++++++++++++++ ++ 2 files changed, 101 insertions(+) ++ ++--- a/arch/arm/boot/dts/armada-388-clearfog-base.dts +++++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts ++@@ -67,3 +67,54 @@ ++ marvell,function = "gpio"; ++ }; ++ }; +++ +++/* +++MPP +++18: pu gpio pca9655 int +++19: gpio phy reset +++20: pu gpio sd0 detect +++21: sd0:cmd +++22: pd gpio mikro int +++23: +++ +++24: ua1:rxd mikro rx +++25: ua1:txd mikro tx +++26: pu i2c1:sck +++27: pu i2c1:sda +++28: sd0:clk +++29: pd gpio mikro rst +++30: +++31: +++ +++32: +++33: +++34: +++35: +++36: +++37: sd0:d3 +++38: sd0:d0 +++39: sd0:d1 +++ +++40: sd0:d2 +++41: +++42: +++43: spi1:cs2 mikro cs +++44: gpio rear button sw3 +++45: ref:clk_out0 phy#0 clock +++46: ref:clk_out1 phy#1 clock +++47: +++ +++48: gpio J18 spare gpio +++49: gpio U10 I2C_IRQ(GNSS) +++50: gpio board id? +++51: +++52: +++53: +++54: gpio mikro pwm +++55: +++ +++56: pu spi1:mosi mikro mosi +++57: pd spi1:sck mikro sck +++58: spi1:miso mikro miso +++59: +++*/ ++--- a/arch/arm/boot/dts/armada-388-clearfog.dts +++++ b/arch/arm/boot/dts/armada-388-clearfog.dts ++@@ -249,3 +249,53 @@ ++ */ ++ pinctrl-0 = <&spi1_pins &clearfog_spi1_cs_pins &mikro_spi_pins>; ++ }; +++/* ++++#define A38x_CUSTOMER_BOARD_1_MPP16_23 0x00400011 +++MPP18: gpio ? (pca9655 int?) +++MPP19: gpio ? (clkreq?) +++MPP20: gpio ? (sd0 detect) +++MPP21: sd0:cmd x sd0 +++MPP22: gpio x mikro int +++MPP23: gpio x switch irq ++++#define A38x_CUSTOMER_BOARD_1_MPP24_31 0x22043333 +++MPP24: ua1:rxd x mikro rx +++MPP25: ua1:txd x mikro tx +++MPP26: i2c1:sck x mikro sck +++MPP27: i2c1:sda x mikro sda +++MPP28: sd0:clk x sd0 +++MPP29: gpio x mikro rst +++MPP30: ge1:txd2 ? (config) +++MPP31: ge1:txd3 ? (config) ++++#define A38x_CUSTOMER_BOARD_1_MPP32_39 0x44400002 +++MPP32: ge1:txctl ? (unused) +++MPP33: gpio ? (pic_com0) +++MPP34: gpio x rear button (pic_com1) +++MPP35: gpio ? (pic_com2) +++MPP36: gpio ? (unused) +++MPP37: sd0:d3 x sd0 +++MPP38: sd0:d0 x sd0 +++MPP39: sd0:d1 x sd0 ++++#define A38x_CUSTOMER_BOARD_1_MPP40_47 0x41144004 +++MPP40: sd0:d2 x sd0 +++MPP41: gpio x switch reset +++MPP42: gpio ? sw1-1 +++MPP43: spi1:cs2 x mikro cs +++MPP44: sata3:prsnt ? (unused) +++MPP45: ref:clk_out0 ? +++MPP46: ref:clk_out1 x switch clk +++MPP47: 4 ? (unused) ++++#define A38x_CUSTOMER_BOARD_1_MPP48_55 0x40333333 +++MPP48: tdm:pclk +++MPP49: tdm:fsync +++MPP50: tdm:drx +++MPP51: tdm:dtx +++MPP52: tdm:int +++MPP53: tdm:rst +++MPP54: gpio ? (pwm) +++MPP55: spi1:cs1 x slic ++++#define A38x_CUSTOMER_BOARD_1_MPP56_63 0x00004444 +++MPP56: spi1:mosi x mikro mosi +++MPP57: spi1:sck x mikro sck +++MPP58: spi1:miso x mikro miso +++MPP59: spi1:cs0 x w25q32 +++*/ +diff --git a/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch b/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch +new file mode 100644 +index 00000000000..880b0d92417 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch +@@ -0,0 +1,40 @@ ++From eefe328439642101774f0f5c4ea0dc6ba1cfb687 Mon Sep 17 00:00:00 2001 ++From: Ding Tao ++Date: Fri, 26 Oct 2018 11:50:27 +0000 ++Subject: [PATCH] arm64: dts: marvell: armada37xx: Add emmc/sdio pinctrl ++ definition ++ ++Add emmc/sdio pinctrl definition for marvell armada37xx SoCs. ++ ++Signed-off-by: Ding Tao ++Signed-off-by: Gregory CLEMENT ++--- ++ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 10 ++++++++++ ++ 1 file changed, 10 insertions(+) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi ++@@ -221,6 +221,11 @@ ++ groups = "uart2"; ++ function = "uart"; ++ }; +++ +++ mmc_pins: mmc-pins { +++ groups = "emmc_nb"; +++ function = "emmc"; +++ }; ++ }; ++ ++ nb_pm: syscon@14000 { ++@@ -253,6 +258,11 @@ ++ function = "mii"; ++ }; ++ +++ sdio_pins: sdio-pins { +++ groups = "sdio_sb"; +++ function = "sdio"; +++ }; +++ ++ }; ++ ++ eth0: ethernet@30000 { +diff --git a/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch b/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch +new file mode 100644 +index 00000000000..77af3d1219d +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch +@@ -0,0 +1,49 @@ ++From 43ebc7c1b3ed8198b9acf3019eca16e722f7331c Mon Sep 17 00:00:00 2001 ++From: Ding Tao ++Date: Fri, 26 Oct 2018 11:50:28 +0000 ++Subject: [PATCH] arm64: dts: marvell: armada-37xx: Enable emmc on espressobin ++ ++The ESPRESSObin board has a emmc interface available on U11: declare it ++and let the bootloader enable it if the emmc is present. ++ ++[gregory.clement@bootlin.com: disable the emmc by default] ++Signed-off-by: Ding Tao ++Signed-off-by: Gregory CLEMENT ++--- ++ .../dts/marvell/armada-3720-espressobin.dts | 22 +++++++++++++++++++ ++ 1 file changed, 22 insertions(+) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts ++@@ -60,9 +60,31 @@ ++ cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>; ++ marvell,pad-type = "sd"; ++ vqmmc-supply = <&vcc_sd_reg1>; +++ +++ pinctrl-names = "default"; +++ pinctrl-0 = <&sdio_pins>; ++ status = "okay"; ++ }; ++ +++/* U11 */ +++&sdhci0 { +++ non-removable; +++ bus-width = <8>; +++ mmc-ddr-1_8v; +++ mmc-hs400-1_8v; +++ marvell,xenon-emmc; +++ marvell,xenon-tun-count = <9>; +++ marvell,pad-type = "fixed-1-8v"; +++ +++ pinctrl-names = "default"; +++ pinctrl-0 = <&mmc_pins>; +++/* +++ * This eMMC is not populated on all boards, so disable it by +++ * default and let the bootloader enable it, if it is present +++ */ +++ status = "disabled"; +++}; +++ ++ &spi0 { ++ status = "okay"; ++ +diff --git a/target/linux/mvebu/patches-5.4/520-arm64-dts-marvell-armada37xx-Add-eth0-alias.patch b/target/linux/mvebu/patches-5.4/520-arm64-dts-marvell-armada37xx-Add-eth0-alias.patch +new file mode 100644 +index 00000000000..e989f59d5cd +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/520-arm64-dts-marvell-armada37xx-Add-eth0-alias.patch +@@ -0,0 +1,20 @@ ++From be893f672e340b56ca60f2f6c32fdd713a5852f5 Mon Sep 17 00:00:00 2001 ++From: Kevin Mihelich ++Date: Tue, 4 Jul 2017 19:25:28 -0600 ++Subject: arm64: dts: marvell: armada37xx: Add eth0 alias ++ ++Signed-off-by: Kevin Mihelich ++--- ++ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 1 + ++ 1 file changed, 1 insertion(+) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi ++@@ -18,6 +18,7 @@ ++ #size-cells = <2>; ++ ++ aliases { +++ ethernet0 = ð0; ++ serial0 = &uart0; ++ serial1 = &uart1; ++ }; +diff --git a/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch b/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch +new file mode 100644 +index 00000000000..0f39b2a3c2c +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch +@@ -0,0 +1,58 @@ ++From 3217cdfe8a3eae76fafbebbe407be5985a7fd4c2 Mon Sep 17 00:00:00 2001 ++From: Tomasz Maciej Nowak ++Date: Mon, 31 Dec 2018 14:18:50 +0100 ++Subject: [PATCH] arm64: dts: armada-3720-espressobin: correct spi node ++ ++The manufacturer of this board, ships it with various SPI NOR chips and ++increments U-Boot bootloader version along the time. There is no way to ++tell which is placed on the board since no revision bump takes place. ++This creates two issues. ++ ++The first, cosmetic. Since the SPI chip may differ, there's message on ++boot stating that kernel expected w25q32dw and found different one. To ++correct this, remove optional device-specific compatible string. Being ++here lets replace bogus "spi-flash" string with proper one. ++ ++The second is linked to partitions layout, it changed after commit [1] ++in Marvells downstream U-Boot fork, shifting environment location to the ++end of boot device. Since the new boards can have U-Boot with this ++change it can lead to improper results writing or reading from these ++partitions. We can't tell if users will update bootloader to recent ++version, so let's drop current layout. ++ ++1. https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/81e7251252aefe1a6b829ed05f3586320cb45372 ++ ++Signed-off-by: Tomasz Maciej Nowak ++--- ++ .../dts/marvell/armada-3720-espressobin.dts | 18 +----------------- ++ 1 file changed, 1 insertion(+), 17 deletions(-) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts ++@@ -90,25 +90,9 @@ ++ ++ flash@0 { ++ reg = <0>; ++- compatible = "winbond,w25q32dw", "jedec,spi-flash"; +++ compatible = "jedec,spi-nor"; ++ spi-max-frequency = <104000000>; ++ m25p,fast-read; ++- ++- partitions { ++- compatible = "fixed-partitions"; ++- #address-cells = <1>; ++- #size-cells = <1>; ++- ++- partition@0 { ++- label = "uboot"; ++- reg = <0 0x180000>; ++- }; ++- ++- partition@180000 { ++- label = "ubootenv"; ++- reg = <0x180000 0x10000>; ++- }; ++- }; ++ }; ++ }; ++ +diff --git a/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch b/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch +new file mode 100644 +index 00000000000..cea0d1db44f +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch +@@ -0,0 +1,26 @@ ++From 6ea9a1ee9367fb35acff1c08a0dc4213ff4687a0 Mon Sep 17 00:00:00 2001 ++From: Tomasz Maciej Nowak ++Date: Tue, 9 Apr 2019 15:53:42 +0200 ++Subject: [PATCH] arm64: dts: marvell: armada-3720-espressobin: add ports ++ phandle ++ ++Instead of referencing the whole mdio node, add ports phandle to adjust ++port labels in dts for different hardware iterations of ESPRESSObin ++boards. ++ ++Signed-off-by: Tomasz Maciej Nowak ++--- ++ arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts ++@@ -132,7 +132,7 @@ ++ ++ dsa,member = <0 0>; ++ ++- ports { +++ ports: ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ +diff --git a/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch b/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch +new file mode 100644 +index 00000000000..3fd561db3a6 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch +@@ -0,0 +1,44 @@ ++From 5e79c0c381eb085a2aa2da175eedea1950f07520 Mon Sep 17 00:00:00 2001 ++From: Tomasz Maciej Nowak ++Date: Tue, 30 Apr 2019 15:37:34 +0200 ++Subject: [PATCH] Revert "PCI: aardvark: Convert to use pci_host_probe()" ++ ++This reverts commit c8e144f8ab00e6c4a070a932ef9c57db09aa41cf. ++--- ++ drivers/pci/controller/pci-aardvark.c | 12 +++++++++++- ++ 1 file changed, 11 insertions(+), 1 deletion(-) ++ ++--- a/drivers/pci/controller/pci-aardvark.c +++++ b/drivers/pci/controller/pci-aardvark.c ++@@ -843,6 +843,7 @@ static int advk_pcie_probe(struct platfo ++ struct device *dev = &pdev->dev; ++ struct advk_pcie *pcie; ++ struct resource *res; +++ struct pci_bus *bus, *child; ++ struct pci_host_bridge *bridge; ++ int ret, irq; ++ ++@@ -896,13 +897,22 @@ static int advk_pcie_probe(struct platfo ++ bridge->map_irq = of_irq_parse_and_map_pci; ++ bridge->swizzle_irq = pci_common_swizzle; ++ ++- ret = pci_host_probe(bridge); +++ ret = pci_scan_root_bus_bridge(bridge); ++ if (ret < 0) { ++ advk_pcie_remove_msi_irq_domain(pcie); ++ advk_pcie_remove_irq_domain(pcie); ++ return ret; ++ } ++ +++ bus = bridge->bus; +++ +++ pci_bus_size_bridges(bus); +++ pci_bus_assign_resources(bus); +++ +++ list_for_each_entry(child, &bus->children, node) +++ pcie_bus_configure_settings(child); +++ +++ pci_bus_add_devices(bus); ++ return 0; ++ } ++ +diff --git a/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch b/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch +new file mode 100644 +index 00000000000..204d6e2aec4 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch +@@ -0,0 +1,138 @@ ++From patchwork Thu Sep 28 12:58:34 2017 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++Subject: [v2, ++ 3/7] PCI: aardvark: set host and device to the same MAX payload size ++X-Patchwork-Submitter: Thomas Petazzoni ++X-Patchwork-Id: 819587 ++Message-Id: <20170928125838.11887-4-thomas.petazzoni@free-electrons.com> ++To: Bjorn Helgaas , linux-pci@vger.kernel.org ++Cc: Jason Cooper , Andrew Lunn , ++ Sebastian Hesselbarth , Gregory Clement ++ , ++ Nadav Haklai , Hanna Hawa , ++ Yehuda Yitschak , ++ linux-arm-kernel@lists.infradead.org, Antoine Tenart ++ , =?utf-8?q?Miqu=C3=A8l_Raynal?= ++ , Victor Gu , ++ Thomas Petazzoni ++Date: Thu, 28 Sep 2017 14:58:34 +0200 ++From: Thomas Petazzoni ++List-Id: ++ ++From: Victor Gu ++ ++Since the Aardvark does not implement a PCIe root bus, the Linux PCIe ++subsystem will not align the MAX payload size between the host and the ++device. This patch ensures that the host and device have the same MAX ++payload size, fixing a number of problems with various PCIe devices. ++ ++This is part of fixing bug ++https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was ++reported as the user to be important to get a Intel 7260 mini-PCIe ++WiFi card working. ++ ++Fixes: Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") ++Signed-off-by: Victor Gu ++Reviewed-by: Evan Wang ++Reviewed-by: Nadav Haklai ++[Thomas: tweak commit log.] ++Signed-off-by: Thomas Petazzoni ++--- ++ drivers/pci/controller/pci-aardvark.c | 60 ++++++++++++++++++++++++++++++++++++++++- ++ 1 file changed, 59 insertions(+), 1 deletion(-) ++ ++--- a/drivers/pci/controller/pci-aardvark.c +++++ b/drivers/pci/controller/pci-aardvark.c ++@@ -29,9 +29,11 @@ ++ #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 ++ #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) ++ #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 +++#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ 0x2 ++ #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) ++ #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 ++ #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2 +++#define PCIE_CORE_MPS_UNIT_BYTE 128 ++ #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 ++ #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) ++ #define PCIE_CORE_LINK_TRAINING BIT(5) ++@@ -253,7 +255,8 @@ static void advk_pcie_setup_hw(struct ad ++ ++ /* Set PCIe Device Control and Status 1 PF0 register */ ++ reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | ++- (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | +++ (PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ << +++ PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | ++ PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | ++ (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << ++ PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); ++@@ -838,6 +841,58 @@ out_release_res: ++ return err; ++ } ++ +++static int advk_pcie_find_smpss(struct pci_dev *dev, void *data) +++{ +++ u8 *smpss = data; +++ +++ if (!dev) +++ return 0; +++ +++ if (!pci_is_pcie(dev)) +++ return 0; +++ +++ if (*smpss > dev->pcie_mpss) +++ *smpss = dev->pcie_mpss; +++ +++ return 0; +++} +++ +++static int advk_pcie_bus_configure_mps(struct pci_dev *dev, void *data) +++{ +++ int mps; +++ +++ if (!dev) +++ return 0; +++ +++ if (!pci_is_pcie(dev)) +++ return 0; +++ +++ mps = PCIE_CORE_MPS_UNIT_BYTE << *(u8 *)data; +++ pcie_set_mps(dev, mps); +++ +++ return 0; +++} +++ +++static void advk_pcie_configure_mps(struct pci_bus *bus, struct advk_pcie *pcie) +++{ +++ u8 smpss = PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ; +++ u32 reg; +++ +++ /* Find the minimal supported MAX payload size */ +++ advk_pcie_find_smpss(bus->self, &smpss); +++ pci_walk_bus(bus, advk_pcie_find_smpss, &smpss); +++ +++ /* Configure RC MAX payload size */ +++ reg = advk_readl(pcie, PCIE_CORE_DEV_CTRL_STATS_REG); +++ reg &= ~PCI_EXP_DEVCTL_PAYLOAD; +++ reg |= smpss << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT; +++ advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); +++ +++ /* Configure device MAX payload size */ +++ advk_pcie_bus_configure_mps(bus->self, &smpss); +++ pci_walk_bus(bus, advk_pcie_bus_configure_mps, &smpss); +++} +++ ++ static int advk_pcie_probe(struct platform_device *pdev) ++ { ++ struct device *dev = &pdev->dev; ++@@ -912,6 +967,9 @@ static int advk_pcie_probe(struct platfo ++ list_for_each_entry(child, &bus->children, node) ++ pcie_bus_configure_settings(child); ++ +++ /* Configure the MAX pay load size */ +++ advk_pcie_configure_mps(bus, pcie); +++ ++ pci_bus_add_devices(bus); ++ return 0; ++ } +diff --git a/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch b/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch +new file mode 100644 +index 00000000000..b6fcec81f8f +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch +@@ -0,0 +1,55 @@ ++From patchwork Thu Sep 28 12:58:36 2017 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++Subject: [v2,5/7] PCI: aardvark: disable LOS state by default ++X-Patchwork-Submitter: Thomas Petazzoni ++X-Patchwork-Id: 819590 ++Message-Id: <20170928125838.11887-6-thomas.petazzoni@free-electrons.com> ++To: Bjorn Helgaas , linux-pci@vger.kernel.org ++Cc: Jason Cooper , Andrew Lunn , ++ Sebastian Hesselbarth , Gregory Clement ++ , ++ Nadav Haklai , Hanna Hawa , ++ Yehuda Yitschak , ++ linux-arm-kernel@lists.infradead.org, Antoine Tenart ++ , =?utf-8?q?Miqu=C3=A8l_Raynal?= ++ , Victor Gu , ++ Thomas Petazzoni ++Date: Thu, 28 Sep 2017 14:58:36 +0200 ++From: Thomas Petazzoni ++List-Id: ++ ++From: Victor Gu ++ ++Some PCIe devices do not support LOS, and will cause timeouts if the ++root complex forces the LOS state. This patch disables the LOS state ++by default. ++ ++This is part of fixing bug ++https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was ++reported as the user to be important to get a Intel 7260 mini-PCIe ++WiFi card working. ++ ++Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") ++Signed-off-by: Victor Gu ++Reviewed-by: Evan Wang ++Reviewed-by: Nadav Haklai ++[Thomas: tweak commit log.] ++Signed-off-by: Thomas Petazzoni ++--- ++ drivers/pci/controller/pci-aardvark.c | 3 +-- ++ 1 file changed, 1 insertion(+), 2 deletions(-) ++ ++--- a/drivers/pci/controller/pci-aardvark.c +++++ b/drivers/pci/controller/pci-aardvark.c ++@@ -324,8 +324,7 @@ static void advk_pcie_setup_hw(struct ad ++ ++ advk_pcie_wait_for_link(pcie); ++ ++- reg = PCIE_CORE_LINK_L0S_ENTRY | ++- (1 << PCIE_CORE_LINK_WIDTH_SHIFT); +++ reg = (1 << PCIE_CORE_LINK_WIDTH_SHIFT); ++ advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); ++ ++ reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); +diff --git a/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch b/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch +new file mode 100644 +index 00000000000..0ac34761473 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch +@@ -0,0 +1,43 @@ ++From f70b629e488cc3f2a325ac35476f4f7ae502c5d0 Mon Sep 17 00:00:00 2001 ++From: Tomasz Maciej Nowak ++Date: Thu, 14 Jun 2018 14:24:40 +0200 ++Subject: [PATCH 1/2] PCI: aardvark: allow to specify link capability ++ ++Use DT of_pci_get_max_link_speed() facility to allow specifying link ++capability. If none or unspecified value is given it falls back to gen2, ++which is default for Armada 3700 SoC. ++ ++Signed-off-by: Tomasz Maciej Nowak ++--- ++ drivers/pci/controller/pci-aardvark.c | 11 +++++++++-- ++ 1 file changed, 9 insertions(+), 2 deletions(-) ++ ++--- a/drivers/pci/controller/pci-aardvark.c +++++ b/drivers/pci/controller/pci-aardvark.c ++@@ -233,6 +233,8 @@ static int advk_pcie_wait_for_link(struc ++ ++ static void advk_pcie_setup_hw(struct advk_pcie *pcie) ++ { +++ struct device *dev = &pcie->pdev->dev; +++ struct device_node *node = dev->of_node; ++ u32 reg; ++ ++ /* Set to Direct mode */ ++@@ -267,10 +269,15 @@ static void advk_pcie_setup_hw(struct ad ++ PCIE_CORE_CTRL2_TD_ENABLE; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); ++ ++- /* Set GEN2 */ +++ /* Set GEN */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg &= ~PCIE_GEN_SEL_MSK; ++- reg |= SPEED_GEN_2; +++ if (of_pci_get_max_link_speed(node) == 1) +++ reg |= SPEED_GEN_1; +++ else if (of_pci_get_max_link_speed(node) == 3) +++ reg |= SPEED_GEN_3; +++ else +++ reg |= SPEED_GEN_2; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* Set lane X1 */ +diff --git a/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch b/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch +new file mode 100644 +index 00000000000..88080d64caa +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch +@@ -0,0 +1,73 @@ ++From 33f8fdcedb01680427328d710594facef7a0092c Mon Sep 17 00:00:00 2001 ++From: Tomasz Maciej Nowak ++Date: Thu, 14 Jun 2018 14:40:26 +0200 ++Subject: [PATCH 2/2] arm64: dts: armada-3720-espressobin: set max link to gen1 ++ ++Since the beginning there's been an issue with initializing the Atheros ++based MiniPCIe wireless cards. Here's an example of kerenel log: ++ ++ OF: PCI: host bridge /soc/pcie@d0070000 ranges: ++ OF: PCI: MEM 0xe8000000..0xe8ffffff -> 0xe8000000 ++ OF: PCI: IO 0xe9000000..0xe900ffff -> 0xe9000000 ++ advk-pcie d0070000.pcie: link up ++ advk-pcie d0070000.pcie: PCI host bridge to bus 0000:00 ++ pci_bus 0000:00: root bus resource [bus 00-ff] ++ pci_bus 0000:00: root bus resource [mem0xe8000000-0xe8ffffff] ++ pci_bus 0000:00: root bus resource [io 0x0000-0xffff](bus address [0xe9000000-0xe900ffff]) ++ pci 0000:00:00.0: BAR 0: assigned [mem0xe8000000-0xe801ffff 64bit] ++ pci 0000:00:00.0: BAR 6: assigned [mem0xe8020000-0xe802ffff pref] ++ [...] ++ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x3c ++ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x44 ++ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4 ++ ath9k 0000:00:00.0: enabling device (0000 -> 0002) ++ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x3c ++ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0xc ++ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4 ++ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x40 ++ ath9k 0000:00:00.0: request_irq failed ++ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4 ++ ath9k: probe of 0000:00:00.0 failed with error -22 ++ ++The same happens for ath5k cards, while ath10k card didn't appear at ++all (not detected): ++ ++ OF: PCI: host bridge /soc/pcie@d0070000 ranges: ++ OF: PCI: MEM 0xe8000000..0xe8ffffff -> 0xe8000000 ++ OF: PCI: IO 0xe9000000..0xe900ffff -> 0xe9000000 ++ advk-pcie d0070000.pcie: link never came up ++ advk-pcie d0070000.pcie: PCI host bridge to bus 0000:00 ++ pci_bus 0000:00: root bus resource [bus 00-ff] ++ pci_bus 0000:00: root bus resource [mem0xe8000000-0xe8ffffff] ++ pci_bus 0000:00: root bus resource [io 0x0000-0xffff](bus address [0xe9000000-0xe900ffff]) ++ advk-pcie d0070000.pcie: config read/write timed out ++ ++Following the issue on esppressobin.net forum [1] the workaround seems ++to be limiting the speed of PCIe bridge to 1st generation. This fixed ++the initialisation of all tested Atheros wireless cards. ++The patch in the forum thread swaped registers which would limit speed ++for all Armada 3700 based boards. The approach in this patch, in ++conjunction with "PCI: aardvark: allow to specify link capability" patch ++is less invasive, it only touches the affected board. ++ ++For the record, the iwlwifi and mt76 cards were not affected by this ++issue. ++ ++1. http://espressobin.net/forums/topic/which-pcie-wlan-cards-are-supported ++ ++Signed-off-by: Tomasz Maciej Nowak ++--- ++ arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | 2 ++ ++ 1 file changed, 2 insertions(+) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts ++@@ -46,6 +46,8 @@ ++ /* J9 */ ++ &pcie0 { ++ status = "okay"; +++ +++ max-link-speed = <1>; ++ }; ++ ++ /* J6 */ +diff --git a/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch b/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch +new file mode 100644 +index 00000000000..a5553a3e96c +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch +@@ -0,0 +1,104 @@ ++From da58a931f248f423f917c3a0b3c94303aa30a738 Mon Sep 17 00:00:00 2001 ++From: Maxime Chevallier ++Date: Tue, 25 Sep 2018 15:59:39 +0200 ++Subject: [PATCH] net: mvneta: Add support for 2500Mbps SGMII ++ ++The mvneta controller can handle speeds up to 2500Mbps on the SGMII ++interface. This relies on serdes configuration, the lane must be ++configured at 3.125Gbps and we can't use in-band autoneg at that speed. ++ ++The main issue when supporting that speed on this particular controller ++is that the link partner can send ethernet frames with a shortened ++preamble, which if not explicitly enabled in the controller will cause ++unexpected behaviours. ++ ++This was tested on Armada 385, with the comphy configuration done in ++bootloader. ++ ++Signed-off-by: Maxime Chevallier ++Signed-off-by: David S. Miller ++--- ++ drivers/net/ethernet/marvell/mvneta.c | 27 +++++++++++++++++++++++---- ++ 1 file changed, 23 insertions(+), 4 deletions(-) ++ ++--- a/drivers/net/ethernet/marvell/mvneta.c +++++ b/drivers/net/ethernet/marvell/mvneta.c ++@@ -221,6 +221,8 @@ ++ #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11) ++ #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12) ++ #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13) +++#define MVNETA_GMAC_CTRL_4 0x2c90 +++#define MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE BIT(1) ++ #define MVNETA_MIB_COUNTERS_BASE 0x3000 ++ #define MVNETA_MIB_LATE_COLLISION 0x7c ++ #define MVNETA_DA_FILT_SPEC_MCAST 0x3400 ++@@ -3359,6 +3361,7 @@ static void mvneta_validate(struct net_d ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ state->interface != PHY_INTERFACE_MODE_QSGMII && ++ state->interface != PHY_INTERFACE_MODE_SGMII && +++ state->interface != PHY_INTERFACE_MODE_2500BASEX && ++ !phy_interface_mode_is_8023z(state->interface) && ++ !phy_interface_mode_is_rgmii(state->interface)) { ++ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); ++@@ -3371,9 +3374,15 @@ static void mvneta_validate(struct net_d ++ ++ /* Asymmetric pause is unsupported */ ++ phylink_set(mask, Pause); ++- /* Half-duplex at speeds higher than 100Mbit is unsupported */ ++- phylink_set(mask, 1000baseT_Full); ++- phylink_set(mask, 1000baseX_Full); +++ +++ /* We cannot use 1Gbps when using the 2.5G interface. */ +++ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { +++ phylink_set(mask, 2500baseT_Full); +++ phylink_set(mask, 2500baseX_Full); +++ } else { +++ phylink_set(mask, 1000baseT_Full); +++ phylink_set(mask, 1000baseX_Full); +++ } ++ ++ if (!phy_interface_mode_is_8023z(state->interface)) { ++ /* 10M and 100M are only supported in non-802.3z mode */ ++@@ -3434,12 +3443,14 @@ static void mvneta_mac_config(struct net ++ struct mvneta_port *pp = netdev_priv(ndev); ++ u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0); ++ u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2); +++ u32 new_ctrl4, gmac_ctrl4 = mvreg_read(pp, MVNETA_GMAC_CTRL_4); ++ u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); ++ u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); ++ ++ new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X; ++ new_ctrl2 = gmac_ctrl2 & ~(MVNETA_GMAC2_INBAND_AN_ENABLE | ++ MVNETA_GMAC2_PORT_RESET); +++ new_ctrl4 = gmac_ctrl4 & ~(MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE); ++ new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE; ++ new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE | ++ MVNETA_GMAC_INBAND_RESTART_AN | ++@@ -3472,7 +3483,7 @@ static void mvneta_mac_config(struct net ++ if (state->duplex) ++ new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; ++ ++- if (state->speed == SPEED_1000) +++ if (state->speed == SPEED_1000 || state->speed == SPEED_2500) ++ new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED; ++ else if (state->speed == SPEED_100) ++ new_an |= MVNETA_GMAC_CONFIG_MII_SPEED; ++@@ -3511,10 +3522,18 @@ static void mvneta_mac_config(struct net ++ MVNETA_GMAC_FORCE_LINK_DOWN); ++ } ++ +++ /* When at 2.5G, the link partner can send frames with shortened +++ * preambles. +++ */ +++ if (state->speed == SPEED_2500) +++ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; +++ ++ if (new_ctrl0 != gmac_ctrl0) ++ mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); ++ if (new_ctrl2 != gmac_ctrl2) ++ mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2); +++ if (new_ctrl4 != gmac_ctrl4) +++ mvreg_write(pp, MVNETA_GMAC_CTRL_4, new_ctrl4); ++ if (new_clk != gmac_clk) ++ mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk); ++ if (new_an != gmac_an) +diff --git a/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch b/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch +new file mode 100644 +index 00000000000..b6e16c54a45 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch +@@ -0,0 +1,33 @@ ++From fbd1d5245372e48b494120a30fe0b34b304576c4 Mon Sep 17 00:00:00 2001 ++From: Alexandre Belloni ++Date: Fri, 9 Nov 2018 17:37:20 +0100 ++Subject: [PATCH] net: mvneta: correct typo ++ ++The reserved variable should be named reserved1. ++ ++Signed-off-by: Alexandre Belloni ++Signed-off-by: David S. Miller ++--- ++ drivers/net/ethernet/marvell/mvneta.c | 4 ++-- ++ 1 file changed, 2 insertions(+), 2 deletions(-) ++ ++--- a/drivers/net/ethernet/marvell/mvneta.c +++++ b/drivers/net/ethernet/marvell/mvneta.c ++@@ -495,7 +495,7 @@ struct mvneta_port { ++ #if defined(__LITTLE_ENDIAN) ++ struct mvneta_tx_desc { ++ u32 command; /* Options used by HW for packet transmitting.*/ ++- u16 reserverd1; /* csum_l4 (for future use) */ +++ u16 reserved1; /* csum_l4 (for future use) */ ++ u16 data_size; /* Data size of transmitted packet in bytes */ ++ u32 buf_phys_addr; /* Physical addr of transmitted buffer */ ++ u32 reserved2; /* hw_cmd - (for future use, PMT) */ ++@@ -520,7 +520,7 @@ struct mvneta_rx_desc { ++ #else ++ struct mvneta_tx_desc { ++ u16 data_size; /* Data size of transmitted packet in bytes */ ++- u16 reserverd1; /* csum_l4 (for future use) */ +++ u16 reserved1; /* csum_l4 (for future use) */ ++ u32 command; /* Options used by HW for packet transmitting.*/ ++ u32 reserved2; /* hw_cmd - (for future use, PMT) */ ++ u32 buf_phys_addr; /* Physical addr of transmitted buffer */ +diff --git a/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch b/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch +new file mode 100644 +index 00000000000..01b101283cd +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch +@@ -0,0 +1,55 @@ ++From 83e65df6dfece9eb588735459428f221eb930c0c Mon Sep 17 00:00:00 2001 ++From: Maxime Chevallier ++Date: Fri, 9 Nov 2018 09:17:33 +0100 ++Subject: [PATCH] net: mvneta: Don't advertise 2.5G modes ++ ++Using 2.5G speed relies on the SerDes lanes being configured ++accordingly. The lanes have to be reconfigured to switch between ++1G and 2.5G, and for now only the bootloader does this configuration. ++ ++In the case we add a Comphy driver to handle switching the lanes ++dynamically, it's better for now to stick with supporting only 1G and ++add advertisement for 2.5G once we really are capable of handling both ++speeds without problem. ++ ++Since the interface mode is initialy taken from the DT, we want to make ++sure that adding comphy support won't break boards that don't update ++their dtb. ++ ++Fixes: da58a931f248 ("net: mvneta: Add support for 2500Mbps SGMII") ++Reported-by: Andrew Lunn ++Reported-by: Russell King ++Signed-off-by: Maxime Chevallier ++Signed-off-by: David S. Miller ++--- ++ drivers/net/ethernet/marvell/mvneta.c | 12 +++--------- ++ 1 file changed, 3 insertions(+), 9 deletions(-) ++ ++--- a/drivers/net/ethernet/marvell/mvneta.c +++++ b/drivers/net/ethernet/marvell/mvneta.c ++@@ -3361,7 +3361,6 @@ static void mvneta_validate(struct net_d ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ state->interface != PHY_INTERFACE_MODE_QSGMII && ++ state->interface != PHY_INTERFACE_MODE_SGMII && ++- state->interface != PHY_INTERFACE_MODE_2500BASEX && ++ !phy_interface_mode_is_8023z(state->interface) && ++ !phy_interface_mode_is_rgmii(state->interface)) { ++ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); ++@@ -3375,14 +3374,9 @@ static void mvneta_validate(struct net_d ++ /* Asymmetric pause is unsupported */ ++ phylink_set(mask, Pause); ++ ++- /* We cannot use 1Gbps when using the 2.5G interface. */ ++- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { ++- phylink_set(mask, 2500baseT_Full); ++- phylink_set(mask, 2500baseX_Full); ++- } else { ++- phylink_set(mask, 1000baseT_Full); ++- phylink_set(mask, 1000baseX_Full); ++- } +++ /* Half-duplex at speeds higher than 100Mbit is unsupported */ +++ phylink_set(mask, 1000baseT_Full); +++ phylink_set(mask, 1000baseX_Full); ++ ++ if (!phy_interface_mode_is_8023z(state->interface)) { ++ /* 10M and 100M are only supported in non-802.3z mode */ +diff --git a/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch b/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch +new file mode 100644 +index 00000000000..fd774e08398 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch +@@ -0,0 +1,30 @@ ++From e4a3e9ff5ba9f6b67595ec2768ed4be2054c2aa5 Mon Sep 17 00:00:00 2001 ++From: YueHaibing ++Date: Thu, 22 Nov 2018 14:42:00 +0800 ++Subject: [PATCH] net: mvneta: remove redundant check for ++ eee->tx_lpi_timer < 0 ++ ++fixes the smatch warning: ++ ++drivers/net/ethernet/marvell/mvneta.c:4252 mvneta_ethtool_set_eee() warn: ++ unsigned 'eee->tx_lpi_timer' is never less than zero. ++ ++Signed-off-by: YueHaibing ++Acked-by: Thomas Petazzoni ++Signed-off-by: David S. Miller ++--- ++ drivers/net/ethernet/marvell/mvneta.c | 3 +-- ++ 1 file changed, 1 insertion(+), 2 deletions(-) ++ ++--- a/drivers/net/ethernet/marvell/mvneta.c +++++ b/drivers/net/ethernet/marvell/mvneta.c ++@@ -4268,8 +4268,7 @@ static int mvneta_ethtool_set_eee(struct ++ ++ /* The Armada 37x documents do not give limits for this other than ++ * it being an 8-bit register. */ ++- if (eee->tx_lpi_enabled && ++- (eee->tx_lpi_timer < 0 || eee->tx_lpi_timer > 255)) +++ if (eee->tx_lpi_enabled && eee->tx_lpi_timer > 255) ++ return -EINVAL; ++ ++ lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0); +diff --git a/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch b/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch +new file mode 100644 +index 00000000000..272beb6950f +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch +@@ -0,0 +1,159 @@ ++From a10c1c8191e04c21769656c2ca8e1c69a6218954 Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Thu, 7 Feb 2019 16:19:26 +0000 ++Subject: [PATCH] net: marvell: neta: add comphy support ++ ++Add support for the common phy binding, so that we can reconfigure the ++comphy according to the desired ethernet speed. This will allow us to ++support 1000base-X and 2500base-X SFPs dynamically on SolidRun Clearfog. ++ ++Signed-off-by: Russell King ++Signed-off-by: David S. Miller ++--- ++ drivers/net/ethernet/marvell/mvneta.c | 45 +++++++++++++++++++++++++++++++---- ++ 1 file changed, 41 insertions(+), 4 deletions(-) ++ ++--- a/drivers/net/ethernet/marvell/mvneta.c +++++ b/drivers/net/ethernet/marvell/mvneta.c ++@@ -27,6 +27,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++@@ -438,6 +439,7 @@ struct mvneta_port { ++ struct device_node *dn; ++ unsigned int tx_csum_limit; ++ struct phylink *phylink; +++ struct phy *comphy; ++ ++ struct mvneta_bm *bm_priv; ++ struct mvneta_bm_pool *pool_long; ++@@ -3168,6 +3170,8 @@ static void mvneta_start_dev(struct mvne ++ { ++ int cpu; ++ +++ WARN_ON(phy_power_on(pp->comphy)); +++ ++ mvneta_max_rx_size_set(pp, pp->pkt_size); ++ mvneta_txq_max_tx_size_set(pp, pp->pkt_size); ++ ++@@ -3230,6 +3234,8 @@ static void mvneta_stop_dev(struct mvnet ++ ++ mvneta_tx_reset(pp); ++ mvneta_rx_reset(pp); +++ +++ WARN_ON(phy_power_off(pp->comphy)); ++ } ++ ++ static void mvneta_percpu_enable(void *arg) ++@@ -3355,6 +3361,7 @@ static int mvneta_set_mac_addr(struct ne ++ static void mvneta_validate(struct net_device *ndev, unsigned long *supported, ++ struct phylink_link_state *state) ++ { +++ struct mvneta_port *pp = netdev_priv(ndev); ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; ++ ++ /* We only support QSGMII, SGMII, 802.3z and RGMII modes */ ++@@ -3375,8 +3382,13 @@ static void mvneta_validate(struct net_d ++ phylink_set(mask, Pause); ++ ++ /* Half-duplex at speeds higher than 100Mbit is unsupported */ ++- phylink_set(mask, 1000baseT_Full); ++- phylink_set(mask, 1000baseX_Full); +++ if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) { +++ phylink_set(mask, 1000baseT_Full); +++ phylink_set(mask, 1000baseX_Full); +++ } +++ if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { +++ phylink_set(mask, 2500baseX_Full); +++ } ++ ++ if (!phy_interface_mode_is_8023z(state->interface)) { ++ /* 10M and 100M are only supported in non-802.3z mode */ ++@@ -3390,6 +3402,11 @@ static void mvneta_validate(struct net_d ++ __ETHTOOL_LINK_MODE_MASK_NBITS); ++ bitmap_and(state->advertising, state->advertising, mask, ++ __ETHTOOL_LINK_MODE_MASK_NBITS); +++ +++ /* We can only operate at 2500BaseX or 1000BaseX. If requested +++ * to advertise both, only report advertising at 2500BaseX. +++ */ +++ phylink_helper_basex_speed(state); ++ } ++ ++ static int mvneta_mac_link_state(struct net_device *ndev, ++@@ -3401,7 +3418,9 @@ static int mvneta_mac_link_state(struct ++ gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS); ++ ++ if (gmac_stat & MVNETA_GMAC_SPEED_1000) ++- state->speed = SPEED_1000; +++ state->speed = +++ state->interface == PHY_INTERFACE_MODE_2500BASEX ? +++ SPEED_2500 : SPEED_1000; ++ else if (gmac_stat & MVNETA_GMAC_SPEED_100) ++ state->speed = SPEED_100; ++ else ++@@ -3516,12 +3535,20 @@ static void mvneta_mac_config(struct net ++ MVNETA_GMAC_FORCE_LINK_DOWN); ++ } ++ +++ ++ /* When at 2.5G, the link partner can send frames with shortened ++ * preambles. ++ */ ++ if (state->speed == SPEED_2500) ++ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; ++ +++ if (pp->comphy && +++ (state->interface == PHY_INTERFACE_MODE_SGMII || +++ state->interface == PHY_INTERFACE_MODE_1000BASEX || +++ state->interface == PHY_INTERFACE_MODE_2500BASEX)) +++ WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, +++ state->interface)); +++ ++ if (new_ctrl0 != gmac_ctrl0) ++ mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); ++ if (new_ctrl2 != gmac_ctrl2) ++@@ -4434,7 +4461,7 @@ static int mvneta_port_power_up(struct m ++ if (phy_mode == PHY_INTERFACE_MODE_QSGMII) ++ mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO); ++ else if (phy_mode == PHY_INTERFACE_MODE_SGMII || ++- phy_mode == PHY_INTERFACE_MODE_1000BASEX) +++ phy_interface_mode_is_8023z(phy_mode)) ++ mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); ++ else if (!phy_interface_mode_is_rgmii(phy_mode)) ++ return -EINVAL; ++@@ -4451,6 +4478,7 @@ static int mvneta_probe(struct platform_ ++ struct mvneta_port *pp; ++ struct net_device *dev; ++ struct phylink *phylink; +++ struct phy *comphy; ++ const char *dt_mac_addr; ++ char hw_mac_addr[ETH_ALEN]; ++ const char *mac_from; ++@@ -4476,6 +4504,14 @@ static int mvneta_probe(struct platform_ ++ goto err_free_irq; ++ } ++ +++ comphy = devm_of_phy_get(&pdev->dev, dn, NULL); +++ if (comphy == ERR_PTR(-EPROBE_DEFER)) { +++ err = -EPROBE_DEFER; +++ goto err_free_irq; +++ } else if (IS_ERR(comphy)) { +++ comphy = NULL; +++ } +++ ++ phylink = phylink_create(dev, pdev->dev.fwnode, phy_mode, ++ &mvneta_phylink_ops); ++ if (IS_ERR(phylink)) { ++@@ -4492,6 +4528,7 @@ static int mvneta_probe(struct platform_ ++ pp = netdev_priv(dev); ++ spin_lock_init(&pp->lock); ++ pp->phylink = phylink; +++ pp->comphy = comphy; ++ pp->phy_interface = phy_mode; ++ pp->dn = dn; ++ +diff --git a/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch b/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch +new file mode 100644 +index 00000000000..bac9a55cf0d +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch +@@ -0,0 +1,78 @@ ++From 031b922bfd60c771588911112f8632783de08e5c Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Marek=20Beh=C3=BAn?= ++Date: Mon, 25 Feb 2019 17:43:03 +0100 ++Subject: [PATCH] net: marvell: neta: disable comphy when setting mode ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++The comphy driver for Armada 3700 by Miquèl Raynal (which is currently ++in linux-next) does not actually set comphy mode when phy_set_mode_ext ++is called. The mode is set at next call of phy_power_on. ++ ++Update the driver to semantics similar to mvpp2: helper ++mvneta_comphy_init sets comphy mode and powers it on. ++When mode is to be changed in mvneta_mac_config, first power the comphy ++off, then call mvneta_comphy_init (which sets the mode to new one). ++ ++Only do this when new mode is different from old mode. ++ ++This should also work for Armada 38x, since in that comphy driver ++methods power_on and power_off are unimplemented. ++ ++Signed-off-by: Marek Behún ++Signed-off-by: David S. Miller ++--- ++ drivers/net/ethernet/marvell/mvneta.c | 28 +++++++++++++++++++++++----- ++ 1 file changed, 23 insertions(+), 5 deletions(-) ++ ++--- a/drivers/net/ethernet/marvell/mvneta.c +++++ b/drivers/net/ethernet/marvell/mvneta.c ++@@ -3166,11 +3166,26 @@ static int mvneta_setup_txqs(struct mvne ++ return 0; ++ } ++ +++static int mvneta_comphy_init(struct mvneta_port *pp) +++{ +++ int ret; +++ +++ if (!pp->comphy) +++ return 0; +++ +++ ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, +++ pp->phy_interface); +++ if (ret) +++ return ret; +++ +++ return phy_power_on(pp->comphy); +++} +++ ++ static void mvneta_start_dev(struct mvneta_port *pp) ++ { ++ int cpu; ++ ++- WARN_ON(phy_power_on(pp->comphy)); +++ WARN_ON(mvneta_comphy_init(pp)); ++ ++ mvneta_max_rx_size_set(pp, pp->pkt_size); ++ mvneta_txq_max_tx_size_set(pp, pp->pkt_size); ++@@ -3542,12 +3557,15 @@ static void mvneta_mac_config(struct net ++ if (state->speed == SPEED_2500) ++ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; ++ ++- if (pp->comphy && +++ if (pp->comphy && pp->phy_interface != state->interface && ++ (state->interface == PHY_INTERFACE_MODE_SGMII || ++ state->interface == PHY_INTERFACE_MODE_1000BASEX || ++- state->interface == PHY_INTERFACE_MODE_2500BASEX)) ++- WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, ++- state->interface)); +++ state->interface == PHY_INTERFACE_MODE_2500BASEX)) { +++ pp->phy_interface = state->interface; +++ +++ WARN_ON(phy_power_off(pp->comphy)); +++ WARN_ON(mvneta_comphy_init(pp)); +++ } ++ ++ if (new_ctrl0 != gmac_ctrl0) ++ mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); +diff --git a/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch b/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch +new file mode 100644 +index 00000000000..9186ceb0da4 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch +@@ -0,0 +1,34 @@ ++From eda3d1b0228484fb52b7244a68fd4cc8a985ed10 Mon Sep 17 00:00:00 2001 ++From: Maxime Chevallier ++Date: Wed, 27 Mar 2019 17:31:06 +0100 ++Subject: [PATCH] net: mvneta: Add 2500BaseT support ++ ++Some PHYs will use the 2500BaseX PHY_INTERFACE_MODE when being linked ++with a partner using 2.5GBaseT. ++ ++Since we can't autonegotiate this speed between the MAC and the PHY, we ++need to have the proper comphy support enabled, to make sure we can ++safely advertise 2.5G and 1G in BaseT and be able to switch between both ++corresponding PHY interface modes. This is now possible since comphy ++support was added to this driver. ++ ++This commit adds the 2500BaseT mode to the list of supported modes when ++using 2500BaseX, and was tested on a setup with an Armada385 and a ++88E2010 PHY, both with and without the comphy node in the DT. ++ ++Signed-off-by: Maxime Chevallier ++Signed-off-by: David S. Miller ++--- ++ drivers/net/ethernet/marvell/mvneta.c | 1 + ++ 1 file changed, 1 insertion(+) ++ ++--- a/drivers/net/ethernet/marvell/mvneta.c +++++ b/drivers/net/ethernet/marvell/mvneta.c ++@@ -3402,6 +3402,7 @@ static void mvneta_validate(struct net_d ++ phylink_set(mask, 1000baseX_Full); ++ } ++ if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { +++ phylink_set(mask, 2500baseT_Full); ++ phylink_set(mask, 2500baseX_Full); ++ } ++ +diff --git a/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch b/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch +new file mode 100644 +index 00000000000..b759b9fb254 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch +@@ -0,0 +1,28 @@ ++From c2a90025ad09d830c8d8ae69f485eac6aaaa2472 Mon Sep 17 00:00:00 2001 ++From: Quentin Schulz ++Date: Thu, 4 Oct 2018 14:22:03 +0200 ++Subject: [PATCH] phy: add QSGMII and PCIE modes ++ ++Prepare for upcoming phys that'll handle QSGMII or PCIe. ++ ++Reviewed-by: Florian Fainelli ++Signed-off-by: Quentin Schulz ++Signed-off-by: David S. Miller ++--- ++ include/linux/phy/phy.h | 2 ++ ++ 1 file changed, 2 insertions(+) ++ ++--- a/include/linux/phy/phy.h +++++ b/include/linux/phy/phy.h ++@@ -37,9 +37,11 @@ enum phy_mode { ++ PHY_MODE_USB_OTG, ++ PHY_MODE_SGMII, ++ PHY_MODE_2500SGMII, +++ PHY_MODE_QSGMII, ++ PHY_MODE_10GKR, ++ PHY_MODE_UFS_HS_A, ++ PHY_MODE_UFS_HS_B, +++ PHY_MODE_PCIE, ++ }; ++ ++ /** +diff --git a/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch b/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch +new file mode 100644 +index 00000000000..68fecadce85 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch +@@ -0,0 +1,24 @@ ++From 2af8caeee47846a84bc96abc3a72f7c991153040 Mon Sep 17 00:00:00 2001 ++From: Grygorii Strashko ++Date: Mon, 19 Nov 2018 19:24:21 -0600 ++Subject: [PATCH] phy: core: add PHY_MODE_ETHERNET ++ ++Add new PHY's mode to be used by Ethernet PHY interface drivers or ++multipurpose PHYs like serdes. It will be reused in further changes. ++ ++Signed-off-by: Grygorii Strashko ++Signed-off-by: Kishon Vijay Abraham I ++--- ++ include/linux/phy/phy.h | 1 + ++ 1 file changed, 1 insertion(+) ++ ++--- a/include/linux/phy/phy.h +++++ b/include/linux/phy/phy.h ++@@ -42,6 +42,7 @@ enum phy_mode { ++ PHY_MODE_UFS_HS_A, ++ PHY_MODE_UFS_HS_B, ++ PHY_MODE_PCIE, +++ PHY_MODE_ETHERNET, ++ }; ++ ++ /** +diff --git a/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch b/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch +new file mode 100644 +index 00000000000..83908af19e6 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch +@@ -0,0 +1,45 @@ ++From e1706720408e72fb883f6b151c2b3b23d8e7e5b2 Mon Sep 17 00:00:00 2001 ++From: John Hubbard ++Date: Sat, 12 Jan 2019 17:29:09 -0800 ++Subject: [PATCH] phy: fix build breakage: add PHY_MODE_SATA ++ ++Commit 49e54187ae0b ("ata: libahci_platform: comply to PHY framework") uses ++the PHY_MODE_SATA, but that enum had not yet been added. This caused a ++build failure for me, with today's linux.git. ++ ++Also, there is a potentially conflicting (mis-named) PHY_MODE_SATA, hiding ++in the Marvell Berlin SATA PHY driver. ++ ++Fix the build by: ++ ++ 1) Renaming Marvell's defined value to a more scoped name, ++ in order to avoid any potential conflicts: PHY_BERLIN_MODE_SATA. ++ ++ 2) Adding the missing enum, which was going to be added anyway as part ++ of [1]. ++ ++[1] https://lkml.kernel.org/r/20190108163124.6409-3-miquel.raynal@bootlin.com ++ ++Fixes: 49e54187ae0b ("ata: libahci_platform: comply to PHY framework") ++ ++Signed-off-by: John Hubbard ++Acked-by: Jens Axboe ++Acked-by: Olof Johansson ++Cc: Grzegorz Jaszczyk ++Cc: Miquel Raynal ++Cc: Hans de Goede ++Signed-off-by: Linus Torvalds ++--- ++ include/linux/phy/phy.h | 1 + ++ 1 file changed, 1 insertion(+) ++ ++--- a/include/linux/phy/phy.h +++++ b/include/linux/phy/phy.h ++@@ -43,6 +43,7 @@ enum phy_mode { ++ PHY_MODE_UFS_HS_B, ++ PHY_MODE_PCIE, ++ PHY_MODE_ETHERNET, +++ PHY_MODE_SATA ++ }; ++ ++ /** +diff --git a/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch b/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch +new file mode 100644 +index 00000000000..e02f203912d +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch +@@ -0,0 +1,134 @@ ++From 79a5a18aa9d1062205cdcfa183d4cd5241d1b8da Mon Sep 17 00:00:00 2001 ++From: Grygorii Strashko ++Date: Mon, 19 Nov 2018 19:24:20 -0600 ++Subject: [PATCH] phy: core: rework phy_set_mode to accept phy mode and submode ++ ++Currently the attempt to add support for Ethernet interface mode PHY ++(MII/GMII/RGMII) will lead to the necessity of extending enum phy_mode and ++duplicate there values from phy_interface_t enum (or introduce more PHY ++callbacks) [1]. Both approaches are ineffective and would lead to fast ++bloating of enum phy_mode or struct phy_ops in the process of adding more ++PHYs for different subsystems which will make them unmaintainable. ++ ++As discussed in [1] the solution could be to introduce dual level PHYs mode ++configuration - PHY mode and PHY submode. The PHY mode will define generic ++PHY type (subsystem - PCIE/ETHERNET/USB_) while the PHY submode - subsystem ++specific interface mode. The last is usually already defined in ++corresponding subsystem headers (phy_interface_t for Ethernet, enum ++usb_device_speed for USB). ++ ++This patch is cumulative change which refactors PHY framework code to ++support dual level PHYs mode configuration - PHY mode and PHY submode. It ++extends .set_mode() callback to support additional parameter "int submode" ++and converts all corresponding PHY drivers to support new .set_mode() ++callback declaration. ++The new extended PHY API ++ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) ++is introduced to support dual level PHYs mode configuration and existing ++phy_set_mode() API is converted to macros, so PHY framework consumers do ++not need to be changed (~21 matches). ++ ++[1] http://lkml.kernel.org/r/d63588f6-9ab0-848a-5ad4-8073143bd95d@ti.com ++Signed-off-by: Grygorii Strashko ++Signed-off-by: Kishon Vijay Abraham I ++--- ++ drivers/phy/allwinner/phy-sun4i-usb.c | 3 ++- ++ drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 +++-- ++ drivers/phy/amlogic/phy-meson-gxl-usb3.c | 5 +++-- ++ drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 3 ++- ++ drivers/phy/mediatek/phy-mtk-tphy.c | 2 +- ++ drivers/phy/mediatek/phy-mtk-xsphy.c | 2 +- ++ drivers/phy/mscc/phy-ocelot-serdes.c | 2 +- ++ drivers/phy/phy-core.c | 6 +++--- ++ drivers/phy/qualcomm/phy-qcom-qmp.c | 3 ++- ++ drivers/phy/qualcomm/phy-qcom-qusb2.c | 3 ++- ++ drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 3 ++- ++ drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 3 ++- ++ drivers/phy/qualcomm/phy-qcom-usb-hs.c | 3 ++- ++ drivers/phy/ti/phy-da8xx-usb.c | 3 ++- ++ drivers/phy/ti/phy-tusb1210.c | 2 +- ++ include/linux/phy/phy.h | 13 ++++++++++--- ++ 16 files changed, 39 insertions(+), 22 deletions(-) ++ ++--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c ++@@ -512,7 +512,8 @@ static int mvebu_comphy_power_on(struct ++ return ret; ++ } ++ ++-static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode) +++static int mvebu_comphy_set_mode(struct phy *phy, +++ enum phy_mode mode, int submode) ++ { ++ struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); ++ ++--- a/drivers/phy/phy-core.c +++++ b/drivers/phy/phy-core.c ++@@ -360,7 +360,7 @@ int phy_power_off(struct phy *phy) ++ } ++ EXPORT_SYMBOL_GPL(phy_power_off); ++ ++-int phy_set_mode(struct phy *phy, enum phy_mode mode) +++int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) ++ { ++ int ret; ++ ++@@ -368,14 +368,14 @@ int phy_set_mode(struct phy *phy, enum p ++ return 0; ++ ++ mutex_lock(&phy->mutex); ++- ret = phy->ops->set_mode(phy, mode); +++ ret = phy->ops->set_mode(phy, mode, submode); ++ if (!ret) ++ phy->attrs.mode = mode; ++ mutex_unlock(&phy->mutex); ++ ++ return ret; ++ } ++-EXPORT_SYMBOL_GPL(phy_set_mode); +++EXPORT_SYMBOL_GPL(phy_set_mode_ext); ++ ++ int phy_reset(struct phy *phy) ++ { ++--- a/include/linux/phy/phy.h +++++ b/include/linux/phy/phy.h ++@@ -62,7 +62,7 @@ struct phy_ops { ++ int (*exit)(struct phy *phy); ++ int (*power_on)(struct phy *phy); ++ int (*power_off)(struct phy *phy); ++- int (*set_mode)(struct phy *phy, enum phy_mode mode); +++ int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode); ++ int (*reset)(struct phy *phy); ++ int (*calibrate)(struct phy *phy); ++ struct module *owner; ++@@ -166,7 +166,10 @@ int phy_init(struct phy *phy); ++ int phy_exit(struct phy *phy); ++ int phy_power_on(struct phy *phy); ++ int phy_power_off(struct phy *phy); ++-int phy_set_mode(struct phy *phy, enum phy_mode mode); +++int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); +++#define phy_set_mode(phy, mode) \ +++ phy_set_mode_ext(phy, mode, 0) +++ ++ static inline enum phy_mode phy_get_mode(struct phy *phy) ++ { ++ return phy->attrs.mode; ++@@ -280,13 +283,17 @@ static inline int phy_power_off(struct p ++ return -ENOSYS; ++ } ++ ++-static inline int phy_set_mode(struct phy *phy, enum phy_mode mode) +++static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, +++ int submode) ++ { ++ if (!phy) ++ return 0; ++ return -ENOSYS; ++ } ++ +++#define phy_set_mode(phy, mode) \ +++ phy_set_mode_ext(phy, mode, 0) +++ ++ static inline enum phy_mode phy_get_mode(struct phy *phy) ++ { ++ return PHY_MODE_INVALID; +diff --git a/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch b/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch +new file mode 100644 +index 00000000000..0964da03a8d +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch +@@ -0,0 +1,381 @@ ++From 9695375a3f4a604406f2e61f2b735eca1de931ed Mon Sep 17 00:00:00 2001 ++From: Miquel Raynal ++Date: Tue, 8 Jan 2019 17:31:20 +0100 ++Subject: [PATCH] phy: add A3700 COMPHY support ++ ++Add a driver to support COMPHY, a hardware block providing shared ++serdes PHYs on Marvell Armada 3700. This driver uses SMC calls and ++rely on having an up-to-date firmware. ++ ++SATA, PCie and USB3 host mode have been tested successfully with an ++ESPRESSObin. (HS)SGMII mode cannot be tested with this platform. ++ ++Evan worked on the original driver structure and Grzegorz on the SMC ++calls rework. The structure of this driver has been copied from ++Antoine Tenart work on CP110 COMPHY driver. ++ ++Signed-off-by: Miquel Raynal ++Co-developed-by: Evan Wang ++Signed-off-by: Evan Wang ++Co-developed-by: Grzegorz Jaszczyk ++Signed-off-by: Grzegorz Jaszczyk ++Signed-off-by: Kishon Vijay Abraham I ++--- ++ drivers/phy/marvell/Kconfig | 12 + ++ drivers/phy/marvell/Makefile | 1 + ++ drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 318 +++++++++++++++++++++++++++ ++ 3 files changed, 331 insertions(+) ++ create mode 100644 drivers/phy/marvell/phy-mvebu-a3700-comphy.c ++ ++--- a/drivers/phy/marvell/Kconfig +++++ b/drivers/phy/marvell/Kconfig ++@@ -21,6 +21,18 @@ config PHY_BERLIN_USB ++ help ++ Enable this to support the USB PHY on Marvell Berlin SoCs. ++ +++config PHY_MVEBU_A3700_COMPHY +++ tristate "Marvell A3700 comphy driver" +++ depends on ARCH_MVEBU || COMPILE_TEST +++ depends on OF +++ depends on HAVE_ARM_SMCCC +++ default y +++ select GENERIC_PHY +++ help +++ This driver allows to control the comphy, a hardware block providing +++ shared serdes PHYs on Marvell Armada 3700. Its serdes lanes can be +++ used by various controllers: Ethernet, SATA, USB3, PCIe. +++ ++ config PHY_MVEBU_CP110_COMPHY ++ tristate "Marvell CP110 comphy driver" ++ depends on ARCH_MVEBU || COMPILE_TEST ++--- a/drivers/phy/marvell/Makefile +++++ b/drivers/phy/marvell/Makefile ++@@ -2,6 +2,7 @@ ++ obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o ++ obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o ++ obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o +++obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o ++ obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o ++ obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o ++ obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o ++--- /dev/null +++++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c ++@@ -0,0 +1,318 @@ +++// SPDX-License-Identifier: GPL-2.0 +++/* +++ * Copyright (C) 2018 Marvell +++ * +++ * Authors: +++ * Evan Wang +++ * Miquèl Raynal +++ * +++ * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart. +++ * SMC call initial support done by Grzegorz Jaszczyk. +++ */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#define MVEBU_A3700_COMPHY_LANES 3 +++#define MVEBU_A3700_COMPHY_PORTS 2 +++ +++/* COMPHY Fast SMC function identifiers */ +++#define COMPHY_SIP_POWER_ON 0x82000001 +++#define COMPHY_SIP_POWER_OFF 0x82000002 +++#define COMPHY_SIP_PLL_LOCK 0x82000003 +++ +++#define COMPHY_FW_MODE_SATA 0x1 +++#define COMPHY_FW_MODE_SGMII 0x2 +++#define COMPHY_FW_MODE_HS_SGMII 0x3 +++#define COMPHY_FW_MODE_USB3H 0x4 +++#define COMPHY_FW_MODE_USB3D 0x5 +++#define COMPHY_FW_MODE_PCIE 0x6 +++#define COMPHY_FW_MODE_RXAUI 0x7 +++#define COMPHY_FW_MODE_XFI 0x8 +++#define COMPHY_FW_MODE_SFI 0x9 +++#define COMPHY_FW_MODE_USB3 0xa +++ +++#define COMPHY_FW_SPEED_1_25G 0 /* SGMII 1G */ +++#define COMPHY_FW_SPEED_2_5G 1 +++#define COMPHY_FW_SPEED_3_125G 2 /* SGMII 2.5G */ +++#define COMPHY_FW_SPEED_5G 3 +++#define COMPHY_FW_SPEED_5_15625G 4 /* XFI 5G */ +++#define COMPHY_FW_SPEED_6G 5 +++#define COMPHY_FW_SPEED_10_3125G 6 /* XFI 10G */ +++#define COMPHY_FW_SPEED_MAX 0x3F +++ +++#define COMPHY_FW_MODE(mode) ((mode) << 12) +++#define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \ +++ ((idx) << 8) | \ +++ ((speed) << 2)) +++#define COMPHY_FW_PCIE(mode, idx, speed, width) (COMPHY_FW_NET(mode, idx, speed) | \ +++ ((width) << 18)) +++ +++struct mvebu_a3700_comphy_conf { +++ unsigned int lane; +++ enum phy_mode mode; +++ int submode; +++ unsigned int port; +++ u32 fw_mode; +++}; +++ +++#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _port, _fw) \ +++ { \ +++ .lane = _lane, \ +++ .mode = _mode, \ +++ .submode = _smode, \ +++ .port = _port, \ +++ .fw_mode = _fw, \ +++ } +++ +++#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _port, _fw) \ +++ MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _port, _fw) +++ +++#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _port, _fw) \ +++ MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _port, _fw) +++ +++static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { +++ /* lane 0 */ +++ MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, 0, +++ COMPHY_FW_MODE_USB3H), +++ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, 1, +++ COMPHY_FW_MODE_SGMII), +++ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, 1, +++ COMPHY_FW_MODE_HS_SGMII), +++ /* lane 1 */ +++ MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, 0, +++ COMPHY_FW_MODE_PCIE), +++ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0, +++ COMPHY_FW_MODE_SGMII), +++ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, 0, +++ COMPHY_FW_MODE_HS_SGMII), +++ /* lane 2 */ +++ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, 0, +++ COMPHY_FW_MODE_SATA), +++ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, 0, +++ COMPHY_FW_MODE_USB3H), +++}; +++ +++struct mvebu_a3700_comphy_lane { +++ struct device *dev; +++ unsigned int id; +++ enum phy_mode mode; +++ int submode; +++ int port; +++}; +++ +++static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane, +++ unsigned long mode) +++{ +++ struct arm_smccc_res res; +++ +++ arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); +++ +++ return res.a0; +++} +++ +++static int mvebu_a3700_comphy_get_fw_mode(int lane, int port, +++ enum phy_mode mode, +++ int submode) +++{ +++ int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes); +++ +++ /* Unused PHY mux value is 0x0 */ +++ if (mode == PHY_MODE_INVALID) +++ return -EINVAL; +++ +++ for (i = 0; i < n; i++) { +++ if (mvebu_a3700_comphy_modes[i].lane == lane && +++ mvebu_a3700_comphy_modes[i].port == port && +++ mvebu_a3700_comphy_modes[i].mode == mode && +++ mvebu_a3700_comphy_modes[i].submode == submode) +++ break; +++ } +++ +++ if (i == n) +++ return -EINVAL; +++ +++ return mvebu_a3700_comphy_modes[i].fw_mode; +++} +++ +++static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, +++ int submode) +++{ +++ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); +++ int fw_mode; +++ +++ if (submode == PHY_INTERFACE_MODE_1000BASEX) +++ submode = PHY_INTERFACE_MODE_SGMII; +++ +++ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, mode, +++ submode); +++ if (fw_mode < 0) { +++ dev_err(lane->dev, "invalid COMPHY mode\n"); +++ return fw_mode; +++ } +++ +++ /* Just remember the mode, ->power_on() will do the real setup */ +++ lane->mode = mode; +++ lane->submode = submode; +++ +++ return 0; +++} +++ +++static int mvebu_a3700_comphy_power_on(struct phy *phy) +++{ +++ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); +++ u32 fw_param; +++ int fw_mode; +++ +++ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, +++ lane->mode, lane->submode); +++ if (fw_mode < 0) { +++ dev_err(lane->dev, "invalid COMPHY mode\n"); +++ return fw_mode; +++ } +++ +++ switch (lane->mode) { +++ case PHY_MODE_USB_HOST_SS: +++ dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); +++ fw_param = COMPHY_FW_MODE(fw_mode); +++ break; +++ case PHY_MODE_SATA: +++ dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); +++ fw_param = COMPHY_FW_MODE(fw_mode); +++ break; +++ case PHY_MODE_ETHERNET: +++ switch (lane->submode) { +++ case PHY_INTERFACE_MODE_SGMII: +++ dev_dbg(lane->dev, "set lane %d to SGMII mode\n", +++ lane->id); +++ fw_param = COMPHY_FW_NET(fw_mode, lane->port, +++ COMPHY_FW_SPEED_1_25G); +++ break; +++ case PHY_INTERFACE_MODE_2500BASEX: +++ dev_dbg(lane->dev, "set lane %d to HS SGMII mode\n", +++ lane->id); +++ fw_param = COMPHY_FW_NET(fw_mode, lane->port, +++ COMPHY_FW_SPEED_3_125G); +++ break; +++ default: +++ dev_err(lane->dev, "unsupported PHY submode (%d)\n", +++ lane->submode); +++ return -ENOTSUPP; +++ } +++ break; +++ case PHY_MODE_PCIE: +++ dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); +++ fw_param = COMPHY_FW_PCIE(fw_mode, lane->port, +++ COMPHY_FW_SPEED_5G, +++ phy->attrs.bus_width); +++ break; +++ default: +++ dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); +++ return -ENOTSUPP; +++ } +++ +++ return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); +++} +++ +++static int mvebu_a3700_comphy_power_off(struct phy *phy) +++{ +++ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); +++ +++ return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_OFF, lane->id, 0); +++} +++ +++static const struct phy_ops mvebu_a3700_comphy_ops = { +++ .power_on = mvebu_a3700_comphy_power_on, +++ .power_off = mvebu_a3700_comphy_power_off, +++ .set_mode = mvebu_a3700_comphy_set_mode, +++ .owner = THIS_MODULE, +++}; +++ +++static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, +++ struct of_phandle_args *args) +++{ +++ struct mvebu_a3700_comphy_lane *lane; +++ struct phy *phy; +++ +++ if (WARN_ON(args->args[0] >= MVEBU_A3700_COMPHY_PORTS)) +++ return ERR_PTR(-EINVAL); +++ +++ phy = of_phy_simple_xlate(dev, args); +++ if (IS_ERR(phy)) +++ return phy; +++ +++ lane = phy_get_drvdata(phy); +++ lane->port = args->args[0]; +++ +++ return phy; +++} +++ +++static int mvebu_a3700_comphy_probe(struct platform_device *pdev) +++{ +++ struct phy_provider *provider; +++ struct device_node *child; +++ +++ for_each_available_child_of_node(pdev->dev.of_node, child) { +++ struct mvebu_a3700_comphy_lane *lane; +++ struct phy *phy; +++ int ret; +++ u32 lane_id; +++ +++ ret = of_property_read_u32(child, "reg", &lane_id); +++ if (ret < 0) { +++ dev_err(&pdev->dev, "missing 'reg' property (%d)\n", +++ ret); +++ continue; +++ } +++ +++ if (lane_id >= MVEBU_A3700_COMPHY_LANES) { +++ dev_err(&pdev->dev, "invalid 'reg' property\n"); +++ continue; +++ } +++ +++ lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); +++ if (!lane) +++ return -ENOMEM; +++ +++ phy = devm_phy_create(&pdev->dev, child, +++ &mvebu_a3700_comphy_ops); +++ if (IS_ERR(phy)) +++ return PTR_ERR(phy); +++ +++ lane->dev = &pdev->dev; +++ lane->mode = PHY_MODE_INVALID; +++ lane->submode = PHY_INTERFACE_MODE_NA; +++ lane->id = lane_id; +++ lane->port = -1; +++ phy_set_drvdata(phy, lane); +++ } +++ +++ provider = devm_of_phy_provider_register(&pdev->dev, +++ mvebu_a3700_comphy_xlate); +++ return PTR_ERR_OR_ZERO(provider); +++} +++ +++static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = { +++ { .compatible = "marvell,comphy-a3700" }, +++ { }, +++}; +++MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table); +++ +++static struct platform_driver mvebu_a3700_comphy_driver = { +++ .probe = mvebu_a3700_comphy_probe, +++ .driver = { +++ .name = "mvebu-a3700-comphy", +++ .of_match_table = mvebu_a3700_comphy_of_match_table, +++ }, +++}; +++module_platform_driver(mvebu_a3700_comphy_driver); +++ +++MODULE_AUTHOR("Miquèl Raynal "); +++MODULE_DESCRIPTION("Common PHY driver for A3700"); +++MODULE_LICENSE("GPL v2"); +diff --git a/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch b/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch +new file mode 100644 +index 00000000000..393f8237944 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch +@@ -0,0 +1,58 @@ ++From 2ef303f0fe44feee4a3ca8bd62fca86c105927d2 Mon Sep 17 00:00:00 2001 ++From: Miquel Raynal ++Date: Tue, 8 Jan 2019 17:31:24 +0100 ++Subject: [PATCH] arm64: dts: marvell: armada-37xx: declare the COMPHY ++ node ++ ++Describe the A3700 COMPHY node. It has three PHYs that can be ++configured as follow: ++* PCIe or GbE ++* USB3 or GbE ++* SATA or USB3 ++Each of them has its own memory area. ++ ++Suggested-by: Grzegorz Jaszczyk ++Signed-off-by: Miquel Raynal ++Signed-off-by: Gregory CLEMENT ++--- ++ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 29 ++++++++++++++++++++++++++++ ++ 1 file changed, 29 insertions(+) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi ++@@ -235,6 +235,35 @@ ++ reg = <0x14000 0x60>; ++ }; ++ +++ comphy: phy@18300 { +++ compatible = "marvell,comphy-a3700"; +++ reg = <0x18300 0x300>, +++ <0x1F000 0x400>, +++ <0x5C000 0x400>, +++ <0xe0178 0x8>; +++ reg-names = "comphy", +++ "lane1_pcie_gbe", +++ "lane0_usb3_gbe", +++ "lane2_sata_usb3"; +++ #address-cells = <1>; +++ #size-cells = <0>; +++ +++ comphy0: phy@0 { +++ reg = <0>; +++ #phy-cells = <1>; +++ }; +++ +++ comphy1: phy@1 { +++ reg = <1>; +++ #phy-cells = <1>; +++ }; +++ +++ comphy2: phy@2 { +++ reg = <2>; +++ #phy-cells = <1>; +++ }; +++ }; +++ ++ pinctrl_sb: pinctrl@18800 { ++ compatible = "marvell,armada3710-sb-pinctrl", ++ "syscon", "simple-mfd"; +diff --git a/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch b/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch +new file mode 100644 +index 00000000000..f72ea93b97e +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch +@@ -0,0 +1,35 @@ ++From 9c222a1d78a1700220e38feb270f00d2ddd3c5ab Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Wed, 6 Nov 2019 13:44:21 +0000 ++Subject: [PATCH 657/660] arm64: dts: uDPU: fix comphy definitions ++ ++The uDPU uses both ethernet controllers, which ties up COMPHY 0 for ++eth1 and COMPHY 1 for eth0, with no USB3 comphy. The addition of ++COMPHY support made the kernel override the setup by the boot loader ++breaking this platform. Delete the USB3 COMPHY definition at platform ++level, and add phy specifications for the ethernet channels. ++ ++Fixes: bd3d25b07342 ("arm64: dts: marvell: armada-37xx: link USB hosts with their PHYs") ++Signed-off-by: Russell King ++--- ++ arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts | 2 ++ ++ 1 file changed, 2 insertions(+) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +++++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts ++@@ -143,6 +143,7 @@ ++ status = "okay"; ++ phy-mode = "sgmii"; ++ managed = "in-band-status"; +++ phys = <&comphy1 0>; ++ sfp = <&sfp_eth0>; ++ }; ++ ++@@ -150,6 +151,7 @@ ++ status = "okay"; ++ phy-mode = "sgmii"; ++ managed = "in-band-status"; +++ phys = <&comphy0 1>; ++ sfp = <&sfp_eth1>; ++ }; ++ +diff --git a/target/linux/mvebu/patches-5.4/545-arm64-dts-uDPU-remove-i2c-fast-mode.patch b/target/linux/mvebu/patches-5.4/545-arm64-dts-uDPU-remove-i2c-fast-mode.patch +new file mode 100644 +index 00000000000..b984eb4ba16 +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/545-arm64-dts-uDPU-remove-i2c-fast-mode.patch +@@ -0,0 +1,30 @@ ++From 662eb8fc87f982e63ccb9a9df25c7aeabf9fe341 Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Thu, 14 Nov 2019 00:23:35 +0000 ++Subject: [PATCH 658/660] arm64: dts: uDPU: remove i2c-fast-mode ++ ++The I2C bus violates the timing specifications when run in fast mode ++on the uDPU, so switch to 100kHz mode. ++ ++Signed-off-by: Russell King ++--- ++ arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts | 2 ++ ++ 1 file changed, 2 insertions(+) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +++++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts ++@@ -119,12 +119,14 @@ ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; +++ /delete-property/mrvl,i2c-fast-mode; ++ }; ++ ++ &i2c1 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; +++ /delete-property/mrvl,i2c-fast-mode; ++ ++ lm75@48 { ++ status = "okay"; +diff --git a/target/linux/mvebu/patches-5.4/546-arm64-dts-uDPU-SFP-cages-support-3W-modules.patch b/target/linux/mvebu/patches-5.4/546-arm64-dts-uDPU-SFP-cages-support-3W-modules.patch +new file mode 100644 +index 00000000000..d025f36a53c +--- /dev/null ++++ b/target/linux/mvebu/patches-5.4/546-arm64-dts-uDPU-SFP-cages-support-3W-modules.patch +@@ -0,0 +1,33 @@ ++From 1cb114a20854e34324a2cb308f23054ff8227ffa Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Tue, 19 Nov 2019 22:48:50 +0000 ++Subject: [PATCH 659/660] arm64: dts: uDPU: SFP cages support 3W modules ++ ++The SFP cages are designed to support up to 3W modules, such as G.hn, ++G.fast and MoCA modules. Although there is no way for such modules to ++declare to software that they consume 3W, we document in DT that this ++is the designed power level for these cages. ++ ++Signed-off-by: Russell King ++--- ++ arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts | 2 ++ ++ 1 file changed, 2 insertions(+) ++ ++--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +++++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts ++@@ -69,6 +69,7 @@ ++ mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>; ++ tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>; ++ tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>; +++ maximum-power-milliwatt = <3000>; ++ }; ++ ++ sfp_eth1: sfp-eth1 { ++@@ -78,6 +79,7 @@ ++ mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>; ++ tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>; ++ tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>; +++ maximum-power-milliwatt = <3000>; ++ }; ++ }; ++ + +From b526702f2900f8fc2126feedb43be3641a7a8484 Mon Sep 17 00:00:00 2001 +From: DENG Qingfang +Date: Wed, 4 Mar 2020 20:46:23 +0800 +Subject: [PATCH 2/4] mvebu: set kernel testing version to 5.4 + +Signed-off-by: DENG Qingfang +--- + target/linux/mvebu/Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/linux/mvebu/Makefile b/target/linux/mvebu/Makefile +index 1688065a5ce..05003689806 100644 +--- a/target/linux/mvebu/Makefile ++++ b/target/linux/mvebu/Makefile +@@ -13,6 +13,7 @@ SUBTARGETS:=cortexa9 cortexa53 cortexa72 + MAINTAINER:=Imre Kaloz + + KERNEL_PATCHVER:=4.19 ++KERNEL_TESTING_PATCHVER:=5.4 + + include $(INCLUDE_DIR)/target.mk + + +From 745a16c12188efbcfb2f8c0797898cf1bab4839d Mon Sep 17 00:00:00 2001 +From: DENG Qingfang +Date: Wed, 4 Mar 2020 20:46:28 +0800 +Subject: [PATCH 3/4] mvebu: refresh patches + +Signed-off-by: DENG Qingfang +--- + .../boot/dts/marvell/armada-3720-uDPU.dts | 162 -------- + .../patches-5.4/002-add_powertables.patch | 2 +- + .../patches-5.4/003-add_switch_nodes.patch | 6 +- + ...Mangle-bootloader-s-kernel-arguments.patch | 10 +- + .../patches-5.4/100-find_active_root.patch | 12 +- + .../210-clearfog_switch_node.patch | 2 +- + .../220-disable-untested-dsa-boards.patch | 4 +- + ...-armada-xp-linksys-mamba-broken-idle.patch | 2 +- + .../300-mvneta-tx-queue-workaround.patch | 7 +- + ...-pci-mvebu-time-out-reset-on-link-up.patch | 6 +- + ...rmada388-clearfog-document-MPP-usage.patch | 124 ------ + ...l-armada37xx-Add-emmc-sdio-pinctrl-d.patch | 40 -- + ...l-armada-37xx-Enable-emmc-on-espress.patch | 49 --- + ...da-3720-espressobin-correct-spi-node.patch | 58 --- + ...l-armada-3720-espressobin-add-ports-.patch | 2 +- + ...rdvark-Convert-to-use-pci_host_probe.patch | 4 +- + ...-device-to-the-same-MAX-payload-size.patch | 8 +- + ...ardvark-disable-LOS-state-by-default.patch | 2 +- + ...ark-allow-to-specify-link-capability.patch | 4 +- + ...-3720-espressobin-set-max-link-to-ge.patch | 8 +- + ...vneta-Add-support-for-2500Mbps-SGMII.patch | 104 ----- + .../532-net-mvneta-correct-typo.patch | 33 -- + ...net-mvneta-Dont-advertise-2.5G-modes.patch | 55 --- + ...et-mvneta-remove-redundant-check-for.patch | 30 -- + ...-net-marvell-neta-add-comphy-support.patch | 159 -------- + ...eta-disable-comphy-when-setting-mode.patch | 78 ---- + ...537-net-mvneta-add-2500baset-support.patch | 34 -- + .../538-phy-add-QSGMII-and-PCIE-modes.patch | 28 -- + .../539-phy-core-add-PHY_MODE_ETHERNET.patch | 24 -- + ...fix-build-breakage-add-PHY_MODE_SATA.patch | 45 --- + ...phy_set_mode-to-accept-phy-mode-and-.patch | 134 ------ + .../542-phy-add-A3700-COMPHY-support.patch | 381 ------------------ + ...rvell-armada-37xx-declare-the-COMPHY.patch | 58 --- + ...rm64-dts-uDPU-fix-comphy-definitions.patch | 35 -- + 34 files changed, 39 insertions(+), 1671 deletions(-) + delete mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts + delete mode 100644 target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch + delete mode 100644 target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch + delete mode 100644 target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch + delete mode 100644 target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch + delete mode 100644 target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch + delete mode 100644 target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch + delete mode 100644 target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch + delete mode 100644 target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch + delete mode 100644 target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch + delete mode 100644 target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch + delete mode 100644 target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch + delete mode 100644 target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch + delete mode 100644 target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch + delete mode 100644 target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch + delete mode 100644 target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch + delete mode 100644 target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch + delete mode 100644 target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch + delete mode 100644 target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch + +diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +deleted file mode 100644 +index 5b722b4f832..00000000000 +--- a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts ++++ /dev/null +@@ -1,162 +0,0 @@ +-// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +-/* +- * Device tree for the uDPU board. +- * Based on Marvell Armada 3720 development board (DB-88F3720-DDR3) +- * Copyright (C) 2016 Marvell +- * Copyright (C) 2019 Methode Electronics +- * Copyright (C) 2019 Telus +- * +- * Vladimir Vid +- */ +- +-/dts-v1/; +- +-#include +-#include "armada-372x.dtsi" +- +-/ { +- model = "Methode uDPU Board"; +- compatible = "methode,udpu", "marvell,armada3720"; +- +- chosen { +- stdout-path = "serial0:115200n8"; +- }; +- +- memory@0 { +- device_type = "memory"; +- reg = <0x00000000 0x00000000 0x00000000 0x20000000>; +- }; +- +- leds { +- pinctrl-names = "default"; +- compatible = "gpio-leds"; +- +- power1 { +- label = "udpu:green:power"; +- gpios = <&gpionb 11 GPIO_ACTIVE_LOW>; +- }; +- +- power2 { +- label = "udpu:red:power"; +- gpios = <&gpionb 12 GPIO_ACTIVE_LOW>; +- }; +- +- network1 { +- label = "udpu:green:network"; +- gpios = <&gpionb 13 GPIO_ACTIVE_LOW>; +- }; +- +- network2 { +- label = "udpu:red:network"; +- gpios = <&gpionb 14 GPIO_ACTIVE_LOW>; +- }; +- +- alarm1 { +- label = "udpu:green:alarm"; +- gpios = <&gpionb 15 GPIO_ACTIVE_LOW>; +- }; +- +- alarm2 { +- label = "udpu:red:alarm"; +- gpios = <&gpionb 16 GPIO_ACTIVE_LOW>; +- }; +- }; +- +- sfp_eth0: sfp-eth0 { +- compatible = "sff,sfp"; +- i2c-bus = <&i2c0>; +- los-gpio = <&gpiosb 2 GPIO_ACTIVE_HIGH>; +- mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>; +- tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>; +- tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>; +- }; +- +- sfp_eth1: sfp-eth1 { +- compatible = "sff,sfp"; +- i2c-bus = <&i2c1>; +- los-gpio = <&gpiosb 7 GPIO_ACTIVE_HIGH>; +- mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>; +- tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>; +- tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>; +- }; +-}; +- +-&sdhci0 { +- status = "okay"; +- bus-width = <8>; +- mmc-ddr-1_8v; +- mmc-hs400-1_8v; +- marvell,pad-type = "fixed-1-8v"; +- non-removable; +- no-sd; +- no-sdio; +-}; +- +-&spi0 { +- status = "okay"; +- pinctrl-names = "default"; +- pinctrl-0 = <&spi_quad_pins>; +- +- flash@0 { +- compatible = "jedec,spi-nor"; +- reg = <0>; +- spi-max-frequency = <54000000>; +- +- partitions { +- compatible = "fixed-partitions"; +- #address-cells = <1>; +- #size-cells = <1>; +- /* only bootloader is located on the SPI */ +- partition@0 { +- label = "uboot"; +- reg = <0 0x400000>; +- }; +- }; +- }; +-}; +- +-&i2c0 { +- status = "okay"; +- pinctrl-names = "default"; +- pinctrl-0 = <&i2c1_pins>; +-}; +- +-&i2c1 { +- status = "okay"; +- pinctrl-names = "default"; +- pinctrl-0 = <&i2c2_pins>; +- +- lm75@48 { +- status = "okay"; +- compatible = "lm75"; +- reg = <0x48>; +- }; +- +- lm75@49 { +- status = "okay"; +- compatible = "lm75"; +- reg = <0x49>; +- }; +-}; +- +-ð0 { +- status = "okay"; +- phy-mode = "sgmii"; +- managed = "in-band-status"; +- sfp = <&sfp_eth0>; +-}; +- +-ð1 { +- status = "okay"; +- phy-mode = "sgmii"; +- managed = "in-band-status"; +- sfp = <&sfp_eth1>; +-}; +- +-&usb3 { +- status = "okay"; +-}; +- +-&uart0 { +- status = "okay"; +-}; +diff --git a/target/linux/mvebu/patches-5.4/002-add_powertables.patch b/target/linux/mvebu/patches-5.4/002-add_powertables.patch +index c2fb748d5d0..efbbbc7d786 100644 +--- a/target/linux/mvebu/patches-5.4/002-add_powertables.patch ++++ b/target/linux/mvebu/patches-5.4/002-add_powertables.patch +@@ -667,7 +667,7 @@ + pinctrl-0 = <&sdhci_pins>; + --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts + +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +-@@ -272,12 +272,100 @@ ++@@ -225,12 +225,100 @@ + pcie@2,0 { + /* Port 0, Lane 1 */ + status = "okay"; +diff --git a/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch b/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch +index b2086389163..e13973767f9 100644 +--- a/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch ++++ b/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch +@@ -1,8 +1,8 @@ + --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts + +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +-@@ -257,6 +257,16 @@ +- }; +- }; ++@@ -210,6 +210,16 @@ ++ compatible = "pwm-fan"; ++ pwms = <&gpio0 24 4000>; + }; + + + + mvsw61xx { +diff --git a/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch +index 0cb9e996027..2f942ea3af6 100644 +--- a/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch ++++ b/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch +@@ -28,7 +28,7 @@ Signed-off-by: Michael Gray + + --- a/arch/arm/Kconfig + +++ b/arch/arm/Kconfig +-@@ -1926,6 +1926,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN ++@@ -1825,6 +1825,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN + The command-line arguments provided by the boot loader will be + appended to the the device tree bootargs property. + +@@ -145,7 +145,7 @@ Signed-off-by: Michael Gray + } + *ptr = '\0'; + +-@@ -148,7 +218,9 @@ int atags_to_fdt(void *atag_list, void * ++@@ -166,7 +236,9 @@ int atags_to_fdt(void *atag_list, void * + else + setprop_string(fdt, "/chosen", "bootargs", + atag->u.cmdline.cmdline); +@@ -156,7 +156,7 @@ Signed-off-by: Michael Gray + if (memcount >= sizeof(mem_reg_property)/4) + continue; + if (!atag->u.mem.size) +-@@ -187,6 +259,10 @@ int atags_to_fdt(void *atag_list, void * ++@@ -210,6 +282,10 @@ int atags_to_fdt(void *atag_list, void * + setprop(fdt, "/memory", "reg", mem_reg_property, + 4 * memcount * memsize); + } +@@ -169,7 +169,7 @@ Signed-off-by: Michael Gray + } + --- a/init/main.c + +++ b/init/main.c +-@@ -102,6 +102,10 @@ ++@@ -103,6 +103,10 @@ + #define CREATE_TRACE_POINTS + #include + +@@ -180,7 +180,7 @@ Signed-off-by: Michael Gray + static int kernel_init(void *); + + extern void init_IRQ(void); +-@@ -591,6 +595,18 @@ asmlinkage __visible void __init start_k ++@@ -630,6 +634,18 @@ asmlinkage __visible void __init start_k + page_alloc_init(); + + pr_notice("Kernel command line: %s\n", boot_command_line); +diff --git a/target/linux/mvebu/patches-5.4/100-find_active_root.patch b/target/linux/mvebu/patches-5.4/100-find_active_root.patch +index f52a5108b85..854031b0d51 100644 +--- a/target/linux/mvebu/patches-5.4/100-find_active_root.patch ++++ b/target/linux/mvebu/patches-5.4/100-find_active_root.patch +@@ -3,9 +3,9 @@ Dynamically rename the active partition to "ubi". + + Signed-off-by: Imre Kaloz + +---- a/drivers/mtd/ofpart.c +-+++ b/drivers/mtd/ofpart.c +-@@ -25,6 +25,8 @@ static bool node_has_compatible(struct d ++--- a/drivers/mtd/parsers/ofpart.c +++++ b/drivers/mtd/parsers/ofpart.c ++@@ -21,6 +21,8 @@ static bool node_has_compatible(struct d + return of_get_property(pp, "compatible", NULL); + } + +@@ -14,7 +14,7 @@ Signed-off-by: Imre Kaloz + static int parse_fixed_partitions(struct mtd_info *master, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +-@@ -33,6 +35,7 @@ static int parse_fixed_partitions(struct ++@@ -29,6 +31,7 @@ static int parse_fixed_partitions(struct + struct device_node *mtd_node; + struct device_node *ofpart_node; + const char *partname; +@@ -22,7 +22,7 @@ Signed-off-by: Imre Kaloz + struct device_node *pp; + int nr_parts, i, ret = 0; + bool dedicated = true; +-@@ -110,9 +113,13 @@ static int parse_fixed_partitions(struct ++@@ -106,9 +109,13 @@ static int parse_fixed_partitions(struct + parts[i].size = of_read_number(reg + a_cells, s_cells); + parts[i].of_node = pp; + +@@ -39,7 +39,7 @@ Signed-off-by: Imre Kaloz + parts[i].name = partname; + + if (of_get_property(pp, "read-only", &len)) +-@@ -219,6 +226,18 @@ static int __init ofpart_parser_init(voi ++@@ -215,6 +222,18 @@ static int __init ofpart_parser_init(voi + return 0; + } + +diff --git a/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch b/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch +index f9677a82f2e..d0e32e19df6 100644 +--- a/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch ++++ b/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch +@@ -1,6 +1,6 @@ + --- a/arch/arm/boot/dts/armada-388-clearfog.dts + +++ b/arch/arm/boot/dts/armada-388-clearfog.dts +-@@ -88,6 +88,18 @@ ++@@ -30,6 +30,18 @@ + }; + }; + +diff --git a/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch b/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch +index 9cc7a113f6c..029eb68e21d 100644 +--- a/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch ++++ b/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch +@@ -10,7 +10,7 @@ + #size-cells = <0>; + --- a/arch/arm/boot/dts/armada-388-clearfog.dts + +++ b/arch/arm/boot/dts/armada-388-clearfog.dts +-@@ -161,6 +161,7 @@ ++@@ -103,6 +103,7 @@ + status = "okay"; + + switch@4 { +@@ -20,7 +20,7 @@ + #size-cells = <0>; + --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts + +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +-@@ -413,6 +413,7 @@ ++@@ -366,6 +366,7 @@ + status = "okay"; + + switch@0 { +diff --git a/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch b/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch +index 935c8fe0935..ee8786c0fce 100644 +--- a/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch ++++ b/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch +@@ -1,6 +1,6 @@ + --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts + +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +-@@ -543,3 +543,7 @@ ++@@ -496,3 +496,7 @@ + }; + }; + }; +diff --git a/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch b/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch +index 4a5ea361449..cc34ec0af7f 100644 +--- a/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch ++++ b/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch +@@ -9,13 +9,12 @@ Signed-off-by: Felix Fietkau + --- + --- a/drivers/net/ethernet/marvell/mvneta.c + +++ b/drivers/net/ethernet/marvell/mvneta.c +-@@ -4272,6 +4272,15 @@ static int mvneta_ethtool_set_eee(struct ++@@ -4333,6 +4333,14 @@ static int mvneta_ethtool_set_eee(struct + return phylink_ethtool_set_eee(pp->phylink, eee); + } + + +static u16 mvneta_select_queue(struct net_device *dev, struct sk_buff *skb, +-+ struct net_device *sb_dev, +-+ select_queue_fallback_t fallback) +++ struct net_device *sb_dev) + +{ + + /* XXX: hardware queue scheduling is broken, + + * use only one queue until it is fixed */ +@@ -25,7 +24,7 @@ Signed-off-by: Felix Fietkau + static const struct net_device_ops mvneta_netdev_ops = { + .ndo_open = mvneta_open, + .ndo_stop = mvneta_stop, +-@@ -4282,6 +4291,7 @@ static const struct net_device_ops mvnet ++@@ -4343,6 +4351,7 @@ static const struct net_device_ops mvnet + .ndo_fix_features = mvneta_fix_features, + .ndo_get_stats64 = mvneta_get_stats64, + .ndo_do_ioctl = mvneta_ioctl, +diff --git a/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch b/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch +index 2bbb6471538..4058dc8ed58 100644 +--- a/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch ++++ b/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch +@@ -13,7 +13,7 @@ Signed-off-by: Russell King + + --- a/drivers/pci/controller/pci-mvebu.c + +++ b/drivers/pci/controller/pci-mvebu.c +-@@ -1112,6 +1112,7 @@ static int mvebu_pcie_powerup(struct mve ++@@ -928,6 +928,7 @@ static int mvebu_pcie_powerup(struct mve + + if (port->reset_gpio) { + u32 reset_udelay = PCI_PM_D3COLD_WAIT * 1000; +@@ -21,7 +21,7 @@ Signed-off-by: Russell King + + of_property_read_u32(port->dn, "reset-delay-us", + &reset_udelay); +-@@ -1119,7 +1120,13 @@ static int mvebu_pcie_powerup(struct mve ++@@ -935,7 +936,13 @@ static int mvebu_pcie_powerup(struct mve + udelay(100); + + gpiod_set_value_cansleep(port->reset_gpio, 0); +@@ -36,7 +36,7 @@ Signed-off-by: Russell King + } + + return 0; +-@@ -1283,15 +1290,16 @@ static int mvebu_pcie_probe(struct platf ++@@ -1099,15 +1106,16 @@ static int mvebu_pcie_probe(struct platf + if (!child) + continue; + +diff --git a/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch b/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch +deleted file mode 100644 +index d64bd8084ea..00000000000 +--- a/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch ++++ /dev/null +@@ -1,124 +0,0 @@ +-From 09a0122c74ec076e08512f1b00b7ccb8a450282f Mon Sep 17 00:00:00 2001 +-From: Russell King +-Date: Tue, 29 Nov 2016 10:15:43 +0000 +-Subject: ARM: dts: armada388-clearfog: document MPP usage +- +-Signed-off-by: Russell King +---- +- arch/arm/boot/dts/armada-388-clearfog-base.dts | 51 ++++++++++++++++++++++++++ +- arch/arm/boot/dts/armada-388-clearfog.dts | 50 +++++++++++++++++++++++++ +- 2 files changed, 101 insertions(+) +- +---- a/arch/arm/boot/dts/armada-388-clearfog-base.dts +-+++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts +-@@ -67,3 +67,54 @@ +- marvell,function = "gpio"; +- }; +- }; +-+ +-+/* +-+MPP +-+18: pu gpio pca9655 int +-+19: gpio phy reset +-+20: pu gpio sd0 detect +-+21: sd0:cmd +-+22: pd gpio mikro int +-+23: +-+ +-+24: ua1:rxd mikro rx +-+25: ua1:txd mikro tx +-+26: pu i2c1:sck +-+27: pu i2c1:sda +-+28: sd0:clk +-+29: pd gpio mikro rst +-+30: +-+31: +-+ +-+32: +-+33: +-+34: +-+35: +-+36: +-+37: sd0:d3 +-+38: sd0:d0 +-+39: sd0:d1 +-+ +-+40: sd0:d2 +-+41: +-+42: +-+43: spi1:cs2 mikro cs +-+44: gpio rear button sw3 +-+45: ref:clk_out0 phy#0 clock +-+46: ref:clk_out1 phy#1 clock +-+47: +-+ +-+48: gpio J18 spare gpio +-+49: gpio U10 I2C_IRQ(GNSS) +-+50: gpio board id? +-+51: +-+52: +-+53: +-+54: gpio mikro pwm +-+55: +-+ +-+56: pu spi1:mosi mikro mosi +-+57: pd spi1:sck mikro sck +-+58: spi1:miso mikro miso +-+59: +-+*/ +---- a/arch/arm/boot/dts/armada-388-clearfog.dts +-+++ b/arch/arm/boot/dts/armada-388-clearfog.dts +-@@ -249,3 +249,53 @@ +- */ +- pinctrl-0 = <&spi1_pins &clearfog_spi1_cs_pins &mikro_spi_pins>; +- }; +-+/* +-++#define A38x_CUSTOMER_BOARD_1_MPP16_23 0x00400011 +-+MPP18: gpio ? (pca9655 int?) +-+MPP19: gpio ? (clkreq?) +-+MPP20: gpio ? (sd0 detect) +-+MPP21: sd0:cmd x sd0 +-+MPP22: gpio x mikro int +-+MPP23: gpio x switch irq +-++#define A38x_CUSTOMER_BOARD_1_MPP24_31 0x22043333 +-+MPP24: ua1:rxd x mikro rx +-+MPP25: ua1:txd x mikro tx +-+MPP26: i2c1:sck x mikro sck +-+MPP27: i2c1:sda x mikro sda +-+MPP28: sd0:clk x sd0 +-+MPP29: gpio x mikro rst +-+MPP30: ge1:txd2 ? (config) +-+MPP31: ge1:txd3 ? (config) +-++#define A38x_CUSTOMER_BOARD_1_MPP32_39 0x44400002 +-+MPP32: ge1:txctl ? (unused) +-+MPP33: gpio ? (pic_com0) +-+MPP34: gpio x rear button (pic_com1) +-+MPP35: gpio ? (pic_com2) +-+MPP36: gpio ? (unused) +-+MPP37: sd0:d3 x sd0 +-+MPP38: sd0:d0 x sd0 +-+MPP39: sd0:d1 x sd0 +-++#define A38x_CUSTOMER_BOARD_1_MPP40_47 0x41144004 +-+MPP40: sd0:d2 x sd0 +-+MPP41: gpio x switch reset +-+MPP42: gpio ? sw1-1 +-+MPP43: spi1:cs2 x mikro cs +-+MPP44: sata3:prsnt ? (unused) +-+MPP45: ref:clk_out0 ? +-+MPP46: ref:clk_out1 x switch clk +-+MPP47: 4 ? (unused) +-++#define A38x_CUSTOMER_BOARD_1_MPP48_55 0x40333333 +-+MPP48: tdm:pclk +-+MPP49: tdm:fsync +-+MPP50: tdm:drx +-+MPP51: tdm:dtx +-+MPP52: tdm:int +-+MPP53: tdm:rst +-+MPP54: gpio ? (pwm) +-+MPP55: spi1:cs1 x slic +-++#define A38x_CUSTOMER_BOARD_1_MPP56_63 0x00004444 +-+MPP56: spi1:mosi x mikro mosi +-+MPP57: spi1:sck x mikro sck +-+MPP58: spi1:miso x mikro miso +-+MPP59: spi1:cs0 x w25q32 +-+*/ +diff --git a/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch b/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch +deleted file mode 100644 +index 880b0d92417..00000000000 +--- a/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch ++++ /dev/null +@@ -1,40 +0,0 @@ +-From eefe328439642101774f0f5c4ea0dc6ba1cfb687 Mon Sep 17 00:00:00 2001 +-From: Ding Tao +-Date: Fri, 26 Oct 2018 11:50:27 +0000 +-Subject: [PATCH] arm64: dts: marvell: armada37xx: Add emmc/sdio pinctrl +- definition +- +-Add emmc/sdio pinctrl definition for marvell armada37xx SoCs. +- +-Signed-off-by: Ding Tao +-Signed-off-by: Gregory CLEMENT +---- +- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 10 ++++++++++ +- 1 file changed, 10 insertions(+) +- +---- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +-+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +-@@ -221,6 +221,11 @@ +- groups = "uart2"; +- function = "uart"; +- }; +-+ +-+ mmc_pins: mmc-pins { +-+ groups = "emmc_nb"; +-+ function = "emmc"; +-+ }; +- }; +- +- nb_pm: syscon@14000 { +-@@ -253,6 +258,11 @@ +- function = "mii"; +- }; +- +-+ sdio_pins: sdio-pins { +-+ groups = "sdio_sb"; +-+ function = "sdio"; +-+ }; +-+ +- }; +- +- eth0: ethernet@30000 { +diff --git a/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch b/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch +deleted file mode 100644 +index 77af3d1219d..00000000000 +--- a/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch ++++ /dev/null +@@ -1,49 +0,0 @@ +-From 43ebc7c1b3ed8198b9acf3019eca16e722f7331c Mon Sep 17 00:00:00 2001 +-From: Ding Tao +-Date: Fri, 26 Oct 2018 11:50:28 +0000 +-Subject: [PATCH] arm64: dts: marvell: armada-37xx: Enable emmc on espressobin +- +-The ESPRESSObin board has a emmc interface available on U11: declare it +-and let the bootloader enable it if the emmc is present. +- +-[gregory.clement@bootlin.com: disable the emmc by default] +-Signed-off-by: Ding Tao +-Signed-off-by: Gregory CLEMENT +---- +- .../dts/marvell/armada-3720-espressobin.dts | 22 +++++++++++++++++++ +- 1 file changed, 22 insertions(+) +- +---- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +-+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +-@@ -60,9 +60,31 @@ +- cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>; +- marvell,pad-type = "sd"; +- vqmmc-supply = <&vcc_sd_reg1>; +-+ +-+ pinctrl-names = "default"; +-+ pinctrl-0 = <&sdio_pins>; +- status = "okay"; +- }; +- +-+/* U11 */ +-+&sdhci0 { +-+ non-removable; +-+ bus-width = <8>; +-+ mmc-ddr-1_8v; +-+ mmc-hs400-1_8v; +-+ marvell,xenon-emmc; +-+ marvell,xenon-tun-count = <9>; +-+ marvell,pad-type = "fixed-1-8v"; +-+ +-+ pinctrl-names = "default"; +-+ pinctrl-0 = <&mmc_pins>; +-+/* +-+ * This eMMC is not populated on all boards, so disable it by +-+ * default and let the bootloader enable it, if it is present +-+ */ +-+ status = "disabled"; +-+}; +-+ +- &spi0 { +- status = "okay"; +- +diff --git a/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch b/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch +deleted file mode 100644 +index 0f39b2a3c2c..00000000000 +--- a/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch ++++ /dev/null +@@ -1,58 +0,0 @@ +-From 3217cdfe8a3eae76fafbebbe407be5985a7fd4c2 Mon Sep 17 00:00:00 2001 +-From: Tomasz Maciej Nowak +-Date: Mon, 31 Dec 2018 14:18:50 +0100 +-Subject: [PATCH] arm64: dts: armada-3720-espressobin: correct spi node +- +-The manufacturer of this board, ships it with various SPI NOR chips and +-increments U-Boot bootloader version along the time. There is no way to +-tell which is placed on the board since no revision bump takes place. +-This creates two issues. +- +-The first, cosmetic. Since the SPI chip may differ, there's message on +-boot stating that kernel expected w25q32dw and found different one. To +-correct this, remove optional device-specific compatible string. Being +-here lets replace bogus "spi-flash" string with proper one. +- +-The second is linked to partitions layout, it changed after commit [1] +-in Marvells downstream U-Boot fork, shifting environment location to the +-end of boot device. Since the new boards can have U-Boot with this +-change it can lead to improper results writing or reading from these +-partitions. We can't tell if users will update bootloader to recent +-version, so let's drop current layout. +- +-1. https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/81e7251252aefe1a6b829ed05f3586320cb45372 +- +-Signed-off-by: Tomasz Maciej Nowak +---- +- .../dts/marvell/armada-3720-espressobin.dts | 18 +----------------- +- 1 file changed, 1 insertion(+), 17 deletions(-) +- +---- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +-+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +-@@ -90,25 +90,9 @@ +- +- flash@0 { +- reg = <0>; +-- compatible = "winbond,w25q32dw", "jedec,spi-flash"; +-+ compatible = "jedec,spi-nor"; +- spi-max-frequency = <104000000>; +- m25p,fast-read; +-- +-- partitions { +-- compatible = "fixed-partitions"; +-- #address-cells = <1>; +-- #size-cells = <1>; +-- +-- partition@0 { +-- label = "uboot"; +-- reg = <0 0x180000>; +-- }; +-- +-- partition@180000 { +-- label = "ubootenv"; +-- reg = <0x180000 0x10000>; +-- }; +-- }; +- }; +- }; +- +diff --git a/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch b/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch +index cea0d1db44f..1a608f2b6ac 100644 +--- a/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch ++++ b/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch +@@ -15,7 +15,7 @@ Signed-off-by: Tomasz Maciej Nowak + + --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts + +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +-@@ -132,7 +132,7 @@ ++@@ -137,7 +137,7 @@ + + dsa,member = <0 0>; + +diff --git a/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch b/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch +index 3fd561db3a6..e1318e825ad 100644 +--- a/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch ++++ b/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch +@@ -10,7 +10,7 @@ This reverts commit c8e144f8ab00e6c4a070a932ef9c57db09aa41cf. + + --- a/drivers/pci/controller/pci-aardvark.c + +++ b/drivers/pci/controller/pci-aardvark.c +-@@ -843,6 +843,7 @@ static int advk_pcie_probe(struct platfo ++@@ -999,6 +999,7 @@ static int advk_pcie_probe(struct platfo + struct device *dev = &pdev->dev; + struct advk_pcie *pcie; + struct resource *res; +@@ -18,7 +18,7 @@ This reverts commit c8e144f8ab00e6c4a070a932ef9c57db09aa41cf. + struct pci_host_bridge *bridge; + int ret, irq; + +-@@ -896,13 +897,22 @@ static int advk_pcie_probe(struct platfo ++@@ -1054,13 +1055,22 @@ static int advk_pcie_probe(struct platfo + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle; + +diff --git a/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch b/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch +index 204d6e2aec4..c6cfe3783c5 100644 +--- a/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch ++++ b/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch +@@ -45,7 +45,7 @@ Signed-off-by: Thomas Petazzoni + + --- a/drivers/pci/controller/pci-aardvark.c + +++ b/drivers/pci/controller/pci-aardvark.c +-@@ -29,9 +29,11 @@ ++@@ -33,9 +33,11 @@ + #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 + #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) + #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 +@@ -57,7 +57,7 @@ Signed-off-by: Thomas Petazzoni + #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 + #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) + #define PCIE_CORE_LINK_TRAINING BIT(5) +-@@ -253,7 +255,8 @@ static void advk_pcie_setup_hw(struct ad ++@@ -276,7 +278,8 @@ static void advk_pcie_setup_hw(struct ad + + /* Set PCIe Device Control and Status 1 PF0 register */ + reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | +@@ -67,7 +67,7 @@ Signed-off-by: Thomas Petazzoni + PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | + (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << + PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); +-@@ -838,6 +841,58 @@ out_release_res: ++@@ -994,6 +997,58 @@ out_release_res: + return err; + } + +@@ -126,7 +126,7 @@ Signed-off-by: Thomas Petazzoni + static int advk_pcie_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +-@@ -912,6 +967,9 @@ static int advk_pcie_probe(struct platfo ++@@ -1070,6 +1125,9 @@ static int advk_pcie_probe(struct platfo + list_for_each_entry(child, &bus->children, node) + pcie_bus_configure_settings(child); + +diff --git a/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch b/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch +index b6fcec81f8f..f865965ed47 100644 +--- a/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch ++++ b/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch +@@ -43,7 +43,7 @@ Signed-off-by: Thomas Petazzoni + + --- a/drivers/pci/controller/pci-aardvark.c + +++ b/drivers/pci/controller/pci-aardvark.c +-@@ -324,8 +324,7 @@ static void advk_pcie_setup_hw(struct ad ++@@ -347,8 +347,7 @@ static void advk_pcie_setup_hw(struct ad + + advk_pcie_wait_for_link(pcie); + +diff --git a/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch b/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch +index 0ac34761473..739292c1bfd 100644 +--- a/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch ++++ b/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch +@@ -14,7 +14,7 @@ Signed-off-by: Tomasz Maciej Nowak + + --- a/drivers/pci/controller/pci-aardvark.c + +++ b/drivers/pci/controller/pci-aardvark.c +-@@ -233,6 +233,8 @@ static int advk_pcie_wait_for_link(struc ++@@ -256,6 +256,8 @@ static void advk_pcie_wait_for_retrain(s + + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { +@@ -23,7 +23,7 @@ Signed-off-by: Tomasz Maciej Nowak + u32 reg; + + /* Set to Direct mode */ +-@@ -267,10 +269,15 @@ static void advk_pcie_setup_hw(struct ad ++@@ -290,10 +292,15 @@ static void advk_pcie_setup_hw(struct ad + PCIE_CORE_CTRL2_TD_ENABLE; + advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); + +diff --git a/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch b/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch +index 88080d64caa..d3a8f58f18f 100644 +--- a/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch ++++ b/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch +@@ -62,10 +62,10 @@ Signed-off-by: Tomasz Maciej Nowak + + --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts + +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +-@@ -46,6 +46,8 @@ +- /* J9 */ +- &pcie0 { +- status = "okay"; ++@@ -49,6 +49,8 @@ ++ phys = <&comphy1 0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; + + + + max-link-speed = <1>; + }; +diff --git a/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch b/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch +deleted file mode 100644 +index a5553a3e96c..00000000000 +--- a/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch ++++ /dev/null +@@ -1,104 +0,0 @@ +-From da58a931f248f423f917c3a0b3c94303aa30a738 Mon Sep 17 00:00:00 2001 +-From: Maxime Chevallier +-Date: Tue, 25 Sep 2018 15:59:39 +0200 +-Subject: [PATCH] net: mvneta: Add support for 2500Mbps SGMII +- +-The mvneta controller can handle speeds up to 2500Mbps on the SGMII +-interface. This relies on serdes configuration, the lane must be +-configured at 3.125Gbps and we can't use in-band autoneg at that speed. +- +-The main issue when supporting that speed on this particular controller +-is that the link partner can send ethernet frames with a shortened +-preamble, which if not explicitly enabled in the controller will cause +-unexpected behaviours. +- +-This was tested on Armada 385, with the comphy configuration done in +-bootloader. +- +-Signed-off-by: Maxime Chevallier +-Signed-off-by: David S. Miller +---- +- drivers/net/ethernet/marvell/mvneta.c | 27 +++++++++++++++++++++++---- +- 1 file changed, 23 insertions(+), 4 deletions(-) +- +---- a/drivers/net/ethernet/marvell/mvneta.c +-+++ b/drivers/net/ethernet/marvell/mvneta.c +-@@ -221,6 +221,8 @@ +- #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11) +- #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12) +- #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13) +-+#define MVNETA_GMAC_CTRL_4 0x2c90 +-+#define MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE BIT(1) +- #define MVNETA_MIB_COUNTERS_BASE 0x3000 +- #define MVNETA_MIB_LATE_COLLISION 0x7c +- #define MVNETA_DA_FILT_SPEC_MCAST 0x3400 +-@@ -3359,6 +3361,7 @@ static void mvneta_validate(struct net_d +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_QSGMII && +- state->interface != PHY_INTERFACE_MODE_SGMII && +-+ state->interface != PHY_INTERFACE_MODE_2500BASEX && +- !phy_interface_mode_is_8023z(state->interface) && +- !phy_interface_mode_is_rgmii(state->interface)) { +- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); +-@@ -3371,9 +3374,15 @@ static void mvneta_validate(struct net_d +- +- /* Asymmetric pause is unsupported */ +- phylink_set(mask, Pause); +-- /* Half-duplex at speeds higher than 100Mbit is unsupported */ +-- phylink_set(mask, 1000baseT_Full); +-- phylink_set(mask, 1000baseX_Full); +-+ +-+ /* We cannot use 1Gbps when using the 2.5G interface. */ +-+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { +-+ phylink_set(mask, 2500baseT_Full); +-+ phylink_set(mask, 2500baseX_Full); +-+ } else { +-+ phylink_set(mask, 1000baseT_Full); +-+ phylink_set(mask, 1000baseX_Full); +-+ } +- +- if (!phy_interface_mode_is_8023z(state->interface)) { +- /* 10M and 100M are only supported in non-802.3z mode */ +-@@ -3434,12 +3443,14 @@ static void mvneta_mac_config(struct net +- struct mvneta_port *pp = netdev_priv(ndev); +- u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0); +- u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2); +-+ u32 new_ctrl4, gmac_ctrl4 = mvreg_read(pp, MVNETA_GMAC_CTRL_4); +- u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); +- u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); +- +- new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X; +- new_ctrl2 = gmac_ctrl2 & ~(MVNETA_GMAC2_INBAND_AN_ENABLE | +- MVNETA_GMAC2_PORT_RESET); +-+ new_ctrl4 = gmac_ctrl4 & ~(MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE); +- new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE; +- new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE | +- MVNETA_GMAC_INBAND_RESTART_AN | +-@@ -3472,7 +3483,7 @@ static void mvneta_mac_config(struct net +- if (state->duplex) +- new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; +- +-- if (state->speed == SPEED_1000) +-+ if (state->speed == SPEED_1000 || state->speed == SPEED_2500) +- new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED; +- else if (state->speed == SPEED_100) +- new_an |= MVNETA_GMAC_CONFIG_MII_SPEED; +-@@ -3511,10 +3522,18 @@ static void mvneta_mac_config(struct net +- MVNETA_GMAC_FORCE_LINK_DOWN); +- } +- +-+ /* When at 2.5G, the link partner can send frames with shortened +-+ * preambles. +-+ */ +-+ if (state->speed == SPEED_2500) +-+ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; +-+ +- if (new_ctrl0 != gmac_ctrl0) +- mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); +- if (new_ctrl2 != gmac_ctrl2) +- mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2); +-+ if (new_ctrl4 != gmac_ctrl4) +-+ mvreg_write(pp, MVNETA_GMAC_CTRL_4, new_ctrl4); +- if (new_clk != gmac_clk) +- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk); +- if (new_an != gmac_an) +diff --git a/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch b/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch +deleted file mode 100644 +index b6e16c54a45..00000000000 +--- a/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch ++++ /dev/null +@@ -1,33 +0,0 @@ +-From fbd1d5245372e48b494120a30fe0b34b304576c4 Mon Sep 17 00:00:00 2001 +-From: Alexandre Belloni +-Date: Fri, 9 Nov 2018 17:37:20 +0100 +-Subject: [PATCH] net: mvneta: correct typo +- +-The reserved variable should be named reserved1. +- +-Signed-off-by: Alexandre Belloni +-Signed-off-by: David S. Miller +---- +- drivers/net/ethernet/marvell/mvneta.c | 4 ++-- +- 1 file changed, 2 insertions(+), 2 deletions(-) +- +---- a/drivers/net/ethernet/marvell/mvneta.c +-+++ b/drivers/net/ethernet/marvell/mvneta.c +-@@ -495,7 +495,7 @@ struct mvneta_port { +- #if defined(__LITTLE_ENDIAN) +- struct mvneta_tx_desc { +- u32 command; /* Options used by HW for packet transmitting.*/ +-- u16 reserverd1; /* csum_l4 (for future use) */ +-+ u16 reserved1; /* csum_l4 (for future use) */ +- u16 data_size; /* Data size of transmitted packet in bytes */ +- u32 buf_phys_addr; /* Physical addr of transmitted buffer */ +- u32 reserved2; /* hw_cmd - (for future use, PMT) */ +-@@ -520,7 +520,7 @@ struct mvneta_rx_desc { +- #else +- struct mvneta_tx_desc { +- u16 data_size; /* Data size of transmitted packet in bytes */ +-- u16 reserverd1; /* csum_l4 (for future use) */ +-+ u16 reserved1; /* csum_l4 (for future use) */ +- u32 command; /* Options used by HW for packet transmitting.*/ +- u32 reserved2; /* hw_cmd - (for future use, PMT) */ +- u32 buf_phys_addr; /* Physical addr of transmitted buffer */ +diff --git a/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch b/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch +deleted file mode 100644 +index 01b101283cd..00000000000 +--- a/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch ++++ /dev/null +@@ -1,55 +0,0 @@ +-From 83e65df6dfece9eb588735459428f221eb930c0c Mon Sep 17 00:00:00 2001 +-From: Maxime Chevallier +-Date: Fri, 9 Nov 2018 09:17:33 +0100 +-Subject: [PATCH] net: mvneta: Don't advertise 2.5G modes +- +-Using 2.5G speed relies on the SerDes lanes being configured +-accordingly. The lanes have to be reconfigured to switch between +-1G and 2.5G, and for now only the bootloader does this configuration. +- +-In the case we add a Comphy driver to handle switching the lanes +-dynamically, it's better for now to stick with supporting only 1G and +-add advertisement for 2.5G once we really are capable of handling both +-speeds without problem. +- +-Since the interface mode is initialy taken from the DT, we want to make +-sure that adding comphy support won't break boards that don't update +-their dtb. +- +-Fixes: da58a931f248 ("net: mvneta: Add support for 2500Mbps SGMII") +-Reported-by: Andrew Lunn +-Reported-by: Russell King +-Signed-off-by: Maxime Chevallier +-Signed-off-by: David S. Miller +---- +- drivers/net/ethernet/marvell/mvneta.c | 12 +++--------- +- 1 file changed, 3 insertions(+), 9 deletions(-) +- +---- a/drivers/net/ethernet/marvell/mvneta.c +-+++ b/drivers/net/ethernet/marvell/mvneta.c +-@@ -3361,7 +3361,6 @@ static void mvneta_validate(struct net_d +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_QSGMII && +- state->interface != PHY_INTERFACE_MODE_SGMII && +-- state->interface != PHY_INTERFACE_MODE_2500BASEX && +- !phy_interface_mode_is_8023z(state->interface) && +- !phy_interface_mode_is_rgmii(state->interface)) { +- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); +-@@ -3375,14 +3374,9 @@ static void mvneta_validate(struct net_d +- /* Asymmetric pause is unsupported */ +- phylink_set(mask, Pause); +- +-- /* We cannot use 1Gbps when using the 2.5G interface. */ +-- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { +-- phylink_set(mask, 2500baseT_Full); +-- phylink_set(mask, 2500baseX_Full); +-- } else { +-- phylink_set(mask, 1000baseT_Full); +-- phylink_set(mask, 1000baseX_Full); +-- } +-+ /* Half-duplex at speeds higher than 100Mbit is unsupported */ +-+ phylink_set(mask, 1000baseT_Full); +-+ phylink_set(mask, 1000baseX_Full); +- +- if (!phy_interface_mode_is_8023z(state->interface)) { +- /* 10M and 100M are only supported in non-802.3z mode */ +diff --git a/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch b/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch +deleted file mode 100644 +index fd774e08398..00000000000 +--- a/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch ++++ /dev/null +@@ -1,30 +0,0 @@ +-From e4a3e9ff5ba9f6b67595ec2768ed4be2054c2aa5 Mon Sep 17 00:00:00 2001 +-From: YueHaibing +-Date: Thu, 22 Nov 2018 14:42:00 +0800 +-Subject: [PATCH] net: mvneta: remove redundant check for +- eee->tx_lpi_timer < 0 +- +-fixes the smatch warning: +- +-drivers/net/ethernet/marvell/mvneta.c:4252 mvneta_ethtool_set_eee() warn: +- unsigned 'eee->tx_lpi_timer' is never less than zero. +- +-Signed-off-by: YueHaibing +-Acked-by: Thomas Petazzoni +-Signed-off-by: David S. Miller +---- +- drivers/net/ethernet/marvell/mvneta.c | 3 +-- +- 1 file changed, 1 insertion(+), 2 deletions(-) +- +---- a/drivers/net/ethernet/marvell/mvneta.c +-+++ b/drivers/net/ethernet/marvell/mvneta.c +-@@ -4268,8 +4268,7 @@ static int mvneta_ethtool_set_eee(struct +- +- /* The Armada 37x documents do not give limits for this other than +- * it being an 8-bit register. */ +-- if (eee->tx_lpi_enabled && +-- (eee->tx_lpi_timer < 0 || eee->tx_lpi_timer > 255)) +-+ if (eee->tx_lpi_enabled && eee->tx_lpi_timer > 255) +- return -EINVAL; +- +- lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0); +diff --git a/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch b/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch +deleted file mode 100644 +index 272beb6950f..00000000000 +--- a/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch ++++ /dev/null +@@ -1,159 +0,0 @@ +-From a10c1c8191e04c21769656c2ca8e1c69a6218954 Mon Sep 17 00:00:00 2001 +-From: Russell King +-Date: Thu, 7 Feb 2019 16:19:26 +0000 +-Subject: [PATCH] net: marvell: neta: add comphy support +- +-Add support for the common phy binding, so that we can reconfigure the +-comphy according to the desired ethernet speed. This will allow us to +-support 1000base-X and 2500base-X SFPs dynamically on SolidRun Clearfog. +- +-Signed-off-by: Russell King +-Signed-off-by: David S. Miller +---- +- drivers/net/ethernet/marvell/mvneta.c | 45 +++++++++++++++++++++++++++++++---- +- 1 file changed, 41 insertions(+), 4 deletions(-) +- +---- a/drivers/net/ethernet/marvell/mvneta.c +-+++ b/drivers/net/ethernet/marvell/mvneta.c +-@@ -27,6 +27,7 @@ +- #include +- #include +- #include +-+#include +- #include +- #include +- #include +-@@ -438,6 +439,7 @@ struct mvneta_port { +- struct device_node *dn; +- unsigned int tx_csum_limit; +- struct phylink *phylink; +-+ struct phy *comphy; +- +- struct mvneta_bm *bm_priv; +- struct mvneta_bm_pool *pool_long; +-@@ -3168,6 +3170,8 @@ static void mvneta_start_dev(struct mvne +- { +- int cpu; +- +-+ WARN_ON(phy_power_on(pp->comphy)); +-+ +- mvneta_max_rx_size_set(pp, pp->pkt_size); +- mvneta_txq_max_tx_size_set(pp, pp->pkt_size); +- +-@@ -3230,6 +3234,8 @@ static void mvneta_stop_dev(struct mvnet +- +- mvneta_tx_reset(pp); +- mvneta_rx_reset(pp); +-+ +-+ WARN_ON(phy_power_off(pp->comphy)); +- } +- +- static void mvneta_percpu_enable(void *arg) +-@@ -3355,6 +3361,7 @@ static int mvneta_set_mac_addr(struct ne +- static void mvneta_validate(struct net_device *ndev, unsigned long *supported, +- struct phylink_link_state *state) +- { +-+ struct mvneta_port *pp = netdev_priv(ndev); +- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; +- +- /* We only support QSGMII, SGMII, 802.3z and RGMII modes */ +-@@ -3375,8 +3382,13 @@ static void mvneta_validate(struct net_d +- phylink_set(mask, Pause); +- +- /* Half-duplex at speeds higher than 100Mbit is unsupported */ +-- phylink_set(mask, 1000baseT_Full); +-- phylink_set(mask, 1000baseX_Full); +-+ if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) { +-+ phylink_set(mask, 1000baseT_Full); +-+ phylink_set(mask, 1000baseX_Full); +-+ } +-+ if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { +-+ phylink_set(mask, 2500baseX_Full); +-+ } +- +- if (!phy_interface_mode_is_8023z(state->interface)) { +- /* 10M and 100M are only supported in non-802.3z mode */ +-@@ -3390,6 +3402,11 @@ static void mvneta_validate(struct net_d +- __ETHTOOL_LINK_MODE_MASK_NBITS); +- bitmap_and(state->advertising, state->advertising, mask, +- __ETHTOOL_LINK_MODE_MASK_NBITS); +-+ +-+ /* We can only operate at 2500BaseX or 1000BaseX. If requested +-+ * to advertise both, only report advertising at 2500BaseX. +-+ */ +-+ phylink_helper_basex_speed(state); +- } +- +- static int mvneta_mac_link_state(struct net_device *ndev, +-@@ -3401,7 +3418,9 @@ static int mvneta_mac_link_state(struct +- gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS); +- +- if (gmac_stat & MVNETA_GMAC_SPEED_1000) +-- state->speed = SPEED_1000; +-+ state->speed = +-+ state->interface == PHY_INTERFACE_MODE_2500BASEX ? +-+ SPEED_2500 : SPEED_1000; +- else if (gmac_stat & MVNETA_GMAC_SPEED_100) +- state->speed = SPEED_100; +- else +-@@ -3516,12 +3535,20 @@ static void mvneta_mac_config(struct net +- MVNETA_GMAC_FORCE_LINK_DOWN); +- } +- +-+ +- /* When at 2.5G, the link partner can send frames with shortened +- * preambles. +- */ +- if (state->speed == SPEED_2500) +- new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; +- +-+ if (pp->comphy && +-+ (state->interface == PHY_INTERFACE_MODE_SGMII || +-+ state->interface == PHY_INTERFACE_MODE_1000BASEX || +-+ state->interface == PHY_INTERFACE_MODE_2500BASEX)) +-+ WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, +-+ state->interface)); +-+ +- if (new_ctrl0 != gmac_ctrl0) +- mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); +- if (new_ctrl2 != gmac_ctrl2) +-@@ -4434,7 +4461,7 @@ static int mvneta_port_power_up(struct m +- if (phy_mode == PHY_INTERFACE_MODE_QSGMII) +- mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO); +- else if (phy_mode == PHY_INTERFACE_MODE_SGMII || +-- phy_mode == PHY_INTERFACE_MODE_1000BASEX) +-+ phy_interface_mode_is_8023z(phy_mode)) +- mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); +- else if (!phy_interface_mode_is_rgmii(phy_mode)) +- return -EINVAL; +-@@ -4451,6 +4478,7 @@ static int mvneta_probe(struct platform_ +- struct mvneta_port *pp; +- struct net_device *dev; +- struct phylink *phylink; +-+ struct phy *comphy; +- const char *dt_mac_addr; +- char hw_mac_addr[ETH_ALEN]; +- const char *mac_from; +-@@ -4476,6 +4504,14 @@ static int mvneta_probe(struct platform_ +- goto err_free_irq; +- } +- +-+ comphy = devm_of_phy_get(&pdev->dev, dn, NULL); +-+ if (comphy == ERR_PTR(-EPROBE_DEFER)) { +-+ err = -EPROBE_DEFER; +-+ goto err_free_irq; +-+ } else if (IS_ERR(comphy)) { +-+ comphy = NULL; +-+ } +-+ +- phylink = phylink_create(dev, pdev->dev.fwnode, phy_mode, +- &mvneta_phylink_ops); +- if (IS_ERR(phylink)) { +-@@ -4492,6 +4528,7 @@ static int mvneta_probe(struct platform_ +- pp = netdev_priv(dev); +- spin_lock_init(&pp->lock); +- pp->phylink = phylink; +-+ pp->comphy = comphy; +- pp->phy_interface = phy_mode; +- pp->dn = dn; +- +diff --git a/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch b/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch +deleted file mode 100644 +index bac9a55cf0d..00000000000 +--- a/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch ++++ /dev/null +@@ -1,78 +0,0 @@ +-From 031b922bfd60c771588911112f8632783de08e5c Mon Sep 17 00:00:00 2001 +-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= +-Date: Mon, 25 Feb 2019 17:43:03 +0100 +-Subject: [PATCH] net: marvell: neta: disable comphy when setting mode +-MIME-Version: 1.0 +-Content-Type: text/plain; charset=UTF-8 +-Content-Transfer-Encoding: 8bit +- +-The comphy driver for Armada 3700 by Miquèl Raynal (which is currently +-in linux-next) does not actually set comphy mode when phy_set_mode_ext +-is called. The mode is set at next call of phy_power_on. +- +-Update the driver to semantics similar to mvpp2: helper +-mvneta_comphy_init sets comphy mode and powers it on. +-When mode is to be changed in mvneta_mac_config, first power the comphy +-off, then call mvneta_comphy_init (which sets the mode to new one). +- +-Only do this when new mode is different from old mode. +- +-This should also work for Armada 38x, since in that comphy driver +-methods power_on and power_off are unimplemented. +- +-Signed-off-by: Marek Behún +-Signed-off-by: David S. Miller +---- +- drivers/net/ethernet/marvell/mvneta.c | 28 +++++++++++++++++++++++----- +- 1 file changed, 23 insertions(+), 5 deletions(-) +- +---- a/drivers/net/ethernet/marvell/mvneta.c +-+++ b/drivers/net/ethernet/marvell/mvneta.c +-@@ -3166,11 +3166,26 @@ static int mvneta_setup_txqs(struct mvne +- return 0; +- } +- +-+static int mvneta_comphy_init(struct mvneta_port *pp) +-+{ +-+ int ret; +-+ +-+ if (!pp->comphy) +-+ return 0; +-+ +-+ ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, +-+ pp->phy_interface); +-+ if (ret) +-+ return ret; +-+ +-+ return phy_power_on(pp->comphy); +-+} +-+ +- static void mvneta_start_dev(struct mvneta_port *pp) +- { +- int cpu; +- +-- WARN_ON(phy_power_on(pp->comphy)); +-+ WARN_ON(mvneta_comphy_init(pp)); +- +- mvneta_max_rx_size_set(pp, pp->pkt_size); +- mvneta_txq_max_tx_size_set(pp, pp->pkt_size); +-@@ -3542,12 +3557,15 @@ static void mvneta_mac_config(struct net +- if (state->speed == SPEED_2500) +- new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; +- +-- if (pp->comphy && +-+ if (pp->comphy && pp->phy_interface != state->interface && +- (state->interface == PHY_INTERFACE_MODE_SGMII || +- state->interface == PHY_INTERFACE_MODE_1000BASEX || +-- state->interface == PHY_INTERFACE_MODE_2500BASEX)) +-- WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, +-- state->interface)); +-+ state->interface == PHY_INTERFACE_MODE_2500BASEX)) { +-+ pp->phy_interface = state->interface; +-+ +-+ WARN_ON(phy_power_off(pp->comphy)); +-+ WARN_ON(mvneta_comphy_init(pp)); +-+ } +- +- if (new_ctrl0 != gmac_ctrl0) +- mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); +diff --git a/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch b/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch +deleted file mode 100644 +index 9186ceb0da4..00000000000 +--- a/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch ++++ /dev/null +@@ -1,34 +0,0 @@ +-From eda3d1b0228484fb52b7244a68fd4cc8a985ed10 Mon Sep 17 00:00:00 2001 +-From: Maxime Chevallier +-Date: Wed, 27 Mar 2019 17:31:06 +0100 +-Subject: [PATCH] net: mvneta: Add 2500BaseT support +- +-Some PHYs will use the 2500BaseX PHY_INTERFACE_MODE when being linked +-with a partner using 2.5GBaseT. +- +-Since we can't autonegotiate this speed between the MAC and the PHY, we +-need to have the proper comphy support enabled, to make sure we can +-safely advertise 2.5G and 1G in BaseT and be able to switch between both +-corresponding PHY interface modes. This is now possible since comphy +-support was added to this driver. +- +-This commit adds the 2500BaseT mode to the list of supported modes when +-using 2500BaseX, and was tested on a setup with an Armada385 and a +-88E2010 PHY, both with and without the comphy node in the DT. +- +-Signed-off-by: Maxime Chevallier +-Signed-off-by: David S. Miller +---- +- drivers/net/ethernet/marvell/mvneta.c | 1 + +- 1 file changed, 1 insertion(+) +- +---- a/drivers/net/ethernet/marvell/mvneta.c +-+++ b/drivers/net/ethernet/marvell/mvneta.c +-@@ -3402,6 +3402,7 @@ static void mvneta_validate(struct net_d +- phylink_set(mask, 1000baseX_Full); +- } +- if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { +-+ phylink_set(mask, 2500baseT_Full); +- phylink_set(mask, 2500baseX_Full); +- } +- +diff --git a/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch b/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch +deleted file mode 100644 +index b759b9fb254..00000000000 +--- a/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch ++++ /dev/null +@@ -1,28 +0,0 @@ +-From c2a90025ad09d830c8d8ae69f485eac6aaaa2472 Mon Sep 17 00:00:00 2001 +-From: Quentin Schulz +-Date: Thu, 4 Oct 2018 14:22:03 +0200 +-Subject: [PATCH] phy: add QSGMII and PCIE modes +- +-Prepare for upcoming phys that'll handle QSGMII or PCIe. +- +-Reviewed-by: Florian Fainelli +-Signed-off-by: Quentin Schulz +-Signed-off-by: David S. Miller +---- +- include/linux/phy/phy.h | 2 ++ +- 1 file changed, 2 insertions(+) +- +---- a/include/linux/phy/phy.h +-+++ b/include/linux/phy/phy.h +-@@ -37,9 +37,11 @@ enum phy_mode { +- PHY_MODE_USB_OTG, +- PHY_MODE_SGMII, +- PHY_MODE_2500SGMII, +-+ PHY_MODE_QSGMII, +- PHY_MODE_10GKR, +- PHY_MODE_UFS_HS_A, +- PHY_MODE_UFS_HS_B, +-+ PHY_MODE_PCIE, +- }; +- +- /** +diff --git a/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch b/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch +deleted file mode 100644 +index 68fecadce85..00000000000 +--- a/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch ++++ /dev/null +@@ -1,24 +0,0 @@ +-From 2af8caeee47846a84bc96abc3a72f7c991153040 Mon Sep 17 00:00:00 2001 +-From: Grygorii Strashko +-Date: Mon, 19 Nov 2018 19:24:21 -0600 +-Subject: [PATCH] phy: core: add PHY_MODE_ETHERNET +- +-Add new PHY's mode to be used by Ethernet PHY interface drivers or +-multipurpose PHYs like serdes. It will be reused in further changes. +- +-Signed-off-by: Grygorii Strashko +-Signed-off-by: Kishon Vijay Abraham I +---- +- include/linux/phy/phy.h | 1 + +- 1 file changed, 1 insertion(+) +- +---- a/include/linux/phy/phy.h +-+++ b/include/linux/phy/phy.h +-@@ -42,6 +42,7 @@ enum phy_mode { +- PHY_MODE_UFS_HS_A, +- PHY_MODE_UFS_HS_B, +- PHY_MODE_PCIE, +-+ PHY_MODE_ETHERNET, +- }; +- +- /** +diff --git a/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch b/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch +deleted file mode 100644 +index 83908af19e6..00000000000 +--- a/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch ++++ /dev/null +@@ -1,45 +0,0 @@ +-From e1706720408e72fb883f6b151c2b3b23d8e7e5b2 Mon Sep 17 00:00:00 2001 +-From: John Hubbard +-Date: Sat, 12 Jan 2019 17:29:09 -0800 +-Subject: [PATCH] phy: fix build breakage: add PHY_MODE_SATA +- +-Commit 49e54187ae0b ("ata: libahci_platform: comply to PHY framework") uses +-the PHY_MODE_SATA, but that enum had not yet been added. This caused a +-build failure for me, with today's linux.git. +- +-Also, there is a potentially conflicting (mis-named) PHY_MODE_SATA, hiding +-in the Marvell Berlin SATA PHY driver. +- +-Fix the build by: +- +- 1) Renaming Marvell's defined value to a more scoped name, +- in order to avoid any potential conflicts: PHY_BERLIN_MODE_SATA. +- +- 2) Adding the missing enum, which was going to be added anyway as part +- of [1]. +- +-[1] https://lkml.kernel.org/r/20190108163124.6409-3-miquel.raynal@bootlin.com +- +-Fixes: 49e54187ae0b ("ata: libahci_platform: comply to PHY framework") +- +-Signed-off-by: John Hubbard +-Acked-by: Jens Axboe +-Acked-by: Olof Johansson +-Cc: Grzegorz Jaszczyk +-Cc: Miquel Raynal +-Cc: Hans de Goede +-Signed-off-by: Linus Torvalds +---- +- include/linux/phy/phy.h | 1 + +- 1 file changed, 1 insertion(+) +- +---- a/include/linux/phy/phy.h +-+++ b/include/linux/phy/phy.h +-@@ -43,6 +43,7 @@ enum phy_mode { +- PHY_MODE_UFS_HS_B, +- PHY_MODE_PCIE, +- PHY_MODE_ETHERNET, +-+ PHY_MODE_SATA +- }; +- +- /** +diff --git a/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch b/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch +deleted file mode 100644 +index e02f203912d..00000000000 +--- a/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch ++++ /dev/null +@@ -1,134 +0,0 @@ +-From 79a5a18aa9d1062205cdcfa183d4cd5241d1b8da Mon Sep 17 00:00:00 2001 +-From: Grygorii Strashko +-Date: Mon, 19 Nov 2018 19:24:20 -0600 +-Subject: [PATCH] phy: core: rework phy_set_mode to accept phy mode and submode +- +-Currently the attempt to add support for Ethernet interface mode PHY +-(MII/GMII/RGMII) will lead to the necessity of extending enum phy_mode and +-duplicate there values from phy_interface_t enum (or introduce more PHY +-callbacks) [1]. Both approaches are ineffective and would lead to fast +-bloating of enum phy_mode or struct phy_ops in the process of adding more +-PHYs for different subsystems which will make them unmaintainable. +- +-As discussed in [1] the solution could be to introduce dual level PHYs mode +-configuration - PHY mode and PHY submode. The PHY mode will define generic +-PHY type (subsystem - PCIE/ETHERNET/USB_) while the PHY submode - subsystem +-specific interface mode. The last is usually already defined in +-corresponding subsystem headers (phy_interface_t for Ethernet, enum +-usb_device_speed for USB). +- +-This patch is cumulative change which refactors PHY framework code to +-support dual level PHYs mode configuration - PHY mode and PHY submode. It +-extends .set_mode() callback to support additional parameter "int submode" +-and converts all corresponding PHY drivers to support new .set_mode() +-callback declaration. +-The new extended PHY API +- int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) +-is introduced to support dual level PHYs mode configuration and existing +-phy_set_mode() API is converted to macros, so PHY framework consumers do +-not need to be changed (~21 matches). +- +-[1] http://lkml.kernel.org/r/d63588f6-9ab0-848a-5ad4-8073143bd95d@ti.com +-Signed-off-by: Grygorii Strashko +-Signed-off-by: Kishon Vijay Abraham I +---- +- drivers/phy/allwinner/phy-sun4i-usb.c | 3 ++- +- drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 +++-- +- drivers/phy/amlogic/phy-meson-gxl-usb3.c | 5 +++-- +- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 3 ++- +- drivers/phy/mediatek/phy-mtk-tphy.c | 2 +- +- drivers/phy/mediatek/phy-mtk-xsphy.c | 2 +- +- drivers/phy/mscc/phy-ocelot-serdes.c | 2 +- +- drivers/phy/phy-core.c | 6 +++--- +- drivers/phy/qualcomm/phy-qcom-qmp.c | 3 ++- +- drivers/phy/qualcomm/phy-qcom-qusb2.c | 3 ++- +- drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 3 ++- +- drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 3 ++- +- drivers/phy/qualcomm/phy-qcom-usb-hs.c | 3 ++- +- drivers/phy/ti/phy-da8xx-usb.c | 3 ++- +- drivers/phy/ti/phy-tusb1210.c | 2 +- +- include/linux/phy/phy.h | 13 ++++++++++--- +- 16 files changed, 39 insertions(+), 22 deletions(-) +- +---- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +-+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +-@@ -512,7 +512,8 @@ static int mvebu_comphy_power_on(struct +- return ret; +- } +- +--static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode) +-+static int mvebu_comphy_set_mode(struct phy *phy, +-+ enum phy_mode mode, int submode) +- { +- struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); +- +---- a/drivers/phy/phy-core.c +-+++ b/drivers/phy/phy-core.c +-@@ -360,7 +360,7 @@ int phy_power_off(struct phy *phy) +- } +- EXPORT_SYMBOL_GPL(phy_power_off); +- +--int phy_set_mode(struct phy *phy, enum phy_mode mode) +-+int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) +- { +- int ret; +- +-@@ -368,14 +368,14 @@ int phy_set_mode(struct phy *phy, enum p +- return 0; +- +- mutex_lock(&phy->mutex); +-- ret = phy->ops->set_mode(phy, mode); +-+ ret = phy->ops->set_mode(phy, mode, submode); +- if (!ret) +- phy->attrs.mode = mode; +- mutex_unlock(&phy->mutex); +- +- return ret; +- } +--EXPORT_SYMBOL_GPL(phy_set_mode); +-+EXPORT_SYMBOL_GPL(phy_set_mode_ext); +- +- int phy_reset(struct phy *phy) +- { +---- a/include/linux/phy/phy.h +-+++ b/include/linux/phy/phy.h +-@@ -62,7 +62,7 @@ struct phy_ops { +- int (*exit)(struct phy *phy); +- int (*power_on)(struct phy *phy); +- int (*power_off)(struct phy *phy); +-- int (*set_mode)(struct phy *phy, enum phy_mode mode); +-+ int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode); +- int (*reset)(struct phy *phy); +- int (*calibrate)(struct phy *phy); +- struct module *owner; +-@@ -166,7 +166,10 @@ int phy_init(struct phy *phy); +- int phy_exit(struct phy *phy); +- int phy_power_on(struct phy *phy); +- int phy_power_off(struct phy *phy); +--int phy_set_mode(struct phy *phy, enum phy_mode mode); +-+int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); +-+#define phy_set_mode(phy, mode) \ +-+ phy_set_mode_ext(phy, mode, 0) +-+ +- static inline enum phy_mode phy_get_mode(struct phy *phy) +- { +- return phy->attrs.mode; +-@@ -280,13 +283,17 @@ static inline int phy_power_off(struct p +- return -ENOSYS; +- } +- +--static inline int phy_set_mode(struct phy *phy, enum phy_mode mode) +-+static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, +-+ int submode) +- { +- if (!phy) +- return 0; +- return -ENOSYS; +- } +- +-+#define phy_set_mode(phy, mode) \ +-+ phy_set_mode_ext(phy, mode, 0) +-+ +- static inline enum phy_mode phy_get_mode(struct phy *phy) +- { +- return PHY_MODE_INVALID; +diff --git a/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch b/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch +deleted file mode 100644 +index 0964da03a8d..00000000000 +--- a/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch ++++ /dev/null +@@ -1,381 +0,0 @@ +-From 9695375a3f4a604406f2e61f2b735eca1de931ed Mon Sep 17 00:00:00 2001 +-From: Miquel Raynal +-Date: Tue, 8 Jan 2019 17:31:20 +0100 +-Subject: [PATCH] phy: add A3700 COMPHY support +- +-Add a driver to support COMPHY, a hardware block providing shared +-serdes PHYs on Marvell Armada 3700. This driver uses SMC calls and +-rely on having an up-to-date firmware. +- +-SATA, PCie and USB3 host mode have been tested successfully with an +-ESPRESSObin. (HS)SGMII mode cannot be tested with this platform. +- +-Evan worked on the original driver structure and Grzegorz on the SMC +-calls rework. The structure of this driver has been copied from +-Antoine Tenart work on CP110 COMPHY driver. +- +-Signed-off-by: Miquel Raynal +-Co-developed-by: Evan Wang +-Signed-off-by: Evan Wang +-Co-developed-by: Grzegorz Jaszczyk +-Signed-off-by: Grzegorz Jaszczyk +-Signed-off-by: Kishon Vijay Abraham I +---- +- drivers/phy/marvell/Kconfig | 12 + +- drivers/phy/marvell/Makefile | 1 + +- drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 318 +++++++++++++++++++++++++++ +- 3 files changed, 331 insertions(+) +- create mode 100644 drivers/phy/marvell/phy-mvebu-a3700-comphy.c +- +---- a/drivers/phy/marvell/Kconfig +-+++ b/drivers/phy/marvell/Kconfig +-@@ -21,6 +21,18 @@ config PHY_BERLIN_USB +- help +- Enable this to support the USB PHY on Marvell Berlin SoCs. +- +-+config PHY_MVEBU_A3700_COMPHY +-+ tristate "Marvell A3700 comphy driver" +-+ depends on ARCH_MVEBU || COMPILE_TEST +-+ depends on OF +-+ depends on HAVE_ARM_SMCCC +-+ default y +-+ select GENERIC_PHY +-+ help +-+ This driver allows to control the comphy, a hardware block providing +-+ shared serdes PHYs on Marvell Armada 3700. Its serdes lanes can be +-+ used by various controllers: Ethernet, SATA, USB3, PCIe. +-+ +- config PHY_MVEBU_CP110_COMPHY +- tristate "Marvell CP110 comphy driver" +- depends on ARCH_MVEBU || COMPILE_TEST +---- a/drivers/phy/marvell/Makefile +-+++ b/drivers/phy/marvell/Makefile +-@@ -2,6 +2,7 @@ +- obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o +- obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o +- obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o +-+obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o +- obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o +- obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o +- obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o +---- /dev/null +-+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c +-@@ -0,0 +1,318 @@ +-+// SPDX-License-Identifier: GPL-2.0 +-+/* +-+ * Copyright (C) 2018 Marvell +-+ * +-+ * Authors: +-+ * Evan Wang +-+ * Miquèl Raynal +-+ * +-+ * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart. +-+ * SMC call initial support done by Grzegorz Jaszczyk. +-+ */ +-+ +-+#include +-+#include +-+#include +-+#include +-+#include +-+#include +-+#include +-+#include +-+ +-+#define MVEBU_A3700_COMPHY_LANES 3 +-+#define MVEBU_A3700_COMPHY_PORTS 2 +-+ +-+/* COMPHY Fast SMC function identifiers */ +-+#define COMPHY_SIP_POWER_ON 0x82000001 +-+#define COMPHY_SIP_POWER_OFF 0x82000002 +-+#define COMPHY_SIP_PLL_LOCK 0x82000003 +-+ +-+#define COMPHY_FW_MODE_SATA 0x1 +-+#define COMPHY_FW_MODE_SGMII 0x2 +-+#define COMPHY_FW_MODE_HS_SGMII 0x3 +-+#define COMPHY_FW_MODE_USB3H 0x4 +-+#define COMPHY_FW_MODE_USB3D 0x5 +-+#define COMPHY_FW_MODE_PCIE 0x6 +-+#define COMPHY_FW_MODE_RXAUI 0x7 +-+#define COMPHY_FW_MODE_XFI 0x8 +-+#define COMPHY_FW_MODE_SFI 0x9 +-+#define COMPHY_FW_MODE_USB3 0xa +-+ +-+#define COMPHY_FW_SPEED_1_25G 0 /* SGMII 1G */ +-+#define COMPHY_FW_SPEED_2_5G 1 +-+#define COMPHY_FW_SPEED_3_125G 2 /* SGMII 2.5G */ +-+#define COMPHY_FW_SPEED_5G 3 +-+#define COMPHY_FW_SPEED_5_15625G 4 /* XFI 5G */ +-+#define COMPHY_FW_SPEED_6G 5 +-+#define COMPHY_FW_SPEED_10_3125G 6 /* XFI 10G */ +-+#define COMPHY_FW_SPEED_MAX 0x3F +-+ +-+#define COMPHY_FW_MODE(mode) ((mode) << 12) +-+#define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \ +-+ ((idx) << 8) | \ +-+ ((speed) << 2)) +-+#define COMPHY_FW_PCIE(mode, idx, speed, width) (COMPHY_FW_NET(mode, idx, speed) | \ +-+ ((width) << 18)) +-+ +-+struct mvebu_a3700_comphy_conf { +-+ unsigned int lane; +-+ enum phy_mode mode; +-+ int submode; +-+ unsigned int port; +-+ u32 fw_mode; +-+}; +-+ +-+#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _port, _fw) \ +-+ { \ +-+ .lane = _lane, \ +-+ .mode = _mode, \ +-+ .submode = _smode, \ +-+ .port = _port, \ +-+ .fw_mode = _fw, \ +-+ } +-+ +-+#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _port, _fw) \ +-+ MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _port, _fw) +-+ +-+#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _port, _fw) \ +-+ MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _port, _fw) +-+ +-+static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { +-+ /* lane 0 */ +-+ MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, 0, +-+ COMPHY_FW_MODE_USB3H), +-+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, 1, +-+ COMPHY_FW_MODE_SGMII), +-+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, 1, +-+ COMPHY_FW_MODE_HS_SGMII), +-+ /* lane 1 */ +-+ MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, 0, +-+ COMPHY_FW_MODE_PCIE), +-+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0, +-+ COMPHY_FW_MODE_SGMII), +-+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, 0, +-+ COMPHY_FW_MODE_HS_SGMII), +-+ /* lane 2 */ +-+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, 0, +-+ COMPHY_FW_MODE_SATA), +-+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, 0, +-+ COMPHY_FW_MODE_USB3H), +-+}; +-+ +-+struct mvebu_a3700_comphy_lane { +-+ struct device *dev; +-+ unsigned int id; +-+ enum phy_mode mode; +-+ int submode; +-+ int port; +-+}; +-+ +-+static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane, +-+ unsigned long mode) +-+{ +-+ struct arm_smccc_res res; +-+ +-+ arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); +-+ +-+ return res.a0; +-+} +-+ +-+static int mvebu_a3700_comphy_get_fw_mode(int lane, int port, +-+ enum phy_mode mode, +-+ int submode) +-+{ +-+ int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes); +-+ +-+ /* Unused PHY mux value is 0x0 */ +-+ if (mode == PHY_MODE_INVALID) +-+ return -EINVAL; +-+ +-+ for (i = 0; i < n; i++) { +-+ if (mvebu_a3700_comphy_modes[i].lane == lane && +-+ mvebu_a3700_comphy_modes[i].port == port && +-+ mvebu_a3700_comphy_modes[i].mode == mode && +-+ mvebu_a3700_comphy_modes[i].submode == submode) +-+ break; +-+ } +-+ +-+ if (i == n) +-+ return -EINVAL; +-+ +-+ return mvebu_a3700_comphy_modes[i].fw_mode; +-+} +-+ +-+static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, +-+ int submode) +-+{ +-+ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); +-+ int fw_mode; +-+ +-+ if (submode == PHY_INTERFACE_MODE_1000BASEX) +-+ submode = PHY_INTERFACE_MODE_SGMII; +-+ +-+ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, mode, +-+ submode); +-+ if (fw_mode < 0) { +-+ dev_err(lane->dev, "invalid COMPHY mode\n"); +-+ return fw_mode; +-+ } +-+ +-+ /* Just remember the mode, ->power_on() will do the real setup */ +-+ lane->mode = mode; +-+ lane->submode = submode; +-+ +-+ return 0; +-+} +-+ +-+static int mvebu_a3700_comphy_power_on(struct phy *phy) +-+{ +-+ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); +-+ u32 fw_param; +-+ int fw_mode; +-+ +-+ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, +-+ lane->mode, lane->submode); +-+ if (fw_mode < 0) { +-+ dev_err(lane->dev, "invalid COMPHY mode\n"); +-+ return fw_mode; +-+ } +-+ +-+ switch (lane->mode) { +-+ case PHY_MODE_USB_HOST_SS: +-+ dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); +-+ fw_param = COMPHY_FW_MODE(fw_mode); +-+ break; +-+ case PHY_MODE_SATA: +-+ dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); +-+ fw_param = COMPHY_FW_MODE(fw_mode); +-+ break; +-+ case PHY_MODE_ETHERNET: +-+ switch (lane->submode) { +-+ case PHY_INTERFACE_MODE_SGMII: +-+ dev_dbg(lane->dev, "set lane %d to SGMII mode\n", +-+ lane->id); +-+ fw_param = COMPHY_FW_NET(fw_mode, lane->port, +-+ COMPHY_FW_SPEED_1_25G); +-+ break; +-+ case PHY_INTERFACE_MODE_2500BASEX: +-+ dev_dbg(lane->dev, "set lane %d to HS SGMII mode\n", +-+ lane->id); +-+ fw_param = COMPHY_FW_NET(fw_mode, lane->port, +-+ COMPHY_FW_SPEED_3_125G); +-+ break; +-+ default: +-+ dev_err(lane->dev, "unsupported PHY submode (%d)\n", +-+ lane->submode); +-+ return -ENOTSUPP; +-+ } +-+ break; +-+ case PHY_MODE_PCIE: +-+ dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); +-+ fw_param = COMPHY_FW_PCIE(fw_mode, lane->port, +-+ COMPHY_FW_SPEED_5G, +-+ phy->attrs.bus_width); +-+ break; +-+ default: +-+ dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); +-+ return -ENOTSUPP; +-+ } +-+ +-+ return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); +-+} +-+ +-+static int mvebu_a3700_comphy_power_off(struct phy *phy) +-+{ +-+ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); +-+ +-+ return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_OFF, lane->id, 0); +-+} +-+ +-+static const struct phy_ops mvebu_a3700_comphy_ops = { +-+ .power_on = mvebu_a3700_comphy_power_on, +-+ .power_off = mvebu_a3700_comphy_power_off, +-+ .set_mode = mvebu_a3700_comphy_set_mode, +-+ .owner = THIS_MODULE, +-+}; +-+ +-+static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, +-+ struct of_phandle_args *args) +-+{ +-+ struct mvebu_a3700_comphy_lane *lane; +-+ struct phy *phy; +-+ +-+ if (WARN_ON(args->args[0] >= MVEBU_A3700_COMPHY_PORTS)) +-+ return ERR_PTR(-EINVAL); +-+ +-+ phy = of_phy_simple_xlate(dev, args); +-+ if (IS_ERR(phy)) +-+ return phy; +-+ +-+ lane = phy_get_drvdata(phy); +-+ lane->port = args->args[0]; +-+ +-+ return phy; +-+} +-+ +-+static int mvebu_a3700_comphy_probe(struct platform_device *pdev) +-+{ +-+ struct phy_provider *provider; +-+ struct device_node *child; +-+ +-+ for_each_available_child_of_node(pdev->dev.of_node, child) { +-+ struct mvebu_a3700_comphy_lane *lane; +-+ struct phy *phy; +-+ int ret; +-+ u32 lane_id; +-+ +-+ ret = of_property_read_u32(child, "reg", &lane_id); +-+ if (ret < 0) { +-+ dev_err(&pdev->dev, "missing 'reg' property (%d)\n", +-+ ret); +-+ continue; +-+ } +-+ +-+ if (lane_id >= MVEBU_A3700_COMPHY_LANES) { +-+ dev_err(&pdev->dev, "invalid 'reg' property\n"); +-+ continue; +-+ } +-+ +-+ lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); +-+ if (!lane) +-+ return -ENOMEM; +-+ +-+ phy = devm_phy_create(&pdev->dev, child, +-+ &mvebu_a3700_comphy_ops); +-+ if (IS_ERR(phy)) +-+ return PTR_ERR(phy); +-+ +-+ lane->dev = &pdev->dev; +-+ lane->mode = PHY_MODE_INVALID; +-+ lane->submode = PHY_INTERFACE_MODE_NA; +-+ lane->id = lane_id; +-+ lane->port = -1; +-+ phy_set_drvdata(phy, lane); +-+ } +-+ +-+ provider = devm_of_phy_provider_register(&pdev->dev, +-+ mvebu_a3700_comphy_xlate); +-+ return PTR_ERR_OR_ZERO(provider); +-+} +-+ +-+static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = { +-+ { .compatible = "marvell,comphy-a3700" }, +-+ { }, +-+}; +-+MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table); +-+ +-+static struct platform_driver mvebu_a3700_comphy_driver = { +-+ .probe = mvebu_a3700_comphy_probe, +-+ .driver = { +-+ .name = "mvebu-a3700-comphy", +-+ .of_match_table = mvebu_a3700_comphy_of_match_table, +-+ }, +-+}; +-+module_platform_driver(mvebu_a3700_comphy_driver); +-+ +-+MODULE_AUTHOR("Miquèl Raynal "); +-+MODULE_DESCRIPTION("Common PHY driver for A3700"); +-+MODULE_LICENSE("GPL v2"); +diff --git a/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch b/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch +deleted file mode 100644 +index 393f8237944..00000000000 +--- a/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch ++++ /dev/null +@@ -1,58 +0,0 @@ +-From 2ef303f0fe44feee4a3ca8bd62fca86c105927d2 Mon Sep 17 00:00:00 2001 +-From: Miquel Raynal +-Date: Tue, 8 Jan 2019 17:31:24 +0100 +-Subject: [PATCH] arm64: dts: marvell: armada-37xx: declare the COMPHY +- node +- +-Describe the A3700 COMPHY node. It has three PHYs that can be +-configured as follow: +-* PCIe or GbE +-* USB3 or GbE +-* SATA or USB3 +-Each of them has its own memory area. +- +-Suggested-by: Grzegorz Jaszczyk +-Signed-off-by: Miquel Raynal +-Signed-off-by: Gregory CLEMENT +---- +- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 29 ++++++++++++++++++++++++++++ +- 1 file changed, 29 insertions(+) +- +---- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +-+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +-@@ -235,6 +235,35 @@ +- reg = <0x14000 0x60>; +- }; +- +-+ comphy: phy@18300 { +-+ compatible = "marvell,comphy-a3700"; +-+ reg = <0x18300 0x300>, +-+ <0x1F000 0x400>, +-+ <0x5C000 0x400>, +-+ <0xe0178 0x8>; +-+ reg-names = "comphy", +-+ "lane1_pcie_gbe", +-+ "lane0_usb3_gbe", +-+ "lane2_sata_usb3"; +-+ #address-cells = <1>; +-+ #size-cells = <0>; +-+ +-+ comphy0: phy@0 { +-+ reg = <0>; +-+ #phy-cells = <1>; +-+ }; +-+ +-+ comphy1: phy@1 { +-+ reg = <1>; +-+ #phy-cells = <1>; +-+ }; +-+ +-+ comphy2: phy@2 { +-+ reg = <2>; +-+ #phy-cells = <1>; +-+ }; +-+ }; +-+ +- pinctrl_sb: pinctrl@18800 { +- compatible = "marvell,armada3710-sb-pinctrl", +- "syscon", "simple-mfd"; +diff --git a/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch b/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch +deleted file mode 100644 +index f72ea93b97e..00000000000 +--- a/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch ++++ /dev/null +@@ -1,35 +0,0 @@ +-From 9c222a1d78a1700220e38feb270f00d2ddd3c5ab Mon Sep 17 00:00:00 2001 +-From: Russell King +-Date: Wed, 6 Nov 2019 13:44:21 +0000 +-Subject: [PATCH 657/660] arm64: dts: uDPU: fix comphy definitions +- +-The uDPU uses both ethernet controllers, which ties up COMPHY 0 for +-eth1 and COMPHY 1 for eth0, with no USB3 comphy. The addition of +-COMPHY support made the kernel override the setup by the boot loader +-breaking this platform. Delete the USB3 COMPHY definition at platform +-level, and add phy specifications for the ethernet channels. +- +-Fixes: bd3d25b07342 ("arm64: dts: marvell: armada-37xx: link USB hosts with their PHYs") +-Signed-off-by: Russell King +---- +- arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts | 2 ++ +- 1 file changed, 2 insertions(+) +- +---- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +-+++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +-@@ -143,6 +143,7 @@ +- status = "okay"; +- phy-mode = "sgmii"; +- managed = "in-band-status"; +-+ phys = <&comphy1 0>; +- sfp = <&sfp_eth0>; +- }; +- +-@@ -150,6 +151,7 @@ +- status = "okay"; +- phy-mode = "sgmii"; +- managed = "in-band-status"; +-+ phys = <&comphy0 1>; +- sfp = <&sfp_eth1>; +- }; +- + +From 192ccdd1402b8e010b3d811372cd1146a123d461 Mon Sep 17 00:00:00 2001 +From: DENG Qingfang +Date: Wed, 4 Mar 2020 20:46:33 +0800 +Subject: [PATCH 4/4] mvebu: refresh config + +Signed-off-by: DENG Qingfang +--- + target/linux/mvebu/config-5.4 | 61 ++++++++++++++++++------- + target/linux/mvebu/cortexa53/config-5.4 | 1 + + target/linux/mvebu/cortexa72/config-5.4 | 1 + + 3 files changed, 47 insertions(+), 16 deletions(-) + +diff --git a/target/linux/mvebu/config-5.4 b/target/linux/mvebu/config-5.4 +index 24093fd386a..41a826ef7f8 100644 +--- a/target/linux/mvebu/config-5.4 ++++ b/target/linux/mvebu/config-5.4 +@@ -1,20 +1,25 @@ + CONFIG_AHCI_MVEBU=y + CONFIG_ALIGNMENT_TRAP=y ++CONFIG_ARCH_32BIT_OFF_T=y + CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_ARCH_HAS_BINFMT_FLAT=y + CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y + CONFIG_ARCH_HAS_ELF_RANDOMIZE=y + CONFIG_ARCH_HAS_FORTIFY_SOURCE=y + CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y + CONFIG_ARCH_HAS_KCOV=y ++CONFIG_ARCH_HAS_KEEPINITRD=y + CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y + CONFIG_ARCH_HAS_PHYS_TO_DMA=y ++CONFIG_ARCH_HAS_SETUP_DMA_OPS=y + CONFIG_ARCH_HAS_SET_MEMORY=y +-CONFIG_ARCH_HAS_SG_CHAIN=y + CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y + CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y ++CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y + CONFIG_ARCH_HAS_TICK_BROADCAST=y + CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y + CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_ARCH_KEEP_MEMBLOCK=y + CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y + CONFIG_ARCH_MULTIPLATFORM=y + CONFIG_ARCH_MULTI_V6_V7=y +@@ -29,17 +34,20 @@ CONFIG_ARCH_SUPPORTS_UPROBES=y + CONFIG_ARCH_SUSPEND_POSSIBLE=y + CONFIG_ARCH_USE_BUILTIN_BSWAP=y + CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y + CONFIG_ARCH_WANT_GENERAL_HUGETLB=y + CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y + CONFIG_ARM=y + CONFIG_ARMADA_370_CLK=y + CONFIG_ARMADA_370_XP_IRQ=y + CONFIG_ARMADA_370_XP_TIMER=y ++# CONFIG_ARMADA_37XX_WATCHDOG is not set + CONFIG_ARMADA_38X_CLK=y + CONFIG_ARMADA_THERMAL=y + CONFIG_ARMADA_XP_CLK=y + CONFIG_ARM_APPENDED_DTB=y + # CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set ++# CONFIG_ARM_ARMADA_8K_CPUFREQ is not set + CONFIG_ARM_ATAG_DTB_COMPAT=y + # CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set + # CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set +@@ -66,6 +74,7 @@ CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y + CONFIG_ATA=y + CONFIG_ATAGS=y + CONFIG_AUTO_ZRELADDR=y ++CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y + CONFIG_BLK_DEV_LOOP=y + CONFIG_BLK_DEV_SD=y + CONFIG_BLK_MQ_PCI=y +@@ -78,6 +87,7 @@ CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y + CONFIG_CLKSRC_MMIO=y + CONFIG_CLONE_BACKWARDS=y + CONFIG_COMMON_CLK=y ++CONFIG_COMPAT_32BIT_TIME=y + CONFIG_CPUFREQ_DT=y + CONFIG_CPUFREQ_DT_PLATDEV=y + CONFIG_CPU_32v6K=y +@@ -104,8 +114,10 @@ CONFIG_CPU_FREQ_STAT=y + CONFIG_CPU_HAS_ASID=y + # CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set + # CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set + CONFIG_CPU_IDLE=y + CONFIG_CPU_IDLE_GOV_LADDER=y ++# CONFIG_CPU_IDLE_GOV_TEO is not set + CONFIG_CPU_PABRT_V7=y + CONFIG_CPU_PJ4B=y + CONFIG_CPU_PM=y +@@ -122,6 +134,7 @@ CONFIG_CRYPTO_AEAD2=y + CONFIG_CRYPTO_AES_ARM=y + CONFIG_CRYPTO_AES_ARM_BS=y + # CONFIG_CRYPTO_AES_ARM_CE is not set ++CONFIG_CRYPTO_ALGAPI=y + # CONFIG_CRYPTO_CHACHA20_NEON is not set + CONFIG_CRYPTO_CRC32=y + CONFIG_CRYPTO_CRC32C=y +@@ -130,10 +143,13 @@ CONFIG_CRYPTO_CRYPTD=y + CONFIG_CRYPTO_DEFLATE=y + CONFIG_CRYPTO_DES=y + CONFIG_CRYPTO_DEV_MARVELL_CESA=y ++CONFIG_CRYPTO_ESSIV=y + # CONFIG_CRYPTO_GHASH_ARM_CE is not set + CONFIG_CRYPTO_HASH=y + CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_HASH_INFO=y + CONFIG_CRYPTO_HW=y ++CONFIG_CRYPTO_LIB_DES=y + CONFIG_CRYPTO_LZO=y + CONFIG_CRYPTO_MANAGER=y + CONFIG_CRYPTO_MANAGER2=y +@@ -147,7 +163,7 @@ CONFIG_CRYPTO_SHA256_ARM=y + # CONFIG_CRYPTO_SHA2_ARM_CE is not set + CONFIG_CRYPTO_SHA512_ARM=y + CONFIG_CRYPTO_SIMD=y +-CONFIG_CRYPTO_WORKQUEUE=y ++CONFIG_CRYPTO_ZSTD=y + CONFIG_DCACHE_WORD_ACCESS=y + CONFIG_DEBUG_ALIGN_RODATA=y + CONFIG_DEBUG_INFO=y +@@ -165,9 +181,11 @@ CONFIG_DEBUG_UART_VIRT=0xfec12000 + CONFIG_DEBUG_UNCOMPRESS=y + CONFIG_DEBUG_USER=y + CONFIG_DMADEVICES=y ++CONFIG_DMA_DECLARE_COHERENT=y + CONFIG_DMA_ENGINE=y + CONFIG_DMA_ENGINE_RAID=y + CONFIG_DMA_OF=y ++CONFIG_DMA_REMAP=y + CONFIG_DTC=y + CONFIG_EARLY_PRINTK=y + CONFIG_EDAC_ATOMIC_SCRUB=y +@@ -183,6 +201,7 @@ CONFIG_FIXED_PHY=y + CONFIG_FIX_EARLYCON_MEM=y + CONFIG_FS_IOMAP=y + CONFIG_FS_MBCACHE=y ++CONFIG_FW_LOADER_PAGED_BUF=y + CONFIG_GENERIC_ALLOCATOR=y + CONFIG_GENERIC_ARCH_TOPOLOGY=y + CONFIG_GENERIC_BUG=y +@@ -234,6 +253,7 @@ CONFIG_HAVE_ARM_TWD=y + CONFIG_HAVE_CLK=y + CONFIG_HAVE_CLK_PREPARE=y + CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_COPY_THREAD_TLS=y + CONFIG_HAVE_C_RECORDMCOUNT=y + CONFIG_HAVE_DEBUG_KMEMLEAK=y + CONFIG_HAVE_DMA_CONTIGUOUS=y +@@ -244,15 +264,14 @@ CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y + CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y + CONFIG_HAVE_FUNCTION_TRACER=y +-CONFIG_HAVE_GENERIC_DMA_COHERENT=y + CONFIG_HAVE_IDE=y + CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y + CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y +-CONFIG_HAVE_MEMBLOCK=y + CONFIG_HAVE_MOD_ARCH_SPECIFIC=y + CONFIG_HAVE_NET_DSA=y + CONFIG_HAVE_OPROFILE=y + CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_PCI=y + CONFIG_HAVE_PERF_EVENTS=y + CONFIG_HAVE_PERF_REGS=y + CONFIG_HAVE_PERF_USER_STACK_DUMP=y +@@ -284,6 +303,7 @@ CONFIG_IRQ_FORCED_THREADING=y + CONFIG_IRQ_WORK=y + # CONFIG_IWMMXT is not set + CONFIG_JBD2=y ++# CONFIG_KASAN_STACK is not set + CONFIG_LEDS_GPIO=y + CONFIG_LEDS_PCA963X=y + CONFIG_LEDS_TLC591XX=y +@@ -310,7 +330,6 @@ CONFIG_MDIO_I2C=y + CONFIG_MEMFD_CREATE=y + CONFIG_MEMORY=y + CONFIG_MIGHT_HAVE_CACHE_L2X0=y +-CONFIG_MIGHT_HAVE_PCI=y + CONFIG_MIGRATION=y + CONFIG_MMC=y + CONFIG_MMC_BLOCK=y +@@ -322,10 +341,10 @@ CONFIG_MMC_SDHCI_PXAV3=y + # CONFIG_MMC_TIFM_SD is not set + CONFIG_MODULES_USE_ELF_REL=y + CONFIG_MTD_CFI_STAA=y +-CONFIG_MTD_M25P80=y +-CONFIG_MTD_NAND=y +-CONFIG_MTD_NAND_ECC=y ++CONFIG_MTD_NAND_CORE=y ++CONFIG_MTD_NAND_ECC_SW_HAMMING=y + CONFIG_MTD_NAND_MARVELL=y ++CONFIG_MTD_RAW_NAND=y + CONFIG_MTD_SPI_NOR=y + CONFIG_MTD_SPLIT_FIRMWARE=y + CONFIG_MTD_UBI=y +@@ -344,11 +363,12 @@ CONFIG_MVMDIO=y + CONFIG_MVNETA=y + CONFIG_MVNETA_BM=y + CONFIG_MVNETA_BM_ENABLE=y +-CONFIG_MVPP2=y ++# CONFIG_MVPP2 is not set + CONFIG_MVSW61XX_PHY=y + CONFIG_MV_XOR=y + CONFIG_NEED_DMA_MAP_STATE=y + CONFIG_NEON=y ++CONFIG_NET_DEVLINK=y + CONFIG_NET_DSA=y + CONFIG_NET_DSA_MV88E6XXX=y + CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y +@@ -359,7 +379,6 @@ CONFIG_NET_FLOW_LIMIT=y + CONFIG_NET_SWITCHDEV=y + CONFIG_NLS=y + CONFIG_NOP_USB_XCEIV=y +-CONFIG_NO_BOOTMEM=y + CONFIG_NR_CPUS=4 + CONFIG_NVMEM=y + CONFIG_OF=y +@@ -380,17 +399,19 @@ CONFIG_OUTER_CACHE_SYNC=y + CONFIG_PADATA=y + CONFIG_PAGE_OFFSET=0xC0000000 + CONFIG_PCI=y ++CONFIG_PCI_BRIDGE_EMUL=y + CONFIG_PCI_DOMAINS=y + CONFIG_PCI_DOMAINS_GENERIC=y + CONFIG_PCI_MSI=y + CONFIG_PCI_MSI_IRQ_DOMAIN=y + CONFIG_PCI_MVEBU=y +-# CONFIG_PCI_V3_SEMI is not set + CONFIG_PERF_USE_VMALLOC=y + CONFIG_PGTABLE_LEVELS=2 + CONFIG_PHYLIB=y + CONFIG_PHYLINK=y + # CONFIG_PHY_MVEBU_A3700_COMPHY is not set ++# CONFIG_PHY_MVEBU_A3700_UTMI is not set ++# CONFIG_PHY_MVEBU_A38X_COMPHY is not set + # CONFIG_PHY_MVEBU_CP110_COMPHY is not set + CONFIG_PINCTRL=y + CONFIG_PINCTRL_ARMADA_370=y +@@ -415,7 +436,6 @@ CONFIG_REFCOUNT_FULL=y + CONFIG_REGMAP=y + CONFIG_REGMAP_I2C=y + CONFIG_REGMAP_MMIO=y +-CONFIG_REGMAP_SPI=y + CONFIG_REGULATOR=y + CONFIG_REGULATOR_FIXED_VOLTAGE=y + CONFIG_RFS_ACCEL=y +@@ -424,9 +444,7 @@ CONFIG_RTC_CLASS=y + CONFIG_RTC_DRV_ARMADA38X=y + CONFIG_RTC_DRV_MV=y + CONFIG_RTC_I2C_AND_SPI=y +-CONFIG_RTC_MC146818_LIB=y + CONFIG_RWSEM_SPIN_ON_OWNER=y +-CONFIG_RWSEM_XCHGADD_ALGORITHM=y + CONFIG_SATA_AHCI_PLATFORM=y + CONFIG_SATA_MV=y + CONFIG_SATA_PMP=y +@@ -434,7 +452,9 @@ CONFIG_SCSI=y + CONFIG_SENSORS_PWM_FAN=y + CONFIG_SENSORS_TMP421=y + CONFIG_SERIAL_8250_DW=y +-CONFIG_SERIAL_8250_FSL=y ++CONFIG_SERIAL_8250_DWLIB=y ++# CONFIG_SERIAL_8250_FSL is not set ++CONFIG_SERIAL_MCTRL_GPIO=y + CONFIG_SERIAL_MVEBU_CONSOLE=y + CONFIG_SERIAL_MVEBU_UART=y + CONFIG_SFP=y +@@ -469,12 +489,18 @@ CONFIG_TIMER_PROBE=y + CONFIG_TREE_RCU=y + CONFIG_TREE_SRCU=y + CONFIG_UBIFS_FS=y +-# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_ADVANCED_COMPR=y + CONFIG_UBIFS_FS_LZO=y + CONFIG_UBIFS_FS_ZLIB=y ++CONFIG_UBIFS_FS_ZSTD=y ++# CONFIG_UBSAN_ALIGNMENT is not set + CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++CONFIG_UNIX_SCM=y ++CONFIG_UNWINDER_ARM=y ++# CONFIG_UNWINDER_FRAME_POINTER is not set + CONFIG_USB=y + CONFIG_USB_COMMON=y ++# CONFIG_USB_EHCI_FSL is not set + CONFIG_USB_EHCI_HCD=y + CONFIG_USB_EHCI_HCD_ORION=y + CONFIG_USB_EHCI_HCD_PLATFORM=y +@@ -490,9 +516,12 @@ CONFIG_VFP=y + CONFIG_VFPv3=y + CONFIG_WATCHDOG_CORE=y + CONFIG_XPS=y ++CONFIG_XXHASH=y + CONFIG_XZ_DEC_ARM=y + CONFIG_XZ_DEC_BCJ=y + CONFIG_ZBOOT_ROM_BSS=0x0 + CONFIG_ZBOOT_ROM_TEXT=0x0 + CONFIG_ZLIB_DEFLATE=y + CONFIG_ZLIB_INFLATE=y ++CONFIG_ZSTD_COMPRESS=y ++CONFIG_ZSTD_DECOMPRESS=y +diff --git a/target/linux/mvebu/cortexa53/config-5.4 b/target/linux/mvebu/cortexa53/config-5.4 +index 7f3c2b21de0..16d861be110 100644 +--- a/target/linux/mvebu/cortexa53/config-5.4 ++++ b/target/linux/mvebu/cortexa53/config-5.4 +@@ -144,6 +144,7 @@ CONFIG_PCI_AARDVARK=y + CONFIG_PGTABLE_LEVELS=3 + CONFIG_PHYS_ADDR_T_64BIT=y + CONFIG_PHY_MVEBU_A3700_COMPHY=y ++CONFIG_PHY_MVEBU_A3700_UTMI=y + CONFIG_PINCTRL_ARMADA_37XX=y + CONFIG_PINCTRL_ARMADA_AP806=y + CONFIG_PINCTRL_ARMADA_CP110=y +diff --git a/target/linux/mvebu/cortexa72/config-5.4 b/target/linux/mvebu/cortexa72/config-5.4 +index c78eb843724..5727ae5918d 100644 +--- a/target/linux/mvebu/cortexa72/config-5.4 ++++ b/target/linux/mvebu/cortexa72/config-5.4 +@@ -138,6 +138,7 @@ CONFIG_MVEBU_GICP=y + CONFIG_MVEBU_ICU=y + CONFIG_MVEBU_ODMI=y + CONFIG_MVEBU_PIC=y ++CONFIG_MVPP2=y + CONFIG_MV_XOR_V2=y + CONFIG_NEED_SG_DMA_LENGTH=y + # CONFIG_NUMA is not set diff --git a/patches/smsc75xx.patch b/patches/smsc75xx.patch new file mode 100644 index 00000000..e08dab97 --- /dev/null +++ b/patches/smsc75xx.patch @@ -0,0 +1,26 @@ +Index: package/kernel/linux/modules/usb.mk +=================================================================== +--- a/package/kernel/linux/modules/usb.mk (revisione 42462) ++++ b/package/kernel/linux/modules/usb.mk (copia locale) +@@ -1091,8 +1091,21 @@ + endef + + $(eval $(call KernelPackage,usb-net-smsc95xx)) ++ ++define KernelPackage/usb-net-smsc75xx ++ TITLE:=SMSC LAN75XX based USB 2.0 Gigabit ethernet devices ++ KCONFIG:=CONFIG_USB_NET_SMSC75XX ++ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/smsc75xx.ko ++ AUTOLOAD:=$(call AutoProbe,smsc75xx) ++ $(call AddDepends/usb-net, +kmod-lib-crc16) ++endef + ++define KernelPackage/usb-net-smsc75xx/description ++ Kernel module for SMSC LAN75XX based devices ++endef + ++$(eval $(call KernelPackage,usb-net-smsc75xx)) ++ + define KernelPackage/usb-net-dm9601-ether + TITLE:=Support for DM9601 ethernet connections + KCONFIG:=CONFIG_USB_NET_DM9601 diff --git a/patches/uefi.patch b/patches/uefi.patch index 2058bec6..317291b8 100644 --- a/patches/uefi.patch +++ b/patches/uefi.patch @@ -1,7 +1,7 @@ -From c8c937208ee2f9cd6f3a206a0f8408951767a9b9 Mon Sep 17 00:00:00 2001 +From 964f624954b5e4ea83a4f05a57d79a6af6836d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Thu, 4 Apr 2019 02:40:15 +0000 -Subject: [PATCH 1/4] firmware-utils: ptgen: add GPT support +Subject: [PATCH 1/8] firmware-utils: ptgen: add GPT support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -23,10 +23,10 @@ Signed-off-by: 李国 2 files changed, 314 insertions(+), 25 deletions(-) diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile -index 2d2c96ce0af..d50faa42db2 100644 +index 97c89eec279..561d6d868fe 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile -@@ -31,7 +31,7 @@ define Host/Compile +@@ -32,7 +32,7 @@ define Host/Compile $(call cc,dgfirmware) $(call cc,mksenaofw md5, -Wall --std=gnu99) $(call cc,trx2usr) @@ -493,10 +493,10 @@ index 0192bb65e51..caee0f94190 100644 + } } -From 252d3e1dfe244a4d5a594a85bdce466bbbc4f19a Mon Sep 17 00:00:00 2001 +From c634da575c221e6a340884219d78978f56f23976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Thu, 4 Apr 2019 03:17:01 +0000 -Subject: [PATCH 2/4] grub2: split to grub2 and grub2-efi packages +Subject: [PATCH 2/8] grub2: split to grub2 and grub2-efi packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -507,106 +507,74 @@ so we split it to grub2 and grub2-efi packages. Signed-off-by: 李国 --- - package/boot/grub2/{Makefile => common.mk} | 52 +++------------------- - package/boot/grub2/grub2-efi/Makefile | 19 ++++++++ - package/boot/grub2/grub2/Makefile | 46 +++++++++++++++++++ - 3 files changed, 72 insertions(+), 45 deletions(-) - rename package/boot/grub2/{Makefile => common.mk} (52%) + package/boot/grub2/common.mk | 54 +++++++++++++++++++++++++ + package/boot/grub2/grub2-efi/Makefile | 19 +++++++++ + package/boot/grub2/{ => grub2}/Makefile | 50 +---------------------- + 3 files changed, 75 insertions(+), 48 deletions(-) + create mode 100644 package/boot/grub2/common.mk create mode 100644 package/boot/grub2/grub2-efi/Makefile - create mode 100644 package/boot/grub2/grub2/Makefile + rename package/boot/grub2/{ => grub2}/Makefile (66%) -diff --git a/package/boot/grub2/Makefile b/package/boot/grub2/common.mk -similarity index 52% -rename from package/boot/grub2/Makefile -rename to package/boot/grub2/common.mk -index 1f92ba92502..53ee26552f8 100644 ---- a/package/boot/grub2/Makefile +diff --git a/package/boot/grub2/common.mk b/package/boot/grub2/common.mk +new file mode 100644 +index 00000000000..53ee26552f8 +--- /dev/null +++ b/package/boot/grub2/common.mk -@@ -11,56 +11,26 @@ include $(INCLUDE_DIR)/kernel.mk - PKG_NAME:=grub - PKG_CPE_ID:=cpe:/a:gnu:grub2 - PKG_VERSION:=2.04 --PKG_RELEASE:=1 +@@ -0,0 +1,54 @@ ++# ++# Copyright (C) 2006-2015 OpenWrt.org ++# ++# This is free software, licensed under the GNU General Public License v2. ++# See /LICENSE for more information. ++# ++ ++include $(TOPDIR)/rules.mk ++include $(INCLUDE_DIR)/kernel.mk ++ ++PKG_NAME:=grub ++PKG_CPE_ID:=cpe:/a:gnu:grub2 ++PKG_VERSION:=2.04 +PKG_RELEASE:=2 - - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz - PKG_SOURCE_URL:=@GNU/grub - PKG_HASH:=e5292496995ad42dabe843a0192cf2a2c502e7ffcc7479398232b10a472df77d - - HOST_BUILD_PARALLEL:=1 --PKG_BUILD_DEPENDS:=grub2/host - - PKG_SSP:=0 - - PKG_FLAGS:=nonshared - --include $(INCLUDE_DIR)/host-build.mk --include $(INCLUDE_DIR)/package.mk -- --define Package/grub2 -- CATEGORY:=Boot Loaders -- SECTION:=boot -- TITLE:=GRand Unified Bootloader -- URL:=http://www.gnu.org/software/grub/ -- DEPENDS:=@TARGET_x86 --endef -- --define Package/grub2-editenv -- CATEGORY:=Utilities -- SECTION:=utils -- SUBMENU:=Boot Loaders -- TITLE:=Grub2 Environment editor -- URL:=http://www.gnu.org/software/grub/ -- DEPENDS:=@TARGET_x86 --endef -- --define Package/grub2-editenv/description -- Edit grub2 environment files. --endef ++ ++PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz ++PKG_SOURCE_URL:=@GNU/grub ++PKG_HASH:=e5292496995ad42dabe843a0192cf2a2c502e7ffcc7479398232b10a472df77d ++ ++HOST_BUILD_PARALLEL:=1 ++ ++PKG_SSP:=0 ++ ++PKG_FLAGS:=nonshared ++ +PATCH_DIR:=../patches - ++ +HOST_BUILD_DIR ?= $(BUILD_DIR_HOST)/$(PKG_NAME)-$(GRUB_PLATFORM)/$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION)) - HOST_BUILD_PREFIX := $(STAGING_DIR_HOST) - --CONFIGURE_VARS += \ -- grub_build_mkfont_excuse="don't want fonts" ++HOST_BUILD_PREFIX := $(STAGING_DIR_HOST) ++ +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk - --CONFIGURE_ARGS += \ -- --target=$(REAL_GNU_TARGET_NAME) \ -- --disable-werror \ -- --disable-nls \ -- --disable-device-mapper \ -- --disable-libzfs \ -- --disable-grub-mkfont \ -- --with-platform=none - - HOST_CONFIGURE_VARS += \ - grub_build_mkfont_excuse="don't want fonts" -@@ -71,7 +41,8 @@ HOST_CONFIGURE_ARGS += \ - --sbindir="$(STAGING_DIR_HOST)/bin" \ - --disable-werror \ - --disable-libzfs \ -- --disable-nls ++ ++ ++HOST_CONFIGURE_VARS += \ ++ grub_build_mkfont_excuse="don't want fonts" ++ ++HOST_CONFIGURE_ARGS += \ ++ --disable-grub-mkfont \ ++ --target=$(REAL_GNU_TARGET_NAME) \ ++ --sbindir="$(STAGING_DIR_HOST)/bin" \ ++ --disable-werror \ ++ --disable-libzfs \ + --disable-nls \ + --with-platform=$(GRUB_PLATFORM) - - HOST_MAKE_FLAGS += \ - TARGET_RANLIB=$(TARGET_RANLIB) \ -@@ -81,12 +52,3 @@ define Host/Configure - $(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in - $(Host/Configure/Default) - endef -- --define Package/grub2-editenv/install -- $(INSTALL_DIR) $(1)/usr/sbin -- $(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-editenv $(1)/usr/sbin/ --endef -- --$(eval $(call HostBuild)) --$(eval $(call BuildPackage,grub2)) --$(eval $(call BuildPackage,grub2-editenv)) ++ ++HOST_MAKE_FLAGS += \ ++ TARGET_RANLIB=$(TARGET_RANLIB) \ ++ LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a ++ ++define Host/Configure ++ $(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in ++ $(Host/Configure/Default) ++endef diff --git a/package/boot/grub2/grub2-efi/Makefile b/package/boot/grub2/grub2-efi/Makefile new file mode 100644 index 00000000000..2fc21fdb890 @@ -632,63 +600,88 @@ index 00000000000..2fc21fdb890 + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,grub2-efi)) -diff --git a/package/boot/grub2/grub2/Makefile b/package/boot/grub2/grub2/Makefile -new file mode 100644 -index 00000000000..b1db13295d9 ---- /dev/null +diff --git a/package/boot/grub2/Makefile b/package/boot/grub2/grub2/Makefile +similarity index 66% +rename from package/boot/grub2/Makefile +rename to package/boot/grub2/grub2/Makefile +index 980a6e372a3..7126beab4cf 100644 +--- a/package/boot/grub2/Makefile +++ b/package/boot/grub2/grub2/Makefile -@@ -0,0 +1,46 @@ +@@ -1,31 +1,7 @@ +-# +-# Copyright (C) 2006-2015 OpenWrt.org +-# +-# This is free software, licensed under the GNU General Public License v2. +-# See /LICENSE for more information. +-# +GRUB_PLATFORM:=pc -+ -+PKG_BUILD_DEPENDS:=grub2/host + +-include $(TOPDIR)/rules.mk +-include $(INCLUDE_DIR)/kernel.mk +- +-PKG_NAME:=grub +-PKG_CPE_ID:=cpe:/a:gnu:grub2 +-PKG_VERSION:=2.04 +-PKG_RELEASE:=1 +- +-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +-PKG_SOURCE_URL:=@GNU/grub +-PKG_HASH:=e5292496995ad42dabe843a0192cf2a2c502e7ffcc7479398232b10a472df77d +- +-HOST_BUILD_PARALLEL:=1 + PKG_BUILD_DEPENDS:=grub2/host +- +-PKG_SSP:=0 +- +-PKG_FLAGS:=nonshared +- +-include $(INCLUDE_DIR)/host-build.mk +-include $(INCLUDE_DIR)/package.mk +include ../common.mk -+ -+define Package/grub2 -+ CATEGORY:=Boot Loaders -+ SECTION:=boot -+ TITLE:=GRand Unified Bootloader -+ URL:=http://www.gnu.org/software/grub/ -+ DEPENDS:=@TARGET_x86 -+endef -+ -+define Package/grub2-editenv -+ CATEGORY:=Utilities -+ SECTION:=utils -+ SUBMENU:=Boot Loaders -+ TITLE:=Grub2 Environment editor -+ URL:=http://www.gnu.org/software/grub/ -+ DEPENDS:=@TARGET_x86 -+endef -+ -+define Package/grub2-editenv/description -+ Edit grub2 environment files. -+endef -+ -+CONFIGURE_VARS += \ -+ grub_build_mkfont_excuse="don't want fonts" -+ -+CONFIGURE_ARGS += \ -+ --target=$(REAL_GNU_TARGET_NAME) \ -+ --disable-werror \ -+ --disable-nls \ -+ --disable-device-mapper \ -+ --disable-libzfs \ -+ --disable-grub-mkfont \ -+ --with-platform=none -+ -+define Package/grub2-editenv/install -+ $(INSTALL_DIR) $(1)/usr/sbin -+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-editenv $(1)/usr/sbin/ -+endef -+ -+$(eval $(call HostBuild)) -+$(eval $(call BuildPackage,grub2)) -+$(eval $(call BuildPackage,grub2-editenv)) + + define Package/grub2 + CATEGORY:=Boot Loaders +@@ -48,8 +24,6 @@ define Package/grub2-editenv/description + Edit grub2 environment files. + endef + +-HOST_BUILD_PREFIX := $(STAGING_DIR_HOST) +- + CONFIGURE_VARS += \ + grub_build_mkfont_excuse="don't want fonts" + +@@ -62,26 +36,6 @@ CONFIGURE_ARGS += \ + --disable-grub-mkfont \ + --with-platform=none + +-HOST_CONFIGURE_VARS += \ +- grub_build_mkfont_excuse="don't want fonts" +- +-HOST_CONFIGURE_ARGS += \ +- --disable-grub-mkfont \ +- --target=$(REAL_GNU_TARGET_NAME) \ +- --sbindir="$(STAGING_DIR_HOST)/bin" \ +- --disable-werror \ +- --disable-libzfs \ +- --disable-nls +- +-HOST_MAKE_FLAGS += \ +- TARGET_RANLIB=$(TARGET_RANLIB) \ +- LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a +- +-define Host/Configure +- $(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in +- $(Host/Configure/Default) +-endef +- + define Host/Install + $(call Host/Install/Default) + -From 4d3e51d9aa9d81b4444e9ed16c41459efa083370 Mon Sep 17 00:00:00 2001 +From 15212ac11ac95a57f75317fff83bb7d53b581a93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Thu, 4 Apr 2019 03:42:16 +0000 -Subject: [PATCH 3/4] x86: add EFI images and make iso images EFI bootable +Subject: [PATCH 3/8] x86: add EFI images and make iso images EFI bootable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -706,22 +699,22 @@ kernel can not find rootfs, we pad enough sectors will be ok. Signed-off-by: 李国 --- - config/Config-images.in | 27 +++-- - .../base-files/files/lib/upgrade/common.sh | 11 ++ - scripts/gen_image_generic.sh | 10 +- - .../x86/base-files/lib/preinit/79_move_config | 6 +- - .../x86/base-files/lib/upgrade/platform.sh | 6 +- - target/linux/x86/generic/config-4.14 | 1 + - target/linux/x86/generic/config-4.19 | 1 + - target/linux/x86/image/Makefile | 103 +++++++++++++++++- - target/linux/x86/image/grub-iso.cfg | 7 +- - 9 files changed, 153 insertions(+), 19 deletions(-) + config/Config-images.in | 23 +++++++++++++------ + .../base-files/files/lib/upgrade/common.sh | 11 +++++++++ + scripts/gen_image_generic.sh | 10 ++++++-- + .../x86/base-files/lib/preinit/79_move_config | 6 +++-- + .../x86/base-files/lib/upgrade/platform.sh | 6 +++-- + target/linux/x86/generic/config-4.19 | 1 + + target/linux/x86/generic/config-5.4 | 1 + + target/linux/x86/image/Makefile | 3 +++ + target/linux/x86/image/grub-iso.cfg | 7 +++++- + 9 files changed, 54 insertions(+), 14 deletions(-) diff --git a/config/Config-images.in b/config/Config-images.in -index a3d99288422..8ba069ed4fc 100644 +index e4db0482ce2..16b575247ea 100644 --- a/config/Config-images.in +++ b/config/Config-images.in -@@ -195,19 +195,28 @@ menu "Target Images" +@@ -188,19 +188,28 @@ menu "Target Images" select PACKAGE_grub2 default y @@ -753,7 +746,7 @@ index a3d99288422..8ba069ed4fc 100644 default 38400 if TARGET_x86_generic default 115200 -@@ -218,20 +227,20 @@ menu "Target Images" +@@ -211,20 +220,20 @@ menu "Target Images" config GRUB_BOOTOPTS string "Extra kernel boot options" @@ -777,23 +770,7 @@ index a3d99288422..8ba069ed4fc 100644 default "OpenWrt" help This is the title of the GRUB menu entry. -@@ -260,21 +269,21 @@ menu "Target Images" - - config TARGET_KERNEL_PARTSIZE - int "Kernel partition size (in MB)" -- depends on GRUB_IMAGES || USES_BOOT_PART -+ depends on GRUB_IMAGES || EFI_IMAGES || USES_BOOT_PART - default 8 if TARGET_apm821xx_sata - default 64 if TARGET_bcm27xx - default 16 - - config TARGET_ROOTFS_PARTSIZE - int "Root filesystem partition size (in MB)" -- depends on GRUB_IMAGES || USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_omap || TARGET_rb532 || TARGET_sunxi || TARGET_uml -+ depends on GRUB_IMAGES || EFI_IMAGES || USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_omap || TARGET_rb532 || TARGET_sunxi || TARGET_uml - default 104 - help - Select the root filesystem partition size. +@@ -272,7 +281,7 @@ menu "Target Images" config TARGET_ROOTFS_PARTNAME string "Root partition on target device" @@ -803,10 +780,10 @@ index a3d99288422..8ba069ed4fc 100644 Override the root partition on the final device. If left empty, it will be mounted by PARTUUID which makes the kernel find the diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh -index efa301cd950..a978c11e445 100644 +index a986cc0b5c7..6e967aeffe8 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh -@@ -134,6 +134,17 @@ export_bootdevice() { +@@ -136,6 +136,17 @@ export_bootdevice() { fi done ;; @@ -825,11 +802,11 @@ index efa301cd950..a978c11e445 100644 uevent="/sys/class/block/${rootpart##*/}/../uevent" ;; diff --git a/scripts/gen_image_generic.sh b/scripts/gen_image_generic.sh -index d9beeb02953..cc5a4d56fbe 100755 +index 2c57d56f073..1df4d0673b3 100755 --- a/scripts/gen_image_generic.sh +++ b/scripts/gen_image_generic.sh @@ -20,7 +20,7 @@ sect=63 - cyl=$(( ($KERNELSIZE + $ROOTFSSIZE) * 1024 * 1024 / ($head * $sect * 512))) + cyl=$(( (KERNELSIZE + ROOTFSSIZE) * 1024 * 1024 / (head * sect * 512))) # create partition table -set $(ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE}) @@ -844,7 +821,7 @@ index d9beeb02953..cc5a4d56fbe 100755 -make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR" +if [ -n "$EFI_SIGNATURE" ]; then + [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$(($ROOTFSOFFSET + $ROOTFSSIZE))" conv=notrunc count="$sect" -+ mkfs.fat -C "$OUTPUT.kernel" -S 512 "$(($KERNELSIZE / 1024))" ++ mkfs.fat -n kernel -C "$OUTPUT.kernel" -S 512 "$(($KERNELSIZE / 1024))" + mcopy -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/ +else + make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR" @@ -852,7 +829,7 @@ index d9beeb02953..cc5a4d56fbe 100755 dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc rm -f "$OUTPUT.kernel" diff --git a/target/linux/x86/base-files/lib/preinit/79_move_config b/target/linux/x86/base-files/lib/preinit/79_move_config -index aff720a52c5..8eea97c5b66 100644 +index 702da9e873d..015efcf748b 100644 --- a/target/linux/x86/base-files/lib/preinit/79_move_config +++ b/target/linux/x86/base-files/lib/preinit/79_move_config @@ -2,13 +2,15 @@ @@ -874,10 +851,10 @@ index aff720a52c5..8eea97c5b66 100644 mv -f "/boot/$BACKUP_FILE" / fi diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh -index 162dbaf3aaa..ac060818df1 100644 +index 53c751861cc..1c93f5bd9b9 100644 --- a/target/linux/x86/base-files/lib/upgrade/platform.sh +++ b/target/linux/x86/base-files/lib/upgrade/platform.sh -@@ -35,10 +35,12 @@ platform_check_image() { +@@ -37,10 +37,12 @@ platform_check_image() { } platform_copy_config() { @@ -892,22 +869,22 @@ index 162dbaf3aaa..ac060818df1 100644 cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE" umount /mnt fi -diff --git a/target/linux/x86/generic/config-4.14 b/target/linux/x86/generic/config-4.14 -index 1e31e117dd0..41bd58afddd 100644 ---- a/target/linux/x86/generic/config-4.14 -+++ b/target/linux/x86/generic/config-4.14 -@@ -125,6 +125,7 @@ CONFIG_FB_EFI=y - CONFIG_FB_HYPERV=y - # CONFIG_FB_I810 is not set - # CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA is not set -+CONFIG_FB_SIMPLE=y - CONFIG_FB_SYS_COPYAREA=y - CONFIG_FB_SYS_FILLRECT=y - CONFIG_FB_SYS_FOPS=y diff --git a/target/linux/x86/generic/config-4.19 b/target/linux/x86/generic/config-4.19 index 4a689ca026c..ada81ce04ea 100644 --- a/target/linux/x86/generic/config-4.19 +++ b/target/linux/x86/generic/config-4.19 +@@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y + CONFIG_FB_EFI=y + CONFIG_FB_HYPERV=y + # CONFIG_FB_I810 is not set ++CONFIG_FB_SIMPLE=y + CONFIG_FB_SYS_COPYAREA=y + CONFIG_FB_SYS_FILLRECT=y + CONFIG_FB_SYS_FOPS=y +diff --git a/target/linux/x86/generic/config-5.4 b/target/linux/x86/generic/config-5.4 +index 4a689ca026c..ada81ce04ea 100644 +--- a/target/linux/x86/generic/config-5.4 ++++ b/target/linux/x86/generic/config-5.4 @@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y CONFIG_FB_EFI=y CONFIG_FB_HYPERV=y @@ -917,18 +894,11 @@ index 4a689ca026c..ada81ce04ea 100644 CONFIG_FB_SYS_FILLRECT=y CONFIG_FB_SYS_FOPS=y diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile -index ac70e771c86..6af5cfed963 100644 +index c2961e5b9c9..aa80d77b978 100644 --- a/target/linux/x86/image/Makefile +++ b/target/linux/x86/image/Makefile -@@ -11,6 +11,7 @@ export PATH=$(TARGET_PATH):/sbin +@@ -38,6 +38,9 @@ endif - GRUB2_MODULES = biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial test vga - GRUB2_MODULES_ISO = biosdisk boot chain configfile iso9660 linux ls part_msdos reboot serial test vga -+GRUB2_MODULES_EFI = boot chain configfile ext2 fat linux ls part_msdos part_gpt reboot serial test efi_gop efi_uga - GRUB_TERMINALS = - GRUB_SERIAL_CONFIG = - GRUB_TERMINAL_CONFIG = -@@ -43,5 +44,8 @@ endif ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME)) ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02) +EFI_SIGNATURE:=$(strip $(shell uuidgen | sed -r 's/[a-zA-Z0-9]{2}$$/00/')) @@ -937,157 +907,8 @@ index ac70e771c86..6af5cfed963 100644 GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT)) GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE)) -@@ -93,9 +97,68 @@ ifneq ($(CONFIG_GRUB_IMAGES),) - endef - endif - -+ifneq ($(CONFIG_EFI_IMAGES),) -+ -+ BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS)) -+ -+ define Image/cmdline/ext4/efi -+ root=$(EFI_ROOTPART) rootfstype=ext4 rootwait -+ endef -+ -+ define Image/cmdline/squashfs/efi -+ root=$(EFI_ROOTPART) rootfstype=squashfs rootwait -+ endef -+ -+ define Image/Build/grub2/efi -+ # left here because the image builder doesnt need these -+ $(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2 $(KDIR)/root.grub/efi/boot -+ $(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz -+ sed -e 's#msdos1#gpt1#g' ./grub-early.cfg > $(KDIR)/grub2/grub-early.cfg -+ -+ grub-mkimage \ -+ -p /boot/grub \ -+ -d $(STAGING_DIR_HOST)/lib/grub/$(CONFIG_ARCH)-efi \ -+ -o $(KDIR)/root.grub/efi/boot/boot$(if $(CONFIG_x86_64),x64,ia32).efi \ -+ -O $(CONFIG_ARCH)-efi \ -+ -c $(KDIR)/grub2/grub-early.cfg \ -+ $(GRUB2_MODULES_EFI) -+ -+ grub-mkimage \ -+ -p /boot/grub \ -+ -d $(STAGING_DIR_HOST)/lib/grub/i386-pc \ -+ -o $(KDIR)/grub2/core.img \ -+ -O i386-pc \ -+ -c $(KDIR)/grub2/grub-early.cfg \ -+ $(GRUB2_MODULES) part_gpt fat -+ -+ $(CP) $(STAGING_DIR_HOST)/lib/grub/i386-pc/*.img $(KDIR)/grub2/ -+ echo '(hd0) $(BIN_DIR)/$(IMG_COMBINED)-$(1)-efi.img' > $(KDIR)/grub2/device.map -+ sed \ -+ -e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \ -+ -e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \ -+ -e 's#@CMDLINE@#$(strip $(call Image/cmdline/$(1)/efi) $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \ -+ -e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \ -+ -e 's#@TITLE@#$(GRUB_TITLE)#g' \ -+ -e 's#msdos1#gpt1#g' \ -+ ./grub.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg -+ -$(CP) $(STAGING_DIR_ROOT)/boot/. $(KDIR)/root.grub/boot/ -+ EFI_SIGNATURE=$(EFI_SIGNATURE) PADDING="1" SIGNATURE="$(SIGNATURE)" PATH="$(TARGET_PATH)" $(SCRIPT_DIR)/gen_image_generic.sh \ -+ $(BIN_DIR)/$(IMG_COMBINED)-$(1)-efi.img \ -+ $(CONFIG_TARGET_KERNEL_PARTSIZE) $(KDIR)/root.grub \ -+ $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(KDIR)/root.$(1) \ -+ 256 -+ grub-bios-setup \ -+ --device-map="$(KDIR)/grub2/device.map" \ -+ -d "$(KDIR)/grub2" \ -+ -r "hd0,gpt1" \ -+ "$(BIN_DIR)/$(IMG_COMBINED)-$(1)-efi.img" -+ endef -+endif -+ - define Image/Build/iso - rm -fR $(KDIR)/root.grub $(KDIR)/grub2 - $(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2 -+ $(INSTALL_DIR) $(KDIR)/root.grub/efi/boot - $(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz - grub-mkimage \ - -p /boot/grub \ -@@ -107,6 +170,17 @@ define Image/Build/iso - $(STAGING_DIR_HOST)/lib/grub/i386-pc/cdboot.img \ - $(KDIR)/grub2/eltorito.img \ - > $(KDIR)/root.grub/boot/grub/eltorito.img -+ grub-mkimage \ -+ -p /boot/grub \ -+ -d $(STAGING_DIR_HOST)/lib/grub/$(CONFIG_ARCH)-efi \ -+ -o $(KDIR)/root.grub/efi/boot/boot$(if $(CONFIG_x86_64),x64,ia32).efi \ -+ -O $(CONFIG_ARCH)-efi \ -+ -c ./grub-early.cfg \ -+ $(GRUB2_MODULES_EFI) iso9660 -+ -+ rm -f $(KDIR)/root.grub/efiboot.img -+ mkfs.fat -C $(TARGET_DIR)/efiboot.img -S 512 1440 -+ mcopy -s -i $(TARGET_DIR)/efiboot.img $(KDIR)/root.grub/efi ::/ - sed \ - -e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \ - -e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \ -@@ -116,11 +190,12 @@ define Image/Build/iso - ./grub-iso.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg - -$(CP) $(STAGING_DIR_ROOT)/boot/. $(KDIR)/root.grub/boot/ - mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \ -+ -boot-load-size 4 -c boot.cat -eltorito-alt-boot -e efiboot.img -no-emul-boot \ - -o $(KDIR)/root.iso $(KDIR)/root.grub $(TARGET_DIR) - endef - - ifneq ($(CONFIG_VDI_IMAGES),) -- define Image/Build/vdi -+ define Image/Build/vdi/default - rm $(BIN_DIR)/$(IMG_COMBINED)-$(1).vdi || true - $(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vdi \ - $(BIN_DIR)/$(IMG_COMBINED)-$(1).img \ -@@ -129,7 +204,7 @@ ifneq ($(CONFIG_VDI_IMAGES),) - endif - - ifneq ($(CONFIG_VMDK_IMAGES),) -- define Image/Build/vmdk -+ define Image/Build/vmdk/default - rm $(BIN_DIR)/$(IMG_COMBINED)-$(1).vmdk || true - $(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vmdk \ - $(BIN_DIR)/$(IMG_COMBINED)-$(1).img \ -@@ -137,8 +212,27 @@ ifneq ($(CONFIG_VMDK_IMAGES),) - endef - endif - -+ifneq ($(CONFIG_GRUB_IMAGES),) -+ define Image/Build/vdi -+ $(call Image/Build/vdi/default,$(1)) -+ endef -+ define Image/Build/vmdk -+ $(call Image/Build/vmdk/default,$(1)) -+ endef -+endif -+ -+ifneq ($(CONFIG_EFI_IMAGES),) -+ define Image/Build/vdi/efi -+ $(call Image/Build/vdi/default,$(1)-efi) -+ endef -+ define Image/Build/vmdk/efi -+ $(call Image/Build/vmdk/default,$(1)-efi) -+ endef -+endif -+ - define Image/Build/gzip -- gzip -f9n $(BIN_DIR)/$(IMG_COMBINED)-$(1).img -+ $(if $(CONFIG_GRUB_IMAGES),gzip -f9n $(BIN_DIR)/$(IMG_COMBINED)-$(1).img) -+ $(if $(CONFIG_EFI_IMAGES),gzip -f9n $(BIN_DIR)/$(IMG_COMBINED)-$(1)-efi.img) - gzip -f9n $(BIN_DIR)/$(IMG_ROOTFS)-$(1).img - endef - -@@ -162,6 +256,9 @@ define Image/Build - $(call Image/Build/grub2,$(1)) - $(call Image/Build/vdi,$(1)) - $(call Image/Build/vmdk,$(1)) -+ $(call Image/Build/grub2/efi,$(1)) -+ $(call Image/Build/vdi/efi,$(1)) -+ $(call Image/Build/vmdk/efi,$(1)) - $(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_ROOTFS)-$(1).img - else - $(CP) $(KDIR)/root.iso $(BIN_DIR)/$(IMG_PREFIX).iso diff --git a/target/linux/x86/image/grub-iso.cfg b/target/linux/x86/image/grub-iso.cfg -index 9c59bdf6d49..92516b61e5e 100644 +index f5848b38534..4bef492a414 100644 --- a/target/linux/x86/image/grub-iso.cfg +++ b/target/linux/x86/image/grub-iso.cfg @@ -3,7 +3,12 @@ @@ -1103,12 +924,12 @@ index 9c59bdf6d49..92516b61e5e 100644 +fi menuentry "@TITLE@" { - linux /boot/vmlinuz @CMDLINE@ noinitrd + linux /boot/vmlinuz root=/dev/sr0 rootfstype=iso9660 rootwait @CMDLINE@ noinitrd -From a72d68886dff937dab696ecae757c5d5f72c7279 Mon Sep 17 00:00:00 2001 +From c24086b352f6f773c07f15f85b0e5ffe26e206af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Sat, 31 Aug 2019 13:28:05 +0000 -Subject: [PATCH 4/4] x86: fix sysupgrade for EFI images +Subject: [PATCH 4/8] x86: fix sysupgrade for EFI images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1120,14 +941,14 @@ Content-Transfer-Encoding: 8bit Signed-off-by: 李国 --- .../base-files/files/lib/upgrade/common.sh | 40 ++++++++++++++----- - .../x86/base-files/lib/upgrade/platform.sh | 17 +++++++- - 2 files changed, 44 insertions(+), 13 deletions(-) + .../x86/base-files/lib/upgrade/platform.sh | 20 ++++++++-- + 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh -index a978c11e445..9ae634932d2 100644 +index 6e967aeffe8..1324b98ed2f 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh -@@ -204,17 +204,35 @@ get_partitions() { # +@@ -218,17 +218,35 @@ get_partitions() { # rm -f "/tmp/partmap.$filename" local part @@ -1175,10 +996,10 @@ index a978c11e445..9ae634932d2 100644 } diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh -index ac060818df1..f66c5873e37 100644 +index 1c93f5bd9b9..3acee2c7a9c 100644 --- a/target/linux/x86/base-files/lib/upgrade/platform.sh +++ b/target/linux/x86/base-files/lib/upgrade/platform.sh -@@ -18,7 +18,7 @@ platform_check_image() { +@@ -20,7 +20,7 @@ platform_check_image() { get_partitions "/dev/$diskdev" bootdisk #extract the boot sector from the image @@ -1187,31 +1008,314 @@ index ac060818df1..f66c5873e37 100644 get_partitions /tmp/image.bs image -@@ -60,7 +60,7 @@ platform_do_upgrade() { +@@ -40,7 +40,7 @@ platform_copy_config() { + local partdev magic parttype=ext4 + + if export_partdevice partdev 1; then +- magic=$(dd if="/dev/$partdev" bs=1 count=3 skip=54 2>/dev/null) ++ magic="$(dd if="/dev/$partdev" bs=1 count=3 skip=54 2>/dev/null)" + [ "$magic" = "FAT" ] && parttype=vfat + mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt + cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE" +@@ -83,7 +83,7 @@ platform_do_upgrade() { get_partitions "/dev/$diskdev" bootdisk #extract the boot sector from the image - get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b -+ get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b ++ get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b >/dev/null get_partitions /tmp/image.bs image -@@ -94,6 +94,18 @@ platform_do_upgrade() { - #copy partition uuid - echo "Writing new UUID to /dev/$diskdev..." +@@ -108,7 +108,7 @@ platform_do_upgrade() { + while read part start size; do + if export_partdevice partdev $part; then + echo "Writing image to /dev/$partdev..." +- get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync ++ get_image "$@" | dd of="/dev/$partdev" ibs=512 obs=1M skip="$start" count="$size" conv=fsync + else + echo "Unable to find partition $part device, skipped." + fi +@@ -119,4 +119,16 @@ platform_do_upgrade() { get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync -+ + + platform_do_bootloader_upgrade "$diskdev" + local magic parttype=ext4 -+ magic=$(dd if="/dev/$diskdev" bs=8 count=1 skip=64 2>/dev/null) ++ magic="$(dd if="/dev/$diskdev" bs=8 count=1 skip=64 2>/dev/null)" + [ "$magic" = "EFI PART" ] || return 0 + if export_partdevice partdev 1; then -+ magic=$(dd if="/dev/$partdev" bs=1 count=3 skip=54 2>/dev/null) ++ magic="$(dd if="/dev/$partdev" bs=1 count=3 skip=54 2>/dev/null)" + [ "$magic" = "FAT" ] && parttype=vfat + mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt -+ set -- $(dd if=/dev/$diskdev bs=1 skip=1168 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') ++ set -- $(dd if="/dev/$diskdev" bs=1 skip=1168 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') + sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1$4$3$2$1-$6$5-$8$7-$9/ig" /mnt/boot/grub/grub.cfg + umount /mnt + fi - - platform_do_bootloader_upgrade "$diskdev" ++ } + +From b915dff5280cc48a2331f01961f2504b9b12f245 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= +Date: Tue, 24 Mar 2020 17:12:22 +0800 +Subject: [PATCH 5/8] grub2: grub-early.cfg auto detect efi platform +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: 李国 +--- + package/boot/grub2/files/grub-early.cfg | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/package/boot/grub2/files/grub-early.cfg b/package/boot/grub2/files/grub-early.cfg +index 4a5b5a60927..9e7cad47607 100644 +--- a/package/boot/grub2/files/grub-early.cfg ++++ b/package/boot/grub2/files/grub-early.cfg +@@ -1 +1,5 @@ +-configfile (hd0,msdos1)/boot/grub/grub.cfg ++if [ "${grub_platform}" = "efi" ]; then ++ configfile (hd0,gpt1)/boot/grub/grub.cfg ++else ++ configfile (hd0,msdos1)/boot/grub/grub.cfg ++fi + +From dce4fc3201395f886e496c3bb5f6ffd979558aa3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= +Date: Tue, 24 Mar 2020 17:13:27 +0800 +Subject: [PATCH 6/8] x86: add efi images + +--- + include/image.mk | 1 + + scripts/gen_image_generic.sh | 4 ++-- + target/linux/x86/image/Makefile | 34 +++++++++++++++++++++++++---- + target/linux/x86/image/grub-efi.cfg | 13 +++++++++++ + 4 files changed, 46 insertions(+), 6 deletions(-) + create mode 100644 target/linux/x86/image/grub-efi.cfg + +diff --git a/include/image.mk b/include/image.mk +index 8af5905c600..051a6206cef 100644 +--- a/include/image.mk ++++ b/include/image.mk +@@ -45,6 +45,7 @@ IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$ + IMG_ROOTFS:=$(IMG_PREFIX)-rootfs + IMG_COMBINED:=$(IMG_PREFIX)-combined + IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | cut -b1-8) ++IMG_PART_UUID:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/') + + MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt + +diff --git a/scripts/gen_image_generic.sh b/scripts/gen_image_generic.sh +index 1df4d0673b3..e45a8dd417e 100755 +--- a/scripts/gen_image_generic.sh ++++ b/scripts/gen_image_generic.sh +@@ -20,7 +20,7 @@ sect=63 + cyl=$(( (KERNELSIZE + ROOTFSSIZE) * 1024 * 1024 / (head * sect * 512))) + + # create partition table +-set $(ptgen -o "$OUTPUT" -h $head -s $sect ${EFI_SIGNATURE:+-g} -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE} ${EFI_SIGNATURE:+-G $EFI_SIGNATURE}) ++set $(ptgen -o "$OUTPUT" -h $head -s $sect ${UUID:+-g} -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE} ${UUID:+-G $UUID}) + + KERNELOFFSET="$(($1 / 512))" + KERNELSIZE="$2" +@@ -30,7 +30,7 @@ ROOTFSSIZE="$(($4 / 512))" + [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE" + dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc + +-if [ -n "$EFI_SIGNATURE" ]; then ++if [ -n "$UUID" ]; then + [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$(($ROOTFSOFFSET + $ROOTFSSIZE))" conv=notrunc count="$sect" + mkfs.fat -n kernel -C "$OUTPUT.kernel" -S 512 "$(($KERNELSIZE / 1024))" + mcopy -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/ +diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile +index aa80d77b978..efb0b1cff99 100644 +--- a/target/linux/x86/image/Makefile ++++ b/target/linux/x86/image/Makefile +@@ -38,9 +38,8 @@ endif + + ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME)) + ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02) +-EFI_SIGNATURE:=$(strip $(shell uuidgen | sed -r 's/[a-zA-Z0-9]{2}$$/00/')) + EFI_ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME)) +-EFI_ROOTPART:=$(if $(EFI_ROOTPART),$(EFI_ROOTPART),PARTUUID=$(shell echo $(EFI_SIGNATURE) | sed 's/00$$/02/')) ++EFI_ROOTPART:=$(if $(EFI_ROOTPART),$(EFI_ROOTPART),PARTUUID=$(shell echo $(IMG_PART_UUID) | sed 's/00$$/02/')) + + GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT)) + GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE)) +@@ -50,7 +49,8 @@ BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS)) + define Build/combined + $(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz + -$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/ +- PADDING="$(CONFIG_TARGET_IMAGES_PAD)" SIGNATURE="$(IMG_PART_SIGNATURE)" $(SCRIPT_DIR)/gen_image_generic.sh \ ++ PADDING="$(CONFIG_TARGET_IMAGES_PAD)" SIGNATURE="$(IMG_PART_SIGNATURE)" \ ++ $(if $(filter $(1),efi),UUID="$(IMG_PART_UUID)") $(SCRIPT_DIR)/gen_image_generic.sh \ + $@ \ + $(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \ + $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \ +@@ -64,6 +64,7 @@ define Build/grub-config + -e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \ + -e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \ + -e 's#@ROOTPART@#root=$(ROOTPART) rootwait#g' \ ++ -e 's#@EFI_ROOTPART@#root=$(EFI_ROOTPART) rootwait#g' \ + -e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \ + -e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \ + -e 's#@TITLE@#$(GRUB_TITLE)#g' \ +@@ -80,7 +81,7 @@ define Build/grub-install + $(STAGING_DIR_HOST)/bin/grub-bios-setup \ + -m "$@.grub2/device.map" \ + -d "$@.grub2" \ +- -r "hd0,msdos1" \ ++ -r "hd0,$(if $(filter $(1),efi),gpt1,msdos1)" \ + $@ + endef + +@@ -91,7 +92,9 @@ define Build/iso + $(STAGING_DIR_HOST)/lib/grub/grub2-iso/eltorito.img \ + > $@.boot/boot/grub/eltorito.img + -$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/ ++ $(if $(filter $(1),efi),$(CP) $(STAGING_DIR_HOST)/lib/grub/grub2-iso/efiboot.img $@.boot/boot/grub/) + mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \ ++ $(if $(filter $(1),efi),-boot-load-size 4 -c boot.cat -eltorito-alt-boot -e boot/grub/efiboot.img -no-emul-boot) \ + -o $@ $@.boot $(TARGET_DIR) + endef + +@@ -102,11 +105,23 @@ define Device/Default + IMAGE/combined.img.gz := append-rootfs | pad-extra 128k | grub-config pc | combined | grub-install | gzip + IMAGE/combined.vdi := append-rootfs | pad-extra 128k | grub-config pc | combined | grub-install | qemu-image vdi + IMAGE/combined.vmdk := append-rootfs | pad-extra 128k | grub-config pc | combined | grub-install | qemu-image vmdk ++ ARTIFACT/image-efi.iso := grub-config iso | iso efi ++ IMAGE/combined-efi.img := append-rootfs | pad-extra 128k | grub-config efi | combined efi | grub-install efi ++ IMAGE/combined-efi.img.gz := append-rootfs | pad-extra 128k | grub-config efi | combined efi | grub-install efi | gzip ++ IMAGE/combined-efi.vdi := append-rootfs | pad-extra 128k | grub-config efi | combined efi | grub-install efi | qemu-image vdi ++ IMAGE/combined-efi.vmdk := append-rootfs | pad-extra 128k | grub-config efi | combined efi | grub-install efi | qemu-image vmdk + ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y) + IMAGES := combined.img.gz + else + IMAGES := combined.img + endif ++ ifeq $(CONFIG_EFI_IMAGES) ++ ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y) ++ IMAGES += combined-efi.img.gz ++ else ++ IMAGES += combined-efi.img ++ endif ++ endif + KERNEL := kernel-bin + KERNEL_INSTALL := 1 + KERNEL_NAME := bzImage +@@ -119,6 +134,17 @@ define Device/Default + ifeq ($(CONFIG_VMDK_IMAGES),y) + IMAGES += combined.vmdk + endif ++ ifeq $(CONFIG_EFI_IMAGES) ++ ifeq ($(CONFIG_ISO_IMAGES),y) ++ ARTIFACTS += image-efi.iso ++ endif ++ ifeq ($(CONFIG_VDI_IMAGES),y) ++ IMAGES += combined-efi.vdi ++ endif ++ ifeq ($(CONFIG_VMDK_IMAGES),y) ++ IMAGES += combined-efi.vmdk ++ endif ++ endif + endef + + $(eval $(call Image/gzip-ext4-padded-squashfs)) +diff --git a/target/linux/x86/image/grub-efi.cfg b/target/linux/x86/image/grub-efi.cfg +new file mode 100644 +index 00000000000..f3f6a02c021 +--- /dev/null ++++ b/target/linux/x86/image/grub-efi.cfg +@@ -0,0 +1,13 @@ ++@SERIAL_CONFIG@ ++@TERMINAL_CONFIG@ ++ ++set default="0" ++set timeout="@TIMEOUT@" ++set root='(hd0,gpt1)' ++ ++menuentry "@TITLE@" { ++ linux /boot/vmlinuz @EFI_ROOTPART@ @CMDLINE@ noinitrd ++} ++menuentry "@TITLE@ (failsafe)" { ++ linux /boot/vmlinuz failsafe=true @EFI_ROOTPART@ @CMDLINE@ noinitrd ++} + +From 317bb3e99c4ad67e6e5680d0fbf03d65294aac2f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= +Date: Tue, 24 Mar 2020 18:01:39 +0800 +Subject: [PATCH 7/8] grub2: fix path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: 李国 +--- + package/boot/grub2/grub2/Makefile | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/package/boot/grub2/grub2/Makefile b/package/boot/grub2/grub2/Makefile +index 7126beab4cf..3302838d719 100644 +--- a/package/boot/grub2/grub2/Makefile ++++ b/package/boot/grub2/grub2/Makefile +@@ -44,7 +44,7 @@ define Host/Install + -d $(STAGING_DIR_HOST)/lib/grub/i386-pc \ + -p /boot/grub \ + -O i386-pc \ +- -c ./files/grub-early.cfg \ ++ -c ../files/grub-early.cfg \ + -o $(STAGING_DIR_HOST)/lib/grub/grub2-generic/core.img \ + at_keyboard biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga + +@@ -53,7 +53,7 @@ define Host/Install + -d $(STAGING_DIR_HOST)/lib/grub/i386-pc \ + -p /boot/grub \ + -O i386-pc \ +- -c ./files/grub-early.cfg \ ++ -c ../files/grub-early.cfg \ + -o $(STAGING_DIR_HOST)/lib/grub/grub2-iso/eltorito.img \ + at_keyboard biosdisk boot chain configfile iso9660 linux ls part_msdos reboot serial vga + +@@ -62,7 +62,7 @@ define Host/Install + -d $(STAGING_DIR_HOST)/lib/grub/i386-pc \ + -p /boot/grub \ + -O i386-pc \ +- -c ./files/grub-early.cfg \ ++ -c ../files/grub-early.cfg \ + -o $(STAGING_DIR_HOST)/lib/grub/grub2-legacy/core.img \ + biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga + endef + +From 784fcc94242d146f2ef2c31e292ace8816985d62 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= +Date: Tue, 24 Mar 2020 18:02:57 +0800 +Subject: [PATCH 8/8] x86: fix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: 李国 +--- + target/linux/x86/image/Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile +index efb0b1cff99..ff964cde8ab 100644 +--- a/target/linux/x86/image/Makefile ++++ b/target/linux/x86/image/Makefile +@@ -115,7 +115,7 @@ define Device/Default + else + IMAGES := combined.img + endif +- ifeq $(CONFIG_EFI_IMAGES) ++ ifeq ($(CONFIG_EFI_IMAGES),y) + ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y) + IMAGES += combined-efi.img.gz + else +@@ -134,7 +134,7 @@ define Device/Default + ifeq ($(CONFIG_VMDK_IMAGES),y) + IMAGES += combined.vmdk + endif +- ifeq $(CONFIG_EFI_IMAGES) ++ ifeq ($(CONFIG_EFI_IMAGES),y) + ifeq ($(CONFIG_ISO_IMAGES),y) + ARTIFACTS += image-efi.iso + endif From 64b7a85cbb74e3fdd6de3f69742b9798da538db6 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 27 Mar 2020 12:12:28 +0100 Subject: [PATCH 04/76] Patch is used instead of replacing file --- .../package/kernel/linux/modules/netfilter.mk | 1169 ----------------- 1 file changed, 1169 deletions(-) delete mode 100644 root/package/kernel/linux/modules/netfilter.mk diff --git a/root/package/kernel/linux/modules/netfilter.mk b/root/package/kernel/linux/modules/netfilter.mk deleted file mode 100644 index 2060760b..00000000 --- a/root/package/kernel/linux/modules/netfilter.mk +++ /dev/null @@ -1,1169 +0,0 @@ - -# -# Copyright (C) 2006-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -NF_MENU:=Netfilter Extensions -NF_KMOD:=1 -include $(INCLUDE_DIR)/netfilter.mk - - -define KernelPackage/nf-reject - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter IPv4 reject support - KCONFIG:= \ - CONFIG_NETFILTER=y \ - CONFIG_NETFILTER_ADVANCED=y \ - $(KCONFIG_NF_REJECT) - FILES:=$(foreach mod,$(NF_REJECT-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_REJECT-m))) -endef - -$(eval $(call KernelPackage,nf-reject)) - - -define KernelPackage/nf-reject6 - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter IPv6 reject support - KCONFIG:= \ - CONFIG_NETFILTER=y \ - CONFIG_NETFILTER_ADVANCED=y \ - $(KCONFIG_NF_REJECT6) - DEPENDS:=@IPV6 - FILES:=$(foreach mod,$(NF_REJECT6-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_REJECT6-m))) -endef - -$(eval $(call KernelPackage,nf-reject6)) - - -define KernelPackage/nf-ipt - SUBMENU:=$(NF_MENU) - TITLE:=Iptables core - KCONFIG:=$(KCONFIG_NF_IPT) - FILES:=$(foreach mod,$(NF_IPT-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_IPT-m))) -endef - -$(eval $(call KernelPackage,nf-ipt)) - - -define KernelPackage/nf-ipt6 - SUBMENU:=$(NF_MENU) - TITLE:=Ip6tables core - KCONFIG:=$(KCONFIG_NF_IPT6) - FILES:=$(foreach mod,$(NF_IPT6-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_IPT6-m))) - DEPENDS:=+kmod-nf-ipt -endef - -$(eval $(call KernelPackage,nf-ipt6)) - - - -define KernelPackage/ipt-core - SUBMENU:=$(NF_MENU) - TITLE:=Iptables core - KCONFIG:=$(KCONFIG_IPT_CORE) - FILES:=$(foreach mod,$(IPT_CORE-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CORE-m))) - DEPENDS:=+kmod-nf-reject +kmod-nf-ipt -endef - -define KernelPackage/ipt-core/description - Netfilter core kernel modules - Includes: - - comment - - limit - - LOG - - mac - - multiport - - REJECT - - TCPMSS -endef - -$(eval $(call KernelPackage,ipt-core)) - - -define KernelPackage/nf-conntrack - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter connection tracking - KCONFIG:= \ - CONFIG_NETFILTER=y \ - CONFIG_NETFILTER_ADVANCED=y \ - CONFIG_NF_CONNTRACK_MARK=y \ - CONFIG_NF_CONNTRACK_ZONES=y \ - $(KCONFIG_NF_CONNTRACK) - FILES:=$(foreach mod,$(NF_CONNTRACK-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_CONNTRACK-m))) -endef - -define KernelPackage/nf-conntrack/install - $(INSTALL_DIR) $(1)/etc/sysctl.d - $(INSTALL_DATA) ./files/sysctl-nf-conntrack.conf $(1)/etc/sysctl.d/11-nf-conntrack.conf -endef - -$(eval $(call KernelPackage,nf-conntrack)) - - -define KernelPackage/nf-conntrack6 - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter IPv6 connection tracking - KCONFIG:=$(KCONFIG_NF_CONNTRACK6) - DEPENDS:=@IPV6 +kmod-nf-conntrack - FILES:=$(foreach mod,$(NF_CONNTRACK6-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_CONNTRACK6-m))) -endef - -$(eval $(call KernelPackage,nf-conntrack6)) - - -define KernelPackage/nf-nat - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter NAT - KCONFIG:=$(KCONFIG_NF_NAT) - DEPENDS:=+kmod-nf-conntrack - FILES:=$(foreach mod,$(NF_NAT-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NAT-m))) -endef - -$(eval $(call KernelPackage,nf-nat)) - - -define KernelPackage/nf-nat6 - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter IPV6-NAT - KCONFIG:=$(KCONFIG_NF_NAT6) - DEPENDS:=+kmod-nf-conntrack6 +kmod-nf-nat - FILES:=$(foreach mod,$(NF_NAT6-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NAT6-m))) -endef - -$(eval $(call KernelPackage,nf-nat6)) - - -define KernelPackage/nf-flow - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter flowtable support - KCONFIG:= \ - CONFIG_NETFILTER_INGRESS=y \ - CONFIG_NF_FLOW_TABLE \ - CONFIG_NF_FLOW_TABLE_HW - DEPENDS:=+kmod-nf-conntrack - FILES:= \ - $(LINUX_DIR)/net/netfilter/nf_flow_table.ko \ - $(LINUX_DIR)/net/netfilter/nf_flow_table_hw.ko - AUTOLOAD:=$(call AutoProbe,nf_flow_table nf_flow_table_hw) -endef - -$(eval $(call KernelPackage,nf-flow)) - - -define AddDepends/ipt - SUBMENU:=$(NF_MENU) - DEPENDS+= +kmod-ipt-core $(1) -endef - - -define KernelPackage/ipt-conntrack - TITLE:=Basic connection tracking modules - KCONFIG:=$(KCONFIG_IPT_CONNTRACK) - FILES:=$(foreach mod,$(IPT_CONNTRACK-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CONNTRACK-m))) - $(call AddDepends/ipt,+kmod-nf-conntrack) -endef - -define KernelPackage/ipt-conntrack/description - Netfilter (IPv4) kernel modules for connection tracking - Includes: - - conntrack - - defrag - - iptables_raw - - NOTRACK - - state -endef - -$(eval $(call KernelPackage,ipt-conntrack)) - - -define KernelPackage/ipt-conntrack-extra - TITLE:=Extra connection tracking modules - KCONFIG:=$(KCONFIG_IPT_CONNTRACK_EXTRA) - FILES:=$(foreach mod,$(IPT_CONNTRACK_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CONNTRACK_EXTRA-m))) - $(call AddDepends/ipt,+kmod-ipt-conntrack) -endef - -define KernelPackage/ipt-conntrack-extra/description - Netfilter (IPv4) extra kernel modules for connection tracking - Includes: - - connbytes - - connmark/CONNMARK - - conntrack - - helper - - recent -endef - -$(eval $(call KernelPackage,ipt-conntrack-extra)) - -define KernelPackage/ipt-conntrack-label - TITLE:=Module for handling connection tracking labels - KCONFIG:=$(KCONFIG_IPT_CONNTRACK_LABEL) - FILES:=$(foreach mod,$(IPT_CONNTRACK_LABEL-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CONNTRACK_LABEL-m))) - $(call AddDepends/ipt,+kmod-ipt-conntrack) -endef - -define KernelPackage/ipt-conntrack-label/description - Netfilter (IPv4) module for handling connection tracking labels - Includes: - - connlabel -endef - -$(eval $(call KernelPackage,ipt-conntrack-label)) - -define KernelPackage/ipt-filter - TITLE:=Modules for packet content inspection - KCONFIG:=$(KCONFIG_IPT_FILTER) - FILES:=$(foreach mod,$(IPT_FILTER-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_FILTER-m))) - $(call AddDepends/ipt,+kmod-lib-textsearch +kmod-ipt-conntrack) -endef - -define KernelPackage/ipt-filter/description - Netfilter (IPv4) kernel modules for packet content inspection - Includes: - - string - - bpf -endef - -$(eval $(call KernelPackage,ipt-filter)) - - -define KernelPackage/ipt-offload - TITLE:=Netfilter routing/NAT offload support - KCONFIG:=$(KCONFIG_IPT_FLOW) - FILES:=$(foreach mod,$(IPT_FLOW-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_FLOW-m))) - $(call AddDepends/ipt,+kmod-nf-flow) -endef - -$(eval $(call KernelPackage,ipt-offload)) - - -define KernelPackage/ipt-ipopt - TITLE:=Modules for matching/changing IP packet options - KCONFIG:=$(KCONFIG_IPT_IPOPT) - FILES:=$(foreach mod,$(IPT_IPOPT-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPOPT-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-ipopt/description - Netfilter (IPv4) modules for matching/changing IP packet options - Includes: - - CLASSIFY - - dscp/DSCP - - ecn/ECN - - hl/HL - - length - - mark/MARK - - statistic - - tcpmss - - time - - ttl/TTL - - unclean -endef - -$(eval $(call KernelPackage,ipt-ipopt)) - - -define KernelPackage/ipt-ipsec - TITLE:=Modules for matching IPSec packets - KCONFIG:=$(KCONFIG_IPT_IPSEC) - FILES:=$(foreach mod,$(IPT_IPSEC-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPSEC-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-ipsec/description - Netfilter (IPv4) modules for matching IPSec packets - Includes: - - ah - - esp - - policy -endef - -$(eval $(call KernelPackage,ipt-ipsec)) - -IPSET_MODULES:= \ - ipset/ip_set \ - ipset/ip_set_bitmap_ip \ - ipset/ip_set_bitmap_ipmac \ - ipset/ip_set_bitmap_port \ - ipset/ip_set_hash_ip \ - ipset/ip_set_hash_ipmark \ - ipset/ip_set_hash_ipport \ - ipset/ip_set_hash_ipportip \ - ipset/ip_set_hash_ipportnet \ - ipset/ip_set_hash_mac \ - ipset/ip_set_hash_netportnet \ - ipset/ip_set_hash_net \ - ipset/ip_set_hash_netnet \ - ipset/ip_set_hash_netport \ - ipset/ip_set_hash_netiface \ - ipset/ip_set_list_set \ - xt_set - -define KernelPackage/ipt-ipset - SUBMENU:=Netfilter Extensions - TITLE:=IPset netfilter modules - DEPENDS+= +kmod-ipt-core +kmod-nfnetlink - KCONFIG:= \ - CONFIG_IP_SET \ - CONFIG_IP_SET_MAX=256 \ - CONFIG_NETFILTER_XT_SET \ - CONFIG_IP_SET_BITMAP_IP \ - CONFIG_IP_SET_BITMAP_IPMAC \ - CONFIG_IP_SET_BITMAP_PORT \ - CONFIG_IP_SET_HASH_IP \ - CONFIG_IP_SET_HASH_IPMAC \ - CONFIG_IP_SET_HASH_IPMARK \ - CONFIG_IP_SET_HASH_IPPORT \ - CONFIG_IP_SET_HASH_IPPORTIP \ - CONFIG_IP_SET_HASH_IPPORTNET \ - CONFIG_IP_SET_HASH_MAC \ - CONFIG_IP_SET_HASH_NET \ - CONFIG_IP_SET_HASH_NETNET \ - CONFIG_IP_SET_HASH_NETIFACE \ - CONFIG_IP_SET_HASH_NETPORT \ - CONFIG_IP_SET_HASH_NETPORTNET \ - CONFIG_IP_SET_LIST_SET \ - CONFIG_NET_EMATCH_IPSET=n - FILES:=$(foreach mod,$(IPSET_MODULES),$(LINUX_DIR)/net/netfilter/$(mod).ko) - AUTOLOAD:=$(call AutoLoad,49,$(notdir $(IPSET_MODULES))) -endef -$(eval $(call KernelPackage,ipt-ipset)) - - -IPVS_MODULES:= \ - ipvs/ip_vs \ - ipvs/ip_vs_lc \ - ipvs/ip_vs_wlc \ - ipvs/ip_vs_rr \ - ipvs/ip_vs_wrr \ - ipvs/ip_vs_lblc \ - ipvs/ip_vs_lblcr \ - ipvs/ip_vs_dh \ - ipvs/ip_vs_sh \ - ipvs/ip_vs_fo \ - ipvs/ip_vs_ovf \ - ipvs/ip_vs_nq \ - ipvs/ip_vs_sed \ - xt_ipvs - -define KernelPackage/nf-ipvs - SUBMENU:=Netfilter Extensions - TITLE:=IP Virtual Server modules - DEPENDS:=@IPV6 +kmod-lib-crc32c +kmod-ipt-conntrack +kmod-nf-conntrack +LINUX_4_14:kmod-nf-conntrack6 - KCONFIG:= \ - CONFIG_IP_VS \ - CONFIG_IP_VS_IPV6=y \ - CONFIG_IP_VS_DEBUG=n \ - CONFIG_IP_VS_PROTO_TCP=y \ - CONFIG_IP_VS_PROTO_UDP=y \ - CONFIG_IP_VS_PROTO_AH_ESP=y \ - CONFIG_IP_VS_PROTO_ESP=y \ - CONFIG_IP_VS_PROTO_AH=y \ - CONFIG_IP_VS_PROTO_SCTP=y \ - CONFIG_IP_VS_TAB_BITS=12 \ - CONFIG_IP_VS_RR \ - CONFIG_IP_VS_WRR \ - CONFIG_IP_VS_LC \ - CONFIG_IP_VS_WLC \ - CONFIG_IP_VS_FO \ - CONFIG_IP_VS_OVF \ - CONFIG_IP_VS_LBLC \ - CONFIG_IP_VS_LBLCR \ - CONFIG_IP_VS_DH \ - CONFIG_IP_VS_SH \ - CONFIG_IP_VS_SED \ - CONFIG_IP_VS_NQ \ - CONFIG_IP_VS_SH_TAB_BITS=8 \ - CONFIG_IP_VS_NFCT=y \ - CONFIG_NETFILTER_XT_MATCH_IPVS - FILES:=$(foreach mod,$(IPVS_MODULES),$(LINUX_DIR)/net/netfilter/$(mod).ko) - $(call AddDepends/ipt,+kmod-ipt-conntrack,+kmod-nf-conntrack) -endef - -define KernelPackage/nf-ipvs/description - IPVS (IP Virtual Server) implements transport-layer load balancing inside - the Linux kernel so called Layer-4 switching. -endef - -$(eval $(call KernelPackage,nf-ipvs)) - - -define KernelPackage/nf-ipvs-ftp - SUBMENU:=$(NF_MENU) - TITLE:=Virtual Server FTP protocol support - KCONFIG:=CONFIG_IP_VS_FTP - DEPENDS:=kmod-nf-ipvs +kmod-nf-nat +kmod-nf-nathelper - FILES:=$(LINUX_DIR)/net/netfilter/ipvs/ip_vs_ftp.ko -endef - -define KernelPackage/nf-ipvs-ftp/description - In the virtual server via Network Address Translation, - the IP address and port number of real servers cannot be sent to - clients in ftp connections directly, so FTP protocol helper is - required for tracking the connection and mangling it back to that of - virtual service. -endef - -$(eval $(call KernelPackage,nf-ipvs-ftp)) - - -define KernelPackage/nf-ipvs-sip - SUBMENU:=$(NF_MENU) - TITLE:=Virtual Server SIP protocol support - KCONFIG:=CONFIG_IP_VS_PE_SIP - DEPENDS:=kmod-nf-ipvs +kmod-nf-nathelper-extra - FILES:=$(LINUX_DIR)/net/netfilter/ipvs/ip_vs_pe_sip.ko -endef - -define KernelPackage/nf-ipvs-sip/description - Allow persistence based on the SIP Call-ID -endef - -$(eval $(call KernelPackage,nf-ipvs-sip)) - - -define KernelPackage/ipt-nat - TITLE:=Basic NAT targets - KCONFIG:=$(KCONFIG_IPT_NAT) - FILES:=$(foreach mod,$(IPT_NAT-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NAT-m))) - $(call AddDepends/ipt,+kmod-nf-nat) -endef - -define KernelPackage/ipt-nat/description - Netfilter (IPv4) kernel modules for basic NAT targets - Includes: - - MASQUERADE -endef - -$(eval $(call KernelPackage,ipt-nat)) - - -define KernelPackage/ipt-raw - TITLE:=Netfilter IPv4 raw table support - KCONFIG:=CONFIG_IP_NF_RAW - FILES:=$(LINUX_DIR)/net/ipv4/netfilter/iptable_raw.ko - AUTOLOAD:=$(call AutoProbe,iptable_raw) - $(call AddDepends/ipt) -endef - -$(eval $(call KernelPackage,ipt-raw)) - - -define KernelPackage/ipt-raw6 - TITLE:=Netfilter IPv6 raw table support - KCONFIG:=CONFIG_IP6_NF_RAW - FILES:=$(LINUX_DIR)/net/ipv6/netfilter/ip6table_raw.ko - AUTOLOAD:=$(call AutoProbe,ip6table_raw) - $(call AddDepends/ipt,+kmod-ip6tables) -endef - -$(eval $(call KernelPackage,ipt-raw6)) - - -define KernelPackage/ipt-nat6 - TITLE:=IPv6 NAT targets - KCONFIG:=$(KCONFIG_IPT_NAT6) - FILES:= \ - $(LINUX_DIR)/net/ipv6/netfilter/ip6table_nat.ko \ - $(LINUX_DIR)/net/ipv6/netfilter/ip6t_NPT.ko - AUTOLOAD:=$(call AutoLoad,43,$(notdir $(IPT_NAT6-m))) - $(call AddDepends/ipt,+kmod-nf-nat6) - $(call AddDepends/ipt,+kmod-ipt-conntrack) - $(call AddDepends/ipt,+kmod-ipt-nat) - $(call AddDepends/ipt,+kmod-ip6tables) -endef - -define KernelPackage/ipt-nat6/description - Netfilter (IPv6) kernel modules for NAT targets -endef - -$(eval $(call KernelPackage,ipt-nat6)) - - -define KernelPackage/ipt-nat-extra - TITLE:=Extra NAT targets - KCONFIG:=$(KCONFIG_IPT_NAT_EXTRA) - FILES:=$(foreach mod,$(IPT_NAT_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NAT_EXTRA-m))) - $(call AddDepends/ipt,+kmod-ipt-nat) -endef - -define KernelPackage/ipt-nat-extra/description - Netfilter (IPv4) kernel modules for extra NAT targets - Includes: - - NETMAP - - REDIRECT -endef - -$(eval $(call KernelPackage,ipt-nat-extra)) - - -define KernelPackage/nf-nathelper - SUBMENU:=$(NF_MENU) - TITLE:=Basic Conntrack and NAT helpers - KCONFIG:=$(KCONFIG_NF_NATHELPER) - FILES:=$(foreach mod,$(NF_NATHELPER-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NATHELPER-m))) - DEPENDS:=+kmod-nf-nat -endef - -define KernelPackage/nf-nathelper/description - Default Netfilter (IPv4) Conntrack and NAT helpers - Includes: - - ftp -endef - -$(eval $(call KernelPackage,nf-nathelper)) - - -define KernelPackage/nf-nathelper-extra - SUBMENU:=$(NF_MENU) - TITLE:=Extra Conntrack and NAT helpers - KCONFIG:=$(KCONFIG_NF_NATHELPER_EXTRA) - FILES:=$(foreach mod,$(NF_NATHELPER_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NATHELPER_EXTRA-m))) - DEPENDS:=+kmod-nf-nat +kmod-lib-textsearch +kmod-ipt-raw +!LINUX_4_14:kmod-asn1-decoder -endef - -define KernelPackage/nf-nathelper-extra/description - Extra Netfilter (IPv4) Conntrack and NAT helpers - Includes: - - amanda - - h323 - - irc - - mms - - pptp - - proto_gre - - sip - - snmp_basic - - tftp - - broadcast -endef - -$(eval $(call KernelPackage,nf-nathelper-extra)) - - -define KernelPackage/ipt-ulog - TITLE:=Module for user-space packet logging - KCONFIG:=$(KCONFIG_IPT_ULOG) - FILES:=$(foreach mod,$(IPT_ULOG-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_ULOG-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-ulog/description - Netfilter (IPv4) module for user-space packet logging - Includes: - - ULOG -endef - -$(eval $(call KernelPackage,ipt-ulog)) - - -define KernelPackage/ipt-nflog - TITLE:=Module for user-space packet logging - KCONFIG:=$(KCONFIG_IPT_NFLOG) - FILES:=$(foreach mod,$(IPT_NFLOG-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NFLOG-m))) - $(call AddDepends/ipt,+kmod-nfnetlink-log) -endef - -define KernelPackage/ipt-nflog/description - Netfilter module for user-space packet logging - Includes: - - NFLOG -endef - -$(eval $(call KernelPackage,ipt-nflog)) - - -define KernelPackage/ipt-nfqueue - TITLE:=Module for user-space packet queuing - KCONFIG:=$(KCONFIG_IPT_NFQUEUE) - FILES:=$(foreach mod,$(IPT_NFQUEUE-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NFQUEUE-m))) - $(call AddDepends/ipt,+kmod-nfnetlink-queue) -endef - -define KernelPackage/ipt-nfqueue/description - Netfilter module for user-space packet queuing - Includes: - - NFQUEUE -endef - -$(eval $(call KernelPackage,ipt-nfqueue)) - - -define KernelPackage/ipt-debug - TITLE:=Module for debugging/development - KCONFIG:=$(KCONFIG_IPT_DEBUG) - FILES:=$(foreach mod,$(IPT_DEBUG-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_DEBUG-m))) - $(call AddDepends/ipt,+kmod-ipt-raw +IPV6:kmod-ipt-raw6) -endef - -define KernelPackage/ipt-debug/description - Netfilter modules for debugging/development of the firewall - Includes: - - TRACE -endef - -$(eval $(call KernelPackage,ipt-debug)) - - -define KernelPackage/ipt-led - TITLE:=Module to trigger a LED with a Netfilter rule - KCONFIG:=$(KCONFIG_IPT_LED) - FILES:=$(foreach mod,$(IPT_LED-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_LED-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-led/description - Netfilter target to trigger a LED when a network packet is matched. -endef - -$(eval $(call KernelPackage,ipt-led)) - -define KernelPackage/ipt-tproxy - TITLE:=Transparent proxying support - DEPENDS+=+kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +IPV6:kmod-ip6tables - KCONFIG:=$(KCONFIG_IPT_TPROXY) - FILES:=$(foreach mod,$(IPT_TPROXY-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_TPROXY-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-tproxy/description - Kernel modules for Transparent Proxying -endef - -$(eval $(call KernelPackage,ipt-tproxy)) - -define KernelPackage/ipt-tee - TITLE:=TEE support - DEPENDS:=+kmod-ipt-conntrack - KCONFIG:=$(KCONFIG_IPT_TEE) - FILES:=$(foreach mod,$(IPT_TEE-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir nf_tee $(IPT_TEE-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-tee/description - Kernel modules for TEE -endef - -$(eval $(call KernelPackage,ipt-tee)) - - -define KernelPackage/ipt-u32 - TITLE:=U32 support - KCONFIG:=$(KCONFIG_IPT_U32) - FILES:=$(foreach mod,$(IPT_U32-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir nf_tee $(IPT_U32-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-u32/description - Kernel modules for U32 -endef - -$(eval $(call KernelPackage,ipt-u32)) - -define KernelPackage/ipt-checksum - TITLE:=CHECKSUM support - KCONFIG:=$(KCONFIG_IPT_CHECKSUM) - FILES:=$(foreach mod,$(IPT_CHECKSUM-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CHECKSUM-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-checksum/description - Kernel modules for CHECKSUM fillin target -endef - -$(eval $(call KernelPackage,ipt-checksum)) - - -define KernelPackage/ipt-iprange - TITLE:=Module for matching ip ranges - KCONFIG:=$(KCONFIG_IPT_IPRANGE) - FILES:=$(foreach mod,$(IPT_IPRANGE-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPRANGE-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-iprange/description - Netfilter (IPv4) module for matching ip ranges - Includes: - - iprange -endef - -$(eval $(call KernelPackage,ipt-iprange)) - -define KernelPackage/ipt-cluster - TITLE:=Module for matching cluster - KCONFIG:=$(KCONFIG_IPT_CLUSTER) - FILES:=$(foreach mod,$(IPT_CLUSTER-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CLUSTER-m))) - $(call AddDepends/ipt,+kmod-nf-conntrack) -endef - -define KernelPackage/ipt-cluster/description - Netfilter (IPv4/IPv6) module for matching cluster - This option allows you to build work-load-sharing clusters of - network servers/stateful firewalls without having a dedicated - load-balancing router/server/switch. Basically, this match returns - true when the packet must be handled by this cluster node. Thus, - all nodes see all packets and this match decides which node handles - what packets. The work-load sharing algorithm is based on source - address hashing. - - This module is usable for ipv4 and ipv6. - - To use it also enable iptables-mod-cluster - - see `iptables -m cluster --help` for more information. -endef - -$(eval $(call KernelPackage,ipt-cluster)) - -define KernelPackage/ipt-clusterip - TITLE:=Module for CLUSTERIP - KCONFIG:=$(KCONFIG_IPT_CLUSTERIP) - FILES:=$(foreach mod,$(IPT_CLUSTERIP-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CLUSTERIP-m))) - $(call AddDepends/ipt,+kmod-nf-conntrack) -endef - -define KernelPackage/ipt-clusterip/description - Netfilter (IPv4-only) module for CLUSTERIP - The CLUSTERIP target allows you to build load-balancing clusters of - network servers without having a dedicated load-balancing - router/server/switch. - - To use it also enable iptables-mod-clusterip - - see `iptables -j CLUSTERIP --help` for more information. -endef - -$(eval $(call KernelPackage,ipt-clusterip)) - - -define KernelPackage/ipt-extra - TITLE:=Extra modules - KCONFIG:=$(KCONFIG_IPT_EXTRA) - FILES:=$(foreach mod,$(IPT_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_EXTRA-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-extra/description - Other Netfilter (IPv4) kernel modules - Includes: - - addrtype - - owner - - pkttype - - quota -endef - -$(eval $(call KernelPackage,ipt-extra)) - - -define KernelPackage/ipt-physdev - TITLE:=physdev module - KCONFIG:=$(KCONFIG_IPT_PHYSDEV) - FILES:=$(foreach mod,$(IPT_PHYSDEV-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_PHYSDEV-m))) - $(call AddDepends/ipt,+kmod-br-netfilter) -endef - -define KernelPackage/ipt-physdev/description - The iptables physdev kernel module -endef - -$(eval $(call KernelPackage,ipt-physdev)) - - -define KernelPackage/ip6tables - SUBMENU:=$(NF_MENU) - TITLE:=IPv6 modules - DEPENDS:=+kmod-nf-reject6 +kmod-nf-ipt6 +kmod-ipt-core - KCONFIG:=$(KCONFIG_IPT_IPV6) - FILES:=$(foreach mod,$(IPT_IPV6-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoLoad,42,$(notdir $(IPT_IPV6-m))) -endef - -define KernelPackage/ip6tables/description - Netfilter IPv6 firewalling support -endef - -$(eval $(call KernelPackage,ip6tables)) - -define KernelPackage/ip6tables-extra - SUBMENU:=$(NF_MENU) - TITLE:=Extra IPv6 modules - DEPENDS:=+kmod-ip6tables - KCONFIG:=$(KCONFIG_IPT_IPV6_EXTRA) - FILES:=$(foreach mod,$(IPT_IPV6_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoLoad,43,$(notdir $(IPT_IPV6_EXTRA-m))) -endef - -define KernelPackage/ip6tables-extra/description - Netfilter IPv6 extra header matching modules -endef - -$(eval $(call KernelPackage,ip6tables-extra)) - -ARP_MODULES = arp_tables arpt_mangle arptable_filter -define KernelPackage/arptables - SUBMENU:=$(NF_MENU) - TITLE:=ARP firewalling modules - DEPENDS:=+kmod-ipt-core - FILES:=$(LINUX_DIR)/net/ipv4/netfilter/arp*.ko - KCONFIG:=CONFIG_IP_NF_ARPTABLES \ - CONFIG_IP_NF_ARPFILTER \ - CONFIG_IP_NF_ARP_MANGLE - AUTOLOAD:=$(call AutoProbe,$(ARP_MODULES)) -endef - -define KernelPackage/arptables/description - Kernel modules for ARP firewalling -endef - -$(eval $(call KernelPackage,arptables)) - - -define KernelPackage/br-netfilter - SUBMENU:=$(NF_MENU) - TITLE:=Bridge netfilter support modules - DEPENDS:=+kmod-ipt-core - FILES:=$(LINUX_DIR)/net/bridge/br_netfilter.ko - KCONFIG:=CONFIG_BRIDGE_NETFILTER - AUTOLOAD:=$(call AutoProbe,br_netfilter) -endef - -define KernelPackage/br-netfilter/install - $(INSTALL_DIR) $(1)/etc/sysctl.d - $(INSTALL_DATA) ./files/sysctl-br-netfilter.conf $(1)/etc/sysctl.d/11-br-netfilter.conf -endef - -$(eval $(call KernelPackage,br-netfilter)) - - -define KernelPackage/ebtables - SUBMENU:=$(NF_MENU) - TITLE:=Bridge firewalling modules - DEPENDS:=+kmod-ipt-core - FILES:=$(foreach mod,$(EBTABLES-m),$(LINUX_DIR)/net/$(mod).ko) - KCONFIG:=$(KCONFIG_EBTABLES) - AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES-m))) -endef - -define KernelPackage/ebtables/description - ebtables is a general, extensible frame/packet identification - framework. It provides you to do Ethernet - filtering/NAT/brouting on the Ethernet bridge. -endef - -$(eval $(call KernelPackage,ebtables)) - - -define AddDepends/ebtables - SUBMENU:=$(NF_MENU) - DEPENDS+= +kmod-ebtables $(1) -endef - - -define KernelPackage/ebtables-ipv4 - TITLE:=ebtables: IPv4 support - FILES:=$(foreach mod,$(EBTABLES_IP4-m),$(LINUX_DIR)/net/$(mod).ko) - KCONFIG:=$(KCONFIG_EBTABLES_IP4) - AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_IP4-m))) - $(call AddDepends/ebtables) -endef - -define KernelPackage/ebtables-ipv4/description - This option adds the IPv4 support to ebtables, which allows basic - IPv4 header field filtering, ARP filtering as well as SNAT, DNAT targets. -endef - -$(eval $(call KernelPackage,ebtables-ipv4)) - - -define KernelPackage/ebtables-ipv6 - TITLE:=ebtables: IPv6 support - FILES:=$(foreach mod,$(EBTABLES_IP6-m),$(LINUX_DIR)/net/$(mod).ko) - KCONFIG:=$(KCONFIG_EBTABLES_IP6) - AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_IP6-m))) - $(call AddDepends/ebtables) -endef - -define KernelPackage/ebtables-ipv6/description - This option adds the IPv6 support to ebtables, which allows basic - IPv6 header field filtering and target support. -endef - -$(eval $(call KernelPackage,ebtables-ipv6)) - - -define KernelPackage/ebtables-watchers - TITLE:=ebtables: watchers support - FILES:=$(foreach mod,$(EBTABLES_WATCHERS-m),$(LINUX_DIR)/net/$(mod).ko) - KCONFIG:=$(KCONFIG_EBTABLES_WATCHERS) - AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_WATCHERS-m))) - $(call AddDepends/ebtables) -endef - -define KernelPackage/ebtables-watchers/description - This option adds the log watchers, that you can use in any rule - in any ebtables table. -endef - -$(eval $(call KernelPackage,ebtables-watchers)) - - -define KernelPackage/nfnetlink - SUBMENU:=$(NF_MENU) - TITLE:=Netlink-based userspace interface - FILES:=$(foreach mod,$(NFNETLINK-m),$(LINUX_DIR)/net/$(mod).ko) - KCONFIG:=$(KCONFIG_NFNETLINK) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK-m))) -endef - -define KernelPackage/nfnetlink/description - Kernel modules support for a netlink-based userspace interface -endef - -$(eval $(call KernelPackage,nfnetlink)) - - -define AddDepends/nfnetlink - SUBMENU:=$(NF_MENU) - DEPENDS+=+kmod-nfnetlink $(1) -endef - - -define KernelPackage/nfnetlink-log - TITLE:=Netfilter LOG over NFNETLINK interface - FILES:=$(foreach mod,$(NFNETLINK_LOG-m),$(LINUX_DIR)/net/$(mod).ko) - KCONFIG:=$(KCONFIG_NFNETLINK_LOG) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK_LOG-m))) - $(call AddDepends/nfnetlink) -endef - -define KernelPackage/nfnetlink-log/description - Kernel modules support for logging packets via NFNETLINK - Includes: - - NFLOG -endef - -$(eval $(call KernelPackage,nfnetlink-log)) - - -define KernelPackage/nfnetlink-queue - TITLE:=Netfilter QUEUE over NFNETLINK interface - FILES:=$(foreach mod,$(NFNETLINK_QUEUE-m),$(LINUX_DIR)/net/$(mod).ko) - KCONFIG:=$(KCONFIG_NFNETLINK_QUEUE) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK_QUEUE-m))) - $(call AddDepends/nfnetlink) -endef - -define KernelPackage/nfnetlink-queue/description - Kernel modules support for queueing packets via NFNETLINK - Includes: - - NFQUEUE -endef - -$(eval $(call KernelPackage,nfnetlink-queue)) - - -define KernelPackage/nf-conntrack-netlink - TITLE:=Connection tracking netlink interface - FILES:=$(LINUX_DIR)/net/netfilter/nf_conntrack_netlink.ko - KCONFIG:=CONFIG_NF_CT_NETLINK CONFIG_NF_CONNTRACK_EVENTS=y - AUTOLOAD:=$(call AutoProbe,nf_conntrack_netlink) - $(call AddDepends/nfnetlink,+kmod-ipt-conntrack) -endef - -define KernelPackage/nf-conntrack-netlink/description - Kernel modules support for a netlink-based connection tracking - userspace interface -endef - -$(eval $(call KernelPackage,nf-conntrack-netlink)) - -define KernelPackage/ipt-hashlimit - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter hashlimit match - DEPENDS:=+kmod-ipt-core - KCONFIG:=$(KCONFIG_IPT_HASHLIMIT) - FILES:=$(LINUX_DIR)/net/netfilter/xt_hashlimit.ko - AUTOLOAD:=$(call AutoProbe,xt_hashlimit) - $(call KernelPackage/ipt) -endef - -define KernelPackage/ipt-hashlimit/description - Kernel modules support for the hashlimit bucket match module -endef - -$(eval $(call KernelPackage,ipt-hashlimit)) - -define KernelPackage/ipt-rpfilter - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter rpfilter match - DEPENDS:=+kmod-ipt-core - KCONFIG:=$(KCONFIG_IPT_RPFILTER) - FILES:=$(realpath \ - $(LINUX_DIR)/net/ipv4/netfilter/ipt_rpfilter.ko \ - $(LINUX_DIR)/net/ipv6/netfilter/ip6t_rpfilter.ko) - AUTOLOAD:=$(call AutoProbe,ipt_rpfilter ip6t_rpfilter) - $(call KernelPackage/ipt) -endef - -define KernelPackage/ipt-rpfilter/description - Kernel modules support for the Netfilter rpfilter match -endef - -$(eval $(call KernelPackage,ipt-rpfilter)) - - -define KernelPackage/nft-core - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter nf_tables support - DEPENDS:=+kmod-nfnetlink +kmod-nf-reject +kmod-nf-reject6 +kmod-nf-conntrack6 +LINUX_5_4:kmod-nf-nat - FILES:=$(foreach mod,$(NFT_CORE-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_CORE-m))) - KCONFIG:= \ - CONFIG_NFT_COMPAT=n \ - CONFIG_NFT_QUEUE=n \ - $(KCONFIG_NFT_CORE) -endef - -define KernelPackage/nft-core/description - Kernel module support for nftables -endef - -$(eval $(call KernelPackage,nft-core)) - - -define KernelPackage/nft-arp - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter nf_tables ARP table support - DEPENDS:=+kmod-nft-core - FILES:=$(foreach mod,$(NFT_ARP-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_ARP-m))) - KCONFIG:=$(KCONFIG_NFT_ARP) -endef - -$(eval $(call KernelPackage,nft-arp)) - - -define KernelPackage/nft-bridge - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter nf_tables bridge table support - DEPENDS:=+kmod-nft-core - FILES:=$(foreach mod,$(NFT_BRIDGE-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_BRIDGE-m))) - KCONFIG:= \ - CONFIG_NF_LOG_BRIDGE=n \ - $(KCONFIG_NFT_BRIDGE) -endef - -$(eval $(call KernelPackage,nft-bridge)) - - -define KernelPackage/nft-nat - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter nf_tables NAT support - DEPENDS:=+kmod-nft-core +kmod-nf-nat - FILES:=$(foreach mod,$(NFT_NAT-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_NAT-m))) - KCONFIG:=$(KCONFIG_NFT_NAT) -endef - -$(eval $(call KernelPackage,nft-nat)) - - -define KernelPackage/nft-offload - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter nf_tables routing/NAT offload support - DEPENDS:=+kmod-nf-flow +kmod-nft-nat - KCONFIG:= \ - CONFIG_NF_FLOW_TABLE_INET \ - CONFIG_NF_FLOW_TABLE_IPV4 \ - CONFIG_NF_FLOW_TABLE_IPV6 \ - CONFIG_NFT_FLOW_OFFLOAD - FILES:= \ - $(LINUX_DIR)/net/netfilter/nf_flow_table_inet.ko \ - $(LINUX_DIR)/net/ipv4/netfilter/nf_flow_table_ipv4.ko \ - $(LINUX_DIR)/net/ipv6/netfilter/nf_flow_table_ipv6.ko \ - $(LINUX_DIR)/net/netfilter/nft_flow_offload.ko - AUTOLOAD:=$(call AutoProbe,nf_flow_table_inet nf_flow_table_ipv4 nf_flow_table_ipv6 nft_flow_offload) -endef - -$(eval $(call KernelPackage,nft-offload)) - - -define KernelPackage/nft-nat6 - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter nf_tables IPv6-NAT support - DEPENDS:=+kmod-nft-nat +kmod-nf-nat6 - FILES:=$(foreach mod,$(NFT_NAT6-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_NAT6-m))) - KCONFIG:=$(KCONFIG_NFT_NAT6) -endef - -$(eval $(call KernelPackage,nft-nat6)) - -define KernelPackage/nft-netdev - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter nf_tables netdev support - DEPENDS:=+kmod-nft-core - KCONFIG:= \ - CONFIG_NETFILTER_INGRESS=y \ - CONFIG_NF_TABLES_NETDEV \ - CONFIG_NF_DUP_NETDEV \ - CONFIG_NFT_DUP_NETDEV \ - CONFIG_NFT_FWD_NETDEV - FILES:= \ - $(LINUX_DIR)/net/netfilter/nf_tables_netdev.ko@lt4.17 \ - $(LINUX_DIR)/net/netfilter/nf_dup_netdev.ko \ - $(LINUX_DIR)/net/netfilter/nft_dup_netdev.ko \ - $(LINUX_DIR)/net/netfilter/nft_fwd_netdev.ko - AUTOLOAD:=$(call AutoProbe,nf_tables_netdev nf_dup_netdev nft_dup_netdev nft_fwd_netdev) -endef - -$(eval $(call KernelPackage,nft-netdev)) - - -define KernelPackage/nft-fib - SUBMENU:=$(NF_MENU) - TITLE:=Netfilter nf_tables fib support - DEPENDS:=+kmod-nft-core - FILES:=$(foreach mod,$(NFT_FIB-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_FIB-m))) - KCONFIG:=$(KCONFIG_NFT_FIB) -endef - -$(eval $(call KernelPackage,nft-fib)) From 254aa838da35219ce4255e237c4465a7bce59768 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 28 Mar 2020 10:44:50 +0100 Subject: [PATCH 05/76] Fix message for mvebu patch --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 7082f7bf..c14947eb 100755 --- a/build.sh +++ b/build.sh @@ -184,7 +184,7 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/ipt-nat6.patch; then fi echo "Done" -echo "Checking if ipt-nat patch is set or not" +echo "Checking if mvebu patch is set or not" if [ ! -d target/linux/mvebu/patches-5.4 ]; then patch -N -p1 -s < ../../patches/mvebu-5.14.patch fi From 8c3788ac58f017cfb9f3678479d20423f0f1a39a Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 28 Mar 2020 10:47:41 +0100 Subject: [PATCH 06/76] Better log messages --- build.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index c14947eb..8a637494 100755 --- a/build.sh +++ b/build.sh @@ -140,17 +140,17 @@ fi cd "$OMR_TARGET/source" -echo "Checking if UEFI patch is set or not" if [ "$OMR_UEFI" = "yes" ] && [ "$OMR_TARGET" = "x86_64" ]; then + echo "Checking if UEFI patch is set or not" if [ "$(grep 'EFI_IMAGES' target/linux/x86/image/Makefile)" = "" ]; then patch -N -p1 -s < ../../patches/uefi.patch fi + echo "Done" else if [ "$(grep 'EFI_IMAGES' target/linux/x86/image/Makefile)" != "" ]; then patch -N -R -p1 -s < ../../patches/uefi.patch fi fi -echo "Done" #if [ "$OMR_TARGET" = "x86_64" ]; then # echo "Checking if Hyper-V patch is set or not" @@ -162,30 +162,35 @@ echo "Done" echo "Checking if No check patch is set or not" if ! patch -Rf -N -p1 -s --dry-run < ../../patches/nocheck.patch; then + echo "apply..." patch -N -p1 -s < ../../patches/nocheck.patch fi echo "Done" echo "Checking if Nanqinlang patch is set or not" if ! patch -Rf -N -p1 -s --dry-run < ../../patches/nanqinlang.patch; then + echo "apply..." patch -N -p1 -s < ../../patches/nanqinlang.patch fi echo "Done" echo "Checking if smsc75xx patch is set or not" if ! patch -Rf -N -p1 -s --dry-run < ../../patches/smsc75xx.patch; then + echo "apply..." patch -N -p1 -s < ../../patches/smsc75xx.patch fi echo "Done" echo "Checking if ipt-nat patch is set or not" if ! patch -Rf -N -p1 -s --dry-run < ../../patches/ipt-nat6.patch; then + echo "apply..." patch -N -p1 -s < ../../patches/ipt-nat6.patch fi echo "Done" echo "Checking if mvebu patch is set or not" if [ ! -d target/linux/mvebu/patches-5.4 ]; then + echo "apply..." patch -N -p1 -s < ../../patches/mvebu-5.14.patch fi echo "Done" From 138b2c224c07119aba7a76bc041361a70b6e159a Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 28 Mar 2020 17:04:32 +0100 Subject: [PATCH 07/76] Remove fbtft modules --- root/package/kernel/linux/modules/fbtft.mk | 98 ---------------------- 1 file changed, 98 deletions(-) delete mode 100644 root/package/kernel/linux/modules/fbtft.mk diff --git a/root/package/kernel/linux/modules/fbtft.mk b/root/package/kernel/linux/modules/fbtft.mk deleted file mode 100644 index 20b4df65..00000000 --- a/root/package/kernel/linux/modules/fbtft.mk +++ /dev/null @@ -1,98 +0,0 @@ -# -# Copyright (C) 2016 OpenWrt.org -# Copyright (C) 2019 Ycarus (Yannick Chabanois) OpenMPTCProuter.com -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -VIDEO_MENU:=Video Support - -# -# FB TFT Display -# - -define KernelPackage/fb-tft-all - SUBMENU:=$(VIDEO_MENU) - TITLE:=Framebuffer support for all TFT displays - DEPENDS:=+kmod-fb-tft - KCONFIG:= \ - CONFIG_STAGING=y \ - CONFIG_FB_TFT_AGM1264K_FL=m \ - CONFIG_FB_TFT_BD663474=m \ - CONFIG_FB_TFT_HX8340BN=m \ - CONFIG_FB_TFT_HX8347D=m \ - CONFIG_FB_TFT_HX8353D=m \ - CONFIG_FB_TFT_HX8357D=m \ - CONFIG_FB_TFT_ILI9163=m \ - CONFIG_FB_TFT_ILI9320=m \ - CONFIG_FB_TFT_ILI9325=m \ - CONFIG_FB_TFT_ILI9340=m \ - CONFIG_FB_TFT_ILI9341=m \ - CONFIG_FB_TFT_ILI9481=m \ - CONFIG_FB_TFT_ILI9486=m \ - CONFIG_FB_TFT_PCD8544=m \ - CONFIG_FB_TFT_RA8875=m \ - CONFIG_FB_TFT_S6D02A1=m \ - CONFIG_FB_TFT_S6D1121=m \ - CONFIG_FB_TFT_SH1106=m \ - CONFIG_FB_TFT_SSD1289=m \ - CONFIG_FB_TFT_SSD1305=m \ - CONFIG_FB_TFT_SSD1306=m \ - CONFIG_FB_TFT_SSD1325=m \ - CONFIG_FB_TFT_SSD1331=m \ - CONFIG_FB_TFT_SSD1351=m \ - CONFIG_FB_TFT_ST7735R=m \ - CONFIG_FB_TFT_ST7789V=m \ - CONFIG_FB_TFT_TINYLCD=m \ - CONFIG_FB_TFT_TLS8204=m \ - CONFIG_FB_TFT_UC1611=m \ - CONFIG_FB_TFT_UC1701=m \ - CONFIG_FB_TFT_UPD161704=m \ - CONFIG_FB_TFT_WATTEROTT=m \ - CONFIG_FB_FLEX=m \ - CONFIG_FB_TFT_FBTFT_DEVICE=m - FILES:=\ - $(LINUX_DIR)/drivers/staging/fbtft/fbtft_device.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/flexfb.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_agm1264k-fl.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_bd663474.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_hx8340bn.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_hx8347d.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_hx8353d.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_hx8357d.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ili9163.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ili9320.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ili9325.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ili9340.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ili9341.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ili9481.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ili9486.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_pcd8544.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ra8875.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_s6d02a1.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_s6d1121.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_sh1106.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ssd1289.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ssd1305.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ssd1306.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ssd1325.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ssd1331.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_ssd1351.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_st7735r.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_st7789v.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_tinylcd.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_tls8204.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_uc1611.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_uc1701.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_upd161704.ko \ - $(LINUX_DIR)/drivers/staging/fbtft/fb_watterott.ko - - AUTOLOAD:=$(call AutoLoad,06,fbtft_device) -endef - -define KernelPackage/fb-tft-all/description - Kernel support for small TFT LCD display modules -endef - -$(eval $(call KernelPackage,fb-tft-all)) From 1dfc55f12ff327f9e8f6a7b0cd1da93f3a93a479 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 30 Mar 2020 15:13:13 +0200 Subject: [PATCH 08/76] Update OpenWrt --- build.sh | 6 ++--- config-rpi2 | 2 +- config-rpi4 | 2 +- patches/uefi.patch | 26 ++++++++++--------- .../generic/hack-5.4/690-mptcp_trunk.patch | 7 +++-- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/build.sh b/build.sh index 8a637494..890e0336 100755 --- a/build.sh +++ b/build.sh @@ -58,9 +58,9 @@ else fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" -_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "dd166960f48580bf6d4a8dde071b96832bfd9e1f" -_get_repo feeds/packages https://github.com/openwrt/packages "ce15a63a9ef2877df1d61429dd6db5432a204d63" -_get_repo feeds/luci https://github.com/openwrt/luci "6efaea2ffb46f9909038b85cf12e7acf4467ae2e" +_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "437eb41f235c25b397a9867527d738778ea489d7" +_get_repo feeds/packages https://github.com/openwrt/packages "61088496009579f86ebc1756e2331dee879ab333" +_get_repo feeds/luci https://github.com/openwrt/luci "3d965195928b993f7e2dacebd4e296a547b32552" if [ -z "$OMR_FEED" ]; then OMR_FEED=feeds/openmptcprouter diff --git a/config-rpi2 b/config-rpi2 index 4d066843..38730cc3 100644 --- a/config-rpi2 +++ b/config-rpi2 @@ -3,4 +3,4 @@ CONFIG_TARGET_bcm27xx_bcm2709=y CONFIG_TARGET_bcm27xx_bcm2709_DEVICE_rpi-2=y CONFIG_PACKAGE_kmod-ath10k-ct=n CONFIG_PACKAGE_kmod-ath9k=y -CONFIG_PACKAGE_rpi-eeprom=y \ No newline at end of file +CONFIG_PACKAGE_bcm27xx-eeprom=y \ No newline at end of file diff --git a/config-rpi4 b/config-rpi4 index 068b443f..b1a97db7 100644 --- a/config-rpi4 +++ b/config-rpi4 @@ -3,4 +3,4 @@ CONFIG_TARGET_bcm27xx_bcm2711=y CONFIG_TARGET_bcm27xx_bcm2711_DEVICE_rpi-4=y CONFIG_PACKAGE_kmod-ath10k-ct=n CONFIG_PACKAGE_kmod-ath9k=y -CONFIG_PACKAGE_rpi-eeprom=y \ No newline at end of file +CONFIG_PACKAGE_bcm27xx-eeprom=y \ No newline at end of file diff --git a/patches/uefi.patch b/patches/uefi.patch index 317291b8..794d6578 100644 --- a/patches/uefi.patch +++ b/patches/uefi.patch @@ -1144,8 +1144,8 @@ index aa80d77b978..efb0b1cff99 100644 define Build/combined $(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz -$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/ -- PADDING="$(CONFIG_TARGET_IMAGES_PAD)" SIGNATURE="$(IMG_PART_SIGNATURE)" $(SCRIPT_DIR)/gen_image_generic.sh \ -+ PADDING="$(CONFIG_TARGET_IMAGES_PAD)" SIGNATURE="$(IMG_PART_SIGNATURE)" \ +- PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" $(SCRIPT_DIR)/gen_image_generic.sh \ ++ PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \ + $(if $(filter $(1),efi),UUID="$(IMG_PART_UUID)") $(SCRIPT_DIR)/gen_image_generic.sh \ $@ \ $(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \ @@ -1177,19 +1177,21 @@ index aa80d77b978..efb0b1cff99 100644 -o $@ $@.boot $(TARGET_DIR) endef -@@ -102,11 +105,23 @@ define Device/Default - IMAGE/combined.img.gz := append-rootfs | pad-extra 128k | grub-config pc | combined | grub-install | gzip - IMAGE/combined.vdi := append-rootfs | pad-extra 128k | grub-config pc | combined | grub-install | qemu-image vdi - IMAGE/combined.vmdk := append-rootfs | pad-extra 128k | grub-config pc | combined | grub-install | qemu-image vmdk +@@ -102,13 +105,25 @@ define Device/Default + IMAGE/combined.img.gz := grub-config pc | combined | grub-install | gzip + IMAGE/combined.vdi := grub-config pc | combined | grub-install | qemu-image vdi + IMAGE/combined.vmdk := grub-config pc | combined | grub-install | qemu-image vmdk + IMAGE/rootfs.img := append-rootfs + IMAGE/rootfs.img.gz := append-rootfs | gzip + ARTIFACT/image-efi.iso := grub-config iso | iso efi -+ IMAGE/combined-efi.img := append-rootfs | pad-extra 128k | grub-config efi | combined efi | grub-install efi -+ IMAGE/combined-efi.img.gz := append-rootfs | pad-extra 128k | grub-config efi | combined efi | grub-install efi | gzip -+ IMAGE/combined-efi.vdi := append-rootfs | pad-extra 128k | grub-config efi | combined efi | grub-install efi | qemu-image vdi -+ IMAGE/combined-efi.vmdk := append-rootfs | pad-extra 128k | grub-config efi | combined efi | grub-install efi | qemu-image vmdk ++ IMAGE/combined-efi.img := grub-config efi | combined efi | grub-install efi ++ IMAGE/combined-efi.img.gz := grub-config efi | combined efi | grub-install efi | gzip ++ IMAGE/combined-efi.vdi := grub-config efi | combined efi | grub-install efi | qemu-image vdi ++ IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y) - IMAGES := combined.img.gz + IMAGES := combined.img.gz rootfs.img.gz else - IMAGES := combined.img + IMAGES := combined.img rootfs.img endif + ifeq $(CONFIG_EFI_IMAGES) + ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index 4d0e692f..d429ab22 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -2799,12 +2799,15 @@ diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c } else sk = kmalloc(prot->obj_size, priority); -@@ -1832,6 +1858,7 @@ +@@ -1832,9 +1858,10 @@ atomic_set(&newsk->sk_zckey, 0); sock_reset_flag(newsk, SOCK_DONE); + sock_reset_flag(newsk, SOCK_MPTCP); - mem_cgroup_sk_alloc(newsk); + + /* sk->sk_memcg will be populated at accept() time */ + newsk->sk_memcg = NULL; + cgroup_sk_alloc(&newsk->sk_cgrp_data); diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c From dfb6aa205a2c2ea7dcefc805f3c09d0d3f6944dc Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 31 Mar 2020 19:29:29 +0200 Subject: [PATCH 09/76] Update MPTCP v0.94 patch --- .../generic/hack-4.14/690-mptcp_v0.94.patch | 932 ++++++++++-------- 1 file changed, 502 insertions(+), 430 deletions(-) diff --git a/root/target/linux/generic/hack-4.14/690-mptcp_v0.94.patch b/root/target/linux/generic/hack-4.14/690-mptcp_v0.94.patch index 32116748..1df18b04 100644 --- a/root/target/linux/generic/hack-4.14/690-mptcp_v0.94.patch +++ b/root/target/linux/generic/hack-4.14/690-mptcp_v0.94.patch @@ -1,6 +1,6 @@ -diff -aurN linux-4.14.127/Documentation/networking/ip-sysctl.txt mptcp-mptcp_v0.94/Documentation/networking/ip-sysctl.txt ---- linux-4.14.127/Documentation/networking/ip-sysctl.txt 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/Documentation/networking/ip-sysctl.txt 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/Documentation/networking/ip-sysctl.txt mptcp-mptcp_v0.94/Documentation/networking/ip-sysctl.txt +--- linux-4.14.174/Documentation/networking/ip-sysctl.txt 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/Documentation/networking/ip-sysctl.txt 2020-03-23 09:45:33.000000000 +0100 @@ -734,6 +734,18 @@ in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks) Default: 100 @@ -20,10 +20,10 @@ diff -aurN linux-4.14.127/Documentation/networking/ip-sysctl.txt mptcp-mptcp_v0. UDP variables: udp_l3mdev_accept - BOOLEAN -diff -aurN linux-4.14.127/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_v0.94/drivers/infiniband/hw/cxgb4/cm.c ---- linux-4.14.127/drivers/infiniband/hw/cxgb4/cm.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/drivers/infiniband/hw/cxgb4/cm.c 2019-06-17 23:59:30.000000000 +0200 -@@ -3755,7 +3755,7 @@ +diff -aurN linux-4.14.174/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_v0.94/drivers/infiniband/hw/cxgb4/cm.c +--- linux-4.14.174/drivers/infiniband/hw/cxgb4/cm.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/drivers/infiniband/hw/cxgb4/cm.c 2020-03-23 09:45:33.000000000 +0100 +@@ -3757,7 +3757,7 @@ */ memset(&tmp_opt, 0, sizeof(tmp_opt)); tcp_clear_options(&tmp_opt); @@ -32,9 +32,9 @@ diff -aurN linux-4.14.127/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_v0.94/dri req = __skb_push(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); -diff -aurN linux-4.14.127/include/linux/skbuff.h mptcp-mptcp_v0.94/include/linux/skbuff.h ---- linux-4.14.127/include/linux/skbuff.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/linux/skbuff.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/linux/skbuff.h mptcp-mptcp_v0.94/include/linux/skbuff.h +--- linux-4.14.174/include/linux/skbuff.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/linux/skbuff.h 2020-03-23 09:45:33.000000000 +0100 @@ -690,7 +690,7 @@ * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. @@ -44,9 +44,9 @@ diff -aurN linux-4.14.127/include/linux/skbuff.h mptcp-mptcp_v0.94/include/linux unsigned long _skb_refdst; void (*destructor)(struct sk_buff *skb); -diff -aurN linux-4.14.127/include/linux/tcp.h mptcp-mptcp_v0.94/include/linux/tcp.h ---- linux-4.14.127/include/linux/tcp.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/linux/tcp.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/linux/tcp.h mptcp-mptcp_v0.94/include/linux/tcp.h +--- linux-4.14.174/include/linux/tcp.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/linux/tcp.h 2020-03-23 09:45:33.000000000 +0100 @@ -58,7 +58,7 @@ /* TCP Fast Open */ #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ @@ -203,9 +203,9 @@ diff -aurN linux-4.14.127/include/linux/tcp.h mptcp-mptcp_v0.94/include/linux/tc }; static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) -diff -aurN linux-4.14.127/include/net/inet_common.h mptcp-mptcp_v0.94/include/net/inet_common.h ---- linux-4.14.127/include/net/inet_common.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/inet_common.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/inet_common.h mptcp-mptcp_v0.94/include/net/inet_common.h +--- linux-4.14.174/include/net/inet_common.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/inet_common.h 2020-03-23 09:45:33.000000000 +0100 @@ -2,6 +2,8 @@ #ifndef _INET_COMMON_H #define _INET_COMMON_H @@ -224,9 +224,9 @@ diff -aurN linux-4.14.127/include/net/inet_common.h mptcp-mptcp_v0.94/include/ne int inet_release(struct socket *sock); int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags); -diff -aurN linux-4.14.127/include/net/inet_connection_sock.h mptcp-mptcp_v0.94/include/net/inet_connection_sock.h ---- linux-4.14.127/include/net/inet_connection_sock.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/inet_connection_sock.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/inet_connection_sock.h mptcp-mptcp_v0.94/include/net/inet_connection_sock.h +--- linux-4.14.174/include/net/inet_connection_sock.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/inet_connection_sock.h 2020-03-23 09:45:33.000000000 +0100 @@ -30,6 +30,7 @@ struct inet_bind_bucket; @@ -235,9 +235,9 @@ diff -aurN linux-4.14.127/include/net/inet_connection_sock.h mptcp-mptcp_v0.94/i /* * Pointers to address related TCP functions -diff -aurN linux-4.14.127/include/net/inet_sock.h mptcp-mptcp_v0.94/include/net/inet_sock.h ---- linux-4.14.127/include/net/inet_sock.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/inet_sock.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/inet_sock.h mptcp-mptcp_v0.94/include/net/inet_sock.h +--- linux-4.14.174/include/net/inet_sock.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/inet_sock.h 2020-03-23 09:45:33.000000000 +0100 @@ -90,7 +90,9 @@ wscale_ok : 1, ecn_ok : 1, @@ -249,10 +249,10 @@ diff -aurN linux-4.14.127/include/net/inet_sock.h mptcp-mptcp_v0.94/include/net/ u32 ir_mark; union { struct ip_options_rcu __rcu *ireq_opt; -diff -aurN linux-4.14.127/include/net/mptcp.h mptcp-mptcp_v0.94/include/net/mptcp.h ---- linux-4.14.127/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/mptcp.h 2019-06-17 23:59:30.000000000 +0200 -@@ -0,0 +1,1522 @@ +diff -aurN linux-4.14.174/include/net/mptcp.h mptcp-mptcp_v0.94/include/net/mptcp.h +--- linux-4.14.174/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/mptcp.h 2020-03-23 09:45:33.000000000 +0100 +@@ -0,0 +1,1529 @@ +/* + * MPTCP implementation + * @@ -532,7 +532,8 @@ diff -aurN linux-4.14.127/include/net/mptcp.h mptcp-mptcp_v0.94/include/net/mptc + dfin_combined:1, /* Was the DFIN combined with subflow-fin? */ + passive_close:1, + snd_hiseq_index:1, /* Index in snd_high_order of snd_nxt */ -+ rcv_hiseq_index:1; /* Index in rcv_high_order of rcv_nxt */ ++ rcv_hiseq_index:1, /* Index in rcv_high_order of rcv_nxt */ ++ tcp_ca_explicit_set:1; /* was meta CC set by app? */ + + /* socket count in this connection */ + u8 cnt_subflows; @@ -1715,6 +1716,8 @@ diff -aurN linux-4.14.127/include/net/mptcp.h mptcp-mptcp_v0.94/include/net/mptc +} +static inline void mptcp_push_pending_frames(struct sock *meta_sk) {} +static inline void mptcp_send_reset(const struct sock *sk) {} ++static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, ++ struct sock *except) {} +static inline bool mptcp_handle_options(struct sock *sk, + const struct tcphdr *th, + struct sk_buff *skb) @@ -1767,6 +1770,10 @@ diff -aurN linux-4.14.127/include/net/mptcp.h mptcp-mptcp_v0.94/include/net/mptc + struct sk_buff *skb) {} +static inline void mptcp_mpcb_put(struct mptcp_cb *mpcb) {} +static inline void mptcp_fin(struct sock *meta_sk) {} ++static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) ++{ ++ return false; ++} +static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) +{ + return false; @@ -1775,9 +1782,9 @@ diff -aurN linux-4.14.127/include/net/mptcp.h mptcp-mptcp_v0.94/include/net/mptc +#endif /* CONFIG_MPTCP */ + +#endif /* _MPTCP_H */ -diff -aurN linux-4.14.127/include/net/mptcp_v4.h mptcp-mptcp_v0.94/include/net/mptcp_v4.h ---- linux-4.14.127/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/mptcp_v4.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/mptcp_v4.h mptcp-mptcp_v0.94/include/net/mptcp_v4.h +--- linux-4.14.174/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/mptcp_v4.h 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,68 @@ +/* + * MPTCP implementation @@ -1847,9 +1854,9 @@ diff -aurN linux-4.14.127/include/net/mptcp_v4.h mptcp-mptcp_v0.94/include/net/m +#endif /* CONFIG_MPTCP */ + +#endif /* MPTCP_V4_H_ */ -diff -aurN linux-4.14.127/include/net/mptcp_v6.h mptcp-mptcp_v0.94/include/net/mptcp_v6.h ---- linux-4.14.127/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/mptcp_v6.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/mptcp_v6.h mptcp-mptcp_v0.94/include/net/mptcp_v6.h +--- linux-4.14.174/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/mptcp_v6.h 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,69 @@ +/* + * MPTCP implementation @@ -1920,9 +1927,9 @@ diff -aurN linux-4.14.127/include/net/mptcp_v6.h mptcp-mptcp_v0.94/include/net/m +#endif /* CONFIG_MPTCP */ + +#endif /* _MPTCP_V6_H */ -diff -aurN linux-4.14.127/include/net/net_namespace.h mptcp-mptcp_v0.94/include/net/net_namespace.h ---- linux-4.14.127/include/net/net_namespace.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/net_namespace.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/net_namespace.h mptcp-mptcp_v0.94/include/net/net_namespace.h +--- linux-4.14.174/include/net/net_namespace.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/net_namespace.h 2020-03-23 09:45:33.000000000 +0100 @@ -18,6 +18,7 @@ #include #include @@ -1941,9 +1948,9 @@ diff -aurN linux-4.14.127/include/net/net_namespace.h mptcp-mptcp_v0.94/include/ #if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) struct netns_ieee802154_lowpan ieee802154_lowpan; #endif -diff -aurN linux-4.14.127/include/net/netns/mptcp.h mptcp-mptcp_v0.94/include/net/netns/mptcp.h ---- linux-4.14.127/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/netns/mptcp.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/netns/mptcp.h mptcp-mptcp_v0.94/include/net/netns/mptcp.h +--- linux-4.14.174/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/netns/mptcp.h 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,52 @@ +/* + * MPTCP implementation - MPTCP namespace @@ -1997,9 +2004,9 @@ diff -aurN linux-4.14.127/include/net/netns/mptcp.h mptcp-mptcp_v0.94/include/ne +}; + +#endif /* __NETNS_MPTCP_H__ */ -diff -aurN linux-4.14.127/include/net/snmp.h mptcp-mptcp_v0.94/include/net/snmp.h ---- linux-4.14.127/include/net/snmp.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/snmp.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/snmp.h mptcp-mptcp_v0.94/include/net/snmp.h +--- linux-4.14.174/include/net/snmp.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/snmp.h 2020-03-23 09:45:33.000000000 +0100 @@ -91,7 +91,6 @@ atomic_long_t mibs[ICMP6MSG_MIB_MAX]; }; @@ -2008,10 +2015,10 @@ diff -aurN linux-4.14.127/include/net/snmp.h mptcp-mptcp_v0.94/include/net/snmp. /* TCP */ #define TCP_MIB_MAX __TCP_MIB_MAX struct tcp_mib { -diff -aurN linux-4.14.127/include/net/sock.h mptcp-mptcp_v0.94/include/net/sock.h ---- linux-4.14.127/include/net/sock.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/sock.h 2019-06-17 23:59:30.000000000 +0200 -@@ -781,6 +781,7 @@ +diff -aurN linux-4.14.174/include/net/sock.h mptcp-mptcp_v0.94/include/net/sock.h +--- linux-4.14.174/include/net/sock.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/sock.h 2020-03-23 09:45:33.000000000 +0100 +@@ -786,6 +786,7 @@ SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */ SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */ SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */ @@ -2019,7 +2026,7 @@ diff -aurN linux-4.14.127/include/net/sock.h mptcp-mptcp_v0.94/include/net/sock. }; #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) -@@ -1081,6 +1082,7 @@ +@@ -1086,6 +1087,7 @@ void (*unhash)(struct sock *sk); void (*rehash)(struct sock *sk); int (*get_port)(struct sock *sk, unsigned short snum); @@ -2027,7 +2034,7 @@ diff -aurN linux-4.14.127/include/net/sock.h mptcp-mptcp_v0.94/include/net/sock. /* Keeping track of sockets in use */ #ifdef CONFIG_PROC_FS -@@ -1505,9 +1507,6 @@ +@@ -1510,9 +1512,6 @@ static inline void sock_owned_by_me(const struct sock *sk) { @@ -2037,9 +2044,9 @@ diff -aurN linux-4.14.127/include/net/sock.h mptcp-mptcp_v0.94/include/net/sock. } static inline bool sock_owned_by_user(const struct sock *sk) -diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h ---- linux-4.14.127/include/net/tcp.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/tcp.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h +--- linux-4.14.174/include/net/tcp.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/tcp.h 2020-03-23 09:45:33.000000000 +0100 @@ -187,6 +187,7 @@ #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ @@ -2195,7 +2202,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h void tcp_req_err(struct sock *sk, u32 seq, bool abort); int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); struct sock *tcp_create_openreq_child(const struct sock *sk, -@@ -525,7 +643,8 @@ +@@ -533,7 +651,8 @@ u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, u16 *mssp); @@ -2205,7 +2212,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h u64 cookie_init_timestamp(struct request_sock *req); bool cookie_timestamp_decode(const struct net *net, struct tcp_options_received *opt); -@@ -539,7 +658,8 @@ +@@ -547,7 +666,8 @@ u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, const struct tcphdr *th, u16 *mssp); @@ -2215,7 +2222,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h #endif /* tcp_output.c */ -@@ -571,10 +691,17 @@ +@@ -579,10 +699,17 @@ void tcp_skb_collapse_tstamp(struct sk_buff *skb, const struct sk_buff *next_skb); @@ -2233,7 +2240,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); void tcp_fin(struct sock *sk); -@@ -613,7 +740,7 @@ +@@ -621,7 +748,7 @@ } /* tcp.c */ @@ -2242,7 +2249,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h /* Read 'sendfile()'-style from a TCP socket */ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, -@@ -807,6 +934,12 @@ +@@ -815,6 +942,12 @@ */ ktime_t swtstamp; }; @@ -2255,7 +2262,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ __u8 sacked; /* State flags for SACK/FACK. */ -@@ -825,6 +958,14 @@ +@@ -833,6 +966,14 @@ has_rxtstamp:1, /* SKB has a RX timestamp */ unused:5; __u32 ack_seq; /* Sequence number ACK'd */ @@ -2270,7 +2277,16 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h union { struct { /* There is space for up to 24 bytes */ -@@ -1326,7 +1467,8 @@ +@@ -1053,6 +1194,8 @@ + int tcp_set_allowed_congestion_control(char *allowed); + int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, + bool reinit, bool cap_net_admin); ++int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, ++ bool reinit, bool cap_net_admin); + u32 tcp_slow_start(struct tcp_sock *tp, u32 acked); + void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked); + +@@ -1335,7 +1478,8 @@ /* Determine a window scaling and initial window to offer. */ void tcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, __u32 *window_clamp, int wscale_ok, @@ -2280,7 +2296,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h static inline int tcp_win_from_space(int space) { -@@ -1337,6 +1479,19 @@ +@@ -1346,6 +1490,19 @@ space - (space>>tcp_adv_win_scale); } @@ -2300,7 +2316,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h /* Note: caller must be prepared to deal with negative returns */ static inline int tcp_space(const struct sock *sk) { -@@ -1613,19 +1768,7 @@ +@@ -1622,19 +1779,7 @@ } /* write queue abstraction */ @@ -2321,7 +2337,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h static inline struct sk_buff *tcp_write_queue_head(const struct sock *sk) { -@@ -1888,6 +2031,30 @@ +@@ -1918,6 +2063,32 @@ #endif }; @@ -2346,13 +2362,15 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h + void (*time_wait)(struct sock *sk, int state, int timeo); + void (*cleanup_rbuf)(struct sock *sk, int copied); + void (*cwnd_validate)(struct sock *sk, bool is_cwnd_limited); ++ int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, ++ bool reinit, bool cap_net_admin); +}; +extern const struct tcp_sock_ops tcp_specific; + struct tcp_request_sock_ops { u16 mss_clamp; #ifdef CONFIG_TCP_MD5SIG -@@ -1898,12 +2065,13 @@ +@@ -1928,12 +2099,13 @@ const struct sock *sk, const struct sk_buff *skb); #endif @@ -2371,7 +2389,7 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h #endif struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, const struct request_sock *req); -@@ -1917,15 +2085,17 @@ +@@ -1947,15 +2119,17 @@ #ifdef CONFIG_SYN_COOKIES static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, @@ -2390,9 +2408,9 @@ diff -aurN linux-4.14.127/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h const struct sock *sk, struct sk_buff *skb, __u16 *mss) { -diff -aurN linux-4.14.127/include/net/tcp_states.h mptcp-mptcp_v0.94/include/net/tcp_states.h ---- linux-4.14.127/include/net/tcp_states.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/tcp_states.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/tcp_states.h mptcp-mptcp_v0.94/include/net/tcp_states.h +--- linux-4.14.174/include/net/tcp_states.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/tcp_states.h 2020-03-23 09:45:33.000000000 +0100 @@ -26,6 +26,7 @@ TCP_LISTEN, TCP_CLOSING, /* Now a valid state */ @@ -2409,9 +2427,9 @@ diff -aurN linux-4.14.127/include/net/tcp_states.h mptcp-mptcp_v0.94/include/net }; #endif /* _LINUX_TCP_STATES_H */ -diff -aurN linux-4.14.127/include/net/transp_v6.h mptcp-mptcp_v0.94/include/net/transp_v6.h ---- linux-4.14.127/include/net/transp_v6.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/net/transp_v6.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/net/transp_v6.h mptcp-mptcp_v0.94/include/net/transp_v6.h +--- linux-4.14.174/include/net/transp_v6.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/net/transp_v6.h 2020-03-23 09:45:33.000000000 +0100 @@ -59,6 +59,8 @@ /* address family specific functions */ @@ -2421,9 +2439,9 @@ diff -aurN linux-4.14.127/include/net/transp_v6.h mptcp-mptcp_v0.94/include/net/ void inet6_destroy_sock(struct sock *sk); -diff -aurN linux-4.14.127/include/uapi/linux/if.h mptcp-mptcp_v0.94/include/uapi/linux/if.h ---- linux-4.14.127/include/uapi/linux/if.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/uapi/linux/if.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/uapi/linux/if.h mptcp-mptcp_v0.94/include/uapi/linux/if.h +--- linux-4.14.174/include/uapi/linux/if.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/uapi/linux/if.h 2020-03-23 09:45:33.000000000 +0100 @@ -132,6 +132,9 @@ #define IFF_ECHO IFF_ECHO #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ @@ -2434,9 +2452,9 @@ diff -aurN linux-4.14.127/include/uapi/linux/if.h mptcp-mptcp_v0.94/include/uapi #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) -diff -aurN linux-4.14.127/include/uapi/linux/tcp.h mptcp-mptcp_v0.94/include/uapi/linux/tcp.h ---- linux-4.14.127/include/uapi/linux/tcp.h 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/include/uapi/linux/tcp.h 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/include/uapi/linux/tcp.h mptcp-mptcp_v0.94/include/uapi/linux/tcp.h +--- linux-4.14.174/include/uapi/linux/tcp.h 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/include/uapi/linux/tcp.h 2020-03-23 09:45:33.000000000 +0100 @@ -18,9 +18,15 @@ #ifndef _UAPI_LINUX_TCP_H #define _UAPI_LINUX_TCP_H @@ -2521,9 +2539,9 @@ diff -aurN linux-4.14.127/include/uapi/linux/tcp.h mptcp-mptcp_v0.94/include/uap /* for TCP_MD5SIG socket option */ #define TCP_MD5SIG_MAXKEYLEN 80 -diff -aurN linux-4.14.127/kernel/rcu/Kconfig.debug mptcp-mptcp_v0.94/kernel/rcu/Kconfig.debug ---- linux-4.14.127/kernel/rcu/Kconfig.debug 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/kernel/rcu/Kconfig.debug 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/kernel/rcu/Kconfig.debug mptcp-mptcp_v0.94/kernel/rcu/Kconfig.debug +--- linux-4.14.174/kernel/rcu/Kconfig.debug 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/kernel/rcu/Kconfig.debug 2020-03-23 09:45:33.000000000 +0100 @@ -4,9 +4,6 @@ menu "RCU Debugging" @@ -2534,9 +2552,9 @@ diff -aurN linux-4.14.127/kernel/rcu/Kconfig.debug mptcp-mptcp_v0.94/kernel/rcu/ config TORTURE_TEST tristate default n -diff -aurN linux-4.14.127/net/core/dev.c mptcp-mptcp_v0.94/net/core/dev.c ---- linux-4.14.127/net/core/dev.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/core/dev.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/core/dev.c mptcp-mptcp_v0.94/net/core/dev.c +--- linux-4.14.174/net/core/dev.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/core/dev.c 2020-03-23 09:45:33.000000000 +0100 @@ -6769,7 +6769,7 @@ dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | @@ -2546,9 +2564,9 @@ diff -aurN linux-4.14.127/net/core/dev.c mptcp-mptcp_v0.94/net/core/dev.c (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC | IFF_ALLMULTI)); -diff -aurN linux-4.14.127/net/core/skbuff.c mptcp-mptcp_v0.94/net/core/skbuff.c ---- linux-4.14.127/net/core/skbuff.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/core/skbuff.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/core/skbuff.c mptcp-mptcp_v0.94/net/core/skbuff.c +--- linux-4.14.174/net/core/skbuff.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/core/skbuff.c 2020-03-23 09:45:33.000000000 +0100 @@ -536,7 +536,7 @@ skb_drop_list(&skb_shinfo(skb)->frag_list); } @@ -2567,9 +2585,9 @@ diff -aurN linux-4.14.127/net/core/skbuff.c mptcp-mptcp_v0.94/net/core/skbuff.c { __copy_skb_header(new, old); -diff -aurN linux-4.14.127/net/core/sock.c mptcp-mptcp_v0.94/net/core/sock.c ---- linux-4.14.127/net/core/sock.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/core/sock.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/core/sock.c mptcp-mptcp_v0.94/net/core/sock.c +--- linux-4.14.174/net/core/sock.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/core/sock.c 2020-03-23 09:45:33.000000000 +0100 @@ -139,6 +139,11 @@ #include @@ -2582,7 +2600,7 @@ diff -aurN linux-4.14.127/net/core/sock.c mptcp-mptcp_v0.94/net/core/sock.c #include #include -@@ -1416,6 +1421,23 @@ +@@ -1413,6 +1418,23 @@ */ static inline void sock_lock_init(struct sock *sk) { @@ -2606,7 +2624,7 @@ diff -aurN linux-4.14.127/net/core/sock.c mptcp-mptcp_v0.94/net/core/sock.c if (sk->sk_kern_sock) sock_lock_init_class_and_name( sk, -@@ -1464,8 +1486,12 @@ +@@ -1461,8 +1483,12 @@ sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); if (!sk) return sk; @@ -2621,17 +2639,17 @@ diff -aurN linux-4.14.127/net/core/sock.c mptcp-mptcp_v0.94/net/core/sock.c } else sk = kmalloc(prot->obj_size, priority); -@@ -1682,6 +1708,7 @@ +@@ -1684,6 +1710,7 @@ atomic_set(&newsk->sk_zckey, 0); sock_reset_flag(newsk, SOCK_DONE); + sock_reset_flag(newsk, SOCK_MPTCP); - mem_cgroup_sk_alloc(newsk); - cgroup_sk_alloc(&newsk->sk_cgrp_data); -diff -aurN linux-4.14.127/net/ipv4/af_inet.c mptcp-mptcp_v0.94/net/ipv4/af_inet.c ---- linux-4.14.127/net/ipv4/af_inet.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/af_inet.c 2019-06-17 23:59:30.000000000 +0200 + /* sk->sk_memcg will be populated at accept() time */ + newsk->sk_memcg = NULL; +diff -aurN linux-4.14.174/net/ipv4/af_inet.c mptcp-mptcp_v0.94/net/ipv4/af_inet.c +--- linux-4.14.174/net/ipv4/af_inet.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/af_inet.c 2020-03-23 09:45:33.000000000 +0100 @@ -104,6 +104,7 @@ #include #include @@ -2694,9 +2712,9 @@ diff -aurN linux-4.14.127/net/ipv4/af_inet.c mptcp-mptcp_v0.94/net/ipv4/af_inet. /* Setup TCP slab cache for open requests. */ tcp_init(); -diff -aurN linux-4.14.127/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.94/net/ipv4/inet_connection_sock.c ---- linux-4.14.127/net/ipv4/inet_connection_sock.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/inet_connection_sock.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.94/net/ipv4/inet_connection_sock.c +--- linux-4.14.174/net/ipv4/inet_connection_sock.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/inet_connection_sock.c 2020-03-23 09:45:33.000000000 +0100 @@ -23,6 +23,7 @@ #include #include @@ -2705,7 +2723,7 @@ diff -aurN linux-4.14.127/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.94/net/ #include #include #include -@@ -689,7 +690,10 @@ +@@ -709,7 +710,10 @@ int max_retries, thresh; u8 defer_accept; @@ -2717,7 +2735,7 @@ diff -aurN linux-4.14.127/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.94/net/ goto drop; max_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries; -@@ -783,7 +787,9 @@ +@@ -803,7 +807,9 @@ const struct request_sock *req, const gfp_t priority) { @@ -2728,7 +2746,7 @@ diff -aurN linux-4.14.127/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.94/net/ if (newsk) { struct inet_connection_sock *newicsk = inet_csk(newsk); -@@ -983,7 +989,14 @@ +@@ -1003,7 +1009,14 @@ */ while ((req = reqsk_queue_remove(queue, sk)) != NULL) { struct sock *child = req->sk; @@ -2743,7 +2761,7 @@ diff -aurN linux-4.14.127/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.94/net/ local_bh_disable(); bh_lock_sock(child); WARN_ON(sock_owned_by_user(child)); -@@ -993,6 +1006,10 @@ +@@ -1013,6 +1026,10 @@ reqsk_put(req); bh_unlock_sock(child); local_bh_enable(); @@ -2754,9 +2772,9 @@ diff -aurN linux-4.14.127/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.94/net/ sock_put(child); cond_resched(); -diff -aurN linux-4.14.127/net/ipv4/ip_sockglue.c mptcp-mptcp_v0.94/net/ipv4/ip_sockglue.c ---- linux-4.14.127/net/ipv4/ip_sockglue.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/ip_sockglue.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/ip_sockglue.c mptcp-mptcp_v0.94/net/ipv4/ip_sockglue.c +--- linux-4.14.174/net/ipv4/ip_sockglue.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/ip_sockglue.c 2020-03-23 09:45:33.000000000 +0100 @@ -44,6 +44,8 @@ #endif #include @@ -2793,9 +2811,9 @@ diff -aurN linux-4.14.127/net/ipv4/ip_sockglue.c mptcp-mptcp_v0.94/net/ipv4/ip_s } break; case IP_TTL: -diff -aurN linux-4.14.127/net/ipv4/Kconfig mptcp-mptcp_v0.94/net/ipv4/Kconfig ---- linux-4.14.127/net/ipv4/Kconfig 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/Kconfig 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/Kconfig mptcp-mptcp_v0.94/net/ipv4/Kconfig +--- linux-4.14.174/net/ipv4/Kconfig 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/Kconfig 2020-03-23 09:45:33.000000000 +0100 @@ -675,6 +675,38 @@ bufferbloat, policers, or AQM schemes that do not provide a delay signal. It requires the fq ("Fair Queue") pacing packet scheduler. @@ -2865,9 +2883,9 @@ diff -aurN linux-4.14.127/net/ipv4/Kconfig mptcp-mptcp_v0.94/net/ipv4/Kconfig default "reno" if DEFAULT_RENO default "dctcp" if DEFAULT_DCTCP default "cdg" if DEFAULT_CDG -diff -aurN linux-4.14.127/net/ipv4/syncookies.c mptcp-mptcp_v0.94/net/ipv4/syncookies.c ---- linux-4.14.127/net/ipv4/syncookies.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/syncookies.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/syncookies.c mptcp-mptcp_v0.94/net/ipv4/syncookies.c +--- linux-4.14.174/net/ipv4/syncookies.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/syncookies.c 2020-03-23 09:45:33.000000000 +0100 @@ -16,6 +16,8 @@ #include #include @@ -2980,9 +2998,9 @@ diff -aurN linux-4.14.127/net/ipv4/syncookies.c mptcp-mptcp_v0.94/net/ipv4/synco ireq->rcv_wscale = rcv_wscale; ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); -diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c ---- linux-4.14.127/net/ipv4/tcp.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c +--- linux-4.14.174/net/ipv4/tcp.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp.c 2020-03-23 09:45:33.000000000 +0100 @@ -273,6 +273,7 @@ #include @@ -2991,7 +3009,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c #include #include #include -@@ -402,6 +403,24 @@ +@@ -402,6 +403,25 @@ return rate64; } @@ -3011,12 +3029,13 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c + .time_wait = tcp_time_wait, + .cleanup_rbuf = tcp_cleanup_rbuf, + .cwnd_validate = tcp_cwnd_validate, ++ .set_cong_ctrl = __tcp_set_congestion_control, +}; + /* Address-family independent initialization for a tcp_sock. * * NOTE: A lot of things set to zero explicitly by call to -@@ -452,6 +471,11 @@ +@@ -452,6 +472,11 @@ sk->sk_sndbuf = sysctl_tcp_wmem[1]; sk->sk_rcvbuf = sysctl_tcp_rmem[1]; @@ -3028,7 +3047,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c sk_sockets_allocated_inc(sk); } EXPORT_SYMBOL(tcp_init_sock); -@@ -766,6 +790,7 @@ +@@ -766,6 +791,7 @@ int ret; sock_rps_record_flow(sk); @@ -3036,7 +3055,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c /* * We can't seek on a socket input */ -@@ -776,6 +801,14 @@ +@@ -776,6 +802,14 @@ lock_sock(sk); @@ -3051,7 +3070,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); while (tss.len) { ret = __tcp_splice_read(sk, &tss); -@@ -879,8 +912,7 @@ +@@ -879,8 +913,7 @@ return NULL; } @@ -3061,7 +3080,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c { struct tcp_sock *tp = tcp_sk(sk); u32 new_size_goal, size_goal; -@@ -908,8 +940,13 @@ +@@ -908,8 +941,13 @@ { int mss_now; @@ -3077,7 +3096,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c return mss_now; } -@@ -928,12 +965,33 @@ +@@ -944,12 +982,33 @@ * is fully established. */ if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && @@ -3112,7 +3131,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); mss_now = tcp_send_mss(sk, &size_goal, flags); -@@ -1050,8 +1108,9 @@ +@@ -1067,8 +1126,9 @@ int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, size_t size, int flags) { @@ -3124,7 +3143,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c return sock_no_sendpage_locked(sk, page, offset, size, flags); tcp_rate_check_app_limited(sk); /* is sending application-limited? */ -@@ -1083,14 +1142,14 @@ +@@ -1100,14 +1160,14 @@ * This also speeds up tso_fragment(), since it wont fallback * to tcp_fragment(). */ @@ -3141,7 +3160,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c { const struct tcp_sock *tp = tcp_sk(sk); int tmp = tp->mss_cache; -@@ -1212,12 +1271,19 @@ +@@ -1229,12 +1289,19 @@ * is fully established. */ if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && @@ -3162,7 +3181,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c if (unlikely(tp->repair)) { if (tp->repair_queue == TCP_RECV_QUEUE) { copied = tcp_send_rcvq(sk, msg, size); -@@ -1253,7 +1319,10 @@ +@@ -1270,7 +1337,10 @@ if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) goto do_error; @@ -3174,7 +3193,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c while (msg_data_left(msg)) { int copy = 0; -@@ -1282,7 +1351,7 @@ +@@ -1299,7 +1369,7 @@ } first_skb = skb_queue_empty(&sk->sk_write_queue); skb = sk_stream_alloc_skb(sk, @@ -3183,7 +3202,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c sk->sk_allocation, first_skb); if (!skb) -@@ -1291,8 +1360,15 @@ +@@ -1308,8 +1378,15 @@ process_backlog = true; /* * Check whether we can use HW checksum. @@ -3200,7 +3219,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c skb->ip_summed = CHECKSUM_PARTIAL; skb_entail(sk, skb); -@@ -1523,7 +1599,7 @@ +@@ -1534,7 +1611,7 @@ * calculation of whether or not we must ACK for the sake of * a window update. */ @@ -3209,7 +3228,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c { struct tcp_sock *tp = tcp_sk(sk); bool time_to_ack = false; -@@ -1566,7 +1642,7 @@ +@@ -1577,7 +1654,7 @@ /* Optimize, __tcp_select_window() is not cheap. */ if (2*rcv_window_now <= tp->window_clamp) { @@ -3218,7 +3237,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c /* Send ACK now, if this read freed lots of space * in our buffer. Certainly, new_window is new window. -@@ -1682,7 +1758,7 @@ +@@ -1693,7 +1770,7 @@ /* Clean up data we have read: This will do ACK frames. */ if (copied > 0) { tcp_recv_skb(sk, seq, &offset); @@ -3227,7 +3246,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c } return copied; } -@@ -1782,6 +1858,14 @@ +@@ -1793,6 +1870,14 @@ lock_sock(sk); @@ -3242,7 +3261,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c err = -ENOTCONN; if (sk->sk_state == TCP_LISTEN) goto out; -@@ -1902,7 +1986,7 @@ +@@ -1913,7 +1998,7 @@ } } @@ -3251,7 +3270,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c if (copied >= target) { /* Do not sleep, just process backlog. */ -@@ -1995,7 +2079,7 @@ +@@ -2006,7 +2091,7 @@ tcp_recv_timestamp(msg, sk, &tss); /* Clean up data we have read: This will do ACK frames. */ @@ -3260,7 +3279,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c release_sock(sk); return copied; -@@ -2073,7 +2157,7 @@ +@@ -2084,7 +2169,7 @@ [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ }; @@ -3269,7 +3288,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c { int next = (int)new_state[sk->sk_state]; int ns = next & TCP_STATE_MASK; -@@ -2103,7 +2187,7 @@ +@@ -2114,7 +2199,7 @@ TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { /* Clear out any half completed packets. FIN if needed. */ if (tcp_close_state(sk)) @@ -3278,7 +3297,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c } } EXPORT_SYMBOL(tcp_shutdown); -@@ -2128,6 +2212,17 @@ +@@ -2139,6 +2224,17 @@ int data_was_unread = 0; int state; @@ -3296,7 +3315,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c lock_sock(sk); sk->sk_shutdown = SHUTDOWN_MASK; -@@ -2172,7 +2267,7 @@ +@@ -2183,7 +2279,7 @@ /* Unread data was tossed, zap the connection. */ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); tcp_set_state(sk, TCP_CLOSE); @@ -3305,7 +3324,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { /* Check zero linger _after_ checking for unread data. */ sk->sk_prot->disconnect(sk, 0); -@@ -2246,7 +2341,7 @@ +@@ -2257,7 +2353,7 @@ struct tcp_sock *tp = tcp_sk(sk); if (tp->linger2 < 0) { tcp_set_state(sk, TCP_CLOSE); @@ -3314,7 +3333,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONLINGER); } else { -@@ -2256,7 +2351,8 @@ +@@ -2267,7 +2363,8 @@ inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); } else { @@ -3324,7 +3343,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c goto out; } } -@@ -2265,7 +2361,7 @@ +@@ -2276,7 +2373,7 @@ sk_mem_reclaim(sk); if (tcp_check_oom(sk, 0)) { tcp_set_state(sk, TCP_CLOSE); @@ -3333,7 +3352,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); } else if (!check_net(sock_net(sk))) { -@@ -2294,15 +2390,6 @@ +@@ -2305,15 +2402,6 @@ } EXPORT_SYMBOL(tcp_close); @@ -3349,7 +3368,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c int tcp_disconnect(struct sock *sk, int flags) { struct inet_sock *inet = inet_sk(sk); -@@ -2325,7 +2412,7 @@ +@@ -2336,7 +2424,7 @@ /* The last check adjusts for discrepancy of Linux wrt. RFC * states */ @@ -3358,7 +3377,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c sk->sk_err = ECONNRESET; } else if (old_state == TCP_SYN_SENT) sk->sk_err = ECONNRESET; -@@ -2341,6 +2428,13 @@ +@@ -2352,6 +2440,13 @@ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) inet_reset_saddr(sk); @@ -3372,7 +3391,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c sk->sk_shutdown = 0; sock_reset_flag(sk, SOCK_DONE); tp->srtt_us = 0; -@@ -2387,7 +2481,7 @@ +@@ -2406,7 +2501,7 @@ static inline bool tcp_can_repair_sock(const struct sock *sk) { return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && @@ -3381,7 +3400,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c } static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) -@@ -2522,6 +2616,61 @@ +@@ -2543,6 +2638,61 @@ release_sock(sk); return err; } @@ -3443,7 +3462,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c default: /* fallthru */ break; -@@ -2699,6 +2848,12 @@ +@@ -2720,6 +2870,12 @@ break; case TCP_DEFER_ACCEPT: @@ -3456,7 +3475,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c /* Translate value in seconds to number of retransmits */ icsk->icsk_accept_queue.rskq_defer_accept = secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -@@ -2726,7 +2881,7 @@ +@@ -2747,7 +2903,7 @@ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && inet_csk_ack_scheduled(sk)) { icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; @@ -3465,7 +3484,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c if (!(val & 1)) icsk->icsk_ack.pingpong = 1; } -@@ -2736,7 +2891,7 @@ +@@ -2757,7 +2913,7 @@ #ifdef CONFIG_TCP_MD5SIG case TCP_MD5SIG: case TCP_MD5SIG_EXT: @@ -3474,7 +3493,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c err = tp->af_specific->md5_parse(sk, optname, optval, optlen); else err = -EINVAL; -@@ -2787,6 +2942,32 @@ +@@ -2808,6 +2964,32 @@ tp->notsent_lowat = val; sk->sk_write_space(sk); break; @@ -3507,7 +3526,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c default: err = -ENOPROTOOPT; break; -@@ -2840,7 +3021,7 @@ +@@ -2861,7 +3043,7 @@ } /* Return information about state of tcp endpoint in API format. */ @@ -3516,7 +3535,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c { const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ const struct inet_connection_sock *icsk = inet_csk(sk); -@@ -2877,7 +3058,8 @@ +@@ -2898,7 +3080,8 @@ return; } @@ -3526,7 +3545,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c info->tcpi_ca_state = icsk->icsk_ca_state; info->tcpi_retransmits = icsk->icsk_retransmits; -@@ -2946,7 +3128,9 @@ +@@ -2967,7 +3150,9 @@ rate64 = tcp_compute_delivery_rate(tp); if (rate64) info->tcpi_delivery_rate = rate64; @@ -3537,7 +3556,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c } EXPORT_SYMBOL_GPL(tcp_get_info); -@@ -3052,7 +3236,7 @@ +@@ -3073,7 +3258,7 @@ if (get_user(len, optlen)) return -EFAULT; @@ -3546,7 +3565,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c len = min_t(unsigned int, len, sizeof(info)); if (put_user(len, optlen)) -@@ -3214,6 +3398,87 @@ +@@ -3235,6 +3420,87 @@ } return 0; } @@ -3634,7 +3653,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c default: return -ENOPROTOOPT; } -@@ -3388,7 +3653,9 @@ +@@ -3409,7 +3675,9 @@ if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); @@ -3644,7 +3663,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c tcp_clear_xmit_timers(sk); if (req) reqsk_fastopen_remove(sk, req, false); -@@ -3404,6 +3671,8 @@ +@@ -3425,6 +3693,8 @@ int tcp_abort(struct sock *sk, int err) { @@ -3653,7 +3672,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c if (!sk_fullsock(sk)) { if (sk->sk_state == TCP_NEW_SYN_RECV) { struct request_sock *req = inet_reqsk(sk); -@@ -3417,7 +3686,7 @@ +@@ -3438,7 +3708,7 @@ } /* Don't race with userspace socket closes such as tcp_close. */ @@ -3662,7 +3681,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c if (sk->sk_state == TCP_LISTEN) { tcp_set_state(sk, TCP_CLOSE); -@@ -3426,7 +3695,7 @@ +@@ -3447,7 +3717,7 @@ /* Don't race with BH socket closes such as inet_csk_listen_stop. */ local_bh_disable(); @@ -3671,7 +3690,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_err = err; -@@ -3434,14 +3703,14 @@ +@@ -3455,14 +3725,14 @@ smp_wmb(); sk->sk_error_report(sk); if (tcp_need_reset(sk->sk_state)) @@ -3689,9 +3708,34 @@ diff -aurN linux-4.14.127/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c return 0; } EXPORT_SYMBOL_GPL(tcp_abort); -diff -aurN linux-4.14.127/net/ipv4/tcp_diag.c mptcp-mptcp_v0.94/net/ipv4/tcp_diag.c ---- linux-4.14.127/net/ipv4/tcp_diag.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_diag.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/tcp_cong.c mptcp-mptcp_v0.94/net/ipv4/tcp_cong.c +--- linux-4.14.174/net/ipv4/tcp_cong.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp_cong.c 2020-03-23 09:45:33.000000000 +0100 +@@ -333,13 +333,19 @@ + return ret; + } + ++int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, ++ bool reinit, bool cap_net_admin) ++{ ++ return tcp_sk(sk)->ops->set_cong_ctrl(sk, name, load, reinit, cap_net_admin); ++} ++ + /* Change congestion control for socket. If load is false, then it is the + * responsibility of the caller to call tcp_init_congestion_control or + * tcp_reinit_congestion_control (if the current congestion control was + * already initialized. + */ +-int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, +- bool reinit, bool cap_net_admin) ++int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, ++ bool reinit, bool cap_net_admin) + { + struct inet_connection_sock *icsk = inet_csk(sk); + const struct tcp_congestion_ops *ca; +diff -aurN linux-4.14.174/net/ipv4/tcp_diag.c mptcp-mptcp_v0.94/net/ipv4/tcp_diag.c +--- linux-4.14.174/net/ipv4/tcp_diag.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp_diag.c 2020-03-23 09:45:33.000000000 +0100 @@ -34,7 +34,7 @@ r->idiag_wqueue = tp->write_seq - tp->snd_una; } @@ -3701,9 +3745,9 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_diag.c mptcp-mptcp_v0.94/net/ipv4/tcp_dia } #ifdef CONFIG_TCP_MD5SIG -diff -aurN linux-4.14.127/net/ipv4/tcp_fastopen.c mptcp-mptcp_v0.94/net/ipv4/tcp_fastopen.c ---- linux-4.14.127/net/ipv4/tcp_fastopen.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_fastopen.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/tcp_fastopen.c mptcp-mptcp_v0.94/net/ipv4/tcp_fastopen.c +--- linux-4.14.174/net/ipv4/tcp_fastopen.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp_fastopen.c 2020-03-23 09:45:33.000000000 +0100 @@ -9,6 +9,7 @@ #include #include @@ -3762,9 +3806,9 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_fastopen.c mptcp-mptcp_v0.94/net/ipv4/tcp /* tcp_conn_request() is sending the SYNACK, * and queues the child into listener accept queue. */ -diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_input.c ---- linux-4.14.127/net/ipv4/tcp_input.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_input.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_input.c +--- linux-4.14.174/net/ipv4/tcp_input.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp_input.c 2020-03-23 09:45:33.000000000 +0100 @@ -76,6 +76,9 @@ #include #include @@ -3892,7 +3936,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { const struct tcp_sock *tp = tcp_sk(sk); /* Old crap is replaced with new one. 8) -@@ -1427,7 +1429,11 @@ +@@ -1428,7 +1430,11 @@ int len; int in_sack; @@ -3905,7 +3949,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in goto fallback; /* Normally R but no L won't result in plain S */ -@@ -2979,7 +2985,7 @@ +@@ -2983,7 +2989,7 @@ */ tcp_update_rtt_min(sk, ca_rtt_us); tcp_rtt_estimator(sk, seq_rtt_us); @@ -3914,7 +3958,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* RFC6298: only reset backoff on valid RTT measurement. */ inet_csk(sk)->icsk_backoff = 0; -@@ -3047,7 +3053,7 @@ +@@ -3051,7 +3057,7 @@ } /* If we get here, the whole TSO packet has not been acked. */ @@ -3923,7 +3967,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { struct tcp_sock *tp = tcp_sk(sk); u32 packets_acked; -@@ -3170,6 +3176,8 @@ +@@ -3174,6 +3180,8 @@ */ if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { flag |= FLAG_DATA_ACKED; @@ -3932,7 +3976,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in } else { flag |= FLAG_SYN_ACKED; tp->retrans_stamp = 0; -@@ -3282,7 +3290,7 @@ +@@ -3286,7 +3294,7 @@ return flag; } @@ -3941,7 +3985,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { const struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); -@@ -3352,9 +3360,8 @@ +@@ -3356,9 +3364,8 @@ /* Check that window update is acceptable. * The function assumes that snd_una<=ack<=snd_next. */ @@ -3953,7 +3997,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { return after(ack, tp->snd_una) || after(ack_seq, tp->snd_wl1) || -@@ -3574,7 +3581,7 @@ +@@ -3578,7 +3585,7 @@ } /* This routine deals with incoming acks, but not outgoing ones. */ @@ -3962,7 +4006,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); -@@ -3681,6 +3688,16 @@ +@@ -3685,6 +3692,16 @@ flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, &acked, &sack_state); @@ -3979,7 +4023,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (tp->tlp_high_seq) tcp_process_tlp_ack(sk, ack, flag); /* If needed, reset TLP/RTO timer; RACK may later override this. */ -@@ -3759,8 +3776,10 @@ +@@ -3763,8 +3780,10 @@ */ void tcp_parse_options(const struct net *net, const struct sk_buff *skb, @@ -3992,7 +4036,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { const unsigned char *ptr; const struct tcphdr *th = tcp_hdr(skb); -@@ -3844,6 +3863,10 @@ +@@ -3848,6 +3867,10 @@ */ break; #endif @@ -4003,7 +4047,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in case TCPOPT_FASTOPEN: tcp_parse_fastopen_option( opsize - TCPOLEN_FASTOPEN_BASE, -@@ -3908,7 +3931,9 @@ +@@ -3912,7 +3935,9 @@ return true; } @@ -4014,7 +4058,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) tp->rx_opt.rcv_tsecr -= tp->tsoffset; -@@ -4065,6 +4090,11 @@ +@@ -4069,6 +4094,11 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4026,7 +4070,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in inet_csk_schedule_ack(sk); sk->sk_shutdown |= RCV_SHUTDOWN; -@@ -4075,6 +4105,10 @@ +@@ -4079,6 +4109,10 @@ case TCP_ESTABLISHED: /* Move to CLOSE_WAIT */ tcp_set_state(sk, TCP_CLOSE_WAIT); @@ -4037,7 +4081,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in inet_csk(sk)->icsk_ack.pingpong = 1; break; -@@ -4097,9 +4131,16 @@ +@@ -4101,9 +4135,16 @@ tcp_set_state(sk, TCP_CLOSING); break; case TCP_FIN_WAIT2: @@ -4055,7 +4099,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in break; default: /* Only TCP_LISTEN and TCP_CLOSE are left, in these -@@ -4121,6 +4162,10 @@ +@@ -4125,6 +4166,10 @@ if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_state_change(sk); @@ -4066,7 +4110,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* Do not send POLL_HUP for half duplex close. */ if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) -@@ -4327,6 +4372,9 @@ +@@ -4331,6 +4376,9 @@ *fragstolen = false; @@ -4076,7 +4120,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* Its possible this segment overlaps with prior segment in queue */ if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq) return false; -@@ -4378,7 +4426,7 @@ +@@ -4382,7 +4430,7 @@ /* This one checks to see if we can put data from the * out_of_order queue into the receive_queue. */ @@ -4085,7 +4129,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { struct tcp_sock *tp = tcp_sk(sk); __u32 dsack_high = tp->rcv_nxt; -@@ -4404,7 +4452,14 @@ +@@ -4408,7 +4456,14 @@ if (TCP_SKB_CB(skb)->has_rxtstamp) skb->tstamp = TCP_SKB_CB(skb)->swtstamp; @@ -4101,7 +4145,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in SOCK_DEBUG(sk, "ofo packet was already received\n"); tcp_drop(sk, skb); continue; -@@ -4439,6 +4494,9 @@ +@@ -4443,6 +4498,9 @@ static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, unsigned int size) { @@ -4111,7 +4155,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || !sk_rmem_schedule(sk, skb, size)) { -@@ -4453,7 +4511,7 @@ +@@ -4457,7 +4515,7 @@ return 0; } @@ -4120,7 +4164,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { struct tcp_sock *tp = tcp_sk(sk); struct rb_node **p, *parent; -@@ -4525,7 +4583,8 @@ +@@ -4529,7 +4587,8 @@ continue; } if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { @@ -4130,7 +4174,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* All the bits are present. Drop. */ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPOFOMERGE); -@@ -4572,6 +4631,11 @@ +@@ -4576,6 +4635,11 @@ end_seq); break; } @@ -4142,7 +4186,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in rb_erase(&skb1->rbnode, &tp->out_of_order_queue); tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, TCP_SKB_CB(skb1)->end_seq); -@@ -4583,7 +4647,7 @@ +@@ -4587,7 +4651,7 @@ tp->ooo_last_skb = skb; add_sack: @@ -4151,7 +4195,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in tcp_sack_new_ofo_skb(sk, seq, end_seq); end: if (skb) { -@@ -4593,8 +4657,8 @@ +@@ -4597,8 +4661,8 @@ } } @@ -4162,7 +4206,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { int eaten; struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4667,10 +4731,14 @@ +@@ -4671,10 +4735,14 @@ bool fragstolen; int eaten; @@ -4178,7 +4222,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in skb_dst_drop(skb); __skb_pull(skb, tcp_hdr(skb)->doff * 4); -@@ -4695,7 +4763,7 @@ +@@ -4699,7 +4767,7 @@ eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen); tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); @@ -4187,7 +4231,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in tcp_event_data_recv(sk, skb); if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) tcp_fin(sk); -@@ -4717,7 +4785,11 @@ +@@ -4721,7 +4789,11 @@ if (eaten > 0) kfree_skb_partial(skb, fragstolen); @@ -4200,7 +4244,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in sk->sk_data_ready(sk); return; } -@@ -5056,7 +5128,7 @@ +@@ -5060,7 +5132,7 @@ return -1; } @@ -4209,7 +4253,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { const struct tcp_sock *tp = tcp_sk(sk); -@@ -5091,7 +5163,7 @@ +@@ -5095,7 +5167,7 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4218,7 +4262,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in tcp_sndbuf_expand(sk); tp->snd_cwnd_stamp = tcp_jiffies32; } -@@ -5105,10 +5177,11 @@ +@@ -5109,10 +5181,11 @@ sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); /* pairs with tcp_poll() */ smp_mb(); @@ -4233,16 +4277,23 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); } } -@@ -5132,7 +5205,7 @@ +@@ -5135,8 +5208,14 @@ + if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && /* ... and right edge of window advances far enough. * (tcp_recvmsg() will send ACK otherwise). Or... ++ * in the case of mptcp the meta ofo queue may ++ * prevent tcp_recvmsg from being called in time ++ * so no data is available for the application, skip the ++ * receive window check as there is no hope that the application ++ * will do a tcp_recvmsg anytime soon. */ - __tcp_select_window(sk) >= tp->rcv_wnd) || -+ tp->ops->__select_window(sk) >= tp->rcv_wnd) || ++ (tp->ops->__select_window(sk) >= tp->rcv_wnd || (mptcp(tp) && ++ skb_queue_empty(&mptcp_meta_sk(sk)->sk_receive_queue)))) || /* We ACK each frame or... */ tcp_in_quickack_mode(sk) || /* We have out of order data. */ -@@ -5234,6 +5307,10 @@ +@@ -5238,6 +5317,10 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4253,7 +4304,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* Check if we get a new urgent pointer - normally not. */ if (th->urg) tcp_check_urg(sk, th); -@@ -5376,9 +5453,15 @@ +@@ -5380,9 +5463,15 @@ goto discard; } @@ -4269,7 +4320,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in tcp_drop(sk, skb); return false; } -@@ -5432,6 +5515,10 @@ +@@ -5436,6 +5525,10 @@ tp->rx_opt.saw_tstamp = 0; @@ -4280,7 +4331,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* pred_flags is 0xS?10 << 16 + snd_wnd * if header_prediction is to be made * 'S' will always be tp->tcp_header_len >> 2 -@@ -5601,7 +5688,7 @@ +@@ -5605,7 +5698,7 @@ */ tp->lsndtime = tcp_jiffies32; @@ -4289,7 +4340,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (sock_flag(sk, SOCK_KEEPOPEN)) inet_csk_reset_keepalive_timer(sk, keepalive_time_when(tp)); -@@ -5616,7 +5703,8 @@ +@@ -5620,7 +5713,8 @@ struct tcp_fastopen_cookie *cookie) { struct tcp_sock *tp = tcp_sk(sk); @@ -4299,7 +4350,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in u16 mss = tp->rx_opt.mss_clamp, try_exp = 0; bool syn_drop = false; -@@ -5626,7 +5714,7 @@ +@@ -5630,7 +5724,7 @@ /* Get original SYNACK MSS value if user MSS sets mss_clamp */ tcp_clear_options(&opt); opt.user_mss = opt.mss_clamp = 0; @@ -4308,7 +4359,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in mss = opt.mss_clamp; } -@@ -5650,7 +5738,11 @@ +@@ -5654,7 +5748,11 @@ tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp); @@ -4321,7 +4372,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in tcp_for_write_queue_from(data, sk) { if (data == tcp_send_head(sk) || __tcp_retransmit_skb(sk, data, 1)) -@@ -5678,9 +5770,13 @@ +@@ -5682,9 +5780,13 @@ struct tcp_sock *tp = tcp_sk(sk); struct tcp_fastopen_cookie foc = { .len = -1 }; int saved_clamp = tp->rx_opt.mss_clamp; @@ -4336,7 +4387,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) tp->rx_opt.rcv_tsecr -= tp->tsoffset; -@@ -5740,6 +5836,35 @@ +@@ -5744,6 +5846,35 @@ tcp_init_wl(tp, TCP_SKB_CB(skb)->seq); tcp_ack(sk, skb, FLAG_SLOWPATH); @@ -4372,7 +4423,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* Ok.. it's good. Set up sequence numbers and * move to established. */ -@@ -5766,6 +5891,11 @@ +@@ -5770,6 +5901,11 @@ tp->tcp_header_len = sizeof(struct tcphdr); } @@ -4384,7 +4435,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (tcp_is_sack(tp) && sysctl_tcp_fack) tcp_enable_fack(tp); -@@ -5791,9 +5921,12 @@ +@@ -5795,9 +5931,12 @@ } if (fastopen_fail) return -1; @@ -4399,7 +4450,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* Save one ACK. Data will be ready after * several ticks, if write_pending is set. * -@@ -5832,6 +5965,7 @@ +@@ -5836,6 +5975,7 @@ tcp_paws_reject(&tp->rx_opt, 0)) goto discard_and_undo; @@ -4407,7 +4458,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (th->syn) { /* We see SYN without ACK. It is attempt of * simultaneous connect with crossed SYNs. -@@ -5848,6 +5982,11 @@ +@@ -5852,6 +5992,11 @@ tp->tcp_header_len = sizeof(struct tcphdr); } @@ -4419,7 +4470,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; tp->copied_seq = tp->rcv_nxt; tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; -@@ -5906,6 +6045,7 @@ +@@ -5910,6 +6055,7 @@ */ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) @@ -4427,7 +4478,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in { struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); -@@ -5948,6 +6088,16 @@ +@@ -5952,6 +6098,16 @@ tp->rx_opt.saw_tstamp = 0; tcp_mstamp_refresh(tp); queued = tcp_rcv_synsent_state_process(sk, skb, th); @@ -4444,7 +4495,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (queued >= 0) return queued; -@@ -6005,7 +6155,7 @@ +@@ -6009,7 +6165,7 @@ tcp_mtup_init(sk); tp->copied_seq = tp->rcv_nxt; @@ -4453,7 +4504,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in } smp_mb(); tcp_set_state(sk, TCP_ESTABLISHED); -@@ -6024,6 +6174,8 @@ +@@ -6028,6 +6184,8 @@ if (tp->rx_opt.tstamp_ok) tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; @@ -4462,7 +4513,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (req) { /* Re-arm the timer because data may have been sent out. -@@ -6046,6 +6198,30 @@ +@@ -6050,6 +6208,30 @@ tcp_initialize_rcv_mss(sk); tcp_fast_path_on(tp); @@ -4493,7 +4544,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in break; case TCP_FIN_WAIT1: { -@@ -6093,7 +6269,8 @@ +@@ -6097,7 +6279,8 @@ tmo = tcp_fin_time(sk); if (tmo > TCP_TIMEWAIT_LEN) { inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); @@ -4503,7 +4554,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in /* Bad case. We could lose such FIN otherwise. * It is not a big problem, but it looks confusing * and not so rare event. We still can lose it now, -@@ -6102,7 +6279,7 @@ +@@ -6106,7 +6289,7 @@ */ inet_csk_reset_keepalive_timer(sk, tmo); } else { @@ -4512,7 +4563,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in goto discard; } break; -@@ -6110,7 +6287,7 @@ +@@ -6114,7 +6297,7 @@ case TCP_CLOSING: if (tp->snd_una == tp->write_seq) { @@ -4521,7 +4572,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in goto discard; } break; -@@ -6122,6 +6299,9 @@ +@@ -6126,6 +6309,9 @@ goto discard; } break; @@ -4531,7 +4582,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in } /* step 6: check the URG bit */ -@@ -6142,7 +6322,8 @@ +@@ -6146,7 +6332,8 @@ */ if (sk->sk_shutdown & RCV_SHUTDOWN) { if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && @@ -4541,7 +4592,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); tcp_reset(sk); return 1; -@@ -6239,6 +6420,8 @@ +@@ -6243,6 +6430,8 @@ ireq->wscale_ok = rx_opt->wscale_ok; ireq->acked = 0; ireq->ecn_ok = 0; @@ -4550,7 +4601,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in ireq->ir_rmt_port = tcp_hdr(skb)->source; ireq->ir_num = ntohs(tcp_hdr(skb)->dest); ireq->ir_mark = inet_request_mark(sk, skb); -@@ -6333,12 +6516,17 @@ +@@ -6337,12 +6526,17 @@ /* TW buckets are converted to open requests without * limitations, they conserve resources and peer is * evidently real one. @@ -4569,7 +4620,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in } if (sk_acceptq_is_full(sk)) { -@@ -6356,8 +6544,8 @@ +@@ -6360,8 +6554,8 @@ tcp_clear_options(&tmp_opt); tmp_opt.mss_clamp = af_ops->mss_clamp; tmp_opt.user_mss = tp->rx_opt.user_mss; @@ -4580,7 +4631,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (want_cookie && !tmp_opt.saw_tstamp) tcp_clear_options(&tmp_opt); -@@ -6369,7 +6557,8 @@ +@@ -6373,7 +6567,8 @@ /* Note: tcp_v6_init_req() might override ir_iif for link locals */ inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb); @@ -4590,7 +4641,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in if (security_inet_conn_request(sk, skb, req)) goto drop_and_free; -@@ -6405,7 +6594,7 @@ +@@ -6409,7 +6604,7 @@ tcp_ecn_create_request(req, skb, sk, dst); if (want_cookie) { @@ -4599,7 +4650,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in req->cookie_ts = tmp_opt.tstamp_ok; if (!tmp_opt.tstamp_ok) inet_rsk(req)->ecn_ok = 0; -@@ -6419,18 +6608,26 @@ +@@ -6423,18 +6618,26 @@ fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc); } if (fastopen_sk) { @@ -4627,9 +4678,9 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_in sock_put(fastopen_sk); } else { tcp_rsk(req)->tfo_listener = false; -diff -aurN linux-4.14.127/net/ipv4/tcp_ipv4.c mptcp-mptcp_v0.94/net/ipv4/tcp_ipv4.c ---- linux-4.14.127/net/ipv4/tcp_ipv4.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_ipv4.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/tcp_ipv4.c mptcp-mptcp_v0.94/net/ipv4/tcp_ipv4.c +--- linux-4.14.174/net/ipv4/tcp_ipv4.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp_ipv4.c 2020-03-23 09:45:33.000000000 +0100 @@ -67,6 +67,8 @@ #include #include @@ -5107,7 +5158,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_ipv4.c mptcp-mptcp_v0.94/net/ipv4/tcp_ipv tcp_cleanup_ulp(sk); /* Cleanup up the write buffer. */ -@@ -2436,6 +2560,9 @@ +@@ -2437,6 +2561,9 @@ .compat_getsockopt = compat_tcp_getsockopt, #endif .diag_destroy = tcp_abort, @@ -5117,9 +5168,9 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_ipv4.c mptcp-mptcp_v0.94/net/ipv4/tcp_ipv }; EXPORT_SYMBOL(tcp_prot); -diff -aurN linux-4.14.127/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tcp_minisocks.c ---- linux-4.14.127/net/ipv4/tcp_minisocks.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_minisocks.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tcp_minisocks.c +--- linux-4.14.174/net/ipv4/tcp_minisocks.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp_minisocks.c 2020-03-23 09:45:33.000000000 +0100 @@ -18,11 +18,13 @@ * Jorge Cwik, */ @@ -5243,7 +5294,15 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tc newtp->tsoffset = treq->ts_off; #ifdef CONFIG_TCP_MD5SIG newtp->md5sig_info = NULL; /*XXX*/ -@@ -564,6 +600,7 @@ +@@ -541,6 +577,7 @@ + newtp->syn_data_acked = 0; + newtp->rack.mstamp = 0; + newtp->rack.advanced = 0; ++ newtp->inside_tk_table = 0; + + __TCP_INC_STATS(sock_net(sk), TCP_MIB_PASSIVEOPENS); + } +@@ -564,6 +601,7 @@ bool fastopen) { struct tcp_options_received tmp_opt; @@ -5251,7 +5310,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tc struct sock *child; const struct tcphdr *th = tcp_hdr(skb); __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); -@@ -571,8 +608,11 @@ +@@ -571,8 +609,11 @@ bool own_req; tmp_opt.saw_tstamp = 0; @@ -5264,7 +5323,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tc if (tmp_opt.saw_tstamp) { tmp_opt.ts_recent = req->ts_recent; -@@ -613,7 +653,14 @@ +@@ -613,7 +654,14 @@ * * Reset timer after retransmitting SYNACK, similar to * the idea of fast retransmit in recovery. @@ -5279,7 +5338,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tc if (!tcp_oow_rate_limited(sock_net(sk), skb, LINUX_MIB_TCPACKSKIPPEDSYNRECV, &tcp_rsk(req)->last_oow_ack_time) && -@@ -766,6 +813,18 @@ +@@ -766,6 +814,18 @@ if (!child) goto listen_overflow; @@ -5298,7 +5357,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tc sock_rps_save_rxhash(child, skb); tcp_synack_rtt_meas(child, req); return inet_csk_complete_hashdance(sk, child, req, own_req); -@@ -813,12 +872,13 @@ +@@ -813,12 +873,13 @@ { int ret = 0; int state = child->sk_state; @@ -5313,7 +5372,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tc ret = tcp_rcv_state_process(child, skb); /* Wakeup parent, send SIGIO */ if (state == TCP_SYN_RECV && child->sk_state != state) -@@ -828,10 +888,14 @@ +@@ -828,10 +889,14 @@ * in main socket hash table and lock on listening * socket does not protect us more. */ @@ -5330,9 +5389,9 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tc sock_put(child); return ret; } -diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_output.c ---- linux-4.14.127/net/ipv4/tcp_output.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_output.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_output.c +--- linux-4.14.174/net/ipv4/tcp_output.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp_output.c 2020-03-23 09:45:33.000000000 +0100 @@ -36,6 +36,12 @@ #define pr_fmt(fmt) "TCP: " fmt @@ -5471,7 +5530,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o return MAX_TCP_OPTION_SPACE - remaining; } -@@ -700,16 +706,22 @@ +@@ -700,6 +706,8 @@ opts->tsecr = tp->rx_opt.ts_recent; size += TCPOLEN_TSTAMP_ALIGNED; } @@ -5480,28 +5539,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; if (unlikely(eff_sacks)) { -- const unsigned int remaining = MAX_TCP_OPTION_SPACE - size; -- opts->num_sack_blocks = -- min_t(unsigned int, eff_sacks, -- (remaining - TCPOLEN_SACK_BASE_ALIGNED) / -- TCPOLEN_SACK_PERBLOCK); -- size += TCPOLEN_SACK_BASE_ALIGNED + -- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; -+ const unsigned remaining = MAX_TCP_OPTION_SPACE - size; -+ if (remaining < TCPOLEN_SACK_BASE_ALIGNED) -+ opts->num_sack_blocks = 0; -+ else -+ opts->num_sack_blocks = -+ min_t(unsigned int, eff_sacks, -+ (remaining - TCPOLEN_SACK_BASE_ALIGNED) / -+ TCPOLEN_SACK_PERBLOCK); -+ if (opts->num_sack_blocks) -+ size += TCPOLEN_SACK_BASE_ALIGNED + -+ opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; - } - - return size; -@@ -749,8 +761,8 @@ +@@ -750,8 +758,8 @@ tcp_xmit_retransmit_queue(sk); } @@ -5512,7 +5550,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o } } /* -@@ -766,7 +778,7 @@ +@@ -767,7 +775,7 @@ unsigned long flags; struct list_head *q, *n; struct tcp_sock *tp; @@ -5521,7 +5559,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o local_irq_save(flags); list_splice_init(&tsq->head, &list); -@@ -780,14 +792,28 @@ +@@ -781,14 +789,28 @@ smp_mb__before_atomic(); clear_bit(TSQ_QUEUED, &sk->sk_tsq_flags); @@ -5554,7 +5592,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o } sk_free(sk); -@@ -797,7 +823,9 @@ +@@ -798,7 +820,9 @@ #define TCP_DEFERRED_ALL (TCPF_TSQ_DEFERRED | \ TCPF_WRITE_TIMER_DEFERRED | \ TCPF_DELACK_TIMER_DEFERRED | \ @@ -5565,7 +5603,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o /** * tcp_release_cb - tcp release_sock() callback * @sk: socket -@@ -817,8 +845,11 @@ +@@ -818,8 +842,11 @@ nflags = flags & ~TCP_DEFERRED_ALL; } while (cmpxchg(&sk->sk_tsq_flags, flags, nflags) != flags); @@ -5578,7 +5616,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o /* Here begins the tricky part : * We are called from release_sock() with : -@@ -843,6 +874,13 @@ +@@ -844,6 +871,13 @@ inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); __sock_put(sk); } @@ -5592,7 +5630,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o } EXPORT_SYMBOL(tcp_release_cb); -@@ -1080,10 +1118,10 @@ +@@ -1081,10 +1115,10 @@ } } @@ -5605,7 +5643,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o tcp_ecn_send(sk, skb, th, tcp_header_size); } else { /* RFC1323: The window in SYN & SYN/ACK segments -@@ -1140,8 +1178,8 @@ +@@ -1141,8 +1175,8 @@ return err; } @@ -5616,7 +5654,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask, tcp_sk(sk)->rcv_nxt); -@@ -1152,7 +1190,7 @@ +@@ -1153,7 +1187,7 @@ * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, * otherwise socket can stall. */ @@ -5625,7 +5663,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { struct tcp_sock *tp = tcp_sk(sk); -@@ -1165,7 +1203,7 @@ +@@ -1166,7 +1200,7 @@ } /* Initialize TSO segments for a packet. */ @@ -5634,7 +5672,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { if (skb->len <= mss_now || skb->ip_summed == CHECKSUM_NONE) { /* Avoid the costly divide in the normal -@@ -1197,7 +1235,7 @@ +@@ -1198,7 +1232,7 @@ /* Pcount in the middle of the write queue got changed, we need to do various * tweaks to fix counters */ @@ -5643,7 +5681,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { struct tcp_sock *tp = tcp_sk(sk); -@@ -1354,7 +1392,7 @@ +@@ -1364,7 +1398,7 @@ /* This is similar to __pskb_pull_tail(). The difference is that pulled * data is not copied, but immediately discarded. */ @@ -5652,7 +5690,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { struct skb_shared_info *shinfo; int i, k, eat; -@@ -1576,6 +1614,7 @@ +@@ -1586,6 +1620,7 @@ return mss_now; } @@ -5660,7 +5698,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. * As additional protections, we do not touch cwnd in retransmission phases, -@@ -1599,7 +1638,7 @@ +@@ -1609,7 +1644,7 @@ tp->snd_cwnd_stamp = tcp_jiffies32; } @@ -5669,7 +5707,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; struct tcp_sock *tp = tcp_sk(sk); -@@ -1657,8 +1696,8 @@ +@@ -1667,8 +1702,8 @@ * But we can avoid doing the divide again given we already have * skb_pcount = skb->len / mss_now */ @@ -5680,7 +5718,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { if (skb->len < tcp_skb_pcount(skb) * mss_now) tp->snd_sml = TCP_SKB_CB(skb)->end_seq; -@@ -1716,11 +1755,11 @@ +@@ -1726,11 +1761,11 @@ } /* Returns the portion of skb which can be sent right away */ @@ -5697,7 +5735,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { const struct tcp_sock *tp = tcp_sk(sk); u32 partial, needed, window, max_len; -@@ -1750,13 +1789,14 @@ +@@ -1760,13 +1795,14 @@ /* Can at least one segment of SKB be sent right now, according to the * congestion window rules? If so, return how many segments are allowed. */ @@ -5715,7 +5753,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o tcp_skb_pcount(skb) == 1) return 1; -@@ -1776,7 +1816,7 @@ +@@ -1786,7 +1822,7 @@ * This must be invoked the first time we consider transmitting * SKB onto the wire. */ @@ -5724,7 +5762,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { int tso_segs = tcp_skb_pcount(skb); -@@ -1791,8 +1831,8 @@ +@@ -1801,8 +1837,8 @@ /* Return true if the Nagle test allows this packet to be * sent now. */ @@ -5735,7 +5773,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { /* Nagle rule does not apply to frames, which sit in the middle of the * write_queue (they have no chances to get new data). -@@ -1804,7 +1844,8 @@ +@@ -1814,7 +1850,8 @@ return true; /* Don't use the nagle rule for urgent data (or for the final FIN). */ @@ -5745,7 +5783,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o return true; if (!tcp_nagle_check(skb->len < cur_mss, tp, nonagle)) -@@ -1814,9 +1855,8 @@ +@@ -1824,9 +1861,8 @@ } /* Does at least the first segment of SKB fit into the send window? */ @@ -5757,7 +5795,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { u32 end_seq = TCP_SKB_CB(skb)->end_seq; -@@ -1973,7 +2013,7 @@ +@@ -1983,7 +2019,7 @@ } /* If this packet won't get more data, do not wait. */ @@ -5766,7 +5804,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o goto send_now; return true; -@@ -2272,6 +2312,23 @@ +@@ -2283,6 +2319,23 @@ tcp_chrono_set(tp, TCP_CHRONO_BUSY); } @@ -5790,7 +5828,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o /* This routine writes packets to the network. It advances the * send_head. This happens as incoming acks open up the remote * window for us. -@@ -2286,7 +2343,7 @@ +@@ -2297,7 +2350,7 @@ * Returns true, if no segments are in flight and we have queued segments, * but cannot send anything now because of SWS or another problem. */ @@ -5799,7 +5837,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o int push_one, gfp_t gfp) { struct tcp_sock *tp = tcp_sk(sk); -@@ -2300,7 +2357,12 @@ +@@ -2311,7 +2364,12 @@ sent_pkts = 0; tcp_mstamp_refresh(tp); @@ -5813,7 +5851,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o /* Do MTU probing. */ result = tcp_mtu_probe(sk); if (!result) { -@@ -2398,7 +2460,8 @@ +@@ -2417,7 +2475,8 @@ if (push_one != 2) tcp_schedule_loss_probe(sk, false); is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); @@ -5823,7 +5861,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o return false; } return !tp->packets_out && tcp_send_head(sk); -@@ -2483,7 +2546,7 @@ +@@ -2502,7 +2561,7 @@ if (skb) { if (tcp_snd_wnd_test(tp, skb, mss)) { pcount = tp->packets_out; @@ -5832,7 +5870,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o if (tp->packets_out > pcount) goto probe_sent; goto rearm_timer; -@@ -2550,8 +2613,8 @@ +@@ -2569,8 +2628,8 @@ if (unlikely(sk->sk_state == TCP_CLOSE)) return; @@ -5843,7 +5881,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o tcp_check_probe_timer(sk); } -@@ -2564,7 +2627,8 @@ +@@ -2583,7 +2642,8 @@ BUG_ON(!skb || skb->len < mss_now); @@ -5853,7 +5891,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o } /* This function returns the amount that we can raise the -@@ -2797,6 +2861,10 @@ +@@ -2816,6 +2876,10 @@ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) return; @@ -5864,7 +5902,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o tcp_for_write_queue_from_safe(skb, tmp, sk) { if (!tcp_can_collapse(sk, skb)) break; -@@ -3254,7 +3322,7 @@ +@@ -3273,7 +3337,7 @@ /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ th->window = htons(min(req->rsk_rcv_wnd, 65535U)); @@ -5873,7 +5911,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o th->doff = (tcp_header_size >> 2); __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); -@@ -3335,13 +3403,13 @@ +@@ -3354,13 +3418,13 @@ if (rcv_wnd == 0) rcv_wnd = dst_metric(dst, RTAX_INITRWND); @@ -5894,7 +5932,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o tp->rx_opt.rcv_wscale = rcv_wscale; tp->rcv_ssthresh = tp->rcv_wnd; -@@ -3366,6 +3434,36 @@ +@@ -3385,6 +3449,36 @@ inet_csk(sk)->icsk_rto = tcp_timeout_init(sk); inet_csk(sk)->icsk_retransmits = 0; tcp_clear_retrans(tp); @@ -5931,7 +5969,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o } static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) -@@ -3626,6 +3724,7 @@ +@@ -3645,6 +3739,7 @@ { __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt); } @@ -5939,7 +5977,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o /* This routine sends a packet with an out of date sequence * number. It assumes the other end will try to ack it. -@@ -3638,7 +3737,7 @@ +@@ -3657,7 +3752,7 @@ * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is * out-of-date with SND.UNA-1 to probe window. */ @@ -5948,7 +5986,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; -@@ -3724,7 +3823,7 @@ +@@ -3743,7 +3838,7 @@ unsigned long probe_max; int err; @@ -5957,9 +5995,9 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_o if (tp->packets_out || !tcp_send_head(sk)) { /* Cancel probe timer, if it is not required. */ -diff -aurN linux-4.14.127/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_timer.c ---- linux-4.14.127/net/ipv4/tcp_timer.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_timer.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_timer.c +--- linux-4.14.174/net/ipv4/tcp_timer.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv4/tcp_timer.c 2020-03-23 09:45:33.000000000 +0100 @@ -20,6 +20,7 @@ #include @@ -6070,7 +6108,18 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_ti sock_put(sk); } -@@ -576,7 +598,7 @@ +@@ -360,6 +382,10 @@ + + if (icsk->icsk_probes_out >= max_probes) { + abort: tcp_write_err(sk); ++ if (is_meta_sk(sk) && ++ mptcp_in_infinite_mapping_weak(tp->mpcb)) { ++ mptcp_sub_force_close_all(tp->mpcb, NULL); ++ } + } else { + /* Only send another probe if we didn't close things up. */ + tcp_send_probe0(sk); +@@ -580,7 +606,7 @@ break; case ICSK_TIME_RETRANS: icsk->icsk_pending = 0; @@ -6079,7 +6128,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_ti break; case ICSK_TIME_PROBE0: icsk->icsk_pending = 0; -@@ -591,16 +613,19 @@ +@@ -595,16 +621,19 @@ static void tcp_write_timer(unsigned long data) { struct sock *sk = (struct sock *)data; @@ -6102,7 +6151,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_ti sock_put(sk); } -@@ -630,11 +655,12 @@ +@@ -634,11 +663,12 @@ struct sock *sk = (struct sock *) data; struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); @@ -6117,7 +6166,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_ti /* Try again later. */ inet_csk_reset_keepalive_timer (sk, HZ/20); goto out; -@@ -646,16 +672,31 @@ +@@ -650,16 +680,31 @@ } tcp_mstamp_refresh(tp); @@ -6151,7 +6200,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_ti goto death; } -@@ -680,11 +721,11 @@ +@@ -684,11 +729,11 @@ icsk->icsk_probes_out > 0) || (icsk->icsk_user_timeout == 0 && icsk->icsk_probes_out >= keepalive_probes(tp))) { @@ -6165,7 +6214,7 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_ti icsk->icsk_probes_out++; elapsed = keepalive_intvl_when(tp); } else { -@@ -708,7 +749,7 @@ +@@ -712,7 +757,7 @@ tcp_done(sk); out: @@ -6174,9 +6223,9 @@ diff -aurN linux-4.14.127/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_ti sock_put(sk); } -diff -aurN linux-4.14.127/net/ipv6/addrconf.c mptcp-mptcp_v0.94/net/ipv6/addrconf.c ---- linux-4.14.127/net/ipv6/addrconf.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv6/addrconf.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv6/addrconf.c mptcp-mptcp_v0.94/net/ipv6/addrconf.c +--- linux-4.14.174/net/ipv6/addrconf.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv6/addrconf.c 2020-03-23 09:45:33.000000000 +0100 @@ -928,6 +928,7 @@ kfree_rcu(ifp, rcu); @@ -6185,9 +6234,9 @@ diff -aurN linux-4.14.127/net/ipv6/addrconf.c mptcp-mptcp_v0.94/net/ipv6/addrcon static void ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -diff -aurN linux-4.14.127/net/ipv6/af_inet6.c mptcp-mptcp_v0.94/net/ipv6/af_inet6.c ---- linux-4.14.127/net/ipv6/af_inet6.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv6/af_inet6.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv6/af_inet6.c mptcp-mptcp_v0.94/net/ipv6/af_inet6.c +--- linux-4.14.174/net/ipv6/af_inet6.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv6/af_inet6.c 2020-03-23 09:45:33.000000000 +0100 @@ -107,8 +107,7 @@ return (struct ipv6_pinfo *)(((u8 *)sk) + offset); } @@ -6198,9 +6247,9 @@ diff -aurN linux-4.14.127/net/ipv6/af_inet6.c mptcp-mptcp_v0.94/net/ipv6/af_inet { struct inet_sock *inet; struct ipv6_pinfo *np; -diff -aurN linux-4.14.127/net/ipv6/ipv6_sockglue.c mptcp-mptcp_v0.94/net/ipv6/ipv6_sockglue.c ---- linux-4.14.127/net/ipv6/ipv6_sockglue.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv6/ipv6_sockglue.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv6/ipv6_sockglue.c mptcp-mptcp_v0.94/net/ipv6/ipv6_sockglue.c +--- linux-4.14.174/net/ipv6/ipv6_sockglue.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv6/ipv6_sockglue.c 2020-03-23 09:45:33.000000000 +0100 @@ -48,6 +48,8 @@ #include #include @@ -6210,7 +6259,7 @@ diff -aurN linux-4.14.127/net/ipv6/ipv6_sockglue.c mptcp-mptcp_v0.94/net/ipv6/ip #include #include #include -@@ -216,7 +218,12 @@ +@@ -222,7 +224,12 @@ sock_prot_inuse_add(net, &tcp_prot, 1); local_bh_enable(); sk->sk_prot = &tcp_prot; @@ -6224,9 +6273,9 @@ diff -aurN linux-4.14.127/net/ipv6/ipv6_sockglue.c mptcp-mptcp_v0.94/net/ipv6/ip sk->sk_socket->ops = &inet_stream_ops; sk->sk_family = PF_INET; tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); -diff -aurN linux-4.14.127/net/ipv6/syncookies.c mptcp-mptcp_v0.94/net/ipv6/syncookies.c ---- linux-4.14.127/net/ipv6/syncookies.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv6/syncookies.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv6/syncookies.c mptcp-mptcp_v0.94/net/ipv6/syncookies.c +--- linux-4.14.174/net/ipv6/syncookies.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv6/syncookies.c 2020-03-23 09:45:33.000000000 +0100 @@ -20,6 +20,8 @@ #include #include @@ -6308,9 +6357,9 @@ diff -aurN linux-4.14.127/net/ipv6/syncookies.c mptcp-mptcp_v0.94/net/ipv6/synco ireq->rcv_wscale = rcv_wscale; ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); -diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv6.c ---- linux-4.14.127/net/ipv6/tcp_ipv6.c 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/ipv6/tcp_ipv6.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv6.c +--- linux-4.14.174/net/ipv6/tcp_ipv6.c 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/ipv6/tcp_ipv6.c 2020-03-23 09:45:33.000000000 +0100 @@ -61,6 +61,8 @@ #include #include @@ -6492,9 +6541,9 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv + struct sk_buff *skb, + bool want_cookie) { + bool l3_slave = ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags); struct inet_request_sock *ireq = inet_rsk(req); - const struct ipv6_pinfo *np = inet6_sk(sk_listener); -@@ -737,6 +750,8 @@ +@@ -738,6 +751,8 @@ refcount_inc(&skb->users); ireq->pktopts = skb; } @@ -6503,7 +6552,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv } static struct dst_entry *tcp_v6_route_req(const struct sock *sk, -@@ -756,7 +771,7 @@ +@@ -757,7 +772,7 @@ .syn_ack_timeout = tcp_syn_ack_timeout, }; @@ -6512,7 +6561,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr), #ifdef CONFIG_TCP_MD5SIG -@@ -774,9 +789,9 @@ +@@ -775,9 +790,9 @@ }; static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq, @@ -6524,7 +6573,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv { const struct tcphdr *th = tcp_hdr(skb); struct tcphdr *t1; -@@ -794,7 +809,10 @@ +@@ -795,7 +810,10 @@ if (key) tot_len += TCPOLEN_MD5SIG_ALIGNED; #endif @@ -6536,7 +6585,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, GFP_ATOMIC); if (!buff) -@@ -832,6 +850,17 @@ +@@ -833,6 +851,17 @@ tcp_v6_md5_hash_hdr((__u8 *)topt, key, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, t1); @@ -6554,7 +6603,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv } #endif -@@ -878,7 +907,7 @@ +@@ -879,7 +908,7 @@ kfree_skb(buff); } @@ -6563,7 +6612,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv { const struct tcphdr *th = tcp_hdr(skb); u32 seq = 0, ack_seq = 0; -@@ -941,7 +970,7 @@ +@@ -942,7 +971,7 @@ (th->doff << 2); oif = sk ? sk->sk_bound_dev_if : 0; @@ -6572,7 +6621,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv #ifdef CONFIG_TCP_MD5SIG out: -@@ -950,30 +979,37 @@ +@@ -951,30 +980,37 @@ } static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, @@ -6617,7 +6666,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv { /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV * sk->sk_state == TCP_SYN_RECV -> for Fast Open. -@@ -983,18 +1019,18 @@ +@@ -984,18 +1020,18 @@ * exception of segments, MUST be right-shifted by * Rcv.Wind.Shift bits: */ @@ -6640,7 +6689,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv { #ifdef CONFIG_SYN_COOKIES const struct tcphdr *th = tcp_hdr(skb); -@@ -1005,7 +1041,7 @@ +@@ -1006,7 +1042,7 @@ return sk; } @@ -6649,7 +6698,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv { if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_conn_request(sk, skb); -@@ -1031,11 +1067,11 @@ +@@ -1032,11 +1068,11 @@ sizeof(struct inet6_skb_parm)); } @@ -6666,7 +6715,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv { struct inet_request_sock *ireq; struct ipv6_pinfo *newnp; -@@ -1072,7 +1108,15 @@ +@@ -1073,7 +1109,15 @@ newnp->saddr = newsk->sk_v6_rcv_saddr; @@ -6683,7 +6732,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv newsk->sk_backlog_rcv = tcp_v4_do_rcv; #ifdef CONFIG_TCP_MD5SIG newtp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -1119,6 +1163,14 @@ +@@ -1120,6 +1164,14 @@ if (!newsk) goto out_nonewsk; @@ -6698,7 +6747,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv /* * No need to charge this sock to the relevant IPv6 refcnt debug socks * count here, tcp_create_openreq_child now does this for us, see the -@@ -1247,7 +1299,7 @@ +@@ -1248,7 +1300,7 @@ * This is because we cannot sleep with the original spinlock * held. */ @@ -6707,7 +6756,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv { struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp; -@@ -1264,6 +1316,9 @@ +@@ -1265,6 +1317,9 @@ if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_do_rcv(sk, skb); @@ -6717,7 +6766,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv /* * socket locking is here for SMP purposes as backlog rcv * is currently called with bh processing disabled. -@@ -1391,6 +1446,10 @@ +@@ -1392,6 +1447,10 @@ TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + skb->len - th->doff*4); TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); @@ -6728,7 +6777,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); TCP_SKB_CB(skb)->tcp_tw_isn = 0; TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); -@@ -1404,8 +1463,8 @@ +@@ -1405,8 +1464,8 @@ int sdif = inet6_sdif(skb); const struct tcphdr *th; const struct ipv6hdr *hdr; @@ -6738,7 +6787,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv int ret; struct net *net = dev_net(skb->dev); -@@ -1458,12 +1517,42 @@ +@@ -1459,12 +1518,42 @@ reqsk_put(req); goto csum_error; } @@ -6782,7 +6831,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv nsk = NULL; if (!tcp_filter(sk, skb)) { th = (const struct tcphdr *)skb->data; -@@ -1473,10 +1562,14 @@ +@@ -1474,10 +1563,14 @@ } if (!nsk) { reqsk_put(req); @@ -6797,7 +6846,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv tcp_v6_restore_cb(skb); } else if (tcp_child_process(sk, nsk, skb)) { tcp_v6_send_reset(nsk, skb); -@@ -1486,6 +1579,7 @@ +@@ -1487,6 +1580,7 @@ return 0; } } @@ -6805,7 +6854,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) { __NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP); goto discard_and_relse; -@@ -1512,15 +1606,25 @@ +@@ -1513,15 +1607,25 @@ sk_incoming_cpu_update(sk); @@ -6835,7 +6884,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv put_and_return: if (refcounted) -@@ -1533,6 +1637,19 @@ +@@ -1534,6 +1638,19 @@ tcp_v6_fill_cb(skb, hdr, th); @@ -6855,7 +6904,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv if (tcp_checksum_complete(skb)) { csum_error: __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1585,6 +1702,18 @@ +@@ -1586,6 +1703,18 @@ refcounted = false; goto process; } @@ -6874,7 +6923,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv /* Fall through to ACK */ } case TCP_TW_ACK: -@@ -1638,13 +1767,13 @@ +@@ -1639,13 +1768,13 @@ } } @@ -6890,7 +6939,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv .queue_xmit = inet6_csk_xmit, .send_check = tcp_v6_send_check, .rebuild_header = inet6_sk_rebuild_header, -@@ -1675,7 +1804,7 @@ +@@ -1676,7 +1805,7 @@ /* * TCP over IPv4 via INET6 API */ @@ -6899,7 +6948,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv .queue_xmit = ip_queue_xmit, .send_check = tcp_v4_send_check, .rebuild_header = inet_sk_rebuild_header, -@@ -1711,7 +1840,12 @@ +@@ -1712,7 +1841,12 @@ tcp_init_sock(sk); @@ -6913,7 +6962,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv #ifdef CONFIG_TCP_MD5SIG tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific; -@@ -1720,7 +1854,7 @@ +@@ -1721,7 +1855,7 @@ return 0; } @@ -6922,7 +6971,7 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv { tcp_v4_destroy_sock(sk); inet6_destroy_sock(sk); -@@ -1954,6 +2088,9 @@ +@@ -1955,6 +2089,9 @@ .compat_getsockopt = compat_tcp_getsockopt, #endif .diag_destroy = tcp_abort, @@ -6932,9 +6981,9 @@ diff -aurN linux-4.14.127/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv }; /* thinking of making this const? Don't. -diff -aurN linux-4.14.127/net/Kconfig mptcp-mptcp_v0.94/net/Kconfig ---- linux-4.14.127/net/Kconfig 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/Kconfig 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/Kconfig mptcp-mptcp_v0.94/net/Kconfig +--- linux-4.14.174/net/Kconfig 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/Kconfig 2020-03-23 09:45:33.000000000 +0100 @@ -88,6 +88,7 @@ source "net/ipv4/Kconfig" source "net/ipv6/Kconfig" @@ -6943,9 +6992,9 @@ diff -aurN linux-4.14.127/net/Kconfig mptcp-mptcp_v0.94/net/Kconfig endif # if INET -diff -aurN linux-4.14.127/net/Makefile mptcp-mptcp_v0.94/net/Makefile ---- linux-4.14.127/net/Makefile 2019-06-17 19:52:45.000000000 +0200 -+++ mptcp-mptcp_v0.94/net/Makefile 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/Makefile mptcp-mptcp_v0.94/net/Makefile +--- linux-4.14.174/net/Makefile 2020-03-20 10:54:27.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/Makefile 2020-03-23 09:45:33.000000000 +0100 @@ -20,6 +20,7 @@ obj-$(CONFIG_XFRM) += xfrm/ obj-$(CONFIG_UNIX) += unix/ @@ -6954,9 +7003,9 @@ diff -aurN linux-4.14.127/net/Makefile mptcp-mptcp_v0.94/net/Makefile obj-$(CONFIG_PACKET) += packet/ obj-$(CONFIG_NET_KEY) += key/ obj-$(CONFIG_BRIDGE) += bridge/ -diff -aurN linux-4.14.127/net/mptcp/Kconfig mptcp-mptcp_v0.94/net/mptcp/Kconfig ---- linux-4.14.127/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/Kconfig 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/Kconfig mptcp-mptcp_v0.94/net/mptcp/Kconfig +--- linux-4.14.174/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/Kconfig 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,129 @@ +# +# MPTCP configuration @@ -7001,7 +7050,7 @@ diff -aurN linux-4.14.127/net/mptcp/Kconfig mptcp-mptcp_v0.94/net/mptcp/Kconfig + +choice + prompt "Default MPTCP Path-Manager" -+ default DEFAULT ++ default DEFAULT_DUMMY + help + Select the Path-Manager of your choice + @@ -7024,7 +7073,7 @@ diff -aurN linux-4.14.127/net/mptcp/Kconfig mptcp-mptcp_v0.94/net/mptcp/Kconfig +config DEFAULT_MPTCP_PM + string + default "default" if DEFAULT_DUMMY -+ default "fullmesh" if DEFAULT_FULLMESH ++ default "fullmesh" if DEFAULT_FULLMESH + default "ndiffports" if DEFAULT_NDIFFPORTS + default "binder" if DEFAULT_BINDER + default "default" @@ -7054,7 +7103,7 @@ diff -aurN linux-4.14.127/net/mptcp/Kconfig mptcp-mptcp_v0.94/net/mptcp/Kconfig + +choice + prompt "Default MPTCP Scheduler" -+ default DEFAULT ++ default DEFAULT_SCHEDULER + help + Select the Scheduler of your choice + @@ -7087,9 +7136,9 @@ diff -aurN linux-4.14.127/net/mptcp/Kconfig mptcp-mptcp_v0.94/net/mptcp/Kconfig + default "redundant" if DEFAULT_REDUNDANT + default "default" + -diff -aurN linux-4.14.127/net/mptcp/Makefile mptcp-mptcp_v0.94/net/mptcp/Makefile ---- linux-4.14.127/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/Makefile 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/Makefile mptcp-mptcp_v0.94/net/mptcp/Makefile +--- linux-4.14.174/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/Makefile 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,22 @@ +# +## Makefile for MultiPath TCP support code. @@ -7113,9 +7162,9 @@ diff -aurN linux-4.14.127/net/mptcp/Makefile mptcp-mptcp_v0.94/net/mptcp/Makefil + +mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o + -diff -aurN linux-4.14.127/net/mptcp/mptcp_balia.c mptcp-mptcp_v0.94/net/mptcp/mptcp_balia.c ---- linux-4.14.127/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_balia.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_balia.c mptcp-mptcp_v0.94/net/mptcp/mptcp_balia.c +--- linux-4.14.174/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_balia.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,268 @@ +/* + * MPTCP implementation - Balia Congestion Control @@ -7385,9 +7434,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_balia.c mptcp-mptcp_v0.94/net/mptcp/mp +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP BALIA CONGESTION CONTROL ALGORITHM"); +MODULE_VERSION("0.1"); -diff -aurN linux-4.14.127/net/mptcp/mptcp_binder.c mptcp-mptcp_v0.94/net/mptcp/mptcp_binder.c ---- linux-4.14.127/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_binder.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_binder.c mptcp-mptcp_v0.94/net/mptcp/mptcp_binder.c +--- linux-4.14.174/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_binder.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,490 @@ +#include + @@ -7879,9 +7928,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_binder.c mptcp-mptcp_v0.94/net/mptcp/m +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("BINDER MPTCP"); +MODULE_VERSION("0.1"); -diff -aurN linux-4.14.127/net/mptcp/mptcp_coupled.c mptcp-mptcp_v0.94/net/mptcp/mptcp_coupled.c ---- linux-4.14.127/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_coupled.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_coupled.c mptcp-mptcp_v0.94/net/mptcp/mptcp_coupled.c +--- linux-4.14.174/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_coupled.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,271 @@ +/* + * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) @@ -8154,10 +8203,10 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_coupled.c mptcp-mptcp_v0.94/net/mptcp/ +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP LINKED INCREASE CONGESTION CONTROL ALGORITHM"); +MODULE_VERSION("0.1"); -diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ctrl.c ---- linux-4.14.127/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ctrl.c 2019-06-17 23:59:30.000000000 +0200 -@@ -0,0 +1,3014 @@ +diff -aurN linux-4.14.174/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ctrl.c +--- linux-4.14.174/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ctrl.c 2020-03-23 09:45:33.000000000 +0100 +@@ -0,0 +1,3038 @@ +/* + * MPTCP implementation - MPTCP-control + * @@ -8933,6 +8982,24 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + } +} + ++static int mptcp_set_congestion_control(struct sock *meta_sk, const char *name, ++ bool load, bool reinit, bool cap_net_admin) ++{ ++ int err, result = 0; ++ struct sock *sk_it; ++ ++ result = __tcp_set_congestion_control(meta_sk, name, load, reinit, cap_net_admin); ++ ++ tcp_sk(meta_sk)->mpcb->tcp_ca_explicit_set = true; ++ ++ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk_it) { ++ err = __tcp_set_congestion_control(sk_it, name, load, reinit, cap_net_admin); ++ if (err) ++ result = err; ++ } ++ return result; ++} ++ +static void mptcp_assign_congestion_control(struct sock *sk) +{ + struct inet_connection_sock *icsk = inet_csk(sk); @@ -8941,8 +9008,11 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + + /* Congestion control is the same as meta. Thus, it has been + * try_module_get'd by tcp_assign_congestion_control. ++ * Congestion control on meta was not explicitly configured by ++ * application, leave default or route based. + */ -+ if (icsk->icsk_ca_ops == ca) ++ if (icsk->icsk_ca_ops == ca || ++ !tcp_sk(mptcp_meta_sk(sk))->mpcb->tcp_ca_explicit_set) + return; + + /* Use the same congestion control as set on the meta-sk */ @@ -8954,6 +9024,7 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + WARN(1, "Could not get the congestion control!"); + return; + } ++ module_put(icsk->icsk_ca_ops->owner); + icsk->icsk_ca_ops = ca; + + /* Clear out private data before diag gets it and @@ -9221,6 +9292,7 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + .retransmit_timer = mptcp_meta_retransmit_timer, + .time_wait = mptcp_time_wait, + .cleanup_rbuf = mptcp_cleanup_rbuf, ++ .set_cong_ctrl = mptcp_set_congestion_control, +}; + +static const struct tcp_sock_ops mptcp_sub_specific = { @@ -9238,6 +9310,7 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + .retransmit_timer = mptcp_sub_retransmit_timer, + .time_wait = tcp_time_wait, + .cleanup_rbuf = tcp_cleanup_rbuf, ++ .set_cong_ctrl = __tcp_set_congestion_control, +}; + +static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, @@ -9261,6 +9334,7 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + goto err_alloc_master; + + master_tp = tcp_sk(master_sk); ++ master_tp->inside_tk_table = 0; + + mpcb = kmem_cache_zalloc(mptcp_cb_cache, GFP_ATOMIC); + if (!mpcb) @@ -9331,7 +9405,6 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + local_bh_enable(); + rcu_read_unlock(); + } -+ master_tp->inside_tk_table = 0; + +#if IS_ENABLED(CONFIG_IPV6) + if (meta_icsk->icsk_af_ops == &mptcp_v6_mapped) { @@ -10312,7 +10385,6 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + u8 hash_mac_check[20]; + + child_tp->out_of_order_queue = RB_ROOT; -+ child_tp->inside_tk_table = 0; + + if (!mopt->join_ack) { + MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKFAIL); @@ -10453,11 +10525,12 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + if (tw->mptcp_tw->in_list) { + list_del_rcu(&tw->mptcp_tw->list); + tw->mptcp_tw->in_list = 0; ++ /* Put, because we added it to the list */ ++ mptcp_mpcb_put(mpcb); + } + spin_unlock(&mpcb->tw_lock); + -+ /* Twice, because we increased it above */ -+ mptcp_mpcb_put(mpcb); ++ /* Second time, because we increased it above */ + mptcp_mpcb_put(mpcb); + } + @@ -11143,7 +11216,7 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt + if (mptcp_register_scheduler(&mptcp_sched_default)) + goto register_sched_failed; + -+ pr_info("MPTCP: Stable release v0.94.6"); ++ pr_info("MPTCP: Stable release v0.94.7"); + + mptcp_init_failed = false; + @@ -11172,9 +11245,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mpt +mptcp_sock_cache_failed: + mptcp_init_failed = true; +} -diff -aurN linux-4.14.127/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_v0.94/net/mptcp/mptcp_fullmesh.c ---- linux-4.14.127/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_fullmesh.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_v0.94/net/mptcp/mptcp_fullmesh.c +--- linux-4.14.174/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_fullmesh.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,2016 @@ +#include +#include @@ -13192,9 +13265,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_v0.94/net/mptcp +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Full-Mesh MPTCP"); +MODULE_VERSION("0.88"); -diff -aurN linux-4.14.127/net/mptcp/mptcp_input.c mptcp-mptcp_v0.94/net/mptcp/mptcp_input.c ---- linux-4.14.127/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_input.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_input.c mptcp-mptcp_v0.94/net/mptcp/mptcp_input.c +--- linux-4.14.174/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_input.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,2475 @@ +/* + * MPTCP implementation - Sending side @@ -15671,9 +15744,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_input.c mptcp-mptcp_v0.94/net/mptcp/mp + tcp_set_rto(sk); + mptcp_set_rto(sk); +} -diff -aurN linux-4.14.127/net/mptcp/mptcp_ipv4.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv4.c ---- linux-4.14.127/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv4.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_ipv4.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv4.c +--- linux-4.14.174/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv4.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,436 @@ +/* + * MPTCP implementation - IPv4-specific functions @@ -16111,9 +16184,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ipv4.c mptcp-mptcp_v0.94/net/mptcp/mpt + kmem_cache_destroy(mptcp_request_sock_ops.slab); + kfree(mptcp_request_sock_ops.slab_name); +} -diff -aurN linux-4.14.127/net/mptcp/mptcp_ipv6.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv6.c ---- linux-4.14.127/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv6.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_ipv6.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv6.c +--- linux-4.14.174/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv6.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,465 @@ +/* + * MPTCP implementation - IPv6-specific functions @@ -16580,9 +16653,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ipv6.c mptcp-mptcp_v0.94/net/mptcp/mpt + kmem_cache_destroy(mptcp6_request_sock_ops.slab); + kfree(mptcp6_request_sock_ops.slab_name); +} -diff -aurN linux-4.14.127/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ndiffports.c ---- linux-4.14.127/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ndiffports.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ndiffports.c +--- linux-4.14.174/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ndiffports.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,173 @@ +#include + @@ -16757,9 +16830,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_v0.94/net/mpt +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("NDIFF-PORTS MPTCP"); +MODULE_VERSION("0.88"); -diff -aurN linux-4.14.127/net/mptcp/mptcp_olia.c mptcp-mptcp_v0.94/net/mptcp/mptcp_olia.c ---- linux-4.14.127/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_olia.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_olia.c mptcp-mptcp_v0.94/net/mptcp/mptcp_olia.c +--- linux-4.14.174/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_olia.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,310 @@ +/* + * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: @@ -17071,9 +17144,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_olia.c mptcp-mptcp_v0.94/net/mptcp/mpt +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP COUPLED CONGESTION CONTROL"); +MODULE_VERSION("0.1"); -diff -aurN linux-4.14.127/net/mptcp/mptcp_output.c mptcp-mptcp_v0.94/net/mptcp/mptcp_output.c ---- linux-4.14.127/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_output.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_output.c mptcp-mptcp_v0.94/net/mptcp/mptcp_output.c +--- linux-4.14.174/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_output.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,1824 @@ +/* + * MPTCP implementation - Sending side @@ -18899,9 +18972,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_output.c mptcp-mptcp_v0.94/net/mptcp/m + return max(xmit_size_goal, mss_now); +} + -diff -aurN linux-4.14.127/net/mptcp/mptcp_pm.c mptcp-mptcp_v0.94/net/mptcp/mptcp_pm.c ---- linux-4.14.127/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_pm.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_pm.c mptcp-mptcp_v0.94/net/mptcp/mptcp_pm.c +--- linux-4.14.174/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_pm.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,226 @@ +/* + * MPTCP implementation - MPTCP-subflow-management @@ -19129,9 +19202,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_pm.c mptcp-mptcp_v0.94/net/mptcp/mptcp + return mptcp_set_default_path_manager(CONFIG_DEFAULT_MPTCP_PM); +} +late_initcall(mptcp_path_manager_default); -diff -aurN linux-4.14.127/net/mptcp/mptcp_redundant.c mptcp-mptcp_v0.94/net/mptcp/mptcp_redundant.c ---- linux-4.14.127/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_redundant.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_redundant.c mptcp-mptcp_v0.94/net/mptcp/mptcp_redundant.c +--- linux-4.14.174/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_redundant.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,301 @@ +/* + * MPTCP Scheduler to reduce latency and jitter. @@ -19434,9 +19507,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_redundant.c mptcp-mptcp_v0.94/net/mptc +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("REDUNDANT MPTCP"); +MODULE_VERSION("0.90"); -diff -aurN linux-4.14.127/net/mptcp/mptcp_rr.c mptcp-mptcp_v0.94/net/mptcp/mptcp_rr.c ---- linux-4.14.127/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_rr.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_rr.c mptcp-mptcp_v0.94/net/mptcp/mptcp_rr.c +--- linux-4.14.174/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_rr.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,301 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -19739,10 +19812,10 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_rr.c mptcp-mptcp_v0.94/net/mptcp/mptcp +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ROUNDROBIN MPTCP"); +MODULE_VERSION("0.89"); -diff -aurN linux-4.14.127/net/mptcp/mptcp_sched.c mptcp-mptcp_v0.94/net/mptcp/mptcp_sched.c ---- linux-4.14.127/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_sched.c 2019-06-17 23:59:30.000000000 +0200 -@@ -0,0 +1,634 @@ +diff -aurN linux-4.14.174/net/mptcp/mptcp_sched.c mptcp-mptcp_v0.94/net/mptcp/mptcp_sched.c +--- linux-4.14.174/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_sched.c 2020-03-23 09:45:33.000000000 +0100 +@@ -0,0 +1,633 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + +#include @@ -20041,7 +20114,7 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_sched.c mptcp-mptcp_v0.94/net/mptcp/mp + if (tcp_jiffies32 - dsp->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) + goto retrans; + -+ /* Half the cwnd of the slow flow */ ++ /* Half the cwnd of the slow flows */ + mptcp_for_each_tp(tp->mpcb, tp_it) { + if (tp_it != tp && + TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { @@ -20056,7 +20129,6 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_sched.c mptcp-mptcp_v0.94/net/mptcp/mp + + dsp->last_rbuf_opti = tcp_jiffies32; + } -+ //break; + } + } + @@ -20377,9 +20449,9 @@ diff -aurN linux-4.14.127/net/mptcp/mptcp_sched.c mptcp-mptcp_v0.94/net/mptcp/mp + return mptcp_set_default_scheduler(CONFIG_DEFAULT_MPTCP_SCHED); +} +late_initcall(mptcp_scheduler_default); -diff -aurN linux-4.14.127/net/mptcp/mptcp_wvegas.c mptcp-mptcp_v0.94/net/mptcp/mptcp_wvegas.c ---- linux-4.14.127/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_wvegas.c 2019-06-17 23:59:30.000000000 +0200 +diff -aurN linux-4.14.174/net/mptcp/mptcp_wvegas.c mptcp-mptcp_v0.94/net/mptcp/mptcp_wvegas.c +--- linux-4.14.174/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_v0.94/net/mptcp/mptcp_wvegas.c 2020-03-23 09:45:33.000000000 +0100 @@ -0,0 +1,270 @@ +/* + * MPTCP implementation - WEIGHTED VEGAS From 5ca9d129bc28a339115028c3449b44bf22c508c4 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 1 Apr 2020 14:46:22 +0200 Subject: [PATCH 10/76] Fix modules dependencie for bpi-r2 --- root/target/linux/mediatek/modules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/root/target/linux/mediatek/modules.mk b/root/target/linux/mediatek/modules.mk index 51217b1b..08961d75 100644 --- a/root/target/linux/mediatek/modules.mk +++ b/root/target/linux/mediatek/modules.mk @@ -52,7 +52,7 @@ $(eval $(call KernelPackage,crypto-hw-mtk)) define KernelPackage/nat-hw-mtk TITLE:= MediaTek's hardware NAT module - DEPENDS:=@TARGET_mediatek @!LINUX_4_19 + DEPENDS:=@TARGET_mediatek @LINUX_4_14 KCONFIG:= \ CONFIG_NET_MEDIATEK_HNAT=y FILES:=$(LINUX_DIR)/drivers/net/ethernet/mediatek/mtk_hnat/mtkhnat.ko From e3c42cf474856aa3db878fa036cbe3573c720762 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 1 Apr 2020 14:47:18 +0200 Subject: [PATCH 11/76] Update OpenWrt and disable UEFI patch not needed anymore --- build.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/build.sh b/build.sh index 890e0336..3f06b9d0 100755 --- a/build.sh +++ b/build.sh @@ -25,7 +25,7 @@ OMR_PORT=${OMR_PORT:-8000} OMR_REPO=${OMR_REPO:-http://$OMR_HOST:$OMR_PORT/release/$OMR_KERNEL} OMR_KEEPBIN=${OMR_KEEPBIN:-no} OMR_IMG=${OMR_IMG:-yes} -OMR_UEFI=${OMR_UEFI:-yes} +#OMR_UEFI=${OMR_UEFI:-yes} OMR_ALL_PACKAGES=${OMR_ALL_PACKAGES:-no} OMR_TARGET=${OMR_TARGET:-x86_64} OMR_TARGET_CONFIG="config-$OMR_TARGET" @@ -58,9 +58,9 @@ else fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" -_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "437eb41f235c25b397a9867527d738778ea489d7" -_get_repo feeds/packages https://github.com/openwrt/packages "61088496009579f86ebc1756e2331dee879ab333" -_get_repo feeds/luci https://github.com/openwrt/luci "3d965195928b993f7e2dacebd4e296a547b32552" +_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "5562c5add2faa5d407c308a98517b2b5cc6d84da" +_get_repo feeds/packages https://github.com/openwrt/packages "f0264eea08761d939b5412cd3f31b824496aa794" +_get_repo feeds/luci https://github.com/openwrt/luci "65a461e8a0340a361545d3510918f34edb27920c" if [ -z "$OMR_FEED" ]; then OMR_FEED=feeds/openmptcprouter @@ -140,17 +140,17 @@ fi cd "$OMR_TARGET/source" -if [ "$OMR_UEFI" = "yes" ] && [ "$OMR_TARGET" = "x86_64" ]; then - echo "Checking if UEFI patch is set or not" - if [ "$(grep 'EFI_IMAGES' target/linux/x86/image/Makefile)" = "" ]; then - patch -N -p1 -s < ../../patches/uefi.patch - fi - echo "Done" -else - if [ "$(grep 'EFI_IMAGES' target/linux/x86/image/Makefile)" != "" ]; then - patch -N -R -p1 -s < ../../patches/uefi.patch - fi -fi +#if [ "$OMR_UEFI" = "yes" ] && [ "$OMR_TARGET" = "x86_64" ]; then +# echo "Checking if UEFI patch is set or not" +# if [ "$(grep 'EFI_IMAGES' target/linux/x86/image/Makefile)" = "" ]; then +# patch -N -p1 -s < ../../patches/uefi.patch +# fi +# echo "Done" +#else +# if [ "$(grep 'EFI_IMAGES' target/linux/x86/image/Makefile)" != "" ]; then +# patch -N -R -p1 -s < ../../patches/uefi.patch +# fi +#fi #if [ "$OMR_TARGET" = "x86_64" ]; then # echo "Checking if Hyper-V patch is set or not" From b46478b0ba5b3845b62efc7af22413868115733a Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 2 Apr 2020 14:14:51 +0200 Subject: [PATCH 12/76] Add Full Cone NAT support --- build.sh | 10 +++++ patches/fullconenat-luci.patch | 13 ++++++ .../config/firewall/patches/fullconenat.patch | 40 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 patches/fullconenat-luci.patch create mode 100644 root/package/network/config/firewall/patches/fullconenat.patch diff --git a/build.sh b/build.sh index 3f06b9d0..450b58ef 100755 --- a/build.sh +++ b/build.sh @@ -228,6 +228,16 @@ echo "Update feeds index" cp .config .config.keep scripts/feeds clean scripts/feeds update -a + +cd - +echo "Checking if fullconenat-luci patch is set or not" +if ! patch -Rf -N -p1 -s --dry-run < patches/fullconenat-luci.patch; then + echo "apply..." + patch -N -p1 -s < patches/fullconenat-luci.patch +fi +echo "Done" +cd "$OMR_TARGET/source" + if [ "$OMR_ALL_PACKAGES" = "yes" ]; then scripts/feeds install -a -p packages scripts/feeds install -a -p luci diff --git a/patches/fullconenat-luci.patch b/patches/fullconenat-luci.patch new file mode 100644 index 00000000..248d4dce --- /dev/null +++ b/patches/fullconenat-luci.patch @@ -0,0 +1,13 @@ +--- a/feeds/luci/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js ++++ b/feeds/luci/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js +@@ -131,6 +131,10 @@ return L.view.extend({ + o = s.taboption('general', form.Flag, 'masq', _('Masquerading')); + o.editable = true; + ++ o = s.taboption('general', form.Flag, 'fullcone', _('Full Cone')); ++ o.editable = true; ++ o.depends('masq', '1'); ++ + o = s.taboption('general', form.Flag, 'mtu_fix', _('MSS clamping')); + o.modalonly = true; + diff --git a/root/package/network/config/firewall/patches/fullconenat.patch b/root/package/network/config/firewall/patches/fullconenat.patch new file mode 100644 index 00000000..825e8c1d --- /dev/null +++ b/root/package/network/config/firewall/patches/fullconenat.patch @@ -0,0 +1,40 @@ +--- a/options.h ++++ b/options.h +@@ -341,6 +341,8 @@ struct fw3_zone + struct list_head masq_src; + struct list_head masq_dest; + ++ bool fullcone; ++ + bool mtu_fix; + + struct list_head cthelpers; +--- a/zones.c ++++ b/zones.c +@@ -77,6 +77,8 @@ const struct fw3_option fw3_zone_opts[] + FW3_LIST("masq_src", network, zone, masq_src), + FW3_LIST("masq_dest", network, zone, masq_dest), + ++ FW3_OPT("fullcone", bool, zone, fullcone), ++ + FW3_OPT("extra", string, zone, extra_src), + FW3_OPT("extra_src", string, zone, extra_src), + FW3_OPT("extra_dest", string, zone, extra_dest), +@@ -709,7 +711,16 @@ print_zone_rule(struct fw3_ipt_handle *h + (mdest = next_addr(mdest, &zone->masq_dest, + handle->family, false)) || first_dest; + first_dest = false) +- { ++ if (zone->fullcone && (access("/usr/lib/iptables/libipt_FULLCONENAT.so", 0) == 0)) { ++ r = fw3_ipt_rule_new(handle); ++ fw3_ipt_rule_src_dest(r, msrc, mdest); ++ fw3_ipt_rule_target(r, "FULLCONENAT"); ++ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); ++ r = fw3_ipt_rule_new(handle); ++ fw3_ipt_rule_src_dest(r, msrc, mdest); ++ fw3_ipt_rule_target(r, "FULLCONENAT"); ++ fw3_ipt_rule_append(r, "zone_%s_prerouting", zone->name); ++ } else { + r = fw3_ipt_rule_new(handle); + fw3_ipt_rule_src_dest(r, msrc, mdest); + fw3_ipt_rule_target(r, "MASQUERADE"); From e936a82cd5a1945a54035e86146bfe5e5d771906 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 3 Apr 2020 21:18:24 +0200 Subject: [PATCH 13/76] Update bpi-r2 config --- root/target/linux/mediatek/image/Makefile | 1 + root/target/linux/mediatek/image/mt7623.mk | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/root/target/linux/mediatek/image/Makefile b/root/target/linux/mediatek/image/Makefile index 089682ac..994a66b8 100644 --- a/root/target/linux/mediatek/image/Makefile +++ b/root/target/linux/mediatek/image/Makefile @@ -1,6 +1,7 @@ # # Copyright (C) 2012-2015 OpenWrt.org # Copyright (C) 2016-2017 LEDE project +# Copyright (C) 2018-2019 Ycarus (Yannick Chabanois) for OpenMPTCProuter # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. diff --git a/root/target/linux/mediatek/image/mt7623.mk b/root/target/linux/mediatek/image/mt7623.mk index a547d535..a8738147 100644 --- a/root/target/linux/mediatek/image/mt7623.mk +++ b/root/target/linux/mediatek/image/mt7623.mk @@ -1,16 +1,19 @@ -define Device/7623a-unielec-u7623-02-emmc-512m - DEVICE_TITLE := MTK7623a UniElec U7623-02 (eMMC/512MB RAM) - DEVICE_DTS := mt7623a-unielec-u7623-02-emmc-512M +define Device/unielec-u7623-02-emmc-512m + DEVICE_VENDOR := UniElec + DEVICE_MODEL := U7623-02 + DEVICE_VARIANT := eMMC/512MB RAM + DEVICE_DTS := mt7623a-unielec-u7623-02-emmc-512m DEVICE_PACKAGES := mkf2fs e2fsprogs kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 kmod-mmc SUPPORTED_DEVICES := unielec,u7623-02-emmc-512m IMAGES := sysupgrade-emmc.bin.gz IMAGE/sysupgrade-emmc.bin.gz := sysupgrade-emmc | gzip | append-metadata endef -TARGET_DEVICES += 7623a-unielec-u7623-02-emmc-512m +TARGET_DEVICES += unielec-u7623-02-emmc-512m define Device/7623n-bananapi-bpi-r2 - DEVICE_TITLE := MTK7623n BananaPi R2 + DEVICE_VENDOR := Bpi + DEVICE_MODEL := Banana Pi R2 DEVICE_DTS := mt7623n-bananapi-bpi-r2 # DEVICE_PACKAGES := wmt uboot-mtk-bpi-r2 kmod-crypto-hw-mtk kmod-nat-hw-mtk DEVICE_PACKAGES := wmt uboot-mtk-bpi-r2 kmod-crypto-hw-mtk kmod-mt6625l-wlan-gen2 kmod-usb-core kmod-ata-core kmod-usb3 kmod-usb2 kmod-usb-ohci mt7623n-preloader From 43075aac5a432acd4c67857baba1d7520529b38f Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 3 Apr 2020 21:19:24 +0200 Subject: [PATCH 14/76] Add patch for full cone nat --- ...k-events-support-multiple-registrant.patch | 325 ++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 root/target/linux/generic/hack-5.4/952-net-conntrack-events-support-multiple-registrant.patch diff --git a/root/target/linux/generic/hack-5.4/952-net-conntrack-events-support-multiple-registrant.patch b/root/target/linux/generic/hack-5.4/952-net-conntrack-events-support-multiple-registrant.patch new file mode 100644 index 00000000..f844328d --- /dev/null +++ b/root/target/linux/generic/hack-5.4/952-net-conntrack-events-support-multiple-registrant.patch @@ -0,0 +1,325 @@ +diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h +index 12d967b..c2b98b6 100644 +--- a/include/net/netfilter/nf_conntrack_ecache.h ++++ b/include/net/netfilter/nf_conntrack_ecache.h +@@ -71,6 +71,10 @@ struct nf_ct_event { + int report; + }; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb); ++extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb); ++#else + struct nf_ct_event_notifier { + int (*fcn)(unsigned int events, struct nf_ct_event *item); + }; +@@ -79,7 +83,7 @@ int nf_conntrack_register_notifier(struc + struct nf_ct_event_notifier *nb); + void nf_conntrack_unregister_notifier(struct net *net, + struct nf_ct_event_notifier *nb); +- ++#endif + void nf_ct_deliver_cached_events(struct nf_conn *ct); + int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, + u32 portid, int report); +@@ -87,12 +91,15 @@ int nf_conntrack_eventmask_report(unsign + static inline void + nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) + { +- struct net *net = nf_ct_net(ct); + struct nf_conntrack_ecache *e; ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return; + ++#endif ++ + e = nf_ct_ecache_find(ct); + if (e == NULL) + return; +@@ -104,10 +111,12 @@ static inline int + nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, + u32 portid, int report) + { ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + const struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return 0; ++#endif + + return nf_conntrack_eventmask_report(1 << event, ct, portid, report); + } +@@ -115,11 +124,14 @@ nf_conntrack_event_report(enum ip_conntr + static inline int + nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) + { ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + const struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return 0; + ++#endif ++ + return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); + } + +diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h +index e469e85..1d31db8 100644 +--- a/include/net/netns/conntrack.h ++++ b/include/net/netns/conntrack.h +@@ -114,7 +114,11 @@ struct netns_ct { + + struct ct_pcpu __percpu *pcpu_lists; + struct ip_conntrack_stat __percpu *stat; ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ struct atomic_notifier_head nf_conntrack_chain; ++#else + struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; ++#endif + struct nf_exp_event_notifier __rcu *nf_expect_event_cb; + struct nf_ip_net nf_ct_proto; + #if defined(CONFIG_NF_CONNTRACK_LABELS) +diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig +index 63073be..08d7aab 100644 +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -118,6 +118,14 @@ config NF_CONNTRACK_EVENTS + + If unsure, say `N'. + ++config NF_CONNTRACK_CHAIN_EVENTS ++ bool "Register multiple callbacks to ct events" ++ depends on NF_CONNTRACK_EVENTS ++ help ++ Support multiple registrations. ++ ++ If unsure, say `N'. ++ + config NF_CONNTRACK_TIMEOUT + bool 'Connection tracking timeout' + depends on NETFILTER_ADVANCED +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index 6bd1508..9b81c7c 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -2167,6 +2167,10 @@ int nf_conntrack_init_net(struct net *ne + ret = nf_conntrack_proto_pernet_init(net); + if (ret < 0) + goto err_proto; ++ ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain); ++#endif + return 0; + + err_proto: +diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c +index da9df2d..e0e2a8f 100644 +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -18,6 +18,9 @@ + #include + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++#include ++#endif + #include + #include + #include +@@ -117,6 +120,38 @@ static void ecache_work(struct work_stru + schedule_delayed_work(&ctnet->ecache_dwork, delay); + } + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++int ++nf_conntrack_eventmask_report(unsigned int eventmask, ++ struct nf_conn *ct, ++ u32 portid, ++ int report) ++{ ++ struct nf_conntrack_ecache *e; ++ struct net *net = nf_ct_net(ct); ++ ++ e = nf_ct_ecache_find(ct); ++ if (e == NULL) ++ return 0; ++ ++ if (nf_ct_is_confirmed(ct)) { ++ struct nf_ct_event item = { ++ .ct = ct, ++ .portid = e->portid ? e->portid : portid, ++ .report = report ++ }; ++ /* This is a resent of a destroy event? If so, skip missed */ ++ unsigned long missed = e->portid ? 0 : e->missed; ++ ++ if (!((eventmask | missed) & e->ctmask)) ++ return 0; ++ ++ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item); ++ } ++ ++ return 0; ++} ++#else + int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, + u32 portid, int report) + { +@@ -171,10 +206,52 @@ out_unlock: + rcu_read_unlock(); + return ret; + } ++#endif + EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report); + + /* deliver cached events and clear cache entry - must be called with locally + * disabled softirqs */ ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++void nf_ct_deliver_cached_events(struct nf_conn *ct) ++{ ++ unsigned long events, missed; ++ struct nf_conntrack_ecache *e; ++ struct nf_ct_event item; ++ struct net *net = nf_ct_net(ct); ++ ++ e = nf_ct_ecache_find(ct); ++ if (e == NULL) ++ return; ++ ++ events = xchg(&e->cache, 0); ++ ++ if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events) ++ return; ++ ++ /* We make a copy of the missed event cache without taking ++ * the lock, thus we may send missed events twice. However, ++ * this does not harm and it happens very rarely. */ ++ missed = e->missed; ++ ++ if (!((events | missed) & e->ctmask)) ++ return; ++ ++ item.ct = ct; ++ item.portid = 0; ++ item.report = 0; ++ ++ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, ++ events | missed, ++ &item); ++ ++ if (likely(!missed)) ++ return; ++ ++ spin_lock_bh(&ct->lock); ++ e->missed &= ~missed; ++ spin_unlock_bh(&ct->lock); ++} ++#else + void nf_ct_deliver_cached_events(struct nf_conn *ct) + { + struct net *net = nf_ct_net(ct); +@@ -225,6 +302,7 @@ void nf_ct_deliver_cached_events(struct + out_unlock: + rcu_read_unlock(); + } ++#endif + EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); + + void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, +@@ -257,6 +335,12 @@ out_unlock: + rcu_read_unlock(); + } + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb); ++} ++#else + int nf_conntrack_register_notifier(struct net *net, + struct nf_ct_event_notifier *new) + { +@@ -277,8 +361,15 @@ out_unlock: + mutex_unlock(&nf_ct_ecache_mutex); + return ret; + } ++#endif + EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier); + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb); ++} ++#else + void nf_conntrack_unregister_notifier(struct net *net, + struct nf_ct_event_notifier *new) + { +@@ -292,6 +383,7 @@ void nf_conntrack_unregister_notifier(st + mutex_unlock(&nf_ct_ecache_mutex); + /* synchronize_rcu() is called from ctnetlink_exit. */ + } ++#endif + EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); + + int nf_ct_expect_register_notifier(struct net *net, +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 04111c1..8c741f7 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -28,6 +28,11 @@ + #include + #include + #include ++ ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++#include ++#endif ++ + #include + + #include +@@ -618,14 +623,22 @@ static size_t ctnetlink_nlmsg_size(const + ; + } + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++static int ctnetlink_conntrack_event(struct notifier_block *this, ++ unsigned long events, void *ptr) ++#else + static int + ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) ++#endif + { + const struct nf_conntrack_zone *zone; + struct net *net; + struct nlmsghdr *nlh; + struct nfgenmsg *nfmsg; + struct nlattr *nest_parms; ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ struct nf_ct_event *item = (struct nf_ct_event *)ptr; ++#endif + struct nf_conn *ct = item->ct; + struct sk_buff *skb; + unsigned int type; +@@ -3290,9 +3303,15 @@ static int ctnetlink_stat_exp_cpu(struct + } + + #ifdef CONFIG_NF_CONNTRACK_EVENTS ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++static struct notifier_block ctnl_notifier = { ++ .notifier_call = ctnetlink_conntrack_event, ++}; ++#else + static struct nf_ct_event_notifier ctnl_notifier = { + .fcn = ctnetlink_conntrack_event, + }; ++#endif + + static struct nf_exp_event_notifier ctnl_notifier_exp = { + .fcn = ctnetlink_expect_event, From e323e7ec6fd773c2172945c41f87d6d153edbc0d Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 3 Apr 2020 21:46:02 +0200 Subject: [PATCH 15/76] Revert "Add patch for full cone nat" This reverts commit 43075aac5a432acd4c67857baba1d7520529b38f. --- ...k-events-support-multiple-registrant.patch | 325 ------------------ 1 file changed, 325 deletions(-) delete mode 100644 root/target/linux/generic/hack-5.4/952-net-conntrack-events-support-multiple-registrant.patch diff --git a/root/target/linux/generic/hack-5.4/952-net-conntrack-events-support-multiple-registrant.patch b/root/target/linux/generic/hack-5.4/952-net-conntrack-events-support-multiple-registrant.patch deleted file mode 100644 index f844328d..00000000 --- a/root/target/linux/generic/hack-5.4/952-net-conntrack-events-support-multiple-registrant.patch +++ /dev/null @@ -1,325 +0,0 @@ -diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h -index 12d967b..c2b98b6 100644 ---- a/include/net/netfilter/nf_conntrack_ecache.h -+++ b/include/net/netfilter/nf_conntrack_ecache.h -@@ -71,6 +71,10 @@ struct nf_ct_event { - int report; - }; - -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb); -+extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb); -+#else - struct nf_ct_event_notifier { - int (*fcn)(unsigned int events, struct nf_ct_event *item); - }; -@@ -79,7 +83,7 @@ int nf_conntrack_register_notifier(struc - struct nf_ct_event_notifier *nb); - void nf_conntrack_unregister_notifier(struct net *net, - struct nf_ct_event_notifier *nb); -- -+#endif - void nf_ct_deliver_cached_events(struct nf_conn *ct); - int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, - u32 portid, int report); -@@ -87,12 +91,15 @@ int nf_conntrack_eventmask_report(unsign - static inline void - nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) - { -- struct net *net = nf_ct_net(ct); - struct nf_conntrack_ecache *e; -+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+ struct net *net = nf_ct_net(ct); - - if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) - return; - -+#endif -+ - e = nf_ct_ecache_find(ct); - if (e == NULL) - return; -@@ -104,10 +111,12 @@ static inline int - nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, - u32 portid, int report) - { -+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS - const struct net *net = nf_ct_net(ct); - - if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) - return 0; -+#endif - - return nf_conntrack_eventmask_report(1 << event, ct, portid, report); - } -@@ -115,11 +124,14 @@ nf_conntrack_event_report(enum ip_conntr - static inline int - nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) - { -+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS - const struct net *net = nf_ct_net(ct); - - if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) - return 0; - -+#endif -+ - return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); - } - -diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h -index e469e85..1d31db8 100644 ---- a/include/net/netns/conntrack.h -+++ b/include/net/netns/conntrack.h -@@ -114,7 +114,11 @@ struct netns_ct { - - struct ct_pcpu __percpu *pcpu_lists; - struct ip_conntrack_stat __percpu *stat; -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+ struct atomic_notifier_head nf_conntrack_chain; -+#else - struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; -+#endif - struct nf_exp_event_notifier __rcu *nf_expect_event_cb; - struct nf_ip_net nf_ct_proto; - #if defined(CONFIG_NF_CONNTRACK_LABELS) -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index 63073be..08d7aab 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -118,6 +118,14 @@ config NF_CONNTRACK_EVENTS - - If unsure, say `N'. - -+config NF_CONNTRACK_CHAIN_EVENTS -+ bool "Register multiple callbacks to ct events" -+ depends on NF_CONNTRACK_EVENTS -+ help -+ Support multiple registrations. -+ -+ If unsure, say `N'. -+ - config NF_CONNTRACK_TIMEOUT - bool 'Connection tracking timeout' - depends on NETFILTER_ADVANCED -diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index 6bd1508..9b81c7c 100644 ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -2167,6 +2167,10 @@ int nf_conntrack_init_net(struct net *ne - ret = nf_conntrack_proto_pernet_init(net); - if (ret < 0) - goto err_proto; -+ -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+ ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain); -+#endif - return 0; - - err_proto: -diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c -index da9df2d..e0e2a8f 100644 ---- a/net/netfilter/nf_conntrack_ecache.c -+++ b/net/netfilter/nf_conntrack_ecache.c -@@ -18,6 +18,9 @@ - #include - #include - #include -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+#include -+#endif - #include - #include - #include -@@ -117,6 +120,38 @@ static void ecache_work(struct work_stru - schedule_delayed_work(&ctnet->ecache_dwork, delay); - } - -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+int -+nf_conntrack_eventmask_report(unsigned int eventmask, -+ struct nf_conn *ct, -+ u32 portid, -+ int report) -+{ -+ struct nf_conntrack_ecache *e; -+ struct net *net = nf_ct_net(ct); -+ -+ e = nf_ct_ecache_find(ct); -+ if (e == NULL) -+ return 0; -+ -+ if (nf_ct_is_confirmed(ct)) { -+ struct nf_ct_event item = { -+ .ct = ct, -+ .portid = e->portid ? e->portid : portid, -+ .report = report -+ }; -+ /* This is a resent of a destroy event? If so, skip missed */ -+ unsigned long missed = e->portid ? 0 : e->missed; -+ -+ if (!((eventmask | missed) & e->ctmask)) -+ return 0; -+ -+ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item); -+ } -+ -+ return 0; -+} -+#else - int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, - u32 portid, int report) - { -@@ -171,10 +206,52 @@ out_unlock: - rcu_read_unlock(); - return ret; - } -+#endif - EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report); - - /* deliver cached events and clear cache entry - must be called with locally - * disabled softirqs */ -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+void nf_ct_deliver_cached_events(struct nf_conn *ct) -+{ -+ unsigned long events, missed; -+ struct nf_conntrack_ecache *e; -+ struct nf_ct_event item; -+ struct net *net = nf_ct_net(ct); -+ -+ e = nf_ct_ecache_find(ct); -+ if (e == NULL) -+ return; -+ -+ events = xchg(&e->cache, 0); -+ -+ if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events) -+ return; -+ -+ /* We make a copy of the missed event cache without taking -+ * the lock, thus we may send missed events twice. However, -+ * this does not harm and it happens very rarely. */ -+ missed = e->missed; -+ -+ if (!((events | missed) & e->ctmask)) -+ return; -+ -+ item.ct = ct; -+ item.portid = 0; -+ item.report = 0; -+ -+ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, -+ events | missed, -+ &item); -+ -+ if (likely(!missed)) -+ return; -+ -+ spin_lock_bh(&ct->lock); -+ e->missed &= ~missed; -+ spin_unlock_bh(&ct->lock); -+} -+#else - void nf_ct_deliver_cached_events(struct nf_conn *ct) - { - struct net *net = nf_ct_net(ct); -@@ -225,6 +302,7 @@ void nf_ct_deliver_cached_events(struct - out_unlock: - rcu_read_unlock(); - } -+#endif - EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); - - void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, -@@ -257,6 +335,12 @@ out_unlock: - rcu_read_unlock(); - } - -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb) -+{ -+ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb); -+} -+#else - int nf_conntrack_register_notifier(struct net *net, - struct nf_ct_event_notifier *new) - { -@@ -277,8 +361,15 @@ out_unlock: - mutex_unlock(&nf_ct_ecache_mutex); - return ret; - } -+#endif - EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier); - -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb) -+{ -+ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb); -+} -+#else - void nf_conntrack_unregister_notifier(struct net *net, - struct nf_ct_event_notifier *new) - { -@@ -292,6 +383,7 @@ void nf_conntrack_unregister_notifier(st - mutex_unlock(&nf_ct_ecache_mutex); - /* synchronize_rcu() is called from ctnetlink_exit. */ - } -+#endif - EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); - - int nf_ct_expect_register_notifier(struct net *net, -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 04111c1..8c741f7 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -28,6 +28,11 @@ - #include - #include - #include -+ -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+#include -+#endif -+ - #include - - #include -@@ -618,14 +623,22 @@ static size_t ctnetlink_nlmsg_size(const - ; - } - -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+static int ctnetlink_conntrack_event(struct notifier_block *this, -+ unsigned long events, void *ptr) -+#else - static int - ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) -+#endif - { - const struct nf_conntrack_zone *zone; - struct net *net; - struct nlmsghdr *nlh; - struct nfgenmsg *nfmsg; - struct nlattr *nest_parms; -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+ struct nf_ct_event *item = (struct nf_ct_event *)ptr; -+#endif - struct nf_conn *ct = item->ct; - struct sk_buff *skb; - unsigned int type; -@@ -3290,9 +3303,15 @@ static int ctnetlink_stat_exp_cpu(struct - } - - #ifdef CONFIG_NF_CONNTRACK_EVENTS -+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -+static struct notifier_block ctnl_notifier = { -+ .notifier_call = ctnetlink_conntrack_event, -+}; -+#else - static struct nf_ct_event_notifier ctnl_notifier = { - .fcn = ctnetlink_conntrack_event, - }; -+#endif - - static struct nf_exp_event_notifier ctnl_notifier_exp = { - .fcn = ctnetlink_expect_event, From 38caba63301600ced221f4ede0c134155e7453e1 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 4 Apr 2020 10:02:05 +0200 Subject: [PATCH 16/76] Fix BPI-R2 uboot compilation --- .../patches/200-fix-dtc-header-guard.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 root/package/boot/uboot-mtk-bpi-r2/patches/200-fix-dtc-header-guard.patch diff --git a/root/package/boot/uboot-mtk-bpi-r2/patches/200-fix-dtc-header-guard.patch b/root/package/boot/uboot-mtk-bpi-r2/patches/200-fix-dtc-header-guard.patch new file mode 100644 index 00000000..88d914b1 --- /dev/null +++ b/root/package/boot/uboot-mtk-bpi-r2/patches/200-fix-dtc-header-guard.patch @@ -0,0 +1,19 @@ +--- a/include/libfdt_env.h ++++ b/include/libfdt_env.h +@@ -8,6 +8,7 @@ + + #ifndef _LIBFDT_ENV_H + #define _LIBFDT_ENV_H ++#define LIBFDT_ENV_H + + #include "compiler.h" + #include "linux/types.h" +--- a/include/libfdt.h ++++ b/include/libfdt.h +@@ -1,5 +1,6 @@ + #ifndef _LIBFDT_H + #define _LIBFDT_H ++#define LIBFDT_H + /* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. From 29e7137a83c8eb5aece5dfd286777f7f0c51fad9 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 4 Apr 2020 16:00:23 +0200 Subject: [PATCH 17/76] Fix opkg install argument list too long --- build.sh | 7 +++++++ patches/package-too-long.patch | 11 +++++++++++ 2 files changed, 18 insertions(+) create mode 100644 patches/package-too-long.patch diff --git a/build.sh b/build.sh index 450b58ef..621901ba 100755 --- a/build.sh +++ b/build.sh @@ -195,6 +195,13 @@ if [ ! -d target/linux/mvebu/patches-5.4 ]; then fi echo "Done" +echo "Checking if opkg install arguement too long patch is set or not" +if ! patch -Rf -N -p1 -s --dry-run < ../../patches/package-too-long.patch; then + echo "apply..." + patch -N -p1 -s < ../../patches/package-too-long.patch +fi +echo "Done" + #echo "Patch protobuf wrong hash" #patch -N -R -p1 -s < ../../patches/protobuf_hash.patch diff --git a/patches/package-too-long.patch b/patches/package-too-long.patch new file mode 100644 index 00000000..00d7afce --- /dev/null +++ b/patches/package-too-long.patch @@ -0,0 +1,11 @@ +--- a/package/Makefile 2020-04-04 15:52:15.706831084 +0200 ++++ b/package/Makefile 2020-04-04 15:53:54.645052663 +0200 +@@ -66,7 +66,7 @@ + rm -rf $(TARGET_DIR) $(TARGET_DIR_ORIG) + mkdir -p $(TARGET_DIR)/tmp + $(call opkg,$(TARGET_DIR)) install \ +- $(call opkg_package_files,$(foreach pkg,$(shell cat $(PACKAGE_INSTALL_FILES) 2>/dev/null),$(pkg)$(call GetABISuffix,$(pkg)))) ++ $(subst $(TOPDIR)/,,$(call opkg_package_files,$(foreach pkg,$(shell cat $(PACKAGE_INSTALL_FILES) 2>/dev/null),$(pkg)$(call GetABISuffix,$(pkg))))) + @for file in $(PACKAGE_INSTALL_FILES); do \ + [ -s $$file.flags ] || continue; \ + for flag in `cat $$file.flags`; do \ From 6551f6088900dd3e417fccdc4108f014ef78c687 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sun, 5 Apr 2020 15:44:20 +0200 Subject: [PATCH 18/76] Update ECF patch --- .../generic/hack-5.4/691-mptcp_ecf.patch | 572 +++++++++++++++++- 1 file changed, 563 insertions(+), 9 deletions(-) diff --git a/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch b/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch index d9cf6251..4925612c 100644 --- a/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch +++ b/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch @@ -1,7 +1,7 @@ -From 35f41229b58cb8c2611207827aa4f658b82db67e Mon Sep 17 00:00:00 2001 +From 025619486cf04c0beb9f395609d7711726fd63c6 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Mon, 5 Aug 2019 14:02:30 +0200 -Subject: [PATCH] mptcp: Earliest Completion First (ECF) Scheduler +Subject: [PATCH 1/3] mptcp: Earliest Completion First (ECF) Scheduler This scheduler works much like the default MPTCP scheduler. It always prefers the subflow with the smallest round-trip-time that is available. @@ -15,7 +15,7 @@ Signed-off-by: Daniel Weber create mode 100644 net/mptcp/mptcp_ecf.c diff --git a/net/mptcp/Kconfig b/net/mptcp/Kconfig -index d22b7b47860f..dd1f859f1070 100644 +index 37f3af3db2a6..829ea084cf70 100644 --- a/net/mptcp/Kconfig +++ b/net/mptcp/Kconfig @@ -109,6 +109,12 @@ config MPTCP_REDUNDANT @@ -30,7 +30,7 @@ index d22b7b47860f..dd1f859f1070 100644 + choice prompt "Default MPTCP Scheduler" - default DEFAULT + default DEFAULT_SCHEDULER diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile index 82a2d4d945ae..369248a2f68e 100644 --- a/net/mptcp/Makefile @@ -44,7 +44,7 @@ index 82a2d4d945ae..369248a2f68e 100644 mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o diff --git a/net/mptcp/mptcp_ecf.c b/net/mptcp/mptcp_ecf.c new file mode 100644 -index 000000000000..d61f4d2ad375 +index 000000000000..e0bd430a8943 --- /dev/null +++ b/net/mptcp/mptcp_ecf.c @@ -0,0 +1,384 @@ @@ -73,9 +73,9 @@ index 000000000000..d61f4d2ad375 +#include +#include + -+static unsigned int r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ -+module_param(r_beta, int, 0644); -+MODULE_PARM_DESC(r_beta, "beta for ECF"); ++static unsigned int mptcp_ecf_r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ ++module_param(mptcp_ecf_r_beta, int, 0644); ++MODULE_PARM_DESC(mptcp_ecf_r_beta, "beta for ECF"); + +struct ecfsched_priv { + u32 last_rbuf_opti; @@ -185,7 +185,7 @@ index 000000000000..d61f4d2ad375 + lhs = srtt_f * (x_f + cwnd_f * mss); + rhs = cwnd_f * mss * (srtt_s + delta); + -+ if (r_beta * lhs < r_beta * rhs + ecf_cb->switching_margin * rhs) { ++ if (mptcp_ecf_r_beta * lhs < mptcp_ecf_r_beta * rhs + ecf_cb->switching_margin * rhs) { + u32 x_s = sndbuf > cwnd_s * mss ? sndbuf : cwnd_s * mss; + u64 lhs_s = srtt_s * x_s; + u64 rhs_s = cwnd_s * mss * (2 * srtt_f + delta); @@ -432,3 +432,557 @@ index 000000000000..d61f4d2ad375 +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ECF (Earliest Completion First) scheduler for MPTCP, based on default minimum RTT scheduler"); +MODULE_VERSION("0.95"); + +From 5a9641c84cbb5a49749d7533c20035631985dbe7 Mon Sep 17 00:00:00 2001 +From: Daniel Weber +Date: Mon, 9 Mar 2020 11:00:23 +0100 +Subject: [PATCH 2/3] mptcp: Reduce code-duplication for other schedulers + +'mptcp_next_segment' now honors the function pointer to the actual part +that makes the scheduling decision in 'sched_ops->get_subflow'. This +allows for a better reuse by other schedulers. + +The BLEST scheduler needs to adapt the direction of lambda value change +depending on the occurrence of a retransmission. In order to remove the +copied 'mptcp_rcv_buf_optimization' as well the scheduler now checks the +tcp 'retrans_stamp' of the meta socket. + +Signed-off-by: Daniel Weber +--- + include/net/mptcp.h | 4 + + net/mptcp/mptcp_blest.c | 200 +--------------------------------------- + net/mptcp/mptcp_sched.c | 9 +- + 3 files changed, 11 insertions(+), 202 deletions(-) + +diff --git a/include/net/mptcp.h b/include/net/mptcp.h +index 02312c9ea3a3..82f66ce206cc 100644 +--- a/include/net/mptcp.h ++++ b/include/net/mptcp.h +@@ -902,6 +902,10 @@ bool subflow_is_active(const struct tcp_sock *tp); + bool subflow_is_backup(const struct tcp_sock *tp); + struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, + bool zero_wnd_test); ++struct sk_buff *mptcp_next_segment(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit); + extern struct mptcp_sched_ops mptcp_sched_default; + + /* Initializes function-pointers and MPTCP-flags */ +diff --git a/net/mptcp/mptcp_blest.c b/net/mptcp/mptcp_blest.c +index 40905a0d1fe5..22e25dd0d44e 100644 +--- a/net/mptcp/mptcp_blest.c ++++ b/net/mptcp/mptcp_blest.c +@@ -21,7 +21,6 @@ + + #include + #include +-#include + + static unsigned char lambda __read_mostly = 12; + module_param(lambda, byte, 0644); +@@ -50,7 +49,6 @@ struct blestsched_priv { + }; + + struct blestsched_cb { +- bool retrans_flag; + s16 lambda_1000; /* values range from min_lambda * 100 to max_lambda * 100 */ + u32 last_lambda_update; + }; +@@ -77,14 +75,13 @@ static void blestsched_update_lambda(struct sock *meta_sk, struct sock *sk) + * during the slow flows last RTT => increase lambda + * otherwise decrease + */ +- if (blest_cb->retrans_flag) { ++ if (tcp_sk(meta_sk)->retrans_stamp) { + /* need to slow down on the slow flow */ + blest_cb->lambda_1000 += dyn_lambda_bad; + } else { + /* use the slow flow more */ + blest_cb->lambda_1000 -= dyn_lambda_good; + } +- blest_cb->retrans_flag = false; + + /* cap lambda_1000 to its value range */ + blest_cb->lambda_1000 = min_t(s16, blest_cb->lambda_1000, max_lambda * 100); +@@ -240,199 +237,6 @@ struct sock *blest_get_available_subflow(struct sock *meta_sk, struct sk_buff *s + return bestsk; + } + +-/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ +-static struct sk_buff *mptcp_blest_rcv_buf_optimization(struct sock *sk, int penal) +-{ +- struct sock *meta_sk; +- const struct tcp_sock *tp = tcp_sk(sk); +- struct mptcp_tcp_sock *mptcp; +- struct sk_buff *skb_head; +- struct blestsched_priv *blest_p = blestsched_get_priv(tp); +- struct blestsched_cb *blest_cb; +- +- meta_sk = mptcp_meta_sk(sk); +- skb_head = tcp_rtx_queue_head(meta_sk); +- +- if (!skb_head) +- return NULL; +- +- /* If penalization is optional (coming from mptcp_next_segment() and +- * We are not send-buffer-limited we do not penalize. The retransmission +- * is just an optimization to fix the idle-time due to the delay before +- * we wake up the application. +- */ +- if (!penal && sk_stream_memory_free(meta_sk)) +- goto retrans; +- +- /* Record the occurrence of a retransmission to update the lambda value */ +- blest_cb = blestsched_get_cb(tcp_sk(meta_sk)); +- blest_cb->retrans_flag = true; +- +- /* Only penalize again after an RTT has elapsed */ +- if (tcp_jiffies32 - blest_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) +- goto retrans; +- +- /* Half the cwnd of the slow flows */ +- mptcp_for_each_sub(tp->mpcb, mptcp) { +- struct tcp_sock *tp_it = mptcp->tp; +- +- if (tp_it != tp && +- TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { +- if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { +- u32 prior_cwnd = tp_it->snd_cwnd; +- +- tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); +- +- /* If in slow start, do not reduce the ssthresh */ +- if (prior_cwnd >= tp_it->snd_ssthresh) +- tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); +- +- blest_p->last_rbuf_opti = tcp_jiffies32; +- } +- } +- } +- +-retrans: +- +- /* Segment not yet injected into this path? Take it!!! */ +- if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { +- bool do_retrans = false; +- mptcp_for_each_sub(tp->mpcb, mptcp) { +- struct tcp_sock *tp_it = mptcp->tp; +- +- if (tp_it != tp && +- TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { +- if (tp_it->snd_cwnd <= 4) { +- do_retrans = true; +- break; +- } +- +- if (4 * tp->srtt_us >= tp_it->srtt_us) { +- do_retrans = false; +- break; +- } else { +- do_retrans = true; +- } +- } +- } +- +- if (do_retrans && mptcp_is_available(sk, skb_head, false)) { +- trace_mptcp_retransmit(sk, skb_head); +- return skb_head; +- } +- } +- return NULL; +-} +- +-/* copy from mptcp_sched.c: __mptcp_next_segment */ +-/* Returns the next segment to be sent from the mptcp meta-queue. +- * (chooses the reinject queue if any segment is waiting in it, otherwise, +- * chooses the normal write queue). +- * Sets *@reinject to 1 if the returned segment comes from the +- * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, +- * and sets it to -1 if it is a meta-level retransmission to optimize the +- * receive-buffer. +- */ +-static struct sk_buff *__mptcp_blest_next_segment(struct sock *meta_sk, int *reinject) +-{ +- const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; +- struct sk_buff *skb = NULL; +- +- *reinject = 0; +- +- /* If we are in fallback-mode, just take from the meta-send-queue */ +- if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) +- return tcp_send_head(meta_sk); +- +- skb = skb_peek(&mpcb->reinject_queue); +- +- if (skb) { +- *reinject = 1; +- } else { +- skb = tcp_send_head(meta_sk); +- +- if (!skb && meta_sk->sk_socket && +- test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && +- sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { +- struct sock *subsk = blest_get_available_subflow(meta_sk, NULL, +- false); +- if (!subsk) +- return NULL; +- +- skb = mptcp_blest_rcv_buf_optimization(subsk, 0); +- if (skb) +- *reinject = -1; +- } +- } +- return skb; +-} +- +-/* copy from mptcp_sched.c: mptcp_next_segment */ +-static struct sk_buff *mptcp_blest_next_segment(struct sock *meta_sk, +- int *reinject, +- struct sock **subsk, +- unsigned int *limit) +-{ +- struct sk_buff *skb = __mptcp_blest_next_segment(meta_sk, reinject); +- unsigned int mss_now; +- struct tcp_sock *subtp; +- u16 gso_max_segs; +- u32 max_len, max_segs, window, needed; +- +- /* As we set it, we have to reset it as well. */ +- *limit = 0; +- +- if (!skb) +- return NULL; +- +- *subsk = blest_get_available_subflow(meta_sk, skb, false); +- if (!*subsk) +- return NULL; +- +- subtp = tcp_sk(*subsk); +- mss_now = tcp_current_mss(*subsk); +- +- if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { +- skb = mptcp_blest_rcv_buf_optimization(*subsk, 1); +- if (skb) +- *reinject = -1; +- else +- return NULL; +- } +- +- /* No splitting required, as we will only send one single segment */ +- if (skb->len <= mss_now) +- return skb; +- +- /* The following is similar to tcp_mss_split_point, but +- * we do not care about nagle, because we will anyways +- * use TCP_NAGLE_PUSH, which overrides this. +- * +- * So, we first limit according to the cwnd/gso-size and then according +- * to the subflow's window. +- */ +- +- gso_max_segs = (*subsk)->sk_gso_max_segs; +- if (!gso_max_segs) /* No gso supported on the subflow's NIC */ +- gso_max_segs = 1; +- max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); +- if (!max_segs) +- return NULL; +- +- max_len = mss_now * max_segs; +- window = tcp_wnd_end(subtp) - subtp->write_seq; +- +- needed = min(skb->len, window); +- if (max_len <= skb->len) +- /* Take max_win, which is actually the cwnd/gso-size */ +- *limit = max_len; +- else +- /* Or, take the window */ +- *limit = needed; +- +- return skb; +-} +- + static void blestsched_init(struct sock *sk) + { + struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); +@@ -450,7 +254,7 @@ static void blestsched_init(struct sock *sk) + + static struct mptcp_sched_ops mptcp_sched_blest = { + .get_subflow = blest_get_available_subflow, +- .next_segment = mptcp_blest_next_segment, ++ .next_segment = mptcp_next_segment, + .init = blestsched_init, + .name = "blest", + .owner = THIS_MODULE, +diff --git a/net/mptcp/mptcp_sched.c b/net/mptcp/mptcp_sched.c +index 18c3559b0d48..5bf2946a5caf 100644 +--- a/net/mptcp/mptcp_sched.c ++++ b/net/mptcp/mptcp_sched.c +@@ -372,8 +372,8 @@ static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) + if (!skb && meta_sk->sk_socket && + test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && + sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { +- struct sock *subsk = get_available_subflow(meta_sk, NULL, +- false); ++ struct sock *subsk = mpcb->sched_ops->get_subflow(meta_sk, NULL, ++ false); + if (!subsk) + return NULL; + +@@ -385,7 +385,7 @@ static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) + return skb; + } + +-static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, ++struct sk_buff *mptcp_next_segment(struct sock *meta_sk, + int *reinject, + struct sock **subsk, + unsigned int *limit) +@@ -402,7 +402,7 @@ static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, + if (!skb) + return NULL; + +- *subsk = get_available_subflow(meta_sk, skb, false); ++ *subsk = tcp_sk(meta_sk)->mpcb->sched_ops->get_subflow(meta_sk, skb, false); + if (!*subsk) + return NULL; + +@@ -449,6 +449,7 @@ static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, + + return skb; + } ++EXPORT_SYMBOL_GPL(mptcp_next_segment); + + static void defsched_init(struct sock *sk) + { + +From 5e8425e43b38e7e0fe566ffd50e197c07807ebdf Mon Sep 17 00:00:00 2001 +From: Daniel Weber +Date: Mon, 9 Mar 2020 11:09:27 +0100 +Subject: [PATCH 3/3] mptcp: Remove code-duplication from ECF scheduler + +The ECF scheduler relies on large parts of the default scheduler. This +commit removes the copied blocks and reuses 'mptcp_next_segment' and +'mptcp_rcv_buf_optimization' directly from it via function pointers. + +Signed-off-by: Daniel Weber +--- + net/mptcp/mptcp_ecf.c | 191 +----------------------------------------- + 1 file changed, 1 insertion(+), 190 deletions(-) + +diff --git a/net/mptcp/mptcp_ecf.c b/net/mptcp/mptcp_ecf.c +index e0bd430a8943..6b976b2b0c72 100644 +--- a/net/mptcp/mptcp_ecf.c ++++ b/net/mptcp/mptcp_ecf.c +@@ -21,7 +21,6 @@ + + #include + #include +-#include + + static unsigned int mptcp_ecf_r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ + module_param(mptcp_ecf_r_beta, int, 0644); +@@ -154,194 +153,6 @@ static struct sock *ecf_get_available_subflow(struct sock *meta_sk, + return bestsk; + } + +-/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ +-static struct sk_buff *mptcp_ecf_rcv_buf_optimization(struct sock *sk, int penal) +-{ +- struct sock *meta_sk; +- const struct tcp_sock *tp = tcp_sk(sk); +- struct mptcp_tcp_sock *mptcp; +- struct sk_buff *skb_head; +- struct ecfsched_priv *ecf_p = ecfsched_get_priv(tp); +- +- meta_sk = mptcp_meta_sk(sk); +- skb_head = tcp_rtx_queue_head(meta_sk); +- +- if (!skb_head) +- return NULL; +- +- /* If penalization is optional (coming from mptcp_next_segment() and +- * We are not send-buffer-limited we do not penalize. The retransmission +- * is just an optimization to fix the idle-time due to the delay before +- * we wake up the application. +- */ +- if (!penal && sk_stream_memory_free(meta_sk)) +- goto retrans; +- +- /* Only penalize again after an RTT has elapsed */ +- if (tcp_jiffies32 - ecf_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) +- goto retrans; +- +- /* Half the cwnd of the slow flows */ +- mptcp_for_each_sub(tp->mpcb, mptcp) { +- struct tcp_sock *tp_it = mptcp->tp; +- +- if (tp_it != tp && +- TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { +- if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { +- u32 prior_cwnd = tp_it->snd_cwnd; +- +- tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); +- +- /* If in slow start, do not reduce the ssthresh */ +- if (prior_cwnd >= tp_it->snd_ssthresh) +- tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); +- +- ecf_p->last_rbuf_opti = tcp_jiffies32; +- } +- } +- } +- +-retrans: +- +- /* Segment not yet injected into this path? Take it!!! */ +- if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { +- bool do_retrans = false; +- mptcp_for_each_sub(tp->mpcb, mptcp) { +- struct tcp_sock *tp_it = mptcp->tp; +- +- if (tp_it != tp && +- TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { +- if (tp_it->snd_cwnd <= 4) { +- do_retrans = true; +- break; +- } +- +- if (4 * tp->srtt_us >= tp_it->srtt_us) { +- do_retrans = false; +- break; +- } else { +- do_retrans = true; +- } +- } +- } +- +- if (do_retrans && mptcp_is_available(sk, skb_head, false)) { +- trace_mptcp_retransmit(sk, skb_head); +- return skb_head; +- } +- } +- return NULL; +-} +- +-/* copy from mptcp_sched.c: __mptcp_next_segment */ +-/* Returns the next segment to be sent from the mptcp meta-queue. +- * (chooses the reinject queue if any segment is waiting in it, otherwise, +- * chooses the normal write queue). +- * Sets *@reinject to 1 if the returned segment comes from the +- * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, +- * and sets it to -1 if it is a meta-level retransmission to optimize the +- * receive-buffer. +- */ +-static struct sk_buff *__mptcp_ecf_next_segment(struct sock *meta_sk, int *reinject) +-{ +- const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; +- struct sk_buff *skb = NULL; +- +- *reinject = 0; +- +- /* If we are in fallback-mode, just take from the meta-send-queue */ +- if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) +- return tcp_send_head(meta_sk); +- +- skb = skb_peek(&mpcb->reinject_queue); +- +- if (skb) { +- *reinject = 1; +- } else { +- skb = tcp_send_head(meta_sk); +- +- if (!skb && meta_sk->sk_socket && +- test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && +- sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { +- struct sock *subsk = ecf_get_available_subflow(meta_sk, NULL, +- false); +- if (!subsk) +- return NULL; +- +- skb = mptcp_ecf_rcv_buf_optimization(subsk, 0); +- if (skb) +- *reinject = -1; +- } +- } +- return skb; +-} +- +-/* copy from mptcp_sched.c: mptcp_next_segment */ +-static struct sk_buff *mptcp_ecf_next_segment(struct sock *meta_sk, +- int *reinject, +- struct sock **subsk, +- unsigned int *limit) +-{ +- struct sk_buff *skb = __mptcp_ecf_next_segment(meta_sk, reinject); +- unsigned int mss_now; +- struct tcp_sock *subtp; +- u16 gso_max_segs; +- u32 max_len, max_segs, window, needed; +- +- /* As we set it, we have to reset it as well. */ +- *limit = 0; +- +- if (!skb) +- return NULL; +- +- *subsk = ecf_get_available_subflow(meta_sk, skb, false); +- if (!*subsk) +- return NULL; +- +- subtp = tcp_sk(*subsk); +- mss_now = tcp_current_mss(*subsk); +- +- if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { +- skb = mptcp_ecf_rcv_buf_optimization(*subsk, 1); +- if (skb) +- *reinject = -1; +- else +- return NULL; +- } +- +- /* No splitting required, as we will only send one single segment */ +- if (skb->len <= mss_now) +- return skb; +- +- /* The following is similar to tcp_mss_split_point, but +- * we do not care about nagle, because we will anyways +- * use TCP_NAGLE_PUSH, which overrides this. +- * +- * So, we first limit according to the cwnd/gso-size and then according +- * to the subflow's window. +- */ +- +- gso_max_segs = (*subsk)->sk_gso_max_segs; +- if (!gso_max_segs) /* No gso supported on the subflow's NIC */ +- gso_max_segs = 1; +- max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); +- if (!max_segs) +- return NULL; +- +- max_len = mss_now * max_segs; +- window = tcp_wnd_end(subtp) - subtp->write_seq; +- +- needed = min(skb->len, window); +- if (max_len <= skb->len) +- /* Take max_win, which is actually the cwnd/gso-size */ +- *limit = max_len; +- else +- /* Or, take the window */ +- *limit = needed; +- +- return skb; +-} +- + static void ecfsched_init(struct sock *sk) + { + struct ecfsched_priv *ecf_p = ecfsched_get_priv(tcp_sk(sk)); +@@ -353,7 +164,7 @@ static void ecfsched_init(struct sock *sk) + + struct mptcp_sched_ops mptcp_sched_ecf = { + .get_subflow = ecf_get_available_subflow, +- .next_segment = mptcp_ecf_next_segment, ++ .next_segment = mptcp_next_segment, + .init = ecfsched_init, + .name = "ecf", + .owner = THIS_MODULE, From ec9f198f19f90741bdc22f1950b5bc5c92544af7 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sun, 5 Apr 2020 15:44:40 +0200 Subject: [PATCH 19/76] Fix kernel size too big --- config-wrt32x | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config-wrt32x b/config-wrt32x index 113d92e1..384ac04c 100644 --- a/config-wrt32x +++ b/config-wrt32x @@ -3,3 +3,5 @@ CONFIG_TARGET_mvebu_cortexa9=y CONFIG_TARGET_mvebu_cortexa9_DEVICE_linksys_wrt32x=y CONFIG_PACKAGE_kmod-6lowpan=y CONFIG_PACKAGE_luci-app-advanced-reboot=y +# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y \ No newline at end of file From dc92e58503a97ef43b8842d97bd36d5a42503595 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 9 Apr 2020 14:38:19 +0200 Subject: [PATCH 20/76] Remove luci patch for full cone NAT --- patches/fullconenat-luci.patch | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 patches/fullconenat-luci.patch diff --git a/patches/fullconenat-luci.patch b/patches/fullconenat-luci.patch deleted file mode 100644 index 248d4dce..00000000 --- a/patches/fullconenat-luci.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/feeds/luci/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js -+++ b/feeds/luci/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js -@@ -131,6 +131,10 @@ return L.view.extend({ - o = s.taboption('general', form.Flag, 'masq', _('Masquerading')); - o.editable = true; - -+ o = s.taboption('general', form.Flag, 'fullcone', _('Full Cone')); -+ o.editable = true; -+ o.depends('masq', '1'); -+ - o = s.taboption('general', form.Flag, 'mtu_fix', _('MSS clamping')); - o.modalonly = true; - From f92d4b54d651235cbf299a870cee0e36115fb6ed Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 9 Apr 2020 14:46:32 +0200 Subject: [PATCH 21/76] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 621901ba..161a2067 100755 --- a/build.sh +++ b/build.sh @@ -58,9 +58,9 @@ else fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" -_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "5562c5add2faa5d407c308a98517b2b5cc6d84da" -_get_repo feeds/packages https://github.com/openwrt/packages "f0264eea08761d939b5412cd3f31b824496aa794" -_get_repo feeds/luci https://github.com/openwrt/luci "65a461e8a0340a361545d3510918f34edb27920c" +_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "02a1914585fffb97b26cc871b303a39ac9d37cbb" +_get_repo feeds/packages https://github.com/openwrt/packages "e086343cb5d0bcda2f85486e56f478987d2ea171" +_get_repo feeds/luci https://github.com/openwrt/luci "1e07e3a52d4d06cc82ab07f2b7fbba0a9a6fb801" if [ -z "$OMR_FEED" ]; then OMR_FEED=feeds/openmptcprouter From 18fcb571f6a4a0adbc74b3cb86b57be9a35ba777 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 9 Apr 2020 14:46:45 +0200 Subject: [PATCH 22/76] Update Issue Template --- .github/ISSUE_TEMPLATE.md | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 8b2450f7..2c2952c1 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,9 +1,14 @@ ## Expected Behavior + + - In English please. - -## Actual Behavior +## Current Behavior + + +## Possible Solution + + ## Steps to Reproduce the Problem @@ -11,8 +16,17 @@ 2. 3. +## Context (Environment) + + + + + + ## Specifications - - OpenMPTCProuter version: (Last is not a version) - - OpenMPTCProuter VPS version: (Last is not a version) - - OpenMPTCProuter platform: (RPI2/RPI3/x86/x86_64) + - OpenMPTCProuter version: + - OpenMPTCProuter VPS version: + - OpenMPTCProuter platform: + + \ No newline at end of file From 92983981c59edf68c8ebc702004a544c489c8529 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 9 Apr 2020 14:57:08 +0200 Subject: [PATCH 23/76] Parameter for OpenWrt commit --- build.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 161a2067..ac912b6a 100755 --- a/build.sh +++ b/build.sh @@ -34,6 +34,8 @@ OMR_KERNEL=${OMR_KERNEL:-5.4} OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" OMR_FEED_SRC="${OMR_FEED_SRC:-develop}" +OMR_OPENWRT=${OMR_OPENWRT:-default} + if [ ! -f "$OMR_TARGET_CONFIG" ]; then echo "Target $OMR_TARGET not found !" #exit 1 @@ -58,9 +60,19 @@ else fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" -_get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "02a1914585fffb97b26cc871b303a39ac9d37cbb" -_get_repo feeds/packages https://github.com/openwrt/packages "e086343cb5d0bcda2f85486e56f478987d2ea171" -_get_repo feeds/luci https://github.com/openwrt/luci "1e07e3a52d4d06cc82ab07f2b7fbba0a9a6fb801" +if [ "$OMR_OPENWRT" = "default" ]; then + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "02a1914585fffb97b26cc871b303a39ac9d37cbb" + _get_repo feeds/packages https://github.com/openwrt/packages "e086343cb5d0bcda2f85486e56f478987d2ea171" + _get_repo feeds/luci https://github.com/openwrt/luci "1e07e3a52d4d06cc82ab07f2b7fbba0a9a6fb801" +elif [ "$OMR_OPENWRT" = "master" ]; then + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" + _get_repo feeds/packages https://github.com/openwrt/packages "master" + _get_repo feeds/luci https://github.com/openwrt/luci "master" +else + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "${OMR_OPENWRT}" + _get_repo feeds/packages https://github.com/openwrt/packages "${OMR_OPENWRT}" + _get_repo feeds/luci https://github.com/openwrt/luci "${OMR_OPENWRT}" +fi if [ -z "$OMR_FEED" ]; then OMR_FEED=feeds/openmptcprouter From 5b99a7fde66c875839361a427f8ba151d385e072 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 9 Apr 2020 15:01:48 +0200 Subject: [PATCH 24/76] Disable fullconnenat aptch --- build.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build.sh b/build.sh index ac912b6a..9837d464 100755 --- a/build.sh +++ b/build.sh @@ -248,14 +248,14 @@ cp .config .config.keep scripts/feeds clean scripts/feeds update -a -cd - -echo "Checking if fullconenat-luci patch is set or not" -if ! patch -Rf -N -p1 -s --dry-run < patches/fullconenat-luci.patch; then - echo "apply..." - patch -N -p1 -s < patches/fullconenat-luci.patch -fi -echo "Done" -cd "$OMR_TARGET/source" +#cd - +#echo "Checking if fullconenat-luci patch is set or not" +##if ! patch -Rf -N -p1 -s --dry-run < patches/fullconenat-luci.patch; then +# echo "apply..." +# patch -N -p1 -s < patches/fullconenat-luci.patch +#fi +#echo "Done" +#cd "$OMR_TARGET/source" if [ "$OMR_ALL_PACKAGES" = "yes" ]; then scripts/feeds install -a -p packages From a997f379a0c34e0596a5fb7821b69a6f48f65ce8 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Apr 2020 10:56:17 +0200 Subject: [PATCH 25/76] Invert sd/mmc --- root/package/boot/uboot-mediatek/uEnv-default.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/root/package/boot/uboot-mediatek/uEnv-default.txt b/root/package/boot/uboot-mediatek/uEnv-default.txt index b5e7af3c..1f0c8913 100644 --- a/root/package/boot/uboot-mediatek/uEnv-default.txt +++ b/root/package/boot/uboot-mediatek/uEnv-default.txt @@ -20,8 +20,8 @@ loadbootenv=if fatload ${device} ${partition} ${scriptaddr} ${bootenv};then run resetenv=env default -a;printenv; # Here we assume that SD card id mmcblk1 and eMMC is mmcblk0 in linux. Swap them if your DTS define them in reverse order. -usesd=setenv partition 1:1; setenv rootdev /dev/mmcblk0p2; setenv bootdev SD; setenv swaproot 'run useemmc'; -useemmc=setenv partition 0:1; setenv rootdev /dev/mmcblk1p2; setenv bootdev eMMC; setenv swaproot 'run usesd'; +usesd=setenv partition 1:1; setenv rootdev /dev/mmcblk1p2; setenv bootdev SD; setenv swaproot 'run useemmc'; +useemmc=setenv partition 0:1; setenv rootdev /dev/mmcblk0p2; setenv bootdev eMMC; setenv swaproot 'run usesd'; checkbootedfrom=if itest.l *81dffff0 == 434d4d65 ; then setenv bootedfrom eMMC; else setenv bootedfrom SD; fi; From 1385e89bce40b6142cfca0eb9d4a8ee1a5b5a01c Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Apr 2020 13:08:08 +0200 Subject: [PATCH 26/76] Update uboot for BPI-R2 --- root/package/boot/uboot-mediatek/Makefile | 10 +- ...dditional-U-boot-options-for-mt7623n.patch | 64 + .../patches/0001-update-defconfig.patch | 39 - ...ding-saveenv-command-for-bananapi-r2.patch | 61 - ...modify-environment-offset-for-mt7623.patch | 23 + ...03-bootmenu-added-key-input-1-9-a-f.patch} | 25 +- ...dd-reset-controller-driver-for-Media.patch | 189 -- .../0004-Add-EXT4-support-in-U-boot.patch | 25 + ...ediaTek-bind-ethsys-reset-controller.patch | 109 -- ...k-add-ethernet-driver-for-MediaTek-A.patch | 1517 ----------------- ...ethernet-related-node-for-MT7623-SoC.patch | 76 - ...ethernet-related-node-for-MT7629-SoC.patch | 95 -- ...d-ethernet-support-for-MT7623-boards.patch | 59 - ...d-ethernet-support-for-MT7629-boards.patch | 58 - ...ERS-ARM-MEDIATEK-update-file-entries.patch | 25 - ...-use-OF_SEPARATE-instead-of-OF_EMBED.patch | 40 - .../0013-test-add-test-for-lib-lmb.c.patch | 326 ---- ...x-allocation-at-end-of-address-range.patch | 157 -- ...ving-overlapping-regions-should-fail.patch | 208 --- ...served-memory-for-memory-reservation.patch | 117 -- ...b-extend-lmb-for-checks-at-load-time.patch | 312 ---- ...-prevent-overwriting-reserved-memory.patch | 138 -- ...common-function-lmb_init_and_reserve.patch | 35 - ...lmb-remove-unused-extern-declaration.patch | 26 - ...-prevent-overwriting-reserved-memory.patch | 172 -- ...sp-detection-at-end-of-address-range.patch | 46 - ...d-strings-and-setenv-used-for-lstftp.patch | 27 - ...-increase-size-for-environment-4k-8k.patch | 22 - .../boot/uboot-mediatek/uEnv-default.txt | 6 +- 29 files changed, 134 insertions(+), 3873 deletions(-) create mode 100644 root/package/boot/uboot-mediatek/patches/0001-defconfig-r2-Add-additional-U-boot-options-for-mt7623n.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0001-update-defconfig.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0002-adding-saveenv-command-for-bananapi-r2.patch create mode 100644 root/package/boot/uboot-mediatek/patches/0002-u-boot-modify-environment-offset-for-mt7623.patch rename root/package/boot/uboot-mediatek/patches/{0025-bootmenu-added-key-input-1-9-a-f.patch => 0003-bootmenu-added-key-input-1-9-a-f.patch} (83%) delete mode 100644 root/package/boot/uboot-mediatek/patches/0003-reset-MedaiTek-add-reset-controller-driver-for-Media.patch create mode 100644 root/package/boot/uboot-mediatek/patches/0004-Add-EXT4-support-in-U-boot.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0004-clk-MediaTek-bind-ethsys-reset-controller.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0005-ethernet-MediaTek-add-ethernet-driver-for-MediaTek-A.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0006-arm-dts-add-ethernet-related-node-for-MT7623-SoC.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0007-arm-dts-add-ethernet-related-node-for-MT7629-SoC.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0008-arm-MediaTek-add-ethernet-support-for-MT7623-boards.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0009-arm-MediaTek-add-ethernet-support-for-MT7629-boards.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0010-MAINTAINERS-ARM-MEDIATEK-update-file-entries.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0011-configs-MediaTek-use-OF_SEPARATE-instead-of-OF_EMBED.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0013-test-add-test-for-lib-lmb.c.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0014-lmb-fix-allocation-at-end-of-address-range.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0015-lib-lmb-reserving-overlapping-regions-should-fail.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0016-fdt-parse-reserved-memory-for-memory-reservation.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0017-lib-lmb-extend-lmb-for-checks-at-load-time.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0018-fs-prevent-overwriting-reserved-memory.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0019-bootm-use-new-common-function-lmb_init_and_reserve.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0020-lmb-remove-unused-extern-declaration.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0021-tftp-prevent-overwriting-reserved-memory.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0022-arm-bootm-fix-sp-detection-at-end-of-address-range.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0023-defconfig-added-strings-and-setenv-used-for-lstftp.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0024-increase-size-for-environment-4k-8k.patch diff --git a/root/package/boot/uboot-mediatek/Makefile b/root/package/boot/uboot-mediatek/Makefile index 9454317f..d255a794 100644 --- a/root/package/boot/uboot-mediatek/Makefile +++ b/root/package/boot/uboot-mediatek/Makefile @@ -9,11 +9,11 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk -PKG_VERSION:=2019.01 +PKG_VERSION:=2020.04-rc5 -PKG_HASH:=50bd7e5a466ab828914d080d5f6a432345b500e8fba1ad3b7b61e95e60d51c22 +PKG_HASH:=1c967c90d3ab4fcc5817fbca4db8928311a8b3dfa9f827e9c585a590fd94ca7a -PKG_MAINTAINER:=Alexey Loukianov +PKG_MAINTAINER:=Cristian Ciobanu include $(INCLUDE_DIR)/u-boot.mk include $(INCLUDE_DIR)/package.mk @@ -28,7 +28,7 @@ endef define U-Boot/mt7623n_bpir2 BUILD_SUBTARGET:=mt7623 NAME:=Bannana PI R2 (mt7623) - BUILD_DEVICES:=7623n-bananapi-bpi-r2 + BUILD_DEVICES:=bpi_bananapi-r2 endef UBOOT_TARGETS := \ @@ -43,7 +43,7 @@ UBOOT_MAKE_FLAGS = \ define Build/Prepare $(call Build/Prepare/Default) - $(CP) uEnv-$(UENV).txt $(PKG_BUILD_DIR)/uEnv.txt + $(CP) uEnv-$(UENV).txt ${PKG_BUILD_DIR}/uEnv.txt endef define Build/InstallDev diff --git a/root/package/boot/uboot-mediatek/patches/0001-defconfig-r2-Add-additional-U-boot-options-for-mt7623n.patch b/root/package/boot/uboot-mediatek/patches/0001-defconfig-r2-Add-additional-U-boot-options-for-mt7623n.patch new file mode 100644 index 00000000..a6959594 --- /dev/null +++ b/root/package/boot/uboot-mediatek/patches/0001-defconfig-r2-Add-additional-U-boot-options-for-mt7623n.patch @@ -0,0 +1,64 @@ +From 075db54b57761868cd63434b466fffe7ba7a564f Mon Sep 17 00:00:00 2001 +From: Cristian Ciobanu +Date: Thu, 9 Apr 2020 17:59:27 +0300 +Subject: [PATCH] defconfig: r2: Add additional U-boot options for mt7623n + +--- + configs/mt7623n_bpir2_defconfig | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig +index 07ddade76a..36a903cbe7 100644 +--- a/configs/mt7623n_bpir2_defconfig ++++ b/configs/mt7623n_bpir2_defconfig +@@ -3,7 +3,7 @@ CONFIG_SYS_THUMB_BUILD=y + CONFIG_ARCH_MEDIATEK=y + CONFIG_SYS_TEXT_BASE=0x81e00000 + CONFIG_SYS_MALLOC_F_LEN=0x4000 +-CONFIG_ENV_SIZE=0x1000 ++CONFIG_ENV_SIZE=0x2000 + CONFIG_ENV_OFFSET=0x100000 + CONFIG_TARGET_MT7623=y + CONFIG_NR_DRAM_BANKS=1 +@@ -14,7 +14,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y + CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2" + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_HUSH_PARSER=y +-CONFIG_SYS_PROMPT="U-Boot> " ++CONFIG_SYS_PROMPT="BPI-R2> " + CONFIG_CMD_BOOTMENU=y + # CONFIG_CMD_ELF is not set + # CONFIG_CMD_XIMG is not set +@@ -57,3 +57,29 @@ CONFIG_MTK_TIMER=y + CONFIG_WDT_MTK=y + CONFIG_LZMA=y + # CONFIG_EFI_LOADER is not set ++ ++CONFIG_LOCALVERSION_AUTO=n ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="uEnv.txt" ++CONFIG_CMD_BOOTZ=y ++CONFIG_OF_LIBFDT_OVERLAY=y ++ ++#commands used in uenv.txt ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_SETEXPR=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_PCI=y ++CONFIG_DM_PCI=y ++CONFIG_PCIE_MEDIATEK=y ++CONFIG_PHY=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_CMD_PCI=y ++CONFIG_AHCI=y ++CONFIG_AHCI_PCI=y ++CONFIG_SCSI=y ++CONFIG_DM_SCSI=y ++CONFIG_SCSI_AHCI=y ++CONFIG_HAVE_BLOCK_DEVICE=y ++CONFIG_POWER_MT6323=y +-- +2.25.1 + diff --git a/root/package/boot/uboot-mediatek/patches/0001-update-defconfig.patch b/root/package/boot/uboot-mediatek/patches/0001-update-defconfig.patch deleted file mode 100644 index 15023e0a..00000000 --- a/root/package/boot/uboot-mediatek/patches/0001-update-defconfig.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig -index ae4fb280..74252cd0 100644 ---- a/configs/mt7623n_bpir2_defconfig -+++ b/configs/mt7623n_bpir2_defconfig -@@ -3,6 +3,7 @@ CONFIG_SYS_THUMB_BUILD=y - CONFIG_ARCH_MEDIATEK=y - CONFIG_SYS_TEXT_BASE=0x81e00000 - CONFIG_SYS_MALLOC_F_LEN=0x4000 -+CONFIG_TARGET_MT7623=y - CONFIG_NR_DRAM_BANKS=1 - CONFIG_FIT=y - CONFIG_FIT_VERBOSE=y -@@ -11,7 +12,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y - CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2" - # CONFIG_DISPLAY_BOARDINFO is not set - CONFIG_HUSH_PARSER=y --CONFIG_SYS_PROMPT="U-Boot> " -+CONFIG_SYS_PROMPT="BPI-R2> " - CONFIG_CMD_BOOTMENU=y - # CONFIG_CMD_ELF is not set - # CONFIG_CMD_XIMG is not set -@@ -51,3 +52,14 @@ CONFIG_MTK_TIMER=y - CONFIG_WDT_MTK=y - CONFIG_LZMA=y - # CONFIG_EFI_LOADER is not set -+ -+CONFIG_CMD_BOOTZ=y -+CONFIG_OF_LIBFDT_OVERLAY=y -+ -+CONFIG_USE_DEFAULT_ENV_FILE=y -+CONFIG_DEFAULT_ENV_FILE="uEnv.txt" -+ -+#enables savenenv-command -+CONFIG_ENV_IS_IN_MMC=y -+ -+CONFIG_CMD_ASKENV=y --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0002-adding-saveenv-command-for-bananapi-r2.patch b/root/package/boot/uboot-mediatek/patches/0002-adding-saveenv-command-for-bananapi-r2.patch deleted file mode 100644 index 59acf675..00000000 --- a/root/package/boot/uboot-mediatek/patches/0002-adding-saveenv-command-for-bananapi-r2.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 2a59134ba1d841cf1a7845017656b74b74412aaf Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Mon, 3 Dec 2018 15:32:58 +0100 -Subject: adding saveenv-command for bananapi r2 - -bananapi r2 can be booted from sd-card and emmc -saving the environment have to choose the storage -from which the device has booted - -also the offset is set to 1MB-50Kb to make sure env is written -to block "user data area" between uboot and first partition - -https://www.fw-web.de/dokuwiki/lib/exe/fetch.php?cache=&media=bpi-r2:boot-structure.png - -v3: removed changes in defconfig (users choice) -v2: fixed bracket-style in if-else statement - -Signed-off-by: Frank Wunderlich - -diff --git a/board/mediatek/mt7623/mt7623_rfb.c b/board/mediatek/mt7623/mt7623_rfb.c -index 08468b50..4ec27649 100644 ---- a/board/mediatek/mt7623/mt7623_rfb.c -+++ b/board/mediatek/mt7623/mt7623_rfb.c -@@ -14,3 +14,22 @@ int board_init(void) - - return 0; - } -+ -+int mmc_get_boot_dev(void) -+{ -+ int g_mmc_devid = -1; -+ char *uflag = (char *)0x81DFFFF0; -+ if (strncmp(uflag,"eMMC",4)==0) { -+ g_mmc_devid = 0; -+ printf("Boot From Emmc(id:%d)\n\n", g_mmc_devid); -+ } else { -+ g_mmc_devid = 1; -+ printf("Boot From SD(id:%d)\n\n", g_mmc_devid); -+ } -+ return g_mmc_devid; -+} -+ -+int mmc_get_env_dev(void) -+{ -+ return mmc_get_boot_dev(); -+} -diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h -index ba763501..fb6ac073 100644 ---- a/include/configs/mt7623.h -+++ b/include/configs/mt7623.h -@@ -53,4 +53,7 @@ - #define CONFIG_EXTRA_ENV_SETTINGS \ - FDT_HIGH - -+#define CONFIG_SYS_MMC_ENV_DEV 0 -+#define CONFIG_ENV_OFFSET 0xF3800 -+ - #endif --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0002-u-boot-modify-environment-offset-for-mt7623.patch b/root/package/boot/uboot-mediatek/patches/0002-u-boot-modify-environment-offset-for-mt7623.patch new file mode 100644 index 00000000..2f0e68a1 --- /dev/null +++ b/root/package/boot/uboot-mediatek/patches/0002-u-boot-modify-environment-offset-for-mt7623.patch @@ -0,0 +1,23 @@ +From 15e032f5b06ba97a7777bc32aef15e10d0086041 Mon Sep 17 00:00:00 2001 +From: Cristian Ciobanu +Date: Wed, 8 Apr 2020 22:27:01 +0300 +Subject: [PATCH] u-boot: Modify environment offset for mt7623 + +--- + include/configs/mt7623.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h +index faab0913fc..5d0da71ce9 100644 +--- a/include/configs/mt7623.h ++++ b/include/configs/mt7623.h +@@ -56,5 +56,6 @@ + #define CONFIG_SERVERIP 192.168.1.2 + + #define CONFIG_SYS_MMC_ENV_DEV 0 ++#define CONFIG_ENV_OFFSET 0xF3800 + + #endif +-- +2.25.1 + diff --git a/root/package/boot/uboot-mediatek/patches/0025-bootmenu-added-key-input-1-9-a-f.patch b/root/package/boot/uboot-mediatek/patches/0003-bootmenu-added-key-input-1-9-a-f.patch similarity index 83% rename from root/package/boot/uboot-mediatek/patches/0025-bootmenu-added-key-input-1-9-a-f.patch rename to root/package/boot/uboot-mediatek/patches/0003-bootmenu-added-key-input-1-9-a-f.patch index b7791007..faa70ac6 100644 --- a/root/package/boot/uboot-mediatek/patches/0025-bootmenu-added-key-input-1-9-a-f.patch +++ b/root/package/boot/uboot-mediatek/patches/0003-bootmenu-added-key-input-1-9-a-f.patch @@ -1,14 +1,17 @@ -From 17843557032cc342117591939483d238e80bd169 Mon Sep 17 00:00:00 2001 +From 798f0fc54926093a074a9cbb011de833a0614c3a Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Fri, 28 Dec 2018 17:56:19 +0100 -Subject: [bootmenu] added key-input (1-9,a-f) +Subject: [PATCH 1/2] bootmenu: added key-input (1-9,a-f) +--- + cmd/bootmenu.c | 145 ++++++++++++++++++++++++++++++++----------------- + 1 file changed, 94 insertions(+), 51 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c -index 7f88c1ed..0935fd40 100644 +index 3dc2c854ac..fd6ba6c8af 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c -@@ -39,7 +39,22 @@ struct bootmenu_data { +@@ -40,7 +40,22 @@ struct bootmenu_data { enum bootmenu_key { KEY_NONE = 0, @@ -32,7 +35,7 @@ index 7f88c1ed..0935fd40 100644 KEY_DOWN, KEY_SELECT, }; -@@ -77,6 +92,23 @@ static void bootmenu_print_entry(void *data) +@@ -78,6 +93,23 @@ static void bootmenu_print_entry(void *data) puts(ANSI_COLOR_RESET); } @@ -56,7 +59,7 @@ index 7f88c1ed..0935fd40 100644 static void bootmenu_autoboot_loop(struct bootmenu_data *menu, enum bootmenu_key *key, int *esc) { -@@ -97,23 +129,23 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu, +@@ -98,23 +130,23 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu, menu->delay = -1; c = getc(); @@ -94,7 +97,7 @@ index 7f88c1ed..0935fd40 100644 if (menu->delay < 0) break; -@@ -140,47 +172,49 @@ static void bootmenu_loop(struct bootmenu_data *menu, +@@ -141,47 +173,49 @@ static void bootmenu_loop(struct bootmenu_data *menu, c = getc(); @@ -179,7 +182,7 @@ index 7f88c1ed..0935fd40 100644 /* enter key was pressed */ if (c == '\r') *key = KEY_SELECT; -@@ -203,6 +237,14 @@ static char *bootmenu_choice_entry(void *data) +@@ -204,6 +238,14 @@ static char *bootmenu_choice_entry(void *data) bootmenu_loop(menu, &key, &esc); } @@ -194,7 +197,7 @@ index 7f88c1ed..0935fd40 100644 switch (key) { case KEY_UP: if (menu->active > 0) -@@ -222,6 +264,7 @@ static char *bootmenu_choice_entry(void *data) +@@ -223,6 +265,7 @@ static char *bootmenu_choice_entry(void *data) default: break; } @@ -202,7 +205,7 @@ index 7f88c1ed..0935fd40 100644 } /* never happens */ -@@ -466,7 +509,7 @@ void menu_display_statusline(struct menu *m) +@@ -467,7 +510,7 @@ void menu_display_statusline(struct menu *m) printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); puts(ANSI_CLEAR_LINE); printf(ANSI_CURSOR_POSITION, menu->count + 6, 1); @@ -212,5 +215,5 @@ index 7f88c1ed..0935fd40 100644 printf(ANSI_CURSOR_POSITION, menu->count + 7, 1); puts(ANSI_CLEAR_LINE); -- -1.8.3.1 +2.25.1 diff --git a/root/package/boot/uboot-mediatek/patches/0003-reset-MedaiTek-add-reset-controller-driver-for-Media.patch b/root/package/boot/uboot-mediatek/patches/0003-reset-MedaiTek-add-reset-controller-driver-for-Media.patch deleted file mode 100644 index ab8f2f42..00000000 --- a/root/package/boot/uboot-mediatek/patches/0003-reset-MedaiTek-add-reset-controller-driver-for-Media.patch +++ /dev/null @@ -1,189 +0,0 @@ -From e4033f535d7f6f86f354d36037565a319c02c324 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:51 +0800 -Subject: reset: MedaiTek: add reset controller driver for MediaTek SoCs - -This patch adds reset controller driver for MediaTek SoCs. - -Signed-off-by: Ryder Lee -Signed-off-by: Weijie Gao - -diff --git a/arch/arm/include/asm/arch-mediatek/reset.h b/arch/arm/include/asm/arch-mediatek/reset.h -new file mode 100644 -index 00000000..9704666d ---- /dev/null -+++ b/arch/arm/include/asm/arch-mediatek/reset.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018 MediaTek Inc. -+ */ -+ -+#ifndef __MEDIATEK_RESET_H -+#define __MEDIATEK_RESET_H -+ -+#include -+ -+int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs); -+ -+#endif /* __MEDIATEK_RESET_H */ -diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig -index 9c5208b7..3a6d61f4 100644 ---- a/drivers/reset/Kconfig -+++ b/drivers/reset/Kconfig -@@ -106,4 +106,11 @@ config RESET_SOCFPGA - help - Support for reset controller on SoCFPGA platform. - -+config RESET_MEDIATEK -+ bool "Reset controller driver for MediaTek SoCs" -+ depends on DM_RESET && ARCH_MEDIATEK && CLK -+ default y -+ help -+ Support for reset controller on MediaTek SoCs. -+ - endmenu -diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile -index f4520878..8a4dcab8 100644 ---- a/drivers/reset/Makefile -+++ b/drivers/reset/Makefile -@@ -17,3 +17,4 @@ obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o - obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o - obj-$(CONFIG_RESET_MESON) += reset-meson.o - obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o -+obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o -diff --git a/drivers/reset/reset-mediatek.c b/drivers/reset/reset-mediatek.c -new file mode 100644 -index 00000000..e3614e6e ---- /dev/null -+++ b/drivers/reset/reset-mediatek.c -@@ -0,0 +1,102 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2018 MediaTek Inc. -+ * -+ * Author: Ryder Lee -+ * Weijie Gao -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct mediatek_reset_priv { -+ struct regmap *regmap; -+ u32 regofs; -+ u32 nr_resets; -+}; -+ -+static int mediatek_reset_request(struct reset_ctl *reset_ctl) -+{ -+ return 0; -+} -+ -+static int mediatek_reset_free(struct reset_ctl *reset_ctl) -+{ -+ return 0; -+} -+ -+static int mediatek_reset_assert(struct reset_ctl *reset_ctl) -+{ -+ struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev); -+ int id = reset_ctl->id; -+ -+ if (id >= priv->nr_resets) -+ return -EINVAL; -+ -+ return regmap_update_bits(priv->regmap, -+ priv->regofs + ((id / 32) << 2), BIT(id % 32), BIT(id % 32)); -+} -+ -+static int mediatek_reset_deassert(struct reset_ctl *reset_ctl) -+{ -+ struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev); -+ int id = reset_ctl->id; -+ -+ if (id >= priv->nr_resets) -+ return -EINVAL; -+ -+ return regmap_update_bits(priv->regmap, -+ priv->regofs + ((id / 32) << 2), BIT(id % 32), 0); -+} -+ -+struct reset_ops mediatek_reset_ops = { -+ .request = mediatek_reset_request, -+ .free = mediatek_reset_free, -+ .rst_assert = mediatek_reset_assert, -+ .rst_deassert = mediatek_reset_deassert, -+}; -+ -+static int mediatek_reset_probe(struct udevice *dev) -+{ -+ struct mediatek_reset_priv *priv = dev_get_priv(dev); -+ -+ if (!priv->regofs && !priv->nr_resets) -+ return -EINVAL; -+ -+ priv->regmap = syscon_node_to_regmap(dev_ofnode(dev)); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ -+ return 0; -+} -+ -+int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs) -+{ -+ struct udevice *rst_dev; -+ struct mediatek_reset_priv *priv; -+ int ret; -+ -+ ret = device_bind_driver_to_node(pdev, "mediatek_reset", "reset", -+ dev_ofnode(pdev), &rst_dev); -+ if (ret) -+ return ret; -+ -+ priv = malloc(sizeof(struct mediatek_reset_priv)); -+ priv->regofs = regofs; -+ priv->nr_resets = num_regs * 32; -+ rst_dev->priv = priv; -+ -+ return 0; -+} -+ -+U_BOOT_DRIVER(mediatek_reset) = { -+ .name = "mediatek_reset", -+ .id = UCLASS_RESET, -+ .probe = mediatek_reset_probe, -+ .ops = &mediatek_reset_ops, -+ .priv_auto_alloc_size = sizeof(struct mediatek_reset_priv), -+}; -diff --git a/include/dt-bindings/reset/mtk-reset.h b/include/dt-bindings/reset/mtk-reset.h -new file mode 100644 -index 00000000..5f0a74f2 ---- /dev/null -+++ b/include/dt-bindings/reset/mtk-reset.h -@@ -0,0 +1,18 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018 MediaTek Inc. -+ */ -+ -+#ifndef _DT_BINDINGS_MTK_RESET_H_ -+#define _DT_BINDINGS_MTK_RESET_H_ -+ -+/* ETHSYS */ -+#define ETHSYS_PPE_RST 31 -+#define ETHSYS_EPHY_RST 24 -+#define ETHSYS_GMAC_RST 23 -+#define ETHSYS_ESW_RST 16 -+#define ETHSYS_FE_RST 6 -+#define ETHSYS_MCM_RST 2 -+#define ETHSYS_SYS_RST 0 -+ -+#endif /* _DT_BINDINGS_MTK_RESET_H_ */ --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0004-Add-EXT4-support-in-U-boot.patch b/root/package/boot/uboot-mediatek/patches/0004-Add-EXT4-support-in-U-boot.patch new file mode 100644 index 00000000..3f1a024b --- /dev/null +++ b/root/package/boot/uboot-mediatek/patches/0004-Add-EXT4-support-in-U-boot.patch @@ -0,0 +1,25 @@ +From 39b0c824b56be1000844cedb5faba506b6b09b9b Mon Sep 17 00:00:00 2001 +From: Cristian Ciobanu +Date: Fri, 10 Apr 2020 00:41:42 +0300 +Subject: [PATCH] Add EXT4 support in U-boot + +--- + configs/mt7623n_bpir2_defconfig | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig +index 36a903cbe7..09b9b6f797 100644 +--- a/configs/mt7623n_bpir2_defconfig ++++ b/configs/mt7623n_bpir2_defconfig +@@ -83,3 +83,8 @@ CONFIG_DM_SCSI=y + CONFIG_SCSI_AHCI=y + CONFIG_HAVE_BLOCK_DEVICE=y + CONFIG_POWER_MT6323=y ++ ++CONFIG_CMD_EXT4=y ++CONFIG_CMD_EXT4_WRITE=y ++CONFIG_FS_EXT4=y ++CONFIG_EXT4_WRITE=y +-- +2.25.1 + diff --git a/root/package/boot/uboot-mediatek/patches/0004-clk-MediaTek-bind-ethsys-reset-controller.patch b/root/package/boot/uboot-mediatek/patches/0004-clk-MediaTek-bind-ethsys-reset-controller.patch deleted file mode 100644 index d8096a40..00000000 --- a/root/package/boot/uboot-mediatek/patches/0004-clk-MediaTek-bind-ethsys-reset-controller.patch +++ /dev/null @@ -1,109 +0,0 @@ -From ab7ad2d077ef18d6d853c8838bc116fbbd0ac154 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:52 +0800 -Subject: clk: MediaTek: bind ethsys reset controller - -The ethsys contains not only the clock gating controller, but also the -reset controller for the whole ethernet subsystem and its components. - -This patch adds binding of the reset controller so that the ethernet node -can have references on it. - -Signed-off-by: Weijie Gao - -diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c -index c6b09d8e..87ad4f79 100644 ---- a/drivers/clk/mediatek/clk-mt7623.c -+++ b/drivers/clk/mediatek/clk-mt7623.c -@@ -8,6 +8,7 @@ - - #include - #include -+#include - #include - #include - -@@ -782,6 +783,19 @@ static int mt7623_ethsys_probe(struct udevice *dev) - return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, eth_cgs); - } - -+static int mt7623_ethsys_bind(struct udevice *dev) -+{ -+ int ret = 0; -+ -+#if CONFIG_IS_ENABLED(RESET_MEDIATEK) -+ ret = mediatek_reset_bind(dev, ETHSYS_RST_CTRL_OFS, 1); -+ if (ret) -+ debug("Warning: failed to bind ethsys reset controller\n"); -+#endif -+ -+ return ret; -+} -+ - static const struct udevice_id mt7623_apmixed_compat[] = { - { .compatible = "mediatek,mt7623-apmixedsys" }, - { } -@@ -865,6 +879,7 @@ U_BOOT_DRIVER(mtk_clk_ethsys) = { - .id = UCLASS_CLK, - .of_match = mt7623_ethsys_compat, - .probe = mt7623_ethsys_probe, -+ .bind = mt7623_ethsys_bind, - .priv_auto_alloc_size = sizeof(struct mtk_cg_priv), - .ops = &mtk_clk_gate_ops, - }; -diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c -index 2601b6cf..6a9f6013 100644 ---- a/drivers/clk/mediatek/clk-mt7629.c -+++ b/drivers/clk/mediatek/clk-mt7629.c -@@ -8,6 +8,7 @@ - - #include - #include -+#include - #include - #include - -@@ -602,6 +603,19 @@ static int mt7629_ethsys_probe(struct udevice *dev) - return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, eth_cgs); - } - -+static int mt7629_ethsys_bind(struct udevice *dev) -+{ -+ int ret = 0; -+ -+#if CONFIG_IS_ENABLED(RESET_MEDIATEK) -+ ret = mediatek_reset_bind(dev, ETHSYS_RST_CTRL_OFS, 1); -+ if (ret) -+ debug("Warning: failed to bind ethsys reset controller\n"); -+#endif -+ -+ return ret; -+} -+ - static int mt7629_sgmiisys_probe(struct udevice *dev) - { - return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, sgmii_cgs); -@@ -695,6 +709,7 @@ U_BOOT_DRIVER(mtk_clk_ethsys) = { - .id = UCLASS_CLK, - .of_match = mt7629_ethsys_compat, - .probe = mt7629_ethsys_probe, -+ .bind = mt7629_ethsys_bind, - .priv_auto_alloc_size = sizeof(struct mtk_cg_priv), - .ops = &mtk_clk_gate_ops, - }; -diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h -index 74152ed9..7847388b 100644 ---- a/drivers/clk/mediatek/clk-mtk.h -+++ b/drivers/clk/mediatek/clk-mtk.h -@@ -23,6 +23,8 @@ - #define CLK_PARENT_TOPCKGEN BIT(5) - #define CLK_PARENT_MASK GENMASK(5, 4) - -+#define ETHSYS_RST_CTRL_OFS 0x34 -+ - /* struct mtk_pll_data - hardware-specific PLLs data */ - struct mtk_pll_data { - const int id; --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0005-ethernet-MediaTek-add-ethernet-driver-for-MediaTek-A.patch b/root/package/boot/uboot-mediatek/patches/0005-ethernet-MediaTek-add-ethernet-driver-for-MediaTek-A.patch deleted file mode 100644 index 7a940f1f..00000000 --- a/root/package/boot/uboot-mediatek/patches/0005-ethernet-MediaTek-add-ethernet-driver-for-MediaTek-A.patch +++ /dev/null @@ -1,1517 +0,0 @@ -From 9d80ec7dff8033a2a7309c0695c30d7299e44901 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:53 +0800 -Subject: ethernet: MediaTek: add ethernet driver for MediaTek ARM-based SoCs - -This patch adds ethernet support for Mediatek ARM-based SoCs, including -a minimum setup of the integrated switch. - -Cc: Joe Hershberger -Signed-off-by: Mark Lee -Signed-off-by: Weijie Gao -Tested-By: "Frank Wunderlich" - -diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig -index 7044c6ad..ff55e03d 100644 ---- a/drivers/net/Kconfig -+++ b/drivers/net/Kconfig -@@ -513,4 +513,14 @@ config TSEC_ENET - This driver implements support for the (Enhanced) Three-Speed - Ethernet Controller found on Freescale SoCs. - -+config MEDIATEK_ETH -+ bool "MediaTek Ethernet GMAC Driver" -+ depends on DM_ETH -+ select PHYLIB -+ select DM_GPIO -+ select DM_RESET -+ help -+ This Driver support MediaTek Ethernet GMAC -+ Say Y to enable support for the MediaTek Ethernet GMAC. -+ - endif # NETDEVICES -diff --git a/drivers/net/Makefile b/drivers/net/Makefile -index 0dbfa033..ee7f3e71 100644 ---- a/drivers/net/Makefile -+++ b/drivers/net/Makefile -@@ -74,3 +74,4 @@ obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o - obj-$(CONFIG_FSL_PFE) += pfe_eth/ - obj-$(CONFIG_SNI_AVE) += sni_ave.o - obj-y += ti/ -+obj-$(CONFIG_MEDIATEK_ETH) += mtk_eth.o -diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c -new file mode 100644 -index 00000000..cc094048 ---- /dev/null -+++ b/drivers/net/mtk_eth.c -@@ -0,0 +1,1175 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2018 MediaTek Inc. -+ * -+ * Author: Weijie Gao -+ * Author: Mark Lee -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtk_eth.h" -+ -+#define NUM_TX_DESC 24 -+#define NUM_RX_DESC 24 -+#define TX_TOTAL_BUF_SIZE (NUM_TX_DESC * PKTSIZE_ALIGN) -+#define RX_TOTAL_BUF_SIZE (NUM_RX_DESC * PKTSIZE_ALIGN) -+#define TOTAL_PKT_BUF_SIZE (TX_TOTAL_BUF_SIZE + RX_TOTAL_BUF_SIZE) -+ -+#define MT7530_NUM_PHYS 5 -+#define MT7530_DFL_SMI_ADDR 31 -+ -+#define MT7530_PHY_ADDR(base, addr) \ -+ (((base) + (addr)) & 0x1f) -+ -+#define GDMA_FWD_TO_CPU \ -+ (0x20000000 | \ -+ GDM_ICS_EN | \ -+ GDM_TCS_EN | \ -+ GDM_UCS_EN | \ -+ STRP_CRC | \ -+ (DP_PDMA << MYMAC_DP_S) | \ -+ (DP_PDMA << BC_DP_S) | \ -+ (DP_PDMA << MC_DP_S) | \ -+ (DP_PDMA << UN_DP_S)) -+ -+#define GDMA_FWD_DISCARD \ -+ (0x20000000 | \ -+ GDM_ICS_EN | \ -+ GDM_TCS_EN | \ -+ GDM_UCS_EN | \ -+ STRP_CRC | \ -+ (DP_DISCARD << MYMAC_DP_S) | \ -+ (DP_DISCARD << BC_DP_S) | \ -+ (DP_DISCARD << MC_DP_S) | \ -+ (DP_DISCARD << UN_DP_S)) -+ -+struct pdma_rxd_info1 { -+ u32 PDP0; -+}; -+ -+struct pdma_rxd_info2 { -+ u32 PLEN1 : 14; -+ u32 LS1 : 1; -+ u32 UN_USED : 1; -+ u32 PLEN0 : 14; -+ u32 LS0 : 1; -+ u32 DDONE : 1; -+}; -+ -+struct pdma_rxd_info3 { -+ u32 PDP1; -+}; -+ -+struct pdma_rxd_info4 { -+ u32 FOE_ENTRY : 14; -+ u32 CRSN : 5; -+ u32 SP : 3; -+ u32 L4F : 1; -+ u32 L4VLD : 1; -+ u32 TACK : 1; -+ u32 IP4F : 1; -+ u32 IP4 : 1; -+ u32 IP6 : 1; -+ u32 UN_USED : 4; -+}; -+ -+struct pdma_rxdesc { -+ struct pdma_rxd_info1 rxd_info1; -+ struct pdma_rxd_info2 rxd_info2; -+ struct pdma_rxd_info3 rxd_info3; -+ struct pdma_rxd_info4 rxd_info4; -+}; -+ -+struct pdma_txd_info1 { -+ u32 SDP0; -+}; -+ -+struct pdma_txd_info2 { -+ u32 SDL1 : 14; -+ u32 LS1 : 1; -+ u32 BURST : 1; -+ u32 SDL0 : 14; -+ u32 LS0 : 1; -+ u32 DDONE : 1; -+}; -+ -+struct pdma_txd_info3 { -+ u32 SDP1; -+}; -+ -+struct pdma_txd_info4 { -+ u32 VLAN_TAG : 16; -+ u32 INS : 1; -+ u32 RESV : 2; -+ u32 UDF : 6; -+ u32 FPORT : 3; -+ u32 TSO : 1; -+ u32 TUI_CO : 3; -+}; -+ -+struct pdma_txdesc { -+ struct pdma_txd_info1 txd_info1; -+ struct pdma_txd_info2 txd_info2; -+ struct pdma_txd_info3 txd_info3; -+ struct pdma_txd_info4 txd_info4; -+}; -+ -+enum mtk_switch { -+ SW_NONE, -+ SW_MT7530 -+}; -+ -+enum mtk_soc { -+ SOC_MT7623, -+ SOC_MT7629 -+}; -+ -+struct mtk_eth_priv { -+ char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN); -+ -+ struct pdma_txdesc *tx_ring_noc; -+ struct pdma_rxdesc *rx_ring_noc; -+ -+ int rx_dma_owner_idx0; -+ int tx_cpu_owner_idx0; -+ -+ void __iomem *fe_base; -+ void __iomem *gmac_base; -+ void __iomem *ethsys_base; -+ -+ struct mii_dev *mdio_bus; -+ int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg); -+ int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val); -+ int (*mmd_read)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg); -+ int (*mmd_write)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg, -+ u16 val); -+ -+ enum mtk_soc soc; -+ int gmac_id; -+ int force_mode; -+ int speed; -+ int duplex; -+ -+ struct phy_device *phydev; -+ int phy_interface; -+ int phy_addr; -+ -+ enum mtk_switch sw; -+ int (*switch_init)(struct mtk_eth_priv *priv); -+ u32 mt7530_smi_addr; -+ u32 mt7530_phy_base; -+ -+ struct gpio_desc rst_gpio; -+ int mcm; -+ -+ struct reset_ctl rst_fe; -+ struct reset_ctl rst_mcm; -+}; -+ -+static void mtk_pdma_write(struct mtk_eth_priv *priv, u32 reg, u32 val) -+{ -+ writel(val, priv->fe_base + PDMA_BASE + reg); -+} -+ -+static void mtk_pdma_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, -+ u32 set) -+{ -+ clrsetbits_le32(priv->fe_base + PDMA_BASE + reg, clr, set); -+} -+ -+static void mtk_gdma_write(struct mtk_eth_priv *priv, int no, u32 reg, -+ u32 val) -+{ -+ u32 gdma_base; -+ -+ if (no == 1) -+ gdma_base = GDMA2_BASE; -+ else -+ gdma_base = GDMA1_BASE; -+ -+ writel(val, priv->fe_base + gdma_base + reg); -+} -+ -+static u32 mtk_gmac_read(struct mtk_eth_priv *priv, u32 reg) -+{ -+ return readl(priv->gmac_base + reg); -+} -+ -+static void mtk_gmac_write(struct mtk_eth_priv *priv, u32 reg, u32 val) -+{ -+ writel(val, priv->gmac_base + reg); -+} -+ -+static void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) -+{ -+ clrsetbits_le32(priv->gmac_base + reg, clr, set); -+} -+ -+static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, -+ u32 set) -+{ -+ clrsetbits_le32(priv->ethsys_base + reg, clr, set); -+} -+ -+/* Direct MDIO clause 22/45 access via SoC */ -+static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data, -+ u32 cmd, u32 st) -+{ -+ int ret; -+ u32 val; -+ -+ val = (st << MDIO_ST_S) | -+ ((cmd << MDIO_CMD_S) & MDIO_CMD_M) | -+ (((u32)phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) | -+ (((u32)reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M); -+ -+ if (cmd == MDIO_CMD_WRITE) -+ val |= data & MDIO_RW_DATA_M; -+ -+ mtk_gmac_write(priv, GMAC_PIAC_REG, val | PHY_ACS_ST); -+ -+ ret = wait_for_bit_le32(priv->gmac_base + GMAC_PIAC_REG, -+ PHY_ACS_ST, 0, 5000, 0); -+ if (ret) { -+ pr_warn("MDIO access timeout\n"); -+ return ret; -+ } -+ -+ if (cmd == MDIO_CMD_READ) { -+ val = mtk_gmac_read(priv, GMAC_PIAC_REG); -+ return val & MDIO_RW_DATA_M; -+ } -+ -+ return 0; -+} -+ -+/* Direct MDIO clause 22 read via SoC */ -+static int mtk_mii_read(struct mtk_eth_priv *priv, u8 phy, u8 reg) -+{ -+ return mtk_mii_rw(priv, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22); -+} -+ -+/* Direct MDIO clause 22 write via SoC */ -+static int mtk_mii_write(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data) -+{ -+ return mtk_mii_rw(priv, phy, reg, data, MDIO_CMD_WRITE, MDIO_ST_C22); -+} -+ -+/* Direct MDIO clause 45 read via SoC */ -+static int mtk_mmd_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg) -+{ -+ int ret; -+ -+ ret = mtk_mii_rw(priv, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45); -+ if (ret) -+ return ret; -+ -+ return mtk_mii_rw(priv, addr, devad, 0, MDIO_CMD_READ_C45, -+ MDIO_ST_C45); -+} -+ -+/* Direct MDIO clause 45 write via SoC */ -+static int mtk_mmd_write(struct mtk_eth_priv *priv, u8 addr, u8 devad, -+ u16 reg, u16 val) -+{ -+ int ret; -+ -+ ret = mtk_mii_rw(priv, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45); -+ if (ret) -+ return ret; -+ -+ return mtk_mii_rw(priv, addr, devad, val, MDIO_CMD_WRITE, -+ MDIO_ST_C45); -+} -+ -+/* Indirect MDIO clause 45 read via MII registers */ -+static int mtk_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, -+ u16 reg) -+{ -+ int ret; -+ -+ ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG, -+ (MMD_ADDR << MMD_CMD_S) | -+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); -+ if (ret) -+ return ret; -+ -+ ret = priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, reg); -+ if (ret) -+ return ret; -+ -+ ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG, -+ (MMD_DATA << MMD_CMD_S) | -+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); -+ if (ret) -+ return ret; -+ -+ return priv->mii_read(priv, addr, MII_MMD_ADDR_DATA_REG); -+} -+ -+/* Indirect MDIO clause 45 write via MII registers */ -+static int mtk_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad, -+ u16 reg, u16 val) -+{ -+ int ret; -+ -+ ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG, -+ (MMD_ADDR << MMD_CMD_S) | -+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); -+ if (ret) -+ return ret; -+ -+ ret = priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, reg); -+ if (ret) -+ return ret; -+ -+ ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG, -+ (MMD_DATA << MMD_CMD_S) | -+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); -+ if (ret) -+ return ret; -+ -+ return priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, val); -+} -+ -+static int mtk_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) -+{ -+ struct mtk_eth_priv *priv = bus->priv; -+ -+ if (devad < 0) -+ return priv->mii_read(priv, addr, reg); -+ else -+ return priv->mmd_read(priv, addr, devad, reg); -+} -+ -+static int mtk_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, -+ u16 val) -+{ -+ struct mtk_eth_priv *priv = bus->priv; -+ -+ if (devad < 0) -+ return priv->mii_write(priv, addr, reg, val); -+ else -+ return priv->mmd_write(priv, addr, devad, reg, val); -+} -+ -+static int mtk_mdio_register(struct udevice *dev) -+{ -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ struct mii_dev *mdio_bus = mdio_alloc(); -+ int ret; -+ -+ if (!mdio_bus) -+ return -ENOMEM; -+ -+ /* Assign MDIO access APIs according to the switch/phy */ -+ switch (priv->sw) { -+ case SW_MT7530: -+ priv->mii_read = mtk_mii_read; -+ priv->mii_write = mtk_mii_write; -+ priv->mmd_read = mtk_mmd_ind_read; -+ priv->mmd_write = mtk_mmd_ind_write; -+ break; -+ default: -+ priv->mii_read = mtk_mii_read; -+ priv->mii_write = mtk_mii_write; -+ priv->mmd_read = mtk_mmd_read; -+ priv->mmd_write = mtk_mmd_write; -+ } -+ -+ mdio_bus->read = mtk_mdio_read; -+ mdio_bus->write = mtk_mdio_write; -+ snprintf(mdio_bus->name, sizeof(mdio_bus->name), dev->name); -+ -+ mdio_bus->priv = (void *)priv; -+ -+ ret = mdio_register(mdio_bus); -+ -+ if (ret) -+ return ret; -+ -+ priv->mdio_bus = mdio_bus; -+ -+ return 0; -+} -+ -+/* -+ * MT7530 Internal Register Address Bits -+ * ------------------------------------------------------------------- -+ * | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 | -+ * |----------------------------------------|---------------|--------| -+ * | Page Address | Reg Address | Unused | -+ * ------------------------------------------------------------------- -+ */ -+ -+static int mt7530_reg_read(struct mtk_eth_priv *priv, u32 reg, u32 *data) -+{ -+ int ret, low_word, high_word; -+ -+ /* Write page address */ -+ ret = mtk_mii_write(priv, priv->mt7530_smi_addr, 0x1f, reg >> 6); -+ if (ret) -+ return ret; -+ -+ /* Read low word */ -+ low_word = mtk_mii_read(priv, priv->mt7530_smi_addr, (reg >> 2) & 0xf); -+ if (low_word < 0) -+ return low_word; -+ -+ /* Read high word */ -+ high_word = mtk_mii_read(priv, priv->mt7530_smi_addr, 0x10); -+ if (high_word < 0) -+ return high_word; -+ -+ if (data) -+ *data = ((u32)high_word << 16) | (low_word & 0xffff); -+ -+ return 0; -+} -+ -+static int mt7530_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 data) -+{ -+ int ret; -+ -+ /* Write page address */ -+ ret = mtk_mii_write(priv, priv->mt7530_smi_addr, 0x1f, reg >> 6); -+ if (ret) -+ return ret; -+ -+ /* Write low word */ -+ ret = mtk_mii_write(priv, priv->mt7530_smi_addr, (reg >> 2) & 0xf, -+ data & 0xffff); -+ if (ret) -+ return ret; -+ -+ /* Write high word */ -+ return mtk_mii_write(priv, priv->mt7530_smi_addr, 0x10, data >> 16); -+} -+ -+static void mt7530_reg_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, -+ u32 set) -+{ -+ u32 val; -+ -+ mt7530_reg_read(priv, reg, &val); -+ val &= ~clr; -+ val |= set; -+ mt7530_reg_write(priv, reg, val); -+} -+ -+static void mt7530_core_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 val) -+{ -+ u8 phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, 0); -+ -+ mtk_mmd_ind_write(priv, phy_addr, 0x1f, reg, val); -+} -+ -+static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode) -+{ -+ u32 ncpo1, ssc_delta; -+ -+ switch (mode) { -+ case PHY_INTERFACE_MODE_RGMII: -+ ncpo1 = 0x0c80; -+ ssc_delta = 0x87; -+ break; -+ default: -+ printf("error: xMII mode %d not supported\n", mode); -+ return -EINVAL; -+ } -+ -+ /* Disable MT7530 core clock */ -+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, 0); -+ -+ /* Disable MT7530 PLL */ -+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1, -+ (2 << RG_GSWPLL_POSDIV_200M_S) | -+ (32 << RG_GSWPLL_FBKDIV_200M_S)); -+ -+ /* For MT7530 core clock = 500Mhz */ -+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP2, -+ (1 << RG_GSWPLL_POSDIV_500M_S) | -+ (25 << RG_GSWPLL_FBKDIV_500M_S)); -+ -+ /* Enable MT7530 PLL */ -+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1, -+ (2 << RG_GSWPLL_POSDIV_200M_S) | -+ (32 << RG_GSWPLL_FBKDIV_200M_S) | -+ RG_GSWPLL_EN_PRE); -+ -+ udelay(20); -+ -+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); -+ -+ /* Setup the MT7530 TRGMII Tx Clock */ -+ mt7530_core_reg_write(priv, CORE_PLL_GROUP5, ncpo1); -+ mt7530_core_reg_write(priv, CORE_PLL_GROUP6, 0); -+ mt7530_core_reg_write(priv, CORE_PLL_GROUP10, ssc_delta); -+ mt7530_core_reg_write(priv, CORE_PLL_GROUP11, ssc_delta); -+ mt7530_core_reg_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN | -+ RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN); -+ -+ mt7530_core_reg_write(priv, CORE_PLL_GROUP2, -+ RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN | -+ (1 << RG_SYSPLL_POSDIV_S)); -+ -+ mt7530_core_reg_write(priv, CORE_PLL_GROUP7, -+ RG_LCDDS_PCW_NCPO_CHG | (3 << RG_LCCDS_C_S) | -+ RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); -+ -+ /* Enable MT7530 core clock */ -+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, -+ REG_GSWCK_EN | REG_TRGMIICK_EN); -+ -+ return 0; -+} -+ -+static int mt7530_setup(struct mtk_eth_priv *priv) -+{ -+ u16 phy_addr, phy_val; -+ u32 val; -+ int i; -+ -+ /* Select 250MHz clk for RGMII mode */ -+ mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG, -+ ETHSYS_TRGMII_CLK_SEL362_5, 0); -+ -+ /* Global reset switch */ -+ if (priv->mcm) { -+ reset_assert(&priv->rst_mcm); -+ udelay(1000); -+ reset_deassert(&priv->rst_mcm); -+ mdelay(1000); -+ } else if (dm_gpio_is_valid(&priv->rst_gpio)) { -+ dm_gpio_set_value(&priv->rst_gpio, 0); -+ udelay(1000); -+ dm_gpio_set_value(&priv->rst_gpio, 1); -+ mdelay(1000); -+ } -+ -+ /* Modify HWTRAP first to allow direct access to internal PHYs */ -+ mt7530_reg_read(priv, HWTRAP_REG, &val); -+ val |= CHG_TRAP; -+ val &= ~C_MDIO_BPS; -+ mt7530_reg_write(priv, MHWTRAP_REG, val); -+ -+ /* Calculate the phy base address */ -+ val = ((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3; -+ priv->mt7530_phy_base = (val | 0x7) + 1; -+ -+ /* Turn off PHYs */ -+ for (i = 0; i < MT7530_NUM_PHYS; i++) { -+ phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, i); -+ phy_val = priv->mii_read(priv, phy_addr, MII_BMCR); -+ phy_val |= BMCR_PDOWN; -+ priv->mii_write(priv, phy_addr, MII_BMCR, phy_val); -+ } -+ -+ /* Force MAC link down before reset */ -+ mt7530_reg_write(priv, PCMR_REG(5), FORCE_MODE); -+ mt7530_reg_write(priv, PCMR_REG(6), FORCE_MODE); -+ -+ /* MT7530 reset */ -+ mt7530_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST); -+ udelay(100); -+ -+ val = (1 << IPG_CFG_S) | -+ MAC_MODE | FORCE_MODE | -+ MAC_TX_EN | MAC_RX_EN | -+ BKOFF_EN | BACKPR_EN | -+ (SPEED_1000M << FORCE_SPD_S) | -+ FORCE_DPX | FORCE_LINK; -+ -+ /* MT7530 Port6: Forced 1000M/FD, FC disabled */ -+ mt7530_reg_write(priv, PCMR_REG(6), val); -+ -+ /* MT7530 Port5: Forced link down */ -+ mt7530_reg_write(priv, PCMR_REG(5), FORCE_MODE); -+ -+ /* MT7530 Port6: Set to RGMII */ -+ mt7530_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII); -+ -+ /* Hardware Trap: Enable Port6, Disable Port5 */ -+ mt7530_reg_read(priv, HWTRAP_REG, &val); -+ val |= CHG_TRAP | LOOPDET_DIS | P5_INTF_DIS | -+ (P5_INTF_SEL_GMAC5 << P5_INTF_SEL_S) | -+ (P5_INTF_MODE_RGMII << P5_INTF_MODE_S); -+ val &= ~(C_MDIO_BPS | P6_INTF_DIS); -+ mt7530_reg_write(priv, MHWTRAP_REG, val); -+ -+ /* Setup switch core pll */ -+ mt7530_pad_clk_setup(priv, priv->phy_interface); -+ -+ /* Lower Tx Driving for TRGMII path */ -+ for (i = 0 ; i < NUM_TRGMII_CTRL ; i++) -+ mt7530_reg_write(priv, MT7530_TRGMII_TD_ODT(i), -+ (8 << TD_DM_DRVP_S) | (8 << TD_DM_DRVN_S)); -+ -+ for (i = 0 ; i < NUM_TRGMII_CTRL; i++) -+ mt7530_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16); -+ -+ /* Turn on PHYs */ -+ for (i = 0; i < MT7530_NUM_PHYS; i++) { -+ phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, i); -+ phy_val = priv->mii_read(priv, phy_addr, MII_BMCR); -+ phy_val &= ~BMCR_PDOWN; -+ priv->mii_write(priv, phy_addr, MII_BMCR, phy_val); -+ } -+ -+ /* Set port isolation */ -+ for (i = 0; i < 8; i++) { -+ /* Set port matrix mode */ -+ if (i != 6) -+ mt7530_reg_write(priv, PCR_REG(i), -+ (0x40 << PORT_MATRIX_S)); -+ else -+ mt7530_reg_write(priv, PCR_REG(i), -+ (0x3f << PORT_MATRIX_S)); -+ -+ /* Set port mode to user port */ -+ mt7530_reg_write(priv, PVC_REG(i), -+ (0x8100 << STAG_VPID_S) | -+ (VLAN_ATTR_USER << VLAN_ATTR_S)); -+ } -+ -+ return 0; -+} -+ -+static void mtk_phy_link_adjust(struct mtk_eth_priv *priv) -+{ -+ u16 lcl_adv = 0, rmt_adv = 0; -+ u8 flowctrl; -+ u32 mcr; -+ -+ mcr = (1 << IPG_CFG_S) | -+ (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) | -+ MAC_MODE | FORCE_MODE | -+ MAC_TX_EN | MAC_RX_EN | -+ BKOFF_EN | BACKPR_EN; -+ -+ switch (priv->phydev->speed) { -+ case SPEED_10: -+ mcr |= (SPEED_10M << FORCE_SPD_S); -+ break; -+ case SPEED_100: -+ mcr |= (SPEED_100M << FORCE_SPD_S); -+ break; -+ case SPEED_1000: -+ mcr |= (SPEED_1000M << FORCE_SPD_S); -+ break; -+ }; -+ -+ if (priv->phydev->link) -+ mcr |= FORCE_LINK; -+ -+ if (priv->phydev->duplex) { -+ mcr |= FORCE_DPX; -+ -+ if (priv->phydev->pause) -+ rmt_adv = LPA_PAUSE_CAP; -+ if (priv->phydev->asym_pause) -+ rmt_adv |= LPA_PAUSE_ASYM; -+ -+ if (priv->phydev->advertising & ADVERTISED_Pause) -+ lcl_adv |= ADVERTISE_PAUSE_CAP; -+ if (priv->phydev->advertising & ADVERTISED_Asym_Pause) -+ lcl_adv |= ADVERTISE_PAUSE_ASYM; -+ -+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); -+ -+ if (flowctrl & FLOW_CTRL_TX) -+ mcr |= FORCE_TX_FC; -+ if (flowctrl & FLOW_CTRL_RX) -+ mcr |= FORCE_RX_FC; -+ -+ debug("rx pause %s, tx pause %s\n", -+ flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled", -+ flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled"); -+ } -+ -+ mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr); -+} -+ -+static int mtk_phy_start(struct mtk_eth_priv *priv) -+{ -+ struct phy_device *phydev = priv->phydev; -+ int ret; -+ -+ ret = phy_startup(phydev); -+ -+ if (ret) { -+ debug("Could not initialize PHY %s\n", phydev->dev->name); -+ return ret; -+ } -+ -+ if (!phydev->link) { -+ debug("%s: link down.\n", phydev->dev->name); -+ return 0; -+ } -+ -+ mtk_phy_link_adjust(priv); -+ -+ debug("Speed: %d, %s duplex%s\n", phydev->speed, -+ (phydev->duplex) ? "full" : "half", -+ (phydev->port == PORT_FIBRE) ? ", fiber mode" : ""); -+ -+ return 0; -+} -+ -+static int mtk_phy_probe(struct udevice *dev) -+{ -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ struct phy_device *phydev; -+ -+ phydev = phy_connect(priv->mdio_bus, priv->phy_addr, dev, -+ priv->phy_interface); -+ if (!phydev) -+ return -ENODEV; -+ -+ phydev->supported &= PHY_GBIT_FEATURES; -+ phydev->advertising = phydev->supported; -+ -+ priv->phydev = phydev; -+ phy_config(phydev); -+ -+ return 0; -+} -+ -+static void mtk_mac_init(struct mtk_eth_priv *priv) -+{ -+ int i, ge_mode = 0; -+ u32 mcr; -+ -+ switch (priv->phy_interface) { -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_SGMII: -+ ge_mode = GE_MODE_RGMII; -+ break; -+ case PHY_INTERFACE_MODE_MII: -+ case PHY_INTERFACE_MODE_GMII: -+ ge_mode = GE_MODE_MII; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ ge_mode = GE_MODE_RMII; -+ break; -+ default: -+ break; -+ } -+ -+ /* set the gmac to the right mode */ -+ mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG, -+ SYSCFG0_GE_MODE_M << SYSCFG0_GE_MODE_S(priv->gmac_id), -+ ge_mode << SYSCFG0_GE_MODE_S(priv->gmac_id)); -+ -+ if (priv->force_mode) { -+ mcr = (1 << IPG_CFG_S) | -+ (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) | -+ MAC_MODE | FORCE_MODE | -+ MAC_TX_EN | MAC_RX_EN | -+ BKOFF_EN | BACKPR_EN | -+ FORCE_LINK; -+ -+ switch (priv->speed) { -+ case SPEED_10: -+ mcr |= SPEED_10M << FORCE_SPD_S; -+ break; -+ case SPEED_100: -+ mcr |= SPEED_100M << FORCE_SPD_S; -+ break; -+ case SPEED_1000: -+ mcr |= SPEED_1000M << FORCE_SPD_S; -+ break; -+ } -+ -+ if (priv->duplex) -+ mcr |= FORCE_DPX; -+ -+ mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr); -+ } -+ -+ if (priv->soc == SOC_MT7623) { -+ /* Lower Tx Driving for TRGMII path */ -+ for (i = 0 ; i < NUM_TRGMII_CTRL; i++) -+ mtk_gmac_write(priv, GMAC_TRGMII_TD_ODT(i), -+ (8 << TD_DM_DRVP_S) | -+ (8 << TD_DM_DRVN_S)); -+ -+ mtk_gmac_rmw(priv, GMAC_TRGMII_RCK_CTRL, 0, -+ RX_RST | RXC_DQSISEL); -+ mtk_gmac_rmw(priv, GMAC_TRGMII_RCK_CTRL, RX_RST, 0); -+ } -+} -+ -+static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) -+{ -+ char *pkt_base = priv->pkt_pool; -+ int i; -+ -+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0); -+ udelay(500); -+ -+ memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct pdma_txdesc)); -+ memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc)); -+ memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE); -+ -+ flush_dcache_range((u32)pkt_base, (u32)(pkt_base + TOTAL_PKT_BUF_SIZE)); -+ -+ priv->rx_dma_owner_idx0 = 0; -+ priv->tx_cpu_owner_idx0 = 0; -+ -+ for (i = 0; i < NUM_TX_DESC; i++) { -+ priv->tx_ring_noc[i].txd_info2.LS0 = 1; -+ priv->tx_ring_noc[i].txd_info2.DDONE = 1; -+ priv->tx_ring_noc[i].txd_info4.FPORT = priv->gmac_id + 1; -+ -+ priv->tx_ring_noc[i].txd_info1.SDP0 = virt_to_phys(pkt_base); -+ pkt_base += PKTSIZE_ALIGN; -+ } -+ -+ for (i = 0; i < NUM_RX_DESC; i++) { -+ priv->rx_ring_noc[i].rxd_info2.PLEN0 = PKTSIZE_ALIGN; -+ priv->rx_ring_noc[i].rxd_info1.PDP0 = virt_to_phys(pkt_base); -+ pkt_base += PKTSIZE_ALIGN; -+ } -+ -+ mtk_pdma_write(priv, TX_BASE_PTR_REG(0), -+ virt_to_phys(priv->tx_ring_noc)); -+ mtk_pdma_write(priv, TX_MAX_CNT_REG(0), NUM_TX_DESC); -+ mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0); -+ -+ mtk_pdma_write(priv, RX_BASE_PTR_REG(0), -+ virt_to_phys(priv->rx_ring_noc)); -+ mtk_pdma_write(priv, RX_MAX_CNT_REG(0), NUM_RX_DESC); -+ mtk_pdma_write(priv, RX_CRX_IDX_REG(0), NUM_RX_DESC - 1); -+ -+ mtk_pdma_write(priv, PDMA_RST_IDX_REG, RST_DTX_IDX0 | RST_DRX_IDX0); -+} -+ -+static int mtk_eth_start(struct udevice *dev) -+{ -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ /* Reset FE */ -+ reset_assert(&priv->rst_fe); -+ udelay(1000); -+ reset_deassert(&priv->rst_fe); -+ mdelay(10); -+ -+ /* Packets forward to PDMA */ -+ mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU); -+ -+ if (priv->gmac_id == 0) -+ mtk_gdma_write(priv, 1, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD); -+ else -+ mtk_gdma_write(priv, 0, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD); -+ -+ udelay(500); -+ -+ mtk_eth_fifo_init(priv); -+ -+ /* Start PHY */ -+ if (priv->sw == SW_NONE) { -+ ret = mtk_phy_start(priv); -+ if (ret) -+ return ret; -+ } -+ -+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0, -+ TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN); -+ udelay(500); -+ -+ return 0; -+} -+ -+static void mtk_eth_stop(struct udevice *dev) -+{ -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ -+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, -+ TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0); -+ udelay(500); -+ -+ wait_for_bit_le32(priv->fe_base + PDMA_BASE + PDMA_GLO_CFG_REG, -+ RX_DMA_BUSY | TX_DMA_BUSY, 0, 5000, 0); -+} -+ -+static int mtk_eth_write_hwaddr(struct udevice *dev) -+{ -+ struct eth_pdata *pdata = dev_get_platdata(dev); -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ unsigned char *mac = pdata->enetaddr; -+ u32 macaddr_lsb, macaddr_msb; -+ -+ macaddr_msb = ((u32)mac[0] << 8) | (u32)mac[1]; -+ macaddr_lsb = ((u32)mac[2] << 24) | ((u32)mac[3] << 16) | -+ ((u32)mac[4] << 8) | (u32)mac[5]; -+ -+ mtk_gdma_write(priv, priv->gmac_id, GDMA_MAC_MSB_REG, macaddr_msb); -+ mtk_gdma_write(priv, priv->gmac_id, GDMA_MAC_LSB_REG, macaddr_lsb); -+ -+ return 0; -+} -+ -+static int mtk_eth_send(struct udevice *dev, void *packet, int length) -+{ -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ u32 idx = priv->tx_cpu_owner_idx0; -+ void *pkt_base; -+ -+ if (!priv->tx_ring_noc[idx].txd_info2.DDONE) { -+ debug("mtk-eth: TX DMA descriptor ring is full\n"); -+ return -EPERM; -+ } -+ -+ pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0); -+ memcpy(pkt_base, packet, length); -+ flush_dcache_range((u32)pkt_base, (u32)pkt_base + -+ roundup(length, ARCH_DMA_MINALIGN)); -+ -+ priv->tx_ring_noc[idx].txd_info2.SDL0 = length; -+ priv->tx_ring_noc[idx].txd_info2.DDONE = 0; -+ -+ priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC; -+ mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0); -+ -+ return 0; -+} -+ -+static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp) -+{ -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ u32 idx = priv->rx_dma_owner_idx0; -+ uchar *pkt_base; -+ u32 length; -+ -+ if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) { -+ debug("mtk-eth: RX DMA descriptor ring is empty\n"); -+ return -EAGAIN; -+ } -+ -+ length = priv->rx_ring_noc[idx].rxd_info2.PLEN0; -+ pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0); -+ invalidate_dcache_range((u32)pkt_base, (u32)pkt_base + -+ roundup(length, ARCH_DMA_MINALIGN)); -+ -+ if (packetp) -+ *packetp = pkt_base; -+ -+ return length; -+} -+ -+static int mtk_eth_free_pkt(struct udevice *dev, uchar *packet, int length) -+{ -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ u32 idx = priv->rx_dma_owner_idx0; -+ -+ priv->rx_ring_noc[idx].rxd_info2.DDONE = 0; -+ priv->rx_ring_noc[idx].rxd_info2.LS0 = 0; -+ priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN; -+ -+ mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx); -+ priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC; -+ -+ return 0; -+} -+ -+static int mtk_eth_probe(struct udevice *dev) -+{ -+ struct eth_pdata *pdata = dev_get_platdata(dev); -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ u32 iobase = pdata->iobase; -+ int ret; -+ -+ /* Frame Engine Register Base */ -+ priv->fe_base = (void *)iobase; -+ -+ /* GMAC Register Base */ -+ priv->gmac_base = (void *)(iobase + GMAC_BASE); -+ -+ /* MDIO register */ -+ ret = mtk_mdio_register(dev); -+ if (ret) -+ return ret; -+ -+ /* Prepare for tx/rx rings */ -+ priv->tx_ring_noc = (struct pdma_txdesc *) -+ noncached_alloc(sizeof(struct pdma_txdesc) * NUM_TX_DESC, -+ ARCH_DMA_MINALIGN); -+ priv->rx_ring_noc = (struct pdma_rxdesc *) -+ noncached_alloc(sizeof(struct pdma_rxdesc) * NUM_RX_DESC, -+ ARCH_DMA_MINALIGN); -+ -+ /* Set MAC mode */ -+ mtk_mac_init(priv); -+ -+ /* Probe phy if switch is not specified */ -+ if (priv->sw == SW_NONE) -+ return mtk_phy_probe(dev); -+ -+ /* Initialize switch */ -+ return priv->switch_init(priv); -+} -+ -+static int mtk_eth_remove(struct udevice *dev) -+{ -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ -+ /* MDIO unregister */ -+ mdio_unregister(priv->mdio_bus); -+ mdio_free(priv->mdio_bus); -+ -+ /* Stop possibly started DMA */ -+ mtk_eth_stop(dev); -+ -+ return 0; -+} -+ -+static int mtk_eth_ofdata_to_platdata(struct udevice *dev) -+{ -+ struct eth_pdata *pdata = dev_get_platdata(dev); -+ struct mtk_eth_priv *priv = dev_get_priv(dev); -+ struct ofnode_phandle_args args; -+ struct regmap *regmap; -+ const char *str; -+ ofnode subnode; -+ int ret; -+ -+ priv->soc = dev_get_driver_data(dev); -+ -+ pdata->iobase = devfdt_get_addr(dev); -+ -+ /* get corresponding ethsys phandle */ -+ ret = dev_read_phandle_with_args(dev, "mediatek,ethsys", NULL, 0, 0, -+ &args); -+ if (ret) -+ return ret; -+ -+ regmap = syscon_node_to_regmap(args.node); -+ if (IS_ERR(regmap)) -+ return PTR_ERR(regmap); -+ -+ priv->ethsys_base = regmap_get_range(regmap, 0); -+ if (!priv->ethsys_base) { -+ dev_err(dev, "Unable to find ethsys\n"); -+ return -ENODEV; -+ } -+ -+ /* Reset controllers */ -+ ret = reset_get_by_name(dev, "fe", &priv->rst_fe); -+ if (ret) { -+ printf("error: Unable to get reset ctrl for frame engine\n"); -+ return ret; -+ } -+ -+ priv->gmac_id = dev_read_u32_default(dev, "mediatek,gmac-id", 0); -+ -+ /* Interface mode is required */ -+ str = dev_read_string(dev, "phy-mode"); -+ if (str) { -+ pdata->phy_interface = phy_get_interface_by_name(str); -+ priv->phy_interface = pdata->phy_interface; -+ } else { -+ printf("error: phy-mode is not set\n"); -+ return -EINVAL; -+ } -+ -+ /* Force mode or autoneg */ -+ subnode = ofnode_find_subnode(dev_ofnode(dev), "fixed-link"); -+ if (ofnode_valid(subnode)) { -+ priv->force_mode = 1; -+ priv->speed = ofnode_read_u32_default(subnode, "speed", 0); -+ priv->duplex = ofnode_read_bool(subnode, "full-duplex"); -+ -+ if (priv->speed != SPEED_10 && priv->speed != SPEED_100 && -+ priv->speed != SPEED_1000) { -+ printf("error: no valid speed set in fixed-link\n"); -+ return -EINVAL; -+ } -+ } -+ -+ /* check for switch first, otherwise phy will be used */ -+ priv->sw = SW_NONE; -+ priv->switch_init = NULL; -+ str = dev_read_string(dev, "mediatek,switch"); -+ -+ if (str) { -+ if (!strcmp(str, "mt7530")) { -+ priv->sw = SW_MT7530; -+ priv->switch_init = mt7530_setup; -+ priv->mt7530_smi_addr = MT7530_DFL_SMI_ADDR; -+ } else { -+ printf("error: unsupported switch\n"); -+ return -EINVAL; -+ } -+ -+ priv->mcm = dev_read_bool(dev, "mediatek,mcm"); -+ if (priv->mcm) { -+ ret = reset_get_by_name(dev, "mcm", &priv->rst_mcm); -+ if (ret) { -+ printf("error: no reset ctrl for mcm\n"); -+ return ret; -+ } -+ } else { -+ gpio_request_by_name(dev, "reset-gpios", 0, -+ &priv->rst_gpio, GPIOD_IS_OUT); -+ } -+ } else { -+ subnode = ofnode_find_subnode(dev_ofnode(dev), "phy-handle"); -+ if (!ofnode_valid(subnode)) { -+ printf("error: phy-handle is not specified\n"); -+ return ret; -+ } -+ -+ priv->phy_addr = ofnode_read_s32_default(subnode, "reg", -1); -+ if (priv->phy_addr < 0) { -+ printf("error: phy address is not specified\n"); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static const struct udevice_id mtk_eth_ids[] = { -+ { .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 }, -+ { .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 }, -+ {} -+}; -+ -+static const struct eth_ops mtk_eth_ops = { -+ .start = mtk_eth_start, -+ .stop = mtk_eth_stop, -+ .send = mtk_eth_send, -+ .recv = mtk_eth_recv, -+ .free_pkt = mtk_eth_free_pkt, -+ .write_hwaddr = mtk_eth_write_hwaddr, -+}; -+ -+U_BOOT_DRIVER(mtk_eth) = { -+ .name = "mtk-eth", -+ .id = UCLASS_ETH, -+ .of_match = mtk_eth_ids, -+ .ofdata_to_platdata = mtk_eth_ofdata_to_platdata, -+ .platdata_auto_alloc_size = sizeof(struct eth_pdata), -+ .probe = mtk_eth_probe, -+ .remove = mtk_eth_remove, -+ .ops = &mtk_eth_ops, -+ .priv_auto_alloc_size = sizeof(struct mtk_eth_priv), -+ .flags = DM_FLAG_ALLOC_PRIV_DMA, -+}; -diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h -new file mode 100644 -index 00000000..fe89a037 ---- /dev/null -+++ b/drivers/net/mtk_eth.h -@@ -0,0 +1,286 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018 MediaTek Inc. -+ * -+ * Author: Weijie Gao -+ * Author: Mark Lee -+ */ -+ -+#ifndef _MTK_ETH_H_ -+#define _MTK_ETH_H_ -+ -+/* Frame Engine Register Bases */ -+#define PDMA_BASE 0x0800 -+#define GDMA1_BASE 0x0500 -+#define GDMA2_BASE 0x1500 -+#define GMAC_BASE 0x10000 -+ -+/* Ethernet subsystem registers */ -+ -+#define ETHSYS_SYSCFG0_REG 0x14 -+#define SYSCFG0_GE_MODE_S(n) (12 + ((n) * 2)) -+#define SYSCFG0_GE_MODE_M 0x3 -+ -+#define ETHSYS_CLKCFG0_REG 0x2c -+#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11) -+ -+/* SYSCFG0_GE_MODE: GE Modes */ -+#define GE_MODE_RGMII 0 -+#define GE_MODE_MII 1 -+#define GE_MODE_MII_PHY 2 -+#define GE_MODE_RMII 3 -+ -+/* Frame Engine Registers */ -+ -+/* PDMA */ -+#define TX_BASE_PTR_REG(n) (0x000 + (n) * 0x10) -+#define TX_MAX_CNT_REG(n) (0x004 + (n) * 0x10) -+#define TX_CTX_IDX_REG(n) (0x008 + (n) * 0x10) -+#define TX_DTX_IDX_REG(n) (0x00c + (n) * 0x10) -+ -+#define RX_BASE_PTR_REG(n) (0x100 + (n) * 0x10) -+#define RX_MAX_CNT_REG(n) (0x104 + (n) * 0x10) -+#define RX_CRX_IDX_REG(n) (0x108 + (n) * 0x10) -+#define RX_DRX_IDX_REG(n) (0x10c + (n) * 0x10) -+ -+#define PDMA_GLO_CFG_REG 0x204 -+#define TX_WB_DDONE BIT(6) -+#define RX_DMA_BUSY BIT(3) -+#define RX_DMA_EN BIT(2) -+#define TX_DMA_BUSY BIT(1) -+#define TX_DMA_EN BIT(0) -+ -+#define PDMA_RST_IDX_REG 0x208 -+#define RST_DRX_IDX0 BIT(16) -+#define RST_DTX_IDX0 BIT(0) -+ -+/* GDMA */ -+#define GDMA_IG_CTRL_REG 0x000 -+#define GDM_ICS_EN BIT(22) -+#define GDM_TCS_EN BIT(21) -+#define GDM_UCS_EN BIT(20) -+#define STRP_CRC BIT(16) -+#define MYMAC_DP_S 12 -+#define MYMAC_DP_M 0xf000 -+#define BC_DP_S 8 -+#define BC_DP_M 0xf00 -+#define MC_DP_S 4 -+#define MC_DP_M 0xf0 -+#define UN_DP_S 0 -+#define UN_DP_M 0x0f -+ -+#define GDMA_MAC_LSB_REG 0x008 -+ -+#define GDMA_MAC_MSB_REG 0x00c -+ -+/* MYMAC_DP/BC_DP/MC_DP/UN_DP: Destination ports */ -+#define DP_PDMA 0 -+#define DP_GDMA1 1 -+#define DP_GDMA2 2 -+#define DP_PPE 4 -+#define DP_QDMA 5 -+#define DP_DISCARD 7 -+ -+/* GMAC Registers */ -+ -+#define GMAC_PIAC_REG 0x0004 -+#define PHY_ACS_ST BIT(31) -+#define MDIO_REG_ADDR_S 25 -+#define MDIO_REG_ADDR_M 0x3e000000 -+#define MDIO_PHY_ADDR_S 20 -+#define MDIO_PHY_ADDR_M 0x1f00000 -+#define MDIO_CMD_S 18 -+#define MDIO_CMD_M 0xc0000 -+#define MDIO_ST_S 16 -+#define MDIO_ST_M 0x30000 -+#define MDIO_RW_DATA_S 0 -+#define MDIO_RW_DATA_M 0xffff -+ -+/* MDIO_CMD: MDIO commands */ -+#define MDIO_CMD_ADDR 0 -+#define MDIO_CMD_WRITE 1 -+#define MDIO_CMD_READ 2 -+#define MDIO_CMD_READ_C45 3 -+ -+/* MDIO_ST: MDIO start field */ -+#define MDIO_ST_C45 0 -+#define MDIO_ST_C22 1 -+ -+#define GMAC_PORT_MCR(p) (0x0100 + (p) * 0x100) -+#define MAC_RX_PKT_LEN_S 24 -+#define MAC_RX_PKT_LEN_M 0x3000000 -+#define IPG_CFG_S 18 -+#define IPG_CFG_M 0xc0000 -+#define MAC_MODE BIT(16) -+#define FORCE_MODE BIT(15) -+#define MAC_TX_EN BIT(14) -+#define MAC_RX_EN BIT(13) -+#define BKOFF_EN BIT(9) -+#define BACKPR_EN BIT(8) -+#define FORCE_RX_FC BIT(5) -+#define FORCE_TX_FC BIT(4) -+#define FORCE_SPD_S 2 -+#define FORCE_SPD_M 0x0c -+#define FORCE_DPX BIT(1) -+#define FORCE_LINK BIT(0) -+ -+/* MAC_RX_PKT_LEN: Max RX packet length */ -+#define MAC_RX_PKT_LEN_1518 0 -+#define MAC_RX_PKT_LEN_1536 1 -+#define MAC_RX_PKT_LEN_1552 2 -+#define MAC_RX_PKT_LEN_JUMBO 3 -+ -+/* FORCE_SPD: Forced link speed */ -+#define SPEED_10M 0 -+#define SPEED_100M 1 -+#define SPEED_1000M 2 -+ -+#define GMAC_TRGMII_RCK_CTRL 0x300 -+#define RX_RST BIT(31) -+#define RXC_DQSISEL BIT(30) -+ -+#define GMAC_TRGMII_TD_ODT(n) (0x354 + (n) * 8) -+#define TD_DM_DRVN_S 4 -+#define TD_DM_DRVN_M 0xf0 -+#define TD_DM_DRVP_S 0 -+#define TD_DM_DRVP_M 0x0f -+ -+/* MT7530 Registers */ -+ -+#define PCR_REG(p) (0x2004 + (p) * 0x100) -+#define PORT_MATRIX_S 16 -+#define PORT_MATRIX_M 0xff0000 -+ -+#define PVC_REG(p) (0x2010 + (p) * 0x100) -+#define STAG_VPID_S 16 -+#define STAG_VPID_M 0xffff0000 -+#define VLAN_ATTR_S 6 -+#define VLAN_ATTR_M 0xc0 -+ -+/* VLAN_ATTR: VLAN attributes */ -+#define VLAN_ATTR_USER 0 -+#define VLAN_ATTR_STACK 1 -+#define VLAN_ATTR_TRANSLATION 2 -+#define VLAN_ATTR_TRANSPARENT 3 -+ -+#define PCMR_REG(p) (0x3000 + (p) * 0x100) -+/* XXX: all fields are defined under GMAC_PORT_MCR */ -+ -+#define SYS_CTRL_REG 0x7000 -+#define SW_PHY_RST BIT(2) -+#define SW_SYS_RST BIT(1) -+#define SW_REG_RST BIT(0) -+ -+#define NUM_TRGMII_CTRL 5 -+ -+#define HWTRAP_REG 0x7800 -+#define MHWTRAP_REG 0x7804 -+#define CHG_TRAP BIT(16) -+#define LOOPDET_DIS BIT(14) -+#define P5_INTF_SEL_S 13 -+#define P5_INTF_SEL_M 0x2000 -+#define SMI_ADDR_S 11 -+#define SMI_ADDR_M 0x1800 -+#define XTAL_FSEL_S 9 -+#define XTAL_FSEL_M 0x600 -+#define P6_INTF_DIS BIT(8) -+#define P5_INTF_MODE_S 7 -+#define P5_INTF_MODE_M 0x80 -+#define P5_INTF_DIS BIT(6) -+#define C_MDIO_BPS BIT(5) -+#define CHIP_MODE_S 0 -+#define CHIP_MODE_M 0x0f -+ -+/* P5_INTF_SEL: Interface type of Port5 */ -+#define P5_INTF_SEL_GPHY 0 -+#define P5_INTF_SEL_GMAC5 1 -+ -+/* P5_INTF_MODE: Interface mode of Port5 */ -+#define P5_INTF_MODE_GMII_MII 0 -+#define P5_INTF_MODE_RGMII 1 -+ -+#define MT7530_P6ECR 0x7830 -+#define P6_INTF_MODE_M 0x3 -+#define P6_INTF_MODE_S 0 -+ -+/* P6_INTF_MODE: Interface mode of Port6 */ -+#define P6_INTF_MODE_RGMII 0 -+#define P6_INTF_MODE_TRGMII 1 -+ -+#define MT7530_TRGMII_RD(n) (0x7a10 + (n) * 8) -+#define RD_TAP_S 0 -+#define RD_TAP_M 0x7f -+ -+#define MT7530_TRGMII_TD_ODT(n) (0x7a54 + (n) * 8) -+/* XXX: all fields are defined under GMAC_TRGMII_TD_ODT */ -+ -+/* MT7530 GPHY MDIO Indirect Access Registers */ -+ -+#define MII_MMD_ACC_CTL_REG 0x0d -+#define MMD_CMD_S 14 -+#define MMD_CMD_M 0xc000 -+#define MMD_DEVAD_S 0 -+#define MMD_DEVAD_M 0x1f -+ -+/* MMD_CMD: MMD commands */ -+#define MMD_ADDR 0 -+#define MMD_DATA 1 -+#define MMD_DATA_RW_POST_INC 2 -+#define MMD_DATA_W_POST_INC 3 -+ -+#define MII_MMD_ADDR_DATA_REG 0x0e -+ -+/* MT7530 GPHY MDIO MMD Registers */ -+ -+#define CORE_PLL_GROUP2 0x401 -+#define RG_SYSPLL_EN_NORMAL BIT(15) -+#define RG_SYSPLL_VODEN BIT(14) -+#define RG_SYSPLL_POSDIV_S 5 -+#define RG_SYSPLL_POSDIV_M 0x60 -+ -+#define CORE_PLL_GROUP4 0x403 -+#define RG_SYSPLL_DDSFBK_EN BIT(12) -+#define RG_SYSPLL_BIAS_EN BIT(11) -+#define RG_SYSPLL_BIAS_LPF_EN BIT(10) -+ -+#define CORE_PLL_GROUP5 0x404 -+#define RG_LCDDS_PCW_NCPO1_S 0 -+#define RG_LCDDS_PCW_NCPO1_M 0xffff -+ -+#define CORE_PLL_GROUP6 0x405 -+#define RG_LCDDS_PCW_NCPO0_S 0 -+#define RG_LCDDS_PCW_NCPO0_M 0xffff -+ -+#define CORE_PLL_GROUP7 0x406 -+#define RG_LCDDS_PWDB BIT(15) -+#define RG_LCDDS_ISO_EN BIT(13) -+#define RG_LCCDS_C_S 4 -+#define RG_LCCDS_C_M 0x70 -+#define RG_LCDDS_PCW_NCPO_CHG BIT(3) -+ -+#define CORE_PLL_GROUP10 0x409 -+#define RG_LCDDS_SSC_DELTA_S 0 -+#define RG_LCDDS_SSC_DELTA_M 0xfff -+ -+#define CORE_PLL_GROUP11 0x40a -+#define RG_LCDDS_SSC_DELTA1_S 0 -+#define RG_LCDDS_SSC_DELTA1_M 0xfff -+ -+#define CORE_GSWPLL_GRP1 0x40d -+#define RG_GSWPLL_POSDIV_200M_S 12 -+#define RG_GSWPLL_POSDIV_200M_M 0x3000 -+#define RG_GSWPLL_EN_PRE BIT(11) -+#define RG_GSWPLL_FBKDIV_200M_S 0 -+#define RG_GSWPLL_FBKDIV_200M_M 0xff -+ -+#define CORE_GSWPLL_GRP2 0x40e -+#define RG_GSWPLL_POSDIV_500M_S 8 -+#define RG_GSWPLL_POSDIV_500M_M 0x300 -+#define RG_GSWPLL_FBKDIV_500M_S 0 -+#define RG_GSWPLL_FBKDIV_500M_M 0xff -+ -+#define CORE_TRGMII_GSW_CLK_CG 0x410 -+#define REG_GSWCK_EN BIT(0) -+#define REG_TRGMIICK_EN BIT(1) -+ -+#endif /* _MTK_ETH_H_ */ --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0006-arm-dts-add-ethernet-related-node-for-MT7623-SoC.patch b/root/package/boot/uboot-mediatek/patches/0006-arm-dts-add-ethernet-related-node-for-MT7623-SoC.patch deleted file mode 100644 index 505af94e..00000000 --- a/root/package/boot/uboot-mediatek/patches/0006-arm-dts-add-ethernet-related-node-for-MT7623-SoC.patch +++ /dev/null @@ -1,76 +0,0 @@ -From fbdf1c37235d4a5a50eaafff41cacff4fd3a6e9f Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:54 +0800 -Subject: arm: dts: add ethernet related node for MT7623 SoC - -This patch adds ethernet gmac node for MT7623 with MT7530 gigabit switch. - -Signed-off-by: Mark Lee - -diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi -index f50f4ef1..448d1d73 100644 ---- a/arch/arm/dts/mt7623.dtsi -+++ b/arch/arm/dts/mt7623.dtsi -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include "skeleton.dtsi" - - / { -@@ -248,8 +249,26 @@ - }; - - ethsys: syscon@1b000000 { -- compatible = "mediatek,mt7623-ethsys"; -+ compatible = "mediatek,mt7623-ethsys", "syscon"; - reg = <0x1b000000 0x1000>; - #clock-cells = <1>; -+ #reset-cells = <1>; -+ }; -+ -+ eth: ethernet@1b100000 { -+ compatible = "mediatek,mt7623-eth", "syscon"; -+ reg = <0x1b100000 0x20000>; -+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>, -+ <ðsys CLK_ETHSYS_ESW>, -+ <ðsys CLK_ETHSYS_GP1>, -+ <ðsys CLK_ETHSYS_GP2>, -+ <&apmixedsys CLK_APMIXED_TRGPLL>; -+ clock-names = "ethif", "esw", "gp1", "gp2", "trgpll"; -+ power-domains = <&scpsys MT7623_POWER_DOMAIN_ETH>; -+ resets = <ðsys ETHSYS_FE_RST>, -+ <ðsys ETHSYS_MCM_RST>; -+ reset-names = "fe", "mcm"; -+ mediatek,ethsys = <ðsys>; -+ status = "disabled"; - }; - }; -diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts -index 84a77fde..51628bb6 100644 ---- a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts -@@ -67,6 +67,19 @@ - }; - }; - -+ð { -+ status = "okay"; -+ mediatek,gmac-id = <0>; -+ phy-mode = "rgmii"; -+ mediatek,switch = "mt7530"; -+ reset-gpios = <&gpio 33 GPIO_ACTIVE_HIGH>; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_default>; --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0007-arm-dts-add-ethernet-related-node-for-MT7629-SoC.patch b/root/package/boot/uboot-mediatek/patches/0007-arm-dts-add-ethernet-related-node-for-MT7629-SoC.patch deleted file mode 100644 index 7c314f50..00000000 --- a/root/package/boot/uboot-mediatek/patches/0007-arm-dts-add-ethernet-related-node-for-MT7629-SoC.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 038e3dc3801007f5025a2e57bb4b715c48b9590d Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:55 +0800 -Subject: arm: dts: add ethernet related node for MT7629 SoC - -This patch adds ethernet gmac node for MT7629 with internal gigabit phy. - -Signed-off-by: Mark Lee - -diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts -index a6d28a06..95d10aa6 100644 ---- a/arch/arm/dts/mt7629-rfb.dts -+++ b/arch/arm/dts/mt7629-rfb.dts -@@ -22,6 +22,17 @@ - }; - }; - -+ð { -+ status = "okay"; -+ mediatek,gmac-id = <1>; -+ phy-mode = "gmii"; -+ phy-handle = <&phy0>; -+ -+ phy0: ethernet-phy@0 { -+ reg = <0>; -+ }; -+}; -+ - &pinctrl { - qspi_pins: qspi-pins { - mux { -diff --git a/arch/arm/dts/mt7629.dtsi b/arch/arm/dts/mt7629.dtsi -index e6052bbd..c87115e0 100644 ---- a/arch/arm/dts/mt7629.dtsi -+++ b/arch/arm/dts/mt7629.dtsi -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include "skeleton.dtsi" - - / { -@@ -228,6 +229,48 @@ - compatible = "mediatek,mt7629-ethsys", "syscon"; - reg = <0x1b000000 0x1000>; - #clock-cells = <1>; -+ #reset-cells = <1>; -+ }; -+ -+ eth: ethernet@1b100000 { -+ compatible = "mediatek,mt7629-eth", "syscon"; -+ reg = <0x1b100000 0x20000>; -+ clocks = <&topckgen CLK_TOP_ETH_SEL>, -+ <&topckgen CLK_TOP_F10M_REF_SEL>, -+ <ðsys CLK_ETH_ESW_EN>, -+ <ðsys CLK_ETH_GP0_EN>, -+ <ðsys CLK_ETH_GP1_EN>, -+ <ðsys CLK_ETH_GP2_EN>, -+ <ðsys CLK_ETH_FE_EN>, -+ <&sgmiisys0 CLK_SGMII_TX_EN>, -+ <&sgmiisys0 CLK_SGMII_RX_EN>, -+ <&sgmiisys0 CLK_SGMII_CDR_REF>, -+ <&sgmiisys0 CLK_SGMII_CDR_FB>, -+ <&sgmiisys1 CLK_SGMII_TX_EN>, -+ <&sgmiisys1 CLK_SGMII_RX_EN>, -+ <&sgmiisys1 CLK_SGMII_CDR_REF>, -+ <&sgmiisys1 CLK_SGMII_CDR_FB>, -+ <&apmixedsys CLK_APMIXED_SGMIPLL>, -+ <&apmixedsys CLK_APMIXED_ETH2PLL>; -+ clock-names = "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", -+ "fe", "sgmii_tx250m", "sgmii_rx250m", -+ "sgmii_cdr_ref", "sgmii_cdr_fb", -+ "sgmii2_tx250m", "sgmii2_rx250m", -+ "sgmii2_cdr_ref", "sgmii2_cdr_fb", -+ "sgmii_ck", "eth2pll"; -+ assigned-clocks = <&topckgen CLK_TOP_ETH_SEL>, -+ <&topckgen CLK_TOP_F10M_REF_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>, -+ <&topckgen CLK_TOP_SGMIIPLL_D2>; -+ power-domains = <&scpsys MT7629_POWER_DOMAIN_ETHSYS>; -+ resets = <ðsys ETHSYS_FE_RST>; -+ reset-names = "fe"; -+ mediatek,ethsys = <ðsys>; -+ mediatek,sgmiisys = <&sgmiisys0>; -+ mediatek,infracfg = <&infracfg>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; - }; - - sgmiisys0: syscon@1b128000 { --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0008-arm-MediaTek-add-ethernet-support-for-MT7623-boards.patch b/root/package/boot/uboot-mediatek/patches/0008-arm-MediaTek-add-ethernet-support-for-MT7623-boards.patch deleted file mode 100644 index 1eabf49b..00000000 --- a/root/package/boot/uboot-mediatek/patches/0008-arm-MediaTek-add-ethernet-support-for-MT7623-boards.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 8da1e0fd083f4c6a71f6735c06698e71250bcc07 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:56 +0800 -Subject: arm: MediaTek: add ethernet support for MT7623 boards - -Enable ethernet related configs to mt7623n_bpir2_defconfig. -Add default IP addresses. -Enable noncached memory region required by ethernet driver. - -Signed-off-by: Mark Lee - -diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig -index 74252cd0..bb67f328 100644 ---- a/configs/mt7623n_bpir2_defconfig -+++ b/configs/mt7623n_bpir2_defconfig -@@ -29,6 +29,7 @@ CONFIG_CMD_FAT=y - CONFIG_CMD_FS_GENERIC=y - CONFIG_OF_EMBED=y - CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2" -+CONFIG_NET_RANDOM_ETHADDR=y - CONFIG_REGMAP=y - CONFIG_SYSCON=y - # CONFIG_BLOCK_CACHE is not set -@@ -38,6 +39,11 @@ CONFIG_DM_MMC=y - # CONFIG_MMC_QUIRKS is not set - CONFIG_MMC_HS400_SUPPORT=y - CONFIG_MMC_MTK=y -+CONFIG_DM_RESET=y -+CONFIG_RESET_MEDIATEK=y -+CONFIG_PHY_FIXED=y -+CONFIG_DM_ETH=y -+CONFIG_MEDIATEK_ETH=y - CONFIG_PINCTRL=y - CONFIG_PINCONF=y - CONFIG_PINCTRL_MT7623=y -diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h -index fb6ac073..7d26debb 100644 ---- a/include/configs/mt7623.h -+++ b/include/configs/mt7623.h -@@ -24,6 +24,7 @@ - - /* Size of malloc() pool */ - #define CONFIG_SYS_MALLOC_LEN SZ_4M -+#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M - - /* Environment */ - #define CONFIG_ENV_SIZE SZ_4K -@@ -56,4 +57,8 @@ - #define CONFIG_SYS_MMC_ENV_DEV 0 - #define CONFIG_ENV_OFFSET 0x100000 - -+/* Ethernet */ -+#define CONFIG_IPADDR 192.168.1.1 -+#define CONFIG_SERVERIP 192.168.1.2 -+ - #endif --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0009-arm-MediaTek-add-ethernet-support-for-MT7629-boards.patch b/root/package/boot/uboot-mediatek/patches/0009-arm-MediaTek-add-ethernet-support-for-MT7629-boards.patch deleted file mode 100644 index 1cc05c6c..00000000 --- a/root/package/boot/uboot-mediatek/patches/0009-arm-MediaTek-add-ethernet-support-for-MT7629-boards.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0fcb7ab842170e1ea7e9bf4d309af584b1e54388 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:57 +0800 -Subject: arm: MediaTek: add ethernet support for MT7629 boards - -Enable ethernet related configs to mt7629_rfb_defconfig. -Add default IP addresses. -Enable noncached memory region required by ethernet driver. - -Signed-off-by: Mark Lee - -diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig -index 1729d13c..fdd5f575 100644 ---- a/configs/mt7629_rfb_defconfig -+++ b/configs/mt7629_rfb_defconfig -@@ -32,6 +32,7 @@ CONFIG_CMD_PING=y - CONFIG_OF_EMBED=y - CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb" - CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents" -+CONFIG_NET_RANDOM_ETHADDR=y - CONFIG_SPL_DM_SEQ_ALIAS=y - CONFIG_REGMAP=y - CONFIG_SPL_REGMAP=y -@@ -51,6 +52,10 @@ CONFIG_SPI_FLASH_MACRONIX=y - CONFIG_SPI_FLASH_SPANSION=y - CONFIG_SPI_FLASH_STMICRO=y - CONFIG_SPI_FLASH_WINBOND=y -+CONFIG_DM_RESET=y -+CONFIG_RESET_MEDIATEK=y -+CONFIG_DM_ETH=y -+CONFIG_MEDIATEK_ETH=y - CONFIG_PINCTRL=y - CONFIG_PINCONF=y - CONFIG_PINCTRL_MT7629=y -diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h -index a665a5eb..9910d8c8 100644 ---- a/include/configs/mt7629.h -+++ b/include/configs/mt7629.h -@@ -24,6 +24,7 @@ - - /* Size of malloc() pool */ - #define CONFIG_SYS_MALLOC_LEN SZ_4M -+#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M - - /* Environment */ - #define CONFIG_ENV_SIZE SZ_4K -@@ -54,4 +55,8 @@ - /* DRAM */ - #define CONFIG_SYS_SDRAM_BASE 0x40000000 - -+/* Ethernet */ -+#define CONFIG_IPADDR 192.168.1.1 -+#define CONFIG_SERVERIP 192.168.1.2 -+ - #endif --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0010-MAINTAINERS-ARM-MEDIATEK-update-file-entries.patch b/root/package/boot/uboot-mediatek/patches/0010-MAINTAINERS-ARM-MEDIATEK-update-file-entries.patch deleted file mode 100644 index 101a4281..00000000 --- a/root/package/boot/uboot-mediatek/patches/0010-MAINTAINERS-ARM-MEDIATEK-update-file-entries.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 31ca82655b5f623303e45508a820205b071df258 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:58 +0800 -Subject: MAINTAINERS: ARM MEDIATEK: update file entries - -This patch adds new file entries for MediaTek SoCs - -Signed-off-by: Weijie Gao - -diff --git a/MAINTAINERS b/MAINTAINERS -index f86fdf9c..e192db07 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -176,6 +176,8 @@ F: drivers/ram/mediatek/ - F: drivers/spi/mtk_qspi.c - F: drivers/timer/mtk_timer.c - F: drivers/watchdog/mtk_wdt.c -+F: drivers/net/mtk_eth.c -+F: drivers/reset/reset-mediatek.c - F: tools/mtk_image.c - F: tools/mtk_image.h - N: mediatek --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0011-configs-MediaTek-use-OF_SEPARATE-instead-of-OF_EMBED.patch b/root/package/boot/uboot-mediatek/patches/0011-configs-MediaTek-use-OF_SEPARATE-instead-of-OF_EMBED.patch deleted file mode 100644 index 31fdc83d..00000000 --- a/root/package/boot/uboot-mediatek/patches/0011-configs-MediaTek-use-OF_SEPARATE-instead-of-OF_EMBED.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d4b93c443372d651bd6f8b78070c54338ee35b91 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Thu, 20 Dec 2018 16:12:59 +0800 -Subject: configs: MediaTek: use OF_SEPARATE instead of OF_EMBED - -This patch replace OF_EMBED with OF_SEPARATE of defconfig files of -MediaTek boards because now OF_EMBED is only used for debugging purpose. - -Signed-off-by: Weijie Gao -Reviewed-by: Simon Glass - -diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig -index bb67f328..a9f4506e 100644 ---- a/configs/mt7623n_bpir2_defconfig -+++ b/configs/mt7623n_bpir2_defconfig -@@ -27,7 +27,7 @@ CONFIG_CMD_READ=y - CONFIG_CMD_PING=y - CONFIG_CMD_FAT=y - CONFIG_CMD_FS_GENERIC=y --CONFIG_OF_EMBED=y -+CONFIG_OF_SEPARATE=y - CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2" - CONFIG_NET_RANDOM_ETHADDR=y - CONFIG_REGMAP=y -diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig -index fdd5f575..1da9932d 100644 ---- a/configs/mt7629_rfb_defconfig -+++ b/configs/mt7629_rfb_defconfig -@@ -29,7 +29,7 @@ CONFIG_CMD_SF_TEST=y - # CONFIG_CMD_NFS is not set - CONFIG_CMD_PING=y - # CONFIG_PARTITIONS is not set --CONFIG_OF_EMBED=y -+CONFIG_OF_SEPARATE=y - CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb" - CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents" - CONFIG_NET_RANDOM_ETHADDR=y --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0013-test-add-test-for-lib-lmb.c.patch b/root/package/boot/uboot-mediatek/patches/0013-test-add-test-for-lib-lmb.c.patch deleted file mode 100644 index 6e883e42..00000000 --- a/root/package/boot/uboot-mediatek/patches/0013-test-add-test-for-lib-lmb.c.patch +++ /dev/null @@ -1,326 +0,0 @@ -From d6755b9b0e59ea0193914e169f74df51d556fbb7 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:14 +0100 -Subject: test: add test for lib/lmb.c - -Add basic tests for the lmb memory allocation code used to reserve and -allocate memory during boot. - -Signed-off-by: Simon Goldschmidt -Reviewed-by: Simon Glass - -diff --git a/test/lib/Makefile b/test/lib/Makefile -index ea68fae5..5a636aac 100644 ---- a/test/lib/Makefile -+++ b/test/lib/Makefile -@@ -3,3 +3,4 @@ - # (C) Copyright 2018 - # Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc - obj-y += hexdump.o -+obj-y += lmb.o -diff --git a/test/lib/lmb.c b/test/lib/lmb.c -new file mode 100644 -index 00000000..dd7ba14b ---- /dev/null -+++ b/test/lib/lmb.c -@@ -0,0 +1,297 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * (C) Copyright 2018 Simon Goldschmidt -+ */ -+ -+#include -+#include -+#include -+#include -+ -+static int check_lmb(struct unit_test_state *uts, struct lmb *lmb, -+ phys_addr_t ram_base, phys_size_t ram_size, -+ unsigned long num_reserved, -+ phys_addr_t base1, phys_size_t size1, -+ phys_addr_t base2, phys_size_t size2, -+ phys_addr_t base3, phys_size_t size3) -+{ -+ ut_asserteq(lmb->memory.cnt, 1); -+ ut_asserteq(lmb->memory.region[0].base, ram_base); -+ ut_asserteq(lmb->memory.region[0].size, ram_size); -+ -+ ut_asserteq(lmb->reserved.cnt, num_reserved); -+ if (num_reserved > 0) { -+ ut_asserteq(lmb->reserved.region[0].base, base1); -+ ut_asserteq(lmb->reserved.region[0].size, size1); -+ } -+ if (num_reserved > 1) { -+ ut_asserteq(lmb->reserved.region[1].base, base2); -+ ut_asserteq(lmb->reserved.region[1].size, size2); -+ } -+ if (num_reserved > 2) { -+ ut_asserteq(lmb->reserved.region[2].base, base3); -+ ut_asserteq(lmb->reserved.region[2].size, size3); -+ } -+ return 0; -+} -+ -+#define ASSERT_LMB(lmb, ram_base, ram_size, num_reserved, base1, size1, \ -+ base2, size2, base3, size3) \ -+ ut_assert(!check_lmb(uts, lmb, ram_base, ram_size, \ -+ num_reserved, base1, size1, base2, size2, base3, \ -+ size3)) -+ -+/* -+ * Test helper function that reserves 64 KiB somewhere in the simulated RAM and -+ * then does some alloc + free tests. -+ */ -+static int test_multi_alloc(struct unit_test_state *uts, -+ const phys_addr_t ram, const phys_size_t ram_size, -+ const phys_addr_t alloc_64k_addr) -+{ -+ const phys_addr_t ram_end = ram + ram_size; -+ const phys_addr_t alloc_64k_end = alloc_64k_addr + 0x10000; -+ -+ struct lmb lmb; -+ long ret; -+ phys_addr_t a, a2, b, b2, c, d; -+ -+ /* check for overflow */ -+ ut_assert(ram_end == 0 || ram_end > ram); -+ ut_assert(alloc_64k_end > alloc_64k_addr); -+ /* check input addresses + size */ -+ ut_assert(alloc_64k_addr >= ram + 8); -+ ut_assert(alloc_64k_end <= ram_end - 8); -+ -+ lmb_init(&lmb); -+ -+ ret = lmb_add(&lmb, ram, ram_size); -+ ut_asserteq(ret, 0); -+ -+ /* reserve 64KiB somewhere */ -+ ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, -+ 0, 0, 0, 0); -+ -+ /* allocate somewhere, should be at the end of RAM */ -+ a = lmb_alloc(&lmb, 4, 1); -+ ut_asserteq(a, ram_end - 4); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, alloc_64k_addr, 0x10000, -+ ram_end - 4, 4, 0, 0); -+ /* alloc below end of reserved region -> below reserved region */ -+ b = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); -+ ut_asserteq(b, alloc_64k_addr - 4); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, -+ alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0); -+ -+ /* 2nd time */ -+ c = lmb_alloc(&lmb, 4, 1); -+ ut_asserteq(c, ram_end - 8); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, -+ alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0); -+ d = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); -+ ut_asserteq(d, alloc_64k_addr - 8); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, -+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); -+ -+ ret = lmb_free(&lmb, a, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, -+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); -+ /* allocate again to ensure we get the same address */ -+ a2 = lmb_alloc(&lmb, 4, 1); -+ ut_asserteq(a, a2); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, -+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); -+ ret = lmb_free(&lmb, a2, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, -+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); -+ -+ ret = lmb_free(&lmb, b, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 3, -+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, -+ ram_end - 8, 4); -+ /* allocate again to ensure we get the same address */ -+ b2 = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); -+ ut_asserteq(b, b2); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, -+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); -+ ret = lmb_free(&lmb, b2, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 3, -+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, -+ ram_end - 8, 4); -+ -+ ret = lmb_free(&lmb, c, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, -+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0); -+ ret = lmb_free(&lmb, d, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, -+ 0, 0, 0, 0); -+ -+ return 0; -+} -+ -+static int test_multi_alloc_512mb(struct unit_test_state *uts, -+ const phys_addr_t ram) -+{ -+ return test_multi_alloc(uts, ram, 0x20000000, ram + 0x10000000); -+} -+ -+/* Create a memory region with one reserved region and allocate */ -+static int lib_test_lmb_simple(struct unit_test_state *uts) -+{ -+ /* simulate 512 MiB RAM beginning at 1GiB */ -+ return test_multi_alloc_512mb(uts, 0x40000000); -+} -+ -+DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -+ -+/* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */ -+static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) -+{ -+ const phys_size_t ram_size = 0x20000000; -+ const phys_size_t big_block_size = 0x10000000; -+ const phys_addr_t ram_end = ram + ram_size; -+ const phys_addr_t alloc_64k_addr = ram + 0x10000000; -+ struct lmb lmb; -+ long ret; -+ phys_addr_t a, b; -+ -+ /* check for overflow */ -+ ut_assert(ram_end == 0 || ram_end > ram); -+ -+ lmb_init(&lmb); -+ -+ ret = lmb_add(&lmb, ram, ram_size); -+ ut_asserteq(ret, 0); -+ -+ /* reserve 64KiB in the middle of RAM */ -+ ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, -+ 0, 0, 0, 0); -+ -+ /* allocate a big block, should be below reserved */ -+ a = lmb_alloc(&lmb, big_block_size, 1); -+ ut_asserteq(a, ram); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, -+ big_block_size + 0x10000, 0, 0, 0, 0); -+ /* allocate 2nd big block */ -+ /* This should fail, printing an error */ -+ b = lmb_alloc(&lmb, big_block_size, 1); -+ ut_asserteq(b, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, -+ big_block_size + 0x10000, 0, 0, 0, 0); -+ -+ ret = lmb_free(&lmb, a, big_block_size); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, -+ 0, 0, 0, 0); -+ -+ /* allocate too big block */ -+ /* This should fail, printing an error */ -+ a = lmb_alloc(&lmb, ram_size, 1); -+ ut_asserteq(a, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, -+ 0, 0, 0, 0); -+ -+ return 0; -+} -+ -+static int lib_test_lmb_big(struct unit_test_state *uts) -+{ -+ return test_bigblock(uts, 0x40000000); -+} -+ -+DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -+ -+/* Simulate 512 MiB RAM, allocate a block without previous reservation */ -+static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram) -+{ -+ const phys_size_t ram_size = 0x20000000; -+ const phys_addr_t ram_end = ram + ram_size; -+ struct lmb lmb; -+ long ret; -+ phys_addr_t a, b; -+ -+ /* check for overflow */ -+ ut_assert(ram_end == 0 || ram_end > ram); -+ -+ lmb_init(&lmb); -+ -+ ret = lmb_add(&lmb, ram, ram_size); -+ ut_asserteq(ret, 0); -+ -+ /* allocate a block */ -+ a = lmb_alloc(&lmb, 4, 1); -+ ut_assert(a != 0); -+ /* and free it */ -+ ret = lmb_free(&lmb, a, 4); -+ ut_asserteq(ret, 0); -+ -+ /* allocate a block with base*/ -+ b = lmb_alloc_base(&lmb, 4, 1, ram_end); -+ ut_assert(a == b); -+ /* and free it */ -+ ret = lmb_free(&lmb, b, 4); -+ ut_asserteq(ret, 0); -+ -+ return 0; -+} -+ -+static int lib_test_lmb_noreserved(struct unit_test_state *uts) -+{ -+ return test_noreserved(uts, 0x40000000); -+} -+ -+DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -+ -+/* -+ * Simulate a RAM that starts at 0 and allocate down to address 0, which must -+ * fail as '0' means failure for the lmb_alloc functions. -+ */ -+static int lib_test_lmb_at_0(struct unit_test_state *uts) -+{ -+ const phys_addr_t ram = 0; -+ const phys_size_t ram_size = 0x20000000; -+ struct lmb lmb; -+ long ret; -+ phys_addr_t a, b; -+ -+ lmb_init(&lmb); -+ -+ ret = lmb_add(&lmb, ram, ram_size); -+ ut_asserteq(ret, 0); -+ -+ /* allocate nearly everything */ -+ a = lmb_alloc(&lmb, ram_size - 4, 1); -+ ut_asserteq(a, ram + 4); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, -+ 0, 0, 0, 0); -+ /* allocate the rest */ -+ /* This should fail as the allocated address would be 0 */ -+ b = lmb_alloc(&lmb, 4, 1); -+ ut_asserteq(b, 0); -+ /* check that this was an error by checking lmb */ -+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, -+ 0, 0, 0, 0); -+ /* check that this was an error by freeing b */ -+ ret = lmb_free(&lmb, b, 4); -+ ut_asserteq(ret, -1); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, -+ 0, 0, 0, 0); -+ -+ ret = lmb_free(&lmb, a, ram_size - 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); -+ -+ return 0; -+} -+ -+DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0014-lmb-fix-allocation-at-end-of-address-range.patch b/root/package/boot/uboot-mediatek/patches/0014-lmb-fix-allocation-at-end-of-address-range.patch deleted file mode 100644 index d62fb4b4..00000000 --- a/root/package/boot/uboot-mediatek/patches/0014-lmb-fix-allocation-at-end-of-address-range.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 8d8854693b9a288c6dbcf5382e74e6ce05839b33 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:15 +0100 -Subject: lmb: fix allocation at end of address range - -The lmb code fails if base + size of RAM overflows to zero. - -Fix this by calculating end as 'base + size - 1' instead of 'base + size' -where appropriate. - -Added tests to assert this is fixed. - -Signed-off-by: Simon Goldschmidt - -diff --git a/lib/lmb.c b/lib/lmb.c -index 17054173..6d3dcf4e 100644 ---- a/lib/lmb.c -+++ b/lib/lmb.c -@@ -43,7 +43,10 @@ void lmb_dump_all(struct lmb *lmb) - static long lmb_addrs_overlap(phys_addr_t base1, - phys_size_t size1, phys_addr_t base2, phys_size_t size2) - { -- return ((base1 < (base2+size2)) && (base2 < (base1+size1))); -+ const phys_addr_t base1_end = base1 + size1 - 1; -+ const phys_addr_t base2_end = base2 + size2 - 1; -+ -+ return ((base1 <= base2_end) && (base2 <= base1_end)); - } - - static long lmb_addrs_adjacent(phys_addr_t base1, phys_size_t size1, -@@ -89,18 +92,9 @@ static void lmb_coalesce_regions(struct lmb_region *rgn, - - void lmb_init(struct lmb *lmb) - { -- /* Create a dummy zero size LMB which will get coalesced away later. -- * This simplifies the lmb_add() code below... -- */ -- lmb->memory.region[0].base = 0; -- lmb->memory.region[0].size = 0; -- lmb->memory.cnt = 1; -+ lmb->memory.cnt = 0; - lmb->memory.size = 0; -- -- /* Ditto. */ -- lmb->reserved.region[0].base = 0; -- lmb->reserved.region[0].size = 0; -- lmb->reserved.cnt = 1; -+ lmb->reserved.cnt = 0; - lmb->reserved.size = 0; - } - -@@ -110,9 +104,10 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t - unsigned long coalesced = 0; - long adjacent, i; - -- if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) { -+ if (rgn->cnt == 0) { - rgn->region[0].base = base; - rgn->region[0].size = size; -+ rgn->cnt = 1; - return 0; - } - -@@ -183,7 +178,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) - { - struct lmb_region *rgn = &(lmb->reserved); - phys_addr_t rgnbegin, rgnend; -- phys_addr_t end = base + size; -+ phys_addr_t end = base + size - 1; - int i; - - rgnbegin = rgnend = 0; /* supress gcc warnings */ -@@ -191,7 +186,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) - /* Find the region where (base, size) belongs to */ - for (i=0; i < rgn->cnt; i++) { - rgnbegin = rgn->region[i].base; -- rgnend = rgnbegin + rgn->region[i].size; -+ rgnend = rgnbegin + rgn->region[i].size - 1; - - if ((rgnbegin <= base) && (end <= rgnend)) - break; -@@ -209,7 +204,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) - - /* Check to see if region is matching at the front */ - if (rgnbegin == base) { -- rgn->region[i].base = end; -+ rgn->region[i].base = end + 1; - rgn->region[i].size -= size; - return 0; - } -@@ -225,7 +220,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) - * beginging of the hole and add the region after hole. - */ - rgn->region[i].size = base - rgn->region[i].base; -- return lmb_add_region(rgn, end, rgnend - end); -+ return lmb_add_region(rgn, end + 1, rgnend - end); - } - - long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size) -diff --git a/test/lib/lmb.c b/test/lib/lmb.c -index dd7ba14b..fb7ca45e 100644 ---- a/test/lib/lmb.c -+++ b/test/lib/lmb.c -@@ -146,8 +146,15 @@ static int test_multi_alloc_512mb(struct unit_test_state *uts, - /* Create a memory region with one reserved region and allocate */ - static int lib_test_lmb_simple(struct unit_test_state *uts) - { -+ int ret; -+ - /* simulate 512 MiB RAM beginning at 1GiB */ -- return test_multi_alloc_512mb(uts, 0x40000000); -+ ret = test_multi_alloc_512mb(uts, 0x40000000); -+ if (ret) -+ return ret; -+ -+ /* simulate 512 MiB RAM beginning at 1.5GiB */ -+ return test_multi_alloc_512mb(uts, 0xE0000000); - } - - DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -@@ -206,7 +213,15 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) - - static int lib_test_lmb_big(struct unit_test_state *uts) - { -- return test_bigblock(uts, 0x40000000); -+ int ret; -+ -+ /* simulate 512 MiB RAM beginning at 1GiB */ -+ ret = test_bigblock(uts, 0x40000000); -+ if (ret) -+ return ret; -+ -+ /* simulate 512 MiB RAM beginning at 1.5GiB */ -+ return test_bigblock(uts, 0xE0000000); - } - - DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -@@ -247,7 +262,15 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram) - - static int lib_test_lmb_noreserved(struct unit_test_state *uts) - { -- return test_noreserved(uts, 0x40000000); -+ int ret; -+ -+ /* simulate 512 MiB RAM beginning at 1GiB */ -+ ret = test_noreserved(uts, 0x40000000); -+ if (ret) -+ return ret; -+ -+ /* simulate 512 MiB RAM beginning at 1.5GiB */ -+ return test_noreserved(uts, 0xE0000000); - } - - DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0015-lib-lmb-reserving-overlapping-regions-should-fail.patch b/root/package/boot/uboot-mediatek/patches/0015-lib-lmb-reserving-overlapping-regions-should-fail.patch deleted file mode 100644 index 61a6c6c0..00000000 --- a/root/package/boot/uboot-mediatek/patches/0015-lib-lmb-reserving-overlapping-regions-should-fail.patch +++ /dev/null @@ -1,208 +0,0 @@ -From 0b66765ffcdc995177753b7e6607be477593041e Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:16 +0100 -Subject: lib: lmb: reserving overlapping regions should fail - -lmb_add_region handles overlapping regions wrong: instead of merging -or rejecting to add a new reserved region that overlaps an existing -one, it just adds the new region. - -Since internally the same function is used for lmb_alloc, change -lmb_add_region to reject overlapping regions. - -Also, to keep reserved memory correct after 'free', reserved entries -created by allocating memory must not set their size to a multiple -of alignment but to the original size. This ensures the reserved -region is completely removed when the caller calls 'lmb_free', as -this one takes the same size as passed to 'lmb_alloc' etc. - -Add test to assert this. - -Signed-off-by: Simon Goldschmidt - -diff --git a/lib/lmb.c b/lib/lmb.c -index 6d3dcf4e..cd297f82 100644 ---- a/lib/lmb.c -+++ b/lib/lmb.c -@@ -131,6 +131,9 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t - rgn->region[i].size += size; - coalesced++; - break; -+ } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { -+ /* regions overlap */ -+ return -1; - } - } - -@@ -269,11 +272,6 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) - return addr & ~(size - 1); - } - --static phys_addr_t lmb_align_up(phys_addr_t addr, ulong size) --{ -- return (addr + (size - 1)) & ~(size - 1); --} -- - phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) - { - long i, j; -@@ -302,8 +300,7 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy - if (j < 0) { - /* This area isn't reserved, take it */ - if (lmb_add_region(&lmb->reserved, base, -- lmb_align_up(size, -- align)) < 0) -+ size) < 0) - return 0; - return base; - } -diff --git a/test/lib/lmb.c b/test/lib/lmb.c -index fb7ca45e..e6acb70e 100644 ---- a/test/lib/lmb.c -+++ b/test/lib/lmb.c -@@ -227,13 +227,16 @@ static int lib_test_lmb_big(struct unit_test_state *uts) - DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); - - /* Simulate 512 MiB RAM, allocate a block without previous reservation */ --static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram) -+static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, -+ const phys_addr_t alloc_size, const ulong align) - { - const phys_size_t ram_size = 0x20000000; - const phys_addr_t ram_end = ram + ram_size; - struct lmb lmb; - long ret; - phys_addr_t a, b; -+ const phys_addr_t alloc_size_aligned = (alloc_size + align - 1) & -+ ~(align - 1); - - /* check for overflow */ - ut_assert(ram_end == 0 || ram_end > ram); -@@ -242,20 +245,43 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram) - - ret = lmb_add(&lmb, ram, ram_size); - ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); - - /* allocate a block */ -- a = lmb_alloc(&lmb, 4, 1); -+ a = lmb_alloc(&lmb, alloc_size, align); - ut_assert(a != 0); -- /* and free it */ -- ret = lmb_free(&lmb, a, 4); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, -+ alloc_size, 0, 0, 0, 0); -+ /* allocate another block */ -+ b = lmb_alloc(&lmb, alloc_size, align); -+ ut_assert(b != 0); -+ if (alloc_size == alloc_size_aligned) { -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - -+ (alloc_size_aligned * 2), alloc_size * 2, 0, 0, 0, -+ 0); -+ } else { -+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram + ram_size - -+ (alloc_size_aligned * 2), alloc_size, ram + ram_size -+ - alloc_size_aligned, alloc_size, 0, 0); -+ } -+ /* and free them */ -+ ret = lmb_free(&lmb, b, alloc_size); - ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, -+ alloc_size, 0, 0, 0, 0); -+ ret = lmb_free(&lmb, a, alloc_size); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); - - /* allocate a block with base*/ -- b = lmb_alloc_base(&lmb, 4, 1, ram_end); -+ b = lmb_alloc_base(&lmb, alloc_size, align, ram_end); - ut_assert(a == b); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, -+ alloc_size, 0, 0, 0, 0); - /* and free it */ -- ret = lmb_free(&lmb, b, 4); -+ ret = lmb_free(&lmb, b, alloc_size); - ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); - - return 0; - } -@@ -265,16 +291,30 @@ static int lib_test_lmb_noreserved(struct unit_test_state *uts) - int ret; - - /* simulate 512 MiB RAM beginning at 1GiB */ -- ret = test_noreserved(uts, 0x40000000); -+ ret = test_noreserved(uts, 0x40000000, 4, 1); - if (ret) - return ret; - - /* simulate 512 MiB RAM beginning at 1.5GiB */ -- return test_noreserved(uts, 0xE0000000); -+ return test_noreserved(uts, 0xE0000000, 4, 1); - } - - DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); - -+static int lib_test_lmb_unaligned_size(struct unit_test_state *uts) -+{ -+ int ret; -+ -+ /* simulate 512 MiB RAM beginning at 1GiB */ -+ ret = test_noreserved(uts, 0x40000000, 5, 8); -+ if (ret) -+ return ret; -+ -+ /* simulate 512 MiB RAM beginning at 1.5GiB */ -+ return test_noreserved(uts, 0xE0000000, 5, 8); -+} -+ -+DM_TEST(lib_test_lmb_unaligned_size, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); - /* - * Simulate a RAM that starts at 0 and allocate down to address 0, which must - * fail as '0' means failure for the lmb_alloc functions. -@@ -318,3 +358,42 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) - } - - DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -+ -+/* Check that calling lmb_reserve with overlapping regions fails. */ -+static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) -+{ -+ const phys_addr_t ram = 0x40000000; -+ const phys_size_t ram_size = 0x20000000; -+ struct lmb lmb; -+ long ret; -+ -+ lmb_init(&lmb); -+ -+ ret = lmb_add(&lmb, ram, ram_size); -+ ut_asserteq(ret, 0); -+ -+ ret = lmb_reserve(&lmb, 0x40010000, 0x10000); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, -+ 0, 0, 0, 0); -+ /* allocate overlapping region should fail */ -+ ret = lmb_reserve(&lmb, 0x40011000, 0x10000); -+ ut_asserteq(ret, -1); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, -+ 0, 0, 0, 0); -+ /* allocate 3nd region */ -+ ret = lmb_reserve(&lmb, 0x40030000, 0x10000); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000, -+ 0x40030000, 0x10000, 0, 0); -+ /* allocate 2nd region */ -+ ret = lmb_reserve(&lmb, 0x40020000, 0x10000); -+ ut_assert(ret >= 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x30000, -+ 0, 0, 0, 0); -+ -+ return 0; -+} -+ -+DM_TEST(lib_test_lmb_overlapping_reserve, -+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0016-fdt-parse-reserved-memory-for-memory-reservation.patch b/root/package/boot/uboot-mediatek/patches/0016-fdt-parse-reserved-memory-for-memory-reservation.patch deleted file mode 100644 index 10593967..00000000 --- a/root/package/boot/uboot-mediatek/patches/0016-fdt-parse-reserved-memory-for-memory-reservation.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 83dc6df2cff9e91e77890107c74d4858182e4b61 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:17 +0100 -Subject: fdt: parse "reserved-memory" for memory reservation - -boot_fdt_add_mem_rsv_regions() adds reserved memory sections to an lmb -struct. Currently, it only parses regions described by /memreserve/ -entries. - -Extend this to the more commonly used scheme of the "reserved-memory" -node. - -Signed-off-by: Simon Goldschmidt -Reviewed-by: Simon Glass - -diff --git a/common/image-fdt.c b/common/image-fdt.c -index 95748f0a..5c0d6db3 100644 ---- a/common/image-fdt.c -+++ b/common/image-fdt.c -@@ -10,6 +10,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -67,30 +68,66 @@ static const image_header_t *image_get_fdt(ulong fdt_addr) - } - #endif - -+static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr, -+ uint64_t size) -+{ -+ int ret; -+ -+ ret = lmb_reserve(lmb, addr, size); -+ if (!ret) { -+ debug(" reserving fdt memory region: addr=%llx size=%llx\n", -+ (unsigned long long)addr, (unsigned long long)size); -+ } else { -+ puts("ERROR: reserving fdt memory region failed "); -+ printf("(addr=%llx size=%llx)\n", -+ (unsigned long long)addr, (unsigned long long)size); -+ } -+} -+ - /** -- * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable -+ * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory -+ * sections as unusable - * @lmb: pointer to lmb handle, will be used for memory mgmt - * @fdt_blob: pointer to fdt blob base address - * -- * Adds the memreserve regions in the dtb to the lmb block. Adding the -- * memreserve regions prevents u-boot from using them to store the initrd -- * or the fdt blob. -+ * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block. -+ * Adding the memreserve regions prevents u-boot from using them to store the -+ * initrd or the fdt blob. - */ - void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) - { - uint64_t addr, size; -- int i, total; -+ int i, total, ret; -+ int nodeoffset, subnode; -+ struct fdt_resource res; - - if (fdt_check_header(fdt_blob) != 0) - return; - -+ /* process memreserve sections */ - total = fdt_num_mem_rsv(fdt_blob); - for (i = 0; i < total; i++) { - if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) - continue; -- printf(" reserving fdt memory region: addr=%llx size=%llx\n", -- (unsigned long long)addr, (unsigned long long)size); -- lmb_reserve(lmb, addr, size); -+ boot_fdt_reserve_region(lmb, addr, size); -+ } -+ -+ /* process reserved-memory */ -+ nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory"); -+ if (nodeoffset >= 0) { -+ subnode = fdt_first_subnode(fdt_blob, nodeoffset); -+ while (subnode >= 0) { -+ /* check if this subnode has a reg property */ -+ ret = fdt_get_resource(fdt_blob, subnode, "reg", 0, -+ &res); -+ if (!ret) { -+ addr = res.start; -+ size = res.end - res.start + 1; -+ boot_fdt_reserve_region(lmb, addr, size); -+ } -+ -+ subnode = fdt_next_subnode(fdt_blob, subnode); -+ } - } - } - -diff --git a/lib/Makefile b/lib/Makefile -index a6dd928a..358789ff 100644 ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -30,6 +30,7 @@ obj-y += crc7.o - obj-y += crc8.o - obj-y += crc16.o - obj-$(CONFIG_ERRNO_STR) += errno_str.o -+obj-$(CONFIG_OF_LIBFDT) += fdtdec.o - obj-$(CONFIG_FIT) += fdtdec_common.o - obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o - obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0017-lib-lmb-extend-lmb-for-checks-at-load-time.patch b/root/package/boot/uboot-mediatek/patches/0017-lib-lmb-extend-lmb-for-checks-at-load-time.patch deleted file mode 100644 index ac9ac256..00000000 --- a/root/package/boot/uboot-mediatek/patches/0017-lib-lmb-extend-lmb-for-checks-at-load-time.patch +++ /dev/null @@ -1,312 +0,0 @@ -From 16448a9becefd10a64601a08bbcacea38075db70 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:18 +0100 -Subject: lib: lmb: extend lmb for checks at load time - -This adds two new functions, lmb_alloc_addr and -lmb_get_unreserved_size. - -lmb_alloc_addr behaves like lmb_alloc, but it tries to allocate a -pre-specified address range. Unlike lmb_reserve, this address range -must be inside one of the memory ranges that has been set up with -lmb_add. - -lmb_get_unreserved_size returns the number of bytes that can be -used up to the next reserved region or the end of valid ram. This -can be 0 if the address passed is reserved. - -Added test for these new functions. - -Signed-off-by: Simon Goldschmidt - -diff --git a/include/lmb.h b/include/lmb.h -index f04d0580..7d7e2a78 100644 ---- a/include/lmb.h -+++ b/include/lmb.h -@@ -38,6 +38,9 @@ extern phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align - phys_addr_t max_addr); - extern phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, - phys_addr_t max_addr); -+extern phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, -+ phys_size_t size); -+extern phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr); - extern int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr); - extern long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size); - -diff --git a/lib/lmb.c b/lib/lmb.c -index cd297f82..e380a0a7 100644 ---- a/lib/lmb.c -+++ b/lib/lmb.c -@@ -313,6 +313,59 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy - return 0; - } - -+/* -+ * Try to allocate a specific address range: must be in defined memory but not -+ * reserved -+ */ -+phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size) -+{ -+ long j; -+ -+ /* Check if the requested address is in one of the memory regions */ -+ j = lmb_overlaps_region(&lmb->memory, base, size); -+ if (j >= 0) { -+ /* -+ * Check if the requested end address is in the same memory -+ * region we found. -+ */ -+ if (lmb_addrs_overlap(lmb->memory.region[j].base, -+ lmb->memory.region[j].size, base + size - -+ 1, 1)) { -+ /* ok, reserve the memory */ -+ if (lmb_reserve(lmb, base, size) >= 0) -+ return base; -+ } -+ } -+ return 0; -+} -+ -+/* Return number of bytes from a given address that are free */ -+phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr) -+{ -+ int i; -+ long j; -+ -+ /* check if the requested address is in the memory regions */ -+ j = lmb_overlaps_region(&lmb->memory, addr, 1); -+ if (j >= 0) { -+ for (i = 0; i < lmb->reserved.cnt; i++) { -+ if (addr < lmb->reserved.region[i].base) { -+ /* first reserved range > requested address */ -+ return lmb->reserved.region[i].base - addr; -+ } -+ if (lmb->reserved.region[i].base + -+ lmb->reserved.region[i].size > addr) { -+ /* requested addr is in this reserved range */ -+ return 0; -+ } -+ } -+ /* if we come here: no reserved ranges above requested addr */ -+ return lmb->memory.region[lmb->memory.cnt - 1].base + -+ lmb->memory.region[lmb->memory.cnt - 1].size - addr; -+ } -+ return 0; -+} -+ - int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) - { - int i; -diff --git a/test/lib/lmb.c b/test/lib/lmb.c -index e6acb70e..058d3c33 100644 ---- a/test/lib/lmb.c -+++ b/test/lib/lmb.c -@@ -397,3 +397,205 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) - - DM_TEST(lib_test_lmb_overlapping_reserve, - DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -+ -+/* -+ * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between. -+ * Expect addresses outside the memory range to fail. -+ */ -+static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) -+{ -+ const phys_size_t ram_size = 0x20000000; -+ const phys_addr_t ram_end = ram + ram_size; -+ const phys_size_t alloc_addr_a = ram + 0x8000000; -+ const phys_size_t alloc_addr_b = ram + 0x8000000 * 2; -+ const phys_size_t alloc_addr_c = ram + 0x8000000 * 3; -+ struct lmb lmb; -+ long ret; -+ phys_addr_t a, b, c, d, e; -+ -+ /* check for overflow */ -+ ut_assert(ram_end == 0 || ram_end > ram); -+ -+ lmb_init(&lmb); -+ -+ ret = lmb_add(&lmb, ram, ram_size); -+ ut_asserteq(ret, 0); -+ -+ /* reserve 3 blocks */ -+ ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000); -+ ut_asserteq(ret, 0); -+ ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000); -+ ut_asserteq(ret, 0); -+ ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000, -+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); -+ -+ /* allocate blocks */ -+ a = lmb_alloc_addr(&lmb, ram, alloc_addr_a - ram); -+ ut_asserteq(a, ram); -+ ASSERT_LMB(&lmb, ram, ram_size, 3, ram, 0x8010000, -+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); -+ b = lmb_alloc_addr(&lmb, alloc_addr_a + 0x10000, -+ alloc_addr_b - alloc_addr_a - 0x10000); -+ ut_asserteq(b, alloc_addr_a + 0x10000); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x10010000, -+ alloc_addr_c, 0x10000, 0, 0); -+ c = lmb_alloc_addr(&lmb, alloc_addr_b + 0x10000, -+ alloc_addr_c - alloc_addr_b - 0x10000); -+ ut_asserteq(c, alloc_addr_b + 0x10000); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, -+ 0, 0, 0, 0); -+ d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, -+ ram_end - alloc_addr_c - 0x10000); -+ ut_asserteq(d, alloc_addr_c + 0x10000); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size, -+ 0, 0, 0, 0); -+ -+ /* allocating anything else should fail */ -+ e = lmb_alloc(&lmb, 1, 1); -+ ut_asserteq(e, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size, -+ 0, 0, 0, 0); -+ -+ ret = lmb_free(&lmb, d, ram_end - alloc_addr_c - 0x10000); -+ ut_asserteq(ret, 0); -+ -+ /* allocate at 3 points in free range */ -+ -+ d = lmb_alloc_addr(&lmb, ram_end - 4, 4); -+ ut_asserteq(d, ram_end - 4); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000, -+ d, 4, 0, 0); -+ ret = lmb_free(&lmb, d, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, -+ 0, 0, 0, 0); -+ -+ d = lmb_alloc_addr(&lmb, ram_end - 128, 4); -+ ut_asserteq(d, ram_end - 128); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000, -+ d, 4, 0, 0); -+ ret = lmb_free(&lmb, d, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, -+ 0, 0, 0, 0); -+ -+ d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, 4); -+ ut_asserteq(d, alloc_addr_c + 0x10000); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010004, -+ 0, 0, 0, 0); -+ ret = lmb_free(&lmb, d, 4); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, -+ 0, 0, 0, 0); -+ -+ /* allocate at the bottom */ -+ ret = lmb_free(&lmb, a, alloc_addr_a - ram); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + 0x8000000, 0x10010000, -+ 0, 0, 0, 0); -+ d = lmb_alloc_addr(&lmb, ram, 4); -+ ut_asserteq(d, ram); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, d, 4, -+ ram + 0x8000000, 0x10010000, 0, 0); -+ -+ /* check that allocating outside memory fails */ -+ if (ram_end != 0) { -+ ret = lmb_alloc_addr(&lmb, ram_end, 1); -+ ut_asserteq(ret, 0); -+ } -+ if (ram != 0) { -+ ret = lmb_alloc_addr(&lmb, ram - 1, 1); -+ ut_asserteq(ret, 0); -+ } -+ -+ return 0; -+} -+ -+static int lib_test_lmb_alloc_addr(struct unit_test_state *uts) -+{ -+ int ret; -+ -+ /* simulate 512 MiB RAM beginning at 1GiB */ -+ ret = test_alloc_addr(uts, 0x40000000); -+ if (ret) -+ return ret; -+ -+ /* simulate 512 MiB RAM beginning at 1.5GiB */ -+ return test_alloc_addr(uts, 0xE0000000); -+} -+ -+DM_TEST(lib_test_lmb_alloc_addr, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -+ -+/* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */ -+static int test_get_unreserved_size(struct unit_test_state *uts, -+ const phys_addr_t ram) -+{ -+ const phys_size_t ram_size = 0x20000000; -+ const phys_addr_t ram_end = ram + ram_size; -+ const phys_size_t alloc_addr_a = ram + 0x8000000; -+ const phys_size_t alloc_addr_b = ram + 0x8000000 * 2; -+ const phys_size_t alloc_addr_c = ram + 0x8000000 * 3; -+ struct lmb lmb; -+ long ret; -+ phys_size_t s; -+ -+ /* check for overflow */ -+ ut_assert(ram_end == 0 || ram_end > ram); -+ -+ lmb_init(&lmb); -+ -+ ret = lmb_add(&lmb, ram, ram_size); -+ ut_asserteq(ret, 0); -+ -+ /* reserve 3 blocks */ -+ ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000); -+ ut_asserteq(ret, 0); -+ ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000); -+ ut_asserteq(ret, 0); -+ ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000, -+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); -+ -+ /* check addresses in between blocks */ -+ s = lmb_get_unreserved_size(&lmb, ram); -+ ut_asserteq(s, alloc_addr_a - ram); -+ s = lmb_get_unreserved_size(&lmb, ram + 0x10000); -+ ut_asserteq(s, alloc_addr_a - ram - 0x10000); -+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a - 4); -+ ut_asserteq(s, 4); -+ -+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x10000); -+ ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x10000); -+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x20000); -+ ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x20000); -+ s = lmb_get_unreserved_size(&lmb, alloc_addr_b - 4); -+ ut_asserteq(s, 4); -+ -+ s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x10000); -+ ut_asserteq(s, ram_end - alloc_addr_c - 0x10000); -+ s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x20000); -+ ut_asserteq(s, ram_end - alloc_addr_c - 0x20000); -+ s = lmb_get_unreserved_size(&lmb, ram_end - 4); -+ ut_asserteq(s, 4); -+ -+ return 0; -+} -+ -+static int lib_test_lmb_get_unreserved_size(struct unit_test_state *uts) -+{ -+ int ret; -+ -+ /* simulate 512 MiB RAM beginning at 1GiB */ -+ ret = test_get_unreserved_size(uts, 0x40000000); -+ if (ret) -+ return ret; -+ -+ /* simulate 512 MiB RAM beginning at 1.5GiB */ -+ return test_get_unreserved_size(uts, 0xE0000000); -+} -+ -+DM_TEST(lib_test_lmb_get_unreserved_size, -+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0018-fs-prevent-overwriting-reserved-memory.patch b/root/package/boot/uboot-mediatek/patches/0018-fs-prevent-overwriting-reserved-memory.patch deleted file mode 100644 index c9df9302..00000000 --- a/root/package/boot/uboot-mediatek/patches/0018-fs-prevent-overwriting-reserved-memory.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 94e5a755db2a72b8bdaceb634b732ed59816b5ac Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:19 +0100 -Subject: fs: prevent overwriting reserved memory - -This fixes CVE-2018-18440 ("insufficient boundary checks in filesystem -image load") by using lmb to check the load size of a file against -reserved memory addresses. - -Signed-off-by: Simon Goldschmidt -Reviewed-by: Simon Glass - -diff --git a/fs/fs.c b/fs/fs.c -index cb265174..7fd22101 100644 ---- a/fs/fs.c -+++ b/fs/fs.c -@@ -429,13 +429,57 @@ int fs_size(const char *filename, loff_t *size) - return ret; - } - --int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, -- loff_t *actread) -+#ifdef CONFIG_LMB -+/* Check if a file may be read to the given address */ -+static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, -+ loff_t len, struct fstype_info *info) -+{ -+ struct lmb lmb; -+ int ret; -+ loff_t size; -+ loff_t read_len; -+ -+ /* get the actual size of the file */ -+ ret = info->size(filename, &size); -+ if (ret) -+ return ret; -+ if (offset >= size) { -+ /* offset >= EOF, no bytes will be written */ -+ return 0; -+ } -+ read_len = size - offset; -+ -+ /* limit to 'len' if it is smaller */ -+ if (len && len < read_len) -+ read_len = len; -+ -+ lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start, -+ gd->bd->bi_dram[0].size, (void *)gd->fdt_blob); -+ lmb_dump_all(&lmb); -+ -+ if (lmb_alloc_addr(&lmb, addr, read_len) == addr) -+ return 0; -+ -+ printf("** Reading file would overwrite reserved memory **\n"); -+ return -ENOSPC; -+} -+#endif -+ -+static int _fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, -+ int do_lmb_check, loff_t *actread) - { - struct fstype_info *info = fs_get_info(fs_type); - void *buf; - int ret; - -+#ifdef CONFIG_LMB -+ if (do_lmb_check) { -+ ret = fs_read_lmb_check(filename, addr, offset, len, info); -+ if (ret) -+ return ret; -+ } -+#endif -+ - /* - * We don't actually know how many bytes are being read, since len==0 - * means read the whole file. -@@ -452,6 +496,12 @@ int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, - return ret; - } - -+int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, -+ loff_t *actread) -+{ -+ return _fs_read(filename, addr, offset, len, 0, actread); -+} -+ - int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, - loff_t *actwrite) - { -@@ -622,7 +672,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], - pos = 0; - - time = get_timer(0); -- ret = fs_read(filename, addr, pos, bytes, &len_read); -+ ret = _fs_read(filename, addr, pos, bytes, 1, &len_read); - time = get_timer(time); - if (ret < 0) - return 1; -diff --git a/include/lmb.h b/include/lmb.h -index 7d7e2a78..62da85e7 100644 ---- a/include/lmb.h -+++ b/include/lmb.h -@@ -31,6 +31,8 @@ struct lmb { - extern struct lmb lmb; - - extern void lmb_init(struct lmb *lmb); -+extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, -+ phys_size_t size, void *fdt_blob); - extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size); - extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size); - extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align); -diff --git a/lib/lmb.c b/lib/lmb.c -index e380a0a7..3407705f 100644 ---- a/lib/lmb.c -+++ b/lib/lmb.c -@@ -98,6 +98,19 @@ void lmb_init(struct lmb *lmb) - lmb->reserved.size = 0; - } - -+/* Initialize the struct, add memory and call arch/board reserve functions */ -+void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size, -+ void *fdt_blob) -+{ -+ lmb_init(lmb); -+ lmb_add(lmb, base, size); -+ arch_lmb_reserve(lmb); -+ board_lmb_reserve(lmb); -+ -+ if (IMAGE_ENABLE_OF_LIBFDT && fdt_blob) -+ boot_fdt_add_mem_rsv_regions(lmb, fdt_blob); -+} -+ - /* This routine called with relocation disabled. */ - static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size) - { --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0019-bootm-use-new-common-function-lmb_init_and_reserve.patch b/root/package/boot/uboot-mediatek/patches/0019-bootm-use-new-common-function-lmb_init_and_reserve.patch deleted file mode 100644 index 8f8924e1..00000000 --- a/root/package/boot/uboot-mediatek/patches/0019-bootm-use-new-common-function-lmb_init_and_reserve.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 2e3bdfbc449a5558ebbb55e36feee31f69fe32f7 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:20 +0100 -Subject: bootm: use new common function lmb_init_and_reserve - -This reduces duplicate code only. - -Signed-off-by: Simon Goldschmidt -Reviewed-by: Simon Glass - -diff --git a/common/bootm.c b/common/bootm.c -index 8bf84ebc..31e4f0f7 100644 ---- a/common/bootm.c -+++ b/common/bootm.c -@@ -56,15 +56,11 @@ static void boot_start_lmb(bootm_headers_t *images) - ulong mem_start; - phys_size_t mem_size; - -- lmb_init(&images->lmb); -- - mem_start = env_get_bootm_low(); - mem_size = env_get_bootm_size(); - -- lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); -- -- arch_lmb_reserve(&images->lmb); -- board_lmb_reserve(&images->lmb); -+ lmb_init_and_reserve(&images->lmb, (phys_addr_t)mem_start, mem_size, -+ NULL); - } - #else - #define lmb_reserve(lmb, base, size) --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0020-lmb-remove-unused-extern-declaration.patch b/root/package/boot/uboot-mediatek/patches/0020-lmb-remove-unused-extern-declaration.patch deleted file mode 100644 index 2e82ddeb..00000000 --- a/root/package/boot/uboot-mediatek/patches/0020-lmb-remove-unused-extern-declaration.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 8b554b62dcab25c0072c5b6880d0fcf079cc9d87 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:21 +0100 -Subject: lmb: remove unused extern declaration - -lmb.h includes an extern declaration of "struct lmb lmb;" which -is not used anywhere, so remove it. - -Signed-off-by: Simon Goldschmidt - -diff --git a/include/lmb.h b/include/lmb.h -index 62da85e7..1bb003e3 100644 ---- a/include/lmb.h -+++ b/include/lmb.h -@@ -28,8 +28,6 @@ struct lmb { - struct lmb_region reserved; - }; - --extern struct lmb lmb; -- - extern void lmb_init(struct lmb *lmb); - extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, - phys_size_t size, void *fdt_blob); --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0021-tftp-prevent-overwriting-reserved-memory.patch b/root/package/boot/uboot-mediatek/patches/0021-tftp-prevent-overwriting-reserved-memory.patch deleted file mode 100644 index da53cc0e..00000000 --- a/root/package/boot/uboot-mediatek/patches/0021-tftp-prevent-overwriting-reserved-memory.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 2e972e30c0b07736fedcc4fad53cfe49249495a5 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:22 +0100 -Subject: tftp: prevent overwriting reserved memory - -This fixes CVE-2018-18439 ("insufficient boundary checks in network -image boot") by using lmb to check for a valid range to store -received blocks. - -Signed-off-by: Simon Goldschmidt -Acked-by: Joe Hershberger - -diff --git a/net/tftp.c b/net/tftp.c -index 68ffd814..a9335b1b 100644 ---- a/net/tftp.c -+++ b/net/tftp.c -@@ -17,6 +17,8 @@ - #include - #endif - -+DECLARE_GLOBAL_DATA_PTR; -+ - /* Well known TFTP port # */ - #define WELL_KNOWN_PORT 69 - /* Millisecs to timeout for lost pkt */ -@@ -81,6 +83,10 @@ static ulong tftp_block_wrap; - /* memory offset due to wrapping */ - static ulong tftp_block_wrap_offset; - static int tftp_state; -+static ulong tftp_load_addr; -+#ifdef CONFIG_LMB -+static ulong tftp_load_size; -+#endif - #ifdef CONFIG_TFTP_TSIZE - /* The file size reported by the server */ - static int tftp_tsize; -@@ -164,10 +170,11 @@ static void mcast_cleanup(void) - - #endif /* CONFIG_MCAST_TFTP */ - --static inline void store_block(int block, uchar *src, unsigned len) -+static inline int store_block(int block, uchar *src, unsigned int len) - { - ulong offset = block * tftp_block_size + tftp_block_wrap_offset; - ulong newsize = offset + len; -+ ulong store_addr = tftp_load_addr + offset; - #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP - int i, rc = 0; - -@@ -175,24 +182,32 @@ static inline void store_block(int block, uchar *src, unsigned len) - /* start address in flash? */ - if (flash_info[i].flash_id == FLASH_UNKNOWN) - continue; -- if (load_addr + offset >= flash_info[i].start[0]) { -+ if (store_addr >= flash_info[i].start[0]) { - rc = 1; - break; - } - } - - if (rc) { /* Flash is destination for this packet */ -- rc = flash_write((char *)src, (ulong)(load_addr+offset), len); -+ rc = flash_write((char *)src, store_addr, len); - if (rc) { - flash_perror(rc); -- net_set_state(NETLOOP_FAIL); -- return; -+ return rc; - } - } else - #endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */ - { -- void *ptr = map_sysmem(load_addr + offset, len); -- -+ void *ptr; -+ -+#ifdef CONFIG_LMB -+ if (store_addr < tftp_load_addr || -+ store_addr + len > tftp_load_addr + tftp_load_size) { -+ puts("\nTFTP error: "); -+ puts("trying to overwrite reserved memory...\n"); -+ return -1; -+ } -+#endif -+ ptr = map_sysmem(store_addr, len); - memcpy(ptr, src, len); - unmap_sysmem(ptr); - } -@@ -203,6 +218,8 @@ static inline void store_block(int block, uchar *src, unsigned len) - - if (net_boot_file_size < newsize) - net_boot_file_size = newsize; -+ -+ return 0; - } - - /* Clear our state ready for a new transfer */ -@@ -606,7 +623,11 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, - timeout_count_max = tftp_timeout_count_max; - net_set_timeout_handler(timeout_ms, tftp_timeout_handler); - -- store_block(tftp_cur_block - 1, pkt + 2, len); -+ if (store_block(tftp_cur_block - 1, pkt + 2, len)) { -+ eth_halt(); -+ net_set_state(NETLOOP_FAIL); -+ break; -+ } - - /* - * Acknowledge the block just received, which will prompt -@@ -695,6 +716,25 @@ static void tftp_timeout_handler(void) - } - } - -+/* Initialize tftp_load_addr and tftp_load_size from load_addr and lmb */ -+static int tftp_init_load_addr(void) -+{ -+#ifdef CONFIG_LMB -+ struct lmb lmb; -+ phys_size_t max_size; -+ -+ lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start, -+ gd->bd->bi_dram[0].size, (void *)gd->fdt_blob); -+ -+ max_size = lmb_get_unreserved_size(&lmb, load_addr); -+ if (!max_size) -+ return -1; -+ -+ tftp_load_size = max_size; -+#endif -+ tftp_load_addr = load_addr; -+ return 0; -+} - - void tftp_start(enum proto_t protocol) - { -@@ -791,7 +831,14 @@ void tftp_start(enum proto_t protocol) - } else - #endif - { -- printf("Load address: 0x%lx\n", load_addr); -+ if (tftp_init_load_addr()) { -+ eth_halt(); -+ net_set_state(NETLOOP_FAIL); -+ puts("\nTFTP error: "); -+ puts("trying to overwrite reserved memory...\n"); -+ return; -+ } -+ printf("Load address: 0x%lx\n", tftp_load_addr); - puts("Loading: *\b"); - tftp_state = STATE_SEND_RRQ; - #ifdef CONFIG_CMD_BOOTEFI -@@ -842,9 +889,15 @@ void tftp_start_server(void) - { - tftp_filename[0] = 0; - -+ if (tftp_init_load_addr()) { -+ eth_halt(); -+ net_set_state(NETLOOP_FAIL); -+ puts("\nTFTP error: trying to overwrite reserved memory...\n"); -+ return; -+ } - printf("Using %s device\n", eth_get_name()); - printf("Listening for TFTP transfer on %pI4\n", &net_ip); -- printf("Load address: 0x%lx\n", load_addr); -+ printf("Load address: 0x%lx\n", tftp_load_addr); - - puts("Loading: *\b"); - --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0022-arm-bootm-fix-sp-detection-at-end-of-address-range.patch b/root/package/boot/uboot-mediatek/patches/0022-arm-bootm-fix-sp-detection-at-end-of-address-range.patch deleted file mode 100644 index 7e7ffe50..00000000 --- a/root/package/boot/uboot-mediatek/patches/0022-arm-bootm-fix-sp-detection-at-end-of-address-range.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 72bc6aa0bc7f034bd6966c872819f19af69f2b64 Mon Sep 17 00:00:00 2001 -From: Simon Goldschmidt -Date: Mon, 14 Jan 2019 22:38:23 +0100 -Subject: arm: bootm: fix sp detection at end of address range - -This fixes 'arch_lmb_reserve()' for ARM that tries to detect in which -DRAM bank 'sp' is in. - -This code failed if a bank was at the end of physical address range -(i.e. size + length overflowed to 0). - -To fix this, calculate 'bank_end' as 'size + length - 1' so that such -banks end at 0xffffffff, not 0. - -Fixes: 15751403b6 ("ARM: bootm: don't assume sp is in DRAM bank 0") -Reported-by: Frank Wunderlich -Signed-off-by: Simon Goldschmidt -Reviewed-by: Stephen Warren - -diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c -index c3c1d2fd..329f20c2 100644 ---- a/arch/arm/lib/bootm.c -+++ b/arch/arm/lib/bootm.c -@@ -64,13 +64,15 @@ void arch_lmb_reserve(struct lmb *lmb) - /* adjust sp by 4K to be safe */ - sp -= 4096; - for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { -- if (sp < gd->bd->bi_dram[bank].start) -+ if (!gd->bd->bi_dram[bank].size || -+ sp < gd->bd->bi_dram[bank].start) - continue; -+ /* Watch out for RAM at end of address space! */ - bank_end = gd->bd->bi_dram[bank].start + -- gd->bd->bi_dram[bank].size; -- if (sp >= bank_end) -+ gd->bd->bi_dram[bank].size - 1; -+ if (sp > bank_end) - continue; -- lmb_reserve(lmb, sp, bank_end - sp); -+ lmb_reserve(lmb, sp, bank_end - sp + 1); - break; - } - } --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0023-defconfig-added-strings-and-setenv-used-for-lstftp.patch b/root/package/boot/uboot-mediatek/patches/0023-defconfig-added-strings-and-setenv-used-for-lstftp.patch deleted file mode 100644 index 48f34b9f..00000000 --- a/root/package/boot/uboot-mediatek/patches/0023-defconfig-added-strings-and-setenv-used-for-lstftp.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 7b492a978a09fbc95340dbcdc1e14d604ac6ae76 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Wed, 23 Jan 2019 16:16:45 +0100 -Subject: [defconfig] added strings and setenv used for lstftp - - -diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig -index a9f4506e..bac45d11 100644 ---- a/configs/mt7623n_bpir2_defconfig -+++ b/configs/mt7623n_bpir2_defconfig -@@ -22,7 +22,6 @@ CONFIG_CMD_GPT=y - CONFIG_CMD_MMC=y - CONFIG_CMD_PART=y - CONFIG_CMD_READ=y --# CONFIG_CMD_SETEXPR is not set - # CONFIG_CMD_NFS is not set - CONFIG_CMD_PING=y - CONFIG_CMD_FAT=y -@@ -69,3 +68,5 @@ CONFIG_DEFAULT_ENV_FILE="uEnv.txt" - CONFIG_ENV_IS_IN_MMC=y - - CONFIG_CMD_ASKENV=y -+CONFIG_CMD_STRINGS=y -+CONFIG_CMD_SETEXPR=y --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0024-increase-size-for-environment-4k-8k.patch b/root/package/boot/uboot-mediatek/patches/0024-increase-size-for-environment-4k-8k.patch deleted file mode 100644 index a69cd7e3..00000000 --- a/root/package/boot/uboot-mediatek/patches/0024-increase-size-for-environment-4k-8k.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0164e641d4a64dcff5d5394b168d612b174d83bd Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Wed, 23 Jan 2019 16:30:39 +0100 -Subject: increase size for environment 4k => 8k - - -diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h -index 7d26debb..aa0314db 100644 ---- a/include/configs/mt7623.h -+++ b/include/configs/mt7623.h -@@ -27,7 +27,7 @@ - #define CONFIG_SYS_NONCACHED_MEMORY SZ_1M - - /* Environment */ --#define CONFIG_ENV_SIZE SZ_4K -+#define CONFIG_ENV_SIZE SZ_8K - /* Allow to overwrite serial and ethaddr */ - #define CONFIG_ENV_OVERWRITE - --- -1.8.3.1 - diff --git a/root/package/boot/uboot-mediatek/uEnv-default.txt b/root/package/boot/uboot-mediatek/uEnv-default.txt index 1f0c8913..10373c46 100644 --- a/root/package/boot/uboot-mediatek/uEnv-default.txt +++ b/root/package/boot/uboot-mediatek/uEnv-default.txt @@ -4,9 +4,9 @@ bootenv=uEnv.txt kernel=uImage loadaddr=0x80200000 #default bootargs will be overidden by buildargs -bootargs=console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait ip=dhcp +bootargs=console=ttyS2,115200 root=/dev/mmcblk1p2 rw rootwait ip=dhcp -console=earlyprintk console=ttyS0,115200 console=tty1 fbcon=map:0 +console=earlyprintk console=ttyS2,115200 console=tty1 fbcon=map:0 roottmpl=${rootdev} rootfstype=ext4 rootwait prepsetroot=setenv setroot setenv root ${roottmpl} bootopts=vmalloc=496M debug=7 initcall_debug=0 @@ -65,7 +65,7 @@ netmask=255.255.255.0 serverip=192.168.0.10 bootfile=uImage -netbootargs=console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait +netbootargs=console=ttyS2,115200 root=/dev/mmcblk1p2 rw rootwait #ip=dhcp sets ip on eth0 instead of wan lstftp=tftp ${loadaddr} ${serverip}:files.lst;setexpr listend ${loadaddr} + ${filesize};mw.b ${listend} 00 2;strings ${loadaddr}; From e69202fe7a56e9ec5e6f1b2afbc1de5b170f4076 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Apr 2020 13:18:39 +0200 Subject: [PATCH 27/76] Update BPI-R2 support --- config-bpi-r2 | 2 +- root/target/linux/mediatek/Makefile | 19 + root/target/linux/mediatek/image/Config.in | 4 + root/target/linux/mediatek/image/Makefile | 93 ++- root/target/linux/mediatek/image/mt7623.mk | 22 +- root/target/linux/mediatek/modules.mk | 37 +- root/target/linux/mediatek/mt7623/config-5.4 | 572 ++++++++++++++++++ ...cket-corruption-on-bridged-interface.patch | 51 ++ 8 files changed, 694 insertions(+), 106 deletions(-) create mode 100644 root/target/linux/mediatek/Makefile create mode 100644 root/target/linux/mediatek/image/Config.in create mode 100644 root/target/linux/mediatek/mt7623/config-5.4 create mode 100644 root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch diff --git a/config-bpi-r2 b/config-bpi-r2 index 6794d248..3de8b943 100644 --- a/config-bpi-r2 +++ b/config-bpi-r2 @@ -1,6 +1,6 @@ CONFIG_TARGET_mediatek=y CONFIG_TARGET_mediatek_mt7623=y -CONFIG_TARGET_mediatek_mt7623_DEVICE_7623n-bananapi-bpi-r2=y +CONFIG_TARGET_mediatek_mt7623_DEVICE_bpi_bananapi-r2=y CONFIG_TARGET_ROOTFS_EXT4FS=y # CONFIG_TARGET_ROOTFS_SQUASHFS is not set CONFIG_PACKAGE_kmod-cryptodev=y diff --git a/root/target/linux/mediatek/Makefile b/root/target/linux/mediatek/Makefile new file mode 100644 index 00000000..8ccaa927 --- /dev/null +++ b/root/target/linux/mediatek/Makefile @@ -0,0 +1,19 @@ +# Copyright (c) 2015 OpenWrt.org +# +include $(TOPDIR)/rules.mk + +ARCH:=arm +BOARD:=mediatek +BOARDNAME:=MediaTek Ralink ARM +SUBTARGETS:=mt7622 mt7623 mt7629 +FEATURES:=squashfs nand ramdisk fpu ext4 usb + +KERNEL_PATCHVER:=5.4 +KERNEL_TESTING_PATCHVER:=5.4 + +include $(INCLUDE_DIR)/target.mk +DEFAULT_PACKAGES += \ + kmod-leds-gpio kmod-gpio-button-hotplug \ + wpad-mini uboot-envtools partx-utils e2fsprogs + +$(eval $(call BuildTarget)) diff --git a/root/target/linux/mediatek/image/Config.in b/root/target/linux/mediatek/image/Config.in new file mode 100644 index 00000000..0daa957a --- /dev/null +++ b/root/target/linux/mediatek/image/Config.in @@ -0,0 +1,4 @@ +config MEDIATEK_SD_BOOT_PARTSIZE + int "Boot (SD Card) filesystem partition size (in MB)" + depends on TARGET_mediatek + default 128 \ No newline at end of file diff --git a/root/target/linux/mediatek/image/Makefile b/root/target/linux/mediatek/image/Makefile index 994a66b8..ecfa4eaf 100644 --- a/root/target/linux/mediatek/image/Makefile +++ b/root/target/linux/mediatek/image/Makefile @@ -1,7 +1,6 @@ # # Copyright (C) 2012-2015 OpenWrt.org # Copyright (C) 2016-2017 LEDE project -# Copyright (C) 2018-2019 Ycarus (Yannick Chabanois) for OpenMPTCProuter # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -9,80 +8,67 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/image.mk +FAT32_BLOCK_SIZE=1024 +FAT32_BLOCKS=$(shell echo $$(($(CONFIG_MEDIATEK_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) + # for arm KERNEL_LOADADDR := 0x80008000 +define Build/mediatek-sdcard + rm -f $@.boot + mkfs.fat $@.boot -C $(FAT32_BLOCKS) + + mcopy -i $@.boot $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-uEnv.txt ::uEnv.txt + mcopy -i $@.boot $(IMAGE_KERNEL) ::uImage + ./gen_mt7623_sdcard_img.sh $@ \ + $(STAGING_DIR_IMAGE)/bpi-r2-preloader.bin \ + $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-uboot-mediatek.bin \ + $@.boot \ + $(IMAGE_ROOTFS) \ + $(CONFIG_MEDIATEK_SD_BOOT_PARTSIZE) \ + $(CONFIG_TARGET_ROOTFS_PARTSIZE) + rm -f $@.boot + +endef + # for arm64 ifeq ($(SUBTARGET),mt7622) KERNEL_LOADADDR = 0x41080000 endif -ifndef $(CONFIG_TARGET_ROOTFS_PARTSIZE) - CONFIG_TARGET_ROOTFS_PARTSIZE := 512 +ifeq ($(SUBTARGET),mt7629) +KERNEL_LOADADDR = 0x40008000 endif -ifndef $(CONFIG_TARGET_KERNEL_PARTSIZE) - CONFIG_TARGET_KERNEL_PARTSIZE := 64 -endif - -FAT32_BLOCK_SIZE=1024 -FAT32_BLOCKS=$(shell echo $$(($(CONFIG_TARGET_KERNEL_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) - -define Build/mediatek-sdcard - rm -f $@.boot - mkfs.fat $@.boot -C $(FAT32_BLOCKS) - mcopy -i $@.boot $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-uEnv.txt ::uEnv.txt - mcopy -i $@.boot $(IMAGE_KERNEL) ::uImage - ./gen_mediatek_sdcard_img.sh $@ \ - $(STAGING_DIR_IMAGE)/bpi-r2-preloader.bin \ - $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-uboot-mediatek.bin \ - $@.boot \ - $(IMAGE_ROOTFS) \ - $(CONFIG_TARGET_KERNEL_PARTSIZE) \ - $(CONFIG_TARGET_ROOTFS_PARTSIZE) - rm -f $@.boot -endef - define Build/sysupgrade-emmc - rm -f $@.recovery - mkfs.fat -C $@.recovery 3070 + rm -f $@.recovery + mkfs.fat -C $@.recovery 3070 - dd bs="512" of="$@" if="$(IMAGE_KERNEL)" - dd bs="512" of="$@" if="$@.recovery" seek="67072" - dd bs="512" of="$@" if="$(IMAGE_ROOTFS)" seek="87552" - dd if=/dev/zero of="$@" bs=128k count=1 oflag=append conv=notrunc -endef - -define Build/sysupgrade-bpi-r2-sd - dd bs="1024" if="$(STAGING_DIR_IMAGE)/mtk-bpi-r2-preloader-sd.bin" of="$@" seek="0" - dd bs="1024" if="$(STAGING_DIR_IMAGE)/mtk-bpi-r2-uboot.bin" of="$@" seek="320" - dd bs="1024" if="$(IMAGE_KERNEL)" of="$@" seek="2048" - dd bs="1024" if="$(IMAGE_ROOTFS)" of="$@" seek="67584" -endef -define Build/sysupgrade-bpi-r2-emmc - dd bs="1024" if="$(STAGING_DIR_IMAGE)/mtk-bpi-r2-preloader-emmc.bin" of="$@" seek="0" - dd bs="1024" if="$(STAGING_DIR_IMAGE)/mtk-bpi-r2-uboot.bin" of="$@" seek="320" - dd bs="1024" if="$(IMAGE_KERNEL)" of="$@" seek="2048" - dd bs="1024" if="$(IMAGE_ROOTFS)" of="$@" seek="67584" + ./gen_mt7623_emmc_img.sh $@ \ + $(IMAGE_KERNEL) \ + $@.recovery \ + $(IMAGE_ROOTFS) endef # default all platform image(fit) build define Device/Default PROFILES = Default $$(DEVICE_NAME) KERNEL_NAME := zImage -# FILESYSTEMS := squashfs + FILESYSTEMS := squashfs DEVICE_DTS_DIR := $(DTS_DIR) IMAGES := sysupgrade.bin - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + SUPPORTED_DEVICES := $(subst _,$(comma),$(1)) ifeq ($(SUBTARGET),mt7623) DEVICE_VARS := MEDIATEK_UBOOT KERNEL_NAME := zImage KERNEL := kernel-bin | append-dtb | uImage none KERNEL_INITRAMFS := kernel-bin | append-dtb | uImage none - FILESYSTEMS := ext4 -endif -ifeq ($(SUBTARGET),mt7622) - FILESYSTEMS := squashfs + FILESYSTEMS += ext4 + IMAGES := sysupgrade.tar sdcard.img.gz + IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata + IMAGE/sdcard.img.gz := mediatek-sdcard | gzip | append-metadata +else KERNEL_NAME := Image KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb KERNEL_INITRAMFS = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb @@ -97,9 +83,8 @@ ifeq ($(SUBTARGET),mt7623) include mt7623.mk endif -define Image/Build - $(call Image/Build/$(1),$(1)) -endef +ifeq ($(SUBTARGET),mt7629) +include mt7629.mk +endif $(eval $(call BuildImage)) - diff --git a/root/target/linux/mediatek/image/mt7623.mk b/root/target/linux/mediatek/image/mt7623.mk index a8738147..678bfed0 100644 --- a/root/target/linux/mediatek/image/mt7623.mk +++ b/root/target/linux/mediatek/image/mt7623.mk @@ -1,29 +1,21 @@ -define Device/unielec-u7623-02-emmc-512m +define Device/unielec_u7623-02-emmc-512m DEVICE_VENDOR := UniElec DEVICE_MODEL := U7623-02 DEVICE_VARIANT := eMMC/512MB RAM DEVICE_DTS := mt7623a-unielec-u7623-02-emmc-512m DEVICE_PACKAGES := mkf2fs e2fsprogs kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 kmod-mmc - SUPPORTED_DEVICES := unielec,u7623-02-emmc-512m IMAGES := sysupgrade-emmc.bin.gz IMAGE/sysupgrade-emmc.bin.gz := sysupgrade-emmc | gzip | append-metadata endef +TARGET_DEVICES += unielec_u7623-02-emmc-512m -TARGET_DEVICES += unielec-u7623-02-emmc-512m - -define Device/7623n-bananapi-bpi-r2 +define Device/bpi_bananapi-r2 DEVICE_VENDOR := Bpi DEVICE_MODEL := Banana Pi R2 DEVICE_DTS := mt7623n-bananapi-bpi-r2 -# DEVICE_PACKAGES := wmt uboot-mtk-bpi-r2 kmod-crypto-hw-mtk kmod-nat-hw-mtk - DEVICE_PACKAGES := wmt uboot-mtk-bpi-r2 kmod-crypto-hw-mtk kmod-mt6625l-wlan-gen2 kmod-usb-core kmod-ata-core kmod-usb3 kmod-usb2 kmod-usb-ohci mt7623n-preloader + DEVICE_PACKAGES := kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb3 \ + kmod-ata-core kmod-ata-ahci-mtk \ + mt7623n-preloader SUPPORTED_DEVICES := bananapi,bpi-r2 - IMAGES := sysupgrade.tar sysupgrade-sd.img.gz sysupgrade-emmc.img.gz sdcard.img.gz -# IMAGES := sdcard.img.gz - IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata - IMAGE/sysupgrade-sd.img.gz := sysupgrade-bpi-r2-sd | gzip | append-metadata - IMAGE/sysupgrade-emmc.img.gz := sysupgrade-bpi-r2-emmc | gzip | append-metadata - IMAGE/sdcard.img.gz := mediatek-sdcard | gzip | append-metadata endef - -TARGET_DEVICES += 7623n-bananapi-bpi-r2 +TARGET_DEVICES += bpi_bananapi-r2 diff --git a/root/target/linux/mediatek/modules.mk b/root/target/linux/mediatek/modules.mk index 08961d75..eb81afe2 100644 --- a/root/target/linux/mediatek/modules.mk +++ b/root/target/linux/mediatek/modules.mk @@ -6,7 +6,7 @@ define KernelPackage/ata-ahci-mtk $(LINUX_DIR)/drivers/ata/libahci_platform.ko AUTOLOAD:=$(call AutoLoad,40,libahci libahci_platform ahci_mtk,1) $(call AddDepends/ata) - DEPENDS+=@TARGET_mediatek_mt7622 + DEPENDS+=@(TARGET_mediatek_mt7622||TARGET_mediatek_mt7623) endef define KernelPackage/ata-ahci-mtk/description @@ -49,38 +49,3 @@ define KernelPackage/crypto-hw-mtk/description endef $(eval $(call KernelPackage,crypto-hw-mtk)) - -define KernelPackage/nat-hw-mtk - TITLE:= MediaTek's hardware NAT module - DEPENDS:=@TARGET_mediatek @LINUX_4_14 - KCONFIG:= \ - CONFIG_NET_MEDIATEK_HNAT=y - FILES:=$(LINUX_DIR)/drivers/net/ethernet/mediatek/mtk_hnat/mtkhnat.ko - AUTOLOAD:=$(call AutoLoad,90,mtkhnat) -endef - -define KernelPackage/nat-hw-mtk/description - MediaTek's hardware NAT driver. -endef - -$(eval $(call KernelPackage,nat-hw-mtk)) - -define KernelPackage/mt6625l-wlan-gen2 - SUBMENU:=$(NETWORK_DEVICES_MENU) - TITLE:=Mediatek mt66xx wlan_gen2 driver - DEPENDS:=@TARGET_mediatek +kmod-mac80211 +@DRIVER_11N_SUPPORT - KCONFIG:= \ - CONFIG_MTK_WAPI_SUPPORT=y \ - CONFIG_MTK_PASSPOINT_R1_SUPPORT=y \ - CONFIG_MTK_PASSPOINT_R2_SUPPORT=y \ - CONFIG_MTK_WIFI_MCC_SUPPORT=y \ - CONFIG_MTK_COMBO_WIFI - FILES:=$(LINUX_DIR)/drivers/misc/mediatek/connectivity/wlan/gen2/wlan_gen2.ko - AUTOLOAD:=$(call AutoProbe,wlan_gen2) -endef - -define KernelPackage/wlan-gen2/description - This package contains the Mediatek mt66xx wlan_gen2 kernel module -endef - -$(eval $(call KernelPackage,mt6625l-wlan-gen2)) \ No newline at end of file diff --git a/root/target/linux/mediatek/mt7623/config-5.4 b/root/target/linux/mediatek/mt7623/config-5.4 new file mode 100644 index 00000000..03a0a002 --- /dev/null +++ b/root/target/linux/mediatek/mt7623/config-5.4 @@ -0,0 +1,572 @@ +# CONFIG_AIO is not set +CONFIG_AHCI_MTK=y +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_RTC_DRV_MT7622=y +CONFIG_WATCHDOG_SYSFS=y +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_HAS_BINFMT_FLAT=y +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_ARCH_HAS_KCOV=y +CONFIG_ARCH_HAS_KEEPINITRD=y +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_ARCH_HAS_PHYS_TO_DMA=y +CONFIG_ARCH_HAS_SETUP_DMA_OPS=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_ARCH_MILBEAUT is not set +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +# CONFIG_ARCH_RDA is not set +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +# CONFIG_ARM_ERRATA_814220 is not set +# CONFIG_ARM_ERRATA_857271 is not set +# CONFIG_ARM_ERRATA_857272 is not set +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +# CONFIG_ARM_LPAE is not set +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BOUNCE=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CC_CAN_LINK=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y +CONFIG_CLEANCACHE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2701=y +# CONFIG_COMMON_CLK_MT2701_AUDSYS is not set +CONFIG_COMMON_CLK_MT2701_BDPSYS=y +CONFIG_COMMON_CLK_MT2701_ETHSYS=y +# CONFIG_COMMON_CLK_MT2701_G3DSYS is not set +CONFIG_COMMON_CLK_MT2701_HIFSYS=y +CONFIG_COMMON_CLK_MT2701_IMGSYS=y +CONFIG_COMMON_CLK_MT2701_MMSYS=y +CONFIG_COMMON_CLK_MT2701_VDECSYS=y +# CONFIG_COMMON_CLK_MT7622 is not set +# CONFIG_COMMON_CLK_MT7629 is not set +# CONFIG_COMMON_CLK_MT8135 is not set +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_COREDUMP=y +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +# CONFIG_CPU_THERMAL is not set +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DEV_MEDIATEK=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_GPIO=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_MISC=y +CONFIG_DEBUG_MT6589_UART0=y +# CONFIG_DEBUG_MT8127_UART0 is not set +# CONFIG_DEBUG_MT8135_UART3 is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_UART_8250=y +# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set +CONFIG_DEBUG_UART_8250_SHIFT=2 +# CONFIG_DEBUG_UART_8250_WORD is not set +CONFIG_DEBUG_UART_PHYS=0x11004000 +CONFIG_DEBUG_UART_VIRT=0xf1004000 +CONFIG_DEBUG_UNCOMPRESS=y +# CONFIG_DEBUG_USER is not set +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_REMAP=y +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EINT_MTK=y +CONFIG_ELF_CORE=y +# CONFIG_ENERGY_MODEL is not set +CONFIG_EXT4_FS=y +CONFIG_VFAT_FS=y +# CONFIG_F2FS_CHECK_FS is not set +CONFIG_F2FS_FS=y +# CONFIG_F2FS_FS_SECURITY is not set +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_STAT_FS=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FREEZER=y +# CONFIG_FSL_QDMA is not set +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HABANA_AI is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_COPY_THREAD_TLS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_PCI=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_SMP=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_HOTPLUG_CPU=y +CONFIG_HWMON=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MT65XX=y +# CONFIG_I2C_NVIDIA_GPU is not set +CONFIG_ICPLUS_PHY=y +# CONFIG_IGC is not set +CONFIG_IIO=y +# CONFIG_IIO_BUFFER is not set +# CONFIG_IIO_TRIGGER is not set +CONFIG_INITRAMFS_COMPRESSION="" +CONFIG_INITRAMFS_ROOT_GID=1000 +CONFIG_INITRAMFS_ROOT_UID=1000 +CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt" +CONFIG_INIT_STACK_NONE=y +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_KALLSYMS=y +CONFIG_LEDS_MT6323=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_MT2701 is not set +# CONFIG_MACH_MT6589 is not set +# CONFIG_MACH_MT6592 is not set +CONFIG_MACH_MT7623=y +# CONFIG_MACH_MT7629 is not set +# CONFIG_MACH_MT8127 is not set +# CONFIG_MACH_MT8135 is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_GPIO=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_CORE=y +CONFIG_MFD_MT6397=y +# CONFIG_MFD_STPMIC1 is not set +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +# CONFIG_MISC_ALCOR_PCI is not set +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MT753X_GSW is not set +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +# CONFIG_MTK_CMDQ is not set +# CONFIG_MTK_CQDMA is not set +CONFIG_MTK_EFUSE=y +# CONFIG_MTK_HSDMA is not set +CONFIG_MTK_INFRACFG=y +# CONFIG_MTK_IOMMU is not set +# CONFIG_MTK_IOMMU_V1 is not set +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +# CONFIG_MTK_UART_APDMA is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEON=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +# CONFIG_NET_DSA_TAG_QCA is not set +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SWITCHDEV=y +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_VENDOR_MEDIATEK=y +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NLS=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +# CONFIG_NVMEM_REBOOT_MODE is not set +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +# CONFIG_PCI_MESON is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +# CONFIG_PCI_V3_SEMI is not set +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_UFS is not set +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MT2701=y +CONFIG_PINCTRL_MT6397=y +CONFIG_PINCTRL_MT7623=y +CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PM=y +CONFIG_PM_CLK=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PREEMPT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +# CONFIG_QCOM_SPMI_ADC5 is not set +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +# CONFIG_RCU_EXPERT is not set +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_REFCOUNT_FULL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MT6323=y +# CONFIG_REGULATOR_MT6380 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_QCOM_SPMI is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_RTC_DRV_MT7622 is not set +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +# CONFIG_SENSORS_OCC_P8_I2C is not set +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +# CONFIG_SMP_ON_UP is not set +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +CONFIG_SPMI=y +CONFIG_SRCU=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TASKS_RCU=y +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +# CONFIG_TI_CPSW_PHY_SEL is not set +CONFIG_TREE_SRCU=y +# CONFIG_TRUSTED_FOUNDATIONS is not set +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_ZSTD=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_UNWINDER_ARM=y +# CONFIG_UNWINDER_FRAME_POINTER is not set +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_OF=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch b/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch new file mode 100644 index 00000000..6c1c2764 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch @@ -0,0 +1,51 @@ +From 0593f719ca873722c6ac66604f027a63663c9b64 Mon Sep 17 00:00:00 2001 +From: Alexey Loukianov +Date: Fri, 7 Jun 2019 12:33:45 +0300 +Subject: [PATCH 04/12] mediatek: fix packet corruption on bridged interface + + This fixes problem that was reported here: + http://forum.banana-pi.org/t/openwrt-18-06-malformed-ip-packets-at-bridged-interface/ + + Fix is to set both gmacs to use trgmii mode. + This fix is not technically correct as second gmac + does not support trgmii mode but current driver + implementation seems to handle it somehow and + it is the only way to have both gmacs enabled + and avoid corruption of the packets on brigded + lanX interfaces. + + Signed-off-by: Alexey Loukianov +--- + .../0067-dts-bpi-r2-fix-second-gmac.patch | 20 +++++++++++++++++++ + 1 file changed, 20 insertions(+) + create mode 100644 target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch + +diff --git a/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch b/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch +new file mode 100644 +index 0000000000..145c188972 +--- /dev/null ++++ b/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch +@@ -0,0 +1,20 @@ ++--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++@@ -141,7 +141,7 @@ ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; ++- phy-mode = "rgmii"; +++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++@@ -206,7 +206,7 @@ ++ reg = <5>; ++ label = "cpu"; ++ ethernet = <&gmac1>; ++- phy-mode = "rgmii"; +++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; +-- +2.23.0 + From 682b6c23ebfb087b01e125b7588fb336c53687aa Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Apr 2020 13:18:56 +0200 Subject: [PATCH 28/76] Update iptables nat6 patch --- patches/ipt-nat6.patch | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/patches/ipt-nat6.patch b/patches/ipt-nat6.patch index 10fc9eaf..f3006a91 100644 --- a/patches/ipt-nat6.patch +++ b/patches/ipt-nat6.patch @@ -1,8 +1,9 @@ --- a/package/kernel/linux/modules/netfilter.mk 2020-03-20 15:41:58.620893747 +0100 +++ b/package/kernel/linux/modules/netfilter.mk 2020-03-20 15:45:34.389015301 +0100 -@@ -483,7 +483,9 @@ +@@ -483,8 +483,10 @@ define KernelPackage/ipt-nat6 TITLE:=IPv6 NAT targets + DEPENDS:=@IPV6 KCONFIG:=$(KCONFIG_IPT_NAT6) - FILES:=$(foreach mod,$(IPT_NAT6-m),$(LINUX_DIR)/net/$(mod).ko) + FILES:= \ From 9717391f3c4c847c936c326fa8f2e630125ddd52 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Apr 2020 16:08:02 +0200 Subject: [PATCH 29/76] Rename sdcard gen script for bpi-r2 --- .../{gen_mediatek_sdcard_img.sh => gen_mt7623_sdcard_img.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename root/target/linux/mediatek/image/{gen_mediatek_sdcard_img.sh => gen_mt7623_sdcard_img.sh} (100%) diff --git a/root/target/linux/mediatek/image/gen_mediatek_sdcard_img.sh b/root/target/linux/mediatek/image/gen_mt7623_sdcard_img.sh similarity index 100% rename from root/target/linux/mediatek/image/gen_mediatek_sdcard_img.sh rename to root/target/linux/mediatek/image/gen_mt7623_sdcard_img.sh From 6a9b7acaf897d7059843925ef63a6563dbe9349e Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Apr 2020 18:18:26 +0200 Subject: [PATCH 30/76] Update uboot-envtools --- root/package/boot/uboot-envtools/Makefile | 78 +++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 root/package/boot/uboot-envtools/Makefile diff --git a/root/package/boot/uboot-envtools/Makefile b/root/package/boot/uboot-envtools/Makefile new file mode 100644 index 00000000..ffd1d7f6 --- /dev/null +++ b/root/package/boot/uboot-envtools/Makefile @@ -0,0 +1,78 @@ +# +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=uboot-envtools +PKG_DISTNAME:=u-boot +PKG_VERSION:=2020.04-rc5 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_SUBDIR:=$(PKG_DISTNAME)-$(PKG_VERSION) +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_DISTNAME)-$(PKG_VERSION) +PKG_SOURCE_URL:=https://git.denx.de/u-boot.git +PKG_SOURCE_VERSION:=0965d2ac93db3900ae20ff0b2e176baf672b63cc +PKG_MIRROR_HASH:=1c967c90d3ab4fcc5817fbca4db8928311a8b3dfa9f827e9c585a590fd94ca7a + +PKG_BUILD_DEPENDS:=fstools + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +PKG_FLAGS:=nonshared + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/uboot-envtools + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Boot Loaders + TITLE:=read/modify U-Boot bootloader environment + URL:=http://www.denx.de/wiki/U-Boot +endef + +define Package/uboot-envtools/description + This package includes tools to read and modify U-Boot bootloader environment. +endef + +define Build/Configure + touch $(PKG_BUILD_DIR)/include/config.h + mkdir -p $(PKG_BUILD_DIR)/include/config + touch $(PKG_BUILD_DIR)/include/config/auto.conf + mkdir -p $(PKG_BUILD_DIR)/include/generated + touch $(PKG_BUILD_DIR)/include/generated/autoconf.h +endef + +MAKE_FLAGS += \ + TARGET_CFLAGS="$(TARGET_CFLAGS)" \ + TARGET_LDFLAGS="$(TARGET_LDFLAGS)" \ + no-dot-config-targets=envtools \ + envtools + +define Package/uboot-envtools/conffiles +/etc/config/ubootenv +/etc/fw_env.config +endef + +define Package/uboot-envtools/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/env/fw_printenv $(1)/usr/sbin + $(LN) fw_printenv $(1)/usr/sbin/fw_setenv + $(INSTALL_DIR) $(1)/lib + $(INSTALL_DATA) ./files/uboot-envtools.sh $(1)/lib + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(if $(wildcard ./files/$(BOARD)), \ + $(INSTALL_DATA) ./files/$(BOARD) \ + $(1)/etc/uci-defaults/30_uboot-envtools \ + ) +endef + +$(eval $(call BuildPackage,uboot-envtools)) From b2caee7b645cc08bdaa7c5b4f1fa66636c165887 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Apr 2020 18:40:17 +0200 Subject: [PATCH 31/76] Update mt7623 preloader package --- root/package/kernel/mt7623-preloader/Makefile | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/root/package/kernel/mt7623-preloader/Makefile b/root/package/kernel/mt7623-preloader/Makefile index 73a1f9e0..d3f752bb 100644 --- a/root/package/kernel/mt7623-preloader/Makefile +++ b/root/package/kernel/mt7623-preloader/Makefile @@ -10,8 +10,8 @@ include $(INCLUDE_DIR)/kernel.mk #include $(INCLUDE_DIR)/image.mk PKG_NAME:=mt7623n-preloader -PKG_VERSION:=2017-08-03 -PKG_RELEASE:=888ad5203d0c9d7dd3d6855c2a9234a70d78dc50 +PKG_VERSION:=2019-10-24 +PKG_RELEASE:=1b7b6039b9d92c48193f38ac29dd2f71e303e280 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)/$(PKG_NAME)-$(PKG_RELEASE) @@ -22,13 +22,13 @@ include $(INCLUDE_DIR)/package.mk BPI_PRELOADER_URL:=@GITHUB/BPI-SINOVOIP/BPI-files/$(PKG_RELEASE)/SD/100MB/ BPI_PRELOADER_PREFIX:=bpi-preloader-$(PKG_RELEASE) -define Download/BPI-R2-preloader-2k.img.gz - FILE:=$(BPI_PRELOADER_PREFIX)-BPI-R2-preloader-2k.img.gz +define Download/BPI-R2-preloader-DDR1600-20191024-2k.img.gz + FILE:=$(BPI_PRELOADER_PREFIX)-BPI-R2-preloader-DDR1600-20191024-2k.img.gz URL:=$(BPI_PRELOADER_URL) - URL_FILE:=BPI-R2-preloader-2k.img.gz - HASH:=9a961a26be17dd410866a2385fca47b6f0e7cce88eed6248ff5fb145cf935d93 + URL_FILE:=BPI-R2-preloader-DDR1600-20191024-2k.img.gz + HASH:=c731cc166c912c84846e2ed5faf727504e4dec1463754baa6328e9908c84a373 endef -$(eval $(call Download,BPI-R2-preloader-2k.img.gz)) +$(eval $(call Download,BPI-R2-preloader-DDR1600-20191024-2k.img.gz)) define Package/mt7623n-preloader @@ -46,7 +46,7 @@ endef define Build/Prepare rm -rf $(PKG_BUILD_DIR) mkdir -p $(PKG_BUILD_DIR) - cp $(DL_DIR)/$(BPI_PRELOADER_PREFIX)-BPI-R2-preloader-2k.img.gz $(PKG_BUILD_DIR)/bpi-r2-preloader.bin.gz + cp $(DL_DIR)/$(BPI_PRELOADER_PREFIX)-BPI-R2-preloader-DDR1600-20191024-2k.img.gz $(PKG_BUILD_DIR)/bpi-r2-preloader.bin.gz endef define Build/Compile @@ -62,4 +62,4 @@ define Build/InstallDev gunzip -c $(PKG_BUILD_DIR)/bpi-r2-preloader.bin.gz > $(STAGING_DIR_IMAGE)/bpi-r2-preloader.bin endef -$(eval $(call BuildPackage,mt7623n-preloader)) +$(eval $(call BuildPackage,mt7623n-preloader)) \ No newline at end of file From 1b9de2ad9e2c2e8fa43f54e4bbbf22a4f35cc2cf Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Apr 2020 19:09:55 +0200 Subject: [PATCH 32/76] Add base files for BPI-R2 --- .../mt7623/base-files/etc/board.d/02_network | 36 ++++ .../base-files/lib/preinit/07_set_iface_mac | 47 ++++++ .../base-files/lib/preinit/79_move_config | 19 +++ .../mt7623/base-files/lib/upgrade/platform.sh | 154 ++++++++++++++++++ 4 files changed, 256 insertions(+) create mode 100755 root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network create mode 100644 root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac create mode 100644 root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config create mode 100755 root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh diff --git a/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network b/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network new file mode 100755 index 00000000..50373f01 --- /dev/null +++ b/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network @@ -0,0 +1,36 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +mediatek_setup_interfaces() +{ + local board="$1" + + case $board in + bananapi,bpi-r2|\ + unielec,u7623-02-emmc-512m) + ucidef_set_interfaces_lan_wan "wan1 wan2 wan3 wan4" "lan" + ;; + esac +} + +mediatek_setup_macs() +{ + local board="$1" + + case $board in + unielec,u7623-02-emmc-512m) + ucidef_set_interface_macaddr "wan" "$(cat /sys/class/net/wan/address)" + ;; + esac +} + +board_config_update +board=$(board_name) +mediatek_setup_interfaces $board +mediatek_setup_macs $board +board_config_flush + +exit 0 diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac new file mode 100644 index 00000000..7a73a2d8 --- /dev/null +++ b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac @@ -0,0 +1,47 @@ +#!/bin/sh +# Copyright (C) 2018 OpenWrt.org + +RECOVERY_PART=/dev/mmcblk0p1 + +preinit_set_mac_address() { + local mac + + . /lib/functions.sh + . /lib/functions/system.sh + + case $(board_name) in + unielec,u7623-02-emmc-512m) + if [ -b $RECOVERY_PART ]; then + insmod nls_cp437 + insmod nls_iso8859-1 + insmod fat + insmod vfat + mkdir -p /tmp/recovery + mount -o rw,noatime $RECOVERY_PART /tmp/recovery + + if [ -f "/tmp/recovery/mac_addr" ]; + then + mac=$(cat /tmp/recovery/mac_addr) + else + mac=$(cat /sys/class/net/eth0/address) + echo "$mac" > /tmp/recovery/mac_addr + fi + + sync + umount /tmp/recovery + rm -rf /tmp/recovery + fi + + ip link set dev wan address $mac 2> /dev/null + + mac=$(macaddr_add $mac 1) + + ip link set dev lan0 address $mac 2>/dev/null + ip link set dev lan1 address $mac 2>/dev/null + ip link set dev lan2 address $mac 2>/dev/null + ip link set dev lan3 address $mac 2>/dev/null + ;; + esac +} + +boot_hook_add preinit_main preinit_set_mac_address diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config new file mode 100644 index 00000000..4be18114 --- /dev/null +++ b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright (C) 2012-2015 OpenWrt.org + +move_config() { + local partdev + + . /lib/upgrade/common.sh + + if export_bootdevice && export_partdevice partdev -1; then + if mount -t vfat -o rw,noatime "/dev/$partdev" /mnt; then + if [ -f /mnt/sysupgrade.tgz ]; then + mv -f /mnt/sysupgrade.tgz / + fi + umount /mnt + fi + fi +} + +boot_hook_add preinit_mount_root move_config diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh b/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh new file mode 100755 index 00000000..f117f98c --- /dev/null +++ b/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh @@ -0,0 +1,154 @@ +platform_do_upgrade() { + local board=$(board_name) + + case "$board" in + unielec,u7623-02-emmc-512m) + #Keep the persisten random mac address (if it exists) + mkdir -p /tmp/recovery + mount -o rw,noatime /dev/mmcblk0p1 /tmp/recovery + [ -f "/tmp/recovery/mac_addr" ] && \ + mv -f /tmp/recovery/mac_addr /tmp/ + umount /tmp/recovery + + #1310720 is the offset in bytes from the start of eMMC and to + #the location of the kernel (2560 512 byte sectors) + get_image "$1" | dd of=/dev/mmcblk0 bs=1310720 seek=1 conv=fsync + + mount -o rw,noatime /dev/mmcblk0p1 /tmp/recovery + [ -f "/tmp/mac_addr" ] && mv -f /tmp/mac_addr /tmp/recovery + sync + umount /tmp/recovery + ;; + bananapi,bpi-r2) + local diskdev partdev diff + + export_bootdevice && export_partdevice diskdev -2 || { + echo "Unable to determine upgrade device" + return 1 + } + + sync + + if [ "$SAVE_PARTITIONS" = "1" ]; then + get_partitions "/dev/$diskdev" bootdisk + + #extract the boot sector from the image + get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b + + get_partitions /tmp/image.bs image + + #compare tables + diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" + else + diff=1 + fi + + if [ -n "$diff" ]; then + get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync + + # Separate removal and addtion is necessary; otherwise, partition 1 + # will be missing if it overlaps with the old partition 2 + partx -d - "/dev/$diskdev" + partx -a - "/dev/$diskdev" + + return 0 + fi + + #write uboot image + get_image "$@" | dd of="$diskdev" bs=1024 skip=320 seek=320 count=700 conv=fsync + #iterate over each partition from the image and write it to the boot disk + while read part start size; do + part="$(($part - 2))" + if export_partdevice partdev $part; then + echo "Writing image to /dev/$partdev..." + get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync + else + echo "Unable to find partition $part device, skipped." + fi + done < /tmp/partmap.image + + #copy partition uuid + echo "Writing new UUID to /dev/$diskdev..." + get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync + ;; + *) + default_do_upgrade "$1" + ;; + esac +} + +PART_NAME=firmware + +platform_check_image() { + local board=$(board_name) + local magic="$(get_magic_long "$1")" + + [ "$#" -gt 1 ] && return 1 + + case "$board" in + unielec,u7623-02-emmc-512m) + [ "$magic" != "27051956" ] && { + echo "Invalid image type." + return 1 + } + return 0 + ;; + bananapi,bpi-r2) + local diskdev partdev diff + + export_bootdevice && export_partdevice diskdev -2 || { + echo "Unable to determine upgrade device" + return 1 + } + + get_partitions "/dev/$diskdev" bootdisk + + #extract the boot sector from the image + get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null + + get_partitions /tmp/image.bs image + + #compare tables + diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" + + rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image + + if [ -n "$diff" ]; then + echo "Partition layout has changed. Full image will be written." + ask_bool 0 "Abort" && exit 1 + return 0 + fi + ;; + *) + echo "Sysupgrade is not supported on your board yet." + return 1 + ;; + esac + + return 0 +} + +platform_copy_config_emmc() { + mkdir -p /recovery + mount -o rw,noatime /dev/mmcblk0p1 /recovery + cp -af "$UPGRADE_BACKUP" "/recovery/$BACKUP_FILE" + sync + umount /recovery +} + +platform_copy_config() { + case "$(board_name)" in + unielec,u7623-02-emmc-512m) + platform_copy_config_emmc + ;; + bananapi,bpi-r2) + local partdev + + if export_partdevice partdev -1; then + mount -t vfat -o rw,noatime "/dev/$partdev" /mnt + cp -af "$CONF_TAR" /mnt/ + umount /mnt + fi + ;; + esac +} From e1ff515aac37dd0e0573cd3e217701b888b59c94 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sun, 12 Apr 2020 14:18:18 +0200 Subject: [PATCH 33/76] Update BPI-R2 support --- .../base-files/etc/board.d/02_network | 41 ------------------- .../mt7623/base-files/etc/board.d/02_network | 2 +- .../base-files/lib/preinit/07_set_iface_mac | 10 ++--- 3 files changed, 6 insertions(+), 47 deletions(-) delete mode 100755 root/target/linux/mediatek/base-files/etc/board.d/02_network diff --git a/root/target/linux/mediatek/base-files/etc/board.d/02_network b/root/target/linux/mediatek/base-files/etc/board.d/02_network deleted file mode 100755 index 05835ac6..00000000 --- a/root/target/linux/mediatek/base-files/etc/board.d/02_network +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -. /lib/functions.sh -. /lib/functions/uci-defaults.sh -. /lib/functions/system.sh - -mediatek_setup_interfaces() -{ - local board="$1" - - case $board in - 'mediatek,mt7623a-rfb-emmc') - ucidef_set_interface_lan "lan0 lan1 lan2 lan3" - ucidef_set_interface_wan eth1 - ;; - 'bananapi,bpi-r2'|\ - "unielec,u7623"*) - ucidef_set_interface_lan "lan" - ;; - esac -} - -mediatek_setup_macs() -{ - local board="$1" - - case $board in - "unielec,u7623"*) - mac=$(cat /sys/class/net/wan/address) - ucidef_set_interface_macaddr "lan" $mac - ;; - esac -} - -board_config_update -board=$(board_name) -mediatek_setup_interfaces $board -mediatek_setup_macs $board -board_config_flush - -exit 0 diff --git a/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network b/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network index 50373f01..a162e373 100755 --- a/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network +++ b/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network @@ -22,7 +22,7 @@ mediatek_setup_macs() case $board in unielec,u7623-02-emmc-512m) - ucidef_set_interface_macaddr "wan" "$(cat /sys/class/net/wan/address)" + ucidef_set_interface_macaddr "lan" "$(cat /sys/class/net/lan/address)" ;; esac } diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac index 7a73a2d8..8141c3db 100644 --- a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac +++ b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac @@ -32,14 +32,14 @@ preinit_set_mac_address() { rm -rf /tmp/recovery fi - ip link set dev wan address $mac 2> /dev/null + ip link set dev lan address $mac 2> /dev/null mac=$(macaddr_add $mac 1) - ip link set dev lan0 address $mac 2>/dev/null - ip link set dev lan1 address $mac 2>/dev/null - ip link set dev lan2 address $mac 2>/dev/null - ip link set dev lan3 address $mac 2>/dev/null + ip link set dev wan1 address $mac 2>/dev/null + ip link set dev wan2 address $mac 2>/dev/null + ip link set dev wan3 address $mac 2>/dev/null + ip link set dev wan4 address $mac 2>/dev/null ;; esac } From d9b5100b7d4a141157f0b2260adfa75c11002478 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 17 Apr 2020 15:04:15 +0200 Subject: [PATCH 34/76] Update openwrt and remove mvebu patch --- build.sh | 24 +- patches/download-ipv4.patch | 13 + patches/mvebu-5.14.patch | 7720 ----------------------------------- 3 files changed, 28 insertions(+), 7729 deletions(-) create mode 100644 patches/download-ipv4.patch delete mode 100644 patches/mvebu-5.14.patch diff --git a/build.sh b/build.sh index 9837d464..09c7618f 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "02a1914585fffb97b26cc871b303a39ac9d37cbb" - _get_repo feeds/packages https://github.com/openwrt/packages "e086343cb5d0bcda2f85486e56f478987d2ea171" - _get_repo feeds/luci https://github.com/openwrt/luci "1e07e3a52d4d06cc82ab07f2b7fbba0a9a6fb801" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "75ef28be59c5b76d73313cfb9650f464ae943cc8" + _get_repo feeds/packages https://github.com/openwrt/packages "c11aaead910d5351d0f3fd4e4460ad98336fa0d4" + _get_repo feeds/luci https://github.com/openwrt/luci "01d8283ecea730191ce41302acb7ecd1aaf0631f" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -200,12 +200,12 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/ipt-nat6.patch; then fi echo "Done" -echo "Checking if mvebu patch is set or not" -if [ ! -d target/linux/mvebu/patches-5.4 ]; then - echo "apply..." - patch -N -p1 -s < ../../patches/mvebu-5.14.patch -fi -echo "Done" +#echo "Checking if mvebu patch is set or not" +#if [ ! -d target/linux/mvebu/patches-5.4 ]; then +# echo "apply..." +# patch -N -p1 -s < ../../patches/mvebu-5.14.patch +#fi +#echo "Done" echo "Checking if opkg install arguement too long patch is set or not" if ! patch -Rf -N -p1 -s --dry-run < ../../patches/package-too-long.patch; then @@ -214,6 +214,12 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/package-too-long.patch; then fi echo "Done" +echo "Downlaod via IPv4" +if ! patch -Rf -N -p1 -s --dry-run < ../../patches/download-ipv4.patch; then + patch -N -p1 -s < ../../patches/download-ipv4.patch +fi +echo "Done" + #echo "Patch protobuf wrong hash" #patch -N -R -p1 -s < ../../patches/protobuf_hash.patch diff --git a/patches/download-ipv4.patch b/patches/download-ipv4.patch new file mode 100644 index 00000000..573ea2c4 --- /dev/null +++ b/patches/download-ipv4.patch @@ -0,0 +1,13 @@ +--- a/scripts/download.pl 2020-04-12 21:41:19.548645048 +0200 ++++ b/scripts/download.pl 2020-04-12 21:41:28.752479609 +0200 +@@ -82,8 +82,8 @@ + } + + return $have_curl +- ? (qw(curl -f --connect-timeout 20 --retry 5 --location --insecure), shellwords($ENV{CURL_OPTIONS} || ''), $url) +- : (qw(wget --tries=5 --timeout=20 --no-check-certificate --output-document=-), shellwords($ENV{WGET_OPTIONS} || ''), $url) ++ ? (qw(curl -4 -f --connect-timeout 20 --retry 5 --location --insecure), shellwords($ENV{CURL_OPTIONS} || ''), $url) ++ : (qw(wget -4 --tries=5 --timeout=20 --no-check-certificate --output-document=-), shellwords($ENV{WGET_OPTIONS} || ''), $url) + ; + } + diff --git a/patches/mvebu-5.14.patch b/patches/mvebu-5.14.patch deleted file mode 100644 index 2d0112c2..00000000 --- a/patches/mvebu-5.14.patch +++ /dev/null @@ -1,7720 +0,0 @@ -From 7d933370e999abf6a25624597f3cb1a15a62d3e2 Mon Sep 17 00:00:00 2001 -From: DENG Qingfang -Date: Wed, 4 Mar 2020 20:46:10 +0800 -Subject: [PATCH 1/4] mvebu: copy files and patches to 5.4 - -Signed-off-by: DENG Qingfang ---- - target/linux/mvebu/config-5.4 | 498 +++++++++++ - target/linux/mvebu/cortexa53/config-5.4 | 169 ++++ - target/linux/mvebu/cortexa72/config-5.4 | 176 ++++ - .../arm/boot/dts/armada-385-linksys-venom.dts | 213 +++++ - .../marvell/armada-3720-espressobin-emmc.dts | 28 + - .../armada-3720-espressobin-v7-emmc.dts | 43 + - .../marvell/armada-3720-espressobin-v7.dts | 31 + - .../boot/dts/marvell/armada-3720-uDPU.dts | 162 ++++ - .../patches-5.4/002-add_powertables.patch | 770 ++++++++++++++++++ - .../patches-5.4/003-add_switch_nodes.patch | 40 + - .../004-add_sata_disk_activity_trigger.patch | 39 + - ...5-linksys_hardcode_nand_ecc_settings.patch | 17 + - ...Mangle-bootloader-s-kernel-arguments.patch | 201 +++++ - .../patches-5.4/100-find_active_root.patch | 60 ++ - .../patches-5.4/102-revert_i2c_delay.patch | 15 + - .../205-armada-385-rd-mtd-partitions.patch | 19 + - .../206-ARM-mvebu-385-ap-Add-partitions.patch | 35 + - .../210-clearfog_switch_node.patch | 21 + - .../220-disable-untested-dsa-boards.patch | 30 + - ...-armada-xp-linksys-mamba-broken-idle.patch | 10 + - .../patches-5.4/240-linksys-status-led.patch | 50 ++ - .../300-mvneta-tx-queue-workaround.patch | 35 + - ...dicate-failure-to-enter-deeper-sleep.patch | 40 + - ...-pci-mvebu-time-out-reset-on-link-up.patch | 60 ++ - ...da388-clearfog-emmc-on-clearfog-base.patch | 87 ++ - ...rmada388-clearfog-document-MPP-usage.patch | 124 +++ - ...l-armada37xx-Add-emmc-sdio-pinctrl-d.patch | 40 + - ...l-armada-37xx-Enable-emmc-on-espress.patch | 49 ++ - ...ts-marvell-armada37xx-Add-eth0-alias.patch | 20 + - ...da-3720-espressobin-correct-spi-node.patch | 58 ++ - ...l-armada-3720-espressobin-add-ports-.patch | 26 + - ...rdvark-Convert-to-use-pci_host_probe.patch | 44 + - ...-device-to-the-same-MAX-payload-size.patch | 138 ++++ - ...ardvark-disable-LOS-state-by-default.patch | 55 ++ - ...ark-allow-to-specify-link-capability.patch | 43 + - ...-3720-espressobin-set-max-link-to-ge.patch | 73 ++ - ...vneta-Add-support-for-2500Mbps-SGMII.patch | 104 +++ - .../532-net-mvneta-correct-typo.patch | 33 + - ...net-mvneta-Dont-advertise-2.5G-modes.patch | 55 ++ - ...et-mvneta-remove-redundant-check-for.patch | 30 + - ...-net-marvell-neta-add-comphy-support.patch | 159 ++++ - ...eta-disable-comphy-when-setting-mode.patch | 78 ++ - ...537-net-mvneta-add-2500baset-support.patch | 34 + - .../538-phy-add-QSGMII-and-PCIE-modes.patch | 28 + - .../539-phy-core-add-PHY_MODE_ETHERNET.patch | 24 + - ...fix-build-breakage-add-PHY_MODE_SATA.patch | 45 + - ...phy_set_mode-to-accept-phy-mode-and-.patch | 134 +++ - .../542-phy-add-A3700-COMPHY-support.patch | 381 +++++++++ - ...rvell-armada-37xx-declare-the-COMPHY.patch | 58 ++ - ...rm64-dts-uDPU-fix-comphy-definitions.patch | 35 + - ...-arm64-dts-uDPU-remove-i2c-fast-mode.patch | 30 + - ...ts-uDPU-SFP-cages-support-3W-modules.patch | 33 + - 52 files changed, 4780 insertions(+) - create mode 100644 target/linux/mvebu/config-5.4 - create mode 100644 target/linux/mvebu/cortexa53/config-5.4 - create mode 100644 target/linux/mvebu/cortexa72/config-5.4 - create mode 100644 target/linux/mvebu/files-5.4/arch/arm/boot/dts/armada-385-linksys-venom.dts - create mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts - create mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts - create mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts - create mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts - create mode 100644 target/linux/mvebu/patches-5.4/002-add_powertables.patch - create mode 100644 target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch - create mode 100644 target/linux/mvebu/patches-5.4/004-add_sata_disk_activity_trigger.patch - create mode 100644 target/linux/mvebu/patches-5.4/005-linksys_hardcode_nand_ecc_settings.patch - create mode 100644 target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch - create mode 100644 target/linux/mvebu/patches-5.4/100-find_active_root.patch - create mode 100644 target/linux/mvebu/patches-5.4/102-revert_i2c_delay.patch - create mode 100644 target/linux/mvebu/patches-5.4/205-armada-385-rd-mtd-partitions.patch - create mode 100644 target/linux/mvebu/patches-5.4/206-ARM-mvebu-385-ap-Add-partitions.patch - create mode 100644 target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch - create mode 100644 target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch - create mode 100644 target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch - create mode 100644 target/linux/mvebu/patches-5.4/240-linksys-status-led.patch - create mode 100644 target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch - create mode 100644 target/linux/mvebu/patches-5.4/400-cpuidle-mvebu-indicate-failure-to-enter-deeper-sleep.patch - create mode 100644 target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch - create mode 100644 target/linux/mvebu/patches-5.4/412-ARM-dts-armada388-clearfog-emmc-on-clearfog-base.patch - create mode 100644 target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch - create mode 100644 target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch - create mode 100644 target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch - create mode 100644 target/linux/mvebu/patches-5.4/520-arm64-dts-marvell-armada37xx-Add-eth0-alias.patch - create mode 100644 target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch - create mode 100644 target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch - create mode 100644 target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch - create mode 100644 target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch - create mode 100644 target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch - create mode 100644 target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch - create mode 100644 target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch - create mode 100644 target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch - create mode 100644 target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch - create mode 100644 target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch - create mode 100644 target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch - create mode 100644 target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch - create mode 100644 target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch - create mode 100644 target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch - create mode 100644 target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch - create mode 100644 target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch - create mode 100644 target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch - create mode 100644 target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch - create mode 100644 target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch - create mode 100644 target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch - create mode 100644 target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch - create mode 100644 target/linux/mvebu/patches-5.4/545-arm64-dts-uDPU-remove-i2c-fast-mode.patch - create mode 100644 target/linux/mvebu/patches-5.4/546-arm64-dts-uDPU-SFP-cages-support-3W-modules.patch - -diff --git a/target/linux/mvebu/config-5.4 b/target/linux/mvebu/config-5.4 -new file mode 100644 -index 00000000000..24093fd386a ---- /dev/null -+++ b/target/linux/mvebu/config-5.4 -@@ -0,0 +1,498 @@ -+CONFIG_AHCI_MVEBU=y -+CONFIG_ALIGNMENT_TRAP=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_ARCH_HAS_KCOV=y -+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -+CONFIG_ARCH_HAS_PHYS_TO_DMA=y -+CONFIG_ARCH_HAS_SET_MEMORY=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -+CONFIG_ARCH_HAS_TICK_BROADCAST=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+CONFIG_ARCH_MULTIPLATFORM=y -+CONFIG_ARCH_MULTI_V6_V7=y -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MVEBU=y -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_ARM=y -+CONFIG_ARMADA_370_CLK=y -+CONFIG_ARMADA_370_XP_IRQ=y -+CONFIG_ARMADA_370_XP_TIMER=y -+CONFIG_ARMADA_38X_CLK=y -+CONFIG_ARMADA_THERMAL=y -+CONFIG_ARMADA_XP_CLK=y -+CONFIG_ARM_APPENDED_DTB=y -+# CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARM_CRYPTO=y -+CONFIG_ARM_ERRATA_720789=y -+CONFIG_ARM_ERRATA_764369=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GLOBAL_TIMER=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_ARM_HEAVY_MB=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+# CONFIG_ARM_LPAE is not set -+CONFIG_ARM_MVEBU_V7_CPUIDLE=y -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_UNWIND=y -+CONFIG_ARM_VIRT_EXT=y -+CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y -+CONFIG_ATA=y -+CONFIG_ATAGS=y -+CONFIG_AUTO_ZRELADDR=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_SD=y -+CONFIG_BLK_MQ_PCI=y -+CONFIG_BLK_SCSI_REQUEST=y -+CONFIG_BOUNCE=y -+# CONFIG_CACHE_FEROCEON_L2 is not set -+CONFIG_CACHE_L2X0=y -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_COMMON_CLK=y -+CONFIG_CPUFREQ_DT=y -+CONFIG_CPUFREQ_DT_PLATDEV=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+# CONFIG_CPU_BIG_ENDIAN is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -+CONFIG_CPU_FREQ_GOV_ATTR_SET=y -+CONFIG_CPU_FREQ_GOV_COMMON=y -+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -+CONFIG_CPU_FREQ_STAT=y -+CONFIG_CPU_HAS_ASID=y -+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+CONFIG_CPU_IDLE=y -+CONFIG_CPU_IDLE_GOV_LADDER=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_PJ4B=y -+CONFIG_CPU_PM=y -+CONFIG_CPU_RMAP=y -+CONFIG_CPU_SPECTRE=y -+CONFIG_CPU_THERMAL=y -+CONFIG_CPU_THUMB_CAPABLE=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_V7=y -+CONFIG_CRC16=y -+CONFIG_CRYPTO_ACOMP2=y -+CONFIG_CRYPTO_AEAD=y -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_AES_ARM=y -+CONFIG_CRYPTO_AES_ARM_BS=y -+# CONFIG_CRYPTO_AES_ARM_CE is not set -+# CONFIG_CRYPTO_CHACHA20_NEON is not set -+CONFIG_CRYPTO_CRC32=y -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32_ARM_CE is not set -+CONFIG_CRYPTO_CRYPTD=y -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_DES=y -+CONFIG_CRYPTO_DEV_MARVELL_CESA=y -+# CONFIG_CRYPTO_GHASH_ARM_CE is not set -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_HW=y -+CONFIG_CRYPTO_LZO=y -+CONFIG_CRYPTO_MANAGER=y -+CONFIG_CRYPTO_MANAGER2=y -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA1_ARM=y -+# CONFIG_CRYPTO_SHA1_ARM_CE is not set -+CONFIG_CRYPTO_SHA1_ARM_NEON=y -+CONFIG_CRYPTO_SHA256_ARM=y -+# CONFIG_CRYPTO_SHA2_ARM_CE is not set -+CONFIG_CRYPTO_SHA512_ARM=y -+CONFIG_CRYPTO_SIMD=y -+CONFIG_CRYPTO_WORKQUEUE=y -+CONFIG_DCACHE_WORD_ACCESS=y -+CONFIG_DEBUG_ALIGN_RODATA=y -+CONFIG_DEBUG_INFO=y -+CONFIG_DEBUG_LL=y -+CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" -+CONFIG_DEBUG_MVEBU_UART0=y -+# CONFIG_DEBUG_MVEBU_UART0_ALTERNATE is not set -+# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set -+CONFIG_DEBUG_UART_8250=y -+# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -+CONFIG_DEBUG_UART_8250_SHIFT=2 -+# CONFIG_DEBUG_UART_8250_WORD is not set -+CONFIG_DEBUG_UART_PHYS=0xd0012000 -+CONFIG_DEBUG_UART_VIRT=0xfec12000 -+CONFIG_DEBUG_UNCOMPRESS=y -+CONFIG_DEBUG_USER=y -+CONFIG_DMADEVICES=y -+CONFIG_DMA_ENGINE=y -+CONFIG_DMA_ENGINE_RAID=y -+CONFIG_DMA_OF=y -+CONFIG_DTC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+CONFIG_EXT4_FS=y -+CONFIG_EXTCON=y -+# CONFIG_F2FS_CHECK_FS is not set -+CONFIG_F2FS_FS=y -+# CONFIG_F2FS_FS_SECURITY is not set -+CONFIG_F2FS_FS_XATTR=y -+CONFIG_F2FS_STAT_FS=y -+CONFIG_FIXED_PHY=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_FS_IOMAP=y -+CONFIG_FS_MBCACHE=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_GENERIC_ARCH_TOPOLOGY=y -+CONFIG_GENERIC_BUG=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -+CONFIG_GENERIC_CPU_AUTOPROBE=y -+CONFIG_GENERIC_EARLY_IOREMAP=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_GENERIC_IRQ_CHIP=y -+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -+CONFIG_GENERIC_IRQ_MIGRATION=y -+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_GENERIC_MSI_IRQ=y -+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_PHY=y -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GLOB=y -+CONFIG_GPIOLIB=y -+CONFIG_GPIOLIB_IRQCHIP=y -+CONFIG_GPIO_GENERIC=y -+CONFIG_GPIO_GENERIC_PLATFORM=y -+CONFIG_GPIO_MVEBU=y -+CONFIG_GPIO_PCA953X=y -+CONFIG_GPIO_PCA953X_IRQ=y -+CONFIG_GPIO_SYSFS=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_HARDEN_BRANCH_PREDICTOR=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_HAS_DMA=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_HAVE_ARCH_KGDB=y -+CONFIG_HAVE_ARCH_PFN_VALID=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_ARM_SCU=y -+CONFIG_HAVE_ARM_SMCCC=y -+CONFIG_HAVE_ARM_TWD=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -+CONFIG_HAVE_EBPF_JIT=y -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_HAVE_IDE=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_HAVE_NET_DSA=y -+CONFIG_HAVE_OPROFILE=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_RSEQ=y -+CONFIG_HAVE_SMP=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_UID16=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HIGHMEM=y -+# CONFIG_HIGHPTE is not set -+CONFIG_HOTPLUG_CPU=y -+CONFIG_HWBM=y -+CONFIG_HWMON=y -+CONFIG_HW_RANDOM=y -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_PERIODIC=y -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MV64XXX=y -+# CONFIG_I2C_PXA is not set -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_IRQCHIP=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_IRQ_WORK=y -+# CONFIG_IWMMXT is not set -+CONFIG_JBD2=y -+CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_PCA963X=y -+CONFIG_LEDS_TLC591XX=y -+CONFIG_LEDS_TRIGGER_DISK=y -+CONFIG_LIBFDT=y -+CONFIG_LOCK_DEBUGGING_SUPPORT=y -+CONFIG_LOCK_SPIN_ON_OWNER=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_MACH_ARMADA_370=y -+# CONFIG_MACH_ARMADA_375 is not set -+CONFIG_MACH_ARMADA_38X=y -+# CONFIG_MACH_ARMADA_39X is not set -+CONFIG_MACH_ARMADA_XP=y -+# CONFIG_MACH_DOVE is not set -+CONFIG_MACH_MVEBU_ANY=y -+CONFIG_MACH_MVEBU_V7=y -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_MANGLE_BOOTARGS=y -+CONFIG_MARVELL_PHY=y -+CONFIG_MDIO_BUS=y -+CONFIG_MDIO_DEVICE=y -+CONFIG_MDIO_I2C=y -+CONFIG_MEMFD_CREATE=y -+CONFIG_MEMORY=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_MIGRATION=y -+CONFIG_MMC=y -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_MVSDIO=y -+CONFIG_MMC_SDHCI=y -+# CONFIG_MMC_SDHCI_PCI is not set -+CONFIG_MMC_SDHCI_PLTFM=y -+CONFIG_MMC_SDHCI_PXAV3=y -+# CONFIG_MMC_TIFM_SD is not set -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_MTD_CFI_STAA=y -+CONFIG_MTD_M25P80=y -+CONFIG_MTD_NAND=y -+CONFIG_MTD_NAND_ECC=y -+CONFIG_MTD_NAND_MARVELL=y -+CONFIG_MTD_SPI_NOR=y -+CONFIG_MTD_SPLIT_FIRMWARE=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+CONFIG_MTD_UBI_BLOCK=y -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MUTEX_SPIN_ON_OWNER=y -+CONFIG_MVEBU_CLK_COMMON=y -+CONFIG_MVEBU_CLK_COREDIV=y -+CONFIG_MVEBU_CLK_CPU=y -+CONFIG_MVEBU_DEVBUS=y -+CONFIG_MVEBU_MBUS=y -+CONFIG_MVMDIO=y -+CONFIG_MVNETA=y -+CONFIG_MVNETA_BM=y -+CONFIG_MVNETA_BM_ENABLE=y -+CONFIG_MVPP2=y -+CONFIG_MVSW61XX_PHY=y -+CONFIG_MV_XOR=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_NEON=y -+CONFIG_NET_DSA=y -+CONFIG_NET_DSA_MV88E6XXX=y -+CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y -+# CONFIG_NET_DSA_MV88E6XXX_PTP is not set -+CONFIG_NET_DSA_TAG_DSA=y -+CONFIG_NET_DSA_TAG_EDSA=y -+CONFIG_NET_FLOW_LIMIT=y -+CONFIG_NET_SWITCHDEV=y -+CONFIG_NLS=y -+CONFIG_NOP_USB_XCEIV=y -+CONFIG_NO_BOOTMEM=y -+CONFIG_NR_CPUS=4 -+CONFIG_NVMEM=y -+CONFIG_OF=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_GPIO=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_KOBJ=y -+CONFIG_OF_MDIO=y -+CONFIG_OF_NET=y -+CONFIG_OF_RESERVED_MEM=y -+CONFIG_OLD_SIGACTION=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_ORION_WATCHDOG=y -+CONFIG_OUTER_CACHE=y -+CONFIG_OUTER_CACHE_SYNC=y -+CONFIG_PADATA=y -+CONFIG_PAGE_OFFSET=0xC0000000 -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_DOMAINS_GENERIC=y -+CONFIG_PCI_MSI=y -+CONFIG_PCI_MSI_IRQ_DOMAIN=y -+CONFIG_PCI_MVEBU=y -+# CONFIG_PCI_V3_SEMI is not set -+CONFIG_PERF_USE_VMALLOC=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_PHYLIB=y -+CONFIG_PHYLINK=y -+# CONFIG_PHY_MVEBU_A3700_COMPHY is not set -+# CONFIG_PHY_MVEBU_CP110_COMPHY is not set -+CONFIG_PINCTRL=y -+CONFIG_PINCTRL_ARMADA_370=y -+CONFIG_PINCTRL_ARMADA_38X=y -+CONFIG_PINCTRL_ARMADA_XP=y -+CONFIG_PINCTRL_MVEBU=y -+# CONFIG_PINCTRL_SINGLE is not set -+CONFIG_PJ4B_ERRATA_4742=y -+# CONFIG_PL310_ERRATA_588369 is not set -+# CONFIG_PL310_ERRATA_727915 is not set -+CONFIG_PL310_ERRATA_753970=y -+# CONFIG_PL310_ERRATA_769419 is not set -+CONFIG_PLAT_ORION=y -+CONFIG_PM_OPP=y -+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=11 -+CONFIG_PWM=y -+CONFIG_PWM_SYSFS=y -+CONFIG_RATIONAL=y -+CONFIG_RCU_NEED_SEGCBLIST=y -+CONFIG_RCU_STALL_COMMON=y -+CONFIG_REFCOUNT_FULL=y -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGULATOR=y -+CONFIG_REGULATOR_FIXED_VOLTAGE=y -+CONFIG_RFS_ACCEL=y -+CONFIG_RPS=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_DRV_ARMADA38X=y -+CONFIG_RTC_DRV_MV=y -+CONFIG_RTC_I2C_AND_SPI=y -+CONFIG_RTC_MC146818_LIB=y -+CONFIG_RWSEM_SPIN_ON_OWNER=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_SATA_AHCI_PLATFORM=y -+CONFIG_SATA_MV=y -+CONFIG_SATA_PMP=y -+CONFIG_SCSI=y -+CONFIG_SENSORS_PWM_FAN=y -+CONFIG_SENSORS_TMP421=y -+CONFIG_SERIAL_8250_DW=y -+CONFIG_SERIAL_8250_FSL=y -+CONFIG_SERIAL_MVEBU_CONSOLE=y -+CONFIG_SERIAL_MVEBU_UART=y -+CONFIG_SFP=y -+CONFIG_SGL_ALLOC=y -+CONFIG_SG_POOL=y -+CONFIG_SMP=y -+CONFIG_SMP_ON_UP=y -+CONFIG_SOC_BUS=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_SPI=y -+# CONFIG_SPI_ARMADA_3700 is not set -+CONFIG_SPI_MASTER=y -+CONFIG_SPI_MEM=y -+CONFIG_SPI_ORION=y -+CONFIG_SRAM=y -+CONFIG_SRAM_EXEC=y -+CONFIG_SRCU=y -+CONFIG_SWCONFIG=y -+CONFIG_SWPHY=y -+CONFIG_SWP_EMULATE=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_THERMAL=y -+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -+CONFIG_THERMAL_GOV_STEP_WISE=y -+CONFIG_THERMAL_HWMON=y -+CONFIG_THERMAL_OF=y -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_TICK_CPU_ACCOUNTING=y -+CONFIG_TIMER_OF=y -+CONFIG_TIMER_PROBE=y -+CONFIG_TREE_RCU=y -+CONFIG_TREE_SRCU=y -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+CONFIG_USB=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_HCD_ORION=y -+CONFIG_USB_EHCI_HCD_PLATFORM=y -+CONFIG_USB_LEDS_TRIGGER_USBPORT=y -+CONFIG_USB_PHY=y -+CONFIG_USB_STORAGE=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_MVEBU=y -+CONFIG_USB_XHCI_PLATFORM=y -+CONFIG_USE_OF=y -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_WATCHDOG_CORE=y -+CONFIG_XPS=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_BCJ=y -+CONFIG_ZBOOT_ROM_BSS=0x0 -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_ZLIB_INFLATE=y -diff --git a/target/linux/mvebu/cortexa53/config-5.4 b/target/linux/mvebu/cortexa53/config-5.4 -new file mode 100644 -index 00000000000..7f3c2b21de0 ---- /dev/null -+++ b/target/linux/mvebu/cortexa53/config-5.4 -@@ -0,0 +1,169 @@ -+CONFIG_64BIT=y -+CONFIG_ARCH_DMA_ADDR_T_64BIT=y -+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -+CONFIG_ARCH_HAS_FAST_MULTIPLIER=y -+CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y -+CONFIG_ARCH_HAS_PTE_SPECIAL=y -+CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y -+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y -+CONFIG_ARCH_INLINE_READ_LOCK=y -+CONFIG_ARCH_INLINE_READ_LOCK_BH=y -+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y -+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y -+CONFIG_ARCH_INLINE_READ_UNLOCK=y -+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y -+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y -+CONFIG_ARCH_INLINE_SPIN_LOCK=y -+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y -+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y -+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y -+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y -+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y -+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y -+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y -+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y -+CONFIG_ARCH_INLINE_WRITE_LOCK=y -+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y -+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y -+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y -+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y -+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y -+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y -+CONFIG_ARCH_MMAP_RND_BITS=18 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=24 -+CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -+CONFIG_ARCH_PROC_KCORE_TEXT=y -+CONFIG_ARCH_SELECT_MEMORY_MODEL=y -+CONFIG_ARCH_SPARSEMEM_DEFAULT=y -+CONFIG_ARCH_SPARSEMEM_ENABLE=y -+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -+CONFIG_ARCH_SUPPORTS_INT128=y -+CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y -+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y -+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -+CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y -+CONFIG_ARCH_WANT_FRAME_POINTERS=y -+CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y -+CONFIG_ARM64=y -+# CONFIG_ARM64_16K_PAGES is not set -+CONFIG_ARM64_4K_PAGES=y -+# CONFIG_ARM64_64K_PAGES is not set -+CONFIG_ARM64_CONT_SHIFT=4 -+# CONFIG_ARM64_CRYPTO is not set -+# CONFIG_ARM64_HW_AFDBM is not set -+# CONFIG_ARM64_LSE_ATOMICS is not set -+CONFIG_ARM64_PAGE_SHIFT=12 -+# CONFIG_ARM64_PAN is not set -+CONFIG_ARM64_PA_BITS=48 -+CONFIG_ARM64_PA_BITS_48=y -+# CONFIG_ARM64_PMEM is not set -+# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -+# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -+CONFIG_ARM64_SSBD=y -+CONFIG_ARM64_SVE=y -+# CONFIG_ARM64_UAO is not set -+CONFIG_ARM64_VA_BITS=39 -+CONFIG_ARM64_VA_BITS_39=y -+# CONFIG_ARM64_VA_BITS_48 is not set -+# CONFIG_ARM64_VHE is not set -+CONFIG_ARMADA_37XX_CLK=y -+CONFIG_ARMADA_AP806_SYSCON=y -+CONFIG_ARMADA_CP110_SYSCON=y -+CONFIG_ARM_AMBA=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+CONFIG_ARM_ARMADA_37XX_CPUFREQ=y -+CONFIG_ARM_GIC_V2M=y -+CONFIG_ARM_GIC_V3=y -+CONFIG_ARM_GIC_V3_ITS=y -+CONFIG_ARM_GIC_V3_ITS_PCI=y -+# CONFIG_ARM_PL172_MPMC is not set -+CONFIG_ARM_PSCI_FW=y -+# CONFIG_ARM_SP805_WATCHDOG is not set -+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -+# CONFIG_DEBUG_ALIGN_RODATA is not set -+CONFIG_DMA_DIRECT_OPS=y -+# CONFIG_FLATMEM_MANUAL is not set -+CONFIG_FRAME_POINTER=y -+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -+CONFIG_GENERIC_CSUM=y -+CONFIG_GENERIC_PINCONF=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y -+CONFIG_HAVE_ARCH_HUGE_VMAP=y -+CONFIG_HAVE_ARCH_KASAN=y -+CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y -+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -+CONFIG_HAVE_ARCH_VMAP_STACK=y -+CONFIG_HAVE_CMPXCHG_DOUBLE=y -+CONFIG_HAVE_CMPXCHG_LOCAL=y -+CONFIG_HAVE_DEBUG_BUGVERBOSE=y -+CONFIG_HAVE_GENERIC_GUP=y -+CONFIG_HAVE_MEMORY_PRESENT=y -+CONFIG_HAVE_PATA_PLATFORM=y -+CONFIG_HAVE_RCU_TABLE_FREE=y -+CONFIG_HOLES_IN_ZONE=y -+# CONFIG_HUGETLBFS is not set -+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -+CONFIG_INLINE_READ_LOCK=y -+CONFIG_INLINE_READ_LOCK_BH=y -+CONFIG_INLINE_READ_LOCK_IRQ=y -+CONFIG_INLINE_READ_LOCK_IRQSAVE=y -+CONFIG_INLINE_READ_UNLOCK_BH=y -+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y -+CONFIG_INLINE_SPIN_LOCK=y -+CONFIG_INLINE_SPIN_LOCK_BH=y -+CONFIG_INLINE_SPIN_LOCK_IRQ=y -+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y -+CONFIG_INLINE_SPIN_TRYLOCK=y -+CONFIG_INLINE_SPIN_TRYLOCK_BH=y -+CONFIG_INLINE_SPIN_UNLOCK_BH=y -+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y -+CONFIG_INLINE_WRITE_LOCK=y -+CONFIG_INLINE_WRITE_LOCK_BH=y -+CONFIG_INLINE_WRITE_LOCK_IRQ=y -+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y -+CONFIG_INLINE_WRITE_UNLOCK_BH=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y -+CONFIG_MFD_SYSCON=y -+CONFIG_MMC_SDHCI_XENON=y -+CONFIG_MODULES_USE_ELF_RELA=y -+CONFIG_MVEBU_GICP=y -+CONFIG_MVEBU_ICU=y -+CONFIG_MVEBU_ODMI=y -+CONFIG_MVEBU_PIC=y -+CONFIG_NEED_SG_DMA_LENGTH=y -+# CONFIG_NUMA is not set -+CONFIG_PARTITION_PERCPU=y -+CONFIG_PCI_AARDVARK=y -+CONFIG_PGTABLE_LEVELS=3 -+CONFIG_PHYS_ADDR_T_64BIT=y -+CONFIG_PHY_MVEBU_A3700_COMPHY=y -+CONFIG_PINCTRL_ARMADA_37XX=y -+CONFIG_PINCTRL_ARMADA_AP806=y -+CONFIG_PINCTRL_ARMADA_CP110=y -+CONFIG_POWER_RESET=y -+CONFIG_POWER_SUPPLY=y -+CONFIG_QUEUED_RWLOCKS=y -+CONFIG_QUEUED_SPINLOCKS=y -+# CONFIG_RANDOMIZE_BASE is not set -+CONFIG_REGULATOR_GPIO=y -+# CONFIG_SERIAL_AMBA_PL011 is not set -+CONFIG_SPARSEMEM=y -+CONFIG_SPARSEMEM_EXTREME=y -+CONFIG_SPARSEMEM_MANUAL=y -+CONFIG_SPARSEMEM_VMEMMAP=y -+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -+CONFIG_SPI_ARMADA_3700=y -+CONFIG_SWIOTLB=y -+CONFIG_SYSCTL_EXCEPTION_TRACE=y -+CONFIG_SYS_SUPPORTS_HUGETLBFS=y -+CONFIG_THREAD_INFO_IN_TASK=y -+CONFIG_UNMAP_KERNEL_AT_EL0=y -+CONFIG_VMAP_STACK=y -+CONFIG_ZONE_DMA32=y -diff --git a/target/linux/mvebu/cortexa72/config-5.4 b/target/linux/mvebu/cortexa72/config-5.4 -new file mode 100644 -index 00000000000..c78eb843724 ---- /dev/null -+++ b/target/linux/mvebu/cortexa72/config-5.4 -@@ -0,0 +1,176 @@ -+CONFIG_64BIT=y -+CONFIG_ARCH_DMA_ADDR_T_64BIT=y -+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -+CONFIG_ARCH_HAS_FAST_MULTIPLIER=y -+CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y -+CONFIG_ARCH_HAS_PTE_SPECIAL=y -+CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y -+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y -+CONFIG_ARCH_INLINE_READ_LOCK=y -+CONFIG_ARCH_INLINE_READ_LOCK_BH=y -+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y -+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y -+CONFIG_ARCH_INLINE_READ_UNLOCK=y -+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y -+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y -+CONFIG_ARCH_INLINE_SPIN_LOCK=y -+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y -+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y -+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y -+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y -+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y -+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y -+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y -+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y -+CONFIG_ARCH_INLINE_WRITE_LOCK=y -+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y -+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y -+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y -+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y -+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y -+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y -+CONFIG_ARCH_MMAP_RND_BITS=18 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=24 -+CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -+CONFIG_ARCH_PROC_KCORE_TEXT=y -+CONFIG_ARCH_SELECT_MEMORY_MODEL=y -+CONFIG_ARCH_SPARSEMEM_DEFAULT=y -+CONFIG_ARCH_SPARSEMEM_ENABLE=y -+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -+CONFIG_ARCH_SUPPORTS_INT128=y -+CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y -+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y -+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -+CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y -+CONFIG_ARCH_WANT_FRAME_POINTERS=y -+CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y -+CONFIG_ARM64=y -+# CONFIG_ARM64_16K_PAGES is not set -+CONFIG_ARM64_4K_PAGES=y -+# CONFIG_ARM64_64K_PAGES is not set -+CONFIG_ARM64_CONT_SHIFT=4 -+# CONFIG_ARM64_CRYPTO is not set -+# CONFIG_ARM64_HW_AFDBM is not set -+# CONFIG_ARM64_LSE_ATOMICS is not set -+CONFIG_ARM64_PAGE_SHIFT=12 -+# CONFIG_ARM64_PAN is not set -+CONFIG_ARM64_PA_BITS=48 -+CONFIG_ARM64_PA_BITS_48=y -+# CONFIG_ARM64_PMEM is not set -+# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -+# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -+CONFIG_ARM64_SSBD=y -+CONFIG_ARM64_SVE=y -+# CONFIG_ARM64_UAO is not set -+CONFIG_ARM64_VA_BITS=39 -+CONFIG_ARM64_VA_BITS_39=y -+# CONFIG_ARM64_VA_BITS_48 is not set -+# CONFIG_ARM64_VHE is not set -+CONFIG_ARMADA_37XX_CLK=y -+CONFIG_ARMADA_AP806_SYSCON=y -+CONFIG_ARMADA_CP110_SYSCON=y -+CONFIG_ARM_AMBA=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+CONFIG_ARM_GIC_V2M=y -+CONFIG_ARM_GIC_V3=y -+CONFIG_ARM_GIC_V3_ITS=y -+CONFIG_ARM_GIC_V3_ITS_PCI=y -+# CONFIG_ARM_PL172_MPMC is not set -+CONFIG_ARM_PSCI_FW=y -+# CONFIG_ARM_SP805_WATCHDOG is not set -+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -+# CONFIG_DEBUG_ALIGN_RODATA is not set -+CONFIG_DMA_DIRECT_OPS=y -+# CONFIG_FLATMEM_MANUAL is not set -+CONFIG_FRAME_POINTER=y -+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -+CONFIG_GENERIC_CSUM=y -+CONFIG_GENERIC_PINCONF=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y -+CONFIG_HAVE_ARCH_HUGE_VMAP=y -+CONFIG_HAVE_ARCH_KASAN=y -+CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y -+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -+CONFIG_HAVE_ARCH_VMAP_STACK=y -+CONFIG_HAVE_CMPXCHG_DOUBLE=y -+CONFIG_HAVE_CMPXCHG_LOCAL=y -+CONFIG_HAVE_DEBUG_BUGVERBOSE=y -+CONFIG_HAVE_GENERIC_GUP=y -+CONFIG_HAVE_MEMORY_PRESENT=y -+CONFIG_HAVE_PATA_PLATFORM=y -+CONFIG_HAVE_RCU_TABLE_FREE=y -+CONFIG_HOLES_IN_ZONE=y -+# CONFIG_HUGETLBFS is not set -+CONFIG_HW_RANDOM_OMAP=y -+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -+CONFIG_INLINE_READ_LOCK=y -+CONFIG_INLINE_READ_LOCK_BH=y -+CONFIG_INLINE_READ_LOCK_IRQ=y -+CONFIG_INLINE_READ_LOCK_IRQSAVE=y -+CONFIG_INLINE_READ_UNLOCK_BH=y -+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y -+CONFIG_INLINE_SPIN_LOCK=y -+CONFIG_INLINE_SPIN_LOCK_BH=y -+CONFIG_INLINE_SPIN_LOCK_IRQ=y -+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y -+CONFIG_INLINE_SPIN_TRYLOCK=y -+CONFIG_INLINE_SPIN_TRYLOCK_BH=y -+CONFIG_INLINE_SPIN_UNLOCK_BH=y -+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y -+CONFIG_INLINE_WRITE_LOCK=y -+CONFIG_INLINE_WRITE_LOCK_BH=y -+CONFIG_INLINE_WRITE_LOCK_IRQ=y -+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y -+CONFIG_INLINE_WRITE_UNLOCK_BH=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y -+CONFIG_MARVELL_10G_PHY=y -+CONFIG_MFD_SYSCON=y -+CONFIG_MMC_SDHCI_XENON=y -+CONFIG_MODULES_USE_ELF_RELA=y -+CONFIG_MVEBU_GICP=y -+CONFIG_MVEBU_ICU=y -+CONFIG_MVEBU_ODMI=y -+CONFIG_MVEBU_PIC=y -+CONFIG_MV_XOR_V2=y -+CONFIG_NEED_SG_DMA_LENGTH=y -+# CONFIG_NUMA is not set -+CONFIG_PARTITION_PERCPU=y -+CONFIG_PCIEAER=y -+CONFIG_PCIEPORTBUS=y -+CONFIG_PCIE_ARMADA_8K=y -+CONFIG_PCIE_DW=y -+CONFIG_PCIE_DW_HOST=y -+# CONFIG_PCI_AARDVARK is not set -+CONFIG_PGTABLE_LEVELS=3 -+CONFIG_PHYS_ADDR_T_64BIT=y -+CONFIG_PHY_MVEBU_CP110_COMPHY=y -+CONFIG_PINCTRL_ARMADA_37XX=y -+CONFIG_PINCTRL_ARMADA_AP806=y -+CONFIG_PINCTRL_ARMADA_CP110=y -+CONFIG_POWER_RESET=y -+CONFIG_POWER_SUPPLY=y -+CONFIG_QUEUED_RWLOCKS=y -+CONFIG_QUEUED_SPINLOCKS=y -+# CONFIG_RANDOMIZE_BASE is not set -+CONFIG_RAS=y -+CONFIG_REGULATOR_GPIO=y -+# CONFIG_SERIAL_AMBA_PL011 is not set -+CONFIG_SPARSEMEM=y -+CONFIG_SPARSEMEM_EXTREME=y -+CONFIG_SPARSEMEM_MANUAL=y -+CONFIG_SPARSEMEM_VMEMMAP=y -+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -+CONFIG_SWIOTLB=y -+CONFIG_SYSCTL_EXCEPTION_TRACE=y -+CONFIG_SYS_SUPPORTS_HUGETLBFS=y -+CONFIG_THREAD_INFO_IN_TASK=y -+CONFIG_UNMAP_KERNEL_AT_EL0=y -+CONFIG_VMAP_STACK=y -+CONFIG_ZONE_DMA32=y -diff --git a/target/linux/mvebu/files-5.4/arch/arm/boot/dts/armada-385-linksys-venom.dts b/target/linux/mvebu/files-5.4/arch/arm/boot/dts/armada-385-linksys-venom.dts -new file mode 100644 -index 00000000000..c152c14c6b9 ---- /dev/null -+++ b/target/linux/mvebu/files-5.4/arch/arm/boot/dts/armada-385-linksys-venom.dts -@@ -0,0 +1,213 @@ -+/* -+ * Device Tree file for the Linksys WRT32X (Venom) -+ * -+ * Copyright (C) 2017 Imre Kaloz -+ * -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without -+ * any warranty of any kind, whether express or implied. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+/dts-v1/; -+#include -+#include -+#include "armada-385-linksys.dtsi" -+ -+/ { -+ model = "Linksys WRT32X"; -+ compatible = "linksys,venom", "linksys,armada385", "marvell,armada385", -+ "marvell,armada380"; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200"; -+ stdout-path = "serial0:115200n8"; -+ append-rootblock = "root=/dev/mtdblock"; -+ }; -+}; -+ -+&expander0 { -+ wan_amber@0 { -+ label = "venom:amber:wan"; -+ reg = <0x0>; -+ }; -+ -+ wan_blue@1 { -+ label = "venom:blue:wan"; -+ reg = <0x1>; -+ }; -+ -+ usb2@5 { -+ label = "venom:blue:usb2"; -+ reg = <0x5>; -+ }; -+ -+ usb3_1@6 { -+ label = "venom:blue:usb3_1"; -+ reg = <0x6>; -+ }; -+ -+ usb3_2@7 { -+ label = "venom:blue:usb3_2"; -+ reg = <0x7>; -+ }; -+ -+ wps_blue@8 { -+ label = "venom:blue:wps"; -+ reg = <0x8>; -+ }; -+ -+ wps_amber@9 { -+ label = "venom:amber:wps"; -+ reg = <0x9>; -+ }; -+}; -+ -+&gpio_leds { -+ power { -+ gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; -+ label = "venom:blue:power"; -+ }; -+ -+ sata { -+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; -+ label = "venom:blue:sata"; -+ }; -+ -+ wlan_2g { -+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; -+ label = "venom:blue:wlan_2g"; -+ }; -+ -+ wlan_5g { -+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; -+ label = "venom:blue:wlan_5g"; -+ }; -+}; -+ -+&gpio_leds_pins { -+ marvell,pins = "mpp21", "mpp45", "mpp46", "mpp56"; -+}; -+ -+&nand { -+ /* Spansion S34ML02G2 256MiB, OEM Layout */ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "u-boot"; -+ reg = <0x0000000 0x200000>; /* 2MB */ -+ read-only; -+ }; -+ -+ partition@200000 { -+ label = "u_env"; -+ reg = <0x200000 0x20000>; /* 128KB */ -+ }; -+ -+ partition@220000 { -+ label = "s_env"; -+ reg = <0x220000 0x40000>; /* 256KB */ -+ }; -+ -+ partition@180000 { -+ label = "unused_area"; -+ reg = <0x260000 0x5c0000>; /* 5.75MB */ -+ }; -+ -+ partition@7e0000 { -+ label = "devinfo"; -+ reg = <0x7e0000 0x40000>; /* 256KB */ -+ read-only; -+ }; -+ -+ /* kernel1 overlaps with rootfs1 by design */ -+ partition@900000 { -+ label = "kernel1"; -+ reg = <0x900000 0x7b00000>; /* 123MB */ -+ }; -+ -+ partition@c00000 { -+ label = "rootfs1"; -+ reg = <0xc00000 0x7800000>; /* 120MB */ -+ }; -+ -+ /* kernel2 overlaps with rootfs2 by design */ -+ partition@8400000 { -+ label = "kernel2"; -+ reg = <0x8400000 0x7b00000>; /* 123MB */ -+ }; -+ -+ partition@8700000 { -+ label = "rootfs2"; -+ reg = <0x8700000 0x7800000>; /* 120MB */ -+ }; -+ -+ /* last MB is for the BBT, not writable */ -+ partition@ff00000 { -+ label = "BBT"; -+ reg = <0xff00000 0x100000>; -+ }; -+ }; -+}; -+ -+ -+&pcie1 { -+ mwlwifi { -+ marvell,chainmask = <4 4>; -+ }; -+}; -+ -+&pcie2 { -+ mwlwifi { -+ marvell,chainmask = <4 4>; -+ }; -+}; -+ -+&sdhci { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhci_pins>; -+ no-1-8-v; -+ non-removable; -+ wp-inverted; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&usb3_1_vbus { -+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; -+}; -+ -+&usb3_1_vbus_pins { -+ marvell,pins = "mpp44"; -+}; -diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts -new file mode 100644 -index 00000000000..ef90a1bd387 ---- /dev/null -+++ b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts -@@ -0,0 +1,28 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board with eMMC -+ * Copyright (C) 2018 Marvell -+ * -+ * Romain Perier -+ * Konstantin Porotchkin -+ * -+ */ -+ -+#include "armada-3720-espressobin.dts" -+ -+/ { -+ model = "Globalscale Marvell ESPRESSOBin Board (eMMC)"; -+ compatible = "globalscale,espressobin-emmc", "globalscale,espressobin", -+ "marvell,armada3720", "marvell,armada3710"; -+}; -+ -+&sdhci0 { -+ status = "okay"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ mmccard: mmccard@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ }; -+}; -diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts -new file mode 100644 -index 00000000000..2b565ca8d82 ---- /dev/null -+++ b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts -@@ -0,0 +1,43 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board V7 with eMMC -+ * Copyright (C) 2018 Marvell -+ * -+ * Romain Perier -+ * Konstantin Porotchkin -+ * -+ */ -+ -+#include "armada-3720-espressobin.dts" -+ -+/ { -+ model = "Globalscale Marvell ESPRESSOBin Board V7 (eMMC)"; -+ compatible = "globalscale,espressobin-v7-emmc", "globalscale,espressobin-v7", -+ "globalscale,espressobin", "marvell,armada3720", -+ "marvell,armada3710"; -+}; -+ -+&ports { -+ port@1 { -+ reg = <1>; -+ label = "lan1"; -+ phy-handle = <&switch0phy0>; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ label = "wan"; -+ phy-handle = <&switch0phy2>; -+ }; -+}; -+ -+&sdhci0 { -+ status = "okay"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ mmccard: mmccard@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ }; -+}; -diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts -new file mode 100644 -index 00000000000..8a408c3c48f ---- /dev/null -+++ b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts -@@ -0,0 +1,31 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board V7 -+ * Copyright (C) 2018 Marvell -+ * -+ * Romain Perier -+ * Konstantin Porotchkin -+ * -+ */ -+ -+#include "armada-3720-espressobin.dts" -+ -+/ { -+ model = "Globalscale Marvell ESPRESSOBin Board V7"; -+ compatible = "globalscale,espressobin-v7", "globalscale,espressobin", -+ "marvell,armada3720", "marvell,armada3710"; -+}; -+ -+&ports { -+ port@1 { -+ reg = <1>; -+ label = "lan1"; -+ phy-handle = <&switch0phy0>; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ label = "wan"; -+ phy-handle = <&switch0phy2>; -+ }; -+}; -diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -new file mode 100644 -index 00000000000..5b722b4f832 ---- /dev/null -+++ b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -@@ -0,0 +1,162 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device tree for the uDPU board. -+ * Based on Marvell Armada 3720 development board (DB-88F3720-DDR3) -+ * Copyright (C) 2016 Marvell -+ * Copyright (C) 2019 Methode Electronics -+ * Copyright (C) 2019 Telus -+ * -+ * Vladimir Vid -+ */ -+ -+/dts-v1/; -+ -+#include -+#include "armada-372x.dtsi" -+ -+/ { -+ model = "Methode uDPU Board"; -+ compatible = "methode,udpu", "marvell,armada3720"; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ memory@0 { -+ device_type = "memory"; -+ reg = <0x00000000 0x00000000 0x00000000 0x20000000>; -+ }; -+ -+ leds { -+ pinctrl-names = "default"; -+ compatible = "gpio-leds"; -+ -+ power1 { -+ label = "udpu:green:power"; -+ gpios = <&gpionb 11 GPIO_ACTIVE_LOW>; -+ }; -+ -+ power2 { -+ label = "udpu:red:power"; -+ gpios = <&gpionb 12 GPIO_ACTIVE_LOW>; -+ }; -+ -+ network1 { -+ label = "udpu:green:network"; -+ gpios = <&gpionb 13 GPIO_ACTIVE_LOW>; -+ }; -+ -+ network2 { -+ label = "udpu:red:network"; -+ gpios = <&gpionb 14 GPIO_ACTIVE_LOW>; -+ }; -+ -+ alarm1 { -+ label = "udpu:green:alarm"; -+ gpios = <&gpionb 15 GPIO_ACTIVE_LOW>; -+ }; -+ -+ alarm2 { -+ label = "udpu:red:alarm"; -+ gpios = <&gpionb 16 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ sfp_eth0: sfp-eth0 { -+ compatible = "sff,sfp"; -+ i2c-bus = <&i2c0>; -+ los-gpio = <&gpiosb 2 GPIO_ACTIVE_HIGH>; -+ mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>; -+ tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>; -+ tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ sfp_eth1: sfp-eth1 { -+ compatible = "sff,sfp"; -+ i2c-bus = <&i2c1>; -+ los-gpio = <&gpiosb 7 GPIO_ACTIVE_HIGH>; -+ mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>; -+ tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>; -+ tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>; -+ }; -+}; -+ -+&sdhci0 { -+ status = "okay"; -+ bus-width = <8>; -+ mmc-ddr-1_8v; -+ mmc-hs400-1_8v; -+ marvell,pad-type = "fixed-1-8v"; -+ non-removable; -+ no-sd; -+ no-sdio; -+}; -+ -+&spi0 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi_quad_pins>; -+ -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <54000000>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ /* only bootloader is located on the SPI */ -+ partition@0 { -+ label = "uboot"; -+ reg = <0 0x400000>; -+ }; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins>; -+ -+ lm75@48 { -+ status = "okay"; -+ compatible = "lm75"; -+ reg = <0x48>; -+ }; -+ -+ lm75@49 { -+ status = "okay"; -+ compatible = "lm75"; -+ reg = <0x49>; -+ }; -+}; -+ -+ð0 { -+ status = "okay"; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ sfp = <&sfp_eth0>; -+}; -+ -+ð1 { -+ status = "okay"; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ sfp = <&sfp_eth1>; -+}; -+ -+&usb3 { -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -diff --git a/target/linux/mvebu/patches-5.4/002-add_powertables.patch b/target/linux/mvebu/patches-5.4/002-add_powertables.patch -new file mode 100644 -index 00000000000..c2fb748d5d0 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/002-add_powertables.patch -@@ -0,0 +1,770 @@ -+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi -++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi -+@@ -212,11 +212,19 @@ -+ &pcie1 { -+ /* Marvell 88W8864, 5GHz-only */ -+ status = "okay"; -++ -++ mwlwifi { -++ marvell,2ghz = <0>; -++ }; -+ }; -+ -+ &pcie2 { -+ /* Marvell 88W8864, 2GHz-only */ -+ status = "okay"; -++ -++ mwlwifi { -++ marvell,5ghz = <0>; -++ }; -+ }; -+ -+ &pinctrl { -+--- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts -++++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts -+@@ -142,3 +142,205 @@ -+ }; -+ }; -+ }; -++ -++&pcie1 { -++ mwlwifi { -++ marvell,chainmask = <2 2>; -++ marvell,powertable { -++ AU = -++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <100 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <104 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <108 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <112 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <116 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <120 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <124 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <128 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <132 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <136 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <140 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>, -++ <149 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>, -++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>, -++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>, -++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>, -++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>; -++ CA = -++ <36 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>, -++ <40 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>, -++ <44 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>, -++ <48 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <149 0 0x1a 0x1a 0x18 0x17 0x19 0x19 0x17 0x15 0x18 0x18 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, -++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, -++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, -++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, -++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>; -++ CN = -++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <100 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <104 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <108 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <112 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <116 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <120 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <124 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <128 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <132 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <136 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <140 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <149 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x11 0x11 0x11 0x11 0 0xf>, -++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>, -++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>, -++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>, -++ <165 0 0x15 0x15 0x15 0x15 0x16 0x16 0x16 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>; -++ ETSI = -++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <100 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <104 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <108 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <112 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <116 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <120 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <124 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <128 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <132 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <136 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <140 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>, -++ <149 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>; -++ FCC = -++ <36 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <40 0 0x19 0x19 0x18 0x17 0x19 0x19 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <44 0 0x19 0x19 0x18 0x17 0x19 0x19 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <48 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <149 0 0x1a 0x1a 0x18 0x17 0x19 0x19 0x17 0x15 0x18 0x18 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, -++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, -++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, -++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>, -++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>; -++ }; -++ }; -++}; -++ -++&pcie2 { -++ mwlwifi { -++ marvell,chainmask = <2 2>; -++ marvell,powertable { -++ AU = -++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>; -++ CA = -++ <1 0 0x19 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 0 0xf>, -++ <2 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <3 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <4 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <5 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <6 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <7 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <8 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <9 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <10 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>, -++ <11 0 0x19 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x00 0x00 0x00 0x00 0 0xf>; -++ CN = -++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <12 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <13 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <14 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>; -++ ETSI = -++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <12 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>, -++ <13 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>; -++ FCC = -++ <1 0 0x19 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0x19 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x0 0x0 0x0 0x0 0 0xf>; -++ }; -++ }; -++}; -+--- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts -++++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts -+@@ -142,3 +142,205 @@ -+ }; -+ }; -+ }; -++ -++&pcie1 { -++ mwlwifi { -++ marvell,chainmask = <4 4>; -++ marvell,powertable { -++ AU = -++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <149 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, -++ <153 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, -++ <157 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, -++ <161 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, -++ <165 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>; -++ CA = -++ <36 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <40 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <44 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <48 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>; -++ CN = -++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <149 0 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <165 0 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>; -++ ETSI = -++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <149 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>; -++ FCC = -++ <36 0 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0 0xf>, -++ <40 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, -++ <44 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, -++ <48 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>; -++ }; -++ }; -++}; -++ -++&pcie2 { -++ mwlwifi { -++ marvell,chainmask = <4 4>; -++ marvell,powertable { -++ AU = -++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; -++ CA = -++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>; -++ CN = -++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <14 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; -++ ETSI = -++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; -++ FCC = -++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>; -++ }; -++ }; -++}; -+--- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts -++++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts -+@@ -142,3 +142,205 @@ -+ }; -+ }; -+ }; -++ -++&pcie1 { -++ mwlwifi { -++ marvell,chainmask = <4 4>; -++ marvell,powertable { -++ AU = -++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <149 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, -++ <153 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, -++ <157 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, -++ <161 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>, -++ <165 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>; -++ CA = -++ <36 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <40 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <44 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <48 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>; -++ CN = -++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <149 0 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>, -++ <165 0 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>; -++ ETSI = -++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>, -++ <149 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>; -++ FCC = -++ <36 0 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0 0xf>, -++ <40 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, -++ <44 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, -++ <48 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>, -++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>, -++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>, -++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>, -++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>; -++ }; -++ }; -++}; -++ -++&pcie2 { -++ mwlwifi { -++ marvell,chainmask = <4 4>; -++ marvell,powertable { -++ AU = -++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; -++ CA = -++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>; -++ CN = -++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <14 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; -++ ETSI = -++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>, -++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>; -++ FCC = -++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>; -++ }; -++ }; -++}; -+--- a/arch/arm/boot/dts/armada-385-linksys-rango.dts -++++ b/arch/arm/boot/dts/armada-385-linksys-rango.dts -+@@ -157,6 +157,18 @@ -+ }; -+ }; -+ -++&pcie1 { -++ mwlwifi { -++ marvell,chainmask = <4 4>; -++ }; -++}; -++ -++&pcie2 { -++ mwlwifi { -++ marvell,chainmask = <4 4>; -++ }; -++}; -++ -+ &sdhci { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhci_pins>; -+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+@@ -272,12 +272,100 @@ -+ pcie@2,0 { -+ /* Port 0, Lane 1 */ -+ status = "okay"; -++ -++ mwlwifi { -++ marvell,5ghz = <0>; -++ marvell,chainmask = <4 4>; -++ marvell,powertable { -++ FCC = -++ <1 0 0x17 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>; -++ -++ ETSI = -++ <1 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <2 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <3 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <4 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <5 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <6 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <7 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <8 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <9 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <10 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <11 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <12 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>, -++ <13 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>; -++ }; -++ }; -+ }; -+ -+ /* Second mini-PCIe port */ -+ pcie@3,0 { -+ /* Port 0, Lane 3 */ -+ status = "okay"; -++ -++ mwlwifi { -++ marvell,2ghz = <0>; -++ marvell,chainmask = <4 4>; -++ marvell,powertable { -++ FCC = -++ <36 0 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <40 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <44 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <48 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>, -++ <52 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>, -++ <56 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>, -++ <60 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>, -++ <64 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>, -++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>, -++ <149 0 0x16 0x16 0x16 0x16 0x14 0x14 0x14 0x14 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>, -++ <153 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>, -++ <157 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>, -++ <161 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>, -++ <165 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>; -++ -++ ETSI = -++ <36 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <40 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <44 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <48 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <52 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <56 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <60 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <64 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <100 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <104 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <108 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <112 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <116 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <120 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <124 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <128 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <132 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <136 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <140 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>, -++ <149 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>; -++ }; -++ }; -+ }; -+ }; -+ -diff --git a/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch b/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch -new file mode 100644 -index 00000000000..b2086389163 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch -@@ -0,0 +1,40 @@ -+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+@@ -257,6 +257,16 @@ -+ }; -+ }; -+ }; -++ -++ mvsw61xx { -++ compatible = "marvell,88e6172"; -++ status = "okay"; -++ reg = <0x10>; -++ -++ mii-bus = <&mdio>; -++ cpu-port-0 = <5>; -++ cpu-port-1 = <6>; -++ }; -+ }; -+ -+ &pciec { -+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi -++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi -+@@ -82,6 +82,18 @@ -+ linux,default-trigger = "disk-activity"; -+ }; -+ }; -++ -++ mvsw61xx { -++ #address-cells = <1>; -++ #size-cells = <0>; -++ compatible = "marvell,88e6176"; -++ status = "okay"; -++ reg = <0x10>; -++ -++ mii-bus = <&mdio>; -++ cpu-port-0 = <5>; -++ cpu-port-1 = <6>; -++ }; -+ }; -+ -+ &ahci0 { -diff --git a/target/linux/mvebu/patches-5.4/004-add_sata_disk_activity_trigger.patch b/target/linux/mvebu/patches-5.4/004-add_sata_disk_activity_trigger.patch -new file mode 100644 -index 00000000000..2cb8f254906 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/004-add_sata_disk_activity_trigger.patch -@@ -0,0 +1,39 @@ -+From 172230195068703b78ad5733a09492f5d6814c09 Mon Sep 17 00:00:00 2001 -+From: Ansuel Smith -+Date: Tue, 28 Feb 2017 14:15:50 +0100 -+Subject: [PATCH] ARM: dts: armada: Add default trigger for sata led -+ -+In others board we have the sata led set to function -+with the sata led trigger by default. -+This patch makes the same for these board that have sata -+led but get disabled by not associating it to any trigger. -+ -+Signed-off-by: Ansuel Smith -+Acked-by: Jason Cooper -+Signed-off-by: Gregory CLEMENT -+--- -+ arch/arm/boot/dts/armada-385-linksys-caiman.dts | 1 + -+ arch/arm/boot/dts/armada-385-linksys-cobra.dts | 1 + -+ arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 1 + -+ 3 files changed, 3 insertions(+) -+ -+--- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts -++++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts -+@@ -68,6 +68,7 @@ -+ -+ sata { -+ label = "caiman:white:sata"; -++ linux,default-trigger = "disk-activity"; -+ }; -+ }; -+ -+--- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts -++++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts -+@@ -68,6 +68,7 @@ -+ -+ sata { -+ label = "cobra:white:sata"; -++ linux,default-trigger = "disk-activity"; -+ }; -+ }; -+ -diff --git a/target/linux/mvebu/patches-5.4/005-linksys_hardcode_nand_ecc_settings.patch b/target/linux/mvebu/patches-5.4/005-linksys_hardcode_nand_ecc_settings.patch -new file mode 100644 -index 00000000000..dfe13bae7b5 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/005-linksys_hardcode_nand_ecc_settings.patch -@@ -0,0 +1,17 @@ -+Newer Linksys boards might come with a Winbond W29N02GV which can be -+configured in different ways. Make sure we configure it the same way -+as the older chips so everything keeps working. -+ -+Signed-off-by: Imre Kaloz -+ -+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi -++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi -+@@ -160,6 +160,8 @@ -+ reg = <0>; -+ label = "pxa3xx_nand-0"; -+ nand-rb = <0>; -++ nand-ecc-strength = <4>; -++ nand-ecc-step-size = <512>; -+ marvell,nand-keep-config; -+ nand-on-flash-bbt; -+ }; -diff --git a/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch -new file mode 100644 -index 00000000000..0cb9e996027 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch -@@ -0,0 +1,201 @@ -+From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001 -+From: Adrian Panella -+Date: Thu, 9 Mar 2017 09:37:17 +0100 -+Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments -+ -+The command-line arguments provided by the boot loader will be -+appended to a new device tree property: bootloader-args. -+If there is a property "append-rootblock" in DT under /chosen -+and a root= option in bootloaders command line it will be parsed -+and added to DT bootargs with the form: XX. -+Only command line ATAG will be processed, the rest of the ATAGs -+sent by bootloader will be ignored. -+This is usefull in dual boot systems, to get the current root partition -+without afecting the rest of the system. -+ -+Signed-off-by: Adrian Panella -+ -+This patch has been modified to be mvebu specific. The original patch -+did not pass the bootloader cmdline on if no append-rootblock stanza -+was found, resulting in blank cmdline and failure to boot. -+ -+Signed-off-by: Michael Gray -+--- -+ arch/arm/Kconfig | 11 +++++ -+ arch/arm/boot/compressed/atags_to_fdt.c | 72 ++++++++++++++++++++++++++++++++- -+ init/main.c | 16 ++++++++ -+ 3 files changed, 98 insertions(+), 1 deletion(-) -+ -+--- a/arch/arm/Kconfig -++++ b/arch/arm/Kconfig -+@@ -1926,6 +1926,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN -+ The command-line arguments provided by the boot loader will be -+ appended to the the device tree bootargs property. -+ -++config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE -++ bool "Append rootblock parsing bootloader's kernel arguments" -++ help -++ The command-line arguments provided by the boot loader will be -++ appended to a new device tree property: bootloader-args. -++ If there is a property "append-rootblock" in DT under /chosen -++ and a root= option in bootloaders command line it will be parsed -++ and added to DT bootargs with the form: XX. -++ Only command line ATAG will be processed, the rest of the ATAGs -++ sent by bootloader will be ignored. -++ -+ endchoice -+ -+ config CMDLINE -+--- a/arch/arm/boot/compressed/atags_to_fdt.c -++++ b/arch/arm/boot/compressed/atags_to_fdt.c -+@@ -4,6 +4,8 @@ -+ -+ #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND) -+ #define do_extend_cmdline 1 -++#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) -++#define do_extend_cmdline 1 -+ #else -+ #define do_extend_cmdline 0 -+ #endif -+@@ -67,6 +69,65 @@ static uint32_t get_cell_size(const void -+ return cell_size; -+ } -+ -++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) -++ -++static char *append_rootblock(char *dest, const char *str, int len, void *fdt) -++{ -++ char *ptr, *end; -++ char *root="root="; -++ int i, l; -++ const char *rootblock; -++ -++ //ARM doesn't have __HAVE_ARCH_STRSTR, so search manually -++ ptr = str - 1; -++ -++ do { -++ //first find an 'r' at the begining or after a space -++ do { -++ ptr++; -++ ptr = strchr(ptr, 'r'); -++ if(!ptr) return dest; -++ -++ } while (ptr != str && *(ptr-1) != ' '); -++ -++ //then check for the rest -++ for(i = 1; i <= 4; i++) -++ if(*(ptr+i) != *(root+i)) break; -++ -++ } while (i != 5); -++ -++ end = strchr(ptr, ' '); -++ end = end ? (end - 1) : (strchr(ptr, 0) - 1); -++ -++ //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX ) -++ for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++); -++ ptr = end + 1; -++ -++ /* if append-rootblock property is set use it to append to command line */ -++ rootblock = getprop(fdt, "/chosen", "append-rootblock", &l); -++ if(rootblock != NULL) { -++ if(*dest != ' ') { -++ *dest = ' '; -++ dest++; -++ len++; -++ } -++ if (len + l + i <= COMMAND_LINE_SIZE) { -++ memcpy(dest, rootblock, l); -++ dest += l - 1; -++ memcpy(dest, ptr, i); -++ dest += i; -++ } -++ } else { -++ len = strlen(str); -++ if (len + 1 < COMMAND_LINE_SIZE) { -++ memcpy(dest, str, len); -++ dest += len; -++ } -++ } -++ return dest; -++} -++#endif -++ -+ static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) -+ { -+ char cmdline[COMMAND_LINE_SIZE]; -+@@ -86,12 +147,21 @@ static void merge_fdt_bootargs(void *fdt -+ -+ /* and append the ATAG_CMDLINE */ -+ if (fdt_cmdline) { -++ -++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) -++ //save original bootloader args -++ //and append ubi.mtd with root partition number to current cmdline -++ setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline); -++ ptr = append_rootblock(ptr, fdt_cmdline, len, fdt); -++ -++#else -+ len = strlen(fdt_cmdline); -+ if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) { -+ *ptr++ = ' '; -+ memcpy(ptr, fdt_cmdline, len); -+ ptr += len; -+ } -++#endif -+ } -+ *ptr = '\0'; -+ -+@@ -148,7 +218,9 @@ int atags_to_fdt(void *atag_list, void * -+ else -+ setprop_string(fdt, "/chosen", "bootargs", -+ atag->u.cmdline.cmdline); -+- } else if (atag->hdr.tag == ATAG_MEM) { -++ } -++#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE -++ else if (atag->hdr.tag == ATAG_MEM) { -+ if (memcount >= sizeof(mem_reg_property)/4) -+ continue; -+ if (!atag->u.mem.size) -+@@ -187,6 +259,10 @@ int atags_to_fdt(void *atag_list, void * -+ setprop(fdt, "/memory", "reg", mem_reg_property, -+ 4 * memcount * memsize); -+ } -++#else -++ -++ } -++#endif -+ -+ return fdt_pack(fdt); -+ } -+--- a/init/main.c -++++ b/init/main.c -+@@ -102,6 +102,10 @@ -+ #define CREATE_TRACE_POINTS -+ #include -+ -++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) -++#include -++#endif -++ -+ static int kernel_init(void *); -+ -+ extern void init_IRQ(void); -+@@ -591,6 +595,18 @@ asmlinkage __visible void __init start_k -+ page_alloc_init(); -+ -+ pr_notice("Kernel command line: %s\n", boot_command_line); -++ -++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) -++ //Show bootloader's original command line for reference -++ if(of_chosen) { -++ const char *prop = of_get_property(of_chosen, "bootloader-args", NULL); -++ if(prop) -++ pr_notice("Bootloader command line (ignored): %s\n", prop); -++ else -++ pr_notice("Bootloader command line not present\n"); -++ } -++#endif -++ -+ /* parameters may set static keys */ -+ jump_label_init(); -+ parse_early_param(); -diff --git a/target/linux/mvebu/patches-5.4/100-find_active_root.patch b/target/linux/mvebu/patches-5.4/100-find_active_root.patch -new file mode 100644 -index 00000000000..f52a5108b85 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/100-find_active_root.patch -@@ -0,0 +1,60 @@ -+The WRT1900AC among other Linksys routers uses a dual-firmware layout. -+Dynamically rename the active partition to "ubi". -+ -+Signed-off-by: Imre Kaloz -+ -+--- a/drivers/mtd/ofpart.c -++++ b/drivers/mtd/ofpart.c -+@@ -25,6 +25,8 @@ static bool node_has_compatible(struct d -+ return of_get_property(pp, "compatible", NULL); -+ } -+ -++static int mangled_rootblock; -++ -+ static int parse_fixed_partitions(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+@@ -33,6 +35,7 @@ static int parse_fixed_partitions(struct -+ struct device_node *mtd_node; -+ struct device_node *ofpart_node; -+ const char *partname; -++ const char *owrtpart = "ubi"; -+ struct device_node *pp; -+ int nr_parts, i, ret = 0; -+ bool dedicated = true; -+@@ -110,9 +113,13 @@ static int parse_fixed_partitions(struct -+ parts[i].size = of_read_number(reg + a_cells, s_cells); -+ parts[i].of_node = pp; -+ -+- partname = of_get_property(pp, "label", &len); -+- if (!partname) -+- partname = of_get_property(pp, "name", &len); -++ if (mangled_rootblock && (i == mangled_rootblock)) { -++ partname = owrtpart; -++ } else { -++ partname = of_get_property(pp, "label", &len); -++ if (!partname) -++ partname = of_get_property(pp, "name", &len); -++ } -+ parts[i].name = partname; -+ -+ if (of_get_property(pp, "read-only", &len)) -+@@ -219,6 +226,18 @@ static int __init ofpart_parser_init(voi -+ return 0; -+ } -+ -++static int __init active_root(char *str) -++{ -++ get_option(&str, &mangled_rootblock); -++ -++ if (!mangled_rootblock) -++ return 1; -++ -++ return 1; -++} -++ -++__setup("mangled_rootblock=", active_root); -++ -+ static void __exit ofpart_parser_exit(void) -+ { -+ deregister_mtd_parser(&ofpart_parser); -diff --git a/target/linux/mvebu/patches-5.4/102-revert_i2c_delay.patch b/target/linux/mvebu/patches-5.4/102-revert_i2c_delay.patch -new file mode 100644 -index 00000000000..930c0f94942 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/102-revert_i2c_delay.patch -@@ -0,0 +1,15 @@ -+--- a/arch/arm/boot/dts/armada-xp.dtsi -++++ b/arch/arm/boot/dts/armada-xp.dtsi -+@@ -237,12 +237,10 @@ -+ }; -+ -+ &i2c0 { -+- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; -+ reg = <0x11000 0x100>; -+ }; -+ -+ &i2c1 { -+- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; -+ reg = <0x11100 0x100>; -+ }; -+ -diff --git a/target/linux/mvebu/patches-5.4/205-armada-385-rd-mtd-partitions.patch b/target/linux/mvebu/patches-5.4/205-armada-385-rd-mtd-partitions.patch -new file mode 100644 -index 00000000000..31bd53b1f3b ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/205-armada-385-rd-mtd-partitions.patch -@@ -0,0 +1,19 @@ -+--- a/arch/arm/boot/dts/armada-388-rd.dts -++++ b/arch/arm/boot/dts/armada-388-rd.dts -+@@ -103,6 +103,16 @@ -+ compatible = "st,m25p128", "jedec,spi-nor"; -+ reg = <0>; /* Chip select 0 */ -+ spi-max-frequency = <108000000>; -++ -++ partition@0 { -++ label = "uboot"; -++ reg = <0 0x400000>; -++ }; -++ -++ partition@1 { -++ label = "firmware"; -++ reg = <0x400000 0xc00000>; -++ }; -+ }; -+ }; -+ -diff --git a/target/linux/mvebu/patches-5.4/206-ARM-mvebu-385-ap-Add-partitions.patch b/target/linux/mvebu/patches-5.4/206-ARM-mvebu-385-ap-Add-partitions.patch -new file mode 100644 -index 00000000000..2057e31c7e9 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/206-ARM-mvebu-385-ap-Add-partitions.patch -@@ -0,0 +1,35 @@ -+From 9861f93a59142a3131870df2521eb2deb73026d7 Mon Sep 17 00:00:00 2001 -+From: Maxime Ripard -+Date: Tue, 13 Jan 2015 11:14:09 +0100 -+Subject: [PATCH 2/2] ARM: mvebu: 385-ap: Add partitions -+ -+Signed-off-by: Maxime Ripard -+--- -+ arch/arm/boot/dts/armada-385-db-ap.dts | 15 +++++++++++++++ -+ 1 file changed, 15 insertions(+) -+ -+--- a/arch/arm/boot/dts/armada-385-db-ap.dts -++++ b/arch/arm/boot/dts/armada-385-db-ap.dts -+@@ -218,19 +218,19 @@ -+ #size-cells = <1>; -+ -+ partition@0 { -+- label = "U-Boot"; -++ label = "u-boot"; -+ reg = <0x00000000 0x00800000>; -+ read-only; -+ }; -+ -+ partition@800000 { -+- label = "uImage"; -++ label = "kernel"; -+ reg = <0x00800000 0x00400000>; -+ read-only; -+ }; -+ -+ partition@c00000 { -+- label = "Root"; -++ label = "ubi"; -+ reg = <0x00c00000 0x3f400000>; -+ }; -+ }; -diff --git a/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch b/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch -new file mode 100644 -index 00000000000..f9677a82f2e ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch -@@ -0,0 +1,21 @@ -+--- a/arch/arm/boot/dts/armada-388-clearfog.dts -++++ b/arch/arm/boot/dts/armada-388-clearfog.dts -+@@ -88,6 +88,18 @@ -+ }; -+ }; -+ -++ mvsw61xx { -++ #address-cells = <1>; -++ #size-cells = <0>; -++ compatible = "marvell,88e6176"; -++ status = "okay"; -++ reg = <0x4>; -++ is-indirect; -++ -++ mii-bus = <&mdio>; -++ cpu-port-0 = <5>; -++ }; -++ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ pinctrl-0 = <&rear_button_pins>; -diff --git a/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch b/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch -new file mode 100644 -index 00000000000..9cc7a113f6c ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch -@@ -0,0 +1,30 @@ -+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi -++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi -+@@ -171,6 +171,7 @@ -+ status = "okay"; -+ -+ switch@0 { -++ status = "disabled"; -+ compatible = "marvell,mv88e6085"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+--- a/arch/arm/boot/dts/armada-388-clearfog.dts -++++ b/arch/arm/boot/dts/armada-388-clearfog.dts -+@@ -161,6 +161,7 @@ -+ status = "okay"; -+ -+ switch@4 { -++ status = "disabled"; -+ compatible = "marvell,mv88e6085"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+@@ -413,6 +413,7 @@ -+ status = "okay"; -+ -+ switch@0 { -++ status = "disabled"; -+ compatible = "marvell,mv88e6085"; -+ #address-cells = <1>; -+ #size-cells = <0>; -diff --git a/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch b/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch -new file mode 100644 -index 00000000000..935c8fe0935 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch -@@ -0,0 +1,10 @@ -+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+@@ -543,3 +543,7 @@ -+ }; -+ }; -+ }; -++ -++&coherencyfab { -++ broken-idle; -++}; -diff --git a/target/linux/mvebu/patches-5.4/240-linksys-status-led.patch b/target/linux/mvebu/patches-5.4/240-linksys-status-led.patch -new file mode 100644 -index 00000000000..e5e83572c9e ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/240-linksys-status-led.patch -@@ -0,0 +1,50 @@ -+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi -++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi -+@@ -14,6 +14,13 @@ -+ compatible = "linksys,armada385", "marvell,armada385", -+ "marvell,armada380"; -+ -++ aliases { -++ led-boot = &led_power; -++ led-failsafe = &led_power; -++ led-running = &led_power; -++ led-upgrade = &led_power; -++ }; -++ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+@@ -71,7 +78,7 @@ -+ pinctrl-0 = <&gpio_leds_pins>; -+ pinctrl-names = "default"; -+ -+- power { -++ led_power: power { -+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; -+ default-state = "on"; -+ }; -+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+@@ -26,6 +26,13 @@ -+ compatible = "linksys,mamba", "marvell,armadaxp-mv78230", -+ "marvell,armadaxp", "marvell,armada-370-xp"; -+ -++ aliases { -++ led-boot = &led_power; -++ led-failsafe = &led_power; -++ led-running = &led_power; -++ led-upgrade = &led_power; -++ }; -++ -+ chosen { -+ bootargs = "console=ttyS0,115200"; -+ stdout-path = &uart0; -+@@ -197,7 +204,7 @@ -+ pinctrl-0 = <&power_led_pin>; -+ pinctrl-names = "default"; -+ -+- power { -++ led_power: power { -+ label = "mamba:white:power"; -+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; -+ default-state = "on"; -diff --git a/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch b/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch -new file mode 100644 -index 00000000000..4a5ea361449 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch -@@ -0,0 +1,35 @@ -+The hardware queue scheduling is apparently configured with fixed -+priorities, which creates a nasty fairness issue where traffic from one -+CPU can starve traffic from all other CPUs. -+ -+Work around this issue by forcing all tx packets to go through one CPU, -+until this issue is fixed properly. -+ -+Signed-off-by: Felix Fietkau -+--- -+--- a/drivers/net/ethernet/marvell/mvneta.c -++++ b/drivers/net/ethernet/marvell/mvneta.c -+@@ -4272,6 +4272,15 @@ static int mvneta_ethtool_set_eee(struct -+ return phylink_ethtool_set_eee(pp->phylink, eee); -+ } -+ -++static u16 mvneta_select_queue(struct net_device *dev, struct sk_buff *skb, -++ struct net_device *sb_dev, -++ select_queue_fallback_t fallback) -++{ -++ /* XXX: hardware queue scheduling is broken, -++ * use only one queue until it is fixed */ -++ return 0; -++} -++ -+ static const struct net_device_ops mvneta_netdev_ops = { -+ .ndo_open = mvneta_open, -+ .ndo_stop = mvneta_stop, -+@@ -4282,6 +4291,7 @@ static const struct net_device_ops mvnet -+ .ndo_fix_features = mvneta_fix_features, -+ .ndo_get_stats64 = mvneta_get_stats64, -+ .ndo_do_ioctl = mvneta_ioctl, -++ .ndo_select_queue = mvneta_select_queue, -+ }; -+ -+ static const struct ethtool_ops mvneta_eth_tool_ops = { -diff --git a/target/linux/mvebu/patches-5.4/400-cpuidle-mvebu-indicate-failure-to-enter-deeper-sleep.patch b/target/linux/mvebu/patches-5.4/400-cpuidle-mvebu-indicate-failure-to-enter-deeper-sleep.patch -new file mode 100644 -index 00000000000..29f36be460d ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/400-cpuidle-mvebu-indicate-failure-to-enter-deeper-sleep.patch -@@ -0,0 +1,40 @@ -+From c28b2d367da8a471482e6a4aa8337ab6369a80c2 Mon Sep 17 00:00:00 2001 -+From: Russell King -+Date: Sat, 3 Oct 2015 09:13:05 +0100 -+Subject: cpuidle: mvebu: indicate failure to enter deeper sleep states -+ -+The cpuidle ->enter method expects the return value to be the sleep -+state we entered. Returning negative numbers or other codes is not -+permissible since coupled CPU idle was merged. -+ -+At least some of the mvebu_v7_cpu_suspend() implementations return the -+value from cpu_suspend(), which returns zero if the CPU vectors back -+into the kernel via cpu_resume() (the success case), or the non-zero -+return value of the suspend actor, or one (failure cases). -+ -+We do not want to be returning the failure case value back to CPU idle -+as that indicates that we successfully entered one of the deeper idle -+states. Always return zero instead, indicating that we slept for the -+shortest amount of time. -+ -+Signed-off-by: Russell King -+--- -+ drivers/cpuidle/cpuidle-mvebu-v7.c | 6 +++++- -+ 1 file changed, 5 insertions(+), 1 deletion(-) -+ -+--- a/drivers/cpuidle/cpuidle-mvebu-v7.c -++++ b/drivers/cpuidle/cpuidle-mvebu-v7.c -+@@ -39,8 +39,12 @@ static int mvebu_v7_enter_idle(struct cp -+ ret = mvebu_v7_cpu_suspend(deepidle); -+ cpu_pm_exit(); -+ -++ /* -++ * If we failed to enter the desired state, indicate that we -++ * slept lightly. -++ */ -+ if (ret) -+- return ret; -++ return 0; -+ -+ return index; -+ } -diff --git a/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch b/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch -new file mode 100644 -index 00000000000..2bbb6471538 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch -@@ -0,0 +1,60 @@ -+From 287b9df160b6159f8d385424904f8bac501280c1 Mon Sep 17 00:00:00 2001 -+From: Russell King -+Date: Sat, 9 Jul 2016 10:58:16 +0100 -+Subject: pci: mvebu: time out reset on link up -+ -+If the port reports that the link is up while we are resetting, there's -+little point in waiting for the full duration. -+ -+Signed-off-by: Russell King -+--- -+ drivers/pci/controller/pci-mvebu.c | 20 ++++++++++++++------ -+ 1 file changed, 14 insertions(+), 6 deletions(-) -+ -+--- a/drivers/pci/controller/pci-mvebu.c -++++ b/drivers/pci/controller/pci-mvebu.c -+@@ -1112,6 +1112,7 @@ static int mvebu_pcie_powerup(struct mve -+ -+ if (port->reset_gpio) { -+ u32 reset_udelay = PCI_PM_D3COLD_WAIT * 1000; -++ unsigned int i; -+ -+ of_property_read_u32(port->dn, "reset-delay-us", -+ &reset_udelay); -+@@ -1119,7 +1120,13 @@ static int mvebu_pcie_powerup(struct mve -+ udelay(100); -+ -+ gpiod_set_value_cansleep(port->reset_gpio, 0); -+- msleep(reset_udelay / 1000); -++ for (i = 0; i < reset_udelay; i += 1000) { -++ if (mvebu_pcie_link_up(port)) -++ break; -++ msleep(1); -++ } -++ -++ printk("%s: reset completed in %dus\n", port->name, i); -+ } -+ -+ return 0; -+@@ -1283,15 +1290,16 @@ static int mvebu_pcie_probe(struct platf -+ if (!child) -+ continue; -+ -+- ret = mvebu_pcie_powerup(port); -+- if (ret < 0) -+- continue; -+- -+ port->base = mvebu_pcie_map_registers(pdev, child, port); -+ if (IS_ERR(port->base)) { -+ dev_err(dev, "%s: cannot map registers\n", port->name); -+ port->base = NULL; -+- mvebu_pcie_powerdown(port); -++ continue; -++ } -++ -++ ret = mvebu_pcie_powerup(port); -++ if (ret < 0) { -++ port->base = NULL; -+ continue; -+ } -+ -diff --git a/target/linux/mvebu/patches-5.4/412-ARM-dts-armada388-clearfog-emmc-on-clearfog-base.patch b/target/linux/mvebu/patches-5.4/412-ARM-dts-armada388-clearfog-emmc-on-clearfog-base.patch -new file mode 100644 -index 00000000000..dd2bef7f632 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/412-ARM-dts-armada388-clearfog-emmc-on-clearfog-base.patch -@@ -0,0 +1,87 @@ -+From 8137da20701c776ad3481115305a5e8e410871ba Mon Sep 17 00:00:00 2001 -+From: Russell King -+Date: Tue, 29 Nov 2016 10:15:45 +0000 -+Subject: ARM: dts: armada388-clearfog: emmc on clearfog base -+ -+Signed-off-by: Russell King -+--- -+ arch/arm/boot/dts/armada-388-clearfog-base.dts | 1 + -+ .../dts/armada-38x-solidrun-microsom-emmc.dtsi | 62 ++++++++++++++++++++++ -+ 2 files changed, 63 insertions(+) -+ create mode 100644 arch/arm/boot/dts/armada-38x-solidrun-microsom-emmc.dtsi -+ -+--- a/arch/arm/boot/dts/armada-388-clearfog-base.dts -++++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts -+@@ -7,6 +7,7 @@ -+ -+ /dts-v1/; -+ #include "armada-388-clearfog.dtsi" -++#include "armada-38x-solidrun-microsom-emmc.dtsi" -+ -+ / { -+ model = "SolidRun Clearfog Base A1"; -+--- /dev/null -++++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom-emmc.dtsi -+@@ -0,0 +1,62 @@ -++/* -++ * Device Tree file for SolidRun Armada 38x Microsom add-on for eMMC -++ * -++ * Copyright (C) 2015 Russell King -++ * -++ * This board is in development; the contents of this file work with -++ * the A1 rev 2.0 of the board, which does not represent final -++ * production board. Things will change, don't expect this file to -++ * remain compatible info the future. -++ * -++ * This file is dual-licensed: you can use it either under the terms -++ * of the GPL or the X11 license, at your option. Note that this dual -++ * licensing only applies to this file, and not this project as a -++ * whole. -++ * -++ * a) This file is free software; you can redistribute it and/or -++ * modify it under the terms of the GNU General Public License -++ * version 2 as published by the Free Software Foundation. -++ * -++ * This file is distributed in the hope that it will be useful -++ * but WITHOUT ANY WARRANTY; without even the implied warranty of -++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -++ * GNU General Public License for more details. -++ * -++ * Or, alternatively -++ * -++ * b) Permission is hereby granted, free of charge, to any person -++ * obtaining a copy of this software and associated documentation -++ * files (the "Software"), to deal in the Software without -++ * restriction, including without limitation the rights to use -++ * copy, modify, merge, publish, distribute, sublicense, and/or -++ * sell copies of the Software, and to permit persons to whom the -++ * Software is furnished to do so, subject to the following -++ * conditions: -++ * -++ * The above copyright notice and this permission notice shall be -++ * included in all copies or substantial portions of the Software. -++ * -++ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND -++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY -++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -++ * OTHER DEALINGS IN THE SOFTWARE. -++ */ -++/ { -++ soc { -++ internal-regs { -++ sdhci@d8000 { -++ bus-width = <4>; -++ no-1-8-v; -++ non-removable; -++ pinctrl-0 = <µsom_sdhci_pins>; -++ pinctrl-names = "default"; -++ status = "okay"; -++ wp-inverted; -++ }; -++ }; -++ }; -++}; -diff --git a/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch b/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch -new file mode 100644 -index 00000000000..d64bd8084ea ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch -@@ -0,0 +1,124 @@ -+From 09a0122c74ec076e08512f1b00b7ccb8a450282f Mon Sep 17 00:00:00 2001 -+From: Russell King -+Date: Tue, 29 Nov 2016 10:15:43 +0000 -+Subject: ARM: dts: armada388-clearfog: document MPP usage -+ -+Signed-off-by: Russell King -+--- -+ arch/arm/boot/dts/armada-388-clearfog-base.dts | 51 ++++++++++++++++++++++++++ -+ arch/arm/boot/dts/armada-388-clearfog.dts | 50 +++++++++++++++++++++++++ -+ 2 files changed, 101 insertions(+) -+ -+--- a/arch/arm/boot/dts/armada-388-clearfog-base.dts -++++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts -+@@ -67,3 +67,54 @@ -+ marvell,function = "gpio"; -+ }; -+ }; -++ -++/* -++MPP -++18: pu gpio pca9655 int -++19: gpio phy reset -++20: pu gpio sd0 detect -++21: sd0:cmd -++22: pd gpio mikro int -++23: -++ -++24: ua1:rxd mikro rx -++25: ua1:txd mikro tx -++26: pu i2c1:sck -++27: pu i2c1:sda -++28: sd0:clk -++29: pd gpio mikro rst -++30: -++31: -++ -++32: -++33: -++34: -++35: -++36: -++37: sd0:d3 -++38: sd0:d0 -++39: sd0:d1 -++ -++40: sd0:d2 -++41: -++42: -++43: spi1:cs2 mikro cs -++44: gpio rear button sw3 -++45: ref:clk_out0 phy#0 clock -++46: ref:clk_out1 phy#1 clock -++47: -++ -++48: gpio J18 spare gpio -++49: gpio U10 I2C_IRQ(GNSS) -++50: gpio board id? -++51: -++52: -++53: -++54: gpio mikro pwm -++55: -++ -++56: pu spi1:mosi mikro mosi -++57: pd spi1:sck mikro sck -++58: spi1:miso mikro miso -++59: -++*/ -+--- a/arch/arm/boot/dts/armada-388-clearfog.dts -++++ b/arch/arm/boot/dts/armada-388-clearfog.dts -+@@ -249,3 +249,53 @@ -+ */ -+ pinctrl-0 = <&spi1_pins &clearfog_spi1_cs_pins &mikro_spi_pins>; -+ }; -++/* -+++#define A38x_CUSTOMER_BOARD_1_MPP16_23 0x00400011 -++MPP18: gpio ? (pca9655 int?) -++MPP19: gpio ? (clkreq?) -++MPP20: gpio ? (sd0 detect) -++MPP21: sd0:cmd x sd0 -++MPP22: gpio x mikro int -++MPP23: gpio x switch irq -+++#define A38x_CUSTOMER_BOARD_1_MPP24_31 0x22043333 -++MPP24: ua1:rxd x mikro rx -++MPP25: ua1:txd x mikro tx -++MPP26: i2c1:sck x mikro sck -++MPP27: i2c1:sda x mikro sda -++MPP28: sd0:clk x sd0 -++MPP29: gpio x mikro rst -++MPP30: ge1:txd2 ? (config) -++MPP31: ge1:txd3 ? (config) -+++#define A38x_CUSTOMER_BOARD_1_MPP32_39 0x44400002 -++MPP32: ge1:txctl ? (unused) -++MPP33: gpio ? (pic_com0) -++MPP34: gpio x rear button (pic_com1) -++MPP35: gpio ? (pic_com2) -++MPP36: gpio ? (unused) -++MPP37: sd0:d3 x sd0 -++MPP38: sd0:d0 x sd0 -++MPP39: sd0:d1 x sd0 -+++#define A38x_CUSTOMER_BOARD_1_MPP40_47 0x41144004 -++MPP40: sd0:d2 x sd0 -++MPP41: gpio x switch reset -++MPP42: gpio ? sw1-1 -++MPP43: spi1:cs2 x mikro cs -++MPP44: sata3:prsnt ? (unused) -++MPP45: ref:clk_out0 ? -++MPP46: ref:clk_out1 x switch clk -++MPP47: 4 ? (unused) -+++#define A38x_CUSTOMER_BOARD_1_MPP48_55 0x40333333 -++MPP48: tdm:pclk -++MPP49: tdm:fsync -++MPP50: tdm:drx -++MPP51: tdm:dtx -++MPP52: tdm:int -++MPP53: tdm:rst -++MPP54: gpio ? (pwm) -++MPP55: spi1:cs1 x slic -+++#define A38x_CUSTOMER_BOARD_1_MPP56_63 0x00004444 -++MPP56: spi1:mosi x mikro mosi -++MPP57: spi1:sck x mikro sck -++MPP58: spi1:miso x mikro miso -++MPP59: spi1:cs0 x w25q32 -++*/ -diff --git a/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch b/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch -new file mode 100644 -index 00000000000..880b0d92417 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch -@@ -0,0 +1,40 @@ -+From eefe328439642101774f0f5c4ea0dc6ba1cfb687 Mon Sep 17 00:00:00 2001 -+From: Ding Tao -+Date: Fri, 26 Oct 2018 11:50:27 +0000 -+Subject: [PATCH] arm64: dts: marvell: armada37xx: Add emmc/sdio pinctrl -+ definition -+ -+Add emmc/sdio pinctrl definition for marvell armada37xx SoCs. -+ -+Signed-off-by: Ding Tao -+Signed-off-by: Gregory CLEMENT -+--- -+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 10 ++++++++++ -+ 1 file changed, 10 insertions(+) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -+@@ -221,6 +221,11 @@ -+ groups = "uart2"; -+ function = "uart"; -+ }; -++ -++ mmc_pins: mmc-pins { -++ groups = "emmc_nb"; -++ function = "emmc"; -++ }; -+ }; -+ -+ nb_pm: syscon@14000 { -+@@ -253,6 +258,11 @@ -+ function = "mii"; -+ }; -+ -++ sdio_pins: sdio-pins { -++ groups = "sdio_sb"; -++ function = "sdio"; -++ }; -++ -+ }; -+ -+ eth0: ethernet@30000 { -diff --git a/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch b/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch -new file mode 100644 -index 00000000000..77af3d1219d ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch -@@ -0,0 +1,49 @@ -+From 43ebc7c1b3ed8198b9acf3019eca16e722f7331c Mon Sep 17 00:00:00 2001 -+From: Ding Tao -+Date: Fri, 26 Oct 2018 11:50:28 +0000 -+Subject: [PATCH] arm64: dts: marvell: armada-37xx: Enable emmc on espressobin -+ -+The ESPRESSObin board has a emmc interface available on U11: declare it -+and let the bootloader enable it if the emmc is present. -+ -+[gregory.clement@bootlin.com: disable the emmc by default] -+Signed-off-by: Ding Tao -+Signed-off-by: Gregory CLEMENT -+--- -+ .../dts/marvell/armada-3720-espressobin.dts | 22 +++++++++++++++++++ -+ 1 file changed, 22 insertions(+) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts -++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts -+@@ -60,9 +60,31 @@ -+ cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>; -+ marvell,pad-type = "sd"; -+ vqmmc-supply = <&vcc_sd_reg1>; -++ -++ pinctrl-names = "default"; -++ pinctrl-0 = <&sdio_pins>; -+ status = "okay"; -+ }; -+ -++/* U11 */ -++&sdhci0 { -++ non-removable; -++ bus-width = <8>; -++ mmc-ddr-1_8v; -++ mmc-hs400-1_8v; -++ marvell,xenon-emmc; -++ marvell,xenon-tun-count = <9>; -++ marvell,pad-type = "fixed-1-8v"; -++ -++ pinctrl-names = "default"; -++ pinctrl-0 = <&mmc_pins>; -++/* -++ * This eMMC is not populated on all boards, so disable it by -++ * default and let the bootloader enable it, if it is present -++ */ -++ status = "disabled"; -++}; -++ -+ &spi0 { -+ status = "okay"; -+ -diff --git a/target/linux/mvebu/patches-5.4/520-arm64-dts-marvell-armada37xx-Add-eth0-alias.patch b/target/linux/mvebu/patches-5.4/520-arm64-dts-marvell-armada37xx-Add-eth0-alias.patch -new file mode 100644 -index 00000000000..e989f59d5cd ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/520-arm64-dts-marvell-armada37xx-Add-eth0-alias.patch -@@ -0,0 +1,20 @@ -+From be893f672e340b56ca60f2f6c32fdd713a5852f5 Mon Sep 17 00:00:00 2001 -+From: Kevin Mihelich -+Date: Tue, 4 Jul 2017 19:25:28 -0600 -+Subject: arm64: dts: marvell: armada37xx: Add eth0 alias -+ -+Signed-off-by: Kevin Mihelich -+--- -+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -+@@ -18,6 +18,7 @@ -+ #size-cells = <2>; -+ -+ aliases { -++ ethernet0 = ð0; -+ serial0 = &uart0; -+ serial1 = &uart1; -+ }; -diff --git a/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch b/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch -new file mode 100644 -index 00000000000..0f39b2a3c2c ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch -@@ -0,0 +1,58 @@ -+From 3217cdfe8a3eae76fafbebbe407be5985a7fd4c2 Mon Sep 17 00:00:00 2001 -+From: Tomasz Maciej Nowak -+Date: Mon, 31 Dec 2018 14:18:50 +0100 -+Subject: [PATCH] arm64: dts: armada-3720-espressobin: correct spi node -+ -+The manufacturer of this board, ships it with various SPI NOR chips and -+increments U-Boot bootloader version along the time. There is no way to -+tell which is placed on the board since no revision bump takes place. -+This creates two issues. -+ -+The first, cosmetic. Since the SPI chip may differ, there's message on -+boot stating that kernel expected w25q32dw and found different one. To -+correct this, remove optional device-specific compatible string. Being -+here lets replace bogus "spi-flash" string with proper one. -+ -+The second is linked to partitions layout, it changed after commit [1] -+in Marvells downstream U-Boot fork, shifting environment location to the -+end of boot device. Since the new boards can have U-Boot with this -+change it can lead to improper results writing or reading from these -+partitions. We can't tell if users will update bootloader to recent -+version, so let's drop current layout. -+ -+1. https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/81e7251252aefe1a6b829ed05f3586320cb45372 -+ -+Signed-off-by: Tomasz Maciej Nowak -+--- -+ .../dts/marvell/armada-3720-espressobin.dts | 18 +----------------- -+ 1 file changed, 1 insertion(+), 17 deletions(-) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts -++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts -+@@ -90,25 +90,9 @@ -+ -+ flash@0 { -+ reg = <0>; -+- compatible = "winbond,w25q32dw", "jedec,spi-flash"; -++ compatible = "jedec,spi-nor"; -+ spi-max-frequency = <104000000>; -+ m25p,fast-read; -+- -+- partitions { -+- compatible = "fixed-partitions"; -+- #address-cells = <1>; -+- #size-cells = <1>; -+- -+- partition@0 { -+- label = "uboot"; -+- reg = <0 0x180000>; -+- }; -+- -+- partition@180000 { -+- label = "ubootenv"; -+- reg = <0x180000 0x10000>; -+- }; -+- }; -+ }; -+ }; -+ -diff --git a/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch b/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch -new file mode 100644 -index 00000000000..cea0d1db44f ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch -@@ -0,0 +1,26 @@ -+From 6ea9a1ee9367fb35acff1c08a0dc4213ff4687a0 Mon Sep 17 00:00:00 2001 -+From: Tomasz Maciej Nowak -+Date: Tue, 9 Apr 2019 15:53:42 +0200 -+Subject: [PATCH] arm64: dts: marvell: armada-3720-espressobin: add ports -+ phandle -+ -+Instead of referencing the whole mdio node, add ports phandle to adjust -+port labels in dts for different hardware iterations of ESPRESSObin -+boards. -+ -+Signed-off-by: Tomasz Maciej Nowak -+--- -+ arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts -++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts -+@@ -132,7 +132,7 @@ -+ -+ dsa,member = <0 0>; -+ -+- ports { -++ ports: ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -diff --git a/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch b/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch -new file mode 100644 -index 00000000000..3fd561db3a6 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch -@@ -0,0 +1,44 @@ -+From 5e79c0c381eb085a2aa2da175eedea1950f07520 Mon Sep 17 00:00:00 2001 -+From: Tomasz Maciej Nowak -+Date: Tue, 30 Apr 2019 15:37:34 +0200 -+Subject: [PATCH] Revert "PCI: aardvark: Convert to use pci_host_probe()" -+ -+This reverts commit c8e144f8ab00e6c4a070a932ef9c57db09aa41cf. -+--- -+ drivers/pci/controller/pci-aardvark.c | 12 +++++++++++- -+ 1 file changed, 11 insertions(+), 1 deletion(-) -+ -+--- a/drivers/pci/controller/pci-aardvark.c -++++ b/drivers/pci/controller/pci-aardvark.c -+@@ -843,6 +843,7 @@ static int advk_pcie_probe(struct platfo -+ struct device *dev = &pdev->dev; -+ struct advk_pcie *pcie; -+ struct resource *res; -++ struct pci_bus *bus, *child; -+ struct pci_host_bridge *bridge; -+ int ret, irq; -+ -+@@ -896,13 +897,22 @@ static int advk_pcie_probe(struct platfo -+ bridge->map_irq = of_irq_parse_and_map_pci; -+ bridge->swizzle_irq = pci_common_swizzle; -+ -+- ret = pci_host_probe(bridge); -++ ret = pci_scan_root_bus_bridge(bridge); -+ if (ret < 0) { -+ advk_pcie_remove_msi_irq_domain(pcie); -+ advk_pcie_remove_irq_domain(pcie); -+ return ret; -+ } -+ -++ bus = bridge->bus; -++ -++ pci_bus_size_bridges(bus); -++ pci_bus_assign_resources(bus); -++ -++ list_for_each_entry(child, &bus->children, node) -++ pcie_bus_configure_settings(child); -++ -++ pci_bus_add_devices(bus); -+ return 0; -+ } -+ -diff --git a/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch b/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch -new file mode 100644 -index 00000000000..204d6e2aec4 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch -@@ -0,0 +1,138 @@ -+From patchwork Thu Sep 28 12:58:34 2017 -+Content-Type: text/plain; charset="utf-8" -+MIME-Version: 1.0 -+Content-Transfer-Encoding: 7bit -+Subject: [v2, -+ 3/7] PCI: aardvark: set host and device to the same MAX payload size -+X-Patchwork-Submitter: Thomas Petazzoni -+X-Patchwork-Id: 819587 -+Message-Id: <20170928125838.11887-4-thomas.petazzoni@free-electrons.com> -+To: Bjorn Helgaas , linux-pci@vger.kernel.org -+Cc: Jason Cooper , Andrew Lunn , -+ Sebastian Hesselbarth , Gregory Clement -+ , -+ Nadav Haklai , Hanna Hawa , -+ Yehuda Yitschak , -+ linux-arm-kernel@lists.infradead.org, Antoine Tenart -+ , =?utf-8?q?Miqu=C3=A8l_Raynal?= -+ , Victor Gu , -+ Thomas Petazzoni -+Date: Thu, 28 Sep 2017 14:58:34 +0200 -+From: Thomas Petazzoni -+List-Id: -+ -+From: Victor Gu -+ -+Since the Aardvark does not implement a PCIe root bus, the Linux PCIe -+subsystem will not align the MAX payload size between the host and the -+device. This patch ensures that the host and device have the same MAX -+payload size, fixing a number of problems with various PCIe devices. -+ -+This is part of fixing bug -+https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was -+reported as the user to be important to get a Intel 7260 mini-PCIe -+WiFi card working. -+ -+Fixes: Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") -+Signed-off-by: Victor Gu -+Reviewed-by: Evan Wang -+Reviewed-by: Nadav Haklai -+[Thomas: tweak commit log.] -+Signed-off-by: Thomas Petazzoni -+--- -+ drivers/pci/controller/pci-aardvark.c | 60 ++++++++++++++++++++++++++++++++++++++++- -+ 1 file changed, 59 insertions(+), 1 deletion(-) -+ -+--- a/drivers/pci/controller/pci-aardvark.c -++++ b/drivers/pci/controller/pci-aardvark.c -+@@ -29,9 +29,11 @@ -+ #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 -+ #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) -+ #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 -++#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ 0x2 -+ #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) -+ #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 -+ #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2 -++#define PCIE_CORE_MPS_UNIT_BYTE 128 -+ #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 -+ #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) -+ #define PCIE_CORE_LINK_TRAINING BIT(5) -+@@ -253,7 +255,8 @@ static void advk_pcie_setup_hw(struct ad -+ -+ /* Set PCIe Device Control and Status 1 PF0 register */ -+ reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | -+- (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | -++ (PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ << -++ PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | -+ PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | -+ (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << -+ PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); -+@@ -838,6 +841,58 @@ out_release_res: -+ return err; -+ } -+ -++static int advk_pcie_find_smpss(struct pci_dev *dev, void *data) -++{ -++ u8 *smpss = data; -++ -++ if (!dev) -++ return 0; -++ -++ if (!pci_is_pcie(dev)) -++ return 0; -++ -++ if (*smpss > dev->pcie_mpss) -++ *smpss = dev->pcie_mpss; -++ -++ return 0; -++} -++ -++static int advk_pcie_bus_configure_mps(struct pci_dev *dev, void *data) -++{ -++ int mps; -++ -++ if (!dev) -++ return 0; -++ -++ if (!pci_is_pcie(dev)) -++ return 0; -++ -++ mps = PCIE_CORE_MPS_UNIT_BYTE << *(u8 *)data; -++ pcie_set_mps(dev, mps); -++ -++ return 0; -++} -++ -++static void advk_pcie_configure_mps(struct pci_bus *bus, struct advk_pcie *pcie) -++{ -++ u8 smpss = PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ; -++ u32 reg; -++ -++ /* Find the minimal supported MAX payload size */ -++ advk_pcie_find_smpss(bus->self, &smpss); -++ pci_walk_bus(bus, advk_pcie_find_smpss, &smpss); -++ -++ /* Configure RC MAX payload size */ -++ reg = advk_readl(pcie, PCIE_CORE_DEV_CTRL_STATS_REG); -++ reg &= ~PCI_EXP_DEVCTL_PAYLOAD; -++ reg |= smpss << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT; -++ advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); -++ -++ /* Configure device MAX payload size */ -++ advk_pcie_bus_configure_mps(bus->self, &smpss); -++ pci_walk_bus(bus, advk_pcie_bus_configure_mps, &smpss); -++} -++ -+ static int advk_pcie_probe(struct platform_device *pdev) -+ { -+ struct device *dev = &pdev->dev; -+@@ -912,6 +967,9 @@ static int advk_pcie_probe(struct platfo -+ list_for_each_entry(child, &bus->children, node) -+ pcie_bus_configure_settings(child); -+ -++ /* Configure the MAX pay load size */ -++ advk_pcie_configure_mps(bus, pcie); -++ -+ pci_bus_add_devices(bus); -+ return 0; -+ } -diff --git a/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch b/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch -new file mode 100644 -index 00000000000..b6fcec81f8f ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch -@@ -0,0 +1,55 @@ -+From patchwork Thu Sep 28 12:58:36 2017 -+Content-Type: text/plain; charset="utf-8" -+MIME-Version: 1.0 -+Content-Transfer-Encoding: 7bit -+Subject: [v2,5/7] PCI: aardvark: disable LOS state by default -+X-Patchwork-Submitter: Thomas Petazzoni -+X-Patchwork-Id: 819590 -+Message-Id: <20170928125838.11887-6-thomas.petazzoni@free-electrons.com> -+To: Bjorn Helgaas , linux-pci@vger.kernel.org -+Cc: Jason Cooper , Andrew Lunn , -+ Sebastian Hesselbarth , Gregory Clement -+ , -+ Nadav Haklai , Hanna Hawa , -+ Yehuda Yitschak , -+ linux-arm-kernel@lists.infradead.org, Antoine Tenart -+ , =?utf-8?q?Miqu=C3=A8l_Raynal?= -+ , Victor Gu , -+ Thomas Petazzoni -+Date: Thu, 28 Sep 2017 14:58:36 +0200 -+From: Thomas Petazzoni -+List-Id: -+ -+From: Victor Gu -+ -+Some PCIe devices do not support LOS, and will cause timeouts if the -+root complex forces the LOS state. This patch disables the LOS state -+by default. -+ -+This is part of fixing bug -+https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was -+reported as the user to be important to get a Intel 7260 mini-PCIe -+WiFi card working. -+ -+Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") -+Signed-off-by: Victor Gu -+Reviewed-by: Evan Wang -+Reviewed-by: Nadav Haklai -+[Thomas: tweak commit log.] -+Signed-off-by: Thomas Petazzoni -+--- -+ drivers/pci/controller/pci-aardvark.c | 3 +-- -+ 1 file changed, 1 insertion(+), 2 deletions(-) -+ -+--- a/drivers/pci/controller/pci-aardvark.c -++++ b/drivers/pci/controller/pci-aardvark.c -+@@ -324,8 +324,7 @@ static void advk_pcie_setup_hw(struct ad -+ -+ advk_pcie_wait_for_link(pcie); -+ -+- reg = PCIE_CORE_LINK_L0S_ENTRY | -+- (1 << PCIE_CORE_LINK_WIDTH_SHIFT); -++ reg = (1 << PCIE_CORE_LINK_WIDTH_SHIFT); -+ advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); -+ -+ reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); -diff --git a/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch b/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch -new file mode 100644 -index 00000000000..0ac34761473 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch -@@ -0,0 +1,43 @@ -+From f70b629e488cc3f2a325ac35476f4f7ae502c5d0 Mon Sep 17 00:00:00 2001 -+From: Tomasz Maciej Nowak -+Date: Thu, 14 Jun 2018 14:24:40 +0200 -+Subject: [PATCH 1/2] PCI: aardvark: allow to specify link capability -+ -+Use DT of_pci_get_max_link_speed() facility to allow specifying link -+capability. If none or unspecified value is given it falls back to gen2, -+which is default for Armada 3700 SoC. -+ -+Signed-off-by: Tomasz Maciej Nowak -+--- -+ drivers/pci/controller/pci-aardvark.c | 11 +++++++++-- -+ 1 file changed, 9 insertions(+), 2 deletions(-) -+ -+--- a/drivers/pci/controller/pci-aardvark.c -++++ b/drivers/pci/controller/pci-aardvark.c -+@@ -233,6 +233,8 @@ static int advk_pcie_wait_for_link(struc -+ -+ static void advk_pcie_setup_hw(struct advk_pcie *pcie) -+ { -++ struct device *dev = &pcie->pdev->dev; -++ struct device_node *node = dev->of_node; -+ u32 reg; -+ -+ /* Set to Direct mode */ -+@@ -267,10 +269,15 @@ static void advk_pcie_setup_hw(struct ad -+ PCIE_CORE_CTRL2_TD_ENABLE; -+ advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); -+ -+- /* Set GEN2 */ -++ /* Set GEN */ -+ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); -+ reg &= ~PCIE_GEN_SEL_MSK; -+- reg |= SPEED_GEN_2; -++ if (of_pci_get_max_link_speed(node) == 1) -++ reg |= SPEED_GEN_1; -++ else if (of_pci_get_max_link_speed(node) == 3) -++ reg |= SPEED_GEN_3; -++ else -++ reg |= SPEED_GEN_2; -+ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); -+ -+ /* Set lane X1 */ -diff --git a/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch b/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch -new file mode 100644 -index 00000000000..88080d64caa ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch -@@ -0,0 +1,73 @@ -+From 33f8fdcedb01680427328d710594facef7a0092c Mon Sep 17 00:00:00 2001 -+From: Tomasz Maciej Nowak -+Date: Thu, 14 Jun 2018 14:40:26 +0200 -+Subject: [PATCH 2/2] arm64: dts: armada-3720-espressobin: set max link to gen1 -+ -+Since the beginning there's been an issue with initializing the Atheros -+based MiniPCIe wireless cards. Here's an example of kerenel log: -+ -+ OF: PCI: host bridge /soc/pcie@d0070000 ranges: -+ OF: PCI: MEM 0xe8000000..0xe8ffffff -> 0xe8000000 -+ OF: PCI: IO 0xe9000000..0xe900ffff -> 0xe9000000 -+ advk-pcie d0070000.pcie: link up -+ advk-pcie d0070000.pcie: PCI host bridge to bus 0000:00 -+ pci_bus 0000:00: root bus resource [bus 00-ff] -+ pci_bus 0000:00: root bus resource [mem0xe8000000-0xe8ffffff] -+ pci_bus 0000:00: root bus resource [io 0x0000-0xffff](bus address [0xe9000000-0xe900ffff]) -+ pci 0000:00:00.0: BAR 0: assigned [mem0xe8000000-0xe801ffff 64bit] -+ pci 0000:00:00.0: BAR 6: assigned [mem0xe8020000-0xe802ffff pref] -+ [...] -+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x3c -+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x44 -+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4 -+ ath9k 0000:00:00.0: enabling device (0000 -> 0002) -+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x3c -+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0xc -+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4 -+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x40 -+ ath9k 0000:00:00.0: request_irq failed -+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4 -+ ath9k: probe of 0000:00:00.0 failed with error -22 -+ -+The same happens for ath5k cards, while ath10k card didn't appear at -+all (not detected): -+ -+ OF: PCI: host bridge /soc/pcie@d0070000 ranges: -+ OF: PCI: MEM 0xe8000000..0xe8ffffff -> 0xe8000000 -+ OF: PCI: IO 0xe9000000..0xe900ffff -> 0xe9000000 -+ advk-pcie d0070000.pcie: link never came up -+ advk-pcie d0070000.pcie: PCI host bridge to bus 0000:00 -+ pci_bus 0000:00: root bus resource [bus 00-ff] -+ pci_bus 0000:00: root bus resource [mem0xe8000000-0xe8ffffff] -+ pci_bus 0000:00: root bus resource [io 0x0000-0xffff](bus address [0xe9000000-0xe900ffff]) -+ advk-pcie d0070000.pcie: config read/write timed out -+ -+Following the issue on esppressobin.net forum [1] the workaround seems -+to be limiting the speed of PCIe bridge to 1st generation. This fixed -+the initialisation of all tested Atheros wireless cards. -+The patch in the forum thread swaped registers which would limit speed -+for all Armada 3700 based boards. The approach in this patch, in -+conjunction with "PCI: aardvark: allow to specify link capability" patch -+is less invasive, it only touches the affected board. -+ -+For the record, the iwlwifi and mt76 cards were not affected by this -+issue. -+ -+1. http://espressobin.net/forums/topic/which-pcie-wlan-cards-are-supported -+ -+Signed-off-by: Tomasz Maciej Nowak -+--- -+ arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts -++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts -+@@ -46,6 +46,8 @@ -+ /* J9 */ -+ &pcie0 { -+ status = "okay"; -++ -++ max-link-speed = <1>; -+ }; -+ -+ /* J6 */ -diff --git a/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch b/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch -new file mode 100644 -index 00000000000..a5553a3e96c ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch -@@ -0,0 +1,104 @@ -+From da58a931f248f423f917c3a0b3c94303aa30a738 Mon Sep 17 00:00:00 2001 -+From: Maxime Chevallier -+Date: Tue, 25 Sep 2018 15:59:39 +0200 -+Subject: [PATCH] net: mvneta: Add support for 2500Mbps SGMII -+ -+The mvneta controller can handle speeds up to 2500Mbps on the SGMII -+interface. This relies on serdes configuration, the lane must be -+configured at 3.125Gbps and we can't use in-band autoneg at that speed. -+ -+The main issue when supporting that speed on this particular controller -+is that the link partner can send ethernet frames with a shortened -+preamble, which if not explicitly enabled in the controller will cause -+unexpected behaviours. -+ -+This was tested on Armada 385, with the comphy configuration done in -+bootloader. -+ -+Signed-off-by: Maxime Chevallier -+Signed-off-by: David S. Miller -+--- -+ drivers/net/ethernet/marvell/mvneta.c | 27 +++++++++++++++++++++++---- -+ 1 file changed, 23 insertions(+), 4 deletions(-) -+ -+--- a/drivers/net/ethernet/marvell/mvneta.c -++++ b/drivers/net/ethernet/marvell/mvneta.c -+@@ -221,6 +221,8 @@ -+ #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11) -+ #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12) -+ #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13) -++#define MVNETA_GMAC_CTRL_4 0x2c90 -++#define MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE BIT(1) -+ #define MVNETA_MIB_COUNTERS_BASE 0x3000 -+ #define MVNETA_MIB_LATE_COLLISION 0x7c -+ #define MVNETA_DA_FILT_SPEC_MCAST 0x3400 -+@@ -3359,6 +3361,7 @@ static void mvneta_validate(struct net_d -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != PHY_INTERFACE_MODE_QSGMII && -+ state->interface != PHY_INTERFACE_MODE_SGMII && -++ state->interface != PHY_INTERFACE_MODE_2500BASEX && -+ !phy_interface_mode_is_8023z(state->interface) && -+ !phy_interface_mode_is_rgmii(state->interface)) { -+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+@@ -3371,9 +3374,15 @@ static void mvneta_validate(struct net_d -+ -+ /* Asymmetric pause is unsupported */ -+ phylink_set(mask, Pause); -+- /* Half-duplex at speeds higher than 100Mbit is unsupported */ -+- phylink_set(mask, 1000baseT_Full); -+- phylink_set(mask, 1000baseX_Full); -++ -++ /* We cannot use 1Gbps when using the 2.5G interface. */ -++ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { -++ phylink_set(mask, 2500baseT_Full); -++ phylink_set(mask, 2500baseX_Full); -++ } else { -++ phylink_set(mask, 1000baseT_Full); -++ phylink_set(mask, 1000baseX_Full); -++ } -+ -+ if (!phy_interface_mode_is_8023z(state->interface)) { -+ /* 10M and 100M are only supported in non-802.3z mode */ -+@@ -3434,12 +3443,14 @@ static void mvneta_mac_config(struct net -+ struct mvneta_port *pp = netdev_priv(ndev); -+ u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0); -+ u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -++ u32 new_ctrl4, gmac_ctrl4 = mvreg_read(pp, MVNETA_GMAC_CTRL_4); -+ u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -+ u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -+ -+ new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X; -+ new_ctrl2 = gmac_ctrl2 & ~(MVNETA_GMAC2_INBAND_AN_ENABLE | -+ MVNETA_GMAC2_PORT_RESET); -++ new_ctrl4 = gmac_ctrl4 & ~(MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE); -+ new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE; -+ new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE | -+ MVNETA_GMAC_INBAND_RESTART_AN | -+@@ -3472,7 +3483,7 @@ static void mvneta_mac_config(struct net -+ if (state->duplex) -+ new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; -+ -+- if (state->speed == SPEED_1000) -++ if (state->speed == SPEED_1000 || state->speed == SPEED_2500) -+ new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED; -+ else if (state->speed == SPEED_100) -+ new_an |= MVNETA_GMAC_CONFIG_MII_SPEED; -+@@ -3511,10 +3522,18 @@ static void mvneta_mac_config(struct net -+ MVNETA_GMAC_FORCE_LINK_DOWN); -+ } -+ -++ /* When at 2.5G, the link partner can send frames with shortened -++ * preambles. -++ */ -++ if (state->speed == SPEED_2500) -++ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; -++ -+ if (new_ctrl0 != gmac_ctrl0) -+ mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); -+ if (new_ctrl2 != gmac_ctrl2) -+ mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2); -++ if (new_ctrl4 != gmac_ctrl4) -++ mvreg_write(pp, MVNETA_GMAC_CTRL_4, new_ctrl4); -+ if (new_clk != gmac_clk) -+ mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk); -+ if (new_an != gmac_an) -diff --git a/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch b/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch -new file mode 100644 -index 00000000000..b6e16c54a45 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch -@@ -0,0 +1,33 @@ -+From fbd1d5245372e48b494120a30fe0b34b304576c4 Mon Sep 17 00:00:00 2001 -+From: Alexandre Belloni -+Date: Fri, 9 Nov 2018 17:37:20 +0100 -+Subject: [PATCH] net: mvneta: correct typo -+ -+The reserved variable should be named reserved1. -+ -+Signed-off-by: Alexandre Belloni -+Signed-off-by: David S. Miller -+--- -+ drivers/net/ethernet/marvell/mvneta.c | 4 ++-- -+ 1 file changed, 2 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/ethernet/marvell/mvneta.c -++++ b/drivers/net/ethernet/marvell/mvneta.c -+@@ -495,7 +495,7 @@ struct mvneta_port { -+ #if defined(__LITTLE_ENDIAN) -+ struct mvneta_tx_desc { -+ u32 command; /* Options used by HW for packet transmitting.*/ -+- u16 reserverd1; /* csum_l4 (for future use) */ -++ u16 reserved1; /* csum_l4 (for future use) */ -+ u16 data_size; /* Data size of transmitted packet in bytes */ -+ u32 buf_phys_addr; /* Physical addr of transmitted buffer */ -+ u32 reserved2; /* hw_cmd - (for future use, PMT) */ -+@@ -520,7 +520,7 @@ struct mvneta_rx_desc { -+ #else -+ struct mvneta_tx_desc { -+ u16 data_size; /* Data size of transmitted packet in bytes */ -+- u16 reserverd1; /* csum_l4 (for future use) */ -++ u16 reserved1; /* csum_l4 (for future use) */ -+ u32 command; /* Options used by HW for packet transmitting.*/ -+ u32 reserved2; /* hw_cmd - (for future use, PMT) */ -+ u32 buf_phys_addr; /* Physical addr of transmitted buffer */ -diff --git a/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch b/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch -new file mode 100644 -index 00000000000..01b101283cd ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch -@@ -0,0 +1,55 @@ -+From 83e65df6dfece9eb588735459428f221eb930c0c Mon Sep 17 00:00:00 2001 -+From: Maxime Chevallier -+Date: Fri, 9 Nov 2018 09:17:33 +0100 -+Subject: [PATCH] net: mvneta: Don't advertise 2.5G modes -+ -+Using 2.5G speed relies on the SerDes lanes being configured -+accordingly. The lanes have to be reconfigured to switch between -+1G and 2.5G, and for now only the bootloader does this configuration. -+ -+In the case we add a Comphy driver to handle switching the lanes -+dynamically, it's better for now to stick with supporting only 1G and -+add advertisement for 2.5G once we really are capable of handling both -+speeds without problem. -+ -+Since the interface mode is initialy taken from the DT, we want to make -+sure that adding comphy support won't break boards that don't update -+their dtb. -+ -+Fixes: da58a931f248 ("net: mvneta: Add support for 2500Mbps SGMII") -+Reported-by: Andrew Lunn -+Reported-by: Russell King -+Signed-off-by: Maxime Chevallier -+Signed-off-by: David S. Miller -+--- -+ drivers/net/ethernet/marvell/mvneta.c | 12 +++--------- -+ 1 file changed, 3 insertions(+), 9 deletions(-) -+ -+--- a/drivers/net/ethernet/marvell/mvneta.c -++++ b/drivers/net/ethernet/marvell/mvneta.c -+@@ -3361,7 +3361,6 @@ static void mvneta_validate(struct net_d -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != PHY_INTERFACE_MODE_QSGMII && -+ state->interface != PHY_INTERFACE_MODE_SGMII && -+- state->interface != PHY_INTERFACE_MODE_2500BASEX && -+ !phy_interface_mode_is_8023z(state->interface) && -+ !phy_interface_mode_is_rgmii(state->interface)) { -+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+@@ -3375,14 +3374,9 @@ static void mvneta_validate(struct net_d -+ /* Asymmetric pause is unsupported */ -+ phylink_set(mask, Pause); -+ -+- /* We cannot use 1Gbps when using the 2.5G interface. */ -+- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { -+- phylink_set(mask, 2500baseT_Full); -+- phylink_set(mask, 2500baseX_Full); -+- } else { -+- phylink_set(mask, 1000baseT_Full); -+- phylink_set(mask, 1000baseX_Full); -+- } -++ /* Half-duplex at speeds higher than 100Mbit is unsupported */ -++ phylink_set(mask, 1000baseT_Full); -++ phylink_set(mask, 1000baseX_Full); -+ -+ if (!phy_interface_mode_is_8023z(state->interface)) { -+ /* 10M and 100M are only supported in non-802.3z mode */ -diff --git a/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch b/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch -new file mode 100644 -index 00000000000..fd774e08398 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch -@@ -0,0 +1,30 @@ -+From e4a3e9ff5ba9f6b67595ec2768ed4be2054c2aa5 Mon Sep 17 00:00:00 2001 -+From: YueHaibing -+Date: Thu, 22 Nov 2018 14:42:00 +0800 -+Subject: [PATCH] net: mvneta: remove redundant check for -+ eee->tx_lpi_timer < 0 -+ -+fixes the smatch warning: -+ -+drivers/net/ethernet/marvell/mvneta.c:4252 mvneta_ethtool_set_eee() warn: -+ unsigned 'eee->tx_lpi_timer' is never less than zero. -+ -+Signed-off-by: YueHaibing -+Acked-by: Thomas Petazzoni -+Signed-off-by: David S. Miller -+--- -+ drivers/net/ethernet/marvell/mvneta.c | 3 +-- -+ 1 file changed, 1 insertion(+), 2 deletions(-) -+ -+--- a/drivers/net/ethernet/marvell/mvneta.c -++++ b/drivers/net/ethernet/marvell/mvneta.c -+@@ -4268,8 +4268,7 @@ static int mvneta_ethtool_set_eee(struct -+ -+ /* The Armada 37x documents do not give limits for this other than -+ * it being an 8-bit register. */ -+- if (eee->tx_lpi_enabled && -+- (eee->tx_lpi_timer < 0 || eee->tx_lpi_timer > 255)) -++ if (eee->tx_lpi_enabled && eee->tx_lpi_timer > 255) -+ return -EINVAL; -+ -+ lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0); -diff --git a/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch b/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch -new file mode 100644 -index 00000000000..272beb6950f ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch -@@ -0,0 +1,159 @@ -+From a10c1c8191e04c21769656c2ca8e1c69a6218954 Mon Sep 17 00:00:00 2001 -+From: Russell King -+Date: Thu, 7 Feb 2019 16:19:26 +0000 -+Subject: [PATCH] net: marvell: neta: add comphy support -+ -+Add support for the common phy binding, so that we can reconfigure the -+comphy according to the desired ethernet speed. This will allow us to -+support 1000base-X and 2500base-X SFPs dynamically on SolidRun Clearfog. -+ -+Signed-off-by: Russell King -+Signed-off-by: David S. Miller -+--- -+ drivers/net/ethernet/marvell/mvneta.c | 45 +++++++++++++++++++++++++++++++---- -+ 1 file changed, 41 insertions(+), 4 deletions(-) -+ -+--- a/drivers/net/ethernet/marvell/mvneta.c -++++ b/drivers/net/ethernet/marvell/mvneta.c -+@@ -27,6 +27,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -438,6 +439,7 @@ struct mvneta_port { -+ struct device_node *dn; -+ unsigned int tx_csum_limit; -+ struct phylink *phylink; -++ struct phy *comphy; -+ -+ struct mvneta_bm *bm_priv; -+ struct mvneta_bm_pool *pool_long; -+@@ -3168,6 +3170,8 @@ static void mvneta_start_dev(struct mvne -+ { -+ int cpu; -+ -++ WARN_ON(phy_power_on(pp->comphy)); -++ -+ mvneta_max_rx_size_set(pp, pp->pkt_size); -+ mvneta_txq_max_tx_size_set(pp, pp->pkt_size); -+ -+@@ -3230,6 +3234,8 @@ static void mvneta_stop_dev(struct mvnet -+ -+ mvneta_tx_reset(pp); -+ mvneta_rx_reset(pp); -++ -++ WARN_ON(phy_power_off(pp->comphy)); -+ } -+ -+ static void mvneta_percpu_enable(void *arg) -+@@ -3355,6 +3361,7 @@ static int mvneta_set_mac_addr(struct ne -+ static void mvneta_validate(struct net_device *ndev, unsigned long *supported, -+ struct phylink_link_state *state) -+ { -++ struct mvneta_port *pp = netdev_priv(ndev); -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -+ -+ /* We only support QSGMII, SGMII, 802.3z and RGMII modes */ -+@@ -3375,8 +3382,13 @@ static void mvneta_validate(struct net_d -+ phylink_set(mask, Pause); -+ -+ /* Half-duplex at speeds higher than 100Mbit is unsupported */ -+- phylink_set(mask, 1000baseT_Full); -+- phylink_set(mask, 1000baseX_Full); -++ if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) { -++ phylink_set(mask, 1000baseT_Full); -++ phylink_set(mask, 1000baseX_Full); -++ } -++ if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { -++ phylink_set(mask, 2500baseX_Full); -++ } -+ -+ if (!phy_interface_mode_is_8023z(state->interface)) { -+ /* 10M and 100M are only supported in non-802.3z mode */ -+@@ -3390,6 +3402,11 @@ static void mvneta_validate(struct net_d -+ __ETHTOOL_LINK_MODE_MASK_NBITS); -+ bitmap_and(state->advertising, state->advertising, mask, -+ __ETHTOOL_LINK_MODE_MASK_NBITS); -++ -++ /* We can only operate at 2500BaseX or 1000BaseX. If requested -++ * to advertise both, only report advertising at 2500BaseX. -++ */ -++ phylink_helper_basex_speed(state); -+ } -+ -+ static int mvneta_mac_link_state(struct net_device *ndev, -+@@ -3401,7 +3418,9 @@ static int mvneta_mac_link_state(struct -+ gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS); -+ -+ if (gmac_stat & MVNETA_GMAC_SPEED_1000) -+- state->speed = SPEED_1000; -++ state->speed = -++ state->interface == PHY_INTERFACE_MODE_2500BASEX ? -++ SPEED_2500 : SPEED_1000; -+ else if (gmac_stat & MVNETA_GMAC_SPEED_100) -+ state->speed = SPEED_100; -+ else -+@@ -3516,12 +3535,20 @@ static void mvneta_mac_config(struct net -+ MVNETA_GMAC_FORCE_LINK_DOWN); -+ } -+ -++ -+ /* When at 2.5G, the link partner can send frames with shortened -+ * preambles. -+ */ -+ if (state->speed == SPEED_2500) -+ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; -+ -++ if (pp->comphy && -++ (state->interface == PHY_INTERFACE_MODE_SGMII || -++ state->interface == PHY_INTERFACE_MODE_1000BASEX || -++ state->interface == PHY_INTERFACE_MODE_2500BASEX)) -++ WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, -++ state->interface)); -++ -+ if (new_ctrl0 != gmac_ctrl0) -+ mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); -+ if (new_ctrl2 != gmac_ctrl2) -+@@ -4434,7 +4461,7 @@ static int mvneta_port_power_up(struct m -+ if (phy_mode == PHY_INTERFACE_MODE_QSGMII) -+ mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO); -+ else if (phy_mode == PHY_INTERFACE_MODE_SGMII || -+- phy_mode == PHY_INTERFACE_MODE_1000BASEX) -++ phy_interface_mode_is_8023z(phy_mode)) -+ mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); -+ else if (!phy_interface_mode_is_rgmii(phy_mode)) -+ return -EINVAL; -+@@ -4451,6 +4478,7 @@ static int mvneta_probe(struct platform_ -+ struct mvneta_port *pp; -+ struct net_device *dev; -+ struct phylink *phylink; -++ struct phy *comphy; -+ const char *dt_mac_addr; -+ char hw_mac_addr[ETH_ALEN]; -+ const char *mac_from; -+@@ -4476,6 +4504,14 @@ static int mvneta_probe(struct platform_ -+ goto err_free_irq; -+ } -+ -++ comphy = devm_of_phy_get(&pdev->dev, dn, NULL); -++ if (comphy == ERR_PTR(-EPROBE_DEFER)) { -++ err = -EPROBE_DEFER; -++ goto err_free_irq; -++ } else if (IS_ERR(comphy)) { -++ comphy = NULL; -++ } -++ -+ phylink = phylink_create(dev, pdev->dev.fwnode, phy_mode, -+ &mvneta_phylink_ops); -+ if (IS_ERR(phylink)) { -+@@ -4492,6 +4528,7 @@ static int mvneta_probe(struct platform_ -+ pp = netdev_priv(dev); -+ spin_lock_init(&pp->lock); -+ pp->phylink = phylink; -++ pp->comphy = comphy; -+ pp->phy_interface = phy_mode; -+ pp->dn = dn; -+ -diff --git a/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch b/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch -new file mode 100644 -index 00000000000..bac9a55cf0d ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch -@@ -0,0 +1,78 @@ -+From 031b922bfd60c771588911112f8632783de08e5c Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -+Date: Mon, 25 Feb 2019 17:43:03 +0100 -+Subject: [PATCH] net: marvell: neta: disable comphy when setting mode -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+The comphy driver for Armada 3700 by Miquèl Raynal (which is currently -+in linux-next) does not actually set comphy mode when phy_set_mode_ext -+is called. The mode is set at next call of phy_power_on. -+ -+Update the driver to semantics similar to mvpp2: helper -+mvneta_comphy_init sets comphy mode and powers it on. -+When mode is to be changed in mvneta_mac_config, first power the comphy -+off, then call mvneta_comphy_init (which sets the mode to new one). -+ -+Only do this when new mode is different from old mode. -+ -+This should also work for Armada 38x, since in that comphy driver -+methods power_on and power_off are unimplemented. -+ -+Signed-off-by: Marek Behún -+Signed-off-by: David S. Miller -+--- -+ drivers/net/ethernet/marvell/mvneta.c | 28 +++++++++++++++++++++++----- -+ 1 file changed, 23 insertions(+), 5 deletions(-) -+ -+--- a/drivers/net/ethernet/marvell/mvneta.c -++++ b/drivers/net/ethernet/marvell/mvneta.c -+@@ -3166,11 +3166,26 @@ static int mvneta_setup_txqs(struct mvne -+ return 0; -+ } -+ -++static int mvneta_comphy_init(struct mvneta_port *pp) -++{ -++ int ret; -++ -++ if (!pp->comphy) -++ return 0; -++ -++ ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, -++ pp->phy_interface); -++ if (ret) -++ return ret; -++ -++ return phy_power_on(pp->comphy); -++} -++ -+ static void mvneta_start_dev(struct mvneta_port *pp) -+ { -+ int cpu; -+ -+- WARN_ON(phy_power_on(pp->comphy)); -++ WARN_ON(mvneta_comphy_init(pp)); -+ -+ mvneta_max_rx_size_set(pp, pp->pkt_size); -+ mvneta_txq_max_tx_size_set(pp, pp->pkt_size); -+@@ -3542,12 +3557,15 @@ static void mvneta_mac_config(struct net -+ if (state->speed == SPEED_2500) -+ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; -+ -+- if (pp->comphy && -++ if (pp->comphy && pp->phy_interface != state->interface && -+ (state->interface == PHY_INTERFACE_MODE_SGMII || -+ state->interface == PHY_INTERFACE_MODE_1000BASEX || -+- state->interface == PHY_INTERFACE_MODE_2500BASEX)) -+- WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, -+- state->interface)); -++ state->interface == PHY_INTERFACE_MODE_2500BASEX)) { -++ pp->phy_interface = state->interface; -++ -++ WARN_ON(phy_power_off(pp->comphy)); -++ WARN_ON(mvneta_comphy_init(pp)); -++ } -+ -+ if (new_ctrl0 != gmac_ctrl0) -+ mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); -diff --git a/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch b/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch -new file mode 100644 -index 00000000000..9186ceb0da4 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch -@@ -0,0 +1,34 @@ -+From eda3d1b0228484fb52b7244a68fd4cc8a985ed10 Mon Sep 17 00:00:00 2001 -+From: Maxime Chevallier -+Date: Wed, 27 Mar 2019 17:31:06 +0100 -+Subject: [PATCH] net: mvneta: Add 2500BaseT support -+ -+Some PHYs will use the 2500BaseX PHY_INTERFACE_MODE when being linked -+with a partner using 2.5GBaseT. -+ -+Since we can't autonegotiate this speed between the MAC and the PHY, we -+need to have the proper comphy support enabled, to make sure we can -+safely advertise 2.5G and 1G in BaseT and be able to switch between both -+corresponding PHY interface modes. This is now possible since comphy -+support was added to this driver. -+ -+This commit adds the 2500BaseT mode to the list of supported modes when -+using 2500BaseX, and was tested on a setup with an Armada385 and a -+88E2010 PHY, both with and without the comphy node in the DT. -+ -+Signed-off-by: Maxime Chevallier -+Signed-off-by: David S. Miller -+--- -+ drivers/net/ethernet/marvell/mvneta.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/net/ethernet/marvell/mvneta.c -++++ b/drivers/net/ethernet/marvell/mvneta.c -+@@ -3402,6 +3402,7 @@ static void mvneta_validate(struct net_d -+ phylink_set(mask, 1000baseX_Full); -+ } -+ if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { -++ phylink_set(mask, 2500baseT_Full); -+ phylink_set(mask, 2500baseX_Full); -+ } -+ -diff --git a/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch b/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch -new file mode 100644 -index 00000000000..b759b9fb254 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch -@@ -0,0 +1,28 @@ -+From c2a90025ad09d830c8d8ae69f485eac6aaaa2472 Mon Sep 17 00:00:00 2001 -+From: Quentin Schulz -+Date: Thu, 4 Oct 2018 14:22:03 +0200 -+Subject: [PATCH] phy: add QSGMII and PCIE modes -+ -+Prepare for upcoming phys that'll handle QSGMII or PCIe. -+ -+Reviewed-by: Florian Fainelli -+Signed-off-by: Quentin Schulz -+Signed-off-by: David S. Miller -+--- -+ include/linux/phy/phy.h | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/include/linux/phy/phy.h -++++ b/include/linux/phy/phy.h -+@@ -37,9 +37,11 @@ enum phy_mode { -+ PHY_MODE_USB_OTG, -+ PHY_MODE_SGMII, -+ PHY_MODE_2500SGMII, -++ PHY_MODE_QSGMII, -+ PHY_MODE_10GKR, -+ PHY_MODE_UFS_HS_A, -+ PHY_MODE_UFS_HS_B, -++ PHY_MODE_PCIE, -+ }; -+ -+ /** -diff --git a/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch b/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch -new file mode 100644 -index 00000000000..68fecadce85 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch -@@ -0,0 +1,24 @@ -+From 2af8caeee47846a84bc96abc3a72f7c991153040 Mon Sep 17 00:00:00 2001 -+From: Grygorii Strashko -+Date: Mon, 19 Nov 2018 19:24:21 -0600 -+Subject: [PATCH] phy: core: add PHY_MODE_ETHERNET -+ -+Add new PHY's mode to be used by Ethernet PHY interface drivers or -+multipurpose PHYs like serdes. It will be reused in further changes. -+ -+Signed-off-by: Grygorii Strashko -+Signed-off-by: Kishon Vijay Abraham I -+--- -+ include/linux/phy/phy.h | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/include/linux/phy/phy.h -++++ b/include/linux/phy/phy.h -+@@ -42,6 +42,7 @@ enum phy_mode { -+ PHY_MODE_UFS_HS_A, -+ PHY_MODE_UFS_HS_B, -+ PHY_MODE_PCIE, -++ PHY_MODE_ETHERNET, -+ }; -+ -+ /** -diff --git a/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch b/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch -new file mode 100644 -index 00000000000..83908af19e6 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch -@@ -0,0 +1,45 @@ -+From e1706720408e72fb883f6b151c2b3b23d8e7e5b2 Mon Sep 17 00:00:00 2001 -+From: John Hubbard -+Date: Sat, 12 Jan 2019 17:29:09 -0800 -+Subject: [PATCH] phy: fix build breakage: add PHY_MODE_SATA -+ -+Commit 49e54187ae0b ("ata: libahci_platform: comply to PHY framework") uses -+the PHY_MODE_SATA, but that enum had not yet been added. This caused a -+build failure for me, with today's linux.git. -+ -+Also, there is a potentially conflicting (mis-named) PHY_MODE_SATA, hiding -+in the Marvell Berlin SATA PHY driver. -+ -+Fix the build by: -+ -+ 1) Renaming Marvell's defined value to a more scoped name, -+ in order to avoid any potential conflicts: PHY_BERLIN_MODE_SATA. -+ -+ 2) Adding the missing enum, which was going to be added anyway as part -+ of [1]. -+ -+[1] https://lkml.kernel.org/r/20190108163124.6409-3-miquel.raynal@bootlin.com -+ -+Fixes: 49e54187ae0b ("ata: libahci_platform: comply to PHY framework") -+ -+Signed-off-by: John Hubbard -+Acked-by: Jens Axboe -+Acked-by: Olof Johansson -+Cc: Grzegorz Jaszczyk -+Cc: Miquel Raynal -+Cc: Hans de Goede -+Signed-off-by: Linus Torvalds -+--- -+ include/linux/phy/phy.h | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/include/linux/phy/phy.h -++++ b/include/linux/phy/phy.h -+@@ -43,6 +43,7 @@ enum phy_mode { -+ PHY_MODE_UFS_HS_B, -+ PHY_MODE_PCIE, -+ PHY_MODE_ETHERNET, -++ PHY_MODE_SATA -+ }; -+ -+ /** -diff --git a/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch b/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch -new file mode 100644 -index 00000000000..e02f203912d ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch -@@ -0,0 +1,134 @@ -+From 79a5a18aa9d1062205cdcfa183d4cd5241d1b8da Mon Sep 17 00:00:00 2001 -+From: Grygorii Strashko -+Date: Mon, 19 Nov 2018 19:24:20 -0600 -+Subject: [PATCH] phy: core: rework phy_set_mode to accept phy mode and submode -+ -+Currently the attempt to add support for Ethernet interface mode PHY -+(MII/GMII/RGMII) will lead to the necessity of extending enum phy_mode and -+duplicate there values from phy_interface_t enum (or introduce more PHY -+callbacks) [1]. Both approaches are ineffective and would lead to fast -+bloating of enum phy_mode or struct phy_ops in the process of adding more -+PHYs for different subsystems which will make them unmaintainable. -+ -+As discussed in [1] the solution could be to introduce dual level PHYs mode -+configuration - PHY mode and PHY submode. The PHY mode will define generic -+PHY type (subsystem - PCIE/ETHERNET/USB_) while the PHY submode - subsystem -+specific interface mode. The last is usually already defined in -+corresponding subsystem headers (phy_interface_t for Ethernet, enum -+usb_device_speed for USB). -+ -+This patch is cumulative change which refactors PHY framework code to -+support dual level PHYs mode configuration - PHY mode and PHY submode. It -+extends .set_mode() callback to support additional parameter "int submode" -+and converts all corresponding PHY drivers to support new .set_mode() -+callback declaration. -+The new extended PHY API -+ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) -+is introduced to support dual level PHYs mode configuration and existing -+phy_set_mode() API is converted to macros, so PHY framework consumers do -+not need to be changed (~21 matches). -+ -+[1] http://lkml.kernel.org/r/d63588f6-9ab0-848a-5ad4-8073143bd95d@ti.com -+Signed-off-by: Grygorii Strashko -+Signed-off-by: Kishon Vijay Abraham I -+--- -+ drivers/phy/allwinner/phy-sun4i-usb.c | 3 ++- -+ drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 +++-- -+ drivers/phy/amlogic/phy-meson-gxl-usb3.c | 5 +++-- -+ drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 3 ++- -+ drivers/phy/mediatek/phy-mtk-tphy.c | 2 +- -+ drivers/phy/mediatek/phy-mtk-xsphy.c | 2 +- -+ drivers/phy/mscc/phy-ocelot-serdes.c | 2 +- -+ drivers/phy/phy-core.c | 6 +++--- -+ drivers/phy/qualcomm/phy-qcom-qmp.c | 3 ++- -+ drivers/phy/qualcomm/phy-qcom-qusb2.c | 3 ++- -+ drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 3 ++- -+ drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 3 ++- -+ drivers/phy/qualcomm/phy-qcom-usb-hs.c | 3 ++- -+ drivers/phy/ti/phy-da8xx-usb.c | 3 ++- -+ drivers/phy/ti/phy-tusb1210.c | 2 +- -+ include/linux/phy/phy.h | 13 ++++++++++--- -+ 16 files changed, 39 insertions(+), 22 deletions(-) -+ -+--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c -++++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c -+@@ -512,7 +512,8 @@ static int mvebu_comphy_power_on(struct -+ return ret; -+ } -+ -+-static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode) -++static int mvebu_comphy_set_mode(struct phy *phy, -++ enum phy_mode mode, int submode) -+ { -+ struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); -+ -+--- a/drivers/phy/phy-core.c -++++ b/drivers/phy/phy-core.c -+@@ -360,7 +360,7 @@ int phy_power_off(struct phy *phy) -+ } -+ EXPORT_SYMBOL_GPL(phy_power_off); -+ -+-int phy_set_mode(struct phy *phy, enum phy_mode mode) -++int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) -+ { -+ int ret; -+ -+@@ -368,14 +368,14 @@ int phy_set_mode(struct phy *phy, enum p -+ return 0; -+ -+ mutex_lock(&phy->mutex); -+- ret = phy->ops->set_mode(phy, mode); -++ ret = phy->ops->set_mode(phy, mode, submode); -+ if (!ret) -+ phy->attrs.mode = mode; -+ mutex_unlock(&phy->mutex); -+ -+ return ret; -+ } -+-EXPORT_SYMBOL_GPL(phy_set_mode); -++EXPORT_SYMBOL_GPL(phy_set_mode_ext); -+ -+ int phy_reset(struct phy *phy) -+ { -+--- a/include/linux/phy/phy.h -++++ b/include/linux/phy/phy.h -+@@ -62,7 +62,7 @@ struct phy_ops { -+ int (*exit)(struct phy *phy); -+ int (*power_on)(struct phy *phy); -+ int (*power_off)(struct phy *phy); -+- int (*set_mode)(struct phy *phy, enum phy_mode mode); -++ int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode); -+ int (*reset)(struct phy *phy); -+ int (*calibrate)(struct phy *phy); -+ struct module *owner; -+@@ -166,7 +166,10 @@ int phy_init(struct phy *phy); -+ int phy_exit(struct phy *phy); -+ int phy_power_on(struct phy *phy); -+ int phy_power_off(struct phy *phy); -+-int phy_set_mode(struct phy *phy, enum phy_mode mode); -++int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); -++#define phy_set_mode(phy, mode) \ -++ phy_set_mode_ext(phy, mode, 0) -++ -+ static inline enum phy_mode phy_get_mode(struct phy *phy) -+ { -+ return phy->attrs.mode; -+@@ -280,13 +283,17 @@ static inline int phy_power_off(struct p -+ return -ENOSYS; -+ } -+ -+-static inline int phy_set_mode(struct phy *phy, enum phy_mode mode) -++static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, -++ int submode) -+ { -+ if (!phy) -+ return 0; -+ return -ENOSYS; -+ } -+ -++#define phy_set_mode(phy, mode) \ -++ phy_set_mode_ext(phy, mode, 0) -++ -+ static inline enum phy_mode phy_get_mode(struct phy *phy) -+ { -+ return PHY_MODE_INVALID; -diff --git a/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch b/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch -new file mode 100644 -index 00000000000..0964da03a8d ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch -@@ -0,0 +1,381 @@ -+From 9695375a3f4a604406f2e61f2b735eca1de931ed Mon Sep 17 00:00:00 2001 -+From: Miquel Raynal -+Date: Tue, 8 Jan 2019 17:31:20 +0100 -+Subject: [PATCH] phy: add A3700 COMPHY support -+ -+Add a driver to support COMPHY, a hardware block providing shared -+serdes PHYs on Marvell Armada 3700. This driver uses SMC calls and -+rely on having an up-to-date firmware. -+ -+SATA, PCie and USB3 host mode have been tested successfully with an -+ESPRESSObin. (HS)SGMII mode cannot be tested with this platform. -+ -+Evan worked on the original driver structure and Grzegorz on the SMC -+calls rework. The structure of this driver has been copied from -+Antoine Tenart work on CP110 COMPHY driver. -+ -+Signed-off-by: Miquel Raynal -+Co-developed-by: Evan Wang -+Signed-off-by: Evan Wang -+Co-developed-by: Grzegorz Jaszczyk -+Signed-off-by: Grzegorz Jaszczyk -+Signed-off-by: Kishon Vijay Abraham I -+--- -+ drivers/phy/marvell/Kconfig | 12 + -+ drivers/phy/marvell/Makefile | 1 + -+ drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 318 +++++++++++++++++++++++++++ -+ 3 files changed, 331 insertions(+) -+ create mode 100644 drivers/phy/marvell/phy-mvebu-a3700-comphy.c -+ -+--- a/drivers/phy/marvell/Kconfig -++++ b/drivers/phy/marvell/Kconfig -+@@ -21,6 +21,18 @@ config PHY_BERLIN_USB -+ help -+ Enable this to support the USB PHY on Marvell Berlin SoCs. -+ -++config PHY_MVEBU_A3700_COMPHY -++ tristate "Marvell A3700 comphy driver" -++ depends on ARCH_MVEBU || COMPILE_TEST -++ depends on OF -++ depends on HAVE_ARM_SMCCC -++ default y -++ select GENERIC_PHY -++ help -++ This driver allows to control the comphy, a hardware block providing -++ shared serdes PHYs on Marvell Armada 3700. Its serdes lanes can be -++ used by various controllers: Ethernet, SATA, USB3, PCIe. -++ -+ config PHY_MVEBU_CP110_COMPHY -+ tristate "Marvell CP110 comphy driver" -+ depends on ARCH_MVEBU || COMPILE_TEST -+--- a/drivers/phy/marvell/Makefile -++++ b/drivers/phy/marvell/Makefile -+@@ -2,6 +2,7 @@ -+ obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o -+ obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o -+ obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o -++obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o -+ obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o -+ obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o -+ obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o -+--- /dev/null -++++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c -+@@ -0,0 +1,318 @@ -++// SPDX-License-Identifier: GPL-2.0 -++/* -++ * Copyright (C) 2018 Marvell -++ * -++ * Authors: -++ * Evan Wang -++ * Miquèl Raynal -++ * -++ * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart. -++ * SMC call initial support done by Grzegorz Jaszczyk. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define MVEBU_A3700_COMPHY_LANES 3 -++#define MVEBU_A3700_COMPHY_PORTS 2 -++ -++/* COMPHY Fast SMC function identifiers */ -++#define COMPHY_SIP_POWER_ON 0x82000001 -++#define COMPHY_SIP_POWER_OFF 0x82000002 -++#define COMPHY_SIP_PLL_LOCK 0x82000003 -++ -++#define COMPHY_FW_MODE_SATA 0x1 -++#define COMPHY_FW_MODE_SGMII 0x2 -++#define COMPHY_FW_MODE_HS_SGMII 0x3 -++#define COMPHY_FW_MODE_USB3H 0x4 -++#define COMPHY_FW_MODE_USB3D 0x5 -++#define COMPHY_FW_MODE_PCIE 0x6 -++#define COMPHY_FW_MODE_RXAUI 0x7 -++#define COMPHY_FW_MODE_XFI 0x8 -++#define COMPHY_FW_MODE_SFI 0x9 -++#define COMPHY_FW_MODE_USB3 0xa -++ -++#define COMPHY_FW_SPEED_1_25G 0 /* SGMII 1G */ -++#define COMPHY_FW_SPEED_2_5G 1 -++#define COMPHY_FW_SPEED_3_125G 2 /* SGMII 2.5G */ -++#define COMPHY_FW_SPEED_5G 3 -++#define COMPHY_FW_SPEED_5_15625G 4 /* XFI 5G */ -++#define COMPHY_FW_SPEED_6G 5 -++#define COMPHY_FW_SPEED_10_3125G 6 /* XFI 10G */ -++#define COMPHY_FW_SPEED_MAX 0x3F -++ -++#define COMPHY_FW_MODE(mode) ((mode) << 12) -++#define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \ -++ ((idx) << 8) | \ -++ ((speed) << 2)) -++#define COMPHY_FW_PCIE(mode, idx, speed, width) (COMPHY_FW_NET(mode, idx, speed) | \ -++ ((width) << 18)) -++ -++struct mvebu_a3700_comphy_conf { -++ unsigned int lane; -++ enum phy_mode mode; -++ int submode; -++ unsigned int port; -++ u32 fw_mode; -++}; -++ -++#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _port, _fw) \ -++ { \ -++ .lane = _lane, \ -++ .mode = _mode, \ -++ .submode = _smode, \ -++ .port = _port, \ -++ .fw_mode = _fw, \ -++ } -++ -++#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _port, _fw) \ -++ MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _port, _fw) -++ -++#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _port, _fw) \ -++ MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _port, _fw) -++ -++static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { -++ /* lane 0 */ -++ MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, 0, -++ COMPHY_FW_MODE_USB3H), -++ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, 1, -++ COMPHY_FW_MODE_SGMII), -++ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, 1, -++ COMPHY_FW_MODE_HS_SGMII), -++ /* lane 1 */ -++ MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, 0, -++ COMPHY_FW_MODE_PCIE), -++ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0, -++ COMPHY_FW_MODE_SGMII), -++ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, 0, -++ COMPHY_FW_MODE_HS_SGMII), -++ /* lane 2 */ -++ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, 0, -++ COMPHY_FW_MODE_SATA), -++ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, 0, -++ COMPHY_FW_MODE_USB3H), -++}; -++ -++struct mvebu_a3700_comphy_lane { -++ struct device *dev; -++ unsigned int id; -++ enum phy_mode mode; -++ int submode; -++ int port; -++}; -++ -++static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane, -++ unsigned long mode) -++{ -++ struct arm_smccc_res res; -++ -++ arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); -++ -++ return res.a0; -++} -++ -++static int mvebu_a3700_comphy_get_fw_mode(int lane, int port, -++ enum phy_mode mode, -++ int submode) -++{ -++ int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes); -++ -++ /* Unused PHY mux value is 0x0 */ -++ if (mode == PHY_MODE_INVALID) -++ return -EINVAL; -++ -++ for (i = 0; i < n; i++) { -++ if (mvebu_a3700_comphy_modes[i].lane == lane && -++ mvebu_a3700_comphy_modes[i].port == port && -++ mvebu_a3700_comphy_modes[i].mode == mode && -++ mvebu_a3700_comphy_modes[i].submode == submode) -++ break; -++ } -++ -++ if (i == n) -++ return -EINVAL; -++ -++ return mvebu_a3700_comphy_modes[i].fw_mode; -++} -++ -++static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, -++ int submode) -++{ -++ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); -++ int fw_mode; -++ -++ if (submode == PHY_INTERFACE_MODE_1000BASEX) -++ submode = PHY_INTERFACE_MODE_SGMII; -++ -++ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, mode, -++ submode); -++ if (fw_mode < 0) { -++ dev_err(lane->dev, "invalid COMPHY mode\n"); -++ return fw_mode; -++ } -++ -++ /* Just remember the mode, ->power_on() will do the real setup */ -++ lane->mode = mode; -++ lane->submode = submode; -++ -++ return 0; -++} -++ -++static int mvebu_a3700_comphy_power_on(struct phy *phy) -++{ -++ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); -++ u32 fw_param; -++ int fw_mode; -++ -++ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, -++ lane->mode, lane->submode); -++ if (fw_mode < 0) { -++ dev_err(lane->dev, "invalid COMPHY mode\n"); -++ return fw_mode; -++ } -++ -++ switch (lane->mode) { -++ case PHY_MODE_USB_HOST_SS: -++ dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); -++ fw_param = COMPHY_FW_MODE(fw_mode); -++ break; -++ case PHY_MODE_SATA: -++ dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); -++ fw_param = COMPHY_FW_MODE(fw_mode); -++ break; -++ case PHY_MODE_ETHERNET: -++ switch (lane->submode) { -++ case PHY_INTERFACE_MODE_SGMII: -++ dev_dbg(lane->dev, "set lane %d to SGMII mode\n", -++ lane->id); -++ fw_param = COMPHY_FW_NET(fw_mode, lane->port, -++ COMPHY_FW_SPEED_1_25G); -++ break; -++ case PHY_INTERFACE_MODE_2500BASEX: -++ dev_dbg(lane->dev, "set lane %d to HS SGMII mode\n", -++ lane->id); -++ fw_param = COMPHY_FW_NET(fw_mode, lane->port, -++ COMPHY_FW_SPEED_3_125G); -++ break; -++ default: -++ dev_err(lane->dev, "unsupported PHY submode (%d)\n", -++ lane->submode); -++ return -ENOTSUPP; -++ } -++ break; -++ case PHY_MODE_PCIE: -++ dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); -++ fw_param = COMPHY_FW_PCIE(fw_mode, lane->port, -++ COMPHY_FW_SPEED_5G, -++ phy->attrs.bus_width); -++ break; -++ default: -++ dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); -++ return -ENOTSUPP; -++ } -++ -++ return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); -++} -++ -++static int mvebu_a3700_comphy_power_off(struct phy *phy) -++{ -++ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); -++ -++ return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_OFF, lane->id, 0); -++} -++ -++static const struct phy_ops mvebu_a3700_comphy_ops = { -++ .power_on = mvebu_a3700_comphy_power_on, -++ .power_off = mvebu_a3700_comphy_power_off, -++ .set_mode = mvebu_a3700_comphy_set_mode, -++ .owner = THIS_MODULE, -++}; -++ -++static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, -++ struct of_phandle_args *args) -++{ -++ struct mvebu_a3700_comphy_lane *lane; -++ struct phy *phy; -++ -++ if (WARN_ON(args->args[0] >= MVEBU_A3700_COMPHY_PORTS)) -++ return ERR_PTR(-EINVAL); -++ -++ phy = of_phy_simple_xlate(dev, args); -++ if (IS_ERR(phy)) -++ return phy; -++ -++ lane = phy_get_drvdata(phy); -++ lane->port = args->args[0]; -++ -++ return phy; -++} -++ -++static int mvebu_a3700_comphy_probe(struct platform_device *pdev) -++{ -++ struct phy_provider *provider; -++ struct device_node *child; -++ -++ for_each_available_child_of_node(pdev->dev.of_node, child) { -++ struct mvebu_a3700_comphy_lane *lane; -++ struct phy *phy; -++ int ret; -++ u32 lane_id; -++ -++ ret = of_property_read_u32(child, "reg", &lane_id); -++ if (ret < 0) { -++ dev_err(&pdev->dev, "missing 'reg' property (%d)\n", -++ ret); -++ continue; -++ } -++ -++ if (lane_id >= MVEBU_A3700_COMPHY_LANES) { -++ dev_err(&pdev->dev, "invalid 'reg' property\n"); -++ continue; -++ } -++ -++ lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); -++ if (!lane) -++ return -ENOMEM; -++ -++ phy = devm_phy_create(&pdev->dev, child, -++ &mvebu_a3700_comphy_ops); -++ if (IS_ERR(phy)) -++ return PTR_ERR(phy); -++ -++ lane->dev = &pdev->dev; -++ lane->mode = PHY_MODE_INVALID; -++ lane->submode = PHY_INTERFACE_MODE_NA; -++ lane->id = lane_id; -++ lane->port = -1; -++ phy_set_drvdata(phy, lane); -++ } -++ -++ provider = devm_of_phy_provider_register(&pdev->dev, -++ mvebu_a3700_comphy_xlate); -++ return PTR_ERR_OR_ZERO(provider); -++} -++ -++static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = { -++ { .compatible = "marvell,comphy-a3700" }, -++ { }, -++}; -++MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table); -++ -++static struct platform_driver mvebu_a3700_comphy_driver = { -++ .probe = mvebu_a3700_comphy_probe, -++ .driver = { -++ .name = "mvebu-a3700-comphy", -++ .of_match_table = mvebu_a3700_comphy_of_match_table, -++ }, -++}; -++module_platform_driver(mvebu_a3700_comphy_driver); -++ -++MODULE_AUTHOR("Miquèl Raynal "); -++MODULE_DESCRIPTION("Common PHY driver for A3700"); -++MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch b/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch -new file mode 100644 -index 00000000000..393f8237944 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch -@@ -0,0 +1,58 @@ -+From 2ef303f0fe44feee4a3ca8bd62fca86c105927d2 Mon Sep 17 00:00:00 2001 -+From: Miquel Raynal -+Date: Tue, 8 Jan 2019 17:31:24 +0100 -+Subject: [PATCH] arm64: dts: marvell: armada-37xx: declare the COMPHY -+ node -+ -+Describe the A3700 COMPHY node. It has three PHYs that can be -+configured as follow: -+* PCIe or GbE -+* USB3 or GbE -+* SATA or USB3 -+Each of them has its own memory area. -+ -+Suggested-by: Grzegorz Jaszczyk -+Signed-off-by: Miquel Raynal -+Signed-off-by: Gregory CLEMENT -+--- -+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 29 ++++++++++++++++++++++++++++ -+ 1 file changed, 29 insertions(+) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -+@@ -235,6 +235,35 @@ -+ reg = <0x14000 0x60>; -+ }; -+ -++ comphy: phy@18300 { -++ compatible = "marvell,comphy-a3700"; -++ reg = <0x18300 0x300>, -++ <0x1F000 0x400>, -++ <0x5C000 0x400>, -++ <0xe0178 0x8>; -++ reg-names = "comphy", -++ "lane1_pcie_gbe", -++ "lane0_usb3_gbe", -++ "lane2_sata_usb3"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ -++ comphy0: phy@0 { -++ reg = <0>; -++ #phy-cells = <1>; -++ }; -++ -++ comphy1: phy@1 { -++ reg = <1>; -++ #phy-cells = <1>; -++ }; -++ -++ comphy2: phy@2 { -++ reg = <2>; -++ #phy-cells = <1>; -++ }; -++ }; -++ -+ pinctrl_sb: pinctrl@18800 { -+ compatible = "marvell,armada3710-sb-pinctrl", -+ "syscon", "simple-mfd"; -diff --git a/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch b/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch -new file mode 100644 -index 00000000000..f72ea93b97e ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch -@@ -0,0 +1,35 @@ -+From 9c222a1d78a1700220e38feb270f00d2ddd3c5ab Mon Sep 17 00:00:00 2001 -+From: Russell King -+Date: Wed, 6 Nov 2019 13:44:21 +0000 -+Subject: [PATCH 657/660] arm64: dts: uDPU: fix comphy definitions -+ -+The uDPU uses both ethernet controllers, which ties up COMPHY 0 for -+eth1 and COMPHY 1 for eth0, with no USB3 comphy. The addition of -+COMPHY support made the kernel override the setup by the boot loader -+breaking this platform. Delete the USB3 COMPHY definition at platform -+level, and add phy specifications for the ethernet channels. -+ -+Fixes: bd3d25b07342 ("arm64: dts: marvell: armada-37xx: link USB hosts with their PHYs") -+Signed-off-by: Russell King -+--- -+ arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -++++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -+@@ -143,6 +143,7 @@ -+ status = "okay"; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -++ phys = <&comphy1 0>; -+ sfp = <&sfp_eth0>; -+ }; -+ -+@@ -150,6 +151,7 @@ -+ status = "okay"; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -++ phys = <&comphy0 1>; -+ sfp = <&sfp_eth1>; -+ }; -+ -diff --git a/target/linux/mvebu/patches-5.4/545-arm64-dts-uDPU-remove-i2c-fast-mode.patch b/target/linux/mvebu/patches-5.4/545-arm64-dts-uDPU-remove-i2c-fast-mode.patch -new file mode 100644 -index 00000000000..b984eb4ba16 ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/545-arm64-dts-uDPU-remove-i2c-fast-mode.patch -@@ -0,0 +1,30 @@ -+From 662eb8fc87f982e63ccb9a9df25c7aeabf9fe341 Mon Sep 17 00:00:00 2001 -+From: Russell King -+Date: Thu, 14 Nov 2019 00:23:35 +0000 -+Subject: [PATCH 658/660] arm64: dts: uDPU: remove i2c-fast-mode -+ -+The I2C bus violates the timing specifications when run in fast mode -+on the uDPU, so switch to 100kHz mode. -+ -+Signed-off-by: Russell King -+--- -+ arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -++++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -+@@ -119,12 +119,14 @@ -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -++ /delete-property/mrvl,i2c-fast-mode; -+ }; -+ -+ &i2c1 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins>; -++ /delete-property/mrvl,i2c-fast-mode; -+ -+ lm75@48 { -+ status = "okay"; -diff --git a/target/linux/mvebu/patches-5.4/546-arm64-dts-uDPU-SFP-cages-support-3W-modules.patch b/target/linux/mvebu/patches-5.4/546-arm64-dts-uDPU-SFP-cages-support-3W-modules.patch -new file mode 100644 -index 00000000000..d025f36a53c ---- /dev/null -+++ b/target/linux/mvebu/patches-5.4/546-arm64-dts-uDPU-SFP-cages-support-3W-modules.patch -@@ -0,0 +1,33 @@ -+From 1cb114a20854e34324a2cb308f23054ff8227ffa Mon Sep 17 00:00:00 2001 -+From: Russell King -+Date: Tue, 19 Nov 2019 22:48:50 +0000 -+Subject: [PATCH 659/660] arm64: dts: uDPU: SFP cages support 3W modules -+ -+The SFP cages are designed to support up to 3W modules, such as G.hn, -+G.fast and MoCA modules. Although there is no way for such modules to -+declare to software that they consume 3W, we document in DT that this -+is the designed power level for these cages. -+ -+Signed-off-by: Russell King -+--- -+ arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -++++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -+@@ -69,6 +69,7 @@ -+ mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>; -+ tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>; -+ tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>; -++ maximum-power-milliwatt = <3000>; -+ }; -+ -+ sfp_eth1: sfp-eth1 { -+@@ -78,6 +79,7 @@ -+ mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>; -+ tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>; -+ tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>; -++ maximum-power-milliwatt = <3000>; -+ }; -+ }; -+ - -From b526702f2900f8fc2126feedb43be3641a7a8484 Mon Sep 17 00:00:00 2001 -From: DENG Qingfang -Date: Wed, 4 Mar 2020 20:46:23 +0800 -Subject: [PATCH 2/4] mvebu: set kernel testing version to 5.4 - -Signed-off-by: DENG Qingfang ---- - target/linux/mvebu/Makefile | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/linux/mvebu/Makefile b/target/linux/mvebu/Makefile -index 1688065a5ce..05003689806 100644 ---- a/target/linux/mvebu/Makefile -+++ b/target/linux/mvebu/Makefile -@@ -13,6 +13,7 @@ SUBTARGETS:=cortexa9 cortexa53 cortexa72 - MAINTAINER:=Imre Kaloz - - KERNEL_PATCHVER:=4.19 -+KERNEL_TESTING_PATCHVER:=5.4 - - include $(INCLUDE_DIR)/target.mk - - -From 745a16c12188efbcfb2f8c0797898cf1bab4839d Mon Sep 17 00:00:00 2001 -From: DENG Qingfang -Date: Wed, 4 Mar 2020 20:46:28 +0800 -Subject: [PATCH 3/4] mvebu: refresh patches - -Signed-off-by: DENG Qingfang ---- - .../boot/dts/marvell/armada-3720-uDPU.dts | 162 -------- - .../patches-5.4/002-add_powertables.patch | 2 +- - .../patches-5.4/003-add_switch_nodes.patch | 6 +- - ...Mangle-bootloader-s-kernel-arguments.patch | 10 +- - .../patches-5.4/100-find_active_root.patch | 12 +- - .../210-clearfog_switch_node.patch | 2 +- - .../220-disable-untested-dsa-boards.patch | 4 +- - ...-armada-xp-linksys-mamba-broken-idle.patch | 2 +- - .../300-mvneta-tx-queue-workaround.patch | 7 +- - ...-pci-mvebu-time-out-reset-on-link-up.patch | 6 +- - ...rmada388-clearfog-document-MPP-usage.patch | 124 ------ - ...l-armada37xx-Add-emmc-sdio-pinctrl-d.patch | 40 -- - ...l-armada-37xx-Enable-emmc-on-espress.patch | 49 --- - ...da-3720-espressobin-correct-spi-node.patch | 58 --- - ...l-armada-3720-espressobin-add-ports-.patch | 2 +- - ...rdvark-Convert-to-use-pci_host_probe.patch | 4 +- - ...-device-to-the-same-MAX-payload-size.patch | 8 +- - ...ardvark-disable-LOS-state-by-default.patch | 2 +- - ...ark-allow-to-specify-link-capability.patch | 4 +- - ...-3720-espressobin-set-max-link-to-ge.patch | 8 +- - ...vneta-Add-support-for-2500Mbps-SGMII.patch | 104 ----- - .../532-net-mvneta-correct-typo.patch | 33 -- - ...net-mvneta-Dont-advertise-2.5G-modes.patch | 55 --- - ...et-mvneta-remove-redundant-check-for.patch | 30 -- - ...-net-marvell-neta-add-comphy-support.patch | 159 -------- - ...eta-disable-comphy-when-setting-mode.patch | 78 ---- - ...537-net-mvneta-add-2500baset-support.patch | 34 -- - .../538-phy-add-QSGMII-and-PCIE-modes.patch | 28 -- - .../539-phy-core-add-PHY_MODE_ETHERNET.patch | 24 -- - ...fix-build-breakage-add-PHY_MODE_SATA.patch | 45 --- - ...phy_set_mode-to-accept-phy-mode-and-.patch | 134 ------ - .../542-phy-add-A3700-COMPHY-support.patch | 381 ------------------ - ...rvell-armada-37xx-declare-the-COMPHY.patch | 58 --- - ...rm64-dts-uDPU-fix-comphy-definitions.patch | 35 -- - 34 files changed, 39 insertions(+), 1671 deletions(-) - delete mode 100644 target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts - delete mode 100644 target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch - delete mode 100644 target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch - delete mode 100644 target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch - delete mode 100644 target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch - delete mode 100644 target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch - delete mode 100644 target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch - delete mode 100644 target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch - delete mode 100644 target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch - delete mode 100644 target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch - delete mode 100644 target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch - delete mode 100644 target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch - delete mode 100644 target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch - delete mode 100644 target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch - delete mode 100644 target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch - delete mode 100644 target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch - delete mode 100644 target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch - delete mode 100644 target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch - delete mode 100644 target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch - -diff --git a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts b/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -deleted file mode 100644 -index 5b722b4f832..00000000000 ---- a/target/linux/mvebu/files-5.4/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts -+++ /dev/null -@@ -1,162 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR MIT) --/* -- * Device tree for the uDPU board. -- * Based on Marvell Armada 3720 development board (DB-88F3720-DDR3) -- * Copyright (C) 2016 Marvell -- * Copyright (C) 2019 Methode Electronics -- * Copyright (C) 2019 Telus -- * -- * Vladimir Vid -- */ -- --/dts-v1/; -- --#include --#include "armada-372x.dtsi" -- --/ { -- model = "Methode uDPU Board"; -- compatible = "methode,udpu", "marvell,armada3720"; -- -- chosen { -- stdout-path = "serial0:115200n8"; -- }; -- -- memory@0 { -- device_type = "memory"; -- reg = <0x00000000 0x00000000 0x00000000 0x20000000>; -- }; -- -- leds { -- pinctrl-names = "default"; -- compatible = "gpio-leds"; -- -- power1 { -- label = "udpu:green:power"; -- gpios = <&gpionb 11 GPIO_ACTIVE_LOW>; -- }; -- -- power2 { -- label = "udpu:red:power"; -- gpios = <&gpionb 12 GPIO_ACTIVE_LOW>; -- }; -- -- network1 { -- label = "udpu:green:network"; -- gpios = <&gpionb 13 GPIO_ACTIVE_LOW>; -- }; -- -- network2 { -- label = "udpu:red:network"; -- gpios = <&gpionb 14 GPIO_ACTIVE_LOW>; -- }; -- -- alarm1 { -- label = "udpu:green:alarm"; -- gpios = <&gpionb 15 GPIO_ACTIVE_LOW>; -- }; -- -- alarm2 { -- label = "udpu:red:alarm"; -- gpios = <&gpionb 16 GPIO_ACTIVE_LOW>; -- }; -- }; -- -- sfp_eth0: sfp-eth0 { -- compatible = "sff,sfp"; -- i2c-bus = <&i2c0>; -- los-gpio = <&gpiosb 2 GPIO_ACTIVE_HIGH>; -- mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>; -- tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>; -- tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>; -- }; -- -- sfp_eth1: sfp-eth1 { -- compatible = "sff,sfp"; -- i2c-bus = <&i2c1>; -- los-gpio = <&gpiosb 7 GPIO_ACTIVE_HIGH>; -- mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>; -- tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>; -- tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>; -- }; --}; -- --&sdhci0 { -- status = "okay"; -- bus-width = <8>; -- mmc-ddr-1_8v; -- mmc-hs400-1_8v; -- marvell,pad-type = "fixed-1-8v"; -- non-removable; -- no-sd; -- no-sdio; --}; -- --&spi0 { -- status = "okay"; -- pinctrl-names = "default"; -- pinctrl-0 = <&spi_quad_pins>; -- -- flash@0 { -- compatible = "jedec,spi-nor"; -- reg = <0>; -- spi-max-frequency = <54000000>; -- -- partitions { -- compatible = "fixed-partitions"; -- #address-cells = <1>; -- #size-cells = <1>; -- /* only bootloader is located on the SPI */ -- partition@0 { -- label = "uboot"; -- reg = <0 0x400000>; -- }; -- }; -- }; --}; -- --&i2c0 { -- status = "okay"; -- pinctrl-names = "default"; -- pinctrl-0 = <&i2c1_pins>; --}; -- --&i2c1 { -- status = "okay"; -- pinctrl-names = "default"; -- pinctrl-0 = <&i2c2_pins>; -- -- lm75@48 { -- status = "okay"; -- compatible = "lm75"; -- reg = <0x48>; -- }; -- -- lm75@49 { -- status = "okay"; -- compatible = "lm75"; -- reg = <0x49>; -- }; --}; -- --ð0 { -- status = "okay"; -- phy-mode = "sgmii"; -- managed = "in-band-status"; -- sfp = <&sfp_eth0>; --}; -- --ð1 { -- status = "okay"; -- phy-mode = "sgmii"; -- managed = "in-band-status"; -- sfp = <&sfp_eth1>; --}; -- --&usb3 { -- status = "okay"; --}; -- --&uart0 { -- status = "okay"; --}; -diff --git a/target/linux/mvebu/patches-5.4/002-add_powertables.patch b/target/linux/mvebu/patches-5.4/002-add_powertables.patch -index c2fb748d5d0..efbbbc7d786 100644 ---- a/target/linux/mvebu/patches-5.4/002-add_powertables.patch -+++ b/target/linux/mvebu/patches-5.4/002-add_powertables.patch -@@ -667,7 +667,7 @@ - pinctrl-0 = <&sdhci_pins>; - --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts - +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts --@@ -272,12 +272,100 @@ -+@@ -225,12 +225,100 @@ - pcie@2,0 { - /* Port 0, Lane 1 */ - status = "okay"; -diff --git a/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch b/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch -index b2086389163..e13973767f9 100644 ---- a/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch -+++ b/target/linux/mvebu/patches-5.4/003-add_switch_nodes.patch -@@ -1,8 +1,8 @@ - --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts - +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts --@@ -257,6 +257,16 @@ -- }; -- }; -+@@ -210,6 +210,16 @@ -+ compatible = "pwm-fan"; -+ pwms = <&gpio0 24 4000>; - }; - + - + mvsw61xx { -diff --git a/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch -index 0cb9e996027..2f942ea3af6 100644 ---- a/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch -+++ b/target/linux/mvebu/patches-5.4/006-mvebu-Mangle-bootloader-s-kernel-arguments.patch -@@ -28,7 +28,7 @@ Signed-off-by: Michael Gray - - --- a/arch/arm/Kconfig - +++ b/arch/arm/Kconfig --@@ -1926,6 +1926,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN -+@@ -1825,6 +1825,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN - The command-line arguments provided by the boot loader will be - appended to the the device tree bootargs property. - -@@ -145,7 +145,7 @@ Signed-off-by: Michael Gray - } - *ptr = '\0'; - --@@ -148,7 +218,9 @@ int atags_to_fdt(void *atag_list, void * -+@@ -166,7 +236,9 @@ int atags_to_fdt(void *atag_list, void * - else - setprop_string(fdt, "/chosen", "bootargs", - atag->u.cmdline.cmdline); -@@ -156,7 +156,7 @@ Signed-off-by: Michael Gray - if (memcount >= sizeof(mem_reg_property)/4) - continue; - if (!atag->u.mem.size) --@@ -187,6 +259,10 @@ int atags_to_fdt(void *atag_list, void * -+@@ -210,6 +282,10 @@ int atags_to_fdt(void *atag_list, void * - setprop(fdt, "/memory", "reg", mem_reg_property, - 4 * memcount * memsize); - } -@@ -169,7 +169,7 @@ Signed-off-by: Michael Gray - } - --- a/init/main.c - +++ b/init/main.c --@@ -102,6 +102,10 @@ -+@@ -103,6 +103,10 @@ - #define CREATE_TRACE_POINTS - #include - -@@ -180,7 +180,7 @@ Signed-off-by: Michael Gray - static int kernel_init(void *); - - extern void init_IRQ(void); --@@ -591,6 +595,18 @@ asmlinkage __visible void __init start_k -+@@ -630,6 +634,18 @@ asmlinkage __visible void __init start_k - page_alloc_init(); - - pr_notice("Kernel command line: %s\n", boot_command_line); -diff --git a/target/linux/mvebu/patches-5.4/100-find_active_root.patch b/target/linux/mvebu/patches-5.4/100-find_active_root.patch -index f52a5108b85..854031b0d51 100644 ---- a/target/linux/mvebu/patches-5.4/100-find_active_root.patch -+++ b/target/linux/mvebu/patches-5.4/100-find_active_root.patch -@@ -3,9 +3,9 @@ Dynamically rename the active partition to "ubi". - - Signed-off-by: Imre Kaloz - ----- a/drivers/mtd/ofpart.c --+++ b/drivers/mtd/ofpart.c --@@ -25,6 +25,8 @@ static bool node_has_compatible(struct d -+--- a/drivers/mtd/parsers/ofpart.c -++++ b/drivers/mtd/parsers/ofpart.c -+@@ -21,6 +21,8 @@ static bool node_has_compatible(struct d - return of_get_property(pp, "compatible", NULL); - } - -@@ -14,7 +14,7 @@ Signed-off-by: Imre Kaloz - static int parse_fixed_partitions(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) --@@ -33,6 +35,7 @@ static int parse_fixed_partitions(struct -+@@ -29,6 +31,7 @@ static int parse_fixed_partitions(struct - struct device_node *mtd_node; - struct device_node *ofpart_node; - const char *partname; -@@ -22,7 +22,7 @@ Signed-off-by: Imre Kaloz - struct device_node *pp; - int nr_parts, i, ret = 0; - bool dedicated = true; --@@ -110,9 +113,13 @@ static int parse_fixed_partitions(struct -+@@ -106,9 +109,13 @@ static int parse_fixed_partitions(struct - parts[i].size = of_read_number(reg + a_cells, s_cells); - parts[i].of_node = pp; - -@@ -39,7 +39,7 @@ Signed-off-by: Imre Kaloz - parts[i].name = partname; - - if (of_get_property(pp, "read-only", &len)) --@@ -219,6 +226,18 @@ static int __init ofpart_parser_init(voi -+@@ -215,6 +222,18 @@ static int __init ofpart_parser_init(voi - return 0; - } - -diff --git a/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch b/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch -index f9677a82f2e..d0e32e19df6 100644 ---- a/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch -+++ b/target/linux/mvebu/patches-5.4/210-clearfog_switch_node.patch -@@ -1,6 +1,6 @@ - --- a/arch/arm/boot/dts/armada-388-clearfog.dts - +++ b/arch/arm/boot/dts/armada-388-clearfog.dts --@@ -88,6 +88,18 @@ -+@@ -30,6 +30,18 @@ - }; - }; - -diff --git a/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch b/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch -index 9cc7a113f6c..029eb68e21d 100644 ---- a/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch -+++ b/target/linux/mvebu/patches-5.4/220-disable-untested-dsa-boards.patch -@@ -10,7 +10,7 @@ - #size-cells = <0>; - --- a/arch/arm/boot/dts/armada-388-clearfog.dts - +++ b/arch/arm/boot/dts/armada-388-clearfog.dts --@@ -161,6 +161,7 @@ -+@@ -103,6 +103,7 @@ - status = "okay"; - - switch@4 { -@@ -20,7 +20,7 @@ - #size-cells = <0>; - --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts - +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts --@@ -413,6 +413,7 @@ -+@@ -366,6 +366,7 @@ - status = "okay"; - - switch@0 { -diff --git a/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch b/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch -index 935c8fe0935..ee8786c0fce 100644 ---- a/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch -+++ b/target/linux/mvebu/patches-5.4/230-armada-xp-linksys-mamba-broken-idle.patch -@@ -1,6 +1,6 @@ - --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts - +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts --@@ -543,3 +543,7 @@ -+@@ -496,3 +496,7 @@ - }; - }; - }; -diff --git a/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch b/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch -index 4a5ea361449..cc34ec0af7f 100644 ---- a/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch -+++ b/target/linux/mvebu/patches-5.4/300-mvneta-tx-queue-workaround.patch -@@ -9,13 +9,12 @@ Signed-off-by: Felix Fietkau - --- - --- a/drivers/net/ethernet/marvell/mvneta.c - +++ b/drivers/net/ethernet/marvell/mvneta.c --@@ -4272,6 +4272,15 @@ static int mvneta_ethtool_set_eee(struct -+@@ -4333,6 +4333,14 @@ static int mvneta_ethtool_set_eee(struct - return phylink_ethtool_set_eee(pp->phylink, eee); - } - - +static u16 mvneta_select_queue(struct net_device *dev, struct sk_buff *skb, --+ struct net_device *sb_dev, --+ select_queue_fallback_t fallback) -++ struct net_device *sb_dev) - +{ - + /* XXX: hardware queue scheduling is broken, - + * use only one queue until it is fixed */ -@@ -25,7 +24,7 @@ Signed-off-by: Felix Fietkau - static const struct net_device_ops mvneta_netdev_ops = { - .ndo_open = mvneta_open, - .ndo_stop = mvneta_stop, --@@ -4282,6 +4291,7 @@ static const struct net_device_ops mvnet -+@@ -4343,6 +4351,7 @@ static const struct net_device_ops mvnet - .ndo_fix_features = mvneta_fix_features, - .ndo_get_stats64 = mvneta_get_stats64, - .ndo_do_ioctl = mvneta_ioctl, -diff --git a/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch b/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch -index 2bbb6471538..4058dc8ed58 100644 ---- a/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch -+++ b/target/linux/mvebu/patches-5.4/401-pci-mvebu-time-out-reset-on-link-up.patch -@@ -13,7 +13,7 @@ Signed-off-by: Russell King - - --- a/drivers/pci/controller/pci-mvebu.c - +++ b/drivers/pci/controller/pci-mvebu.c --@@ -1112,6 +1112,7 @@ static int mvebu_pcie_powerup(struct mve -+@@ -928,6 +928,7 @@ static int mvebu_pcie_powerup(struct mve - - if (port->reset_gpio) { - u32 reset_udelay = PCI_PM_D3COLD_WAIT * 1000; -@@ -21,7 +21,7 @@ Signed-off-by: Russell King - - of_property_read_u32(port->dn, "reset-delay-us", - &reset_udelay); --@@ -1119,7 +1120,13 @@ static int mvebu_pcie_powerup(struct mve -+@@ -935,7 +936,13 @@ static int mvebu_pcie_powerup(struct mve - udelay(100); - - gpiod_set_value_cansleep(port->reset_gpio, 0); -@@ -36,7 +36,7 @@ Signed-off-by: Russell King - } - - return 0; --@@ -1283,15 +1290,16 @@ static int mvebu_pcie_probe(struct platf -+@@ -1099,15 +1106,16 @@ static int mvebu_pcie_probe(struct platf - if (!child) - continue; - -diff --git a/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch b/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch -deleted file mode 100644 -index d64bd8084ea..00000000000 ---- a/target/linux/mvebu/patches-5.4/415-ARM-dts-armada388-clearfog-document-MPP-usage.patch -+++ /dev/null -@@ -1,124 +0,0 @@ --From 09a0122c74ec076e08512f1b00b7ccb8a450282f Mon Sep 17 00:00:00 2001 --From: Russell King --Date: Tue, 29 Nov 2016 10:15:43 +0000 --Subject: ARM: dts: armada388-clearfog: document MPP usage -- --Signed-off-by: Russell King ----- -- arch/arm/boot/dts/armada-388-clearfog-base.dts | 51 ++++++++++++++++++++++++++ -- arch/arm/boot/dts/armada-388-clearfog.dts | 50 +++++++++++++++++++++++++ -- 2 files changed, 101 insertions(+) -- ----- a/arch/arm/boot/dts/armada-388-clearfog-base.dts --+++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts --@@ -67,3 +67,54 @@ -- marvell,function = "gpio"; -- }; -- }; --+ --+/* --+MPP --+18: pu gpio pca9655 int --+19: gpio phy reset --+20: pu gpio sd0 detect --+21: sd0:cmd --+22: pd gpio mikro int --+23: --+ --+24: ua1:rxd mikro rx --+25: ua1:txd mikro tx --+26: pu i2c1:sck --+27: pu i2c1:sda --+28: sd0:clk --+29: pd gpio mikro rst --+30: --+31: --+ --+32: --+33: --+34: --+35: --+36: --+37: sd0:d3 --+38: sd0:d0 --+39: sd0:d1 --+ --+40: sd0:d2 --+41: --+42: --+43: spi1:cs2 mikro cs --+44: gpio rear button sw3 --+45: ref:clk_out0 phy#0 clock --+46: ref:clk_out1 phy#1 clock --+47: --+ --+48: gpio J18 spare gpio --+49: gpio U10 I2C_IRQ(GNSS) --+50: gpio board id? --+51: --+52: --+53: --+54: gpio mikro pwm --+55: --+ --+56: pu spi1:mosi mikro mosi --+57: pd spi1:sck mikro sck --+58: spi1:miso mikro miso --+59: --+*/ ----- a/arch/arm/boot/dts/armada-388-clearfog.dts --+++ b/arch/arm/boot/dts/armada-388-clearfog.dts --@@ -249,3 +249,53 @@ -- */ -- pinctrl-0 = <&spi1_pins &clearfog_spi1_cs_pins &mikro_spi_pins>; -- }; --+/* --++#define A38x_CUSTOMER_BOARD_1_MPP16_23 0x00400011 --+MPP18: gpio ? (pca9655 int?) --+MPP19: gpio ? (clkreq?) --+MPP20: gpio ? (sd0 detect) --+MPP21: sd0:cmd x sd0 --+MPP22: gpio x mikro int --+MPP23: gpio x switch irq --++#define A38x_CUSTOMER_BOARD_1_MPP24_31 0x22043333 --+MPP24: ua1:rxd x mikro rx --+MPP25: ua1:txd x mikro tx --+MPP26: i2c1:sck x mikro sck --+MPP27: i2c1:sda x mikro sda --+MPP28: sd0:clk x sd0 --+MPP29: gpio x mikro rst --+MPP30: ge1:txd2 ? (config) --+MPP31: ge1:txd3 ? (config) --++#define A38x_CUSTOMER_BOARD_1_MPP32_39 0x44400002 --+MPP32: ge1:txctl ? (unused) --+MPP33: gpio ? (pic_com0) --+MPP34: gpio x rear button (pic_com1) --+MPP35: gpio ? (pic_com2) --+MPP36: gpio ? (unused) --+MPP37: sd0:d3 x sd0 --+MPP38: sd0:d0 x sd0 --+MPP39: sd0:d1 x sd0 --++#define A38x_CUSTOMER_BOARD_1_MPP40_47 0x41144004 --+MPP40: sd0:d2 x sd0 --+MPP41: gpio x switch reset --+MPP42: gpio ? sw1-1 --+MPP43: spi1:cs2 x mikro cs --+MPP44: sata3:prsnt ? (unused) --+MPP45: ref:clk_out0 ? --+MPP46: ref:clk_out1 x switch clk --+MPP47: 4 ? (unused) --++#define A38x_CUSTOMER_BOARD_1_MPP48_55 0x40333333 --+MPP48: tdm:pclk --+MPP49: tdm:fsync --+MPP50: tdm:drx --+MPP51: tdm:dtx --+MPP52: tdm:int --+MPP53: tdm:rst --+MPP54: gpio ? (pwm) --+MPP55: spi1:cs1 x slic --++#define A38x_CUSTOMER_BOARD_1_MPP56_63 0x00004444 --+MPP56: spi1:mosi x mikro mosi --+MPP57: spi1:sck x mikro sck --+MPP58: spi1:miso x mikro miso --+MPP59: spi1:cs0 x w25q32 --+*/ -diff --git a/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch b/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch -deleted file mode 100644 -index 880b0d92417..00000000000 ---- a/target/linux/mvebu/patches-5.4/513-arm64-dts-marvell-armada37xx-Add-emmc-sdio-pinctrl-d.patch -+++ /dev/null -@@ -1,40 +0,0 @@ --From eefe328439642101774f0f5c4ea0dc6ba1cfb687 Mon Sep 17 00:00:00 2001 --From: Ding Tao --Date: Fri, 26 Oct 2018 11:50:27 +0000 --Subject: [PATCH] arm64: dts: marvell: armada37xx: Add emmc/sdio pinctrl -- definition -- --Add emmc/sdio pinctrl definition for marvell armada37xx SoCs. -- --Signed-off-by: Ding Tao --Signed-off-by: Gregory CLEMENT ----- -- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 10 ++++++++++ -- 1 file changed, 10 insertions(+) -- ----- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi --+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi --@@ -221,6 +221,11 @@ -- groups = "uart2"; -- function = "uart"; -- }; --+ --+ mmc_pins: mmc-pins { --+ groups = "emmc_nb"; --+ function = "emmc"; --+ }; -- }; -- -- nb_pm: syscon@14000 { --@@ -253,6 +258,11 @@ -- function = "mii"; -- }; -- --+ sdio_pins: sdio-pins { --+ groups = "sdio_sb"; --+ function = "sdio"; --+ }; --+ -- }; -- -- eth0: ethernet@30000 { -diff --git a/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch b/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch -deleted file mode 100644 -index 77af3d1219d..00000000000 ---- a/target/linux/mvebu/patches-5.4/514-arm64-dts-marvell-armada-37xx-Enable-emmc-on-espress.patch -+++ /dev/null -@@ -1,49 +0,0 @@ --From 43ebc7c1b3ed8198b9acf3019eca16e722f7331c Mon Sep 17 00:00:00 2001 --From: Ding Tao --Date: Fri, 26 Oct 2018 11:50:28 +0000 --Subject: [PATCH] arm64: dts: marvell: armada-37xx: Enable emmc on espressobin -- --The ESPRESSObin board has a emmc interface available on U11: declare it --and let the bootloader enable it if the emmc is present. -- --[gregory.clement@bootlin.com: disable the emmc by default] --Signed-off-by: Ding Tao --Signed-off-by: Gregory CLEMENT ----- -- .../dts/marvell/armada-3720-espressobin.dts | 22 +++++++++++++++++++ -- 1 file changed, 22 insertions(+) -- ----- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts --+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts --@@ -60,9 +60,31 @@ -- cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>; -- marvell,pad-type = "sd"; -- vqmmc-supply = <&vcc_sd_reg1>; --+ --+ pinctrl-names = "default"; --+ pinctrl-0 = <&sdio_pins>; -- status = "okay"; -- }; -- --+/* U11 */ --+&sdhci0 { --+ non-removable; --+ bus-width = <8>; --+ mmc-ddr-1_8v; --+ mmc-hs400-1_8v; --+ marvell,xenon-emmc; --+ marvell,xenon-tun-count = <9>; --+ marvell,pad-type = "fixed-1-8v"; --+ --+ pinctrl-names = "default"; --+ pinctrl-0 = <&mmc_pins>; --+/* --+ * This eMMC is not populated on all boards, so disable it by --+ * default and let the bootloader enable it, if it is present --+ */ --+ status = "disabled"; --+}; --+ -- &spi0 { -- status = "okay"; -- -diff --git a/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch b/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch -deleted file mode 100644 -index 0f39b2a3c2c..00000000000 ---- a/target/linux/mvebu/patches-5.4/521-arm64-dts-armada-3720-espressobin-correct-spi-node.patch -+++ /dev/null -@@ -1,58 +0,0 @@ --From 3217cdfe8a3eae76fafbebbe407be5985a7fd4c2 Mon Sep 17 00:00:00 2001 --From: Tomasz Maciej Nowak --Date: Mon, 31 Dec 2018 14:18:50 +0100 --Subject: [PATCH] arm64: dts: armada-3720-espressobin: correct spi node -- --The manufacturer of this board, ships it with various SPI NOR chips and --increments U-Boot bootloader version along the time. There is no way to --tell which is placed on the board since no revision bump takes place. --This creates two issues. -- --The first, cosmetic. Since the SPI chip may differ, there's message on --boot stating that kernel expected w25q32dw and found different one. To --correct this, remove optional device-specific compatible string. Being --here lets replace bogus "spi-flash" string with proper one. -- --The second is linked to partitions layout, it changed after commit [1] --in Marvells downstream U-Boot fork, shifting environment location to the --end of boot device. Since the new boards can have U-Boot with this --change it can lead to improper results writing or reading from these --partitions. We can't tell if users will update bootloader to recent --version, so let's drop current layout. -- --1. https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/81e7251252aefe1a6b829ed05f3586320cb45372 -- --Signed-off-by: Tomasz Maciej Nowak ----- -- .../dts/marvell/armada-3720-espressobin.dts | 18 +----------------- -- 1 file changed, 1 insertion(+), 17 deletions(-) -- ----- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts --+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts --@@ -90,25 +90,9 @@ -- -- flash@0 { -- reg = <0>; --- compatible = "winbond,w25q32dw", "jedec,spi-flash"; --+ compatible = "jedec,spi-nor"; -- spi-max-frequency = <104000000>; -- m25p,fast-read; --- --- partitions { --- compatible = "fixed-partitions"; --- #address-cells = <1>; --- #size-cells = <1>; --- --- partition@0 { --- label = "uboot"; --- reg = <0 0x180000>; --- }; --- --- partition@180000 { --- label = "ubootenv"; --- reg = <0x180000 0x10000>; --- }; --- }; -- }; -- }; -- -diff --git a/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch b/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch -index cea0d1db44f..1a608f2b6ac 100644 ---- a/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch -+++ b/target/linux/mvebu/patches-5.4/522-arm64-dts-marvell-armada-3720-espressobin-add-ports-.patch -@@ -15,7 +15,7 @@ Signed-off-by: Tomasz Maciej Nowak - - --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts - +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts --@@ -132,7 +132,7 @@ -+@@ -137,7 +137,7 @@ - - dsa,member = <0 0>; - -diff --git a/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch b/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch -index 3fd561db3a6..e1318e825ad 100644 ---- a/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch -+++ b/target/linux/mvebu/patches-5.4/523-Revert-PCI-aardvark-Convert-to-use-pci_host_probe.patch -@@ -10,7 +10,7 @@ This reverts commit c8e144f8ab00e6c4a070a932ef9c57db09aa41cf. - - --- a/drivers/pci/controller/pci-aardvark.c - +++ b/drivers/pci/controller/pci-aardvark.c --@@ -843,6 +843,7 @@ static int advk_pcie_probe(struct platfo -+@@ -999,6 +999,7 @@ static int advk_pcie_probe(struct platfo - struct device *dev = &pdev->dev; - struct advk_pcie *pcie; - struct resource *res; -@@ -18,7 +18,7 @@ This reverts commit c8e144f8ab00e6c4a070a932ef9c57db09aa41cf. - struct pci_host_bridge *bridge; - int ret, irq; - --@@ -896,13 +897,22 @@ static int advk_pcie_probe(struct platfo -+@@ -1054,13 +1055,22 @@ static int advk_pcie_probe(struct platfo - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; - -diff --git a/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch b/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch -index 204d6e2aec4..c6cfe3783c5 100644 ---- a/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch -+++ b/target/linux/mvebu/patches-5.4/524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch -@@ -45,7 +45,7 @@ Signed-off-by: Thomas Petazzoni - - --- a/drivers/pci/controller/pci-aardvark.c - +++ b/drivers/pci/controller/pci-aardvark.c --@@ -29,9 +29,11 @@ -+@@ -33,9 +33,11 @@ - #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 - #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) - #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 -@@ -57,7 +57,7 @@ Signed-off-by: Thomas Petazzoni - #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 - #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) - #define PCIE_CORE_LINK_TRAINING BIT(5) --@@ -253,7 +255,8 @@ static void advk_pcie_setup_hw(struct ad -+@@ -276,7 +278,8 @@ static void advk_pcie_setup_hw(struct ad - - /* Set PCIe Device Control and Status 1 PF0 register */ - reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | -@@ -67,7 +67,7 @@ Signed-off-by: Thomas Petazzoni - PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | - (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << - PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); --@@ -838,6 +841,58 @@ out_release_res: -+@@ -994,6 +997,58 @@ out_release_res: - return err; - } - -@@ -126,7 +126,7 @@ Signed-off-by: Thomas Petazzoni - static int advk_pcie_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; --@@ -912,6 +967,9 @@ static int advk_pcie_probe(struct platfo -+@@ -1070,6 +1125,9 @@ static int advk_pcie_probe(struct platfo - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - -diff --git a/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch b/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch -index b6fcec81f8f..f865965ed47 100644 ---- a/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch -+++ b/target/linux/mvebu/patches-5.4/526-PCI-aardvark-disable-LOS-state-by-default.patch -@@ -43,7 +43,7 @@ Signed-off-by: Thomas Petazzoni - - --- a/drivers/pci/controller/pci-aardvark.c - +++ b/drivers/pci/controller/pci-aardvark.c --@@ -324,8 +324,7 @@ static void advk_pcie_setup_hw(struct ad -+@@ -347,8 +347,7 @@ static void advk_pcie_setup_hw(struct ad - - advk_pcie_wait_for_link(pcie); - -diff --git a/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch b/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch -index 0ac34761473..739292c1bfd 100644 ---- a/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch -+++ b/target/linux/mvebu/patches-5.4/527-PCI-aardvark-allow-to-specify-link-capability.patch -@@ -14,7 +14,7 @@ Signed-off-by: Tomasz Maciej Nowak - - --- a/drivers/pci/controller/pci-aardvark.c - +++ b/drivers/pci/controller/pci-aardvark.c --@@ -233,6 +233,8 @@ static int advk_pcie_wait_for_link(struc -+@@ -256,6 +256,8 @@ static void advk_pcie_wait_for_retrain(s - - static void advk_pcie_setup_hw(struct advk_pcie *pcie) - { -@@ -23,7 +23,7 @@ Signed-off-by: Tomasz Maciej Nowak - u32 reg; - - /* Set to Direct mode */ --@@ -267,10 +269,15 @@ static void advk_pcie_setup_hw(struct ad -+@@ -290,10 +292,15 @@ static void advk_pcie_setup_hw(struct ad - PCIE_CORE_CTRL2_TD_ENABLE; - advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); - -diff --git a/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch b/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch -index 88080d64caa..d3a8f58f18f 100644 ---- a/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch -+++ b/target/linux/mvebu/patches-5.4/528-arm64-dts-armada-3720-espressobin-set-max-link-to-ge.patch -@@ -62,10 +62,10 @@ Signed-off-by: Tomasz Maciej Nowak - - --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts - +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts --@@ -46,6 +46,8 @@ -- /* J9 */ -- &pcie0 { -- status = "okay"; -+@@ -49,6 +49,8 @@ -+ phys = <&comphy1 0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; - + - + max-link-speed = <1>; - }; -diff --git a/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch b/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch -deleted file mode 100644 -index a5553a3e96c..00000000000 ---- a/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch -+++ /dev/null -@@ -1,104 +0,0 @@ --From da58a931f248f423f917c3a0b3c94303aa30a738 Mon Sep 17 00:00:00 2001 --From: Maxime Chevallier --Date: Tue, 25 Sep 2018 15:59:39 +0200 --Subject: [PATCH] net: mvneta: Add support for 2500Mbps SGMII -- --The mvneta controller can handle speeds up to 2500Mbps on the SGMII --interface. This relies on serdes configuration, the lane must be --configured at 3.125Gbps and we can't use in-band autoneg at that speed. -- --The main issue when supporting that speed on this particular controller --is that the link partner can send ethernet frames with a shortened --preamble, which if not explicitly enabled in the controller will cause --unexpected behaviours. -- --This was tested on Armada 385, with the comphy configuration done in --bootloader. -- --Signed-off-by: Maxime Chevallier --Signed-off-by: David S. Miller ----- -- drivers/net/ethernet/marvell/mvneta.c | 27 +++++++++++++++++++++++---- -- 1 file changed, 23 insertions(+), 4 deletions(-) -- ----- a/drivers/net/ethernet/marvell/mvneta.c --+++ b/drivers/net/ethernet/marvell/mvneta.c --@@ -221,6 +221,8 @@ -- #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11) -- #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12) -- #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13) --+#define MVNETA_GMAC_CTRL_4 0x2c90 --+#define MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE BIT(1) -- #define MVNETA_MIB_COUNTERS_BASE 0x3000 -- #define MVNETA_MIB_LATE_COLLISION 0x7c -- #define MVNETA_DA_FILT_SPEC_MCAST 0x3400 --@@ -3359,6 +3361,7 @@ static void mvneta_validate(struct net_d -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_QSGMII && -- state->interface != PHY_INTERFACE_MODE_SGMII && --+ state->interface != PHY_INTERFACE_MODE_2500BASEX && -- !phy_interface_mode_is_8023z(state->interface) && -- !phy_interface_mode_is_rgmii(state->interface)) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); --@@ -3371,9 +3374,15 @@ static void mvneta_validate(struct net_d -- -- /* Asymmetric pause is unsupported */ -- phylink_set(mask, Pause); --- /* Half-duplex at speeds higher than 100Mbit is unsupported */ --- phylink_set(mask, 1000baseT_Full); --- phylink_set(mask, 1000baseX_Full); --+ --+ /* We cannot use 1Gbps when using the 2.5G interface. */ --+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { --+ phylink_set(mask, 2500baseT_Full); --+ phylink_set(mask, 2500baseX_Full); --+ } else { --+ phylink_set(mask, 1000baseT_Full); --+ phylink_set(mask, 1000baseX_Full); --+ } -- -- if (!phy_interface_mode_is_8023z(state->interface)) { -- /* 10M and 100M are only supported in non-802.3z mode */ --@@ -3434,12 +3443,14 @@ static void mvneta_mac_config(struct net -- struct mvneta_port *pp = netdev_priv(ndev); -- u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0); -- u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2); --+ u32 new_ctrl4, gmac_ctrl4 = mvreg_read(pp, MVNETA_GMAC_CTRL_4); -- u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -- u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -- -- new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X; -- new_ctrl2 = gmac_ctrl2 & ~(MVNETA_GMAC2_INBAND_AN_ENABLE | -- MVNETA_GMAC2_PORT_RESET); --+ new_ctrl4 = gmac_ctrl4 & ~(MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE); -- new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE; -- new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE | -- MVNETA_GMAC_INBAND_RESTART_AN | --@@ -3472,7 +3483,7 @@ static void mvneta_mac_config(struct net -- if (state->duplex) -- new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; -- --- if (state->speed == SPEED_1000) --+ if (state->speed == SPEED_1000 || state->speed == SPEED_2500) -- new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED; -- else if (state->speed == SPEED_100) -- new_an |= MVNETA_GMAC_CONFIG_MII_SPEED; --@@ -3511,10 +3522,18 @@ static void mvneta_mac_config(struct net -- MVNETA_GMAC_FORCE_LINK_DOWN); -- } -- --+ /* When at 2.5G, the link partner can send frames with shortened --+ * preambles. --+ */ --+ if (state->speed == SPEED_2500) --+ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; --+ -- if (new_ctrl0 != gmac_ctrl0) -- mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); -- if (new_ctrl2 != gmac_ctrl2) -- mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2); --+ if (new_ctrl4 != gmac_ctrl4) --+ mvreg_write(pp, MVNETA_GMAC_CTRL_4, new_ctrl4); -- if (new_clk != gmac_clk) -- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk); -- if (new_an != gmac_an) -diff --git a/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch b/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch -deleted file mode 100644 -index b6e16c54a45..00000000000 ---- a/target/linux/mvebu/patches-5.4/532-net-mvneta-correct-typo.patch -+++ /dev/null -@@ -1,33 +0,0 @@ --From fbd1d5245372e48b494120a30fe0b34b304576c4 Mon Sep 17 00:00:00 2001 --From: Alexandre Belloni --Date: Fri, 9 Nov 2018 17:37:20 +0100 --Subject: [PATCH] net: mvneta: correct typo -- --The reserved variable should be named reserved1. -- --Signed-off-by: Alexandre Belloni --Signed-off-by: David S. Miller ----- -- drivers/net/ethernet/marvell/mvneta.c | 4 ++-- -- 1 file changed, 2 insertions(+), 2 deletions(-) -- ----- a/drivers/net/ethernet/marvell/mvneta.c --+++ b/drivers/net/ethernet/marvell/mvneta.c --@@ -495,7 +495,7 @@ struct mvneta_port { -- #if defined(__LITTLE_ENDIAN) -- struct mvneta_tx_desc { -- u32 command; /* Options used by HW for packet transmitting.*/ --- u16 reserverd1; /* csum_l4 (for future use) */ --+ u16 reserved1; /* csum_l4 (for future use) */ -- u16 data_size; /* Data size of transmitted packet in bytes */ -- u32 buf_phys_addr; /* Physical addr of transmitted buffer */ -- u32 reserved2; /* hw_cmd - (for future use, PMT) */ --@@ -520,7 +520,7 @@ struct mvneta_rx_desc { -- #else -- struct mvneta_tx_desc { -- u16 data_size; /* Data size of transmitted packet in bytes */ --- u16 reserverd1; /* csum_l4 (for future use) */ --+ u16 reserved1; /* csum_l4 (for future use) */ -- u32 command; /* Options used by HW for packet transmitting.*/ -- u32 reserved2; /* hw_cmd - (for future use, PMT) */ -- u32 buf_phys_addr; /* Physical addr of transmitted buffer */ -diff --git a/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch b/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch -deleted file mode 100644 -index 01b101283cd..00000000000 ---- a/target/linux/mvebu/patches-5.4/533-net-mvneta-Dont-advertise-2.5G-modes.patch -+++ /dev/null -@@ -1,55 +0,0 @@ --From 83e65df6dfece9eb588735459428f221eb930c0c Mon Sep 17 00:00:00 2001 --From: Maxime Chevallier --Date: Fri, 9 Nov 2018 09:17:33 +0100 --Subject: [PATCH] net: mvneta: Don't advertise 2.5G modes -- --Using 2.5G speed relies on the SerDes lanes being configured --accordingly. The lanes have to be reconfigured to switch between --1G and 2.5G, and for now only the bootloader does this configuration. -- --In the case we add a Comphy driver to handle switching the lanes --dynamically, it's better for now to stick with supporting only 1G and --add advertisement for 2.5G once we really are capable of handling both --speeds without problem. -- --Since the interface mode is initialy taken from the DT, we want to make --sure that adding comphy support won't break boards that don't update --their dtb. -- --Fixes: da58a931f248 ("net: mvneta: Add support for 2500Mbps SGMII") --Reported-by: Andrew Lunn --Reported-by: Russell King --Signed-off-by: Maxime Chevallier --Signed-off-by: David S. Miller ----- -- drivers/net/ethernet/marvell/mvneta.c | 12 +++--------- -- 1 file changed, 3 insertions(+), 9 deletions(-) -- ----- a/drivers/net/ethernet/marvell/mvneta.c --+++ b/drivers/net/ethernet/marvell/mvneta.c --@@ -3361,7 +3361,6 @@ static void mvneta_validate(struct net_d -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_QSGMII && -- state->interface != PHY_INTERFACE_MODE_SGMII && --- state->interface != PHY_INTERFACE_MODE_2500BASEX && -- !phy_interface_mode_is_8023z(state->interface) && -- !phy_interface_mode_is_rgmii(state->interface)) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); --@@ -3375,14 +3374,9 @@ static void mvneta_validate(struct net_d -- /* Asymmetric pause is unsupported */ -- phylink_set(mask, Pause); -- --- /* We cannot use 1Gbps when using the 2.5G interface. */ --- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { --- phylink_set(mask, 2500baseT_Full); --- phylink_set(mask, 2500baseX_Full); --- } else { --- phylink_set(mask, 1000baseT_Full); --- phylink_set(mask, 1000baseX_Full); --- } --+ /* Half-duplex at speeds higher than 100Mbit is unsupported */ --+ phylink_set(mask, 1000baseT_Full); --+ phylink_set(mask, 1000baseX_Full); -- -- if (!phy_interface_mode_is_8023z(state->interface)) { -- /* 10M and 100M are only supported in non-802.3z mode */ -diff --git a/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch b/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch -deleted file mode 100644 -index fd774e08398..00000000000 ---- a/target/linux/mvebu/patches-5.4/534-net-mvneta-remove-redundant-check-for.patch -+++ /dev/null -@@ -1,30 +0,0 @@ --From e4a3e9ff5ba9f6b67595ec2768ed4be2054c2aa5 Mon Sep 17 00:00:00 2001 --From: YueHaibing --Date: Thu, 22 Nov 2018 14:42:00 +0800 --Subject: [PATCH] net: mvneta: remove redundant check for -- eee->tx_lpi_timer < 0 -- --fixes the smatch warning: -- --drivers/net/ethernet/marvell/mvneta.c:4252 mvneta_ethtool_set_eee() warn: -- unsigned 'eee->tx_lpi_timer' is never less than zero. -- --Signed-off-by: YueHaibing --Acked-by: Thomas Petazzoni --Signed-off-by: David S. Miller ----- -- drivers/net/ethernet/marvell/mvneta.c | 3 +-- -- 1 file changed, 1 insertion(+), 2 deletions(-) -- ----- a/drivers/net/ethernet/marvell/mvneta.c --+++ b/drivers/net/ethernet/marvell/mvneta.c --@@ -4268,8 +4268,7 @@ static int mvneta_ethtool_set_eee(struct -- -- /* The Armada 37x documents do not give limits for this other than -- * it being an 8-bit register. */ --- if (eee->tx_lpi_enabled && --- (eee->tx_lpi_timer < 0 || eee->tx_lpi_timer > 255)) --+ if (eee->tx_lpi_enabled && eee->tx_lpi_timer > 255) -- return -EINVAL; -- -- lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0); -diff --git a/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch b/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch -deleted file mode 100644 -index 272beb6950f..00000000000 ---- a/target/linux/mvebu/patches-5.4/535-net-marvell-neta-add-comphy-support.patch -+++ /dev/null -@@ -1,159 +0,0 @@ --From a10c1c8191e04c21769656c2ca8e1c69a6218954 Mon Sep 17 00:00:00 2001 --From: Russell King --Date: Thu, 7 Feb 2019 16:19:26 +0000 --Subject: [PATCH] net: marvell: neta: add comphy support -- --Add support for the common phy binding, so that we can reconfigure the --comphy according to the desired ethernet speed. This will allow us to --support 1000base-X and 2500base-X SFPs dynamically on SolidRun Clearfog. -- --Signed-off-by: Russell King --Signed-off-by: David S. Miller ----- -- drivers/net/ethernet/marvell/mvneta.c | 45 +++++++++++++++++++++++++++++++---- -- 1 file changed, 41 insertions(+), 4 deletions(-) -- ----- a/drivers/net/ethernet/marvell/mvneta.c --+++ b/drivers/net/ethernet/marvell/mvneta.c --@@ -27,6 +27,7 @@ -- #include -- #include -- #include --+#include -- #include -- #include -- #include --@@ -438,6 +439,7 @@ struct mvneta_port { -- struct device_node *dn; -- unsigned int tx_csum_limit; -- struct phylink *phylink; --+ struct phy *comphy; -- -- struct mvneta_bm *bm_priv; -- struct mvneta_bm_pool *pool_long; --@@ -3168,6 +3170,8 @@ static void mvneta_start_dev(struct mvne -- { -- int cpu; -- --+ WARN_ON(phy_power_on(pp->comphy)); --+ -- mvneta_max_rx_size_set(pp, pp->pkt_size); -- mvneta_txq_max_tx_size_set(pp, pp->pkt_size); -- --@@ -3230,6 +3234,8 @@ static void mvneta_stop_dev(struct mvnet -- -- mvneta_tx_reset(pp); -- mvneta_rx_reset(pp); --+ --+ WARN_ON(phy_power_off(pp->comphy)); -- } -- -- static void mvneta_percpu_enable(void *arg) --@@ -3355,6 +3361,7 @@ static int mvneta_set_mac_addr(struct ne -- static void mvneta_validate(struct net_device *ndev, unsigned long *supported, -- struct phylink_link_state *state) -- { --+ struct mvneta_port *pp = netdev_priv(ndev); -- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -- -- /* We only support QSGMII, SGMII, 802.3z and RGMII modes */ --@@ -3375,8 +3382,13 @@ static void mvneta_validate(struct net_d -- phylink_set(mask, Pause); -- -- /* Half-duplex at speeds higher than 100Mbit is unsupported */ --- phylink_set(mask, 1000baseT_Full); --- phylink_set(mask, 1000baseX_Full); --+ if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) { --+ phylink_set(mask, 1000baseT_Full); --+ phylink_set(mask, 1000baseX_Full); --+ } --+ if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { --+ phylink_set(mask, 2500baseX_Full); --+ } -- -- if (!phy_interface_mode_is_8023z(state->interface)) { -- /* 10M and 100M are only supported in non-802.3z mode */ --@@ -3390,6 +3402,11 @@ static void mvneta_validate(struct net_d -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); --+ --+ /* We can only operate at 2500BaseX or 1000BaseX. If requested --+ * to advertise both, only report advertising at 2500BaseX. --+ */ --+ phylink_helper_basex_speed(state); -- } -- -- static int mvneta_mac_link_state(struct net_device *ndev, --@@ -3401,7 +3418,9 @@ static int mvneta_mac_link_state(struct -- gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS); -- -- if (gmac_stat & MVNETA_GMAC_SPEED_1000) --- state->speed = SPEED_1000; --+ state->speed = --+ state->interface == PHY_INTERFACE_MODE_2500BASEX ? --+ SPEED_2500 : SPEED_1000; -- else if (gmac_stat & MVNETA_GMAC_SPEED_100) -- state->speed = SPEED_100; -- else --@@ -3516,12 +3535,20 @@ static void mvneta_mac_config(struct net -- MVNETA_GMAC_FORCE_LINK_DOWN); -- } -- --+ -- /* When at 2.5G, the link partner can send frames with shortened -- * preambles. -- */ -- if (state->speed == SPEED_2500) -- new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; -- --+ if (pp->comphy && --+ (state->interface == PHY_INTERFACE_MODE_SGMII || --+ state->interface == PHY_INTERFACE_MODE_1000BASEX || --+ state->interface == PHY_INTERFACE_MODE_2500BASEX)) --+ WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, --+ state->interface)); --+ -- if (new_ctrl0 != gmac_ctrl0) -- mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); -- if (new_ctrl2 != gmac_ctrl2) --@@ -4434,7 +4461,7 @@ static int mvneta_port_power_up(struct m -- if (phy_mode == PHY_INTERFACE_MODE_QSGMII) -- mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO); -- else if (phy_mode == PHY_INTERFACE_MODE_SGMII || --- phy_mode == PHY_INTERFACE_MODE_1000BASEX) --+ phy_interface_mode_is_8023z(phy_mode)) -- mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); -- else if (!phy_interface_mode_is_rgmii(phy_mode)) -- return -EINVAL; --@@ -4451,6 +4478,7 @@ static int mvneta_probe(struct platform_ -- struct mvneta_port *pp; -- struct net_device *dev; -- struct phylink *phylink; --+ struct phy *comphy; -- const char *dt_mac_addr; -- char hw_mac_addr[ETH_ALEN]; -- const char *mac_from; --@@ -4476,6 +4504,14 @@ static int mvneta_probe(struct platform_ -- goto err_free_irq; -- } -- --+ comphy = devm_of_phy_get(&pdev->dev, dn, NULL); --+ if (comphy == ERR_PTR(-EPROBE_DEFER)) { --+ err = -EPROBE_DEFER; --+ goto err_free_irq; --+ } else if (IS_ERR(comphy)) { --+ comphy = NULL; --+ } --+ -- phylink = phylink_create(dev, pdev->dev.fwnode, phy_mode, -- &mvneta_phylink_ops); -- if (IS_ERR(phylink)) { --@@ -4492,6 +4528,7 @@ static int mvneta_probe(struct platform_ -- pp = netdev_priv(dev); -- spin_lock_init(&pp->lock); -- pp->phylink = phylink; --+ pp->comphy = comphy; -- pp->phy_interface = phy_mode; -- pp->dn = dn; -- -diff --git a/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch b/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch -deleted file mode 100644 -index bac9a55cf0d..00000000000 ---- a/target/linux/mvebu/patches-5.4/536-net-marvell-neta-disable-comphy-when-setting-mode.patch -+++ /dev/null -@@ -1,78 +0,0 @@ --From 031b922bfd60c771588911112f8632783de08e5c Mon Sep 17 00:00:00 2001 --From: =?UTF-8?q?Marek=20Beh=C3=BAn?= --Date: Mon, 25 Feb 2019 17:43:03 +0100 --Subject: [PATCH] net: marvell: neta: disable comphy when setting mode --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --The comphy driver for Armada 3700 by Miquèl Raynal (which is currently --in linux-next) does not actually set comphy mode when phy_set_mode_ext --is called. The mode is set at next call of phy_power_on. -- --Update the driver to semantics similar to mvpp2: helper --mvneta_comphy_init sets comphy mode and powers it on. --When mode is to be changed in mvneta_mac_config, first power the comphy --off, then call mvneta_comphy_init (which sets the mode to new one). -- --Only do this when new mode is different from old mode. -- --This should also work for Armada 38x, since in that comphy driver --methods power_on and power_off are unimplemented. -- --Signed-off-by: Marek Behún --Signed-off-by: David S. Miller ----- -- drivers/net/ethernet/marvell/mvneta.c | 28 +++++++++++++++++++++++----- -- 1 file changed, 23 insertions(+), 5 deletions(-) -- ----- a/drivers/net/ethernet/marvell/mvneta.c --+++ b/drivers/net/ethernet/marvell/mvneta.c --@@ -3166,11 +3166,26 @@ static int mvneta_setup_txqs(struct mvne -- return 0; -- } -- --+static int mvneta_comphy_init(struct mvneta_port *pp) --+{ --+ int ret; --+ --+ if (!pp->comphy) --+ return 0; --+ --+ ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, --+ pp->phy_interface); --+ if (ret) --+ return ret; --+ --+ return phy_power_on(pp->comphy); --+} --+ -- static void mvneta_start_dev(struct mvneta_port *pp) -- { -- int cpu; -- --- WARN_ON(phy_power_on(pp->comphy)); --+ WARN_ON(mvneta_comphy_init(pp)); -- -- mvneta_max_rx_size_set(pp, pp->pkt_size); -- mvneta_txq_max_tx_size_set(pp, pp->pkt_size); --@@ -3542,12 +3557,15 @@ static void mvneta_mac_config(struct net -- if (state->speed == SPEED_2500) -- new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; -- --- if (pp->comphy && --+ if (pp->comphy && pp->phy_interface != state->interface && -- (state->interface == PHY_INTERFACE_MODE_SGMII || -- state->interface == PHY_INTERFACE_MODE_1000BASEX || --- state->interface == PHY_INTERFACE_MODE_2500BASEX)) --- WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, --- state->interface)); --+ state->interface == PHY_INTERFACE_MODE_2500BASEX)) { --+ pp->phy_interface = state->interface; --+ --+ WARN_ON(phy_power_off(pp->comphy)); --+ WARN_ON(mvneta_comphy_init(pp)); --+ } -- -- if (new_ctrl0 != gmac_ctrl0) -- mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); -diff --git a/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch b/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch -deleted file mode 100644 -index 9186ceb0da4..00000000000 ---- a/target/linux/mvebu/patches-5.4/537-net-mvneta-add-2500baset-support.patch -+++ /dev/null -@@ -1,34 +0,0 @@ --From eda3d1b0228484fb52b7244a68fd4cc8a985ed10 Mon Sep 17 00:00:00 2001 --From: Maxime Chevallier --Date: Wed, 27 Mar 2019 17:31:06 +0100 --Subject: [PATCH] net: mvneta: Add 2500BaseT support -- --Some PHYs will use the 2500BaseX PHY_INTERFACE_MODE when being linked --with a partner using 2.5GBaseT. -- --Since we can't autonegotiate this speed between the MAC and the PHY, we --need to have the proper comphy support enabled, to make sure we can --safely advertise 2.5G and 1G in BaseT and be able to switch between both --corresponding PHY interface modes. This is now possible since comphy --support was added to this driver. -- --This commit adds the 2500BaseT mode to the list of supported modes when --using 2500BaseX, and was tested on a setup with an Armada385 and a --88E2010 PHY, both with and without the comphy node in the DT. -- --Signed-off-by: Maxime Chevallier --Signed-off-by: David S. Miller ----- -- drivers/net/ethernet/marvell/mvneta.c | 1 + -- 1 file changed, 1 insertion(+) -- ----- a/drivers/net/ethernet/marvell/mvneta.c --+++ b/drivers/net/ethernet/marvell/mvneta.c --@@ -3402,6 +3402,7 @@ static void mvneta_validate(struct net_d -- phylink_set(mask, 1000baseX_Full); -- } -- if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { --+ phylink_set(mask, 2500baseT_Full); -- phylink_set(mask, 2500baseX_Full); -- } -- -diff --git a/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch b/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch -deleted file mode 100644 -index b759b9fb254..00000000000 ---- a/target/linux/mvebu/patches-5.4/538-phy-add-QSGMII-and-PCIE-modes.patch -+++ /dev/null -@@ -1,28 +0,0 @@ --From c2a90025ad09d830c8d8ae69f485eac6aaaa2472 Mon Sep 17 00:00:00 2001 --From: Quentin Schulz --Date: Thu, 4 Oct 2018 14:22:03 +0200 --Subject: [PATCH] phy: add QSGMII and PCIE modes -- --Prepare for upcoming phys that'll handle QSGMII or PCIe. -- --Reviewed-by: Florian Fainelli --Signed-off-by: Quentin Schulz --Signed-off-by: David S. Miller ----- -- include/linux/phy/phy.h | 2 ++ -- 1 file changed, 2 insertions(+) -- ----- a/include/linux/phy/phy.h --+++ b/include/linux/phy/phy.h --@@ -37,9 +37,11 @@ enum phy_mode { -- PHY_MODE_USB_OTG, -- PHY_MODE_SGMII, -- PHY_MODE_2500SGMII, --+ PHY_MODE_QSGMII, -- PHY_MODE_10GKR, -- PHY_MODE_UFS_HS_A, -- PHY_MODE_UFS_HS_B, --+ PHY_MODE_PCIE, -- }; -- -- /** -diff --git a/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch b/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch -deleted file mode 100644 -index 68fecadce85..00000000000 ---- a/target/linux/mvebu/patches-5.4/539-phy-core-add-PHY_MODE_ETHERNET.patch -+++ /dev/null -@@ -1,24 +0,0 @@ --From 2af8caeee47846a84bc96abc3a72f7c991153040 Mon Sep 17 00:00:00 2001 --From: Grygorii Strashko --Date: Mon, 19 Nov 2018 19:24:21 -0600 --Subject: [PATCH] phy: core: add PHY_MODE_ETHERNET -- --Add new PHY's mode to be used by Ethernet PHY interface drivers or --multipurpose PHYs like serdes. It will be reused in further changes. -- --Signed-off-by: Grygorii Strashko --Signed-off-by: Kishon Vijay Abraham I ----- -- include/linux/phy/phy.h | 1 + -- 1 file changed, 1 insertion(+) -- ----- a/include/linux/phy/phy.h --+++ b/include/linux/phy/phy.h --@@ -42,6 +42,7 @@ enum phy_mode { -- PHY_MODE_UFS_HS_A, -- PHY_MODE_UFS_HS_B, -- PHY_MODE_PCIE, --+ PHY_MODE_ETHERNET, -- }; -- -- /** -diff --git a/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch b/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch -deleted file mode 100644 -index 83908af19e6..00000000000 ---- a/target/linux/mvebu/patches-5.4/540-phy-fix-build-breakage-add-PHY_MODE_SATA.patch -+++ /dev/null -@@ -1,45 +0,0 @@ --From e1706720408e72fb883f6b151c2b3b23d8e7e5b2 Mon Sep 17 00:00:00 2001 --From: John Hubbard --Date: Sat, 12 Jan 2019 17:29:09 -0800 --Subject: [PATCH] phy: fix build breakage: add PHY_MODE_SATA -- --Commit 49e54187ae0b ("ata: libahci_platform: comply to PHY framework") uses --the PHY_MODE_SATA, but that enum had not yet been added. This caused a --build failure for me, with today's linux.git. -- --Also, there is a potentially conflicting (mis-named) PHY_MODE_SATA, hiding --in the Marvell Berlin SATA PHY driver. -- --Fix the build by: -- -- 1) Renaming Marvell's defined value to a more scoped name, -- in order to avoid any potential conflicts: PHY_BERLIN_MODE_SATA. -- -- 2) Adding the missing enum, which was going to be added anyway as part -- of [1]. -- --[1] https://lkml.kernel.org/r/20190108163124.6409-3-miquel.raynal@bootlin.com -- --Fixes: 49e54187ae0b ("ata: libahci_platform: comply to PHY framework") -- --Signed-off-by: John Hubbard --Acked-by: Jens Axboe --Acked-by: Olof Johansson --Cc: Grzegorz Jaszczyk --Cc: Miquel Raynal --Cc: Hans de Goede --Signed-off-by: Linus Torvalds ----- -- include/linux/phy/phy.h | 1 + -- 1 file changed, 1 insertion(+) -- ----- a/include/linux/phy/phy.h --+++ b/include/linux/phy/phy.h --@@ -43,6 +43,7 @@ enum phy_mode { -- PHY_MODE_UFS_HS_B, -- PHY_MODE_PCIE, -- PHY_MODE_ETHERNET, --+ PHY_MODE_SATA -- }; -- -- /** -diff --git a/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch b/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch -deleted file mode 100644 -index e02f203912d..00000000000 ---- a/target/linux/mvebu/patches-5.4/541-phy-core-rework-phy_set_mode-to-accept-phy-mode-and-.patch -+++ /dev/null -@@ -1,134 +0,0 @@ --From 79a5a18aa9d1062205cdcfa183d4cd5241d1b8da Mon Sep 17 00:00:00 2001 --From: Grygorii Strashko --Date: Mon, 19 Nov 2018 19:24:20 -0600 --Subject: [PATCH] phy: core: rework phy_set_mode to accept phy mode and submode -- --Currently the attempt to add support for Ethernet interface mode PHY --(MII/GMII/RGMII) will lead to the necessity of extending enum phy_mode and --duplicate there values from phy_interface_t enum (or introduce more PHY --callbacks) [1]. Both approaches are ineffective and would lead to fast --bloating of enum phy_mode or struct phy_ops in the process of adding more --PHYs for different subsystems which will make them unmaintainable. -- --As discussed in [1] the solution could be to introduce dual level PHYs mode --configuration - PHY mode and PHY submode. The PHY mode will define generic --PHY type (subsystem - PCIE/ETHERNET/USB_) while the PHY submode - subsystem --specific interface mode. The last is usually already defined in --corresponding subsystem headers (phy_interface_t for Ethernet, enum --usb_device_speed for USB). -- --This patch is cumulative change which refactors PHY framework code to --support dual level PHYs mode configuration - PHY mode and PHY submode. It --extends .set_mode() callback to support additional parameter "int submode" --and converts all corresponding PHY drivers to support new .set_mode() --callback declaration. --The new extended PHY API -- int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) --is introduced to support dual level PHYs mode configuration and existing --phy_set_mode() API is converted to macros, so PHY framework consumers do --not need to be changed (~21 matches). -- --[1] http://lkml.kernel.org/r/d63588f6-9ab0-848a-5ad4-8073143bd95d@ti.com --Signed-off-by: Grygorii Strashko --Signed-off-by: Kishon Vijay Abraham I ----- -- drivers/phy/allwinner/phy-sun4i-usb.c | 3 ++- -- drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 +++-- -- drivers/phy/amlogic/phy-meson-gxl-usb3.c | 5 +++-- -- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 3 ++- -- drivers/phy/mediatek/phy-mtk-tphy.c | 2 +- -- drivers/phy/mediatek/phy-mtk-xsphy.c | 2 +- -- drivers/phy/mscc/phy-ocelot-serdes.c | 2 +- -- drivers/phy/phy-core.c | 6 +++--- -- drivers/phy/qualcomm/phy-qcom-qmp.c | 3 ++- -- drivers/phy/qualcomm/phy-qcom-qusb2.c | 3 ++- -- drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 3 ++- -- drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 3 ++- -- drivers/phy/qualcomm/phy-qcom-usb-hs.c | 3 ++- -- drivers/phy/ti/phy-da8xx-usb.c | 3 ++- -- drivers/phy/ti/phy-tusb1210.c | 2 +- -- include/linux/phy/phy.h | 13 ++++++++++--- -- 16 files changed, 39 insertions(+), 22 deletions(-) -- ----- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c --+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c --@@ -512,7 +512,8 @@ static int mvebu_comphy_power_on(struct -- return ret; -- } -- ---static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode) --+static int mvebu_comphy_set_mode(struct phy *phy, --+ enum phy_mode mode, int submode) -- { -- struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); -- ----- a/drivers/phy/phy-core.c --+++ b/drivers/phy/phy-core.c --@@ -360,7 +360,7 @@ int phy_power_off(struct phy *phy) -- } -- EXPORT_SYMBOL_GPL(phy_power_off); -- ---int phy_set_mode(struct phy *phy, enum phy_mode mode) --+int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) -- { -- int ret; -- --@@ -368,14 +368,14 @@ int phy_set_mode(struct phy *phy, enum p -- return 0; -- -- mutex_lock(&phy->mutex); --- ret = phy->ops->set_mode(phy, mode); --+ ret = phy->ops->set_mode(phy, mode, submode); -- if (!ret) -- phy->attrs.mode = mode; -- mutex_unlock(&phy->mutex); -- -- return ret; -- } ---EXPORT_SYMBOL_GPL(phy_set_mode); --+EXPORT_SYMBOL_GPL(phy_set_mode_ext); -- -- int phy_reset(struct phy *phy) -- { ----- a/include/linux/phy/phy.h --+++ b/include/linux/phy/phy.h --@@ -62,7 +62,7 @@ struct phy_ops { -- int (*exit)(struct phy *phy); -- int (*power_on)(struct phy *phy); -- int (*power_off)(struct phy *phy); --- int (*set_mode)(struct phy *phy, enum phy_mode mode); --+ int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode); -- int (*reset)(struct phy *phy); -- int (*calibrate)(struct phy *phy); -- struct module *owner; --@@ -166,7 +166,10 @@ int phy_init(struct phy *phy); -- int phy_exit(struct phy *phy); -- int phy_power_on(struct phy *phy); -- int phy_power_off(struct phy *phy); ---int phy_set_mode(struct phy *phy, enum phy_mode mode); --+int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); --+#define phy_set_mode(phy, mode) \ --+ phy_set_mode_ext(phy, mode, 0) --+ -- static inline enum phy_mode phy_get_mode(struct phy *phy) -- { -- return phy->attrs.mode; --@@ -280,13 +283,17 @@ static inline int phy_power_off(struct p -- return -ENOSYS; -- } -- ---static inline int phy_set_mode(struct phy *phy, enum phy_mode mode) --+static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, --+ int submode) -- { -- if (!phy) -- return 0; -- return -ENOSYS; -- } -- --+#define phy_set_mode(phy, mode) \ --+ phy_set_mode_ext(phy, mode, 0) --+ -- static inline enum phy_mode phy_get_mode(struct phy *phy) -- { -- return PHY_MODE_INVALID; -diff --git a/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch b/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch -deleted file mode 100644 -index 0964da03a8d..00000000000 ---- a/target/linux/mvebu/patches-5.4/542-phy-add-A3700-COMPHY-support.patch -+++ /dev/null -@@ -1,381 +0,0 @@ --From 9695375a3f4a604406f2e61f2b735eca1de931ed Mon Sep 17 00:00:00 2001 --From: Miquel Raynal --Date: Tue, 8 Jan 2019 17:31:20 +0100 --Subject: [PATCH] phy: add A3700 COMPHY support -- --Add a driver to support COMPHY, a hardware block providing shared --serdes PHYs on Marvell Armada 3700. This driver uses SMC calls and --rely on having an up-to-date firmware. -- --SATA, PCie and USB3 host mode have been tested successfully with an --ESPRESSObin. (HS)SGMII mode cannot be tested with this platform. -- --Evan worked on the original driver structure and Grzegorz on the SMC --calls rework. The structure of this driver has been copied from --Antoine Tenart work on CP110 COMPHY driver. -- --Signed-off-by: Miquel Raynal --Co-developed-by: Evan Wang --Signed-off-by: Evan Wang --Co-developed-by: Grzegorz Jaszczyk --Signed-off-by: Grzegorz Jaszczyk --Signed-off-by: Kishon Vijay Abraham I ----- -- drivers/phy/marvell/Kconfig | 12 + -- drivers/phy/marvell/Makefile | 1 + -- drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 318 +++++++++++++++++++++++++++ -- 3 files changed, 331 insertions(+) -- create mode 100644 drivers/phy/marvell/phy-mvebu-a3700-comphy.c -- ----- a/drivers/phy/marvell/Kconfig --+++ b/drivers/phy/marvell/Kconfig --@@ -21,6 +21,18 @@ config PHY_BERLIN_USB -- help -- Enable this to support the USB PHY on Marvell Berlin SoCs. -- --+config PHY_MVEBU_A3700_COMPHY --+ tristate "Marvell A3700 comphy driver" --+ depends on ARCH_MVEBU || COMPILE_TEST --+ depends on OF --+ depends on HAVE_ARM_SMCCC --+ default y --+ select GENERIC_PHY --+ help --+ This driver allows to control the comphy, a hardware block providing --+ shared serdes PHYs on Marvell Armada 3700. Its serdes lanes can be --+ used by various controllers: Ethernet, SATA, USB3, PCIe. --+ -- config PHY_MVEBU_CP110_COMPHY -- tristate "Marvell CP110 comphy driver" -- depends on ARCH_MVEBU || COMPILE_TEST ----- a/drivers/phy/marvell/Makefile --+++ b/drivers/phy/marvell/Makefile --@@ -2,6 +2,7 @@ -- obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o -- obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o -- obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o --+obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o -- obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o -- obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o -- obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o ----- /dev/null --+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c --@@ -0,0 +1,318 @@ --+// SPDX-License-Identifier: GPL-2.0 --+/* --+ * Copyright (C) 2018 Marvell --+ * --+ * Authors: --+ * Evan Wang --+ * Miquèl Raynal --+ * --+ * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart. --+ * SMC call initial support done by Grzegorz Jaszczyk. --+ */ --+ --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+ --+#define MVEBU_A3700_COMPHY_LANES 3 --+#define MVEBU_A3700_COMPHY_PORTS 2 --+ --+/* COMPHY Fast SMC function identifiers */ --+#define COMPHY_SIP_POWER_ON 0x82000001 --+#define COMPHY_SIP_POWER_OFF 0x82000002 --+#define COMPHY_SIP_PLL_LOCK 0x82000003 --+ --+#define COMPHY_FW_MODE_SATA 0x1 --+#define COMPHY_FW_MODE_SGMII 0x2 --+#define COMPHY_FW_MODE_HS_SGMII 0x3 --+#define COMPHY_FW_MODE_USB3H 0x4 --+#define COMPHY_FW_MODE_USB3D 0x5 --+#define COMPHY_FW_MODE_PCIE 0x6 --+#define COMPHY_FW_MODE_RXAUI 0x7 --+#define COMPHY_FW_MODE_XFI 0x8 --+#define COMPHY_FW_MODE_SFI 0x9 --+#define COMPHY_FW_MODE_USB3 0xa --+ --+#define COMPHY_FW_SPEED_1_25G 0 /* SGMII 1G */ --+#define COMPHY_FW_SPEED_2_5G 1 --+#define COMPHY_FW_SPEED_3_125G 2 /* SGMII 2.5G */ --+#define COMPHY_FW_SPEED_5G 3 --+#define COMPHY_FW_SPEED_5_15625G 4 /* XFI 5G */ --+#define COMPHY_FW_SPEED_6G 5 --+#define COMPHY_FW_SPEED_10_3125G 6 /* XFI 10G */ --+#define COMPHY_FW_SPEED_MAX 0x3F --+ --+#define COMPHY_FW_MODE(mode) ((mode) << 12) --+#define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \ --+ ((idx) << 8) | \ --+ ((speed) << 2)) --+#define COMPHY_FW_PCIE(mode, idx, speed, width) (COMPHY_FW_NET(mode, idx, speed) | \ --+ ((width) << 18)) --+ --+struct mvebu_a3700_comphy_conf { --+ unsigned int lane; --+ enum phy_mode mode; --+ int submode; --+ unsigned int port; --+ u32 fw_mode; --+}; --+ --+#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _port, _fw) \ --+ { \ --+ .lane = _lane, \ --+ .mode = _mode, \ --+ .submode = _smode, \ --+ .port = _port, \ --+ .fw_mode = _fw, \ --+ } --+ --+#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _port, _fw) \ --+ MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _port, _fw) --+ --+#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _port, _fw) \ --+ MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _port, _fw) --+ --+static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { --+ /* lane 0 */ --+ MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, 0, --+ COMPHY_FW_MODE_USB3H), --+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, 1, --+ COMPHY_FW_MODE_SGMII), --+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, 1, --+ COMPHY_FW_MODE_HS_SGMII), --+ /* lane 1 */ --+ MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, 0, --+ COMPHY_FW_MODE_PCIE), --+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0, --+ COMPHY_FW_MODE_SGMII), --+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, 0, --+ COMPHY_FW_MODE_HS_SGMII), --+ /* lane 2 */ --+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, 0, --+ COMPHY_FW_MODE_SATA), --+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, 0, --+ COMPHY_FW_MODE_USB3H), --+}; --+ --+struct mvebu_a3700_comphy_lane { --+ struct device *dev; --+ unsigned int id; --+ enum phy_mode mode; --+ int submode; --+ int port; --+}; --+ --+static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane, --+ unsigned long mode) --+{ --+ struct arm_smccc_res res; --+ --+ arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); --+ --+ return res.a0; --+} --+ --+static int mvebu_a3700_comphy_get_fw_mode(int lane, int port, --+ enum phy_mode mode, --+ int submode) --+{ --+ int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes); --+ --+ /* Unused PHY mux value is 0x0 */ --+ if (mode == PHY_MODE_INVALID) --+ return -EINVAL; --+ --+ for (i = 0; i < n; i++) { --+ if (mvebu_a3700_comphy_modes[i].lane == lane && --+ mvebu_a3700_comphy_modes[i].port == port && --+ mvebu_a3700_comphy_modes[i].mode == mode && --+ mvebu_a3700_comphy_modes[i].submode == submode) --+ break; --+ } --+ --+ if (i == n) --+ return -EINVAL; --+ --+ return mvebu_a3700_comphy_modes[i].fw_mode; --+} --+ --+static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, --+ int submode) --+{ --+ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); --+ int fw_mode; --+ --+ if (submode == PHY_INTERFACE_MODE_1000BASEX) --+ submode = PHY_INTERFACE_MODE_SGMII; --+ --+ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, mode, --+ submode); --+ if (fw_mode < 0) { --+ dev_err(lane->dev, "invalid COMPHY mode\n"); --+ return fw_mode; --+ } --+ --+ /* Just remember the mode, ->power_on() will do the real setup */ --+ lane->mode = mode; --+ lane->submode = submode; --+ --+ return 0; --+} --+ --+static int mvebu_a3700_comphy_power_on(struct phy *phy) --+{ --+ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); --+ u32 fw_param; --+ int fw_mode; --+ --+ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, --+ lane->mode, lane->submode); --+ if (fw_mode < 0) { --+ dev_err(lane->dev, "invalid COMPHY mode\n"); --+ return fw_mode; --+ } --+ --+ switch (lane->mode) { --+ case PHY_MODE_USB_HOST_SS: --+ dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); --+ fw_param = COMPHY_FW_MODE(fw_mode); --+ break; --+ case PHY_MODE_SATA: --+ dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); --+ fw_param = COMPHY_FW_MODE(fw_mode); --+ break; --+ case PHY_MODE_ETHERNET: --+ switch (lane->submode) { --+ case PHY_INTERFACE_MODE_SGMII: --+ dev_dbg(lane->dev, "set lane %d to SGMII mode\n", --+ lane->id); --+ fw_param = COMPHY_FW_NET(fw_mode, lane->port, --+ COMPHY_FW_SPEED_1_25G); --+ break; --+ case PHY_INTERFACE_MODE_2500BASEX: --+ dev_dbg(lane->dev, "set lane %d to HS SGMII mode\n", --+ lane->id); --+ fw_param = COMPHY_FW_NET(fw_mode, lane->port, --+ COMPHY_FW_SPEED_3_125G); --+ break; --+ default: --+ dev_err(lane->dev, "unsupported PHY submode (%d)\n", --+ lane->submode); --+ return -ENOTSUPP; --+ } --+ break; --+ case PHY_MODE_PCIE: --+ dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); --+ fw_param = COMPHY_FW_PCIE(fw_mode, lane->port, --+ COMPHY_FW_SPEED_5G, --+ phy->attrs.bus_width); --+ break; --+ default: --+ dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); --+ return -ENOTSUPP; --+ } --+ --+ return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); --+} --+ --+static int mvebu_a3700_comphy_power_off(struct phy *phy) --+{ --+ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); --+ --+ return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_OFF, lane->id, 0); --+} --+ --+static const struct phy_ops mvebu_a3700_comphy_ops = { --+ .power_on = mvebu_a3700_comphy_power_on, --+ .power_off = mvebu_a3700_comphy_power_off, --+ .set_mode = mvebu_a3700_comphy_set_mode, --+ .owner = THIS_MODULE, --+}; --+ --+static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, --+ struct of_phandle_args *args) --+{ --+ struct mvebu_a3700_comphy_lane *lane; --+ struct phy *phy; --+ --+ if (WARN_ON(args->args[0] >= MVEBU_A3700_COMPHY_PORTS)) --+ return ERR_PTR(-EINVAL); --+ --+ phy = of_phy_simple_xlate(dev, args); --+ if (IS_ERR(phy)) --+ return phy; --+ --+ lane = phy_get_drvdata(phy); --+ lane->port = args->args[0]; --+ --+ return phy; --+} --+ --+static int mvebu_a3700_comphy_probe(struct platform_device *pdev) --+{ --+ struct phy_provider *provider; --+ struct device_node *child; --+ --+ for_each_available_child_of_node(pdev->dev.of_node, child) { --+ struct mvebu_a3700_comphy_lane *lane; --+ struct phy *phy; --+ int ret; --+ u32 lane_id; --+ --+ ret = of_property_read_u32(child, "reg", &lane_id); --+ if (ret < 0) { --+ dev_err(&pdev->dev, "missing 'reg' property (%d)\n", --+ ret); --+ continue; --+ } --+ --+ if (lane_id >= MVEBU_A3700_COMPHY_LANES) { --+ dev_err(&pdev->dev, "invalid 'reg' property\n"); --+ continue; --+ } --+ --+ lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); --+ if (!lane) --+ return -ENOMEM; --+ --+ phy = devm_phy_create(&pdev->dev, child, --+ &mvebu_a3700_comphy_ops); --+ if (IS_ERR(phy)) --+ return PTR_ERR(phy); --+ --+ lane->dev = &pdev->dev; --+ lane->mode = PHY_MODE_INVALID; --+ lane->submode = PHY_INTERFACE_MODE_NA; --+ lane->id = lane_id; --+ lane->port = -1; --+ phy_set_drvdata(phy, lane); --+ } --+ --+ provider = devm_of_phy_provider_register(&pdev->dev, --+ mvebu_a3700_comphy_xlate); --+ return PTR_ERR_OR_ZERO(provider); --+} --+ --+static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = { --+ { .compatible = "marvell,comphy-a3700" }, --+ { }, --+}; --+MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table); --+ --+static struct platform_driver mvebu_a3700_comphy_driver = { --+ .probe = mvebu_a3700_comphy_probe, --+ .driver = { --+ .name = "mvebu-a3700-comphy", --+ .of_match_table = mvebu_a3700_comphy_of_match_table, --+ }, --+}; --+module_platform_driver(mvebu_a3700_comphy_driver); --+ --+MODULE_AUTHOR("Miquèl Raynal "); --+MODULE_DESCRIPTION("Common PHY driver for A3700"); --+MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch b/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch -deleted file mode 100644 -index 393f8237944..00000000000 ---- a/target/linux/mvebu/patches-5.4/543-arm64-dts-marvell-armada-37xx-declare-the-COMPHY.patch -+++ /dev/null -@@ -1,58 +0,0 @@ --From 2ef303f0fe44feee4a3ca8bd62fca86c105927d2 Mon Sep 17 00:00:00 2001 --From: Miquel Raynal --Date: Tue, 8 Jan 2019 17:31:24 +0100 --Subject: [PATCH] arm64: dts: marvell: armada-37xx: declare the COMPHY -- node -- --Describe the A3700 COMPHY node. It has three PHYs that can be --configured as follow: --* PCIe or GbE --* USB3 or GbE --* SATA or USB3 --Each of them has its own memory area. -- --Suggested-by: Grzegorz Jaszczyk --Signed-off-by: Miquel Raynal --Signed-off-by: Gregory CLEMENT ----- -- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 29 ++++++++++++++++++++++++++++ -- 1 file changed, 29 insertions(+) -- ----- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi --+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi --@@ -235,6 +235,35 @@ -- reg = <0x14000 0x60>; -- }; -- --+ comphy: phy@18300 { --+ compatible = "marvell,comphy-a3700"; --+ reg = <0x18300 0x300>, --+ <0x1F000 0x400>, --+ <0x5C000 0x400>, --+ <0xe0178 0x8>; --+ reg-names = "comphy", --+ "lane1_pcie_gbe", --+ "lane0_usb3_gbe", --+ "lane2_sata_usb3"; --+ #address-cells = <1>; --+ #size-cells = <0>; --+ --+ comphy0: phy@0 { --+ reg = <0>; --+ #phy-cells = <1>; --+ }; --+ --+ comphy1: phy@1 { --+ reg = <1>; --+ #phy-cells = <1>; --+ }; --+ --+ comphy2: phy@2 { --+ reg = <2>; --+ #phy-cells = <1>; --+ }; --+ }; --+ -- pinctrl_sb: pinctrl@18800 { -- compatible = "marvell,armada3710-sb-pinctrl", -- "syscon", "simple-mfd"; -diff --git a/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch b/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch -deleted file mode 100644 -index f72ea93b97e..00000000000 ---- a/target/linux/mvebu/patches-5.4/544-arm64-dts-uDPU-fix-comphy-definitions.patch -+++ /dev/null -@@ -1,35 +0,0 @@ --From 9c222a1d78a1700220e38feb270f00d2ddd3c5ab Mon Sep 17 00:00:00 2001 --From: Russell King --Date: Wed, 6 Nov 2019 13:44:21 +0000 --Subject: [PATCH 657/660] arm64: dts: uDPU: fix comphy definitions -- --The uDPU uses both ethernet controllers, which ties up COMPHY 0 for --eth1 and COMPHY 1 for eth0, with no USB3 comphy. The addition of --COMPHY support made the kernel override the setup by the boot loader --breaking this platform. Delete the USB3 COMPHY definition at platform --level, and add phy specifications for the ethernet channels. -- --Fixes: bd3d25b07342 ("arm64: dts: marvell: armada-37xx: link USB hosts with their PHYs") --Signed-off-by: Russell King ----- -- arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts | 2 ++ -- 1 file changed, 2 insertions(+) -- ----- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts --+++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts --@@ -143,6 +143,7 @@ -- status = "okay"; -- phy-mode = "sgmii"; -- managed = "in-band-status"; --+ phys = <&comphy1 0>; -- sfp = <&sfp_eth0>; -- }; -- --@@ -150,6 +151,7 @@ -- status = "okay"; -- phy-mode = "sgmii"; -- managed = "in-band-status"; --+ phys = <&comphy0 1>; -- sfp = <&sfp_eth1>; -- }; -- - -From 192ccdd1402b8e010b3d811372cd1146a123d461 Mon Sep 17 00:00:00 2001 -From: DENG Qingfang -Date: Wed, 4 Mar 2020 20:46:33 +0800 -Subject: [PATCH 4/4] mvebu: refresh config - -Signed-off-by: DENG Qingfang ---- - target/linux/mvebu/config-5.4 | 61 ++++++++++++++++++------- - target/linux/mvebu/cortexa53/config-5.4 | 1 + - target/linux/mvebu/cortexa72/config-5.4 | 1 + - 3 files changed, 47 insertions(+), 16 deletions(-) - -diff --git a/target/linux/mvebu/config-5.4 b/target/linux/mvebu/config-5.4 -index 24093fd386a..41a826ef7f8 100644 ---- a/target/linux/mvebu/config-5.4 -+++ b/target/linux/mvebu/config-5.4 -@@ -1,20 +1,25 @@ - CONFIG_AHCI_MVEBU=y - CONFIG_ALIGNMENT_TRAP=y -+CONFIG_ARCH_32BIT_OFF_T=y - CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_ARCH_HAS_BINFMT_FLAT=y - CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y - CONFIG_ARCH_HAS_ELF_RANDOMIZE=y - CONFIG_ARCH_HAS_FORTIFY_SOURCE=y - CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y - CONFIG_ARCH_HAS_KCOV=y -+CONFIG_ARCH_HAS_KEEPINITRD=y - CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y - CONFIG_ARCH_HAS_PHYS_TO_DMA=y -+CONFIG_ARCH_HAS_SETUP_DMA_OPS=y - CONFIG_ARCH_HAS_SET_MEMORY=y --CONFIG_ARCH_HAS_SG_CHAIN=y - CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y - CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -+CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y - CONFIG_ARCH_HAS_TICK_BROADCAST=y - CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y - CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_ARCH_KEEP_MEMBLOCK=y - CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y - CONFIG_ARCH_MULTIPLATFORM=y - CONFIG_ARCH_MULTI_V6_V7=y -@@ -29,17 +34,20 @@ CONFIG_ARCH_SUPPORTS_UPROBES=y - CONFIG_ARCH_SUSPEND_POSSIBLE=y - CONFIG_ARCH_USE_BUILTIN_BSWAP=y - CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y - CONFIG_ARCH_WANT_GENERAL_HUGETLB=y - CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y - CONFIG_ARM=y - CONFIG_ARMADA_370_CLK=y - CONFIG_ARMADA_370_XP_IRQ=y - CONFIG_ARMADA_370_XP_TIMER=y -+# CONFIG_ARMADA_37XX_WATCHDOG is not set - CONFIG_ARMADA_38X_CLK=y - CONFIG_ARMADA_THERMAL=y - CONFIG_ARMADA_XP_CLK=y - CONFIG_ARM_APPENDED_DTB=y - # CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set -+# CONFIG_ARM_ARMADA_8K_CPUFREQ is not set - CONFIG_ARM_ATAG_DTB_COMPAT=y - # CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set - # CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set -@@ -66,6 +74,7 @@ CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y - CONFIG_ATA=y - CONFIG_ATAGS=y - CONFIG_AUTO_ZRELADDR=y -+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_SD=y - CONFIG_BLK_MQ_PCI=y -@@ -78,6 +87,7 @@ CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y - CONFIG_CLKSRC_MMIO=y - CONFIG_CLONE_BACKWARDS=y - CONFIG_COMMON_CLK=y -+CONFIG_COMPAT_32BIT_TIME=y - CONFIG_CPUFREQ_DT=y - CONFIG_CPUFREQ_DT_PLATDEV=y - CONFIG_CPU_32v6K=y -@@ -104,8 +114,10 @@ CONFIG_CPU_FREQ_STAT=y - CONFIG_CPU_HAS_ASID=y - # CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set - # CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set - CONFIG_CPU_IDLE=y - CONFIG_CPU_IDLE_GOV_LADDER=y -+# CONFIG_CPU_IDLE_GOV_TEO is not set - CONFIG_CPU_PABRT_V7=y - CONFIG_CPU_PJ4B=y - CONFIG_CPU_PM=y -@@ -122,6 +134,7 @@ CONFIG_CRYPTO_AEAD2=y - CONFIG_CRYPTO_AES_ARM=y - CONFIG_CRYPTO_AES_ARM_BS=y - # CONFIG_CRYPTO_AES_ARM_CE is not set -+CONFIG_CRYPTO_ALGAPI=y - # CONFIG_CRYPTO_CHACHA20_NEON is not set - CONFIG_CRYPTO_CRC32=y - CONFIG_CRYPTO_CRC32C=y -@@ -130,10 +143,13 @@ CONFIG_CRYPTO_CRYPTD=y - CONFIG_CRYPTO_DEFLATE=y - CONFIG_CRYPTO_DES=y - CONFIG_CRYPTO_DEV_MARVELL_CESA=y -+CONFIG_CRYPTO_ESSIV=y - # CONFIG_CRYPTO_GHASH_ARM_CE is not set - CONFIG_CRYPTO_HASH=y - CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_HASH_INFO=y - CONFIG_CRYPTO_HW=y -+CONFIG_CRYPTO_LIB_DES=y - CONFIG_CRYPTO_LZO=y - CONFIG_CRYPTO_MANAGER=y - CONFIG_CRYPTO_MANAGER2=y -@@ -147,7 +163,7 @@ CONFIG_CRYPTO_SHA256_ARM=y - # CONFIG_CRYPTO_SHA2_ARM_CE is not set - CONFIG_CRYPTO_SHA512_ARM=y - CONFIG_CRYPTO_SIMD=y --CONFIG_CRYPTO_WORKQUEUE=y -+CONFIG_CRYPTO_ZSTD=y - CONFIG_DCACHE_WORD_ACCESS=y - CONFIG_DEBUG_ALIGN_RODATA=y - CONFIG_DEBUG_INFO=y -@@ -165,9 +181,11 @@ CONFIG_DEBUG_UART_VIRT=0xfec12000 - CONFIG_DEBUG_UNCOMPRESS=y - CONFIG_DEBUG_USER=y - CONFIG_DMADEVICES=y -+CONFIG_DMA_DECLARE_COHERENT=y - CONFIG_DMA_ENGINE=y - CONFIG_DMA_ENGINE_RAID=y - CONFIG_DMA_OF=y -+CONFIG_DMA_REMAP=y - CONFIG_DTC=y - CONFIG_EARLY_PRINTK=y - CONFIG_EDAC_ATOMIC_SCRUB=y -@@ -183,6 +201,7 @@ CONFIG_FIXED_PHY=y - CONFIG_FIX_EARLYCON_MEM=y - CONFIG_FS_IOMAP=y - CONFIG_FS_MBCACHE=y -+CONFIG_FW_LOADER_PAGED_BUF=y - CONFIG_GENERIC_ALLOCATOR=y - CONFIG_GENERIC_ARCH_TOPOLOGY=y - CONFIG_GENERIC_BUG=y -@@ -234,6 +253,7 @@ CONFIG_HAVE_ARM_TWD=y - CONFIG_HAVE_CLK=y - CONFIG_HAVE_CLK_PREPARE=y - CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_COPY_THREAD_TLS=y - CONFIG_HAVE_C_RECORDMCOUNT=y - CONFIG_HAVE_DEBUG_KMEMLEAK=y - CONFIG_HAVE_DMA_CONTIGUOUS=y -@@ -244,15 +264,14 @@ CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y - CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y - CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y - CONFIG_HAVE_FUNCTION_TRACER=y --CONFIG_HAVE_GENERIC_DMA_COHERENT=y - CONFIG_HAVE_IDE=y - CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y - CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y --CONFIG_HAVE_MEMBLOCK=y - CONFIG_HAVE_MOD_ARCH_SPECIFIC=y - CONFIG_HAVE_NET_DSA=y - CONFIG_HAVE_OPROFILE=y - CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_PCI=y - CONFIG_HAVE_PERF_EVENTS=y - CONFIG_HAVE_PERF_REGS=y - CONFIG_HAVE_PERF_USER_STACK_DUMP=y -@@ -284,6 +303,7 @@ CONFIG_IRQ_FORCED_THREADING=y - CONFIG_IRQ_WORK=y - # CONFIG_IWMMXT is not set - CONFIG_JBD2=y -+# CONFIG_KASAN_STACK is not set - CONFIG_LEDS_GPIO=y - CONFIG_LEDS_PCA963X=y - CONFIG_LEDS_TLC591XX=y -@@ -310,7 +330,6 @@ CONFIG_MDIO_I2C=y - CONFIG_MEMFD_CREATE=y - CONFIG_MEMORY=y - CONFIG_MIGHT_HAVE_CACHE_L2X0=y --CONFIG_MIGHT_HAVE_PCI=y - CONFIG_MIGRATION=y - CONFIG_MMC=y - CONFIG_MMC_BLOCK=y -@@ -322,10 +341,10 @@ CONFIG_MMC_SDHCI_PXAV3=y - # CONFIG_MMC_TIFM_SD is not set - CONFIG_MODULES_USE_ELF_REL=y - CONFIG_MTD_CFI_STAA=y --CONFIG_MTD_M25P80=y --CONFIG_MTD_NAND=y --CONFIG_MTD_NAND_ECC=y -+CONFIG_MTD_NAND_CORE=y -+CONFIG_MTD_NAND_ECC_SW_HAMMING=y - CONFIG_MTD_NAND_MARVELL=y -+CONFIG_MTD_RAW_NAND=y - CONFIG_MTD_SPI_NOR=y - CONFIG_MTD_SPLIT_FIRMWARE=y - CONFIG_MTD_UBI=y -@@ -344,11 +363,12 @@ CONFIG_MVMDIO=y - CONFIG_MVNETA=y - CONFIG_MVNETA_BM=y - CONFIG_MVNETA_BM_ENABLE=y --CONFIG_MVPP2=y -+# CONFIG_MVPP2 is not set - CONFIG_MVSW61XX_PHY=y - CONFIG_MV_XOR=y - CONFIG_NEED_DMA_MAP_STATE=y - CONFIG_NEON=y -+CONFIG_NET_DEVLINK=y - CONFIG_NET_DSA=y - CONFIG_NET_DSA_MV88E6XXX=y - CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y -@@ -359,7 +379,6 @@ CONFIG_NET_FLOW_LIMIT=y - CONFIG_NET_SWITCHDEV=y - CONFIG_NLS=y - CONFIG_NOP_USB_XCEIV=y --CONFIG_NO_BOOTMEM=y - CONFIG_NR_CPUS=4 - CONFIG_NVMEM=y - CONFIG_OF=y -@@ -380,17 +399,19 @@ CONFIG_OUTER_CACHE_SYNC=y - CONFIG_PADATA=y - CONFIG_PAGE_OFFSET=0xC0000000 - CONFIG_PCI=y -+CONFIG_PCI_BRIDGE_EMUL=y - CONFIG_PCI_DOMAINS=y - CONFIG_PCI_DOMAINS_GENERIC=y - CONFIG_PCI_MSI=y - CONFIG_PCI_MSI_IRQ_DOMAIN=y - CONFIG_PCI_MVEBU=y --# CONFIG_PCI_V3_SEMI is not set - CONFIG_PERF_USE_VMALLOC=y - CONFIG_PGTABLE_LEVELS=2 - CONFIG_PHYLIB=y - CONFIG_PHYLINK=y - # CONFIG_PHY_MVEBU_A3700_COMPHY is not set -+# CONFIG_PHY_MVEBU_A3700_UTMI is not set -+# CONFIG_PHY_MVEBU_A38X_COMPHY is not set - # CONFIG_PHY_MVEBU_CP110_COMPHY is not set - CONFIG_PINCTRL=y - CONFIG_PINCTRL_ARMADA_370=y -@@ -415,7 +436,6 @@ CONFIG_REFCOUNT_FULL=y - CONFIG_REGMAP=y - CONFIG_REGMAP_I2C=y - CONFIG_REGMAP_MMIO=y --CONFIG_REGMAP_SPI=y - CONFIG_REGULATOR=y - CONFIG_REGULATOR_FIXED_VOLTAGE=y - CONFIG_RFS_ACCEL=y -@@ -424,9 +444,7 @@ CONFIG_RTC_CLASS=y - CONFIG_RTC_DRV_ARMADA38X=y - CONFIG_RTC_DRV_MV=y - CONFIG_RTC_I2C_AND_SPI=y --CONFIG_RTC_MC146818_LIB=y - CONFIG_RWSEM_SPIN_ON_OWNER=y --CONFIG_RWSEM_XCHGADD_ALGORITHM=y - CONFIG_SATA_AHCI_PLATFORM=y - CONFIG_SATA_MV=y - CONFIG_SATA_PMP=y -@@ -434,7 +452,9 @@ CONFIG_SCSI=y - CONFIG_SENSORS_PWM_FAN=y - CONFIG_SENSORS_TMP421=y - CONFIG_SERIAL_8250_DW=y --CONFIG_SERIAL_8250_FSL=y -+CONFIG_SERIAL_8250_DWLIB=y -+# CONFIG_SERIAL_8250_FSL is not set -+CONFIG_SERIAL_MCTRL_GPIO=y - CONFIG_SERIAL_MVEBU_CONSOLE=y - CONFIG_SERIAL_MVEBU_UART=y - CONFIG_SFP=y -@@ -469,12 +489,18 @@ CONFIG_TIMER_PROBE=y - CONFIG_TREE_RCU=y - CONFIG_TREE_SRCU=y - CONFIG_UBIFS_FS=y --# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_ADVANCED_COMPR=y - CONFIG_UBIFS_FS_LZO=y - CONFIG_UBIFS_FS_ZLIB=y -+CONFIG_UBIFS_FS_ZSTD=y -+# CONFIG_UBSAN_ALIGNMENT is not set - CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+CONFIG_UNIX_SCM=y -+CONFIG_UNWINDER_ARM=y -+# CONFIG_UNWINDER_FRAME_POINTER is not set - CONFIG_USB=y - CONFIG_USB_COMMON=y -+# CONFIG_USB_EHCI_FSL is not set - CONFIG_USB_EHCI_HCD=y - CONFIG_USB_EHCI_HCD_ORION=y - CONFIG_USB_EHCI_HCD_PLATFORM=y -@@ -490,9 +516,12 @@ CONFIG_VFP=y - CONFIG_VFPv3=y - CONFIG_WATCHDOG_CORE=y - CONFIG_XPS=y -+CONFIG_XXHASH=y - CONFIG_XZ_DEC_ARM=y - CONFIG_XZ_DEC_BCJ=y - CONFIG_ZBOOT_ROM_BSS=0x0 - CONFIG_ZBOOT_ROM_TEXT=0x0 - CONFIG_ZLIB_DEFLATE=y - CONFIG_ZLIB_INFLATE=y -+CONFIG_ZSTD_COMPRESS=y -+CONFIG_ZSTD_DECOMPRESS=y -diff --git a/target/linux/mvebu/cortexa53/config-5.4 b/target/linux/mvebu/cortexa53/config-5.4 -index 7f3c2b21de0..16d861be110 100644 ---- a/target/linux/mvebu/cortexa53/config-5.4 -+++ b/target/linux/mvebu/cortexa53/config-5.4 -@@ -144,6 +144,7 @@ CONFIG_PCI_AARDVARK=y - CONFIG_PGTABLE_LEVELS=3 - CONFIG_PHYS_ADDR_T_64BIT=y - CONFIG_PHY_MVEBU_A3700_COMPHY=y -+CONFIG_PHY_MVEBU_A3700_UTMI=y - CONFIG_PINCTRL_ARMADA_37XX=y - CONFIG_PINCTRL_ARMADA_AP806=y - CONFIG_PINCTRL_ARMADA_CP110=y -diff --git a/target/linux/mvebu/cortexa72/config-5.4 b/target/linux/mvebu/cortexa72/config-5.4 -index c78eb843724..5727ae5918d 100644 ---- a/target/linux/mvebu/cortexa72/config-5.4 -+++ b/target/linux/mvebu/cortexa72/config-5.4 -@@ -138,6 +138,7 @@ CONFIG_MVEBU_GICP=y - CONFIG_MVEBU_ICU=y - CONFIG_MVEBU_ODMI=y - CONFIG_MVEBU_PIC=y -+CONFIG_MVPP2=y - CONFIG_MV_XOR_V2=y - CONFIG_NEED_SG_DMA_LENGTH=y - # CONFIG_NUMA is not set From b1be088d7f7ce6e283dfea7a34f4a991341aa29e Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 17 Apr 2020 15:04:33 +0200 Subject: [PATCH 35/76] Fix for some themes --- config | 1 + 1 file changed, 1 insertion(+) diff --git a/config b/config index 374ec969..25f43785 100644 --- a/config +++ b/config @@ -234,3 +234,4 @@ CONFIG_LUCI_LANG_it=y CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=64 CONFIG_OPENSSL_WITH_CHACHA_POLY1305=y +# CONFIG_LUCI_CSSTIDY is not set \ No newline at end of file From 8b04e8ac65bbcfdbf526300a115d08e346c6dc10 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 20 Apr 2020 09:45:14 +0200 Subject: [PATCH 36/76] Add patches for BPI-R2 --- config-bpi-r2 | 8 +- root/target/linux/mediatek/mt7623/config-5.4 | 13 +- .../0006-dts-fix-bpi2-console.patch | 10 + .../0100-dts-add-second-gmac.patch | 54 ++ .../patches-5.4/0101-dsa-enable-vlan.patch | 43 ++ .../0102-dsa-mt7530-Extend-device-data.patch | 389 ++++++++++++++ .../0103-net-support-net-labels.patch | 39 ++ .../0104-dts-add-pause-to-port6.patch | 22 + .../patches-5.4/0110-rtc-mt6397.patch | 249 +++++++++ .../patches-5.4/0111-mt6323-poweroff.patch | 160 ++++++ .../0112-dts-mt6323-add-key-rtc-power.patch | 57 ++ .../0170-dts-mt7623-add-display.patch | 500 ++++++++++++++++++ .../0171-dts-mt7623-add-mali450.patch | 77 +++ .../patches-5.4/0180-lima-power-on-off.patch | 68 +++ .../0181-drm-Add-get_possible_crtc.patch | 84 +++ .../0182-drm-change-possible_crtc.patch | 45 ++ .../patches-5.4/0183-drm-fix-DRM_INFO.patch | 21 + .../0184-drm-config-component-output.patch | 146 +++++ .../patches-5.4/0185-drm-fix-boot-up.patch | 55 ++ .../patches-5.4/0190-thermal-add-sensor.patch | 56 ++ .../mediatek/patches-5.4/0191-thermal.patch | 35 ++ .../mediatek/patches-5.4/0230-pthread.patch | 14 + .../patches-5.4/0999-lan-to-wan.patch | 49 ++ 23 files changed, 2179 insertions(+), 15 deletions(-) create mode 100644 root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0100-dts-add-second-gmac.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0101-dsa-enable-vlan.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0102-dsa-mt7530-Extend-device-data.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0104-dts-add-pause-to-port6.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0191-thermal.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0230-pthread.patch create mode 100644 root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch diff --git a/config-bpi-r2 b/config-bpi-r2 index 3de8b943..8b2fd154 100644 --- a/config-bpi-r2 +++ b/config-bpi-r2 @@ -7,11 +7,13 @@ CONFIG_PACKAGE_kmod-cryptodev=y CONFIG_OPENSSL_HARDWARE_SUPPORT=y CONFIG_OPENSSL_ENGINE_CRYPTO=y CONFIG_OPENSSL_ENGINE_DIGEST=y -CONFIG_PACKAGE_wmt=y -CONFIG_PACKAGE_kmod-mt6625l-wlan-gen2=y -CONFIG_PACKAGE_u-boot-bpi_r2=y CONFIG_PACKAGE_uboot-envtools=y CONFIG_PACKAGE_attr=y CONFIG_PACKAGE_f2fs-tools=y CONFIG_PACKAGE_f2fsck=y CONFIG_PACKAGE_mkf2fs=y +# CONFIG_PACKAGE_kmod-fs-nfs-v3 is not set +# CONFIG_PACKAGE_kmod-fs-nfs-v4 is not set +# CONFIG_PACKAGE_kmod-rtl8812au-ct is not set +# CONFIG_PACKAGE_kmod-mt6625l-bt is not set +# CONFIG_PACKAGE_kmod-mt6625l-wlan-gen-2 is not set \ No newline at end of file diff --git a/root/target/linux/mediatek/mt7623/config-5.4 b/root/target/linux/mediatek/mt7623/config-5.4 index 03a0a002..6e1ff28b 100644 --- a/root/target/linux/mediatek/mt7623/config-5.4 +++ b/root/target/linux/mediatek/mt7623/config-5.4 @@ -1,12 +1,4 @@ # CONFIG_AIO is not set -CONFIG_AHCI_MTK=y -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_AHCI_PLATFORM=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_RTC_DRV_MT7622=y -CONFIG_WATCHDOG_SYSFS=y CONFIG_ALIGNMENT_TRAP=y CONFIG_ARCH_32BIT_OFF_T=y CONFIG_ARCH_CLOCKSOURCE_DATA=y @@ -50,9 +42,7 @@ CONFIG_ARM=y CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ATAG_DTB_COMPAT=y -CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set +# CONFIG_ARM_ATAG_DTB_COMPAT is not set CONFIG_ARM_CPU_SUSPEND=y # CONFIG_ARM_CPU_TOPOLOGY is not set # CONFIG_ARM_ERRATA_814220 is not set @@ -211,7 +201,6 @@ CONFIG_EINT_MTK=y CONFIG_ELF_CORE=y # CONFIG_ENERGY_MODEL is not set CONFIG_EXT4_FS=y -CONFIG_VFAT_FS=y # CONFIG_F2FS_CHECK_FS is not set CONFIG_F2FS_FS=y # CONFIG_F2FS_FS_SECURITY is not set diff --git a/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch b/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch new file mode 100644 index 00000000..be378827 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch @@ -0,0 +1,10 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -19,6 +19,7 @@ + + chosen { + stdout-path = "serial2:115200n8"; ++ bootargs = "console=ttyS2,115200n8 root=/dev/mmcblk1p2 rootfstype=ext4 rootwait vmalloc=496M"; + }; + + cpus { diff --git a/root/target/linux/mediatek/patches-5.4/0100-dts-add-second-gmac.patch b/root/target/linux/mediatek/patches-5.4/0100-dts-add-second-gmac.patch new file mode 100644 index 00000000..d985a929 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0100-dts-add-second-gmac.patch @@ -0,0 +1,54 @@ +From 97fdec52fff8079d3af104e8723602a3cb9d2a11 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 20 Jun 2019 23:06:41 +0200 +Subject: [PATCH] net: dts: add second gmac for bananapi r2 + +--- + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index 2b760f90f38c..fad09608b86c 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -143,13 +143,25 @@ + }; + }; + ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; ++ label = "wan"; ++ phy-mode = "rgmii"; ++ phy-handle = <&ephy0>; ++ }; ++ + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + +- switch@0 { +- compatible = "mediatek,mt7530"; ++ ephy0: ethernet-phy@0 { + reg = <0>; ++ }; ++ ++ switch@1f { ++ compatible = "mediatek,mt7530"; ++ reg = <0x1f>; + reset-gpios = <&pio 33 0>; + core-supply = <&mt6323_vpa_reg>; + io-supply = <&mt6323_vemc3v3_reg>; +@@ -158,10 +170,12 @@ + #address-cells = <1>; + #size-cells = <0>; + ++/* Disabled, is now handled by gmac1 (eth1/wan) via phy-handle! + port@0 { + reg = <0>; + label = "wan"; + }; ++*/ + + port@1 { + reg = <1>; diff --git a/root/target/linux/mediatek/patches-5.4/0101-dsa-enable-vlan.patch b/root/target/linux/mediatek/patches-5.4/0101-dsa-enable-vlan.patch new file mode 100644 index 00000000..065fda3f --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0101-dsa-enable-vlan.patch @@ -0,0 +1,43 @@ +From 35082b70e998d5b419e351010005494e7a5b9412 Mon Sep 17 00:00:00 2001 +From: Landen Chao +Date: Tue, 31 Dec 2019 11:48:41 +0100 +Subject: [PATCH] net: dsa: enable vlan without bridge on dsa user port + +--- + drivers/net/dsa/mt7530.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c +index 1d8d36de4d20..7e285aa9bd7c 100644 +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -1165,8 +1165,13 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port, + /* The port is kept as VLAN-unaware if bridge with vlan_filtering not + * being set. + */ +- if (!dsa_port_is_vlan_filtering(&ds->ports[port])) ++ if (!dsa_port_is_vlan_filtering(&ds->ports[port])){ ++ /* Enable VLAN tagged in port-based vlan setting. */ ++ if ((vlan->vid_begin != 0) && (vlan->vid_end != 0)) ++ mt7530_rmw(priv, MT7530_PCR_P(port), EG_TAG(3), ++ EG_TAG(2)); + return; ++ } + + mutex_lock(&priv->reg_mutex); + +@@ -1196,8 +1201,13 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port, + /* The port is kept as VLAN-unaware if bridge with vlan_filtering not + * being set. + */ +- if (!dsa_port_is_vlan_filtering(&ds->ports[port])) ++ if (!dsa_port_is_vlan_filtering(&ds->ports[port])) { ++ /* Disable VLAN tagged in port-based vlan setting. */ ++ if ((vlan->vid_begin != 0) && (vlan->vid_end != 0)) ++ mt7530_rmw(priv, MT7530_PCR_P(port), EG_TAG(3), ++ EG_TAG(0)); + return 0; ++ } + + mutex_lock(&priv->reg_mutex); + diff --git a/root/target/linux/mediatek/patches-5.4/0102-dsa-mt7530-Extend-device-data.patch b/root/target/linux/mediatek/patches-5.4/0102-dsa-mt7530-Extend-device-data.patch new file mode 100644 index 00000000..1beee7a2 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0102-dsa-mt7530-Extend-device-data.patch @@ -0,0 +1,389 @@ +From 0277af939e559d5dd77955ad6eed55b9f582dd38 Mon Sep 17 00:00:00 2001 +From: Landen Chao +Date: Tue, 10 Dec 2019 16:14:38 +0800 +Subject: [PATCH] net: dsa: mt7530: Extend device data ready for adding a new + hardware + +Add a structure holding required operations for each device such as device +initialization, PHY port read or write, a checker whether PHY interface is +supported on a certain port, MAC port setup for either bus pad or a +specific PHY interface. + +The patch is done for ready adding a new hardware MT7531. + +Signed-off-by: Landen Chao +Signed-off-by: Sean Wang +--- + drivers/net/dsa/mt7530.c | 231 +++++++++++++++++++++++++++++---------- + drivers/net/dsa/mt7530.h | 29 ++++- + 2 files changed, 203 insertions(+), 57 deletions(-) + +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c +index 7e285aa9bd7c..a3f3ba95c55b 100644 +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -425,7 +425,7 @@ mt7530_fdb_write(struct mt7530_priv *pri + } + + static int +-mt7530_pad_clk_setup(struct dsa_switch *ds, int mode) ++mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t mode) + { + struct mt7530_priv *priv = ds->priv; + u32 ncpo1, ssc_delta, trgint, i, xtal; +@@ -1447,13 +1447,111 @@ mt7530_setup(struct dsa_switch *ds) + return 0; + } + +-static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port, ++static bool mt7530_phy_supported(struct dsa_switch *ds, int port, ++ const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ switch (port) { ++ case 0: /* Internal phy */ ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ if (state->interface != PHY_INTERFACE_MODE_GMII) ++ goto unsupported; ++ break; ++ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ ++ if (!phy_interface_mode_is_rgmii(state->interface) && ++ state->interface != PHY_INTERFACE_MODE_MII && ++ state->interface != PHY_INTERFACE_MODE_GMII) ++ goto unsupported; ++ break; ++ case 6: /* 1st cpu port */ ++ if (state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_TRGMII) ++ goto unsupported; ++ break; ++ default: ++ dev_err(priv->dev, "%s: unsupported port: %i\n", __func__, ++ port); ++ goto unsupported; ++ } ++ ++ return true; ++ ++unsupported: ++ return false; ++} ++ ++static bool mt753x_phy_supported(struct dsa_switch *ds, int port, ++ const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->phy_supported(ds, port, state); ++} ++ ++static int ++mt7530_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ /* Setup TX circuit incluing relevant PAD and driving */ ++ mt7530_pad_clk_setup(ds, state->interface); ++ ++ if (priv->id == ID_MT7530) { ++ /* Setup RX circuit, relevant PAD and driving on the ++ * host which must be placed after the setup on the ++ * device side is all finished. ++ */ ++ mt7623_pad_clk_setup(ds); ++ } ++ ++ return 0; ++} ++ ++static int ++mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->pad_setup(ds, state); ++} ++ ++static int ++mt7530_mac_setup(struct dsa_switch *ds, int port, unsigned int mode, ++ const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ /* Only need to setup port5. */ ++ if (port != 5) ++ return 0; ++ ++ mt7530_setup_port5(priv->ds, state->interface); ++ ++ return 0; ++} ++ ++static int mt753x_mac_setup(struct dsa_switch *ds, int port, unsigned int mode, ++ const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->mac_setup(ds, port, mode, state); ++} ++ ++static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port, + unsigned int mode, + const struct phylink_link_state *state) + { + struct mt7530_priv *priv = ds->priv; + u32 mcr_cur, mcr_new; + ++ if (!mt753x_phy_supported(ds, port, state)) ++ return; ++ + switch (port) { + case 0: /* Internal phy */ + case 1: +@@ -1466,35 +1564,24 @@ static void mt7530_phylink_mac_config(st + case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ + if (priv->p5_interface == state->interface) + break; +- if (!phy_interface_mode_is_rgmii(state->interface) && +- state->interface != PHY_INTERFACE_MODE_MII && +- state->interface != PHY_INTERFACE_MODE_GMII) +- return; + +- mt7530_setup_port5(ds, state->interface); ++ if (mt753x_mac_setup(ds, port, mode, state) < 0) ++ goto unsupported; ++ + break; + case 6: /* 1st cpu port */ + if (priv->p6_interface == state->interface) + break; + +- if (state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_TRGMII) +- return; +- +- /* Setup TX circuit incluing relevant PAD and driving */ +- mt7530_pad_clk_setup(ds, state->interface); ++ mt753x_pad_setup(ds, state); + +- if (priv->id == ID_MT7530) { +- /* Setup RX circuit, relevant PAD and driving on the +- * host which must be placed after the setup on the +- * device side is all finished. +- */ +- mt7623_pad_clk_setup(ds); +- } ++ if (mt753x_mac_setup(ds, port, mode, state) < 0) ++ goto unsupported; + + priv->p6_interface = state->interface; + break; + default: ++unsupported: + dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); + return; + } +@@ -1555,38 +1642,14 @@ static void mt7530_phylink_mac_link_up(s + mt7530_port_set_status(priv, port, 1); + } + +-static void mt7530_phylink_validate(struct dsa_switch *ds, int port, ++static void mt753x_phylink_validate(struct dsa_switch *ds, int port, + unsigned long *supported, + struct phylink_link_state *state) + { + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; + +- switch (port) { +- case 0: /* Internal phy */ +- case 1: +- case 2: +- case 3: +- case 4: +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_GMII) +- goto unsupported; +- break; +- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- !phy_interface_mode_is_rgmii(state->interface) && +- state->interface != PHY_INTERFACE_MODE_MII && +- state->interface != PHY_INTERFACE_MODE_GMII) +- goto unsupported; +- break; +- case 6: /* 1st cpu port */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_TRGMII) +- goto unsupported; +- break; +- default: +- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); +-unsupported: ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ !mt753x_phy_supported(ds, port, state)) { + linkmode_zero(supported); + return; + } +@@ -1657,12 +1720,36 @@ mt7530_phylink_mac_link_state(struct dsa + return 1; + } + ++static int ++mt753x_setup(struct dsa_switch *ds) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->setup(ds); ++} ++ ++static int ++mt753x_phy_read(struct dsa_switch *ds, int port, int regnum) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->phy_read(ds, port, regnum); ++} ++ ++static int ++mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->phy_write(ds, port, regnum, val); ++} ++ + static const struct dsa_switch_ops mt7530_switch_ops = { + .get_tag_protocol = mtk_get_tag_protocol, +- .setup = mt7530_setup, ++ .setup = mt753x_setup, + .get_strings = mt7530_get_strings, +- .phy_read = mt7530_phy_read, +- .phy_write = mt7530_phy_write, ++ .phy_read = mt753x_phy_read, ++ .phy_write = mt753x_phy_write, + .get_ethtool_stats = mt7530_get_ethtool_stats, + .get_sset_count = mt7530_get_sset_count, + .port_enable = mt7530_port_enable, +@@ -1679,16 +1766,37 @@ static const struct dsa_switch_ops mt753 + .port_vlan_del = mt7530_port_vlan_del, + .port_mirror_add = mt7530_port_mirror_add, + .port_mirror_del = mt7530_port_mirror_del, +- .phylink_validate = mt7530_phylink_validate, ++ .phylink_validate = mt753x_phylink_validate, + .phylink_mac_link_state = mt7530_phylink_mac_link_state, +- .phylink_mac_config = mt7530_phylink_mac_config, ++ .phylink_mac_config = mt753x_phylink_mac_config, + .phylink_mac_link_down = mt7530_phylink_mac_link_down, + .phylink_mac_link_up = mt7530_phylink_mac_link_up, + }; + ++static const struct mt753x_info mt753x_table[] = { ++ [ID_MT7621] = { ++ .id = ID_MT7621, ++ .setup = mt7530_setup, ++ .phy_read = mt7530_phy_read, ++ .phy_write = mt7530_phy_write, ++ .phy_supported = mt7530_phy_supported, ++ .pad_setup = mt7530_pad_setup, ++ .mac_setup = mt7530_mac_setup, ++ }, ++ [ID_MT7530] = { ++ .id = ID_MT7530, ++ .setup = mt7530_setup, ++ .phy_read = mt7530_phy_read, ++ .phy_write = mt7530_phy_write, ++ .phy_supported = mt7530_phy_supported, ++ .pad_setup = mt7530_pad_setup, ++ .mac_setup = mt7530_mac_setup, ++ }, ++}; ++ + static const struct of_device_id mt7530_of_match[] = { +- { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, }, +- { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, }, ++ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], }, ++ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, mt7530_of_match); +@@ -1726,8 +1834,19 @@ mt7530_probe(struct mdio_device *mdiodev + /* Get the hardware identifier from the devicetree node. + * We will need it for some of the clock and regulator setup. + */ +- priv->id = (unsigned int)(unsigned long) +- of_device_get_match_data(&mdiodev->dev); ++ priv->info = of_device_get_match_data(&mdiodev->dev); ++ if (!priv->info) ++ return -EINVAL; ++ ++ /* Sanity check if these required device operstaions are filled ++ * properly. ++ */ ++ if (!priv->info->setup || !priv->info->phy_read || ++ !priv->info->phy_write || !priv->info->phy_supported || ++ !priv->info->pad_setup || !priv->info->mac_setup) ++ return -EINVAL; ++ ++ priv->id = priv->info->id; + + if (priv->id == ID_MT7530) { + priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); +diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h +index ccb9da8cad0d..aac86e4fc148 100644 +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -11,7 +11,7 @@ + #define MT7530_NUM_FDB_RECORDS 2048 + #define MT7530_ALL_MEMBERS 0xff + +-enum { ++enum mt753x_id { + ID_MT7530 = 0, + ID_MT7621 = 1, + }; +@@ -428,6 +428,32 @@ static const char *p5_intf_modes(unsigned int p5_interface) + } + } + ++/* struct mt753x_info - This is the main data structure for holding the specific ++ * part for each supported device ++ * @setup: Holding the handler to a device initialization ++ * @phy_read: Holding the way reading PHY port ++ * @phy_write: Holding the way writing PHY port ++ * @phy_supported: Check if the PHY type is being supported on a certain ++ * port ++ * @pad_setup: Holding the way setting up the bus pad for a certain MAC ++ * port ++ * @mac_setup: Holding the way setting up the PHY attribute for a ++ * certain MAC port ++ */ ++struct mt753x_info { ++ enum mt753x_id id; ++ ++ int (*setup)(struct dsa_switch *ds); ++ int (*phy_read)(struct dsa_switch *ds, int port, int regnum); ++ int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val); ++ bool (*phy_supported)(struct dsa_switch *ds, int port, ++ const struct phylink_link_state *state); ++ int (*pad_setup)(struct dsa_switch *ds, ++ const struct phylink_link_state *state); ++ int (*mac_setup)(struct dsa_switch *ds, int port, unsigned int mode, ++ const struct phylink_link_state *state); ++}; ++ + /* struct mt7530_priv - This is the main data structure for holding the state + * of the driver + * @dev: The device pointer +@@ -455,6 +481,7 @@ struct mt7530_priv { + struct regulator *core_pwr; + struct regulator *io_pwr; + struct gpio_desc *reset; ++ const struct mt753x_info *info; + unsigned int id; + bool mcm; + phy_interface_t p6_interface; diff --git a/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch b/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch new file mode 100644 index 00000000..1c58130b --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch @@ -0,0 +1,39 @@ +From 934747eba782050ba87a29a3a59f805e36410685 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= +Date: Fri, 21 Jun 2019 10:04:05 +0200 +Subject: [PATCH] net: ethernet: mediatek: support net-labels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With this patch, device name can be set within dts file in the same way as dsa +port can. +Add: label = "wan"; to GMAC node. + +Signed-off-by: René van Dorst +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index c61069340f4f..87ced6269411 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2756,6 +2756,7 @@ static const struct net_device_ops mtk_netdev_ops = { + + static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + { ++ const char *name = of_get_property(np, "label", NULL); + const __be32 *_id = of_get_property(np, "reg", NULL); + struct phylink *phylink; + int phy_mode, id, err; +@@ -2846,6 +2847,9 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + eth->netdev[id]->irq = eth->irq[0]; + eth->netdev[id]->dev.of_node = np; + ++ if (name) ++ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ); ++ + return 0; + + free_netdev: diff --git a/root/target/linux/mediatek/patches-5.4/0104-dts-add-pause-to-port6.patch b/root/target/linux/mediatek/patches-5.4/0104-dts-add-pause-to-port6.patch new file mode 100644 index 00000000..a8bc7979 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0104-dts-add-pause-to-port6.patch @@ -0,0 +1,22 @@ +From 3a466fd3d5b921c085fd3c863cab3f1afdb90c9c Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 12 Jan 2020 16:46:33 +0100 +Subject: [PATCH] arm: dts: add pause to port6 of switch + +to be same as gmac0 +--- + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index 52343bd76fe5..7b8383af87e0 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -253,6 +253,7 @@ + fixed-link { + speed = <1000>; + full-duplex; ++ pause; + }; + }; + }; diff --git a/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch b/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch new file mode 100644 index 00000000..bbb478e7 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch @@ -0,0 +1,249 @@ +--- a/drivers/rtc/rtc-mt6397.c 2020-03-05 23:43:52.000000000 +0800 ++++ b/drivers/rtc/rtc-mt6397.c 2020-03-18 00:54:20.445907453 +0800 +@@ -4,48 +4,18 @@ + * Author: Tianping.Fang + */ + +-#include +-#include ++#include ++#include ++#include + #include ++#include ++#include + #include + #include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define RTC_BBPU 0x0000 +-#define RTC_BBPU_CBUSY BIT(6) +- +-#define RTC_WRTGR 0x003c ++#include ++#include + +-#define RTC_IRQ_STA 0x0002 +-#define RTC_IRQ_STA_AL BIT(0) +-#define RTC_IRQ_STA_LP BIT(3) +- +-#define RTC_IRQ_EN 0x0004 +-#define RTC_IRQ_EN_AL BIT(0) +-#define RTC_IRQ_EN_ONESHOT BIT(2) +-#define RTC_IRQ_EN_LP BIT(3) +-#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) +- +-#define RTC_AL_MASK 0x0008 +-#define RTC_AL_MASK_DOW BIT(4) +- +-#define RTC_TC_SEC 0x000a +-/* Min, Hour, Dom... register offset to RTC_TC_SEC */ +-#define RTC_OFFSET_SEC 0 +-#define RTC_OFFSET_MIN 1 +-#define RTC_OFFSET_HOUR 2 +-#define RTC_OFFSET_DOM 3 +-#define RTC_OFFSET_DOW 4 +-#define RTC_OFFSET_MTH 5 +-#define RTC_OFFSET_YEAR 6 +-#define RTC_OFFSET_COUNT 7 +- +-#define RTC_AL_SEC 0x0018 ++#include + + #define RTC_AL_SEC_MASK 0x003f + #define RTC_AL_MIN_MASK 0x003f +@@ -55,26 +25,8 @@ + #define RTC_AL_MTH_MASK 0x000f + #define RTC_AL_YEA_MASK 0x007f + +-#define RTC_PDN2 0x002e +-#define RTC_PDN2_PWRON_ALARM BIT(4) +- +-#define RTC_MIN_YEAR 1968 +-#define RTC_BASE_YEAR 1900 +-#define RTC_NUM_YEARS 128 +-#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) +- +-struct mt6397_rtc { +- struct device *dev; +- struct rtc_device *rtc_dev; +- struct mutex lock; +- struct regmap *regmap; +- int irq; +- u32 addr_base; +-}; +- + static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) + { +- unsigned long timeout = jiffies + HZ; + int ret; + u32 data; + +@@ -82,19 +34,13 @@ static int mtk_rtc_write_trigger(struct + if (ret < 0) + return ret; + +- while (1) { +- ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU, +- &data); +- if (ret < 0) +- break; +- if (!(data & RTC_BBPU_CBUSY)) +- break; +- if (time_after(jiffies, timeout)) { +- ret = -ETIMEDOUT; +- break; +- } +- cpu_relax(); +- } ++ ret = regmap_read_poll_timeout(rtc->regmap, ++ rtc->addr_base + RTC_BBPU, data, ++ !(data & RTC_BBPU_CBUSY), ++ MTK_RTC_POLL_DELAY_US, ++ MTK_RTC_POLL_TIMEOUT); ++ if (ret < 0) ++ dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret); + + return ret; + } +@@ -338,19 +284,19 @@ static int mtk_rtc_probe(struct platform + return rtc->irq; + + rtc->regmap = mt6397_chip->regmap; +- rtc->dev = &pdev->dev; + mutex_init(&rtc->lock); + + platform_set_drvdata(pdev, rtc); + +- rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev); ++ rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + +- ret = request_threaded_irq(rtc->irq, NULL, +- mtk_rtc_irq_handler_thread, +- IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- "mt6397-rtc", rtc); ++ ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, ++ mtk_rtc_irq_handler_thread, ++ IRQF_ONESHOT | IRQF_TRIGGER_HIGH, ++ "mt6397-rtc", rtc); ++ + if (ret) { + dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", + rtc->irq, ret); +@@ -372,15 +318,6 @@ out_free_irq: + return ret; + } + +-static int mtk_rtc_remove(struct platform_device *pdev) +-{ +- struct mt6397_rtc *rtc = platform_get_drvdata(pdev); +- +- free_irq(rtc->irq, rtc); +- +- return 0; +-} +- + #ifdef CONFIG_PM_SLEEP + static int mt6397_rtc_suspend(struct device *dev) + { +@@ -407,6 +344,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, + mt6397_rtc_resume); + + static const struct of_device_id mt6397_rtc_of_match[] = { ++ { .compatible = "mediatek,mt6323-rtc", }, + { .compatible = "mediatek,mt6397-rtc", }, + { } + }; +@@ -419,7 +357,6 @@ static struct platform_driver mtk_rtc_dr + .pm = &mt6397_pm_ops, + }, + .probe = mtk_rtc_probe, +- .remove = mtk_rtc_remove, + }; + + module_platform_driver(mtk_rtc_driver); +diff --git a/include/linux/mfd/mt6397/rtc.h b/include/linux/mfd/mt6397/rtc.h +new file mode 100644 +index 000000000000..f84b9163c0ee +--- /dev/null ++++ b/include/linux/mfd/mt6397/rtc.h +@@ -0,0 +1,71 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2014-2019 MediaTek Inc. ++ * ++ * Author: Tianping.Fang ++ * Sean Wang ++ */ ++ ++#ifndef _LINUX_MFD_MT6397_RTC_H_ ++#define _LINUX_MFD_MT6397_RTC_H_ ++ ++#include ++#include ++#include ++#include ++ ++#define RTC_BBPU 0x0000 ++#define RTC_BBPU_CBUSY BIT(6) ++#define RTC_BBPU_KEY (0x43 << 8) ++ ++#define RTC_WRTGR 0x003c ++ ++#define RTC_IRQ_STA 0x0002 ++#define RTC_IRQ_STA_AL BIT(0) ++#define RTC_IRQ_STA_LP BIT(3) ++ ++#define RTC_IRQ_EN 0x0004 ++#define RTC_IRQ_EN_AL BIT(0) ++#define RTC_IRQ_EN_ONESHOT BIT(2) ++#define RTC_IRQ_EN_LP BIT(3) ++#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) ++ ++#define RTC_AL_MASK 0x0008 ++#define RTC_AL_MASK_DOW BIT(4) ++ ++#define RTC_TC_SEC 0x000a ++/* Min, Hour, Dom... register offset to RTC_TC_SEC */ ++#define RTC_OFFSET_SEC 0 ++#define RTC_OFFSET_MIN 1 ++#define RTC_OFFSET_HOUR 2 ++#define RTC_OFFSET_DOM 3 ++#define RTC_OFFSET_DOW 4 ++#define RTC_OFFSET_MTH 5 ++#define RTC_OFFSET_YEAR 6 ++#define RTC_OFFSET_COUNT 7 ++ ++#define RTC_AL_SEC 0x0018 ++ ++#define RTC_PDN2 0x002e ++#define RTC_PDN2_PWRON_ALARM BIT(4) ++ ++#define RTC_MIN_YEAR 1968 ++#define RTC_BASE_YEAR 1900 ++#define RTC_NUM_YEARS 128 ++#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) ++ ++#define MTK_RTC_POLL_DELAY_US 10 ++#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ)) ++ ++struct mt6397_rtc { ++ struct device *dev; ++ struct rtc_device *rtc_dev; ++ ++ /* Protect register access from multiple tasks */ ++ struct mutex lock; ++ struct regmap *regmap; ++ int irq; ++ u32 addr_base; ++}; ++ ++#endif /* _LINUX_MFD_MT6397_RTC_H_ */ + diff --git a/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch b/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch new file mode 100644 index 00000000..b8552824 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch @@ -0,0 +1,160 @@ +From 559614ab0ae2c85596218226f095be36c12cf0fa Mon Sep 17 00:00:00 2001 +From: Josef Friedl +Date: Wed, 3 Jul 2019 12:24:52 +0200 +Subject: [PATCH] power: reset: add driver for mt6323 poweroff + +add poweroff driver for mt6323 and make Makefile and Kconfig-Entries + +Suggested-by: Frank Wunderlich +Signed-off-by: Josef Friedl +Signed-off-by: Frank Wunderlich +Acked-by: Sebastian Reichel +--- +changes since v6: none +changes since v5: split out mfd/mt6397/core.h +changes since v4: none +changes since v3: none +changes since v2: none (=v2 part 5) +--- + drivers/power/reset/Kconfig | 10 +++ + drivers/power/reset/Makefile | 1 + + drivers/power/reset/mt6323-poweroff.c | 97 +++++++++++++++++++++++++++ + 3 files changed, 108 insertions(+) + create mode 100644 drivers/power/reset/mt6323-poweroff.c + +diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig +index a564237278ff..c721939767eb 100644 +--- a/drivers/power/reset/Kconfig ++++ b/drivers/power/reset/Kconfig +@@ -140,6 +140,16 @@ config POWER_RESET_LTC2952 + This driver supports an external powerdown trigger and board power + down via the LTC2952. Bindings are made in the device tree. + ++config POWER_RESET_MT6323 ++ bool "MediaTek MT6323 power-off driver" ++ depends on MFD_MT6397 ++ help ++ The power-off driver is responsible for externally shutdown down ++ the power of a remote MediaTek SoC MT6323 is connected to through ++ controlling a tiny circuit BBPU inside MT6323 RTC. ++ ++ Say Y if you have a board where MT6323 could be found. ++ + config POWER_RESET_QNAP + bool "QNAP power-off driver" + depends on OF_GPIO && PLAT_ORION +diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile +index 85da3198e4e0..da37f8b851dc 100644 +--- a/drivers/power/reset/Makefile ++++ b/drivers/power/reset/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o + obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o + obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o + obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o ++obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o + obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o + obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o + obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o +diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c +new file mode 100644 +index 000000000000..1caf43d9e46d +--- /dev/null ++++ b/drivers/power/reset/mt6323-poweroff.c +@@ -0,0 +1,97 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Power off through MediaTek PMIC ++ * ++ * Copyright (C) 2018 MediaTek Inc. ++ * ++ * Author: Sean Wang ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct mt6323_pwrc { ++ struct device *dev; ++ struct regmap *regmap; ++ u32 base; ++}; ++ ++static struct mt6323_pwrc *mt_pwrc; ++ ++static void mt6323_do_pwroff(void) ++{ ++ struct mt6323_pwrc *pwrc = mt_pwrc; ++ unsigned int val; ++ int ret; ++ ++ regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY); ++ regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1); ++ ++ ret = regmap_read_poll_timeout(pwrc->regmap, ++ pwrc->base + RTC_BBPU, val, ++ !(val & RTC_BBPU_CBUSY), ++ MTK_RTC_POLL_DELAY_US, ++ MTK_RTC_POLL_TIMEOUT); ++ if (ret) ++ dev_err(pwrc->dev, "failed to write BBPU: %d\n", ret); ++ ++ /* Wait some time until system down, otherwise, notice with a warn */ ++ mdelay(1000); ++ ++ WARN_ONCE(1, "Unable to power off system\n"); ++} ++ ++static int mt6323_pwrc_probe(struct platform_device *pdev) ++{ ++ struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent); ++ struct mt6323_pwrc *pwrc; ++ struct resource *res; ++ ++ pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL); ++ if (!pwrc) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ pwrc->base = res->start; ++ pwrc->regmap = mt6397_chip->regmap; ++ pwrc->dev = &pdev->dev; ++ mt_pwrc = pwrc; ++ ++ pm_power_off = &mt6323_do_pwroff; ++ ++ return 0; ++} ++ ++static int mt6323_pwrc_remove(struct platform_device *pdev) ++{ ++ if (pm_power_off == &mt6323_do_pwroff) ++ pm_power_off = NULL; ++ ++ return 0; ++} ++ ++static const struct of_device_id mt6323_pwrc_dt_match[] = { ++ { .compatible = "mediatek,mt6323-pwrc" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match); ++ ++static struct platform_driver mt6323_pwrc_driver = { ++ .probe = mt6323_pwrc_probe, ++ .remove = mt6323_pwrc_remove, ++ .driver = { ++ .name = "mt6323-pwrc", ++ .of_match_table = mt6323_pwrc_dt_match, ++ }, ++}; ++ ++module_platform_driver(mt6323_pwrc_driver); ++ ++MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC"); ++MODULE_AUTHOR("Sean Wang "); ++MODULE_LICENSE("GPL v2"); diff --git a/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch b/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch new file mode 100644 index 00000000..41a4305c --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch @@ -0,0 +1,57 @@ +From c3db4c1163cc20ab0a456086a15c00acb022a67d Mon Sep 17 00:00:00 2001 +From: Josef Friedl +Date: Thu, 20 Dec 2018 18:27:17 +0100 +Subject: [PATCH] arm: dts: mt6323: add keys, power-controller, rtc and codec + +support poweroff and power-related keys on bpi-r2 + +Suggested-by: Frank Wunderlich +Signed-off-by: Josef Friedl +Signed-off-by: Frank Wunderlich +--- +changes since v6: none +changes since v5: none +changes since v4: none +changes since v3: none +changes since v2: none (=v2 part 7) +--- + arch/arm/boot/dts/mt6323.dtsi | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/arch/arm/boot/dts/mt6323.dtsi b/arch/arm/boot/dts/mt6323.dtsi +index ba397407c1dd..7fda40ab5fe8 100644 +--- a/arch/arm/boot/dts/mt6323.dtsi ++++ b/arch/arm/boot/dts/mt6323.dtsi +@@ -238,5 +238,32 @@ + regulator-enable-ramp-delay = <216>; + }; + }; ++ ++ mt6323keys: mt6323keys { ++ compatible = "mediatek,mt6323-keys"; ++ mediatek,long-press-mode = <1>; ++ power-off-time-sec = <0>; ++ ++ power { ++ linux,keycodes = <116>; ++ wakeup-source; ++ }; ++ ++ home { ++ linux,keycodes = <114>; ++ }; ++ }; ++ ++ codec: mt6397codec { ++ compatible = "mediatek,mt6397-codec"; ++ }; ++ ++ power-controller { ++ compatible = "mediatek,mt6323-pwrc"; ++ }; ++ ++ rtc { ++ compatible = "mediatek,mt6323-rtc"; ++ }; + }; + }; diff --git a/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch b/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch new file mode 100644 index 00000000..36c38786 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch @@ -0,0 +1,500 @@ +From ae7a8d61a108bb58af8c3ecb16d8e95aad0b1975 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Wed, 5 Sep 2018 22:09:27 +0800 +Subject: [PATCH] arm: dts: mt7623: add display subsystem related device nodes + +Add display subsystem related device nodes for MT7623. + +Cc: CK Hu +Signed-off-by: chunhui dai +Signed-off-by: Bibby Hsieh +Signed-off-by: Ryder Lee + +additional fixes: + +[hdmi,dts] fixed dts-warnings +author: Bibby Hsieh + +[dtsi] fix dpi0-node +author: Ryder Lee + +Signed-off-by: Frank Wunderlich +Tested-by: Frank Wunderlich +--- + arch/arm/boot/dts/mt7623.dtsi | 177 ++++++++++++++++++ + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 85 +++++++++ + arch/arm/boot/dts/mt7623n-rfb-emmc.dts | 85 +++++++++ + 3 files changed, 347 insertions(+) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 59e69f3dffa2..f1880ff04193 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -23,6 +23,11 @@ + #address-cells = <2>; + #size-cells = <2>; + ++ aliases { ++ rdma0 = &rdma0; ++ rdma1 = &rdma1; ++ }; ++ + cpu_opp_table: opp-table { + compatible = "operating-points-v2"; + opp-shared; +@@ -320,6 +325,25 @@ + clock-names = "spi", "wrap"; + }; + ++ mipi_tx0: mipi-dphy@10010000 { ++ compatible = "mediatek,mt7623-mipi-tx", ++ "mediatek,mt2701-mipi-tx"; ++ reg = <0 0x10010000 0 0x90>; ++ clocks = <&clk26m>; ++ clock-output-names = "mipi_tx0_pll"; ++ #clock-cells = <0>; ++ #phy-cells = <0>; ++ }; ++ ++ cec: cec@10012000 { ++ compatible = "mediatek,mt7623-cec", ++ "mediatek,mt8173-cec"; ++ reg = <0 0x10012000 0 0xbc>; ++ interrupts = ; ++ clocks = <&infracfg CLK_INFRA_CEC>; ++ status = "disabled"; ++ }; ++ + cir: cir@10013000 { + compatible = "mediatek,mt7623-cir"; + reg = <0 0x10013000 0 0x1000>; +@@ -368,6 +392,18 @@ + #clock-cells = <1>; + }; + ++ hdmi_phy: phy@10209100 { ++ compatible = "mediatek,mt7623-hdmi-phy", ++ "mediatek,mt2701-hdmi-phy"; ++ reg = <0 0x10209100 0 0x24>; ++ clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>; ++ clock-names = "pll_ref"; ++ clock-output-names = "hdmitx_dig_cts"; ++ #clock-cells = <0>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ + rng: rng@1020f000 { + compatible = "mediatek,mt7623-rng"; + reg = <0 0x1020f000 0 0x1000>; +@@ -567,6 +603,16 @@ + status = "disabled"; + }; + ++ hdmiddc0: i2c@11013000 { ++ compatible = "mediatek,mt7623-hdmi-ddc", ++ "mediatek,mt8173-hdmi-ddc"; ++ interrupts = ; ++ reg = <0 0x11013000 0 0x1C>; ++ clocks = <&pericfg CLK_PERI_I2C3>; ++ clock-names = "ddc-i2c"; ++ status = "disabled"; ++ }; ++ + nor_flash: spi@11014000 { + compatible = "mediatek,mt7623-nor", + "mediatek,mt8173-nor"; +@@ -741,6 +787,84 @@ + #clock-cells = <1>; + }; + ++ display_components: dispsys@14000000 { ++ compatible = "mediatek,mt7623-mmsys", ++ "mediatek,mt2701-mmsys"; ++ reg = <0 0x14000000 0 0x1000>; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; ++ }; ++ ++ ovl@14007000 { ++ compatible = "mediatek,mt7623-disp-ovl", ++ "mediatek,mt2701-disp-ovl"; ++ reg = <0 0x14007000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_OVL>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_OVL_0>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ rdma0: rdma@14008000 { ++ compatible = "mediatek,mt7623-disp-rdma", ++ "mediatek,mt2701-disp-rdma"; ++ reg = <0 0x14008000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_RDMA>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ wdma@14009000 { ++ compatible = "mediatek,mt7623-disp-wdma", ++ "mediatek,mt2701-disp-wdma"; ++ reg = <0 0x14009000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_WDMA>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_WDMA>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ bls: pwm@1400a000 { ++ compatible = "mediatek,mt7623-disp-pwm", ++ "mediatek,mt2701-disp-pwm"; ++ reg = <0 0x1400a000 0 0x1000>; ++ #pwm-cells = <2>; ++ clocks = <&mmsys CLK_MM_MDP_BLS_26M>, ++ <&mmsys CLK_MM_DISP_BLS>; ++ clock-names = "main", "mm"; ++ status = "disabled"; ++ }; ++ ++ color@1400b000 { ++ compatible = "mediatek,mt7623-disp-color", ++ "mediatek,mt2701-disp-color"; ++ reg = <0 0x1400b000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_COLOR>; ++ }; ++ ++ dsi: dsi@1400c000 { ++ compatible = "mediatek,mt7623-dsi", ++ "mediatek,mt2701-dsi"; ++ reg = <0 0x1400c000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DSI_ENGINE>, ++ <&mmsys CLK_MM_DSI_DIG>, ++ <&mipi_tx0>; ++ clock-names = "engine", "digital", "hs"; ++ phys = <&mipi_tx0>; ++ phy-names = "dphy"; ++ status = "disabled"; ++ }; ++ ++ mutex: mutex@1400e000 { ++ compatible = "mediatek,mt7623-disp-mutex", ++ "mediatek,mt2701-disp-mutex"; ++ reg = <0 0x1400e000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_MUTEX_32K>; ++ }; ++ + larb0: larb@14010000 { + compatible = "mediatek,mt7623-smi-larb", + "mediatek,mt2701-smi-larb"; +@@ -753,6 +877,44 @@ + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; + }; + ++ rdma1: rdma@14012000 { ++ compatible = "mediatek,mt7623-disp-rdma", ++ "mediatek,mt2701-disp-rdma"; ++ reg = <0 0x14012000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_RDMA1>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA1>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ dpi0: dpi@14014000 { ++ compatible = "mediatek,mt7623-dpi", ++ "mediatek,mt2701-dpi"; ++ reg = <0 0x14014000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DPI1_DIGL>, ++ <&mmsys CLK_MM_DPI1_ENGINE>, ++ <&apmixedsys CLK_APMIXED_TVDPLL>; ++ clock-names = "pixel", "engine", "pll"; ++ status = "disabled"; ++ }; ++ ++ hdmi0: hdmi@14015000 { ++ compatible = "mediatek,mt7623-hdmi", ++ "mediatek,mt8173-hdmi"; ++ reg = <0 0x14015000 0 0x400>; ++ clocks = <&mmsys CLK_MM_HDMI_PIXEL>, ++ <&mmsys CLK_MM_HDMI_PLL>, ++ <&mmsys CLK_MM_HDMI_AUDIO>, ++ <&mmsys CLK_MM_HDMI_SPDIF>; ++ clock-names = "pixel", "pll", "bclk", "spdif"; ++ phys = <&hdmi_phy>; ++ phy-names = "hdmi"; ++ mediatek,syscon-hdmi = <&mmsys 0x900>; ++ cec = <&cec>; ++ status = "disabled"; ++ }; ++ + imgsys: syscon@15000000 { + compatible = "mediatek,mt7623-imgsys", + "mediatek,mt2701-imgsys", +@@ -1077,6 +1239,21 @@ + }; + }; + ++ hdmi_pins_a: hdmi-default { ++ pins-hdmi { ++ pinmux = ; ++ input-enable; ++ bias-pull-down; ++ }; ++ }; ++ ++ hdmi_ddc_pins_a: hdmi_ddc-default { ++ pins-hdmi-ddc { ++ pinmux = , ++ ; ++ }; ++ }; ++ + i2c0_pins_a: i2c0-default { + pins-i2c0 { + pinmux = , +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index 2b760f90f38c..7a1763472018 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -21,6 +21,19 @@ + stdout-path = "serial2:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ label = "hdmi"; ++ type = "d"; ++ ddc-i2c-bus = <&hdmiddc0>; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi0_out>; ++ }; ++ }; ++ }; ++ + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; +@@ -114,10 +127,24 @@ + }; + }; + ++&bls { ++ status = "okay"; ++ ++ port { ++ bls_out: endpoint { ++ remote-endpoint = <&dpi0_in>; ++ }; ++ }; ++}; ++ + &btif { + status = "okay"; + }; + ++&cec { ++ status = "okay"; ++}; ++ + &cir { + pinctrl-names = "default"; + pinctrl-0 = <&cir_pins_a>; +@@ -128,6 +155,28 @@ + status = "okay"; + }; + ++&dpi0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ dpi0_out: endpoint { ++ remote-endpoint = <&hdmi0_in>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dpi0_in: endpoint { ++ remote-endpoint = <&bls_out>; ++ }; ++ }; ++ }; ++}; ++ + ð { + status = "okay"; + +@@ -199,6 +248,42 @@ + }; + }; + ++&hdmi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_pins_a>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ hdmi0_in: endpoint { ++ remote-endpoint = <&dpi0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ hdmi0_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++ }; ++ }; ++}; ++ ++&hdmiddc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_ddc_pins_a>; ++ status = "okay"; ++}; ++ ++&hdmi_phy { ++ mediatek,ibias = <0xa>; ++ mediatek,ibias_up = <0x1c>; ++ status = "okay"; ++}; ++ + &i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; +diff --git a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts +index b7606130ade9..3e5911d8d6bc 100644 +--- a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts ++++ b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts +@@ -24,6 +24,19 @@ + stdout-path = "serial2:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ label = "hdmi"; ++ type = "d"; ++ ddc-i2c-bus = <&hdmiddc0>; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi0_out>; ++ }; ++ }; ++ }; ++ + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; +@@ -106,10 +119,24 @@ + }; + }; + ++&bls { ++ status = "okay"; ++ ++ port { ++ bls_out: endpoint { ++ remote-endpoint = <&dpi0_in>; ++ }; ++ }; ++}; ++ + &btif { + status = "okay"; + }; + ++&cec { ++ status = "okay"; ++}; ++ + &cir { + pinctrl-names = "default"; + pinctrl-0 = <&cir_pins_a>; +@@ -120,6 +147,28 @@ + status = "okay"; + }; + ++&dpi0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ dpi0_out: endpoint { ++ remote-endpoint = <&hdmi0_in>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dpi0_in: endpoint { ++ remote-endpoint = <&bls_out>; ++ }; ++ }; ++ }; ++}; ++ + ð { + status = "okay"; + +@@ -202,6 +251,42 @@ + }; + }; + ++&hdmi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_pins_a>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ hdmi0_in: endpoint { ++ remote-endpoint = <&dpi0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ hdmi0_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++ }; ++ }; ++}; ++ ++&hdmiddc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_ddc_pins_a>; ++ status = "okay"; ++}; ++ ++&hdmi_phy { ++ mediatek,ibias = <0xa>; ++ mediatek,ibias_up = <0x1c>; ++ status = "okay"; ++}; ++ + &i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; diff --git a/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch b/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch new file mode 100644 index 00000000..c49690c5 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch @@ -0,0 +1,77 @@ +From 6468d187f12604f38f0a3acde430fdc5c5390771 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Tue, 23 Jul 2019 11:32:50 +0800 +Subject: [PATCH] arm: dts: mt7623: add Mali-450 device nodes + +Add nodes for Mali-450 and iommu larb3. + +Signed-off-by: Sean Wang +Signed-off-by: Ryder Lee +--- + arch/arm/boot/dts/mt7623.dtsi | 39 ++++++++++++++++++++++++++++++++++- + 1 file changed, 38 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 8d0807fd9460..f7905561b30e 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -3,6 +3,7 @@ + * Copyright (c) 2017-2018 MediaTek Inc. + * Author: John Crispin + * Sean Wang ++ * Ryder Lee + * + */ + +@@ -371,7 +372,7 @@ + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; +- mediatek,larbs = <&larb0 &larb1 &larb2>; ++ mediatek,larbs = <&larb0 &larb1 &larb2 &larb3>; + #iommu-cells = <1>; + }; + +@@ -794,6 +795,42 @@ + #reset-cells = <1>; + }; + ++ larb3: larb@13010000 { ++ compatible = "mediatek,mt7623-smi-larb", ++ "mediatek,mt2701-smi-larb"; ++ reg = <0 0x13010000 0 0x1000>; ++ mediatek,smi = <&smi_common>; ++ mediatek,larb-id = <3>; ++ clocks = <&clk26m>, <&clk26m>; ++ clock-names = "apb", "smi"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_MFG>; ++ }; ++ ++ mali: gpu@13040000 { ++ compatible = "mediatek,mt7623-mali", "arm,mali-450"; ++ reg = <0 0x13040000 0 0x30000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = "gp", "gpmmu", "pp0", "ppmmu0", "pp1", ++ "ppmmu1", "pp2", "ppmmu2", "pp3", "ppmmu3", ++ "pp"; ++ clocks = <&topckgen CLK_TOP_MMPLL>, ++ <&g3dsys CLK_G3DSYS_CORE>; ++ clock-names = "bus", "core"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_MFG>; ++ mediatek,larb = <&larb3>; ++ resets = <&g3dsys MT2701_G3DSYS_CORE_RST>; ++ }; ++ + mmsys: syscon@14000000 { + compatible = "mediatek,mt7623-mmsys", + "mediatek,mt2701-mmsys", diff --git a/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch b/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch new file mode 100644 index 00000000..fe4b742c --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch @@ -0,0 +1,68 @@ +From d87e1a23e51158f9c2923f6213a42d5e942a4091 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 23 Jan 2020 07:16:30 +0100 +Subject: [PATCH] lima: power on/off via register (function) + +--- + drivers/gpu/drm/lima/lima_device.c | 31 ++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index d86b8d81a483..7d5d45e176f2 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include "lima_device.h" + #include "lima_gp.h" +@@ -287,11 +288,33 @@ static void lima_fini_pp_pipe(struct lima_device *dev) + lima_sched_pipe_fini(pipe); + } + ++void mtk_set_power(bool on) ++{ ++ if (on) { ++ void __iomem *wakeup_register; ++ wakeup_register = ioremap(0x10003014 , 0x04); ++ writel(0x00000001,wakeup_register); // this may be wrong, may need bitbang 0th bit to 1 ++ iounmap(wakeup_register); ++ }else { ++ void __iomem *powerdown_register; ++ powerdown_register = ioremap(0x1000300C , 0x04); // powerdown register ++ writel(0x00000001,powerdown_register); // this may be wrong, may need bitbang 0th bit to 1 ++ iounmap(powerdown_register); ++ } ++} ++ + int lima_device_init(struct lima_device *ldev) + { + int err, i; + struct resource *res; + ++ #ifdef CONFIG_MTK_COMBO_CHIP_CONSYS_7623 ++ mtk_set_power(true); ++ pm_runtime_enable(ldev->dev); ++ pm_runtime_set_active(ldev->dev); ++ pm_runtime_get_sync(ldev->dev); ++ #endif ++ + dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); + + err = lima_clk_init(ldev); +@@ -385,4 +408,12 @@ void lima_device_fini(struct lima_device *ldev) + lima_regulator_fini(ldev); + + lima_clk_fini(ldev); ++ ++ #ifdef CONFIG_MTK_COMBO_CHIP_CONSYS_7623 ++ pm_runtime_set_suspended(ldev->dev); ++ pm_runtime_put_noidle(ldev->dev); ++ pm_runtime_disable(ldev->dev); ++ ++ mtk_set_power(false); ++ #endif + } diff --git a/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch b/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch new file mode 100644 index 00000000..ff149dce --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch @@ -0,0 +1,84 @@ +From 452b508468a46ef0fe7357fab6b000c52fd047d3 Mon Sep 17 00:00:00 2001 +From: Stu Hsieh +Date: Fri, 16 Nov 2018 16:33:00 +0100 +Subject: [PATCH] drm: Add get_possible_crtc API for dpi, dsi + +Test: build pass and run ok + +Signed-off-by: Stu Hsieh +--- + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 40 +++++++++++++++++++++ + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 ++ + 2 files changed, 42 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +index efa85973e46b..29796e78b26a 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +@@ -237,6 +237,22 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { + [DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL }, + }; + ++static bool mtk_drm_find_comp_in_ddp(struct mtk_ddp_comp ddp_comp, ++ const enum mtk_ddp_comp_id *path, ++ unsigned int path_len) ++{ ++ unsigned int i; ++ ++ if (path == NULL) ++ return false; ++ ++ for (i = 0U; i < path_len; i++) ++ if (ddp_comp.id == path[i]) ++ return true; ++ ++ return false; ++} ++ + int mtk_ddp_comp_get_id(struct device_node *node, + enum mtk_ddp_comp_type comp_type) + { +@@ -252,6 +268,30 @@ int mtk_ddp_comp_get_id(struct device_node *node, + return -EINVAL; + } + ++unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, ++ struct mtk_ddp_comp ddp_comp) ++{ ++ struct mtk_drm_private *private = drm->dev_private; ++ unsigned int ret; ++ ++ if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->main_path, ++ private->data->main_len) == true) { ++ ret = BIT(0); ++ } else if (mtk_drm_find_comp_in_ddp(ddp_comp, ++ private->data->ext_path, ++ private->data->ext_len) == true) { ++ ret = BIT(1); ++ } else if (mtk_drm_find_comp_in_ddp(ddp_comp, ++ private->data->third_path, ++ private->data->third_len) == true) { ++ ret = BIT(2); ++ } else { ++ DRM_INFO("Failed to find comp in ddp table\n"); ++ ret = 0; ++ } ++ return ret; ++} ++ + int mtk_ddp_comp_init(struct device *dev, struct device_node *node, + struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id, + const struct mtk_ddp_comp_funcs *funcs) +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +index 0ad287f427cc..97be111c3e52 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +@@ -160,6 +160,8 @@ static inline void mtk_ddp_gamma_set(struct mtk_ddp_comp *comp, + + int mtk_ddp_comp_get_id(struct device_node *node, + enum mtk_ddp_comp_type comp_type); ++unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, ++ struct mtk_ddp_comp ddp_comp); + int mtk_ddp_comp_init(struct device *dev, struct device_node *comp_node, + struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id, + const struct mtk_ddp_comp_funcs *funcs); diff --git a/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch b/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch new file mode 100644 index 00000000..c92e18cc --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch @@ -0,0 +1,45 @@ +From f4ca44932ccf088f225062aafef04d2bd629b2c4 Mon Sep 17 00:00:00 2001 +From: Jitao Shi +Date: Fri, 3 May 2019 17:16:19 +0200 +Subject: [PATCH] drm/mediatek: dpi/dsi: change the getting possible_crtc way + +[Detail] +dpi/dsi get the possible_crtc by +mtk_drm_find_possible_crtc_by_comp(*drm_dev, ddp_comp) + +Test: build pass and boot to logo + +Signed-off-by: Jitao Shi +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 3 ++- + drivers/gpu/drm/mediatek/mtk_dsi.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index be6d95c5ff25..00d31b5aa09f 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -604,7 +604,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) + drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs); + + /* Currently DPI0 is fixed to be driven by OVL1 */ +- dpi->encoder.possible_crtcs = BIT(1); ++ dpi->encoder.possible_crtcs = ++ mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->ddp_comp); + + ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL); + if (ret) { +diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c +index 224afb666881..2c2d3643f3e8 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dsi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c +@@ -817,7 +817,8 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi) + * Currently display data paths are statically assigned to a crtc each. + * crtc 0 is OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 + */ +- dsi->encoder.possible_crtcs = 1; ++ dsi->encoder.possible_crtcs = ++ mtk_drm_find_possible_crtc_by_comp(drm, dsi->ddp_comp); + + /* If there's a bridge, attach to it and let it create the connector */ + if (dsi->bridge) { diff --git a/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch b/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch new file mode 100644 index 00000000..98bba9dc --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch @@ -0,0 +1,21 @@ +From 34dd2a86c9e3b3ad1a3a00add409edda2b2ed776 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 1 Oct 2019 11:21:03 +0200 +Subject: [PATCH] drm: fix implicit declaration of function 'DRM_INFO' + +--- + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +index 29796e78b26a..e65d83267563 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #include "mtk_drm_drv.h" + #include "mtk_drm_plane.h" diff --git a/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch b/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch new file mode 100644 index 00000000..adc35c7d --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch @@ -0,0 +1,146 @@ +From 6e3f7375acdcf714d1fcbae1238cd39cc9391560 Mon Sep 17 00:00:00 2001 +From: Bibby Hsieh +Date: Fri, 21 Sep 2018 11:28:22 +0800 +Subject: [PATCH] drm/mediatek: config component output by device node port + +We can select output component by decive node port. +Main path default output component is DSI. +External path default output component is DPI. + +Signed-off-by: Bibby Hsieh + +added small fixes for warnings + +Signed-off-by: Frank Wunderlich +Tested-by: Frank Wunderlich +--- + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 46 ++++++++++++++++++++++---- + drivers/gpu/drm/mediatek/mtk_drm_drv.h | 4 +-- + 2 files changed, 42 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +index 352b81a7a670..33511c77b800 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +@@ -21,6 +21,13 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + #include "mtk_drm_crtc.h" + #include "mtk_drm_ddp.h" +@@ -121,7 +128,7 @@ static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = { + .atomic_commit = mtk_atomic_commit, + }; + +-static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_RDMA0, + DDP_COMPONENT_COLOR0, +@@ -129,12 +136,12 @@ static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { + DDP_COMPONENT_DSI0, + }; + +-static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { + DDP_COMPONENT_RDMA1, + DDP_COMPONENT_DPI0, + }; + +-static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_COLOR0, + DDP_COMPONENT_AAL0, +@@ -144,7 +151,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { + DDP_COMPONENT_PWM0, + }; + +-static const enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { + DDP_COMPONENT_OVL1, + DDP_COMPONENT_COLOR1, + DDP_COMPONENT_AAL1, +@@ -160,7 +167,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = { + DDP_COMPONENT_PWM2, + }; + +-static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_COLOR0, + DDP_COMPONENT_AAL0, +@@ -171,7 +178,7 @@ static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { + DDP_COMPONENT_PWM0, + }; + +-static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { + DDP_COMPONENT_OVL1, + DDP_COMPONENT_COLOR1, + DDP_COMPONENT_GAMMA, +@@ -510,6 +517,7 @@ static int mtk_drm_probe(struct platform_device *pdev) + + /* Iterate over sibling DISP function blocks */ + for_each_child_of_node(dev->of_node->parent, node) { ++ struct device_node *port, *ep, *remote; + const struct of_device_id *of_id; + enum mtk_ddp_comp_type comp_type; + int comp_id; +@@ -572,6 +580,32 @@ static int mtk_drm_probe(struct platform_device *pdev) + + private->ddp_comp[comp_id] = comp; + } ++ ++ if (comp_type != MTK_DSI && comp_type != MTK_DPI) { ++ port = of_graph_get_port_by_id(node, 0); ++ if (!port) ++ continue; ++ ep = of_get_child_by_name(port, "endpoint"); ++ of_node_put(port); ++ if (!ep) ++ continue; ++ remote = of_graph_get_remote_port_parent(ep); ++ of_node_put(ep); ++ if (!remote) ++ continue; ++ of_id = of_match_node(mtk_ddp_comp_dt_ids, remote); ++ if (!of_id) ++ continue; ++ comp_type = (enum mtk_ddp_comp_type)of_id->data; ++ for (i = 0; i < private->data->main_len - 1; i++) ++ if (private->data->main_path[i] == comp_id) ++ private->data->main_path[i + 1] = ++ mtk_ddp_comp_get_id(node, comp_type); ++ for (i = 0; i < private->data->ext_len - 1; i++) ++ if (private->data->ext_path[i] == comp_id) ++ private->data->ext_path[i + 1] = ++ mtk_ddp_comp_get_id(node, comp_type); ++ } + } + + if (!private->mutex_node) { +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h +index e03fea12ff59..5fb723415ff6 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h +@@ -21,9 +21,9 @@ struct drm_property; + struct regmap; + + struct mtk_mmsys_driver_data { +- const enum mtk_ddp_comp_id *main_path; ++ enum mtk_ddp_comp_id *main_path; + unsigned int main_len; +- const enum mtk_ddp_comp_id *ext_path; ++ enum mtk_ddp_comp_id *ext_path; + unsigned int ext_len; + const enum mtk_ddp_comp_id *third_path; + unsigned int third_len; diff --git a/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch b/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch new file mode 100644 index 00000000..247853f3 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch @@ -0,0 +1,55 @@ +From ba9c6527b05d294bdda7910db224e327f1460166 Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 31 Oct 2018 16:59:34 +0800 +Subject: [PATCH] drm/mediatek: fix boot up for 720 and 480 but 1080 + +- 1080 plg in/out with ng/ok +- support other resolutions like 1280x1024 + +Signed-off-by: chunhui dai +Signed-off-by: Frank Wunderlich +Tested-by: Frank Wunderlich +--- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 3 +++ + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 1 + + drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 1 + + 3 files changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +index 5223498502c4..edadb7a700f1 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -184,6 +184,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) + return PTR_ERR(phy_provider); + } + ++ if (hdmi_phy->conf->pll_default_off) ++ hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy); ++ + return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, + hdmi_phy->pll); + } +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +index 2d8b3182470d..f472fdeb63dc 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -22,6 +22,7 @@ struct mtk_hdmi_phy; + struct mtk_hdmi_phy_conf { + bool tz_disabled; + unsigned long flags; ++ bool pll_default_off; + const struct clk_ops *hdmi_phy_clk_ops; + void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); + void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +index d3cc4022e988..6fbedacfc1e8 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -239,6 +239,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) + struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { + .tz_disabled = true, + .flags = CLK_SET_RATE_GATE, ++ .pll_default_off = true, + .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, + .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, + .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, diff --git a/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch b/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch new file mode 100644 index 00000000..cc897705 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch @@ -0,0 +1,56 @@ +From aa97a44297179ab6ba1aa8f59e781541a320066b Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 31 Jan 2020 17:28:04 +0100 +Subject: [PATCH] thermal: mediatek: add sensors-support + +--- + drivers/thermal/mtk_thermal.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c +index d1b066383c45..8cf3a69bfa46 100644 +--- a/drivers/thermal/mtk_thermal.c ++++ b/drivers/thermal/mtk_thermal.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include "thermal_hwmon.h" ++ + /* AUXADC Registers */ + #define AUXADC_CON1_SET_V 0x008 + #define AUXADC_CON1_CLR_V 0x00c +@@ -990,6 +992,13 @@ static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt, + writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1); + } + ++static void mtk_thermal_hwmon_action(void *data) ++{ ++ struct thermal_zone_device *zone = data; ++ ++ thermal_remove_hwmon_sysfs(zone); ++} ++ + static int mtk_thermal_probe(struct platform_device *pdev) + { + int ret, i, ctrl_id; +@@ -1094,6 +1103,19 @@ static int mtk_thermal_probe(struct platform_device *pdev) + goto err_disable_clk_peri_therm; + } + ++ tzdev->tzp->no_hwmon = false; ++ ret = thermal_add_hwmon_sysfs(tzdev); ++ if (ret) ++ dev_err(&pdev->dev,"error in thermal_add_hwmon_sysfs"); ++ //goto err_disable_clk_peri_therm; ++ ++ ret = devm_add_action(&pdev->dev, mtk_thermal_hwmon_action, tzdev); ++ if (ret) { ++ dev_err(&pdev->dev,"error in devm_add_action"); ++ mtk_thermal_hwmon_action(tzdev); ++ //goto err_disable_clk_peri_therm; ++ } ++ + return 0; + + err_disable_clk_peri_therm: diff --git a/root/target/linux/mediatek/patches-5.4/0191-thermal.patch b/root/target/linux/mediatek/patches-5.4/0191-thermal.patch new file mode 100644 index 00000000..01ead975 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0191-thermal.patch @@ -0,0 +1,35 @@ +From 9847677bda4920bbba15499f28009ce095f02c99 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 31 Jan 2020 18:49:56 +0100 +Subject: [PATCH] thermal: mediatek: execute hwmon-code only if hwmon_thermal + is set + +--- + drivers/thermal/mtk_thermal.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c +index 8cf3a69bfa46..3a646b88f587 100644 +--- a/drivers/thermal/mtk_thermal.c ++++ b/drivers/thermal/mtk_thermal.c +@@ -1103,18 +1103,18 @@ static int mtk_thermal_probe(struct platform_device *pdev) + goto err_disable_clk_peri_therm; + } + ++#ifdef CONFIG_THERMAL_HWMON + tzdev->tzp->no_hwmon = false; + ret = thermal_add_hwmon_sysfs(tzdev); + if (ret) + dev_err(&pdev->dev,"error in thermal_add_hwmon_sysfs"); +- //goto err_disable_clk_peri_therm; + + ret = devm_add_action(&pdev->dev, mtk_thermal_hwmon_action, tzdev); + if (ret) { + dev_err(&pdev->dev,"error in devm_add_action"); + mtk_thermal_hwmon_action(tzdev); +- //goto err_disable_clk_peri_therm; + } ++#endif + + return 0; + diff --git a/root/target/linux/mediatek/patches-5.4/0230-pthread.patch b/root/target/linux/mediatek/patches-5.4/0230-pthread.patch new file mode 100644 index 00000000..ab5523cf --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0230-pthread.patch @@ -0,0 +1,14 @@ +--- a/scripts/Makefile 2020-03-21 22:28:13.290800484 +0800 ++++ b/scripts/Makefile 2020-03-21 22:28:26.230870790 +0800 +@@ -23,8 +23,8 @@ hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFIC + + HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include + HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include +-HOSTLDLIBS_sign-file = -lcrypto +-HOSTLDLIBS_extract-cert = -lcrypto ++HOSTLDLIBS_sign-file = -lcrypto -lpthread ++HOSTLDLIBS_extract-cert = -lcrypto -lpthread + + always := $(hostprogs-y) $(hostprogs-m) + + diff --git a/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch b/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch new file mode 100644 index 00000000..d780caba --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch @@ -0,0 +1,49 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2020-04-19 11:02:56.505715879 +0200 ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2020-04-19 11:03:53.620780390 +0200 +@@ -196,7 +196,7 @@ + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; +- label = "wan"; ++ label = "lan"; + phy-mode = "rgmii"; + phy-handle = <&ephy0>; + local-mac-address = [00 0a 35 00 00 02]; +@@ -221,31 +221,31 @@ + #address-cells = <1>; + #size-cells = <0>; + +-/* Disabled, is now handled by gmac1 (eth1/wan) via phy-handle! ++/* Disabled, is now handled by gmac1 (eth1/lan) via phy-handle! + port@0 { + reg = <0>; +- label = "wan"; ++ label = "lan"; + }; + */ + + port@1 { + reg = <1>; +- label = "lan0"; ++ label = "wan1"; + }; + + port@2 { + reg = <2>; +- label = "lan1"; ++ label = "wan2"; + }; + + port@3 { + reg = <3>; +- label = "lan2"; ++ label = "wan3"; + }; + + port@4 { + reg = <4>; +- label = "lan3"; ++ label = "wan4"; + }; + + port@6 { From aac4ff3c5bfec232ed0d0ae4159de7b9823d656f Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 20 Apr 2020 16:45:17 +0200 Subject: [PATCH 37/76] Update OpenWrt --- build.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build.sh b/build.sh index 09c7618f..444a5944 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "75ef28be59c5b76d73313cfb9650f464ae943cc8" - _get_repo feeds/packages https://github.com/openwrt/packages "c11aaead910d5351d0f3fd4e4460ad98336fa0d4" - _get_repo feeds/luci https://github.com/openwrt/luci "01d8283ecea730191ce41302acb7ecd1aaf0631f" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "29a458b0cae3435bce41136ee3b4132b4103ffae" + _get_repo feeds/packages https://github.com/openwrt/packages "e40f92c90dbed675d2f1555f65e3d25d9a9aad5a" + _get_repo feeds/luci https://github.com/openwrt/luci "79814b2f5286b6956d555b796407e2394169669d" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -193,12 +193,12 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/smsc75xx.patch; then fi echo "Done" -echo "Checking if ipt-nat patch is set or not" -if ! patch -Rf -N -p1 -s --dry-run < ../../patches/ipt-nat6.patch; then - echo "apply..." - patch -N -p1 -s < ../../patches/ipt-nat6.patch -fi -echo "Done" +#echo "Checking if ipt-nat patch is set or not" +#if ! patch -Rf -N -p1 -s --dry-run < ../../patches/ipt-nat6.patch; then +# echo "apply..." +# patch -N -p1 -s < ../../patches/ipt-nat6.patch +#fi +#echo "Done" #echo "Checking if mvebu patch is set or not" #if [ ! -d target/linux/mvebu/patches-5.4 ]; then From 45cbdb3d124df9101e7cfc0e290006ee94617720 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 23 Apr 2020 14:56:24 +0200 Subject: [PATCH 38/76] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 444a5944..e8da0f0d 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "29a458b0cae3435bce41136ee3b4132b4103ffae" - _get_repo feeds/packages https://github.com/openwrt/packages "e40f92c90dbed675d2f1555f65e3d25d9a9aad5a" - _get_repo feeds/luci https://github.com/openwrt/luci "79814b2f5286b6956d555b796407e2394169669d" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "df27e949fbbf13e1e2ab4db49f608165ef0ba9fe" + _get_repo feeds/packages https://github.com/openwrt/packages "a4bb706918c58c7f8718e5de1de2e719eecabbd2" + _get_repo feeds/luci https://github.com/openwrt/luci "d0518a11e124e124bfaa02551bc2d028fad2d69d" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From 18661b4aa7aaf0adda0183feeab168d89b849427 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 23 Apr 2020 18:58:27 +0200 Subject: [PATCH 39/76] Fix config --- config | 2 +- config-bpi-r2 | 2 +- config-rpi2 | 2 +- config-rpi4 | 2 +- config-wrt32x | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config b/config index 25f43785..59064a66 100644 --- a/config +++ b/config @@ -234,4 +234,4 @@ CONFIG_LUCI_LANG_it=y CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=64 CONFIG_OPENSSL_WITH_CHACHA_POLY1305=y -# CONFIG_LUCI_CSSTIDY is not set \ No newline at end of file +# CONFIG_LUCI_CSSTIDY is not set diff --git a/config-bpi-r2 b/config-bpi-r2 index 8b2fd154..08dac613 100644 --- a/config-bpi-r2 +++ b/config-bpi-r2 @@ -16,4 +16,4 @@ CONFIG_PACKAGE_mkf2fs=y # CONFIG_PACKAGE_kmod-fs-nfs-v4 is not set # CONFIG_PACKAGE_kmod-rtl8812au-ct is not set # CONFIG_PACKAGE_kmod-mt6625l-bt is not set -# CONFIG_PACKAGE_kmod-mt6625l-wlan-gen-2 is not set \ No newline at end of file +# CONFIG_PACKAGE_kmod-mt6625l-wlan-gen-2 is not set diff --git a/config-rpi2 b/config-rpi2 index 38730cc3..de4667ba 100644 --- a/config-rpi2 +++ b/config-rpi2 @@ -3,4 +3,4 @@ CONFIG_TARGET_bcm27xx_bcm2709=y CONFIG_TARGET_bcm27xx_bcm2709_DEVICE_rpi-2=y CONFIG_PACKAGE_kmod-ath10k-ct=n CONFIG_PACKAGE_kmod-ath9k=y -CONFIG_PACKAGE_bcm27xx-eeprom=y \ No newline at end of file +CONFIG_PACKAGE_bcm27xx-eeprom=y diff --git a/config-rpi4 b/config-rpi4 index b1a97db7..c5c07f5c 100644 --- a/config-rpi4 +++ b/config-rpi4 @@ -3,4 +3,4 @@ CONFIG_TARGET_bcm27xx_bcm2711=y CONFIG_TARGET_bcm27xx_bcm2711_DEVICE_rpi-4=y CONFIG_PACKAGE_kmod-ath10k-ct=n CONFIG_PACKAGE_kmod-ath9k=y -CONFIG_PACKAGE_bcm27xx-eeprom=y \ No newline at end of file +CONFIG_PACKAGE_bcm27xx-eeprom=y diff --git a/config-wrt32x b/config-wrt32x index 384ac04c..eba5cbec 100644 --- a/config-wrt32x +++ b/config-wrt32x @@ -4,4 +4,4 @@ CONFIG_TARGET_mvebu_cortexa9_DEVICE_linksys_wrt32x=y CONFIG_PACKAGE_kmod-6lowpan=y CONFIG_PACKAGE_luci-app-advanced-reboot=y # CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set -CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y \ No newline at end of file +CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y From 453824ec3a36e3ada7fc387a1062dd8ec3a0f262 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 24 Apr 2020 11:09:25 +0200 Subject: [PATCH 40/76] Remove not needed patch --- .../0102-dsa-mt7530-Extend-device-data.patch | 389 ------------------ 1 file changed, 389 deletions(-) delete mode 100644 root/target/linux/mediatek/patches-5.4/0102-dsa-mt7530-Extend-device-data.patch diff --git a/root/target/linux/mediatek/patches-5.4/0102-dsa-mt7530-Extend-device-data.patch b/root/target/linux/mediatek/patches-5.4/0102-dsa-mt7530-Extend-device-data.patch deleted file mode 100644 index 1beee7a2..00000000 --- a/root/target/linux/mediatek/patches-5.4/0102-dsa-mt7530-Extend-device-data.patch +++ /dev/null @@ -1,389 +0,0 @@ -From 0277af939e559d5dd77955ad6eed55b9f582dd38 Mon Sep 17 00:00:00 2001 -From: Landen Chao -Date: Tue, 10 Dec 2019 16:14:38 +0800 -Subject: [PATCH] net: dsa: mt7530: Extend device data ready for adding a new - hardware - -Add a structure holding required operations for each device such as device -initialization, PHY port read or write, a checker whether PHY interface is -supported on a certain port, MAC port setup for either bus pad or a -specific PHY interface. - -The patch is done for ready adding a new hardware MT7531. - -Signed-off-by: Landen Chao -Signed-off-by: Sean Wang ---- - drivers/net/dsa/mt7530.c | 231 +++++++++++++++++++++++++++++---------- - drivers/net/dsa/mt7530.h | 29 ++++- - 2 files changed, 203 insertions(+), 57 deletions(-) - -diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c -index 7e285aa9bd7c..a3f3ba95c55b 100644 ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -425,7 +425,7 @@ mt7530_fdb_write(struct mt7530_priv *pri - } - - static int --mt7530_pad_clk_setup(struct dsa_switch *ds, int mode) -+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t mode) - { - struct mt7530_priv *priv = ds->priv; - u32 ncpo1, ssc_delta, trgint, i, xtal; -@@ -1447,13 +1447,111 @@ mt7530_setup(struct dsa_switch *ds) - return 0; - } - --static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port, -+static bool mt7530_phy_supported(struct dsa_switch *ds, int port, -+ const struct phylink_link_state *state) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ switch (port) { -+ case 0: /* Internal phy */ -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ if (state->interface != PHY_INTERFACE_MODE_GMII) -+ goto unsupported; -+ break; -+ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -+ if (!phy_interface_mode_is_rgmii(state->interface) && -+ state->interface != PHY_INTERFACE_MODE_MII && -+ state->interface != PHY_INTERFACE_MODE_GMII) -+ goto unsupported; -+ break; -+ case 6: /* 1st cpu port */ -+ if (state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_TRGMII) -+ goto unsupported; -+ break; -+ default: -+ dev_err(priv->dev, "%s: unsupported port: %i\n", __func__, -+ port); -+ goto unsupported; -+ } -+ -+ return true; -+ -+unsupported: -+ return false; -+} -+ -+static bool mt753x_phy_supported(struct dsa_switch *ds, int port, -+ const struct phylink_link_state *state) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ return priv->info->phy_supported(ds, port, state); -+} -+ -+static int -+mt7530_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ /* Setup TX circuit incluing relevant PAD and driving */ -+ mt7530_pad_clk_setup(ds, state->interface); -+ -+ if (priv->id == ID_MT7530) { -+ /* Setup RX circuit, relevant PAD and driving on the -+ * host which must be placed after the setup on the -+ * device side is all finished. -+ */ -+ mt7623_pad_clk_setup(ds); -+ } -+ -+ return 0; -+} -+ -+static int -+mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ return priv->info->pad_setup(ds, state); -+} -+ -+static int -+mt7530_mac_setup(struct dsa_switch *ds, int port, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ /* Only need to setup port5. */ -+ if (port != 5) -+ return 0; -+ -+ mt7530_setup_port5(priv->ds, state->interface); -+ -+ return 0; -+} -+ -+static int mt753x_mac_setup(struct dsa_switch *ds, int port, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ return priv->info->mac_setup(ds, port, mode, state); -+} -+ -+static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port, - unsigned int mode, - const struct phylink_link_state *state) - { - struct mt7530_priv *priv = ds->priv; - u32 mcr_cur, mcr_new; - -+ if (!mt753x_phy_supported(ds, port, state)) -+ return; -+ - switch (port) { - case 0: /* Internal phy */ - case 1: -@@ -1466,35 +1564,24 @@ static void mt7530_phylink_mac_config(st - case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ - if (priv->p5_interface == state->interface) - break; -- if (!phy_interface_mode_is_rgmii(state->interface) && -- state->interface != PHY_INTERFACE_MODE_MII && -- state->interface != PHY_INTERFACE_MODE_GMII) -- return; - -- mt7530_setup_port5(ds, state->interface); -+ if (mt753x_mac_setup(ds, port, mode, state) < 0) -+ goto unsupported; -+ - break; - case 6: /* 1st cpu port */ - if (priv->p6_interface == state->interface) - break; - -- if (state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_TRGMII) -- return; -- -- /* Setup TX circuit incluing relevant PAD and driving */ -- mt7530_pad_clk_setup(ds, state->interface); -+ mt753x_pad_setup(ds, state); - -- if (priv->id == ID_MT7530) { -- /* Setup RX circuit, relevant PAD and driving on the -- * host which must be placed after the setup on the -- * device side is all finished. -- */ -- mt7623_pad_clk_setup(ds); -- } -+ if (mt753x_mac_setup(ds, port, mode, state) < 0) -+ goto unsupported; - - priv->p6_interface = state->interface; - break; - default: -+unsupported: - dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); - return; - } -@@ -1555,38 +1642,14 @@ static void mt7530_phylink_mac_link_up(s - mt7530_port_set_status(priv, port, 1); - } - --static void mt7530_phylink_validate(struct dsa_switch *ds, int port, -+static void mt753x_phylink_validate(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state) - { - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - -- switch (port) { -- case 0: /* Internal phy */ -- case 1: -- case 2: -- case 3: -- case 4: -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_GMII) -- goto unsupported; -- break; -- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -- if (state->interface != PHY_INTERFACE_MODE_NA && -- !phy_interface_mode_is_rgmii(state->interface) && -- state->interface != PHY_INTERFACE_MODE_MII && -- state->interface != PHY_INTERFACE_MODE_GMII) -- goto unsupported; -- break; -- case 6: /* 1st cpu port */ -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_TRGMII) -- goto unsupported; -- break; -- default: -- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); --unsupported: -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ !mt753x_phy_supported(ds, port, state)) { - linkmode_zero(supported); - return; - } -@@ -1657,12 +1720,36 @@ mt7530_phylink_mac_link_state(struct dsa - return 1; - } - -+static int -+mt753x_setup(struct dsa_switch *ds) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ return priv->info->setup(ds); -+} -+ -+static int -+mt753x_phy_read(struct dsa_switch *ds, int port, int regnum) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ return priv->info->phy_read(ds, port, regnum); -+} -+ -+static int -+mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ return priv->info->phy_write(ds, port, regnum, val); -+} -+ - static const struct dsa_switch_ops mt7530_switch_ops = { - .get_tag_protocol = mtk_get_tag_protocol, -- .setup = mt7530_setup, -+ .setup = mt753x_setup, - .get_strings = mt7530_get_strings, -- .phy_read = mt7530_phy_read, -- .phy_write = mt7530_phy_write, -+ .phy_read = mt753x_phy_read, -+ .phy_write = mt753x_phy_write, - .get_ethtool_stats = mt7530_get_ethtool_stats, - .get_sset_count = mt7530_get_sset_count, - .port_enable = mt7530_port_enable, -@@ -1679,16 +1766,37 @@ static const struct dsa_switch_ops mt753 - .port_vlan_del = mt7530_port_vlan_del, - .port_mirror_add = mt7530_port_mirror_add, - .port_mirror_del = mt7530_port_mirror_del, -- .phylink_validate = mt7530_phylink_validate, -+ .phylink_validate = mt753x_phylink_validate, - .phylink_mac_link_state = mt7530_phylink_mac_link_state, -- .phylink_mac_config = mt7530_phylink_mac_config, -+ .phylink_mac_config = mt753x_phylink_mac_config, - .phylink_mac_link_down = mt7530_phylink_mac_link_down, - .phylink_mac_link_up = mt7530_phylink_mac_link_up, - }; - -+static const struct mt753x_info mt753x_table[] = { -+ [ID_MT7621] = { -+ .id = ID_MT7621, -+ .setup = mt7530_setup, -+ .phy_read = mt7530_phy_read, -+ .phy_write = mt7530_phy_write, -+ .phy_supported = mt7530_phy_supported, -+ .pad_setup = mt7530_pad_setup, -+ .mac_setup = mt7530_mac_setup, -+ }, -+ [ID_MT7530] = { -+ .id = ID_MT7530, -+ .setup = mt7530_setup, -+ .phy_read = mt7530_phy_read, -+ .phy_write = mt7530_phy_write, -+ .phy_supported = mt7530_phy_supported, -+ .pad_setup = mt7530_pad_setup, -+ .mac_setup = mt7530_mac_setup, -+ }, -+}; -+ - static const struct of_device_id mt7530_of_match[] = { -- { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, }, -- { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, }, -+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], }, -+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], }, - { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, mt7530_of_match); -@@ -1726,8 +1834,19 @@ mt7530_probe(struct mdio_device *mdiodev - /* Get the hardware identifier from the devicetree node. - * We will need it for some of the clock and regulator setup. - */ -- priv->id = (unsigned int)(unsigned long) -- of_device_get_match_data(&mdiodev->dev); -+ priv->info = of_device_get_match_data(&mdiodev->dev); -+ if (!priv->info) -+ return -EINVAL; -+ -+ /* Sanity check if these required device operstaions are filled -+ * properly. -+ */ -+ if (!priv->info->setup || !priv->info->phy_read || -+ !priv->info->phy_write || !priv->info->phy_supported || -+ !priv->info->pad_setup || !priv->info->mac_setup) -+ return -EINVAL; -+ -+ priv->id = priv->info->id; - - if (priv->id == ID_MT7530) { - priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h -index ccb9da8cad0d..aac86e4fc148 100644 ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -11,7 +11,7 @@ - #define MT7530_NUM_FDB_RECORDS 2048 - #define MT7530_ALL_MEMBERS 0xff - --enum { -+enum mt753x_id { - ID_MT7530 = 0, - ID_MT7621 = 1, - }; -@@ -428,6 +428,32 @@ static const char *p5_intf_modes(unsigned int p5_interface) - } - } - -+/* struct mt753x_info - This is the main data structure for holding the specific -+ * part for each supported device -+ * @setup: Holding the handler to a device initialization -+ * @phy_read: Holding the way reading PHY port -+ * @phy_write: Holding the way writing PHY port -+ * @phy_supported: Check if the PHY type is being supported on a certain -+ * port -+ * @pad_setup: Holding the way setting up the bus pad for a certain MAC -+ * port -+ * @mac_setup: Holding the way setting up the PHY attribute for a -+ * certain MAC port -+ */ -+struct mt753x_info { -+ enum mt753x_id id; -+ -+ int (*setup)(struct dsa_switch *ds); -+ int (*phy_read)(struct dsa_switch *ds, int port, int regnum); -+ int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val); -+ bool (*phy_supported)(struct dsa_switch *ds, int port, -+ const struct phylink_link_state *state); -+ int (*pad_setup)(struct dsa_switch *ds, -+ const struct phylink_link_state *state); -+ int (*mac_setup)(struct dsa_switch *ds, int port, unsigned int mode, -+ const struct phylink_link_state *state); -+}; -+ - /* struct mt7530_priv - This is the main data structure for holding the state - * of the driver - * @dev: The device pointer -@@ -455,6 +481,7 @@ struct mt7530_priv { - struct regulator *core_pwr; - struct regulator *io_pwr; - struct gpio_desc *reset; -+ const struct mt753x_info *info; - unsigned int id; - bool mcm; - phy_interface_t p6_interface; From 9e3569f70dc5492376b77fd1cfeb06ab78e72db9 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 24 Apr 2020 20:26:01 +0200 Subject: [PATCH 41/76] Update u-boot --- root/package/boot/uboot-envtools/Makefile | 6 +++--- root/package/boot/uboot-mediatek/Makefile | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/root/package/boot/uboot-envtools/Makefile b/root/package/boot/uboot-envtools/Makefile index ffd1d7f6..5ea32d88 100644 --- a/root/package/boot/uboot-envtools/Makefile +++ b/root/package/boot/uboot-envtools/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uboot-envtools PKG_DISTNAME:=u-boot -PKG_VERSION:=2020.04-rc5 +PKG_VERSION:=2020.04 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git @@ -17,8 +17,8 @@ PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_SUBDIR:=$(PKG_DISTNAME)-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_DISTNAME)-$(PKG_VERSION) PKG_SOURCE_URL:=https://git.denx.de/u-boot.git -PKG_SOURCE_VERSION:=0965d2ac93db3900ae20ff0b2e176baf672b63cc -PKG_MIRROR_HASH:=1c967c90d3ab4fcc5817fbca4db8928311a8b3dfa9f827e9c585a590fd94ca7a +PKG_SOURCE_VERSION:=36fec02b1f90b92cf51ec531564f9284eae27ab4 +PKG_MIRROR_HASH:=fe732aaf037d9cc3c0909bad8362af366ae964bbdac6913a34081ff4ad565372 PKG_BUILD_DEPENDS:=fstools diff --git a/root/package/boot/uboot-mediatek/Makefile b/root/package/boot/uboot-mediatek/Makefile index d255a794..150abe59 100644 --- a/root/package/boot/uboot-mediatek/Makefile +++ b/root/package/boot/uboot-mediatek/Makefile @@ -9,9 +9,9 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk -PKG_VERSION:=2020.04-rc5 +PKG_VERSION:=2020.04 -PKG_HASH:=1c967c90d3ab4fcc5817fbca4db8928311a8b3dfa9f827e9c585a590fd94ca7a +PKG_HASH:=fe732aaf037d9cc3c0909bad8362af366ae964bbdac6913a34081ff4ad565372 PKG_MAINTAINER:=Cristian Ciobanu From 02bb895673a0e880ddccd42503c195aaafd8ee86 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 24 Apr 2020 21:56:50 +0200 Subject: [PATCH 42/76] Remove HNAT patch --- build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.sh b/build.sh index e8da0f0d..882aacbf 100755 --- a/build.sh +++ b/build.sh @@ -220,6 +220,9 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/download-ipv4.patch; then fi echo "Done" +if [ -f target/linux/mediatek/patches-5.4/0999-hnat.patch ]; then + rm -f target/linux/mediatek/patches-5.4/0999-hnat.patch +fi #echo "Patch protobuf wrong hash" #patch -N -R -p1 -s < ../../patches/protobuf_hash.patch From c45d3625a7815d1aff9e327bbbf741712acba744 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sun, 26 Apr 2020 12:59:30 +0200 Subject: [PATCH 43/76] Update default 5.4 config --- root/target/linux/generic/config-5.4 | 124 +++++++++++++++++---------- 1 file changed, 80 insertions(+), 44 deletions(-) diff --git a/root/target/linux/generic/config-5.4 b/root/target/linux/generic/config-5.4 index 91d8268c..90d9a44e 100644 --- a/root/target/linux/generic/config-5.4 +++ b/root/target/linux/generic/config-5.4 @@ -81,24 +81,17 @@ CONFIG_64BIT_TIME=y # CONFIG_AD9832 is not set # CONFIG_AD9834 is not set # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_ADE7753 is not set -# CONFIG_ADE7754 is not set -# CONFIG_ADE7758 is not set -# CONFIG_ADE7759 is not set # CONFIG_ADE7854 is not set # CONFIG_ADF4350 is not set # CONFIG_ADF4371 is not set # CONFIG_ADFS_FS is not set # CONFIG_ADIN_PHY is not set -# CONFIG_ADIS16060 is not set # CONFIG_ADIS16080 is not set # CONFIG_ADIS16130 is not set # CONFIG_ADIS16136 is not set # CONFIG_ADIS16201 is not set # CONFIG_ADIS16203 is not set -# CONFIG_ADIS16204 is not set # CONFIG_ADIS16209 is not set -# CONFIG_ADIS16220 is not set # CONFIG_ADIS16240 is not set # CONFIG_ADIS16260 is not set # CONFIG_ADIS16400 is not set @@ -118,6 +111,7 @@ CONFIG_AEABI=y # CONFIG_AFE4403 is not set # CONFIG_AFE4404 is not set # CONFIG_AFFS_FS is not set +# CONFIG_AFS_DEBUG_CURSOR is not set # CONFIG_AFS_FS is not set # CONFIG_AF_KCM is not set # CONFIG_AF_RXRPC is not set @@ -161,7 +155,6 @@ CONFIG_ANON_INODES=y # CONFIG_APDS9960 is not set # CONFIG_APM8018X is not set # CONFIG_APM_EMULATION is not set -# CONFIG_ENERGY_MODEL is not set # CONFIG_APPLE_GMUX is not set # CONFIG_APPLE_PROPERTIES is not set # CONFIG_APPLICOM is not set @@ -172,10 +165,12 @@ CONFIG_ANON_INODES=y # CONFIG_AR8216_PHY is not set # CONFIG_AR8216_PHY_LEDS is not set # CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_AGILEX is not set # CONFIG_ARCH_ALPINE is not set # CONFIG_ARCH_ARTPEC is not set # CONFIG_ARCH_ASPEED is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_AXXIA is not set # CONFIG_ARCH_BCM is not set # CONFIG_ARCH_BCM2835 is not set # CONFIG_ARCH_BCM_21664 is not set @@ -188,6 +183,7 @@ CONFIG_ANON_INODES=y # CONFIG_ARCH_BCM_IPROC is not set # CONFIG_ARCH_BCM_NSP is not set # CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BITMAIN is not set # CONFIG_ARCH_BRCMSTB is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CNS3XXX is not set @@ -248,7 +244,6 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARCH_OMAP4 is not set # CONFIG_ARCH_ORION5X is not set # CONFIG_ARCH_OXNAS is not set -# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set # CONFIG_ARCH_PICOXCELL is not set # CONFIG_ARCH_PRIMA2 is not set # CONFIG_ARCH_PXA is not set @@ -265,7 +260,6 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_SEATTLE is not set # CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_SHMOBILE_MULTI is not set # CONFIG_ARCH_SIRF is not set # CONFIG_ARCH_SOCFPGA is not set # CONFIG_ARCH_SPRD is not set @@ -288,7 +282,6 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARCH_VULCAN is not set # CONFIG_ARCH_W90X900 is not set # CONFIG_ARCH_WANTS_THP_SWAP is not set -# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set # CONFIG_ARCH_WM8505 is not set # CONFIG_ARCH_WM8750 is not set # CONFIG_ARCH_WM8850 is not set @@ -299,6 +292,9 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARCNET is not set # CONFIG_ARC_EMAC is not set # CONFIG_ARC_IRQ_NO_AUTOSAVE is not set +# CONFIG_ARM64_16K_PAGES is not set +# CONFIG_ARM64_64K_PAGES is not set +# CONFIG_ARM64_CRYPTO is not set # CONFIG_ARM64_ERRATUM_1024718 is not set # CONFIG_ARM64_ERRATUM_1463225 is not set # CONFIG_ARM64_ERRATUM_819472 is not set @@ -310,11 +306,23 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARM64_ERRATUM_843419 is not set # CONFIG_ARM64_ERRATUM_845719 is not set # CONFIG_ARM64_ERRATUM_858921 is not set +# CONFIG_ARM64_HW_AFDBM is not set +# CONFIG_ARM64_LSE_ATOMICS is not set +# CONFIG_ARM64_MODULE_PLTS is not set +# CONFIG_ARM64_PAN is not set +# CONFIG_ARM64_PMEM is not set +# CONFIG_ARM64_PSEUDO_NMI is not set +# CONFIG_ARM64_PTDUMP_DEBUGFS is not set +# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set # CONFIG_ARM64_RAS_EXTN is not set # CONFIG_ARM64_RELOC_TEST is not set CONFIG_ARM64_SW_TTBR0_PAN=y +# CONFIG_ARM64_UAO is not set +# CONFIG_ARM64_VA_BITS_48 is not set +# CONFIG_ARM64_VHE is not set # CONFIG_ARM_APPENDED_DTB is not set # CONFIG_ARM_ARCH_TIMER is not set +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set # CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set # CONFIG_ARM_CCI is not set # CONFIG_ARM_CCI400_PMU is not set @@ -344,29 +352,30 @@ CONFIG_ARM_DMA_MEM_BUFFERABLE=y # CONFIG_ARM_ERRATA_773022 is not set # CONFIG_ARM_ERRATA_775420 is not set # CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_814220 is not set # CONFIG_ARM_ERRATA_818325_852422 is not set # CONFIG_ARM_ERRATA_821420 is not set # CONFIG_ARM_ERRATA_825619 is not set -# CONFIG_ARM_ERRATA_857271 is not set # CONFIG_ARM_ERRATA_852421 is not set # CONFIG_ARM_ERRATA_852423 is not set +# CONFIG_ARM_ERRATA_857271 is not set # CONFIG_ARM_ERRATA_857272 is not set -# CONFIG_ARM_ERRATA_814220 is not set CONFIG_ARM_GIC_MAX_NR=1 -# CONFIG_ARM_KERNMEM_PERMS is not set # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set # CONFIG_ARM_KPROBES_TEST is not set +# CONFIG_ARM_LPAE is not set # CONFIG_ARM_MHU is not set # CONFIG_ARM_MODULE_PLTS is not set # CONFIG_ARM_PATCH_PHYS_VIRT is not set # CONFIG_ARM_PSCI is not set # CONFIG_ARM_PSCI_CHECKER is not set -# CONFIG_ARM_PTDUMP is not set # CONFIG_ARM_PTDUMP_DEBUGFS is not set # CONFIG_ARM_SBSA_WATCHDOG is not set # CONFIG_ARM_SCPI_PROTOCOL is not set # CONFIG_ARM_SDE_INTERFACE is not set +# CONFIG_ARM_SP805_WATCHDOG is not set # CONFIG_ARM_SPE_PMU is not set +# CONFIG_ARM_THUMBEE is not set # CONFIG_ARM_TIMER_SP804 is not set # CONFIG_ARM_UNWIND is not set # CONFIG_ARM_VIRT_EXT is not set @@ -528,8 +537,6 @@ CONFIG_BITREVERSE=y # CONFIG_BLK_CGROUP_IOCOST is not set # CONFIG_BLK_CGROUP_IOLATENCY is not set # CONFIG_BLK_CMDLINE_PARSER is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEBUG_FS is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_3W_XXXX_RAID is not set @@ -556,7 +563,6 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_DTC2278 is not set # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_HD is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_HT6560B is not set # CONFIG_BLK_DEV_IDEACPI is not set @@ -625,9 +631,6 @@ CONFIG_BLOCK=y # CONFIG_BMI160_I2C is not set # CONFIG_BMI160_SPI is not set # CONFIG_BMIPS_GENERIC is not set -# CONFIG_BMP085 is not set -# CONFIG_BMP085_I2C is not set -# CONFIG_BMP085_SPI is not set # CONFIG_BMP280 is not set # CONFIG_BNA is not set # CONFIG_BNX2 is not set @@ -700,7 +703,6 @@ CONFIG_BT_BNEP_PROTO_FILTER=y # CONFIG_BT_HCIBPA10X is not set # CONFIG_BT_HCIBT3C is not set # CONFIG_BT_HCIBTSDIO is not set -# CONFIG_BT_HCIBTUART is not set # CONFIG_BT_HCIBTUSB is not set # CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set # CONFIG_BT_HCIBTUSB_MTK is not set @@ -790,6 +792,7 @@ CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CGROUPS is not set # CONFIG_CGROUP_BPF is not set # CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_HUGETLB is not set # CONFIG_CGROUP_NET_CLASSID is not set # CONFIG_CGROUP_NET_PRIO is not set # CONFIG_CGROUP_RDMA is not set @@ -903,6 +906,8 @@ CONFIG_CONSTRUCTORS=y # CONFIG_CORTINA_PHY is not set # CONFIG_COUNTER is not set # CONFIG_CPA_DEBUG is not set +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_FREQ is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set @@ -912,8 +917,12 @@ CONFIG_CONSTRUCTORS=y # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set # CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set # CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set # CONFIG_CPU_IDLE is not set # CONFIG_CPU_IDLE_GOV_MENU is not set +# CONFIG_CPU_IDLE_GOV_TEO is not set # CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set # CONFIG_CPU_ISOLATION is not set # CONFIG_CPU_NO_EFFICIENT_FFS is not set @@ -999,6 +1008,7 @@ CONFIG_CRYPTO_BLKCIPHER2=y # CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set # CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_CRYPTO_DEV_HISI_SEC is not set +# CONFIG_CRYPTO_DEV_HISI_ZIP is not set # CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set # CONFIG_CRYPTO_DEV_MARVELL_CESA is not set # CONFIG_CRYPTO_DEV_MV_CESA is not set @@ -1186,6 +1196,7 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_TIMEKEEPING is not set # CONFIG_DEBUG_UART_8250_PALMCHIP is not set # CONFIG_DEBUG_UART_BCM63XX is not set +# CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_VIRTUAL is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set @@ -1326,6 +1337,7 @@ CONFIG_DQL=y # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set # CONFIG_DRM_LVDS_ENCODER is not set # CONFIG_DRM_MALI_DISPLAY is not set +# CONFIG_DRM_MCDE is not set # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set # CONFIG_DRM_MGAG200 is not set # CONFIG_DRM_MXSFB is not set @@ -1341,6 +1353,8 @@ CONFIG_DQL=y # CONFIG_DRM_PANEL_LG_LG4573 is not set # CONFIG_DRM_PANEL_LVDS is not set # CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set +# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set # CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set # CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set # CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set @@ -1348,16 +1362,18 @@ CONFIG_DQL=y # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set # CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set # CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set # CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set # CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set +# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set # CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set +# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set +# CONFIG_DRM_PANEL_TPO_TPG110 is not set # CONFIG_DRM_PANFROST is not set -# CONFIG_DRM_TOSHIBA_TC358764 is not set -# CONFIG_DRM_TI_SN65DSI86 is not set # CONFIG_DRM_PARADE_PS8622 is not set # CONFIG_DRM_PL111 is not set # CONFIG_DRM_QXL is not set @@ -1374,7 +1390,9 @@ CONFIG_DQL=y # CONFIG_DRM_THINE_THC63LVD1024 is not set # CONFIG_DRM_TILCDC is not set # CONFIG_DRM_TINYDRM is not set +# CONFIG_DRM_TI_SN65DSI86 is not set # CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_TOSHIBA_TC358764 is not set # CONFIG_DRM_TOSHIBA_TC358767 is not set # CONFIG_DRM_UDL is not set # CONFIG_DRM_VBOXVIDEO is not set @@ -1398,6 +1416,7 @@ CONFIG_DUMMY_CONSOLE_ROWS=25 # CONFIG_DVB_TUNER_DIB0070 is not set # CONFIG_DVB_TUNER_DIB0090 is not set # CONFIG_DWC_XLGMAC is not set +# CONFIG_DWMAC_DWC_QOS_ETH is not set # CONFIG_DWMAC_IPQ806X is not set # CONFIG_DWMAC_LPC18XX is not set # CONFIG_DWMAC_MESON is not set @@ -1446,6 +1465,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ENCRYPTED_KEYS is not set # CONFIG_ENCX24J600 is not set +# CONFIG_ENERGY_MODEL is not set # CONFIG_ENIC is not set # CONFIG_ENVELOPE_DETECTOR is not set # CONFIG_EPAPR_PARAVIRT is not set @@ -1489,10 +1509,12 @@ CONFIG_EXTRA_TARGETS="" # CONFIG_EXYNOS_VIDEO is not set # CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set # CONFIG_EZX_PCAP is not set +# CONFIG_F2FS_CHECK_FS is not set # CONFIG_F2FS_FAULT_INJECTION is not set # CONFIG_F2FS_FS is not set # CONFIG_F2FS_FS_ENCRYPTION is not set # CONFIG_F2FS_FS_POSIX_ACL is not set +# CONFIG_F2FS_FS_SECURITY is not set # CONFIG_F2FS_IO_TRACE is not set # CONFIG_FAILOVER is not set # CONFIG_FAIR_GROUP_SCHED is not set @@ -1631,13 +1653,13 @@ CONFIG_FILE_LOCKING=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_FIRMWARE_MEMMAP is not set -# CONFIG_TRUSTED_FOUNDATIONS is not set # CONFIG_FIXED_PHY is not set CONFIG_FLATMEM=y CONFIG_FLATMEM_MANUAL=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_FM10K is not set # CONFIG_FMC is not set +# CONFIG_FONTS is not set # CONFIG_FONT_TER16x32 is not set # CONFIG_FORCEDETH is not set CONFIG_FORCE_MAX_ZONEORDER=11 @@ -1652,10 +1674,10 @@ CONFIG_FRAME_WARN=1024 # CONFIG_FSCACHE is not set # CONFIG_FSI is not set # CONFIG_FSL_EDMA is not set -# CONFIG_FSL_QDMA is not set # CONFIG_FSL_ERRATUM_A008585 is not set # CONFIG_FSL_MC_BUS is not set # CONFIG_FSL_PQ_MDIO is not set +# CONFIG_FSL_QDMA is not set # CONFIG_FSL_XGMAC_MDIO is not set CONFIG_FSNOTIFY=y # CONFIG_FS_DAX is not set @@ -1686,6 +1708,8 @@ CONFIG_FW_LOADER=y CONFIG_FW_LOADER_USER_HELPER=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y # CONFIG_FXAS21002C is not set +# CONFIG_FXOS8700_I2C is not set +# CONFIG_FXOS8700_SPI is not set CONFIG_GACT_PROB=y # CONFIG_GADGET_UAC1 is not set # CONFIG_GAMEPORT is not set @@ -1969,6 +1993,7 @@ CONFIG_HPET_MMAP_DEFAULT=y # CONFIG_HTC_PASIC3 is not set # CONFIG_HTS221 is not set # CONFIG_HTU21 is not set +# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_HVC_DCC is not set # CONFIG_HVC_UDBG is not set @@ -1998,8 +2023,8 @@ CONFIG_HW_RANDOM_TPM=y # CONFIG_HYPERV is not set # CONFIG_HYPERV_TSCPAGE is not set # CONFIG_HYSDN is not set -CONFIG_HZ=100 -CONFIG_HZ_100=y +# CONFIG_HZ is not set +# CONFIG_HZ_100 is not set # CONFIG_HZ_1000 is not set # CONFIG_HZ_1024 is not set # CONFIG_HZ_128 is not set @@ -2127,6 +2152,7 @@ CONFIG_HZ_100=y # CONFIG_IGBVF is not set # CONFIG_IGC is not set # CONFIG_IIO is not set +# CONFIG_IIO_BUFFER is not set # CONFIG_IIO_BUFFER_CB is not set # CONFIG_IIO_BUFFER_HW_CONSUMER is not set # CONFIG_IIO_CONFIGFS is not set @@ -2146,6 +2172,7 @@ CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # CONFIG_IIO_SW_DEVICE is not set # CONFIG_IIO_SW_TRIGGER is not set # CONFIG_IIO_SYSFS_TRIGGER is not set +# CONFIG_IIO_TRIGGER is not set # CONFIG_IKCONFIG is not set # CONFIG_IKCONFIG_PROC is not set # CONFIG_IKHEADERS is not set @@ -2819,6 +2846,7 @@ CONFIG_MAY_USE_DEVLINK=y CONFIG_MEMBARRIER=y # CONFIG_MEMORY is not set # CONFIG_MEMORY_FAILURE is not set +# CONFIG_MEMORY_HOTPLUG is not set # CONFIG_MEMSTICK is not set # CONFIG_MEMTEST is not set # CONFIG_MEN_A21_WDT is not set @@ -2828,6 +2856,7 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MFD_88PM805 is not set # CONFIG_MFD_88PM860X is not set # CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_AC100 is not set # CONFIG_MFD_ACT8945A is not set # CONFIG_MFD_ARIZONA_I2C is not set # CONFIG_MFD_ARIZONA_SPI is not set @@ -2888,8 +2917,6 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MFD_RN5T618 is not set # CONFIG_MFD_ROHM_BD70528 is not set # CONFIG_MFD_ROHM_BD718XX is not set -# CONFIG_MFD_ROHM_BD70528 is not set -# CONFIG_MFD_STPMIC1 is not set # CONFIG_MFD_RT5033 is not set # CONFIG_MFD_RTSX_PCI is not set # CONFIG_MFD_RTSX_USB is not set @@ -2926,7 +2953,6 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MFD_TQMX86 is not set # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_VX855 is not set -# CONFIG_MFD_LOCHNAGAR is not set # CONFIG_MFD_WL1273_CORE is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM831X_I2C is not set @@ -2989,7 +3015,6 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_MMC is not set # CONFIG_MMC35240 is not set # CONFIG_MMC_ARMMMCI is not set -# CONFIG_MMC_STM32_SDMMC is not set # CONFIG_MMC_AU1X is not set # CONFIG_MMC_BLOCK is not set CONFIG_MMC_BLOCK_BOUNCE=y @@ -3024,6 +3049,7 @@ CONFIG_MMC_BLOCK_MINORS=8 # CONFIG_MMC_SDHCI_XENON is not set # CONFIG_MMC_SDRICOH_CS is not set # CONFIG_MMC_SPI is not set +# CONFIG_MMC_STM32_SDMMC is not set # CONFIG_MMC_TEST is not set # CONFIG_MMC_TOSHIBA_PCI is not set # CONFIG_MMC_USDHI6ROL0 is not set @@ -3096,6 +3122,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_GEN_PROBE=y # CONFIG_MTD_GPIO_ADDR is not set # CONFIG_MTD_HYPERBUS is not set +# CONFIG_MTD_IMPA7 is not set # CONFIG_MTD_INTEL_VR_NOR is not set # CONFIG_MTD_JEDECPROBE is not set # CONFIG_MTD_LATCH_ADDR is not set @@ -3187,7 +3214,6 @@ CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_PMC551 is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_RAW_NAND is not set -# CONFIG_MTD_NAND_ECC_SW_BCH is not set CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_REDBOOT_PARTS_READONLY is not set @@ -3512,7 +3538,6 @@ CONFIG_NET_VENDOR_FARADAY=y CONFIG_NET_VENDOR_FREESCALE=y CONFIG_NET_VENDOR_FUJITSU=y CONFIG_NET_VENDOR_GOOGLE=y -# CONFIG_GVE is not set CONFIG_NET_VENDOR_HISILICON=y CONFIG_NET_VENDOR_HP=y CONFIG_NET_VENDOR_HUAWEI=y @@ -3738,10 +3763,12 @@ CONFIG_NMI_LOG_BUF_SHIFT=13 # CONFIG_NTFS_RW is not set # CONFIG_NTP_PPS is not set # CONFIG_NULL_TTY is not set +# CONFIG_NUMA is not set # CONFIG_NVM is not set # CONFIG_NVMEM is not set # CONFIG_NVMEM_BCM_OCOTP is not set # CONFIG_NVMEM_IMX_OCOTP is not set +# CONFIG_NVMEM_REBOOT_MODE is not set # CONFIG_NVMEM_SYSFS is not set # CONFIG_NVME_FC is not set # CONFIG_NVME_TARGET is not set @@ -3983,6 +4010,10 @@ CONFIG_PINCTRL_SINGLE=y # CONFIG_PINCTRL_SX150X is not set CONFIG_PINMUX=y # CONFIG_PKCS7_MESSAGE_PARSER is not set +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_PL310_ERRATA_769419 is not set # CONFIG_PL320_MBOX is not set # CONFIG_PL330_DMA is not set # CONFIG_PLATFORM_MHU is not set @@ -3995,7 +4026,9 @@ CONFIG_PLUGIN_HOSTCC="" # CONFIG_PMC_MSP is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMS7003 is not set # CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_DEBUG is not set # CONFIG_PM_DEVFREQ is not set # CONFIG_PM_WAKELOCKS is not set # CONFIG_POSIX_MQUEUE is not set @@ -4137,12 +4170,14 @@ CONFIG_PWRSEQ_SIMPLE=y # CONFIG_RAID_ATTRS is not set # CONFIG_RALINK is not set # CONFIG_RANDOM32_SELFTEST is not set +# CONFIG_RANDOMIZE_BASE is not set # CONFIG_RANDOM_TRUST_BOOTLOADER is not set # CONFIG_RANDOM_TRUST_CPU is not set # CONFIG_RAPIDIO is not set # CONFIG_RAS is not set # CONFIG_RAW_DRIVER is not set # CONFIG_RBTREE_TEST is not set +# CONFIG_RCU_BOOST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 # CONFIG_RCU_EQS_DEBUG is not set # CONFIG_RCU_EXPEDITE_BOOT is not set @@ -4277,7 +4312,7 @@ CONFIG_RFKILL=y # CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_CADENCE is not set -# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_CMOS=y # CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1302 is not set # CONFIG_RTC_DRV_DS1305 is not set @@ -4634,6 +4669,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_LTC4245 is not set # CONFIG_SENSORS_LTC4260 is not set # CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_LTQ_CPUTEMP is not set # CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX16064 is not set # CONFIG_SENSORS_MAX16065 is not set @@ -4657,7 +4693,6 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_NCT7802 is not set # CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_NPCM7XX is not set -# CONFIG_SENSORS_OCC_P8_I2C is not set # CONFIG_SENSORS_NSA320 is not set # CONFIG_SENSORS_NTC_THERMISTOR is not set # CONFIG_SENSORS_OCC_P8_I2C is not set @@ -4744,6 +4779,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=2 # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set # CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set # CONFIG_SERIAL_ARC is not set # CONFIG_SERIAL_BCM63XX is not set # CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set @@ -5039,6 +5075,7 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_CS53L30 is not set # CONFIG_SND_SOC_CX2072X is not set # CONFIG_SND_SOC_DIO2125 is not set +# CONFIG_SND_SOC_DMIC is not set # CONFIG_SND_SOC_ES7134 is not set # CONFIG_SND_SOC_ES7241 is not set # CONFIG_SND_SOC_ES8316 is not set @@ -5246,6 +5283,7 @@ CONFIG_SND_X86=y # CONFIG_SOUND is not set # CONFIG_SOUNDWIRE is not set # CONFIG_SOUND_OSS_CORE is not set +# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set # CONFIG_SOUND_PRIME is not set # CONFIG_SP5100_TCO is not set # CONFIG_SPARSEMEM_MANUAL is not set @@ -5289,8 +5327,8 @@ CONFIG_SND_X86=y # CONFIG_SPI_PPC4xx is not set # CONFIG_SPI_PXA2XX is not set # CONFIG_SPI_PXA2XX_PCI is not set -# CONFIG_SPI_ROCKCHIP is not set # CONFIG_SPI_QCOM_QSPI is not set +# CONFIG_SPI_ROCKCHIP is not set # CONFIG_SPI_S3C64XX is not set # CONFIG_SPI_SC18IS602 is not set # CONFIG_SPI_SIFIVE is not set @@ -5398,7 +5436,6 @@ CONFIG_SWAP=y # CONFIG_SYNOPSYS_DWC_ETH_QOS is not set CONFIG_SYN_COOKIES=y # CONFIG_SYSCON_REBOOT_MODE is not set -# CONFIG_NVMEM_REBOOT_MODE is not set CONFIG_SYSCTL=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_SYSFS=y @@ -5513,6 +5550,7 @@ CONFIG_TEXTSEARCH=y # CONFIG_THINKPAD_ACPI is not set CONFIG_THIN_ARCHIVES=y # CONFIG_THRUSTMASTER_FF is not set +# CONFIG_THUMB2_KERNEL is not set # CONFIG_THUNDERBOLT is not set # CONFIG_THUNDER_NIC_BGX is not set # CONFIG_THUNDER_NIC_PF is not set @@ -5712,6 +5750,7 @@ CONFIG_TRAD_SIGNALS=y # CONFIG_TREE_RCU is not set # CONFIG_TREE_RCU_TRACE is not set # CONFIG_TRIM_UNUSED_KSYMS is not set +# CONFIG_TRUSTED_FOUNDATIONS is not set # CONFIG_TRUSTED_KEYS is not set # CONFIG_TSL2583 is not set # CONFIG_TSL2772 is not set @@ -5762,6 +5801,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_UNIX_DIAG is not set CONFIG_UNIX_SCM=y # CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_UNWINDER_FRAME_POINTER is not set # CONFIG_UPROBES is not set # CONFIG_UPROBE_EVENTS is not set # CONFIG_US5182D is not set @@ -5803,6 +5843,7 @@ CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_DWC2_DUAL_ROLE is not set # CONFIG_USB_DWC2_HOST is not set # CONFIG_USB_DWC2_PERIPHERAL is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set # CONFIG_USB_DWC3 is not set # CONFIG_USB_DWC3_EXYNOS is not set # CONFIG_USB_DWC3_HAPS is not set @@ -5814,6 +5855,7 @@ CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_EG20T is not set # CONFIG_USB_EHCI_ATH79 is not set +# CONFIG_USB_EHCI_FSL is not set # CONFIG_USB_EHCI_HCD_AT91 is not set # CONFIG_USB_EHCI_HCD_OMAP is not set # CONFIG_USB_EHCI_HCD_PPC_OF is not set @@ -6284,7 +6326,6 @@ CONFIG_VMSPLIT_3G=y # CONFIG_W1_MASTER_GPIO is not set # CONFIG_W1_MASTER_MATROX is not set # CONFIG_W1_MASTER_SGI is not set -# CONFIG_W1_SLAVE_BQ27000 is not set # CONFIG_W1_SLAVE_DS2405 is not set # CONFIG_W1_SLAVE_DS2406 is not set # CONFIG_W1_SLAVE_DS2408 is not set @@ -6294,7 +6335,6 @@ CONFIG_VMSPLIT_3G=y # CONFIG_W1_SLAVE_DS2433 is not set # CONFIG_W1_SLAVE_DS2438 is not set # CONFIG_W1_SLAVE_DS250X is not set -# CONFIG_W1_SLAVE_DS2760 is not set # CONFIG_W1_SLAVE_DS2780 is not set # CONFIG_W1_SLAVE_DS2781 is not set # CONFIG_W1_SLAVE_DS2805 is not set @@ -6324,7 +6364,6 @@ CONFIG_WEXT_PROC=y CONFIG_WEXT_SPY=y CONFIG_WILINK_PLATFORM_DATA=y # CONFIG_WIMAX is not set -# CONFIG_WIMAX_GDM72XX is not set CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y # CONFIG_WIRELESS_WDS is not set @@ -6351,14 +6390,11 @@ CONFIG_WLAN=y # CONFIG_WLAN_VENDOR_TI is not set # CONFIG_WLAN_VENDOR_ZYDAS is not set # CONFIG_WLCORE is not set -# CONFIG_WL_MEDIATEK is not set -CONFIG_WL_TI=y CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y # CONFIG_WQ_WATCHDOG is not set # CONFIG_WW_MUTEX_SELFTEST is not set # CONFIG_X25 is not set # CONFIG_X509_CERTIFICATE_PARSER is not set -# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set # CONFIG_X86_PKG_TEMP_THERMAL is not set CONFIG_X86_SYSFB=y # CONFIG_XDP_SOCKETS is not set From 388603370b676b1b8e3326494b9369cec84af68e Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 27 Apr 2020 11:05:12 +0200 Subject: [PATCH 44/76] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 882aacbf..42c7c4d2 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "df27e949fbbf13e1e2ab4db49f608165ef0ba9fe" - _get_repo feeds/packages https://github.com/openwrt/packages "a4bb706918c58c7f8718e5de1de2e719eecabbd2" - _get_repo feeds/luci https://github.com/openwrt/luci "d0518a11e124e124bfaa02551bc2d028fad2d69d" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "3fdb08681b36537f430dc55743c90154790554ce" + _get_repo feeds/packages https://github.com/openwrt/packages "3c9dbc1429532d9d370d0b976ac812845b43a897" + _get_repo feeds/luci https://github.com/openwrt/luci "551d839f90853b58f81d124c77442009d4df0cb4" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From f9736ae7fc0edf90502caced4e588fe2a370aeb3 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 5 May 2020 10:52:08 +0200 Subject: [PATCH 45/76] Add some MPTCP fixes --- .../generic/hack-5.4/693-mptcp-fixes.patch | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch diff --git a/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch b/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch new file mode 100644 index 00000000..e8f9fec8 --- /dev/null +++ b/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch @@ -0,0 +1,171 @@ +diff -aurN mptcp-mptcp_trunk/include/net/tcp.h mptcp/include/net/tcp.h +--- mptcp-mptcp_trunk/include/net/tcp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/include/net/tcp.h 2020-05-03 12:20:25.179226306 +0200 +@@ -343,7 +343,6 @@ + struct mptcp_options_received; + + void tcp_cleanup_rbuf(struct sock *sk, int copied); +-void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited); + int tcp_close_state(struct sock *sk); + void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, + const struct sk_buff *skb); +@@ -2126,7 +2125,6 @@ + void (*retransmit_timer)(struct sock *sk); + void (*time_wait)(struct sock *sk, int state, int timeo); + void (*cleanup_rbuf)(struct sock *sk, int copied); +- void (*cwnd_validate)(struct sock *sk, bool is_cwnd_limited); + int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, + bool reinit, bool cap_net_admin); + }; +diff -aurN mptcp-mptcp_trunk/net/ipv4/tcp.c mptcp/net/ipv4/tcp.c +--- mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/ipv4/tcp.c 2020-05-03 12:20:25.179226306 +0200 +@@ -415,7 +415,6 @@ + .retransmit_timer = tcp_retransmit_timer, + .time_wait = tcp_time_wait, + .cleanup_rbuf = tcp_cleanup_rbuf, +- .cwnd_validate = tcp_cwnd_validate, + .set_cong_ctrl = __tcp_set_congestion_control, + }; + +diff -aurN mptcp-mptcp_trunk/net/ipv4/tcp_output.c mptcp/net/ipv4/tcp_output.c +--- mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/ipv4/tcp_output.c 2020-05-03 12:20:25.179226306 +0200 +@@ -825,8 +825,8 @@ + if (mptcp(tp)) + tcp_tsq_write(meta_sk); + } else { +- if (!test_and_set_bit(TCP_TSQ_DEFERRED, &meta_sk->sk_tsq_flags)) +- sock_hold(meta_sk); ++ if (!test_and_set_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags)) ++ sock_hold(sk); + + if ((mptcp(tp)) && (sk->sk_state != TCP_CLOSE)) + mptcp_tsq_flags(sk); +@@ -1672,7 +1672,7 @@ + tp->snd_cwnd_stamp = tcp_jiffies32; + } + +-void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) ++static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) + { + const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; + struct tcp_sock *tp = tcp_sk(sk); +@@ -2512,8 +2512,7 @@ + if (push_one != 2) + tcp_schedule_loss_probe(sk, false); + is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); +- if (tp->ops->cwnd_validate) +- tp->ops->cwnd_validate(sk, is_cwnd_limited); ++ tcp_cwnd_validate(sk, is_cwnd_limited); + return false; + } + return !tp->packets_out && !tcp_write_queue_empty(sk); +diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_output.c mptcp/net/mptcp/mptcp_output.c +--- mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_output.c 2020-05-03 12:20:25.183226240 +0200 +@@ -851,10 +851,7 @@ + + if (!mptcp_skb_entail(subsk, skb, reinject)) + break; +- /* Nagle is handled at the MPTCP-layer, so +- * always push on the subflow +- */ +- __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); ++ + if (reinject <= 0) + tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); + meta_tp->lsndtime = tcp_jiffies32; +@@ -886,14 +883,12 @@ + if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) + continue; + +- /* We have pushed data on this subflow. We ignore the call to +- * cwnd_validate in tcp_write_xmit as is_cwnd_limited will never +- * be true (we never push more than what the cwnd can accept). +- * We need to ensure that we call tcp_cwnd_validate with +- * is_cwnd_limited set to true if we have filled the cwnd. ++ mss_now = tcp_current_mss(subsk); ++ ++ /* Nagle is handled at the MPTCP-layer, so ++ * always push on the subflow + */ +- tcp_cwnd_validate(subsk, tcp_packets_in_flight(subtp) >= +- subtp->snd_cwnd); ++ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); + } + + return !meta_tp->packets_out && tcp_send_head(meta_sk); +diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c mptcp/net/mptcp/mptcp_sched.c +--- mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_sched.c 2020-05-03 12:20:31.843115714 +0200 +@@ -76,7 +76,7 @@ + */ + space = (tp->snd_cwnd - in_flight) * tp->mss_cache; + +- if (tp->write_seq - tp->snd_nxt > space) ++ if (tp->write_seq - tp->snd_nxt >= space) + return true; + + if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) +@@ -391,10 +391,10 @@ + unsigned int *limit) + { + struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); +- unsigned int mss_now; ++ unsigned int mss_now, in_flight_space; + struct tcp_sock *subtp; + u16 gso_max_segs; +- u32 max_len, max_segs, window, needed; ++ u32 max_len, max_segs, window; + + /* As we set it, we have to reset it as well. */ + *limit = 0; +@@ -424,9 +424,6 @@ + /* The following is similar to tcp_mss_split_point, but + * we do not care about nagle, because we will anyways + * use TCP_NAGLE_PUSH, which overrides this. +- * +- * So, we first limit according to the cwnd/gso-size and then according +- * to the subflow's window. + */ + + gso_max_segs = (*subsk)->sk_gso_max_segs; +@@ -436,16 +433,29 @@ + if (!max_segs) + return NULL; + +- max_len = mss_now * max_segs; +- window = tcp_wnd_end(subtp) - subtp->write_seq; ++ /* max_len is what would fit in the cwnd (respecting the 2GSO-limit of ++ * tcp_cwnd_test), but ignoring whatever was already queued. ++ */ ++ max_len = min(mss_now * max_segs, skb->len); + +- needed = min(skb->len, window); +- if (max_len <= skb->len) +- /* Take max_win, which is actually the cwnd/gso-size */ +- *limit = max_len; ++ in_flight_space = (subtp->snd_cwnd - tcp_packets_in_flight(subtp)) * mss_now; ++ ++ if ((int)in_flight_space - (subtp->write_seq - subtp->snd_nxt) <= 0) ++ WARN(1, "in_flight %u cwnd %u wseq %u snxt %u mss_now %u cache %u", ++ tcp_packets_in_flight(subtp), subtp->snd_cwnd, ++ subtp->write_seq, subtp->snd_nxt, mss_now, subtp->mss_cache); + else +- /* Or, take the window */ +- *limit = needed; ++ /* max_len now fits exactly in the write-queue, taking into ++ * account what was already queued. ++ */ ++ max_len = min(max_len, in_flight_space - (subtp->write_seq - subtp->snd_nxt)); ++ ++ window = tcp_wnd_end(subtp) - subtp->write_seq; ++ ++ /* max_len now also respects the announced receive-window */ ++ max_len = min(max_len, window); ++ ++ *limit = max_len; + + return skb; + } From 9d7a56a2f0c5e3e48a6e26246642b0b6a36c8d3a Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 5 May 2020 10:53:03 +0200 Subject: [PATCH 46/76] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 42c7c4d2..78da9aa6 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "3fdb08681b36537f430dc55743c90154790554ce" - _get_repo feeds/packages https://github.com/openwrt/packages "3c9dbc1429532d9d370d0b976ac812845b43a897" - _get_repo feeds/luci https://github.com/openwrt/luci "551d839f90853b58f81d124c77442009d4df0cb4" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "49ab97ca86593de1bcb16c70e58e3cb62c16623d" + _get_repo feeds/packages https://github.com/openwrt/packages "6198128711fec34579cd16c2e6f4aff098862e87" + _get_repo feeds/luci https://github.com/openwrt/luci "10d5410bb62ba389696fc94b773932e64c6f3b41" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From 526613c184f0b036892e5ae2cdc916706949ac57 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 14 May 2020 16:49:19 +0200 Subject: [PATCH 47/76] Update OpenWrt and MPTCP --- build.sh | 11 +- config | 11 +- root/target/linux/generic/config-5.4 | 1 + .../generic/hack-5.4/693-mptcp-fixes.patch | 1724 ++++++++++++++++- 4 files changed, 1715 insertions(+), 32 deletions(-) diff --git a/build.sh b/build.sh index 78da9aa6..6d39dbad 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "49ab97ca86593de1bcb16c70e58e3cb62c16623d" - _get_repo feeds/packages https://github.com/openwrt/packages "6198128711fec34579cd16c2e6f4aff098862e87" - _get_repo feeds/luci https://github.com/openwrt/luci "10d5410bb62ba389696fc94b773932e64c6f3b41" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "eb17ee294ca8e2b59051a4337779af7a3f4812d5" + _get_repo feeds/packages https://github.com/openwrt/packages "a22fff844db6927bbe77570d21a7e08d5f5424f3" + _get_repo feeds/luci https://github.com/openwrt/luci "750e6c1df9624198f4f11e0675de428ec33fd564" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -143,6 +143,7 @@ else fi if [ "$OMR_ALL_PACKAGES" = "yes" ]; then echo 'CONFIG_ALL=y' >> "$OMR_TARGET/source/.config" + echo 'CONFIG_ALL_NONSHARED=y' >> "$OMR_TARGET/source/.config" fi if [ "$OMR_IMG" = "yes" ] && [ "$OMR_TARGET" = "x86_64" ]; then echo 'CONFIG_VDI_IMAGES=y' >> "$OMR_TARGET/source/.config" @@ -267,8 +268,8 @@ scripts/feeds update -a #cd "$OMR_TARGET/source" if [ "$OMR_ALL_PACKAGES" = "yes" ]; then - scripts/feeds install -a -p packages - scripts/feeds install -a -p luci + scripts/feeds install -a -d m -p packages + scripts/feeds install -a -d m -p luci fi scripts/feeds install -a -d y -f -p openmptcprouter cp .config.keep .config diff --git a/config b/config index 59064a66..971e38db 100644 --- a/config +++ b/config @@ -194,17 +194,18 @@ CONFIG_KERNEL_TCP_CONG_BALIA=y CONFIG_KERNEL_MPTCP_FULLMESH=y CONFIG_KERNEL_DEFAULT_FULLMESH=y CONFIG_KERNEL_MPTCP_NDIFFPORTS=y -CONFIG_KERNEL_DEFAULT_NDIFFPORTS=n +# CONFIG_KERNEL_DEFAULT_NDIFFPORTS is not set CONFIG_KERNEL_MPTCP_BINDER=y CONFIG_KERNEL_MPTCP_ECF=y -CONFIG_KERNEL_DEFAULT_BINDER=n -CONFIG_KERNEL_DEFAULT_DUMMY=n +# CONFIG_KERNEL_DEFAULT_BINDER is not set +# CONFIG_KERNEL_DEFAULT_DUMMY is not set CONFIG_KERNEL_MPTCP_ROUNDROBIN=y -CONFIG_KERNEL_DEFAULT_ROUNDROBIN=n +# CONFIG_KERNEL_DEFAULT_ROUNDROBIN is not set CONFIG_KERNEL_MPTCP_REDUNDANT=y -CONFIG_KERNEL_DEFAULT_REDUNDANT=n +# CONFIG_KERNEL_DEFAULT_REDUNDANT is not set CONFIG_KERNEL_DEFAULT_SCHEDULER=y CONFIG_KERNEL_MPTCP=y +CONFIG_KERNEL_CRYPTO_SHA256=y CONFIG_LUCI_LANG_hu=y CONFIG_LUCI_LANG_pt=y CONFIG_LUCI_LANG_sk=y diff --git a/root/target/linux/generic/config-5.4 b/root/target/linux/generic/config-5.4 index 90d9a44e..3b71ac91 100644 --- a/root/target/linux/generic/config-5.4 +++ b/root/target/linux/generic/config-5.4 @@ -6498,3 +6498,4 @@ CONFIG_DEFAULT_SCHEDULER=y # CONFIG_DEFAULT_BLEST is not set # CONFIG_DEFAULT_REDUNDANT is not set CONFIG_NF_CONNTRACK_CUSTOM=2 +CONFIG_CRYPTO_SHA256=y \ No newline at end of file diff --git a/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch b/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch index e8f9fec8..372825f6 100644 --- a/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch +++ b/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch @@ -1,6 +1,128 @@ -diff -aurN mptcp-mptcp_trunk/include/net/tcp.h mptcp/include/net/tcp.h +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/include/net/mptcp.h mptcp/include/net/mptcp.h +--- mptcp-mptcp_trunk/include/net/mptcp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/include/net/mptcp.h 2020-05-14 15:15:39.929940266 +0200 +@@ -102,7 +102,8 @@ + + u8 loc_id; + u8 rem_id; /* Address-id in the MP_JOIN */ +- u8 dss_csum:1, ++ u16 dss_csum:1, ++ rem_key_set:1, + is_sub:1, /* Is this a new subflow? */ + low_prio:1, /* Interface set to low-prio? */ + rcv_low_prio:1, +@@ -240,7 +241,6 @@ + struct module *owner; + }; + +-#define MPTCP_SCHED_NAME_MAX 16 + struct mptcp_sched_ops { + struct list_head list; + +@@ -272,6 +272,8 @@ + u32 rcv_high_order[2]; + + u16 send_infinite_mapping:1, ++ send_mptcpv1_mpcapable:1, ++ rem_key_set:1, + in_time_wait:1, + list_rcvd:1, /* XXX TO REMOVE */ + addr_signal:1, /* Path-manager wants us to call addr_signal */ +@@ -354,6 +356,16 @@ + #define MPTCP_SUB_LEN_CAPABLE_ACK 20 + #define MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN 20 + ++#define MPTCPV1_SUB_LEN_CAPABLE_SYN 4 ++#define MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN 4 ++#define MPTCPV1_SUB_LEN_CAPABLE_SYNACK 12 ++#define MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN 12 ++#define MPTCPV1_SUB_LEN_CAPABLE_ACK 20 ++#define MPTCPV1_SUB_LEN_CAPABLE_ACK_ALIGN 20 ++#define MPTCPV1_SUB_LEN_CAPABLE_DATA 22 ++#define MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM 22 ++#define MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN 24 ++ + #define MPTCP_SUB_JOIN 1 + #define MPTCP_SUB_LEN_JOIN_SYN 12 + #define MPTCP_SUB_LEN_JOIN_SYN_ALIGN 12 +@@ -450,14 +462,15 @@ + #define MPTCPHDR_SEQ 0x01 /* DSS.M option is present */ + #define MPTCPHDR_FIN 0x02 /* DSS.F option is present */ + #define MPTCPHDR_SEQ64_INDEX 0x04 /* index of seq in mpcb->snd_high_order */ ++#define MPTCPHDR_MPC_DATA 0x08 + /* MPTCP flags: RX only */ +-#define MPTCPHDR_ACK 0x08 +-#define MPTCPHDR_SEQ64_SET 0x10 /* Did we received a 64-bit seq number? */ +-#define MPTCPHDR_SEQ64_OFO 0x20 /* Is it not in our circular array? */ +-#define MPTCPHDR_DSS_CSUM 0x40 ++#define MPTCPHDR_ACK 0x10 ++#define MPTCPHDR_SEQ64_SET 0x20 /* Did we received a 64-bit seq number? */ ++#define MPTCPHDR_SEQ64_OFO 0x40 /* Is it not in our circular array? */ ++#define MPTCPHDR_DSS_CSUM 0x80 + /* MPTCP flags: TX only */ +-#define MPTCPHDR_INF 0x08 +-#define MPTCP_REINJECT 0x10 /* Did we reinject this segment? */ ++#define MPTCPHDR_INF 0x10 ++#define MPTCP_REINJECT 0x20 /* Did we reinject this segment? */ + + struct mptcp_option { + __u8 kind; +@@ -800,10 +813,11 @@ + void mptcp_close(struct sock *meta_sk, long timeout); + bool mptcp_doit(struct sock *sk); + int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, +- __u8 mptcp_ver, u32 window); ++ int rem_key_set, __u8 mptcp_ver, u32 window); + int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req); + int mptcp_check_req_master(struct sock *sk, struct sock *child, + struct request_sock *req, const struct sk_buff *skb, ++ const struct mptcp_options_received *mopt, + int drop, u32 tsoff); + struct sock *mptcp_check_req_child(struct sock *meta_sk, + struct sock *child, +@@ -816,8 +830,8 @@ + int wscale_ok, __u8 *rcv_wscale, + __u32 init_rcv_wnd); + unsigned int mptcp_current_mss(struct sock *meta_sk); +-void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, +- int arg_num, ...); ++void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, ...); + void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); + void mptcp_fin(struct sock *meta_sk); + void mptcp_meta_retransmit_timer(struct sock *meta_sk); +@@ -827,6 +841,8 @@ + void mptcp_sub_close(struct sock *sk, unsigned long delay); + struct sock *mptcp_select_ack_sock(const struct sock *meta_sk); + void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb); ++void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb, ++ __u64 remote_key); + int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb); + void mptcp_ack_handler(struct timer_list *t); + bool mptcp_check_rtt(const struct tcp_sock *tp, int time); +@@ -982,6 +998,11 @@ + } + } + ++static inline bool mptcp_is_data_mpcapable(const struct sk_buff *skb) ++{ ++ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_MPC_DATA; ++} ++ + static inline bool mptcp_is_data_seq(const struct sk_buff *skb) + { + return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ; +@@ -1399,6 +1420,7 @@ + const struct sock *child, + const struct request_sock *req, + const struct sk_buff *skb, ++ const struct mptcp_options_received *mopt, + int drop, + u32 tsoff) + { +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/include/net/tcp.h mptcp/include/net/tcp.h --- mptcp-mptcp_trunk/include/net/tcp.h 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/include/net/tcp.h 2020-05-03 12:20:25.179226306 +0200 ++++ mptcp/include/net/tcp.h 2020-05-14 15:15:27.126152589 +0200 @@ -343,7 +343,6 @@ struct mptcp_options_received; @@ -9,7 +131,15 @@ diff -aurN mptcp-mptcp_trunk/include/net/tcp.h mptcp/include/net/tcp.h int tcp_close_state(struct sock *sk); void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, const struct sk_buff *skb); -@@ -2126,7 +2125,6 @@ +@@ -583,6 +582,7 @@ + /* From syncookies.c */ + struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, + struct request_sock *req, ++ const struct mptcp_options_received *mopt, + struct dst_entry *dst, u32 tsoff); + int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, + u32 cookie); +@@ -2126,7 +2126,6 @@ void (*retransmit_timer)(struct sock *sk); void (*time_wait)(struct sock *sk, int state, int timeo); void (*cleanup_rbuf)(struct sock *sk, int copied); @@ -17,9 +147,38 @@ diff -aurN mptcp-mptcp_trunk/include/net/tcp.h mptcp/include/net/tcp.h int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, bool reinit, bool cap_net_admin); }; -diff -aurN mptcp-mptcp_trunk/net/ipv4/tcp.c mptcp/net/ipv4/tcp.c +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv4/syncookies.c mptcp/net/ipv4/syncookies.c +--- mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/ipv4/syncookies.c 2020-05-14 15:15:27.126152589 +0200 +@@ -203,6 +203,7 @@ + + struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, + struct request_sock *req, ++ const struct mptcp_options_received *mopt, + struct dst_entry *dst, u32 tsoff) + { + struct inet_connection_sock *icsk = inet_csk(sk); +@@ -219,7 +220,7 @@ + if (!child) + goto listen_overflow; + +- ret = mptcp_check_req_master(sk, child, req, skb, 0, tsoff); ++ ret = mptcp_check_req_master(sk, child, req, skb, mopt, 0, tsoff); + if (ret < 0) + return NULL; + +@@ -428,7 +429,7 @@ + ireq->rcv_wscale = rcv_wscale; + ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); + +- ret = tcp_get_cookie_sock(sk, skb, req, &rt->dst, tsoff); ++ ret = tcp_get_cookie_sock(sk, skb, req, &mopt, &rt->dst, tsoff); + /* ip_queue_xmit() depends on our flow being setup + * Normal sockets get it right from inet_csk_route_child_sock() + */ +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv4/tcp.c mptcp/net/ipv4/tcp.c --- mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/ipv4/tcp.c 2020-05-03 12:20:25.179226306 +0200 ++++ mptcp/net/ipv4/tcp.c 2020-05-11 09:40:04.803741955 +0200 @@ -415,7 +415,6 @@ .retransmit_timer = tcp_retransmit_timer, .time_wait = tcp_time_wait, @@ -28,9 +187,21 @@ diff -aurN mptcp-mptcp_trunk/net/ipv4/tcp.c mptcp/net/ipv4/tcp.c .set_cong_ctrl = __tcp_set_congestion_control, }; -diff -aurN mptcp-mptcp_trunk/net/ipv4/tcp_output.c mptcp/net/ipv4/tcp_output.c +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c mptcp/net/ipv4/tcp_minisocks.c +--- mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/ipv4/tcp_minisocks.c 2020-05-14 15:15:27.138152390 +0200 +@@ -828,7 +828,7 @@ + goto listen_overflow; + + if (own_req && !is_meta_sk(sk)) { +- int ret = mptcp_check_req_master(sk, child, req, skb, 1, 0); ++ int ret = mptcp_check_req_master(sk, child, req, skb, &mopt, 1, 0); + if (ret < 0) + goto listen_overflow; + +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv4/tcp_output.c mptcp/net/ipv4/tcp_output.c --- mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/ipv4/tcp_output.c 2020-05-03 12:20:25.179226306 +0200 ++++ mptcp/net/ipv4/tcp_output.c 2020-05-11 09:40:04.803741955 +0200 @@ -825,8 +825,8 @@ if (mptcp(tp)) tcp_tsq_write(meta_sk); @@ -61,10 +232,959 @@ diff -aurN mptcp-mptcp_trunk/net/ipv4/tcp_output.c mptcp/net/ipv4/tcp_output.c return false; } return !tp->packets_out && !tcp_write_queue_empty(sk); -diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_output.c mptcp/net/mptcp/mptcp_output.c +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv6/syncookies.c mptcp/net/ipv6/syncookies.c +--- mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/ipv6/syncookies.c 2020-05-14 15:15:27.142152325 +0200 +@@ -267,7 +267,7 @@ + ireq->rcv_wscale = rcv_wscale; + ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); + +- ret = tcp_get_cookie_sock(sk, skb, req, dst, tsoff); ++ ret = tcp_get_cookie_sock(sk, skb, req, &mopt, dst, tsoff); + out: + return ret; + out_free: +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c mptcp/net/mptcp/mptcp_ctrl.c +--- mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_ctrl.c 2020-05-14 15:15:39.953939868 +0200 +@@ -27,6 +27,8 @@ + * 2 of the License, or (at your option) any later version. + */ + ++#include ++ + #include + #include + #include +@@ -77,7 +79,7 @@ + struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; + EXPORT_SYMBOL(mptcp_static_key); + +-static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn); ++static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn); + + static int proc_mptcp_path_manager(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, +@@ -286,7 +288,7 @@ + #endif + } + +- mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); ++ mptcp_key_hash(mtreq->mptcp_ver, mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); + } + + /* New MPTCP-connection request, prepare a new token for the meta-socket that +@@ -319,7 +321,11 @@ + spin_unlock(&mptcp_tk_hashlock); + local_bh_enable(); + rcu_read_unlock(); +- mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ ++ if (mtreq->mptcp_ver == MPTCP_VERSION_0) { ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ mtreq->rem_key_set = 1; ++ } + } + + static int mptcp_reqsk_new_cookie(struct request_sock *req, +@@ -355,7 +361,10 @@ + local_bh_enable(); + rcu_read_unlock(); + +- mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ if (mtreq->mptcp_ver == MPTCP_VERSION_0) { ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ mtreq->rem_key_set = 1; ++ } + + return true; + } +@@ -380,8 +389,7 @@ + mptcp_seed++); + #endif + +- mptcp_key_sha1(tp->mptcp_loc_key, +- &tp->mptcp_loc_token, NULL); ++ mptcp_key_hash(tp->mptcp_ver, tp->mptcp_loc_key, &tp->mptcp_loc_token, NULL); + } + + #ifdef CONFIG_JUMP_LABEL +@@ -835,6 +843,71 @@ + siphash_key_t mptcp_secret __read_mostly; + u32 mptcp_seed = 0; + ++#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / 4) ++ ++static void mptcp_key_sha256(const u64 key, u32 *token, u64 *idsn) ++{ ++ u32 mptcp_hashed_key[SHA256_DIGEST_WORDS]; ++ struct sha256_state state; ++ ++ sha256_init(&state); ++ sha256_update(&state, (const u8 *)&key, sizeof(key)); ++ sha256_final(&state, (u8 *)mptcp_hashed_key); ++ ++ if (token) ++ *token = mptcp_hashed_key[0]; ++ if (idsn) ++ *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[6])); ++} ++ ++static void mptcp_hmac_sha256(const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, va_list list) ++{ ++ u8 input[SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE]; ++ __be32 output[SHA256_DIGEST_WORDS]; ++ struct sha256_state state; ++ int index, msg_length; ++ int length = 0; ++ u8 *msg; ++ int i; ++ ++ /* Generate key xored with ipad */ ++ memset(input, 0x36, SHA256_BLOCK_SIZE); ++ for (i = 0; i < 8; i++) ++ input[i] ^= key_1[i]; ++ for (i = 0; i < 8; i++) ++ input[i + 8] ^= key_2[i]; ++ ++ index = SHA256_BLOCK_SIZE; ++ msg_length = 0; ++ for (i = 0; i < arg_num; i++) { ++ length = va_arg(list, int); ++ msg = va_arg(list, u8 *); ++ BUG_ON(index + length >= sizeof(input)); /* Message is too long */ ++ memcpy(&input[index], msg, length); ++ index += length; ++ msg_length += length; ++ } ++ ++ sha256_init(&state); ++ sha256_update(&state, input, SHA256_BLOCK_SIZE + msg_length); ++ sha256_final(&state, &input[SHA256_BLOCK_SIZE]); ++ ++ /* Prepare second part of hmac */ ++ memset(input, 0x5C, SHA256_BLOCK_SIZE); ++ for (i = 0; i < 8; i++) ++ input[i] ^= key_1[i]; ++ for (i = 0; i < 8; i++) ++ input[i + 8] ^= key_2[i]; ++ ++ sha256_init(&state); ++ sha256_update(&state, input, sizeof(input)); ++ sha256_final(&state, (u8 *)output); ++ ++ for (i = 0; i < 5; i++) ++ hash_out[i] = output[i]; ++} ++ + static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) + { + u32 workspace[SHA_WORKSPACE_WORDS]; +@@ -864,8 +937,16 @@ + *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[3])); + } + +-void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, +- int arg_num, ...) ++static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn) ++{ ++ if (version == MPTCP_VERSION_0) ++ mptcp_key_sha1(key, token, idsn); ++ else if (version >= MPTCP_VERSION_1) ++ mptcp_key_sha256(key, token, idsn); ++} ++ ++static void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, va_list list) + { + u32 workspace[SHA_WORKSPACE_WORDS]; + u8 input[128]; /* 2 512-bit blocks */ +@@ -873,7 +954,6 @@ + int index; + int length; + u8 *msg; +- va_list list; + + memset(workspace, 0, sizeof(workspace)); + +@@ -884,7 +964,6 @@ + for (i = 0; i < 8; i++) + input[i + 8] ^= key_2[i]; + +- va_start(list, arg_num); + index = 64; + for (i = 0; i < arg_num; i++) { + length = va_arg(list, int); +@@ -893,7 +972,6 @@ + memcpy(&input[index], msg, length); + index += length; + } +- va_end(list); + + input[index] = 0x80; /* Padding: First bit after message = 1 */ + memset(&input[index + 1], 0, (126 - index)); +@@ -936,7 +1014,20 @@ + for (i = 0; i < 5; i++) + hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); + } +-EXPORT_SYMBOL(mptcp_hmac_sha1); ++ ++void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, ...) ++{ ++ va_list args; ++ ++ va_start(args, arg_num); ++ if (ver == MPTCP_VERSION_0) ++ mptcp_hmac_sha1(key_1, key_2, hash_out, arg_num, args); ++ else if (ver >= MPTCP_VERSION_1) ++ mptcp_hmac_sha256(key_1, key_2, hash_out, arg_num, args); ++ va_end(args); ++} ++EXPORT_SYMBOL(mptcp_hmac); + + static void mptcp_mpcb_inherit_sockopts(struct sock *meta_sk, struct sock *master_sk) + { +@@ -1169,14 +1260,33 @@ + .set_cong_ctrl = __tcp_set_congestion_control, + }; + ++void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb, ++ __u64 remote_key) ++{ ++ u64 idsn; ++ ++ mpcb->mptcp_rem_key = remote_key; ++ mpcb->rem_key_set = 1; ++ mptcp_key_hash(mpcb->mptcp_ver, mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &idsn); ++ ++ idsn++; ++ mpcb->rcv_high_order[0] = idsn >> 32; ++ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; ++ meta_tp->copied_seq = (u32)idsn; ++ meta_tp->rcv_nxt = (u32)idsn; ++ meta_tp->rcv_wup = (u32)idsn; ++ ++ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; ++} ++ + static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, +- __u8 mptcp_ver, u32 window) ++ int rem_key_set, __u8 mptcp_ver, u32 window) + { + struct mptcp_cb *mpcb; + struct sock *master_sk; + struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); + struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk); +- u64 snd_idsn, rcv_idsn; ++ u64 snd_idsn; + + dst_release(meta_sk->sk_rx_dst); + meta_sk->sk_rx_dst = NULL; +@@ -1204,17 +1314,11 @@ + mpcb->mptcp_loc_token = meta_tp->mptcp_loc_token; + + /* Generate Initial data-sequence-numbers */ +- mptcp_key_sha1(mpcb->mptcp_loc_key, NULL, &snd_idsn); ++ mptcp_key_hash(mpcb->mptcp_ver, mpcb->mptcp_loc_key, NULL, &snd_idsn); + snd_idsn++; + mpcb->snd_high_order[0] = snd_idsn >> 32; + mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1; + +- mpcb->mptcp_rem_key = remote_key; +- mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &rcv_idsn); +- rcv_idsn++; +- mpcb->rcv_high_order[0] = rcv_idsn >> 32; +- mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; +- + mpcb->meta_sk = meta_sk; + mpcb->master_sk = master_sk; + +@@ -1326,11 +1430,9 @@ + meta_tp->pushed_seq = meta_tp->write_seq; + meta_tp->snd_up = meta_tp->write_seq; + +- meta_tp->copied_seq = (u32)rcv_idsn; +- meta_tp->rcv_nxt = (u32)rcv_idsn; +- meta_tp->rcv_wup = (u32)rcv_idsn; ++ if (rem_key_set) ++ mptcp_initialize_recv_vars(meta_tp, mpcb, remote_key); + +- meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; + meta_tp->snd_wnd = window; + meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */ + +@@ -2077,12 +2179,12 @@ + } + + int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, +- __u8 mptcp_ver, u32 window) ++ int rem_key_set, __u8 mptcp_ver, u32 window) + { + struct tcp_sock *master_tp; + struct sock *master_sk; + +- if (mptcp_alloc_mpcb(meta_sk, remote_key, mptcp_ver, window)) ++ if (mptcp_alloc_mpcb(meta_sk, remote_key, rem_key_set, mptcp_ver, window)) + goto err_alloc_mpcb; + + master_sk = tcp_sk(meta_sk)->mpcb->master_sk; +@@ -2110,6 +2212,7 @@ + } + + static int __mptcp_check_req_master(struct sock *child, ++ const struct mptcp_options_received *mopt, + struct request_sock *req) + { + struct tcp_sock *child_tp = tcp_sk(child); +@@ -2121,6 +2224,8 @@ + if (!inet_rsk(req)->mptcp_rqsk) + return 1; + ++ mtreq = mptcp_rsk(req); ++ + if (!inet_rsk(req)->saw_mpc) { + /* Fallback to regular TCP, because we saw one SYN without + * MP_CAPABLE. In tcp_check_req we continue the regular path. +@@ -2132,15 +2237,21 @@ + return 1; + } + ++ /* mopt can be NULL when coming from FAST-OPEN */ ++ if (mopt && mopt->saw_mpc && mtreq->mptcp_ver == MPTCP_VERSION_1) { ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ mtreq->rem_key_set = 1; ++ } ++ + MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK); + + /* Just set this values to pass them to mptcp_alloc_mpcb */ +- mtreq = mptcp_rsk(req); + child_tp->mptcp_loc_key = mtreq->mptcp_loc_key; + child_tp->mptcp_loc_token = mtreq->mptcp_loc_token; + + if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, +- mtreq->mptcp_ver, child_tp->snd_wnd)) { ++ mtreq->rem_key_set, mtreq->mptcp_ver, ++ child_tp->snd_wnd)) { + inet_csk_prepare_forced_close(meta_sk); + tcp_done(meta_sk); + +@@ -2175,7 +2286,7 @@ + u32 new_mapping; + int ret; + +- ret = __mptcp_check_req_master(child, req); ++ ret = __mptcp_check_req_master(child, NULL, req); + if (ret) + return ret; + +@@ -2218,12 +2329,13 @@ + + int mptcp_check_req_master(struct sock *sk, struct sock *child, + struct request_sock *req, const struct sk_buff *skb, ++ const struct mptcp_options_received *mopt, + int drop, u32 tsoff) + { + struct sock *meta_sk = child; + int ret; + +- ret = __mptcp_check_req_master(child, req); ++ ret = __mptcp_check_req_master(child, mopt, req); + if (ret) + return ret; + child = tcp_sk(child)->mpcb->master_sk; +@@ -2281,11 +2393,10 @@ + goto teardown; + } + +- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, +- (u8 *)&mpcb->mptcp_loc_key, +- (u32 *)hash_mac_check, 2, +- 4, (u8 *)&mtreq->mptcp_rem_nonce, +- 4, (u8 *)&mtreq->mptcp_loc_nonce); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)&mpcb->mptcp_loc_key, (u32 *)hash_mac_check, 2, ++ 4, (u8 *)&mtreq->mptcp_rem_nonce, ++ 4, (u8 *)&mtreq->mptcp_loc_nonce); + + if (memcmp(hash_mac_check, (char *)&mopt->mptcp_recv_mac, 20)) { + MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKMAC); +@@ -2547,11 +2658,10 @@ + + mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; + +- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, +- (u8 *)&mpcb->mptcp_rem_key, +- (u32 *)mptcp_hash_mac, 2, +- 4, (u8 *)&mtreq->mptcp_loc_nonce, +- 4, (u8 *)&mtreq->mptcp_rem_nonce); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)&mpcb->mptcp_rem_key, (u32 *)mptcp_hash_mac, 2, ++ 4, (u8 *)&mtreq->mptcp_loc_nonce, ++ 4, (u8 *)&mtreq->mptcp_rem_nonce); + mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; + + mtreq->rem_id = mopt.rem_id; +@@ -2591,11 +2701,13 @@ + /* Absolutely need to always initialize this. */ + mtreq->hash_entry.pprev = NULL; + ++ mtreq->mptcp_ver = mopt->mptcp_ver; + mtreq->mptcp_rem_key = mopt->mptcp_sender_key; + mtreq->mptcp_loc_key = mopt->mptcp_receiver_key; ++ mtreq->rem_key_set = 1; + + /* Generate the token */ +- mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); ++ mptcp_key_hash(mtreq->mptcp_ver, mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); + + rcu_read_lock(); + local_bh_disable(); +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c mptcp/net/mptcp/mptcp_fullmesh.c +--- mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_fullmesh.c 2020-05-14 15:15:39.957939801 +0200 +@@ -1596,11 +1596,10 @@ + u8 no_key[8]; + + *(u64 *)no_key = 0; +- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, +- (u8 *)no_key, +- (u32 *)mptcp_hash_mac, 2, +- 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, +- 4, (u8 *)&opts->add_addr4.addr.s_addr); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)no_key, (u32 *)mptcp_hash_mac, 2, ++ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, ++ 4, (u8 *)&opts->add_addr4.addr.s_addr); + opts->add_addr4.trunc_mac = *(u64 *)mptcp_hash_mac; + } + +@@ -1639,11 +1638,10 @@ + u8 no_key[8]; + + *(u64 *)no_key = 0; +- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, +- (u8 *)no_key, +- (u32 *)mptcp_hash_mac, 2, +- 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, +- 16, (u8 *)&opts->add_addr6.addr.s6_addr); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)no_key, (u32 *)mptcp_hash_mac, 2, ++ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, ++ 16, (u8 *)&opts->add_addr6.addr.s6_addr); + opts->add_addr6.trunc_mac = *(u64 *)mptcp_hash_mac; + } + +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_input.c mptcp/net/mptcp/mptcp_input.c +--- mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_input.c 2020-05-14 15:15:39.965939670 +0200 +@@ -176,6 +176,10 @@ + } + + /* Inspired by tcp_rcv_state_process */ ++/* Returns 0 if processing the packet can continue ++ * -1 if connection was closed with an active reset ++ * 1 if connection was closed and processing should stop. ++ */ + static int mptcp_rcv_state_process(struct sock *meta_sk, struct sock *sk, + const struct sk_buff *skb, u32 data_seq, + u16 data_len) +@@ -216,7 +220,7 @@ + mptcp_send_active_reset(meta_sk, GFP_ATOMIC); + tcp_done(meta_sk); + __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); +- return 1; ++ return -1; + } + + tmo = tcp_fin_time(meta_sk); +@@ -259,7 +263,7 @@ + __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); + mptcp_send_active_reset(meta_sk, GFP_ATOMIC); + tcp_reset(meta_sk); +- return 1; ++ return -1; + } + } + break; +@@ -344,6 +348,17 @@ + sizeof(data_seq), csum_tcp); + + dss_csum_added = 1; /* Just do it once */ ++ } else if (mptcp_is_data_mpcapable(tmp) && !dss_csum_added) { ++ u32 offset = skb_transport_offset(tmp) + TCP_SKB_CB(tmp)->dss_off; ++ __be64 data_seq = htonll(tp->mptcp->map_data_seq); ++ __be32 rel_seq = htonl(tp->mptcp->map_subseq - tp->mptcp->rcv_isn); ++ ++ csum_tcp = csum_partial(&data_seq, sizeof(data_seq), csum_tcp); ++ csum_tcp = csum_partial(&rel_seq, sizeof(rel_seq), csum_tcp); ++ ++ csum_tcp = skb_checksum(tmp, offset, 4, csum_tcp); ++ ++ dss_csum_added = 1; + } + last = tmp; + iter++; +@@ -554,11 +569,12 @@ + * this segment, this path has to fallback to infinite or be torn down. + */ + if (!tp->mptcp->fully_established && !mptcp_is_data_seq(skb) && ++ !mptcp_is_data_mpcapable(skb) && + !tp->mptcp->mapping_present && !mpcb->infinite_mapping_rcv) { +- pr_debug("%s %#x will fallback - pi %d from %pS, seq %u\n", ++ pr_debug("%s %#x will fallback - pi %d from %pS, seq %u mptcp-flags %#x\n", + __func__, mpcb->mptcp_loc_token, + tp->mptcp->path_index, __builtin_return_address(0), +- TCP_SKB_CB(skb)->seq); ++ TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->mptcp_flags); + + if (!is_master_tp(tp)) { + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATASUB); +@@ -666,25 +682,36 @@ + return 0; + } + +- /* No mapping here? Exit - it is either already set or still on its way */ +- if (!mptcp_is_data_seq(skb)) { +- /* Too many packets without a mapping - this subflow is broken */ ++ if (!tp->mptcp->mapping_present && mptcp_is_data_mpcapable(skb)) { ++ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); ++ ++ sub_seq = 1 + tp->mptcp->rcv_isn; ++ data_seq = meta_tp->rcv_nxt; ++ data_len = get_unaligned_be16(ptr); ++ } else if (!mptcp_is_data_seq(skb)) { ++ /* No mapping here? ++ * Exit - it is either already set or still on its way ++ */ + if (!tp->mptcp->mapping_present && + tp->rcv_nxt - tp->copied_seq > 65536) { ++ /* Too many packets without a mapping, ++ * this subflow is broken ++ */ + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); + mptcp_send_reset(sk); + return 1; + } + + return 0; ++ } else { ++ /* Well, then the DSS-mapping is there. So, read it! */ ++ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); ++ ptr++; ++ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; ++ ptr++; ++ data_len = get_unaligned_be16(ptr); + } + +- ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); +- ptr++; +- sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; +- ptr++; +- data_len = get_unaligned_be16(ptr); +- + /* If it's an empty skb with DATA_FIN, sub_seq must get fixed. + * The draft sets it to 0, but we really would like to have the + * real value, to have an easy handling afterwards here in this +@@ -1397,7 +1424,7 @@ + } + + /* Handle the DATA_ACK */ +-static void mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) ++static int mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) + { + struct sock *meta_sk = mptcp_meta_sk(sk); + struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); +@@ -1425,7 +1452,7 @@ + * set by mptcp_clean_rtx_infinite. + */ + if (!(tcb->mptcp_flags & MPTCPHDR_ACK) && !tp->mpcb->infinite_mapping_snd) +- return; ++ return 0; + + if (unlikely(!tp->mptcp->fully_established) && + tp->mptcp->snt_isn + 1 != TCP_SKB_CB(skb)->ack_seq) +@@ -1439,7 +1466,7 @@ + * processing. + */ + if (meta_sk->sk_state == TCP_CLOSE) +- return; ++ return 0; + + /* Get the data_seq */ + if (mptcp_is_data_seq(skb)) { +@@ -1463,6 +1490,9 @@ + if (after(data_ack, meta_tp->snd_nxt)) + goto exit; + ++ /* First valid DATA_ACK, we can stop sending the special MP_CAPABLE */ ++ tp->mpcb->send_mptcpv1_mpcapable = 0; ++ + /*** Now, update the window - inspired by tcp_ack_update_window ***/ + nwin = ntohs(tcp_hdr(skb)->window); + +@@ -1520,14 +1550,19 @@ + meta_sk->sk_write_space(meta_sk); + } + +- if (meta_sk->sk_state != TCP_ESTABLISHED && +- mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len)) +- return; ++ if (meta_sk->sk_state != TCP_ESTABLISHED) { ++ int ret = mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len); ++ ++ if (ret < 0) ++ return 1; ++ else if (ret > 0) ++ return 0; ++ } + + exit: + mptcp_push_pending_frames(meta_sk); + +- return; ++ return 0; + + no_queue: + if (tcp_send_head(meta_sk)) +@@ -1535,7 +1570,7 @@ + + mptcp_push_pending_frames(meta_sk); + +- return; ++ return 0; + } + + void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk) +@@ -1604,6 +1639,7 @@ + struct tcp_sock *tp) + { + const struct mptcp_option *mp_opt = (struct mptcp_option *)ptr; ++ const struct tcphdr *th = tcp_hdr(skb); + + /* If the socket is mp-capable we would have a mopt. */ + if (!mopt) +@@ -1614,9 +1650,21 @@ + { + const struct mp_capable *mpcapable = (struct mp_capable *)ptr; + +- if (opsize != MPTCP_SUB_LEN_CAPABLE_SYN && +- opsize != MPTCP_SUB_LEN_CAPABLE_ACK) { +- mptcp_debug("%s: mp_capable: bad option size %d\n", ++ if (mpcapable->ver == MPTCP_VERSION_0 && ++ ((th->syn && opsize != MPTCP_SUB_LEN_CAPABLE_SYN) || ++ (!th->syn && th->ack && opsize != MPTCP_SUB_LEN_CAPABLE_ACK))) { ++ mptcp_debug("%s: mp_capable v0: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ if (mpcapable->ver == MPTCP_VERSION_1 && ++ ((th->syn && !th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_SYN) || ++ (th->syn && th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_SYNACK) || ++ (!th->syn && th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_ACK && ++ opsize != MPTCPV1_SUB_LEN_CAPABLE_DATA && ++ opsize != MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM))) { ++ mptcp_debug("%s: mp_capable v1: bad option size %d\n", + __func__, opsize); + break; + } +@@ -1640,10 +1688,38 @@ + mopt->saw_mpc = 1; + mopt->dss_csum = sysctl_mptcp_checksum || mpcapable->a; + +- if (opsize >= MPTCP_SUB_LEN_CAPABLE_SYN) +- mopt->mptcp_sender_key = mpcapable->sender_key; +- if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) +- mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ if (mpcapable->ver == MPTCP_VERSION_0) { ++ if (opsize == MPTCP_SUB_LEN_CAPABLE_SYN) ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ ++ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) { ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ } ++ } else if (mpcapable->ver == MPTCP_VERSION_1) { ++ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_SYNACK) ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ ++ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_ACK) { ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ } ++ ++ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA || ++ opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM) { ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ ++ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_MPC_DATA; ++ ++ ptr += sizeof(struct mp_capable); ++ TCP_SKB_CB(skb)->dss_off = (ptr - skb_transport_header(skb)); ++ ++ /* Is a check-sum present? */ ++ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM) ++ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_DSS_CSUM; ++ } ++ } + + mopt->mptcp_ver = mpcapable->ver; + break; +@@ -1917,12 +1993,11 @@ + } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { + msg_parts = 3; + } +- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, +- (u8 *)no_key, +- (u32 *)hash_mac_check, msg_parts, +- 1, (u8 *)&mpadd->addr_id, +- 4, (u8 *)&mpadd->u.v4.addr.s_addr, +- 2, (u8 *)&mpadd->u.v4.port); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)no_key, (u32 *)hash_mac_check, msg_parts, ++ 1, (u8 *)&mpadd->addr_id, ++ 4, (u8 *)&mpadd->u.v4.addr.s_addr, ++ 2, (u8 *)&mpadd->u.v4.port); + if (memcmp(hash_mac_check, recv_hmac, 8) != 0) + /* ADD_ADDR2 discarded */ + return; +@@ -1952,12 +2027,11 @@ + } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { + msg_parts = 3; + } +- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, +- (u8 *)no_key, +- (u32 *)hash_mac_check, msg_parts, +- 1, (u8 *)&mpadd->addr_id, +- 16, (u8 *)&mpadd->u.v6.addr.s6_addr, +- 2, (u8 *)&mpadd->u.v6.port); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)no_key, (u32 *)hash_mac_check, msg_parts, ++ 1, (u8 *)&mpadd->addr_id, ++ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, ++ 2, (u8 *)&mpadd->u.v6.port); + if (memcmp(hash_mac_check, recv_hmac, 8) != 0) + /* ADD_ADDR2 discarded */ + return; +@@ -2115,6 +2189,10 @@ + if (sk->sk_state == TCP_RST_WAIT && !th->rst) + return true; + ++ if (mopt->saw_mpc && !tp->mpcb->rem_key_set) ++ mptcp_initialize_recv_vars(mptcp_meta_tp(tp), tp->mpcb, ++ mopt->mptcp_sender_key); ++ + if (unlikely(mopt->mp_fail)) + mptcp_mp_fail_rcvd(sk, th); + +@@ -2122,7 +2200,8 @@ + * If a checksum is not present when its use has been negotiated, the + * receiver MUST close the subflow with a RST as it is considered broken. + */ +- if (mptcp_is_data_seq(skb) && tp->mpcb->dss_csum && ++ if ((mptcp_is_data_seq(skb) || mptcp_is_data_mpcapable(skb)) && ++ tp->mpcb->dss_csum && + !(TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_DSS_CSUM)) { + mptcp_send_reset(sk); + return true; +@@ -2171,7 +2250,8 @@ + mopt->saw_low_prio = 0; + } + +- mptcp_data_ack(sk, skb); ++ if (mptcp_data_ack(sk, skb)) ++ return true; + + mptcp_path_array_check(mptcp_meta_sk(sk)); + /* Socket may have been mp_killed by a REMOVE_ADDR */ +@@ -2297,11 +2377,10 @@ + u8 hash_mac_check[20]; + struct mptcp_cb *mpcb = tp->mpcb; + +- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, +- (u8 *)&mpcb->mptcp_loc_key, +- (u32 *)hash_mac_check, 2, +- 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, +- 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)&mpcb->mptcp_loc_key, (u32 *)hash_mac_check, 2, ++ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, ++ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); + if (memcmp(hash_mac_check, + (char *)&tp->mptcp->rx_opt.mptcp_recv_tmac, 8)) { + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); +@@ -2315,11 +2394,11 @@ + tp->mptcp->pre_established = 1; + tp->mptcp->rcv_low_prio = tp->mptcp->rx_opt.low_prio; + +- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, +- (u8 *)&mpcb->mptcp_rem_key, +- (u32 *)&tp->mptcp->sender_mac[0], 2, +- 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, +- 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)&mpcb->mptcp_rem_key, ++ (u32 *)&tp->mptcp->sender_mac[0], 2, ++ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, ++ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); + + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); + } else if (mopt->saw_mpc) { +@@ -2329,8 +2408,13 @@ + if (mopt->mptcp_ver > tcp_sk(sk)->mptcp_ver) + /* TODO Consider adding new MPTCP_INC_STATS entry */ + goto fallback; ++ if (tcp_sk(sk)->mptcp_ver == MPTCP_VERSION_1 && ++ mopt->mptcp_ver < MPTCP_VERSION_1) ++ /* TODO Consider adding new MPTCP_INC_STATS entry */ ++ /* TODO - record this in the cache - use v0 next time */ ++ goto fallback; + +- if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, ++ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, 1, + mopt->mptcp_ver, + ntohs(tcp_hdr(skb)->window))) + return 2; +@@ -2358,6 +2442,9 @@ + if (tp->mpcb->dss_csum) + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMENABLED); + ++ if (tp->mpcb->mptcp_ver >= MPTCP_VERSION_1) ++ tp->mpcb->send_mptcpv1_mpcapable = 1; ++ + tp->mptcp->include_mpc = 1; + + /* Ensure that fastopen is handled at the meta-level. */ +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c mptcp/net/mptcp/mptcp_ipv4.c +--- mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_ipv4.c 2020-05-14 15:15:27.158152059 +0200 +@@ -106,6 +106,9 @@ + int loc_id; + bool low_prio = false; + ++ if (!mpcb->rem_key_set) ++ return -1; ++ + /* We need to do this as early as possible. Because, if we fail later + * (e.g., get_local_id), then reqsk_free tries to remove the + * request-socket from the htb in mptcp_hash_request_remove as pprev +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c mptcp/net/mptcp/mptcp_ipv6.c +--- mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_ipv6.c 2020-05-14 15:15:27.170151859 +0200 +@@ -135,6 +135,9 @@ + int loc_id; + bool low_prio = false; + ++ if (!mpcb->rem_key_set) ++ return -1; ++ + /* We need to do this as early as possible. Because, if we fail later + * (e.g., get_local_id), then reqsk_free tries to remove the + * request-socket from the htb in mptcp_hash_request_remove as pprev +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_output.c mptcp/net/mptcp/mptcp_output.c --- mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_output.c 2020-05-03 12:20:25.183226240 +0200 -@@ -851,10 +851,7 @@ ++++ mptcp/net/mptcp/mptcp_output.c 2020-05-14 15:15:27.170151859 +0200 +@@ -479,30 +479,78 @@ + ptr += mptcp_write_dss_mapping(tp, skb, ptr); + } + ++/* Write the MP_CAPABLE with data-option */ ++static int mptcp_write_mpcapable_data(const struct tcp_sock *tp, ++ struct sk_buff *skb, ++ __be32 *ptr) ++{ ++ struct mp_capable *mpc = (struct mp_capable *)ptr; ++ u8 length; ++ ++ if (tp->mpcb->dss_csum) ++ length = MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM; ++ else ++ length = MPTCPV1_SUB_LEN_CAPABLE_DATA; ++ ++ mpc->kind = TCPOPT_MPTCP; ++ mpc->len = length; ++ mpc->sub = MPTCP_SUB_CAPABLE; ++ mpc->ver = MPTCP_VERSION_1; ++ mpc->a = tp->mpcb->dss_csum; ++ mpc->b = 0; ++ mpc->rsv = 0; ++ mpc->h = 1; ++ ++ ptr++; ++ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); ++ ++ mpc->sender_key = tp->mpcb->mptcp_loc_key; ++ mpc->receiver_key = tp->mpcb->mptcp_rem_key; ++ ++ /* dss is in a union with inet_skb_parm and ++ * the IP layer expects zeroed IPCB fields. ++ */ ++ memset(TCP_SKB_CB(skb)->dss, 0, mptcp_dss_len); ++ ++ return MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN / sizeof(*ptr); ++} ++ + /* Write the saved DSS mapping to the header */ + static int mptcp_write_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb, + __be32 *ptr) + { ++ int length; + __be32 *start = ptr; + +- memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); ++ if (tp->mpcb->rem_key_set) { ++ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); ++ ++ /* update the data_ack */ ++ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); ++ ++ length = mptcp_dss_len / sizeof(*ptr); ++ } else { ++ memcpy(ptr, TCP_SKB_CB(skb)->dss, MPTCP_SUB_LEN_DSS_ALIGN); + +- /* update the data_ack */ +- start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); ++ ptr++; ++ memcpy(ptr, TCP_SKB_CB(skb)->dss + 2, MPTCP_SUB_LEN_SEQ_ALIGN); ++ ++ length = (MPTCP_SUB_LEN_DSS_ALIGN + MPTCP_SUB_LEN_SEQ_ALIGN) / sizeof(*ptr); ++ } + + /* dss is in a union with inet_skb_parm and + * the IP layer expects zeroed IPCB fields. + */ + memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); + +- return mptcp_dss_len/sizeof(*ptr); ++ return length; + } + + static bool mptcp_skb_entail(struct sock *sk, struct sk_buff *skb, int reinject) + { + struct tcp_sock *tp = tcp_sk(sk); + const struct sock *meta_sk = mptcp_meta_sk(sk); +- const struct mptcp_cb *mpcb = tp->mpcb; ++ struct mptcp_cb *mpcb = tp->mpcb; + struct tcp_skb_cb *tcb; + struct sk_buff *subskb = NULL; + +@@ -544,6 +592,11 @@ + + mptcp_save_dss_data_seq(tp, subskb); + ++ if (mpcb->send_mptcpv1_mpcapable) { ++ TCP_SKB_CB(subskb)->mptcp_flags |= MPTCPHDR_MPC_DATA; ++ mpcb->send_mptcpv1_mpcapable = 0; ++ } ++ + tcb->seq = tp->write_seq; + + /* Take into account seg len */ +@@ -851,10 +904,7 @@ if (!mptcp_skb_entail(subsk, skb, reinject)) break; @@ -76,7 +1196,7 @@ diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_output.c mptcp/net/mptcp/mptcp_outp if (reinject <= 0) tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); meta_tp->lsndtime = tcp_jiffies32; -@@ -886,14 +883,12 @@ +@@ -886,14 +936,12 @@ if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) continue; @@ -96,9 +1216,567 @@ diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_output.c mptcp/net/mptcp/mptcp_outp } return !meta_tp->packets_out && tcp_send_head(meta_sk); -diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c mptcp/net/mptcp/mptcp_sched.c +@@ -988,8 +1036,13 @@ + opts->options |= OPTION_MPTCP; + if (is_master_tp(tp)) { + opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYN; +- opts->mptcp_ver = tcp_sk(sk)->mptcp_ver; +- *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ opts->mptcp_ver = tp->mptcp_ver; ++ ++ if (tp->mptcp_ver >= MPTCP_VERSION_1) ++ *remaining -= MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN; ++ else ++ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ + opts->mp_capable.sender_key = tp->mptcp_loc_key; + opts->dss_csum = !!sysctl_mptcp_checksum; + } else { +@@ -1017,7 +1070,11 @@ + opts->mptcp_ver = mtreq->mptcp_ver; + opts->mp_capable.sender_key = mtreq->mptcp_loc_key; + opts->dss_csum = !!sysctl_mptcp_checksum || mtreq->dss_csum; +- *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ if (mtreq->mptcp_ver >= MPTCP_VERSION_1) { ++ *remaining -= MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN; ++ } else { ++ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ } + } else { + opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYNACK; + opts->mp_join_syns.sender_truncated_mac = +@@ -1080,7 +1137,12 @@ + opts->options |= OPTION_MPTCP; + opts->mptcp_options |= OPTION_MP_CAPABLE | + OPTION_TYPE_ACK; +- *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; ++ ++ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) ++ *size += MPTCPV1_SUB_LEN_CAPABLE_ACK_ALIGN; ++ else ++ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; ++ + opts->mptcp_ver = mpcb->mptcp_ver; + opts->mp_capable.sender_key = mpcb->mptcp_loc_key; + opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; +@@ -1111,14 +1173,20 @@ + /* If !skb, we come from tcp_current_mss and thus we always + * assume that the DSS-option will be set for the data-packet. + */ +- if (skb && !mptcp_is_data_seq(skb)) { ++ if (skb && !mptcp_is_data_seq(skb) && mpcb->rem_key_set) { + *size += MPTCP_SUB_LEN_ACK_ALIGN; ++ } else if ((skb && mptcp_is_data_mpcapable(skb)) || ++ (!skb && tp->mpcb->send_mptcpv1_mpcapable)) { ++ *size += MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN; + } else { + /* Doesn't matter, if csum included or not. It will be + * either 10 or 12, and thus aligned = 12 + */ +- *size += MPTCP_SUB_LEN_ACK_ALIGN + +- MPTCP_SUB_LEN_SEQ_ALIGN; ++ if (mpcb->rem_key_set) ++ *size += MPTCP_SUB_LEN_ACK_ALIGN + ++ MPTCP_SUB_LEN_SEQ_ALIGN; ++ else ++ *size += MPTCP_SUB_LEN_SEQ_ALIGN; + } + + *size += MPTCP_SUB_LEN_DSS_ALIGN; +@@ -1171,18 +1239,36 @@ + + mpc->kind = TCPOPT_MPTCP; + +- if ((OPTION_TYPE_SYN & opts->mptcp_options) || +- (OPTION_TYPE_SYNACK & opts->mptcp_options)) { +- mpc->sender_key = opts->mp_capable.sender_key; +- mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; ++ if (OPTION_TYPE_SYN & opts->mptcp_options) { + mpc->ver = opts->mptcp_ver; +- ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; +- } else if (OPTION_TYPE_ACK & opts->mptcp_options) { ++ ++ if (mpc->ver >= MPTCP_VERSION_1) { ++ mpc->len = MPTCPV1_SUB_LEN_CAPABLE_SYN; ++ ptr += MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; ++ } else { ++ mpc->sender_key = opts->mp_capable.sender_key; ++ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; ++ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; ++ } ++ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { ++ mpc->ver = opts->mptcp_ver; ++ ++ if (mpc->ver >= MPTCP_VERSION_1) { ++ mpc->len = MPTCPV1_SUB_LEN_CAPABLE_SYNACK; ++ ptr += MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN >> 2; ++ } else { ++ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; ++ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; ++ } ++ + mpc->sender_key = opts->mp_capable.sender_key; +- mpc->receiver_key = opts->mp_capable.receiver_key; ++ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { + mpc->len = MPTCP_SUB_LEN_CAPABLE_ACK; + mpc->ver = opts->mptcp_ver; + ptr += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN >> 2; ++ ++ mpc->sender_key = opts->mp_capable.sender_key; ++ mpc->receiver_key = opts->mp_capable.receiver_key; + } + + mpc->sub = MPTCP_SUB_CAPABLE; +@@ -1312,8 +1398,10 @@ + } + + if (OPTION_DATA_ACK & opts->mptcp_options) { +- if (!mptcp_is_data_seq(skb)) ++ if (!mptcp_is_data_seq(skb) && tp->mpcb->rem_key_set) + ptr += mptcp_write_dss_data_ack(tp, skb, ptr); ++ else if (mptcp_is_data_mpcapable(skb)) ++ ptr += mptcp_write_mpcapable_data(tp, skb, ptr); + else + ptr += mptcp_write_dss_data_seq(tp, skb, ptr); + } +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c mptcp/net/mptcp/mptcp_redundant.c +--- mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_redundant.c 2020-05-14 15:11:23.662202401 +0200 +@@ -187,7 +187,9 @@ + { + struct tcp_sock *meta_tp = tcp_sk(meta_sk); + +- if (red_p->skb && !after(red_p->skb_end_seq, meta_tp->snd_una)) ++ if (red_p->skb && ++ (!after(red_p->skb_end_seq, meta_tp->snd_una) || ++ after(red_p->skb_end_seq, meta_tp->snd_nxt))) + red_p->skb = NULL; + } + +@@ -197,9 +199,13 @@ + struct sock *meta_sk) + { + struct sk_buff *skb; +- +- if (!previous) ++ if (!previous){ ++ if (tcp_rtx_queue_head(meta_sk)){ ++ return tcp_rtx_queue_head(meta_sk); ++ } + return skb_peek(queue); ++ } ++ + + /* sk_data->skb stores the last scheduled packet for this subflow. + * If sk_data->skb was scheduled but not sent (e.g., due to nagle), +@@ -246,7 +252,8 @@ + *limit = 0; + + if (skb_queue_empty(&mpcb->reinject_queue) && +- skb_queue_empty(&meta_sk->sk_write_queue)) ++ skb_queue_empty(&meta_sk->sk_write_queue) && ++ tcp_rtx_queue_empty(meta_sk)) + /* Nothing to send */ + return NULL; + +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c.orig mptcp/net/mptcp/mptcp_redundant.c.orig +--- mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp/net/mptcp/mptcp_redundant.c.orig 2020-05-11 09:39:24.476475868 +0200 +@@ -0,0 +1,391 @@ ++/* ++ * MPTCP Scheduler to reduce latency and jitter. ++ * ++ * This scheduler sends all packets redundantly on all available subflows. ++ * ++ * Initial Design & Implementation: ++ * Tobias Erbshaeusser ++ * Alexander Froemmgen ++ * ++ * Initial corrections & modifications: ++ * Christian Pinedo ++ * Igor Lopez ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++/* Struct to store the data of a single subflow */ ++struct redsched_priv { ++ /* The skb or NULL */ ++ struct sk_buff *skb; ++ /* End sequence number of the skb. This number should be checked ++ * to be valid before the skb field is used ++ */ ++ u32 skb_end_seq; ++}; ++ ++/* Struct to store the data of the control block */ ++struct redsched_cb { ++ /* The next subflow where a skb should be sent or NULL */ ++ struct tcp_sock *next_subflow; ++}; ++ ++/* Returns the socket data from a given subflow socket */ ++static struct redsched_priv *redsched_get_priv(struct tcp_sock *tp) ++{ ++ return (struct redsched_priv *)&tp->mptcp->mptcp_sched[0]; ++} ++ ++/* Returns the control block data from a given meta socket */ ++static struct redsched_cb *redsched_get_cb(struct tcp_sock *tp) ++{ ++ return (struct redsched_cb *)&tp->mpcb->mptcp_sched[0]; ++} ++ ++static bool redsched_get_active_valid_sks(struct sock *meta_sk) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct mptcp_tcp_sock *mptcp; ++ int active_valid_sks = 0; ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if (subflow_is_active((struct tcp_sock *)sk) && ++ !mptcp_is_def_unavailable(sk)) ++ active_valid_sks++; ++ } ++ ++ return active_valid_sks; ++} ++ ++static bool redsched_use_subflow(struct sock *meta_sk, ++ int active_valid_sks, ++ struct tcp_sock *tp, ++ struct sk_buff *skb) ++{ ++ if (!skb || !mptcp_is_available((struct sock *)tp, skb, false)) ++ return false; ++ ++ if (TCP_SKB_CB(skb)->path_mask != 0) ++ return subflow_is_active(tp); ++ ++ if (TCP_SKB_CB(skb)->path_mask == 0) { ++ if (active_valid_sks == -1) ++ active_valid_sks = redsched_get_active_valid_sks(meta_sk); ++ ++ if (subflow_is_backup(tp) && active_valid_sks > 0) ++ return false; ++ else ++ return true; ++ } ++ ++ return false; ++} ++ ++#define mptcp_entry_next_rcu(__mptcp) \ ++ hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ ++ &(__mptcp)->node)), struct mptcp_tcp_sock, node) ++ ++static void redsched_update_next_subflow(struct tcp_sock *tp, ++ struct redsched_cb *red_cb) ++{ ++ struct mptcp_tcp_sock *mptcp = mptcp_entry_next_rcu(tp->mptcp); ++ ++ if (mptcp) ++ red_cb->next_subflow = mptcp->tp; ++ else ++ red_cb->next_subflow = NULL; ++} ++ ++static struct sock *red_get_available_subflow(struct sock *meta_sk, ++ struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); ++ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; ++ struct mptcp_tcp_sock *mptcp; ++ int found = 0; ++ ++ /* Answer data_fin on same subflow */ ++ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && ++ skb && mptcp_is_data_fin(skb)) { ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct sock *sk = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(sk)->mptcp->path_index == ++ mpcb->dfin_path_index && ++ mptcp_is_available(sk, skb, zero_wnd_test)) ++ return sk; ++ } ++ } ++ ++ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { ++ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), ++ struct mptcp_tcp_sock, node)->tp; ++ } ++ tp = first_tp; ++ ++ /* still NULL (no subflow in conn_list?) */ ++ if (!first_tp) ++ return NULL; ++ ++ /* Search for a subflow to send it. ++ * ++ * We want to pick a subflow that is after 'first_tp' in the list of subflows. ++ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up ++ * to the subflow 'tp' and then checks whether any one of the remaining ++ * ones is eligible to send. ++ * The second mptcp_for_each-sub()-loop is then iterating from the ++ * beginning of the list up to 'first_tp'. ++ */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ /* We go up to the subflow 'tp' and start from there */ ++ if (tp == mptcp->tp) ++ found = 1; ++ ++ if (!found) ++ continue; ++ tp = mptcp->tp; ++ ++ if (mptcp_is_available((struct sock *)tp, skb, ++ zero_wnd_test)) { ++ redsched_update_next_subflow(tp, red_cb); ++ return (struct sock *)tp; ++ } ++ } ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ tp = mptcp->tp; ++ ++ if (tp == first_tp) ++ break; ++ ++ if (mptcp_is_available((struct sock *)tp, skb, ++ zero_wnd_test)) { ++ redsched_update_next_subflow(tp, red_cb); ++ return (struct sock *)tp; ++ } ++ } ++ ++ /* No space */ ++ return NULL; ++} ++ ++/* Corrects the stored skb pointers if they are invalid */ ++static void redsched_correct_skb_pointers(struct sock *meta_sk, ++ struct redsched_priv *red_p) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ ++ if (red_p->skb && ++ (!after(red_p->skb_end_seq, meta_tp->snd_una) || ++ after(red_p->skb_end_seq, meta_tp->snd_nxt))) ++ red_p->skb = NULL; ++} ++ ++/* Returns the next skb from the queue */ ++static struct sk_buff *redsched_next_skb_from_queue(struct sk_buff_head *queue, ++ struct sk_buff *previous, ++ struct sock *meta_sk) ++{ ++ struct sk_buff *skb; ++ ++ if (!previous) ++ return skb_peek(queue); ++ ++ /* sk_data->skb stores the last scheduled packet for this subflow. ++ * If sk_data->skb was scheduled but not sent (e.g., due to nagle), ++ * we have to schedule it again. ++ * ++ * For the redundant scheduler, there are two cases: ++ * 1. sk_data->skb was not sent on another subflow: ++ * we have to schedule it again to ensure that we do not ++ * skip this packet. ++ * 2. sk_data->skb was already sent on another subflow: ++ * with regard to the redundant semantic, we have to ++ * schedule it again. However, we keep it simple and ignore it, ++ * as it was already sent by another subflow. ++ * This might be changed in the future. ++ * ++ * For case 1, send_head is equal previous, as only a single ++ * packet can be skipped. ++ */ ++ if (tcp_send_head(meta_sk) == previous) ++ return tcp_send_head(meta_sk); ++ ++ skb = skb_rb_next(previous); ++ if (skb) ++ return skb; ++ ++ return tcp_send_head(meta_sk); ++} ++ ++static struct sk_buff *mptcp_red_next_segment(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit) ++{ ++ struct tcp_sock *meta_tp = tcp_sk(meta_sk); ++ struct mptcp_cb *mpcb = meta_tp->mpcb; ++ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); ++ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; ++ struct mptcp_tcp_sock *mptcp; ++ int active_valid_sks = -1; ++ struct sk_buff *skb; ++ int found = 0; ++ ++ /* As we set it, we have to reset it as well. */ ++ *limit = 0; ++ ++ if (skb_queue_empty(&mpcb->reinject_queue) && ++ skb_queue_empty(&meta_sk->sk_write_queue)) ++ /* Nothing to send */ ++ return NULL; ++ ++ /* First try reinjections */ ++ skb = skb_peek(&mpcb->reinject_queue); ++ if (skb) { ++ *subsk = get_available_subflow(meta_sk, skb, false); ++ if (!*subsk) ++ return NULL; ++ *reinject = 1; ++ return skb; ++ } ++ ++ /* Then try indistinctly redundant and normal skbs */ ++ ++ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { ++ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), ++ struct mptcp_tcp_sock, node)->tp; ++ } ++ ++ /* still NULL (no subflow in conn_list?) */ ++ if (!first_tp) ++ return NULL; ++ ++ tp = first_tp; ++ ++ *reinject = 0; ++ active_valid_sks = redsched_get_active_valid_sks(meta_sk); ++ ++ /* We want to pick a subflow that is after 'first_tp' in the list of subflows. ++ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up ++ * to the subflow 'tp' and then checks whether any one of the remaining ++ * ones can send a segment. ++ * The second mptcp_for_each-sub()-loop is then iterating from the ++ * beginning of the list up to 'first_tp'. ++ */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct redsched_priv *red_p; ++ ++ if (tp == mptcp->tp) ++ found = 1; ++ ++ if (!found) ++ continue; ++ ++ tp = mptcp->tp; ++ ++ /* Correct the skb pointers of the current subflow */ ++ red_p = redsched_get_priv(tp); ++ redsched_correct_skb_pointers(meta_sk, red_p); ++ ++ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, ++ red_p->skb, meta_sk); ++ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, ++ skb)) { ++ red_p->skb = skb; ++ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; ++ redsched_update_next_subflow(tp, red_cb); ++ *subsk = (struct sock *)tp; ++ ++ if (TCP_SKB_CB(skb)->path_mask) ++ *reinject = -1; ++ return skb; ++ } ++ } ++ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ struct redsched_priv *red_p; ++ ++ tp = mptcp->tp; ++ ++ if (tp == first_tp) ++ break; ++ ++ /* Correct the skb pointers of the current subflow */ ++ red_p = redsched_get_priv(tp); ++ redsched_correct_skb_pointers(meta_sk, red_p); ++ ++ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, ++ red_p->skb, meta_sk); ++ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, ++ skb)) { ++ red_p->skb = skb; ++ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; ++ redsched_update_next_subflow(tp, red_cb); ++ *subsk = (struct sock *)tp; ++ ++ if (TCP_SKB_CB(skb)->path_mask) ++ *reinject = -1; ++ return skb; ++ } ++ } ++ ++ /* Nothing to send */ ++ return NULL; ++} ++ ++static void redsched_release(struct sock *sk) ++{ ++ struct tcp_sock *tp = tcp_sk(sk); ++ struct redsched_cb *red_cb = redsched_get_cb(tp); ++ ++ /* Check if the next subflow would be the released one. If yes correct ++ * the pointer ++ */ ++ if (red_cb->next_subflow == tp) ++ redsched_update_next_subflow(tp, red_cb); ++} ++ ++static struct mptcp_sched_ops mptcp_sched_red = { ++ .get_subflow = red_get_available_subflow, ++ .next_segment = mptcp_red_next_segment, ++ .release = redsched_release, ++ .name = "redundant", ++ .owner = THIS_MODULE, ++}; ++ ++static int __init red_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct redsched_priv) > MPTCP_SCHED_SIZE); ++ BUILD_BUG_ON(sizeof(struct redsched_cb) > MPTCP_SCHED_DATA_SIZE); ++ ++ if (mptcp_register_scheduler(&mptcp_sched_red)) ++ return -1; ++ ++ return 0; ++} ++ ++static void red_unregister(void) ++{ ++ mptcp_unregister_scheduler(&mptcp_sched_red); ++} ++ ++module_init(red_register); ++module_exit(red_unregister); ++ ++MODULE_AUTHOR("Tobias Erbshaeusser, Alexander Froemmgen"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("REDUNDANT MPTCP"); ++MODULE_VERSION("0.90"); +diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c mptcp/net/mptcp/mptcp_sched.c --- mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_sched.c 2020-05-03 12:20:31.843115714 +0200 ++++ mptcp/net/mptcp/mptcp_sched.c 2020-05-11 09:40:13.463584360 +0200 @@ -76,7 +76,7 @@ */ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; @@ -108,20 +1786,21 @@ diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c mptcp/net/mptcp/mptcp_sched return true; if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -@@ -391,10 +391,10 @@ +@@ -391,10 +391,11 @@ unsigned int *limit) { struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); - unsigned int mss_now; + unsigned int mss_now, in_flight_space; ++ int remaining_in_flight_space; ++ u32 max_len, max_segs, window; struct tcp_sock *subtp; u16 gso_max_segs; - u32 max_len, max_segs, window, needed; -+ u32 max_len, max_segs, window; /* As we set it, we have to reset it as well. */ *limit = 0; -@@ -424,9 +424,6 @@ +@@ -424,9 +425,6 @@ /* The following is similar to tcp_mss_split_point, but * we do not care about nagle, because we will anyways * use TCP_NAGLE_PUSH, which overrides this. @@ -131,7 +1810,7 @@ diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c mptcp/net/mptcp/mptcp_sched */ gso_max_segs = (*subsk)->sk_gso_max_segs; -@@ -436,16 +433,29 @@ +@@ -436,16 +434,30 @@ if (!max_segs) return NULL; @@ -147,18 +1826,19 @@ diff -aurN mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c mptcp/net/mptcp/mptcp_sched - /* Take max_win, which is actually the cwnd/gso-size */ - *limit = max_len; + in_flight_space = (subtp->snd_cwnd - tcp_packets_in_flight(subtp)) * mss_now; ++ remaining_in_flight_space = (int)in_flight_space - (subtp->write_seq - subtp->snd_nxt); + -+ if ((int)in_flight_space - (subtp->write_seq - subtp->snd_nxt) <= 0) -+ WARN(1, "in_flight %u cwnd %u wseq %u snxt %u mss_now %u cache %u", -+ tcp_packets_in_flight(subtp), subtp->snd_cwnd, -+ subtp->write_seq, subtp->snd_nxt, mss_now, subtp->mss_cache); ++ if (remaining_in_flight_space <= 0) ++ WARN_ONCE(1, "in_flight %u cwnd %u wseq %u snxt %u mss_now %u cache %u", ++ tcp_packets_in_flight(subtp), subtp->snd_cwnd, ++ subtp->write_seq, subtp->snd_nxt, mss_now, subtp->mss_cache); else - /* Or, take the window */ - *limit = needed; + /* max_len now fits exactly in the write-queue, taking into + * account what was already queued. + */ -+ max_len = min(max_len, in_flight_space - (subtp->write_seq - subtp->snd_nxt)); ++ max_len = min_t(u32, max_len, remaining_in_flight_space); + + window = tcp_wnd_end(subtp) - subtp->write_seq; + From fbe0ae9b2431c90da6b2521f7737e659c90cec64 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 14 May 2020 17:35:11 +0200 Subject: [PATCH 48/76] Fix https://github.com/Ysurac/openmptcprouter/issues/1025 --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 6d39dbad..7e5d40ef 100755 --- a/build.sh +++ b/build.sh @@ -215,7 +215,7 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/package-too-long.patch; then fi echo "Done" -echo "Downlaod via IPv4" +echo "Download via IPv4" if ! patch -Rf -N -p1 -s --dry-run < ../../patches/download-ipv4.patch; then patch -N -p1 -s < ../../patches/download-ipv4.patch fi From a7609e7508b9fd66b0c6edc0f0c26c82ce1b7d3b Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 16 May 2020 20:46:50 +0200 Subject: [PATCH 49/76] Force local libwebp for WRTX --- build.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sh b/build.sh index 7e5d40ef..01c1d717 100755 --- a/build.sh +++ b/build.sh @@ -253,6 +253,8 @@ fi # Remove patch that can make BPI-R2 slow rm -rf target/linux/mediatek/patches-4.14/0027-*.patch +rm -rf feeds/packages/libs/libwebp + echo "Update feeds index" cp .config .config.keep scripts/feeds clean From b28a91a433f9cb9856d8240abf05eee29166bf7a Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 20 May 2020 17:45:18 +0200 Subject: [PATCH 50/76] Update MPTCP patch --- .../generic/hack-5.4/690-mptcp_trunk.patch | 1018 ++++++--- .../generic/hack-5.4/693-mptcp-fixes.patch | 1851 ----------------- 2 files changed, 673 insertions(+), 2196 deletions(-) delete mode 100644 root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index d429ab22..d6915244 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -1,6 +1,6 @@ diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt --- linux-5.4/Documentation/networking/ip-sysctl.txt 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-05-16 10:39:52.000000000 +0200 @@ -818,6 +818,18 @@ Default: 0 (disabled) @@ -22,7 +22,7 @@ diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Do udp_l3mdev_accept - BOOLEAN diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c --- linux-5.4/drivers/infiniband/hw/cxgb4/cm.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-05-16 10:39:52.000000000 +0200 @@ -3946,7 +3946,7 @@ */ memset(&tmp_opt, 0, sizeof(tmp_opt)); @@ -34,7 +34,7 @@ diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/ memset(req, 0, sizeof(*req)); diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbuff.h --- linux-5.4/include/linux/skbuff.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-05-16 10:39:52.000000000 +0200 @@ -717,7 +717,7 @@ * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. @@ -46,7 +46,7 @@ diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbu struct { diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h --- linux-5.4/include/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-05-16 10:39:52.000000000 +0200 @@ -54,7 +54,7 @@ /* TCP Fast Open */ #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ @@ -205,7 +205,7 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/inet_common.h --- linux-5.4/include/net/inet_common.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-05-16 10:39:52.000000000 +0200 @@ -2,6 +2,7 @@ #ifndef _INET_COMMON_H #define _INET_COMMON_H @@ -225,7 +225,7 @@ diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/ine int addr_len, int flags); diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/include/net/inet_connection_sock.h --- linux-5.4/include/net/inet_connection_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-05-16 10:39:52.000000000 +0200 @@ -25,6 +25,7 @@ struct inet_bind_bucket; @@ -236,7 +236,7 @@ diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/includ * Pointers to address related TCP functions diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_sock.h --- linux-5.4/include/net/inet_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-05-16 10:39:52.000000000 +0200 @@ -79,7 +79,7 @@ #define ireq_state req.__req_common.skc_state #define ireq_family req.__req_common.skc_family @@ -257,8 +257,8 @@ diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_ union { diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h --- linux-5.4/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,1497 @@ ++++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,1519 @@ +/* + * MPTCP implementation + * @@ -363,7 +363,8 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + + u8 loc_id; + u8 rem_id; /* Address-id in the MP_JOIN */ -+ u8 dss_csum:1, ++ u16 dss_csum:1, ++ rem_key_set:1, + is_sub:1, /* Is this a new subflow? */ + low_prio:1, /* Interface set to low-prio? */ + rcv_low_prio:1, @@ -501,7 +502,6 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + struct module *owner; +}; + -+#define MPTCP_SCHED_NAME_MAX 16 +struct mptcp_sched_ops { + struct list_head list; + @@ -533,6 +533,8 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + u32 rcv_high_order[2]; + + u16 send_infinite_mapping:1, ++ send_mptcpv1_mpcapable:1, ++ rem_key_set:1, + in_time_wait:1, + list_rcvd:1, /* XXX TO REMOVE */ + addr_signal:1, /* Path-manager wants us to call addr_signal */ @@ -615,6 +617,16 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +#define MPTCP_SUB_LEN_CAPABLE_ACK 20 +#define MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN 20 + ++#define MPTCPV1_SUB_LEN_CAPABLE_SYN 4 ++#define MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN 4 ++#define MPTCPV1_SUB_LEN_CAPABLE_SYNACK 12 ++#define MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN 12 ++#define MPTCPV1_SUB_LEN_CAPABLE_ACK 20 ++#define MPTCPV1_SUB_LEN_CAPABLE_ACK_ALIGN 20 ++#define MPTCPV1_SUB_LEN_CAPABLE_DATA 22 ++#define MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM 22 ++#define MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN 24 ++ +#define MPTCP_SUB_JOIN 1 +#define MPTCP_SUB_LEN_JOIN_SYN 12 +#define MPTCP_SUB_LEN_JOIN_SYN_ALIGN 12 @@ -711,14 +723,15 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +#define MPTCPHDR_SEQ 0x01 /* DSS.M option is present */ +#define MPTCPHDR_FIN 0x02 /* DSS.F option is present */ +#define MPTCPHDR_SEQ64_INDEX 0x04 /* index of seq in mpcb->snd_high_order */ ++#define MPTCPHDR_MPC_DATA 0x08 +/* MPTCP flags: RX only */ -+#define MPTCPHDR_ACK 0x08 -+#define MPTCPHDR_SEQ64_SET 0x10 /* Did we received a 64-bit seq number? */ -+#define MPTCPHDR_SEQ64_OFO 0x20 /* Is it not in our circular array? */ -+#define MPTCPHDR_DSS_CSUM 0x40 ++#define MPTCPHDR_ACK 0x10 ++#define MPTCPHDR_SEQ64_SET 0x20 /* Did we received a 64-bit seq number? */ ++#define MPTCPHDR_SEQ64_OFO 0x40 /* Is it not in our circular array? */ ++#define MPTCPHDR_DSS_CSUM 0x80 +/* MPTCP flags: TX only */ -+#define MPTCPHDR_INF 0x08 -+#define MPTCP_REINJECT 0x10 /* Did we reinject this segment? */ ++#define MPTCPHDR_INF 0x10 ++#define MPTCP_REINJECT 0x20 /* Did we reinject this segment? */ + +struct mptcp_option { + __u8 kind; @@ -1061,10 +1074,11 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +void mptcp_close(struct sock *meta_sk, long timeout); +bool mptcp_doit(struct sock *sk); +int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window); ++ int rem_key_set, __u8 mptcp_ver, u32 window); +int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req); +int mptcp_check_req_master(struct sock *sk, struct sock *child, + struct request_sock *req, const struct sk_buff *skb, ++ const struct mptcp_options_received *mopt, + int drop, u32 tsoff); +struct sock *mptcp_check_req_child(struct sock *meta_sk, + struct sock *child, @@ -1077,8 +1091,8 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + int wscale_ok, __u8 *rcv_wscale, + __u32 init_rcv_wnd); +unsigned int mptcp_current_mss(struct sock *meta_sk); -+void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...); ++void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, ...); +void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); +void mptcp_fin(struct sock *meta_sk); +void mptcp_meta_retransmit_timer(struct sock *meta_sk); @@ -1088,6 +1102,8 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +void mptcp_sub_close(struct sock *sk, unsigned long delay); +struct sock *mptcp_select_ack_sock(const struct sock *meta_sk); +void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb); ++void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb, ++ __u64 remote_key); +int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb); +void mptcp_ack_handler(struct timer_list *t); +bool mptcp_check_rtt(const struct tcp_sock *tp, int time); @@ -1243,6 +1259,11 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + } +} + ++static inline bool mptcp_is_data_mpcapable(const struct sk_buff *skb) ++{ ++ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_MPC_DATA; ++} ++ +static inline bool mptcp_is_data_seq(const struct sk_buff *skb) +{ + return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ; @@ -1660,6 +1681,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + const struct sock *child, + const struct request_sock *req, + const struct sk_buff *skb, ++ const struct mptcp_options_received *mopt, + int drop, + u32 tsoff) +{ @@ -1758,7 +1780,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +#endif /* _MPTCP_H */ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_v4.h --- linux-5.4/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,76 @@ +/* + * MPTCP implementation @@ -1838,7 +1860,7 @@ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* MPTCP_V4_H_ */ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_v6.h --- linux-5.4/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,77 @@ +/* + * MPTCP implementation @@ -1919,7 +1941,7 @@ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* _MPTCP_V6_H */ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/net_namespace.h --- linux-5.4/include/net/net_namespace.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-05-16 10:39:52.000000000 +0200 @@ -19,6 +19,7 @@ #include #include @@ -1940,7 +1962,7 @@ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/n #endif diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/netns/mptcp.h --- linux-5.4/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,52 @@ +/* + * MPTCP implementation - MPTCP namespace @@ -1996,7 +2018,7 @@ diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/net +#endif /* __NETNS_MPTCP_H__ */ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h --- linux-5.4/include/net/snmp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/snmp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/snmp.h 2020-05-16 10:39:52.000000000 +0200 @@ -86,7 +86,6 @@ atomic_long_t mibs[ICMP6MSG_MIB_MAX]; }; @@ -2007,7 +2029,7 @@ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h struct tcp_mib { diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h --- linux-5.4/include/net/sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/sock.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/sock.h 2020-05-16 10:39:52.000000000 +0200 @@ -814,6 +814,7 @@ SOCK_TXTIME, SOCK_XDP, /* XDP is attached */ @@ -2026,7 +2048,7 @@ diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h #ifdef CONFIG_PROC_FS diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h --- linux-5.4/include/net/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/tcp.h 2020-05-16 10:39:52.000000000 +0200 @@ -182,6 +182,7 @@ #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ @@ -2067,7 +2089,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h /* sysctl variables for tcp */ extern int sysctl_tcp_max_orphans; -@@ -310,6 +336,97 @@ +@@ -310,6 +336,96 @@ #define TCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mib.tcp_statistics, field) #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) @@ -2078,7 +2100,6 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h +struct mptcp_options_received; + +void tcp_cleanup_rbuf(struct sock *sk, int copied); -+void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited); +int tcp_close_state(struct sock *sk); +void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, + const struct sk_buff *skb); @@ -2165,7 +2186,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h void tcp_tasklet_init(void); int tcp_v4_err(struct sk_buff *skb, u32); -@@ -411,7 +528,9 @@ +@@ -411,7 +527,9 @@ #endif void tcp_parse_options(const struct net *net, const struct sk_buff *skb, struct tcp_options_received *opt_rx, @@ -2176,7 +2197,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); /* -@@ -430,6 +549,7 @@ +@@ -430,6 +548,7 @@ void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); void tcp_v4_mtu_reduced(struct sock *sk); @@ -2184,7 +2205,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h void tcp_req_err(struct sock *sk, u32 seq, bool abort); int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); struct sock *tcp_create_openreq_child(const struct sock *sk, -@@ -453,6 +573,7 @@ +@@ -453,6 +572,7 @@ struct request_sock *req, struct tcp_fastopen_cookie *foc, enum tcp_synack_type synack_type); @@ -2192,6 +2213,14 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h int tcp_disconnect(struct sock *sk, int flags); void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); +@@ -462,6 +582,7 @@ + /* From syncookies.c */ + struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, + struct request_sock *req, ++ const struct mptcp_options_received *mopt, + struct dst_entry *dst, u32 tsoff); + int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, + u32 cookie); @@ -536,7 +657,8 @@ u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, @@ -2295,7 +2324,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h /* Note: caller must be prepared to deal with negative returns */ static inline int tcp_space(const struct sock *sk) { -@@ -1949,6 +2107,31 @@ +@@ -1949,6 +2107,30 @@ #endif }; @@ -2318,7 +2347,6 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h + void (*retransmit_timer)(struct sock *sk); + void (*time_wait)(struct sock *sk, int state, int timeo); + void (*cleanup_rbuf)(struct sock *sk, int copied); -+ void (*cwnd_validate)(struct sock *sk, bool is_cwnd_limited); + int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, + bool reinit, bool cap_net_admin); +}; @@ -2327,7 +2355,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h struct tcp_request_sock_ops { u16 mss_clamp; #ifdef CONFIG_TCP_MD5SIG -@@ -1959,12 +2142,13 @@ +@@ -1959,12 +2141,13 @@ const struct sock *sk, const struct sk_buff *skb); #endif @@ -2346,7 +2374,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h #endif struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, const struct request_sock *req); -@@ -1978,15 +2162,17 @@ +@@ -1978,15 +2161,17 @@ #ifdef CONFIG_SYN_COOKIES static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, @@ -2367,7 +2395,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h { diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_states.h --- linux-5.4/include/net/tcp_states.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-05-16 10:39:52.000000000 +0200 @@ -22,6 +22,7 @@ TCP_LISTEN, TCP_CLOSING, /* Now a valid state */ @@ -2386,7 +2414,7 @@ diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_ #endif /* _LINUX_TCP_STATES_H */ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/transp_v6.h --- linux-5.4/include/net/transp_v6.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-05-16 10:39:52.000000000 +0200 @@ -58,6 +58,8 @@ /* address family specific functions */ @@ -2398,7 +2426,7 @@ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/trans diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/events/tcp.h --- linux-5.4/include/trace/events/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-05-16 10:39:52.000000000 +0200 @@ -10,6 +10,7 @@ #include #include @@ -2449,7 +2477,7 @@ diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/ #endif /* _TRACE_TCP_H */ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/linux/bpf.h --- linux-5.4/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-05-16 10:39:52.000000000 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ @@ -2460,7 +2488,7 @@ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/lin }; diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linux/if.h --- linux-5.4/include/uapi/linux/if.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-05-16 10:39:52.000000000 +0200 @@ -132,6 +132,9 @@ #define IFF_ECHO IFF_ECHO #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ @@ -2473,7 +2501,7 @@ diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linu diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/linux/mptcp.h --- linux-5.4/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* @@ -2626,7 +2654,7 @@ diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/l +#endif /* _LINUX_MPTCP_H */ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/linux/tcp.h --- linux-5.4/include/uapi/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-05-16 10:39:52.000000000 +0200 @@ -18,9 +18,15 @@ #ifndef _UAPI_LINUX_TCP_H #define _UAPI_LINUX_TCP_H @@ -2714,7 +2742,7 @@ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/lin diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c --- linux-5.4/net/core/dev.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/dev.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/core/dev.c 2020-05-16 10:39:52.000000000 +0200 @@ -7855,7 +7855,7 @@ dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | @@ -2726,7 +2754,7 @@ diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces.c --- linux-5.4/net/core/net-traces.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-05-16 10:39:52.000000000 +0200 @@ -60,3 +60,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); @@ -2735,7 +2763,7 @@ diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces +EXPORT_TRACEPOINT_SYMBOL_GPL(mptcp_retransmit); diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c --- linux-5.4/net/core/skbuff.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-05-16 10:39:52.000000000 +0200 @@ -573,7 +573,7 @@ skb_drop_list(&skb_shinfo(skb)->frag_list); } @@ -2747,7 +2775,7 @@ diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c --- linux-5.4/net/core/sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/sock.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/core/sock.c 2020-05-16 10:39:52.000000000 +0200 @@ -135,6 +135,11 @@ #include @@ -2799,20 +2827,16 @@ diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c } else sk = kmalloc(prot->obj_size, priority); -@@ -1832,9 +1858,10 @@ +@@ -1832,4 +1858,5 @@ atomic_set(&newsk->sk_zckey, 0); sock_reset_flag(newsk, SOCK_DONE); + sock_reset_flag(newsk, SOCK_MPTCP); /* sk->sk_memcg will be populated at accept() time */ - newsk->sk_memcg = NULL; - - cgroup_sk_alloc(&newsk->sk_cgrp_data); - diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c --- linux-5.4/net/ipv4/af_inet.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-05-16 10:39:52.000000000 +0200 @@ -100,6 +100,7 @@ #include #include @@ -2878,7 +2902,7 @@ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c --- linux-5.4/net/ipv4/inet_connection_sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-05-16 10:39:52.000000000 +0200 @@ -19,6 +19,7 @@ #include #include @@ -2938,7 +2962,7 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ cond_resched(); diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c --- linux-5.4/net/ipv4/ip_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-05-16 10:39:52.000000000 +0200 @@ -44,6 +44,8 @@ #endif #include @@ -2980,7 +3004,7 @@ diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockgl case IP_TTL: diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig --- linux-5.4/net/ipv4/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-05-16 10:39:52.000000000 +0200 @@ -654,6 +654,51 @@ bufferbloat, policers, or AQM schemes that do not provide a delay signal. It requires the fq ("Fair Queue") pacing packet scheduler. @@ -3068,7 +3092,7 @@ diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig default "cdg" if DEFAULT_CDG diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies.c --- linux-5.4/net/ipv4/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-05-16 10:39:52.000000000 +0200 @@ -12,6 +12,8 @@ #include #include @@ -3088,7 +3112,13 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies { const struct iphdr *iph = ip_hdr(skb); const struct tcphdr *th = tcp_hdr(skb); -@@ -205,9 +208,27 @@ +@@ -200,14 +203,33 @@ + + struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, + struct request_sock *req, ++ const struct mptcp_options_received *mopt, + struct dst_entry *dst, u32 tsoff) + { struct inet_connection_sock *icsk = inet_csk(sk); struct sock *child; bool own_req; @@ -3103,7 +3133,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies + if (!child) + goto listen_overflow; + -+ ret = mptcp_check_req_master(sk, child, req, skb, 0, tsoff); ++ ret = mptcp_check_req_master(sk, child, req, skb, mopt, 0, tsoff); + if (ret < 0) + return NULL; + @@ -3116,7 +3146,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies if (child) { refcount_set(&req->rsk_refcnt, 1); tcp_sk(child)->tsoffset = tsoff; -@@ -284,6 +305,7 @@ +@@ -284,6 +306,7 @@ { struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; struct tcp_options_received tcp_opt; @@ -3124,7 +3154,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies struct inet_request_sock *ireq; struct tcp_request_sock *treq; struct tcp_sock *tp = tcp_sk(sk); -@@ -313,7 +335,8 @@ +@@ -313,7 +336,8 @@ /* check for timestamp cookie support */ memset(&tcp_opt, 0, sizeof(tcp_opt)); @@ -3134,7 +3164,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { tsoff = secure_tcp_ts_off(sock_net(sk), -@@ -326,7 +349,12 @@ +@@ -326,7 +350,12 @@ goto out; ret = NULL; @@ -3148,7 +3178,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies if (!req) goto out; -@@ -346,6 +374,8 @@ +@@ -346,6 +375,8 @@ ireq->sack_ok = tcp_opt.sack_ok; ireq->wscale_ok = tcp_opt.wscale_ok; ireq->tstamp_ok = tcp_opt.saw_tstamp; @@ -3157,7 +3187,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; treq->snt_synack = 0; treq->tfo_listener = false; -@@ -354,6 +384,9 @@ +@@ -354,6 +385,9 @@ ireq->ir_iif = inet_request_bound_dev_if(sk, skb); @@ -3167,7 +3197,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies /* We throwed the options of the initial SYN away, so we hope * the ACK carries the same options again (see RFC1122 4.2.3.8) */ -@@ -387,10 +420,10 @@ +@@ -387,15 +421,15 @@ /* Try to redo what tcp_v4_send_synack did. */ req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW); @@ -3182,9 +3212,15 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies ireq->rcv_wscale = rcv_wscale; ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); + +- ret = tcp_get_cookie_sock(sk, skb, req, &rt->dst, tsoff); ++ ret = tcp_get_cookie_sock(sk, skb, req, &mopt, &rt->dst, tsoff); + /* ip_queue_xmit() depends on our flow being setup + * Normal sockets get it right from inet_csk_route_child_sock() + */ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c --- linux-5.4/net/ipv4/tcp.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-05-16 10:39:52.000000000 +0200 @@ -270,6 +270,7 @@ #include @@ -3193,7 +3229,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c #include #include #include -@@ -400,6 +401,24 @@ +@@ -400,6 +401,23 @@ return rate64; } @@ -3211,14 +3247,13 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c + .retransmit_timer = tcp_retransmit_timer, + .time_wait = tcp_time_wait, + .cleanup_rbuf = tcp_cleanup_rbuf, -+ .cwnd_validate = tcp_cwnd_validate, + .set_cong_ctrl = __tcp_set_congestion_control, +}; + /* Address-family independent initialization for a tcp_sock. * * NOTE: A lot of things set to zero explicitly by call to -@@ -453,6 +472,11 @@ +@@ -453,6 +471,11 @@ WRITE_ONCE(sk->sk_sndbuf, sock_net(sk)->ipv4.sysctl_tcp_wmem[1]); WRITE_ONCE(sk->sk_rcvbuf, sock_net(sk)->ipv4.sysctl_tcp_rmem[1]); @@ -3230,7 +3265,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c sk_sockets_allocated_inc(sk); sk->sk_route_forced_caps = NETIF_F_GSO; } -@@ -777,6 +801,7 @@ +@@ -777,6 +800,7 @@ int ret; sock_rps_record_flow(sk); @@ -3238,7 +3273,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c /* * We can't seek on a socket input */ -@@ -787,6 +812,16 @@ +@@ -787,6 +811,16 @@ lock_sock(sk); @@ -3255,7 +3290,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); while (tss.len) { ret = __tcp_splice_read(sk, &tss); -@@ -902,8 +937,7 @@ +@@ -902,8 +936,7 @@ return NULL; } @@ -3265,7 +3300,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { struct tcp_sock *tp = tcp_sk(sk); u32 new_size_goal, size_goal; -@@ -931,8 +965,13 @@ +@@ -931,8 +964,13 @@ { int mss_now; @@ -3281,7 +3316,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c return mss_now; } -@@ -971,12 +1010,34 @@ +@@ -971,12 +1009,34 @@ * is fully established. */ if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && @@ -3317,7 +3352,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); mss_now = tcp_send_mss(sk, &size_goal, flags); -@@ -1099,7 +1160,8 @@ +@@ -1099,7 +1159,8 @@ int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, size_t size, int flags) { @@ -3327,7 +3362,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c return sock_no_sendpage_locked(sk, page, offset, size, flags); tcp_rate_check_app_limited(sk); /* is sending application-limited? */ -@@ -1221,12 +1283,21 @@ +@@ -1221,12 +1282,21 @@ * is fully established. */ if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && @@ -3350,7 +3385,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (unlikely(tp->repair)) { if (tp->repair_queue == TCP_RECV_QUEUE) { copied = tcp_send_rcvq(sk, msg, size); -@@ -1520,7 +1591,7 @@ +@@ -1520,7 +1590,7 @@ * calculation of whether or not we must ACK for the sake of * a window update. */ @@ -3359,7 +3394,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { struct tcp_sock *tp = tcp_sk(sk); bool time_to_ack = false; -@@ -1563,7 +1634,7 @@ +@@ -1563,7 +1633,7 @@ /* Optimize, __tcp_select_window() is not cheap. */ if (2*rcv_window_now <= tp->window_clamp) { @@ -3368,7 +3403,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c /* Send ACK now, if this read freed lots of space * in our buffer. Certainly, new_window is new window. -@@ -1679,7 +1750,7 @@ +@@ -1679,7 +1749,7 @@ /* Clean up data we have read: This will do ACK frames. */ if (copied > 0) { tcp_recv_skb(sk, seq, &offset); @@ -3377,7 +3412,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } return copied; } -@@ -1970,6 +2041,16 @@ +@@ -1970,6 +2040,16 @@ lock_sock(sk); @@ -3394,7 +3429,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c err = -ENOTCONN; if (sk->sk_state == TCP_LISTEN) goto out; -@@ -2088,7 +2169,7 @@ +@@ -2088,7 +2168,7 @@ } } @@ -3403,7 +3438,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (copied >= target) { /* Do not sleep, just process backlog. */ -@@ -2179,7 +2260,7 @@ +@@ -2179,7 +2259,7 @@ */ /* Clean up data we have read: This will do ACK frames. */ @@ -3412,7 +3447,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c release_sock(sk); -@@ -2287,7 +2368,7 @@ +@@ -2287,7 +2367,7 @@ [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ }; @@ -3421,7 +3456,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { int next = (int)new_state[sk->sk_state]; int ns = next & TCP_STATE_MASK; -@@ -2317,7 +2398,7 @@ +@@ -2317,7 +2397,7 @@ TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { /* Clear out any half completed packets. FIN if needed. */ if (tcp_close_state(sk)) @@ -3430,7 +3465,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } } EXPORT_SYMBOL(tcp_shutdown); -@@ -2342,6 +2423,17 @@ +@@ -2342,6 +2422,17 @@ int data_was_unread = 0; int state; @@ -3448,7 +3483,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c lock_sock(sk); sk->sk_shutdown = SHUTDOWN_MASK; -@@ -2386,7 +2478,7 @@ +@@ -2386,7 +2477,7 @@ /* Unread data was tossed, zap the connection. */ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); tcp_set_state(sk, TCP_CLOSE); @@ -3457,7 +3492,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { /* Check zero linger _after_ checking for unread data. */ sk->sk_prot->disconnect(sk, 0); -@@ -2460,7 +2552,7 @@ +@@ -2460,7 +2551,7 @@ struct tcp_sock *tp = tcp_sk(sk); if (tp->linger2 < 0) { tcp_set_state(sk, TCP_CLOSE); @@ -3466,7 +3501,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONLINGER); } else { -@@ -2470,7 +2562,8 @@ +@@ -2470,7 +2561,8 @@ inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); } else { @@ -3476,7 +3511,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c goto out; } } -@@ -2479,7 +2572,7 @@ +@@ -2479,7 +2571,7 @@ sk_mem_reclaim(sk); if (tcp_check_oom(sk, 0)) { tcp_set_state(sk, TCP_CLOSE); @@ -3485,7 +3520,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); } else if (!check_net(sock_net(sk))) { -@@ -2511,15 +2604,6 @@ +@@ -2511,15 +2603,6 @@ } EXPORT_SYMBOL(tcp_close); @@ -3501,7 +3536,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c static void tcp_rtx_queue_purge(struct sock *sk) { struct rb_node *p = rb_first(&sk->tcp_rtx_queue); -@@ -2540,6 +2624,10 @@ +@@ -2540,6 +2623,10 @@ { struct sk_buff *skb; @@ -3512,7 +3547,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tcp_chrono_stop(sk, TCP_CHRONO_BUSY); while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { tcp_skb_tsorted_anchor_cleanup(skb); -@@ -2558,6 +2646,29 @@ +@@ -2558,6 +2645,29 @@ inet_csk(sk)->icsk_backoff = 0; } @@ -3542,7 +3577,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c int tcp_disconnect(struct sock *sk, int flags) { struct inet_sock *inet = inet_sk(sk); -@@ -2580,7 +2691,7 @@ +@@ -2580,7 +2690,7 @@ /* The last check adjusts for discrepancy of Linux wrt. RFC * states */ @@ -3551,7 +3586,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c sk->sk_err = ECONNRESET; } else if (old_state == TCP_SYN_SENT) sk->sk_err = ECONNRESET; -@@ -2602,11 +2713,15 @@ +@@ -2602,11 +2712,15 @@ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) inet_reset_saddr(sk); @@ -3570,7 +3605,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c seq = tp->write_seq + tp->max_window + 2; if (!seq) -@@ -2616,17 +2731,11 @@ +@@ -2616,17 +2730,11 @@ icsk->icsk_backoff = 0; tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; @@ -3591,7 +3626,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c inet_csk_delack_init(sk); /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 * issue in __tcp_select_window() -@@ -2636,14 +2747,10 @@ +@@ -2636,14 +2746,10 @@ sk->sk_rx_dst = NULL; tcp_saved_syn_free(tp); tp->compressed_ack = 0; @@ -3606,7 +3641,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tp->duplicate_sack[0].start_seq = 0; tp->duplicate_sack[0].end_seq = 0; tp->dsack_dups = 0; -@@ -2648,8 +2755,6 @@ +@@ -2648,8 +2754,6 @@ tp->sacked_out = 0; tp->tlp_high_seq = 0; tp->last_oow_ack_time = 0; @@ -3615,7 +3650,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tp->rack.mstamp = 0; tp->rack.advanced = 0; tp->rack.reo_wnd_steps = 1; -@@ -2683,7 +2788,7 @@ +@@ -2683,7 +2787,7 @@ static inline bool tcp_can_repair_sock(const struct sock *sk) { return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && @@ -3624,7 +3659,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) -@@ -2852,6 +2957,61 @@ +@@ -2852,6 +2956,61 @@ return tcp_fastopen_reset_cipher(net, sk, key, backup_key); } @@ -3686,7 +3721,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c default: /* fallthru */ break; -@@ -3032,6 +3192,12 @@ +@@ -3032,6 +3191,12 @@ break; case TCP_DEFER_ACCEPT: @@ -3699,7 +3734,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c /* Translate value in seconds to number of retransmits */ icsk->icsk_accept_queue.rskq_defer_accept = secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -@@ -3059,7 +3225,7 @@ +@@ -3059,7 +3224,7 @@ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && inet_csk_ack_scheduled(sk)) { icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; @@ -3708,7 +3743,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!(val & 1)) inet_csk_enter_pingpong_mode(sk); } -@@ -3069,7 +3235,7 @@ +@@ -3069,7 +3234,7 @@ #ifdef CONFIG_TCP_MD5SIG case TCP_MD5SIG: case TCP_MD5SIG_EXT: @@ -3717,7 +3752,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c err = tp->af_specific->md5_parse(sk, optname, optval, optlen); else err = -EINVAL; -@@ -3128,6 +3294,32 @@ +@@ -3128,6 +3293,32 @@ tp->notsent_lowat = val; sk->sk_write_space(sk); break; @@ -3750,7 +3785,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c case TCP_INQ: if (val > 1 || val < 0) err = -EINVAL; -@@ -3192,7 +3384,7 @@ +@@ -3192,7 +3383,7 @@ } /* Return information about state of tcp endpoint in API format. */ @@ -3759,7 +3794,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ const struct inet_connection_sock *icsk = inet_csk(sk); -@@ -3229,7 +3421,8 @@ +@@ -3229,7 +3420,8 @@ return; } @@ -3769,7 +3804,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c info->tcpi_ca_state = icsk->icsk_ca_state; info->tcpi_retransmits = icsk->icsk_retransmits; -@@ -3305,7 +3498,9 @@ +@@ -3305,7 +3497,9 @@ info->tcpi_reord_seen = tp->reord_seen; info->tcpi_rcv_ooopack = tp->rcv_ooopack; info->tcpi_snd_wnd = tp->snd_wnd; @@ -3780,7 +3815,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } EXPORT_SYMBOL_GPL(tcp_get_info); -@@ -3452,7 +3647,7 @@ +@@ -3452,7 +3646,7 @@ if (get_user(len, optlen)) return -EFAULT; @@ -3789,7 +3824,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c len = min_t(unsigned int, len, sizeof(info)); if (put_user(len, optlen)) -@@ -3649,6 +3844,87 @@ +@@ -3649,6 +3843,87 @@ } return 0; } @@ -3877,7 +3912,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c #ifdef CONFIG_MMU case TCP_ZEROCOPY_RECEIVE: { struct tcp_zerocopy_receive zc; -@@ -3851,7 +4127,9 @@ +@@ -3851,7 +4126,9 @@ if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); @@ -3887,7 +3922,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tcp_clear_xmit_timers(sk); if (req) reqsk_fastopen_remove(sk, req, false); -@@ -3867,6 +4145,8 @@ +@@ -3867,6 +4144,8 @@ int tcp_abort(struct sock *sk, int err) { @@ -3896,7 +3931,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!sk_fullsock(sk)) { if (sk->sk_state == TCP_NEW_SYN_RECV) { struct request_sock *req = inet_reqsk(sk); -@@ -3880,7 +4160,7 @@ +@@ -3880,7 +4159,7 @@ } /* Don't race with userspace socket closes such as tcp_close. */ @@ -3905,7 +3940,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (sk->sk_state == TCP_LISTEN) { tcp_set_state(sk, TCP_CLOSE); -@@ -3889,7 +4169,7 @@ +@@ -3889,7 +4168,7 @@ /* Don't race with BH socket closes such as inet_csk_listen_stop. */ local_bh_disable(); @@ -3914,7 +3949,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_err = err; -@@ -3897,14 +4177,14 @@ +@@ -3897,14 +4176,14 @@ smp_wmb(); sk->sk_error_report(sk); if (tcp_need_reset(sk->sk_state)) @@ -3934,7 +3969,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c EXPORT_SYMBOL_GPL(tcp_abort); diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c --- linux-5.4/net/ipv4/tcp_cong.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-05-16 10:39:52.000000000 +0200 @@ -328,13 +328,19 @@ return ret; } @@ -3959,7 +3994,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c const struct tcp_congestion_ops *ca; diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c --- linux-5.4/net/ipv4/tcp_diag.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-05-16 10:39:52.000000000 +0200 @@ -31,7 +31,7 @@ r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; } @@ -3971,7 +4006,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c #ifdef CONFIG_TCP_MD5SIG diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c --- linux-5.4/net/ipv4/tcp_fastopen.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-05-16 10:39:52.000000000 +0200 @@ -9,6 +9,7 @@ #include #include @@ -4032,7 +4067,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fast */ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c --- linux-5.4/net/ipv4/tcp_input.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-05-16 10:39:52.000000000 +0200 @@ -76,35 +76,15 @@ #include #include @@ -4916,7 +4951,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_rsk(req)->tfo_listener = false; diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c --- linux-5.4/net/ipv4/tcp_ipv4.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-05-16 10:39:52.000000000 +0200 @@ -62,6 +62,8 @@ #include #include @@ -5381,7 +5416,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c --- linux-5.4/net/ipv4/tcp_minisocks.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-05-16 10:39:52.000000000 +0200 @@ -19,11 +19,13 @@ * Jorge Cwik, */ @@ -5564,7 +5599,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min goto listen_overflow; + if (own_req && !is_meta_sk(sk)) { -+ int ret = mptcp_check_req_master(sk, child, req, skb, 1, 0); ++ int ret = mptcp_check_req_master(sk, child, req, skb, &mopt, 1, 0); + if (ret < 0) + goto listen_overflow; + @@ -5623,7 +5658,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min } diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output.c --- linux-5.4/net/ipv4/tcp_output.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-05-16 10:39:52.000000000 +0200 @@ -37,6 +37,12 @@ #define pr_fmt(fmt) "TCP: " fmt @@ -5819,8 +5854,8 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output + if (mptcp(tp)) + tcp_tsq_write(meta_sk); + } else { -+ if (!test_and_set_bit(TCP_TSQ_DEFERRED, &meta_sk->sk_tsq_flags)) -+ sock_hold(meta_sk); ++ if (!test_and_set_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags)) ++ sock_hold(sk); + + if ((mptcp(tp)) && (sk->sk_state != TCP_CLOSE)) + mptcp_tsq_flags(sk); @@ -5944,15 +5979,6 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. * As additional protections, we do not touch cwnd in retransmission phases, -@@ -1635,7 +1672,7 @@ - tp->snd_cwnd_stamp = tcp_jiffies32; - } - --static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) -+void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) - { - const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; - struct tcp_sock *tp = tcp_sk(sk); @@ -1693,8 +1730,8 @@ * But we can avoid doing the divide again given we already have * skb_pcount = skb->len / mss_now @@ -6088,17 +6114,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Do MTU probing. */ result = tcp_mtu_probe(sk); if (!result) { -@@ -2466,7 +2512,8 @@ - if (push_one != 2) - tcp_schedule_loss_probe(sk, false); - is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); -- tcp_cwnd_validate(sk, is_cwnd_limited); -+ if (tp->ops->cwnd_validate) -+ tp->ops->cwnd_validate(sk, is_cwnd_limited); - return false; - } - return !tp->packets_out && !tcp_write_queue_empty(sk); -@@ -2549,7 +2596,7 @@ +@@ -2549,7 +2595,7 @@ skb = tcp_send_head(sk); if (skb && tcp_snd_wnd_test(tp, skb, mss)) { pcount = tp->packets_out; @@ -6107,7 +6123,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output if (tp->packets_out > pcount) goto probe_sent; goto rearm_timer; -@@ -2613,8 +2660,8 @@ +@@ -2613,8 +2659,8 @@ if (unlikely(sk->sk_state == TCP_CLOSE)) return; @@ -6118,7 +6134,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output tcp_check_probe_timer(sk); } -@@ -2627,7 +2674,8 @@ +@@ -2627,7 +2673,8 @@ BUG_ON(!skb || skb->len < mss_now); @@ -6128,7 +6144,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output } /* This function returns the amount that we can raise the -@@ -2849,6 +2897,10 @@ +@@ -2849,6 +2896,10 @@ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) return; @@ -6139,7 +6155,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output skb_rbtree_walk_from_safe(skb, tmp) { if (!tcp_can_collapse(sk, skb)) break; -@@ -3325,7 +3377,7 @@ +@@ -3325,7 +3376,7 @@ /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ th->window = htons(min(req->rsk_rcv_wnd, 65535U)); @@ -6148,7 +6164,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output th->doff = (tcp_header_size >> 2); __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); -@@ -3407,13 +3459,13 @@ +@@ -3407,13 +3458,13 @@ if (rcv_wnd == 0) rcv_wnd = dst_metric(dst, RTAX_INITRWND); @@ -6169,7 +6185,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output tp->rx_opt.rcv_wscale = rcv_wscale; tp->rcv_ssthresh = tp->rcv_wnd; -@@ -3438,6 +3490,36 @@ +@@ -3438,6 +3489,36 @@ inet_csk(sk)->icsk_rto = tcp_timeout_init(sk); inet_csk(sk)->icsk_retransmits = 0; tcp_clear_retrans(tp); @@ -6206,7 +6222,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output } static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) -@@ -3701,6 +3783,7 @@ +@@ -3701,6 +3782,7 @@ { __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt); } @@ -6214,7 +6230,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* This routine sends a packet with an out of date sequence * number. It assumes the other end will try to ack it. -@@ -3713,7 +3796,7 @@ +@@ -3713,7 +3795,7 @@ * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is * out-of-date with SND.UNA-1 to probe window. */ @@ -6223,7 +6239,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; -@@ -3800,7 +3883,7 @@ +@@ -3800,7 +3882,7 @@ unsigned long timeout; int err; @@ -6234,7 +6250,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Cancel probe timer, if it is not required. */ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c --- linux-5.4/net/ipv4/tcp_timer.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-05-16 10:39:52.000000000 +0200 @@ -21,6 +21,7 @@ #include @@ -6448,7 +6464,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c --- linux-5.4/net/ipv6/addrconf.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-05-16 10:39:52.000000000 +0200 @@ -967,6 +967,7 @@ kfree_rcu(ifp, rcu); @@ -6459,7 +6475,7 @@ diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c --- linux-5.4/net/ipv6/af_inet6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-05-16 10:39:52.000000000 +0200 @@ -104,8 +104,7 @@ return (struct ipv6_pinfo *)(((u8 *)sk) + offset); } @@ -6472,7 +6488,7 @@ diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c struct ipv6_pinfo *np; diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c --- linux-5.4/net/ipv6/ipv6_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-05-16 10:39:52.000000000 +0200 @@ -44,6 +44,8 @@ #include #include @@ -6498,7 +6514,7 @@ diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_so tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies.c --- linux-5.4/net/ipv6/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-05-16 10:39:52.000000000 +0200 @@ -15,6 +15,8 @@ #include #include @@ -6565,7 +6581,7 @@ diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies if (security_inet_conn_request(sk, skb, req)) goto out_free; -@@ -241,10 +259,10 @@ +@@ -241,15 +259,15 @@ } req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); @@ -6580,9 +6596,15 @@ diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies ireq->rcv_wscale = rcv_wscale; ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); + +- ret = tcp_get_cookie_sock(sk, skb, req, dst, tsoff); ++ ret = tcp_get_cookie_sock(sk, skb, req, &mopt, dst, tsoff); + out: + return ret; + out_free: diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c --- linux-5.4/net/ipv6/tcp_ipv6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-05-16 10:39:52.000000000 +0200 @@ -58,6 +58,8 @@ #include #include @@ -7176,7 +7198,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c /* thinking of making this const? Don't. diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig --- linux-5.4/net/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Kconfig 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/Kconfig 2020-05-16 10:39:52.000000000 +0200 @@ -91,6 +91,7 @@ source "net/ipv4/Kconfig" source "net/ipv6/Kconfig" @@ -7187,7 +7209,7 @@ diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile --- linux-5.4/net/Makefile 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Makefile 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/Makefile 2020-05-16 10:39:52.000000000 +0200 @@ -20,6 +20,7 @@ obj-$(CONFIG_XFRM) += xfrm/ obj-$(CONFIG_UNIX_SCM) += unix/ @@ -7198,7 +7220,7 @@ diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile obj-$(CONFIG_NET_KEY) += key/ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig --- linux-5.4/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,146 @@ +# +# MPTCP configuration @@ -7348,7 +7370,7 @@ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig + diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile --- linux-5.4/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,24 @@ +# +## Makefile for MultiPath TCP support code. @@ -7376,7 +7398,7 @@ diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile +mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c --- linux-5.4/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,193 @@ +/* + * Desynchronized Multi-Channel TCP Congestion Control Algorithm @@ -7573,7 +7595,7 @@ diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_ +MODULE_VERSION("1.0"); diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c --- linux-5.4/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,261 @@ +/* + * MPTCP implementation - Balia Congestion Control @@ -7838,7 +7860,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c --- linux-5.4/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,494 @@ +#include + @@ -8336,7 +8358,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c --- linux-5.4/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,481 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP Scheduler to reduce HoL-blocking and spurious retransmissions. @@ -8821,7 +8843,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_VERSION("0.95"); diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c --- linux-5.4/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,262 @@ +/* + * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) @@ -9087,8 +9109,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c --- linux-5.4/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,3142 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,3254 @@ +/* + * MPTCP implementation - MPTCP-control + * @@ -9118,6 +9140,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + * 2 of the License, or (at your option) any later version. + */ + ++#include ++ +#include +#include +#include @@ -9168,7 +9192,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; +EXPORT_SYMBOL(mptcp_static_key); + -+static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn); ++static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn); + +static int proc_mptcp_path_manager(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, @@ -9377,7 +9401,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +#endif + } + -+ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); ++ mptcp_key_hash(mtreq->mptcp_ver, mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); +} + +/* New MPTCP-connection request, prepare a new token for the meta-socket that @@ -9410,7 +9434,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + spin_unlock(&mptcp_tk_hashlock); + local_bh_enable(); + rcu_read_unlock(); -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ ++ if (mtreq->mptcp_ver == MPTCP_VERSION_0) { ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ mtreq->rem_key_set = 1; ++ } +} + +static int mptcp_reqsk_new_cookie(struct request_sock *req, @@ -9446,7 +9474,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + local_bh_enable(); + rcu_read_unlock(); + -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ if (mtreq->mptcp_ver == MPTCP_VERSION_0) { ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ mtreq->rem_key_set = 1; ++ } + + return true; +} @@ -9471,8 +9502,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + mptcp_seed++); +#endif + -+ mptcp_key_sha1(tp->mptcp_loc_key, -+ &tp->mptcp_loc_token, NULL); ++ mptcp_key_hash(tp->mptcp_ver, tp->mptcp_loc_key, &tp->mptcp_loc_token, NULL); +} + +#ifdef CONFIG_JUMP_LABEL @@ -9926,6 +9956,71 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +siphash_key_t mptcp_secret __read_mostly; +u32 mptcp_seed = 0; + ++#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / 4) ++ ++static void mptcp_key_sha256(const u64 key, u32 *token, u64 *idsn) ++{ ++ u32 mptcp_hashed_key[SHA256_DIGEST_WORDS]; ++ struct sha256_state state; ++ ++ sha256_init(&state); ++ sha256_update(&state, (const u8 *)&key, sizeof(key)); ++ sha256_final(&state, (u8 *)mptcp_hashed_key); ++ ++ if (token) ++ *token = mptcp_hashed_key[0]; ++ if (idsn) ++ *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[6])); ++} ++ ++static void mptcp_hmac_sha256(const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, va_list list) ++{ ++ u8 input[SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE]; ++ __be32 output[SHA256_DIGEST_WORDS]; ++ struct sha256_state state; ++ int index, msg_length; ++ int length = 0; ++ u8 *msg; ++ int i; ++ ++ /* Generate key xored with ipad */ ++ memset(input, 0x36, SHA256_BLOCK_SIZE); ++ for (i = 0; i < 8; i++) ++ input[i] ^= key_1[i]; ++ for (i = 0; i < 8; i++) ++ input[i + 8] ^= key_2[i]; ++ ++ index = SHA256_BLOCK_SIZE; ++ msg_length = 0; ++ for (i = 0; i < arg_num; i++) { ++ length = va_arg(list, int); ++ msg = va_arg(list, u8 *); ++ BUG_ON(index + length >= sizeof(input)); /* Message is too long */ ++ memcpy(&input[index], msg, length); ++ index += length; ++ msg_length += length; ++ } ++ ++ sha256_init(&state); ++ sha256_update(&state, input, SHA256_BLOCK_SIZE + msg_length); ++ sha256_final(&state, &input[SHA256_BLOCK_SIZE]); ++ ++ /* Prepare second part of hmac */ ++ memset(input, 0x5C, SHA256_BLOCK_SIZE); ++ for (i = 0; i < 8; i++) ++ input[i] ^= key_1[i]; ++ for (i = 0; i < 8; i++) ++ input[i + 8] ^= key_2[i]; ++ ++ sha256_init(&state); ++ sha256_update(&state, input, sizeof(input)); ++ sha256_final(&state, (u8 *)output); ++ ++ for (i = 0; i < 5; i++) ++ hash_out[i] = output[i]; ++} ++ +static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) +{ + u32 workspace[SHA_WORKSPACE_WORDS]; @@ -9955,8 +10050,16 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[3])); +} + -+void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...) ++static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn) ++{ ++ if (version == MPTCP_VERSION_0) ++ mptcp_key_sha1(key, token, idsn); ++ else if (version >= MPTCP_VERSION_1) ++ mptcp_key_sha256(key, token, idsn); ++} ++ ++static void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, va_list list) +{ + u32 workspace[SHA_WORKSPACE_WORDS]; + u8 input[128]; /* 2 512-bit blocks */ @@ -9964,7 +10067,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + int index; + int length; + u8 *msg; -+ va_list list; + + memset(workspace, 0, sizeof(workspace)); + @@ -9975,7 +10077,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + for (i = 0; i < 8; i++) + input[i + 8] ^= key_2[i]; + -+ va_start(list, arg_num); + index = 64; + for (i = 0; i < arg_num; i++) { + length = va_arg(list, int); @@ -9984,7 +10085,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + memcpy(&input[index], msg, length); + index += length; + } -+ va_end(list); + + input[index] = 0x80; /* Padding: First bit after message = 1 */ + memset(&input[index + 1], 0, (126 - index)); @@ -10027,7 +10127,20 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + for (i = 0; i < 5; i++) + hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); +} -+EXPORT_SYMBOL(mptcp_hmac_sha1); ++ ++void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u32 *hash_out, ++ int arg_num, ...) ++{ ++ va_list args; ++ ++ va_start(args, arg_num); ++ if (ver == MPTCP_VERSION_0) ++ mptcp_hmac_sha1(key_1, key_2, hash_out, arg_num, args); ++ else if (ver >= MPTCP_VERSION_1) ++ mptcp_hmac_sha256(key_1, key_2, hash_out, arg_num, args); ++ va_end(args); ++} ++EXPORT_SYMBOL(mptcp_hmac); + +static void mptcp_mpcb_inherit_sockopts(struct sock *meta_sk, struct sock *master_sk) +{ @@ -10260,14 +10373,33 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + .set_cong_ctrl = __tcp_set_congestion_control, +}; + ++void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb, ++ __u64 remote_key) ++{ ++ u64 idsn; ++ ++ mpcb->mptcp_rem_key = remote_key; ++ mpcb->rem_key_set = 1; ++ mptcp_key_hash(mpcb->mptcp_ver, mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &idsn); ++ ++ idsn++; ++ mpcb->rcv_high_order[0] = idsn >> 32; ++ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; ++ meta_tp->copied_seq = (u32)idsn; ++ meta_tp->rcv_nxt = (u32)idsn; ++ meta_tp->rcv_wup = (u32)idsn; ++ ++ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; ++} ++ +static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window) ++ int rem_key_set, __u8 mptcp_ver, u32 window) +{ + struct mptcp_cb *mpcb; + struct sock *master_sk; + struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); + struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk); -+ u64 snd_idsn, rcv_idsn; ++ u64 snd_idsn; + + dst_release(meta_sk->sk_rx_dst); + meta_sk->sk_rx_dst = NULL; @@ -10295,17 +10427,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + mpcb->mptcp_loc_token = meta_tp->mptcp_loc_token; + + /* Generate Initial data-sequence-numbers */ -+ mptcp_key_sha1(mpcb->mptcp_loc_key, NULL, &snd_idsn); ++ mptcp_key_hash(mpcb->mptcp_ver, mpcb->mptcp_loc_key, NULL, &snd_idsn); + snd_idsn++; + mpcb->snd_high_order[0] = snd_idsn >> 32; + mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1; + -+ mpcb->mptcp_rem_key = remote_key; -+ mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &rcv_idsn); -+ rcv_idsn++; -+ mpcb->rcv_high_order[0] = rcv_idsn >> 32; -+ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; -+ + mpcb->meta_sk = meta_sk; + mpcb->master_sk = master_sk; + @@ -10417,11 +10543,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + meta_tp->pushed_seq = meta_tp->write_seq; + meta_tp->snd_up = meta_tp->write_seq; + -+ meta_tp->copied_seq = (u32)rcv_idsn; -+ meta_tp->rcv_nxt = (u32)rcv_idsn; -+ meta_tp->rcv_wup = (u32)rcv_idsn; ++ if (rem_key_set) ++ mptcp_initialize_recv_vars(meta_tp, mpcb, remote_key); + -+ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; + meta_tp->snd_wnd = window; + meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */ + @@ -11168,12 +11292,12 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +} + +int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window) ++ int rem_key_set, __u8 mptcp_ver, u32 window) +{ + struct tcp_sock *master_tp; + struct sock *master_sk; + -+ if (mptcp_alloc_mpcb(meta_sk, remote_key, mptcp_ver, window)) ++ if (mptcp_alloc_mpcb(meta_sk, remote_key, rem_key_set, mptcp_ver, window)) + goto err_alloc_mpcb; + + master_sk = tcp_sk(meta_sk)->mpcb->master_sk; @@ -11201,6 +11325,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +} + +static int __mptcp_check_req_master(struct sock *child, ++ const struct mptcp_options_received *mopt, + struct request_sock *req) +{ + struct tcp_sock *child_tp = tcp_sk(child); @@ -11212,6 +11337,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + if (!inet_rsk(req)->mptcp_rqsk) + return 1; + ++ mtreq = mptcp_rsk(req); ++ + if (!inet_rsk(req)->saw_mpc) { + /* Fallback to regular TCP, because we saw one SYN without + * MP_CAPABLE. In tcp_check_req we continue the regular path. @@ -11223,15 +11350,21 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + return 1; + } + ++ /* mopt can be NULL when coming from FAST-OPEN */ ++ if (mopt && mopt->saw_mpc && mtreq->mptcp_ver == MPTCP_VERSION_1) { ++ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; ++ mtreq->rem_key_set = 1; ++ } ++ + MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK); + + /* Just set this values to pass them to mptcp_alloc_mpcb */ -+ mtreq = mptcp_rsk(req); + child_tp->mptcp_loc_key = mtreq->mptcp_loc_key; + child_tp->mptcp_loc_token = mtreq->mptcp_loc_token; + + if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, -+ mtreq->mptcp_ver, child_tp->snd_wnd)) { ++ mtreq->rem_key_set, mtreq->mptcp_ver, ++ child_tp->snd_wnd)) { + inet_csk_prepare_forced_close(meta_sk); + tcp_done(meta_sk); + @@ -11266,7 +11399,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + u32 new_mapping; + int ret; + -+ ret = __mptcp_check_req_master(child, req); ++ ret = __mptcp_check_req_master(child, NULL, req); + if (ret) + return ret; + @@ -11309,12 +11442,13 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + +int mptcp_check_req_master(struct sock *sk, struct sock *child, + struct request_sock *req, const struct sk_buff *skb, ++ const struct mptcp_options_received *mopt, + int drop, u32 tsoff) +{ + struct sock *meta_sk = child; + int ret; + -+ ret = __mptcp_check_req_master(child, req); ++ ret = __mptcp_check_req_master(child, mopt, req); + if (ret) + return ret; + child = tcp_sk(child)->mpcb->master_sk; @@ -11372,11 +11506,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + goto teardown; + } + -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, -+ (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)&mpcb->mptcp_loc_key, (u32 *)hash_mac_check, 2, ++ 4, (u8 *)&mtreq->mptcp_rem_nonce, ++ 4, (u8 *)&mtreq->mptcp_loc_nonce); + + if (memcmp(hash_mac_check, (char *)&mopt->mptcp_recv_mac, 20)) { + MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKMAC); @@ -11638,11 +11771,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + + mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; + -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)&mpcb->mptcp_rem_key, (u32 *)mptcp_hash_mac, 2, ++ 4, (u8 *)&mtreq->mptcp_loc_nonce, ++ 4, (u8 *)&mtreq->mptcp_rem_nonce); + mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; + + mtreq->rem_id = mopt.rem_id; @@ -11682,11 +11814,13 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + /* Absolutely need to always initialize this. */ + mtreq->hash_entry.pprev = NULL; + ++ mtreq->mptcp_ver = mopt->mptcp_ver; + mtreq->mptcp_rem_key = mopt->mptcp_sender_key; + mtreq->mptcp_loc_key = mopt->mptcp_receiver_key; ++ mtreq->rem_key_set = 1; + + /* Generate the token */ -+ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); ++ mptcp_key_hash(mtreq->mptcp_ver, mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); + + rcu_read_lock(); + local_bh_disable(); @@ -12233,8 +12367,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +} diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c --- linux-5.4/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,1943 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,1941 @@ +#include +#include + @@ -13833,11 +13967,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc + u8 no_key[8]; + + *(u64 *)no_key = 0; -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, -+ 4, (u8 *)&opts->add_addr4.addr.s_addr); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)no_key, (u32 *)mptcp_hash_mac, 2, ++ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, ++ 4, (u8 *)&opts->add_addr4.addr.s_addr); + opts->add_addr4.trunc_mac = *(u64 *)mptcp_hash_mac; + } + @@ -13876,11 +14009,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc + u8 no_key[8]; + + *(u64 *)no_key = 0; -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, -+ 16, (u8 *)&opts->add_addr6.addr.s6_addr); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)no_key, (u32 *)mptcp_hash_mac, 2, ++ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, ++ 16, (u8 *)&opts->add_addr6.addr.s6_addr); + opts->add_addr6.trunc_mac = *(u64 *)mptcp_hash_mac; + } + @@ -14180,8 +14312,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc +MODULE_VERSION("0.88"); diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_input.c --- linux-5.4/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,2436 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,2523 @@ +/* + * MPTCP implementation - Sending side + * @@ -14360,6 +14492,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i +} + +/* Inspired by tcp_rcv_state_process */ ++/* Returns 0 if processing the packet can continue ++ * -1 if connection was closed with an active reset ++ * 1 if connection was closed and processing should stop. ++ */ +static int mptcp_rcv_state_process(struct sock *meta_sk, struct sock *sk, + const struct sk_buff *skb, u32 data_seq, + u16 data_len) @@ -14400,7 +14536,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + mptcp_send_active_reset(meta_sk, GFP_ATOMIC); + tcp_done(meta_sk); + __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ return 1; ++ return -1; + } + + tmo = tcp_fin_time(meta_sk); @@ -14443,7 +14579,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); + mptcp_send_active_reset(meta_sk, GFP_ATOMIC); + tcp_reset(meta_sk); -+ return 1; ++ return -1; + } + } + break; @@ -14528,6 +14664,17 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + sizeof(data_seq), csum_tcp); + + dss_csum_added = 1; /* Just do it once */ ++ } else if (mptcp_is_data_mpcapable(tmp) && !dss_csum_added) { ++ u32 offset = skb_transport_offset(tmp) + TCP_SKB_CB(tmp)->dss_off; ++ __be64 data_seq = htonll(tp->mptcp->map_data_seq); ++ __be32 rel_seq = htonl(tp->mptcp->map_subseq - tp->mptcp->rcv_isn); ++ ++ csum_tcp = csum_partial(&data_seq, sizeof(data_seq), csum_tcp); ++ csum_tcp = csum_partial(&rel_seq, sizeof(rel_seq), csum_tcp); ++ ++ csum_tcp = skb_checksum(tmp, offset, 4, csum_tcp); ++ ++ dss_csum_added = 1; + } + last = tmp; + iter++; @@ -14738,11 +14885,12 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + * this segment, this path has to fallback to infinite or be torn down. + */ + if (!tp->mptcp->fully_established && !mptcp_is_data_seq(skb) && ++ !mptcp_is_data_mpcapable(skb) && + !tp->mptcp->mapping_present && !mpcb->infinite_mapping_rcv) { -+ pr_debug("%s %#x will fallback - pi %d from %pS, seq %u\n", ++ pr_debug("%s %#x will fallback - pi %d from %pS, seq %u mptcp-flags %#x\n", + __func__, mpcb->mptcp_loc_token, + tp->mptcp->path_index, __builtin_return_address(0), -+ TCP_SKB_CB(skb)->seq); ++ TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->mptcp_flags); + + if (!is_master_tp(tp)) { + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATASUB); @@ -14850,25 +14998,36 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + return 0; + } + -+ /* No mapping here? Exit - it is either already set or still on its way */ -+ if (!mptcp_is_data_seq(skb)) { -+ /* Too many packets without a mapping - this subflow is broken */ ++ if (!tp->mptcp->mapping_present && mptcp_is_data_mpcapable(skb)) { ++ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); ++ ++ sub_seq = 1 + tp->mptcp->rcv_isn; ++ data_seq = meta_tp->rcv_nxt; ++ data_len = get_unaligned_be16(ptr); ++ } else if (!mptcp_is_data_seq(skb)) { ++ /* No mapping here? ++ * Exit - it is either already set or still on its way ++ */ + if (!tp->mptcp->mapping_present && + tp->rcv_nxt - tp->copied_seq > 65536) { ++ /* Too many packets without a mapping, ++ * this subflow is broken ++ */ + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); + mptcp_send_reset(sk); + return 1; + } + + return 0; ++ } else { ++ /* Well, then the DSS-mapping is there. So, read it! */ ++ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); ++ ptr++; ++ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; ++ ptr++; ++ data_len = get_unaligned_be16(ptr); + } + -+ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); -+ ptr++; -+ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; -+ ptr++; -+ data_len = get_unaligned_be16(ptr); -+ + /* If it's an empty skb with DATA_FIN, sub_seq must get fixed. + * The draft sets it to 0, but we really would like to have the + * real value, to have an easy handling afterwards here in this @@ -15581,7 +15740,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i +} + +/* Handle the DATA_ACK */ -+static void mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) ++static bool mptcp_process_data_ack(struct sock *sk, const struct sk_buff *skb) +{ + struct sock *meta_sk = mptcp_meta_sk(sk); + struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); @@ -15609,7 +15768,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + * set by mptcp_clean_rtx_infinite. + */ + if (!(tcb->mptcp_flags & MPTCPHDR_ACK) && !tp->mpcb->infinite_mapping_snd) -+ return; ++ return false; + + if (unlikely(!tp->mptcp->fully_established) && + tp->mptcp->snt_isn + 1 != TCP_SKB_CB(skb)->ack_seq) @@ -15623,7 +15782,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + * processing. + */ + if (meta_sk->sk_state == TCP_CLOSE) -+ return; ++ return false; + + /* Get the data_seq */ + if (mptcp_is_data_seq(skb)) { @@ -15647,6 +15806,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + if (after(data_ack, meta_tp->snd_nxt)) + goto exit; + ++ /* First valid DATA_ACK, we can stop sending the special MP_CAPABLE */ ++ tp->mpcb->send_mptcpv1_mpcapable = 0; ++ + /*** Now, update the window - inspired by tcp_ack_update_window ***/ + nwin = ntohs(tcp_hdr(skb)->window); + @@ -15704,14 +15866,19 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + meta_sk->sk_write_space(meta_sk); + } + -+ if (meta_sk->sk_state != TCP_ESTABLISHED && -+ mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len)) -+ return; ++ if (meta_sk->sk_state != TCP_ESTABLISHED) { ++ int ret = mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len); ++ ++ if (ret < 0) ++ return true; ++ else if (ret > 0) ++ return false; ++ } + +exit: + mptcp_push_pending_frames(meta_sk); + -+ return; ++ return false; + +no_queue: + if (tcp_send_head(meta_sk)) @@ -15719,7 +15886,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + + mptcp_push_pending_frames(meta_sk); + -+ return; ++ return false; +} + +void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk) @@ -15738,7 +15905,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + tp->mptcp->rx_opt.data_ack = meta_tp->snd_nxt - tp->snd_nxt + + tp->snd_una; + -+ mptcp_data_ack(sk, skb); ++ mptcp_process_data_ack(sk, skb); +} + +/**** static functions used by mptcp_parse_options */ @@ -15788,6 +15955,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + struct tcp_sock *tp) +{ + const struct mptcp_option *mp_opt = (struct mptcp_option *)ptr; ++ const struct tcphdr *th = tcp_hdr(skb); + + /* If the socket is mp-capable we would have a mopt. */ + if (!mopt) @@ -15798,9 +15966,21 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + { + const struct mp_capable *mpcapable = (struct mp_capable *)ptr; + -+ if (opsize != MPTCP_SUB_LEN_CAPABLE_SYN && -+ opsize != MPTCP_SUB_LEN_CAPABLE_ACK) { -+ mptcp_debug("%s: mp_capable: bad option size %d\n", ++ if (mpcapable->ver == MPTCP_VERSION_0 && ++ ((th->syn && opsize != MPTCP_SUB_LEN_CAPABLE_SYN) || ++ (!th->syn && th->ack && opsize != MPTCP_SUB_LEN_CAPABLE_ACK))) { ++ mptcp_debug("%s: mp_capable v0: bad option size %d\n", ++ __func__, opsize); ++ break; ++ } ++ ++ if (mpcapable->ver == MPTCP_VERSION_1 && ++ ((th->syn && !th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_SYN) || ++ (th->syn && th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_SYNACK) || ++ (!th->syn && th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_ACK && ++ opsize != MPTCPV1_SUB_LEN_CAPABLE_DATA && ++ opsize != MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM))) { ++ mptcp_debug("%s: mp_capable v1: bad option size %d\n", + __func__, opsize); + break; + } @@ -15824,10 +16004,38 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + mopt->saw_mpc = 1; + mopt->dss_csum = sysctl_mptcp_checksum || mpcapable->a; + -+ if (opsize >= MPTCP_SUB_LEN_CAPABLE_SYN) -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ if (mpcapable->ver == MPTCP_VERSION_0) { ++ if (opsize == MPTCP_SUB_LEN_CAPABLE_SYN) ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ ++ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) { ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ } ++ } else if (mpcapable->ver == MPTCP_VERSION_1) { ++ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_SYNACK) ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ ++ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_ACK) { ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ } ++ ++ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA || ++ opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM) { ++ mopt->mptcp_sender_key = mpcapable->sender_key; ++ mopt->mptcp_receiver_key = mpcapable->receiver_key; ++ ++ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_MPC_DATA; ++ ++ ptr += sizeof(struct mp_capable); ++ TCP_SKB_CB(skb)->dss_off = (ptr - skb_transport_header(skb)); ++ ++ /* Is a check-sum present? */ ++ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM) ++ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_DSS_CSUM; ++ } ++ } + + mopt->mptcp_ver = mpcapable->ver; + break; @@ -16101,12 +16309,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { + msg_parts = 3; + } -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, -+ (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 4, (u8 *)&mpadd->u.v4.addr.s_addr, -+ 2, (u8 *)&mpadd->u.v4.port); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)no_key, (u32 *)hash_mac_check, msg_parts, ++ 1, (u8 *)&mpadd->addr_id, ++ 4, (u8 *)&mpadd->u.v4.addr.s_addr, ++ 2, (u8 *)&mpadd->u.v4.port); + if (memcmp(hash_mac_check, recv_hmac, 8) != 0) + /* ADD_ADDR2 discarded */ + return; @@ -16136,12 +16343,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { + msg_parts = 3; + } -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, -+ (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, -+ 2, (u8 *)&mpadd->u.v6.port); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)no_key, (u32 *)hash_mac_check, msg_parts, ++ 1, (u8 *)&mpadd->addr_id, ++ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, ++ 2, (u8 *)&mpadd->u.v6.port); + if (memcmp(hash_mac_check, recv_hmac, 8) != 0) + /* ADD_ADDR2 discarded */ + return; @@ -16299,6 +16505,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + if (sk->sk_state == TCP_RST_WAIT && !th->rst) + return true; + ++ if (mopt->saw_mpc && !tp->mpcb->rem_key_set) ++ mptcp_initialize_recv_vars(mptcp_meta_tp(tp), tp->mpcb, ++ mopt->mptcp_sender_key); ++ + if (unlikely(mopt->mp_fail)) + mptcp_mp_fail_rcvd(sk, th); + @@ -16306,7 +16516,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + * If a checksum is not present when its use has been negotiated, the + * receiver MUST close the subflow with a RST as it is considered broken. + */ -+ if (mptcp_is_data_seq(skb) && tp->mpcb->dss_csum && ++ if ((mptcp_is_data_seq(skb) || mptcp_is_data_mpcapable(skb)) && ++ tp->mpcb->dss_csum && + !(TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_DSS_CSUM)) { + mptcp_send_reset(sk); + return true; @@ -16355,7 +16566,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + mopt->saw_low_prio = 0; + } + -+ mptcp_data_ack(sk, skb); ++ if (mptcp_process_data_ack(sk, skb)) ++ return true; + + mptcp_path_array_check(mptcp_meta_sk(sk)); + /* Socket may have been mp_killed by a REMOVE_ADDR */ @@ -16481,11 +16693,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + u8 hash_mac_check[20]; + struct mptcp_cb *mpcb = tp->mpcb; + -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, -+ (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, ++ (u8 *)&mpcb->mptcp_loc_key, (u32 *)hash_mac_check, 2, ++ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, ++ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); + if (memcmp(hash_mac_check, + (char *)&tp->mptcp->rx_opt.mptcp_recv_tmac, 8)) { + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); @@ -16499,11 +16710,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + tp->mptcp->pre_established = 1; + tp->mptcp->rcv_low_prio = tp->mptcp->rx_opt.low_prio; + -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)&tp->mptcp->sender_mac[0], 2, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); ++ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, ++ (u8 *)&mpcb->mptcp_rem_key, ++ (u32 *)&tp->mptcp->sender_mac[0], 2, ++ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, ++ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); + + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); + } else if (mopt->saw_mpc) { @@ -16513,8 +16724,13 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + if (mopt->mptcp_ver > tcp_sk(sk)->mptcp_ver) + /* TODO Consider adding new MPTCP_INC_STATS entry */ + goto fallback; ++ if (tcp_sk(sk)->mptcp_ver == MPTCP_VERSION_1 && ++ mopt->mptcp_ver < MPTCP_VERSION_1) ++ /* TODO Consider adding new MPTCP_INC_STATS entry */ ++ /* TODO - record this in the cache - use v0 next time */ ++ goto fallback; + -+ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, ++ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, 1, + mopt->mptcp_ver, + ntohs(tcp_hdr(skb)->window))) + return 2; @@ -16542,6 +16758,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + if (tp->mpcb->dss_csum) + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMENABLED); + ++ if (tp->mpcb->mptcp_ver >= MPTCP_VERSION_1) ++ tp->mpcb->send_mptcpv1_mpcapable = 1; ++ + tp->mptcp->include_mpc = 1; + + /* Ensure that fastopen is handled at the meta-level. */ @@ -16620,8 +16839,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i +} diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c --- linux-5.4/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,427 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,430 @@ +/* + * MPTCP implementation - IPv4-specific functions + * @@ -16730,6 +16949,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip + int loc_id; + bool low_prio = false; + ++ if (!mpcb->rem_key_set) ++ return -1; ++ + /* We need to do this as early as possible. Because, if we fail later + * (e.g., get_local_id), then reqsk_free tries to remove the + * request-socket from the htb in mptcp_hash_request_remove as pprev @@ -17051,8 +17273,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip +} diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c --- linux-5.4/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,475 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,478 @@ +/* + * MPTCP implementation - IPv6-specific functions + * @@ -17190,6 +17412,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip + int loc_id; + bool low_prio = false; + ++ if (!mpcb->rem_key_set) ++ return -1; ++ + /* We need to do this as early as possible. Because, if we fail later + * (e.g., get_local_id), then reqsk_free tries to remove the + * request-socket from the htb in mptcp_hash_request_remove as pprev @@ -17530,7 +17755,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip +} diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c --- linux-5.4/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,174 @@ +#include + @@ -17708,7 +17933,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mp +MODULE_VERSION("0.88"); diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c --- linux-5.4/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,1271 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP implementation - Netlink Path Manager @@ -18983,7 +19208,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_ALIAS_GENL_FAMILY(MPTCP_GENL_NAME); diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c --- linux-5.4/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,318 @@ +/* + * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: @@ -19305,8 +19530,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_ol +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_output.c --- linux-5.4/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,1900 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,1988 @@ +/* + * MPTCP implementation - Sending side + * @@ -19788,30 +20013,78 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + ptr += mptcp_write_dss_mapping(tp, skb, ptr); +} + ++/* Write the MP_CAPABLE with data-option */ ++static int mptcp_write_mpcapable_data(const struct tcp_sock *tp, ++ struct sk_buff *skb, ++ __be32 *ptr) ++{ ++ struct mp_capable *mpc = (struct mp_capable *)ptr; ++ u8 length; ++ ++ if (tp->mpcb->dss_csum) ++ length = MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM; ++ else ++ length = MPTCPV1_SUB_LEN_CAPABLE_DATA; ++ ++ mpc->kind = TCPOPT_MPTCP; ++ mpc->len = length; ++ mpc->sub = MPTCP_SUB_CAPABLE; ++ mpc->ver = MPTCP_VERSION_1; ++ mpc->a = tp->mpcb->dss_csum; ++ mpc->b = 0; ++ mpc->rsv = 0; ++ mpc->h = 1; ++ ++ ptr++; ++ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); ++ ++ mpc->sender_key = tp->mpcb->mptcp_loc_key; ++ mpc->receiver_key = tp->mpcb->mptcp_rem_key; ++ ++ /* dss is in a union with inet_skb_parm and ++ * the IP layer expects zeroed IPCB fields. ++ */ ++ memset(TCP_SKB_CB(skb)->dss, 0, mptcp_dss_len); ++ ++ return MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN / sizeof(*ptr); ++} ++ +/* Write the saved DSS mapping to the header */ +static int mptcp_write_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb, + __be32 *ptr) +{ ++ int length; + __be32 *start = ptr; + -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); ++ if (tp->mpcb->rem_key_set) { ++ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); + -+ /* update the data_ack */ -+ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); ++ /* update the data_ack */ ++ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); ++ ++ length = mptcp_dss_len / sizeof(*ptr); ++ } else { ++ memcpy(ptr, TCP_SKB_CB(skb)->dss, MPTCP_SUB_LEN_DSS_ALIGN); ++ ++ ptr++; ++ memcpy(ptr, TCP_SKB_CB(skb)->dss + 2, MPTCP_SUB_LEN_SEQ_ALIGN); ++ ++ length = (MPTCP_SUB_LEN_DSS_ALIGN + MPTCP_SUB_LEN_SEQ_ALIGN) / sizeof(*ptr); ++ } + + /* dss is in a union with inet_skb_parm and + * the IP layer expects zeroed IPCB fields. + */ + memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); + -+ return mptcp_dss_len/sizeof(*ptr); ++ return length; +} + +static bool mptcp_skb_entail(struct sock *sk, struct sk_buff *skb, int reinject) +{ + struct tcp_sock *tp = tcp_sk(sk); + const struct sock *meta_sk = mptcp_meta_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; ++ struct mptcp_cb *mpcb = tp->mpcb; + struct tcp_skb_cb *tcb; + struct sk_buff *subskb = NULL; + @@ -19853,6 +20126,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + + mptcp_save_dss_data_seq(tp, subskb); + ++ if (mpcb->send_mptcpv1_mpcapable) { ++ TCP_SKB_CB(subskb)->mptcp_flags |= MPTCPHDR_MPC_DATA; ++ mpcb->send_mptcpv1_mpcapable = 0; ++ } ++ + tcb->seq = tp->write_seq; + + /* Take into account seg len */ @@ -20160,10 +20438,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + + if (!mptcp_skb_entail(subsk, skb, reinject)) + break; -+ /* Nagle is handled at the MPTCP-layer, so -+ * always push on the subflow -+ */ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); ++ + if (reinject <= 0) + tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); + meta_tp->lsndtime = tcp_jiffies32; @@ -20195,14 +20470,12 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) + continue; + -+ /* We have pushed data on this subflow. We ignore the call to -+ * cwnd_validate in tcp_write_xmit as is_cwnd_limited will never -+ * be true (we never push more than what the cwnd can accept). -+ * We need to ensure that we call tcp_cwnd_validate with -+ * is_cwnd_limited set to true if we have filled the cwnd. ++ mss_now = tcp_current_mss(subsk); ++ ++ /* Nagle is handled at the MPTCP-layer, so ++ * always push on the subflow + */ -+ tcp_cwnd_validate(subsk, tcp_packets_in_flight(subtp) >= -+ subtp->snd_cwnd); ++ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); + } + + return !meta_tp->packets_out && tcp_send_head(meta_sk); @@ -20297,8 +20570,13 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + opts->options |= OPTION_MPTCP; + if (is_master_tp(tp)) { + opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYN; -+ opts->mptcp_ver = tcp_sk(sk)->mptcp_ver; -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ opts->mptcp_ver = tp->mptcp_ver; ++ ++ if (tp->mptcp_ver >= MPTCP_VERSION_1) ++ *remaining -= MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN; ++ else ++ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ + opts->mp_capable.sender_key = tp->mptcp_loc_key; + opts->dss_csum = !!sysctl_mptcp_checksum; + } else { @@ -20326,7 +20604,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + opts->mptcp_ver = mtreq->mptcp_ver; + opts->mp_capable.sender_key = mtreq->mptcp_loc_key; + opts->dss_csum = !!sysctl_mptcp_checksum || mtreq->dss_csum; -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ if (mtreq->mptcp_ver >= MPTCP_VERSION_1) { ++ *remaining -= MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN; ++ } else { ++ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; ++ } + } else { + opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYNACK; + opts->mp_join_syns.sender_truncated_mac = @@ -20389,7 +20671,12 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + opts->options |= OPTION_MPTCP; + opts->mptcp_options |= OPTION_MP_CAPABLE | + OPTION_TYPE_ACK; -+ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; ++ ++ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) ++ *size += MPTCPV1_SUB_LEN_CAPABLE_ACK_ALIGN; ++ else ++ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; ++ + opts->mptcp_ver = mpcb->mptcp_ver; + opts->mp_capable.sender_key = mpcb->mptcp_loc_key; + opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; @@ -20420,14 +20707,20 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + /* If !skb, we come from tcp_current_mss and thus we always + * assume that the DSS-option will be set for the data-packet. + */ -+ if (skb && !mptcp_is_data_seq(skb)) { ++ if (skb && !mptcp_is_data_seq(skb) && mpcb->rem_key_set) { + *size += MPTCP_SUB_LEN_ACK_ALIGN; ++ } else if ((skb && mptcp_is_data_mpcapable(skb)) || ++ (!skb && tp->mpcb->send_mptcpv1_mpcapable)) { ++ *size += MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN; + } else { + /* Doesn't matter, if csum included or not. It will be + * either 10 or 12, and thus aligned = 12 + */ -+ *size += MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; ++ if (mpcb->rem_key_set) ++ *size += MPTCP_SUB_LEN_ACK_ALIGN + ++ MPTCP_SUB_LEN_SEQ_ALIGN; ++ else ++ *size += MPTCP_SUB_LEN_SEQ_ALIGN; + } + + *size += MPTCP_SUB_LEN_DSS_ALIGN; @@ -20480,18 +20773,36 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + + mpc->kind = TCPOPT_MPTCP; + -+ if ((OPTION_TYPE_SYN & opts->mptcp_options) || -+ (OPTION_TYPE_SYNACK & opts->mptcp_options)) { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; ++ if (OPTION_TYPE_SYN & opts->mptcp_options) { + mpc->ver = opts->mptcp_ver; -+ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { ++ ++ if (mpc->ver >= MPTCP_VERSION_1) { ++ mpc->len = MPTCPV1_SUB_LEN_CAPABLE_SYN; ++ ptr += MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; ++ } else { ++ mpc->sender_key = opts->mp_capable.sender_key; ++ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; ++ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; ++ } ++ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { ++ mpc->ver = opts->mptcp_ver; ++ ++ if (mpc->ver >= MPTCP_VERSION_1) { ++ mpc->len = MPTCPV1_SUB_LEN_CAPABLE_SYNACK; ++ ptr += MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN >> 2; ++ } else { ++ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; ++ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; ++ } ++ + mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->receiver_key = opts->mp_capable.receiver_key; ++ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { + mpc->len = MPTCP_SUB_LEN_CAPABLE_ACK; + mpc->ver = opts->mptcp_ver; + ptr += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN >> 2; ++ ++ mpc->sender_key = opts->mp_capable.sender_key; ++ mpc->receiver_key = opts->mp_capable.receiver_key; + } + + mpc->sub = MPTCP_SUB_CAPABLE; @@ -20621,8 +20932,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + } + + if (OPTION_DATA_ACK & opts->mptcp_options) { -+ if (!mptcp_is_data_seq(skb)) ++ if (!mptcp_is_data_seq(skb) && tp->mpcb->rem_key_set) + ptr += mptcp_write_dss_data_ack(tp, skb, ptr); ++ else if (mptcp_is_data_mpcapable(skb)) ++ ptr += mptcp_write_mpcapable_data(tp, skb, ptr); + else + ptr += mptcp_write_dss_data_seq(tp, skb, ptr); + } @@ -21209,7 +21522,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c --- linux-5.4/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,226 @@ +/* + * MPTCP implementation - MPTCP-subflow-management @@ -21439,8 +21752,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c +late_initcall(mptcp_path_manager_default); diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c --- linux-5.4/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,389 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,392 @@ +/* + * MPTCP Scheduler to reduce latency and jitter. + * @@ -21630,7 +21943,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mpt +{ + struct tcp_sock *meta_tp = tcp_sk(meta_sk); + -+ if (red_p->skb && !after(red_p->skb_end_seq, meta_tp->snd_una)) ++ if (red_p->skb && ++ (!after(red_p->skb_end_seq, meta_tp->snd_una) || ++ after(red_p->skb_end_seq, meta_tp->snd_nxt))) + red_p->skb = NULL; +} + @@ -21642,7 +21957,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mpt + struct sk_buff *skb; + + if (!previous) -+ return skb_peek(queue); ++ return tcp_rtx_queue_head(meta_sk) ? : skb_peek(queue); + + /* sk_data->skb stores the last scheduled packet for this subflow. + * If sk_data->skb was scheduled but not sent (e.g., due to nagle), @@ -21689,7 +22004,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mpt + *limit = 0; + + if (skb_queue_empty(&mpcb->reinject_queue) && -+ skb_queue_empty(&meta_sk->sk_write_queue)) ++ skb_queue_empty(&meta_sk->sk_write_queue) && ++ tcp_rtx_queue_empty(meta_sk)) + /* Nothing to send */ + return NULL; + @@ -21832,7 +22148,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mpt +MODULE_VERSION("0.90"); diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c --- linux-5.4/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,309 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -22145,8 +22461,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c +MODULE_VERSION("0.89"); diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c --- linux-5.4/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-02-20 18:07:47.000000000 +0100 -@@ -0,0 +1,634 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-05-16 10:39:52.000000000 +0200 +@@ -0,0 +1,646 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + +#include @@ -22225,7 +22541,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + */ + space = (tp->snd_cwnd - in_flight) * tp->mss_cache; + -+ if (tp->write_seq - tp->snd_nxt > space) ++ if (tp->write_seq - tp->snd_nxt >= space) + return true; + + if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) @@ -22540,10 +22856,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + unsigned int *limit) +{ + struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); -+ unsigned int mss_now; ++ unsigned int mss_now, in_flight_space; ++ int remaining_in_flight_space; ++ u32 max_len, max_segs, window; + struct tcp_sock *subtp; + u16 gso_max_segs; -+ u32 max_len, max_segs, window, needed; + + /* As we set it, we have to reset it as well. */ + *limit = 0; @@ -22573,9 +22890,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + /* The following is similar to tcp_mss_split_point, but + * we do not care about nagle, because we will anyways + * use TCP_NAGLE_PUSH, which overrides this. -+ * -+ * So, we first limit according to the cwnd/gso-size and then according -+ * to the subflow's window. + */ + + gso_max_segs = (*subsk)->sk_gso_max_segs; @@ -22585,16 +22899,30 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + if (!max_segs) + return NULL; + -+ max_len = mss_now * max_segs; ++ /* max_len is what would fit in the cwnd (respecting the 2GSO-limit of ++ * tcp_cwnd_test), but ignoring whatever was already queued. ++ */ ++ max_len = min(mss_now * max_segs, skb->len); ++ ++ in_flight_space = (subtp->snd_cwnd - tcp_packets_in_flight(subtp)) * mss_now; ++ remaining_in_flight_space = (int)in_flight_space - (subtp->write_seq - subtp->snd_nxt); ++ ++ if (remaining_in_flight_space <= 0) ++ WARN_ONCE(1, "in_flight %u cwnd %u wseq %u snxt %u mss_now %u cache %u", ++ tcp_packets_in_flight(subtp), subtp->snd_cwnd, ++ subtp->write_seq, subtp->snd_nxt, mss_now, subtp->mss_cache); ++ else ++ /* max_len now fits exactly in the write-queue, taking into ++ * account what was already queued. ++ */ ++ max_len = min_t(u32, max_len, remaining_in_flight_space); ++ + window = tcp_wnd_end(subtp) - subtp->write_seq; + -+ needed = min(skb->len, window); -+ if (max_len <= skb->len) -+ /* Take max_win, which is actually the cwnd/gso-size */ -+ *limit = max_len; -+ else -+ /* Or, take the window */ -+ *limit = needed; ++ /* max_len now also respects the announced receive-window */ ++ max_len = min(max_len, window); ++ ++ *limit = max_len; + + return skb; +} @@ -22783,7 +23111,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s +late_initcall(mptcp_scheduler_default); diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c --- linux-5.4/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-05-16 10:39:52.000000000 +0200 @@ -0,0 +1,271 @@ +/* + * MPTCP implementation - WEIGHTED VEGAS @@ -23058,7 +23386,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_VERSION("0.1"); diff -aurN linux-5.4/tools/include/uapi/linux/bpf.h mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h --- linux-5.4/tools/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-02-20 18:07:47.000000000 +0100 ++++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-05-16 10:39:52.000000000 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ diff --git a/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch b/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch deleted file mode 100644 index 372825f6..00000000 --- a/root/target/linux/generic/hack-5.4/693-mptcp-fixes.patch +++ /dev/null @@ -1,1851 +0,0 @@ -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/include/net/mptcp.h mptcp/include/net/mptcp.h ---- mptcp-mptcp_trunk/include/net/mptcp.h 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/include/net/mptcp.h 2020-05-14 15:15:39.929940266 +0200 -@@ -102,7 +102,8 @@ - - u8 loc_id; - u8 rem_id; /* Address-id in the MP_JOIN */ -- u8 dss_csum:1, -+ u16 dss_csum:1, -+ rem_key_set:1, - is_sub:1, /* Is this a new subflow? */ - low_prio:1, /* Interface set to low-prio? */ - rcv_low_prio:1, -@@ -240,7 +241,6 @@ - struct module *owner; - }; - --#define MPTCP_SCHED_NAME_MAX 16 - struct mptcp_sched_ops { - struct list_head list; - -@@ -272,6 +272,8 @@ - u32 rcv_high_order[2]; - - u16 send_infinite_mapping:1, -+ send_mptcpv1_mpcapable:1, -+ rem_key_set:1, - in_time_wait:1, - list_rcvd:1, /* XXX TO REMOVE */ - addr_signal:1, /* Path-manager wants us to call addr_signal */ -@@ -354,6 +356,16 @@ - #define MPTCP_SUB_LEN_CAPABLE_ACK 20 - #define MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN 20 - -+#define MPTCPV1_SUB_LEN_CAPABLE_SYN 4 -+#define MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN 4 -+#define MPTCPV1_SUB_LEN_CAPABLE_SYNACK 12 -+#define MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN 12 -+#define MPTCPV1_SUB_LEN_CAPABLE_ACK 20 -+#define MPTCPV1_SUB_LEN_CAPABLE_ACK_ALIGN 20 -+#define MPTCPV1_SUB_LEN_CAPABLE_DATA 22 -+#define MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM 22 -+#define MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN 24 -+ - #define MPTCP_SUB_JOIN 1 - #define MPTCP_SUB_LEN_JOIN_SYN 12 - #define MPTCP_SUB_LEN_JOIN_SYN_ALIGN 12 -@@ -450,14 +462,15 @@ - #define MPTCPHDR_SEQ 0x01 /* DSS.M option is present */ - #define MPTCPHDR_FIN 0x02 /* DSS.F option is present */ - #define MPTCPHDR_SEQ64_INDEX 0x04 /* index of seq in mpcb->snd_high_order */ -+#define MPTCPHDR_MPC_DATA 0x08 - /* MPTCP flags: RX only */ --#define MPTCPHDR_ACK 0x08 --#define MPTCPHDR_SEQ64_SET 0x10 /* Did we received a 64-bit seq number? */ --#define MPTCPHDR_SEQ64_OFO 0x20 /* Is it not in our circular array? */ --#define MPTCPHDR_DSS_CSUM 0x40 -+#define MPTCPHDR_ACK 0x10 -+#define MPTCPHDR_SEQ64_SET 0x20 /* Did we received a 64-bit seq number? */ -+#define MPTCPHDR_SEQ64_OFO 0x40 /* Is it not in our circular array? */ -+#define MPTCPHDR_DSS_CSUM 0x80 - /* MPTCP flags: TX only */ --#define MPTCPHDR_INF 0x08 --#define MPTCP_REINJECT 0x10 /* Did we reinject this segment? */ -+#define MPTCPHDR_INF 0x10 -+#define MPTCP_REINJECT 0x20 /* Did we reinject this segment? */ - - struct mptcp_option { - __u8 kind; -@@ -800,10 +813,11 @@ - void mptcp_close(struct sock *meta_sk, long timeout); - bool mptcp_doit(struct sock *sk); - int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -- __u8 mptcp_ver, u32 window); -+ int rem_key_set, __u8 mptcp_ver, u32 window); - int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req); - int mptcp_check_req_master(struct sock *sk, struct sock *child, - struct request_sock *req, const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, - int drop, u32 tsoff); - struct sock *mptcp_check_req_child(struct sock *meta_sk, - struct sock *child, -@@ -816,8 +830,8 @@ - int wscale_ok, __u8 *rcv_wscale, - __u32 init_rcv_wnd); - unsigned int mptcp_current_mss(struct sock *meta_sk); --void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -- int arg_num, ...); -+void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...); - void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); - void mptcp_fin(struct sock *meta_sk); - void mptcp_meta_retransmit_timer(struct sock *meta_sk); -@@ -827,6 +841,8 @@ - void mptcp_sub_close(struct sock *sk, unsigned long delay); - struct sock *mptcp_select_ack_sock(const struct sock *meta_sk); - void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb); -+void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb, -+ __u64 remote_key); - int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb); - void mptcp_ack_handler(struct timer_list *t); - bool mptcp_check_rtt(const struct tcp_sock *tp, int time); -@@ -982,6 +998,11 @@ - } - } - -+static inline bool mptcp_is_data_mpcapable(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_MPC_DATA; -+} -+ - static inline bool mptcp_is_data_seq(const struct sk_buff *skb) - { - return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ; -@@ -1399,6 +1420,7 @@ - const struct sock *child, - const struct request_sock *req, - const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, - int drop, - u32 tsoff) - { -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/include/net/tcp.h mptcp/include/net/tcp.h ---- mptcp-mptcp_trunk/include/net/tcp.h 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/include/net/tcp.h 2020-05-14 15:15:27.126152589 +0200 -@@ -343,7 +343,6 @@ - struct mptcp_options_received; - - void tcp_cleanup_rbuf(struct sock *sk, int copied); --void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited); - int tcp_close_state(struct sock *sk); - void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, - const struct sk_buff *skb); -@@ -583,6 +582,7 @@ - /* From syncookies.c */ - struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, - struct request_sock *req, -+ const struct mptcp_options_received *mopt, - struct dst_entry *dst, u32 tsoff); - int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, - u32 cookie); -@@ -2126,7 +2126,6 @@ - void (*retransmit_timer)(struct sock *sk); - void (*time_wait)(struct sock *sk, int state, int timeo); - void (*cleanup_rbuf)(struct sock *sk, int copied); -- void (*cwnd_validate)(struct sock *sk, bool is_cwnd_limited); - int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, - bool reinit, bool cap_net_admin); - }; -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv4/syncookies.c mptcp/net/ipv4/syncookies.c ---- mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/ipv4/syncookies.c 2020-05-14 15:15:27.126152589 +0200 -@@ -203,6 +203,7 @@ - - struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, - struct request_sock *req, -+ const struct mptcp_options_received *mopt, - struct dst_entry *dst, u32 tsoff) - { - struct inet_connection_sock *icsk = inet_csk(sk); -@@ -219,7 +220,7 @@ - if (!child) - goto listen_overflow; - -- ret = mptcp_check_req_master(sk, child, req, skb, 0, tsoff); -+ ret = mptcp_check_req_master(sk, child, req, skb, mopt, 0, tsoff); - if (ret < 0) - return NULL; - -@@ -428,7 +429,7 @@ - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); - -- ret = tcp_get_cookie_sock(sk, skb, req, &rt->dst, tsoff); -+ ret = tcp_get_cookie_sock(sk, skb, req, &mopt, &rt->dst, tsoff); - /* ip_queue_xmit() depends on our flow being setup - * Normal sockets get it right from inet_csk_route_child_sock() - */ -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv4/tcp.c mptcp/net/ipv4/tcp.c ---- mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/ipv4/tcp.c 2020-05-11 09:40:04.803741955 +0200 -@@ -415,7 +415,6 @@ - .retransmit_timer = tcp_retransmit_timer, - .time_wait = tcp_time_wait, - .cleanup_rbuf = tcp_cleanup_rbuf, -- .cwnd_validate = tcp_cwnd_validate, - .set_cong_ctrl = __tcp_set_congestion_control, - }; - -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c mptcp/net/ipv4/tcp_minisocks.c ---- mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/ipv4/tcp_minisocks.c 2020-05-14 15:15:27.138152390 +0200 -@@ -828,7 +828,7 @@ - goto listen_overflow; - - if (own_req && !is_meta_sk(sk)) { -- int ret = mptcp_check_req_master(sk, child, req, skb, 1, 0); -+ int ret = mptcp_check_req_master(sk, child, req, skb, &mopt, 1, 0); - if (ret < 0) - goto listen_overflow; - -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv4/tcp_output.c mptcp/net/ipv4/tcp_output.c ---- mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/ipv4/tcp_output.c 2020-05-11 09:40:04.803741955 +0200 -@@ -825,8 +825,8 @@ - if (mptcp(tp)) - tcp_tsq_write(meta_sk); - } else { -- if (!test_and_set_bit(TCP_TSQ_DEFERRED, &meta_sk->sk_tsq_flags)) -- sock_hold(meta_sk); -+ if (!test_and_set_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags)) -+ sock_hold(sk); - - if ((mptcp(tp)) && (sk->sk_state != TCP_CLOSE)) - mptcp_tsq_flags(sk); -@@ -1672,7 +1672,7 @@ - tp->snd_cwnd_stamp = tcp_jiffies32; - } - --void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) -+static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) - { - const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; - struct tcp_sock *tp = tcp_sk(sk); -@@ -2512,8 +2512,7 @@ - if (push_one != 2) - tcp_schedule_loss_probe(sk, false); - is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); -- if (tp->ops->cwnd_validate) -- tp->ops->cwnd_validate(sk, is_cwnd_limited); -+ tcp_cwnd_validate(sk, is_cwnd_limited); - return false; - } - return !tp->packets_out && !tcp_write_queue_empty(sk); -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/ipv6/syncookies.c mptcp/net/ipv6/syncookies.c ---- mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/ipv6/syncookies.c 2020-05-14 15:15:27.142152325 +0200 -@@ -267,7 +267,7 @@ - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); - -- ret = tcp_get_cookie_sock(sk, skb, req, dst, tsoff); -+ ret = tcp_get_cookie_sock(sk, skb, req, &mopt, dst, tsoff); - out: - return ret; - out_free: -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c mptcp/net/mptcp/mptcp_ctrl.c ---- mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_ctrl.c 2020-05-14 15:15:39.953939868 +0200 -@@ -27,6 +27,8 @@ - * 2 of the License, or (at your option) any later version. - */ - -+#include -+ - #include - #include - #include -@@ -77,7 +79,7 @@ - struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; - EXPORT_SYMBOL(mptcp_static_key); - --static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn); -+static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn); - - static int proc_mptcp_path_manager(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, -@@ -286,7 +288,7 @@ - #endif - } - -- mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+ mptcp_key_hash(mtreq->mptcp_ver, mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); - } - - /* New MPTCP-connection request, prepare a new token for the meta-socket that -@@ -319,7 +321,11 @@ - spin_unlock(&mptcp_tk_hashlock); - local_bh_enable(); - rcu_read_unlock(); -- mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ -+ if (mtreq->mptcp_ver == MPTCP_VERSION_0) { -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->rem_key_set = 1; -+ } - } - - static int mptcp_reqsk_new_cookie(struct request_sock *req, -@@ -355,7 +361,10 @@ - local_bh_enable(); - rcu_read_unlock(); - -- mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ if (mtreq->mptcp_ver == MPTCP_VERSION_0) { -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->rem_key_set = 1; -+ } - - return true; - } -@@ -380,8 +389,7 @@ - mptcp_seed++); - #endif - -- mptcp_key_sha1(tp->mptcp_loc_key, -- &tp->mptcp_loc_token, NULL); -+ mptcp_key_hash(tp->mptcp_ver, tp->mptcp_loc_key, &tp->mptcp_loc_token, NULL); - } - - #ifdef CONFIG_JUMP_LABEL -@@ -835,6 +843,71 @@ - siphash_key_t mptcp_secret __read_mostly; - u32 mptcp_seed = 0; - -+#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / 4) -+ -+static void mptcp_key_sha256(const u64 key, u32 *token, u64 *idsn) -+{ -+ u32 mptcp_hashed_key[SHA256_DIGEST_WORDS]; -+ struct sha256_state state; -+ -+ sha256_init(&state); -+ sha256_update(&state, (const u8 *)&key, sizeof(key)); -+ sha256_final(&state, (u8 *)mptcp_hashed_key); -+ -+ if (token) -+ *token = mptcp_hashed_key[0]; -+ if (idsn) -+ *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[6])); -+} -+ -+static void mptcp_hmac_sha256(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, va_list list) -+{ -+ u8 input[SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE]; -+ __be32 output[SHA256_DIGEST_WORDS]; -+ struct sha256_state state; -+ int index, msg_length; -+ int length = 0; -+ u8 *msg; -+ int i; -+ -+ /* Generate key xored with ipad */ -+ memset(input, 0x36, SHA256_BLOCK_SIZE); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ index = SHA256_BLOCK_SIZE; -+ msg_length = 0; -+ for (i = 0; i < arg_num; i++) { -+ length = va_arg(list, int); -+ msg = va_arg(list, u8 *); -+ BUG_ON(index + length >= sizeof(input)); /* Message is too long */ -+ memcpy(&input[index], msg, length); -+ index += length; -+ msg_length += length; -+ } -+ -+ sha256_init(&state); -+ sha256_update(&state, input, SHA256_BLOCK_SIZE + msg_length); -+ sha256_final(&state, &input[SHA256_BLOCK_SIZE]); -+ -+ /* Prepare second part of hmac */ -+ memset(input, 0x5C, SHA256_BLOCK_SIZE); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ sha256_init(&state); -+ sha256_update(&state, input, sizeof(input)); -+ sha256_final(&state, (u8 *)output); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = output[i]; -+} -+ - static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) - { - u32 workspace[SHA_WORKSPACE_WORDS]; -@@ -864,8 +937,16 @@ - *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[3])); - } - --void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -- int arg_num, ...) -+static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn) -+{ -+ if (version == MPTCP_VERSION_0) -+ mptcp_key_sha1(key, token, idsn); -+ else if (version >= MPTCP_VERSION_1) -+ mptcp_key_sha256(key, token, idsn); -+} -+ -+static void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, va_list list) - { - u32 workspace[SHA_WORKSPACE_WORDS]; - u8 input[128]; /* 2 512-bit blocks */ -@@ -873,7 +954,6 @@ - int index; - int length; - u8 *msg; -- va_list list; - - memset(workspace, 0, sizeof(workspace)); - -@@ -884,7 +964,6 @@ - for (i = 0; i < 8; i++) - input[i + 8] ^= key_2[i]; - -- va_start(list, arg_num); - index = 64; - for (i = 0; i < arg_num; i++) { - length = va_arg(list, int); -@@ -893,7 +972,6 @@ - memcpy(&input[index], msg, length); - index += length; - } -- va_end(list); - - input[index] = 0x80; /* Padding: First bit after message = 1 */ - memset(&input[index + 1], 0, (126 - index)); -@@ -936,7 +1014,20 @@ - for (i = 0; i < 5; i++) - hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); - } --EXPORT_SYMBOL(mptcp_hmac_sha1); -+ -+void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...) -+{ -+ va_list args; -+ -+ va_start(args, arg_num); -+ if (ver == MPTCP_VERSION_0) -+ mptcp_hmac_sha1(key_1, key_2, hash_out, arg_num, args); -+ else if (ver >= MPTCP_VERSION_1) -+ mptcp_hmac_sha256(key_1, key_2, hash_out, arg_num, args); -+ va_end(args); -+} -+EXPORT_SYMBOL(mptcp_hmac); - - static void mptcp_mpcb_inherit_sockopts(struct sock *meta_sk, struct sock *master_sk) - { -@@ -1169,14 +1260,33 @@ - .set_cong_ctrl = __tcp_set_congestion_control, - }; - -+void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb, -+ __u64 remote_key) -+{ -+ u64 idsn; -+ -+ mpcb->mptcp_rem_key = remote_key; -+ mpcb->rem_key_set = 1; -+ mptcp_key_hash(mpcb->mptcp_ver, mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &idsn); -+ -+ idsn++; -+ mpcb->rcv_high_order[0] = idsn >> 32; -+ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; -+ meta_tp->copied_seq = (u32)idsn; -+ meta_tp->rcv_nxt = (u32)idsn; -+ meta_tp->rcv_wup = (u32)idsn; -+ -+ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; -+} -+ - static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, -- __u8 mptcp_ver, u32 window) -+ int rem_key_set, __u8 mptcp_ver, u32 window) - { - struct mptcp_cb *mpcb; - struct sock *master_sk; - struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); - struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk); -- u64 snd_idsn, rcv_idsn; -+ u64 snd_idsn; - - dst_release(meta_sk->sk_rx_dst); - meta_sk->sk_rx_dst = NULL; -@@ -1204,17 +1314,11 @@ - mpcb->mptcp_loc_token = meta_tp->mptcp_loc_token; - - /* Generate Initial data-sequence-numbers */ -- mptcp_key_sha1(mpcb->mptcp_loc_key, NULL, &snd_idsn); -+ mptcp_key_hash(mpcb->mptcp_ver, mpcb->mptcp_loc_key, NULL, &snd_idsn); - snd_idsn++; - mpcb->snd_high_order[0] = snd_idsn >> 32; - mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1; - -- mpcb->mptcp_rem_key = remote_key; -- mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &rcv_idsn); -- rcv_idsn++; -- mpcb->rcv_high_order[0] = rcv_idsn >> 32; -- mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; -- - mpcb->meta_sk = meta_sk; - mpcb->master_sk = master_sk; - -@@ -1326,11 +1430,9 @@ - meta_tp->pushed_seq = meta_tp->write_seq; - meta_tp->snd_up = meta_tp->write_seq; - -- meta_tp->copied_seq = (u32)rcv_idsn; -- meta_tp->rcv_nxt = (u32)rcv_idsn; -- meta_tp->rcv_wup = (u32)rcv_idsn; -+ if (rem_key_set) -+ mptcp_initialize_recv_vars(meta_tp, mpcb, remote_key); - -- meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; - meta_tp->snd_wnd = window; - meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */ - -@@ -2077,12 +2179,12 @@ - } - - int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -- __u8 mptcp_ver, u32 window) -+ int rem_key_set, __u8 mptcp_ver, u32 window) - { - struct tcp_sock *master_tp; - struct sock *master_sk; - -- if (mptcp_alloc_mpcb(meta_sk, remote_key, mptcp_ver, window)) -+ if (mptcp_alloc_mpcb(meta_sk, remote_key, rem_key_set, mptcp_ver, window)) - goto err_alloc_mpcb; - - master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -@@ -2110,6 +2212,7 @@ - } - - static int __mptcp_check_req_master(struct sock *child, -+ const struct mptcp_options_received *mopt, - struct request_sock *req) - { - struct tcp_sock *child_tp = tcp_sk(child); -@@ -2121,6 +2224,8 @@ - if (!inet_rsk(req)->mptcp_rqsk) - return 1; - -+ mtreq = mptcp_rsk(req); -+ - if (!inet_rsk(req)->saw_mpc) { - /* Fallback to regular TCP, because we saw one SYN without - * MP_CAPABLE. In tcp_check_req we continue the regular path. -@@ -2132,15 +2237,21 @@ - return 1; - } - -+ /* mopt can be NULL when coming from FAST-OPEN */ -+ if (mopt && mopt->saw_mpc && mtreq->mptcp_ver == MPTCP_VERSION_1) { -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->rem_key_set = 1; -+ } -+ - MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK); - - /* Just set this values to pass them to mptcp_alloc_mpcb */ -- mtreq = mptcp_rsk(req); - child_tp->mptcp_loc_key = mtreq->mptcp_loc_key; - child_tp->mptcp_loc_token = mtreq->mptcp_loc_token; - - if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, -- mtreq->mptcp_ver, child_tp->snd_wnd)) { -+ mtreq->rem_key_set, mtreq->mptcp_ver, -+ child_tp->snd_wnd)) { - inet_csk_prepare_forced_close(meta_sk); - tcp_done(meta_sk); - -@@ -2175,7 +2286,7 @@ - u32 new_mapping; - int ret; - -- ret = __mptcp_check_req_master(child, req); -+ ret = __mptcp_check_req_master(child, NULL, req); - if (ret) - return ret; - -@@ -2218,12 +2329,13 @@ - - int mptcp_check_req_master(struct sock *sk, struct sock *child, - struct request_sock *req, const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, - int drop, u32 tsoff) - { - struct sock *meta_sk = child; - int ret; - -- ret = __mptcp_check_req_master(child, req); -+ ret = __mptcp_check_req_master(child, mopt, req); - if (ret) - return ret; - child = tcp_sk(child)->mpcb->master_sk; -@@ -2281,11 +2393,10 @@ - goto teardown; - } - -- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -- (u8 *)&mpcb->mptcp_loc_key, -- (u32 *)hash_mac_check, 2, -- 4, (u8 *)&mtreq->mptcp_rem_nonce, -- 4, (u8 *)&mtreq->mptcp_loc_nonce); -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce); - - if (memcmp(hash_mac_check, (char *)&mopt->mptcp_recv_mac, 20)) { - MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKMAC); -@@ -2547,11 +2658,10 @@ - - mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; - -- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -- (u8 *)&mpcb->mptcp_rem_key, -- (u32 *)mptcp_hash_mac, 2, -- 4, (u8 *)&mtreq->mptcp_loc_nonce, -- 4, (u8 *)&mtreq->mptcp_rem_nonce); -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, (u32 *)mptcp_hash_mac, 2, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce); - mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; - - mtreq->rem_id = mopt.rem_id; -@@ -2591,11 +2701,13 @@ - /* Absolutely need to always initialize this. */ - mtreq->hash_entry.pprev = NULL; - -+ mtreq->mptcp_ver = mopt->mptcp_ver; - mtreq->mptcp_rem_key = mopt->mptcp_sender_key; - mtreq->mptcp_loc_key = mopt->mptcp_receiver_key; -+ mtreq->rem_key_set = 1; - - /* Generate the token */ -- mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+ mptcp_key_hash(mtreq->mptcp_ver, mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); - - rcu_read_lock(); - local_bh_disable(); -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c mptcp/net/mptcp/mptcp_fullmesh.c ---- mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_fullmesh.c 2020-05-14 15:15:39.957939801 +0200 -@@ -1596,11 +1596,10 @@ - u8 no_key[8]; - - *(u64 *)no_key = 0; -- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -- (u8 *)no_key, -- (u32 *)mptcp_hash_mac, 2, -- 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, -- 4, (u8 *)&opts->add_addr4.addr.s_addr); -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, -+ 4, (u8 *)&opts->add_addr4.addr.s_addr); - opts->add_addr4.trunc_mac = *(u64 *)mptcp_hash_mac; - } - -@@ -1639,11 +1638,10 @@ - u8 no_key[8]; - - *(u64 *)no_key = 0; -- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -- (u8 *)no_key, -- (u32 *)mptcp_hash_mac, 2, -- 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, -- 16, (u8 *)&opts->add_addr6.addr.s6_addr); -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, -+ 16, (u8 *)&opts->add_addr6.addr.s6_addr); - opts->add_addr6.trunc_mac = *(u64 *)mptcp_hash_mac; - } - -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_input.c mptcp/net/mptcp/mptcp_input.c ---- mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_input.c 2020-05-14 15:15:39.965939670 +0200 -@@ -176,6 +176,10 @@ - } - - /* Inspired by tcp_rcv_state_process */ -+/* Returns 0 if processing the packet can continue -+ * -1 if connection was closed with an active reset -+ * 1 if connection was closed and processing should stop. -+ */ - static int mptcp_rcv_state_process(struct sock *meta_sk, struct sock *sk, - const struct sk_buff *skb, u32 data_seq, - u16 data_len) -@@ -216,7 +220,7 @@ - mptcp_send_active_reset(meta_sk, GFP_ATOMIC); - tcp_done(meta_sk); - __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -- return 1; -+ return -1; - } - - tmo = tcp_fin_time(meta_sk); -@@ -259,7 +263,7 @@ - __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); - mptcp_send_active_reset(meta_sk, GFP_ATOMIC); - tcp_reset(meta_sk); -- return 1; -+ return -1; - } - } - break; -@@ -344,6 +348,17 @@ - sizeof(data_seq), csum_tcp); - - dss_csum_added = 1; /* Just do it once */ -+ } else if (mptcp_is_data_mpcapable(tmp) && !dss_csum_added) { -+ u32 offset = skb_transport_offset(tmp) + TCP_SKB_CB(tmp)->dss_off; -+ __be64 data_seq = htonll(tp->mptcp->map_data_seq); -+ __be32 rel_seq = htonl(tp->mptcp->map_subseq - tp->mptcp->rcv_isn); -+ -+ csum_tcp = csum_partial(&data_seq, sizeof(data_seq), csum_tcp); -+ csum_tcp = csum_partial(&rel_seq, sizeof(rel_seq), csum_tcp); -+ -+ csum_tcp = skb_checksum(tmp, offset, 4, csum_tcp); -+ -+ dss_csum_added = 1; - } - last = tmp; - iter++; -@@ -554,11 +569,12 @@ - * this segment, this path has to fallback to infinite or be torn down. - */ - if (!tp->mptcp->fully_established && !mptcp_is_data_seq(skb) && -+ !mptcp_is_data_mpcapable(skb) && - !tp->mptcp->mapping_present && !mpcb->infinite_mapping_rcv) { -- pr_debug("%s %#x will fallback - pi %d from %pS, seq %u\n", -+ pr_debug("%s %#x will fallback - pi %d from %pS, seq %u mptcp-flags %#x\n", - __func__, mpcb->mptcp_loc_token, - tp->mptcp->path_index, __builtin_return_address(0), -- TCP_SKB_CB(skb)->seq); -+ TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->mptcp_flags); - - if (!is_master_tp(tp)) { - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATASUB); -@@ -666,25 +682,36 @@ - return 0; - } - -- /* No mapping here? Exit - it is either already set or still on its way */ -- if (!mptcp_is_data_seq(skb)) { -- /* Too many packets without a mapping - this subflow is broken */ -+ if (!tp->mptcp->mapping_present && mptcp_is_data_mpcapable(skb)) { -+ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); -+ -+ sub_seq = 1 + tp->mptcp->rcv_isn; -+ data_seq = meta_tp->rcv_nxt; -+ data_len = get_unaligned_be16(ptr); -+ } else if (!mptcp_is_data_seq(skb)) { -+ /* No mapping here? -+ * Exit - it is either already set or still on its way -+ */ - if (!tp->mptcp->mapping_present && - tp->rcv_nxt - tp->copied_seq > 65536) { -+ /* Too many packets without a mapping, -+ * this subflow is broken -+ */ - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); - mptcp_send_reset(sk); - return 1; - } - - return 0; -+ } else { -+ /* Well, then the DSS-mapping is there. So, read it! */ -+ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); -+ ptr++; -+ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; -+ ptr++; -+ data_len = get_unaligned_be16(ptr); - } - -- ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); -- ptr++; -- sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; -- ptr++; -- data_len = get_unaligned_be16(ptr); -- - /* If it's an empty skb with DATA_FIN, sub_seq must get fixed. - * The draft sets it to 0, but we really would like to have the - * real value, to have an easy handling afterwards here in this -@@ -1397,7 +1424,7 @@ - } - - /* Handle the DATA_ACK */ --static void mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) -+static int mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) - { - struct sock *meta_sk = mptcp_meta_sk(sk); - struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -@@ -1425,7 +1452,7 @@ - * set by mptcp_clean_rtx_infinite. - */ - if (!(tcb->mptcp_flags & MPTCPHDR_ACK) && !tp->mpcb->infinite_mapping_snd) -- return; -+ return 0; - - if (unlikely(!tp->mptcp->fully_established) && - tp->mptcp->snt_isn + 1 != TCP_SKB_CB(skb)->ack_seq) -@@ -1439,7 +1466,7 @@ - * processing. - */ - if (meta_sk->sk_state == TCP_CLOSE) -- return; -+ return 0; - - /* Get the data_seq */ - if (mptcp_is_data_seq(skb)) { -@@ -1463,6 +1490,9 @@ - if (after(data_ack, meta_tp->snd_nxt)) - goto exit; - -+ /* First valid DATA_ACK, we can stop sending the special MP_CAPABLE */ -+ tp->mpcb->send_mptcpv1_mpcapable = 0; -+ - /*** Now, update the window - inspired by tcp_ack_update_window ***/ - nwin = ntohs(tcp_hdr(skb)->window); - -@@ -1520,14 +1550,19 @@ - meta_sk->sk_write_space(meta_sk); - } - -- if (meta_sk->sk_state != TCP_ESTABLISHED && -- mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len)) -- return; -+ if (meta_sk->sk_state != TCP_ESTABLISHED) { -+ int ret = mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len); -+ -+ if (ret < 0) -+ return 1; -+ else if (ret > 0) -+ return 0; -+ } - - exit: - mptcp_push_pending_frames(meta_sk); - -- return; -+ return 0; - - no_queue: - if (tcp_send_head(meta_sk)) -@@ -1535,7 +1570,7 @@ - - mptcp_push_pending_frames(meta_sk); - -- return; -+ return 0; - } - - void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk) -@@ -1604,6 +1639,7 @@ - struct tcp_sock *tp) - { - const struct mptcp_option *mp_opt = (struct mptcp_option *)ptr; -+ const struct tcphdr *th = tcp_hdr(skb); - - /* If the socket is mp-capable we would have a mopt. */ - if (!mopt) -@@ -1614,9 +1650,21 @@ - { - const struct mp_capable *mpcapable = (struct mp_capable *)ptr; - -- if (opsize != MPTCP_SUB_LEN_CAPABLE_SYN && -- opsize != MPTCP_SUB_LEN_CAPABLE_ACK) { -- mptcp_debug("%s: mp_capable: bad option size %d\n", -+ if (mpcapable->ver == MPTCP_VERSION_0 && -+ ((th->syn && opsize != MPTCP_SUB_LEN_CAPABLE_SYN) || -+ (!th->syn && th->ack && opsize != MPTCP_SUB_LEN_CAPABLE_ACK))) { -+ mptcp_debug("%s: mp_capable v0: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ if (mpcapable->ver == MPTCP_VERSION_1 && -+ ((th->syn && !th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_SYN) || -+ (th->syn && th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_SYNACK) || -+ (!th->syn && th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_ACK && -+ opsize != MPTCPV1_SUB_LEN_CAPABLE_DATA && -+ opsize != MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM))) { -+ mptcp_debug("%s: mp_capable v1: bad option size %d\n", - __func__, opsize); - break; - } -@@ -1640,10 +1688,38 @@ - mopt->saw_mpc = 1; - mopt->dss_csum = sysctl_mptcp_checksum || mpcapable->a; - -- if (opsize >= MPTCP_SUB_LEN_CAPABLE_SYN) -- mopt->mptcp_sender_key = mpcapable->sender_key; -- if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) -- mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ if (mpcapable->ver == MPTCP_VERSION_0) { -+ if (opsize == MPTCP_SUB_LEN_CAPABLE_SYN) -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ -+ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) { -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ } -+ } else if (mpcapable->ver == MPTCP_VERSION_1) { -+ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_SYNACK) -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ -+ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_ACK) { -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ } -+ -+ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA || -+ opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM) { -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_MPC_DATA; -+ -+ ptr += sizeof(struct mp_capable); -+ TCP_SKB_CB(skb)->dss_off = (ptr - skb_transport_header(skb)); -+ -+ /* Is a check-sum present? */ -+ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM) -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_DSS_CSUM; -+ } -+ } - - mopt->mptcp_ver = mpcapable->ver; - break; -@@ -1917,12 +1993,11 @@ - } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { - msg_parts = 3; - } -- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -- (u8 *)no_key, -- (u32 *)hash_mac_check, msg_parts, -- 1, (u8 *)&mpadd->addr_id, -- 4, (u8 *)&mpadd->u.v4.addr.s_addr, -- 2, (u8 *)&mpadd->u.v4.port); -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 4, (u8 *)&mpadd->u.v4.addr.s_addr, -+ 2, (u8 *)&mpadd->u.v4.port); - if (memcmp(hash_mac_check, recv_hmac, 8) != 0) - /* ADD_ADDR2 discarded */ - return; -@@ -1952,12 +2027,11 @@ - } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { - msg_parts = 3; - } -- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -- (u8 *)no_key, -- (u32 *)hash_mac_check, msg_parts, -- 1, (u8 *)&mpadd->addr_id, -- 16, (u8 *)&mpadd->u.v6.addr.s6_addr, -- 2, (u8 *)&mpadd->u.v6.port); -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, -+ 2, (u8 *)&mpadd->u.v6.port); - if (memcmp(hash_mac_check, recv_hmac, 8) != 0) - /* ADD_ADDR2 discarded */ - return; -@@ -2115,6 +2189,10 @@ - if (sk->sk_state == TCP_RST_WAIT && !th->rst) - return true; - -+ if (mopt->saw_mpc && !tp->mpcb->rem_key_set) -+ mptcp_initialize_recv_vars(mptcp_meta_tp(tp), tp->mpcb, -+ mopt->mptcp_sender_key); -+ - if (unlikely(mopt->mp_fail)) - mptcp_mp_fail_rcvd(sk, th); - -@@ -2122,7 +2200,8 @@ - * If a checksum is not present when its use has been negotiated, the - * receiver MUST close the subflow with a RST as it is considered broken. - */ -- if (mptcp_is_data_seq(skb) && tp->mpcb->dss_csum && -+ if ((mptcp_is_data_seq(skb) || mptcp_is_data_mpcapable(skb)) && -+ tp->mpcb->dss_csum && - !(TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_DSS_CSUM)) { - mptcp_send_reset(sk); - return true; -@@ -2171,7 +2250,8 @@ - mopt->saw_low_prio = 0; - } - -- mptcp_data_ack(sk, skb); -+ if (mptcp_data_ack(sk, skb)) -+ return true; - - mptcp_path_array_check(mptcp_meta_sk(sk)); - /* Socket may have been mp_killed by a REMOVE_ADDR */ -@@ -2297,11 +2377,10 @@ - u8 hash_mac_check[20]; - struct mptcp_cb *mpcb = tp->mpcb; - -- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -- (u8 *)&mpcb->mptcp_loc_key, -- (u32 *)hash_mac_check, 2, -- 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, -- 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); - if (memcmp(hash_mac_check, - (char *)&tp->mptcp->rx_opt.mptcp_recv_tmac, 8)) { - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); -@@ -2315,11 +2394,11 @@ - tp->mptcp->pre_established = 1; - tp->mptcp->rcv_low_prio = tp->mptcp->rx_opt.low_prio; - -- mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -- (u8 *)&mpcb->mptcp_rem_key, -- (u32 *)&tp->mptcp->sender_mac[0], 2, -- 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, -- 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)&tp->mptcp->sender_mac[0], 2, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); - - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); - } else if (mopt->saw_mpc) { -@@ -2329,8 +2408,13 @@ - if (mopt->mptcp_ver > tcp_sk(sk)->mptcp_ver) - /* TODO Consider adding new MPTCP_INC_STATS entry */ - goto fallback; -+ if (tcp_sk(sk)->mptcp_ver == MPTCP_VERSION_1 && -+ mopt->mptcp_ver < MPTCP_VERSION_1) -+ /* TODO Consider adding new MPTCP_INC_STATS entry */ -+ /* TODO - record this in the cache - use v0 next time */ -+ goto fallback; - -- if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, -+ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, 1, - mopt->mptcp_ver, - ntohs(tcp_hdr(skb)->window))) - return 2; -@@ -2358,6 +2442,9 @@ - if (tp->mpcb->dss_csum) - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMENABLED); - -+ if (tp->mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ tp->mpcb->send_mptcpv1_mpcapable = 1; -+ - tp->mptcp->include_mpc = 1; - - /* Ensure that fastopen is handled at the meta-level. */ -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c mptcp/net/mptcp/mptcp_ipv4.c ---- mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_ipv4.c 2020-05-14 15:15:27.158152059 +0200 -@@ -106,6 +106,9 @@ - int loc_id; - bool low_prio = false; - -+ if (!mpcb->rem_key_set) -+ return -1; -+ - /* We need to do this as early as possible. Because, if we fail later - * (e.g., get_local_id), then reqsk_free tries to remove the - * request-socket from the htb in mptcp_hash_request_remove as pprev -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c mptcp/net/mptcp/mptcp_ipv6.c ---- mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_ipv6.c 2020-05-14 15:15:27.170151859 +0200 -@@ -135,6 +135,9 @@ - int loc_id; - bool low_prio = false; - -+ if (!mpcb->rem_key_set) -+ return -1; -+ - /* We need to do this as early as possible. Because, if we fail later - * (e.g., get_local_id), then reqsk_free tries to remove the - * request-socket from the htb in mptcp_hash_request_remove as pprev -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_output.c mptcp/net/mptcp/mptcp_output.c ---- mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_output.c 2020-05-14 15:15:27.170151859 +0200 -@@ -479,30 +479,78 @@ - ptr += mptcp_write_dss_mapping(tp, skb, ptr); - } - -+/* Write the MP_CAPABLE with data-option */ -+static int mptcp_write_mpcapable_data(const struct tcp_sock *tp, -+ struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ struct mp_capable *mpc = (struct mp_capable *)ptr; -+ u8 length; -+ -+ if (tp->mpcb->dss_csum) -+ length = MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM; -+ else -+ length = MPTCPV1_SUB_LEN_CAPABLE_DATA; -+ -+ mpc->kind = TCPOPT_MPTCP; -+ mpc->len = length; -+ mpc->sub = MPTCP_SUB_CAPABLE; -+ mpc->ver = MPTCP_VERSION_1; -+ mpc->a = tp->mpcb->dss_csum; -+ mpc->b = 0; -+ mpc->rsv = 0; -+ mpc->h = 1; -+ -+ ptr++; -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); -+ -+ mpc->sender_key = tp->mpcb->mptcp_loc_key; -+ mpc->receiver_key = tp->mpcb->mptcp_rem_key; -+ -+ /* dss is in a union with inet_skb_parm and -+ * the IP layer expects zeroed IPCB fields. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0, mptcp_dss_len); -+ -+ return MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN / sizeof(*ptr); -+} -+ - /* Write the saved DSS mapping to the header */ - static int mptcp_write_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb, - __be32 *ptr) - { -+ int length; - __be32 *start = ptr; - -- memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); -+ if (tp->mpcb->rem_key_set) { -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); -+ -+ /* update the data_ack */ -+ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ length = mptcp_dss_len / sizeof(*ptr); -+ } else { -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, MPTCP_SUB_LEN_DSS_ALIGN); - -- /* update the data_ack */ -- start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ ptr++; -+ memcpy(ptr, TCP_SKB_CB(skb)->dss + 2, MPTCP_SUB_LEN_SEQ_ALIGN); -+ -+ length = (MPTCP_SUB_LEN_DSS_ALIGN + MPTCP_SUB_LEN_SEQ_ALIGN) / sizeof(*ptr); -+ } - - /* dss is in a union with inet_skb_parm and - * the IP layer expects zeroed IPCB fields. - */ - memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); - -- return mptcp_dss_len/sizeof(*ptr); -+ return length; - } - - static bool mptcp_skb_entail(struct sock *sk, struct sk_buff *skb, int reinject) - { - struct tcp_sock *tp = tcp_sk(sk); - const struct sock *meta_sk = mptcp_meta_sk(sk); -- const struct mptcp_cb *mpcb = tp->mpcb; -+ struct mptcp_cb *mpcb = tp->mpcb; - struct tcp_skb_cb *tcb; - struct sk_buff *subskb = NULL; - -@@ -544,6 +592,11 @@ - - mptcp_save_dss_data_seq(tp, subskb); - -+ if (mpcb->send_mptcpv1_mpcapable) { -+ TCP_SKB_CB(subskb)->mptcp_flags |= MPTCPHDR_MPC_DATA; -+ mpcb->send_mptcpv1_mpcapable = 0; -+ } -+ - tcb->seq = tp->write_seq; - - /* Take into account seg len */ -@@ -851,10 +904,7 @@ - - if (!mptcp_skb_entail(subsk, skb, reinject)) - break; -- /* Nagle is handled at the MPTCP-layer, so -- * always push on the subflow -- */ -- __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ - if (reinject <= 0) - tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); - meta_tp->lsndtime = tcp_jiffies32; -@@ -886,14 +936,12 @@ - if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) - continue; - -- /* We have pushed data on this subflow. We ignore the call to -- * cwnd_validate in tcp_write_xmit as is_cwnd_limited will never -- * be true (we never push more than what the cwnd can accept). -- * We need to ensure that we call tcp_cwnd_validate with -- * is_cwnd_limited set to true if we have filled the cwnd. -+ mss_now = tcp_current_mss(subsk); -+ -+ /* Nagle is handled at the MPTCP-layer, so -+ * always push on the subflow - */ -- tcp_cwnd_validate(subsk, tcp_packets_in_flight(subtp) >= -- subtp->snd_cwnd); -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); - } - - return !meta_tp->packets_out && tcp_send_head(meta_sk); -@@ -988,8 +1036,13 @@ - opts->options |= OPTION_MPTCP; - if (is_master_tp(tp)) { - opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYN; -- opts->mptcp_ver = tcp_sk(sk)->mptcp_ver; -- *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ opts->mptcp_ver = tp->mptcp_ver; -+ -+ if (tp->mptcp_ver >= MPTCP_VERSION_1) -+ *remaining -= MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN; -+ else -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ - opts->mp_capable.sender_key = tp->mptcp_loc_key; - opts->dss_csum = !!sysctl_mptcp_checksum; - } else { -@@ -1017,7 +1070,11 @@ - opts->mptcp_ver = mtreq->mptcp_ver; - opts->mp_capable.sender_key = mtreq->mptcp_loc_key; - opts->dss_csum = !!sysctl_mptcp_checksum || mtreq->dss_csum; -- *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ if (mtreq->mptcp_ver >= MPTCP_VERSION_1) { -+ *remaining -= MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN; -+ } else { -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ } - } else { - opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYNACK; - opts->mp_join_syns.sender_truncated_mac = -@@ -1080,7 +1137,12 @@ - opts->options |= OPTION_MPTCP; - opts->mptcp_options |= OPTION_MP_CAPABLE | - OPTION_TYPE_ACK; -- *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; -+ -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCPV1_SUB_LEN_CAPABLE_ACK_ALIGN; -+ else -+ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; -+ - opts->mptcp_ver = mpcb->mptcp_ver; - opts->mp_capable.sender_key = mpcb->mptcp_loc_key; - opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -@@ -1111,14 +1173,20 @@ - /* If !skb, we come from tcp_current_mss and thus we always - * assume that the DSS-option will be set for the data-packet. - */ -- if (skb && !mptcp_is_data_seq(skb)) { -+ if (skb && !mptcp_is_data_seq(skb) && mpcb->rem_key_set) { - *size += MPTCP_SUB_LEN_ACK_ALIGN; -+ } else if ((skb && mptcp_is_data_mpcapable(skb)) || -+ (!skb && tp->mpcb->send_mptcpv1_mpcapable)) { -+ *size += MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN; - } else { - /* Doesn't matter, if csum included or not. It will be - * either 10 or 12, and thus aligned = 12 - */ -- *size += MPTCP_SUB_LEN_ACK_ALIGN + -- MPTCP_SUB_LEN_SEQ_ALIGN; -+ if (mpcb->rem_key_set) -+ *size += MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ else -+ *size += MPTCP_SUB_LEN_SEQ_ALIGN; - } - - *size += MPTCP_SUB_LEN_DSS_ALIGN; -@@ -1171,18 +1239,36 @@ - - mpc->kind = TCPOPT_MPTCP; - -- if ((OPTION_TYPE_SYN & opts->mptcp_options) || -- (OPTION_TYPE_SYNACK & opts->mptcp_options)) { -- mpc->sender_key = opts->mp_capable.sender_key; -- mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; -+ if (OPTION_TYPE_SYN & opts->mptcp_options) { - mpc->ver = opts->mptcp_ver; -- ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -- } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ -+ if (mpc->ver >= MPTCP_VERSION_1) { -+ mpc->len = MPTCPV1_SUB_LEN_CAPABLE_SYN; -+ ptr += MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } else { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; -+ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } -+ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { -+ mpc->ver = opts->mptcp_ver; -+ -+ if (mpc->ver >= MPTCP_VERSION_1) { -+ mpc->len = MPTCPV1_SUB_LEN_CAPABLE_SYNACK; -+ ptr += MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN >> 2; -+ } else { -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; -+ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } -+ - mpc->sender_key = opts->mp_capable.sender_key; -- mpc->receiver_key = opts->mp_capable.receiver_key; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { - mpc->len = MPTCP_SUB_LEN_CAPABLE_ACK; - mpc->ver = opts->mptcp_ver; - ptr += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN >> 2; -+ -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->receiver_key = opts->mp_capable.receiver_key; - } - - mpc->sub = MPTCP_SUB_CAPABLE; -@@ -1312,8 +1398,10 @@ - } - - if (OPTION_DATA_ACK & opts->mptcp_options) { -- if (!mptcp_is_data_seq(skb)) -+ if (!mptcp_is_data_seq(skb) && tp->mpcb->rem_key_set) - ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ else if (mptcp_is_data_mpcapable(skb)) -+ ptr += mptcp_write_mpcapable_data(tp, skb, ptr); - else - ptr += mptcp_write_dss_data_seq(tp, skb, ptr); - } -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c mptcp/net/mptcp/mptcp_redundant.c ---- mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_redundant.c 2020-05-14 15:11:23.662202401 +0200 -@@ -187,7 +187,9 @@ - { - struct tcp_sock *meta_tp = tcp_sk(meta_sk); - -- if (red_p->skb && !after(red_p->skb_end_seq, meta_tp->snd_una)) -+ if (red_p->skb && -+ (!after(red_p->skb_end_seq, meta_tp->snd_una) || -+ after(red_p->skb_end_seq, meta_tp->snd_nxt))) - red_p->skb = NULL; - } - -@@ -197,9 +199,13 @@ - struct sock *meta_sk) - { - struct sk_buff *skb; -- -- if (!previous) -+ if (!previous){ -+ if (tcp_rtx_queue_head(meta_sk)){ -+ return tcp_rtx_queue_head(meta_sk); -+ } - return skb_peek(queue); -+ } -+ - - /* sk_data->skb stores the last scheduled packet for this subflow. - * If sk_data->skb was scheduled but not sent (e.g., due to nagle), -@@ -246,7 +252,8 @@ - *limit = 0; - - if (skb_queue_empty(&mpcb->reinject_queue) && -- skb_queue_empty(&meta_sk->sk_write_queue)) -+ skb_queue_empty(&meta_sk->sk_write_queue) && -+ tcp_rtx_queue_empty(meta_sk)) - /* Nothing to send */ - return NULL; - -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c.orig mptcp/net/mptcp/mptcp_redundant.c.orig ---- mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_redundant.c.orig 2020-05-11 09:39:24.476475868 +0200 -@@ -0,0 +1,391 @@ -+/* -+ * MPTCP Scheduler to reduce latency and jitter. -+ * -+ * This scheduler sends all packets redundantly on all available subflows. -+ * -+ * Initial Design & Implementation: -+ * Tobias Erbshaeusser -+ * Alexander Froemmgen -+ * -+ * Initial corrections & modifications: -+ * Christian Pinedo -+ * Igor Lopez -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+/* Struct to store the data of a single subflow */ -+struct redsched_priv { -+ /* The skb or NULL */ -+ struct sk_buff *skb; -+ /* End sequence number of the skb. This number should be checked -+ * to be valid before the skb field is used -+ */ -+ u32 skb_end_seq; -+}; -+ -+/* Struct to store the data of the control block */ -+struct redsched_cb { -+ /* The next subflow where a skb should be sent or NULL */ -+ struct tcp_sock *next_subflow; -+}; -+ -+/* Returns the socket data from a given subflow socket */ -+static struct redsched_priv *redsched_get_priv(struct tcp_sock *tp) -+{ -+ return (struct redsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* Returns the control block data from a given meta socket */ -+static struct redsched_cb *redsched_get_cb(struct tcp_sock *tp) -+{ -+ return (struct redsched_cb *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+static bool redsched_get_active_valid_sks(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ int active_valid_sks = 0; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (subflow_is_active((struct tcp_sock *)sk) && -+ !mptcp_is_def_unavailable(sk)) -+ active_valid_sks++; -+ } -+ -+ return active_valid_sks; -+} -+ -+static bool redsched_use_subflow(struct sock *meta_sk, -+ int active_valid_sks, -+ struct tcp_sock *tp, -+ struct sk_buff *skb) -+{ -+ if (!skb || !mptcp_is_available((struct sock *)tp, skb, false)) -+ return false; -+ -+ if (TCP_SKB_CB(skb)->path_mask != 0) -+ return subflow_is_active(tp); -+ -+ if (TCP_SKB_CB(skb)->path_mask == 0) { -+ if (active_valid_sks == -1) -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ -+ if (subflow_is_backup(tp) && active_valid_sks > 0) -+ return false; -+ else -+ return true; -+ } -+ -+ return false; -+} -+ -+#define mptcp_entry_next_rcu(__mptcp) \ -+ hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ -+ &(__mptcp)->node)), struct mptcp_tcp_sock, node) -+ -+static void redsched_update_next_subflow(struct tcp_sock *tp, -+ struct redsched_cb *red_cb) -+{ -+ struct mptcp_tcp_sock *mptcp = mptcp_entry_next_rcu(tp->mptcp); -+ -+ if (mptcp) -+ red_cb->next_subflow = mptcp->tp; -+ else -+ red_cb->next_subflow = NULL; -+} -+ -+static struct sock *red_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); -+ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; -+ struct mptcp_tcp_sock *mptcp; -+ int found = 0; -+ -+ /* Answer data_fin on same subflow */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk)->mptcp->path_index == -+ mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { -+ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), -+ struct mptcp_tcp_sock, node)->tp; -+ } -+ tp = first_tp; -+ -+ /* still NULL (no subflow in conn_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ /* Search for a subflow to send it. -+ * -+ * We want to pick a subflow that is after 'first_tp' in the list of subflows. -+ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up -+ * to the subflow 'tp' and then checks whether any one of the remaining -+ * ones is eligible to send. -+ * The second mptcp_for_each-sub()-loop is then iterating from the -+ * beginning of the list up to 'first_tp'. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ /* We go up to the subflow 'tp' and start from there */ -+ if (tp == mptcp->tp) -+ found = 1; -+ -+ if (!found) -+ continue; -+ tp = mptcp->tp; -+ -+ if (mptcp_is_available((struct sock *)tp, skb, -+ zero_wnd_test)) { -+ redsched_update_next_subflow(tp, red_cb); -+ return (struct sock *)tp; -+ } -+ } -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ tp = mptcp->tp; -+ -+ if (tp == first_tp) -+ break; -+ -+ if (mptcp_is_available((struct sock *)tp, skb, -+ zero_wnd_test)) { -+ redsched_update_next_subflow(tp, red_cb); -+ return (struct sock *)tp; -+ } -+ } -+ -+ /* No space */ -+ return NULL; -+} -+ -+/* Corrects the stored skb pointers if they are invalid */ -+static void redsched_correct_skb_pointers(struct sock *meta_sk, -+ struct redsched_priv *red_p) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (red_p->skb && -+ (!after(red_p->skb_end_seq, meta_tp->snd_una) || -+ after(red_p->skb_end_seq, meta_tp->snd_nxt))) -+ red_p->skb = NULL; -+} -+ -+/* Returns the next skb from the queue */ -+static struct sk_buff *redsched_next_skb_from_queue(struct sk_buff_head *queue, -+ struct sk_buff *previous, -+ struct sock *meta_sk) -+{ -+ struct sk_buff *skb; -+ -+ if (!previous) -+ return skb_peek(queue); -+ -+ /* sk_data->skb stores the last scheduled packet for this subflow. -+ * If sk_data->skb was scheduled but not sent (e.g., due to nagle), -+ * we have to schedule it again. -+ * -+ * For the redundant scheduler, there are two cases: -+ * 1. sk_data->skb was not sent on another subflow: -+ * we have to schedule it again to ensure that we do not -+ * skip this packet. -+ * 2. sk_data->skb was already sent on another subflow: -+ * with regard to the redundant semantic, we have to -+ * schedule it again. However, we keep it simple and ignore it, -+ * as it was already sent by another subflow. -+ * This might be changed in the future. -+ * -+ * For case 1, send_head is equal previous, as only a single -+ * packet can be skipped. -+ */ -+ if (tcp_send_head(meta_sk) == previous) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_rb_next(previous); -+ if (skb) -+ return skb; -+ -+ return tcp_send_head(meta_sk); -+} -+ -+static struct sk_buff *mptcp_red_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); -+ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; -+ struct mptcp_tcp_sock *mptcp; -+ int active_valid_sks = -1; -+ struct sk_buff *skb; -+ int found = 0; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (skb_queue_empty(&mpcb->reinject_queue) && -+ skb_queue_empty(&meta_sk->sk_write_queue)) -+ /* Nothing to send */ -+ return NULL; -+ -+ /* First try reinjections */ -+ skb = skb_peek(&mpcb->reinject_queue); -+ if (skb) { -+ *subsk = get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ *reinject = 1; -+ return skb; -+ } -+ -+ /* Then try indistinctly redundant and normal skbs */ -+ -+ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { -+ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), -+ struct mptcp_tcp_sock, node)->tp; -+ } -+ -+ /* still NULL (no subflow in conn_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ tp = first_tp; -+ -+ *reinject = 0; -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ -+ /* We want to pick a subflow that is after 'first_tp' in the list of subflows. -+ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up -+ * to the subflow 'tp' and then checks whether any one of the remaining -+ * ones can send a segment. -+ * The second mptcp_for_each-sub()-loop is then iterating from the -+ * beginning of the list up to 'first_tp'. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct redsched_priv *red_p; -+ -+ if (tp == mptcp->tp) -+ found = 1; -+ -+ if (!found) -+ continue; -+ -+ tp = mptcp->tp; -+ -+ /* Correct the skb pointers of the current subflow */ -+ red_p = redsched_get_priv(tp); -+ redsched_correct_skb_pointers(meta_sk, red_p); -+ -+ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, -+ red_p->skb, meta_sk); -+ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, -+ skb)) { -+ red_p->skb = skb; -+ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; -+ redsched_update_next_subflow(tp, red_cb); -+ *subsk = (struct sock *)tp; -+ -+ if (TCP_SKB_CB(skb)->path_mask) -+ *reinject = -1; -+ return skb; -+ } -+ } -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct redsched_priv *red_p; -+ -+ tp = mptcp->tp; -+ -+ if (tp == first_tp) -+ break; -+ -+ /* Correct the skb pointers of the current subflow */ -+ red_p = redsched_get_priv(tp); -+ redsched_correct_skb_pointers(meta_sk, red_p); -+ -+ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, -+ red_p->skb, meta_sk); -+ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, -+ skb)) { -+ red_p->skb = skb; -+ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; -+ redsched_update_next_subflow(tp, red_cb); -+ *subsk = (struct sock *)tp; -+ -+ if (TCP_SKB_CB(skb)->path_mask) -+ *reinject = -1; -+ return skb; -+ } -+ } -+ -+ /* Nothing to send */ -+ return NULL; -+} -+ -+static void redsched_release(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct redsched_cb *red_cb = redsched_get_cb(tp); -+ -+ /* Check if the next subflow would be the released one. If yes correct -+ * the pointer -+ */ -+ if (red_cb->next_subflow == tp) -+ redsched_update_next_subflow(tp, red_cb); -+} -+ -+static struct mptcp_sched_ops mptcp_sched_red = { -+ .get_subflow = red_get_available_subflow, -+ .next_segment = mptcp_red_next_segment, -+ .release = redsched_release, -+ .name = "redundant", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init red_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct redsched_priv) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct redsched_cb) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_red)) -+ return -1; -+ -+ return 0; -+} -+ -+static void red_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_red); -+} -+ -+module_init(red_register); -+module_exit(red_unregister); -+ -+MODULE_AUTHOR("Tobias Erbshaeusser, Alexander Froemmgen"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("REDUNDANT MPTCP"); -+MODULE_VERSION("0.90"); -diff -aurN '--exclude=.git' mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c mptcp/net/mptcp/mptcp_sched.c ---- mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-02-20 18:07:47.000000000 +0100 -+++ mptcp/net/mptcp/mptcp_sched.c 2020-05-11 09:40:13.463584360 +0200 -@@ -76,7 +76,7 @@ - */ - space = (tp->snd_cwnd - in_flight) * tp->mss_cache; - -- if (tp->write_seq - tp->snd_nxt > space) -+ if (tp->write_seq - tp->snd_nxt >= space) - return true; - - if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -@@ -391,10 +391,11 @@ - unsigned int *limit) - { - struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); -- unsigned int mss_now; -+ unsigned int mss_now, in_flight_space; -+ int remaining_in_flight_space; -+ u32 max_len, max_segs, window; - struct tcp_sock *subtp; - u16 gso_max_segs; -- u32 max_len, max_segs, window, needed; - - /* As we set it, we have to reset it as well. */ - *limit = 0; -@@ -424,9 +425,6 @@ - /* The following is similar to tcp_mss_split_point, but - * we do not care about nagle, because we will anyways - * use TCP_NAGLE_PUSH, which overrides this. -- * -- * So, we first limit according to the cwnd/gso-size and then according -- * to the subflow's window. - */ - - gso_max_segs = (*subsk)->sk_gso_max_segs; -@@ -436,16 +434,30 @@ - if (!max_segs) - return NULL; - -- max_len = mss_now * max_segs; -- window = tcp_wnd_end(subtp) - subtp->write_seq; -+ /* max_len is what would fit in the cwnd (respecting the 2GSO-limit of -+ * tcp_cwnd_test), but ignoring whatever was already queued. -+ */ -+ max_len = min(mss_now * max_segs, skb->len); - -- needed = min(skb->len, window); -- if (max_len <= skb->len) -- /* Take max_win, which is actually the cwnd/gso-size */ -- *limit = max_len; -+ in_flight_space = (subtp->snd_cwnd - tcp_packets_in_flight(subtp)) * mss_now; -+ remaining_in_flight_space = (int)in_flight_space - (subtp->write_seq - subtp->snd_nxt); -+ -+ if (remaining_in_flight_space <= 0) -+ WARN_ONCE(1, "in_flight %u cwnd %u wseq %u snxt %u mss_now %u cache %u", -+ tcp_packets_in_flight(subtp), subtp->snd_cwnd, -+ subtp->write_seq, subtp->snd_nxt, mss_now, subtp->mss_cache); - else -- /* Or, take the window */ -- *limit = needed; -+ /* max_len now fits exactly in the write-queue, taking into -+ * account what was already queued. -+ */ -+ max_len = min_t(u32, max_len, remaining_in_flight_space); -+ -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ /* max_len now also respects the announced receive-window */ -+ max_len = min(max_len, window); -+ -+ *limit = max_len; - - return skb; - } From aeb821bc2a5d44c1d59704f85c462c3b4a5bd0b4 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 20 May 2020 17:45:41 +0200 Subject: [PATCH 51/76] Add bcm27xx userland package --- config-rpi2 | 1 + config-rpi4 | 1 + 2 files changed, 2 insertions(+) diff --git a/config-rpi2 b/config-rpi2 index de4667ba..e79e72d2 100644 --- a/config-rpi2 +++ b/config-rpi2 @@ -4,3 +4,4 @@ CONFIG_TARGET_bcm27xx_bcm2709_DEVICE_rpi-2=y CONFIG_PACKAGE_kmod-ath10k-ct=n CONFIG_PACKAGE_kmod-ath9k=y CONFIG_PACKAGE_bcm27xx-eeprom=y +CONFIG_PACKAGE_bcm27xx-userland=y diff --git a/config-rpi4 b/config-rpi4 index c5c07f5c..7fb408aa 100644 --- a/config-rpi4 +++ b/config-rpi4 @@ -4,3 +4,4 @@ CONFIG_TARGET_bcm27xx_bcm2711_DEVICE_rpi-4=y CONFIG_PACKAGE_kmod-ath10k-ct=n CONFIG_PACKAGE_kmod-ath9k=y CONFIG_PACKAGE_bcm27xx-eeprom=y +CONFIG_PACKAGE_bcm27xx-userland=y From 5b987b9c833e96eb7e42f419d3e737de94a2a539 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 20 May 2020 20:18:49 +0200 Subject: [PATCH 52/76] Fix MPTCP patch for 5.4.42 kernel --- root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index d6915244..2ebe3630 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -4466,12 +4466,13 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { int eaten; struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4746,7 +4811,7 @@ +@@ -4746,8 +4811,8 @@ const struct tcp_sock *tp = tcp_sk(sk); int avail = tp->rcv_nxt - tp->copied_seq; -- if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE)) -+ if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) +- if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && ++ if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && !mptcp(tp) && + !sock_flag(sk, SOCK_DONE)) return; sk->sk_data_ready(sk); From 7cc4ba13473fadbe26d95b6102aacc89128aafa3 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 21 May 2020 00:28:55 +0200 Subject: [PATCH 53/76] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 01c1d717..00a88201 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "eb17ee294ca8e2b59051a4337779af7a3f4812d5" - _get_repo feeds/packages https://github.com/openwrt/packages "a22fff844db6927bbe77570d21a7e08d5f5424f3" - _get_repo feeds/luci https://github.com/openwrt/luci "750e6c1df9624198f4f11e0675de428ec33fd564" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "5ff4b0d0242da8adf83d7d8f00f60198f41afb51" + _get_repo feeds/packages https://github.com/openwrt/packages "061e22606ced7724c15a778a1fb31b0b340aed92" + _get_repo feeds/luci https://github.com/openwrt/luci "4643883a8b386f8a461d933d5901b0ecf31aa142" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From 32ac59143969bb95736eff830c55b2e838a03025 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 26 May 2020 07:55:16 +0200 Subject: [PATCH 54/76] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 00a88201..d17afc6e 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "5ff4b0d0242da8adf83d7d8f00f60198f41afb51" - _get_repo feeds/packages https://github.com/openwrt/packages "061e22606ced7724c15a778a1fb31b0b340aed92" - _get_repo feeds/luci https://github.com/openwrt/luci "4643883a8b386f8a461d933d5901b0ecf31aa142" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "1b2144e81f74bc49705a4c0828a9678b899188ce" + _get_repo feeds/packages https://github.com/openwrt/packages "947c85bff0176c0bb7b6dce796ee32bd9fa868da" + _get_repo feeds/luci https://github.com/openwrt/luci "91249c0e926bb343c95b0916ded4a9eda146c975" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From 59ce9be78be29b6955317bbcbdcaacbe175d2010 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 30 May 2020 07:47:21 +0200 Subject: [PATCH 55/76] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index d17afc6e..667bf351 100755 --- a/build.sh +++ b/build.sh @@ -61,9 +61,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "1b2144e81f74bc49705a4c0828a9678b899188ce" - _get_repo feeds/packages https://github.com/openwrt/packages "947c85bff0176c0bb7b6dce796ee32bd9fa868da" - _get_repo feeds/luci https://github.com/openwrt/luci "91249c0e926bb343c95b0916ded4a9eda146c975" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "559b3384666bbc6e4e9e6d86cf54bd88d30b341f" + _get_repo feeds/packages https://github.com/openwrt/packages "b7c82d57b69efee3b4e04483d5e7db9cfa5dcad5" + _get_repo feeds/luci https://github.com/openwrt/luci "6be8f8dbaee90a8a7e8bc87350f21793b9aed35c" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From e131493bf17a01d557b7c4840833d978b4fe7711 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 8 Jun 2020 20:19:14 +0200 Subject: [PATCH 56/76] Update MPTCP --- .../generic/hack-5.4/690-mptcp_trunk.patch | 755 ++++++------- .../generic/hack-5.4/691-mptcp_ecf.patch | 988 ------------------ 2 files changed, 393 insertions(+), 1350 deletions(-) delete mode 100644 root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index 2ebe3630..819773ee 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -1,6 +1,6 @@ diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt --- linux-5.4/Documentation/networking/ip-sysctl.txt 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-06-08 19:41:07.000000000 +0200 @@ -818,6 +818,18 @@ Default: 0 (disabled) @@ -22,7 +22,7 @@ diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Do udp_l3mdev_accept - BOOLEAN diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c --- linux-5.4/drivers/infiniband/hw/cxgb4/cm.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-06-08 19:41:07.000000000 +0200 @@ -3946,7 +3946,7 @@ */ memset(&tmp_opt, 0, sizeof(tmp_opt)); @@ -34,7 +34,7 @@ diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/ memset(req, 0, sizeof(*req)); diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbuff.h --- linux-5.4/include/linux/skbuff.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-06-08 19:41:07.000000000 +0200 @@ -717,7 +717,7 @@ * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. @@ -46,7 +46,7 @@ diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbu struct { diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h --- linux-5.4/include/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-06-08 19:41:07.000000000 +0200 @@ -54,7 +54,7 @@ /* TCP Fast Open */ #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ @@ -205,7 +205,7 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/inet_common.h --- linux-5.4/include/net/inet_common.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-06-08 19:41:07.000000000 +0200 @@ -2,6 +2,7 @@ #ifndef _INET_COMMON_H #define _INET_COMMON_H @@ -225,7 +225,7 @@ diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/ine int addr_len, int flags); diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/include/net/inet_connection_sock.h --- linux-5.4/include/net/inet_connection_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-06-08 19:41:07.000000000 +0200 @@ -25,6 +25,7 @@ struct inet_bind_bucket; @@ -236,7 +236,7 @@ diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/includ * Pointers to address related TCP functions diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_sock.h --- linux-5.4/include/net/inet_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-06-08 19:41:07.000000000 +0200 @@ -79,7 +79,7 @@ #define ireq_state req.__req_common.skc_state #define ireq_family req.__req_common.skc_family @@ -257,8 +257,8 @@ diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_ union { diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h --- linux-5.4/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,1519 @@ ++++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,1542 @@ +/* + * MPTCP implementation + * @@ -305,6 +305,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +#include +#include +#include ++#include +#include + +#if defined(__LITTLE_ENDIAN_BITFIELD) @@ -463,7 +464,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + struct timer_list mptcp_ack_timer; + + /* HMAC of the third ack */ -+ char sender_mac[20]; ++ char sender_mac[SHA256_DIGEST_SIZE]; +}; + +struct mptcp_tw { @@ -831,11 +832,29 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + __u8 kind; + __u8 len; +#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ipver:4, -+ sub:4; ++ union { ++ struct { ++ __u8 ipver:4, ++ sub:4; ++ } v0; ++ struct { ++ __u8 echo:1, ++ rsv:3, ++ sub:4; ++ } v1; ++ } u_bit; +#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ipver:4; ++ union { ++ struct { ++ __u8 sub:4, ++ ipver:4; ++ } v0; ++ struct { ++ __u8 sub:4, ++ rsv:3, ++ echo:1; ++ } v1; ++ } u_bit; +#else +#error "Adjust your defines" +#endif @@ -1091,7 +1110,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + int wscale_ok, __u8 *rcv_wscale, + __u32 init_rcv_wnd); +unsigned int mptcp_current_mss(struct sock *meta_sk); -+void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u32 *hash_out, ++void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u8 *hash_out, + int arg_num, ...); +void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); +void mptcp_fin(struct sock *meta_sk); @@ -1179,6 +1198,10 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +bool subflow_is_backup(const struct tcp_sock *tp); +struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, + bool zero_wnd_test); ++struct sk_buff *mptcp_next_segment(struct sock *meta_sk, ++ int *reinject, ++ struct sock **subsk, ++ unsigned int *limit); +extern struct mptcp_sched_ops mptcp_sched_default; + +/* Initializes function-pointers and MPTCP-flags */ @@ -1780,7 +1803,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +#endif /* _MPTCP_H */ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_v4.h --- linux-5.4/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,76 @@ +/* + * MPTCP implementation @@ -1860,7 +1883,7 @@ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* MPTCP_V4_H_ */ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_v6.h --- linux-5.4/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,77 @@ +/* + * MPTCP implementation @@ -1941,7 +1964,7 @@ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* _MPTCP_V6_H */ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/net_namespace.h --- linux-5.4/include/net/net_namespace.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-06-08 19:41:07.000000000 +0200 @@ -19,6 +19,7 @@ #include #include @@ -1962,7 +1985,7 @@ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/n #endif diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/netns/mptcp.h --- linux-5.4/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,52 @@ +/* + * MPTCP implementation - MPTCP namespace @@ -2018,7 +2041,7 @@ diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/net +#endif /* __NETNS_MPTCP_H__ */ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h --- linux-5.4/include/net/snmp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/snmp.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/snmp.h 2020-06-08 19:41:07.000000000 +0200 @@ -86,7 +86,6 @@ atomic_long_t mibs[ICMP6MSG_MIB_MAX]; }; @@ -2029,7 +2052,7 @@ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h struct tcp_mib { diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h --- linux-5.4/include/net/sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/sock.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/sock.h 2020-06-08 19:41:07.000000000 +0200 @@ -814,6 +814,7 @@ SOCK_TXTIME, SOCK_XDP, /* XDP is attached */ @@ -2048,7 +2071,7 @@ diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h #ifdef CONFIG_PROC_FS diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h --- linux-5.4/include/net/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/tcp.h 2020-06-08 19:41:07.000000000 +0200 @@ -182,6 +182,7 @@ #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ @@ -2395,7 +2418,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h { diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_states.h --- linux-5.4/include/net/tcp_states.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-06-08 19:41:07.000000000 +0200 @@ -22,6 +22,7 @@ TCP_LISTEN, TCP_CLOSING, /* Now a valid state */ @@ -2414,7 +2437,7 @@ diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_ #endif /* _LINUX_TCP_STATES_H */ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/transp_v6.h --- linux-5.4/include/net/transp_v6.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-06-08 19:41:07.000000000 +0200 @@ -58,6 +58,8 @@ /* address family specific functions */ @@ -2426,7 +2449,7 @@ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/trans diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/events/tcp.h --- linux-5.4/include/trace/events/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-06-08 19:41:07.000000000 +0200 @@ -10,6 +10,7 @@ #include #include @@ -2477,7 +2500,7 @@ diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/ #endif /* _TRACE_TCP_H */ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/linux/bpf.h --- linux-5.4/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-06-08 19:41:07.000000000 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ @@ -2488,7 +2511,7 @@ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/lin }; diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linux/if.h --- linux-5.4/include/uapi/linux/if.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-06-08 19:41:07.000000000 +0200 @@ -132,6 +132,9 @@ #define IFF_ECHO IFF_ECHO #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ @@ -2501,7 +2524,7 @@ diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linu diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/linux/mptcp.h --- linux-5.4/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* @@ -2654,7 +2677,7 @@ diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/l +#endif /* _LINUX_MPTCP_H */ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/linux/tcp.h --- linux-5.4/include/uapi/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-06-08 19:41:07.000000000 +0200 @@ -18,9 +18,15 @@ #ifndef _UAPI_LINUX_TCP_H #define _UAPI_LINUX_TCP_H @@ -2742,7 +2765,7 @@ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/lin diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c --- linux-5.4/net/core/dev.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/dev.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/dev.c 2020-06-08 19:41:07.000000000 +0200 @@ -7855,7 +7855,7 @@ dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | @@ -2754,7 +2777,7 @@ diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces.c --- linux-5.4/net/core/net-traces.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-06-08 19:41:07.000000000 +0200 @@ -60,3 +60,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); @@ -2763,7 +2786,7 @@ diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces +EXPORT_TRACEPOINT_SYMBOL_GPL(mptcp_retransmit); diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c --- linux-5.4/net/core/skbuff.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-06-08 19:41:07.000000000 +0200 @@ -573,7 +573,7 @@ skb_drop_list(&skb_shinfo(skb)->frag_list); } @@ -2775,7 +2798,7 @@ diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c --- linux-5.4/net/core/sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/sock.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/sock.c 2020-06-08 19:41:07.000000000 +0200 @@ -135,6 +135,11 @@ #include @@ -2827,16 +2850,17 @@ diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c } else sk = kmalloc(prot->obj_size, priority); -@@ -1832,4 +1858,5 @@ +@@ -1832,6 +1858,7 @@ atomic_set(&newsk->sk_zckey, 0); sock_reset_flag(newsk, SOCK_DONE); + sock_reset_flag(newsk, SOCK_MPTCP); + mem_cgroup_sk_alloc(newsk); + cgroup_sk_alloc(&newsk->sk_cgrp_data); - /* sk->sk_memcg will be populated at accept() time */ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c --- linux-5.4/net/ipv4/af_inet.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-06-08 19:41:07.000000000 +0200 @@ -100,6 +100,7 @@ #include #include @@ -2902,7 +2926,7 @@ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c --- linux-5.4/net/ipv4/inet_connection_sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-06-08 19:41:07.000000000 +0200 @@ -19,6 +19,7 @@ #include #include @@ -2962,7 +2986,7 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ cond_resched(); diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c --- linux-5.4/net/ipv4/ip_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-06-08 19:41:07.000000000 +0200 @@ -44,6 +44,8 @@ #endif #include @@ -3004,7 +3028,7 @@ diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockgl case IP_TTL: diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig --- linux-5.4/net/ipv4/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-06-08 19:41:07.000000000 +0200 @@ -654,6 +654,51 @@ bufferbloat, policers, or AQM schemes that do not provide a delay signal. It requires the fq ("Fair Queue") pacing packet scheduler. @@ -3092,7 +3116,7 @@ diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig default "cdg" if DEFAULT_CDG diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies.c --- linux-5.4/net/ipv4/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-06-08 19:41:07.000000000 +0200 @@ -12,6 +12,8 @@ #include #include @@ -3220,7 +3244,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies */ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c --- linux-5.4/net/ipv4/tcp.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-06-08 19:41:07.000000000 +0200 @@ -270,6 +270,7 @@ #include @@ -3605,7 +3629,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c seq = tp->write_seq + tp->max_window + 2; if (!seq) -@@ -2616,17 +2730,11 @@ +@@ -2616,15 +2730,11 @@ icsk->icsk_backoff = 0; tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; @@ -3614,7 +3638,6 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c - tp->snd_cwnd = TCP_INIT_CWND; - tp->snd_cwnd_cnt = 0; tp->window_clamp = 0; -- tp->delivered = 0; - tp->delivered_ce = 0; + + tcp_reset_vars(sk); @@ -3622,22 +3645,17 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tcp_set_ca_state(sk, TCP_CA_Open); - tp->is_sack_reneg = 0; - tcp_clear_retrans(tp); -- tp->total_retrans = 0; inet_csk_delack_init(sk); /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 * issue in __tcp_select_window() -@@ -2636,14 +2746,10 @@ +@@ -2636,10 +2746,6 @@ sk->sk_rx_dst = NULL; tcp_saved_syn_free(tp); tp->compressed_ack = 0; - tp->segs_in = 0; - tp->segs_out = 0; - tp->bytes_sent = 0; - tp->bytes_acked = 0; - tp->bytes_received = 0; - tp->bytes_retrans = 0; - tp->data_segs_in = 0; - tp->data_segs_out = 0; tp->duplicate_sack[0].start_seq = 0; tp->duplicate_sack[0].end_seq = 0; tp->dsack_dups = 0; @@ -3969,7 +3987,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c EXPORT_SYMBOL_GPL(tcp_abort); diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c --- linux-5.4/net/ipv4/tcp_cong.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-06-08 19:41:07.000000000 +0200 @@ -328,13 +328,19 @@ return ret; } @@ -3994,7 +4012,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c const struct tcp_congestion_ops *ca; diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c --- linux-5.4/net/ipv4/tcp_diag.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-06-08 19:41:07.000000000 +0200 @@ -31,7 +31,7 @@ r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; } @@ -4006,7 +4024,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c #ifdef CONFIG_TCP_MD5SIG diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c --- linux-5.4/net/ipv4/tcp_fastopen.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-06-08 19:41:07.000000000 +0200 @@ -9,6 +9,7 @@ #include #include @@ -4067,7 +4085,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fast */ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c --- linux-5.4/net/ipv4/tcp_input.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-06-08 19:41:07.000000000 +0200 @@ -76,35 +76,15 @@ #include #include @@ -4466,13 +4484,12 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { int eaten; struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4746,8 +4811,8 @@ +@@ -4746,7 +4811,7 @@ const struct tcp_sock *tp = tcp_sk(sk); int avail = tp->rcv_nxt - tp->copied_seq; -- if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && -+ if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && !mptcp(tp) && - !sock_flag(sk, SOCK_DONE)) +- if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE)) ++ if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) return; sk->sk_data_ready(sk); @@ -4952,7 +4969,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_rsk(req)->tfo_listener = false; diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c --- linux-5.4/net/ipv4/tcp_ipv4.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-06-08 19:41:07.000000000 +0200 @@ -62,6 +62,8 @@ #include #include @@ -5417,7 +5434,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c --- linux-5.4/net/ipv4/tcp_minisocks.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-06-08 19:41:07.000000000 +0200 @@ -19,11 +19,13 @@ * Jorge Cwik, */ @@ -5659,7 +5676,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min } diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output.c --- linux-5.4/net/ipv4/tcp_output.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-06-08 19:41:07.000000000 +0200 @@ -37,6 +37,12 @@ #define pr_fmt(fmt) "TCP: " fmt @@ -5796,7 +5813,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output return MAX_TCP_OPTION_SPACE - remaining; } -@@ -747,17 +753,22 @@ +@@ -747,16 +753,22 @@ opts->tsecr = tp->rx_opt.ts_recent; size += TCPOLEN_TSTAMP_ALIGNED; } @@ -5810,9 +5827,8 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output - min_t(unsigned int, eff_sacks, - (remaining - TCPOLEN_SACK_BASE_ALIGNED) / - TCPOLEN_SACK_PERBLOCK); -- if (likely(opts->num_sack_blocks)) -- size += TCPOLEN_SACK_BASE_ALIGNED + -- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; +- size += TCPOLEN_SACK_BASE_ALIGNED + +- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; + const unsigned remaining = MAX_TCP_OPTION_SPACE - size; + if (remaining < TCPOLEN_SACK_BASE_ALIGNED) + opts->num_sack_blocks = 0; @@ -5821,7 +5837,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output + min_t(unsigned int, eff_sacks, + (remaining - TCPOLEN_SACK_BASE_ALIGNED) / + TCPOLEN_SACK_PERBLOCK); -+ if (likely(opts->num_sack_blocks)) ++ if (opts->num_sack_blocks) + size += TCPOLEN_SACK_BASE_ALIGNED + + opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; } @@ -6251,7 +6267,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Cancel probe timer, if it is not required. */ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c --- linux-5.4/net/ipv4/tcp_timer.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-06-08 19:41:07.000000000 +0200 @@ -21,6 +21,7 @@ #include @@ -6465,7 +6481,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c --- linux-5.4/net/ipv6/addrconf.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-06-08 19:41:07.000000000 +0200 @@ -967,6 +967,7 @@ kfree_rcu(ifp, rcu); @@ -6476,7 +6492,7 @@ diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c --- linux-5.4/net/ipv6/af_inet6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-06-08 19:41:07.000000000 +0200 @@ -104,8 +104,7 @@ return (struct ipv6_pinfo *)(((u8 *)sk) + offset); } @@ -6489,7 +6505,7 @@ diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c struct ipv6_pinfo *np; diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c --- linux-5.4/net/ipv6/ipv6_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-06-08 19:41:07.000000000 +0200 @@ -44,6 +44,8 @@ #include #include @@ -6515,7 +6531,7 @@ diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_so tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies.c --- linux-5.4/net/ipv6/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-06-08 19:41:07.000000000 +0200 @@ -15,6 +15,8 @@ #include #include @@ -6605,7 +6621,7 @@ diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies out_free: diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c --- linux-5.4/net/ipv6/tcp_ipv6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-06-08 19:41:07.000000000 +0200 @@ -58,6 +58,8 @@ #include #include @@ -7199,7 +7215,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c /* thinking of making this const? Don't. diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig --- linux-5.4/net/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Kconfig 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/Kconfig 2020-06-08 19:41:07.000000000 +0200 @@ -91,6 +91,7 @@ source "net/ipv4/Kconfig" source "net/ipv6/Kconfig" @@ -7210,7 +7226,7 @@ diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile --- linux-5.4/net/Makefile 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Makefile 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/Makefile 2020-06-08 19:41:07.000000000 +0200 @@ -20,6 +20,7 @@ obj-$(CONFIG_XFRM) += xfrm/ obj-$(CONFIG_UNIX_SCM) += unix/ @@ -7221,8 +7237,8 @@ diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile obj-$(CONFIG_NET_KEY) += key/ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig --- linux-5.4/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,146 @@ ++++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,152 @@ +# +# MPTCP configuration +# @@ -7334,6 +7350,12 @@ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig + This scheduler sends all packets redundantly over all subflows to decreases + latency and jitter on the cost of lower throughput. + ++config MPTCP_ECF ++ tristate "MPTCP ECF" ++ depends on (MPTCP=y) ++ ---help--- ++ This is an experimental Earliest Completion First (ECF) scheduler. ++ +choice + prompt "Default MPTCP Scheduler" + default DEFAULT_SCHEDULER @@ -7371,8 +7393,8 @@ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig + diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile --- linux-5.4/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,24 @@ ++++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,25 @@ +# +## Makefile for MultiPath TCP support code. +# @@ -7395,11 +7417,12 @@ diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile +obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o +obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o +obj-$(CONFIG_MPTCP_BLEST) += mptcp_blest.o ++obj-$(CONFIG_MPTCP_ECF) += mptcp_ecf.o + +mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c --- linux-5.4/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,193 @@ +/* + * Desynchronized Multi-Channel TCP Congestion Control Algorithm @@ -7596,7 +7619,7 @@ diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_ +MODULE_VERSION("1.0"); diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c --- linux-5.4/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,261 @@ +/* + * MPTCP implementation - Balia Congestion Control @@ -7861,7 +7884,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c --- linux-5.4/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,494 @@ +#include + @@ -8359,8 +8382,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c --- linux-5.4/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,481 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,285 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP Scheduler to reduce HoL-blocking and spurious retransmissions. + * @@ -8384,7 +8407,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b + +#include +#include -+#include + +static unsigned char lambda __read_mostly = 12; +module_param(lambda, byte, 0644); @@ -8413,7 +8435,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +}; + +struct blestsched_cb { -+ bool retrans_flag; + s16 lambda_1000; /* values range from min_lambda * 100 to max_lambda * 100 */ + u32 last_lambda_update; +}; @@ -8440,14 +8461,13 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b + * during the slow flows last RTT => increase lambda + * otherwise decrease + */ -+ if (blest_cb->retrans_flag) { ++ if (tcp_sk(meta_sk)->retrans_stamp) { + /* need to slow down on the slow flow */ + blest_cb->lambda_1000 += dyn_lambda_bad; + } else { + /* use the slow flow more */ + blest_cb->lambda_1000 -= dyn_lambda_good; + } -+ blest_cb->retrans_flag = false; + + /* cap lambda_1000 to its value range */ + blest_cb->lambda_1000 = min_t(s16, blest_cb->lambda_1000, max_lambda * 100); @@ -8603,199 +8623,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b + return bestsk; +} + -+/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ -+static struct sk_buff *mptcp_blest_rcv_buf_optimization(struct sock *sk, int penal) -+{ -+ struct sock *meta_sk; -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb_head; -+ struct blestsched_priv *blest_p = blestsched_get_priv(tp); -+ struct blestsched_cb *blest_cb; -+ -+ meta_sk = mptcp_meta_sk(sk); -+ skb_head = tcp_rtx_queue_head(meta_sk); -+ -+ if (!skb_head) -+ return NULL; -+ -+ /* If penalization is optional (coming from mptcp_next_segment() and -+ * We are not send-buffer-limited we do not penalize. The retransmission -+ * is just an optimization to fix the idle-time due to the delay before -+ * we wake up the application. -+ */ -+ if (!penal && sk_stream_memory_free(meta_sk)) -+ goto retrans; -+ -+ /* Record the occurrence of a retransmission to update the lambda value */ -+ blest_cb = blestsched_get_cb(tcp_sk(meta_sk)); -+ blest_cb->retrans_flag = true; -+ -+ /* Only penalize again after an RTT has elapsed */ -+ if (tcp_jiffies32 - blest_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -+ goto retrans; -+ -+ /* Half the cwnd of the slow flows */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -+ u32 prior_cwnd = tp_it->snd_cwnd; -+ -+ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -+ -+ /* If in slow start, do not reduce the ssthresh */ -+ if (prior_cwnd >= tp_it->snd_ssthresh) -+ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -+ -+ blest_p->last_rbuf_opti = tcp_jiffies32; -+ } -+ } -+ } -+ -+retrans: -+ -+ /* Segment not yet injected into this path? Take it!!! */ -+ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -+ bool do_retrans = false; -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp_it->snd_cwnd <= 4) { -+ do_retrans = true; -+ break; -+ } -+ -+ if (4 * tp->srtt_us >= tp_it->srtt_us) { -+ do_retrans = false; -+ break; -+ } else { -+ do_retrans = true; -+ } -+ } -+ } -+ -+ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { -+ trace_mptcp_retransmit(sk, skb_head); -+ return skb_head; -+ } -+ } -+ return NULL; -+} -+ -+/* copy from mptcp_sched.c: __mptcp_next_segment */ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_blest_next_segment(struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) { -+ *reinject = 1; -+ } else { -+ skb = tcp_send_head(meta_sk); -+ -+ if (!skb && meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -+ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = blest_get_available_subflow(meta_sk, NULL, -+ false); -+ if (!subsk) -+ return NULL; -+ -+ skb = mptcp_blest_rcv_buf_optimization(subsk, 0); -+ if (skb) -+ *reinject = -1; -+ } -+ } -+ return skb; -+} -+ -+/* copy from mptcp_sched.c: mptcp_next_segment */ -+static struct sk_buff *mptcp_blest_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct sk_buff *skb = __mptcp_blest_next_segment(meta_sk, reinject); -+ unsigned int mss_now; -+ struct tcp_sock *subtp; -+ u16 gso_max_segs; -+ u32 max_len, max_segs, window, needed; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ *subsk = blest_get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ subtp = tcp_sk(*subsk); -+ mss_now = tcp_current_mss(*subsk); -+ -+ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -+ skb = mptcp_blest_rcv_buf_optimization(*subsk, 1); -+ if (skb) -+ *reinject = -1; -+ else -+ return NULL; -+ } -+ -+ /* No splitting required, as we will only send one single segment */ -+ if (skb->len <= mss_now) -+ return skb; -+ -+ /* The following is similar to tcp_mss_split_point, but -+ * we do not care about nagle, because we will anyways -+ * use TCP_NAGLE_PUSH, which overrides this. -+ * -+ * So, we first limit according to the cwnd/gso-size and then according -+ * to the subflow's window. -+ */ -+ -+ gso_max_segs = (*subsk)->sk_gso_max_segs; -+ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -+ gso_max_segs = 1; -+ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -+ if (!max_segs) -+ return NULL; -+ -+ max_len = mss_now * max_segs; -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ needed = min(skb->len, window); -+ if (max_len <= skb->len) -+ /* Take max_win, which is actually the cwnd/gso-size */ -+ *limit = max_len; -+ else -+ /* Or, take the window */ -+ *limit = needed; -+ -+ return skb; -+} -+ +static void blestsched_init(struct sock *sk) +{ + struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); @@ -8813,7 +8640,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b + +static struct mptcp_sched_ops mptcp_sched_blest = { + .get_subflow = blest_get_available_subflow, -+ .next_segment = mptcp_blest_next_segment, ++ .next_segment = mptcp_next_segment, + .init = blestsched_init, + .name = "blest", + .owner = THIS_MODULE, @@ -8844,7 +8671,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_VERSION("0.95"); diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c --- linux-5.4/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,262 @@ +/* + * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) @@ -9110,8 +8937,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c --- linux-5.4/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,3254 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,3250 @@ +/* + * MPTCP implementation - MPTCP-control + * @@ -9974,11 +9801,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[6])); +} + -+static void mptcp_hmac_sha256(const u8 *key_1, const u8 *key_2, u32 *hash_out, ++static void mptcp_hmac_sha256(const u8 *key_1, const u8 *key_2, u8 *hash_out, + int arg_num, va_list list) +{ + u8 input[SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE]; -+ __be32 output[SHA256_DIGEST_WORDS]; + struct sha256_state state; + int index, msg_length; + int length = 0; @@ -10016,10 +9842,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + + sha256_init(&state); + sha256_update(&state, input, sizeof(input)); -+ sha256_final(&state, (u8 *)output); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = output[i]; ++ sha256_final(&state, hash_out); +} + +static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) @@ -10129,14 +9952,14 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); +} + -+void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u32 *hash_out, ++void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u8 *hash_out, + int arg_num, ...) +{ + va_list args; + + va_start(args, arg_num); + if (ver == MPTCP_VERSION_0) -+ mptcp_hmac_sha1(key_1, key_2, hash_out, arg_num, args); ++ mptcp_hmac_sha1(key_1, key_2, (u32 *)hash_out, arg_num, args); + else if (ver >= MPTCP_VERSION_1) + mptcp_hmac_sha256(key_1, key_2, hash_out, arg_num, args); + va_end(args); @@ -11500,7 +11323,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; + struct mptcp_request_sock *mtreq = mptcp_rsk(req); + struct tcp_sock *child_tp = tcp_sk(child); -+ u8 hash_mac_check[20]; ++ u8 hash_mac_check[SHA256_DIGEST_SIZE]; + + if (!mopt->join_ack) { + MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKFAIL); @@ -11508,7 +11331,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + } + + mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, (u32 *)hash_mac_check, 2, ++ (u8 *)&mpcb->mptcp_loc_key, hash_mac_check, 2, + 4, (u8 *)&mtreq->mptcp_rem_nonce, + 4, (u8 *)&mtreq->mptcp_loc_nonce); + @@ -11761,8 +11584,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + struct sk_buff *skb) +{ + struct mptcp_request_sock *mtreq = mptcp_rsk(req); ++ u8 mptcp_hash_mac[SHA256_DIGEST_SIZE]; + struct mptcp_options_received mopt; -+ u8 mptcp_hash_mac[20]; + + mptcp_init_mp_opt(&mopt); + tcp_parse_mptcp_options(skb, &mopt); @@ -11773,7 +11596,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; + + mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, (u32 *)mptcp_hash_mac, 2, ++ (u8 *)&mpcb->mptcp_rem_key, mptcp_hash_mac, 2, + 4, (u8 *)&mtreq->mptcp_loc_nonce, + 4, (u8 *)&mtreq->mptcp_rem_nonce); + mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; @@ -12366,10 +12189,209 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +mptcp_sock_cache_failed: + mptcp_init_failed = true; +} +diff -aurN linux-5.4/net/mptcp/mptcp_ecf.c mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c +--- linux-5.4/net/mptcp/mptcp_ecf.c 1970-01-01 01:00:00.000000000 +0100 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,195 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* MPTCP ECF Scheduler ++ * ++ * Algorithm Design: ++ * Yeon-sup Lim ++ * Don Towsley ++ * Erich M. Nahum ++ * Richard J. Gibbens ++ * ++ * Initial Implementation: ++ * Yeon-sup Lim ++ * ++ * Additional Authors: ++ * Daniel Weber ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static unsigned int mptcp_ecf_r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ ++module_param(mptcp_ecf_r_beta, int, 0644); ++MODULE_PARM_DESC(mptcp_ecf_r_beta, "beta for ECF"); ++ ++struct ecfsched_priv { ++ u32 last_rbuf_opti; ++}; ++ ++struct ecfsched_cb { ++ u32 switching_margin; /* this is "waiting" in algorithm description */ ++}; ++ ++static struct ecfsched_priv *ecfsched_get_priv(const struct tcp_sock *tp) ++{ ++ return (struct ecfsched_priv *)&tp->mptcp->mptcp_sched[0]; ++} ++ ++static struct ecfsched_cb *ecfsched_get_cb(const struct tcp_sock *tp) ++{ ++ return (struct ecfsched_cb *)&tp->mpcb->mptcp_sched[0]; ++} ++ ++/* This is the ECF scheduler. This function decides on which flow to send ++ * a given MSS. If all subflows are found to be busy or the currently best ++ * subflow is estimated to be slower than waiting for minsk, NULL is returned. ++ */ ++static struct sock *ecf_get_available_subflow(struct sock *meta_sk, ++ struct sk_buff *skb, ++ bool zero_wnd_test) ++{ ++ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; ++ struct sock *bestsk, *minsk = NULL; ++ struct tcp_sock *besttp; ++ struct mptcp_tcp_sock *mptcp; ++ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(meta_sk)); ++ u32 min_srtt = U32_MAX; ++ u32 sub_sndbuf = 0; ++ u32 sub_packets_out = 0; ++ ++ /* Answer data_fin on same subflow!!! */ ++ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && ++ skb && mptcp_is_data_fin(skb)) { ++ mptcp_for_each_sub(mpcb, mptcp) { ++ bestsk = mptcp_to_sock(mptcp); ++ ++ if (tcp_sk(bestsk)->mptcp->path_index == mpcb->dfin_path_index && ++ mptcp_is_available(bestsk, skb, zero_wnd_test)) ++ return bestsk; ++ } ++ } ++ ++ /* First, find the overall best (fastest) subflow */ ++ mptcp_for_each_sub(mpcb, mptcp) { ++ bestsk = mptcp_to_sock(mptcp); ++ besttp = tcp_sk(bestsk); ++ ++ /* Set of states for which we are allowed to send data */ ++ if (!mptcp_sk_can_send(bestsk)) ++ continue; ++ ++ /* We do not send data on this subflow unless it is ++ * fully established, i.e. the 4th ack has been received. ++ */ ++ if (besttp->mptcp->pre_established) ++ continue; ++ ++ sub_sndbuf += bestsk->sk_wmem_queued; ++ sub_packets_out += besttp->packets_out; ++ ++ /* record minimal rtt */ ++ if (besttp->srtt_us < min_srtt) { ++ min_srtt = besttp->srtt_us; ++ minsk = bestsk; ++ } ++ } ++ ++ /* find the current best subflow according to the default scheduler */ ++ bestsk = get_available_subflow(meta_sk, skb, zero_wnd_test); ++ ++ /* if we decided to use a slower flow, we have the option of not using it at all */ ++ if (bestsk && minsk && bestsk != minsk) { ++ u32 mss = tcp_current_mss(bestsk); /* assuming equal MSS */ ++ u32 sndbuf_meta = meta_sk->sk_wmem_queued; ++ u32 sndbuf_minus = sub_sndbuf; ++ u32 sndbuf = 0; ++ ++ u32 cwnd_f = tcp_sk(minsk)->snd_cwnd; ++ u32 srtt_f = tcp_sk(minsk)->srtt_us >> 3; ++ u32 rttvar_f = tcp_sk(minsk)->rttvar_us >> 1; ++ ++ u32 cwnd_s = tcp_sk(bestsk)->snd_cwnd; ++ u32 srtt_s = tcp_sk(bestsk)->srtt_us >> 3; ++ u32 rttvar_s = tcp_sk(bestsk)->rttvar_us >> 1; ++ ++ u32 delta = max(rttvar_f, rttvar_s); ++ ++ u32 x_f; ++ u64 lhs, rhs; /* to avoid overflow, using u64 */ ++ ++ if (tcp_sk(meta_sk)->packets_out > sub_packets_out) ++ sndbuf_minus += (tcp_sk(meta_sk)->packets_out - sub_packets_out) * mss; ++ ++ if (sndbuf_meta > sndbuf_minus) ++ sndbuf = sndbuf_meta - sndbuf_minus; ++ ++ /* we have something to send. ++ * at least one time tx over fastest subflow is required ++ */ ++ x_f = sndbuf > cwnd_f * mss ? sndbuf : cwnd_f * mss; ++ lhs = srtt_f * (x_f + cwnd_f * mss); ++ rhs = cwnd_f * mss * (srtt_s + delta); ++ ++ if (mptcp_ecf_r_beta * lhs < mptcp_ecf_r_beta * rhs + ecf_cb->switching_margin * rhs) { ++ u32 x_s = sndbuf > cwnd_s * mss ? sndbuf : cwnd_s * mss; ++ u64 lhs_s = srtt_s * x_s; ++ u64 rhs_s = cwnd_s * mss * (2 * srtt_f + delta); ++ ++ if (lhs_s >= rhs_s) { ++ /* too slower than fastest */ ++ ecf_cb->switching_margin = 1; ++ return NULL; ++ } ++ } else { ++ /* use slower one */ ++ ecf_cb->switching_margin = 0; ++ } ++ } ++ ++ return bestsk; ++} ++ ++static void ecfsched_init(struct sock *sk) ++{ ++ struct ecfsched_priv *ecf_p = ecfsched_get_priv(tcp_sk(sk)); ++ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(mptcp_meta_sk(sk))); ++ ++ ecf_p->last_rbuf_opti = tcp_jiffies32; ++ ecf_cb->switching_margin = 0; ++} ++ ++struct mptcp_sched_ops mptcp_sched_ecf = { ++ .get_subflow = ecf_get_available_subflow, ++ .next_segment = mptcp_next_segment, ++ .init = ecfsched_init, ++ .name = "ecf", ++ .owner = THIS_MODULE, ++}; ++ ++static int __init ecf_register(void) ++{ ++ BUILD_BUG_ON(sizeof(struct ecfsched_priv) > MPTCP_SCHED_SIZE); ++ BUILD_BUG_ON(sizeof(struct ecfsched_cb) > MPTCP_SCHED_DATA_SIZE); ++ ++ if (mptcp_register_scheduler(&mptcp_sched_ecf)) ++ return -1; ++ ++ return 0; ++} ++ ++static void ecf_unregister(void) ++{ ++ mptcp_unregister_scheduler(&mptcp_sched_ecf); ++} ++ ++module_init(ecf_register); ++module_exit(ecf_unregister); ++ ++MODULE_AUTHOR("Yeon-sup Lim, Daniel Weber"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("ECF (Earliest Completion First) scheduler for MPTCP, based on default minimum RTT scheduler"); ++MODULE_VERSION("0.95"); diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c --- linux-5.4/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,1941 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,1937 @@ +#include +#include + @@ -13964,15 +13986,13 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc + opts->add_addr4.addr = mptcp_local->locaddr4[ind].addr; + opts->add_addr_v4 = 1; + if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[20]; -+ u8 no_key[8]; ++ u8 mptcp_hash_mac[SHA256_DIGEST_SIZE]; + -+ *(u64 *)no_key = 0; + mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, (u32 *)mptcp_hash_mac, 2, ++ (u8 *)&mpcb->mptcp_rem_key, mptcp_hash_mac, 2, + 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, + 4, (u8 *)&opts->add_addr4.addr.s_addr); -+ opts->add_addr4.trunc_mac = *(u64 *)mptcp_hash_mac; ++ opts->add_addr4.trunc_mac = *(u64 *)&mptcp_hash_mac[SHA256_DIGEST_SIZE - sizeof(u64)]; + } + + if (skb) { @@ -14006,15 +14026,13 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc + opts->add_addr6.addr = mptcp_local->locaddr6[ind].addr; + opts->add_addr_v6 = 1; + if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[20]; -+ u8 no_key[8]; ++ u8 mptcp_hash_mac[SHA256_DIGEST_SIZE]; + -+ *(u64 *)no_key = 0; + mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, (u32 *)mptcp_hash_mac, 2, ++ (u8 *)&mpcb->mptcp_rem_key, mptcp_hash_mac, 2, + 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, + 16, (u8 *)&opts->add_addr6.addr.s6_addr); -+ opts->add_addr6.trunc_mac = *(u64 *)mptcp_hash_mac; ++ opts->add_addr6.trunc_mac = *(u64 *)&mptcp_hash_mac[SHA256_DIGEST_SIZE - sizeof(u64)]; + } + + if (skb) { @@ -14313,8 +14331,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc +MODULE_VERSION("0.88"); diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_input.c --- linux-5.4/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,2523 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,2529 @@ +/* + * MPTCP implementation - Sending side + * @@ -15931,19 +15949,21 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + int opsize) +{ +#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 6) { ++ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->u_bit.v0.ipver == 6) { + return opsize == MPTCP_SUB_LEN_ADD_ADDR6 || + opsize == MPTCP_SUB_LEN_ADD_ADDR6 + 2; + } -+ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 6) ++ if (mptcp_ver >= MPTCP_VERSION_1) + return opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2; ++ opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2 || ++ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || ++ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; +#endif -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 4) { ++ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->u_bit.v0.ipver == 4) { + return opsize == MPTCP_SUB_LEN_ADD_ADDR4 || + opsize == MPTCP_SUB_LEN_ADD_ADDR4 + 2; + } -+ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 4) { ++ if (mptcp_ver >= MPTCP_VERSION_1) { + return opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || + opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; + } @@ -16289,33 +16309,42 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i +{ + struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; + struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ __be16 port = 0; + union inet_addr addr; + sa_family_t family; ++ __be16 port = 0; ++ bool is_v4; + -+ if (mpadd->ipver == 4) { ++ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { ++ is_v4 = mpadd->u_bit.v0.ipver == 4; ++ } else { ++ is_v4 = mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || ++ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; ++ ++ /* TODO: support ADD_ADDRv1 retransmissions */ ++ if (mpadd->u_bit.v1.echo) ++ return; ++ } ++ ++ if (is_v4) { ++ u8 hash_mac_check[SHA256_DIGEST_SIZE]; ++ __be16 hmacport = 0; + char *recv_hmac; -+ u8 hash_mac_check[20]; -+ u8 no_key[8]; -+ int msg_parts = 0; + + if (mpcb->mptcp_ver < MPTCP_VERSION_1) + goto skip_hmac_v4; + -+ *(u64 *)no_key = 0; + recv_hmac = (char *)mpadd->u.v4.mac; + if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1) { + recv_hmac -= sizeof(mpadd->u.v4.port); -+ msg_parts = 2; + } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { -+ msg_parts = 3; ++ hmacport = mpadd->u.v4.port; + } + mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, (u32 *)hash_mac_check, msg_parts, ++ (u8 *)&mpcb->mptcp_loc_key, hash_mac_check, 3, + 1, (u8 *)&mpadd->addr_id, + 4, (u8 *)&mpadd->u.v4.addr.s_addr, -+ 2, (u8 *)&mpadd->u.v4.port); -+ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) ++ 2, (u8 *)&hmacport); ++ if (memcmp(&hash_mac_check[SHA256_DIGEST_SIZE - sizeof(u64)], recv_hmac, 8) != 0) + /* ADD_ADDR2 discarded */ + return; +skip_hmac_v4: @@ -16327,29 +16356,26 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + family = AF_INET; + addr.in = mpadd->u.v4.addr; +#if IS_ENABLED(CONFIG_IPV6) -+ } else if (mpadd->ipver == 6) { ++ } else { ++ u8 hash_mac_check[SHA256_DIGEST_SIZE]; ++ __be16 hmacport = 0; + char *recv_hmac; -+ u8 hash_mac_check[20]; -+ u8 no_key[8]; -+ int msg_parts = 0; + + if (mpcb->mptcp_ver < MPTCP_VERSION_1) + goto skip_hmac_v6; + -+ *(u64 *)no_key = 0; + recv_hmac = (char *)mpadd->u.v6.mac; + if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1) { + recv_hmac -= sizeof(mpadd->u.v6.port); -+ msg_parts = 2; + } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { -+ msg_parts = 3; ++ hmacport = mpadd->u.v6.port; + } + mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, (u32 *)hash_mac_check, msg_parts, ++ (u8 *)&mpcb->mptcp_loc_key, hash_mac_check, 3, + 1, (u8 *)&mpadd->addr_id, + 16, (u8 *)&mpadd->u.v6.addr.s6_addr, -+ 2, (u8 *)&mpadd->u.v6.port); -+ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) ++ 2, (u8 *)&hmacport); ++ if (memcmp(&hash_mac_check[SHA256_DIGEST_SIZE - sizeof(u64)], recv_hmac, 8) != 0) + /* ADD_ADDR2 discarded */ + return; +skip_hmac_v6: @@ -16361,8 +16387,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + family = AF_INET6; + addr.in6 = mpadd->u.v6.addr; +#endif /* CONFIG_IPV6 */ -+ } else { -+ return; + } + + if (mpcb->pm_ops->add_raddr) @@ -16691,11 +16715,11 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + struct tcp_sock *tp = tcp_sk(sk); + + if (mptcp(tp)) { -+ u8 hash_mac_check[20]; ++ u8 hash_mac_check[SHA256_DIGEST_SIZE]; + struct mptcp_cb *mpcb = tp->mpcb; + + mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, (u32 *)hash_mac_check, 2, ++ (u8 *)&mpcb->mptcp_loc_key, hash_mac_check, 2, + 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, + 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); + if (memcmp(hash_mac_check, @@ -16713,7 +16737,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + + mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, + (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)&tp->mptcp->sender_mac[0], 2, ++ tp->mptcp->sender_mac, 2, + 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, + 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); + @@ -16840,7 +16864,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i +} diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c --- linux-5.4/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,430 @@ +/* + * MPTCP implementation - IPv4-specific functions @@ -17274,7 +17298,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip +} diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c --- linux-5.4/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,478 @@ +/* + * MPTCP implementation - IPv6-specific functions @@ -17756,7 +17780,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip +} diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c --- linux-5.4/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,174 @@ +#include + @@ -17934,7 +17958,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mp +MODULE_VERSION("0.88"); diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c --- linux-5.4/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,1271 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP implementation - Netlink Path Manager @@ -19209,7 +19233,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_ALIAS_GENL_FAMILY(MPTCP_GENL_NAME); diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c --- linux-5.4/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,318 @@ +/* + * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: @@ -19531,8 +19555,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_ol +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_output.c --- linux-5.4/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,1988 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,1994 @@ +/* + * MPTCP implementation - Sending side + * @@ -20847,29 +20871,35 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + + mpadd->kind = TCPOPT_MPTCP; + if (opts->add_addr_v4) { -+ mpadd->sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->ipver = 4; + mpadd->addr_id = opts->add_addr4.addr_id; + mpadd->u.v4.addr = opts->add_addr4.addr; + if (mpcb->mptcp_ver < MPTCP_VERSION_1) { ++ mpadd->u_bit.v0.sub = MPTCP_SUB_ADD_ADDR; ++ mpadd->u_bit.v0.ipver = 4; + mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4; + ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN >> 2; + } else { ++ mpadd->u_bit.v1.sub = MPTCP_SUB_ADD_ADDR; ++ mpadd->u_bit.v1.rsv = 0; ++ mpadd->u_bit.v1.echo = 0; + memcpy((char *)mpadd->u.v4.mac - 2, + (char *)&opts->add_addr4.trunc_mac, 8); + mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4_VER1; + ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 >> 2; + } + } else if (opts->add_addr_v6) { -+ mpadd->sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->ipver = 6; + mpadd->addr_id = opts->add_addr6.addr_id; + memcpy(&mpadd->u.v6.addr, &opts->add_addr6.addr, + sizeof(mpadd->u.v6.addr)); + if (mpcb->mptcp_ver < MPTCP_VERSION_1) { ++ mpadd->u_bit.v0.sub = MPTCP_SUB_ADD_ADDR; ++ mpadd->u_bit.v0.ipver = 6; + mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6; + ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN >> 2; + } else { ++ mpadd->u_bit.v1.sub = MPTCP_SUB_ADD_ADDR; ++ mpadd->u_bit.v1.rsv = 0; ++ mpadd->u_bit.v1.echo = 0; + memcpy((char *)mpadd->u.v6.mac - 2, + (char *)&opts->add_addr6.trunc_mac, 8); + mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6_VER1; @@ -21523,7 +21553,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c --- linux-5.4/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,226 @@ +/* + * MPTCP implementation - MPTCP-subflow-management @@ -21753,7 +21783,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c +late_initcall(mptcp_path_manager_default); diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c --- linux-5.4/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,392 @@ +/* + * MPTCP Scheduler to reduce latency and jitter. @@ -22149,7 +22179,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mpt +MODULE_VERSION("0.90"); diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c --- linux-5.4/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,309 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -22462,8 +22492,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c +MODULE_VERSION("0.89"); diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c --- linux-5.4/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-05-16 10:39:52.000000000 +0200 -@@ -0,0 +1,646 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-06-08 19:41:07.000000000 +0200 +@@ -0,0 +1,647 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + +#include @@ -22838,8 +22868,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + if (!skb && meta_sk->sk_socket && + test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && + sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = get_available_subflow(meta_sk, NULL, -+ false); ++ struct sock *subsk = mpcb->sched_ops->get_subflow(meta_sk, NULL, ++ false); + if (!subsk) + return NULL; + @@ -22851,7 +22881,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + return skb; +} + -+static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, ++struct sk_buff *mptcp_next_segment(struct sock *meta_sk, + int *reinject, + struct sock **subsk, + unsigned int *limit) @@ -22869,7 +22899,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + if (!skb) + return NULL; + -+ *subsk = get_available_subflow(meta_sk, skb, false); ++ *subsk = tcp_sk(meta_sk)->mpcb->sched_ops->get_subflow(meta_sk, skb, false); + if (!*subsk) + return NULL; + @@ -22927,6 +22957,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + + return skb; +} ++EXPORT_SYMBOL_GPL(mptcp_next_segment); + +static void defsched_init(struct sock *sk) +{ @@ -23112,7 +23143,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s +late_initcall(mptcp_scheduler_default); diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c --- linux-5.4/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-06-08 19:41:07.000000000 +0200 @@ -0,0 +1,271 @@ +/* + * MPTCP implementation - WEIGHTED VEGAS @@ -23387,7 +23418,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_VERSION("0.1"); diff -aurN linux-5.4/tools/include/uapi/linux/bpf.h mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h --- linux-5.4/tools/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-05-16 10:39:52.000000000 +0200 ++++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-06-08 19:41:07.000000000 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ diff --git a/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch b/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch deleted file mode 100644 index 4925612c..00000000 --- a/root/target/linux/generic/hack-5.4/691-mptcp_ecf.patch +++ /dev/null @@ -1,988 +0,0 @@ -From 025619486cf04c0beb9f395609d7711726fd63c6 Mon Sep 17 00:00:00 2001 -From: Daniel Weber -Date: Mon, 5 Aug 2019 14:02:30 +0200 -Subject: [PATCH 1/3] mptcp: Earliest Completion First (ECF) Scheduler - -This scheduler works much like the default MPTCP scheduler. It always -prefers the subflow with the smallest round-trip-time that is available. - -Signed-off-by: Daniel Weber ---- - net/mptcp/Kconfig | 6 + - net/mptcp/Makefile | 1 + - net/mptcp/mptcp_ecf.c | 384 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 391 insertions(+) - create mode 100644 net/mptcp/mptcp_ecf.c - -diff --git a/net/mptcp/Kconfig b/net/mptcp/Kconfig -index 37f3af3db2a6..829ea084cf70 100644 ---- a/net/mptcp/Kconfig -+++ b/net/mptcp/Kconfig -@@ -109,6 +109,12 @@ config MPTCP_REDUNDANT - This scheduler sends all packets redundantly over all subflows to decreases - latency and jitter on the cost of lower throughput. - -+config MPTCP_ECF -+ tristate "MPTCP ECF" -+ depends on (MPTCP=y) -+ ---help--- -+ This is an experimental Earliest Completion First (ECF) scheduler. -+ - choice - prompt "Default MPTCP Scheduler" - default DEFAULT_SCHEDULER -diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile -index 82a2d4d945ae..369248a2f68e 100644 ---- a/net/mptcp/Makefile -+++ b/net/mptcp/Makefile -@@ -20,5 +20,6 @@ obj-$(CONFIG_MPTCP_NETLINK) += mptcp_netlink.o - obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o - obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o - obj-$(CONFIG_MPTCP_BLEST) += mptcp_blest.o -+obj-$(CONFIG_MPTCP_ECF) += mptcp_ecf.o - - mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o -diff --git a/net/mptcp/mptcp_ecf.c b/net/mptcp/mptcp_ecf.c -new file mode 100644 -index 000000000000..e0bd430a8943 ---- /dev/null -+++ b/net/mptcp/mptcp_ecf.c -@@ -0,0 +1,384 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* MPTCP ECF Scheduler -+ * -+ * Algorithm Design: -+ * Yeon-sup Lim -+ * Don Towsley -+ * Erich M. Nahum -+ * Richard J. Gibbens -+ * -+ * Initial Implementation: -+ * Yeon-sup Lim -+ * -+ * Additional Authors: -+ * Daniel Weber -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+static unsigned int mptcp_ecf_r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ -+module_param(mptcp_ecf_r_beta, int, 0644); -+MODULE_PARM_DESC(mptcp_ecf_r_beta, "beta for ECF"); -+ -+struct ecfsched_priv { -+ u32 last_rbuf_opti; -+}; -+ -+struct ecfsched_cb { -+ u32 switching_margin; /* this is "waiting" in algorithm description */ -+}; -+ -+static struct ecfsched_priv *ecfsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct ecfsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+static struct ecfsched_cb *ecfsched_get_cb(const struct tcp_sock *tp) -+{ -+ return (struct ecfsched_cb *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+/* This is the ECF scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy or the currently best -+ * subflow is estimated to be slower than waiting for minsk, NULL is returned. -+ */ -+static struct sock *ecf_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *bestsk, *minsk = NULL; -+ struct tcp_sock *besttp; -+ struct mptcp_tcp_sock *mptcp; -+ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(meta_sk)); -+ u32 min_srtt = U32_MAX; -+ u32 sub_sndbuf = 0; -+ u32 sub_packets_out = 0; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(bestsk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(bestsk, skb, zero_wnd_test)) -+ return bestsk; -+ } -+ } -+ -+ /* First, find the overall best (fastest) subflow */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ besttp = tcp_sk(bestsk); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(bestsk)) -+ continue; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (besttp->mptcp->pre_established) -+ continue; -+ -+ sub_sndbuf += bestsk->sk_wmem_queued; -+ sub_packets_out += besttp->packets_out; -+ -+ /* record minimal rtt */ -+ if (besttp->srtt_us < min_srtt) { -+ min_srtt = besttp->srtt_us; -+ minsk = bestsk; -+ } -+ } -+ -+ /* find the current best subflow according to the default scheduler */ -+ bestsk = get_available_subflow(meta_sk, skb, zero_wnd_test); -+ -+ /* if we decided to use a slower flow, we have the option of not using it at all */ -+ if (bestsk && minsk && bestsk != minsk) { -+ u32 mss = tcp_current_mss(bestsk); /* assuming equal MSS */ -+ u32 sndbuf_meta = meta_sk->sk_wmem_queued; -+ u32 sndbuf_minus = sub_sndbuf; -+ u32 sndbuf = 0; -+ -+ u32 cwnd_f = tcp_sk(minsk)->snd_cwnd; -+ u32 srtt_f = tcp_sk(minsk)->srtt_us >> 3; -+ u32 rttvar_f = tcp_sk(minsk)->rttvar_us >> 1; -+ -+ u32 cwnd_s = tcp_sk(bestsk)->snd_cwnd; -+ u32 srtt_s = tcp_sk(bestsk)->srtt_us >> 3; -+ u32 rttvar_s = tcp_sk(bestsk)->rttvar_us >> 1; -+ -+ u32 delta = max(rttvar_f, rttvar_s); -+ -+ u32 x_f; -+ u64 lhs, rhs; /* to avoid overflow, using u64 */ -+ -+ if (tcp_sk(meta_sk)->packets_out > sub_packets_out) -+ sndbuf_minus += (tcp_sk(meta_sk)->packets_out - sub_packets_out) * mss; -+ -+ if (sndbuf_meta > sndbuf_minus) -+ sndbuf = sndbuf_meta - sndbuf_minus; -+ -+ /* we have something to send. -+ * at least one time tx over fastest subflow is required -+ */ -+ x_f = sndbuf > cwnd_f * mss ? sndbuf : cwnd_f * mss; -+ lhs = srtt_f * (x_f + cwnd_f * mss); -+ rhs = cwnd_f * mss * (srtt_s + delta); -+ -+ if (mptcp_ecf_r_beta * lhs < mptcp_ecf_r_beta * rhs + ecf_cb->switching_margin * rhs) { -+ u32 x_s = sndbuf > cwnd_s * mss ? sndbuf : cwnd_s * mss; -+ u64 lhs_s = srtt_s * x_s; -+ u64 rhs_s = cwnd_s * mss * (2 * srtt_f + delta); -+ -+ if (lhs_s >= rhs_s) { -+ /* too slower than fastest */ -+ ecf_cb->switching_margin = 1; -+ return NULL; -+ } -+ } else { -+ /* use slower one */ -+ ecf_cb->switching_margin = 0; -+ } -+ } -+ -+ return bestsk; -+} -+ -+/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ -+static struct sk_buff *mptcp_ecf_rcv_buf_optimization(struct sock *sk, int penal) -+{ -+ struct sock *meta_sk; -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb_head; -+ struct ecfsched_priv *ecf_p = ecfsched_get_priv(tp); -+ -+ meta_sk = mptcp_meta_sk(sk); -+ skb_head = tcp_rtx_queue_head(meta_sk); -+ -+ if (!skb_head) -+ return NULL; -+ -+ /* If penalization is optional (coming from mptcp_next_segment() and -+ * We are not send-buffer-limited we do not penalize. The retransmission -+ * is just an optimization to fix the idle-time due to the delay before -+ * we wake up the application. -+ */ -+ if (!penal && sk_stream_memory_free(meta_sk)) -+ goto retrans; -+ -+ /* Only penalize again after an RTT has elapsed */ -+ if (tcp_jiffies32 - ecf_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -+ goto retrans; -+ -+ /* Half the cwnd of the slow flows */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -+ u32 prior_cwnd = tp_it->snd_cwnd; -+ -+ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -+ -+ /* If in slow start, do not reduce the ssthresh */ -+ if (prior_cwnd >= tp_it->snd_ssthresh) -+ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -+ -+ ecf_p->last_rbuf_opti = tcp_jiffies32; -+ } -+ } -+ } -+ -+retrans: -+ -+ /* Segment not yet injected into this path? Take it!!! */ -+ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -+ bool do_retrans = false; -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp_it->snd_cwnd <= 4) { -+ do_retrans = true; -+ break; -+ } -+ -+ if (4 * tp->srtt_us >= tp_it->srtt_us) { -+ do_retrans = false; -+ break; -+ } else { -+ do_retrans = true; -+ } -+ } -+ } -+ -+ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { -+ trace_mptcp_retransmit(sk, skb_head); -+ return skb_head; -+ } -+ } -+ return NULL; -+} -+ -+/* copy from mptcp_sched.c: __mptcp_next_segment */ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_ecf_next_segment(struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) { -+ *reinject = 1; -+ } else { -+ skb = tcp_send_head(meta_sk); -+ -+ if (!skb && meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -+ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = ecf_get_available_subflow(meta_sk, NULL, -+ false); -+ if (!subsk) -+ return NULL; -+ -+ skb = mptcp_ecf_rcv_buf_optimization(subsk, 0); -+ if (skb) -+ *reinject = -1; -+ } -+ } -+ return skb; -+} -+ -+/* copy from mptcp_sched.c: mptcp_next_segment */ -+static struct sk_buff *mptcp_ecf_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct sk_buff *skb = __mptcp_ecf_next_segment(meta_sk, reinject); -+ unsigned int mss_now; -+ struct tcp_sock *subtp; -+ u16 gso_max_segs; -+ u32 max_len, max_segs, window, needed; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ *subsk = ecf_get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ subtp = tcp_sk(*subsk); -+ mss_now = tcp_current_mss(*subsk); -+ -+ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -+ skb = mptcp_ecf_rcv_buf_optimization(*subsk, 1); -+ if (skb) -+ *reinject = -1; -+ else -+ return NULL; -+ } -+ -+ /* No splitting required, as we will only send one single segment */ -+ if (skb->len <= mss_now) -+ return skb; -+ -+ /* The following is similar to tcp_mss_split_point, but -+ * we do not care about nagle, because we will anyways -+ * use TCP_NAGLE_PUSH, which overrides this. -+ * -+ * So, we first limit according to the cwnd/gso-size and then according -+ * to the subflow's window. -+ */ -+ -+ gso_max_segs = (*subsk)->sk_gso_max_segs; -+ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -+ gso_max_segs = 1; -+ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -+ if (!max_segs) -+ return NULL; -+ -+ max_len = mss_now * max_segs; -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ needed = min(skb->len, window); -+ if (max_len <= skb->len) -+ /* Take max_win, which is actually the cwnd/gso-size */ -+ *limit = max_len; -+ else -+ /* Or, take the window */ -+ *limit = needed; -+ -+ return skb; -+} -+ -+static void ecfsched_init(struct sock *sk) -+{ -+ struct ecfsched_priv *ecf_p = ecfsched_get_priv(tcp_sk(sk)); -+ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(mptcp_meta_sk(sk))); -+ -+ ecf_p->last_rbuf_opti = tcp_jiffies32; -+ ecf_cb->switching_margin = 0; -+} -+ -+struct mptcp_sched_ops mptcp_sched_ecf = { -+ .get_subflow = ecf_get_available_subflow, -+ .next_segment = mptcp_ecf_next_segment, -+ .init = ecfsched_init, -+ .name = "ecf", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init ecf_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct ecfsched_priv) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct ecfsched_cb) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_ecf)) -+ return -1; -+ -+ return 0; -+} -+ -+static void ecf_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_ecf); -+} -+ -+module_init(ecf_register); -+module_exit(ecf_unregister); -+ -+MODULE_AUTHOR("Yeon-sup Lim, Daniel Weber"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("ECF (Earliest Completion First) scheduler for MPTCP, based on default minimum RTT scheduler"); -+MODULE_VERSION("0.95"); - -From 5a9641c84cbb5a49749d7533c20035631985dbe7 Mon Sep 17 00:00:00 2001 -From: Daniel Weber -Date: Mon, 9 Mar 2020 11:00:23 +0100 -Subject: [PATCH 2/3] mptcp: Reduce code-duplication for other schedulers - -'mptcp_next_segment' now honors the function pointer to the actual part -that makes the scheduling decision in 'sched_ops->get_subflow'. This -allows for a better reuse by other schedulers. - -The BLEST scheduler needs to adapt the direction of lambda value change -depending on the occurrence of a retransmission. In order to remove the -copied 'mptcp_rcv_buf_optimization' as well the scheduler now checks the -tcp 'retrans_stamp' of the meta socket. - -Signed-off-by: Daniel Weber ---- - include/net/mptcp.h | 4 + - net/mptcp/mptcp_blest.c | 200 +--------------------------------------- - net/mptcp/mptcp_sched.c | 9 +- - 3 files changed, 11 insertions(+), 202 deletions(-) - -diff --git a/include/net/mptcp.h b/include/net/mptcp.h -index 02312c9ea3a3..82f66ce206cc 100644 ---- a/include/net/mptcp.h -+++ b/include/net/mptcp.h -@@ -902,6 +902,10 @@ bool subflow_is_active(const struct tcp_sock *tp); - bool subflow_is_backup(const struct tcp_sock *tp); - struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, - bool zero_wnd_test); -+struct sk_buff *mptcp_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit); - extern struct mptcp_sched_ops mptcp_sched_default; - - /* Initializes function-pointers and MPTCP-flags */ -diff --git a/net/mptcp/mptcp_blest.c b/net/mptcp/mptcp_blest.c -index 40905a0d1fe5..22e25dd0d44e 100644 ---- a/net/mptcp/mptcp_blest.c -+++ b/net/mptcp/mptcp_blest.c -@@ -21,7 +21,6 @@ - - #include - #include --#include - - static unsigned char lambda __read_mostly = 12; - module_param(lambda, byte, 0644); -@@ -50,7 +49,6 @@ struct blestsched_priv { - }; - - struct blestsched_cb { -- bool retrans_flag; - s16 lambda_1000; /* values range from min_lambda * 100 to max_lambda * 100 */ - u32 last_lambda_update; - }; -@@ -77,14 +75,13 @@ static void blestsched_update_lambda(struct sock *meta_sk, struct sock *sk) - * during the slow flows last RTT => increase lambda - * otherwise decrease - */ -- if (blest_cb->retrans_flag) { -+ if (tcp_sk(meta_sk)->retrans_stamp) { - /* need to slow down on the slow flow */ - blest_cb->lambda_1000 += dyn_lambda_bad; - } else { - /* use the slow flow more */ - blest_cb->lambda_1000 -= dyn_lambda_good; - } -- blest_cb->retrans_flag = false; - - /* cap lambda_1000 to its value range */ - blest_cb->lambda_1000 = min_t(s16, blest_cb->lambda_1000, max_lambda * 100); -@@ -240,199 +237,6 @@ struct sock *blest_get_available_subflow(struct sock *meta_sk, struct sk_buff *s - return bestsk; - } - --/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ --static struct sk_buff *mptcp_blest_rcv_buf_optimization(struct sock *sk, int penal) --{ -- struct sock *meta_sk; -- const struct tcp_sock *tp = tcp_sk(sk); -- struct mptcp_tcp_sock *mptcp; -- struct sk_buff *skb_head; -- struct blestsched_priv *blest_p = blestsched_get_priv(tp); -- struct blestsched_cb *blest_cb; -- -- meta_sk = mptcp_meta_sk(sk); -- skb_head = tcp_rtx_queue_head(meta_sk); -- -- if (!skb_head) -- return NULL; -- -- /* If penalization is optional (coming from mptcp_next_segment() and -- * We are not send-buffer-limited we do not penalize. The retransmission -- * is just an optimization to fix the idle-time due to the delay before -- * we wake up the application. -- */ -- if (!penal && sk_stream_memory_free(meta_sk)) -- goto retrans; -- -- /* Record the occurrence of a retransmission to update the lambda value */ -- blest_cb = blestsched_get_cb(tcp_sk(meta_sk)); -- blest_cb->retrans_flag = true; -- -- /* Only penalize again after an RTT has elapsed */ -- if (tcp_jiffies32 - blest_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -- goto retrans; -- -- /* Half the cwnd of the slow flows */ -- mptcp_for_each_sub(tp->mpcb, mptcp) { -- struct tcp_sock *tp_it = mptcp->tp; -- -- if (tp_it != tp && -- TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -- if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -- u32 prior_cwnd = tp_it->snd_cwnd; -- -- tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -- -- /* If in slow start, do not reduce the ssthresh */ -- if (prior_cwnd >= tp_it->snd_ssthresh) -- tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -- -- blest_p->last_rbuf_opti = tcp_jiffies32; -- } -- } -- } -- --retrans: -- -- /* Segment not yet injected into this path? Take it!!! */ -- if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -- bool do_retrans = false; -- mptcp_for_each_sub(tp->mpcb, mptcp) { -- struct tcp_sock *tp_it = mptcp->tp; -- -- if (tp_it != tp && -- TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -- if (tp_it->snd_cwnd <= 4) { -- do_retrans = true; -- break; -- } -- -- if (4 * tp->srtt_us >= tp_it->srtt_us) { -- do_retrans = false; -- break; -- } else { -- do_retrans = true; -- } -- } -- } -- -- if (do_retrans && mptcp_is_available(sk, skb_head, false)) { -- trace_mptcp_retransmit(sk, skb_head); -- return skb_head; -- } -- } -- return NULL; --} -- --/* copy from mptcp_sched.c: __mptcp_next_segment */ --/* Returns the next segment to be sent from the mptcp meta-queue. -- * (chooses the reinject queue if any segment is waiting in it, otherwise, -- * chooses the normal write queue). -- * Sets *@reinject to 1 if the returned segment comes from the -- * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -- * and sets it to -1 if it is a meta-level retransmission to optimize the -- * receive-buffer. -- */ --static struct sk_buff *__mptcp_blest_next_segment(struct sock *meta_sk, int *reinject) --{ -- const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -- struct sk_buff *skb = NULL; -- -- *reinject = 0; -- -- /* If we are in fallback-mode, just take from the meta-send-queue */ -- if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -- return tcp_send_head(meta_sk); -- -- skb = skb_peek(&mpcb->reinject_queue); -- -- if (skb) { -- *reinject = 1; -- } else { -- skb = tcp_send_head(meta_sk); -- -- if (!skb && meta_sk->sk_socket && -- test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -- sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -- struct sock *subsk = blest_get_available_subflow(meta_sk, NULL, -- false); -- if (!subsk) -- return NULL; -- -- skb = mptcp_blest_rcv_buf_optimization(subsk, 0); -- if (skb) -- *reinject = -1; -- } -- } -- return skb; --} -- --/* copy from mptcp_sched.c: mptcp_next_segment */ --static struct sk_buff *mptcp_blest_next_segment(struct sock *meta_sk, -- int *reinject, -- struct sock **subsk, -- unsigned int *limit) --{ -- struct sk_buff *skb = __mptcp_blest_next_segment(meta_sk, reinject); -- unsigned int mss_now; -- struct tcp_sock *subtp; -- u16 gso_max_segs; -- u32 max_len, max_segs, window, needed; -- -- /* As we set it, we have to reset it as well. */ -- *limit = 0; -- -- if (!skb) -- return NULL; -- -- *subsk = blest_get_available_subflow(meta_sk, skb, false); -- if (!*subsk) -- return NULL; -- -- subtp = tcp_sk(*subsk); -- mss_now = tcp_current_mss(*subsk); -- -- if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -- skb = mptcp_blest_rcv_buf_optimization(*subsk, 1); -- if (skb) -- *reinject = -1; -- else -- return NULL; -- } -- -- /* No splitting required, as we will only send one single segment */ -- if (skb->len <= mss_now) -- return skb; -- -- /* The following is similar to tcp_mss_split_point, but -- * we do not care about nagle, because we will anyways -- * use TCP_NAGLE_PUSH, which overrides this. -- * -- * So, we first limit according to the cwnd/gso-size and then according -- * to the subflow's window. -- */ -- -- gso_max_segs = (*subsk)->sk_gso_max_segs; -- if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -- gso_max_segs = 1; -- max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -- if (!max_segs) -- return NULL; -- -- max_len = mss_now * max_segs; -- window = tcp_wnd_end(subtp) - subtp->write_seq; -- -- needed = min(skb->len, window); -- if (max_len <= skb->len) -- /* Take max_win, which is actually the cwnd/gso-size */ -- *limit = max_len; -- else -- /* Or, take the window */ -- *limit = needed; -- -- return skb; --} -- - static void blestsched_init(struct sock *sk) - { - struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); -@@ -450,7 +254,7 @@ static void blestsched_init(struct sock *sk) - - static struct mptcp_sched_ops mptcp_sched_blest = { - .get_subflow = blest_get_available_subflow, -- .next_segment = mptcp_blest_next_segment, -+ .next_segment = mptcp_next_segment, - .init = blestsched_init, - .name = "blest", - .owner = THIS_MODULE, -diff --git a/net/mptcp/mptcp_sched.c b/net/mptcp/mptcp_sched.c -index 18c3559b0d48..5bf2946a5caf 100644 ---- a/net/mptcp/mptcp_sched.c -+++ b/net/mptcp/mptcp_sched.c -@@ -372,8 +372,8 @@ static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) - if (!skb && meta_sk->sk_socket && - test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && - sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -- struct sock *subsk = get_available_subflow(meta_sk, NULL, -- false); -+ struct sock *subsk = mpcb->sched_ops->get_subflow(meta_sk, NULL, -+ false); - if (!subsk) - return NULL; - -@@ -385,7 +385,7 @@ static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) - return skb; - } - --static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, -+struct sk_buff *mptcp_next_segment(struct sock *meta_sk, - int *reinject, - struct sock **subsk, - unsigned int *limit) -@@ -402,7 +402,7 @@ static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, - if (!skb) - return NULL; - -- *subsk = get_available_subflow(meta_sk, skb, false); -+ *subsk = tcp_sk(meta_sk)->mpcb->sched_ops->get_subflow(meta_sk, skb, false); - if (!*subsk) - return NULL; - -@@ -449,6 +449,7 @@ static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, - - return skb; - } -+EXPORT_SYMBOL_GPL(mptcp_next_segment); - - static void defsched_init(struct sock *sk) - { - -From 5e8425e43b38e7e0fe566ffd50e197c07807ebdf Mon Sep 17 00:00:00 2001 -From: Daniel Weber -Date: Mon, 9 Mar 2020 11:09:27 +0100 -Subject: [PATCH 3/3] mptcp: Remove code-duplication from ECF scheduler - -The ECF scheduler relies on large parts of the default scheduler. This -commit removes the copied blocks and reuses 'mptcp_next_segment' and -'mptcp_rcv_buf_optimization' directly from it via function pointers. - -Signed-off-by: Daniel Weber ---- - net/mptcp/mptcp_ecf.c | 191 +----------------------------------------- - 1 file changed, 1 insertion(+), 190 deletions(-) - -diff --git a/net/mptcp/mptcp_ecf.c b/net/mptcp/mptcp_ecf.c -index e0bd430a8943..6b976b2b0c72 100644 ---- a/net/mptcp/mptcp_ecf.c -+++ b/net/mptcp/mptcp_ecf.c -@@ -21,7 +21,6 @@ - - #include - #include --#include - - static unsigned int mptcp_ecf_r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ - module_param(mptcp_ecf_r_beta, int, 0644); -@@ -154,194 +153,6 @@ static struct sock *ecf_get_available_subflow(struct sock *meta_sk, - return bestsk; - } - --/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ --static struct sk_buff *mptcp_ecf_rcv_buf_optimization(struct sock *sk, int penal) --{ -- struct sock *meta_sk; -- const struct tcp_sock *tp = tcp_sk(sk); -- struct mptcp_tcp_sock *mptcp; -- struct sk_buff *skb_head; -- struct ecfsched_priv *ecf_p = ecfsched_get_priv(tp); -- -- meta_sk = mptcp_meta_sk(sk); -- skb_head = tcp_rtx_queue_head(meta_sk); -- -- if (!skb_head) -- return NULL; -- -- /* If penalization is optional (coming from mptcp_next_segment() and -- * We are not send-buffer-limited we do not penalize. The retransmission -- * is just an optimization to fix the idle-time due to the delay before -- * we wake up the application. -- */ -- if (!penal && sk_stream_memory_free(meta_sk)) -- goto retrans; -- -- /* Only penalize again after an RTT has elapsed */ -- if (tcp_jiffies32 - ecf_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -- goto retrans; -- -- /* Half the cwnd of the slow flows */ -- mptcp_for_each_sub(tp->mpcb, mptcp) { -- struct tcp_sock *tp_it = mptcp->tp; -- -- if (tp_it != tp && -- TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -- if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -- u32 prior_cwnd = tp_it->snd_cwnd; -- -- tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -- -- /* If in slow start, do not reduce the ssthresh */ -- if (prior_cwnd >= tp_it->snd_ssthresh) -- tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -- -- ecf_p->last_rbuf_opti = tcp_jiffies32; -- } -- } -- } -- --retrans: -- -- /* Segment not yet injected into this path? Take it!!! */ -- if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -- bool do_retrans = false; -- mptcp_for_each_sub(tp->mpcb, mptcp) { -- struct tcp_sock *tp_it = mptcp->tp; -- -- if (tp_it != tp && -- TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -- if (tp_it->snd_cwnd <= 4) { -- do_retrans = true; -- break; -- } -- -- if (4 * tp->srtt_us >= tp_it->srtt_us) { -- do_retrans = false; -- break; -- } else { -- do_retrans = true; -- } -- } -- } -- -- if (do_retrans && mptcp_is_available(sk, skb_head, false)) { -- trace_mptcp_retransmit(sk, skb_head); -- return skb_head; -- } -- } -- return NULL; --} -- --/* copy from mptcp_sched.c: __mptcp_next_segment */ --/* Returns the next segment to be sent from the mptcp meta-queue. -- * (chooses the reinject queue if any segment is waiting in it, otherwise, -- * chooses the normal write queue). -- * Sets *@reinject to 1 if the returned segment comes from the -- * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -- * and sets it to -1 if it is a meta-level retransmission to optimize the -- * receive-buffer. -- */ --static struct sk_buff *__mptcp_ecf_next_segment(struct sock *meta_sk, int *reinject) --{ -- const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -- struct sk_buff *skb = NULL; -- -- *reinject = 0; -- -- /* If we are in fallback-mode, just take from the meta-send-queue */ -- if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -- return tcp_send_head(meta_sk); -- -- skb = skb_peek(&mpcb->reinject_queue); -- -- if (skb) { -- *reinject = 1; -- } else { -- skb = tcp_send_head(meta_sk); -- -- if (!skb && meta_sk->sk_socket && -- test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -- sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -- struct sock *subsk = ecf_get_available_subflow(meta_sk, NULL, -- false); -- if (!subsk) -- return NULL; -- -- skb = mptcp_ecf_rcv_buf_optimization(subsk, 0); -- if (skb) -- *reinject = -1; -- } -- } -- return skb; --} -- --/* copy from mptcp_sched.c: mptcp_next_segment */ --static struct sk_buff *mptcp_ecf_next_segment(struct sock *meta_sk, -- int *reinject, -- struct sock **subsk, -- unsigned int *limit) --{ -- struct sk_buff *skb = __mptcp_ecf_next_segment(meta_sk, reinject); -- unsigned int mss_now; -- struct tcp_sock *subtp; -- u16 gso_max_segs; -- u32 max_len, max_segs, window, needed; -- -- /* As we set it, we have to reset it as well. */ -- *limit = 0; -- -- if (!skb) -- return NULL; -- -- *subsk = ecf_get_available_subflow(meta_sk, skb, false); -- if (!*subsk) -- return NULL; -- -- subtp = tcp_sk(*subsk); -- mss_now = tcp_current_mss(*subsk); -- -- if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -- skb = mptcp_ecf_rcv_buf_optimization(*subsk, 1); -- if (skb) -- *reinject = -1; -- else -- return NULL; -- } -- -- /* No splitting required, as we will only send one single segment */ -- if (skb->len <= mss_now) -- return skb; -- -- /* The following is similar to tcp_mss_split_point, but -- * we do not care about nagle, because we will anyways -- * use TCP_NAGLE_PUSH, which overrides this. -- * -- * So, we first limit according to the cwnd/gso-size and then according -- * to the subflow's window. -- */ -- -- gso_max_segs = (*subsk)->sk_gso_max_segs; -- if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -- gso_max_segs = 1; -- max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -- if (!max_segs) -- return NULL; -- -- max_len = mss_now * max_segs; -- window = tcp_wnd_end(subtp) - subtp->write_seq; -- -- needed = min(skb->len, window); -- if (max_len <= skb->len) -- /* Take max_win, which is actually the cwnd/gso-size */ -- *limit = max_len; -- else -- /* Or, take the window */ -- *limit = needed; -- -- return skb; --} -- - static void ecfsched_init(struct sock *sk) - { - struct ecfsched_priv *ecf_p = ecfsched_get_priv(tcp_sk(sk)); -@@ -353,7 +164,7 @@ static void ecfsched_init(struct sock *sk) - - struct mptcp_sched_ops mptcp_sched_ecf = { - .get_subflow = ecf_get_available_subflow, -- .next_segment = mptcp_ecf_next_segment, -+ .next_segment = mptcp_next_segment, - .init = ecfsched_init, - .name = "ecf", - .owner = THIS_MODULE, From 1ce31508e2de666c25e238e9167ec44233f0341f Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 9 Jun 2020 17:38:50 +0200 Subject: [PATCH 57/76] Update MPTCP --- .../generic/hack-5.4/690-mptcp_trunk.patch | 269 +++++++++++------- 1 file changed, 168 insertions(+), 101 deletions(-) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index 819773ee..7f47e778 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -1,6 +1,20 @@ +diff -aurN linux-5.4/Documentation/admin-guide/kernel-parameters.txt mptcp-mptcp_trunk/Documentation/admin-guide/kernel-parameters.txt +--- linux-5.4/Documentation/admin-guide/kernel-parameters.txt 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/Documentation/admin-guide/kernel-parameters.txt 2020-06-09 17:33:41.000000000 +0200 +@@ -2724,6 +2724,10 @@ + allocations which rules out almost all kernel + allocations. Use with caution! + ++ mptcp_htable_entries= ++ [KNL,NET] Set number of hash buckets for MPTCP token ++ hashtables. ++ + MTD_Partition= [MTD] + Format: ,,, + diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt --- linux-5.4/Documentation/networking/ip-sysctl.txt 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-06-09 17:33:41.000000000 +0200 @@ -818,6 +818,18 @@ Default: 0 (disabled) @@ -22,7 +36,7 @@ diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Do udp_l3mdev_accept - BOOLEAN diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c --- linux-5.4/drivers/infiniband/hw/cxgb4/cm.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-06-09 17:33:41.000000000 +0200 @@ -3946,7 +3946,7 @@ */ memset(&tmp_opt, 0, sizeof(tmp_opt)); @@ -34,7 +48,7 @@ diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/ memset(req, 0, sizeof(*req)); diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbuff.h --- linux-5.4/include/linux/skbuff.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-06-09 17:33:41.000000000 +0200 @@ -717,7 +717,7 @@ * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. @@ -46,7 +60,7 @@ diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbu struct { diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h --- linux-5.4/include/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-06-09 17:33:41.000000000 +0200 @@ -54,7 +54,7 @@ /* TCP Fast Open */ #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ @@ -205,7 +219,7 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/inet_common.h --- linux-5.4/include/net/inet_common.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-06-09 17:33:41.000000000 +0200 @@ -2,6 +2,7 @@ #ifndef _INET_COMMON_H #define _INET_COMMON_H @@ -225,7 +239,7 @@ diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/ine int addr_len, int flags); diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/include/net/inet_connection_sock.h --- linux-5.4/include/net/inet_connection_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-06-09 17:33:41.000000000 +0200 @@ -25,6 +25,7 @@ struct inet_bind_bucket; @@ -236,7 +250,7 @@ diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/includ * Pointers to address related TCP functions diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_sock.h --- linux-5.4/include/net/inet_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-06-09 17:33:41.000000000 +0200 @@ -79,7 +79,7 @@ #define ireq_state req.__req_common.skc_state #define ireq_family req.__req_common.skc_family @@ -257,8 +271,8 @@ diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_ union { diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h --- linux-5.4/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-06-08 19:41:07.000000000 +0200 -@@ -0,0 +1,1542 @@ ++++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-06-09 17:33:41.000000000 +0200 +@@ -0,0 +1,1545 @@ +/* + * MPTCP implementation + * @@ -940,6 +954,11 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + __u8 addr_id; +} __attribute__((__packed__)); + ++struct mptcp_hashtable { ++ struct hlist_nulls_head *hashtable; ++ unsigned int mask; ++}; ++ +static inline int mptcp_sub_len_dss(const struct mp_dss *m, const int csum) +{ + return 4 + m->A * (4 + m->a * 4) + m->M * (10 + m->m * 4 + csum * 2); @@ -1046,9 +1065,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + */ +extern u32 mptcp_seed; + -+#define MPTCP_HASH_SIZE 1024 -+ -+extern struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; ++extern struct mptcp_hashtable mptcp_tk_htable; + +/* Request-sockets can be hashed in the tk_htb for collision-detection or in + * the regular htb for join-connections. We need to define different NULLS @@ -1803,7 +1820,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +#endif /* _MPTCP_H */ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_v4.h --- linux-5.4/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,76 @@ +/* + * MPTCP implementation @@ -1883,7 +1900,7 @@ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* MPTCP_V4_H_ */ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_v6.h --- linux-5.4/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,77 @@ +/* + * MPTCP implementation @@ -1964,7 +1981,7 @@ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* _MPTCP_V6_H */ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/net_namespace.h --- linux-5.4/include/net/net_namespace.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-06-09 17:33:41.000000000 +0200 @@ -19,6 +19,7 @@ #include #include @@ -1985,7 +2002,7 @@ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/n #endif diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/netns/mptcp.h --- linux-5.4/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,52 @@ +/* + * MPTCP implementation - MPTCP namespace @@ -2041,7 +2058,7 @@ diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/net +#endif /* __NETNS_MPTCP_H__ */ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h --- linux-5.4/include/net/snmp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/snmp.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/snmp.h 2020-06-09 17:33:41.000000000 +0200 @@ -86,7 +86,6 @@ atomic_long_t mibs[ICMP6MSG_MIB_MAX]; }; @@ -2052,7 +2069,7 @@ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h struct tcp_mib { diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h --- linux-5.4/include/net/sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/sock.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/sock.h 2020-06-09 17:33:41.000000000 +0200 @@ -814,6 +814,7 @@ SOCK_TXTIME, SOCK_XDP, /* XDP is attached */ @@ -2071,7 +2088,7 @@ diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h #ifdef CONFIG_PROC_FS diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h --- linux-5.4/include/net/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/tcp.h 2020-06-09 17:33:41.000000000 +0200 @@ -182,6 +182,7 @@ #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ @@ -2418,7 +2435,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h { diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_states.h --- linux-5.4/include/net/tcp_states.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-06-09 17:33:41.000000000 +0200 @@ -22,6 +22,7 @@ TCP_LISTEN, TCP_CLOSING, /* Now a valid state */ @@ -2437,7 +2454,7 @@ diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_ #endif /* _LINUX_TCP_STATES_H */ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/transp_v6.h --- linux-5.4/include/net/transp_v6.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-06-09 17:33:41.000000000 +0200 @@ -58,6 +58,8 @@ /* address family specific functions */ @@ -2449,7 +2466,7 @@ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/trans diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/events/tcp.h --- linux-5.4/include/trace/events/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-06-09 17:33:41.000000000 +0200 @@ -10,6 +10,7 @@ #include #include @@ -2500,7 +2517,7 @@ diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/ #endif /* _TRACE_TCP_H */ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/linux/bpf.h --- linux-5.4/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-06-09 17:33:41.000000000 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ @@ -2511,7 +2528,7 @@ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/lin }; diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linux/if.h --- linux-5.4/include/uapi/linux/if.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-06-09 17:33:41.000000000 +0200 @@ -132,6 +132,9 @@ #define IFF_ECHO IFF_ECHO #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ @@ -2524,7 +2541,7 @@ diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linu diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/linux/mptcp.h --- linux-5.4/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* @@ -2677,7 +2694,7 @@ diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/l +#endif /* _LINUX_MPTCP_H */ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/linux/tcp.h --- linux-5.4/include/uapi/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-06-09 17:33:41.000000000 +0200 @@ -18,9 +18,15 @@ #ifndef _UAPI_LINUX_TCP_H #define _UAPI_LINUX_TCP_H @@ -2765,7 +2782,7 @@ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/lin diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c --- linux-5.4/net/core/dev.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/dev.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/dev.c 2020-06-09 17:33:41.000000000 +0200 @@ -7855,7 +7855,7 @@ dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | @@ -2777,7 +2794,7 @@ diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces.c --- linux-5.4/net/core/net-traces.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-06-09 17:33:41.000000000 +0200 @@ -60,3 +60,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); @@ -2786,7 +2803,7 @@ diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces +EXPORT_TRACEPOINT_SYMBOL_GPL(mptcp_retransmit); diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c --- linux-5.4/net/core/skbuff.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-06-09 17:33:41.000000000 +0200 @@ -573,7 +573,7 @@ skb_drop_list(&skb_shinfo(skb)->frag_list); } @@ -2798,7 +2815,7 @@ diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c --- linux-5.4/net/core/sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/sock.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/sock.c 2020-06-09 17:33:41.000000000 +0200 @@ -135,6 +135,11 @@ #include @@ -2860,7 +2877,7 @@ diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c --- linux-5.4/net/ipv4/af_inet.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-06-09 17:33:41.000000000 +0200 @@ -100,6 +100,7 @@ #include #include @@ -2926,7 +2943,7 @@ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c --- linux-5.4/net/ipv4/inet_connection_sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-06-09 17:33:41.000000000 +0200 @@ -19,6 +19,7 @@ #include #include @@ -2986,7 +3003,7 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ cond_resched(); diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c --- linux-5.4/net/ipv4/ip_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-06-09 17:33:41.000000000 +0200 @@ -44,6 +44,8 @@ #endif #include @@ -3028,7 +3045,7 @@ diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockgl case IP_TTL: diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig --- linux-5.4/net/ipv4/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-06-09 17:33:41.000000000 +0200 @@ -654,6 +654,51 @@ bufferbloat, policers, or AQM schemes that do not provide a delay signal. It requires the fq ("Fair Queue") pacing packet scheduler. @@ -3116,7 +3133,7 @@ diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig default "cdg" if DEFAULT_CDG diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies.c --- linux-5.4/net/ipv4/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-06-09 17:33:41.000000000 +0200 @@ -12,6 +12,8 @@ #include #include @@ -3244,7 +3261,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies */ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c --- linux-5.4/net/ipv4/tcp.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-06-09 17:33:41.000000000 +0200 @@ -270,6 +270,7 @@ #include @@ -3987,7 +4004,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c EXPORT_SYMBOL_GPL(tcp_abort); diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c --- linux-5.4/net/ipv4/tcp_cong.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-06-09 17:33:41.000000000 +0200 @@ -328,13 +328,19 @@ return ret; } @@ -4012,7 +4029,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c const struct tcp_congestion_ops *ca; diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c --- linux-5.4/net/ipv4/tcp_diag.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-06-09 17:33:41.000000000 +0200 @@ -31,7 +31,7 @@ r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; } @@ -4024,7 +4041,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c #ifdef CONFIG_TCP_MD5SIG diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c --- linux-5.4/net/ipv4/tcp_fastopen.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-06-09 17:33:41.000000000 +0200 @@ -9,6 +9,7 @@ #include #include @@ -4085,7 +4102,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fast */ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c --- linux-5.4/net/ipv4/tcp_input.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-06-09 17:33:41.000000000 +0200 @@ -76,35 +76,15 @@ #include #include @@ -4969,7 +4986,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_rsk(req)->tfo_listener = false; diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c --- linux-5.4/net/ipv4/tcp_ipv4.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-06-09 17:33:41.000000000 +0200 @@ -62,6 +62,8 @@ #include #include @@ -5434,7 +5451,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c --- linux-5.4/net/ipv4/tcp_minisocks.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-06-09 17:33:41.000000000 +0200 @@ -19,11 +19,13 @@ * Jorge Cwik, */ @@ -5676,7 +5693,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min } diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output.c --- linux-5.4/net/ipv4/tcp_output.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-06-09 17:33:41.000000000 +0200 @@ -37,6 +37,12 @@ #define pr_fmt(fmt) "TCP: " fmt @@ -6267,7 +6284,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Cancel probe timer, if it is not required. */ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c --- linux-5.4/net/ipv4/tcp_timer.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-06-09 17:33:41.000000000 +0200 @@ -21,6 +21,7 @@ #include @@ -6481,7 +6498,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c --- linux-5.4/net/ipv6/addrconf.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-06-09 17:33:41.000000000 +0200 @@ -967,6 +967,7 @@ kfree_rcu(ifp, rcu); @@ -6492,7 +6509,7 @@ diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c --- linux-5.4/net/ipv6/af_inet6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-06-09 17:33:41.000000000 +0200 @@ -104,8 +104,7 @@ return (struct ipv6_pinfo *)(((u8 *)sk) + offset); } @@ -6505,7 +6522,7 @@ diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c struct ipv6_pinfo *np; diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c --- linux-5.4/net/ipv6/ipv6_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-06-09 17:33:41.000000000 +0200 @@ -44,6 +44,8 @@ #include #include @@ -6531,7 +6548,7 @@ diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_so tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies.c --- linux-5.4/net/ipv6/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-06-09 17:33:41.000000000 +0200 @@ -15,6 +15,8 @@ #include #include @@ -6621,7 +6638,7 @@ diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies out_free: diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c --- linux-5.4/net/ipv6/tcp_ipv6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-06-09 17:33:41.000000000 +0200 @@ -58,6 +58,8 @@ #include #include @@ -7215,7 +7232,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c /* thinking of making this const? Don't. diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig --- linux-5.4/net/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Kconfig 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/Kconfig 2020-06-09 17:33:41.000000000 +0200 @@ -91,6 +91,7 @@ source "net/ipv4/Kconfig" source "net/ipv6/Kconfig" @@ -7226,7 +7243,7 @@ diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile --- linux-5.4/net/Makefile 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Makefile 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/Makefile 2020-06-09 17:33:41.000000000 +0200 @@ -20,6 +20,7 @@ obj-$(CONFIG_XFRM) += xfrm/ obj-$(CONFIG_UNIX_SCM) += unix/ @@ -7237,7 +7254,7 @@ diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile obj-$(CONFIG_NET_KEY) += key/ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig --- linux-5.4/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,152 @@ +# +# MPTCP configuration @@ -7393,7 +7410,7 @@ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig + diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile --- linux-5.4/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,25 @@ +# +## Makefile for MultiPath TCP support code. @@ -7422,7 +7439,7 @@ diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile +mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c --- linux-5.4/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,193 @@ +/* + * Desynchronized Multi-Channel TCP Congestion Control Algorithm @@ -7619,7 +7636,7 @@ diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_ +MODULE_VERSION("1.0"); diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c --- linux-5.4/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,261 @@ +/* + * MPTCP implementation - Balia Congestion Control @@ -7884,7 +7901,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c --- linux-5.4/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,494 @@ +#include + @@ -8382,7 +8399,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c --- linux-5.4/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP Scheduler to reduce HoL-blocking and spurious retransmissions. @@ -8671,7 +8688,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_VERSION("0.95"); diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c --- linux-5.4/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,262 @@ +/* + * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) @@ -8937,8 +8954,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c --- linux-5.4/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-06-08 19:41:07.000000000 +0200 -@@ -0,0 +1,3250 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-06-09 17:33:41.000000000 +0200 +@@ -0,0 +1,3299 @@ +/* + * MPTCP implementation - MPTCP-control + * @@ -8986,6 +9003,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +#include +#include + ++#include +#include +#include +#include @@ -9113,16 +9131,16 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + { } +}; + -+static inline u32 mptcp_hash_tk(u32 token) ++static inline u32 mptcp_hash_tk(u32 token, struct mptcp_hashtable *htable) +{ -+ return token % MPTCP_HASH_SIZE; ++ return token & htable->mask; +} + -+struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; -+EXPORT_SYMBOL(tk_hashtable); ++struct mptcp_hashtable mptcp_tk_htable; ++EXPORT_SYMBOL(mptcp_tk_htable); + +/* The following hash table is used to avoid collision of token */ -+static struct hlist_nulls_head mptcp_reqsk_tk_htb[MPTCP_HASH_SIZE]; ++static struct mptcp_hashtable mptcp_reqsk_tk_htb; + +/* Lock, protecting the two hash-tables that hold the token. Namely, + * mptcp_reqsk_tk_htb and tk_hashtable @@ -9131,13 +9149,14 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + +static bool mptcp_reqsk_find_tk(const u32 token) +{ -+ const u32 hash = mptcp_hash_tk(token); ++ const u32 hash = mptcp_hash_tk(token, &mptcp_reqsk_tk_htb); + const struct mptcp_request_sock *mtreqsk; + const struct hlist_nulls_node *node; + +begin: + hlist_nulls_for_each_entry_rcu(mtreqsk, node, -+ &mptcp_reqsk_tk_htb[hash], hash_entry) { ++ &mptcp_reqsk_tk_htb.hashtable[hash], ++ hash_entry) { + if (token == mtreqsk->mptcp_loc_token) + return true; + } @@ -9154,10 +9173,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + +static void mptcp_reqsk_insert_tk(struct request_sock *reqsk, const u32 token) +{ -+ u32 hash = mptcp_hash_tk(token); ++ u32 hash = mptcp_hash_tk(token, &mptcp_reqsk_tk_htb); + + hlist_nulls_add_head_rcu(&mptcp_rsk(reqsk)->hash_entry, -+ &mptcp_reqsk_tk_htb[hash]); ++ &mptcp_reqsk_tk_htb.hashtable[hash]); +} + +static void mptcp_reqsk_remove_tk(const struct request_sock *reqsk) @@ -9179,19 +9198,23 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + +static void __mptcp_hash_insert(struct tcp_sock *meta_tp, const u32 token) +{ -+ u32 hash = mptcp_hash_tk(token); -+ hlist_nulls_add_head_rcu(&meta_tp->tk_table, &tk_hashtable[hash]); ++ u32 hash = mptcp_hash_tk(token, &mptcp_tk_htable); ++ ++ hlist_nulls_add_head_rcu(&meta_tp->tk_table, ++ &mptcp_tk_htable.hashtable[hash]); + meta_tp->inside_tk_table = 1; +} + +static bool mptcp_find_token(u32 token) +{ -+ const u32 hash = mptcp_hash_tk(token); ++ const u32 hash = mptcp_hash_tk(token, &mptcp_tk_htable); + const struct tcp_sock *meta_tp; + const struct hlist_nulls_node *node; + +begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], tk_table) { ++ hlist_nulls_for_each_entry_rcu(meta_tp, node, ++ &mptcp_tk_htable.hashtable[hash], ++ tk_table) { + if (token == meta_tp->mptcp_loc_token) + return true; + } @@ -9470,7 +9493,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + */ +struct sock *mptcp_hash_find(const struct net *net, const u32 token) +{ -+ const u32 hash = mptcp_hash_tk(token); ++ const u32 hash = mptcp_hash_tk(token, &mptcp_tk_htable); + const struct tcp_sock *meta_tp; + struct sock *meta_sk = NULL; + const struct hlist_nulls_node *node; @@ -9478,7 +9501,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + rcu_read_lock(); + local_bh_disable(); +begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], ++ hlist_nulls_for_each_entry_rcu(meta_tp, node, ++ &mptcp_tk_htable.hashtable[hash], + tk_table) { + meta_sk = (struct sock *)meta_tp; + if (token == meta_tp->mptcp_loc_token && @@ -11978,17 +12002,18 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +{ + struct tcp_sock *meta_tp; + const struct net *net = seq->private; -+ int i, n = 0; ++ unsigned int i, n = 0; + + seq_printf(seq, " sl loc_tok rem_tok v6 local_address remote_address st ns tx_queue rx_queue inode"); + seq_putc(seq, '\n'); + -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { ++ for (i = 0; i <= mptcp_tk_htable.mask; i++) { + struct hlist_nulls_node *node; + rcu_read_lock(); + local_bh_disable(); + hlist_nulls_for_each_entry_rcu(meta_tp, node, -+ &tk_hashtable[i], tk_table) { ++ &mptcp_tk_htable.hashtable[i], ++ tk_table) { + struct sock *meta_sk = (struct sock *)meta_tp; + struct inet_sock *isk = inet_sk(meta_sk); + struct mptcp_cb *mpcb = meta_tp->mpcb; @@ -12102,10 +12127,27 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + .exit = mptcp_pm_exit_net, +}; + ++static unsigned long mptcp_htable_entries __initdata; ++ ++static int __init set_mptcp_htable_entries(char *str) ++{ ++ ssize_t ret; ++ ++ if (!str) ++ return 0; ++ ++ ret = kstrtoul(str, 0, &mptcp_htable_entries); ++ if (ret) ++ return 0; ++ ++ return 1; ++} ++__setup("mptcp_htable_entries=", set_mptcp_htable_entries); ++ +/* General initialization of mptcp */ +void __init mptcp_init(void) +{ -+ int i; ++ unsigned int i; + struct ctl_table_header *mptcp_sysctl; + + mptcp_sock_cache = kmem_cache_create("mptcp_sock", @@ -12133,10 +12175,34 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + if (!mptcp_wq) + goto alloc_workqueue_failed; + -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ INIT_HLIST_NULLS_HEAD(&tk_hashtable[i], i); -+ INIT_HLIST_NULLS_HEAD(&mptcp_reqsk_tk_htb[i], i); -+ } ++ mptcp_tk_htable.hashtable = ++ alloc_large_system_hash("MPTCP tokens", ++ sizeof(mptcp_tk_htable.hashtable[0]), ++ mptcp_htable_entries, ++ 18, /* one slot per 256KB of memory */ ++ 0, ++ NULL, ++ &mptcp_tk_htable.mask, ++ 1024, ++ mptcp_htable_entries ? 0 : 1024 * 1024); ++ ++ for (i = 0; i <= mptcp_tk_htable.mask; i++) ++ INIT_HLIST_NULLS_HEAD(&mptcp_tk_htable.hashtable[i], i); ++ ++ mptcp_reqsk_tk_htb.hashtable = ++ alloc_large_system_hash("MPTCP request tokens", ++ sizeof(mptcp_reqsk_tk_htb.hashtable[0]), ++ mptcp_htable_entries, ++ 18, /* one slot per 256KB of memory */ ++ 0, ++ NULL, ++ &mptcp_reqsk_tk_htb.mask, ++ 1024, ++ mptcp_htable_entries ? 0 : 1024 * 1024); ++ ++ for (i = 0; i <= mptcp_reqsk_tk_htb.mask; i++) ++ INIT_HLIST_NULLS_HEAD(&mptcp_reqsk_tk_htb.hashtable[i], i); ++ + + spin_lock_init(&mptcp_tk_hashlock); + @@ -12191,7 +12257,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +} diff -aurN linux-5.4/net/mptcp/mptcp_ecf.c mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c --- linux-5.4/net/mptcp/mptcp_ecf.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP ECF Scheduler @@ -12390,8 +12456,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ecf.c mptcp-mptcp_trunk/net/mptcp/mptcp_ecf +MODULE_VERSION("0.95"); diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c --- linux-5.4/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-06-08 19:41:07.000000000 +0200 -@@ -0,0 +1,1937 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-06-09 17:33:41.000000000 +0200 +@@ -0,0 +1,1938 @@ +#include +#include + @@ -13239,12 +13305,13 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc + goto next_event; + + /* Now we iterate over the MPTCP-sockets and apply the event. */ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { ++ for (i = 0; i <= mptcp_tk_htable.mask; i++) { + const struct hlist_nulls_node *node; + struct tcp_sock *meta_tp; + + rcu_read_lock_bh(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[i], ++ hlist_nulls_for_each_entry_rcu(meta_tp, node, ++ &mptcp_tk_htable.hashtable[i], + tk_table) { + struct sock *meta_sk = (struct sock *)meta_tp, *sk; + bool meta_v4 = meta_sk->sk_family == AF_INET; @@ -14331,7 +14398,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc +MODULE_VERSION("0.88"); diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_input.c --- linux-5.4/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,2529 @@ +/* + * MPTCP implementation - Sending side @@ -16864,7 +16931,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i +} diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c --- linux-5.4/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,430 @@ +/* + * MPTCP implementation - IPv4-specific functions @@ -17298,7 +17365,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip +} diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c --- linux-5.4/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,478 @@ +/* + * MPTCP implementation - IPv6-specific functions @@ -17780,7 +17847,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip +} diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c --- linux-5.4/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,174 @@ +#include + @@ -17958,7 +18025,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mp +MODULE_VERSION("0.88"); diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c --- linux-5.4/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,1271 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP implementation - Netlink Path Manager @@ -19233,7 +19300,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_ALIAS_GENL_FAMILY(MPTCP_GENL_NAME); diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c --- linux-5.4/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,318 @@ +/* + * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: @@ -19555,7 +19622,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_ol +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_output.c --- linux-5.4/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,1994 @@ +/* + * MPTCP implementation - Sending side @@ -21553,7 +21620,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c --- linux-5.4/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,226 @@ +/* + * MPTCP implementation - MPTCP-subflow-management @@ -21783,7 +21850,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c +late_initcall(mptcp_path_manager_default); diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c --- linux-5.4/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,392 @@ +/* + * MPTCP Scheduler to reduce latency and jitter. @@ -22179,7 +22246,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mpt +MODULE_VERSION("0.90"); diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c --- linux-5.4/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,309 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -22492,7 +22559,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c +MODULE_VERSION("0.89"); diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c --- linux-5.4/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,647 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -23143,7 +23210,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s +late_initcall(mptcp_scheduler_default); diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c --- linux-5.4/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-06-09 17:33:41.000000000 +0200 @@ -0,0 +1,271 @@ +/* + * MPTCP implementation - WEIGHTED VEGAS @@ -23418,7 +23485,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_VERSION("0.1"); diff -aurN linux-5.4/tools/include/uapi/linux/bpf.h mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h --- linux-5.4/tools/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-06-08 19:41:07.000000000 +0200 ++++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-06-09 17:33:41.000000000 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ From dd134438c6d3cbd01fde376f5502682316451dbc Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 9 Jun 2020 22:40:25 +0200 Subject: [PATCH 58/76] Fix MPTCP patch for 5.4.45 kernel --- .../generic/hack-5.4/690-mptcp_trunk.patch | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index 7f47e778..af8944c8 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -2872,8 +2872,8 @@ diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c sock_reset_flag(newsk, SOCK_DONE); + sock_reset_flag(newsk, SOCK_MPTCP); - mem_cgroup_sk_alloc(newsk); - cgroup_sk_alloc(&newsk->sk_cgrp_data); + + /* sk->sk_memcg will be populated at accept() time */ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c --- linux-5.4/net/ipv4/af_inet.c 2019-11-25 01:32:01.000000000 +0100 @@ -3646,7 +3646,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c seq = tp->write_seq + tp->max_window + 2; if (!seq) -@@ -2616,15 +2730,11 @@ +@@ -2616,17 +2730,11 @@ icsk->icsk_backoff = 0; tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; @@ -3655,6 +3655,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c - tp->snd_cwnd = TCP_INIT_CWND; - tp->snd_cwnd_cnt = 0; tp->window_clamp = 0; +- tp->delivered = 0; - tp->delivered_ce = 0; + + tcp_reset_vars(sk); @@ -3662,17 +3663,22 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tcp_set_ca_state(sk, TCP_CA_Open); - tp->is_sack_reneg = 0; - tcp_clear_retrans(tp); +- tp->total_retrans = 0; inet_csk_delack_init(sk); /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 * issue in __tcp_select_window() -@@ -2636,10 +2746,6 @@ +@@ -2636,14 +2746,10 @@ sk->sk_rx_dst = NULL; tcp_saved_syn_free(tp); tp->compressed_ack = 0; + tp->segs_in = 0; + tp->segs_out = 0; - tp->bytes_sent = 0; - tp->bytes_acked = 0; - tp->bytes_received = 0; - tp->bytes_retrans = 0; + tp->data_segs_in = 0; + tp->data_segs_out = 0; tp->duplicate_sack[0].start_seq = 0; tp->duplicate_sack[0].end_seq = 0; tp->dsack_dups = 0; @@ -4501,12 +4507,14 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { int eaten; struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4746,7 +4811,7 @@ +@@ -4746,8 +4811,8 @@ const struct tcp_sock *tp = tcp_sk(sk); int avail = tp->rcv_nxt - tp->copied_seq; -- if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE)) -+ if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) +- if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && +- !sock_flag(sk, SOCK_DONE)) ++ if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && !mptcp(tp) && ++ !sock_flag(sk, SOCK_DONE)) return; sk->sk_data_ready(sk); @@ -5830,7 +5838,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output return MAX_TCP_OPTION_SPACE - remaining; } -@@ -747,16 +753,22 @@ +@@ -747,17 +753,22 @@ opts->tsecr = tp->rx_opt.ts_recent; size += TCPOLEN_TSTAMP_ALIGNED; } @@ -5844,8 +5852,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output - min_t(unsigned int, eff_sacks, - (remaining - TCPOLEN_SACK_BASE_ALIGNED) / - TCPOLEN_SACK_PERBLOCK); -- size += TCPOLEN_SACK_BASE_ALIGNED + -- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; +- if (likely(opts->num_sack_blocks)) +- size += TCPOLEN_SACK_BASE_ALIGNED + +- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; + const unsigned remaining = MAX_TCP_OPTION_SPACE - size; + if (remaining < TCPOLEN_SACK_BASE_ALIGNED) + opts->num_sack_blocks = 0; @@ -5854,7 +5863,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output + min_t(unsigned int, eff_sacks, + (remaining - TCPOLEN_SACK_BASE_ALIGNED) / + TCPOLEN_SACK_PERBLOCK); -+ if (opts->num_sack_blocks) ++ if (likely(opts->num_sack_blocks)) + size += TCPOLEN_SACK_BASE_ALIGNED + + opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; } From 48bd9621aaa8cd8f1be74205249b2bc934957276 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 9 Jun 2020 22:40:38 +0200 Subject: [PATCH 59/76] Update to latest OpenWrt --- build.sh | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/build.sh b/build.sh index 667bf351..08185f96 100755 --- a/build.sh +++ b/build.sh @@ -26,10 +26,12 @@ OMR_REPO=${OMR_REPO:-http://$OMR_HOST:$OMR_PORT/release/$OMR_KERNEL} OMR_KEEPBIN=${OMR_KEEPBIN:-no} OMR_IMG=${OMR_IMG:-yes} #OMR_UEFI=${OMR_UEFI:-yes} +OMR_PACKAGES=${OMR_PACKAGES:-full} OMR_ALL_PACKAGES=${OMR_ALL_PACKAGES:-no} OMR_TARGET=${OMR_TARGET:-x86_64} OMR_TARGET_CONFIG="config-$OMR_TARGET" OMR_KERNEL=${OMR_KERNEL:-5.4} +OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1` | sed 's/[^0-9.]//g')} OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" OMR_FEED_SRC="${OMR_FEED_SRC:-develop}" @@ -61,9 +63,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "559b3384666bbc6e4e9e6d86cf54bd88d30b341f" - _get_repo feeds/packages https://github.com/openwrt/packages "b7c82d57b69efee3b4e04483d5e7db9cfa5dcad5" - _get_repo feeds/luci https://github.com/openwrt/luci "6be8f8dbaee90a8a7e8bc87350f21793b9aed35c" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "8a858363b00d9496a04ff381d65301b1d529faee" + _get_repo feeds/packages https://github.com/openwrt/packages "534b88c5f8f0c4f608b7dd7eed1bdabf10252de2" + _get_repo feeds/luci https://github.com/openwrt/luci "0412e85a57c2f271c24fe837e3a6adcf60bc63f1" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -107,12 +109,19 @@ src-link luci $(readlink -f feeds/luci) src-link openmptcprouter $(readlink -f "$OMR_FEED") EOF +#cat > "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" < "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" < "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" <> "$OMR_TARGET/source/.config" fi +if [ "$OMR_PACKAGES" = "full" ]; then + echo 'CONFIG_PACKAGE_${OMR_DIST}-full=y' >> "$OMR_TARGET/source/.config" +fi +if [ "$OMR_PACKAGES" = "mini" ]; then + echo 'CONFIG_PACKAGE_${OMR_DIST}-mini=y' >> "$OMR_TARGET/source/.config" +fi + cd "$OMR_TARGET/source" #if [ "$OMR_UEFI" = "yes" ] && [ "$OMR_TARGET" = "x86_64" ]; then @@ -273,7 +289,9 @@ if [ "$OMR_ALL_PACKAGES" = "yes" ]; then scripts/feeds install -a -d m -p packages scripts/feeds install -a -d m -p luci fi -scripts/feeds install -a -d y -f -p openmptcprouter +rm -rf feeds/luci/modules/luci-mod-network +#scripts/feeds install -a -d y -f -p openmptcprouter +scripts/feeds install -d y -f -p openmptcprouter cp .config.keep .config echo "Done" From 530261b60656b93eb3b1bb98bd5ccf6bd11acb46 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 10 Jun 2020 09:31:00 +0200 Subject: [PATCH 60/76] Remove BPI-R2 patch not needed anymore --- .../patches-5.4/0101-dsa-enable-vlan.patch | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 root/target/linux/mediatek/patches-5.4/0101-dsa-enable-vlan.patch diff --git a/root/target/linux/mediatek/patches-5.4/0101-dsa-enable-vlan.patch b/root/target/linux/mediatek/patches-5.4/0101-dsa-enable-vlan.patch deleted file mode 100644 index 065fda3f..00000000 --- a/root/target/linux/mediatek/patches-5.4/0101-dsa-enable-vlan.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 35082b70e998d5b419e351010005494e7a5b9412 Mon Sep 17 00:00:00 2001 -From: Landen Chao -Date: Tue, 31 Dec 2019 11:48:41 +0100 -Subject: [PATCH] net: dsa: enable vlan without bridge on dsa user port - ---- - drivers/net/dsa/mt7530.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c -index 1d8d36de4d20..7e285aa9bd7c 100644 ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1165,8 +1165,13 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port, - /* The port is kept as VLAN-unaware if bridge with vlan_filtering not - * being set. - */ -- if (!dsa_port_is_vlan_filtering(&ds->ports[port])) -+ if (!dsa_port_is_vlan_filtering(&ds->ports[port])){ -+ /* Enable VLAN tagged in port-based vlan setting. */ -+ if ((vlan->vid_begin != 0) && (vlan->vid_end != 0)) -+ mt7530_rmw(priv, MT7530_PCR_P(port), EG_TAG(3), -+ EG_TAG(2)); - return; -+ } - - mutex_lock(&priv->reg_mutex); - -@@ -1196,8 +1201,13 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port, - /* The port is kept as VLAN-unaware if bridge with vlan_filtering not - * being set. - */ -- if (!dsa_port_is_vlan_filtering(&ds->ports[port])) -+ if (!dsa_port_is_vlan_filtering(&ds->ports[port])) { -+ /* Disable VLAN tagged in port-based vlan setting. */ -+ if ((vlan->vid_begin != 0) && (vlan->vid_end != 0)) -+ mt7530_rmw(priv, MT7530_PCR_P(port), EG_TAG(3), -+ EG_TAG(0)); - return 0; -+ } - - mutex_lock(&priv->reg_mutex); - From 558bed738764f828ed21518c25c2eb62375f56c3 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 10 Jun 2020 20:25:34 +0200 Subject: [PATCH 61/76] Update OpenWrt and use OMR package only if it's to compile OMR --- build.sh | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/build.sh b/build.sh index 08185f96..bd41df55 100755 --- a/build.sh +++ b/build.sh @@ -63,9 +63,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "8a858363b00d9496a04ff381d65301b1d529faee" - _get_repo feeds/packages https://github.com/openwrt/packages "534b88c5f8f0c4f608b7dd7eed1bdabf10252de2" - _get_repo feeds/luci https://github.com/openwrt/luci "0412e85a57c2f271c24fe837e3a6adcf60bc63f1" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "e5aa498acb847320a382034ba0b9cfc55e6f13ca" + _get_repo feeds/packages https://github.com/openwrt/packages "69fd6ab319e170dd690a6495e8c1a7abe79f3960" + _get_repo feeds/luci https://github.com/openwrt/luci "16f443bf4caf6e7dd85efd1ce111b45779acdf5e" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -109,20 +109,23 @@ src-link luci $(readlink -f feeds/luci) src-link openmptcprouter $(readlink -f "$OMR_FEED") EOF -#cat > "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" < "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" < "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" <<-EOF + src/gz openwrt_luci http://packages.openmptcprouter.com/${OMR_RELEASE}/${OMR_REAL_TARGET}/luci + src/gz openwrt_packages http://packages.openmptcprouter.com/${OMR_RELEASE}/${OMR_REAL_TARGET}/packages + src/gz openwrt_base http://packages.openmptcprouter.com/${OMR_RELEASE}/${OMR_REAL_TARGET}/base + src/gz openwrt_routing http://packages.openmptcprouter.com/${OMR_RELEASE}/${OMR_REAL_TARGET}/routing + src/gz openwrt_telephony http://packages.openmptcprouter.com/${OMR_RELEASE}/${OMR_REAL_TARGET}/telephony + EOF +else + cat > "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" <<-EOF + src/gz openwrt_luci http://downloads.openwrt.org/snapshots/packages/${OMR_REAL_TARGET}/luci + src/gz openwrt_packages http://downloads.openwrt.org/snapshots/packages/${OMR_REAL_TARGET}/packages + src/gz openwrt_base http://downloads.openwrt.org/snapshots/packages/${OMR_REAL_TARGET}/base + src/gz openwrt_routing http://downloads.openwrt.org/snapshots/packages/${OMR_REAL_TARGET}/routing + src/gz openwrt_telephony http://downloads.openwrt.org/snapshots/packages/${OMR_REAL_TARGET}/telephony + EOF +fi #cat > "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" < Date: Thu, 11 Jun 2020 08:35:21 +0200 Subject: [PATCH 62/76] Fix --- build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index bd41df55..00d03d1c 100755 --- a/build.sh +++ b/build.sh @@ -275,6 +275,8 @@ rm -rf target/linux/mediatek/patches-4.14/0027-*.patch rm -rf feeds/packages/libs/libwebp echo "Update feeds index" +rm -rf feeds/luci/modules/luci-mod-network + cp .config .config.keep scripts/feeds clean scripts/feeds update -a @@ -292,7 +294,6 @@ if [ "$OMR_ALL_PACKAGES" = "yes" ]; then scripts/feeds install -a -d m -p packages scripts/feeds install -a -d m -p luci fi -rm -rf feeds/luci/modules/luci-mod-network scripts/feeds install -a -d y -f -p openmptcprouter cp .config.keep .config echo "Done" From 1d23197b5dfda585ef2f8864da3473243f66f106 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 26 Jun 2020 21:23:24 +0200 Subject: [PATCH 63/76] Update OpenWrt --- build.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/build.sh b/build.sh index 00d03d1c..ea642ed6 100755 --- a/build.sh +++ b/build.sh @@ -31,7 +31,8 @@ OMR_ALL_PACKAGES=${OMR_ALL_PACKAGES:-no} OMR_TARGET=${OMR_TARGET:-x86_64} OMR_TARGET_CONFIG="config-$OMR_TARGET" OMR_KERNEL=${OMR_KERNEL:-5.4} -OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1` | sed 's/[^0-9.]//g')} +#OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1` | sed 's/^\([0-9.]*\).*/\1/')} +OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1`)} OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" OMR_FEED_SRC="${OMR_FEED_SRC:-develop}" @@ -63,9 +64,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "e5aa498acb847320a382034ba0b9cfc55e6f13ca" - _get_repo feeds/packages https://github.com/openwrt/packages "69fd6ab319e170dd690a6495e8c1a7abe79f3960" - _get_repo feeds/luci https://github.com/openwrt/luci "16f443bf4caf6e7dd85efd1ce111b45779acdf5e" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "635f111148c3f7ccb0ecc92863a3b1a142f6ebeb" + _get_repo feeds/packages https://github.com/openwrt/packages "c7dca50f110d5458ceff21a2274eddae2aae119b" + _get_repo feeds/luci https://github.com/openwrt/luci "558525783cf33a986efa33d23f5283b33a6c936e" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From 9ca8f2dda552fb932833aaad964b2cd72bc8c709 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 29 Jun 2020 15:10:24 +0200 Subject: [PATCH 64/76] Add chinese and fix getting last tag --- build.sh | 2 +- config | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index ea642ed6..bbed9188 100755 --- a/build.sh +++ b/build.sh @@ -32,7 +32,7 @@ OMR_TARGET=${OMR_TARGET:-x86_64} OMR_TARGET_CONFIG="config-$OMR_TARGET" OMR_KERNEL=${OMR_KERNEL:-5.4} #OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1` | sed 's/^\([0-9.]*\).*/\1/')} -OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1`)} +OMR_RELEASE=${OMR_RELEASE:-$(git tag --sort=committerdate | tail -1)} OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" OMR_FEED_SRC="${OMR_FEED_SRC:-develop}" diff --git a/config b/config index 971e38db..e4fc694a 100644 --- a/config +++ b/config @@ -218,7 +218,8 @@ CONFIG_LUCI_LANG_vi=y CONFIG_LUCI_LANG_de=y CONFIG_LUCI_LANG_no=y CONFIG_LUCI_LANG_ms=y -CONFIG_LUCI_LANG_zh-cn=y +CONFIG_LUCI_LANG_zh_Hans=y +CONFIG_LUCI_LANG_zh_Hant=y CONFIG_LUCI_LANG_ko=y CONFIG_LUCI_LANG_he=y CONFIG_LUCI_LANG_zh-tw=y @@ -228,10 +229,17 @@ CONFIG_LUCI_LANG_ru=y CONFIG_LUCI_LANG_el=y CONFIG_LUCI_LANG_ca=y CONFIG_LUCI_LANG_es=y -CONFIG_LUCI_LANG_pt-br=y +CONFIG_LUCI_LANG_pt_BR=y CONFIG_LUCI_LANG_cs=y CONFIG_LUCI_LANG_fr=y CONFIG_LUCI_LANG_it=y +CONFIG_LUCI_LANG_ar=y +CONFIG_LUCI_LANG_bg=y +CONFIG_LUCI_LANG_bn_BD=y +CONFIG_LUCI_LANG_fi=y +CONFIG_LUCI_LANG_hi=y +CONFIG_LUCI_LANG_mr=y +CONFIG_LUCI_LANG_nb_NO=y CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=64 CONFIG_OPENSSL_WITH_CHACHA_POLY1305=y From 0496b08b896fe76160562d8c23418650448d92d3 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 3 Jul 2020 19:05:23 +0200 Subject: [PATCH 65/76] Update OpenWrt --- build.sh | 8 ++++---- root/target/linux/mediatek/image/Config.in | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.sh b/build.sh index bbed9188..56a616e2 100755 --- a/build.sh +++ b/build.sh @@ -22,7 +22,6 @@ _get_repo() ( OMR_DIST=${OMR_DIST:-openmptcprouter} OMR_HOST=${OMR_HOST:-$(curl -sS ifconfig.co)} OMR_PORT=${OMR_PORT:-8000} -OMR_REPO=${OMR_REPO:-http://$OMR_HOST:$OMR_PORT/release/$OMR_KERNEL} OMR_KEEPBIN=${OMR_KEEPBIN:-no} OMR_IMG=${OMR_IMG:-yes} #OMR_UEFI=${OMR_UEFI:-yes} @@ -33,6 +32,7 @@ OMR_TARGET_CONFIG="config-$OMR_TARGET" OMR_KERNEL=${OMR_KERNEL:-5.4} #OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1` | sed 's/^\([0-9.]*\).*/\1/')} OMR_RELEASE=${OMR_RELEASE:-$(git tag --sort=committerdate | tail -1)} +OMR_REPO=${OMR_REPO:-http://$OMR_HOST:$OMR_PORT/release/$OMR_RELEASE} OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" OMR_FEED_SRC="${OMR_FEED_SRC:-develop}" @@ -64,9 +64,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "635f111148c3f7ccb0ecc92863a3b1a142f6ebeb" - _get_repo feeds/packages https://github.com/openwrt/packages "c7dca50f110d5458ceff21a2274eddae2aae119b" - _get_repo feeds/luci https://github.com/openwrt/luci "558525783cf33a986efa33d23f5283b33a6c936e" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "b123ffdf6ebaa3108524bb50d306d6ae73ff7405" + _get_repo feeds/packages https://github.com/openwrt/packages "477a881f14e0b0772002dbd2ee2d2c89139fc149" + _get_repo feeds/luci https://github.com/openwrt/luci "051c828aeb754a70cf9a3c710985992c29b35b7b" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" diff --git a/root/target/linux/mediatek/image/Config.in b/root/target/linux/mediatek/image/Config.in index 0daa957a..22a49ea6 100644 --- a/root/target/linux/mediatek/image/Config.in +++ b/root/target/linux/mediatek/image/Config.in @@ -1,4 +1,4 @@ config MEDIATEK_SD_BOOT_PARTSIZE int "Boot (SD Card) filesystem partition size (in MB)" depends on TARGET_mediatek - default 128 \ No newline at end of file + default 128 From 46c823063e29a61d8772596be3c2a04bb9f57017 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 10 Jul 2020 22:20:05 +0200 Subject: [PATCH 66/76] Update MPTCP --- root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index af8944c8..c0b10832 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -8964,7 +8964,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c --- linux-5.4/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 +++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-06-09 17:33:41.000000000 +0200 -@@ -0,0 +1,3299 @@ +@@ -0,0 +1,3303 @@ +/* + * MPTCP implementation - MPTCP-control + * @@ -10269,6 +10269,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + if (!master_sk) + goto err_alloc_master; + ++ /* Same as in inet_csk_clone_lock - need to init to 0 */ ++ memset(&inet_csk(master_sk)->icsk_accept_queue, 0, ++ sizeof(inet_csk(master_sk)->icsk_accept_queue)); ++ + master_tp = tcp_sk(master_sk); + master_tp->inside_tk_table = 0; + From 9ae587ca64dd86dd9e349dcb79e297a9f434decf Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 10 Jul 2020 22:20:19 +0200 Subject: [PATCH 67/76] Update OpenWrt --- build.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/build.sh b/build.sh index 56a616e2..2fb7ecd8 100755 --- a/build.sh +++ b/build.sh @@ -56,6 +56,8 @@ elif [ "$OMR_TARGET" = "wrt32x" ]; then OMR_REAL_TARGET="arm_cortex-a9_vfpv3" elif [ "$OMR_TARGET" = "bpi-r2" ]; then OMR_REAL_TARGET="arm_cortex-a7_neon-vfpv4" +elif [ "$OMR_TARGET" = "bpi-r64" ]; then + OMR_REAL_TARGET="aarch64_cortex-a53" elif [ "$OMR_TARGET" = "x86" ]; then OMR_REAL_TARGET="i386_pentium4" else @@ -64,9 +66,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "b123ffdf6ebaa3108524bb50d306d6ae73ff7405" - _get_repo feeds/packages https://github.com/openwrt/packages "477a881f14e0b0772002dbd2ee2d2c89139fc149" - _get_repo feeds/luci https://github.com/openwrt/luci "051c828aeb754a70cf9a3c710985992c29b35b7b" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "f632747704f172e5c6d3a7c5715dc8d2f50d8da8" + _get_repo feeds/packages https://github.com/openwrt/packages "9bd81604b76a9b1abc0bb8146fb55c00c2445f1b" + _get_repo feeds/luci https://github.com/openwrt/luci "4ddcb360885030f33baa73f8569640db93250878" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -270,10 +272,7 @@ if [ "$OMR_KERNEL" = "5.4" ]; then echo "Done" fi -# Remove patch that can make BPI-R2 slow -rm -rf target/linux/mediatek/patches-4.14/0027-*.patch - -rm -rf feeds/packages/libs/libwebp +#rm -rf feeds/packages/libs/libwebp echo "Update feeds index" rm -rf feeds/luci/modules/luci-mod-network From a5813fe1e4066ced8460df80740b6623d55cd58d Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 11 Jul 2020 07:25:21 +0200 Subject: [PATCH 68/76] Remove BPI-R2 image generation, now available upstream --- root/package/boot/uboot-mediatek/Makefile | 58 ---- ...dditional-U-boot-options-for-mt7623n.patch | 64 ---- ...modify-environment-offset-for-mt7623.patch | 23 -- ...003-bootmenu-added-key-input-1-9-a-f.patch | 219 ------------- .../0004-Add-EXT4-support-in-U-boot.patch | 25 -- .../boot/uboot-mediatek/uEnv-default.txt | 91 ------ root/package/boot/uboot-mtk-bpi-r2/Makefile | 49 --- .../patches/002-use-static-inline.patch | 56 ---- .../patches/003-use-weak-in-board.patch | 38 --- .../patches/004-use-weak-in-main.patch | 14 - .../patches/200-fix-dtc-header-guard.patch | 19 -- .../patches/420-gcc-7-compiler.patch | 287 ------------------ .../patches/421-gcc-8-compiler.patch | 287 ------------------ root/package/kernel/mt7623-preloader/Makefile | 65 ---- root/target/linux/mediatek/image/Config.in | 4 - root/target/linux/mediatek/image/Makefile | 90 ------ .../mediatek/image/gen_mt7623_sdcard_img.sh | 48 --- root/target/linux/mediatek/image/mt7623.mk | 21 -- 18 files changed, 1458 deletions(-) delete mode 100644 root/package/boot/uboot-mediatek/Makefile delete mode 100644 root/package/boot/uboot-mediatek/patches/0001-defconfig-r2-Add-additional-U-boot-options-for-mt7623n.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0002-u-boot-modify-environment-offset-for-mt7623.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0003-bootmenu-added-key-input-1-9-a-f.patch delete mode 100644 root/package/boot/uboot-mediatek/patches/0004-Add-EXT4-support-in-U-boot.patch delete mode 100644 root/package/boot/uboot-mediatek/uEnv-default.txt delete mode 100644 root/package/boot/uboot-mtk-bpi-r2/Makefile delete mode 100644 root/package/boot/uboot-mtk-bpi-r2/patches/002-use-static-inline.patch delete mode 100644 root/package/boot/uboot-mtk-bpi-r2/patches/003-use-weak-in-board.patch delete mode 100644 root/package/boot/uboot-mtk-bpi-r2/patches/004-use-weak-in-main.patch delete mode 100644 root/package/boot/uboot-mtk-bpi-r2/patches/200-fix-dtc-header-guard.patch delete mode 100644 root/package/boot/uboot-mtk-bpi-r2/patches/420-gcc-7-compiler.patch delete mode 100644 root/package/boot/uboot-mtk-bpi-r2/patches/421-gcc-8-compiler.patch delete mode 100644 root/package/kernel/mt7623-preloader/Makefile delete mode 100644 root/target/linux/mediatek/image/Config.in delete mode 100644 root/target/linux/mediatek/image/Makefile delete mode 100755 root/target/linux/mediatek/image/gen_mt7623_sdcard_img.sh delete mode 100644 root/target/linux/mediatek/image/mt7623.mk diff --git a/root/package/boot/uboot-mediatek/Makefile b/root/package/boot/uboot-mediatek/Makefile deleted file mode 100644 index 150abe59..00000000 --- a/root/package/boot/uboot-mediatek/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# -# Copyright (C) 2013-2019 OpenWrt.org -# Copyright (C) 2019 Alexey Loukianov -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_VERSION:=2020.04 - -PKG_HASH:=fe732aaf037d9cc3c0909bad8362af366ae964bbdac6913a34081ff4ad565372 - -PKG_MAINTAINER:=Cristian Ciobanu - -include $(INCLUDE_DIR)/u-boot.mk -include $(INCLUDE_DIR)/package.mk - -define U-Boot/Default - BUILD_TARGET:=mediatek - UBOOT_IMAGE:=u-boot.bin - UENV:=default - HIDDEN:=1 -endef - -define U-Boot/mt7623n_bpir2 - BUILD_SUBTARGET:=mt7623 - NAME:=Bannana PI R2 (mt7623) - BUILD_DEVICES:=bpi_bananapi-r2 -endef - -UBOOT_TARGETS := \ - mt7623n_bpir2 - -UBOOT_CONFIGURE_VARS += USE_PRIVATE_LIBGCC=yes - -UBOOT_MAKE_FLAGS = \ - HOSTCC="$(HOSTCC)" \ - HOSTCFLAGS="$(HOST_CFLAGS) $(HOST_CPPFLAGS) -std=gnu11" \ - HOSTLDFLAGS="$(HOST_LDFLAGS)" - -define Build/Prepare - $(call Build/Prepare/Default) - $(CP) uEnv-$(UENV).txt ${PKG_BUILD_DIR}/uEnv.txt -endef - -define Build/InstallDev - $(INSTALL_DIR) $(STAGING_DIR_IMAGE) - $(CP) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-uboot-mediatek.bin - $(CP) $(PKG_BUILD_DIR)/uEnv.txt $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-uEnv.txt -endef - -define Package/u-boot/install/default -endef - -$(eval $(call BuildPackage/U-Boot)) diff --git a/root/package/boot/uboot-mediatek/patches/0001-defconfig-r2-Add-additional-U-boot-options-for-mt7623n.patch b/root/package/boot/uboot-mediatek/patches/0001-defconfig-r2-Add-additional-U-boot-options-for-mt7623n.patch deleted file mode 100644 index a6959594..00000000 --- a/root/package/boot/uboot-mediatek/patches/0001-defconfig-r2-Add-additional-U-boot-options-for-mt7623n.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 075db54b57761868cd63434b466fffe7ba7a564f Mon Sep 17 00:00:00 2001 -From: Cristian Ciobanu -Date: Thu, 9 Apr 2020 17:59:27 +0300 -Subject: [PATCH] defconfig: r2: Add additional U-boot options for mt7623n - ---- - configs/mt7623n_bpir2_defconfig | 30 ++++++++++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - -diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig -index 07ddade76a..36a903cbe7 100644 ---- a/configs/mt7623n_bpir2_defconfig -+++ b/configs/mt7623n_bpir2_defconfig -@@ -3,7 +3,7 @@ CONFIG_SYS_THUMB_BUILD=y - CONFIG_ARCH_MEDIATEK=y - CONFIG_SYS_TEXT_BASE=0x81e00000 - CONFIG_SYS_MALLOC_F_LEN=0x4000 --CONFIG_ENV_SIZE=0x1000 -+CONFIG_ENV_SIZE=0x2000 - CONFIG_ENV_OFFSET=0x100000 - CONFIG_TARGET_MT7623=y - CONFIG_NR_DRAM_BANKS=1 -@@ -14,7 +14,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y - CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2" - # CONFIG_DISPLAY_BOARDINFO is not set - CONFIG_HUSH_PARSER=y --CONFIG_SYS_PROMPT="U-Boot> " -+CONFIG_SYS_PROMPT="BPI-R2> " - CONFIG_CMD_BOOTMENU=y - # CONFIG_CMD_ELF is not set - # CONFIG_CMD_XIMG is not set -@@ -57,3 +57,29 @@ CONFIG_MTK_TIMER=y - CONFIG_WDT_MTK=y - CONFIG_LZMA=y - # CONFIG_EFI_LOADER is not set -+ -+CONFIG_LOCALVERSION_AUTO=n -+CONFIG_USE_DEFAULT_ENV_FILE=y -+CONFIG_DEFAULT_ENV_FILE="uEnv.txt" -+CONFIG_CMD_BOOTZ=y -+CONFIG_OF_LIBFDT_OVERLAY=y -+ -+#commands used in uenv.txt -+CONFIG_CMD_ASKENV=y -+CONFIG_CMD_STRINGS=y -+CONFIG_CMD_SETEXPR=y -+CONFIG_CMD_CACHE=y -+CONFIG_CMD_ERASEENV=y -+CONFIG_PCI=y -+CONFIG_DM_PCI=y -+CONFIG_PCIE_MEDIATEK=y -+CONFIG_PHY=y -+CONFIG_PHY_MTK_TPHY=y -+CONFIG_CMD_PCI=y -+CONFIG_AHCI=y -+CONFIG_AHCI_PCI=y -+CONFIG_SCSI=y -+CONFIG_DM_SCSI=y -+CONFIG_SCSI_AHCI=y -+CONFIG_HAVE_BLOCK_DEVICE=y -+CONFIG_POWER_MT6323=y --- -2.25.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0002-u-boot-modify-environment-offset-for-mt7623.patch b/root/package/boot/uboot-mediatek/patches/0002-u-boot-modify-environment-offset-for-mt7623.patch deleted file mode 100644 index 2f0e68a1..00000000 --- a/root/package/boot/uboot-mediatek/patches/0002-u-boot-modify-environment-offset-for-mt7623.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 15e032f5b06ba97a7777bc32aef15e10d0086041 Mon Sep 17 00:00:00 2001 -From: Cristian Ciobanu -Date: Wed, 8 Apr 2020 22:27:01 +0300 -Subject: [PATCH] u-boot: Modify environment offset for mt7623 - ---- - include/configs/mt7623.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h -index faab0913fc..5d0da71ce9 100644 ---- a/include/configs/mt7623.h -+++ b/include/configs/mt7623.h -@@ -56,5 +56,6 @@ - #define CONFIG_SERVERIP 192.168.1.2 - - #define CONFIG_SYS_MMC_ENV_DEV 0 -+#define CONFIG_ENV_OFFSET 0xF3800 - - #endif --- -2.25.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0003-bootmenu-added-key-input-1-9-a-f.patch b/root/package/boot/uboot-mediatek/patches/0003-bootmenu-added-key-input-1-9-a-f.patch deleted file mode 100644 index faa70ac6..00000000 --- a/root/package/boot/uboot-mediatek/patches/0003-bootmenu-added-key-input-1-9-a-f.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 798f0fc54926093a074a9cbb011de833a0614c3a Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 28 Dec 2018 17:56:19 +0100 -Subject: [PATCH 1/2] bootmenu: added key-input (1-9,a-f) - ---- - cmd/bootmenu.c | 145 ++++++++++++++++++++++++++++++++----------------- - 1 file changed, 94 insertions(+), 51 deletions(-) - -diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c -index 3dc2c854ac..fd6ba6c8af 100644 ---- a/cmd/bootmenu.c -+++ b/cmd/bootmenu.c -@@ -40,7 +40,22 @@ struct bootmenu_data { - - enum bootmenu_key { - KEY_NONE = 0, -- KEY_UP, -+ KEY_1, -+ KEY_2, -+ KEY_3, -+ KEY_4, -+ KEY_5, -+ KEY_6, -+ KEY_7, -+ KEY_8, -+ KEY_9, -+ KEY_a, -+ KEY_b, -+ KEY_c, -+ KEY_d, -+ KEY_e, -+ KEY_f, -+ KEY_UP = 20, - KEY_DOWN, - KEY_SELECT, - }; -@@ -78,6 +93,23 @@ static void bootmenu_print_entry(void *data) - puts(ANSI_COLOR_RESET); - } - -+bool get_bootmenu_key(enum bootmenu_key *key, int c) -+{ -+ /* ANSI '1~9' - was pressed */ -+ if (c <= '9' && c >= '1' ) -+ { -+ *key = c-48; -+ return true; -+ }else -+ /* ANSI 'a~f' - was pressed */ -+ if (c <= 'f' && c >= 'a' ) -+ { -+ *key = c-87; -+ return true; -+ } -+ return false; -+} -+ - static void bootmenu_autoboot_loop(struct bootmenu_data *menu, - enum bootmenu_key *key, int *esc) - { -@@ -98,23 +130,23 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu, - - menu->delay = -1; - c = getc(); -- -- switch (c) { -- case '\e': -- *esc = 1; -- *key = KEY_NONE; -- break; -- case '\r': -- *key = KEY_SELECT; -- break; -- default: -- *key = KEY_NONE; -- break; -+ if (!get_bootmenu_key(key,c)) -+ { -+ switch (c) { -+ case '\e': -+ *esc = 1; -+ *key = KEY_NONE; -+ break; -+ case '\r': -+ *key = KEY_SELECT; -+ break; -+ default: -+ *key = KEY_NONE; -+ break; -+ } - } -- - break; - } -- - if (menu->delay < 0) - break; - -@@ -141,47 +173,49 @@ static void bootmenu_loop(struct bootmenu_data *menu, - - c = getc(); - -- switch (*esc) { -- case 0: -- /* First char of ANSI escape sequence '\e' */ -- if (c == '\e') { -- *esc = 1; -- *key = KEY_NONE; -- } -- break; -- case 1: -- /* Second char of ANSI '[' */ -- if (c == '[') { -- *esc = 2; -- *key = KEY_NONE; -- } else { -- *esc = 0; -- } -- break; -- case 2: -- case 3: -- /* Third char of ANSI (number '1') - optional */ -- if (*esc == 2 && c == '1') { -- *esc = 3; -+ if (!get_bootmenu_key(key,c)) -+ { -+ switch (*esc) { -+ case 0: -+ /* First char of ANSI escape sequence '\e' */ -+ if (c == '\e') { -+ *esc = 1; -+ *key = KEY_NONE; -+ } -+ break; -+ case 1: -+ /* Second char of ANSI '[' */ -+ if (c == '[') { -+ *esc = 2; - *key = KEY_NONE; -+ } else { -+ *esc = 0; -+ } - break; -- } -+ case 2: -+ case 3: -+ /* Third char of ANSI (number '1') - optional */ -+ if (*esc == 2 && c == '1') { -+ *esc = 3; -+ *key = KEY_NONE; -+ break; -+ } - -- *esc = 0; -+ *esc = 0; - -- /* ANSI 'A' - key up was pressed */ -- if (c == 'A') -- *key = KEY_UP; -- /* ANSI 'B' - key down was pressed */ -- else if (c == 'B') -- *key = KEY_DOWN; -- /* other key was pressed */ -- else -- *key = KEY_NONE; -+ /* ANSI 'A' - key up was pressed */ -+ if (c == 'A') -+ *key = KEY_UP; -+ /* ANSI 'B' - key down was pressed */ -+ else if (c == 'B') -+ *key = KEY_DOWN; -+ /* other key was pressed */ -+ else -+ *key = KEY_NONE; - -- break; -+ break; -+ } - } -- - /* enter key was pressed */ - if (c == '\r') - *key = KEY_SELECT; -@@ -204,6 +238,14 @@ static char *bootmenu_choice_entry(void *data) - bootmenu_loop(menu, &key, &esc); - } - -+ if (key < KEY_UP && key > KEY_NONE) -+ { -+ menu->active = key-1; -+ return NULL; -+ } -+ else -+ { -+ - switch (key) { - case KEY_UP: - if (menu->active > 0) -@@ -223,6 +265,7 @@ static char *bootmenu_choice_entry(void *data) - default: - break; - } -+ } - } - - /* never happens */ -@@ -467,7 +510,7 @@ void menu_display_statusline(struct menu *m) - printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); - puts(ANSI_CLEAR_LINE); - printf(ANSI_CURSOR_POSITION, menu->count + 6, 1); -- puts(" Press UP/DOWN to move, ENTER to select"); -+ puts(" Press UP/DOWN to move or Press 1~9,a~f to choose, ENTER to select"); - puts(ANSI_CLEAR_LINE_TO_END); - printf(ANSI_CURSOR_POSITION, menu->count + 7, 1); - puts(ANSI_CLEAR_LINE); --- -2.25.1 - diff --git a/root/package/boot/uboot-mediatek/patches/0004-Add-EXT4-support-in-U-boot.patch b/root/package/boot/uboot-mediatek/patches/0004-Add-EXT4-support-in-U-boot.patch deleted file mode 100644 index 3f1a024b..00000000 --- a/root/package/boot/uboot-mediatek/patches/0004-Add-EXT4-support-in-U-boot.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 39b0c824b56be1000844cedb5faba506b6b09b9b Mon Sep 17 00:00:00 2001 -From: Cristian Ciobanu -Date: Fri, 10 Apr 2020 00:41:42 +0300 -Subject: [PATCH] Add EXT4 support in U-boot - ---- - configs/mt7623n_bpir2_defconfig | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig -index 36a903cbe7..09b9b6f797 100644 ---- a/configs/mt7623n_bpir2_defconfig -+++ b/configs/mt7623n_bpir2_defconfig -@@ -83,3 +83,8 @@ CONFIG_DM_SCSI=y - CONFIG_SCSI_AHCI=y - CONFIG_HAVE_BLOCK_DEVICE=y - CONFIG_POWER_MT6323=y -+ -+CONFIG_CMD_EXT4=y -+CONFIG_CMD_EXT4_WRITE=y -+CONFIG_FS_EXT4=y -+CONFIG_EXT4_WRITE=y --- -2.25.1 - diff --git a/root/package/boot/uboot-mediatek/uEnv-default.txt b/root/package/boot/uboot-mediatek/uEnv-default.txt deleted file mode 100644 index 10373c46..00000000 --- a/root/package/boot/uboot-mediatek/uEnv-default.txt +++ /dev/null @@ -1,91 +0,0 @@ -scriptaddr=0x83000000 -device=mmc -bootenv=uEnv.txt -kernel=uImage -loadaddr=0x80200000 -#default bootargs will be overidden by buildargs -bootargs=console=ttyS2,115200 root=/dev/mmcblk1p2 rw rootwait ip=dhcp - -console=earlyprintk console=ttyS2,115200 console=tty1 fbcon=map:0 -roottmpl=${rootdev} rootfstype=ext4 rootwait -prepsetroot=setenv setroot setenv root ${roottmpl} -bootopts=vmalloc=496M debug=7 initcall_debug=0 -graphic=video=1920x1080 drm.debug=0x7 - -buildargs=setenv bootargs "console=${console} root=${root} ${bootopts} ${graphic}" - -checkenv=test -e ${device} ${partition} ${bootenv} -importenv=env import -t ${scriptaddr} ${filesize} -loadbootenv=if fatload ${device} ${partition} ${scriptaddr} ${bootenv};then run importenv;else echo "fatload (${bootenv}) failed";fi -resetenv=env default -a;printenv; - -# Here we assume that SD card id mmcblk1 and eMMC is mmcblk0 in linux. Swap them if your DTS define them in reverse order. -usesd=setenv partition 1:1; setenv rootdev /dev/mmcblk1p2; setenv bootdev SD; setenv swaproot 'run useemmc'; -useemmc=setenv partition 0:1; setenv rootdev /dev/mmcblk0p2; setenv bootdev eMMC; setenv swaproot 'run usesd'; - -checkbootedfrom=if itest.l *81dffff0 == 434d4d65 ; then setenv bootedfrom eMMC; else setenv bootedfrom SD; fi; - -checkroot=fatinfo ${device} ${partition} -checksd=fatinfo ${device} 1:1 -checkmmc=fatinfo ${device} 0:1 - -reportbootedfrom=echo "Preloader/U-Boot loaded from ${bootedfrom}."; run validroot || echo "Both SD and eMMC pt#1 are not FAT, falling back to U-Boot shell." -reportvalidroot=run validroot || echo "Both SD and eMMC pt#1 are not FAT, falling back to U-Boot shell." -reportrootswapwarn=if test "${bootedfrom}" != "${bootdev}" ; then echo "Warning: Partition 1 on ${bootedfrom} is not FAT, failing back to ${bootdev}"; fi; true; -reportbootdev=echo "Booting from ${bootdev}." -reportboot=run reportbootedfrom reportvalidroot reportrootswapwarn reportbootdev - -detectroot=run useemmc; run checkbootedfrom; if test "${bootedfrom}" == "SD"; then run usesd; fi; run validateroot; -validateroot=setenv validroot false; run checkroot || run swaproot; run checkroot && setenv validroot true || run swaproot; - -newboot=run prepsetroot; run setroot;run buildargs;printenv bootargs;fatload ${device} ${partition} ${loadaddr} ${kernel}; bootm - -reloadenv=run detectroot; if run validroot; then if run checkenv; then run loadbootenv; run detectroot; else echo uEnv.txt file not found on ${bootdev}; fi; fi; -reloadmenu=run reloadenv; run reportboot; if run validroot; then if run checkenv; then run loadbootenv; else echo uEnv.txt file not found on ${bootdev}; fi; bootmenu; fi; - -lskernel=ls ${device} ${partition}; -lsdtb=ls ${device} ${partition} dtb -askkernel=askenv kernelinput "enter uImage-name:"; -askdtb=askenv dtbinput "enter dtb-name:"; - -#bootmenu -boot0=run lskernel;run askkernel;if printenv kernelinput ;then setenv kernel ${kernelinput};run lsdtb;run askdtb;if printenv dtbinput ;then setenv fdt ${dtbinput};fi; run newboot2; fi; -boot1=run newboot; - -bootmenu_default=2 -bootmenu_0=1. Enter kernel-name to boot from SD/EMMC.=run boot0 -bootmenu_1=2. Boot kernel from TFTP.=run bootnet -bootmenu_2=3. Boot from SD/EMMC.=run boot1 -bootmenu_3=4. Boot from eMMC.=run useemmc; run boot1 -bootmenu_4=5. Boot from SD.=run usesd; run boot1 - -#Netboot -ipaddr=192.168.0.11 -netmask=255.255.255.0 -serverip=192.168.0.10 - -bootfile=uImage -netbootargs=console=ttyS2,115200 root=/dev/mmcblk1p2 rw rootwait -#ip=dhcp sets ip on eth0 instead of wan - -lstftp=tftp ${loadaddr} ${serverip}:files.lst;setexpr listend ${loadaddr} + ${filesize};mw.b ${listend} 00 2;strings ${loadaddr}; -#md.b ${loadaddr} 60; - -bootnet=run lstftp;run askkernel;if printenv kernelinput ;then setenv bootfile "${kernelinput}"; fi;printenv; setenv bootargs ${netbootargs};tftp ${loadaddr} ${bootfile};bootm - -#separate fdt+dto -dtaddr=0x83f00000 -fdt_high=0xffffffff - -loadfdt=fatload ${device} ${partition} ${dtaddr} dtb/${fdt} -loadkernel=echo "loading kernel ${kernel}...";fatload ${device} ${partition} ${loadaddr} ${kernel} - -loaddto=echo "loaddto:${dto}";fdt addr ${dtaddr};fdt resize 8192; setexpr fdtovaddr ${dtaddr} + F000;fatload ${device} ${partition} ${fdtovaddr} dtb/${dto} && fdt apply ${fdtovaddr} -loaddtolist=for dto in ${dtolist} ; do run loaddto ; done - -bootall=if printenv fdt; then run loadfdt; if printenv dtolist;then run loaddtolist;fi; bootm ${loadaddr} - ${dtaddr} ;else bootm; fi -newboot2=run prepsetroot; run setroot;run buildargs; printenv bootargs; run loadkernel; run bootall; - -#automatic reload from sd/emmc -bootdelay=0 -bootcmd=setenv bootdelay 3; run reloadmenu; diff --git a/root/package/boot/uboot-mtk-bpi-r2/Makefile b/root/package/boot/uboot-mtk-bpi-r2/Makefile deleted file mode 100644 index 622f6ca5..00000000 --- a/root/package/boot/uboot-mtk-bpi-r2/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# -# Copyright (C) 2016 Gary Wang -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=uboot-mtk-bpi-r2 -PKG_VERSION:=v1.0 -PKG_RELEASE:=1 -HOSTCPPFLAGS:="-I." -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/BPI-SINOVOIP/BPI-R2-LEDE-Uboot.git -PKG_SOURCE_VERSION:=b05a4e323e1fd8727fcfe32c35d562f12b88a23b - -PKG_LICENSE:=GPL-2.0 GPL-2.0+ -PKG_LICENSE_FILES:=Licenses/README - -PKG_MAINTAINER:=Gary Wang - -include $(INCLUDE_DIR)/u-boot.mk -include $(INCLUDE_DIR)/package.mk - -define U-Boot/bpi_r2 - BUILD_TARGET:=mediatek - NAME:=Mediatek Banana Pi R2 board - BUILD_DEVICES:=7623n-bananapi-bpi-r2 -endef - -UBOOT_TARGETS := \ - bpi_r2 - - -UBOOT_CONFIGURE_VARS += USE_PRIVATE_LIBGCC=yes - -define Build/InstallDev - $(INSTALL_DIR) $(STAGING_DIR_IMAGE) - $(CP) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/mtk-bpi-r2-uboot.bin - $(CP) $(PKG_BUILD_DIR)/bpi_r2_preloader/EMMC_PRELOADER_1600MHz.img $(STAGING_DIR_IMAGE)/mtk-bpi-r2-preloader-emmc.bin - $(CP) $(PKG_BUILD_DIR)/bpi_r2_preloader/SD_PRELOADER_1600MHz.img $(STAGING_DIR_IMAGE)/mtk-bpi-r2-preloader-sd.bin -endef - -define Package/u-boot/install/default -endef - -$(eval $(call BuildPackage/U-Boot)) diff --git a/root/package/boot/uboot-mtk-bpi-r2/patches/002-use-static-inline.patch b/root/package/boot/uboot-mtk-bpi-r2/patches/002-use-static-inline.patch deleted file mode 100644 index 2fc7bfbb..00000000 --- a/root/package/boot/uboot-mtk-bpi-r2/patches/002-use-static-inline.patch +++ /dev/null @@ -1,56 +0,0 @@ -Index: uboot-mtk-bpi-r2-v1.0/arch/arm/include/asm/io.h -=================================================================== ---- uboot-mtk-bpi-r2-v1.0.orig/arch/arm/include/asm/io.h -+++ uboot-mtk-bpi-r2-v1.0/arch/arm/include/asm/io.h -@@ -75,7 +75,7 @@ static inline phys_addr_t virt_to_phys(v - #define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) - #define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) - --extern inline void __raw_writesb(unsigned long addr, const void *data, -+static inline void __raw_writesb(unsigned long addr, const void *data, - int bytelen) - { - uint8_t *buf = (uint8_t *)data; -@@ -83,7 +83,7 @@ extern inline void __raw_writesb(unsigne - __arch_putb(*buf++, addr); - } - --extern inline void __raw_writesw(unsigned long addr, const void *data, -+static inline void __raw_writesw(unsigned long addr, const void *data, - int wordlen) - { - uint16_t *buf = (uint16_t *)data; -@@ -91,7 +91,7 @@ extern inline void __raw_writesw(unsigne - __arch_putw(*buf++, addr); - } - --extern inline void __raw_writesl(unsigned long addr, const void *data, -+static inline void __raw_writesl(unsigned long addr, const void *data, - int longlen) - { - uint32_t *buf = (uint32_t *)data; -@@ -99,21 +99,21 @@ extern inline void __raw_writesl(unsigne - __arch_putl(*buf++, addr); - } - --extern inline void __raw_readsb(unsigned long addr, void *data, int bytelen) -+static inline void __raw_readsb(unsigned long addr, void *data, int bytelen) - { - uint8_t *buf = (uint8_t *)data; - while(bytelen--) - *buf++ = __arch_getb(addr); - } - --extern inline void __raw_readsw(unsigned long addr, void *data, int wordlen) -+static inline void __raw_readsw(unsigned long addr, void *data, int wordlen) - { - uint16_t *buf = (uint16_t *)data; - while(wordlen--) - *buf++ = __arch_getw(addr); - } - --extern inline void __raw_readsl(unsigned long addr, void *data, int longlen) -+static inline void __raw_readsl(unsigned long addr, void *data, int longlen) - { - uint32_t *buf = (uint32_t *)data; - while(longlen--) diff --git a/root/package/boot/uboot-mtk-bpi-r2/patches/003-use-weak-in-board.patch b/root/package/boot/uboot-mtk-bpi-r2/patches/003-use-weak-in-board.patch deleted file mode 100644 index 2968a54f..00000000 --- a/root/package/boot/uboot-mtk-bpi-r2/patches/003-use-weak-in-board.patch +++ /dev/null @@ -1,38 +0,0 @@ -Index: uboot-mtk-bpi-r2-v1.0/arch/arm/lib/board.c -=================================================================== ---- uboot-mtk-bpi-r2-v1.0.orig/arch/arm/lib/board.c -+++ uboot-mtk-bpi-r2-v1.0/arch/arm/lib/board.c -@@ -69,24 +69,15 @@ extern void dataflash_print_info(void); - ************************************************************************ - * May be supplied by boards if desired - */ --inline void __coloured_LED_init(void) {} --void coloured_LED_init(void) __attribute__((weak, alias("__coloured_LED_init"))); --inline void __red_led_on(void) {} --void red_led_on(void) __attribute__((weak, alias("__red_led_on"))); --inline void __red_led_off(void) {} --void red_led_off(void) __attribute__((weak, alias("__red_led_off"))); --inline void __green_led_on(void) {} --void green_led_on(void) __attribute__((weak, alias("__green_led_on"))); --inline void __green_led_off(void) {} --void green_led_off(void) __attribute__((weak, alias("__green_led_off"))); --inline void __yellow_led_on(void) {} --void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on"))); --inline void __yellow_led_off(void) {} --void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off"))); --inline void __blue_led_on(void) {} --void blue_led_on(void) __attribute__((weak, alias("__blue_led_on"))); --inline void __blue_led_off(void) {} --void blue_led_off(void) __attribute__((weak, alias("__blue_led_off"))); -+__weak void coloured_LED_init(void) {} -+__weak void red_led_on(void) {} -+__weak void red_led_off(void) {} -+__weak void green_led_on(void) {} -+__weak void green_led_off(void) {} -+__weak void yellow_led_on(void) {} -+__weak void yellow_led_off(void) {} -+__weak void blue_led_on(void) {} -+__weak void blue_led_off(void) {} - - /* - ************************************************************************ diff --git a/root/package/boot/uboot-mtk-bpi-r2/patches/004-use-weak-in-main.patch b/root/package/boot/uboot-mtk-bpi-r2/patches/004-use-weak-in-main.patch deleted file mode 100644 index be731ae4..00000000 --- a/root/package/boot/uboot-mtk-bpi-r2/patches/004-use-weak-in-main.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: uboot-mtk-bpi-r2-v1.0/common/main.c -=================================================================== ---- uboot-mtk-bpi-r2-v1.0.orig/common/main.c -+++ uboot-mtk-bpi-r2-v1.0/common/main.c -@@ -27,8 +27,7 @@ DECLARE_GLOBAL_DATA_PTR; - /* - * Board-specific Platform code can reimplement show_boot_progress () if needed - */ --void inline __show_boot_progress (int val) {} --void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress"))); -+__weak void show_boot_progress(int val) {} - - #define MAX_DELAY_STOP_STR 32 - diff --git a/root/package/boot/uboot-mtk-bpi-r2/patches/200-fix-dtc-header-guard.patch b/root/package/boot/uboot-mtk-bpi-r2/patches/200-fix-dtc-header-guard.patch deleted file mode 100644 index 88d914b1..00000000 --- a/root/package/boot/uboot-mtk-bpi-r2/patches/200-fix-dtc-header-guard.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/include/libfdt_env.h -+++ b/include/libfdt_env.h -@@ -8,6 +8,7 @@ - - #ifndef _LIBFDT_ENV_H - #define _LIBFDT_ENV_H -+#define LIBFDT_ENV_H - - #include "compiler.h" - #include "linux/types.h" ---- a/include/libfdt.h -+++ b/include/libfdt.h -@@ -1,5 +1,6 @@ - #ifndef _LIBFDT_H - #define _LIBFDT_H -+#define LIBFDT_H - /* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. diff --git a/root/package/boot/uboot-mtk-bpi-r2/patches/420-gcc-7-compiler.patch b/root/package/boot/uboot-mtk-bpi-r2/patches/420-gcc-7-compiler.patch deleted file mode 100644 index 09516296..00000000 --- a/root/package/boot/uboot-mtk-bpi-r2/patches/420-gcc-7-compiler.patch +++ /dev/null @@ -1,287 +0,0 @@ ---- /dev/null -+++ b/include/linux/compiler-gcc7.h -@@ -0,0 +1,284 @@ -+#ifndef __LINUX_COMPILER_H -+#error "Please don't include directly, include instead." -+#endif -+ -+/* -+ * Common definitions for all gcc versions go here. -+ */ -+#define GCC_VERSION (__GNUC__ * 10000 \ -+ + __GNUC_MINOR__ * 100 \ -+ + __GNUC_PATCHLEVEL__) -+ -+/* Optimization barrier */ -+ -+/* The "volatile" is due to gcc bugs */ -+#define barrier() __asm__ __volatile__("": : :"memory") -+/* -+ * This version is i.e. to prevent dead stores elimination on @ptr -+ * where gcc and llvm may behave differently when otherwise using -+ * normal barrier(): while gcc behavior gets along with a normal -+ * barrier(), llvm needs an explicit input variable to be assumed -+ * clobbered. The issue is as follows: while the inline asm might -+ * access any memory it wants, the compiler could have fit all of -+ * @ptr into memory registers instead, and since @ptr never escaped -+ * from that, it proofed that the inline asm wasn't touching any of -+ * it. This version works well with both compilers, i.e. we're telling -+ * the compiler that the inline asm absolutely may see the contents -+ * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495 -+ */ -+#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory") -+ -+/* -+ * This macro obfuscates arithmetic on a variable address so that gcc -+ * shouldn't recognize the original var, and make assumptions about it. -+ * -+ * This is needed because the C standard makes it undefined to do -+ * pointer arithmetic on "objects" outside their boundaries and the -+ * gcc optimizers assume this is the case. In particular they -+ * assume such arithmetic does not wrap. -+ * -+ * A miscompilation has been observed because of this on PPC. -+ * To work around it we hide the relationship of the pointer and the object -+ * using this macro. -+ * -+ * Versions of the ppc64 compiler before 4.1 had a bug where use of -+ * RELOC_HIDE could trash r30. The bug can be worked around by changing -+ * the inline assembly constraint from =g to =r, in this particular -+ * case either is valid. -+ */ -+#define RELOC_HIDE(ptr, off) \ -+({ \ -+ unsigned long __ptr; \ -+ __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \ -+ (typeof(ptr)) (__ptr + (off)); \ -+}) -+ -+/* Make the optimizer believe the variable can be manipulated arbitrarily. */ -+#define OPTIMIZER_HIDE_VAR(var) \ -+ __asm__ ("" : "=r" (var) : "0" (var)) -+ -+#ifdef __CHECKER__ -+#define __must_be_array(a) 0 -+#else -+/* &a[0] degrades to a pointer: a different type from an array */ -+#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) -+#endif -+ -+/* -+ * Force always-inline if the user requests it so via the .config, -+ * or if gcc is too old: -+ */ -+#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ -+ !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) -+#define inline inline __attribute__((always_inline)) notrace -+#define __inline__ __inline__ __attribute__((always_inline)) notrace -+#define __inline __inline __attribute__((always_inline)) notrace -+#else -+/* A lot of inline functions can cause havoc with function tracing */ -+#define inline inline notrace -+#define __inline__ __inline__ notrace -+#define __inline __inline notrace -+#endif -+ -+#define __always_inline inline __attribute__((always_inline)) -+#define noinline __attribute__((noinline)) -+ -+#define __deprecated __attribute__((deprecated)) -+#define __packed __attribute__((packed)) -+#define __weak __attribute__((weak)) -+#define __alias(symbol) __attribute__((alias(#symbol))) -+ -+/* -+ * it doesn't make sense on ARM (currently the only user of __naked) -+ * to trace naked functions because then mcount is called without -+ * stack and frame pointer being set up and there is no chance to -+ * restore the lr register to the value before mcount was called. -+ * -+ * The asm() bodies of naked functions often depend on standard calling -+ * conventions, therefore they must be noinline and noclone. -+ * -+ * GCC 4.[56] currently fail to enforce this, so we must do so ourselves. -+ * See GCC PR44290. -+ */ -+#define __naked __attribute__((naked)) noinline __noclone notrace -+ -+#define __noreturn __attribute__((noreturn)) -+ -+/* -+ * From the GCC manual: -+ * -+ * Many functions have no effects except the return value and their -+ * return value depends only on the parameters and/or global -+ * variables. Such a function can be subject to common subexpression -+ * elimination and loop optimization just as an arithmetic operator -+ * would be. -+ * [...] -+ */ -+#define __pure __attribute__((pure)) -+#define __aligned(x) __attribute__((aligned(x))) -+#define __printf(a, b) __attribute__((format(printf, a, b))) -+#define __scanf(a, b) __attribute__((format(scanf, a, b))) -+#define __attribute_const__ __attribute__((__const__)) -+#define __maybe_unused __attribute__((unused)) -+#define __always_unused __attribute__((unused)) -+ -+/* gcc version specific checks */ -+ -+#if GCC_VERSION < 30200 -+# error Sorry, your compiler is too old - please upgrade it. -+#endif -+ -+#if GCC_VERSION < 30300 -+# define __used __attribute__((__unused__)) -+#else -+# define __used __attribute__((__used__)) -+#endif -+ -+#ifdef CONFIG_GCOV_KERNEL -+# if GCC_VERSION < 30400 -+# error "GCOV profiling support for gcc versions below 3.4 not included" -+# endif /* __GNUC_MINOR__ */ -+#endif /* CONFIG_GCOV_KERNEL */ -+ -+#if GCC_VERSION >= 30400 -+#define __must_check __attribute__((warn_unused_result)) -+#define __malloc __attribute__((__malloc__)) -+#endif -+ -+#if GCC_VERSION >= 40000 -+ -+/* GCC 4.1.[01] miscompiles __weak */ -+#ifdef __KERNEL__ -+# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101 -+# error Your version of gcc miscompiles the __weak directive -+# endif -+#endif -+ -+#define __used __attribute__((__used__)) -+#define __compiler_offsetof(a, b) \ -+ __builtin_offsetof(a, b) -+ -+#if GCC_VERSION >= 40100 && GCC_VERSION < 40600 -+# define __compiletime_object_size(obj) __builtin_object_size(obj, 0) -+#endif -+ -+#if GCC_VERSION >= 40300 -+/* Mark functions as cold. gcc will assume any path leading to a call -+ * to them will be unlikely. This means a lot of manual unlikely()s -+ * are unnecessary now for any paths leading to the usual suspects -+ * like BUG(), printk(), panic() etc. [but let's keep them for now for -+ * older compilers] -+ * -+ * Early snapshots of gcc 4.3 don't support this and we can't detect this -+ * in the preprocessor, but we can live with this because they're unreleased. -+ * Maketime probing would be overkill here. -+ * -+ * gcc also has a __attribute__((__hot__)) to move hot functions into -+ * a special section, but I don't see any sense in this right now in -+ * the kernel context -+ */ -+#define __cold __attribute__((__cold__)) -+ -+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) -+ -+#ifndef __CHECKER__ -+# define __compiletime_warning(message) __attribute__((warning(message))) -+# define __compiletime_error(message) __attribute__((error(message))) -+#endif /* __CHECKER__ */ -+#endif /* GCC_VERSION >= 40300 */ -+ -+#if GCC_VERSION >= 40500 -+/* -+ * Mark a position in code as unreachable. This can be used to -+ * suppress control flow warnings after asm blocks that transfer -+ * control elsewhere. -+ * -+ * Early snapshots of gcc 4.5 don't support this and we can't detect -+ * this in the preprocessor, but we can live with this because they're -+ * unreleased. Really, we need to have autoconf for the kernel. -+ */ -+#define unreachable() __builtin_unreachable() -+ -+/* Mark a function definition as prohibited from being cloned. */ -+#define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) -+ -+#endif /* GCC_VERSION >= 40500 */ -+ -+#if GCC_VERSION >= 40600 -+/* -+ * When used with Link Time Optimization, gcc can optimize away C functions or -+ * variables which are referenced only from assembly code. __visible tells the -+ * optimizer that something else uses this function or variable, thus preventing -+ * this. -+ */ -+#define __visible __attribute__((externally_visible)) -+#endif -+ -+ -+#if GCC_VERSION >= 40900 && !defined(__CHECKER__) -+/* -+ * __assume_aligned(n, k): Tell the optimizer that the returned -+ * pointer can be assumed to be k modulo n. The second argument is -+ * optional (default 0), so we use a variadic macro to make the -+ * shorthand. -+ * -+ * Beware: Do not apply this to functions which may return -+ * ERR_PTRs. Also, it is probably unwise to apply it to functions -+ * returning extra information in the low bits (but in that case the -+ * compiler should see some alignment anyway, when the return value is -+ * massaged by 'flags = ptr & 3; ptr &= ~3;'). -+ */ -+#define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) -+#endif -+ -+/* -+ * GCC 'asm goto' miscompiles certain code sequences: -+ * -+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 -+ * -+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. -+ * -+ * (asm goto is automatically volatile - the naming reflects this.) -+ */ -+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) -+ -+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP -+#if GCC_VERSION >= 40400 -+#define __HAVE_BUILTIN_BSWAP32__ -+#define __HAVE_BUILTIN_BSWAP64__ -+#endif -+#if GCC_VERSION >= 40800 -+#define __HAVE_BUILTIN_BSWAP16__ -+#endif -+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ -+ -+#if GCC_VERSION >= 50000 -+#define KASAN_ABI_VERSION 4 -+#elif GCC_VERSION >= 40902 -+#define KASAN_ABI_VERSION 3 -+#endif -+ -+#if GCC_VERSION >= 40902 -+/* -+ * Tell the compiler that address safety instrumentation (KASAN) -+ * should not be applied to that function. -+ * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 -+ */ -+#define __no_sanitize_address __attribute__((no_sanitize_address)) -+#endif -+ -+#endif /* gcc version >= 40000 specific checks */ -+ -+#if !defined(__noclone) -+#define __noclone /* not needed */ -+#endif -+ -+#if !defined(__no_sanitize_address) -+#define __no_sanitize_address -+#endif -+ -+/* -+ * A trick to suppress uninitialized variable warning without generating any -+ * code -+ */ -+#define uninitialized_var(x) x = x diff --git a/root/package/boot/uboot-mtk-bpi-r2/patches/421-gcc-8-compiler.patch b/root/package/boot/uboot-mtk-bpi-r2/patches/421-gcc-8-compiler.patch deleted file mode 100644 index ab3a0171..00000000 --- a/root/package/boot/uboot-mtk-bpi-r2/patches/421-gcc-8-compiler.patch +++ /dev/null @@ -1,287 +0,0 @@ ---- /dev/null -+++ b/include/linux/compiler-gcc8.h -@@ -0,0 +1,284 @@ -+#ifndef __LINUX_COMPILER_H -+#error "Please don't include directly, include instead." -+#endif -+ -+/* -+ * Common definitions for all gcc versions go here. -+ */ -+#define GCC_VERSION (__GNUC__ * 10000 \ -+ + __GNUC_MINOR__ * 100 \ -+ + __GNUC_PATCHLEVEL__) -+ -+/* Optimization barrier */ -+ -+/* The "volatile" is due to gcc bugs */ -+#define barrier() __asm__ __volatile__("": : :"memory") -+/* -+ * This version is i.e. to prevent dead stores elimination on @ptr -+ * where gcc and llvm may behave differently when otherwise using -+ * normal barrier(): while gcc behavior gets along with a normal -+ * barrier(), llvm needs an explicit input variable to be assumed -+ * clobbered. The issue is as follows: while the inline asm might -+ * access any memory it wants, the compiler could have fit all of -+ * @ptr into memory registers instead, and since @ptr never escaped -+ * from that, it proofed that the inline asm wasn't touching any of -+ * it. This version works well with both compilers, i.e. we're telling -+ * the compiler that the inline asm absolutely may see the contents -+ * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495 -+ */ -+#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory") -+ -+/* -+ * This macro obfuscates arithmetic on a variable address so that gcc -+ * shouldn't recognize the original var, and make assumptions about it. -+ * -+ * This is needed because the C standard makes it undefined to do -+ * pointer arithmetic on "objects" outside their boundaries and the -+ * gcc optimizers assume this is the case. In particular they -+ * assume such arithmetic does not wrap. -+ * -+ * A miscompilation has been observed because of this on PPC. -+ * To work around it we hide the relationship of the pointer and the object -+ * using this macro. -+ * -+ * Versions of the ppc64 compiler before 4.1 had a bug where use of -+ * RELOC_HIDE could trash r30. The bug can be worked around by changing -+ * the inline assembly constraint from =g to =r, in this particular -+ * case either is valid. -+ */ -+#define RELOC_HIDE(ptr, off) \ -+({ \ -+ unsigned long __ptr; \ -+ __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \ -+ (typeof(ptr)) (__ptr + (off)); \ -+}) -+ -+/* Make the optimizer believe the variable can be manipulated arbitrarily. */ -+#define OPTIMIZER_HIDE_VAR(var) \ -+ __asm__ ("" : "=r" (var) : "0" (var)) -+ -+#ifdef __CHECKER__ -+#define __must_be_array(a) 0 -+#else -+/* &a[0] degrades to a pointer: a different type from an array */ -+#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) -+#endif -+ -+/* -+ * Force always-inline if the user requests it so via the .config, -+ * or if gcc is too old: -+ */ -+#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ -+ !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) -+#define inline inline __attribute__((always_inline)) notrace -+#define __inline__ __inline__ __attribute__((always_inline)) notrace -+#define __inline __inline __attribute__((always_inline)) notrace -+#else -+/* A lot of inline functions can cause havoc with function tracing */ -+#define inline inline notrace -+#define __inline__ __inline__ notrace -+#define __inline __inline notrace -+#endif -+ -+#define __always_inline inline __attribute__((always_inline)) -+#define noinline __attribute__((noinline)) -+ -+#define __deprecated __attribute__((deprecated)) -+#define __packed __attribute__((packed)) -+#define __weak __attribute__((weak)) -+#define __alias(symbol) __attribute__((alias(#symbol))) -+ -+/* -+ * it doesn't make sense on ARM (currently the only user of __naked) -+ * to trace naked functions because then mcount is called without -+ * stack and frame pointer being set up and there is no chance to -+ * restore the lr register to the value before mcount was called. -+ * -+ * The asm() bodies of naked functions often depend on standard calling -+ * conventions, therefore they must be noinline and noclone. -+ * -+ * GCC 4.[56] currently fail to enforce this, so we must do so ourselves. -+ * See GCC PR44290. -+ */ -+#define __naked __attribute__((naked)) noinline __noclone notrace -+ -+#define __noreturn __attribute__((noreturn)) -+ -+/* -+ * From the GCC manual: -+ * -+ * Many functions have no effects except the return value and their -+ * return value depends only on the parameters and/or global -+ * variables. Such a function can be subject to common subexpression -+ * elimination and loop optimization just as an arithmetic operator -+ * would be. -+ * [...] -+ */ -+#define __pure __attribute__((pure)) -+#define __aligned(x) __attribute__((aligned(x))) -+#define __printf(a, b) __attribute__((format(printf, a, b))) -+#define __scanf(a, b) __attribute__((format(scanf, a, b))) -+#define __attribute_const__ __attribute__((__const__)) -+#define __maybe_unused __attribute__((unused)) -+#define __always_unused __attribute__((unused)) -+ -+/* gcc version specific checks */ -+ -+#if GCC_VERSION < 30200 -+# error Sorry, your compiler is too old - please upgrade it. -+#endif -+ -+#if GCC_VERSION < 30300 -+# define __used __attribute__((__unused__)) -+#else -+# define __used __attribute__((__used__)) -+#endif -+ -+#ifdef CONFIG_GCOV_KERNEL -+# if GCC_VERSION < 30400 -+# error "GCOV profiling support for gcc versions below 3.4 not included" -+# endif /* __GNUC_MINOR__ */ -+#endif /* CONFIG_GCOV_KERNEL */ -+ -+#if GCC_VERSION >= 30400 -+#define __must_check __attribute__((warn_unused_result)) -+#define __malloc __attribute__((__malloc__)) -+#endif -+ -+#if GCC_VERSION >= 40000 -+ -+/* GCC 4.1.[01] miscompiles __weak */ -+#ifdef __KERNEL__ -+# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101 -+# error Your version of gcc miscompiles the __weak directive -+# endif -+#endif -+ -+#define __used __attribute__((__used__)) -+#define __compiler_offsetof(a, b) \ -+ __builtin_offsetof(a, b) -+ -+#if GCC_VERSION >= 40100 && GCC_VERSION < 40600 -+# define __compiletime_object_size(obj) __builtin_object_size(obj, 0) -+#endif -+ -+#if GCC_VERSION >= 40300 -+/* Mark functions as cold. gcc will assume any path leading to a call -+ * to them will be unlikely. This means a lot of manual unlikely()s -+ * are unnecessary now for any paths leading to the usual suspects -+ * like BUG(), printk(), panic() etc. [but let's keep them for now for -+ * older compilers] -+ * -+ * Early snapshots of gcc 4.3 don't support this and we can't detect this -+ * in the preprocessor, but we can live with this because they're unreleased. -+ * Maketime probing would be overkill here. -+ * -+ * gcc also has a __attribute__((__hot__)) to move hot functions into -+ * a special section, but I don't see any sense in this right now in -+ * the kernel context -+ */ -+#define __cold __attribute__((__cold__)) -+ -+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) -+ -+#ifndef __CHECKER__ -+# define __compiletime_warning(message) __attribute__((warning(message))) -+# define __compiletime_error(message) __attribute__((error(message))) -+#endif /* __CHECKER__ */ -+#endif /* GCC_VERSION >= 40300 */ -+ -+#if GCC_VERSION >= 40500 -+/* -+ * Mark a position in code as unreachable. This can be used to -+ * suppress control flow warnings after asm blocks that transfer -+ * control elsewhere. -+ * -+ * Early snapshots of gcc 4.5 don't support this and we can't detect -+ * this in the preprocessor, but we can live with this because they're -+ * unreleased. Really, we need to have autoconf for the kernel. -+ */ -+#define unreachable() __builtin_unreachable() -+ -+/* Mark a function definition as prohibited from being cloned. */ -+#define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) -+ -+#endif /* GCC_VERSION >= 40500 */ -+ -+#if GCC_VERSION >= 40600 -+/* -+ * When used with Link Time Optimization, gcc can optimize away C functions or -+ * variables which are referenced only from assembly code. __visible tells the -+ * optimizer that something else uses this function or variable, thus preventing -+ * this. -+ */ -+#define __visible __attribute__((externally_visible)) -+#endif -+ -+ -+#if GCC_VERSION >= 40900 && !defined(__CHECKER__) -+/* -+ * __assume_aligned(n, k): Tell the optimizer that the returned -+ * pointer can be assumed to be k modulo n. The second argument is -+ * optional (default 0), so we use a variadic macro to make the -+ * shorthand. -+ * -+ * Beware: Do not apply this to functions which may return -+ * ERR_PTRs. Also, it is probably unwise to apply it to functions -+ * returning extra information in the low bits (but in that case the -+ * compiler should see some alignment anyway, when the return value is -+ * massaged by 'flags = ptr & 3; ptr &= ~3;'). -+ */ -+#define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) -+#endif -+ -+/* -+ * GCC 'asm goto' miscompiles certain code sequences: -+ * -+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 -+ * -+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. -+ * -+ * (asm goto is automatically volatile - the naming reflects this.) -+ */ -+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) -+ -+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP -+#if GCC_VERSION >= 40400 -+#define __HAVE_BUILTIN_BSWAP32__ -+#define __HAVE_BUILTIN_BSWAP64__ -+#endif -+#if GCC_VERSION >= 40800 -+#define __HAVE_BUILTIN_BSWAP16__ -+#endif -+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ -+ -+#if GCC_VERSION >= 50000 -+#define KASAN_ABI_VERSION 4 -+#elif GCC_VERSION >= 40902 -+#define KASAN_ABI_VERSION 3 -+#endif -+ -+#if GCC_VERSION >= 40902 -+/* -+ * Tell the compiler that address safety instrumentation (KASAN) -+ * should not be applied to that function. -+ * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 -+ */ -+#define __no_sanitize_address __attribute__((no_sanitize_address)) -+#endif -+ -+#endif /* gcc version >= 40000 specific checks */ -+ -+#if !defined(__noclone) -+#define __noclone /* not needed */ -+#endif -+ -+#if !defined(__no_sanitize_address) -+#define __no_sanitize_address -+#endif -+ -+/* -+ * A trick to suppress uninitialized variable warning without generating any -+ * code -+ */ -+#define uninitialized_var(x) x = x diff --git a/root/package/kernel/mt7623-preloader/Makefile b/root/package/kernel/mt7623-preloader/Makefile deleted file mode 100644 index d3f752bb..00000000 --- a/root/package/kernel/mt7623-preloader/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# -# Copyright (C) 2012-2016 OpenWrt.org -# Copyright (C) 2017 LEDE project -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk -#include $(INCLUDE_DIR)/image.mk - -PKG_NAME:=mt7623n-preloader -PKG_VERSION:=2019-10-24 -PKG_RELEASE:=1b7b6039b9d92c48193f38ac29dd2f71e303e280 - -PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)/$(PKG_NAME)-$(PKG_RELEASE) - -PKG_FLAGS:=nonshared - -include $(INCLUDE_DIR)/package.mk - -BPI_PRELOADER_URL:=@GITHUB/BPI-SINOVOIP/BPI-files/$(PKG_RELEASE)/SD/100MB/ -BPI_PRELOADER_PREFIX:=bpi-preloader-$(PKG_RELEASE) - -define Download/BPI-R2-preloader-DDR1600-20191024-2k.img.gz - FILE:=$(BPI_PRELOADER_PREFIX)-BPI-R2-preloader-DDR1600-20191024-2k.img.gz - URL:=$(BPI_PRELOADER_URL) - URL_FILE:=BPI-R2-preloader-DDR1600-20191024-2k.img.gz - HASH:=c731cc166c912c84846e2ed5faf727504e4dec1463754baa6328e9908c84a373 -endef -$(eval $(call Download,BPI-R2-preloader-DDR1600-20191024-2k.img.gz)) - - -define Package/mt7623n-preloader - SECTION:=boot - CATEGORY:=Boot Loaders - DEPENDS:=@TARGET_mediatek_mt7623 - TITLE:=mt7623n-preloader - DEFAULT:=y if TARGET_mediatek -endef - -define Package/mt7623n-preloader/description - Preloader image for mt7623n based boards like Bannana Pi R2. -endef - -define Build/Prepare - rm -rf $(PKG_BUILD_DIR) - mkdir -p $(PKG_BUILD_DIR) - cp $(DL_DIR)/$(BPI_PRELOADER_PREFIX)-BPI-R2-preloader-DDR1600-20191024-2k.img.gz $(PKG_BUILD_DIR)/bpi-r2-preloader.bin.gz -endef - -define Build/Compile - true -endef - -define Package/brcm2708-gpu-fw/install - true -endef - -define Build/InstallDev - mkdir -p $(STAGING_DIR_IMAGE) - gunzip -c $(PKG_BUILD_DIR)/bpi-r2-preloader.bin.gz > $(STAGING_DIR_IMAGE)/bpi-r2-preloader.bin -endef - -$(eval $(call BuildPackage,mt7623n-preloader)) \ No newline at end of file diff --git a/root/target/linux/mediatek/image/Config.in b/root/target/linux/mediatek/image/Config.in deleted file mode 100644 index 22a49ea6..00000000 --- a/root/target/linux/mediatek/image/Config.in +++ /dev/null @@ -1,4 +0,0 @@ -config MEDIATEK_SD_BOOT_PARTSIZE - int "Boot (SD Card) filesystem partition size (in MB)" - depends on TARGET_mediatek - default 128 diff --git a/root/target/linux/mediatek/image/Makefile b/root/target/linux/mediatek/image/Makefile deleted file mode 100644 index ecfa4eaf..00000000 --- a/root/target/linux/mediatek/image/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -# -# Copyright (C) 2012-2015 OpenWrt.org -# Copyright (C) 2016-2017 LEDE project -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/image.mk - -FAT32_BLOCK_SIZE=1024 -FAT32_BLOCKS=$(shell echo $$(($(CONFIG_MEDIATEK_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) - -# for arm -KERNEL_LOADADDR := 0x80008000 - -define Build/mediatek-sdcard - rm -f $@.boot - mkfs.fat $@.boot -C $(FAT32_BLOCKS) - - mcopy -i $@.boot $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-uEnv.txt ::uEnv.txt - mcopy -i $@.boot $(IMAGE_KERNEL) ::uImage - ./gen_mt7623_sdcard_img.sh $@ \ - $(STAGING_DIR_IMAGE)/bpi-r2-preloader.bin \ - $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-uboot-mediatek.bin \ - $@.boot \ - $(IMAGE_ROOTFS) \ - $(CONFIG_MEDIATEK_SD_BOOT_PARTSIZE) \ - $(CONFIG_TARGET_ROOTFS_PARTSIZE) - rm -f $@.boot - -endef - -# for arm64 -ifeq ($(SUBTARGET),mt7622) -KERNEL_LOADADDR = 0x41080000 -endif - -ifeq ($(SUBTARGET),mt7629) -KERNEL_LOADADDR = 0x40008000 -endif - -define Build/sysupgrade-emmc - rm -f $@.recovery - mkfs.fat -C $@.recovery 3070 - - ./gen_mt7623_emmc_img.sh $@ \ - $(IMAGE_KERNEL) \ - $@.recovery \ - $(IMAGE_ROOTFS) -endef - -# default all platform image(fit) build -define Device/Default - PROFILES = Default $$(DEVICE_NAME) - KERNEL_NAME := zImage - FILESYSTEMS := squashfs - DEVICE_DTS_DIR := $(DTS_DIR) - IMAGES := sysupgrade.bin - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata - SUPPORTED_DEVICES := $(subst _,$(comma),$(1)) -ifeq ($(SUBTARGET),mt7623) - DEVICE_VARS := MEDIATEK_UBOOT - KERNEL_NAME := zImage - KERNEL := kernel-bin | append-dtb | uImage none - KERNEL_INITRAMFS := kernel-bin | append-dtb | uImage none - FILESYSTEMS += ext4 - IMAGES := sysupgrade.tar sdcard.img.gz - IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata - IMAGE/sdcard.img.gz := mediatek-sdcard | gzip | append-metadata -else - KERNEL_NAME := Image - KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb - KERNEL_INITRAMFS = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb -endif -endef - -ifeq ($(SUBTARGET),mt7622) -include mt7622.mk -endif - -ifeq ($(SUBTARGET),mt7623) -include mt7623.mk -endif - -ifeq ($(SUBTARGET),mt7629) -include mt7629.mk -endif - -$(eval $(call BuildImage)) diff --git a/root/target/linux/mediatek/image/gen_mt7623_sdcard_img.sh b/root/target/linux/mediatek/image/gen_mt7623_sdcard_img.sh deleted file mode 100755 index f9a8dbde..00000000 --- a/root/target/linux/mediatek/image/gen_mt7623_sdcard_img.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2013 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -set -e -[ $# -eq 7 ] || { - echo "SYNTAX: $0 " - exit 1 -} - -OUTPUT="$1" -PRELOADER="$2" -UBOOT="$3" -BOOTFS="$4" -ROOTFS="$5" -BOOTFSSIZE="$6" -ROOTFSSIZE="$7" - -head=4 -sect=63 - -set `ptgen -o $OUTPUT -h $head -s $sect -l 1024 -t c -p ${BOOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M -a 0` - -BOOT_OFFSET="$(($1 / 512))" -BOOT_SIZE="$(($2 / 512))" -ROOTFS_OFFSET="$(($3 / 512))" -ROOTFS_SIZE="$(($4 / 512))" - -PRELOADER_OFFSET=2 # 2KB -UBOOT_OFFSET=320 # 320KB - -SDMMC_BOOT="SDMMC_BOOT\x00\x00\x01\x00\x00\x00\x00\x02\x00\x00" -BRLYT="\ -BRLYT\x00\x00\x00\x01\x00\x00\x00\x00\x08\x00\x00\ -\x00\x08\x00\x00\x42\x42\x42\x42\x08\x00\x01\x00\x00\x08\x00\x00\ -\x00\x08\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - -echo -en "${SDMMC_BOOT}" | dd bs=1 of="${OUTPUT}" seek=0 conv=notrunc -echo -en "${BRLYT}" | dd bs=1 of="${OUTPUT}" seek=512 conv=notrunc - -dd bs=1024 if="${PRELOADER}" of="${OUTPUT}" seek="${PRELOADER_OFFSET}" conv=notrunc -dd bs=1024 if="${UBOOT}" of="${OUTPUT}" seek="${UBOOT_OFFSET}" conv=notrunc -dd bs=512 if="${BOOTFS}" of="${OUTPUT}" seek="${BOOT_OFFSET}" conv=notrunc -dd bs=512 if="${ROOTFS}" of="${OUTPUT}" seek="${ROOTFS_OFFSET}" conv=notrunc diff --git a/root/target/linux/mediatek/image/mt7623.mk b/root/target/linux/mediatek/image/mt7623.mk deleted file mode 100644 index 678bfed0..00000000 --- a/root/target/linux/mediatek/image/mt7623.mk +++ /dev/null @@ -1,21 +0,0 @@ -define Device/unielec_u7623-02-emmc-512m - DEVICE_VENDOR := UniElec - DEVICE_MODEL := U7623-02 - DEVICE_VARIANT := eMMC/512MB RAM - DEVICE_DTS := mt7623a-unielec-u7623-02-emmc-512m - DEVICE_PACKAGES := mkf2fs e2fsprogs kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 kmod-mmc - IMAGES := sysupgrade-emmc.bin.gz - IMAGE/sysupgrade-emmc.bin.gz := sysupgrade-emmc | gzip | append-metadata -endef -TARGET_DEVICES += unielec_u7623-02-emmc-512m - -define Device/bpi_bananapi-r2 - DEVICE_VENDOR := Bpi - DEVICE_MODEL := Banana Pi R2 - DEVICE_DTS := mt7623n-bananapi-bpi-r2 - DEVICE_PACKAGES := kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb3 \ - kmod-ata-core kmod-ata-ahci-mtk \ - mt7623n-preloader - SUPPORTED_DEVICES := bananapi,bpi-r2 -endef -TARGET_DEVICES += bpi_bananapi-r2 From c47cd77038711bf2ef6993f32dff65120d1260b9 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 15 Jul 2020 15:02:35 +0200 Subject: [PATCH 69/76] Change repo URL --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 2fb7ecd8..fe1344d3 100755 --- a/build.sh +++ b/build.sh @@ -32,7 +32,7 @@ OMR_TARGET_CONFIG="config-$OMR_TARGET" OMR_KERNEL=${OMR_KERNEL:-5.4} #OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1` | sed 's/^\([0-9.]*\).*/\1/')} OMR_RELEASE=${OMR_RELEASE:-$(git tag --sort=committerdate | tail -1)} -OMR_REPO=${OMR_REPO:-http://$OMR_HOST:$OMR_PORT/release/$OMR_RELEASE} +OMR_REPO=${OMR_REPO:-http://$OMR_HOST:$OMR_PORT/release/$OMR_RELEASE/$OMR_TARGET} OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" OMR_FEED_SRC="${OMR_FEED_SRC:-develop}" From d5a0680c07616934a33424a22cec8e88115b67c6 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 20 Jul 2020 15:13:52 +0200 Subject: [PATCH 70/76] Update MPTCP --- .../generic/hack-5.4/690-mptcp_trunk.patch | 720 +++++++++++------- 1 file changed, 439 insertions(+), 281 deletions(-) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index c0b10832..7457f75d 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -1,6 +1,6 @@ diff -aurN linux-5.4/Documentation/admin-guide/kernel-parameters.txt mptcp-mptcp_trunk/Documentation/admin-guide/kernel-parameters.txt --- linux-5.4/Documentation/admin-guide/kernel-parameters.txt 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/Documentation/admin-guide/kernel-parameters.txt 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/Documentation/admin-guide/kernel-parameters.txt 2020-07-14 19:34:59.000000000 +0200 @@ -2724,6 +2724,10 @@ allocations which rules out almost all kernel allocations. Use with caution! @@ -14,7 +14,7 @@ diff -aurN linux-5.4/Documentation/admin-guide/kernel-parameters.txt mptcp-mptcp diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt --- linux-5.4/Documentation/networking/ip-sysctl.txt 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-07-14 19:34:59.000000000 +0200 @@ -818,6 +818,18 @@ Default: 0 (disabled) @@ -36,7 +36,7 @@ diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Do udp_l3mdev_accept - BOOLEAN diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c --- linux-5.4/drivers/infiniband/hw/cxgb4/cm.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-07-14 19:34:59.000000000 +0200 @@ -3946,7 +3946,7 @@ */ memset(&tmp_opt, 0, sizeof(tmp_opt)); @@ -48,7 +48,7 @@ diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/ memset(req, 0, sizeof(*req)); diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbuff.h --- linux-5.4/include/linux/skbuff.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-07-14 19:34:59.000000000 +0200 @@ -717,7 +717,7 @@ * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. @@ -60,7 +60,7 @@ diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbu struct { diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h --- linux-5.4/include/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-07-14 19:34:59.000000000 +0200 @@ -54,7 +54,7 @@ /* TCP Fast Open */ #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ @@ -219,7 +219,7 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/inet_common.h --- linux-5.4/include/net/inet_common.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-07-14 19:34:59.000000000 +0200 @@ -2,6 +2,7 @@ #ifndef _INET_COMMON_H #define _INET_COMMON_H @@ -239,7 +239,7 @@ diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/ine int addr_len, int flags); diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/include/net/inet_connection_sock.h --- linux-5.4/include/net/inet_connection_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-07-14 19:34:59.000000000 +0200 @@ -25,6 +25,7 @@ struct inet_bind_bucket; @@ -250,7 +250,7 @@ diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/includ * Pointers to address related TCP functions diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_sock.h --- linux-5.4/include/net/inet_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-07-14 19:34:59.000000000 +0200 @@ -79,7 +79,7 @@ #define ireq_state req.__req_common.skc_state #define ireq_family req.__req_common.skc_family @@ -271,8 +271,8 @@ diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_ union { diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h --- linux-5.4/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-06-09 17:33:41.000000000 +0200 -@@ -0,0 +1,1545 @@ ++++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-07-14 19:34:59.000000000 +0200 +@@ -0,0 +1,1571 @@ +/* + * MPTCP implementation + * @@ -964,7 +964,10 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + return 4 + m->A * (4 + m->a * 4) + m->M * (10 + m->m * 4 + csum * 2); +} + -+#define MPTCP_SYSCTL 1 ++#define MPTCP_ENABLE 0x01 ++#define MPTCP_SOCKOPT 0x02 ++#define MPTCP_CLIENT_DISABLE 0x04 ++#define MPTCP_SERVER_DISABLE 0x08 + +extern int sysctl_mptcp_enabled; +extern int sysctl_mptcp_version; @@ -1000,6 +1003,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + mptcp_for_each_bit_set(~b, i) + +#define MPTCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) ++#define MPTCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mptcp.mptcp_statistics, field) +#define MPTCP_INC_STATS_BH(net, field) __SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) + +enum @@ -1045,6 +1049,8 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h + MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */ + MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */ + MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */ ++ MPTCP_MIB_JOINALTERNATEPORT, /* Established a subflow on a different destination port-number */ ++ MPTCP_MIB_CURRESTAB, /* Current established MPTCP connections */ + __MPTCP_MIB_MAX +}; + @@ -1224,7 +1230,25 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +/* Initializes function-pointers and MPTCP-flags */ +static inline void mptcp_init_tcp_sock(struct sock *sk) +{ -+ if (!mptcp_init_failed && sysctl_mptcp_enabled == MPTCP_SYSCTL) ++ if (!mptcp_init_failed && sysctl_mptcp_enabled == MPTCP_ENABLE) ++ mptcp_enable_sock(sk); ++} ++ ++static inline void mptcp_init_listen(struct sock *sk) ++{ ++ if (!mptcp_init_failed && ++ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && ++ sysctl_mptcp_enabled & MPTCP_ENABLE && ++ !(sysctl_mptcp_enabled & MPTCP_SERVER_DISABLE)) ++ mptcp_enable_sock(sk); ++} ++ ++static inline void mptcp_init_connect(struct sock *sk) ++{ ++ if (!mptcp_init_failed && ++ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && ++ sysctl_mptcp_enabled & MPTCP_ENABLE && ++ !(sysctl_mptcp_enabled & MPTCP_CLIENT_DISABLE)) + mptcp_enable_sock(sk); +} + @@ -1800,6 +1824,8 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +static inline void mptcp_remove_shortcuts(const struct mptcp_cb *mpcb, + const struct sk_buff *skb) {} +static inline void mptcp_init_tcp_sock(struct sock *sk) {} ++static inline void mptcp_init_listen(struct sock *sk) {} ++static inline void mptcp_init_connect(struct sock *sk) {} +static inline void mptcp_disable_static_key(void) {} +static inline void mptcp_cookies_reqsk_init(struct request_sock *req, + struct mptcp_options_received *mopt, @@ -1820,7 +1846,7 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +#endif /* _MPTCP_H */ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_v4.h --- linux-5.4/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,76 @@ +/* + * MPTCP implementation @@ -1900,7 +1926,7 @@ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* MPTCP_V4_H_ */ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_v6.h --- linux-5.4/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,77 @@ +/* + * MPTCP implementation @@ -1981,7 +2007,7 @@ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* _MPTCP_V6_H */ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/net_namespace.h --- linux-5.4/include/net/net_namespace.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-07-14 19:34:59.000000000 +0200 @@ -19,6 +19,7 @@ #include #include @@ -2002,7 +2028,7 @@ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/n #endif diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/netns/mptcp.h --- linux-5.4/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,52 @@ +/* + * MPTCP implementation - MPTCP namespace @@ -2058,7 +2084,7 @@ diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/net +#endif /* __NETNS_MPTCP_H__ */ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h --- linux-5.4/include/net/snmp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/snmp.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/snmp.h 2020-07-14 19:34:59.000000000 +0200 @@ -86,7 +86,6 @@ atomic_long_t mibs[ICMP6MSG_MIB_MAX]; }; @@ -2069,7 +2095,7 @@ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h struct tcp_mib { diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h --- linux-5.4/include/net/sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/sock.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/sock.h 2020-07-14 19:34:59.000000000 +0200 @@ -814,6 +814,7 @@ SOCK_TXTIME, SOCK_XDP, /* XDP is attached */ @@ -2088,7 +2114,7 @@ diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h #ifdef CONFIG_PROC_FS diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h --- linux-5.4/include/net/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/tcp.h 2020-07-14 19:34:59.000000000 +0200 @@ -182,6 +182,7 @@ #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ @@ -2129,7 +2155,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h /* sysctl variables for tcp */ extern int sysctl_tcp_max_orphans; -@@ -310,6 +336,96 @@ +@@ -310,6 +336,97 @@ #define TCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mib.tcp_statistics, field) #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) @@ -2203,6 +2229,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h +unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, + int large_allowed); +u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb); ++void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, u32 prior_snd_una); + +void skb_clone_fraglist(struct sk_buff *skb); + @@ -2226,7 +2253,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h void tcp_tasklet_init(void); int tcp_v4_err(struct sk_buff *skb, u32); -@@ -411,7 +527,9 @@ +@@ -411,7 +528,9 @@ #endif void tcp_parse_options(const struct net *net, const struct sk_buff *skb, struct tcp_options_received *opt_rx, @@ -2237,7 +2264,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); /* -@@ -430,6 +548,7 @@ +@@ -430,6 +549,7 @@ void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); void tcp_v4_mtu_reduced(struct sock *sk); @@ -2245,7 +2272,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h void tcp_req_err(struct sock *sk, u32 seq, bool abort); int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); struct sock *tcp_create_openreq_child(const struct sock *sk, -@@ -453,6 +572,7 @@ +@@ -453,6 +573,7 @@ struct request_sock *req, struct tcp_fastopen_cookie *foc, enum tcp_synack_type synack_type); @@ -2253,7 +2280,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h int tcp_disconnect(struct sock *sk, int flags); void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); -@@ -462,6 +582,7 @@ +@@ -462,6 +583,7 @@ /* From syncookies.c */ struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, struct request_sock *req, @@ -2261,7 +2288,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h struct dst_entry *dst, u32 tsoff); int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, u32 cookie); -@@ -536,7 +657,8 @@ +@@ -536,7 +658,8 @@ u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, u16 *mssp); @@ -2271,7 +2298,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h u64 cookie_init_timestamp(struct request_sock *req); bool cookie_timestamp_decode(const struct net *net, struct tcp_options_received *opt); -@@ -550,7 +672,8 @@ +@@ -550,7 +673,8 @@ u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, const struct tcphdr *th, u16 *mssp); @@ -2281,7 +2308,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h #endif /* tcp_output.c */ -@@ -586,10 +709,16 @@ +@@ -586,10 +710,16 @@ void tcp_skb_collapse_tstamp(struct sk_buff *skb, const struct sk_buff *next_skb); @@ -2298,7 +2325,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); void tcp_fin(struct sock *sk); -@@ -633,7 +762,7 @@ +@@ -633,7 +763,7 @@ } /* tcp.c */ @@ -2307,7 +2334,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h /* Read 'sendfile()'-style from a TCP socket */ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, -@@ -817,6 +946,12 @@ +@@ -817,6 +947,12 @@ u16 tcp_gso_size; }; }; @@ -2320,7 +2347,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ __u8 sacked; /* State flags for SACK. */ -@@ -835,6 +970,14 @@ +@@ -835,6 +971,14 @@ has_rxtstamp:1, /* SKB has a RX timestamp */ unused:5; __u32 ack_seq; /* Sequence number ACK'd */ @@ -2335,7 +2362,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h union { struct { /* There is space for up to 24 bytes */ -@@ -1076,6 +1219,8 @@ +@@ -1076,6 +1220,8 @@ int tcp_set_allowed_congestion_control(char *allowed); int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, bool reinit, bool cap_net_admin); @@ -2344,7 +2371,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h u32 tcp_slow_start(struct tcp_sock *tp, u32 acked); void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked); -@@ -1377,6 +1522,19 @@ +@@ -1377,6 +1523,19 @@ space - (space>>tcp_adv_win_scale); } @@ -2364,7 +2391,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h /* Note: caller must be prepared to deal with negative returns */ static inline int tcp_space(const struct sock *sk) { -@@ -1949,6 +2107,30 @@ +@@ -1949,6 +2108,30 @@ #endif }; @@ -2395,7 +2422,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h struct tcp_request_sock_ops { u16 mss_clamp; #ifdef CONFIG_TCP_MD5SIG -@@ -1959,12 +2141,13 @@ +@@ -1959,12 +2142,13 @@ const struct sock *sk, const struct sk_buff *skb); #endif @@ -2414,7 +2441,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h #endif struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, const struct request_sock *req); -@@ -1978,15 +2161,17 @@ +@@ -1978,15 +2162,17 @@ #ifdef CONFIG_SYN_COOKIES static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, @@ -2435,7 +2462,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h { diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_states.h --- linux-5.4/include/net/tcp_states.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-07-14 19:34:59.000000000 +0200 @@ -22,6 +22,7 @@ TCP_LISTEN, TCP_CLOSING, /* Now a valid state */ @@ -2454,7 +2481,7 @@ diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_ #endif /* _LINUX_TCP_STATES_H */ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/transp_v6.h --- linux-5.4/include/net/transp_v6.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-07-14 19:34:59.000000000 +0200 @@ -58,6 +58,8 @@ /* address family specific functions */ @@ -2466,7 +2493,7 @@ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/trans diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/events/tcp.h --- linux-5.4/include/trace/events/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-07-14 19:34:59.000000000 +0200 @@ -10,6 +10,7 @@ #include #include @@ -2517,7 +2544,7 @@ diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/ #endif /* _TRACE_TCP_H */ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/linux/bpf.h --- linux-5.4/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-07-14 19:34:59.000000000 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ @@ -2528,7 +2555,7 @@ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/lin }; diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linux/if.h --- linux-5.4/include/uapi/linux/if.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-07-14 19:34:59.000000000 +0200 @@ -132,6 +132,9 @@ #define IFF_ECHO IFF_ECHO #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ @@ -2539,9 +2566,21 @@ diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linu #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) +diff -aurN linux-5.4/include/uapi/linux/in.h mptcp-mptcp_trunk/include/uapi/linux/in.h +--- linux-5.4/include/uapi/linux/in.h 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/include/uapi/linux/in.h 2020-07-14 19:34:59.000000000 +0200 +@@ -76,6 +76,8 @@ + #define IPPROTO_MPLS IPPROTO_MPLS + IPPROTO_RAW = 255, /* Raw IP packets */ + #define IPPROTO_RAW IPPROTO_RAW ++ IPPROTO_MPTCP = 262, /* Multipath TCP connection */ ++#define IPPROTO_MPTCP IPPROTO_MPTCP + IPPROTO_MAX + }; + #endif diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/linux/mptcp.h --- linux-5.4/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* @@ -2694,7 +2733,7 @@ diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/l +#endif /* _LINUX_MPTCP_H */ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/linux/tcp.h --- linux-5.4/include/uapi/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-07-14 19:34:59.000000000 +0200 @@ -18,9 +18,15 @@ #ifndef _UAPI_LINUX_TCP_H #define _UAPI_LINUX_TCP_H @@ -2782,7 +2821,7 @@ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/lin diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c --- linux-5.4/net/core/dev.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/dev.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/dev.c 2020-07-14 19:34:59.000000000 +0200 @@ -7855,7 +7855,7 @@ dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | @@ -2794,7 +2833,7 @@ diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces.c --- linux-5.4/net/core/net-traces.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-07-14 19:34:59.000000000 +0200 @@ -60,3 +60,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); @@ -2803,7 +2842,7 @@ diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces +EXPORT_TRACEPOINT_SYMBOL_GPL(mptcp_retransmit); diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c --- linux-5.4/net/core/skbuff.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-07-14 19:34:59.000000000 +0200 @@ -573,7 +573,7 @@ skb_drop_list(&skb_shinfo(skb)->frag_list); } @@ -2815,7 +2854,7 @@ diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c --- linux-5.4/net/core/sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/sock.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/core/sock.c 2020-07-14 19:34:59.000000000 +0200 @@ -135,6 +135,11 @@ #include @@ -2867,17 +2906,15 @@ diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c } else sk = kmalloc(prot->obj_size, priority); -@@ -1832,6 +1858,7 @@ +@@ -1832,4 +1858,5 @@ atomic_set(&newsk->sk_zckey, 0); sock_reset_flag(newsk, SOCK_DONE); + sock_reset_flag(newsk, SOCK_MPTCP); - /* sk->sk_memcg will be populated at accept() time */ - diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c --- linux-5.4/net/ipv4/af_inet.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-07-14 19:34:59.000000000 +0200 @@ -100,6 +100,7 @@ #include #include @@ -2896,7 +2933,16 @@ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c WARN_ON(atomic_read(&sk->sk_rmem_alloc)); WARN_ON(refcount_read(&sk->sk_wmem_alloc)); WARN_ON(sk->sk_wmem_queued); -@@ -244,8 +248,7 @@ +@@ -227,6 +231,8 @@ + tcp_fastopen_init_key_once(sock_net(sk)); + } + ++ mptcp_init_listen(sk); ++ + err = inet_csk_listen_start(sk, backlog); + if (err) + goto out; +@@ -244,8 +250,7 @@ * Create an inet socket. */ @@ -2906,7 +2952,7 @@ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c { struct sock *sk; struct inet_protosw *answer; -@@ -739,6 +742,24 @@ +@@ -739,6 +744,24 @@ lock_sock(sk2); sock_rps_record_flow(sk2); @@ -2931,7 +2977,7 @@ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c WARN_ON(!((1 << sk2->sk_state) & (TCPF_ESTABLISHED | TCPF_SYN_RECV | TCPF_CLOSE_WAIT | TCPF_CLOSE))); -@@ -1974,6 +1995,9 @@ +@@ -1974,6 +1997,9 @@ ip_init(); @@ -2943,7 +2989,7 @@ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c --- linux-5.4/net/ipv4/inet_connection_sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-07-14 19:34:59.000000000 +0200 @@ -19,6 +19,7 @@ #include #include @@ -3003,7 +3049,7 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ cond_resched(); diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c --- linux-5.4/net/ipv4/ip_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-07-14 19:34:59.000000000 +0200 @@ -44,6 +44,8 @@ #endif #include @@ -3045,7 +3091,7 @@ diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockgl case IP_TTL: diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig --- linux-5.4/net/ipv4/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-07-14 19:34:59.000000000 +0200 @@ -654,6 +654,51 @@ bufferbloat, policers, or AQM schemes that do not provide a delay signal. It requires the fq ("Fair Queue") pacing packet scheduler. @@ -3133,7 +3179,7 @@ diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig default "cdg" if DEFAULT_CDG diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies.c --- linux-5.4/net/ipv4/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-07-14 19:34:59.000000000 +0200 @@ -12,6 +12,8 @@ #include #include @@ -3261,7 +3307,7 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies */ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c --- linux-5.4/net/ipv4/tcp.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-07-14 19:34:59.000000000 +0200 @@ -270,6 +270,7 @@ #include @@ -3488,7 +3534,33 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c release_sock(sk); -@@ -2287,7 +2367,7 @@ +@@ -2238,8 +2318,11 @@ + + switch (state) { + case TCP_ESTABLISHED: +- if (oldstate != TCP_ESTABLISHED) ++ if (oldstate != TCP_ESTABLISHED) { + TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); ++ if (is_meta_sk(sk)) ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB); ++ } + break; + + case TCP_CLOSE: +@@ -2252,8 +2335,11 @@ + inet_put_port(sk); + /* fall through */ + default: +- if (oldstate == TCP_ESTABLISHED) ++ if (oldstate == TCP_ESTABLISHED) { + TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); ++ if (is_meta_sk(sk)) ++ MPTCP_DEC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB); ++ } + } + + /* Change state AFTER socket is unhashed to avoid closed +@@ -2287,7 +2373,7 @@ [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ }; @@ -3497,7 +3569,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { int next = (int)new_state[sk->sk_state]; int ns = next & TCP_STATE_MASK; -@@ -2317,7 +2397,7 @@ +@@ -2317,7 +2403,7 @@ TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { /* Clear out any half completed packets. FIN if needed. */ if (tcp_close_state(sk)) @@ -3506,7 +3578,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } } EXPORT_SYMBOL(tcp_shutdown); -@@ -2342,6 +2422,17 @@ +@@ -2342,6 +2428,17 @@ int data_was_unread = 0; int state; @@ -3524,7 +3596,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c lock_sock(sk); sk->sk_shutdown = SHUTDOWN_MASK; -@@ -2386,7 +2477,7 @@ +@@ -2386,7 +2483,7 @@ /* Unread data was tossed, zap the connection. */ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); tcp_set_state(sk, TCP_CLOSE); @@ -3533,7 +3605,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { /* Check zero linger _after_ checking for unread data. */ sk->sk_prot->disconnect(sk, 0); -@@ -2460,7 +2551,7 @@ +@@ -2460,7 +2557,7 @@ struct tcp_sock *tp = tcp_sk(sk); if (tp->linger2 < 0) { tcp_set_state(sk, TCP_CLOSE); @@ -3542,7 +3614,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONLINGER); } else { -@@ -2470,7 +2561,8 @@ +@@ -2470,7 +2567,8 @@ inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); } else { @@ -3552,7 +3624,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c goto out; } } -@@ -2479,7 +2571,7 @@ +@@ -2479,7 +2577,7 @@ sk_mem_reclaim(sk); if (tcp_check_oom(sk, 0)) { tcp_set_state(sk, TCP_CLOSE); @@ -3561,7 +3633,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); } else if (!check_net(sock_net(sk))) { -@@ -2511,15 +2603,6 @@ +@@ -2511,15 +2609,6 @@ } EXPORT_SYMBOL(tcp_close); @@ -3577,7 +3649,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c static void tcp_rtx_queue_purge(struct sock *sk) { struct rb_node *p = rb_first(&sk->tcp_rtx_queue); -@@ -2540,6 +2623,10 @@ +@@ -2540,6 +2629,10 @@ { struct sk_buff *skb; @@ -3588,7 +3660,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tcp_chrono_stop(sk, TCP_CHRONO_BUSY); while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { tcp_skb_tsorted_anchor_cleanup(skb); -@@ -2558,6 +2645,29 @@ +@@ -2558,6 +2651,29 @@ inet_csk(sk)->icsk_backoff = 0; } @@ -3618,7 +3690,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c int tcp_disconnect(struct sock *sk, int flags) { struct inet_sock *inet = inet_sk(sk); -@@ -2580,7 +2690,7 @@ +@@ -2580,7 +2696,7 @@ /* The last check adjusts for discrepancy of Linux wrt. RFC * states */ @@ -3627,7 +3699,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c sk->sk_err = ECONNRESET; } else if (old_state == TCP_SYN_SENT) sk->sk_err = ECONNRESET; -@@ -2602,11 +2712,15 @@ +@@ -2602,11 +2718,15 @@ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) inet_reset_saddr(sk); @@ -3646,7 +3718,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c seq = tp->write_seq + tp->max_window + 2; if (!seq) -@@ -2616,17 +2730,11 @@ +@@ -2616,17 +2736,11 @@ icsk->icsk_backoff = 0; tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; @@ -3667,7 +3739,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c inet_csk_delack_init(sk); /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 * issue in __tcp_select_window() -@@ -2636,14 +2746,10 @@ +@@ -2636,14 +2752,10 @@ sk->sk_rx_dst = NULL; tcp_saved_syn_free(tp); tp->compressed_ack = 0; @@ -3677,12 +3749,12 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c - tp->bytes_acked = 0; - tp->bytes_received = 0; - tp->bytes_retrans = 0; - tp->data_segs_in = 0; - tp->data_segs_out = 0; + tp->data_segs_in = 0; + tp->data_segs_out = 0; tp->duplicate_sack[0].start_seq = 0; tp->duplicate_sack[0].end_seq = 0; tp->dsack_dups = 0; -@@ -2648,8 +2754,6 @@ +@@ -2648,8 +2760,6 @@ tp->sacked_out = 0; tp->tlp_high_seq = 0; tp->last_oow_ack_time = 0; @@ -3691,7 +3763,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tp->rack.mstamp = 0; tp->rack.advanced = 0; tp->rack.reo_wnd_steps = 1; -@@ -2683,7 +2787,7 @@ +@@ -2683,7 +2793,7 @@ static inline bool tcp_can_repair_sock(const struct sock *sk) { return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && @@ -3700,7 +3772,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) -@@ -2852,6 +2956,61 @@ +@@ -2852,6 +2962,61 @@ return tcp_fastopen_reset_cipher(net, sk, key, backup_key); } @@ -3762,7 +3834,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c default: /* fallthru */ break; -@@ -3032,6 +3191,12 @@ +@@ -3032,6 +3197,12 @@ break; case TCP_DEFER_ACCEPT: @@ -3775,7 +3847,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c /* Translate value in seconds to number of retransmits */ icsk->icsk_accept_queue.rskq_defer_accept = secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -@@ -3059,7 +3224,7 @@ +@@ -3059,7 +3230,7 @@ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && inet_csk_ack_scheduled(sk)) { icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; @@ -3784,7 +3856,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!(val & 1)) inet_csk_enter_pingpong_mode(sk); } -@@ -3069,7 +3234,7 @@ +@@ -3069,7 +3240,7 @@ #ifdef CONFIG_TCP_MD5SIG case TCP_MD5SIG: case TCP_MD5SIG_EXT: @@ -3793,7 +3865,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c err = tp->af_specific->md5_parse(sk, optname, optval, optlen); else err = -EINVAL; -@@ -3128,6 +3293,32 @@ +@@ -3128,6 +3299,32 @@ tp->notsent_lowat = val; sk->sk_write_space(sk); break; @@ -3826,7 +3898,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c case TCP_INQ: if (val > 1 || val < 0) err = -EINVAL; -@@ -3192,7 +3383,7 @@ +@@ -3192,7 +3389,7 @@ } /* Return information about state of tcp endpoint in API format. */ @@ -3835,7 +3907,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ const struct inet_connection_sock *icsk = inet_csk(sk); -@@ -3229,7 +3420,8 @@ +@@ -3229,7 +3426,8 @@ return; } @@ -3845,7 +3917,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c info->tcpi_ca_state = icsk->icsk_ca_state; info->tcpi_retransmits = icsk->icsk_retransmits; -@@ -3305,7 +3497,9 @@ +@@ -3305,7 +3503,9 @@ info->tcpi_reord_seen = tp->reord_seen; info->tcpi_rcv_ooopack = tp->rcv_ooopack; info->tcpi_snd_wnd = tp->snd_wnd; @@ -3856,7 +3928,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } EXPORT_SYMBOL_GPL(tcp_get_info); -@@ -3452,7 +3646,7 @@ +@@ -3452,7 +3652,7 @@ if (get_user(len, optlen)) return -EFAULT; @@ -3865,7 +3937,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c len = min_t(unsigned int, len, sizeof(info)); if (put_user(len, optlen)) -@@ -3649,6 +3843,87 @@ +@@ -3649,6 +3849,87 @@ } return 0; } @@ -3953,7 +4025,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c #ifdef CONFIG_MMU case TCP_ZEROCOPY_RECEIVE: { struct tcp_zerocopy_receive zc; -@@ -3851,7 +4126,9 @@ +@@ -3851,7 +4132,9 @@ if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); @@ -3963,7 +4035,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tcp_clear_xmit_timers(sk); if (req) reqsk_fastopen_remove(sk, req, false); -@@ -3867,6 +4144,8 @@ +@@ -3867,6 +4150,8 @@ int tcp_abort(struct sock *sk, int err) { @@ -3972,7 +4044,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!sk_fullsock(sk)) { if (sk->sk_state == TCP_NEW_SYN_RECV) { struct request_sock *req = inet_reqsk(sk); -@@ -3880,7 +4159,7 @@ +@@ -3880,7 +4165,7 @@ } /* Don't race with userspace socket closes such as tcp_close. */ @@ -3981,7 +4053,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (sk->sk_state == TCP_LISTEN) { tcp_set_state(sk, TCP_CLOSE); -@@ -3889,7 +4168,7 @@ +@@ -3889,7 +4174,7 @@ /* Don't race with BH socket closes such as inet_csk_listen_stop. */ local_bh_disable(); @@ -3990,7 +4062,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_err = err; -@@ -3897,14 +4176,14 @@ +@@ -3897,14 +4182,14 @@ smp_wmb(); sk->sk_error_report(sk); if (tcp_need_reset(sk->sk_state)) @@ -4010,7 +4082,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c EXPORT_SYMBOL_GPL(tcp_abort); diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c --- linux-5.4/net/ipv4/tcp_cong.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-07-14 19:34:59.000000000 +0200 @@ -328,13 +328,19 @@ return ret; } @@ -4035,7 +4107,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c const struct tcp_congestion_ops *ca; diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c --- linux-5.4/net/ipv4/tcp_diag.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-07-14 19:34:59.000000000 +0200 @@ -31,7 +31,7 @@ r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; } @@ -4047,7 +4119,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c #ifdef CONFIG_TCP_MD5SIG diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c --- linux-5.4/net/ipv4/tcp_fastopen.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-07-14 19:34:59.000000000 +0200 @@ -9,6 +9,7 @@ #include #include @@ -4108,7 +4180,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fast */ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c --- linux-5.4/net/ipv4/tcp_input.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-07-14 19:34:59.000000000 +0200 @@ -76,35 +76,15 @@ #include #include @@ -4268,7 +4340,17 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct tcp_sock *tp = tcp_sk(sk); u32 packets_acked; -@@ -3147,6 +3154,8 @@ +@@ -3041,8 +3048,7 @@ + return packets_acked; + } + +-static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, +- u32 prior_snd_una) ++void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, u32 prior_snd_una) + { + const struct skb_shared_info *shinfo; + +@@ -3147,6 +3153,8 @@ */ if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { flag |= FLAG_DATA_ACKED; @@ -4277,7 +4359,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } else { flag |= FLAG_SYN_ACKED; tp->retrans_stamp = 0; -@@ -3266,7 +3275,7 @@ +@@ -3266,7 +3274,7 @@ return flag; } @@ -4286,7 +4368,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct inet_connection_sock *icsk = inet_csk(sk); struct sk_buff *head = tcp_send_head(sk); -@@ -3338,9 +3347,8 @@ +@@ -3338,9 +3346,8 @@ /* Check that window update is acceptable. * The function assumes that snd_una<=ack<=snd_next. */ @@ -4298,7 +4380,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { return after(ack, tp->snd_una) || after(ack_seq, tp->snd_wl1) || -@@ -3577,7 +3585,7 @@ +@@ -3577,7 +3584,7 @@ } /* This routine deals with incoming acks, but not outgoing ones. */ @@ -4307,7 +4389,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); -@@ -3691,6 +3699,16 @@ +@@ -3691,6 +3698,16 @@ tcp_rack_update_reo_wnd(sk, &rs); @@ -4324,7 +4406,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (tp->tlp_high_seq) tcp_process_tlp_ack(sk, ack, flag); /* If needed, reset TLP/RTO timer; RACK may later override this. */ -@@ -3833,8 +3851,10 @@ +@@ -3833,8 +3850,10 @@ */ void tcp_parse_options(const struct net *net, const struct sk_buff *skb, @@ -4337,7 +4419,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { const unsigned char *ptr; const struct tcphdr *th = tcp_hdr(skb); -@@ -3920,6 +3940,10 @@ +@@ -3920,6 +3939,10 @@ */ break; #endif @@ -4348,7 +4430,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c case TCPOPT_FASTOPEN: tcp_parse_fastopen_option( opsize - TCPOLEN_FASTOPEN_BASE, -@@ -3987,7 +4011,9 @@ +@@ -3987,7 +4010,9 @@ return true; } @@ -4359,7 +4441,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) tp->rx_opt.rcv_tsecr -= tp->tsoffset; -@@ -4146,6 +4172,11 @@ +@@ -4146,6 +4171,11 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4371,7 +4453,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c inet_csk_schedule_ack(sk); sk->sk_shutdown |= RCV_SHUTDOWN; -@@ -4156,6 +4187,10 @@ +@@ -4156,6 +4186,10 @@ case TCP_ESTABLISHED: /* Move to CLOSE_WAIT */ tcp_set_state(sk, TCP_CLOSE_WAIT); @@ -4382,7 +4464,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c inet_csk_enter_pingpong_mode(sk); break; -@@ -4178,9 +4213,16 @@ +@@ -4178,9 +4212,16 @@ tcp_set_state(sk, TCP_CLOSING); break; case TCP_FIN_WAIT2: @@ -4400,7 +4482,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c break; default: /* Only TCP_LISTEN and TCP_CLOSE are left, in these -@@ -4202,6 +4244,10 @@ +@@ -4202,6 +4243,10 @@ if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_state_change(sk); @@ -4411,7 +4493,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Do not send POLL_HUP for half duplex close. */ if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) -@@ -4416,6 +4462,9 @@ +@@ -4416,6 +4461,9 @@ *fragstolen = false; @@ -4421,7 +4503,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Its possible this segment overlaps with prior segment in queue */ if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq) return false; -@@ -4470,7 +4519,7 @@ +@@ -4470,7 +4518,7 @@ /* This one checks to see if we can put data from the * out_of_order queue into the receive_queue. */ @@ -4430,7 +4512,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct tcp_sock *tp = tcp_sk(sk); __u32 dsack_high = tp->rcv_nxt; -@@ -4493,7 +4542,14 @@ +@@ -4493,7 +4541,14 @@ p = rb_next(p); rb_erase(&skb->rbnode, &tp->out_of_order_queue); @@ -4446,7 +4528,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_drop(sk, skb); continue; } -@@ -4523,6 +4579,9 @@ +@@ -4523,6 +4578,9 @@ static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, unsigned int size) { @@ -4456,7 +4538,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || !sk_rmem_schedule(sk, skb, size)) { -@@ -4537,7 +4596,7 @@ +@@ -4537,7 +4595,7 @@ return 0; } @@ -4465,7 +4547,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct tcp_sock *tp = tcp_sk(sk); struct rb_node **p, *parent; -@@ -4604,7 +4663,8 @@ +@@ -4604,7 +4662,8 @@ continue; } if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { @@ -4475,7 +4557,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* All the bits are present. Drop. */ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPOFOMERGE); -@@ -4651,6 +4711,11 @@ +@@ -4651,6 +4710,11 @@ end_seq); break; } @@ -4487,7 +4569,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c rb_erase(&skb1->rbnode, &tp->out_of_order_queue); tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, TCP_SKB_CB(skb1)->end_seq); -@@ -4662,7 +4727,7 @@ +@@ -4662,7 +4726,7 @@ tp->ooo_last_skb = skb; add_sack: @@ -4496,7 +4578,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_sack_new_ofo_skb(sk, seq, end_seq); end: if (skb) { -@@ -4672,8 +4737,8 @@ +@@ -4672,8 +4736,8 @@ } } @@ -4507,18 +4589,17 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { int eaten; struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4746,8 +4811,8 @@ +@@ -4746,8 +4810,7 @@ const struct tcp_sock *tp = tcp_sk(sk); int avail = tp->rcv_nxt - tp->copied_seq; - if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && - !sock_flag(sk, SOCK_DONE)) -+ if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && !mptcp(tp) && -+ !sock_flag(sk, SOCK_DONE)) ++ if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) return; sk->sk_data_ready(sk); -@@ -4758,10 +4823,14 @@ +@@ -4758,10 +4822,14 @@ bool fragstolen; int eaten; @@ -4534,7 +4615,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c skb_dst_drop(skb); __skb_pull(skb, tcp_hdr(skb)->doff * 4); -@@ -4789,7 +4858,7 @@ +@@ -4789,7 +4857,7 @@ } eaten = tcp_queue_rcv(sk, skb, &fragstolen); @@ -4543,7 +4624,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_event_data_recv(sk, skb); if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) tcp_fin(sk); -@@ -4811,7 +4880,11 @@ +@@ -4811,7 +4879,11 @@ if (eaten > 0) kfree_skb_partial(skb, fragstolen); @@ -4556,7 +4637,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_data_ready(sk); return; } -@@ -5154,7 +5227,7 @@ +@@ -5154,7 +5226,7 @@ return -1; } @@ -4565,7 +4646,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { const struct tcp_sock *tp = tcp_sk(sk); -@@ -5189,7 +5262,7 @@ +@@ -5189,7 +5261,7 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4574,7 +4655,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_sndbuf_expand(sk); tp->snd_cwnd_stamp = tcp_jiffies32; } -@@ -5203,10 +5276,11 @@ +@@ -5203,10 +5275,11 @@ sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); /* pairs with tcp_poll() */ smp_mb(); @@ -4589,7 +4670,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); } } -@@ -5225,6 +5299,8 @@ +@@ -5225,6 +5298,8 @@ { struct tcp_sock *tp = tcp_sk(sk); unsigned long rtt, delay; @@ -4598,7 +4679,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* More than one full frame received... */ if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && -@@ -5233,8 +5309,8 @@ +@@ -5233,8 +5308,8 @@ * If application uses SO_RCVLOWAT, we want send ack now if * we have not received enough bytes to satisfy the condition. */ @@ -4609,7 +4690,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* We ACK each frame or... */ tcp_in_quickack_mode(sk) || /* Protocol state mandates a one-time immediate ACK */ -@@ -5369,6 +5445,10 @@ +@@ -5369,6 +5444,10 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4620,7 +4701,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Check if we get a new urgent pointer - normally not. */ if (th->urg) tcp_check_urg(sk, th); -@@ -5511,9 +5591,15 @@ +@@ -5511,9 +5590,15 @@ goto discard; } @@ -4636,7 +4717,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_drop(sk, skb); return false; } -@@ -5570,6 +5656,10 @@ +@@ -5570,6 +5655,10 @@ tp->rx_opt.saw_tstamp = 0; @@ -4647,7 +4728,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* pred_flags is 0xS?10 << 16 + snd_wnd * if header_prediction is to be made * 'S' will always be tp->tcp_header_len >> 2 -@@ -5742,7 +5832,7 @@ +@@ -5742,7 +5831,7 @@ tcp_call_bpf(sk, bpf_op, 0, NULL); tcp_init_congestion_control(sk); @@ -4656,7 +4737,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) -@@ -5779,17 +5869,24 @@ +@@ -5779,17 +5868,24 @@ struct tcp_fastopen_cookie *cookie) { struct tcp_sock *tp = tcp_sk(sk); @@ -4683,7 +4764,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c mss = opt.mss_clamp; } -@@ -5813,7 +5910,11 @@ +@@ -5813,7 +5909,11 @@ tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp); @@ -4696,7 +4777,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c skb_rbtree_walk_from(data) { if (__tcp_retransmit_skb(sk, data, 1)) break; -@@ -5868,9 +5969,13 @@ +@@ -5868,9 +5968,13 @@ struct tcp_sock *tp = tcp_sk(sk); struct tcp_fastopen_cookie foc = { .len = -1 }; int saved_clamp = tp->rx_opt.mss_clamp; @@ -4711,7 +4792,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) tp->rx_opt.rcv_tsecr -= tp->tsoffset; -@@ -5931,6 +6036,35 @@ +@@ -5931,6 +6035,35 @@ tcp_try_undo_spurious_syn(sk); tcp_ack(sk, skb, FLAG_SLOWPATH); @@ -4747,7 +4828,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Ok.. it's good. Set up sequence numbers and * move to established. */ -@@ -5957,6 +6091,11 @@ +@@ -5957,6 +6090,11 @@ tp->tcp_header_len = sizeof(struct tcphdr); } @@ -4759,7 +4840,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); tcp_initialize_rcv_mss(sk); -@@ -5980,9 +6119,12 @@ +@@ -5980,9 +6118,12 @@ } if (fastopen_fail) return -1; @@ -4774,7 +4855,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Save one ACK. Data will be ready after * several ticks, if write_pending is set. * -@@ -6021,6 +6163,7 @@ +@@ -6021,6 +6162,7 @@ tcp_paws_reject(&tp->rx_opt, 0)) goto discard_and_undo; @@ -4782,7 +4863,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (th->syn) { /* We see SYN without ACK. It is attempt of * simultaneous connect with crossed SYNs. -@@ -6037,6 +6180,11 @@ +@@ -6037,6 +6179,11 @@ tp->tcp_header_len = sizeof(struct tcphdr); } @@ -4794,7 +4875,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c WRITE_ONCE(tp->rcv_nxt, TCP_SKB_CB(skb)->seq + 1); WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; -@@ -6123,6 +6271,7 @@ +@@ -6123,6 +6270,7 @@ */ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) @@ -4802,7 +4883,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); -@@ -6165,6 +6314,16 @@ +@@ -6165,6 +6313,16 @@ tp->rx_opt.saw_tstamp = 0; tcp_mstamp_refresh(tp); queued = tcp_rcv_synsent_state_process(sk, skb, th); @@ -4819,7 +4900,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (queued >= 0) return queued; -@@ -6237,6 +6396,8 @@ +@@ -6237,6 +6395,8 @@ if (tp->rx_opt.tstamp_ok) tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; @@ -4828,7 +4909,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (!inet_csk(sk)->icsk_ca_ops->cong_control) tcp_update_pacing_rate(sk); -@@ -6246,6 +6407,30 @@ +@@ -6246,6 +6406,30 @@ tcp_initialize_rcv_mss(sk); tcp_fast_path_on(tp); @@ -4859,7 +4940,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c break; case TCP_FIN_WAIT1: { -@@ -6286,7 +6471,8 @@ +@@ -6286,7 +6470,8 @@ tmo = tcp_fin_time(sk); if (tmo > TCP_TIMEWAIT_LEN) { inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); @@ -4869,7 +4950,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Bad case. We could lose such FIN otherwise. * It is not a big problem, but it looks confusing * and not so rare event. We still can lose it now, -@@ -6295,7 +6481,7 @@ +@@ -6295,7 +6480,7 @@ */ inet_csk_reset_keepalive_timer(sk, tmo); } else { @@ -4878,7 +4959,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c goto discard; } break; -@@ -6303,7 +6489,7 @@ +@@ -6303,7 +6488,7 @@ case TCP_CLOSING: if (tp->snd_una == tp->write_seq) { @@ -4887,7 +4968,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c goto discard; } break; -@@ -6315,6 +6501,9 @@ +@@ -6315,6 +6500,9 @@ goto discard; } break; @@ -4897,7 +4978,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } /* step 6: check the URG bit */ -@@ -6336,7 +6525,8 @@ +@@ -6336,7 +6524,8 @@ */ if (sk->sk_shutdown & RCV_SHUTDOWN) { if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && @@ -4907,7 +4988,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); tcp_reset(sk); return 1; -@@ -6438,6 +6628,8 @@ +@@ -6438,6 +6627,8 @@ ireq->wscale_ok = rx_opt->wscale_ok; ireq->acked = 0; ireq->ecn_ok = 0; @@ -4916,7 +4997,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c ireq->ir_rmt_port = tcp_hdr(skb)->source; ireq->ir_num = ntohs(tcp_hdr(skb)->dest); ireq->ir_mark = inet_request_mark(sk, skb); -@@ -6563,12 +6755,17 @@ +@@ -6563,12 +6754,17 @@ /* TW buckets are converted to open requests without * limitations, they conserve resources and peer is * evidently real one. @@ -4935,7 +5016,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } if (sk_acceptq_is_full(sk)) { -@@ -6586,8 +6783,8 @@ +@@ -6586,8 +6782,8 @@ tcp_clear_options(&tmp_opt); tmp_opt.mss_clamp = af_ops->mss_clamp; tmp_opt.user_mss = tp->rx_opt.user_mss; @@ -4946,7 +5027,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (want_cookie && !tmp_opt.saw_tstamp) tcp_clear_options(&tmp_opt); -@@ -6602,7 +6799,8 @@ +@@ -6602,7 +6798,8 @@ /* Note: tcp_v6_init_req() might override ir_iif for link locals */ inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb); @@ -4956,7 +5037,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (security_inet_conn_request(sk, skb, req)) goto drop_and_free; -@@ -6638,7 +6836,7 @@ +@@ -6638,7 +6835,7 @@ tcp_ecn_create_request(req, skb, sk, dst); if (want_cookie) { @@ -4965,7 +5046,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c req->cookie_ts = tmp_opt.tstamp_ok; if (!tmp_opt.tstamp_ok) inet_rsk(req)->ecn_ok = 0; -@@ -6653,17 +6851,25 @@ +@@ -6653,17 +6850,25 @@ fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst); } if (fastopen_sk) { @@ -4994,7 +5075,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_rsk(req)->tfo_listener = false; diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c --- linux-5.4/net/ipv4/tcp_ipv4.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-07-14 19:34:59.000000000 +0200 @@ -62,6 +62,8 @@ #include #include @@ -5004,7 +5085,16 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c #include #include #include -@@ -430,7 +432,7 @@ +@@ -209,6 +211,8 @@ + struct ip_options_rcu *inet_opt; + struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row; + ++ mptcp_init_connect(sk); ++ + if (addr_len < sizeof(struct sockaddr_in)) + return -EINVAL; + +@@ -430,7 +434,7 @@ struct inet_sock *inet; const int type = icmp_hdr(icmp_skb)->type; const int code = icmp_hdr(icmp_skb)->code; @@ -5013,7 +5103,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c struct sk_buff *skb; struct request_sock *fastopen; u32 seq, snd_una; -@@ -460,13 +462,19 @@ +@@ -460,13 +464,19 @@ return 0; } @@ -5035,7 +5125,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); } -@@ -479,7 +487,6 @@ +@@ -479,7 +489,6 @@ } icsk = inet_csk(sk); @@ -5043,7 +5133,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ fastopen = rcu_dereference(tp->fastopen_rsk); snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -513,11 +520,13 @@ +@@ -513,11 +522,13 @@ goto out; tp->mtu_info = info; @@ -5058,7 +5148,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c } goto out; } -@@ -531,7 +540,7 @@ +@@ -531,7 +542,7 @@ !icsk->icsk_backoff || fastopen) break; @@ -5067,7 +5157,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c break; skb = tcp_rtx_queue_head(sk); -@@ -555,7 +564,7 @@ +@@ -555,7 +566,7 @@ } else { /* RTO revert clocked out retransmission. * Will retransmit now */ @@ -5076,7 +5166,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c } break; -@@ -575,7 +584,7 @@ +@@ -575,7 +586,7 @@ if (fastopen && !fastopen->sk) break; @@ -5085,7 +5175,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c sk->sk_err = err; sk->sk_error_report(sk); -@@ -604,7 +613,7 @@ +@@ -604,7 +615,7 @@ */ inet = inet_sk(sk); @@ -5094,7 +5184,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c sk->sk_err = err; sk->sk_error_report(sk); } else { /* Only an error on timeout */ -@@ -612,7 +621,7 @@ +@@ -612,7 +623,7 @@ } out: @@ -5103,7 +5193,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c sock_put(sk); return 0; } -@@ -648,7 +657,7 @@ +@@ -648,7 +659,7 @@ * Exception: precedence violation. We do not implement it in any case. */ @@ -5112,7 +5202,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { const struct tcphdr *th = tcp_hdr(skb); struct { -@@ -800,10 +809,10 @@ +@@ -800,10 +811,10 @@ */ static void tcp_v4_send_ack(const struct sock *sk, @@ -5125,7 +5215,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { const struct tcphdr *th = tcp_hdr(skb); struct { -@@ -812,6 +821,10 @@ +@@ -812,6 +823,10 @@ #ifdef CONFIG_TCP_MD5SIG + (TCPOLEN_MD5SIG_ALIGNED >> 2) #endif @@ -5136,7 +5226,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c ]; } rep; struct net *net = sock_net(sk); -@@ -858,6 +871,21 @@ +@@ -858,6 +873,21 @@ ip_hdr(skb)->daddr, &rep.th); } #endif @@ -5158,7 +5248,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c arg.flags = reply_flags; arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, ip_hdr(skb)->saddr, /* XXX */ -@@ -889,28 +917,36 @@ +@@ -889,28 +919,36 @@ { struct inet_timewait_sock *tw = inet_twsk(sk); struct tcp_timewait_sock *tcptw = tcp_twsk(sk); @@ -5200,7 +5290,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c tcp_sk(sk)->snd_nxt; /* RFC 7323 2.3 -@@ -919,7 +955,7 @@ +@@ -919,7 +957,7 @@ * Rcv.Wind.Shift bits: */ tcp_v4_send_ack(sk, skb, seq, @@ -5209,7 +5299,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, req->ts_recent, -@@ -927,7 +963,7 @@ +@@ -927,7 +965,7 @@ tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr, AF_INET), inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, @@ -5218,7 +5308,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c } /* -@@ -935,11 +971,11 @@ +@@ -935,11 +973,11 @@ * This still operates on a request_sock only, not on a big * socket. */ @@ -5235,7 +5325,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { const struct inet_request_sock *ireq = inet_rsk(req); struct flowi4 fl4; -@@ -969,7 +1005,7 @@ +@@ -969,7 +1007,7 @@ /* * IPv4 request_sock destructor. */ @@ -5244,7 +5334,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); } -@@ -1345,9 +1381,10 @@ +@@ -1345,9 +1383,10 @@ return false; } @@ -5258,7 +5348,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { struct inet_request_sock *ireq = inet_rsk(req); struct net *net = sock_net(sk_listener); -@@ -1355,6 +1392,8 @@ +@@ -1355,6 +1394,8 @@ sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); @@ -5267,7 +5357,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c } static struct dst_entry *tcp_v4_route_req(const struct sock *sk, -@@ -1374,7 +1413,7 @@ +@@ -1374,7 +1415,7 @@ .syn_ack_timeout = tcp_syn_ack_timeout, }; @@ -5276,7 +5366,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c .mss_clamp = TCP_MSS_DEFAULT, #ifdef CONFIG_TCP_MD5SIG .req_md5_lookup = tcp_v4_md5_lookup, -@@ -1511,7 +1550,7 @@ +@@ -1511,7 +1552,7 @@ } EXPORT_SYMBOL(tcp_v4_syn_recv_sock); @@ -5285,7 +5375,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { #ifdef CONFIG_SYN_COOKIES const struct tcphdr *th = tcp_hdr(skb); -@@ -1549,6 +1588,9 @@ +@@ -1549,6 +1590,9 @@ { struct sock *rsk; @@ -5295,7 +5385,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ struct dst_entry *dst = sk->sk_rx_dst; -@@ -1793,6 +1835,10 @@ +@@ -1793,6 +1837,10 @@ TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + skb->len - th->doff * 4); TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); @@ -5306,7 +5396,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); TCP_SKB_CB(skb)->tcp_tw_isn = 0; TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); -@@ -1812,8 +1858,8 @@ +@@ -1812,8 +1860,8 @@ int sdif = inet_sdif(skb); const struct iphdr *iph; const struct tcphdr *th; @@ -5316,7 +5406,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c int ret; if (skb->pkt_type != PACKET_HOST) -@@ -1867,7 +1913,11 @@ +@@ -1867,7 +1915,11 @@ reqsk_put(req); goto csum_error; } @@ -5329,7 +5419,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c inet_csk_reqsk_queue_drop_and_put(sk, req); goto lookup; } -@@ -1876,6 +1926,7 @@ +@@ -1876,6 +1928,7 @@ */ sock_hold(sk); refcounted = true; @@ -5337,7 +5427,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c nsk = NULL; if (!tcp_filter(sk, skb)) { th = (const struct tcphdr *)skb->data; -@@ -1936,19 +1987,28 @@ +@@ -1936,19 +1989,28 @@ sk_incoming_cpu_update(sk); @@ -5370,7 +5460,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c if (skb_to_free) __kfree_skb(skb_to_free); -@@ -1964,6 +2024,19 @@ +@@ -1964,6 +2026,19 @@ tcp_v4_fill_cb(skb, iph, th); @@ -5390,7 +5480,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c if (tcp_checksum_complete(skb)) { csum_error: __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -2012,6 +2085,18 @@ +@@ -2012,6 +2087,18 @@ refcounted = false; goto process; } @@ -5409,7 +5499,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c } /* to ACK */ /* fall through */ -@@ -2081,7 +2166,12 @@ +@@ -2081,7 +2168,12 @@ tcp_init_sock(sk); @@ -5423,7 +5513,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c #ifdef CONFIG_TCP_MD5SIG tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific; -@@ -2100,6 +2190,11 @@ +@@ -2100,6 +2192,11 @@ tcp_cleanup_congestion_control(sk); @@ -5435,7 +5525,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c tcp_cleanup_ulp(sk); /* Cleanup up the write buffer. */ -@@ -2603,6 +2698,11 @@ +@@ -2603,6 +2700,11 @@ .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), .max_header = MAX_TCP_HEADER, .obj_size = sizeof(struct tcp_sock), @@ -5447,7 +5537,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c .slab_flags = SLAB_TYPESAFE_BY_RCU, .twsk_prot = &tcp_timewait_sock_ops, .rsk_prot = &tcp_request_sock_ops, -@@ -2613,6 +2713,9 @@ +@@ -2613,6 +2715,9 @@ .compat_getsockopt = compat_tcp_getsockopt, #endif .diag_destroy = tcp_abort, @@ -5459,7 +5549,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c --- linux-5.4/net/ipv4/tcp_minisocks.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-07-14 19:34:59.000000000 +0200 @@ -19,11 +19,13 @@ * Jorge Cwik, */ @@ -5594,7 +5684,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min __TCP_INC_STATS(sock_net(sk), TCP_MIB_PASSIVEOPENS); -@@ -570,6 +612,7 @@ +@@ -570,15 +612,20 @@ bool fastopen, bool *req_stolen) { struct tcp_options_received tmp_opt; @@ -5602,8 +5692,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min struct sock *child; const struct tcphdr *th = tcp_hdr(skb); __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); -@@ -577,8 +620,11 @@ + bool paws_reject = false; bool own_req; ++ bool meta_locked = false; tmp_opt.saw_tstamp = 0; + @@ -5615,7 +5706,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min if (tmp_opt.saw_tstamp) { tmp_opt.ts_recent = req->ts_recent; -@@ -619,7 +665,14 @@ +@@ -619,7 +666,14 @@ * * Reset timer after retransmitting SYNACK, similar to * the idea of fast retransmit in recovery. @@ -5630,12 +5721,14 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min if (!tcp_oow_rate_limited(sock_net(sk), skb, LINUX_MIB_TCPACKSKIPPEDSYNRECV, &tcp_rsk(req)->last_oow_ack_time) && -@@ -767,17 +820,37 @@ +@@ -767,17 +821,40 @@ * ESTABLISHED STATE. If it will be dropped after * socket is created, wait for troubles. */ -+ if (is_meta_sk(sk)) ++ if (is_meta_sk(sk)) { + bh_lock_sock_nested(sk); ++ meta_locked = true; ++ } child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, req, &own_req); if (!child) @@ -5653,22 +5746,23 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min + return mptcp_check_req_child(sk, child, req, skb, &mopt); + } + -+ if (is_meta_sk(sk)) ++ if (meta_locked) + bh_unlock_sock(sk); + sock_rps_save_rxhash(child, skb); tcp_synack_rtt_meas(child, req); *req_stolen = !own_req; ++ return inet_csk_complete_hashdance(sk, child, req, own_req); listen_overflow: -+ if (is_meta_sk(sk)) ++ if (meta_locked) + bh_unlock_sock(sk); + if (!sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow) { inet_rsk(req)->acked = 1; return NULL; -@@ -820,12 +893,13 @@ +@@ -820,12 +897,13 @@ { int ret = 0; int state = child->sk_state; @@ -5683,7 +5777,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min ret = tcp_rcv_state_process(child, skb); /* Wakeup parent, send SIGIO */ if (state == TCP_SYN_RECV && child->sk_state != state) -@@ -835,10 +909,14 @@ +@@ -835,10 +913,14 @@ * in main socket hash table and lock on listening * socket does not protect us more. */ @@ -5701,7 +5795,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min } diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output.c --- linux-5.4/net/ipv4/tcp_output.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-07-14 19:34:59.000000000 +0200 @@ -37,6 +37,12 @@ #define pr_fmt(fmt) "TCP: " fmt @@ -6293,7 +6387,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Cancel probe timer, if it is not required. */ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c --- linux-5.4/net/ipv4/tcp_timer.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-07-14 19:34:59.000000000 +0200 @@ -21,6 +21,7 @@ #include @@ -6507,7 +6601,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c --- linux-5.4/net/ipv6/addrconf.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-07-14 19:34:59.000000000 +0200 @@ -967,6 +967,7 @@ kfree_rcu(ifp, rcu); @@ -6518,7 +6612,7 @@ diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c --- linux-5.4/net/ipv6/af_inet6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-07-14 19:34:59.000000000 +0200 @@ -104,8 +104,7 @@ return (struct ipv6_pinfo *)(((u8 *)sk) + offset); } @@ -6531,7 +6625,7 @@ diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c struct ipv6_pinfo *np; diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c --- linux-5.4/net/ipv6/ipv6_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-07-14 19:34:59.000000000 +0200 @@ -44,6 +44,8 @@ #include #include @@ -6557,7 +6651,7 @@ diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_so tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies.c --- linux-5.4/net/ipv6/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-07-14 19:34:59.000000000 +0200 @@ -15,6 +15,8 @@ #include #include @@ -6647,7 +6741,7 @@ diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies out_free: diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c --- linux-5.4/net/ipv6/tcp_ipv6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-07-14 19:34:59.000000000 +0200 @@ -58,6 +58,8 @@ #include #include @@ -6691,7 +6785,16 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c int addr_len) { struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; -@@ -236,7 +229,12 @@ +@@ -157,6 +150,8 @@ + int err; + struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row; + ++ mptcp_init_connect(sk); ++ + if (addr_len < SIN6_LEN_RFC2133) + return -EINVAL; + +@@ -236,7 +231,12 @@ sin.sin_port = usin->sin6_port; sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; @@ -6705,7 +6808,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c sk->sk_backlog_rcv = tcp_v4_do_rcv; #ifdef CONFIG_TCP_MD5SIG tp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -246,7 +244,12 @@ +@@ -246,7 +246,12 @@ if (err) { icsk->icsk_ext_hdr_len = exthdrlen; @@ -6719,7 +6822,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c sk->sk_backlog_rcv = tcp_v6_do_rcv; #ifdef CONFIG_TCP_MD5SIG tp->af_specific = &tcp_sock_ipv6_specific; -@@ -340,7 +343,7 @@ +@@ -340,7 +345,7 @@ return err; } @@ -6728,7 +6831,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { struct dst_entry *dst; -@@ -367,7 +370,7 @@ +@@ -367,7 +372,7 @@ struct ipv6_pinfo *np; struct tcp_sock *tp; __u32 seq, snd_una; @@ -6737,7 +6840,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c bool fatal; int err; -@@ -393,8 +396,14 @@ +@@ -393,8 +398,14 @@ return 0; } @@ -6754,7 +6857,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); if (sk->sk_state == TCP_CLOSE) -@@ -405,7 +414,6 @@ +@@ -405,7 +416,6 @@ goto out; } @@ -6762,7 +6865,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ fastopen = rcu_dereference(tp->fastopen_rsk); snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -439,11 +447,15 @@ +@@ -439,11 +449,15 @@ goto out; tp->mtu_info = ntohl(info); @@ -6782,7 +6885,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c goto out; } -@@ -458,7 +470,7 @@ +@@ -458,7 +472,7 @@ if (fastopen && !fastopen->sk) break; @@ -6791,7 +6894,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c sk->sk_err = err; sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ -@@ -468,14 +480,14 @@ +@@ -468,14 +482,14 @@ goto out; } @@ -6808,7 +6911,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c sock_put(sk); return 0; } -@@ -523,8 +535,7 @@ +@@ -523,8 +537,7 @@ return err; } @@ -6818,7 +6921,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { kfree(inet_rsk(req)->ipv6_opt); kfree_skb(inet_rsk(req)->pktopts); -@@ -742,9 +753,10 @@ +@@ -742,9 +755,10 @@ return false; } @@ -6832,7 +6935,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { bool l3_slave = ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags); struct inet_request_sock *ireq = inet_rsk(req); -@@ -766,6 +778,8 @@ +@@ -766,6 +780,8 @@ refcount_inc(&skb->users); ireq->pktopts = skb; } @@ -6841,7 +6944,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c } static struct dst_entry *tcp_v6_route_req(const struct sock *sk, -@@ -785,7 +799,7 @@ +@@ -785,7 +801,7 @@ .syn_ack_timeout = tcp_syn_ack_timeout, }; @@ -6850,7 +6953,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr), #ifdef CONFIG_TCP_MD5SIG -@@ -803,9 +817,9 @@ +@@ -803,9 +819,9 @@ }; static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq, @@ -6862,7 +6965,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { const struct tcphdr *th = tcp_hdr(skb); struct tcphdr *t1; -@@ -824,7 +838,10 @@ +@@ -824,7 +840,10 @@ if (key) tot_len += TCPOLEN_MD5SIG_ALIGNED; #endif @@ -6874,7 +6977,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, GFP_ATOMIC); if (!buff) -@@ -862,6 +879,17 @@ +@@ -862,6 +881,17 @@ tcp_v6_md5_hash_hdr((__u8 *)topt, key, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, t1); @@ -6892,7 +6995,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c } #endif -@@ -920,7 +948,7 @@ +@@ -920,7 +950,7 @@ kfree_skb(buff); } @@ -6901,7 +7004,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { const struct tcphdr *th = tcp_hdr(skb); struct ipv6hdr *ipv6h = ipv6_hdr(skb); -@@ -1005,8 +1033,8 @@ +@@ -1005,8 +1035,8 @@ label = ip6_flowlabel(ipv6h); } @@ -6912,7 +7015,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c #ifdef CONFIG_TCP_MD5SIG out: -@@ -1015,30 +1043,37 @@ +@@ -1015,30 +1045,37 @@ } static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, @@ -6957,7 +7060,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV * sk->sk_state == TCP_SYN_RECV -> for Fast Open. -@@ -1048,18 +1083,18 @@ +@@ -1048,18 +1085,18 @@ * exception of segments, MUST be right-shifted by * Rcv.Wind.Shift bits: */ @@ -6980,7 +7083,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { #ifdef CONFIG_SYN_COOKIES const struct tcphdr *th = tcp_hdr(skb); -@@ -1085,7 +1120,7 @@ +@@ -1085,7 +1122,7 @@ return mss; } @@ -6989,7 +7092,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_conn_request(sk, skb); -@@ -1111,11 +1146,11 @@ +@@ -1111,11 +1148,11 @@ sizeof(struct inet6_skb_parm)); } @@ -7006,7 +7109,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { struct inet_request_sock *ireq; struct ipv6_pinfo *newnp; -@@ -1150,7 +1185,15 @@ +@@ -1150,7 +1187,15 @@ newnp->saddr = newsk->sk_v6_rcv_saddr; @@ -7023,7 +7126,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c newsk->sk_backlog_rcv = tcp_v4_do_rcv; #ifdef CONFIG_TCP_MD5SIG newtp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -1197,6 +1240,14 @@ +@@ -1197,6 +1242,14 @@ if (!newsk) goto out_nonewsk; @@ -7038,7 +7141,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c /* * No need to charge this sock to the relevant IPv6 refcnt debug socks * count here, tcp_create_openreq_child now does this for us, see the -@@ -1324,7 +1375,7 @@ +@@ -1324,7 +1377,7 @@ * This is because we cannot sleep with the original spinlock * held. */ @@ -7047,7 +7150,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { struct ipv6_pinfo *np = tcp_inet6_sk(sk); struct sk_buff *opt_skb = NULL; -@@ -1341,6 +1392,9 @@ +@@ -1341,6 +1394,9 @@ if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_do_rcv(sk, skb); @@ -7057,7 +7160,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c /* * socket locking is here for SMP purposes as backlog rcv * is currently called with bh processing disabled. -@@ -1468,6 +1522,10 @@ +@@ -1468,6 +1524,10 @@ TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + skb->len - th->doff*4); TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); @@ -7068,7 +7171,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); TCP_SKB_CB(skb)->tcp_tw_isn = 0; TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); -@@ -1482,8 +1540,8 @@ +@@ -1482,8 +1542,8 @@ int sdif = inet6_sdif(skb); const struct tcphdr *th; const struct ipv6hdr *hdr; @@ -7078,7 +7181,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c int ret; struct net *net = dev_net(skb->dev); -@@ -1537,12 +1595,17 @@ +@@ -1537,12 +1597,17 @@ reqsk_put(req); goto csum_error; } @@ -7097,7 +7200,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c nsk = NULL; if (!tcp_filter(sk, skb)) { th = (const struct tcphdr *)skb->data; -@@ -1601,19 +1664,28 @@ +@@ -1601,19 +1666,28 @@ sk_incoming_cpu_update(sk); @@ -7130,7 +7233,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c if (skb_to_free) __kfree_skb(skb_to_free); put_and_return: -@@ -1627,6 +1699,19 @@ +@@ -1627,6 +1701,19 @@ tcp_v6_fill_cb(skb, hdr, th); @@ -7150,7 +7253,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c if (tcp_checksum_complete(skb)) { csum_error: __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1679,6 +1764,18 @@ +@@ -1679,6 +1766,18 @@ refcounted = false; goto process; } @@ -7169,7 +7272,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c } /* to ACK */ /* fall through */ -@@ -1733,13 +1830,13 @@ +@@ -1733,13 +1832,13 @@ } } @@ -7185,7 +7288,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c .queue_xmit = inet6_csk_xmit, .send_check = tcp_v6_send_check, .rebuild_header = inet6_sk_rebuild_header, -@@ -1770,7 +1867,7 @@ +@@ -1770,7 +1869,7 @@ /* * TCP over IPv4 via INET6 API */ @@ -7194,7 +7297,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c .queue_xmit = ip_queue_xmit, .send_check = tcp_v4_send_check, .rebuild_header = inet_sk_rebuild_header, -@@ -1806,7 +1903,12 @@ +@@ -1806,7 +1905,12 @@ tcp_init_sock(sk); @@ -7208,7 +7311,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c #ifdef CONFIG_TCP_MD5SIG tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific; -@@ -1815,7 +1917,7 @@ +@@ -1815,7 +1919,7 @@ return 0; } @@ -7217,7 +7320,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c { tcp_v4_destroy_sock(sk); inet6_destroy_sock(sk); -@@ -2038,6 +2140,11 @@ +@@ -2038,6 +2142,11 @@ .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), .max_header = MAX_TCP_HEADER, .obj_size = sizeof(struct tcp6_sock), @@ -7229,7 +7332,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c .slab_flags = SLAB_TYPESAFE_BY_RCU, .twsk_prot = &tcp6_timewait_sock_ops, .rsk_prot = &tcp6_request_sock_ops, -@@ -2048,6 +2155,9 @@ +@@ -2048,6 +2157,9 @@ .compat_getsockopt = compat_tcp_getsockopt, #endif .diag_destroy = tcp_abort, @@ -7241,7 +7344,7 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c /* thinking of making this const? Don't. diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig --- linux-5.4/net/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Kconfig 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/Kconfig 2020-07-14 19:34:59.000000000 +0200 @@ -91,6 +91,7 @@ source "net/ipv4/Kconfig" source "net/ipv6/Kconfig" @@ -7252,7 +7355,7 @@ diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile --- linux-5.4/net/Makefile 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Makefile 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/Makefile 2020-07-14 19:34:59.000000000 +0200 @@ -20,6 +20,7 @@ obj-$(CONFIG_XFRM) += xfrm/ obj-$(CONFIG_UNIX_SCM) += unix/ @@ -7263,14 +7366,16 @@ diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile obj-$(CONFIG_NET_KEY) += key/ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig --- linux-5.4/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-06-09 17:33:41.000000000 +0200 -@@ -0,0 +1,152 @@ ++++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-07-14 19:34:59.000000000 +0200 +@@ -0,0 +1,154 @@ +# +# MPTCP configuration +# +config MPTCP + bool "MPTCP protocol" + depends on (IPV6=y || IPV6=n) ++ select CRYPTO_LIB_SHA256 ++ select CRYPTO + ---help--- + This replaces the normal TCP stack with a Multipath TCP stack, + able to use several paths at once. @@ -7419,7 +7524,7 @@ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig + diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile --- linux-5.4/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,25 @@ +# +## Makefile for MultiPath TCP support code. @@ -7448,7 +7553,7 @@ diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile +mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c --- linux-5.4/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,193 @@ +/* + * Desynchronized Multi-Channel TCP Congestion Control Algorithm @@ -7645,7 +7750,7 @@ diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_ +MODULE_VERSION("1.0"); diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c --- linux-5.4/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,261 @@ +/* + * MPTCP implementation - Balia Congestion Control @@ -7910,7 +8015,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c --- linux-5.4/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,494 @@ +#include + @@ -8408,7 +8513,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c --- linux-5.4/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP Scheduler to reduce HoL-blocking and spurious retransmissions. @@ -8697,7 +8802,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_VERSION("0.95"); diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c --- linux-5.4/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,262 @@ +/* + * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) @@ -8963,8 +9068,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c --- linux-5.4/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-06-09 17:33:41.000000000 +0200 -@@ -0,0 +1,3303 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-07-14 19:34:59.000000000 +0200 +@@ -0,0 +1,3309 @@ +/* + * MPTCP implementation - MPTCP-control + * @@ -11437,6 +11542,10 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + reqsk_put(req); + + MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKRX); ++ ++ if (inet_sk(child)->inet_sport != inet_sk(meta_sk)->inet_sport) ++ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINALTERNATEPORT); ++ + return child; + +teardown: @@ -12004,6 +12113,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct + SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX), + SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX), + SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX), ++ SNMP_MIB_ITEM("MPJoinAlternatePort", MPTCP_MIB_JOINALTERNATEPORT), ++ SNMP_MIB_ITEM("MPCurrEstab", MPTCP_MIB_CURRESTAB), + SNMP_MIB_SENTINEL +}; + @@ -12270,7 +12381,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +} diff -aurN linux-5.4/net/mptcp/mptcp_ecf.c mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c --- linux-5.4/net/mptcp/mptcp_ecf.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP ECF Scheduler @@ -12469,7 +12580,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ecf.c mptcp-mptcp_trunk/net/mptcp/mptcp_ecf +MODULE_VERSION("0.95"); diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c --- linux-5.4/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,1938 @@ +#include +#include @@ -14243,7 +14354,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc + mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { + struct mptcp_loc4 *loc4 = &mptcp_local->locaddr4[i]; + -+ seq_printf(seq, "%u, %u, %u, %pI4 %u\n", i, loc4->loc4_id, ++ seq_printf(seq, "%u, %u, %u, %pI4, %u\n", i, loc4->loc4_id, + loc4->low_prio, &loc4->addr, loc4->if_idx); + } + @@ -14252,7 +14363,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc + mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { + struct mptcp_loc6 *loc6 = &mptcp_local->locaddr6[i]; + -+ seq_printf(seq, "%u, %u, %u, %pI6 %u\n", i, loc6->loc6_id, ++ seq_printf(seq, "%u, %u, %u, %pI6, %u\n", i, loc6->loc6_id, + loc6->low_prio, &loc6->addr, loc6->if_idx); + } + rcu_read_unlock_bh(); @@ -14411,8 +14522,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc +MODULE_VERSION("0.88"); diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_input.c --- linux-5.4/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-06-09 17:33:41.000000000 +0200 -@@ -0,0 +1,2529 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-07-14 19:34:59.000000000 +0200 +@@ -0,0 +1,2531 @@ +/* + * MPTCP implementation - Sending side + * @@ -14510,21 +14621,23 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + struct sk_buff *skb, *tmp, *next; + struct tcp_sock *meta_tp = tcp_sk(meta_sk); + struct mptcp_cb *mpcb = meta_tp->mpcb; ++ bool fully_acked = true; + bool acked = false; + u32 acked_pcount; + + for (skb = skb_rb_first(&meta_sk->tcp_rtx_queue); skb; skb = next) { -+ bool fully_acked = true; ++ struct tcp_skb_cb *scb = TCP_SKB_CB(skb); + -+ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { ++ tcp_ack_tstamp(meta_sk, skb, prior_snd_una); ++ ++ if (after(scb->end_seq, meta_tp->snd_una)) { + if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) ++ !after(meta_tp->snd_una, scb->seq)) + break; + + acked_pcount = tcp_tso_acked(meta_sk, skb); + if (!acked_pcount) + break; -+ + fully_acked = false; + } else { + acked_pcount = tcp_skb_pcount(skb); @@ -16944,8 +17057,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i +} diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c --- linux-5.4/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-06-09 17:33:41.000000000 +0200 -@@ -0,0 +1,430 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-07-14 19:34:59.000000000 +0200 +@@ -0,0 +1,431 @@ +/* + * MPTCP implementation - IPv4-specific functions + * @@ -17154,6 +17267,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip + goto reset_and_discard; + } + ++ bh_unlock_sock(meta_sk); + local_bh_enable(); + return 0; + } @@ -17378,8 +17492,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip +} diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c --- linux-5.4/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-06-09 17:33:41.000000000 +0200 -@@ -0,0 +1,478 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-07-14 19:34:59.000000000 +0200 +@@ -0,0 +1,479 @@ +/* + * MPTCP implementation - IPv6-specific functions + * @@ -17616,6 +17730,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip + goto reset_and_discard; + } + ++ bh_unlock_sock(meta_sk); + local_bh_enable(); + return 0; + } @@ -17860,7 +17975,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip +} diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c --- linux-5.4/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,174 @@ +#include + @@ -18038,7 +18153,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mp +MODULE_VERSION("0.88"); diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c --- linux-5.4/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,1271 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP implementation - Netlink Path Manager @@ -19313,7 +19428,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_ALIAS_GENL_FAMILY(MPTCP_GENL_NAME); diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c --- linux-5.4/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,318 @@ +/* + * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: @@ -19635,8 +19750,8 @@ diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_ol +MODULE_VERSION("0.1"); diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_output.c --- linux-5.4/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-06-09 17:33:41.000000000 +0200 -@@ -0,0 +1,1994 @@ ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-07-14 19:34:59.000000000 +0200 +@@ -0,0 +1,1997 @@ +/* + * MPTCP implementation - Sending side + * @@ -20242,6 +20357,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + tp->write_seq += subskb->len + ((tcb->tcp_flags & TCPHDR_FIN) ? 1 : 0); + tcb->end_seq = tp->write_seq; + ++ /* txstamp_ack is handled at the meta-level */ ++ tcb->txstamp_ack = 0; ++ + /* If it's a non-payload DATA_FIN (also no subflow-fin), the + * segment is not part of the subflow but on a meta-only-level. + */ @@ -21633,7 +21751,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c --- linux-5.4/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,226 @@ +/* + * MPTCP implementation - MPTCP-subflow-management @@ -21863,7 +21981,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c +late_initcall(mptcp_path_manager_default); diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c --- linux-5.4/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,392 @@ +/* + * MPTCP Scheduler to reduce latency and jitter. @@ -22259,7 +22377,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mpt +MODULE_VERSION("0.90"); diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c --- linux-5.4/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,309 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -22572,7 +22690,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c +MODULE_VERSION("0.89"); diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c --- linux-5.4/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,647 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -23223,7 +23341,7 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s +late_initcall(mptcp_scheduler_default); diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c --- linux-5.4/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-07-14 19:34:59.000000000 +0200 @@ -0,0 +1,271 @@ +/* + * MPTCP implementation - WEIGHTED VEGAS @@ -23496,9 +23614,49 @@ diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP wVegas"); +MODULE_VERSION("0.1"); +diff -aurN linux-5.4/net/socket.c mptcp-mptcp_trunk/net/socket.c +--- linux-5.4/net/socket.c 2019-11-25 01:32:01.000000000 +0100 ++++ mptcp-mptcp_trunk/net/socket.c 2020-07-14 19:34:59.000000000 +0200 +@@ -91,6 +91,7 @@ + #include + + #include ++#include + #include + #include + +@@ -1350,6 +1351,7 @@ + int err; + struct socket *sock; + const struct net_proto_family *pf; ++ int old_protocol = protocol; + + /* + * Check protocol is in range +@@ -1370,6 +1372,9 @@ + family = PF_PACKET; + } + ++ if (old_protocol == IPPROTO_MPTCP) ++ protocol = IPPROTO_TCP; ++ + err = security_socket_create(family, type, protocol, kern); + if (err) + return err; +@@ -1419,6 +1424,10 @@ + if (err < 0) + goto out_module_put; + ++ if (sysctl_mptcp_enabled && old_protocol == IPPROTO_MPTCP && ++ type == SOCK_STREAM && (family == AF_INET || family == AF_INET6)) ++ mptcp_enable_sock(sock->sk); ++ + /* + * Now to bump the refcnt of the [loadable] module that owns this + * socket at sock_release time we decrement its refcnt. diff -aurN linux-5.4/tools/include/uapi/linux/bpf.h mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h --- linux-5.4/tools/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-06-09 17:33:41.000000000 +0200 ++++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-07-14 19:34:59.000000000 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ From a7439609e4a90af640e1d61ddf707ec0bff0761d Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 20 Jul 2020 15:14:13 +0200 Subject: [PATCH 71/76] Update OpenWrt and add espressobin v7 support --- build.sh | 8 +++++--- config-espressobin | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 config-espressobin diff --git a/build.sh b/build.sh index fe1344d3..c7009f63 100755 --- a/build.sh +++ b/build.sh @@ -58,6 +58,8 @@ elif [ "$OMR_TARGET" = "bpi-r2" ]; then OMR_REAL_TARGET="arm_cortex-a7_neon-vfpv4" elif [ "$OMR_TARGET" = "bpi-r64" ]; then OMR_REAL_TARGET="aarch64_cortex-a53" +elif [ "$OMR_TARGET" = "espressobin" ]; then + OMR_REAL_TARGET="aarch64_cortex-a53" elif [ "$OMR_TARGET" = "x86" ]; then OMR_REAL_TARGET="i386_pentium4" else @@ -66,9 +68,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "f632747704f172e5c6d3a7c5715dc8d2f50d8da8" - _get_repo feeds/packages https://github.com/openwrt/packages "9bd81604b76a9b1abc0bb8146fb55c00c2445f1b" - _get_repo feeds/luci https://github.com/openwrt/luci "4ddcb360885030f33baa73f8569640db93250878" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "65e9de3c333bae1ccef1dfb0cc008ad6f13958e4" + _get_repo feeds/packages https://github.com/openwrt/packages "38db6a2e3ea62b03ef7c26401a3d26edaf621487" + _get_repo feeds/luci https://github.com/openwrt/luci "7edd635026594da577b73f059c0d8b95d653f8fc" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" diff --git a/config-espressobin b/config-espressobin new file mode 100644 index 00000000..b11d9a82 --- /dev/null +++ b/config-espressobin @@ -0,0 +1,7 @@ +CONFIG_TARGET_mvebu=y +CONFIG_TARGET_mvebu_cortexa53=y +CONFIG_TARGET_mvebu_cortexa53_DEVICE_globalscale_espressobin-v7=y +CONFIG_PACKAGE_kmod-6lowpan=y +CONFIG_PACKAGE_luci-app-advanced-reboot=y +# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y From 948d909538294537cc20aa19ddc0dffce3181cf1 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 21 Jul 2020 21:50:18 +0200 Subject: [PATCH 72/76] Fix for openmptcprouter mini --- build.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build.sh b/build.sh index c7009f63..8fcd1f37 100755 --- a/build.sh +++ b/build.sh @@ -146,7 +146,6 @@ if [ -f "$OMR_TARGET_CONFIG" ]; then CONFIG_VERSION_DIST="$OMR_DIST" CONFIG_VERSION_REPO="$OMR_REPO" CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" describe --tag --always)" - CONFIG_PACKAGE_${OMR_DIST}-full=y EOF else cat config -> "$OMR_TARGET/source/.config" <<-EOF @@ -155,7 +154,6 @@ else CONFIG_VERSION_DIST="$OMR_DIST" CONFIG_VERSION_REPO="$OMR_REPO" CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" describe --tag --always)" - CONFIG_PACKAGE_${OMR_DIST}-full=y EOF fi if [ "$OMR_ALL_PACKAGES" = "yes" ]; then @@ -169,10 +167,10 @@ if [ "$OMR_IMG" = "yes" ] && [ "$OMR_TARGET" = "x86_64" ]; then fi if [ "$OMR_PACKAGES" = "full" ]; then - echo 'CONFIG_PACKAGE_${OMR_DIST}-full=y' >> "$OMR_TARGET/source/.config" + echo "CONFIG_PACKAGE_${OMR_DIST}-full=y" >> "$OMR_TARGET/source/.config" fi if [ "$OMR_PACKAGES" = "mini" ]; then - echo 'CONFIG_PACKAGE_${OMR_DIST}-mini=y' >> "$OMR_TARGET/source/.config" + echo "CONFIG_PACKAGE_${OMR_DIST}-mini=y" >> "$OMR_TARGET/source/.config" fi cd "$OMR_TARGET/source" From fa8d87d2c498f965f5f2c30344f4cc9ad69f8162 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Sat, 25 Jul 2020 10:26:00 +0200 Subject: [PATCH 73/76] Fix process list --- config | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config b/config index e4fc694a..ae512ee1 100644 --- a/config +++ b/config @@ -17,9 +17,9 @@ CONFIG_BUSYBOX_CONFIG_FEATURE_SEAMLESS_BZ2=y CONFIG_BUSYBOX_CONFIG_FEATURE_SHOW_THREADS=y CONFIG_BUSYBOX_CONFIG_FEATURE_STAT_FILESYSTEM=y CONFIG_BUSYBOX_CONFIG_FEATURE_STAT_FORMAT=y -CONFIG_BUSYBOX_CONFIG_FEATURE_TOP_DECIMALS=y -CONFIG_BUSYBOX_CONFIG_FEATURE_TOP_SMP_CPU=y -CONFIG_BUSYBOX_CONFIG_FEATURE_TOP_SMP_PROCESS=y +# CONFIG_BUSYBOX_CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_BUSYBOX_CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_BUSYBOX_CONFIG_FEATURE_TOP_SMP_PROCESS is not set CONFIG_BUSYBOX_CONFIG_FEATURE_USE_TERMIOS=y CONFIG_BUSYBOX_CONFIG_FEATURE_VI_UNDO=y CONFIG_BUSYBOX_CONFIG_FEATURE_VI_UNDO_QUEUE=y From 75ccf18e543506a558a96292f49347f7049f0146 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 29 Jul 2020 15:36:45 +0200 Subject: [PATCH 74/76] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 8fcd1f37..8d136a91 100755 --- a/build.sh +++ b/build.sh @@ -68,9 +68,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "65e9de3c333bae1ccef1dfb0cc008ad6f13958e4" - _get_repo feeds/packages https://github.com/openwrt/packages "38db6a2e3ea62b03ef7c26401a3d26edaf621487" - _get_repo feeds/luci https://github.com/openwrt/luci "7edd635026594da577b73f059c0d8b95d653f8fc" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "c5360894dc9c064bf920c1b7a2cb363d105207d5" + _get_repo feeds/packages https://github.com/openwrt/packages "5bb13435b74c276b676e0561984cb37e4a74ca1d" + _get_repo feeds/luci https://github.com/openwrt/luci "1c92d9f706de9a411c549bac60a9a3ba67533f4e" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From ae651511a753ce5efdc5ded65ef233f5c0bab4ec Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Mon, 3 Aug 2020 16:53:41 +0200 Subject: [PATCH 75/76] Update OpenWrt --- build.sh | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/build.sh b/build.sh index 8d136a91..12cc2927 100755 --- a/build.sh +++ b/build.sh @@ -37,6 +37,8 @@ OMR_REPO=${OMR_REPO:-http://$OMR_HOST:$OMR_PORT/release/$OMR_RELEASE/$OMR_TARGET OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" OMR_FEED_SRC="${OMR_FEED_SRC:-develop}" +CUSTOM_FEED_URL="${CUSTOM_FEED_URL}" + OMR_OPENWRT=${OMR_OPENWRT:-default} if [ ! -f "$OMR_TARGET_CONFIG" ]; then @@ -68,9 +70,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "c5360894dc9c064bf920c1b7a2cb363d105207d5" - _get_repo feeds/packages https://github.com/openwrt/packages "5bb13435b74c276b676e0561984cb37e4a74ca1d" - _get_repo feeds/luci https://github.com/openwrt/luci "1c92d9f706de9a411c549bac60a9a3ba67533f4e" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "18b7d87a8f76b4cf36e943d9211bd26d79f55ec6" + _get_repo feeds/packages https://github.com/openwrt/packages "1c67444c33d85cd74d3a68d1a251626342554f03" + _get_repo feeds/luci https://github.com/openwrt/luci "b2e00f23a7862f47b8bd975207ba8242b55e6cf0" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -86,6 +88,11 @@ if [ -z "$OMR_FEED" ]; then _get_repo "$OMR_FEED" "$OMR_FEED_URL" "$OMR_FEED_SRC" fi +if [ -n "$CUSTOM_FEED_URL" ]; then + CUSTOM_FEED=feeds/${OMR_DIST} + _get_repo "$CUSTOM_FEED" "$CUSTOM_FEED_URL" "master" +fi + if [ -n "$1" ] && [ -f "$OMR_FEED/$1/Makefile" ]; then OMR_DIST=$1 shift 1 @@ -114,6 +121,10 @@ src-link luci $(readlink -f feeds/luci) src-link openmptcprouter $(readlink -f "$OMR_FEED") EOF +if [ -n "$CUSTOM_FEED" ]; then + echo "src-link ${OMR_DIST} $(readlink -f ${CUSTOM_FEED})" >> "$OMR_TARGET/source/feeds.conf" +fi + if [ "$OMR_DIST" = "openmptcprouter" ]; then cat > "$OMR_TARGET/source/package/system/opkg/files/customfeeds.conf" <<-EOF src/gz openwrt_luci http://packages.openmptcprouter.com/${OMR_RELEASE}/${OMR_REAL_TARGET}/luci @@ -294,7 +305,12 @@ if [ "$OMR_ALL_PACKAGES" = "yes" ]; then scripts/feeds install -a -d m -p packages scripts/feeds install -a -d m -p luci fi -scripts/feeds install -a -d y -f -p openmptcprouter +if [ -n "$CUSTOM_FEED" ]; then + scripts/feeds install -a -d m -p openmptcprouter + scripts/feeds install -a -d y -f -p ${OMR_DIST} +else + scripts/feeds install -a -d y -f -p openmptcprouter +fi cp .config.keep .config echo "Done" From d576c7225332337a32237b139180eb702b404c35 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 6 Aug 2020 11:08:56 +0200 Subject: [PATCH 76/76] Use squashfs for BPI-R2 --- config-bpi-r2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-bpi-r2 b/config-bpi-r2 index 08dac613..4022b63d 100644 --- a/config-bpi-r2 +++ b/config-bpi-r2 @@ -2,7 +2,7 @@ CONFIG_TARGET_mediatek=y CONFIG_TARGET_mediatek_mt7623=y CONFIG_TARGET_mediatek_mt7623_DEVICE_bpi_bananapi-r2=y CONFIG_TARGET_ROOTFS_EXT4FS=y -# CONFIG_TARGET_ROOTFS_SQUASHFS is not set +CONFIG_TARGET_ROOTFS_SQUASHFS=y CONFIG_PACKAGE_kmod-cryptodev=y CONFIG_OPENSSL_HARDWARE_SUPPORT=y CONFIG_OPENSSL_ENGINE_CRYPTO=y