From: Felix Fietkau Date: Mon, 13 Feb 2017 10:02:06 +0000 (+0100) Subject: mvebu: remove linux 4.4 support X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=51397d7d95d9f5e210a5557f65de1fa21e6f5921;p=openwrt%2Fstaging%2Fstintel.git mvebu: remove linux 4.4 support Signed-off-by: Felix Fietkau --- diff --git a/target/linux/mvebu/config-4.4 b/target/linux/mvebu/config-4.4 deleted file mode 100644 index d8199707b1..0000000000 --- a/target/linux/mvebu/config-4.4 +++ /dev/null @@ -1,437 +0,0 @@ -CONFIG_AHCI_MVEBU=y -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_SG_CHAIN=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_CPU_AUTO is not set -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_MVEBU=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_REQUIRE_GPIOLIB=y -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -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_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_ARM=y -CONFIG_ARMADA_370_CLK=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_ATAG_DTB_COMPAT=y -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_CRYPTO=y -CONFIG_ARM_ERRATA_720789=y -CONFIG_ARM_GIC=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_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_BOUNCE=y -# CONFIG_CACHE_FEROCEON_L2 is not set -CONFIG_CACHE_L2X0=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLKSRC_OF=y -CONFIG_CLKSRC_PROBE=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_CPUFREQ_DT=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_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_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_THERMAL=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRC16=y -CONFIG_CRYPTO_ABLK_HELPER=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_CRC32C=y -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_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=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_DW_DMAC_PCI is not set -CONFIG_EARLY_PRINTK=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EXT4_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_FS_MBCACHE=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IO=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=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_GPIO_DEVRES=y -CONFIG_GPIO_MVEBU=y -CONFIG_GPIO_MVEBU_PWM=y -CONFIG_GPIO_PCA953X=y -# CONFIG_GPIO_PCA953X_IRQ is not set -CONFIG_GPIO_SYSFS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -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_TRACEHOOK=y -CONFIG_HAVE_ARM_SCU=y -CONFIG_HAVE_ARM_TWD=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_BPF_JIT=y -CONFIG_HAVE_CC_STACKPROTECTOR=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_API_DEBUG=y -CONFIG_HAVE_DMA_ATTRS=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=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_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_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_HZ_FIXED=0 -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MV64XXX=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IOMMU_HELPER=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_DEBUG=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_LIBFDT=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_BOARDINFO=y -CONFIG_MDIO_I2C=y -CONFIG_MEMORY=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGHT_HAVE_PCI=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_PXA3xx=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_MULTI_IRQ_HANDLER=y -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_MVSW61XX_PHY=y -CONFIG_MV_XOR=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NLS=y -CONFIG_NOP_USB_XCEIV=y -CONFIG_NO_BOOTMEM=y -CONFIG_NR_CPUS=4 -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_ADDRESS_PCI=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_MDIO=y -CONFIG_OF_MTD=y -CONFIG_OF_NET=y -CONFIG_OF_PCI=y -CONFIG_OF_PCI_IRQ=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_PAGE_OFFSET=0xC0000000 -CONFIG_PCI=y -# CONFIG_PCI_DOMAINS_GENERIC is not set -CONFIG_PCI_MVEBU=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -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 is not set -# CONFIG_PL310_ERRATA_769419 is not set -CONFIG_PLAT_ORION=y -CONFIG_PM_OPP=y -CONFIG_PWM=y -CONFIG_PWM_SYSFS=y -CONFIG_RATIONAL=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=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_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_SATA_AHCI_PLATFORM=y -CONFIG_SATA_MV=y -CONFIG_SCHED_HRTICK=y -# CONFIG_SCHED_INFO is not set -CONFIG_SCSI=y -CONFIG_SENSORS_PWM_FAN=y -CONFIG_SENSORS_TMP421=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SFP=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SOC_BUS=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_ORION=y -CONFIG_SRAM=y -CONFIG_SRCU=y -CONFIG_SWCONFIG=y -CONFIG_SWIOTLB=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_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_STATS=y -CONFIG_TREE_RCU=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_EHCI_PCI=y -CONFIG_USB_LEDS_TRIGGER_USBPORT=y -CONFIG_USB_PHY=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -# CONFIG_USB_UHCI_HCD is not set -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_MVEBU=y -CONFIG_USB_XHCI_PCI=y -CONFIG_USB_XHCI_PLATFORM=y -CONFIG_USE_OF=y -CONFIG_VECTORS_BASE=0xffff0000 -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 -CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/mvebu/patches-4.4/002-add_powertables.patch b/target/linux/mvebu/patches-4.4/002-add_powertables.patch deleted file mode 100644 index a5a47e4ab2..0000000000 --- a/target/linux/mvebu/patches-4.4/002-add_powertables.patch +++ /dev/null @@ -1,748 +0,0 @@ ---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -@@ -86,12 +86,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>; -+ }; -+ }; - }; - }; - ---- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts -+++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts -@@ -100,6 +100,212 @@ - }; - }; - }; -+ -+ pcie-controller { -+ pcie@1,0 { -+ mwlwifi { -+ marvell,2ghz = <0>; -+ 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>; -+ }; -+ }; -+ }; -+ -+ pcie@2,0 { -+ mwlwifi { -+ marvell,5ghz = <0>; -+ 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>; -+ }; -+ }; -+ }; -+ }; - }; - - gpio-leds { ---- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts -+++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts -@@ -100,6 +100,212 @@ - }; - }; - }; -+ -+ pcie-controller { -+ pcie@1,0 { -+ mwlwifi { -+ marvell,2ghz = <0>; -+ 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>; -+ }; -+ }; -+ }; -+ -+ pcie@2,0 { -+ mwlwifi { -+ marvell,5ghz = <0>; -+ 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>; -+ }; -+ }; -+ }; -+ }; - }; - - gpio-leds { ---- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts -+++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts -@@ -100,6 +100,212 @@ - }; - }; - }; -+ -+ pcie-controller { -+ pcie@1,0 { -+ mwlwifi { -+ marvell,2ghz = <0>; -+ 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>; -+ }; -+ }; -+ }; -+ -+ pcie@2,0 { -+ mwlwifi { -+ marvell,5ghz = <0>; -+ 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>; -+ }; -+ }; -+ }; -+ }; - }; - - gpio-leds { diff --git a/target/linux/mvebu/patches-4.4/003-add_switch_nodes.patch b/target/linux/mvebu/patches-4.4/003-add_switch_nodes.patch deleted file mode 100644 index 1502b6b142..0000000000 --- a/target/linux/mvebu/patches-4.4/003-add_switch_nodes.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -@@ -467,6 +467,16 @@ - }; - }; - }; -+ -+ mvsw61xx { -+ compatible = "marvell,88e6172"; -+ status = "okay"; -+ reg = <0x10>; -+ -+ mii-bus = <&mdio>; -+ cpu-port-0 = <5>; -+ cpu-port-1 = <6>; -+ }; - }; - - &pinctrl { ---- a/arch/arm/boot/dts/armada-385-linksys.dtsi -+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi -@@ -309,6 +309,18 @@ - }; - }; - }; -+ -+ 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>; -+ }; - }; - - &pinctrl { diff --git a/target/linux/mvebu/patches-4.4/010-build_new_dtbs.patch b/target/linux/mvebu/patches-4.4/010-build_new_dtbs.patch deleted file mode 100644 index 6ba9ee6e82..0000000000 --- a/target/linux/mvebu/patches-4.4/010-build_new_dtbs.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -748,6 +748,8 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ - armada-385-db-ap.dtb \ - armada-385-linksys-caiman.dtb \ - armada-385-linksys-cobra.dtb \ -+ armada-385-linksys-rango.dtb \ -+ armada-385-linksys-shelby.dtb \ - armada-388-db.dtb \ - armada-388-gp.dtb \ - armada-388-rd.dtb diff --git a/target/linux/mvebu/patches-4.4/020-mtd-nand-pxa3xx_nand-add-support-for-partial-chunks.patch b/target/linux/mvebu/patches-4.4/020-mtd-nand-pxa3xx_nand-add-support-for-partial-chunks.patch deleted file mode 100644 index 2e6709781f..0000000000 --- a/target/linux/mvebu/patches-4.4/020-mtd-nand-pxa3xx_nand-add-support-for-partial-chunks.patch +++ /dev/null @@ -1,428 +0,0 @@ -From: Thomas Petazzoni -Date: Wed, 10 Feb 2016 14:54:21 +0100 -Subject: [PATCH] mtd: nand: pxa3xx_nand: add support for partial chunks - -This commit is needed to properly support the 8-bits ECC configuration -with 4KB pages. - -When pages larger than 2 KB are used on platforms using the PXA3xx -NAND controller, the reading/programming operations need to be split -in chunks of 2 KBs or less because the controller FIFO is limited to -about 2 KB (i.e a bit more than 2 KB to accommodate OOB data). Due to -this requirement, the data layout on NAND is a bit strange, with ECC -interleaved with data, at the end of each chunk. - -When a 4-bits ECC configuration is used with 4 KB pages, the physical -data layout on the NAND looks like this: - -| 2048 data | 32 spare | 30 ECC | 2048 data | 32 spare | 30 ECC | - -So the data chunks have an equal size, 2080 bytes for each chunk, -which the driver supports properly. - -When a 8-bits ECC configuration is used with 4KB pages, the physical -data layout on the NAND looks like this: - -| 1024 data | 30 ECC | 1024 data | 30 ECC | 1024 data | 30 ECC | 1024 data | 30 ECC | 64 spare | 30 ECC | - -So, the spare area is stored in its own chunk, which has a different -size than the other chunks. Since OOB is not used by UBIFS, the initial -implementation of the driver has chosen to not support reading this -additional "spare" chunk of data. - -Unfortunately, Marvell has chosen to store the BBT signature in the -OOB area. Therefore, if the driver doesn't read this spare area, Linux -has no way of finding the BBT. It thinks there is no BBT, and rewrites -one, which U-Boot does not recognize, causing compatibility problems -between the bootloader and the kernel in terms of NAND usage. - -To fix this, this commit implements the support for reading a partial -last chunk. This support is currently only useful for the case of 8 -bits ECC with 4 KB pages, but it will be useful in the future to -enable other configurations such as 12 bits and 16 bits ECC with 4 KB -pages, or 8 bits ECC with 8 KB pages, etc. All those configurations -have a "last" chunk that doesn't have the same size as the other -chunks. - -In order to implement reading of the last chunk, this commit: - - - Adds a number of new fields to the pxa3xx_nand_info to describe how - many full chunks and how many chunks we have, the size of full - chunks and partial chunks, both in terms of data area and spare - area. - - - Fills in the step_chunk_size and step_spare_size variables to - describe how much data and spare should be read/written for the - current read/program step. - - - Reworks the state machine to accommodate doing the additional read - or program step when a last partial chunk is used. - -This commit has been tested on a Marvell Armada 398 DB board, with a -4KB page NAND, tested in both 4 bits ECC and 8 bits ECC -configurations. Robert Jarzmik has tested on some PXA platforms. - -Signed-off-by: Thomas Petazzoni -Tested-by: Robert Jarzmik -Acked-by: Ezequiel Garcia -Signed-off-by: Brian Norris ---- - ---- a/drivers/mtd/nand/pxa3xx_nand.c -+++ b/drivers/mtd/nand/pxa3xx_nand.c -@@ -228,15 +228,44 @@ struct pxa3xx_nand_info { - int use_spare; /* use spare ? */ - int need_wait; - -- unsigned int data_size; /* data to be read from FIFO */ -- unsigned int chunk_size; /* split commands chunk size */ -- unsigned int oob_size; -+ /* Amount of real data per full chunk */ -+ unsigned int chunk_size; -+ -+ /* Amount of spare data per full chunk */ - unsigned int spare_size; -+ -+ /* Number of full chunks (i.e chunk_size + spare_size) */ -+ unsigned int nfullchunks; -+ -+ /* -+ * Total number of chunks. If equal to nfullchunks, then there -+ * are only full chunks. Otherwise, there is one last chunk of -+ * size (last_chunk_size + last_spare_size) -+ */ -+ unsigned int ntotalchunks; -+ -+ /* Amount of real data in the last chunk */ -+ unsigned int last_chunk_size; -+ -+ /* Amount of spare data in the last chunk */ -+ unsigned int last_spare_size; -+ - unsigned int ecc_size; - unsigned int ecc_err_cnt; - unsigned int max_bitflips; - int retcode; - -+ /* -+ * Variables only valid during command -+ * execution. step_chunk_size and step_spare_size is the -+ * amount of real data and spare data in the current -+ * chunk. cur_chunk is the current chunk being -+ * read/programmed. -+ */ -+ unsigned int step_chunk_size; -+ unsigned int step_spare_size; -+ unsigned int cur_chunk; -+ - /* cached register value */ - uint32_t reg_ndcr; - uint32_t ndtr0cs0; -@@ -531,25 +560,6 @@ static int pxa3xx_nand_init(struct pxa3x - return 0; - } - --/* -- * Set the data and OOB size, depending on the selected -- * spare and ECC configuration. -- * Only applicable to READ0, READOOB and PAGEPROG commands. -- */ --static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info, -- struct mtd_info *mtd) --{ -- int oob_enable = info->reg_ndcr & NDCR_SPARE_EN; -- -- info->data_size = mtd->writesize; -- if (!oob_enable) -- return; -- -- info->oob_size = info->spare_size; -- if (!info->use_ecc) -- info->oob_size += info->ecc_size; --} -- - /** - * NOTE: it is a must to set ND_RUN firstly, then write - * command buffer, otherwise, it does not work. -@@ -665,28 +675,28 @@ static void drain_fifo(struct pxa3xx_nan - - static void handle_data_pio(struct pxa3xx_nand_info *info) - { -- unsigned int do_bytes = min(info->data_size, info->chunk_size); -- - switch (info->state) { - case STATE_PIO_WRITING: -- writesl(info->mmio_base + NDDB, -- info->data_buff + info->data_buff_pos, -- DIV_ROUND_UP(do_bytes, 4)); -+ if (info->step_chunk_size) -+ writesl(info->mmio_base + NDDB, -+ info->data_buff + info->data_buff_pos, -+ DIV_ROUND_UP(info->step_chunk_size, 4)); - -- if (info->oob_size > 0) -+ if (info->step_spare_size) - writesl(info->mmio_base + NDDB, - info->oob_buff + info->oob_buff_pos, -- DIV_ROUND_UP(info->oob_size, 4)); -+ DIV_ROUND_UP(info->step_spare_size, 4)); - break; - case STATE_PIO_READING: -- drain_fifo(info, -- info->data_buff + info->data_buff_pos, -- DIV_ROUND_UP(do_bytes, 4)); -+ if (info->step_chunk_size) -+ drain_fifo(info, -+ info->data_buff + info->data_buff_pos, -+ DIV_ROUND_UP(info->step_chunk_size, 4)); - -- if (info->oob_size > 0) -+ if (info->step_spare_size) - drain_fifo(info, - info->oob_buff + info->oob_buff_pos, -- DIV_ROUND_UP(info->oob_size, 4)); -+ DIV_ROUND_UP(info->step_spare_size, 4)); - break; - default: - dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, -@@ -695,9 +705,8 @@ static void handle_data_pio(struct pxa3x - } - - /* Update buffer pointers for multi-page read/write */ -- info->data_buff_pos += do_bytes; -- info->oob_buff_pos += info->oob_size; -- info->data_size -= do_bytes; -+ info->data_buff_pos += info->step_chunk_size; -+ info->oob_buff_pos += info->step_spare_size; - } - - static void pxa3xx_nand_data_dma_irq(void *data) -@@ -738,8 +747,9 @@ static void start_data_dma(struct pxa3xx - info->state); - BUG(); - } -- info->sg.length = info->data_size + -- (info->oob_size ? info->spare_size + info->ecc_size : 0); -+ info->sg.length = info->chunk_size; -+ if (info->use_spare) -+ info->sg.length += info->spare_size + info->ecc_size; - dma_map_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir); - - tx = dmaengine_prep_slave_sg(info->dma_chan, &info->sg, 1, direction, -@@ -900,9 +910,11 @@ static void prepare_start_command(struct - /* reset data and oob column point to handle data */ - info->buf_start = 0; - info->buf_count = 0; -- info->oob_size = 0; - info->data_buff_pos = 0; - info->oob_buff_pos = 0; -+ info->step_chunk_size = 0; -+ info->step_spare_size = 0; -+ info->cur_chunk = 0; - info->use_ecc = 0; - info->use_spare = 1; - info->retcode = ERR_NONE; -@@ -914,8 +926,6 @@ static void prepare_start_command(struct - case NAND_CMD_READ0: - case NAND_CMD_PAGEPROG: - info->use_ecc = 1; -- case NAND_CMD_READOOB: -- pxa3xx_set_datasize(info, mtd); - break; - case NAND_CMD_PARAM: - info->use_spare = 0; -@@ -974,6 +984,14 @@ static int prepare_set_command(struct px - if (command == NAND_CMD_READOOB) - info->buf_start += mtd->writesize; - -+ if (info->cur_chunk < info->nfullchunks) { -+ info->step_chunk_size = info->chunk_size; -+ info->step_spare_size = info->spare_size; -+ } else { -+ info->step_chunk_size = info->last_chunk_size; -+ info->step_spare_size = info->last_spare_size; -+ } -+ - /* - * Multiple page read needs an 'extended command type' field, - * which is either naked-read or last-read according to the -@@ -985,8 +1003,8 @@ static int prepare_set_command(struct px - info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8) - | NDCB0_LEN_OVRD - | NDCB0_EXT_CMD_TYPE(ext_cmd_type); -- info->ndcb3 = info->chunk_size + -- info->oob_size; -+ info->ndcb3 = info->step_chunk_size + -+ info->step_spare_size; - } - - set_command_address(info, mtd->writesize, column, page_addr); -@@ -1006,8 +1024,6 @@ static int prepare_set_command(struct px - | NDCB0_EXT_CMD_TYPE(ext_cmd_type) - | addr_cycle - | command; -- /* No data transfer in this case */ -- info->data_size = 0; - exec_cmd = 1; - } - break; -@@ -1019,6 +1035,14 @@ static int prepare_set_command(struct px - break; - } - -+ if (info->cur_chunk < info->nfullchunks) { -+ info->step_chunk_size = info->chunk_size; -+ info->step_spare_size = info->spare_size; -+ } else { -+ info->step_chunk_size = info->last_chunk_size; -+ info->step_spare_size = info->last_spare_size; -+ } -+ - /* Second command setting for large pages */ - if (mtd->writesize > PAGE_CHUNK_SIZE) { - /* -@@ -1029,14 +1053,14 @@ static int prepare_set_command(struct px - info->ndcb0 |= NDCB0_CMD_TYPE(0x1) - | NDCB0_LEN_OVRD - | NDCB0_EXT_CMD_TYPE(ext_cmd_type); -- info->ndcb3 = info->chunk_size + -- info->oob_size; -+ info->ndcb3 = info->step_chunk_size + -+ info->step_spare_size; - - /* - * This is the command dispatch that completes a chunked - * page program operation. - */ -- if (info->data_size == 0) { -+ if (info->cur_chunk == info->ntotalchunks) { - info->ndcb0 = NDCB0_CMD_TYPE(0x1) - | NDCB0_EXT_CMD_TYPE(ext_cmd_type) - | command; -@@ -1063,7 +1087,7 @@ static int prepare_set_command(struct px - | command; - info->ndcb1 = (column & 0xFF); - info->ndcb3 = INIT_BUFFER_SIZE; -- info->data_size = INIT_BUFFER_SIZE; -+ info->step_chunk_size = INIT_BUFFER_SIZE; - break; - - case NAND_CMD_READID: -@@ -1073,7 +1097,7 @@ static int prepare_set_command(struct px - | command; - info->ndcb1 = (column & 0xFF); - -- info->data_size = 8; -+ info->step_chunk_size = 8; - break; - case NAND_CMD_STATUS: - info->buf_count = 1; -@@ -1081,7 +1105,7 @@ static int prepare_set_command(struct px - | NDCB0_ADDR_CYC(1) - | command; - -- info->data_size = 8; -+ info->step_chunk_size = 8; - break; - - case NAND_CMD_ERASE1: -@@ -1220,6 +1244,7 @@ static void nand_cmdfunc_extended(struct - init_completion(&info->dev_ready); - do { - info->state = STATE_PREPARED; -+ - exec_cmd = prepare_set_command(info, command, ext_cmd_type, - column, page_addr); - if (!exec_cmd) { -@@ -1239,22 +1264,30 @@ static void nand_cmdfunc_extended(struct - break; - } - -+ /* Only a few commands need several steps */ -+ if (command != NAND_CMD_PAGEPROG && -+ command != NAND_CMD_READ0 && -+ command != NAND_CMD_READOOB) -+ break; -+ -+ info->cur_chunk++; -+ - /* Check if the sequence is complete */ -- if (info->data_size == 0 && command != NAND_CMD_PAGEPROG) -+ if (info->cur_chunk == info->ntotalchunks && command != NAND_CMD_PAGEPROG) - break; - - /* - * After a splitted program command sequence has issued - * the command dispatch, the command sequence is complete. - */ -- if (info->data_size == 0 && -+ if (info->cur_chunk == (info->ntotalchunks + 1) && - command == NAND_CMD_PAGEPROG && - ext_cmd_type == EXT_CMD_TYPE_DISPATCH) - break; - - if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) { - /* Last read: issue a 'last naked read' */ -- if (info->data_size == info->chunk_size) -+ if (info->cur_chunk == info->ntotalchunks - 1) - ext_cmd_type = EXT_CMD_TYPE_LAST_RW; - else - ext_cmd_type = EXT_CMD_TYPE_NAKED_RW; -@@ -1264,7 +1297,7 @@ static void nand_cmdfunc_extended(struct - * the command dispatch must be issued to complete. - */ - } else if (command == NAND_CMD_PAGEPROG && -- info->data_size == 0) { -+ info->cur_chunk == info->ntotalchunks) { - ext_cmd_type = EXT_CMD_TYPE_DISPATCH; - } - } while (1); -@@ -1514,6 +1547,8 @@ static int pxa_ecc_init(struct pxa3xx_na - int strength, int ecc_stepsize, int page_size) - { - if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) { -+ info->nfullchunks = 1; -+ info->ntotalchunks = 1; - info->chunk_size = 2048; - info->spare_size = 40; - info->ecc_size = 24; -@@ -1522,6 +1557,8 @@ static int pxa_ecc_init(struct pxa3xx_na - ecc->strength = 1; - - } else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) { -+ info->nfullchunks = 1; -+ info->ntotalchunks = 1; - info->chunk_size = 512; - info->spare_size = 8; - info->ecc_size = 8; -@@ -1535,6 +1572,8 @@ static int pxa_ecc_init(struct pxa3xx_na - */ - } else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) { - info->ecc_bch = 1; -+ info->nfullchunks = 1; -+ info->ntotalchunks = 1; - info->chunk_size = 2048; - info->spare_size = 32; - info->ecc_size = 32; -@@ -1545,6 +1584,8 @@ static int pxa_ecc_init(struct pxa3xx_na - - } else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) { - info->ecc_bch = 1; -+ info->nfullchunks = 2; -+ info->ntotalchunks = 2; - info->chunk_size = 2048; - info->spare_size = 32; - info->ecc_size = 32; -@@ -1559,8 +1600,12 @@ static int pxa_ecc_init(struct pxa3xx_na - */ - } else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) { - info->ecc_bch = 1; -+ info->nfullchunks = 4; -+ info->ntotalchunks = 5; - info->chunk_size = 1024; - info->spare_size = 0; -+ info->last_chunk_size = 0; -+ info->last_spare_size = 64; - info->ecc_size = 32; - ecc->mode = NAND_ECC_HW; - ecc->size = info->chunk_size; diff --git a/target/linux/mvebu/patches-4.4/021-mtd-pxa3xx_nand-Increase-the-initial-chunk-size.patch b/target/linux/mvebu/patches-4.4/021-mtd-pxa3xx_nand-Increase-the-initial-chunk-size.patch deleted file mode 100644 index 0b0e047c02..0000000000 --- a/target/linux/mvebu/patches-4.4/021-mtd-pxa3xx_nand-Increase-the-initial-chunk-size.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= -Date: Wed, 4 Nov 2015 13:13:41 -0300 -Subject: [PATCH] mtd: pxa3xx_nand: Increase the initial chunk size - -The chunk size represents the size of the data chunks, which -is used by the controllers that allow to split transfered data. - -However, the initial chunk size is used in a non-splitted way, -during device identification. Therefore, it must be large enough -for all the NAND commands issued during device identification. -This includes NAND_CMD_PARAM which was recently changed to -transfer up to 2048 bytes (for the redundant parameter pages). - -Thus, the initial chunk size should be 2048 as well. - -On Armada 370/XP platforms (NFCv2) booted without the keep-config -devicetree property, this commit fixes a timeout on the NAND_CMD_PARAM -command: - - [..] - pxa3xx-nand f10d0000.nand: This platform can't do DMA on this device - pxa3xx-nand f10d0000.nand: Wait time out!!! - nand: device found, Manufacturer ID: 0x2c, Chip ID: 0x38 - nand: Micron MT29F8G08ABABAWP - nand: 1024 MiB, SLC, erase size: 512 KiB, page size: 4096, OOB size: 224 - -Signed-off-by: Ezequiel Garcia -Acked-by: Robert Jarzmik -Signed-off-by: Brian Norris ---- - ---- a/drivers/mtd/nand/pxa3xx_nand.c -+++ b/drivers/mtd/nand/pxa3xx_nand.c -@@ -1637,7 +1637,7 @@ static int pxa3xx_nand_scan(struct mtd_i - goto KEEP_CONFIG; - - /* Set a default chunk size */ -- info->chunk_size = 512; -+ info->chunk_size = PAGE_CHUNK_SIZE; - - ret = pxa3xx_nand_config_flash(info); - if (ret) diff --git a/target/linux/mvebu/patches-4.4/022-mtd-pxa3xx_nand-Fix-initial-controller-configuration.patch b/target/linux/mvebu/patches-4.4/022-mtd-pxa3xx_nand-Fix-initial-controller-configuration.patch deleted file mode 100644 index 7d07fb9423..0000000000 --- a/target/linux/mvebu/patches-4.4/022-mtd-pxa3xx_nand-Fix-initial-controller-configuration.patch +++ /dev/null @@ -1,104 +0,0 @@ -From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= -Date: Wed, 4 Nov 2015 13:13:42 -0300 -Subject: [PATCH] mtd: pxa3xx_nand: Fix initial controller configuration - -The Data Flash Control Register (NDCR) contains two types -of parameters: those that are needed for device identification, -and those that can only be set after device identification. - -Therefore, the driver can't set them all at once and instead -needs to configure the first group before nand_scan_ident() -and the second group later. - -Let's split pxa3xx_nand_config in two halves, and set the -parameters that depend on the device geometry once this is known. - -Signed-off-by: Ezequiel Garcia -Signed-off-by: Brian Norris ---- - ---- a/drivers/mtd/nand/pxa3xx_nand.c -+++ b/drivers/mtd/nand/pxa3xx_nand.c -@@ -1420,34 +1420,43 @@ static int pxa3xx_nand_waitfunc(struct m - return NAND_STATUS_READY; - } - --static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info) -+static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info) - { - struct platform_device *pdev = info->pdev; - struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); -- struct pxa3xx_nand_host *host = info->host[info->cs]; -- struct mtd_info *mtd = host->mtd; -- struct nand_chip *chip = mtd->priv; - -- /* configure default flash values */ -+ /* Configure default flash values */ -+ info->chunk_size = PAGE_CHUNK_SIZE; - info->reg_ndcr = 0x0; /* enable all interrupts */ - info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; - info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES); -- info->reg_ndcr |= NDCR_SPARE_EN; /* enable spare by default */ -+ info->reg_ndcr |= NDCR_SPARE_EN; -+ -+ return 0; -+} -+ -+static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info) -+{ -+ struct pxa3xx_nand_host *host = info->host[info->cs]; -+ struct mtd_info *mtd = host->mtd; -+ struct nand_chip *chip = mtd->priv; -+ - info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; - info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0; - info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0; -- -- return 0; - } - - static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) - { -+ struct platform_device *pdev = info->pdev; -+ struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); - uint32_t ndcr = nand_readl(info, NDCR); - - /* Set an initial chunk size */ - info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; - info->reg_ndcr = ndcr & - ~(NDCR_INT_MASK | NDCR_ND_ARB_EN | NFCV1_NDCR_ARB_CNTL); -+ info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; - info->ndtr0cs0 = nand_readl(info, NDTR0CS0); - info->ndtr1cs0 = nand_readl(info, NDTR1CS0); - return 0; -@@ -1636,10 +1645,7 @@ static int pxa3xx_nand_scan(struct mtd_i - if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) - goto KEEP_CONFIG; - -- /* Set a default chunk size */ -- info->chunk_size = PAGE_CHUNK_SIZE; -- -- ret = pxa3xx_nand_config_flash(info); -+ ret = pxa3xx_nand_config_ident(info); - if (ret) - return ret; - -@@ -1652,7 +1658,6 @@ static int pxa3xx_nand_scan(struct mtd_i - } - - KEEP_CONFIG: -- info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; - if (info->reg_ndcr & NDCR_DWIDTH_M) - chip->options |= NAND_BUSWIDTH_16; - -@@ -1737,6 +1742,10 @@ KEEP_CONFIG: - host->row_addr_cycles = 3; - else - host->row_addr_cycles = 2; -+ -+ if (!pdata->keep_config) -+ pxa3xx_nand_config_tail(info); -+ - return nand_scan_tail(mtd); - } - diff --git a/target/linux/mvebu/patches-4.4/023-bus-mvebu-mbus-provide-api-for-obtaining-IO-and-DRAM.patch b/target/linux/mvebu/patches-4.4/023-bus-mvebu-mbus-provide-api-for-obtaining-IO-and-DRAM.patch deleted file mode 100644 index 58687f36ad..0000000000 --- a/target/linux/mvebu/patches-4.4/023-bus-mvebu-mbus-provide-api-for-obtaining-IO-and-DRAM.patch +++ /dev/null @@ -1,94 +0,0 @@ -From: Marcin Wojtas -Date: Mon, 14 Mar 2016 09:39:02 +0100 -Subject: [PATCH] bus: mvebu-mbus: provide api for obtaining IO and DRAM window - information - -This commit enables finding appropriate mbus window and obtaining its -target id and attribute for given physical address in two separate -routines, both for IO and DRAM windows. This functionality -is needed for Armada XP/38x Network Controller's Buffer Manager and -PnC configuration. - -[gregory.clement@free-electrons.com: Fix size test for -mvebu_mbus_get_dram_win_info] - -Signed-off-by: Marcin Wojtas -[DRAM window information reference in LKv3.10] -Signed-off-by: Evan Wang -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/bus/mvebu-mbus.c -+++ b/drivers/bus/mvebu-mbus.c -@@ -948,6 +948,58 @@ void mvebu_mbus_get_pcie_io_aperture(str - *res = mbus_state.pcie_io_aperture; - } - -+int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr) -+{ -+ const struct mbus_dram_target_info *dram; -+ int i; -+ -+ /* Get dram info */ -+ dram = mv_mbus_dram_info(); -+ if (!dram) { -+ pr_err("missing DRAM information\n"); -+ return -ENODEV; -+ } -+ -+ /* Try to find matching DRAM window for phyaddr */ -+ for (i = 0; i < dram->num_cs; i++) { -+ const struct mbus_dram_window *cs = dram->cs + i; -+ -+ if (cs->base <= phyaddr && -+ phyaddr <= (cs->base + cs->size - 1)) { -+ *target = dram->mbus_dram_target_id; -+ *attr = cs->mbus_attr; -+ return 0; -+ } -+ } -+ -+ pr_err("invalid dram address 0x%x\n", phyaddr); -+ return -EINVAL; -+} -+EXPORT_SYMBOL_GPL(mvebu_mbus_get_dram_win_info); -+ -+int mvebu_mbus_get_io_win_info(phys_addr_t phyaddr, u32 *size, u8 *target, -+ u8 *attr) -+{ -+ int win; -+ -+ for (win = 0; win < mbus_state.soc->num_wins; win++) { -+ u64 wbase; -+ int enabled; -+ -+ mvebu_mbus_read_window(&mbus_state, win, &enabled, &wbase, -+ size, target, attr, NULL); -+ -+ if (!enabled) -+ continue; -+ -+ if (wbase <= phyaddr && phyaddr <= wbase + *size) -+ return win; -+ } -+ -+ return -EINVAL; -+} -+EXPORT_SYMBOL_GPL(mvebu_mbus_get_io_win_info); -+ - static __init int mvebu_mbus_debugfs_init(void) - { - struct mvebu_mbus_state *s = &mbus_state; ---- a/include/linux/mbus.h -+++ b/include/linux/mbus.h -@@ -69,6 +69,9 @@ static inline const struct mbus_dram_tar - int mvebu_mbus_save_cpu_target(u32 *store_addr); - void mvebu_mbus_get_pcie_mem_aperture(struct resource *res); - void mvebu_mbus_get_pcie_io_aperture(struct resource *res); -+int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr); -+int mvebu_mbus_get_io_win_info(phys_addr_t phyaddr, u32 *size, u8 *target, -+ u8 *attr); - int mvebu_mbus_add_window_remap_by_id(unsigned int target, - unsigned int attribute, - phys_addr_t base, size_t size, diff --git a/target/linux/mvebu/patches-4.4/030-mvneta-consolidate-autoneg-enabling.patch b/target/linux/mvebu/patches-4.4/030-mvneta-consolidate-autoneg-enabling.patch deleted file mode 100644 index 1d98c7decc..0000000000 --- a/target/linux/mvebu/patches-4.4/030-mvneta-consolidate-autoneg-enabling.patch +++ /dev/null @@ -1,55 +0,0 @@ -From: Stas Sergeev -Date: Wed, 2 Dec 2015 20:33:56 +0300 -Subject: [PATCH] mvneta: consolidate autoneg enabling - -This moves autoneg-related bit manipulations to the single place. - -CC: Thomas Petazzoni -CC: netdev@vger.kernel.org -CC: linux-kernel@vger.kernel.org - -Signed-off-by: Stas Sergeev -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -1067,15 +1067,28 @@ static void mvneta_defaults_set(struct m - MVNETA_GMAC_AN_SPEED_EN | - MVNETA_GMAC_AN_DUPLEX_EN; - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -+ - val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); - val |= MVNETA_GMAC_1MS_CLOCK_ENABLE; - mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -+ -+ val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -+ val |= MVNETA_GMAC2_INBAND_AN_ENABLE; -+ mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); - } else { - val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); - val &= ~(MVNETA_GMAC_INBAND_AN_ENABLE | - MVNETA_GMAC_AN_SPEED_EN | - MVNETA_GMAC_AN_DUPLEX_EN); - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -+ -+ val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -+ val &= ~MVNETA_GMAC_1MS_CLOCK_ENABLE; -+ mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -+ -+ val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -+ val &= ~MVNETA_GMAC2_INBAND_AN_ENABLE; -+ mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); - } - - mvneta_set_ucast_table(pp, -1); -@@ -3230,9 +3243,6 @@ static int mvneta_port_power_up(struct m - return -EINVAL; - } - -- if (pp->use_inband_status) -- ctrl |= MVNETA_GMAC2_INBAND_AN_ENABLE; -- - /* Cancel Port Reset */ - ctrl &= ~MVNETA_GMAC2_PORT_RESET; - mvreg_write(pp, MVNETA_GMAC_CTRL_2, ctrl); diff --git a/target/linux/mvebu/patches-4.4/031-mvneta-implement-ethtool-autonegotiation-control.patch b/target/linux/mvebu/patches-4.4/031-mvneta-implement-ethtool-autonegotiation-control.patch deleted file mode 100644 index 626b511c45..0000000000 --- a/target/linux/mvebu/patches-4.4/031-mvneta-implement-ethtool-autonegotiation-control.patch +++ /dev/null @@ -1,165 +0,0 @@ -From: Stas Sergeev -Date: Wed, 2 Dec 2015 20:35:11 +0300 -Subject: [PATCH] mvneta: implement ethtool autonegotiation control - -This patch allows to do -ethtool -s eth0 autoneg off -ethtool -s eth0 autoneg on -to disable or enable autonegotiation at run-time. -Without that functionality, the only way to control the autonegotiation -is to modify the device tree. - -This is needed if you plan to use the same kernel with -different ethernet switches, the ones that support the in-band -status and the ones that not. - -CC: Thomas Petazzoni -CC: netdev@vger.kernel.org -CC: linux-kernel@vger.kernel.org - -Signed-off-by: Stas Sergeev -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -371,7 +371,7 @@ struct mvneta_port { - unsigned int duplex; - unsigned int speed; - unsigned int tx_csum_limit; -- int use_inband_status:1; -+ unsigned int use_inband_status:1; - - u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)]; - }; -@@ -973,6 +973,44 @@ static void mvneta_set_other_mcast_table - mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val); - } - -+static void mvneta_set_autoneg(struct mvneta_port *pp, int enable) -+{ -+ u32 val; -+ -+ if (enable) { -+ val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -+ val &= ~(MVNETA_GMAC_FORCE_LINK_PASS | -+ MVNETA_GMAC_FORCE_LINK_DOWN | -+ MVNETA_GMAC_AN_FLOW_CTRL_EN); -+ val |= MVNETA_GMAC_INBAND_AN_ENABLE | -+ MVNETA_GMAC_AN_SPEED_EN | -+ MVNETA_GMAC_AN_DUPLEX_EN; -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -+ -+ val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -+ val |= MVNETA_GMAC_1MS_CLOCK_ENABLE; -+ mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -+ -+ val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -+ val |= MVNETA_GMAC2_INBAND_AN_ENABLE; -+ mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -+ } else { -+ val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -+ val &= ~(MVNETA_GMAC_INBAND_AN_ENABLE | -+ MVNETA_GMAC_AN_SPEED_EN | -+ MVNETA_GMAC_AN_DUPLEX_EN); -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -+ -+ val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -+ val &= ~MVNETA_GMAC_1MS_CLOCK_ENABLE; -+ mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -+ -+ val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -+ val &= ~MVNETA_GMAC2_INBAND_AN_ENABLE; -+ mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -+ } -+} -+ - /* This method sets defaults to the NETA port: - * Clears interrupt Cause and Mask registers. - * Clears all MAC tables. -@@ -1058,39 +1096,7 @@ static void mvneta_defaults_set(struct m - val &= ~MVNETA_PHY_POLLING_ENABLE; - mvreg_write(pp, MVNETA_UNIT_CONTROL, val); - -- if (pp->use_inband_status) { -- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -- val &= ~(MVNETA_GMAC_FORCE_LINK_PASS | -- MVNETA_GMAC_FORCE_LINK_DOWN | -- MVNETA_GMAC_AN_FLOW_CTRL_EN); -- val |= MVNETA_GMAC_INBAND_AN_ENABLE | -- MVNETA_GMAC_AN_SPEED_EN | -- MVNETA_GMAC_AN_DUPLEX_EN; -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -- val |= MVNETA_GMAC_1MS_CLOCK_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -- val |= MVNETA_GMAC2_INBAND_AN_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -- } else { -- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -- val &= ~(MVNETA_GMAC_INBAND_AN_ENABLE | -- MVNETA_GMAC_AN_SPEED_EN | -- MVNETA_GMAC_AN_DUPLEX_EN); -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -- val &= ~MVNETA_GMAC_1MS_CLOCK_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -- val &= ~MVNETA_GMAC2_INBAND_AN_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -- } -- -+ mvneta_set_autoneg(pp, pp->use_inband_status); - mvneta_set_ucast_table(pp, -1); - mvneta_set_special_mcast_table(pp, -1); - mvneta_set_other_mcast_table(pp, -1); -@@ -2956,10 +2962,43 @@ int mvneta_ethtool_get_settings(struct n - int mvneta_ethtool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - struct mvneta_port *pp = netdev_priv(dev); -+ struct phy_device *phydev = pp->phy_dev; - -- if (!pp->phy_dev) -+ if (!phydev) - return -ENODEV; - -+ if ((cmd->autoneg == AUTONEG_ENABLE) != pp->use_inband_status) { -+ u32 val; -+ -+ mvneta_set_autoneg(pp, cmd->autoneg == AUTONEG_ENABLE); -+ -+ if (cmd->autoneg == AUTONEG_DISABLE) { -+ val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -+ val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED | -+ MVNETA_GMAC_CONFIG_GMII_SPEED | -+ MVNETA_GMAC_CONFIG_FULL_DUPLEX); -+ -+ if (phydev->duplex) -+ val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; -+ -+ if (phydev->speed == SPEED_1000) -+ val |= MVNETA_GMAC_CONFIG_GMII_SPEED; -+ else if (phydev->speed == SPEED_100) -+ val |= MVNETA_GMAC_CONFIG_MII_SPEED; -+ -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -+ } -+ -+ pp->use_inband_status = (cmd->autoneg == AUTONEG_ENABLE); -+ netdev_info(pp->dev, "autoneg status set to %i\n", -+ pp->use_inband_status); -+ -+ if (netif_running(dev)) { -+ mvneta_port_down(pp); -+ mvneta_port_up(pp); -+ } -+ } -+ - return phy_ethtool_sset(pp->phy_dev, cmd); - } - diff --git a/target/linux/mvebu/patches-4.4/032-net-mvneta-Make-the-default-queue-related-for-each-p.patch b/target/linux/mvebu/patches-4.4/032-net-mvneta-Make-the-default-queue-related-for-each-p.patch deleted file mode 100644 index 54c93998f6..0000000000 --- a/target/linux/mvebu/patches-4.4/032-net-mvneta-Make-the-default-queue-related-for-each-p.patch +++ /dev/null @@ -1,131 +0,0 @@ -From: Gregory CLEMENT -Date: Wed, 9 Dec 2015 18:23:48 +0100 -Subject: [PATCH] net: mvneta: Make the default queue related for each port - -Instead of using the same default queue for all the port. Move it in the -port struct. It will allow have a different default queue for each port. - -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -356,6 +356,7 @@ struct mvneta_port { - struct mvneta_tx_queue *txqs; - struct net_device *dev; - struct notifier_block cpu_notifier; -+ int rxq_def; - - /* Core clock */ - struct clk *clk; -@@ -819,7 +820,7 @@ static void mvneta_port_up(struct mvneta - mvreg_write(pp, MVNETA_TXQ_CMD, q_map); - - /* Enable all initialized RXQs. */ -- mvreg_write(pp, MVNETA_RXQ_CMD, BIT(rxq_def)); -+ mvreg_write(pp, MVNETA_RXQ_CMD, BIT(pp->rxq_def)); - } - - /* Stop the Ethernet port activity */ -@@ -1067,7 +1068,7 @@ static void mvneta_defaults_set(struct m - mvreg_write(pp, MVNETA_ACC_MODE, val); - - /* Update val of portCfg register accordingly with all RxQueue types */ -- val = MVNETA_PORT_CONFIG_DEFL_VALUE(rxq_def); -+ val = MVNETA_PORT_CONFIG_DEFL_VALUE(pp->rxq_def); - mvreg_write(pp, MVNETA_PORT_CONFIG, val); - - val = 0; -@@ -2101,19 +2102,19 @@ static void mvneta_set_rx_mode(struct ne - if (dev->flags & IFF_PROMISC) { - /* Accept all: Multicast + Unicast */ - mvneta_rx_unicast_promisc_set(pp, 1); -- mvneta_set_ucast_table(pp, rxq_def); -- mvneta_set_special_mcast_table(pp, rxq_def); -- mvneta_set_other_mcast_table(pp, rxq_def); -+ mvneta_set_ucast_table(pp, pp->rxq_def); -+ mvneta_set_special_mcast_table(pp, pp->rxq_def); -+ mvneta_set_other_mcast_table(pp, pp->rxq_def); - } else { - /* Accept single Unicast */ - mvneta_rx_unicast_promisc_set(pp, 0); - mvneta_set_ucast_table(pp, -1); -- mvneta_mac_addr_set(pp, dev->dev_addr, rxq_def); -+ mvneta_mac_addr_set(pp, dev->dev_addr, pp->rxq_def); - - if (dev->flags & IFF_ALLMULTI) { - /* Accept all multicast */ -- mvneta_set_special_mcast_table(pp, rxq_def); -- mvneta_set_other_mcast_table(pp, rxq_def); -+ mvneta_set_special_mcast_table(pp, pp->rxq_def); -+ mvneta_set_other_mcast_table(pp, pp->rxq_def); - } else { - /* Accept only initialized multicast */ - mvneta_set_special_mcast_table(pp, -1); -@@ -2122,7 +2123,7 @@ static void mvneta_set_rx_mode(struct ne - if (!netdev_mc_empty(dev)) { - netdev_for_each_mc_addr(ha, dev) { - mvneta_mcast_addr_set(pp, ha->addr, -- rxq_def); -+ pp->rxq_def); - } - } - } -@@ -2205,7 +2206,7 @@ static int mvneta_poll(struct napi_struc - * RX packets - */ - cause_rx_tx |= port->cause_rx_tx; -- rx_done = mvneta_rx(pp, budget, &pp->rxqs[rxq_def]); -+ rx_done = mvneta_rx(pp, budget, &pp->rxqs[pp->rxq_def]); - budget -= rx_done; - - if (budget > 0) { -@@ -2418,17 +2419,17 @@ static void mvneta_cleanup_txqs(struct m - /* Cleanup all Rx queues */ - static void mvneta_cleanup_rxqs(struct mvneta_port *pp) - { -- mvneta_rxq_deinit(pp, &pp->rxqs[rxq_def]); -+ mvneta_rxq_deinit(pp, &pp->rxqs[pp->rxq_def]); - } - - - /* Init all Rx queues */ - static int mvneta_setup_rxqs(struct mvneta_port *pp) - { -- int err = mvneta_rxq_init(pp, &pp->rxqs[rxq_def]); -+ int err = mvneta_rxq_init(pp, &pp->rxqs[pp->rxq_def]); - if (err) { - netdev_err(pp->dev, "%s: can't create rxq=%d\n", -- __func__, rxq_def); -+ __func__, pp->rxq_def); - mvneta_cleanup_rxqs(pp); - return err; - } -@@ -2634,7 +2635,7 @@ static int mvneta_set_mac_addr(struct ne - mvneta_mac_addr_set(pp, dev->dev_addr, -1); - - /* Set new addr in hw */ -- mvneta_mac_addr_set(pp, sockaddr->sa_data, rxq_def); -+ mvneta_mac_addr_set(pp, sockaddr->sa_data, pp->rxq_def); - - eth_commit_mac_addr_change(dev, addr); - return 0; -@@ -2753,7 +2754,7 @@ static void mvneta_percpu_elect(struct m - { - int online_cpu_idx, cpu, i = 0; - -- online_cpu_idx = rxq_def % num_online_cpus(); -+ online_cpu_idx = pp->rxq_def % num_online_cpus(); - - for_each_online_cpu(cpu) { - if (i == online_cpu_idx) -@@ -3363,6 +3364,8 @@ static int mvneta_probe(struct platform_ - strcmp(managed, "in-band-status") == 0); - pp->cpu_notifier.notifier_call = mvneta_percpu_notifier; - -+ pp->rxq_def = rxq_def; -+ - pp->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(pp->clk)) { - err = PTR_ERR(pp->clk); diff --git a/target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch b/target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch deleted file mode 100644 index 636c6cf364..0000000000 --- a/target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch +++ /dev/null @@ -1,278 +0,0 @@ -From: Gregory CLEMENT -Date: Wed, 9 Dec 2015 18:23:49 +0100 -Subject: [PATCH] net: mvneta: Associate RX queues with each CPU - -We enable the percpu interrupt for all the CPU and we just associate a -CPU to a few queue at the neta level. The mapping between the CPUs and -the queues is static. The queues are associated to the CPU module the -number of CPUs. However currently we only use on RX queue for a given -Ethernet port. - -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -110,9 +110,16 @@ - #define MVNETA_CPU_MAP(cpu) (0x2540 + ((cpu) << 2)) - #define MVNETA_CPU_RXQ_ACCESS_ALL_MASK 0x000000ff - #define MVNETA_CPU_TXQ_ACCESS_ALL_MASK 0x0000ff00 -+#define MVNETA_CPU_RXQ_ACCESS(rxq) BIT(rxq) - #define MVNETA_RXQ_TIME_COAL_REG(q) (0x2580 + ((q) << 2)) - --/* Exception Interrupt Port/Queue Cause register */ -+/* Exception Interrupt Port/Queue Cause register -+ * -+ * Their behavior depend of the mapping done using the PCPX2Q -+ * registers. For a given CPU if the bit associated to a queue is not -+ * set, then for the register a read from this CPU will always return -+ * 0 and a write won't do anything -+ */ - - #define MVNETA_INTR_NEW_CAUSE 0x25a0 - #define MVNETA_INTR_NEW_MASK 0x25a4 -@@ -820,7 +827,13 @@ static void mvneta_port_up(struct mvneta - mvreg_write(pp, MVNETA_TXQ_CMD, q_map); - - /* Enable all initialized RXQs. */ -- mvreg_write(pp, MVNETA_RXQ_CMD, BIT(pp->rxq_def)); -+ for (queue = 0; queue < rxq_number; queue++) { -+ struct mvneta_rx_queue *rxq = &pp->rxqs[queue]; -+ -+ if (rxq->descs != NULL) -+ q_map |= (1 << queue); -+ } -+ mvreg_write(pp, MVNETA_RXQ_CMD, q_map); - } - - /* Stop the Ethernet port activity */ -@@ -1026,6 +1039,7 @@ static void mvneta_defaults_set(struct m - int cpu; - int queue; - u32 val; -+ int max_cpu = num_present_cpus(); - - /* Clear all Cause registers */ - mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0); -@@ -1041,13 +1055,23 @@ static void mvneta_defaults_set(struct m - /* Enable MBUS Retry bit16 */ - mvreg_write(pp, MVNETA_MBUS_RETRY, 0x20); - -- /* Set CPU queue access map - all CPUs have access to all RX -- * queues and to all TX queues -+ /* Set CPU queue access map. CPUs are assigned to the RX -+ * queues modulo their number and all the TX queues are -+ * assigned to the CPU associated to the default RX queue. - */ -- for_each_present_cpu(cpu) -- mvreg_write(pp, MVNETA_CPU_MAP(cpu), -- (MVNETA_CPU_RXQ_ACCESS_ALL_MASK | -- MVNETA_CPU_TXQ_ACCESS_ALL_MASK)); -+ for_each_present_cpu(cpu) { -+ int rxq_map = 0, txq_map = 0; -+ int rxq; -+ -+ for (rxq = 0; rxq < rxq_number; rxq++) -+ if ((rxq % max_cpu) == cpu) -+ rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq); -+ -+ if (cpu == rxq_def) -+ txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; -+ -+ mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map); -+ } - - /* Reset RX and TX DMAs */ - mvreg_write(pp, MVNETA_PORT_RX_RESET, MVNETA_PORT_RX_DMA_RESET); -@@ -2174,6 +2198,7 @@ static int mvneta_poll(struct napi_struc - { - int rx_done = 0; - u32 cause_rx_tx; -+ int rx_queue; - struct mvneta_port *pp = netdev_priv(napi->dev); - struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports); - -@@ -2205,8 +2230,15 @@ static int mvneta_poll(struct napi_struc - /* For the case where the last mvneta_poll did not process all - * RX packets - */ -+ rx_queue = fls(((cause_rx_tx >> 8) & 0xff)); -+ - cause_rx_tx |= port->cause_rx_tx; -- rx_done = mvneta_rx(pp, budget, &pp->rxqs[pp->rxq_def]); -+ -+ if (rx_queue) { -+ rx_queue = rx_queue - 1; -+ rx_done = mvneta_rx(pp, budget, &pp->rxqs[rx_queue]); -+ } -+ - budget -= rx_done; - - if (budget > 0) { -@@ -2419,19 +2451,27 @@ static void mvneta_cleanup_txqs(struct m - /* Cleanup all Rx queues */ - static void mvneta_cleanup_rxqs(struct mvneta_port *pp) - { -- mvneta_rxq_deinit(pp, &pp->rxqs[pp->rxq_def]); -+ int queue; -+ -+ for (queue = 0; queue < txq_number; queue++) -+ mvneta_rxq_deinit(pp, &pp->rxqs[queue]); - } - - - /* Init all Rx queues */ - static int mvneta_setup_rxqs(struct mvneta_port *pp) - { -- int err = mvneta_rxq_init(pp, &pp->rxqs[pp->rxq_def]); -- if (err) { -- netdev_err(pp->dev, "%s: can't create rxq=%d\n", -- __func__, pp->rxq_def); -- mvneta_cleanup_rxqs(pp); -- return err; -+ int queue; -+ -+ for (queue = 0; queue < rxq_number; queue++) { -+ int err = mvneta_rxq_init(pp, &pp->rxqs[queue]); -+ -+ if (err) { -+ netdev_err(pp->dev, "%s: can't create rxq=%d\n", -+ __func__, queue); -+ mvneta_cleanup_rxqs(pp); -+ return err; -+ } - } - - return 0; -@@ -2455,6 +2495,19 @@ static int mvneta_setup_txqs(struct mvne - return 0; - } - -+static void mvneta_percpu_unmask_interrupt(void *arg) -+{ -+ struct mvneta_port *pp = arg; -+ -+ /* All the queue are unmasked, but actually only the ones -+ * maped to this CPU will be unmasked -+ */ -+ mvreg_write(pp, MVNETA_INTR_NEW_MASK, -+ MVNETA_RX_INTR_MASK_ALL | -+ MVNETA_TX_INTR_MASK_ALL | -+ MVNETA_MISCINTR_INTR_MASK); -+} -+ - static void mvneta_start_dev(struct mvneta_port *pp) - { - unsigned int cpu; -@@ -2472,11 +2525,10 @@ static void mvneta_start_dev(struct mvne - napi_enable(&port->napi); - } - -- /* Unmask interrupts */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, -- MVNETA_RX_INTR_MASK(rxq_number) | -- MVNETA_TX_INTR_MASK(txq_number) | -- MVNETA_MISCINTR_INTR_MASK); -+ /* Unmask interrupts. It has to be done from each CPU */ -+ for_each_online_cpu(cpu) -+ smp_call_function_single(cpu, mvneta_percpu_unmask_interrupt, -+ pp, true); - mvreg_write(pp, MVNETA_INTR_MISC_MASK, - MVNETA_CAUSE_PHY_STATUS_CHANGE | - MVNETA_CAUSE_LINK_CHANGE | -@@ -2752,22 +2804,35 @@ static void mvneta_percpu_disable(void * - - static void mvneta_percpu_elect(struct mvneta_port *pp) - { -- int online_cpu_idx, cpu, i = 0; -+ int online_cpu_idx, max_cpu, cpu, i = 0; - - online_cpu_idx = pp->rxq_def % num_online_cpus(); -+ max_cpu = num_present_cpus(); - - for_each_online_cpu(cpu) { -- if (i == online_cpu_idx) -- /* Enable per-CPU interrupt on the one CPU we -- * just elected -+ int rxq_map = 0, txq_map = 0; -+ int rxq; -+ -+ for (rxq = 0; rxq < rxq_number; rxq++) -+ if ((rxq % max_cpu) == cpu) -+ rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq); -+ -+ if (i == online_cpu_idx) { -+ /* Map the default receive queue and transmit -+ * queue to the elected CPU - */ -- smp_call_function_single(cpu, mvneta_percpu_enable, -- pp, true); -- else -- /* Disable per-CPU interrupt on all the other CPU */ -- smp_call_function_single(cpu, mvneta_percpu_disable, -- pp, true); -+ rxq_map |= MVNETA_CPU_RXQ_ACCESS(pp->rxq_def); -+ txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; -+ } -+ mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map); -+ -+ /* Update the interrupt mask on each CPU according the -+ * new mapping -+ */ -+ smp_call_function_single(cpu, mvneta_percpu_unmask_interrupt, -+ pp, true); - i++; -+ - } - }; - -@@ -2802,12 +2867,22 @@ static int mvneta_percpu_notifier(struct - mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0); - napi_enable(&port->napi); - -+ -+ /* Enable per-CPU interrupts on the CPU that is -+ * brought up. -+ */ -+ smp_call_function_single(cpu, mvneta_percpu_enable, -+ pp, true); -+ - /* Enable per-CPU interrupt on the one CPU we care - * about. - */ - mvneta_percpu_elect(pp); - -- /* Unmask all ethernet port interrupts */ -+ /* Unmask all ethernet port interrupts, as this -+ * notifier is called for each CPU then the CPU to -+ * Queue mapping is applied -+ */ - mvreg_write(pp, MVNETA_INTR_NEW_MASK, - MVNETA_RX_INTR_MASK(rxq_number) | - MVNETA_TX_INTR_MASK(txq_number) | -@@ -2858,7 +2933,7 @@ static int mvneta_percpu_notifier(struct - static int mvneta_open(struct net_device *dev) - { - struct mvneta_port *pp = netdev_priv(dev); -- int ret; -+ int ret, cpu; - - pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu); - pp->frag_size = SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(pp->pkt_size)) + -@@ -2888,8 +2963,13 @@ static int mvneta_open(struct net_device - */ - mvneta_percpu_disable(pp); - -- /* Elect a CPU to handle our RX queue interrupt */ -- mvneta_percpu_elect(pp); -+ /* Enable per-CPU interrupt on all the CPU to handle our RX -+ * queue interrupts -+ */ -+ for_each_online_cpu(cpu) -+ smp_call_function_single(cpu, mvneta_percpu_enable, -+ pp, true); -+ - - /* Register a CPU notifier to handle the case where our CPU - * might be taken offline. diff --git a/target/linux/mvebu/patches-4.4/034-net-mvneta-Add-naive-RSS-support.patch b/target/linux/mvebu/patches-4.4/034-net-mvneta-Add-naive-RSS-support.patch deleted file mode 100644 index 629c44c8a1..0000000000 --- a/target/linux/mvebu/patches-4.4/034-net-mvneta-Add-naive-RSS-support.patch +++ /dev/null @@ -1,191 +0,0 @@ -From: Gregory CLEMENT -Date: Wed, 9 Dec 2015 18:23:50 +0100 -Subject: [PATCH] net: mvneta: Add naive RSS support - -This patch adds the support for the RSS related ethtool -function. Currently it only uses one entry in the indirection table which -allows associating an mvneta interface to a given CPU. - -Signed-off-by: Gregory CLEMENT -Tested-by: Marcin Wojtas -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -261,6 +261,11 @@ - - #define MVNETA_TX_MTU_MAX 0x3ffff - -+/* The RSS lookup table actually has 256 entries but we do not use -+ * them yet -+ */ -+#define MVNETA_RSS_LU_TABLE_SIZE 1 -+ - /* TSO header size */ - #define TSO_HEADER_SIZE 128 - -@@ -382,6 +387,8 @@ struct mvneta_port { - unsigned int use_inband_status:1; - - u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)]; -+ -+ u32 indir[MVNETA_RSS_LU_TABLE_SIZE]; - }; - - /* The mvneta_tx_desc and mvneta_rx_desc structures describe the -@@ -1067,7 +1074,7 @@ static void mvneta_defaults_set(struct m - if ((rxq % max_cpu) == cpu) - rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq); - -- if (cpu == rxq_def) -+ if (cpu == pp->rxq_def) - txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; - - mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map); -@@ -2508,6 +2515,18 @@ static void mvneta_percpu_unmask_interru - MVNETA_MISCINTR_INTR_MASK); - } - -+static void mvneta_percpu_mask_interrupt(void *arg) -+{ -+ struct mvneta_port *pp = arg; -+ -+ /* All the queue are masked, but actually only the ones -+ * maped to this CPU will be masked -+ */ -+ mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); -+ mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0); -+ mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0); -+} -+ - static void mvneta_start_dev(struct mvneta_port *pp) - { - unsigned int cpu; -@@ -3231,6 +3250,106 @@ static int mvneta_ethtool_get_sset_count - return -EOPNOTSUPP; - } - -+static u32 mvneta_ethtool_get_rxfh_indir_size(struct net_device *dev) -+{ -+ return MVNETA_RSS_LU_TABLE_SIZE; -+} -+ -+static int mvneta_ethtool_get_rxnfc(struct net_device *dev, -+ struct ethtool_rxnfc *info, -+ u32 *rules __always_unused) -+{ -+ switch (info->cmd) { -+ case ETHTOOL_GRXRINGS: -+ info->data = rxq_number; -+ return 0; -+ case ETHTOOL_GRXFH: -+ return -EOPNOTSUPP; -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int mvneta_config_rss(struct mvneta_port *pp) -+{ -+ int cpu; -+ u32 val; -+ -+ netif_tx_stop_all_queues(pp->dev); -+ -+ for_each_online_cpu(cpu) -+ smp_call_function_single(cpu, mvneta_percpu_mask_interrupt, -+ pp, true); -+ -+ /* We have to synchronise on the napi of each CPU */ -+ for_each_online_cpu(cpu) { -+ struct mvneta_pcpu_port *pcpu_port = -+ per_cpu_ptr(pp->ports, cpu); -+ -+ napi_synchronize(&pcpu_port->napi); -+ napi_disable(&pcpu_port->napi); -+ } -+ -+ pp->rxq_def = pp->indir[0]; -+ -+ /* Update unicast mapping */ -+ mvneta_set_rx_mode(pp->dev); -+ -+ /* Update val of portCfg register accordingly with all RxQueue types */ -+ val = MVNETA_PORT_CONFIG_DEFL_VALUE(pp->rxq_def); -+ mvreg_write(pp, MVNETA_PORT_CONFIG, val); -+ -+ /* Update the elected CPU matching the new rxq_def */ -+ mvneta_percpu_elect(pp); -+ -+ /* We have to synchronise on the napi of each CPU */ -+ for_each_online_cpu(cpu) { -+ struct mvneta_pcpu_port *pcpu_port = -+ per_cpu_ptr(pp->ports, cpu); -+ -+ napi_enable(&pcpu_port->napi); -+ } -+ -+ netif_tx_start_all_queues(pp->dev); -+ -+ return 0; -+} -+ -+static int mvneta_ethtool_set_rxfh(struct net_device *dev, const u32 *indir, -+ const u8 *key, const u8 hfunc) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ /* We require at least one supported parameter to be changed -+ * and no change in any of the unsupported parameters -+ */ -+ if (key || -+ (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)) -+ return -EOPNOTSUPP; -+ -+ if (!indir) -+ return 0; -+ -+ memcpy(pp->indir, indir, MVNETA_RSS_LU_TABLE_SIZE); -+ -+ return mvneta_config_rss(pp); -+} -+ -+static int mvneta_ethtool_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, -+ u8 *hfunc) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ -+ if (hfunc) -+ *hfunc = ETH_RSS_HASH_TOP; -+ -+ if (!indir) -+ return 0; -+ -+ memcpy(indir, pp->indir, MVNETA_RSS_LU_TABLE_SIZE); -+ -+ return 0; -+} -+ - static const struct net_device_ops mvneta_netdev_ops = { - .ndo_open = mvneta_open, - .ndo_stop = mvneta_stop, -@@ -3255,6 +3374,10 @@ const struct ethtool_ops mvneta_eth_tool - .get_strings = mvneta_ethtool_get_strings, - .get_ethtool_stats = mvneta_ethtool_get_stats, - .get_sset_count = mvneta_ethtool_get_sset_count, -+ .get_rxfh_indir_size = mvneta_ethtool_get_rxfh_indir_size, -+ .get_rxnfc = mvneta_ethtool_get_rxnfc, -+ .get_rxfh = mvneta_ethtool_get_rxfh, -+ .set_rxfh = mvneta_ethtool_set_rxfh, - }; - - /* Initialize hw */ -@@ -3446,6 +3569,8 @@ static int mvneta_probe(struct platform_ - - pp->rxq_def = rxq_def; - -+ pp->indir[0] = rxq_def; -+ - pp->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(pp->clk)) { - err = PTR_ERR(pp->clk); diff --git a/target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch b/target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch deleted file mode 100644 index 5b35b6442b..0000000000 --- a/target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch +++ /dev/null @@ -1,124 +0,0 @@ -From: Gregory CLEMENT -Date: Wed, 9 Dec 2015 18:23:51 +0100 -Subject: [PATCH] net: mvneta: Configure XPS support - -With this patch each CPU is associated with its own set of TX queues. - -It also setup the XPS with an initial configuration which set the -affinity matching the hardware configuration. - -Suggested-by: Arnd Bergmann -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -111,6 +111,7 @@ - #define MVNETA_CPU_RXQ_ACCESS_ALL_MASK 0x000000ff - #define MVNETA_CPU_TXQ_ACCESS_ALL_MASK 0x0000ff00 - #define MVNETA_CPU_RXQ_ACCESS(rxq) BIT(rxq) -+#define MVNETA_CPU_TXQ_ACCESS(txq) BIT(txq + 8) - #define MVNETA_RXQ_TIME_COAL_REG(q) (0x2580 + ((q) << 2)) - - /* Exception Interrupt Port/Queue Cause register -@@ -514,6 +515,9 @@ struct mvneta_tx_queue { - - /* DMA address of TSO headers */ - dma_addr_t tso_hdrs_phys; -+ -+ /* Affinity mask for CPUs*/ -+ cpumask_t affinity_mask; - }; - - struct mvneta_rx_queue { -@@ -1062,20 +1066,30 @@ static void mvneta_defaults_set(struct m - /* Enable MBUS Retry bit16 */ - mvreg_write(pp, MVNETA_MBUS_RETRY, 0x20); - -- /* Set CPU queue access map. CPUs are assigned to the RX -- * queues modulo their number and all the TX queues are -- * assigned to the CPU associated to the default RX queue. -+ /* Set CPU queue access map. CPUs are assigned to the RX and -+ * TX queues modulo their number. If there is only one TX -+ * queue then it is assigned to the CPU associated to the -+ * default RX queue. - */ - for_each_present_cpu(cpu) { - int rxq_map = 0, txq_map = 0; -- int rxq; -+ int rxq, txq; - - for (rxq = 0; rxq < rxq_number; rxq++) - if ((rxq % max_cpu) == cpu) - rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq); - -- if (cpu == pp->rxq_def) -- txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; -+ for (txq = 0; txq < txq_number; txq++) -+ if ((txq % max_cpu) == cpu) -+ txq_map |= MVNETA_CPU_TXQ_ACCESS(txq); -+ -+ /* With only one TX queue we configure a special case -+ * which will allow to get all the irq on a single -+ * CPU -+ */ -+ if (txq_number == 1) -+ txq_map = (cpu == pp->rxq_def) ? -+ MVNETA_CPU_TXQ_ACCESS(1) : 0; - - mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map); - } -@@ -2362,6 +2376,8 @@ static void mvneta_rxq_deinit(struct mvn - static int mvneta_txq_init(struct mvneta_port *pp, - struct mvneta_tx_queue *txq) - { -+ int cpu; -+ - txq->size = pp->tx_ring_size; - - /* A queue must always have room for at least one skb. -@@ -2414,6 +2430,14 @@ static int mvneta_txq_init(struct mvneta - } - mvneta_tx_done_pkts_coal_set(pp, txq, txq->done_pkts_coal); - -+ /* Setup XPS mapping */ -+ if (txq_number > 1) -+ cpu = txq->id % num_present_cpus(); -+ else -+ cpu = pp->rxq_def % num_present_cpus(); -+ cpumask_set_cpu(cpu, &txq->affinity_mask); -+ netif_set_xps_queue(pp->dev, &txq->affinity_mask, txq->id); -+ - return 0; - } - -@@ -2836,13 +2860,23 @@ static void mvneta_percpu_elect(struct m - if ((rxq % max_cpu) == cpu) - rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq); - -- if (i == online_cpu_idx) { -- /* Map the default receive queue and transmit -- * queue to the elected CPU -+ if (i == online_cpu_idx) -+ /* Map the default receive queue queue to the -+ * elected CPU - */ - rxq_map |= MVNETA_CPU_RXQ_ACCESS(pp->rxq_def); -- txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; -- } -+ -+ /* We update the TX queue map only if we have one -+ * queue. In this case we associate the TX queue to -+ * the CPU bound to the default RX queue -+ */ -+ if (txq_number == 1) -+ txq_map = (i == online_cpu_idx) ? -+ MVNETA_CPU_TXQ_ACCESS(1) : 0; -+ else -+ txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) & -+ MVNETA_CPU_TXQ_ACCESS_ALL_MASK; -+ - mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map); - - /* Update the interrupt mask on each CPU according the diff --git a/target/linux/mvebu/patches-4.4/036-net-mvneta-fix-trivial-cut-off-issue-in-mvneta_ethto.patch b/target/linux/mvebu/patches-4.4/036-net-mvneta-fix-trivial-cut-off-issue-in-mvneta_ethto.patch deleted file mode 100644 index 2bd7a88032..0000000000 --- a/target/linux/mvebu/patches-4.4/036-net-mvneta-fix-trivial-cut-off-issue-in-mvneta_ethto.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: Jisheng Zhang -Date: Wed, 20 Jan 2016 16:36:25 +0800 -Subject: [PATCH] net: mvneta: fix trivial cut-off issue in - mvneta_ethtool_update_stats - -When s->type is T_REG_64, the high 32bits are lost in val. This patch -fixes this trivial issue. - -Signed-off-by: Jisheng Zhang -Fixes: 9b0cdefa4cd5 ("net: mvneta: add ethtool statistics") -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3242,26 +3242,25 @@ static void mvneta_ethtool_update_stats( - const struct mvneta_statistic *s; - void __iomem *base = pp->base; - u32 high, low, val; -+ u64 val64; - int i; - - for (i = 0, s = mvneta_statistics; - s < mvneta_statistics + ARRAY_SIZE(mvneta_statistics); - s++, i++) { -- val = 0; -- - switch (s->type) { - case T_REG_32: - val = readl_relaxed(base + s->offset); -+ pp->ethtool_stats[i] += val; - break; - case T_REG_64: - /* Docs say to read low 32-bit then high */ - low = readl_relaxed(base + s->offset); - high = readl_relaxed(base + s->offset + 4); -- val = (u64)high << 32 | low; -+ val64 = (u64)high << 32 | low; -+ pp->ethtool_stats[i] += val64; - break; - } -- -- pp->ethtool_stats[i] += val; - } - } - diff --git a/target/linux/mvebu/patches-4.4/037-net-mvneta-Fix-for_each_present_cpu-usage.patch b/target/linux/mvebu/patches-4.4/037-net-mvneta-Fix-for_each_present_cpu-usage.patch deleted file mode 100644 index 9ded5b71fe..0000000000 --- a/target/linux/mvebu/patches-4.4/037-net-mvneta-Fix-for_each_present_cpu-usage.patch +++ /dev/null @@ -1,55 +0,0 @@ -From: Gregory CLEMENT -Date: Thu, 4 Feb 2016 22:09:23 +0100 -Subject: [PATCH] net: mvneta: Fix for_each_present_cpu usage - -This patch convert the for_each_present in on_each_cpu, instead of -applying on the present cpus it will be applied only on the online cpus. -This fix a bug reported on -http://thread.gmane.org/gmane.linux.ports.arm.kernel/468173. - -Using the macro on_each_cpu (instead of a for_each_* loop) also ensures -that all the calls will be done all at once. - -Fixes: f86428854480 ("net: mvneta: Statically assign queues to CPUs") -Reported-by: Stefan Roese -Suggested-by: Jisheng Zhang -Suggested-by: Russell King -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -2562,7 +2562,7 @@ static void mvneta_start_dev(struct mvne - mvneta_port_enable(pp); - - /* Enable polling on the port */ -- for_each_present_cpu(cpu) { -+ for_each_online_cpu(cpu) { - struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu); - - napi_enable(&port->napi); -@@ -2587,7 +2587,7 @@ static void mvneta_stop_dev(struct mvnet - - phy_stop(pp->phy_dev); - -- for_each_present_cpu(cpu) { -+ for_each_online_cpu(cpu) { - struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu); - - napi_disable(&port->napi); -@@ -3055,13 +3055,11 @@ err_cleanup_rxqs: - static int mvneta_stop(struct net_device *dev) - { - struct mvneta_port *pp = netdev_priv(dev); -- int cpu; - - mvneta_stop_dev(pp); - mvneta_mdio_remove(pp); - unregister_cpu_notifier(&pp->cpu_notifier); -- for_each_present_cpu(cpu) -- smp_call_function_single(cpu, mvneta_percpu_disable, pp, true); -+ on_each_cpu(mvneta_percpu_disable, pp, true); - free_percpu_irq(dev->irq, pp->ports); - mvneta_cleanup_rxqs(pp); - mvneta_cleanup_txqs(pp); diff --git a/target/linux/mvebu/patches-4.4/038-net-mvneta-Fix-the-CPU-choice-in-mvneta_percpu_elect.patch b/target/linux/mvebu/patches-4.4/038-net-mvneta-Fix-the-CPU-choice-in-mvneta_percpu_elect.patch deleted file mode 100644 index 4fc9ccc76a..0000000000 --- a/target/linux/mvebu/patches-4.4/038-net-mvneta-Fix-the-CPU-choice-in-mvneta_percpu_elect.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: Gregory CLEMENT -Date: Thu, 4 Feb 2016 22:09:24 +0100 -Subject: [PATCH] net: mvneta: Fix the CPU choice in mvneta_percpu_elect - -When passing to the management of multiple RX queue, the -mvneta_percpu_elect function was broken. The use of the modulo can lead -to elect the wrong cpu. For example with rxq_def=2, if the CPU 2 goes -offline and then online, we ended with the third RX queue activated in -the same time on CPU 0 and CPU2, which lead to a kernel crash. - -With this fix, we don't try to get "the closer" CPU if the default CPU is -gone, now we just use CPU 0 which always be there. Thanks to this, the -code becomes more readable, easier to maintain and more predicable. - -Cc: stable@vger.kernel.org -Fixes: 2dcf75e2793c ("net: mvneta: Associate RX queues with each CPU") -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -2847,9 +2847,14 @@ static void mvneta_percpu_disable(void * - - static void mvneta_percpu_elect(struct mvneta_port *pp) - { -- int online_cpu_idx, max_cpu, cpu, i = 0; -+ int elected_cpu = 0, max_cpu, cpu, i = 0; -+ -+ /* Use the cpu associated to the rxq when it is online, in all -+ * the other cases, use the cpu 0 which can't be offline. -+ */ -+ if (cpu_online(pp->rxq_def)) -+ elected_cpu = pp->rxq_def; - -- online_cpu_idx = pp->rxq_def % num_online_cpus(); - max_cpu = num_present_cpus(); - - for_each_online_cpu(cpu) { -@@ -2860,7 +2865,7 @@ static void mvneta_percpu_elect(struct m - if ((rxq % max_cpu) == cpu) - rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq); - -- if (i == online_cpu_idx) -+ if (cpu == elected_cpu) - /* Map the default receive queue queue to the - * elected CPU - */ -@@ -2871,7 +2876,7 @@ static void mvneta_percpu_elect(struct m - * the CPU bound to the default RX queue - */ - if (txq_number == 1) -- txq_map = (i == online_cpu_idx) ? -+ txq_map = (cpu == elected_cpu) ? - MVNETA_CPU_TXQ_ACCESS(1) : 0; - else - txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) & diff --git a/target/linux/mvebu/patches-4.4/039-net-mvneta-Use-on_each_cpu-when-possible.patch b/target/linux/mvebu/patches-4.4/039-net-mvneta-Use-on_each_cpu-when-possible.patch deleted file mode 100644 index 76257a2a71..0000000000 --- a/target/linux/mvebu/patches-4.4/039-net-mvneta-Use-on_each_cpu-when-possible.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Gregory CLEMENT -Date: Thu, 4 Feb 2016 22:09:25 +0100 -Subject: [PATCH] net: mvneta: Use on_each_cpu when possible - -Instead of using a for_each_* loop in which we just call the -smp_call_function_single macro, it is more simple to directly use the -on_each_cpu macro. Moreover, this macro ensures that the calls will be -done all at once. - -Suggested-by: Russell King -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -2553,7 +2553,7 @@ static void mvneta_percpu_mask_interrupt - - static void mvneta_start_dev(struct mvneta_port *pp) - { -- unsigned int cpu; -+ int cpu; - - mvneta_max_rx_size_set(pp, pp->pkt_size); - mvneta_txq_max_tx_size_set(pp, pp->pkt_size); -@@ -2569,9 +2569,8 @@ static void mvneta_start_dev(struct mvne - } - - /* Unmask interrupts. It has to be done from each CPU */ -- for_each_online_cpu(cpu) -- smp_call_function_single(cpu, mvneta_percpu_unmask_interrupt, -- pp, true); -+ on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true); -+ - mvreg_write(pp, MVNETA_INTR_MISC_MASK, - MVNETA_CAUSE_PHY_STATUS_CHANGE | - MVNETA_CAUSE_LINK_CHANGE | -@@ -2991,7 +2990,7 @@ static int mvneta_percpu_notifier(struct - static int mvneta_open(struct net_device *dev) - { - struct mvneta_port *pp = netdev_priv(dev); -- int ret, cpu; -+ int ret; - - pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu); - pp->frag_size = SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(pp->pkt_size)) + -@@ -3024,9 +3023,7 @@ static int mvneta_open(struct net_device - /* Enable per-CPU interrupt on all the CPU to handle our RX - * queue interrupts - */ -- for_each_online_cpu(cpu) -- smp_call_function_single(cpu, mvneta_percpu_enable, -- pp, true); -+ on_each_cpu(mvneta_percpu_enable, pp, true); - - - /* Register a CPU notifier to handle the case where our CPU -@@ -3313,9 +3310,7 @@ static int mvneta_config_rss(struct mvn - - netif_tx_stop_all_queues(pp->dev); - -- for_each_online_cpu(cpu) -- smp_call_function_single(cpu, mvneta_percpu_mask_interrupt, -- pp, true); -+ on_each_cpu(mvneta_percpu_mask_interrupt, pp, true); - - /* We have to synchronise on the napi of each CPU */ - for_each_online_cpu(cpu) { diff --git a/target/linux/mvebu/patches-4.4/040-net-mvneta-Modify-the-queue-related-fields-from-each.patch b/target/linux/mvebu/patches-4.4/040-net-mvneta-Modify-the-queue-related-fields-from-each.patch deleted file mode 100644 index b025777df9..0000000000 --- a/target/linux/mvebu/patches-4.4/040-net-mvneta-Modify-the-queue-related-fields-from-each.patch +++ /dev/null @@ -1,179 +0,0 @@ -From: Gregory CLEMENT -Date: Thu, 4 Feb 2016 22:09:27 +0100 -Subject: [PATCH] net: mvneta: Modify the queue related fields from each cpu - -In the MVNETA_INTR_* registers, the queues related fields are per cpu, -according to the datasheet (comment in [] are added by me): -"In a multi-CPU system, bits of RX[or TX] queues for which the access by -the reading[or writing] CPU is disabled are read as 0, and cannot be -cleared[or written]." - -That means that each time we want to manipulate these bits we had to do -it on each cpu and not only on the current cpu. - -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -1036,6 +1036,43 @@ static void mvneta_set_autoneg(struct mv - } - } - -+static void mvneta_percpu_unmask_interrupt(void *arg) -+{ -+ struct mvneta_port *pp = arg; -+ -+ /* All the queue are unmasked, but actually only the ones -+ * mapped to this CPU will be unmasked -+ */ -+ mvreg_write(pp, MVNETA_INTR_NEW_MASK, -+ MVNETA_RX_INTR_MASK_ALL | -+ MVNETA_TX_INTR_MASK_ALL | -+ MVNETA_MISCINTR_INTR_MASK); -+} -+ -+static void mvneta_percpu_mask_interrupt(void *arg) -+{ -+ struct mvneta_port *pp = arg; -+ -+ /* All the queue are masked, but actually only the ones -+ * mapped to this CPU will be masked -+ */ -+ mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); -+ mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0); -+ mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0); -+} -+ -+static void mvneta_percpu_clear_intr_cause(void *arg) -+{ -+ struct mvneta_port *pp = arg; -+ -+ /* All the queue are cleared, but actually only the ones -+ * mapped to this CPU will be cleared -+ */ -+ mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0); -+ mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0); -+ mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0); -+} -+ - /* This method sets defaults to the NETA port: - * Clears interrupt Cause and Mask registers. - * Clears all MAC tables. -@@ -1053,14 +1090,10 @@ static void mvneta_defaults_set(struct m - int max_cpu = num_present_cpus(); - - /* Clear all Cause registers */ -- mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0); -- mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0); -- mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0); -+ on_each_cpu(mvneta_percpu_clear_intr_cause, pp, true); - - /* Mask all interrupts */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0); -+ on_each_cpu(mvneta_percpu_mask_interrupt, pp, true); - mvreg_write(pp, MVNETA_INTR_ENABLE, 0); - - /* Enable MBUS Retry bit16 */ -@@ -2526,31 +2559,6 @@ static int mvneta_setup_txqs(struct mvne - return 0; - } - --static void mvneta_percpu_unmask_interrupt(void *arg) --{ -- struct mvneta_port *pp = arg; -- -- /* All the queue are unmasked, but actually only the ones -- * maped to this CPU will be unmasked -- */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, -- MVNETA_RX_INTR_MASK_ALL | -- MVNETA_TX_INTR_MASK_ALL | -- MVNETA_MISCINTR_INTR_MASK); --} -- --static void mvneta_percpu_mask_interrupt(void *arg) --{ -- struct mvneta_port *pp = arg; -- -- /* All the queue are masked, but actually only the ones -- * maped to this CPU will be masked -- */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0); --} -- - static void mvneta_start_dev(struct mvneta_port *pp) - { - int cpu; -@@ -2601,13 +2609,10 @@ static void mvneta_stop_dev(struct mvnet - mvneta_port_disable(pp); - - /* Clear all ethernet port interrupts */ -- mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0); -- mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0); -+ on_each_cpu(mvneta_percpu_clear_intr_cause, pp, true); - - /* Mask all ethernet port interrupts */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0); -+ on_each_cpu(mvneta_percpu_mask_interrupt, pp, true); - - mvneta_tx_reset(pp); - mvneta_rx_reset(pp); -@@ -2919,9 +2924,7 @@ static int mvneta_percpu_notifier(struct - } - - /* Mask all ethernet port interrupts */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0); -+ on_each_cpu(mvneta_percpu_mask_interrupt, pp, true); - napi_enable(&port->napi); - - -@@ -2936,14 +2939,8 @@ static int mvneta_percpu_notifier(struct - */ - mvneta_percpu_elect(pp); - -- /* Unmask all ethernet port interrupts, as this -- * notifier is called for each CPU then the CPU to -- * Queue mapping is applied -- */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, -- MVNETA_RX_INTR_MASK(rxq_number) | -- MVNETA_TX_INTR_MASK(txq_number) | -- MVNETA_MISCINTR_INTR_MASK); -+ /* Unmask all ethernet port interrupts */ -+ on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true); - mvreg_write(pp, MVNETA_INTR_MISC_MASK, - MVNETA_CAUSE_PHY_STATUS_CHANGE | - MVNETA_CAUSE_LINK_CHANGE | -@@ -2954,9 +2951,7 @@ static int mvneta_percpu_notifier(struct - case CPU_DOWN_PREPARE_FROZEN: - netif_tx_stop_all_queues(pp->dev); - /* Mask all ethernet port interrupts */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0); -- mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0); -+ on_each_cpu(mvneta_percpu_mask_interrupt, pp, true); - - napi_synchronize(&port->napi); - napi_disable(&port->napi); -@@ -2972,10 +2967,7 @@ static int mvneta_percpu_notifier(struct - /* Check if a new CPU must be elected now this on is down */ - mvneta_percpu_elect(pp); - /* Unmask all ethernet port interrupts */ -- mvreg_write(pp, MVNETA_INTR_NEW_MASK, -- MVNETA_RX_INTR_MASK(rxq_number) | -- MVNETA_TX_INTR_MASK(txq_number) | -- MVNETA_MISCINTR_INTR_MASK); -+ on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true); - mvreg_write(pp, MVNETA_INTR_MISC_MASK, - MVNETA_CAUSE_PHY_STATUS_CHANGE | - MVNETA_CAUSE_LINK_CHANGE | diff --git a/target/linux/mvebu/patches-4.4/041-net-mvneta-The-mvneta_percpu_elect-function-should-b.patch b/target/linux/mvebu/patches-4.4/041-net-mvneta-The-mvneta_percpu_elect-function-should-b.patch deleted file mode 100644 index a77bef44e4..0000000000 --- a/target/linux/mvebu/patches-4.4/041-net-mvneta-The-mvneta_percpu_elect-function-should-b.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Gregory CLEMENT -Date: Thu, 4 Feb 2016 22:09:28 +0100 -Subject: [PATCH] net: mvneta: The mvneta_percpu_elect function should be - atomic - -Electing a CPU must be done in an atomic way: it should be done after or -before the removal/insertion of a CPU and this function is not reentrant. - -During the loop of mvneta_percpu_elect we associates the queues to the -CPUs, if there is a topology change during this loop, then the mapping -between the CPUs and the queues could be wrong. During this loop the -interrupt mask is also updating for each CPUs, It should not be changed -in the same time by other part of the driver. - -This patch adds spinlock to create the needed critical sections. - -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -370,6 +370,10 @@ struct mvneta_port { - struct net_device *dev; - struct notifier_block cpu_notifier; - int rxq_def; -+ /* Protect the access to the percpu interrupt registers, -+ * ensuring that the configuration remains coherent. -+ */ -+ spinlock_t lock; - - /* Core clock */ - struct clk *clk; -@@ -2853,6 +2857,12 @@ static void mvneta_percpu_elect(struct m - { - int elected_cpu = 0, max_cpu, cpu, i = 0; - -+ /* Electing a CPU must be done in an atomic way: it should be -+ * done after or before the removal/insertion of a CPU and -+ * this function is not reentrant. -+ */ -+ spin_lock(&pp->lock); -+ - /* Use the cpu associated to the rxq when it is online, in all - * the other cases, use the cpu 0 which can't be offline. - */ -@@ -2896,6 +2906,7 @@ static void mvneta_percpu_elect(struct m - i++; - - } -+ spin_unlock(&pp->lock); - }; - - static int mvneta_percpu_notifier(struct notifier_block *nfb, -@@ -2950,8 +2961,13 @@ static int mvneta_percpu_notifier(struct - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - netif_tx_stop_all_queues(pp->dev); -+ /* Thanks to this lock we are sure that any pending -+ * cpu election is done -+ */ -+ spin_lock(&pp->lock); - /* Mask all ethernet port interrupts */ - on_each_cpu(mvneta_percpu_mask_interrupt, pp, true); -+ spin_unlock(&pp->lock); - - napi_synchronize(&port->napi); - napi_disable(&port->napi); diff --git a/target/linux/mvebu/patches-4.4/042-net-mvneta-Fix-race-condition-during-stopping.patch b/target/linux/mvebu/patches-4.4/042-net-mvneta-Fix-race-condition-during-stopping.patch deleted file mode 100644 index 9936ebf320..0000000000 --- a/target/linux/mvebu/patches-4.4/042-net-mvneta-Fix-race-condition-during-stopping.patch +++ /dev/null @@ -1,128 +0,0 @@ -From: Gregory CLEMENT -Date: Thu, 4 Feb 2016 22:09:29 +0100 -Subject: [PATCH] net: mvneta: Fix race condition during stopping - -When stopping the port, the CPU notifier are still there whereas the -mvneta_stop_dev function calls mvneta_percpu_disable() on each CPUs. -It was possible to have a new CPU coming at this point which could be -racy. - -This patch adds a flag preventing executing the code notifier for a new -CPU when the port is stopping. It also uses the spinlock introduces -previously. To avoid the deadlock, the lock has been moved outside the -mvneta_percpu_elect function. - -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -374,6 +374,7 @@ struct mvneta_port { - * ensuring that the configuration remains coherent. - */ - spinlock_t lock; -+ bool is_stopped; - - /* Core clock */ - struct clk *clk; -@@ -2853,16 +2854,14 @@ static void mvneta_percpu_disable(void * - disable_percpu_irq(pp->dev->irq); - } - -+/* Electing a CPU must be done in an atomic way: it should be done -+ * after or before the removal/insertion of a CPU and this function is -+ * not reentrant. -+ */ - static void mvneta_percpu_elect(struct mvneta_port *pp) - { - int elected_cpu = 0, max_cpu, cpu, i = 0; - -- /* Electing a CPU must be done in an atomic way: it should be -- * done after or before the removal/insertion of a CPU and -- * this function is not reentrant. -- */ -- spin_lock(&pp->lock); -- - /* Use the cpu associated to the rxq when it is online, in all - * the other cases, use the cpu 0 which can't be offline. - */ -@@ -2906,7 +2905,6 @@ static void mvneta_percpu_elect(struct m - i++; - - } -- spin_unlock(&pp->lock); - }; - - static int mvneta_percpu_notifier(struct notifier_block *nfb, -@@ -2920,6 +2918,14 @@ static int mvneta_percpu_notifier(struct - switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: -+ spin_lock(&pp->lock); -+ /* Configuring the driver for a new CPU while the -+ * driver is stopping is racy, so just avoid it. -+ */ -+ if (pp->is_stopped) { -+ spin_unlock(&pp->lock); -+ break; -+ } - netif_tx_stop_all_queues(pp->dev); - - /* We have to synchronise on tha napi of each CPU -@@ -2957,6 +2963,7 @@ static int mvneta_percpu_notifier(struct - MVNETA_CAUSE_LINK_CHANGE | - MVNETA_CAUSE_PSC_SYNC_CHANGE); - netif_tx_start_all_queues(pp->dev); -+ spin_unlock(&pp->lock); - break; - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: -@@ -2981,7 +2988,9 @@ static int mvneta_percpu_notifier(struct - case CPU_DEAD: - case CPU_DEAD_FROZEN: - /* Check if a new CPU must be elected now this on is down */ -+ spin_lock(&pp->lock); - mvneta_percpu_elect(pp); -+ spin_unlock(&pp->lock); - /* Unmask all ethernet port interrupts */ - on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true); - mvreg_write(pp, MVNETA_INTR_MISC_MASK, -@@ -3033,7 +3042,7 @@ static int mvneta_open(struct net_device - */ - on_each_cpu(mvneta_percpu_enable, pp, true); - -- -+ pp->is_stopped = false; - /* Register a CPU notifier to handle the case where our CPU - * might be taken offline. - */ -@@ -3066,9 +3075,18 @@ static int mvneta_stop(struct net_device - { - struct mvneta_port *pp = netdev_priv(dev); - -+ /* Inform that we are stopping so we don't want to setup the -+ * driver for new CPUs in the notifiers -+ */ -+ spin_lock(&pp->lock); -+ pp->is_stopped = true; - mvneta_stop_dev(pp); - mvneta_mdio_remove(pp); - unregister_cpu_notifier(&pp->cpu_notifier); -+ /* Now that the notifier are unregistered, we can release le -+ * lock -+ */ -+ spin_unlock(&pp->lock); - on_each_cpu(mvneta_percpu_disable, pp, true); - free_percpu_irq(dev->irq, pp->ports); - mvneta_cleanup_rxqs(pp); -@@ -3339,7 +3357,9 @@ static int mvneta_config_rss(struct mvn - mvreg_write(pp, MVNETA_PORT_CONFIG, val); - - /* Update the elected CPU matching the new rxq_def */ -+ spin_lock(&pp->lock); - mvneta_percpu_elect(pp); -+ spin_unlock(&pp->lock); - - /* We have to synchronise on the napi of each CPU */ - for_each_online_cpu(cpu) { diff --git a/target/linux/mvebu/patches-4.4/043-net-mvneta-sort-the-headers-in-alphabetic-order.patch b/target/linux/mvebu/patches-4.4/043-net-mvneta-sort-the-headers-in-alphabetic-order.patch deleted file mode 100644 index 502c2584d9..0000000000 --- a/target/linux/mvebu/patches-4.4/043-net-mvneta-sort-the-headers-in-alphabetic-order.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Jisheng Zhang -Date: Wed, 20 Jan 2016 19:27:22 +0800 -Subject: [PATCH] net: mvneta: sort the headers in alphabetic order - -Sorting the headers in alphabetic order will help to reduce the conflict -when adding new headers in the future. - -Signed-off-by: Jisheng Zhang -Acked-by: Thomas Petazzoni -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -11,28 +11,28 @@ - * warranty of any kind, whether express or implied. - */ - --#include --#include -+#include -+#include - #include --#include --#include -+#include - #include --#include --#include - #include --#include --#include --#include - #include --#include -+#include -+#include -+#include -+#include - #include -+#include - #include - #include - #include --#include - #include --#include --#include -+#include -+#include -+#include -+#include -+#include - - /* Registers */ - #define MVNETA_RXQ_CONFIG_REG(q) (0x1400 + ((q) << 2)) diff --git a/target/linux/mvebu/patches-4.4/044-net-add-a-hardware-buffer-management-helper-API.patch b/target/linux/mvebu/patches-4.4/044-net-add-a-hardware-buffer-management-helper-API.patch deleted file mode 100644 index d4bc6a0088..0000000000 --- a/target/linux/mvebu/patches-4.4/044-net-add-a-hardware-buffer-management-helper-API.patch +++ /dev/null @@ -1,159 +0,0 @@ -From: Gregory CLEMENT -Date: Mon, 14 Mar 2016 09:39:04 +0100 -Subject: [PATCH] net: add a hardware buffer management helper API - -This basic implementation allows to share code between driver using -hardware buffer management. As the code is hardware agnostic, there is -few helpers, most of the optimization brought by the an HW BM has to be -done at driver level. - -Tested-by: Sebastian Careba -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - create mode 100644 include/net/hwbm.h - create mode 100644 net/core/hwbm.c - ---- /dev/null -+++ b/include/net/hwbm.h -@@ -0,0 +1,28 @@ -+#ifndef _HWBM_H -+#define _HWBM_H -+ -+struct hwbm_pool { -+ /* Capacity of the pool */ -+ int size; -+ /* Size of the buffers managed */ -+ int frag_size; -+ /* Number of buffers currently used by this pool */ -+ int buf_num; -+ /* constructor called during alocation */ -+ int (*construct)(struct hwbm_pool *bm_pool, void *buf); -+ /* protect acces to the buffer counter*/ -+ spinlock_t lock; -+ /* private data */ -+ void *priv; -+}; -+#ifdef CONFIG_HWBM -+void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf); -+int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp); -+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp); -+#else -+void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf) {} -+int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp) { return 0; } -+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp) -+{ return 0; } -+#endif /* CONFIG_HWBM */ -+#endif /* _HWBM_H */ ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -259,6 +259,9 @@ config XPS - depends on SMP - default y - -+config HWBM -+ bool -+ - config CGROUP_NET_PRIO - bool "Network priority cgroup" - depends on CGROUPS ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -14,6 +14,7 @@ obj-y += dev.o ethtool.o dev_addr_ - obj-$(CONFIG_SOCK_DIAG) += sock_diag.o - obj-$(CONFIG_XFRM) += flow.o - obj-y += net-sysfs.o -+obj-$(CONFIG_HWBM) += hwbm.o - obj-$(CONFIG_PROC_FS) += net-procfs.o - obj-$(CONFIG_NET_PKTGEN) += pktgen.o - obj-$(CONFIG_NETPOLL) += netpoll.o ---- /dev/null -+++ b/net/core/hwbm.c -@@ -0,0 +1,87 @@ -+/* Support for hardware buffer manager. -+ * -+ * Copyright (C) 2016 Marvell -+ * -+ * Gregory CLEMENT -+ * -+ * 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 -+ -+void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf) -+{ -+ if (likely(bm_pool->frag_size <= PAGE_SIZE)) -+ skb_free_frag(buf); -+ else -+ kfree(buf); -+} -+EXPORT_SYMBOL_GPL(hwbm_buf_free); -+ -+/* Refill processing for HW buffer management */ -+int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp) -+{ -+ int frag_size = bm_pool->frag_size; -+ void *buf; -+ -+ if (likely(frag_size <= PAGE_SIZE)) -+ buf = netdev_alloc_frag(frag_size); -+ else -+ buf = kmalloc(frag_size, gfp); -+ -+ if (!buf) -+ return -ENOMEM; -+ -+ if (bm_pool->construct) -+ if (bm_pool->construct(bm_pool, buf)) { -+ hwbm_buf_free(bm_pool, buf); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(hwbm_pool_refill); -+ -+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp) -+{ -+ int err, i; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&bm_pool->lock, flags); -+ if (bm_pool->buf_num == bm_pool->size) { -+ pr_warn("pool already filled\n"); -+ return bm_pool->buf_num; -+ } -+ -+ if (buf_num + bm_pool->buf_num > bm_pool->size) { -+ pr_warn("cannot allocate %d buffers for pool\n", -+ buf_num); -+ return 0; -+ } -+ -+ if ((buf_num + bm_pool->buf_num) < bm_pool->buf_num) { -+ pr_warn("Adding %d buffers to the %d current buffers will overflow\n", -+ buf_num, bm_pool->buf_num); -+ return 0; -+ } -+ -+ for (i = 0; i < buf_num; i++) { -+ err = hwbm_pool_refill(bm_pool, gfp); -+ if (err < 0) -+ break; -+ } -+ -+ /* Update BM driver with number of buffers added to pool */ -+ bm_pool->buf_num += i; -+ -+ pr_debug("hwpm pool: %d of %d buffers added\n", i, buf_num); -+ spin_unlock_irqrestore(&bm_pool->lock, flags); -+ -+ return i; -+} -+EXPORT_SYMBOL_GPL(hwbm_pool_add); diff --git a/target/linux/mvebu/patches-4.4/045-net-mvneta-bm-add-support-for-hardware-buffer-manage.patch b/target/linux/mvebu/patches-4.4/045-net-mvneta-bm-add-support-for-hardware-buffer-manage.patch deleted file mode 100644 index d343b3983f..0000000000 --- a/target/linux/mvebu/patches-4.4/045-net-mvneta-bm-add-support-for-hardware-buffer-manage.patch +++ /dev/null @@ -1,1684 +0,0 @@ -From: Marcin Wojtas -Date: Mon, 14 Mar 2016 09:39:03 +0100 -Subject: [PATCH] net: mvneta: bm: add support for hardware buffer management - -Buffer manager (BM) is a dedicated hardware unit that can be used by all -ethernet ports of Armada XP and 38x SoC's. It allows to offload CPU on RX -path by sparing DRAM access on refilling buffer pool, hardware-based -filling of descriptor ring data and better memory utilization due to HW -arbitration for using 'short' pools for small packets. - -Tests performed with A388 SoC working as a network bridge between two -packet generators showed increase of maximum processed 64B packets by -~20k (~555k packets with BM enabled vs ~535 packets without BM). Also -when pushing 1500B-packets with a line rate achieved, CPU load decreased -from around 25% without BM to 20% with BM. - -BM comprise up to 4 buffer pointers' (BP) rings kept in DRAM, which -are called external BP pools - BPPE. Allocating and releasing buffer -pointers (BP) to/from BPPE is performed indirectly by write/read access -to a dedicated internal SRAM, where internal BP pools (BPPI) are placed. -BM hardware controls status of BPPE automatically, as well as assigning -proper buffers to RX descriptors. For more details please refer to -Functional Specification of Armada XP or 38x SoC. - -In order to enable support for a separate hardware block, common for all -ports, a new driver has to be implemented ('mvneta_bm'). It provides -initialization sequence of address space, clocks, registers, SRAM, -empty pools' structures and also obtaining optional configuration -from DT (please refer to device tree binding documentation). mvneta_bm -exposes also a necessary API to mvneta driver, as well as a dedicated -structure with BM information (bm_priv), whose presence is used as a -flag notifying of BM usage by port. It has to be ensured that mvneta_bm -probe is executed prior to the ones in ports' driver. In case BM is not -used or its probe fails, mvneta falls back to use software buffer -management. - -A sequence executed in mvneta_probe function is modified in order to have -an access to needed resources before possible port's BM initialization is -done. According to port-pools mapping provided by DT appropriate registers -are configured and the buffer pools are filled. RX path is modified -accordingly. Becaues the hardware allows a wide variety of configuration -options, following assumptions are made: -* using BM mechanisms can be selectively disabled/enabled basing - on DT configuration among the ports -* 'long' pool's single buffer size is tied to port's MTU -* using 'long' pool by port is obligatory and it cannot be shared -* using 'short' pool for smaller packets is optional -* one 'short' pool can be shared among all ports - -This commit enables hardware buffer management operation cooperating with -existing mvneta driver. New device tree binding documentation is added and -the one of mvneta is updated accordingly. - -[gregory.clement@free-electrons.com: removed the suspend/resume part] - -Signed-off-by: Marcin Wojtas -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - create mode 100644 Documentation/devicetree/bindings/net/marvell-neta-bm.txt - create mode 100644 drivers/net/ethernet/marvell/mvneta_bm.c - create mode 100644 drivers/net/ethernet/marvell/mvneta_bm.h - ---- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt -+++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt -@@ -13,15 +13,30 @@ Optional properties: - Value is presented in bytes. If not used, by default 1600B is set for - "marvell,armada-370-neta" and 9800B for others. - -+Optional properties (valid only for Armada XP/38x): -+ -+- buffer-manager: a phandle to a buffer manager node. Please refer to -+ Documentation/devicetree/bindings/net/marvell-neta-bm.txt -+- bm,pool-long: ID of a pool, that will accept all packets of a size -+ higher than 'short' pool's threshold (if set) and up to MTU value. -+ Obligatory, when the port is supposed to use hardware -+ buffer management. -+- bm,pool-short: ID of a pool, that will be used for accepting -+ packets of a size lower than given threshold. If not set, the port -+ will use a single 'long' pool for all packets, as defined above. -+ - Example: - --ethernet@d0070000 { -+ethernet@70000 { - compatible = "marvell,armada-370-neta"; -- reg = <0xd0070000 0x2500>; -+ reg = <0x70000 0x2500>; - interrupts = <8>; - clocks = <&gate_clk 4>; - tx-csum-limit = <9800> - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <0>; -+ bm,pool-short = <1>; - }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/marvell-neta-bm.txt -@@ -0,0 +1,49 @@ -+* Marvell Armada 380/XP Buffer Manager driver (BM) -+ -+Required properties: -+ -+- compatible: should be "marvell,armada-380-neta-bm". -+- reg: address and length of the register set for the device. -+- clocks: a pointer to the reference clock for this device. -+- internal-mem: a phandle to BM internal SRAM definition. -+ -+Optional properties (port): -+ -+- pool<0 : 3>,capacity: size of external buffer pointers' ring maintained -+ in DRAM. Can be set for each pool (id 0 : 3) separately. The value has -+ to be chosen between 128 and 16352 and it also has to be aligned to 32. -+ Otherwise the driver would adjust a given number or choose default if -+ not set. -+- pool<0 : 3>,pkt-size: maximum size of a packet accepted by a given buffer -+ pointers' pool (id 0 : 3). It will be taken into consideration only when pool -+ type is 'short'. For 'long' ones it would be overridden by port's MTU. -+ If not set a driver will choose a default value. -+ -+In order to see how to hook the BM to a given ethernet port, please -+refer to Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt. -+ -+Example: -+ -+- main node: -+ -+bm: bm@c8000 { -+ compatible = "marvell,armada-380-neta-bm"; -+ reg = <0xc8000 0xac>; -+ clocks = <&gateclk 13>; -+ internal-mem = <&bm_bppi>; -+ status = "okay"; -+ pool2,capacity = <4096>; -+ pool1,pkt-size = <512>; -+}; -+ -+- internal SRAM node: -+ -+bm_bppi: bm-bppi { -+ compatible = "mmio-sram"; -+ reg = ; -+ ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ clocks = <&gateclk 13>; -+ status = "okay"; -+}; ---- a/drivers/net/ethernet/marvell/Kconfig -+++ b/drivers/net/ethernet/marvell/Kconfig -@@ -40,6 +40,19 @@ config MVMDIO - - This driver is used by the MV643XX_ETH and MVNETA drivers. - -+config MVNETA_BM -+ tristate "Marvell Armada 38x/XP network interface BM support" -+ depends on MVNETA -+ ---help--- -+ This driver supports auxiliary block of the network -+ interface units in the Marvell ARMADA XP and ARMADA 38x SoC -+ family, which is called buffer manager. -+ -+ This driver, when enabled, strictly cooperates with mvneta -+ driver and is common for all network ports of the devices, -+ even for Armada 370 SoC, which doesn't support hardware -+ buffer management. -+ - config MVNETA - tristate "Marvell Armada 370/38x/XP network interface support" - depends on PLAT_ORION ---- a/drivers/net/ethernet/marvell/Makefile -+++ b/drivers/net/ethernet/marvell/Makefile -@@ -4,6 +4,7 @@ - - obj-$(CONFIG_MVMDIO) += mvmdio.o - obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o -+obj-$(CONFIG_MVNETA_BM) += mvneta_bm.o - obj-$(CONFIG_MVNETA) += mvneta.o - obj-$(CONFIG_MVPP2) += mvpp2.o - obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include "mvneta_bm.h" - #include - #include - #include -@@ -37,6 +38,10 @@ - /* Registers */ - #define MVNETA_RXQ_CONFIG_REG(q) (0x1400 + ((q) << 2)) - #define MVNETA_RXQ_HW_BUF_ALLOC BIT(0) -+#define MVNETA_RXQ_SHORT_POOL_ID_SHIFT 4 -+#define MVNETA_RXQ_SHORT_POOL_ID_MASK 0x30 -+#define MVNETA_RXQ_LONG_POOL_ID_SHIFT 6 -+#define MVNETA_RXQ_LONG_POOL_ID_MASK 0xc0 - #define MVNETA_RXQ_PKT_OFFSET_ALL_MASK (0xf << 8) - #define MVNETA_RXQ_PKT_OFFSET_MASK(offs) ((offs) << 8) - #define MVNETA_RXQ_THRESHOLD_REG(q) (0x14c0 + ((q) << 2)) -@@ -50,6 +55,9 @@ - #define MVNETA_RXQ_STATUS_UPDATE_REG(q) (0x1500 + ((q) << 2)) - #define MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT 16 - #define MVNETA_RXQ_ADD_NON_OCCUPIED_MAX 255 -+#define MVNETA_PORT_POOL_BUFFER_SZ_REG(pool) (0x1700 + ((pool) << 2)) -+#define MVNETA_PORT_POOL_BUFFER_SZ_SHIFT 3 -+#define MVNETA_PORT_POOL_BUFFER_SZ_MASK 0xfff8 - #define MVNETA_PORT_RX_RESET 0x1cc0 - #define MVNETA_PORT_RX_DMA_RESET BIT(0) - #define MVNETA_PHY_ADDR 0x2000 -@@ -107,6 +115,7 @@ - #define MVNETA_GMAC_CLOCK_DIVIDER 0x24f4 - #define MVNETA_GMAC_1MS_CLOCK_ENABLE BIT(31) - #define MVNETA_ACC_MODE 0x2500 -+#define MVNETA_BM_ADDRESS 0x2504 - #define MVNETA_CPU_MAP(cpu) (0x2540 + ((cpu) << 2)) - #define MVNETA_CPU_RXQ_ACCESS_ALL_MASK 0x000000ff - #define MVNETA_CPU_TXQ_ACCESS_ALL_MASK 0x0000ff00 -@@ -253,7 +262,10 @@ - #define MVNETA_CPU_D_CACHE_LINE_SIZE 32 - #define MVNETA_TX_CSUM_DEF_SIZE 1600 - #define MVNETA_TX_CSUM_MAX_SIZE 9800 --#define MVNETA_ACC_MODE_EXT 1 -+#define MVNETA_ACC_MODE_EXT1 1 -+#define MVNETA_ACC_MODE_EXT2 2 -+ -+#define MVNETA_MAX_DECODE_WIN 6 - - /* Timeout constants */ - #define MVNETA_TX_DISABLE_TIMEOUT_MSEC 1000 -@@ -293,7 +305,8 @@ - ((addr >= txq->tso_hdrs_phys) && \ - (addr < txq->tso_hdrs_phys + txq->size * TSO_HEADER_SIZE)) - --#define MVNETA_RX_BUF_SIZE(pkt_size) ((pkt_size) + NET_SKB_PAD) -+#define MVNETA_RX_GET_BM_POOL_ID(rxd) \ -+ (((rxd)->status & MVNETA_RXD_BM_POOL_MASK) >> MVNETA_RXD_BM_POOL_SHIFT) - - struct mvneta_statistic { - unsigned short offset; -@@ -359,6 +372,7 @@ struct mvneta_pcpu_port { - }; - - struct mvneta_port { -+ u8 id; - struct mvneta_pcpu_port __percpu *ports; - struct mvneta_pcpu_stats __percpu *stats; - -@@ -392,6 +406,11 @@ struct mvneta_port { - unsigned int tx_csum_limit; - unsigned int use_inband_status:1; - -+ struct mvneta_bm *bm_priv; -+ struct mvneta_bm_pool *pool_long; -+ struct mvneta_bm_pool *pool_short; -+ int bm_win_id; -+ - u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)]; - - u32 indir[MVNETA_RSS_LU_TABLE_SIZE]; -@@ -417,6 +436,8 @@ struct mvneta_port { - #define MVNETA_TX_L4_CSUM_NOT BIT(31) - - #define MVNETA_RXD_ERR_CRC 0x0 -+#define MVNETA_RXD_BM_POOL_SHIFT 13 -+#define MVNETA_RXD_BM_POOL_MASK (BIT(13) | BIT(14)) - #define MVNETA_RXD_ERR_SUMMARY BIT(16) - #define MVNETA_RXD_ERR_OVERRUN BIT(17) - #define MVNETA_RXD_ERR_LEN BIT(18) -@@ -561,6 +582,9 @@ static int rxq_def; - - static int rx_copybreak __read_mostly = 256; - -+/* HW BM need that each port be identify by a unique ID */ -+static int global_port_id; -+ - #define MVNETA_DRIVER_NAME "mvneta" - #define MVNETA_DRIVER_VERSION "1.0" - -@@ -827,6 +851,214 @@ static void mvneta_rxq_bm_disable(struct - mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val); - } - -+/* Enable buffer management (BM) */ -+static void mvneta_rxq_bm_enable(struct mvneta_port *pp, -+ struct mvneta_rx_queue *rxq) -+{ -+ u32 val; -+ -+ val = mvreg_read(pp, MVNETA_RXQ_CONFIG_REG(rxq->id)); -+ val |= MVNETA_RXQ_HW_BUF_ALLOC; -+ mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val); -+} -+ -+/* Notify HW about port's assignment of pool for bigger packets */ -+static void mvneta_rxq_long_pool_set(struct mvneta_port *pp, -+ struct mvneta_rx_queue *rxq) -+{ -+ u32 val; -+ -+ val = mvreg_read(pp, MVNETA_RXQ_CONFIG_REG(rxq->id)); -+ val &= ~MVNETA_RXQ_LONG_POOL_ID_MASK; -+ val |= (pp->pool_long->id << MVNETA_RXQ_LONG_POOL_ID_SHIFT); -+ -+ mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val); -+} -+ -+/* Notify HW about port's assignment of pool for smaller packets */ -+static void mvneta_rxq_short_pool_set(struct mvneta_port *pp, -+ struct mvneta_rx_queue *rxq) -+{ -+ u32 val; -+ -+ val = mvreg_read(pp, MVNETA_RXQ_CONFIG_REG(rxq->id)); -+ val &= ~MVNETA_RXQ_SHORT_POOL_ID_MASK; -+ val |= (pp->pool_short->id << MVNETA_RXQ_SHORT_POOL_ID_SHIFT); -+ -+ mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val); -+} -+ -+/* Set port's receive buffer size for assigned BM pool */ -+static inline void mvneta_bm_pool_bufsize_set(struct mvneta_port *pp, -+ int buf_size, -+ u8 pool_id) -+{ -+ u32 val; -+ -+ if (!IS_ALIGNED(buf_size, 8)) { -+ dev_warn(pp->dev->dev.parent, -+ "illegal buf_size value %d, round to %d\n", -+ buf_size, ALIGN(buf_size, 8)); -+ buf_size = ALIGN(buf_size, 8); -+ } -+ -+ val = mvreg_read(pp, MVNETA_PORT_POOL_BUFFER_SZ_REG(pool_id)); -+ val |= buf_size & MVNETA_PORT_POOL_BUFFER_SZ_MASK; -+ mvreg_write(pp, MVNETA_PORT_POOL_BUFFER_SZ_REG(pool_id), val); -+} -+ -+/* Configure MBUS window in order to enable access BM internal SRAM */ -+static int mvneta_mbus_io_win_set(struct mvneta_port *pp, u32 base, u32 wsize, -+ u8 target, u8 attr) -+{ -+ u32 win_enable, win_protect; -+ int i; -+ -+ win_enable = mvreg_read(pp, MVNETA_BASE_ADDR_ENABLE); -+ -+ if (pp->bm_win_id < 0) { -+ /* Find first not occupied window */ -+ for (i = 0; i < MVNETA_MAX_DECODE_WIN; i++) { -+ if (win_enable & (1 << i)) { -+ pp->bm_win_id = i; -+ break; -+ } -+ } -+ if (i == MVNETA_MAX_DECODE_WIN) -+ return -ENOMEM; -+ } else { -+ i = pp->bm_win_id; -+ } -+ -+ mvreg_write(pp, MVNETA_WIN_BASE(i), 0); -+ mvreg_write(pp, MVNETA_WIN_SIZE(i), 0); -+ -+ if (i < 4) -+ mvreg_write(pp, MVNETA_WIN_REMAP(i), 0); -+ -+ mvreg_write(pp, MVNETA_WIN_BASE(i), (base & 0xffff0000) | -+ (attr << 8) | target); -+ -+ mvreg_write(pp, MVNETA_WIN_SIZE(i), (wsize - 1) & 0xffff0000); -+ -+ win_protect = mvreg_read(pp, MVNETA_ACCESS_PROTECT_ENABLE); -+ win_protect |= 3 << (2 * i); -+ mvreg_write(pp, MVNETA_ACCESS_PROTECT_ENABLE, win_protect); -+ -+ win_enable &= ~(1 << i); -+ mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable); -+ -+ return 0; -+} -+ -+/* Assign and initialize pools for port. In case of fail -+ * buffer manager will remain disabled for current port. -+ */ -+static int mvneta_bm_port_init(struct platform_device *pdev, -+ struct mvneta_port *pp) -+{ -+ struct device_node *dn = pdev->dev.of_node; -+ u32 long_pool_id, short_pool_id, wsize; -+ u8 target, attr; -+ int err; -+ -+ /* Get BM window information */ -+ err = mvebu_mbus_get_io_win_info(pp->bm_priv->bppi_phys_addr, &wsize, -+ &target, &attr); -+ if (err < 0) -+ return err; -+ -+ pp->bm_win_id = -1; -+ -+ /* Open NETA -> BM window */ -+ err = mvneta_mbus_io_win_set(pp, pp->bm_priv->bppi_phys_addr, wsize, -+ target, attr); -+ if (err < 0) { -+ netdev_info(pp->dev, "fail to configure mbus window to BM\n"); -+ return err; -+ } -+ -+ if (of_property_read_u32(dn, "bm,pool-long", &long_pool_id)) { -+ netdev_info(pp->dev, "missing long pool id\n"); -+ return -EINVAL; -+ } -+ -+ /* Create port's long pool depending on mtu */ -+ pp->pool_long = mvneta_bm_pool_use(pp->bm_priv, long_pool_id, -+ MVNETA_BM_LONG, pp->id, -+ MVNETA_RX_PKT_SIZE(pp->dev->mtu)); -+ if (!pp->pool_long) { -+ netdev_info(pp->dev, "fail to obtain long pool for port\n"); -+ return -ENOMEM; -+ } -+ -+ pp->pool_long->port_map |= 1 << pp->id; -+ -+ mvneta_bm_pool_bufsize_set(pp, pp->pool_long->buf_size, -+ pp->pool_long->id); -+ -+ /* If short pool id is not defined, assume using single pool */ -+ if (of_property_read_u32(dn, "bm,pool-short", &short_pool_id)) -+ short_pool_id = long_pool_id; -+ -+ /* Create port's short pool */ -+ pp->pool_short = mvneta_bm_pool_use(pp->bm_priv, short_pool_id, -+ MVNETA_BM_SHORT, pp->id, -+ MVNETA_BM_SHORT_PKT_SIZE); -+ if (!pp->pool_short) { -+ netdev_info(pp->dev, "fail to obtain short pool for port\n"); -+ mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id); -+ return -ENOMEM; -+ } -+ -+ if (short_pool_id != long_pool_id) { -+ pp->pool_short->port_map |= 1 << pp->id; -+ mvneta_bm_pool_bufsize_set(pp, pp->pool_short->buf_size, -+ pp->pool_short->id); -+ } -+ -+ return 0; -+} -+ -+/* Update settings of a pool for bigger packets */ -+static void mvneta_bm_update_mtu(struct mvneta_port *pp, int mtu) -+{ -+ struct mvneta_bm_pool *bm_pool = pp->pool_long; -+ int num; -+ -+ /* Release all buffers from long pool */ -+ mvneta_bm_bufs_free(pp->bm_priv, bm_pool, 1 << pp->id); -+ if (bm_pool->buf_num) { -+ WARN(1, "cannot free all buffers in pool %d\n", -+ bm_pool->id); -+ goto bm_mtu_err; -+ } -+ -+ bm_pool->pkt_size = MVNETA_RX_PKT_SIZE(mtu); -+ bm_pool->buf_size = MVNETA_RX_BUF_SIZE(bm_pool->pkt_size); -+ bm_pool->frag_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + -+ SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size)); -+ -+ /* Fill entire long pool */ -+ num = mvneta_bm_bufs_add(pp->bm_priv, bm_pool, bm_pool->size); -+ if (num != bm_pool->size) { -+ WARN(1, "pool %d: %d of %d allocated\n", -+ bm_pool->id, num, bm_pool->size); -+ goto bm_mtu_err; -+ } -+ mvneta_bm_pool_bufsize_set(pp, bm_pool->buf_size, bm_pool->id); -+ -+ return; -+ -+bm_mtu_err: -+ mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id); -+ mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short, 1 << pp->id); -+ -+ pp->bm_priv = NULL; -+ mvreg_write(pp, MVNETA_ACC_MODE, MVNETA_ACC_MODE_EXT1); -+ netdev_info(pp->dev, "fail to update MTU, fall back to software BM\n"); -+} -+ - /* Start the Ethernet port RX and TX activity */ - static void mvneta_port_up(struct mvneta_port *pp) - { -@@ -1147,9 +1379,17 @@ static void mvneta_defaults_set(struct m - mvreg_write(pp, MVNETA_PORT_RX_RESET, 0); - - /* Set Port Acceleration Mode */ -- val = MVNETA_ACC_MODE_EXT; -+ if (pp->bm_priv) -+ /* HW buffer management + legacy parser */ -+ val = MVNETA_ACC_MODE_EXT2; -+ else -+ /* SW buffer management + legacy parser */ -+ val = MVNETA_ACC_MODE_EXT1; - mvreg_write(pp, MVNETA_ACC_MODE, val); - -+ if (pp->bm_priv) -+ mvreg_write(pp, MVNETA_BM_ADDRESS, pp->bm_priv->bppi_phys_addr); -+ - /* Update val of portCfg register accordingly with all RxQueue types */ - val = MVNETA_PORT_CONFIG_DEFL_VALUE(pp->rxq_def); - mvreg_write(pp, MVNETA_PORT_CONFIG, val); -@@ -1516,23 +1756,25 @@ static void mvneta_txq_done(struct mvnet - } - } - --static void *mvneta_frag_alloc(const struct mvneta_port *pp) -+void *mvneta_frag_alloc(unsigned int frag_size) - { -- if (likely(pp->frag_size <= PAGE_SIZE)) -- return netdev_alloc_frag(pp->frag_size); -+ if (likely(frag_size <= PAGE_SIZE)) -+ return netdev_alloc_frag(frag_size); - else -- return kmalloc(pp->frag_size, GFP_ATOMIC); -+ return kmalloc(frag_size, GFP_ATOMIC); - } -+EXPORT_SYMBOL_GPL(mvneta_frag_alloc); - --static void mvneta_frag_free(const struct mvneta_port *pp, void *data) -+void mvneta_frag_free(unsigned int frag_size, void *data) - { -- if (likely(pp->frag_size <= PAGE_SIZE)) -+ if (likely(frag_size <= PAGE_SIZE)) - skb_free_frag(data); - else - kfree(data); - } -+EXPORT_SYMBOL_GPL(mvneta_frag_free); - --/* Refill processing */ -+/* Refill processing for SW buffer management */ - static int mvneta_rx_refill(struct mvneta_port *pp, - struct mvneta_rx_desc *rx_desc) - -@@ -1540,7 +1782,7 @@ static int mvneta_rx_refill(struct mvnet - dma_addr_t phys_addr; - void *data; - -- data = mvneta_frag_alloc(pp); -+ data = mvneta_frag_alloc(pp->frag_size); - if (!data) - return -ENOMEM; - -@@ -1548,7 +1790,7 @@ static int mvneta_rx_refill(struct mvnet - MVNETA_RX_BUF_SIZE(pp->pkt_size), - DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(pp->dev->dev.parent, phys_addr))) { -- mvneta_frag_free(pp, data); -+ mvneta_frag_free(pp->frag_size, data); - return -ENOMEM; - } - -@@ -1594,22 +1836,156 @@ static void mvneta_rxq_drop_pkts(struct - int rx_done, i; - - rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq); -+ if (rx_done) -+ mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done); -+ -+ if (pp->bm_priv) { -+ for (i = 0; i < rx_done; i++) { -+ struct mvneta_rx_desc *rx_desc = -+ mvneta_rxq_next_desc_get(rxq); -+ u8 pool_id = MVNETA_RX_GET_BM_POOL_ID(rx_desc); -+ struct mvneta_bm_pool *bm_pool; -+ -+ bm_pool = &pp->bm_priv->bm_pools[pool_id]; -+ /* Return dropped buffer to the pool */ -+ mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool, -+ rx_desc->buf_phys_addr); -+ } -+ return; -+ } -+ - for (i = 0; i < rxq->size; i++) { - struct mvneta_rx_desc *rx_desc = rxq->descs + i; - void *data = (void *)rx_desc->buf_cookie; - - dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr, - MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); -- mvneta_frag_free(pp, data); -+ mvneta_frag_free(pp->frag_size, data); - } -+} - -- if (rx_done) -- mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done); -+/* Main rx processing when using software buffer management */ -+static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo, -+ struct mvneta_rx_queue *rxq) -+{ -+ struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports); -+ struct net_device *dev = pp->dev; -+ int rx_done; -+ u32 rcvd_pkts = 0; -+ u32 rcvd_bytes = 0; -+ -+ /* Get number of received packets */ -+ rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq); -+ -+ if (rx_todo > rx_done) -+ rx_todo = rx_done; -+ -+ rx_done = 0; -+ -+ /* Fairness NAPI loop */ -+ while (rx_done < rx_todo) { -+ struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq); -+ struct sk_buff *skb; -+ unsigned char *data; -+ dma_addr_t phys_addr; -+ u32 rx_status, frag_size; -+ int rx_bytes, err; -+ -+ rx_done++; -+ rx_status = rx_desc->status; -+ rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE); -+ data = (unsigned char *)rx_desc->buf_cookie; -+ phys_addr = rx_desc->buf_phys_addr; -+ -+ if (!mvneta_rxq_desc_is_first_last(rx_status) || -+ (rx_status & MVNETA_RXD_ERR_SUMMARY)) { -+err_drop_frame: -+ dev->stats.rx_errors++; -+ mvneta_rx_error(pp, rx_desc); -+ /* leave the descriptor untouched */ -+ continue; -+ } -+ -+ if (rx_bytes <= rx_copybreak) { -+ /* better copy a small frame and not unmap the DMA region */ -+ skb = netdev_alloc_skb_ip_align(dev, rx_bytes); -+ if (unlikely(!skb)) -+ goto err_drop_frame; -+ -+ dma_sync_single_range_for_cpu(dev->dev.parent, -+ rx_desc->buf_phys_addr, -+ MVNETA_MH_SIZE + NET_SKB_PAD, -+ rx_bytes, -+ DMA_FROM_DEVICE); -+ memcpy(skb_put(skb, rx_bytes), -+ data + MVNETA_MH_SIZE + NET_SKB_PAD, -+ rx_bytes); -+ -+ skb->protocol = eth_type_trans(skb, dev); -+ mvneta_rx_csum(pp, rx_status, skb); -+ napi_gro_receive(&port->napi, skb); -+ -+ rcvd_pkts++; -+ rcvd_bytes += rx_bytes; -+ -+ /* leave the descriptor and buffer untouched */ -+ continue; -+ } -+ -+ /* Refill processing */ -+ err = mvneta_rx_refill(pp, rx_desc); -+ if (err) { -+ netdev_err(dev, "Linux processing - Can't refill\n"); -+ rxq->missed++; -+ goto err_drop_frame; -+ } -+ -+ frag_size = pp->frag_size; -+ -+ skb = build_skb(data, frag_size > PAGE_SIZE ? 0 : frag_size); -+ -+ /* After refill old buffer has to be unmapped regardless -+ * the skb is successfully built or not. -+ */ -+ dma_unmap_single(dev->dev.parent, phys_addr, -+ MVNETA_RX_BUF_SIZE(pp->pkt_size), -+ DMA_FROM_DEVICE); -+ -+ if (!skb) -+ goto err_drop_frame; -+ -+ rcvd_pkts++; -+ rcvd_bytes += rx_bytes; -+ -+ /* Linux processing */ -+ skb_reserve(skb, MVNETA_MH_SIZE + NET_SKB_PAD); -+ skb_put(skb, rx_bytes); -+ -+ skb->protocol = eth_type_trans(skb, dev); -+ -+ mvneta_rx_csum(pp, rx_status, skb); -+ -+ napi_gro_receive(&port->napi, skb); -+ } -+ -+ if (rcvd_pkts) { -+ struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats); -+ -+ u64_stats_update_begin(&stats->syncp); -+ stats->rx_packets += rcvd_pkts; -+ stats->rx_bytes += rcvd_bytes; -+ u64_stats_update_end(&stats->syncp); -+ } -+ -+ /* Update rxq management counters */ -+ mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done); -+ -+ return rx_done; - } - --/* Main rx processing */ --static int mvneta_rx(struct mvneta_port *pp, int rx_todo, -- struct mvneta_rx_queue *rxq) -+/* Main rx processing when using hardware buffer management */ -+static int mvneta_rx_hwbm(struct mvneta_port *pp, int rx_todo, -+ struct mvneta_rx_queue *rxq) - { - struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports); - struct net_device *dev = pp->dev; -@@ -1628,21 +2004,29 @@ static int mvneta_rx(struct mvneta_port - /* Fairness NAPI loop */ - while (rx_done < rx_todo) { - struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq); -+ struct mvneta_bm_pool *bm_pool = NULL; - struct sk_buff *skb; - unsigned char *data; - dma_addr_t phys_addr; -- u32 rx_status; -+ u32 rx_status, frag_size; - int rx_bytes, err; -+ u8 pool_id; - - rx_done++; - rx_status = rx_desc->status; - rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE); - data = (unsigned char *)rx_desc->buf_cookie; - phys_addr = rx_desc->buf_phys_addr; -+ pool_id = MVNETA_RX_GET_BM_POOL_ID(rx_desc); -+ bm_pool = &pp->bm_priv->bm_pools[pool_id]; - - if (!mvneta_rxq_desc_is_first_last(rx_status) || - (rx_status & MVNETA_RXD_ERR_SUMMARY)) { -- err_drop_frame: -+err_drop_frame_ret_pool: -+ /* Return the buffer to the pool */ -+ mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool, -+ rx_desc->buf_phys_addr); -+err_drop_frame: - dev->stats.rx_errors++; - mvneta_rx_error(pp, rx_desc); - /* leave the descriptor untouched */ -@@ -1653,7 +2037,7 @@ static int mvneta_rx(struct mvneta_port - /* better copy a small frame and not unmap the DMA region */ - skb = netdev_alloc_skb_ip_align(dev, rx_bytes); - if (unlikely(!skb)) -- goto err_drop_frame; -+ goto err_drop_frame_ret_pool; - - dma_sync_single_range_for_cpu(dev->dev.parent, - rx_desc->buf_phys_addr, -@@ -1671,26 +2055,31 @@ static int mvneta_rx(struct mvneta_port - rcvd_pkts++; - rcvd_bytes += rx_bytes; - -+ /* Return the buffer to the pool */ -+ mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool, -+ rx_desc->buf_phys_addr); -+ - /* leave the descriptor and buffer untouched */ - continue; - } - - /* Refill processing */ -- err = mvneta_rx_refill(pp, rx_desc); -+ err = mvneta_bm_pool_refill(pp->bm_priv, bm_pool); - if (err) { - netdev_err(dev, "Linux processing - Can't refill\n"); - rxq->missed++; -- goto err_drop_frame; -+ goto err_drop_frame_ret_pool; - } - -- skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size); -+ frag_size = bm_pool->frag_size; -+ -+ skb = build_skb(data, frag_size > PAGE_SIZE ? 0 : frag_size); - - /* After refill old buffer has to be unmapped regardless - * the skb is successfully built or not. - */ -- dma_unmap_single(dev->dev.parent, phys_addr, -- MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); -- -+ dma_unmap_single(&pp->bm_priv->pdev->dev, phys_addr, -+ bm_pool->buf_size, DMA_FROM_DEVICE); - if (!skb) - goto err_drop_frame; - -@@ -2295,7 +2684,10 @@ static int mvneta_poll(struct napi_struc - - if (rx_queue) { - rx_queue = rx_queue - 1; -- rx_done = mvneta_rx(pp, budget, &pp->rxqs[rx_queue]); -+ if (pp->bm_priv) -+ rx_done = mvneta_rx_hwbm(pp, budget, &pp->rxqs[rx_queue]); -+ else -+ rx_done = mvneta_rx_swbm(pp, budget, &pp->rxqs[rx_queue]); - } - - budget -= rx_done; -@@ -2384,9 +2776,17 @@ static int mvneta_rxq_init(struct mvneta - mvneta_rx_pkts_coal_set(pp, rxq, rxq->pkts_coal); - mvneta_rx_time_coal_set(pp, rxq, rxq->time_coal); - -- /* Fill RXQ with buffers from RX pool */ -- mvneta_rxq_buf_size_set(pp, rxq, MVNETA_RX_BUF_SIZE(pp->pkt_size)); -- mvneta_rxq_bm_disable(pp, rxq); -+ if (!pp->bm_priv) { -+ /* Fill RXQ with buffers from RX pool */ -+ mvneta_rxq_buf_size_set(pp, rxq, -+ MVNETA_RX_BUF_SIZE(pp->pkt_size)); -+ mvneta_rxq_bm_disable(pp, rxq); -+ } else { -+ mvneta_rxq_bm_enable(pp, rxq); -+ mvneta_rxq_long_pool_set(pp, rxq); -+ mvneta_rxq_short_pool_set(pp, rxq); -+ } -+ - mvneta_rxq_fill(pp, rxq, rxq->size); - - return 0; -@@ -2659,6 +3059,9 @@ static int mvneta_change_mtu(struct net_ - dev->mtu = mtu; - - if (!netif_running(dev)) { -+ if (pp->bm_priv) -+ mvneta_bm_update_mtu(pp, mtu); -+ - netdev_update_features(dev); - return 0; - } -@@ -2671,6 +3074,9 @@ static int mvneta_change_mtu(struct net_ - mvneta_cleanup_txqs(pp); - mvneta_cleanup_rxqs(pp); - -+ if (pp->bm_priv) -+ mvneta_bm_update_mtu(pp, mtu); -+ - pp->pkt_size = MVNETA_RX_PKT_SIZE(dev->mtu); - pp->frag_size = SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(pp->pkt_size)) + - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -@@ -3563,6 +3969,7 @@ static int mvneta_probe(struct platform_ - struct resource *res; - struct device_node *dn = pdev->dev.of_node; - struct device_node *phy_node; -+ struct device_node *bm_node; - struct mvneta_port *pp; - struct net_device *dev; - const char *dt_mac_addr; -@@ -3690,26 +4097,39 @@ static int mvneta_probe(struct platform_ - - pp->tx_csum_limit = tx_csum_limit; - -+ dram_target_info = mv_mbus_dram_info(); -+ if (dram_target_info) -+ mvneta_conf_mbus_windows(pp, dram_target_info); -+ - pp->tx_ring_size = MVNETA_MAX_TXD; - pp->rx_ring_size = MVNETA_MAX_RXD; - - pp->dev = dev; - SET_NETDEV_DEV(dev, &pdev->dev); - -+ pp->id = global_port_id++; -+ -+ /* Obtain access to BM resources if enabled and already initialized */ -+ bm_node = of_parse_phandle(dn, "buffer-manager", 0); -+ if (bm_node && bm_node->data) { -+ pp->bm_priv = bm_node->data; -+ err = mvneta_bm_port_init(pdev, pp); -+ if (err < 0) { -+ dev_info(&pdev->dev, "use SW buffer management\n"); -+ pp->bm_priv = NULL; -+ } -+ } -+ - err = mvneta_init(&pdev->dev, pp); - if (err < 0) -- goto err_free_stats; -+ goto err_netdev; - - err = mvneta_port_power_up(pp, phy_mode); - if (err < 0) { - dev_err(&pdev->dev, "can't power up port\n"); -- goto err_free_stats; -+ goto err_netdev; - } - -- dram_target_info = mv_mbus_dram_info(); -- if (dram_target_info) -- mvneta_conf_mbus_windows(pp, dram_target_info); -- - for_each_present_cpu(cpu) { - struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu); - -@@ -3744,6 +4164,13 @@ static int mvneta_probe(struct platform_ - - return 0; - -+err_netdev: -+ unregister_netdev(dev); -+ if (pp->bm_priv) { -+ mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id); -+ mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short, -+ 1 << pp->id); -+ } - err_free_stats: - free_percpu(pp->stats); - err_free_ports: -@@ -3773,6 +4200,12 @@ static int mvneta_remove(struct platform - of_node_put(pp->phy_node); - free_netdev(dev); - -+ if (pp->bm_priv) { -+ mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id); -+ mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short, -+ 1 << pp->id); -+ } -+ - return 0; - } - ---- /dev/null -+++ b/drivers/net/ethernet/marvell/mvneta_bm.c -@@ -0,0 +1,546 @@ -+/* -+ * Driver for Marvell NETA network controller Buffer Manager. -+ * -+ * Copyright (C) 2015 Marvell -+ * -+ * Marcin Wojtas -+ * -+ * 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "mvneta_bm.h" -+ -+#define MVNETA_BM_DRIVER_NAME "mvneta_bm" -+#define MVNETA_BM_DRIVER_VERSION "1.0" -+ -+static void mvneta_bm_write(struct mvneta_bm *priv, u32 offset, u32 data) -+{ -+ writel(data, priv->reg_base + offset); -+} -+ -+static u32 mvneta_bm_read(struct mvneta_bm *priv, u32 offset) -+{ -+ return readl(priv->reg_base + offset); -+} -+ -+static void mvneta_bm_pool_enable(struct mvneta_bm *priv, int pool_id) -+{ -+ u32 val; -+ -+ val = mvneta_bm_read(priv, MVNETA_BM_POOL_BASE_REG(pool_id)); -+ val |= MVNETA_BM_POOL_ENABLE_MASK; -+ mvneta_bm_write(priv, MVNETA_BM_POOL_BASE_REG(pool_id), val); -+ -+ /* Clear BM cause register */ -+ mvneta_bm_write(priv, MVNETA_BM_INTR_CAUSE_REG, 0); -+} -+ -+static void mvneta_bm_pool_disable(struct mvneta_bm *priv, int pool_id) -+{ -+ u32 val; -+ -+ val = mvneta_bm_read(priv, MVNETA_BM_POOL_BASE_REG(pool_id)); -+ val &= ~MVNETA_BM_POOL_ENABLE_MASK; -+ mvneta_bm_write(priv, MVNETA_BM_POOL_BASE_REG(pool_id), val); -+} -+ -+static inline void mvneta_bm_config_set(struct mvneta_bm *priv, u32 mask) -+{ -+ u32 val; -+ -+ val = mvneta_bm_read(priv, MVNETA_BM_CONFIG_REG); -+ val |= mask; -+ mvneta_bm_write(priv, MVNETA_BM_CONFIG_REG, val); -+} -+ -+static inline void mvneta_bm_config_clear(struct mvneta_bm *priv, u32 mask) -+{ -+ u32 val; -+ -+ val = mvneta_bm_read(priv, MVNETA_BM_CONFIG_REG); -+ val &= ~mask; -+ mvneta_bm_write(priv, MVNETA_BM_CONFIG_REG, val); -+} -+ -+static void mvneta_bm_pool_target_set(struct mvneta_bm *priv, int pool_id, -+ u8 target_id, u8 attr) -+{ -+ u32 val; -+ -+ val = mvneta_bm_read(priv, MVNETA_BM_XBAR_POOL_REG(pool_id)); -+ val &= ~MVNETA_BM_TARGET_ID_MASK(pool_id); -+ val &= ~MVNETA_BM_XBAR_ATTR_MASK(pool_id); -+ val |= MVNETA_BM_TARGET_ID_VAL(pool_id, target_id); -+ val |= MVNETA_BM_XBAR_ATTR_VAL(pool_id, attr); -+ -+ mvneta_bm_write(priv, MVNETA_BM_XBAR_POOL_REG(pool_id), val); -+} -+ -+/* Allocate skb for BM pool */ -+void *mvneta_buf_alloc(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -+ dma_addr_t *buf_phys_addr) -+{ -+ void *buf; -+ dma_addr_t phys_addr; -+ -+ buf = mvneta_frag_alloc(bm_pool->frag_size); -+ if (!buf) -+ return NULL; -+ -+ /* In order to update buf_cookie field of RX descriptor properly, -+ * BM hardware expects buf virtual address to be placed in the -+ * first four bytes of mapped buffer. -+ */ -+ *(u32 *)buf = (u32)buf; -+ phys_addr = dma_map_single(&priv->pdev->dev, buf, bm_pool->buf_size, -+ DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(&priv->pdev->dev, phys_addr))) { -+ mvneta_frag_free(bm_pool->frag_size, buf); -+ return NULL; -+ } -+ *buf_phys_addr = phys_addr; -+ -+ return buf; -+} -+ -+/* Refill processing for HW buffer management */ -+int mvneta_bm_pool_refill(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool) -+{ -+ dma_addr_t buf_phys_addr; -+ void *buf; -+ -+ buf = mvneta_buf_alloc(priv, bm_pool, &buf_phys_addr); -+ if (!buf) -+ return -ENOMEM; -+ -+ mvneta_bm_pool_put_bp(priv, bm_pool, buf_phys_addr); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mvneta_bm_pool_refill); -+ -+/* Allocate buffers for the pool */ -+int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -+ int buf_num) -+{ -+ int err, i; -+ -+ if (bm_pool->buf_num == bm_pool->size) { -+ dev_dbg(&priv->pdev->dev, "pool %d already filled\n", -+ bm_pool->id); -+ return bm_pool->buf_num; -+ } -+ -+ if (buf_num < 0 || -+ (buf_num + bm_pool->buf_num > bm_pool->size)) { -+ dev_err(&priv->pdev->dev, -+ "cannot allocate %d buffers for pool %d\n", -+ buf_num, bm_pool->id); -+ return 0; -+ } -+ -+ for (i = 0; i < buf_num; i++) { -+ err = mvneta_bm_pool_refill(priv, bm_pool); -+ if (err < 0) -+ break; -+ } -+ -+ /* Update BM driver with number of buffers added to pool */ -+ bm_pool->buf_num += i; -+ -+ dev_dbg(&priv->pdev->dev, -+ "%s pool %d: pkt_size=%4d, buf_size=%4d, frag_size=%4d\n", -+ bm_pool->type == MVNETA_BM_SHORT ? "short" : "long", -+ bm_pool->id, bm_pool->pkt_size, bm_pool->buf_size, -+ bm_pool->frag_size); -+ -+ dev_dbg(&priv->pdev->dev, -+ "%s pool %d: %d of %d buffers added\n", -+ bm_pool->type == MVNETA_BM_SHORT ? "short" : "long", -+ bm_pool->id, i, buf_num); -+ -+ return i; -+} -+EXPORT_SYMBOL_GPL(mvneta_bm_bufs_add); -+ -+/* Create pool */ -+static int mvneta_bm_pool_create(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool) -+{ -+ struct platform_device *pdev = priv->pdev; -+ u8 target_id, attr; -+ int size_bytes, err; -+ -+ size_bytes = sizeof(u32) * bm_pool->size; -+ bm_pool->virt_addr = dma_alloc_coherent(&pdev->dev, size_bytes, -+ &bm_pool->phys_addr, -+ GFP_KERNEL); -+ if (!bm_pool->virt_addr) -+ return -ENOMEM; -+ -+ if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVNETA_BM_POOL_PTR_ALIGN)) { -+ dma_free_coherent(&pdev->dev, size_bytes, bm_pool->virt_addr, -+ bm_pool->phys_addr); -+ dev_err(&pdev->dev, "BM pool %d is not %d bytes aligned\n", -+ bm_pool->id, MVNETA_BM_POOL_PTR_ALIGN); -+ return -ENOMEM; -+ } -+ -+ err = mvebu_mbus_get_dram_win_info(bm_pool->phys_addr, &target_id, -+ &attr); -+ if (err < 0) { -+ dma_free_coherent(&pdev->dev, size_bytes, bm_pool->virt_addr, -+ bm_pool->phys_addr); -+ return err; -+ } -+ -+ /* Set pool address */ -+ mvneta_bm_write(priv, MVNETA_BM_POOL_BASE_REG(bm_pool->id), -+ bm_pool->phys_addr); -+ -+ mvneta_bm_pool_target_set(priv, bm_pool->id, target_id, attr); -+ mvneta_bm_pool_enable(priv, bm_pool->id); -+ -+ return 0; -+} -+ -+/* Notify the driver that BM pool is being used as specific type and return the -+ * pool pointer on success -+ */ -+struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, -+ enum mvneta_bm_type type, u8 port_id, -+ int pkt_size) -+{ -+ struct mvneta_bm_pool *new_pool = &priv->bm_pools[pool_id]; -+ int num, err; -+ -+ if (new_pool->type == MVNETA_BM_LONG && -+ new_pool->port_map != 1 << port_id) { -+ dev_err(&priv->pdev->dev, -+ "long pool cannot be shared by the ports\n"); -+ return NULL; -+ } -+ -+ if (new_pool->type == MVNETA_BM_SHORT && new_pool->type != type) { -+ dev_err(&priv->pdev->dev, -+ "mixing pools' types between the ports is forbidden\n"); -+ return NULL; -+ } -+ -+ if (new_pool->pkt_size == 0 || type != MVNETA_BM_SHORT) -+ new_pool->pkt_size = pkt_size; -+ -+ /* Allocate buffers in case BM pool hasn't been used yet */ -+ if (new_pool->type == MVNETA_BM_FREE) { -+ new_pool->type = type; -+ new_pool->buf_size = MVNETA_RX_BUF_SIZE(new_pool->pkt_size); -+ new_pool->frag_size = -+ SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(new_pool->pkt_size)) + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ -+ /* Create new pool */ -+ err = mvneta_bm_pool_create(priv, new_pool); -+ if (err) { -+ dev_err(&priv->pdev->dev, "fail to create pool %d\n", -+ new_pool->id); -+ return NULL; -+ } -+ -+ /* Allocate buffers for this pool */ -+ num = mvneta_bm_bufs_add(priv, new_pool, new_pool->size); -+ if (num != new_pool->size) { -+ WARN(1, "pool %d: %d of %d allocated\n", -+ new_pool->id, num, new_pool->size); -+ return NULL; -+ } -+ } -+ -+ return new_pool; -+} -+EXPORT_SYMBOL_GPL(mvneta_bm_pool_use); -+ -+/* Free all buffers from the pool */ -+void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -+ u8 port_map) -+{ -+ int i; -+ -+ bm_pool->port_map &= ~port_map; -+ if (bm_pool->port_map) -+ return; -+ -+ mvneta_bm_config_set(priv, MVNETA_BM_EMPTY_LIMIT_MASK); -+ -+ for (i = 0; i < bm_pool->buf_num; i++) { -+ dma_addr_t buf_phys_addr; -+ u32 *vaddr; -+ -+ /* Get buffer physical address (indirect access) */ -+ buf_phys_addr = mvneta_bm_pool_get_bp(priv, bm_pool); -+ -+ /* Work-around to the problems when destroying the pool, -+ * when it occurs that a read access to BPPI returns 0. -+ */ -+ if (buf_phys_addr == 0) -+ continue; -+ -+ vaddr = phys_to_virt(buf_phys_addr); -+ if (!vaddr) -+ break; -+ -+ dma_unmap_single(&priv->pdev->dev, buf_phys_addr, -+ bm_pool->buf_size, DMA_FROM_DEVICE); -+ mvneta_frag_free(bm_pool->frag_size, vaddr); -+ } -+ -+ mvneta_bm_config_clear(priv, MVNETA_BM_EMPTY_LIMIT_MASK); -+ -+ /* Update BM driver with number of buffers removed from pool */ -+ bm_pool->buf_num -= i; -+} -+EXPORT_SYMBOL_GPL(mvneta_bm_bufs_free); -+ -+/* Cleanup pool */ -+void mvneta_bm_pool_destroy(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool, u8 port_map) -+{ -+ bm_pool->port_map &= ~port_map; -+ if (bm_pool->port_map) -+ return; -+ -+ bm_pool->type = MVNETA_BM_FREE; -+ -+ mvneta_bm_bufs_free(priv, bm_pool, port_map); -+ if (bm_pool->buf_num) -+ WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id); -+ -+ if (bm_pool->virt_addr) { -+ dma_free_coherent(&priv->pdev->dev, sizeof(u32) * bm_pool->size, -+ bm_pool->virt_addr, bm_pool->phys_addr); -+ bm_pool->virt_addr = NULL; -+ } -+ -+ mvneta_bm_pool_disable(priv, bm_pool->id); -+} -+EXPORT_SYMBOL_GPL(mvneta_bm_pool_destroy); -+ -+static void mvneta_bm_pools_init(struct mvneta_bm *priv) -+{ -+ struct device_node *dn = priv->pdev->dev.of_node; -+ struct mvneta_bm_pool *bm_pool; -+ char prop[15]; -+ u32 size; -+ int i; -+ -+ /* Activate BM unit */ -+ mvneta_bm_write(priv, MVNETA_BM_COMMAND_REG, MVNETA_BM_START_MASK); -+ -+ /* Create all pools with maximum size */ -+ for (i = 0; i < MVNETA_BM_POOLS_NUM; i++) { -+ bm_pool = &priv->bm_pools[i]; -+ bm_pool->id = i; -+ bm_pool->type = MVNETA_BM_FREE; -+ -+ /* Reset read pointer */ -+ mvneta_bm_write(priv, MVNETA_BM_POOL_READ_PTR_REG(i), 0); -+ -+ /* Reset write pointer */ -+ mvneta_bm_write(priv, MVNETA_BM_POOL_WRITE_PTR_REG(i), 0); -+ -+ /* Configure pool size according to DT or use default value */ -+ sprintf(prop, "pool%d,capacity", i); -+ if (of_property_read_u32(dn, prop, &size)) { -+ size = MVNETA_BM_POOL_CAP_DEF; -+ } else if (size > MVNETA_BM_POOL_CAP_MAX) { -+ dev_warn(&priv->pdev->dev, -+ "Illegal pool %d capacity %d, set to %d\n", -+ i, size, MVNETA_BM_POOL_CAP_MAX); -+ size = MVNETA_BM_POOL_CAP_MAX; -+ } else if (size < MVNETA_BM_POOL_CAP_MIN) { -+ dev_warn(&priv->pdev->dev, -+ "Illegal pool %d capacity %d, set to %d\n", -+ i, size, MVNETA_BM_POOL_CAP_MIN); -+ size = MVNETA_BM_POOL_CAP_MIN; -+ } else if (!IS_ALIGNED(size, MVNETA_BM_POOL_CAP_ALIGN)) { -+ dev_warn(&priv->pdev->dev, -+ "Illegal pool %d capacity %d, round to %d\n", -+ i, size, ALIGN(size, -+ MVNETA_BM_POOL_CAP_ALIGN)); -+ size = ALIGN(size, MVNETA_BM_POOL_CAP_ALIGN); -+ } -+ bm_pool->size = size; -+ -+ mvneta_bm_write(priv, MVNETA_BM_POOL_SIZE_REG(i), -+ bm_pool->size); -+ -+ /* Obtain custom pkt_size from DT */ -+ sprintf(prop, "pool%d,pkt-size", i); -+ if (of_property_read_u32(dn, prop, &bm_pool->pkt_size)) -+ bm_pool->pkt_size = 0; -+ } -+} -+ -+static void mvneta_bm_default_set(struct mvneta_bm *priv) -+{ -+ u32 val; -+ -+ /* Mask BM all interrupts */ -+ mvneta_bm_write(priv, MVNETA_BM_INTR_MASK_REG, 0); -+ -+ /* Clear BM cause register */ -+ mvneta_bm_write(priv, MVNETA_BM_INTR_CAUSE_REG, 0); -+ -+ /* Set BM configuration register */ -+ val = mvneta_bm_read(priv, MVNETA_BM_CONFIG_REG); -+ -+ /* Reduce MaxInBurstSize from 32 BPs to 16 BPs */ -+ val &= ~MVNETA_BM_MAX_IN_BURST_SIZE_MASK; -+ val |= MVNETA_BM_MAX_IN_BURST_SIZE_16BP; -+ mvneta_bm_write(priv, MVNETA_BM_CONFIG_REG, val); -+} -+ -+static int mvneta_bm_init(struct mvneta_bm *priv) -+{ -+ mvneta_bm_default_set(priv); -+ -+ /* Allocate and initialize BM pools structures */ -+ priv->bm_pools = devm_kcalloc(&priv->pdev->dev, MVNETA_BM_POOLS_NUM, -+ sizeof(struct mvneta_bm_pool), -+ GFP_KERNEL); -+ if (!priv->bm_pools) -+ return -ENOMEM; -+ -+ mvneta_bm_pools_init(priv); -+ -+ return 0; -+} -+ -+static int mvneta_bm_get_sram(struct device_node *dn, -+ struct mvneta_bm *priv) -+{ -+ priv->bppi_pool = of_gen_pool_get(dn, "internal-mem", 0); -+ if (!priv->bppi_pool) -+ return -ENOMEM; -+ -+ priv->bppi_virt_addr = gen_pool_dma_alloc(priv->bppi_pool, -+ MVNETA_BM_BPPI_SIZE, -+ &priv->bppi_phys_addr); -+ if (!priv->bppi_virt_addr) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static void mvneta_bm_put_sram(struct mvneta_bm *priv) -+{ -+ gen_pool_free(priv->bppi_pool, priv->bppi_phys_addr, -+ MVNETA_BM_BPPI_SIZE); -+} -+ -+static int mvneta_bm_probe(struct platform_device *pdev) -+{ -+ struct device_node *dn = pdev->dev.of_node; -+ struct mvneta_bm *priv; -+ struct resource *res; -+ int err; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(struct mvneta_bm), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ priv->reg_base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->reg_base)) -+ return PTR_ERR(priv->reg_base); -+ -+ priv->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(priv->clk)) -+ return PTR_ERR(priv->clk); -+ err = clk_prepare_enable(priv->clk); -+ if (err < 0) -+ return err; -+ -+ err = mvneta_bm_get_sram(dn, priv); -+ if (err < 0) { -+ dev_err(&pdev->dev, "failed to allocate internal memory\n"); -+ goto err_clk; -+ } -+ -+ priv->pdev = pdev; -+ -+ /* Initialize buffer manager internals */ -+ err = mvneta_bm_init(priv); -+ if (err < 0) { -+ dev_err(&pdev->dev, "failed to initialize controller\n"); -+ goto err_sram; -+ } -+ -+ dn->data = priv; -+ platform_set_drvdata(pdev, priv); -+ -+ dev_info(&pdev->dev, "Buffer Manager for network controller enabled\n"); -+ -+ return 0; -+ -+err_sram: -+ mvneta_bm_put_sram(priv); -+err_clk: -+ clk_disable_unprepare(priv->clk); -+ return err; -+} -+ -+static int mvneta_bm_remove(struct platform_device *pdev) -+{ -+ struct mvneta_bm *priv = platform_get_drvdata(pdev); -+ u8 all_ports_map = 0xff; -+ int i = 0; -+ -+ for (i = 0; i < MVNETA_BM_POOLS_NUM; i++) { -+ struct mvneta_bm_pool *bm_pool = &priv->bm_pools[i]; -+ -+ mvneta_bm_pool_destroy(priv, bm_pool, all_ports_map); -+ } -+ -+ mvneta_bm_put_sram(priv); -+ -+ /* Dectivate BM unit */ -+ mvneta_bm_write(priv, MVNETA_BM_COMMAND_REG, MVNETA_BM_STOP_MASK); -+ -+ clk_disable_unprepare(priv->clk); -+ -+ return 0; -+} -+ -+static const struct of_device_id mvneta_bm_match[] = { -+ { .compatible = "marvell,armada-380-neta-bm" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, mvneta_bm_match); -+ -+static struct platform_driver mvneta_bm_driver = { -+ .probe = mvneta_bm_probe, -+ .remove = mvneta_bm_remove, -+ .driver = { -+ .name = MVNETA_BM_DRIVER_NAME, -+ .of_match_table = mvneta_bm_match, -+ }, -+}; -+ -+module_platform_driver(mvneta_bm_driver); -+ -+MODULE_DESCRIPTION("Marvell NETA Buffer Manager Driver - www.marvell.com"); -+MODULE_AUTHOR("Marcin Wojtas "); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/net/ethernet/marvell/mvneta_bm.h -@@ -0,0 +1,189 @@ -+/* -+ * Driver for Marvell NETA network controller Buffer Manager. -+ * -+ * Copyright (C) 2015 Marvell -+ * -+ * Marcin Wojtas -+ * -+ * 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. -+ */ -+ -+#ifndef _MVNETA_BM_H_ -+#define _MVNETA_BM_H_ -+ -+/* BM Configuration Register */ -+#define MVNETA_BM_CONFIG_REG 0x0 -+#define MVNETA_BM_STATUS_MASK 0x30 -+#define MVNETA_BM_ACTIVE_MASK BIT(4) -+#define MVNETA_BM_MAX_IN_BURST_SIZE_MASK 0x60000 -+#define MVNETA_BM_MAX_IN_BURST_SIZE_16BP BIT(18) -+#define MVNETA_BM_EMPTY_LIMIT_MASK BIT(19) -+ -+/* BM Activation Register */ -+#define MVNETA_BM_COMMAND_REG 0x4 -+#define MVNETA_BM_START_MASK BIT(0) -+#define MVNETA_BM_STOP_MASK BIT(1) -+#define MVNETA_BM_PAUSE_MASK BIT(2) -+ -+/* BM Xbar interface Register */ -+#define MVNETA_BM_XBAR_01_REG 0x8 -+#define MVNETA_BM_XBAR_23_REG 0xc -+#define MVNETA_BM_XBAR_POOL_REG(pool) \ -+ (((pool) < 2) ? MVNETA_BM_XBAR_01_REG : MVNETA_BM_XBAR_23_REG) -+#define MVNETA_BM_TARGET_ID_OFFS(pool) (((pool) & 1) ? 16 : 0) -+#define MVNETA_BM_TARGET_ID_MASK(pool) \ -+ (0xf << MVNETA_BM_TARGET_ID_OFFS(pool)) -+#define MVNETA_BM_TARGET_ID_VAL(pool, id) \ -+ ((id) << MVNETA_BM_TARGET_ID_OFFS(pool)) -+#define MVNETA_BM_XBAR_ATTR_OFFS(pool) (((pool) & 1) ? 20 : 4) -+#define MVNETA_BM_XBAR_ATTR_MASK(pool) \ -+ (0xff << MVNETA_BM_XBAR_ATTR_OFFS(pool)) -+#define MVNETA_BM_XBAR_ATTR_VAL(pool, attr) \ -+ ((attr) << MVNETA_BM_XBAR_ATTR_OFFS(pool)) -+ -+/* Address of External Buffer Pointers Pool Register */ -+#define MVNETA_BM_POOL_BASE_REG(pool) (0x10 + ((pool) << 4)) -+#define MVNETA_BM_POOL_ENABLE_MASK BIT(0) -+ -+/* External Buffer Pointers Pool RD pointer Register */ -+#define MVNETA_BM_POOL_READ_PTR_REG(pool) (0x14 + ((pool) << 4)) -+#define MVNETA_BM_POOL_SET_READ_PTR_MASK 0xfffc -+#define MVNETA_BM_POOL_GET_READ_PTR_OFFS 16 -+#define MVNETA_BM_POOL_GET_READ_PTR_MASK 0xfffc0000 -+ -+/* External Buffer Pointers Pool WR pointer */ -+#define MVNETA_BM_POOL_WRITE_PTR_REG(pool) (0x18 + ((pool) << 4)) -+#define MVNETA_BM_POOL_SET_WRITE_PTR_OFFS 0 -+#define MVNETA_BM_POOL_SET_WRITE_PTR_MASK 0xfffc -+#define MVNETA_BM_POOL_GET_WRITE_PTR_OFFS 16 -+#define MVNETA_BM_POOL_GET_WRITE_PTR_MASK 0xfffc0000 -+ -+/* External Buffer Pointers Pool Size Register */ -+#define MVNETA_BM_POOL_SIZE_REG(pool) (0x1c + ((pool) << 4)) -+#define MVNETA_BM_POOL_SIZE_MASK 0x3fff -+ -+/* BM Interrupt Cause Register */ -+#define MVNETA_BM_INTR_CAUSE_REG (0x50) -+ -+/* BM interrupt Mask Register */ -+#define MVNETA_BM_INTR_MASK_REG (0x54) -+ -+/* Other definitions */ -+#define MVNETA_BM_SHORT_PKT_SIZE 256 -+#define MVNETA_BM_POOLS_NUM 4 -+#define MVNETA_BM_POOL_CAP_MIN 128 -+#define MVNETA_BM_POOL_CAP_DEF 2048 -+#define MVNETA_BM_POOL_CAP_MAX \ -+ (16 * 1024 - MVNETA_BM_POOL_CAP_ALIGN) -+#define MVNETA_BM_POOL_CAP_ALIGN 32 -+#define MVNETA_BM_POOL_PTR_ALIGN 32 -+ -+#define MVNETA_BM_POOL_ACCESS_OFFS 8 -+ -+#define MVNETA_BM_BPPI_SIZE 0x100000 -+ -+#define MVNETA_RX_BUF_SIZE(pkt_size) ((pkt_size) + NET_SKB_PAD) -+ -+enum mvneta_bm_type { -+ MVNETA_BM_FREE, -+ MVNETA_BM_LONG, -+ MVNETA_BM_SHORT -+}; -+ -+struct mvneta_bm { -+ void __iomem *reg_base; -+ struct clk *clk; -+ struct platform_device *pdev; -+ -+ struct gen_pool *bppi_pool; -+ /* BPPI virtual base address */ -+ void __iomem *bppi_virt_addr; -+ /* BPPI physical base address */ -+ dma_addr_t bppi_phys_addr; -+ -+ /* BM pools */ -+ struct mvneta_bm_pool *bm_pools; -+}; -+ -+struct mvneta_bm_pool { -+ /* Pool number in the range 0-3 */ -+ u8 id; -+ enum mvneta_bm_type type; -+ -+ /* Buffer Pointers Pool External (BPPE) size in number of bytes */ -+ int size; -+ /* Number of buffers used by this pool */ -+ int buf_num; -+ /* Pool buffer size */ -+ int buf_size; -+ /* Packet size */ -+ int pkt_size; -+ /* Single frag size */ -+ u32 frag_size; -+ -+ /* BPPE virtual base address */ -+ u32 *virt_addr; -+ /* BPPE physical base address */ -+ dma_addr_t phys_addr; -+ -+ /* Ports using BM pool */ -+ u8 port_map; -+ -+ struct mvneta_bm *priv; -+}; -+ -+/* Declarations and definitions */ -+void *mvneta_frag_alloc(unsigned int frag_size); -+void mvneta_frag_free(unsigned int frag_size, void *data); -+ -+#if defined(CONFIG_MVNETA_BM) || defined(CONFIG_MVNETA_BM_MODULE) -+void mvneta_bm_pool_destroy(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool, u8 port_map); -+void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -+ u8 port_map); -+int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -+ int buf_num); -+int mvneta_bm_pool_refill(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool); -+struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, -+ enum mvneta_bm_type type, u8 port_id, -+ int pkt_size); -+ -+static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool, -+ dma_addr_t buf_phys_addr) -+{ -+ writel_relaxed(buf_phys_addr, priv->bppi_virt_addr + -+ (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS)); -+} -+ -+static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool) -+{ -+ return readl_relaxed(priv->bppi_virt_addr + -+ (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS)); -+} -+#else -+void mvneta_bm_pool_destroy(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool, u8 port_map) {} -+void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -+ u8 port_map) {} -+int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -+ int buf_num) { return 0; } -+int mvneta_bm_pool_refill(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool) {return 0; } -+struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, -+ enum mvneta_bm_type type, u8 port_id, -+ int pkt_size) { return NULL; } -+ -+static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool, -+ dma_addr_t buf_phys_addr) {} -+ -+static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, -+ struct mvneta_bm_pool *bm_pool) -+{ return 0; } -+#endif /* CONFIG_MVNETA_BM */ -+#endif diff --git a/target/linux/mvebu/patches-4.4/046-net-mvneta-Use-the-new-hwbm-framework.patch b/target/linux/mvebu/patches-4.4/046-net-mvneta-Use-the-new-hwbm-framework.patch deleted file mode 100644 index 210504c39e..0000000000 --- a/target/linux/mvebu/patches-4.4/046-net-mvneta-Use-the-new-hwbm-framework.patch +++ /dev/null @@ -1,359 +0,0 @@ -From: Gregory CLEMENT -Date: Mon, 14 Mar 2016 09:39:05 +0100 -Subject: [PATCH] net: mvneta: Use the new hwbm framework - -Now that the hardware buffer management framework had been introduced, -let's use it. - -Tested-by: Sebastian Careba -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/Kconfig -+++ b/drivers/net/ethernet/marvell/Kconfig -@@ -43,6 +43,7 @@ config MVMDIO - config MVNETA_BM - tristate "Marvell Armada 38x/XP network interface BM support" - depends on MVNETA -+ select HWBM - ---help--- - This driver supports auxiliary block of the network - interface units in the Marvell ARMADA XP and ARMADA 38x SoC ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - #include "mvneta_bm.h" - #include - #include -@@ -1024,11 +1025,12 @@ static int mvneta_bm_port_init(struct pl - static void mvneta_bm_update_mtu(struct mvneta_port *pp, int mtu) - { - struct mvneta_bm_pool *bm_pool = pp->pool_long; -+ struct hwbm_pool *hwbm_pool = &bm_pool->hwbm_pool; - int num; - - /* Release all buffers from long pool */ - mvneta_bm_bufs_free(pp->bm_priv, bm_pool, 1 << pp->id); -- if (bm_pool->buf_num) { -+ if (hwbm_pool->buf_num) { - WARN(1, "cannot free all buffers in pool %d\n", - bm_pool->id); - goto bm_mtu_err; -@@ -1036,14 +1038,14 @@ static void mvneta_bm_update_mtu(struct - - bm_pool->pkt_size = MVNETA_RX_PKT_SIZE(mtu); - bm_pool->buf_size = MVNETA_RX_BUF_SIZE(bm_pool->pkt_size); -- bm_pool->frag_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + -- SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size)); -+ hwbm_pool->frag_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + -+ SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size)); - - /* Fill entire long pool */ -- num = mvneta_bm_bufs_add(pp->bm_priv, bm_pool, bm_pool->size); -- if (num != bm_pool->size) { -+ num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC); -+ if (num != hwbm_pool->size) { - WARN(1, "pool %d: %d of %d allocated\n", -- bm_pool->id, num, bm_pool->size); -+ bm_pool->id, num, hwbm_pool->size); - goto bm_mtu_err; - } - mvneta_bm_pool_bufsize_set(pp, bm_pool->buf_size, bm_pool->id); -@@ -2064,14 +2066,14 @@ err_drop_frame: - } - - /* Refill processing */ -- err = mvneta_bm_pool_refill(pp->bm_priv, bm_pool); -+ err = hwbm_pool_refill(&bm_pool->hwbm_pool, GFP_ATOMIC); - if (err) { - netdev_err(dev, "Linux processing - Can't refill\n"); - rxq->missed++; - goto err_drop_frame_ret_pool; - } - -- frag_size = bm_pool->frag_size; -+ frag_size = bm_pool->hwbm_pool.frag_size; - - skb = build_skb(data, frag_size > PAGE_SIZE ? 0 : frag_size); - ---- a/drivers/net/ethernet/marvell/mvneta_bm.c -+++ b/drivers/net/ethernet/marvell/mvneta_bm.c -@@ -10,16 +10,17 @@ - * warranty of any kind, whether express or implied. - */ - --#include -+#include - #include --#include --#include --#include -+#include -+#include - #include - #include --#include -+#include - #include --#include -+#include -+#include -+#include - #include "mvneta_bm.h" - - #define MVNETA_BM_DRIVER_NAME "mvneta_bm" -@@ -88,17 +89,13 @@ static void mvneta_bm_pool_target_set(st - mvneta_bm_write(priv, MVNETA_BM_XBAR_POOL_REG(pool_id), val); - } - --/* Allocate skb for BM pool */ --void *mvneta_buf_alloc(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -- dma_addr_t *buf_phys_addr) -+int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf) - { -- void *buf; -+ struct mvneta_bm_pool *bm_pool = -+ (struct mvneta_bm_pool *)hwbm_pool->priv; -+ struct mvneta_bm *priv = bm_pool->priv; - dma_addr_t phys_addr; - -- buf = mvneta_frag_alloc(bm_pool->frag_size); -- if (!buf) -- return NULL; -- - /* In order to update buf_cookie field of RX descriptor properly, - * BM hardware expects buf virtual address to be placed in the - * first four bytes of mapped buffer. -@@ -106,75 +103,13 @@ void *mvneta_buf_alloc(struct mvneta_bm - *(u32 *)buf = (u32)buf; - phys_addr = dma_map_single(&priv->pdev->dev, buf, bm_pool->buf_size, - DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(&priv->pdev->dev, phys_addr))) { -- mvneta_frag_free(bm_pool->frag_size, buf); -- return NULL; -- } -- *buf_phys_addr = phys_addr; -- -- return buf; --} -- --/* Refill processing for HW buffer management */ --int mvneta_bm_pool_refill(struct mvneta_bm *priv, -- struct mvneta_bm_pool *bm_pool) --{ -- dma_addr_t buf_phys_addr; -- void *buf; -- -- buf = mvneta_buf_alloc(priv, bm_pool, &buf_phys_addr); -- if (!buf) -+ if (unlikely(dma_mapping_error(&priv->pdev->dev, phys_addr))) - return -ENOMEM; - -- mvneta_bm_pool_put_bp(priv, bm_pool, buf_phys_addr); -- -+ mvneta_bm_pool_put_bp(priv, bm_pool, phys_addr); - return 0; - } --EXPORT_SYMBOL_GPL(mvneta_bm_pool_refill); -- --/* Allocate buffers for the pool */ --int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -- int buf_num) --{ -- int err, i; -- -- if (bm_pool->buf_num == bm_pool->size) { -- dev_dbg(&priv->pdev->dev, "pool %d already filled\n", -- bm_pool->id); -- return bm_pool->buf_num; -- } -- -- if (buf_num < 0 || -- (buf_num + bm_pool->buf_num > bm_pool->size)) { -- dev_err(&priv->pdev->dev, -- "cannot allocate %d buffers for pool %d\n", -- buf_num, bm_pool->id); -- return 0; -- } -- -- for (i = 0; i < buf_num; i++) { -- err = mvneta_bm_pool_refill(priv, bm_pool); -- if (err < 0) -- break; -- } -- -- /* Update BM driver with number of buffers added to pool */ -- bm_pool->buf_num += i; -- -- dev_dbg(&priv->pdev->dev, -- "%s pool %d: pkt_size=%4d, buf_size=%4d, frag_size=%4d\n", -- bm_pool->type == MVNETA_BM_SHORT ? "short" : "long", -- bm_pool->id, bm_pool->pkt_size, bm_pool->buf_size, -- bm_pool->frag_size); -- -- dev_dbg(&priv->pdev->dev, -- "%s pool %d: %d of %d buffers added\n", -- bm_pool->type == MVNETA_BM_SHORT ? "short" : "long", -- bm_pool->id, i, buf_num); -- -- return i; --} --EXPORT_SYMBOL_GPL(mvneta_bm_bufs_add); -+EXPORT_SYMBOL_GPL(mvneta_bm_construct); - - /* Create pool */ - static int mvneta_bm_pool_create(struct mvneta_bm *priv, -@@ -183,8 +118,7 @@ static int mvneta_bm_pool_create(struct - struct platform_device *pdev = priv->pdev; - u8 target_id, attr; - int size_bytes, err; -- -- size_bytes = sizeof(u32) * bm_pool->size; -+ size_bytes = sizeof(u32) * bm_pool->hwbm_pool.size; - bm_pool->virt_addr = dma_alloc_coherent(&pdev->dev, size_bytes, - &bm_pool->phys_addr, - GFP_KERNEL); -@@ -245,11 +179,16 @@ struct mvneta_bm_pool *mvneta_bm_pool_us - - /* Allocate buffers in case BM pool hasn't been used yet */ - if (new_pool->type == MVNETA_BM_FREE) { -+ struct hwbm_pool *hwbm_pool = &new_pool->hwbm_pool; -+ -+ new_pool->priv = priv; - new_pool->type = type; - new_pool->buf_size = MVNETA_RX_BUF_SIZE(new_pool->pkt_size); -- new_pool->frag_size = -+ hwbm_pool->frag_size = - SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(new_pool->pkt_size)) + - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ hwbm_pool->construct = mvneta_bm_construct; -+ hwbm_pool->priv = new_pool; - - /* Create new pool */ - err = mvneta_bm_pool_create(priv, new_pool); -@@ -260,10 +199,10 @@ struct mvneta_bm_pool *mvneta_bm_pool_us - } - - /* Allocate buffers for this pool */ -- num = mvneta_bm_bufs_add(priv, new_pool, new_pool->size); -- if (num != new_pool->size) { -+ num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC); -+ if (num != hwbm_pool->size) { - WARN(1, "pool %d: %d of %d allocated\n", -- new_pool->id, num, new_pool->size); -+ new_pool->id, num, hwbm_pool->size); - return NULL; - } - } -@@ -284,7 +223,7 @@ void mvneta_bm_bufs_free(struct mvneta_b - - mvneta_bm_config_set(priv, MVNETA_BM_EMPTY_LIMIT_MASK); - -- for (i = 0; i < bm_pool->buf_num; i++) { -+ for (i = 0; i < bm_pool->hwbm_pool.buf_num; i++) { - dma_addr_t buf_phys_addr; - u32 *vaddr; - -@@ -303,13 +242,13 @@ void mvneta_bm_bufs_free(struct mvneta_b - - dma_unmap_single(&priv->pdev->dev, buf_phys_addr, - bm_pool->buf_size, DMA_FROM_DEVICE); -- mvneta_frag_free(bm_pool->frag_size, vaddr); -+ hwbm_buf_free(&bm_pool->hwbm_pool, vaddr); - } - - mvneta_bm_config_clear(priv, MVNETA_BM_EMPTY_LIMIT_MASK); - - /* Update BM driver with number of buffers removed from pool */ -- bm_pool->buf_num -= i; -+ bm_pool->hwbm_pool.buf_num -= i; - } - EXPORT_SYMBOL_GPL(mvneta_bm_bufs_free); - -@@ -317,6 +256,7 @@ EXPORT_SYMBOL_GPL(mvneta_bm_bufs_free); - void mvneta_bm_pool_destroy(struct mvneta_bm *priv, - struct mvneta_bm_pool *bm_pool, u8 port_map) - { -+ struct hwbm_pool *hwbm_pool = &bm_pool->hwbm_pool; - bm_pool->port_map &= ~port_map; - if (bm_pool->port_map) - return; -@@ -324,11 +264,12 @@ void mvneta_bm_pool_destroy(struct mvnet - bm_pool->type = MVNETA_BM_FREE; - - mvneta_bm_bufs_free(priv, bm_pool, port_map); -- if (bm_pool->buf_num) -+ if (hwbm_pool->buf_num) - WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id); - - if (bm_pool->virt_addr) { -- dma_free_coherent(&priv->pdev->dev, sizeof(u32) * bm_pool->size, -+ dma_free_coherent(&priv->pdev->dev, -+ sizeof(u32) * hwbm_pool->size, - bm_pool->virt_addr, bm_pool->phys_addr); - bm_pool->virt_addr = NULL; - } -@@ -381,10 +322,10 @@ static void mvneta_bm_pools_init(struct - MVNETA_BM_POOL_CAP_ALIGN)); - size = ALIGN(size, MVNETA_BM_POOL_CAP_ALIGN); - } -- bm_pool->size = size; -+ bm_pool->hwbm_pool.size = size; - - mvneta_bm_write(priv, MVNETA_BM_POOL_SIZE_REG(i), -- bm_pool->size); -+ bm_pool->hwbm_pool.size); - - /* Obtain custom pkt_size from DT */ - sprintf(prop, "pool%d,pkt-size", i); ---- a/drivers/net/ethernet/marvell/mvneta_bm.h -+++ b/drivers/net/ethernet/marvell/mvneta_bm.h -@@ -108,20 +108,15 @@ struct mvneta_bm { - }; - - struct mvneta_bm_pool { -+ struct hwbm_pool hwbm_pool; - /* Pool number in the range 0-3 */ - u8 id; - enum mvneta_bm_type type; - -- /* Buffer Pointers Pool External (BPPE) size in number of bytes */ -- int size; -- /* Number of buffers used by this pool */ -- int buf_num; -- /* Pool buffer size */ -- int buf_size; - /* Packet size */ - int pkt_size; -- /* Single frag size */ -- u32 frag_size; -+ /* Size of the buffer acces through DMA*/ -+ u32 buf_size; - - /* BPPE virtual base address */ - u32 *virt_addr; -@@ -143,8 +138,7 @@ void mvneta_bm_pool_destroy(struct mvnet - struct mvneta_bm_pool *bm_pool, u8 port_map); - void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, - u8 port_map); --int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -- int buf_num); -+int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf); - int mvneta_bm_pool_refill(struct mvneta_bm *priv, - struct mvneta_bm_pool *bm_pool); - struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, -@@ -170,8 +164,7 @@ void mvneta_bm_pool_destroy(struct mvnet - struct mvneta_bm_pool *bm_pool, u8 port_map) {} - void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, - u8 port_map) {} --int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, -- int buf_num) { return 0; } -+int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf) { return 0; } - int mvneta_bm_pool_refill(struct mvneta_bm *priv, - struct mvneta_bm_pool *bm_pool) {return 0; } - struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, diff --git a/target/linux/mvebu/patches-4.4/047-net-mvneta-Fix-spinlock-usage.patch b/target/linux/mvebu/patches-4.4/047-net-mvneta-Fix-spinlock-usage.patch deleted file mode 100644 index a8e78df2e9..0000000000 --- a/target/linux/mvebu/patches-4.4/047-net-mvneta-Fix-spinlock-usage.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Gregory CLEMENT -Date: Sat, 12 Mar 2016 18:44:17 +0100 -Subject: [PATCH] net: mvneta: Fix spinlock usage - -In the previous patch, the spinlock was not initialized. While it didn't -cause any trouble yet it could be a problem to use it uninitialized. - -The most annoying part was the critical section protected by the spinlock -in mvneta_stop(). Some of the functions could sleep as pointed when -activated CONFIG_DEBUG_ATOMIC_SLEEP. Actually, in mvneta_stop() we only -need to protect the is_stopped flagged, indeed the code of the notifier -for CPU online is protected by the same spinlock, so when we get the -lock, the notifer work is done. - -Reported-by: Patrick Uiterwijk -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3484,17 +3484,17 @@ static int mvneta_stop(struct net_device - struct mvneta_port *pp = netdev_priv(dev); - - /* Inform that we are stopping so we don't want to setup the -- * driver for new CPUs in the notifiers -+ * driver for new CPUs in the notifiers. The code of the -+ * notifier for CPU online is protected by the same spinlock, -+ * so when we get the lock, the notifer work is done. - */ - spin_lock(&pp->lock); - pp->is_stopped = true; -+ spin_unlock(&pp->lock); -+ - mvneta_stop_dev(pp); - mvneta_mdio_remove(pp); - unregister_cpu_notifier(&pp->cpu_notifier); -- /* Now that the notifier are unregistered, we can release le -- * lock -- */ -- spin_unlock(&pp->lock); - on_each_cpu(mvneta_percpu_disable, pp, true); - free_percpu_irq(dev->irq, pp->ports); - mvneta_cleanup_rxqs(pp); -@@ -4027,6 +4027,7 @@ static int mvneta_probe(struct platform_ - dev->ethtool_ops = &mvneta_eth_tool_ops; - - pp = netdev_priv(dev); -+ spin_lock_init(&pp->lock); - pp->phy_node = phy_node; - pp->phy_interface = phy_mode; - diff --git a/target/linux/mvebu/patches-4.4/048-net-mvneta-fix-error-messages-in-mvneta_port_down-fu.patch b/target/linux/mvebu/patches-4.4/048-net-mvneta-fix-error-messages-in-mvneta_port_down-fu.patch deleted file mode 100644 index fd1f1ae203..0000000000 --- a/target/linux/mvebu/patches-4.4/048-net-mvneta-fix-error-messages-in-mvneta_port_down-fu.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Dmitri Epshtein -Date: Sat, 12 Mar 2016 18:44:19 +0100 -Subject: [PATCH] net: mvneta: fix error messages in mvneta_port_down function - -This commit corrects error printing when shutting down the port. - -[gregory.clement@free-electrons.com: split initial commit in two -individual changes] -Signed-off-by: Dmitri Epshtein -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -1105,7 +1105,7 @@ static void mvneta_port_down(struct mvne - do { - if (count++ >= MVNETA_RX_DISABLE_TIMEOUT_MSEC) { - netdev_warn(pp->dev, -- "TIMEOUT for RX stopped ! rx_queue_cmd: 0x08%x\n", -+ "TIMEOUT for RX stopped ! rx_queue_cmd: 0x%08x\n", - val); - break; - } -@@ -1144,7 +1144,7 @@ static void mvneta_port_down(struct mvne - do { - if (count++ >= MVNETA_TX_FIFO_EMPTY_TIMEOUT) { - netdev_warn(pp->dev, -- "TX FIFO empty timeout status=0x08%x\n", -+ "TX FIFO empty timeout status=0x%08x\n", - val); - break; - } diff --git a/target/linux/mvebu/patches-4.4/049-net-mvneta-replace-MVNETA_CPU_D_CACHE_LINE_SIZE-with.patch b/target/linux/mvebu/patches-4.4/049-net-mvneta-replace-MVNETA_CPU_D_CACHE_LINE_SIZE-with.patch deleted file mode 100644 index c12d98a4e2..0000000000 --- a/target/linux/mvebu/patches-4.4/049-net-mvneta-replace-MVNETA_CPU_D_CACHE_LINE_SIZE-with.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Jisheng Zhang -Date: Wed, 30 Mar 2016 19:55:21 +0800 -Subject: [PATCH] net: mvneta: replace MVNETA_CPU_D_CACHE_LINE_SIZE with - L1_CACHE_BYTES - -The mvneta is also used in some Marvell berlin family SoCs which may -have 64bytes cacheline size. Replace the MVNETA_CPU_D_CACHE_LINE_SIZE -usage with L1_CACHE_BYTES. - -And since dma_alloc_coherent() is always cacheline size aligned, so -remove the align checks. - -Signed-off-by: Jisheng Zhang -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -260,7 +260,6 @@ - - #define MVNETA_VLAN_TAG_LEN 4 - --#define MVNETA_CPU_D_CACHE_LINE_SIZE 32 - #define MVNETA_TX_CSUM_DEF_SIZE 1600 - #define MVNETA_TX_CSUM_MAX_SIZE 9800 - #define MVNETA_ACC_MODE_EXT1 1 -@@ -300,7 +299,7 @@ - #define MVNETA_RX_PKT_SIZE(mtu) \ - ALIGN((mtu) + MVNETA_MH_SIZE + MVNETA_VLAN_TAG_LEN + \ - ETH_HLEN + ETH_FCS_LEN, \ -- MVNETA_CPU_D_CACHE_LINE_SIZE) -+ L1_CACHE_BYTES) - - #define IS_TSO_HEADER(txq, addr) \ - ((addr >= txq->tso_hdrs_phys) && \ -@@ -2762,9 +2761,6 @@ static int mvneta_rxq_init(struct mvneta - if (rxq->descs == NULL) - return -ENOMEM; - -- BUG_ON(rxq->descs != -- PTR_ALIGN(rxq->descs, MVNETA_CPU_D_CACHE_LINE_SIZE)); -- - rxq->last_desc = rxq->size - 1; - - /* Set Rx descriptors queue starting address */ -@@ -2835,10 +2831,6 @@ static int mvneta_txq_init(struct mvneta - if (txq->descs == NULL) - return -ENOMEM; - -- /* Make sure descriptor address is cache line size aligned */ -- BUG_ON(txq->descs != -- PTR_ALIGN(txq->descs, MVNETA_CPU_D_CACHE_LINE_SIZE)); -- - txq->last_desc = txq->size - 1; - - /* Set maximum bandwidth for enabled TXQs */ diff --git a/target/linux/mvebu/patches-4.4/050-net-mvneta-fix-changing-MTU-when-using-per-cpu-proce.patch b/target/linux/mvebu/patches-4.4/050-net-mvneta-fix-changing-MTU-when-using-per-cpu-proce.patch deleted file mode 100644 index 07862008a7..0000000000 --- a/target/linux/mvebu/patches-4.4/050-net-mvneta-fix-changing-MTU-when-using-per-cpu-proce.patch +++ /dev/null @@ -1,75 +0,0 @@ -From: Marcin Wojtas -Date: Fri, 1 Apr 2016 15:21:18 +0200 -Subject: [PATCH] net: mvneta: fix changing MTU when using per-cpu processing - -After enabling per-cpu processing it appeared that under heavy load -changing MTU can result in blocking all port's interrupts and -transmitting data is not possible after the change. - -This commit fixes above issue by disabling percpu interrupts for the -time, when TXQs and RXQs are reconfigured. - -Signed-off-by: Marcin Wojtas -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3040,6 +3040,20 @@ static int mvneta_check_mtu_valid(struct - return mtu; - } - -+static void mvneta_percpu_enable(void *arg) -+{ -+ struct mvneta_port *pp = arg; -+ -+ enable_percpu_irq(pp->dev->irq, IRQ_TYPE_NONE); -+} -+ -+static void mvneta_percpu_disable(void *arg) -+{ -+ struct mvneta_port *pp = arg; -+ -+ disable_percpu_irq(pp->dev->irq); -+} -+ - /* Change the device mtu */ - static int mvneta_change_mtu(struct net_device *dev, int mtu) - { -@@ -3064,6 +3078,7 @@ static int mvneta_change_mtu(struct net_ - * reallocation of the queues - */ - mvneta_stop_dev(pp); -+ on_each_cpu(mvneta_percpu_disable, pp, true); - - mvneta_cleanup_txqs(pp); - mvneta_cleanup_rxqs(pp); -@@ -3087,6 +3102,7 @@ static int mvneta_change_mtu(struct net_ - return ret; - } - -+ on_each_cpu(mvneta_percpu_enable, pp, true); - mvneta_start_dev(pp); - mvneta_port_up(pp); - -@@ -3240,20 +3256,6 @@ static void mvneta_mdio_remove(struct mv - pp->phy_dev = NULL; - } - --static void mvneta_percpu_enable(void *arg) --{ -- struct mvneta_port *pp = arg; -- -- enable_percpu_irq(pp->dev->irq, IRQ_TYPE_NONE); --} -- --static void mvneta_percpu_disable(void *arg) --{ -- struct mvneta_port *pp = arg; -- -- disable_percpu_irq(pp->dev->irq); --} -- - /* Electing a CPU must be done in an atomic way: it should be done - * after or before the removal/insertion of a CPU and this function is - * not reentrant. diff --git a/target/linux/mvebu/patches-4.4/051-ARM-dts-armada-38x-add-buffer-manager-nodes.patch b/target/linux/mvebu/patches-4.4/051-ARM-dts-armada-38x-add-buffer-manager-nodes.patch deleted file mode 100644 index b56de94e3d..0000000000 --- a/target/linux/mvebu/patches-4.4/051-ARM-dts-armada-38x-add-buffer-manager-nodes.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Marcin Wojtas -Date: Mon, 14 Mar 2016 09:38:57 +0100 -Subject: [PATCH] ARM: dts: armada-38x: add buffer manager nodes - -Armada 38x network controller supports hardware buffer management (BM). -Since it is now enabled in mvneta driver, appropriate nodes can be added -to armada-38x.dtsi - for the actual common BM unit (bm@c8000) and its -internal SRAM (bm-bppi), which is used for indirect access to buffer -pointer ring residing in DRAM. - -Pools - ports mapping, bm-bppi entry in 'soc' node's ranges and optional -parameters are supposed to be set in board files. - -Signed-off-by: Marcin Wojtas -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/arch/arm/boot/dts/armada-38x.dtsi -+++ b/arch/arm/boot/dts/armada-38x.dtsi -@@ -540,6 +540,14 @@ - status = "disabled"; - }; - -+ bm: bm@c8000 { -+ compatible = "marvell,armada-380-neta-bm"; -+ reg = <0xc8000 0xac>; -+ clocks = <&gateclk 13>; -+ internal-mem = <&bm_bppi>; -+ status = "disabled"; -+ }; -+ - sata@e0000 { - compatible = "marvell,armada-380-ahci"; - reg = <0xe0000 0x2000>; -@@ -618,6 +626,17 @@ - #size-cells = <1>; - ranges = <0 MBUS_ID(0x09, 0x15) 0 0x800>; - }; -+ -+ bm_bppi: bm-bppi { -+ compatible = "mmio-sram"; -+ reg = ; -+ ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ clocks = <&gateclk 13>; -+ no-memory-wc; -+ status = "disabled"; -+ }; - }; - - clocks { diff --git a/target/linux/mvebu/patches-4.4/052-ARM-dts-armada-xp-add-buffer-manager-nodes.patch b/target/linux/mvebu/patches-4.4/052-ARM-dts-armada-xp-add-buffer-manager-nodes.patch deleted file mode 100644 index 65fafd7101..0000000000 --- a/target/linux/mvebu/patches-4.4/052-ARM-dts-armada-xp-add-buffer-manager-nodes.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Marcin Wojtas -Date: Mon, 14 Mar 2016 09:38:59 +0100 -Subject: [PATCH] ARM: dts: armada-xp: add buffer manager nodes - -Armada XP network controller supports hardware buffer management (BM). -Since it is now enabled in mvneta driver, appropriate nodes can be added -to armada-xp.dtsi - for the actual common BM unit (bm@c0000) and its -internal SRAM (bm-bppi), which is used for indirect access to buffer -pointer ring residing in DRAM. - -Pools - ports mapping, bm-bppi entry in 'soc' node's ranges and optional -parameters are supposed to be set in board files. - -Signed-off-by: Marcin Wojtas -Signed-off-by: Gregory CLEMENT -Signed-off-by: David S. Miller ---- - ---- a/arch/arm/boot/dts/armada-xp.dtsi -+++ b/arch/arm/boot/dts/armada-xp.dtsi -@@ -253,6 +253,14 @@ - marvell,crypto-sram-size = <0x800>; - }; - -+ bm: bm@c0000 { -+ compatible = "marvell,armada-380-neta-bm"; -+ reg = <0xc0000 0xac>; -+ clocks = <&gateclk 13>; -+ internal-mem = <&bm_bppi>; -+ status = "disabled"; -+ }; -+ - xor@f0900 { - compatible = "marvell,orion-xor"; - reg = <0xF0900 0x100 -@@ -291,6 +299,17 @@ - #size-cells = <1>; - ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>; - }; -+ -+ bm_bppi: bm-bppi { -+ compatible = "mmio-sram"; -+ reg = ; -+ ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ clocks = <&gateclk 13>; -+ no-memory-wc; -+ status = "disabled"; -+ }; - }; - - clocks { diff --git a/target/linux/mvebu/patches-4.4/053-ARM-dts-Add-SolidRun-Armada-388-Clearfog-A1-DT-file.patch b/target/linux/mvebu/patches-4.4/053-ARM-dts-Add-SolidRun-Armada-388-Clearfog-A1-DT-file.patch deleted file mode 100644 index b25d71071f..0000000000 --- a/target/linux/mvebu/patches-4.4/053-ARM-dts-Add-SolidRun-Armada-388-Clearfog-A1-DT-file.patch +++ /dev/null @@ -1,611 +0,0 @@ -From 4c945e8556ec7ea5b19d4f8721b212f468656e0d Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 6 Dec 2015 21:52:06 +0000 -Subject: [PATCH] ARM: dts: Add SolidRun Armada 388 Clearfog A1 DT file - -Add support for the SolidRun Armada 388 Clearfog A1 board. This board -has an Armada 388 microsom, dedicated gigabit ethernet, six switched -gigabit ethernet ports, SFP cage, two Mini-PCIe/mSATA slots, a m.2 SATA -slot, and a MikroBUS connector to allow MikroBUS modules to be added. - -This DT file adds support for all board facilities with the exception -of full SFP support. - -Signed-off-by: Russell King -Acked-by: Gregory CLEMENT -Signed-off-by: Gregory CLEMENT ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/armada-388-clearfog.dts | 456 +++++++++++++++++++++ - .../arm/boot/dts/armada-38x-solidrun-microsom.dtsi | 115 ++++++ - 3 files changed, 572 insertions(+) - create mode 100644 arch/arm/boot/dts/armada-388-clearfog.dts - create mode 100644 arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -750,6 +750,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ - armada-385-linksys-cobra.dtb \ - armada-385-linksys-rango.dtb \ - armada-385-linksys-shelby.dtb \ -+ armada-388-clearfog.dtb \ - armada-388-db.dtb \ - armada-388-gp.dtb \ - armada-388-rd.dtb ---- /dev/null -+++ b/arch/arm/boot/dts/armada-388-clearfog.dts -@@ -0,0 +1,456 @@ -+/* -+ * Device Tree file for SolidRun Clearfog revision A1 rev 2.0 (88F6828) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+#include "armada-388.dtsi" -+#include "armada-38x-solidrun-microsom.dtsi" -+ -+/ { -+ model = "SolidRun Clearfog A1"; -+ compatible = "solidrun,clearfog-a1", "marvell,armada388", -+ "marvell,armada385", "marvell,armada380"; -+ -+ aliases { -+ /* So that mvebu u-boot can update the MAC addresses */ -+ ethernet1 = ð0; -+ ethernet2 = ð1; -+ ethernet3 = ð2; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "3P3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ soc { -+ internal-regs { -+ ethernet@30000 { -+ phy-mode = "sgmii"; -+ status = "okay"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ ethernet@34000 { -+ phy-mode = "sgmii"; -+ status = "okay"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ i2c@11000 { -+ /* Is there anything on this? */ -+ clock-frequency = <100000>; -+ pinctrl-0 = <&i2c0_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ -+ /* -+ * PCA9655 GPIO expander, up to 1MHz clock. -+ * 0-CON3 CLKREQ# -+ * 1-CON3 PERST# -+ * 2-CON2 PERST# -+ * 3-CON3 W_DISABLE -+ * 4-CON2 CLKREQ# -+ * 5-USB3 overcurrent -+ * 6-USB3 power -+ * 7-CON2 W_DISABLE -+ * 8-JP4 P1 -+ * 9-JP4 P4 -+ * 10-JP4 P5 -+ * 11-m.2 DEVSLP -+ * 12-SFP_LOS -+ * 13-SFP_TX_FAULT -+ * 14-SFP_TX_DISABLE -+ * 15-SFP_MOD_DEF0 -+ */ -+ expander0: gpio-expander@20 { -+ /* -+ * This is how it should be: -+ * compatible = "onnn,pca9655", -+ * "nxp,pca9555"; -+ * but you can't do this because of -+ * the way I2C works. -+ */ -+ compatible = "nxp,pca9555"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ reg = <0x20>; -+ -+ pcie1_0_clkreq { -+ gpio-hog; -+ gpios = <0 GPIO_ACTIVE_LOW>; -+ input; -+ line-name = "pcie1.0-clkreq"; -+ }; -+ pcie1_0_w_disable { -+ gpio-hog; -+ gpios = <3 GPIO_ACTIVE_LOW>; -+ output-low; -+ line-name = "pcie1.0-w-disable"; -+ }; -+ pcie2_0_clkreq { -+ gpio-hog; -+ gpios = <4 GPIO_ACTIVE_LOW>; -+ input; -+ line-name = "pcie2.0-clkreq"; -+ }; -+ pcie2_0_w_disable { -+ gpio-hog; -+ gpios = <7 GPIO_ACTIVE_LOW>; -+ output-low; -+ line-name = "pcie2.0-w-disable"; -+ }; -+ usb3_ilimit { -+ gpio-hog; -+ gpios = <5 GPIO_ACTIVE_LOW>; -+ input; -+ line-name = "usb3-current-limit"; -+ }; -+ usb3_power { -+ gpio-hog; -+ gpios = <6 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "usb3-power"; -+ }; -+ m2_devslp { -+ gpio-hog; -+ gpios = <11 GPIO_ACTIVE_HIGH>; -+ output-low; -+ line-name = "m.2 devslp"; -+ }; -+ sfp_los { -+ /* SFP loss of signal */ -+ gpio-hog; -+ gpios = <12 GPIO_ACTIVE_HIGH>; -+ input; -+ line-name = "sfp-los"; -+ }; -+ sfp_tx_fault { -+ /* SFP laser fault */ -+ gpio-hog; -+ gpios = <13 GPIO_ACTIVE_HIGH>; -+ input; -+ line-name = "sfp-tx-fault"; -+ }; -+ sfp_tx_disable { -+ /* SFP transmit disable */ -+ gpio-hog; -+ gpios = <14 GPIO_ACTIVE_HIGH>; -+ output-low; -+ line-name = "sfp-tx-disable"; -+ }; -+ sfp_mod_def0 { -+ /* SFP module present */ -+ gpio-hog; -+ gpios = <15 GPIO_ACTIVE_LOW>; -+ input; -+ line-name = "sfp-mod-def0"; -+ }; -+ }; -+ -+ /* The MCP3021 is 100kHz clock only */ -+ mikrobus_adc: mcp3021@4c { -+ compatible = "microchip,mcp3021"; -+ reg = <0x4c>; -+ }; -+ -+ /* Also something at 0x64 */ -+ }; -+ -+ i2c@11100 { -+ /* -+ * Routed to SFP, mikrobus, and PCIe. -+ * SFP limits this to 100kHz, and requires -+ * an AT24C01A/02/04 with address pins tied -+ * low, which takes addresses 0x50 and 0x51. -+ * Mikrobus doesn't specify beyond an I2C -+ * bus being present. -+ * PCIe uses ARP to assign addresses, or -+ * 0x63-0x64. -+ */ -+ clock-frequency = <100000>; -+ pinctrl-0 = <&clearfog_i2c1_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ }; -+ -+ mdio@72004 { -+ pinctrl-0 = <&mdio_pins>; -+ pinctrl-names = "default"; -+ -+ phy_dedicated: ethernet-phy@0 { -+ /* -+ * Annoyingly, the marvell phy driver -+ * configures the LED register, rather -+ * than preserving reset-loaded setting. -+ * We undo that rubbish here. -+ */ -+ marvell,reg-init = <3 16 0 0x101e>; -+ reg = <0>; -+ }; -+ }; -+ -+ pinctrl@18000 { -+ clearfog_dsa0_clk_pins: clearfog-dsa0-clk-pins { -+ marvell,pins = "mpp46"; -+ marvell,function = "ref"; -+ }; -+ clearfog_dsa0_pins: clearfog-dsa0-pins { -+ marvell,pins = "mpp23", "mpp41"; -+ marvell,function = "gpio"; -+ }; -+ clearfog_i2c1_pins: i2c1-pins { -+ /* SFP, PCIe, mSATA, mikrobus */ -+ marvell,pins = "mpp26", "mpp27"; -+ marvell,function = "i2c1"; -+ }; -+ clearfog_sdhci_cd_pins: clearfog-sdhci-cd-pins { -+ marvell,pins = "mpp20"; -+ marvell,function = "gpio"; -+ }; -+ clearfog_sdhci_pins: clearfog-sdhci-pins { -+ marvell,pins = "mpp21", "mpp28", -+ "mpp37", "mpp38", -+ "mpp39", "mpp40"; -+ marvell,function = "sd0"; -+ }; -+ clearfog_spi1_cs_pins: spi1-cs-pins { -+ marvell,pins = "mpp55"; -+ marvell,function = "spi1"; -+ }; -+ mikro_pins: mikro-pins { -+ /* int: mpp22 rst: mpp29 */ -+ marvell,pins = "mpp22", "mpp29"; -+ marvell,function = "gpio"; -+ }; -+ mikro_spi_pins: mikro-spi-pins { -+ marvell,pins = "mpp43"; -+ marvell,function = "spi1"; -+ }; -+ mikro_uart_pins: mikro-uart-pins { -+ marvell,pins = "mpp24", "mpp25"; -+ marvell,function = "ua1"; -+ }; -+ rear_button_pins: rear-button-pins { -+ marvell,pins = "mpp34"; -+ marvell,function = "gpio"; -+ }; -+ }; -+ -+ sata@a8000 { -+ /* pinctrl? */ -+ status = "okay"; -+ }; -+ -+ sata@e0000 { -+ /* pinctrl? */ -+ status = "okay"; -+ }; -+ -+ sdhci@d8000 { -+ bus-width = <4>; -+ cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; -+ no-1-8-v; -+ pinctrl-0 = <&clearfog_sdhci_pins -+ &clearfog_sdhci_cd_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ vmmc = <®_3p3v>; -+ wp-inverted; -+ }; -+ -+ serial@12100 { -+ /* mikrobus uart */ -+ pinctrl-0 = <&mikro_uart_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ }; -+ -+ spi@10680 { -+ /* -+ * We don't seem to have the W25Q32 on the -+ * A1 Rev 2.0 boards, so disable SPI. -+ * CS0: W25Q32 (doesn't appear to be present) -+ * CS1: -+ * CS2: mikrobus -+ */ -+ pinctrl-0 = <&spi1_pins -+ &clearfog_spi1_cs_pins -+ &mikro_spi_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ -+ spi-flash@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "w25q32", "jedec,spi-nor"; -+ reg = <0>; /* Chip select 0 */ -+ spi-max-frequency = <3000000>; -+ status = "disabled"; -+ }; -+ }; -+ -+ usb@58000 { -+ /* CON3, nearest power. */ -+ status = "okay"; -+ }; -+ -+ usb3@f0000 { -+ /* CON2, nearest CPU, USB2 only. */ -+ status = "okay"; -+ }; -+ -+ usb3@f8000 { -+ /* CON7 */ -+ status = "okay"; -+ }; -+ }; -+ -+ pcie-controller { -+ status = "okay"; -+ /* -+ * The two PCIe units are accessible through -+ * the mini-PCIe connectors on the board. -+ */ -+ pcie@2,0 { -+ /* Port 1, Lane 0. CON3, nearest power. */ -+ reset-gpios = <&expander0 1 GPIO_ACTIVE_LOW>; -+ status = "okay"; -+ }; -+ pcie@3,0 { -+ /* Port 2, Lane 0. CON2, nearest CPU. */ -+ reset-gpios = <&expander0 2 GPIO_ACTIVE_LOW>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ dsa@0 { -+ compatible = "marvell,dsa"; -+ dsa,ethernet = <ð1>; -+ dsa,mii-bus = <&mdio>; -+ pinctrl-0 = <&clearfog_dsa0_clk_pins &clearfog_dsa0_pins>; -+ pinctrl-names = "default"; -+ #address-cells = <2>; -+ #size-cells = <0>; -+ -+ switch@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4 0>; -+ -+ port@0 { -+ reg = <0>; -+ label = "lan1"; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ label = "lan2"; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ label = "lan3"; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ label = "lan4"; -+ }; -+ -+ port@4 { -+ reg = <4>; -+ label = "lan5"; -+ }; -+ -+ port@5 { -+ reg = <5>; -+ label = "cpu"; -+ }; -+ -+ port@6 { -+ /* 88E1512 external phy */ -+ reg = <6>; -+ label = "lan6"; -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ }; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ pinctrl-0 = <&rear_button_pins>; -+ pinctrl-names = "default"; -+ -+ button_0 { -+ /* The rear SW3 button */ -+ label = "Rear Button"; -+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; -+ linux,can-disable; -+ linux,code = ; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi -@@ -0,0 +1,115 @@ -+/* -+ * Device Tree file for SolidRun Armada 38x Microsom -+ * -+ * 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. -+ */ -+#include -+#include -+ -+/ { -+ memory { -+ device_type = "memory"; -+ reg = <0x00000000 0x10000000>; /* 256 MB */ -+ }; -+ -+ soc { -+ ranges = ; -+ -+ internal-regs { -+ ethernet@70000 { -+ pinctrl-0 = <&ge0_rgmii_pins>; -+ pinctrl-names = "default"; -+ phy = <&phy_dedicated>; -+ phy-mode = "rgmii-id"; -+ status = "okay"; -+ }; -+ -+ mdio@72004 { -+ /* -+ * Add the phy clock here, so the phy can be -+ * accessed to read its IDs prior to binding -+ * with the driver. -+ */ -+ pinctrl-0 = <&mdio_pins µsom_phy_clk_pins>; -+ pinctrl-names = "default"; -+ -+ phy_dedicated: ethernet-phy@0 { -+ /* -+ * Annoyingly, the marvell phy driver -+ * configures the LED register, rather -+ * than preserving reset-loaded setting. -+ * We undo that rubbish here. -+ */ -+ marvell,reg-init = <3 16 0 0x101e>; -+ reg = <0>; -+ }; -+ }; -+ -+ pinctrl@18000 { -+ microsom_phy_clk_pins: microsom-phy-clk-pins { -+ marvell,pins = "mpp45"; -+ marvell,function = "ref"; -+ }; -+ }; -+ -+ rtc@a3800 { -+ /* -+ * If the rtc doesn't work, run "date reset" -+ * twice in u-boot. -+ */ -+ status = "okay"; -+ }; -+ -+ serial@12000 { -+ pinctrl-0 = <&uart0_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/target/linux/mvebu/patches-4.4/054-ARM-dts-armada-38x-enable-buffer-manager-support-on-.patch b/target/linux/mvebu/patches-4.4/054-ARM-dts-armada-38x-enable-buffer-manager-support-on-.patch deleted file mode 100644 index 705d503c68..0000000000 --- a/target/linux/mvebu/patches-4.4/054-ARM-dts-armada-38x-enable-buffer-manager-support-on-.patch +++ /dev/null @@ -1,256 +0,0 @@ -From c49e99c2b25a412623412a461bb751239208b9b3 Mon Sep 17 00:00:00 2001 -From: Marcin Wojtas -Date: Mon, 14 Mar 2016 09:38:58 +0100 -Subject: [PATCH] ARM: dts: armada-38x: enable buffer manager support on Armada - 38x boards - -Since mvneta driver supports using hardware buffer management (BM), in -order to use it, board files have to be adjusted accordingly. This commit -enables BM on: -* A385-DB-AP - each port has its own pool for long and common pool for -short packets, -* A388-ClearFog - same as above, -* A388-DB - to each port unique 'short' and 'long' pools are mapped, -* A388-GP - same as above. - -Moreover appropriate entry is added to 'soc' node ranges, as well as "okay" -status for 'bm' and 'bm-bppi' (internal SRAM) nodes. - -[gregory.clement@free-electrons.com: add suppport for the ClearFog board] - -Signed-off-by: Marcin Wojtas -Signed-off-by: Gregory CLEMENT -Acked-by: Russell King -Signed-off-by: David S. Miller ---- - arch/arm/boot/dts/armada-385-db-ap.dts | 20 +++++++++++++++++++- - arch/arm/boot/dts/armada-388-clearfog.dts | 6 ++++++ - arch/arm/boot/dts/armada-388-db.dts | 17 ++++++++++++++++- - arch/arm/boot/dts/armada-388-gp.dts | 17 ++++++++++++++++- - arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi | 15 ++++++++++++++- - 5 files changed, 71 insertions(+), 4 deletions(-) - ---- a/arch/arm/boot/dts/armada-385-db-ap.dts -+++ b/arch/arm/boot/dts/armada-385-db-ap.dts -@@ -61,7 +61,8 @@ - ranges = ; -+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 -+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; - - internal-regs { - spi1: spi@10680 { -@@ -138,12 +139,18 @@ - status = "okay"; - phy = <&phy2>; - phy-mode = "sgmii"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <1>; -+ bm,pool-short = <3>; - }; - - ethernet@34000 { - status = "okay"; - phy = <&phy1>; - phy-mode = "sgmii"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <2>; -+ bm,pool-short = <3>; - }; - - ethernet@70000 { -@@ -157,6 +164,13 @@ - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <0>; -+ bm,pool-short = <3>; -+ }; -+ -+ bm@c8000 { -+ status = "okay"; - }; - - nfc: flash@d0000 { -@@ -178,6 +192,10 @@ - }; - }; - -+ bm-bppi { -+ status = "okay"; -+ }; -+ - pcie-controller { - status = "okay"; - ---- a/arch/arm/boot/dts/armada-388-clearfog.dts -+++ b/arch/arm/boot/dts/armada-388-clearfog.dts -@@ -78,6 +78,9 @@ - internal-regs { - ethernet@30000 { - phy-mode = "sgmii"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <2>; -+ bm,pool-short = <1>; - status = "okay"; - - fixed-link { -@@ -88,6 +91,9 @@ - - ethernet@34000 { - phy-mode = "sgmii"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <3>; -+ bm,pool-short = <1>; - status = "okay"; - - fixed-link { ---- a/arch/arm/boot/dts/armada-388-db.dts -+++ b/arch/arm/boot/dts/armada-388-db.dts -@@ -66,7 +66,8 @@ - ranges = ; -+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 -+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; - - internal-regs { - spi@10600 { -@@ -99,6 +100,9 @@ - status = "okay"; - phy = <&phy1>; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <2>; -+ bm,pool-short = <3>; - }; - - usb@58000 { -@@ -109,6 +113,9 @@ - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <0>; -+ bm,pool-short = <1>; - }; - - mdio@72004 { -@@ -129,6 +136,10 @@ - status = "okay"; - }; - -+ bm@c8000 { -+ status = "okay"; -+ }; -+ - flash@d0000 { - status = "okay"; - num-cs = <1>; -@@ -169,6 +180,10 @@ - }; - }; - -+ bm-bppi { -+ status = "okay"; -+ }; -+ - pcie-controller { - status = "okay"; - /* ---- a/arch/arm/boot/dts/armada-388-gp.dts -+++ b/arch/arm/boot/dts/armada-388-gp.dts -@@ -60,7 +60,8 @@ - ranges = ; -+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 -+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; - - internal-regs { - spi@10600 { -@@ -133,6 +134,9 @@ - status = "okay"; - phy = <&phy1>; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <2>; -+ bm,pool-short = <3>; - }; - - /* CON4 */ -@@ -152,6 +156,9 @@ - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <0>; -+ bm,pool-short = <1>; - }; - - -@@ -186,6 +193,10 @@ - }; - }; - -+ bm@c8000 { -+ status = "okay"; -+ }; -+ - sata@e0000 { - pinctrl-names = "default"; - pinctrl-0 = <&sata2_pins>, <&sata3_pins>; -@@ -240,6 +251,10 @@ - }; - }; - -+ bm-bppi { -+ status = "okay"; -+ }; -+ - pcie-controller { - status = "okay"; - /* ---- a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi -+++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi -@@ -58,7 +58,8 @@ - ranges = ; -+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 -+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; - - internal-regs { - ethernet@70000 { -@@ -66,6 +67,9 @@ - pinctrl-names = "default"; - phy = <&phy_dedicated>; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <0>; -+ bm,pool-short = <1>; - status = "okay"; - }; - -@@ -110,6 +114,15 @@ - pinctrl-names = "default"; - status = "okay"; - }; -+ -+ bm@c8000 { -+ status = "okay"; -+ }; - }; -+ -+ bm-bppi { -+ status = "okay"; -+ }; -+ - }; - }; diff --git a/target/linux/mvebu/patches-4.4/055-ARM-dts-armada-388-clearfog-remove-duplicate-mdio-en.patch b/target/linux/mvebu/patches-4.4/055-ARM-dts-armada-388-clearfog-remove-duplicate-mdio-en.patch deleted file mode 100644 index 823d514dfa..0000000000 --- a/target/linux/mvebu/patches-4.4/055-ARM-dts-armada-388-clearfog-remove-duplicate-mdio-en.patch +++ /dev/null @@ -1,41 +0,0 @@ -From d261861ab52623e34a25fe6ae76714456edda033 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 10 Jul 2016 16:27:38 +0100 -Subject: [PATCH] ARM: dts: armada-388-clearfog: remove duplicate mdio entry - -The clearfog DTS should not be defining the on-board phy, this device -is located on the microsom. Remove the duplicated definition. - -Reported-by: Jon Nettleton -Signed-off-by: Russell King -Reviewed-by: Andrew Lunn -Signed-off-by: Gregory CLEMENT ---- - arch/arm/boot/dts/armada-388-clearfog.dts | 16 ---------------- - 1 file changed, 16 deletions(-) - ---- a/arch/arm/boot/dts/armada-388-clearfog.dts -+++ b/arch/arm/boot/dts/armada-388-clearfog.dts -@@ -239,22 +239,6 @@ - status = "okay"; - }; - -- mdio@72004 { -- pinctrl-0 = <&mdio_pins>; -- pinctrl-names = "default"; -- -- phy_dedicated: ethernet-phy@0 { -- /* -- * Annoyingly, the marvell phy driver -- * configures the LED register, rather -- * than preserving reset-loaded setting. -- * We undo that rubbish here. -- */ -- marvell,reg-init = <3 16 0 0x101e>; -- reg = <0>; -- }; -- }; -- - pinctrl@18000 { - clearfog_dsa0_clk_pins: clearfog-dsa0-clk-pins { - marvell,pins = "mpp46"; diff --git a/target/linux/mvebu/patches-4.4/100-find_active_root.patch b/target/linux/mvebu/patches-4.4/100-find_active_root.patch deleted file mode 100644 index c997f5b342..0000000000 --- a/target/linux/mvebu/patches-4.4/100-find_active_root.patch +++ /dev/null @@ -1,62 +0,0 @@ -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_ofpart_partitions(struct mtd_info *master, - struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -@@ -32,6 +34,7 @@ static int parse_ofpart_partitions(struc - 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,15 @@ static int parse_ofpart_partitions(struc - (*pparts)[i].offset = of_read_number(reg, a_cells); - (*pparts)[i].size = of_read_number(reg + a_cells, s_cells); - -- 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); -+ } -+ - (*pparts)[i].name = partname; - - if (of_get_property(pp, "read-only", &len)) -@@ -215,6 +224,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-4.4/102-revert_i2c_delay.patch b/target/linux/mvebu/patches-4.4/102-revert_i2c_delay.patch deleted file mode 100644 index f97bba2ec8..0000000000 --- a/target/linux/mvebu/patches-4.4/102-revert_i2c_delay.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/arch/arm/boot/dts/armada-xp.dtsi -+++ b/arch/arm/boot/dts/armada-xp.dtsi -@@ -98,12 +98,10 @@ - - - i2c0: i2c@11000 { -- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; - reg = <0x11000 0x100>; - }; - - i2c1: i2c@11100 { -- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; - reg = <0x11100 0x100>; - }; - diff --git a/target/linux/mvebu/patches-4.4/103-remove-nand-driver-bug.patch b/target/linux/mvebu/patches-4.4/103-remove-nand-driver-bug.patch deleted file mode 100644 index e9cc027b3c..0000000000 --- a/target/linux/mvebu/patches-4.4/103-remove-nand-driver-bug.patch +++ /dev/null @@ -1,13 +0,0 @@ -Remove a BUG() call that would crash on a race condition that should -otherwise be harmless. - ---- a/drivers/mtd/nand/pxa3xx_nand.c -+++ b/drivers/mtd/nand/pxa3xx_nand.c -@@ -701,7 +701,6 @@ static void handle_data_pio(struct pxa3x - default: - dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, - info->state); -- BUG(); - } - - /* Update buffer pointers for multi-page read/write */ diff --git a/target/linux/mvebu/patches-4.4/104-linksys_mamba_disable_keep_config.patch b/target/linux/mvebu/patches-4.4/104-linksys_mamba_disable_keep_config.patch deleted file mode 100644 index 4c6b3115ed..0000000000 --- a/target/linux/mvebu/patches-4.4/104-linksys_mamba_disable_keep_config.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -@@ -298,7 +298,6 @@ - nand@d0000 { - status = "okay"; - num-cs = <1>; -- marvell,nand-keep-config; - marvell,nand-enable-arbiter; - nand-on-flash-bbt; - nand-ecc-strength = <4>; diff --git a/target/linux/mvebu/patches-4.4/106-enable-bm-on-linksys-devices.patch b/target/linux/mvebu/patches-4.4/106-enable-bm-on-linksys-devices.patch deleted file mode 100644 index e80bc39a69..0000000000 --- a/target/linux/mvebu/patches-4.4/106-enable-bm-on-linksys-devices.patch +++ /dev/null @@ -1,107 +0,0 @@ ---- a/arch/arm/boot/dts/armada-385-linksys.dtsi -+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi -@@ -59,7 +59,8 @@ - ranges = ; -+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 -+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; - - internal-regs { - -@@ -93,6 +94,9 @@ - ethernet@70000 { - status = "okay"; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <0>; -+ bm,pool-short = <3>; - fixed-link { - speed = <1000>; - full-duplex; -@@ -102,6 +106,9 @@ - ethernet@34000 { - status = "okay"; - phy-mode = "sgmii"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <2>; -+ bm,pool-short = <3>; - fixed-link { - speed = <1000>; - full-duplex; -@@ -112,6 +119,10 @@ - status = "okay"; - }; - -+ bm@c8000 { -+ status = "okay"; -+ }; -+ - sata@a8000 { - status = "okay"; - }; -@@ -198,6 +209,10 @@ - }; - }; - -+ bm-bppi { -+ status = "okay"; -+ }; -+ - pcie-controller { - status = "okay"; - ---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -@@ -71,7 +71,8 @@ - ranges = ; -+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000 -+ MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>; - - pcie-controller { - status = "okay"; -@@ -205,6 +206,9 @@ - pinctrl-names = "default"; - status = "okay"; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <0>; -+ bm,pool-short = <3>; - fixed-link { - speed = <1000>; - full-duplex; -@@ -216,12 +220,19 @@ - pinctrl-names = "default"; - status = "okay"; - phy-mode = "rgmii-id"; -+ buffer-manager = <&bm>; -+ bm,pool-long = <1>; -+ bm,pool-short = <3>; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - -+ bm@c0000 { -+ status = "okay"; -+ }; -+ - /* USB part of the eSATA/USB 2.0 port */ - usb@50000 { - status = "okay"; -@@ -379,6 +390,10 @@ - }; - }; - }; -+ -+ bm-bppi { -+ status = "okay"; -+ }; - }; - - gpio_keys { diff --git a/target/linux/mvebu/patches-4.4/110-pxa3xxx_revert_irq_thread.patch b/target/linux/mvebu/patches-4.4/110-pxa3xxx_revert_irq_thread.patch deleted file mode 100644 index 30da17deb9..0000000000 --- a/target/linux/mvebu/patches-4.4/110-pxa3xxx_revert_irq_thread.patch +++ /dev/null @@ -1,69 +0,0 @@ -Revert "mtd: pxa3xx-nand: handle PIO in threaded interrupt" - -This reverts commit 24542257a3b987025d4b998ec2d15e556c98ad3f -This upstream change has been causing spurious timeouts on accesses -to the NAND flash if something else on the system is causing -significant latency. - -Nothing guarantees that the thread will run in time, so the -usual timeout is unreliable. - -Signed-off-by: Felix Fietkau - ---- a/drivers/mtd/nand/pxa3xx_nand.c -+++ b/drivers/mtd/nand/pxa3xx_nand.c -@@ -765,24 +765,11 @@ static void start_data_dma(struct pxa3xx - __func__, direction, info->dma_cookie, info->sg.length); - } - --static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data) --{ -- struct pxa3xx_nand_info *info = data; -- -- handle_data_pio(info); -- -- info->state = STATE_CMD_DONE; -- nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ); -- -- return IRQ_HANDLED; --} -- - static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) - { - struct pxa3xx_nand_info *info = devid; - unsigned int status, is_completed = 0, is_ready = 0; - unsigned int ready, cmd_done; -- irqreturn_t ret = IRQ_HANDLED; - - if (info->cs == 0) { - ready = NDSR_FLASH_RDY; -@@ -824,8 +811,7 @@ static irqreturn_t pxa3xx_nand_irq(int i - } else { - info->state = (status & NDSR_RDDREQ) ? - STATE_PIO_READING : STATE_PIO_WRITING; -- ret = IRQ_WAKE_THREAD; -- goto NORMAL_IRQ_EXIT; -+ handle_data_pio(info); - } - } - if (status & cmd_done) { -@@ -870,7 +856,7 @@ static irqreturn_t pxa3xx_nand_irq(int i - if (is_ready) - complete(&info->dev_ready); - NORMAL_IRQ_EXIT: -- return ret; -+ return IRQ_HANDLED; - } - - static inline int is_buf_blank(uint8_t *buf, size_t len) -@@ -1849,9 +1835,7 @@ static int alloc_nand_resource(struct pl - /* initialize all interrupts to be disabled */ - disable_int(info, NDSR_MASK); - -- ret = request_threaded_irq(irq, pxa3xx_nand_irq, -- pxa3xx_nand_irq_thread, IRQF_ONESHOT, -- pdev->name, info); -+ ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info); - if (ret < 0) { - dev_err(&pdev->dev, "failed to request IRQ\n"); - goto fail_free_buf; diff --git a/target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch b/target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch deleted file mode 100644 index 00745f1c9b..0000000000 --- a/target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch +++ /dev/null @@ -1,306 +0,0 @@ -From 4d5621372f6e7ddbfd5879602f82073987bcc722 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 20 Sep 2015 09:57:10 +0100 -Subject: [PATCH 709/744] phy: move fixed_phy MII register generation to a - library - -Move the fixed_phy MII register generation to a library to allow other -software phy implementations to use this code. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/Kconfig | 4 ++ - drivers/net/phy/Makefile | 3 +- - drivers/net/phy/fixed_phy.c | 95 ++------------------------------- - drivers/net/phy/swphy.c | 126 ++++++++++++++++++++++++++++++++++++++++++++ - drivers/net/phy/swphy.h | 8 +++ - 5 files changed, 143 insertions(+), 93 deletions(-) - create mode 100644 drivers/net/phy/swphy.c - create mode 100644 drivers/net/phy/swphy.h - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -26,6 +26,9 @@ config SWCONFIG_LEDS - bool "Switch LED trigger support" - depends on (SWCONFIG && LEDS_TRIGGERS) - -+config SWPHY -+ bool -+ - comment "MII PHY device drivers" - - config AQUANTIA_PHY -@@ -205,6 +208,7 @@ config RTL8306_PHY - config FIXED_PHY - tristate "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB -+ select SWPHY - ---help--- - Adds the platform "fixed" MDIO Bus to cover the boards that use - PHYs that are not connected to the real MDIO bus. ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -1,6 +1,7 @@ - # Makefile for Linux PHY drivers - --libphy-objs := phy.o phy_device.o mdio_bus.o -+libphy-y := phy.o phy_device.o mdio_bus.o -+libphy-$(CONFIG_SWPHY) += swphy.o - - obj-$(CONFIG_MDIO_BOARDINFO) += mdio-boardinfo.o - ---- a/drivers/net/phy/fixed_phy.c -+++ b/drivers/net/phy/fixed_phy.c -@@ -24,6 +24,8 @@ - #include - #include - -+#include "swphy.h" -+ - #define MII_REGS_NUM 29 - - struct fixed_mdio_bus { -@@ -49,101 +51,10 @@ static struct fixed_mdio_bus platform_fm - - static int fixed_phy_update_regs(struct fixed_phy *fp) - { -- u16 bmsr = BMSR_ANEGCAPABLE; -- u16 bmcr = 0; -- u16 lpagb = 0; -- u16 lpa = 0; -- - if (gpio_is_valid(fp->link_gpio)) - fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); - -- if (fp->status.duplex) { -- switch (fp->status.speed) { -- case 1000: -- bmsr |= BMSR_ESTATEN; -- break; -- case 100: -- bmsr |= BMSR_100FULL; -- break; -- case 10: -- bmsr |= BMSR_10FULL; -- break; -- default: -- break; -- } -- } else { -- switch (fp->status.speed) { -- case 1000: -- bmsr |= BMSR_ESTATEN; -- break; -- case 100: -- bmsr |= BMSR_100HALF; -- break; -- case 10: -- bmsr |= BMSR_10HALF; -- break; -- default: -- break; -- } -- } -- -- if (fp->status.link) { -- bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE; -- -- if (fp->status.duplex) { -- bmcr |= BMCR_FULLDPLX; -- -- switch (fp->status.speed) { -- case 1000: -- bmcr |= BMCR_SPEED1000; -- lpagb |= LPA_1000FULL; -- break; -- case 100: -- bmcr |= BMCR_SPEED100; -- lpa |= LPA_100FULL; -- break; -- case 10: -- lpa |= LPA_10FULL; -- break; -- default: -- pr_warn("fixed phy: unknown speed\n"); -- return -EINVAL; -- } -- } else { -- switch (fp->status.speed) { -- case 1000: -- bmcr |= BMCR_SPEED1000; -- lpagb |= LPA_1000HALF; -- break; -- case 100: -- bmcr |= BMCR_SPEED100; -- lpa |= LPA_100HALF; -- break; -- case 10: -- lpa |= LPA_10HALF; -- break; -- default: -- pr_warn("fixed phy: unknown speed\n"); -- return -EINVAL; -- } -- } -- -- if (fp->status.pause) -- lpa |= LPA_PAUSE_CAP; -- -- if (fp->status.asym_pause) -- lpa |= LPA_PAUSE_ASYM; -- } -- -- fp->regs[MII_PHYSID1] = 0; -- fp->regs[MII_PHYSID2] = 0; -- -- fp->regs[MII_BMSR] = bmsr; -- fp->regs[MII_BMCR] = bmcr; -- fp->regs[MII_LPA] = lpa; -- fp->regs[MII_STAT1000] = lpagb; -- -- return 0; -+ return swphy_update_regs(fp->regs, &fp->status); - } - - static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num) ---- /dev/null -+++ b/drivers/net/phy/swphy.c -@@ -0,0 +1,126 @@ -+/* -+ * Software PHY emulation -+ * -+ * Code taken from fixed_phy.c by Russell King -+ * -+ * Author: Vitaly Bordug -+ * Anton Vorontsov -+ * -+ * Copyright (c) 2006-2007 MontaVista Software, Inc. -+ * -+ * 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 "swphy.h" -+ -+/** -+ * swphy_update_regs - update MII register array with fixed phy state -+ * @regs: array of 32 registers to update -+ * @state: fixed phy status -+ * -+ * Update the array of MII registers with the fixed phy link, speed, -+ * duplex and pause mode settings. -+ */ -+int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state) -+{ -+ u16 bmsr = BMSR_ANEGCAPABLE; -+ u16 bmcr = 0; -+ u16 lpagb = 0; -+ u16 lpa = 0; -+ -+ if (state->duplex) { -+ switch (state->speed) { -+ case 1000: -+ bmsr |= BMSR_ESTATEN; -+ break; -+ case 100: -+ bmsr |= BMSR_100FULL; -+ break; -+ case 10: -+ bmsr |= BMSR_10FULL; -+ break; -+ default: -+ break; -+ } -+ } else { -+ switch (state->speed) { -+ case 1000: -+ bmsr |= BMSR_ESTATEN; -+ break; -+ case 100: -+ bmsr |= BMSR_100HALF; -+ break; -+ case 10: -+ bmsr |= BMSR_10HALF; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ if (state->link) { -+ bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE; -+ -+ if (state->duplex) { -+ bmcr |= BMCR_FULLDPLX; -+ -+ switch (state->speed) { -+ case 1000: -+ bmcr |= BMCR_SPEED1000; -+ lpagb |= LPA_1000FULL; -+ break; -+ case 100: -+ bmcr |= BMCR_SPEED100; -+ lpa |= LPA_100FULL; -+ break; -+ case 10: -+ lpa |= LPA_10FULL; -+ break; -+ default: -+ pr_warn("swphy: unknown speed\n"); -+ return -EINVAL; -+ } -+ } else { -+ switch (state->speed) { -+ case 1000: -+ bmcr |= BMCR_SPEED1000; -+ lpagb |= LPA_1000HALF; -+ break; -+ case 100: -+ bmcr |= BMCR_SPEED100; -+ lpa |= LPA_100HALF; -+ break; -+ case 10: -+ lpa |= LPA_10HALF; -+ break; -+ default: -+ pr_warn("swphy: unknown speed\n"); -+ return -EINVAL; -+ } -+ } -+ -+ if (state->pause) -+ lpa |= LPA_PAUSE_CAP; -+ -+ if (state->asym_pause) -+ lpa |= LPA_PAUSE_ASYM; -+ } -+ -+ regs[MII_PHYSID1] = 0; -+ regs[MII_PHYSID2] = 0; -+ -+ regs[MII_BMSR] = bmsr; -+ regs[MII_BMCR] = bmcr; -+ regs[MII_LPA] = lpa; -+ regs[MII_STAT1000] = lpagb; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(swphy_update_regs); ---- /dev/null -+++ b/drivers/net/phy/swphy.h -@@ -0,0 +1,8 @@ -+#ifndef SWPHY_H -+#define SWPHY_H -+ -+struct fixed_phy_status; -+ -+int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state); -+ -+#endif diff --git a/target/linux/mvebu/patches-4.4/121-phy-convert-swphy-register-generation-to-tabular-for.patch b/target/linux/mvebu/patches-4.4/121-phy-convert-swphy-register-generation-to-tabular-for.patch deleted file mode 100644 index 0d689f39a3..0000000000 --- a/target/linux/mvebu/patches-4.4/121-phy-convert-swphy-register-generation-to-tabular-for.patch +++ /dev/null @@ -1,203 +0,0 @@ -From cd834fe430f030a63bfa9277bba194e8eef4dbd0 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 20 Sep 2015 10:18:59 +0100 -Subject: [PATCH 710/744] phy: convert swphy register generation to tabular - form - -Convert the swphy register generation to tabular form which allows us -to eliminate multiple switch() statements. This results in a smaller -object code size, more efficient, and easier to add support for faster -speeds. - -Before: - -Idx Name Size VMA LMA File off Algn - 0 .text 00000164 00000000 00000000 00000034 2**2 - - text data bss dec hex filename - 388 0 0 388 184 swphy.o - -After: - -Idx Name Size VMA LMA File off Algn - 0 .text 000000fc 00000000 00000000 00000034 2**2 - 5 .rodata 00000028 00000000 00000000 00000138 2**2 - - text data bss dec hex filename - 324 0 0 324 144 swphy.o - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/swphy.c | 143 ++++++++++++++++++++++++++---------------------- - 1 file changed, 78 insertions(+), 65 deletions(-) - ---- a/drivers/net/phy/swphy.c -+++ b/drivers/net/phy/swphy.c -@@ -20,6 +20,72 @@ - - #include "swphy.h" - -+struct swmii_regs { -+ u16 bmcr; -+ u16 bmsr; -+ u16 lpa; -+ u16 lpagb; -+}; -+ -+enum { -+ SWMII_SPEED_10 = 0, -+ SWMII_SPEED_100, -+ SWMII_SPEED_1000, -+ SWMII_DUPLEX_HALF = 0, -+ SWMII_DUPLEX_FULL, -+}; -+ -+/* -+ * These two tables get bitwise-anded together to produce the final result. -+ * This means the speed table must contain both duplex settings, and the -+ * duplex table must contain all speed settings. -+ */ -+static const struct swmii_regs speed[] = { -+ [SWMII_SPEED_10] = { -+ .bmcr = BMCR_FULLDPLX, -+ .lpa = LPA_10FULL | LPA_10HALF, -+ }, -+ [SWMII_SPEED_100] = { -+ .bmcr = BMCR_FULLDPLX | BMCR_SPEED100, -+ .bmsr = BMSR_100FULL | BMSR_100HALF, -+ .lpa = LPA_100FULL | LPA_100HALF, -+ }, -+ [SWMII_SPEED_1000] = { -+ .bmcr = BMCR_FULLDPLX | BMCR_SPEED1000, -+ .bmsr = BMSR_ESTATEN, -+ .lpagb = LPA_1000FULL | LPA_1000HALF, -+ }, -+}; -+ -+static const struct swmii_regs duplex[] = { -+ [SWMII_DUPLEX_HALF] = { -+ .bmcr = ~BMCR_FULLDPLX, -+ .bmsr = BMSR_ESTATEN | BMSR_100HALF, -+ .lpa = LPA_10HALF | LPA_100HALF, -+ .lpagb = LPA_1000HALF, -+ }, -+ [SWMII_DUPLEX_FULL] = { -+ .bmcr = ~0, -+ .bmsr = BMSR_ESTATEN | BMSR_100FULL, -+ .lpa = LPA_10FULL | LPA_100FULL, -+ .lpagb = LPA_1000FULL, -+ }, -+}; -+ -+static int swphy_decode_speed(int speed) -+{ -+ switch (speed) { -+ case 1000: -+ return SWMII_SPEED_1000; -+ case 100: -+ return SWMII_SPEED_100; -+ case 10: -+ return SWMII_SPEED_10; -+ default: -+ return -EINVAL; -+ } -+} -+ - /** - * swphy_update_regs - update MII register array with fixed phy state - * @regs: array of 32 registers to update -@@ -30,81 +96,28 @@ - */ - int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state) - { -+ int speed_index, duplex_index; - u16 bmsr = BMSR_ANEGCAPABLE; - u16 bmcr = 0; - u16 lpagb = 0; - u16 lpa = 0; - -- if (state->duplex) { -- switch (state->speed) { -- case 1000: -- bmsr |= BMSR_ESTATEN; -- break; -- case 100: -- bmsr |= BMSR_100FULL; -- break; -- case 10: -- bmsr |= BMSR_10FULL; -- break; -- default: -- break; -- } -- } else { -- switch (state->speed) { -- case 1000: -- bmsr |= BMSR_ESTATEN; -- break; -- case 100: -- bmsr |= BMSR_100HALF; -- break; -- case 10: -- bmsr |= BMSR_10HALF; -- break; -- default: -- break; -- } -+ speed_index = swphy_decode_speed(state->speed); -+ if (speed_index < 0) { -+ pr_warn("swphy: unknown speed\n"); -+ return -EINVAL; - } - -+ duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF; -+ -+ bmsr |= speed[speed_index].bmsr & duplex[duplex_index].bmsr; -+ - if (state->link) { - bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE; - -- if (state->duplex) { -- bmcr |= BMCR_FULLDPLX; -- -- switch (state->speed) { -- case 1000: -- bmcr |= BMCR_SPEED1000; -- lpagb |= LPA_1000FULL; -- break; -- case 100: -- bmcr |= BMCR_SPEED100; -- lpa |= LPA_100FULL; -- break; -- case 10: -- lpa |= LPA_10FULL; -- break; -- default: -- pr_warn("swphy: unknown speed\n"); -- return -EINVAL; -- } -- } else { -- switch (state->speed) { -- case 1000: -- bmcr |= BMCR_SPEED1000; -- lpagb |= LPA_1000HALF; -- break; -- case 100: -- bmcr |= BMCR_SPEED100; -- lpa |= LPA_100HALF; -- break; -- case 10: -- lpa |= LPA_10HALF; -- break; -- default: -- pr_warn("swphy: unknown speed\n"); -- return -EINVAL; -- } -- } -+ bmcr |= speed[speed_index].bmcr & duplex[duplex_index].bmcr; -+ lpa |= speed[speed_index].lpa & duplex[duplex_index].lpa; -+ lpagb |= speed[speed_index].lpagb & duplex[duplex_index].lpagb; - - if (state->pause) - lpa |= LPA_PAUSE_CAP; diff --git a/target/linux/mvebu/patches-4.4/122-phy-separate-swphy-state-validation-from-register-ge.patch b/target/linux/mvebu/patches-4.4/122-phy-separate-swphy-state-validation-from-register-ge.patch deleted file mode 100644 index 4b332cc8b7..0000000000 --- a/target/linux/mvebu/patches-4.4/122-phy-separate-swphy-state-validation-from-register-ge.patch +++ /dev/null @@ -1,138 +0,0 @@ -From e07630ad84c7dc145863f079f108154fb7c975e7 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 20 Sep 2015 11:12:15 +0100 -Subject: [PATCH 711/744] phy: separate swphy state validation from register - generation - -Separate out the generation of MII registers from the state validation. -This allows us to simplify the error handing in fixed_phy() by allowing -earlier error detection. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/fixed_phy.c | 15 +++++++-------- - drivers/net/phy/swphy.c | 33 ++++++++++++++++++++++++++------- - drivers/net/phy/swphy.h | 3 ++- - 3 files changed, 35 insertions(+), 16 deletions(-) - ---- a/drivers/net/phy/fixed_phy.c -+++ b/drivers/net/phy/fixed_phy.c -@@ -49,12 +49,12 @@ static struct fixed_mdio_bus platform_fm - .phys = LIST_HEAD_INIT(platform_fmb.phys), - }; - --static int fixed_phy_update_regs(struct fixed_phy *fp) -+static void fixed_phy_update_regs(struct fixed_phy *fp) - { - if (gpio_is_valid(fp->link_gpio)) - fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); - -- return swphy_update_regs(fp->regs, &fp->status); -+ swphy_update_regs(fp->regs, &fp->status); - } - - static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num) -@@ -161,6 +161,10 @@ int fixed_phy_add(unsigned int irq, int - struct fixed_mdio_bus *fmb = &platform_fmb; - struct fixed_phy *fp; - -+ ret = swphy_validate_state(status); -+ if (ret < 0) -+ return ret; -+ - fp = kzalloc(sizeof(*fp), GFP_KERNEL); - if (!fp) - return -ENOMEM; -@@ -180,17 +184,12 @@ int fixed_phy_add(unsigned int irq, int - goto err_regs; - } - -- ret = fixed_phy_update_regs(fp); -- if (ret) -- goto err_gpio; -+ fixed_phy_update_regs(fp); - - list_add_tail(&fp->node, &fmb->phys); - - return 0; - --err_gpio: -- if (gpio_is_valid(fp->link_gpio)) -- gpio_free(fp->link_gpio); - err_regs: - kfree(fp); - return ret; ---- a/drivers/net/phy/swphy.c -+++ b/drivers/net/phy/swphy.c -@@ -87,6 +87,29 @@ static int swphy_decode_speed(int speed) - } - - /** -+ * swphy_validate_state - validate the software phy status -+ * @state: software phy status -+ * -+ * This checks that we can represent the state stored in @state can be -+ * represented in the emulated MII registers. Returns 0 if it can, -+ * otherwise returns -EINVAL. -+ */ -+int swphy_validate_state(const struct fixed_phy_status *state) -+{ -+ int err; -+ -+ if (state->link) { -+ err = swphy_decode_speed(state->speed); -+ if (err < 0) { -+ pr_warn("swphy: unknown speed\n"); -+ return -EINVAL; -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL_GPL(swphy_validate_state); -+ -+/** - * swphy_update_regs - update MII register array with fixed phy state - * @regs: array of 32 registers to update - * @state: fixed phy status -@@ -94,7 +117,7 @@ static int swphy_decode_speed(int speed) - * Update the array of MII registers with the fixed phy link, speed, - * duplex and pause mode settings. - */ --int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state) -+void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state) - { - int speed_index, duplex_index; - u16 bmsr = BMSR_ANEGCAPABLE; -@@ -103,10 +126,8 @@ int swphy_update_regs(u16 *regs, const s - u16 lpa = 0; - - speed_index = swphy_decode_speed(state->speed); -- if (speed_index < 0) { -- pr_warn("swphy: unknown speed\n"); -- return -EINVAL; -- } -+ if (WARN_ON(speed_index < 0)) -+ return; - - duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF; - -@@ -133,7 +154,5 @@ int swphy_update_regs(u16 *regs, const s - regs[MII_BMCR] = bmcr; - regs[MII_LPA] = lpa; - regs[MII_STAT1000] = lpagb; -- -- return 0; - } - EXPORT_SYMBOL_GPL(swphy_update_regs); ---- a/drivers/net/phy/swphy.h -+++ b/drivers/net/phy/swphy.h -@@ -3,6 +3,7 @@ - - struct fixed_phy_status; - --int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state); -+int swphy_validate_state(const struct fixed_phy_status *state); -+void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state); - - #endif diff --git a/target/linux/mvebu/patches-4.4/123-phy-generate-swphy-registers-on-the-fly.patch b/target/linux/mvebu/patches-4.4/123-phy-generate-swphy-registers-on-the-fly.patch deleted file mode 100644 index 218b902e7d..0000000000 --- a/target/linux/mvebu/patches-4.4/123-phy-generate-swphy-registers-on-the-fly.patch +++ /dev/null @@ -1,204 +0,0 @@ -From e0f33a88243329da1aa5a90fe10ab25c9fb0a091 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 20 Sep 2015 11:28:39 +0100 -Subject: [PATCH 712/744] phy: generate swphy registers on the fly - -Generate software phy registers as and when requested, rather than -duplicating the state in fixed_phy. This allows us to eliminate -the duplicate storage of of the same data, which is only different -in format. - -As fixed_phy_update_regs() no longer updates register state, rename -it to fixed_phy_update(). - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/fixed_phy.c | 31 +++++------------------------- - drivers/net/phy/swphy.c | 47 ++++++++++++++++++++++++++++++++------------- - drivers/net/phy/swphy.h | 2 +- - 3 files changed, 40 insertions(+), 40 deletions(-) - ---- a/drivers/net/phy/fixed_phy.c -+++ b/drivers/net/phy/fixed_phy.c -@@ -26,8 +26,6 @@ - - #include "swphy.h" - --#define MII_REGS_NUM 29 -- - struct fixed_mdio_bus { - int irqs[PHY_MAX_ADDR]; - struct mii_bus *mii_bus; -@@ -36,7 +34,6 @@ struct fixed_mdio_bus { - - struct fixed_phy { - int addr; -- u16 regs[MII_REGS_NUM]; - struct phy_device *phydev; - struct fixed_phy_status status; - int (*link_update)(struct net_device *, struct fixed_phy_status *); -@@ -49,12 +46,10 @@ static struct fixed_mdio_bus platform_fm - .phys = LIST_HEAD_INIT(platform_fmb.phys), - }; - --static void fixed_phy_update_regs(struct fixed_phy *fp) -+static void fixed_phy_update(struct fixed_phy *fp) - { - if (gpio_is_valid(fp->link_gpio)) - fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); -- -- swphy_update_regs(fp->regs, &fp->status); - } - - static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num) -@@ -62,29 +57,15 @@ static int fixed_mdio_read(struct mii_bu - struct fixed_mdio_bus *fmb = bus->priv; - struct fixed_phy *fp; - -- if (reg_num >= MII_REGS_NUM) -- return -1; -- -- /* We do not support emulating Clause 45 over Clause 22 register reads -- * return an error instead of bogus data. -- */ -- switch (reg_num) { -- case MII_MMD_CTRL: -- case MII_MMD_DATA: -- return -1; -- default: -- break; -- } -- - list_for_each_entry(fp, &fmb->phys, node) { - if (fp->addr == phy_addr) { - /* Issue callback if user registered it. */ - if (fp->link_update) { - fp->link_update(fp->phydev->attached_dev, - &fp->status); -- fixed_phy_update_regs(fp); -+ fixed_phy_update(fp); - } -- return fp->regs[reg_num]; -+ return swphy_read_reg(reg_num, &fp->status); - } - } - -@@ -144,7 +125,7 @@ int fixed_phy_update_state(struct phy_de - _UPD(pause); - _UPD(asym_pause); - #undef _UPD -- fixed_phy_update_regs(fp); -+ fixed_phy_update(fp); - return 0; - } - } -@@ -169,8 +150,6 @@ int fixed_phy_add(unsigned int irq, int - if (!fp) - return -ENOMEM; - -- memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM); -- - fmb->irqs[phy_addr] = irq; - - fp->addr = phy_addr; -@@ -184,7 +163,7 @@ int fixed_phy_add(unsigned int irq, int - goto err_regs; - } - -- fixed_phy_update_regs(fp); -+ fixed_phy_update(fp); - - list_add_tail(&fp->node, &fmb->phys); - ---- a/drivers/net/phy/swphy.c -+++ b/drivers/net/phy/swphy.c -@@ -20,6 +20,8 @@ - - #include "swphy.h" - -+#define MII_REGS_NUM 29 -+ - struct swmii_regs { - u16 bmcr; - u16 bmsr; -@@ -110,14 +112,13 @@ int swphy_validate_state(const struct fi - EXPORT_SYMBOL_GPL(swphy_validate_state); - - /** -- * swphy_update_regs - update MII register array with fixed phy state -- * @regs: array of 32 registers to update -+ * swphy_read_reg - return a MII register from the fixed phy state -+ * @reg: MII register - * @state: fixed phy status - * -- * Update the array of MII registers with the fixed phy link, speed, -- * duplex and pause mode settings. -+ * Return the MII @reg register generated from the fixed phy state @state. - */ --void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state) -+int swphy_read_reg(int reg, const struct fixed_phy_status *state) - { - int speed_index, duplex_index; - u16 bmsr = BMSR_ANEGCAPABLE; -@@ -125,9 +126,12 @@ void swphy_update_regs(u16 *regs, const - u16 lpagb = 0; - u16 lpa = 0; - -+ if (reg > MII_REGS_NUM) -+ return -1; -+ - speed_index = swphy_decode_speed(state->speed); - if (WARN_ON(speed_index < 0)) -- return; -+ return 0; - - duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF; - -@@ -147,12 +151,29 @@ void swphy_update_regs(u16 *regs, const - lpa |= LPA_PAUSE_ASYM; - } - -- regs[MII_PHYSID1] = 0; -- regs[MII_PHYSID2] = 0; -+ switch (reg) { -+ case MII_BMCR: -+ return bmcr; -+ case MII_BMSR: -+ return bmsr; -+ case MII_PHYSID1: -+ case MII_PHYSID2: -+ return 0; -+ case MII_LPA: -+ return lpa; -+ case MII_STAT1000: -+ return lpagb; -+ -+ /* -+ * We do not support emulating Clause 45 over Clause 22 register -+ * reads. Return an error instead of bogus data. -+ */ -+ case MII_MMD_CTRL: -+ case MII_MMD_DATA: -+ return -1; - -- regs[MII_BMSR] = bmsr; -- regs[MII_BMCR] = bmcr; -- regs[MII_LPA] = lpa; -- regs[MII_STAT1000] = lpagb; -+ default: -+ return 0xffff; -+ } - } --EXPORT_SYMBOL_GPL(swphy_update_regs); -+EXPORT_SYMBOL_GPL(swphy_read_reg); ---- a/drivers/net/phy/swphy.h -+++ b/drivers/net/phy/swphy.h -@@ -4,6 +4,6 @@ - struct fixed_phy_status; - - int swphy_validate_state(const struct fixed_phy_status *state); --void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state); -+int swphy_read_reg(int reg, const struct fixed_phy_status *state); - - #endif diff --git a/target/linux/mvebu/patches-4.4/124-phy-improve-safety-of-fixed-phy-MII-register-reading.patch b/target/linux/mvebu/patches-4.4/124-phy-improve-safety-of-fixed-phy-MII-register-reading.patch deleted file mode 100644 index 5167b07101..0000000000 --- a/target/linux/mvebu/patches-4.4/124-phy-improve-safety-of-fixed-phy-MII-register-reading.patch +++ /dev/null @@ -1,92 +0,0 @@ -From c36739c3cfd277a4cc9820a29dd0f4b7fbac795b Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 20 Sep 2015 18:31:36 +0100 -Subject: [PATCH 713/744] phy: improve safety of fixed-phy MII register reading - -There is no prevention of a concurrent call to both fixed_mdio_read() -and fixed_phy_update_state(), which can result in the state being -modified while it's being inspected. Fix this by using a seqcount -to detect modifications, and memcpy()ing the state. - -We remain slightly naughty here, calling link_update() and updating -the link status within the read-side loop - which would need rework -of the design to change. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/fixed_phy.c | 28 +++++++++++++++++++++------- - 1 file changed, 21 insertions(+), 7 deletions(-) - ---- a/drivers/net/phy/fixed_phy.c -+++ b/drivers/net/phy/fixed_phy.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include "swphy.h" - -@@ -35,6 +36,7 @@ struct fixed_mdio_bus { - struct fixed_phy { - int addr; - struct phy_device *phydev; -+ seqcount_t seqcount; - struct fixed_phy_status status; - int (*link_update)(struct net_device *, struct fixed_phy_status *); - struct list_head node; -@@ -59,13 +61,21 @@ static int fixed_mdio_read(struct mii_bu - - list_for_each_entry(fp, &fmb->phys, node) { - if (fp->addr == phy_addr) { -- /* Issue callback if user registered it. */ -- if (fp->link_update) { -- fp->link_update(fp->phydev->attached_dev, -- &fp->status); -- fixed_phy_update(fp); -- } -- return swphy_read_reg(reg_num, &fp->status); -+ struct fixed_phy_status state; -+ int s; -+ -+ do { -+ s = read_seqcount_begin(&fp->seqcount); -+ /* Issue callback if user registered it. */ -+ if (fp->link_update) { -+ fp->link_update(fp->phydev->attached_dev, -+ &fp->status); -+ fixed_phy_update(fp); -+ } -+ state = fp->status; -+ } while (read_seqcount_retry(&fp->seqcount, s)); -+ -+ return swphy_read_reg(reg_num, &state); - } - } - -@@ -117,6 +127,7 @@ int fixed_phy_update_state(struct phy_de - - list_for_each_entry(fp, &fmb->phys, node) { - if (fp->addr == phydev->addr) { -+ write_seqcount_begin(&fp->seqcount); - #define _UPD(x) if (changed->x) \ - fp->status.x = status->x - _UPD(link); -@@ -126,6 +137,7 @@ int fixed_phy_update_state(struct phy_de - _UPD(asym_pause); - #undef _UPD - fixed_phy_update(fp); -+ write_seqcount_end(&fp->seqcount); - return 0; - } - } -@@ -150,6 +162,8 @@ int fixed_phy_add(unsigned int irq, int - if (!fp) - return -ENOMEM; - -+ seqcount_init(&fp->seqcount); -+ - fmb->irqs[phy_addr] = irq; - - fp->addr = phy_addr; diff --git a/target/linux/mvebu/patches-4.4/125-phy-provide-a-hook-for-link-up-link-down-events.patch b/target/linux/mvebu/patches-4.4/125-phy-provide-a-hook-for-link-up-link-down-events.patch deleted file mode 100644 index b00968961f..0000000000 --- a/target/linux/mvebu/patches-4.4/125-phy-provide-a-hook-for-link-up-link-down-events.patch +++ /dev/null @@ -1,183 +0,0 @@ -From d8b4e728f598d3c8a9b219d4679d5de350caa082 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Fri, 18 Sep 2015 14:42:16 +0100 -Subject: [PATCH 714/744] phy: provide a hook for link up/link down events - -Sometimes, we need to do additional work between the PHY coming up and -marking the carrier present - for example, we may need to wait for the -PHY to MAC link to finish negotiation. This changes phylib to provide -a notification function pointer which avoids the built-in -netif_carrier_on() and netif_carrier_off() functions. - -Standard ->adjust_link functionality is provided by hooking a helper -into the new ->phy_link_change method. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/phy.c | 42 ++++++++++++++++++++++-------------------- - drivers/net/phy/phy_device.c | 14 ++++++++++++++ - include/linux/phy.h | 1 + - 3 files changed, 37 insertions(+), 20 deletions(-) - ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -849,6 +849,16 @@ void phy_start(struct phy_device *phydev - } - EXPORT_SYMBOL(phy_start); - -+static void phy_link_up(struct phy_device *phydev) -+{ -+ phydev->phy_link_change(phydev, true, true); -+} -+ -+static void phy_link_down(struct phy_device *phydev, bool do_carrier) -+{ -+ phydev->phy_link_change(phydev, false, do_carrier); -+} -+ - /** - * phy_state_machine - Handle the state machine - * @work: work_struct that describes the work to be done -@@ -890,8 +900,7 @@ void phy_state_machine(struct work_struc - /* If the link is down, give up on negotiation for now */ - if (!phydev->link) { - phydev->state = PHY_NOLINK; -- netif_carrier_off(phydev->attached_dev); -- phydev->adjust_link(phydev->attached_dev); -+ phy_link_down(phydev, true); - break; - } - -@@ -903,9 +912,7 @@ void phy_state_machine(struct work_struc - /* If AN is done, we're running */ - if (err > 0) { - phydev->state = PHY_RUNNING; -- netif_carrier_on(phydev->attached_dev); -- phydev->adjust_link(phydev->attached_dev); -- -+ phy_link_up(phydev); - } else if (0 == phydev->link_timeout--) - needs_aneg = true; - break; -@@ -930,8 +937,7 @@ void phy_state_machine(struct work_struc - } - } - phydev->state = PHY_RUNNING; -- netif_carrier_on(phydev->attached_dev); -- phydev->adjust_link(phydev->attached_dev); -+ phy_link_up(phydev); - } - break; - case PHY_FORCING: -@@ -941,13 +947,12 @@ void phy_state_machine(struct work_struc - - if (phydev->link) { - phydev->state = PHY_RUNNING; -- netif_carrier_on(phydev->attached_dev); -+ phy_link_up(phydev); - } else { - if (0 == phydev->link_timeout--) - needs_aneg = true; -+ phy_link_down(phydev, false); - } -- -- phydev->adjust_link(phydev->attached_dev); - break; - case PHY_RUNNING: - /* Only register a CHANGE if we are polling or ignoring -@@ -970,14 +975,12 @@ void phy_state_machine(struct work_struc - - if (phydev->link) { - phydev->state = PHY_RUNNING; -- netif_carrier_on(phydev->attached_dev); -+ phy_link_up(phydev); - } else { - phydev->state = PHY_NOLINK; -- netif_carrier_off(phydev->attached_dev); -+ phy_link_down(phydev, true); - } - -- phydev->adjust_link(phydev->attached_dev); -- - if (phy_interrupt_is_valid(phydev)) - err = phy_config_interrupt(phydev, - PHY_INTERRUPT_ENABLED); -@@ -985,8 +988,7 @@ void phy_state_machine(struct work_struc - case PHY_HALTED: - if (phydev->link) { - phydev->link = 0; -- netif_carrier_off(phydev->attached_dev); -- phydev->adjust_link(phydev->attached_dev); -+ phy_link_down(phydev, true); - do_suspend = true; - } - break; -@@ -1006,11 +1008,11 @@ void phy_state_machine(struct work_struc - - if (phydev->link) { - phydev->state = PHY_RUNNING; -- netif_carrier_on(phydev->attached_dev); -+ phy_link_up(phydev); - } else { - phydev->state = PHY_NOLINK; -+ phy_link_down(phydev, false); - } -- phydev->adjust_link(phydev->attached_dev); - } else { - phydev->state = PHY_AN; - phydev->link_timeout = PHY_AN_TIMEOUT; -@@ -1022,11 +1024,11 @@ void phy_state_machine(struct work_struc - - if (phydev->link) { - phydev->state = PHY_RUNNING; -- netif_carrier_on(phydev->attached_dev); -+ phy_link_up(phydev); - } else { - phydev->state = PHY_NOLINK; -+ phy_link_down(phydev, false); - } -- phydev->adjust_link(phydev->attached_dev); - } - break; - } ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -441,6 +441,19 @@ struct phy_device *phy_find_first(struct - } - EXPORT_SYMBOL(phy_find_first); - -+static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier) -+{ -+ struct net_device *netdev = phydev->attached_dev; -+ -+ if (do_carrier) { -+ if (up) -+ netif_carrier_on(netdev); -+ else -+ netif_carrier_off(netdev); -+ } -+ phydev->adjust_link(netdev); -+} -+ - /** - * phy_prepare_link - prepares the PHY layer to monitor link status - * @phydev: target phy_device struct -@@ -659,6 +672,7 @@ int phy_attach_direct(struct net_device - goto error; - } - -+ phydev->phy_link_change = phy_link_change; - phydev->attached_dev = dev; - dev->phydev = phydev; - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -433,6 +433,7 @@ struct phy_device { - - u8 mdix; - -+ void (*phy_link_change)(struct phy_device *, bool up, bool do_carrier); - void (*adjust_link)(struct net_device *dev); - }; - #define to_phy_device(d) container_of(d, struct phy_device, dev) diff --git a/target/linux/mvebu/patches-4.4/126-phy-marvell-88E1512-add-flow-control-support.patch b/target/linux/mvebu/patches-4.4/126-phy-marvell-88E1512-add-flow-control-support.patch deleted file mode 100644 index e731c4ddf5..0000000000 --- a/target/linux/mvebu/patches-4.4/126-phy-marvell-88E1512-add-flow-control-support.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5eed0bf3bc3e69b20a13d8ffcdf97cb720391637 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 00:34:08 +0100 -Subject: [PATCH 735/744] phy: marvell: 88E1512: add flow control support - -The Marvell PHYs support pause frame advertisments, so we should not be -masking their support off. Add the necessary flag to the Marvell PHY -to allow any MAC level pause frame support to be advertised. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/marvell.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -1142,7 +1142,7 @@ static struct phy_driver marvell_drivers - .phy_id = MARVELL_PHY_ID_88E1510, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1510", -- .features = PHY_GBIT_FEATURES, -+ .features = PHY_GBIT_FEATURES | SUPPORTED_Pause, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &m88e1510_config_aneg, - .read_status = &marvell_read_status, diff --git a/target/linux/mvebu/patches-4.4/127-phy-export-phy_start_machine-for-phylink.patch b/target/linux/mvebu/patches-4.4/127-phy-export-phy_start_machine-for-phylink.patch deleted file mode 100644 index eb73933f3d..0000000000 --- a/target/linux/mvebu/patches-4.4/127-phy-export-phy_start_machine-for-phylink.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f2a9687b39cda3fb67ecd5eaa88e3545e78c982c Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Fri, 16 Oct 2015 12:18:41 +0100 -Subject: [PATCH 715/744] phy: export phy_start_machine() for phylink - -phylink will need phy_start_machine exported, so lets export it as a -GPL symbol. Documentation/networking/phy.txt indicates that this -should be a PHY API function. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/phy.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -568,6 +568,7 @@ void phy_start_machine(struct phy_device - { - queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ); - } -+EXPORT_SYMBOL_GPL(phy_start_machine); - - /** - * phy_stop_machine - stop the PHY state machine tracking diff --git a/target/linux/mvebu/patches-4.4/128-phy-export-phy_speed_to_str-for-phylink.patch b/target/linux/mvebu/patches-4.4/128-phy-export-phy_speed_to_str-for-phylink.patch deleted file mode 100644 index c43607029c..0000000000 --- a/target/linux/mvebu/patches-4.4/128-phy-export-phy_speed_to_str-for-phylink.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 5c77cc2ffd5deb4762d9551409472f2441297fe7 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 18 Oct 2015 19:51:10 +0100 -Subject: [PATCH 716/744] phy: export phy_speed_to_str() for phylink - -phylink would like to reuse phy_speed_to_str() to convert the speed -to a string. Add a prototype and export this helper function. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/phy.c | 3 ++- - include/linux/phy.h | 1 + - 2 files changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -38,7 +38,7 @@ - - #include - --static const char *phy_speed_to_str(int speed) -+const char *phy_speed_to_str(int speed) - { - switch (speed) { - case SPEED_10: -@@ -57,6 +57,7 @@ static const char *phy_speed_to_str(int - return "Unsupported (update phy.c)"; - } - } -+EXPORT_SYMBOL_GPL(phy_speed_to_str); - - #define PHY_STATE_STR(_state) \ - case PHY_##_state: \ ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -812,6 +812,7 @@ int phy_ethtool_gset(struct phy_device * - int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr); - int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd); - int phy_start_interrupts(struct phy_device *phydev); -+const char *phy_speed_to_str(int speed); - void phy_print_status(struct phy_device *phydev); - void phy_device_free(struct phy_device *phydev); - int phy_set_max_speed(struct phy_device *phydev, u32 max_speed); diff --git a/target/linux/mvebu/patches-4.4/129-phy-add-I2C-mdio-bus.patch b/target/linux/mvebu/patches-4.4/129-phy-add-I2C-mdio-bus.patch deleted file mode 100644 index 13f8ecfcd4..0000000000 --- a/target/linux/mvebu/patches-4.4/129-phy-add-I2C-mdio-bus.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 7f36ac946bfbd4090b8b94be3661b41ac73e21f4 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Fri, 25 Sep 2015 17:43:52 +0100 -Subject: [PATCH 717/744] phy: add I2C mdio bus - -Add an I2C MDIO bus bridge library, to allow phylib to access PHYs which -are connected to an I2C bus instead of the more conventional MDIO bus. -Such PHYs can be found in SFP adapters and SFF modules. - -Signed-off-by: Russell King ---- - drivers/net/phy/Kconfig | 10 ++++++ - drivers/net/phy/Makefile | 1 + - drivers/net/phy/mdio-i2c.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++ - drivers/net/phy/mdio-i2c.h | 19 ++++++++++ - 4 files changed, 120 insertions(+) - create mode 100644 drivers/net/phy/mdio-i2c.c - create mode 100644 drivers/net/phy/mdio-i2c.h - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -233,6 +233,16 @@ config MDIO_GPIO - To compile this driver as a module, choose M here: the module - will be called mdio-gpio. - -+config MDIO_I2C -+ tristate -+ depends on I2C -+ help -+ Support I2C based PHYs. This provides a MDIO bus bridged -+ to I2C to allow PHYs connected in I2C mode to be accessed -+ using the existing infrastructure. -+ -+ This is library mode. -+ - config MDIO_OCTEON - tristate "Support for MDIO buses on Octeon and ThunderX SOCs" - depends on 64BIT ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -41,6 +41,7 @@ obj-$(CONFIG_SWCONFIG_B53) += b53/ - obj-$(CONFIG_FIXED_PHY) += fixed_phy.o - obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o - obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o -+obj-$(CONFIG_MDIO_I2C) += mdio-i2c.o - obj-$(CONFIG_NATIONAL_PHY) += national.o - obj-$(CONFIG_DP83640_PHY) += dp83640.o - obj-$(CONFIG_DP83848_PHY) += dp83848.o ---- /dev/null -+++ b/drivers/net/phy/mdio-i2c.c -@@ -0,0 +1,90 @@ -+/* -+ * MDIO I2C bridge -+ * -+ * Copyright (C) 2015 Russell King -+ * -+ * This program 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. -+ */ -+#include -+#include -+ -+#include "mdio-i2c.h" -+ -+static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg) -+{ -+ struct i2c_adapter *i2c = bus->priv; -+ struct i2c_msg msgs[2]; -+ u8 data[2], dev_addr = reg; -+ int bus_addr, ret; -+ -+ bus_addr = 0x40 + phy_id; -+ if (bus_addr == 0x50 || bus_addr == 0x51) -+ return 0xffff; -+ -+ msgs[0].addr = bus_addr; -+ msgs[0].flags = 0; -+ msgs[0].len = 1; -+ msgs[0].buf = &dev_addr; -+ msgs[1].addr = bus_addr; -+ msgs[1].flags = I2C_M_RD; -+ msgs[1].len = sizeof(data); -+ msgs[1].buf = data; -+ -+ ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs)); -+ if (ret != ARRAY_SIZE(msgs)) -+ return 0xffff; -+ -+ return data[0] << 8 | data[1]; -+} -+ -+static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val) -+{ -+ struct i2c_adapter *i2c = bus->priv; -+ struct i2c_msg msg; -+ int bus_addr, ret; -+ u8 data[3]; -+ -+ bus_addr = 0x40 + phy_id; -+ if (bus_addr == 0x50 || bus_addr == 0x51) -+ return 0; -+ -+ data[0] = reg; -+ data[1] = val >> 8; -+ data[2] = val; -+ -+ msg.addr = bus_addr; -+ msg.flags = 0; -+ msg.len = 3; -+ msg.buf = data; -+ -+ ret = i2c_transfer(i2c, &msg, 1); -+ -+ return ret < 0 ? ret : 0; -+} -+ -+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c) -+{ -+ struct mii_bus *mii; -+ -+ if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) -+ return ERR_PTR(-EINVAL); -+ -+ mii = mdiobus_alloc(); -+ if (!mii) -+ return ERR_PTR(-ENOMEM); -+ -+ snprintf(mii->id, MII_BUS_ID_SIZE, "i2c:%s", dev_name(parent)); -+ mii->parent = parent; -+ mii->read = i2c_mii_read; -+ mii->write = i2c_mii_write; -+ mii->priv = i2c; -+ -+ return mii; -+} -+EXPORT_SYMBOL_GPL(mdio_i2c_alloc); -+ -+MODULE_AUTHOR("Russell King"); -+MODULE_DESCRIPTION("MDIO I2C bridge library"); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/net/phy/mdio-i2c.h -@@ -0,0 +1,19 @@ -+/* -+ * MDIO I2C bridge -+ * -+ * Copyright (C) 2015 Russell King -+ * -+ * This program 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. -+ */ -+#ifndef MDIO_I2C_H -+#define MDIO_I2C_H -+ -+struct device; -+struct i2c_adapter; -+struct mii_bus; -+ -+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c); -+ -+#endif diff --git a/target/linux/mvebu/patches-4.4/130-phylink-add-phylink-infrastructure.patch b/target/linux/mvebu/patches-4.4/130-phylink-add-phylink-infrastructure.patch deleted file mode 100644 index 0d340c8278..0000000000 --- a/target/linux/mvebu/patches-4.4/130-phylink-add-phylink-infrastructure.patch +++ /dev/null @@ -1,1005 +0,0 @@ -From c6de6de7d3df13822872ac756eebe868d236297a Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Tue, 22 Sep 2015 20:52:18 +0100 -Subject: [PATCH 718/744] phylink: add phylink infrastructure - -The link between the ethernet MAC and its PHY has become more complex -as the interface evolves. This is especially true with serdes links, -where the part of the PHY is effectively integrated into the MAC. - -Serdes links can be connected to a variety of devices, including SFF -modules soldered down onto the board with the MAC, a SFP cage with -a hotpluggable SFP module which may contain a PHY or directly modulate -the serdes signals onto optical media with or without a PHY, or even -a classical PHY connection. - -Moreover, the negotiation information on serdes links comes in two -varieties - SGMII mode, where the PHY provides its speed/duplex/flow -control information to the MAC, and 1000base-X mode where both ends -exchange their abilities and each resolve the link capabilities. - -This means we need a more flexible means to support these arrangements, -particularly with the hotpluggable nature of SFP, where the PHY can -be attached or detached after the network device has been brought up. - -Ethtool information can come from multiple sources: -- we may have a PHY operating in either SGMII or 1000base-X mode, in - which case we take ethtool/mii data directly from the PHY. -- we may have a optical SFP module without a PHY, with the MAC - operating in 1000base-X mode - the ethtool/mii data needs to come - from the MAC. -- we may have a copper SFP module with a PHY whic can't be accessed, - which means we need to take ethtool/mii data from the MAC. - -Phylink aims to solve this by providing an intermediary between the -MAC and PHY, providing a safe way for PHYs to be hotplugged, and -allowing a SFP driver to reconfigure the serdes connection. - -Phylink also takes over support of fixed link connections, where -the speed/duplex/flow control are fixed, but link status may be -controlled by a GPIO signal. By avoiding the fixed-phy implementation, -phylink can provide a faster response to link events: fixed-phy has -to wait for phylib to operate its state machine, which can take -several seconds. In comparison, phylink takes milliseconds. - -Signed-off-by: Russell King ---- - drivers/net/phy/Kconfig | 10 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/phy_device.c | 1 + - drivers/net/phy/phylink.c | 816 +++++++++++++++++++++++++++++++++++++++++++ - include/linux/phy.h | 2 + - include/linux/phylink.h | 70 ++++ - 6 files changed, 900 insertions(+) - create mode 100644 drivers/net/phy/phylink.c - create mode 100644 include/linux/phylink.h - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -10,6 +10,16 @@ menuconfig PHYLIB - devices. This option provides infrastructure for - managing PHY devices. - -+config PHYLINK -+ tristate -+ depends on NETDEVICES -+ select PHYLIB -+ select SWPHY -+ help -+ PHYlink models the link between the PHY and MAC, allowing fixed -+ configuration links, PHYs, and Serdes links with MAC level -+ autonegotiation modes. -+ - if PHYLIB - - config MDIO_BOARDINFO ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -5,6 +5,7 @@ libphy-$(CONFIG_SWPHY) += swphy.o - - obj-$(CONFIG_MDIO_BOARDINFO) += mdio-boardinfo.o - -+obj-$(CONFIG_PHYLINK) += phylink.o - obj-$(CONFIG_PHYLIB) += libphy.o - obj-$(CONFIG_SWCONFIG) += swconfig.o - obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -754,6 +754,7 @@ void phy_detach(struct phy_device *phyde - phydev->attached_dev->phydev = NULL; - phydev->attached_dev = NULL; - phy_suspend(phydev); -+ phydev->phylink = NULL; - - /* If the device had no specific driver before (i.e. - it - * was using the generic driver), we unbind the device ---- /dev/null -+++ b/drivers/net/phy/phylink.c -@@ -0,0 +1,816 @@ -+/* -+ * phylink models the MAC to optional PHY connection, supporting -+ * technologies such as SFP cages where the PHY is hot-pluggable. -+ * -+ * Copyright (C) 2015 Russell King -+ * -+ * This program 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. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "swphy.h" -+ -+#define SUPPORTED_INTERFACES \ -+ (SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_FIBRE | \ -+ SUPPORTED_BNC | SUPPORTED_AUI | SUPPORTED_Backplane) -+#define ADVERTISED_INTERFACES \ -+ (ADVERTISED_TP | ADVERTISED_MII | ADVERTISED_FIBRE | \ -+ ADVERTISED_BNC | ADVERTISED_AUI | ADVERTISED_Backplane) -+ -+enum { -+ PHYLINK_DISABLE_STOPPED, -+}; -+ -+struct phylink { -+ struct net_device *netdev; -+ const struct phylink_mac_ops *ops; -+ struct mutex config_mutex; -+ -+ unsigned long phylink_disable_state; /* bitmask of disables */ -+ struct phy_device *phydev; -+ phy_interface_t link_interface; /* PHY_INTERFACE_xxx */ -+ u8 link_an_mode; /* MLO_AN_xxx */ -+ u8 link_port; /* The current non-phy ethtool port */ -+ u32 link_port_support; /* SUPPORTED_xxx ethtool for ports */ -+ -+ /* The link configuration settings */ -+ struct phylink_link_state link_config; -+ struct gpio_desc *link_gpio; -+ -+ struct mutex state_mutex; /* may be taken within config_mutex */ -+ struct phylink_link_state phy_state; -+ struct work_struct resolve; -+ -+ bool mac_link_up; -+}; -+ -+static const char *phylink_an_mode_str(unsigned int mode) -+{ -+ static const char *modestr[] = { -+ [MLO_AN_PHY] = "phy", -+ [MLO_AN_FIXED] = "fixed", -+ [MLO_AN_SGMII] = "SGMII", -+ [MLO_AN_8023Z] = "802.3z", -+ }; -+ -+ return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown"; -+} -+ -+static int phylink_parse_fixedlink(struct phylink *pl, struct device_node *np) -+{ -+ struct device_node *fixed_node; -+ int ret, len; -+ -+ fixed_node = of_get_child_by_name(np, "fixed-link"); -+ if (fixed_node) { -+ struct gpio_desc *desc; -+ u32 speed; -+ -+ ret = of_property_read_u32(fixed_node, "speed", &speed); -+ -+ pl->link_an_mode = MLO_AN_FIXED; -+ pl->link_config.link = 1; -+ pl->link_config.an_complete = 1; -+ pl->link_config.speed = speed; -+ pl->link_config.duplex = DUPLEX_HALF; -+ pl->link_config.pause = MLO_PAUSE_NONE; -+ -+ if (of_property_read_bool(fixed_node, "full-duplex")) -+ pl->link_config.duplex = DUPLEX_FULL; -+ if (of_property_read_bool(fixed_node, "pause")) -+ pl->link_config.pause |= MLO_PAUSE_SYM; -+ if (of_property_read_bool(fixed_node, "asym-pause")) -+ pl->link_config.pause |= MLO_PAUSE_ASYM; -+ -+ if (ret == 0) { -+ desc = fwnode_get_named_gpiod(&fixed_node->fwnode, -+ "link-gpios"); -+ -+ if (!IS_ERR(desc)) -+ pl->link_gpio = desc; -+ else if (desc == ERR_PTR(-EPROBE_DEFER)) -+ ret = -EPROBE_DEFER; -+ } -+ of_node_put(fixed_node); -+ } else { -+ const __be32 *fixed_prop; -+ -+ fixed_prop = of_get_property(np, "fixed-link", &len); -+ if (fixed_prop && len == 5 * sizeof(*fixed_prop)) { -+ pl->link_config.duplex = be32_to_cpu(fixed_prop[1]) ? -+ DUPLEX_FULL : DUPLEX_HALF; -+ pl->link_config.speed = be32_to_cpu(fixed_prop[2]); -+ pl->link_config.pause = MLO_PAUSE_NONE; -+ if (be32_to_cpu(fixed_prop[3])) -+ pl->link_config.pause |= MLO_PAUSE_SYM; -+ if (be32_to_cpu(fixed_prop[4])) -+ pl->link_config.pause |= MLO_PAUSE_ASYM; -+ -+ pl->link_an_mode = MLO_AN_FIXED; -+ } -+ ret = 0; -+ } -+ -+ if (pl->link_an_mode == MLO_AN_FIXED) { -+ /* Generate the supported/advertising masks */ -+ if (pl->link_config.pause & MLO_PAUSE_SYM) { -+ pl->link_config.supported |= SUPPORTED_Pause; -+ pl->link_config.advertising |= ADVERTISED_Pause; -+ } -+ if (pl->link_config.pause & MLO_PAUSE_ASYM) { -+ pl->link_config.supported |= SUPPORTED_Asym_Pause; -+ pl->link_config.advertising |= ADVERTISED_Asym_Pause; -+ } -+ -+ if (pl->link_config.speed > SPEED_1000 && -+ pl->link_config.duplex != DUPLEX_FULL) -+ netdev_warn(pl->netdev, "fixed link specifies half duplex for %dMbps link?\n", -+ pl->link_config.speed); -+ -+#define S(spd) \ -+ pl->link_config.supported |= pl->link_config.duplex ? \ -+ SUPPORTED_##spd##_Full : SUPPORTED_##spd##_Half -+#define A(spd) \ -+ pl->link_config.advertising |= pl->link_config.duplex ? \ -+ ADVERTISED_##spd##_Full : ADVERTISED_##spd##_Half -+#define C(spd, tech) \ -+ case spd: \ -+ S(spd##tech); \ -+ A(spd##tech); \ -+ break -+ switch (pl->link_config.speed) { -+ C(10, baseT); -+ C(100, baseT); -+ C(1000, baseT); -+#undef S -+#undef A -+#define S(spd) pl->link_config.supported |= SUPPORTED_##spd##_Full -+#define A(spd) pl->link_config.advertising |= ADVERTISED_##spd##_Full -+ C(2500, baseX); -+ C(10000, baseT); -+ } -+#undef S -+#undef A -+#undef C -+ } -+ return ret; -+} -+ -+static int phylink_parse_managed(struct phylink *pl, struct device_node *np) -+{ -+ const char *managed; -+ -+ if (of_property_read_string(np, "managed", &managed) == 0 && -+ strcmp(managed, "in-band-status") == 0) { -+ if (pl->link_an_mode == MLO_AN_FIXED) { -+ netdev_err(pl->netdev, -+ "can't use both fixed-link and in-band-status\n"); -+ return -EINVAL; -+ } -+ pl->link_an_mode = MLO_AN_SGMII; -+ pl->link_config.an_enabled = true; -+ } -+ -+ return 0; -+} -+ -+ -+static int phylink_get_support(struct phylink *pl, unsigned int mode) -+{ -+ struct phylink_link_state state = pl->link_config; -+ int ret; -+ -+ ret = pl->ops->mac_get_support(pl->netdev, mode, &state); -+ if (ret == 0) { -+ pl->link_an_mode = mode; -+ pl->link_config = state; -+ } -+ -+ return ret; -+} -+ -+static void phylink_mac_config(struct phylink *pl, -+ const struct phylink_link_state *state) -+{ -+ pl->ops->mac_config(pl->netdev, pl->link_an_mode, state); -+} -+ -+static void phylink_mac_an_restart(struct phylink *pl) -+{ -+ if (pl->link_config.an_enabled) -+ pl->ops->mac_an_restart(pl->netdev, pl->link_an_mode); -+} -+ -+static int phylink_get_mac_state(struct phylink *pl, struct phylink_link_state *state) -+{ -+ struct net_device *ndev = pl->netdev; -+ -+ state->supported = pl->link_config.supported; -+ state->advertising = pl->link_config.advertising; -+ state->an_enabled = pl->link_config.an_enabled; -+ state->link = 1; -+ state->sync = 1; -+ -+ return pl->ops->mac_link_state(ndev, state); -+} -+ -+/* The fixed state is... fixed except for the link state, -+ * which may be determined by a GPIO. -+ */ -+static void phylink_get_fixed_state(struct phylink *pl, struct phylink_link_state *state) -+{ -+ *state = pl->link_config; -+ if (pl->link_gpio) -+ state->link = !!gpiod_get_value(pl->link_gpio); -+} -+ -+extern const char *phy_speed_to_str(int speed); -+ -+static void phylink_resolve(struct work_struct *w) -+{ -+ struct phylink *pl = container_of(w, struct phylink, resolve); -+ struct phylink_link_state link_state; -+ struct net_device *ndev = pl->netdev; -+ -+ mutex_lock(&pl->state_mutex); -+ if (pl->phylink_disable_state) { -+ link_state.link = false; -+ } else { -+ switch (pl->link_an_mode) { -+ case MLO_AN_PHY: -+ link_state = pl->phy_state; -+ break; -+ -+ case MLO_AN_FIXED: -+ phylink_get_fixed_state(pl, &link_state); -+ break; -+ -+ case MLO_AN_SGMII: -+ phylink_get_mac_state(pl, &link_state); -+ if (pl->phydev) -+ link_state.link = link_state.link && -+ pl->phy_state.link; -+ break; -+ -+ case MLO_AN_8023Z: -+ phylink_get_mac_state(pl, &link_state); -+ break; -+ } -+ } -+ -+ if (link_state.link != netif_carrier_ok(ndev)) { -+ if (!link_state.link) { -+ netif_carrier_off(ndev); -+ pl->ops->mac_link_down(ndev, pl->link_an_mode); -+ netdev_info(ndev, "Link is Down\n"); -+ } else { -+ /* If we have a PHY, we need the MAC updated with -+ * the current link parameters (eg, in SGMII mode, -+ * with flow control status.) -+ */ -+ if (pl->phydev) -+ phylink_mac_config(pl, &link_state); -+ -+ pl->ops->mac_link_up(ndev, pl->link_an_mode); -+ -+ netif_carrier_on(ndev); -+ -+ netdev_info(ndev, -+ "Link is Up - %s/%s - flow control %s\n", -+ phy_speed_to_str(link_state.speed), -+ link_state.duplex ? "Full" : "Half", -+ link_state.pause ? "rx/tx" : "off"); -+ } -+ } -+ mutex_unlock(&pl->state_mutex); -+} -+ -+static void phylink_run_resolve(struct phylink *pl) -+{ -+ if (!pl->phylink_disable_state) -+ queue_work(system_power_efficient_wq, &pl->resolve); -+} -+ -+struct phylink *phylink_create(struct net_device *ndev, struct device_node *np, -+ phy_interface_t iface, const struct phylink_mac_ops *ops) -+{ -+ struct phylink *pl; -+ int ret; -+ -+ pl = kzalloc(sizeof(*pl), GFP_KERNEL); -+ if (!pl) -+ return ERR_PTR(-ENOMEM); -+ -+ mutex_init(&pl->state_mutex); -+ mutex_init(&pl->config_mutex); -+ INIT_WORK(&pl->resolve, phylink_resolve); -+ pl->netdev = ndev; -+ pl->link_interface = iface; -+ pl->link_port_support = SUPPORTED_MII; -+ pl->link_port = PORT_MII; -+ pl->ops = ops; -+ __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); -+ -+ ret = phylink_parse_fixedlink(pl, np); -+ if (ret < 0) { -+ kfree(pl); -+ return ERR_PTR(ret); -+ } -+ -+ ret = phylink_parse_managed(pl, np); -+ if (ret < 0) { -+ kfree(pl); -+ return ERR_PTR(ret); -+ } -+ -+ ret = phylink_get_support(pl, pl->link_an_mode); -+ if (ret) { -+ kfree(pl); -+ return ERR_PTR(ret); -+ } -+ -+ return pl; -+} -+EXPORT_SYMBOL_GPL(phylink_create); -+ -+void phylink_destroy(struct phylink *pl) -+{ -+ cancel_work_sync(&pl->resolve); -+ kfree(pl); -+} -+EXPORT_SYMBOL_GPL(phylink_destroy); -+ -+void phylink_phy_change(struct phy_device *phy, bool up, bool do_carrier) -+{ -+ struct phylink *pl = phy->phylink; -+ -+ mutex_lock(&pl->state_mutex); -+ pl->phy_state.speed = phy->speed; -+ pl->phy_state.duplex = phy->duplex; -+ pl->phy_state.pause = MLO_PAUSE_NONE; -+ if (phy->pause) -+ pl->phy_state.pause |= MLO_PAUSE_SYM; -+ if (phy->asym_pause) -+ pl->phy_state.pause |= MLO_PAUSE_ASYM; -+ pl->phy_state.link = up; -+ mutex_unlock(&pl->state_mutex); -+ -+ phylink_run_resolve(pl); -+ -+ netdev_dbg(pl->netdev, "phy link %s\n", up ? "up" : "down"); -+} -+ -+static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy) -+{ -+ mutex_lock(&pl->config_mutex); -+ phy->phylink = pl; -+ phy->phy_link_change = phylink_phy_change; -+ -+ netdev_info(pl->netdev, -+ "PHY [%s] driver [%s]\n", dev_name(&phy->dev), -+ phy->drv->name); -+ -+ mutex_lock(&pl->state_mutex); -+ pl->phydev = phy; -+ -+ /* Restrict the phy advertisment to the union of the PHY and -+ * MAC-level advert. -+ */ -+ phy->advertising &= ADVERTISED_INTERFACES | -+ pl->link_config.advertising; -+ mutex_unlock(&pl->state_mutex); -+ -+ phy_start_machine(phy); -+ if (phy->irq > 0) -+ phy_start_interrupts(phy); -+ -+ mutex_unlock(&pl->config_mutex); -+ -+ return 0; -+} -+ -+int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) -+{ -+ int ret; -+ -+ ret = phy_attach_direct(pl->netdev, phy, 0, pl->link_interface); -+ if (ret) -+ return ret; -+ -+ ret = phylink_bringup_phy(pl, phy); -+ if (ret) -+ phy_detach(phy); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_connect_phy); -+ -+int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn) -+{ -+ struct device_node *phy_node; -+ struct phy_device *phy_dev; -+ int ret; -+ -+ /* Fixed links are handled without needing a PHY */ -+ if (pl->link_an_mode == MLO_AN_FIXED) -+ return 0; -+ -+ phy_node = of_parse_phandle(dn, "phy-handle", 0); -+ if (!phy_node) -+ phy_node = of_parse_phandle(dn, "phy", 0); -+ if (!phy_node) -+ phy_node = of_parse_phandle(dn, "phy-device", 0); -+ -+ if (!phy_node) { -+ if (pl->link_an_mode == MLO_AN_PHY) { -+ netdev_err(pl->netdev, "unable to find PHY node\n"); -+ return -ENODEV; -+ } -+ return 0; -+ } -+ -+ phy_dev = of_phy_attach(pl->netdev, phy_node, 0, pl->link_interface); -+ /* We're done with the phy_node handle */ -+ of_node_put(phy_node); -+ -+ if (!phy_dev) -+ return -ENODEV; -+ -+ ret = phylink_bringup_phy(pl, phy_dev); -+ if (ret) -+ phy_detach(phy_dev); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_of_phy_connect); -+ -+void phylink_disconnect_phy(struct phylink *pl) -+{ -+ struct phy_device *phy; -+ -+ mutex_lock(&pl->config_mutex); -+ phy = pl->phydev; -+ -+ mutex_lock(&pl->state_mutex); -+ pl->phydev = NULL; -+ mutex_unlock(&pl->state_mutex); -+ flush_work(&pl->resolve); -+ -+ if (phy) -+ phy_disconnect(phy); -+ -+ mutex_unlock(&pl->config_mutex); -+} -+EXPORT_SYMBOL_GPL(phylink_disconnect_phy); -+ -+void phylink_mac_change(struct phylink *pl, bool up) -+{ -+ phylink_run_resolve(pl); -+ netdev_dbg(pl->netdev, "mac link %s\n", up ? "up" : "down"); -+} -+EXPORT_SYMBOL_GPL(phylink_mac_change); -+ -+void phylink_start(struct phylink *pl) -+{ -+ mutex_lock(&pl->config_mutex); -+ -+ netdev_info(pl->netdev, "configuring for %s link mode\n", -+ phylink_an_mode_str(pl->link_an_mode)); -+ -+ /* Apply the link configuration to the MAC when starting. This allows -+ * a fixed-link to start with the correct parameters, and also -+ * ensures that we set the appropriate advertisment for Serdes links. -+ */ -+ phylink_mac_config(pl, &pl->link_config); -+ -+ clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); -+ phylink_run_resolve(pl); -+ -+ if (pl->phydev) -+ phy_start(pl->phydev); -+ -+ mutex_unlock(&pl->config_mutex); -+} -+EXPORT_SYMBOL_GPL(phylink_start); -+ -+void phylink_stop(struct phylink *pl) -+{ -+ mutex_lock(&pl->config_mutex); -+ -+ if (pl->phydev) -+ phy_stop(pl->phydev); -+ -+ set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); -+ flush_work(&pl->resolve); -+ -+ pl->mac_link_up = false; -+ -+ mutex_unlock(&pl->config_mutex); -+} -+EXPORT_SYMBOL_GPL(phylink_stop); -+ -+static void phylink_get_ethtool(const struct phylink_link_state *state, -+ struct ethtool_cmd *cmd) -+{ -+ cmd->supported &= SUPPORTED_INTERFACES; -+ cmd->supported |= state->supported; -+ cmd->advertising &= ADVERTISED_INTERFACES; -+ cmd->advertising |= state->advertising; -+ ethtool_cmd_speed_set(cmd, state->speed); -+ cmd->duplex = state->duplex; -+ -+ cmd->autoneg = state->an_enabled ? AUTONEG_ENABLE : AUTONEG_DISABLE; -+} -+ -+static int phylink_ethtool_gset(struct phylink *pl, struct ethtool_cmd *cmd) -+{ -+ struct phylink_link_state link_state; -+ int ret; -+ -+ if (pl->phydev) { -+ ret = phy_ethtool_gset(pl->phydev, cmd); -+ if (ret) -+ return ret; -+ -+ cmd->supported &= SUPPORTED_INTERFACES | -+ pl->link_config.supported; -+ } else { -+ cmd->supported = pl->link_port_support; -+ cmd->transceiver = XCVR_EXTERNAL; -+ cmd->port = pl->link_port; -+ } -+ -+ switch (pl->link_an_mode) { -+ case MLO_AN_FIXED: -+ /* We are using fixed settings. Report these as the -+ * current link settings - and note that these also -+ * represent the supported speeds/duplex/pause modes. -+ */ -+ phylink_get_fixed_state(pl, &link_state); -+ phylink_get_ethtool(&link_state, cmd); -+ break; -+ -+ case MLO_AN_SGMII: -+ /* If there is a phy attached, then use the reported -+ * settings from the phy with no modification. -+ */ -+ if (pl->phydev) -+ break; -+ -+ case MLO_AN_8023Z: -+ phylink_get_mac_state(pl, &link_state); -+ -+ /* The MAC is reporting the link results from its own PCS -+ * layer via in-band status. Report these as the current -+ * link settings. -+ */ -+ phylink_get_ethtool(&link_state, cmd); -+ break; -+ } -+ -+ return 0; -+} -+ -+int phylink_ethtool_get_settings(struct phylink *pl, struct ethtool_cmd *cmd) -+{ -+ int ret; -+ -+ mutex_lock(&pl->config_mutex); -+ ret = phylink_ethtool_gset(pl, cmd); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_get_settings); -+ -+static int phylink_ethtool_sset(struct phylink *pl, struct ethtool_cmd *cmd) -+{ -+ u32 supported; -+ int ret; -+ -+ /* Calculate the union of the MAC support and attached phy support */ -+ supported = pl->link_config.supported; -+ if (pl->phydev) -+ supported &= pl->phydev->supported; -+ -+ /* Mask out unsupported advertisments */ -+ cmd->advertising &= supported; -+ -+ /* FIXME: should we reject autoneg if phy/mac does not support it? */ -+ -+ if (cmd->autoneg == AUTONEG_DISABLE) { -+ /* Autonegotiation disabled, validate speed and duplex */ -+ if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) -+ return -EINVAL; -+ -+ /* FIXME: validate speed/duplex against supported */ -+ -+ cmd->advertising &= ~ADVERTISED_Autoneg; -+ } else { -+ /* Autonegotiation enabled, validate advertisment */ -+ /* FIXME: shouldn't we ensure there's some duplex/speeds set */ -+ if (cmd->advertising == 0) -+ return -EINVAL; -+ -+ cmd->advertising |= ADVERTISED_Autoneg; -+ } -+ -+ /* If we have a fixed link (as specified by firmware), refuse -+ * to enable autonegotiation, or change link parameters. -+ */ -+ if (pl->link_an_mode == MLO_AN_FIXED) { -+ if (cmd->autoneg != AUTONEG_DISABLE || -+ ethtool_cmd_speed(cmd) != pl->link_config.speed || -+ cmd->duplex != pl->link_config.duplex) -+ return -EINVAL; -+ } -+ -+ /* If we have a PHY, configure the phy */ -+ if (pl->phydev) { -+ ret = phy_ethtool_sset(pl->phydev, cmd); -+ if (ret) -+ return ret; -+ } -+ -+ mutex_lock(&pl->state_mutex); -+ /* Configure the MAC to match the new settings */ -+ pl->link_config.advertising = cmd->advertising; -+ pl->link_config.speed = cmd->speed; -+ pl->link_config.duplex = cmd->duplex; -+ pl->link_config.an_enabled = cmd->autoneg != AUTONEG_DISABLE; -+ -+ phylink_mac_config(pl, &pl->link_config); -+ phylink_mac_an_restart(pl); -+ mutex_unlock(&pl->state_mutex); -+ -+ return ret; -+} -+ -+int phylink_ethtool_set_settings(struct phylink *pl, struct ethtool_cmd *cmd) -+{ -+ int ret; -+ -+ if (cmd->autoneg != AUTONEG_DISABLE && cmd->autoneg != AUTONEG_ENABLE) -+ return -EINVAL; -+ -+ mutex_lock(&pl->config_mutex); -+ ret = phylink_ethtool_sset(pl, cmd); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_set_settings); -+ -+/* This emulates MII registers for a fixed-mode phy operating as per the -+ * passed in state. "aneg" defines if we report negotiation is possible. -+ * -+ * FIXME: should deal with negotiation state too. -+ */ -+static int phylink_mii_emul_read(struct net_device *ndev, unsigned int reg, -+ struct phylink_link_state *state, bool aneg) -+{ -+ struct fixed_phy_status fs; -+ int val; -+ -+ fs.link = state->link; -+ fs.speed = state->speed; -+ fs.duplex = state->duplex; -+ fs.pause = state->pause & MLO_PAUSE_SYM; -+ fs.asym_pause = state->pause & MLO_PAUSE_ASYM; -+ -+ val = swphy_read_reg(reg, &fs); -+ if (reg == MII_BMSR) { -+ if (!state->an_complete) -+ val &= ~BMSR_ANEGCOMPLETE; -+ if (!aneg) -+ val &= ~BMSR_ANEGCAPABLE; -+ } -+ return val; -+} -+ -+static int phylink_mii_read(struct phylink *pl, unsigned int phy_id, -+ unsigned int reg) -+{ -+ struct phylink_link_state state; -+ int val = 0xffff; -+ -+ if (pl->phydev && pl->phydev->addr != phy_id) -+ return mdiobus_read(pl->phydev->bus, phy_id, reg); -+ -+ if (!pl->phydev && phy_id != 0) -+ return val; -+ -+ switch (pl->link_an_mode) { -+ case MLO_AN_FIXED: -+ phylink_get_fixed_state(pl, &state); -+ val = phylink_mii_emul_read(pl->netdev, reg, &state, true); -+ break; -+ -+ case MLO_AN_PHY: -+ val = mdiobus_read(pl->phydev->bus, phy_id, reg); -+ break; -+ -+ case MLO_AN_SGMII: -+ if (pl->phydev) { -+ val = mdiobus_read(pl->phydev->bus, -+ pl->phydev->addr, reg); -+ break; -+ } -+ /* No phy, fall through to reading the MAC end */ -+ case MLO_AN_8023Z: -+ val = phylink_get_mac_state(pl, &state); -+ if (val < 0) -+ return val; -+ -+ val = phylink_mii_emul_read(pl->netdev, reg, &state, true); -+ break; -+ } -+ -+ return val & 0xffff; -+} -+ -+static void phylink_mii_write(struct phylink *pl, unsigned int phy_id, -+ unsigned int reg, unsigned int val) -+{ -+ if (pl->phydev && pl->phydev->addr != phy_id) { -+ mdiobus_write(pl->phydev->bus, phy_id, reg, val); -+ return; -+ } -+ -+ if (!pl->phydev && phy_id != 0) -+ return; -+ -+ switch (pl->link_an_mode) { -+ case MLO_AN_FIXED: -+ break; -+ -+ case MLO_AN_PHY: -+ mdiobus_write(pl->phydev->bus, pl->phydev->addr, -+ reg, val); -+ break; -+ -+ case MLO_AN_SGMII: -+ if (pl->phydev) { -+ mdiobus_write(pl->phydev->bus, phy_id, reg, val); -+ break; -+ } -+ /* No phy, fall through to reading the MAC end */ -+ case MLO_AN_8023Z: -+ break; -+ } -+} -+ -+int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd) -+{ -+ struct mii_ioctl_data *mii_data = if_mii(ifr); -+ int val, ret; -+ -+ mutex_lock(&pl->config_mutex); -+ -+ switch (cmd) { -+ case SIOCGMIIPHY: -+ mii_data->phy_id = pl->phydev ? pl->phydev->addr : 0; -+ /* fallthrough */ -+ -+ case SIOCGMIIREG: -+ val = phylink_mii_read(pl, mii_data->phy_id, mii_data->reg_num); -+ if (val < 0) { -+ ret = val; -+ } else { -+ mii_data->val_out = val; -+ ret = 0; -+ } -+ break; -+ -+ case SIOCSMIIREG: -+ phylink_mii_write(pl, mii_data->phy_id, mii_data->reg_num, -+ mii_data->val_in); -+ ret = 0; -+ break; -+ -+ default: -+ ret = -EOPNOTSUPP; -+ if (pl->phydev) -+ ret = phy_mii_ioctl(pl->phydev, ifr, cmd); -+ break; -+ } -+ -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_mii_ioctl); -+ -+MODULE_LICENSE("GPL"); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -147,6 +147,7 @@ static inline const char *phy_modes(phy_ - #define MII_ADDR_C45 (1<<30) - - struct device; -+struct phylink; - struct sk_buff; - - /* -@@ -429,6 +430,7 @@ struct phy_device { - - struct mutex lock; - -+ struct phylink *phylink; - struct net_device *attached_dev; - - u8 mdix; ---- /dev/null -+++ b/include/linux/phylink.h -@@ -0,0 +1,70 @@ -+#ifndef NETDEV_PCS_H -+#define NETDEV_PCS_H -+ -+#include -+#include -+#include -+ -+struct device_node; -+struct ethtool_cmd; -+struct net_device; -+ -+enum { -+ MLO_PAUSE_NONE, -+ MLO_PAUSE_ASYM = BIT(0), -+ MLO_PAUSE_SYM = BIT(1), -+ -+ MLO_AN_PHY = 0, -+ MLO_AN_FIXED, -+ MLO_AN_SGMII, -+ MLO_AN_8023Z, -+}; -+ -+struct phylink_link_state { -+ u32 supported; -+ u32 advertising; -+ u32 lp_advertising; -+ int speed; -+ int duplex; -+ int pause; -+ unsigned int link:1; -+ unsigned int sync:1; -+ unsigned int an_enabled:1; -+ unsigned int an_complete:1; -+}; -+ -+struct phylink_mac_ops { -+ /* Get the ethtool supported mask for the indicated mode */ -+ int (*mac_get_support)(struct net_device *, unsigned int mode, -+ struct phylink_link_state *); -+ -+ /* Read the current link state from the hardware */ -+ int (*mac_link_state)(struct net_device *, struct phylink_link_state *); -+ -+ /* Configure the MAC */ -+ void (*mac_config)(struct net_device *, unsigned int mode, -+ const struct phylink_link_state *); -+ void (*mac_an_restart)(struct net_device *, unsigned int mode); -+ -+ void (*mac_link_down)(struct net_device *, unsigned int mode); -+ void (*mac_link_up)(struct net_device *, unsigned int mode); -+}; -+ -+struct phylink *phylink_create(struct net_device *, struct device_node *, -+ phy_interface_t iface, const struct phylink_mac_ops *ops); -+void phylink_destroy(struct phylink *); -+ -+int phylink_connect_phy(struct phylink *, struct phy_device *); -+int phylink_of_phy_connect(struct phylink *, struct device_node *); -+void phylink_disconnect_phy(struct phylink *); -+ -+void phylink_mac_change(struct phylink *, bool up); -+ -+void phylink_start(struct phylink *); -+void phylink_stop(struct phylink *); -+ -+int phylink_ethtool_get_settings(struct phylink *, struct ethtool_cmd *); -+int phylink_ethtool_set_settings(struct phylink *, struct ethtool_cmd *); -+int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); -+ -+#endif diff --git a/target/linux/mvebu/patches-4.4/131-phylink-add-hooks-for-SFP-support.patch b/target/linux/mvebu/patches-4.4/131-phylink-add-hooks-for-SFP-support.patch deleted file mode 100644 index 64a1c1ff1d..0000000000 --- a/target/linux/mvebu/patches-4.4/131-phylink-add-hooks-for-SFP-support.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 0a0c4b3dd4f34df4532f254a5940b520015d766f Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 24 Sep 2015 11:01:13 +0100 -Subject: [PATCH 719/744] phylink: add hooks for SFP support - -Add support to phylink for SFP, which needs to control and configure -the ethernet MAC link state. Specifically, SFP needs to: - -1. set the negotiation mode between SGMII and 1000base-X -2. attach and detach the module PHY -3. prevent the link coming up when errors are reported - -In the absence of a PHY, we also need to set the ethtool port type -according to the module plugged in. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/phylink.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/phylink.h | 6 ++++ - 2 files changed, 88 insertions(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -29,11 +30,16 @@ - (ADVERTISED_TP | ADVERTISED_MII | ADVERTISED_FIBRE | \ - ADVERTISED_BNC | ADVERTISED_AUI | ADVERTISED_Backplane) - -+static LIST_HEAD(phylinks); -+static DEFINE_MUTEX(phylink_mutex); -+ - enum { - PHYLINK_DISABLE_STOPPED, -+ PHYLINK_DISABLE_LINK, - }; - - struct phylink { -+ struct list_head node; - struct net_device *netdev; - const struct phylink_mac_ops *ops; - struct mutex config_mutex; -@@ -341,12 +347,20 @@ struct phylink *phylink_create(struct ne - return ERR_PTR(ret); - } - -+ mutex_lock(&phylink_mutex); -+ list_add_tail(&pl->node, &phylinks); -+ mutex_unlock(&phylink_mutex); -+ - return pl; - } - EXPORT_SYMBOL_GPL(phylink_create); - - void phylink_destroy(struct phylink *pl) - { -+ mutex_lock(&phylink_mutex); -+ list_del(&pl->node); -+ mutex_unlock(&phylink_mutex); -+ - cancel_work_sync(&pl->resolve); - kfree(pl); - } -@@ -813,4 +827,72 @@ int phylink_mii_ioctl(struct phylink *pl - } - EXPORT_SYMBOL_GPL(phylink_mii_ioctl); - -+ -+ -+void phylink_disable(struct phylink *pl) -+{ -+ set_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); -+ flush_work(&pl->resolve); -+ -+ netif_carrier_off(pl->netdev); -+} -+EXPORT_SYMBOL_GPL(phylink_disable); -+ -+void phylink_enable(struct phylink *pl) -+{ -+ clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); -+ phylink_run_resolve(pl); -+} -+EXPORT_SYMBOL_GPL(phylink_enable); -+ -+void phylink_set_link_port(struct phylink *pl, u32 support, u8 port) -+{ -+ WARN_ON(support & ~SUPPORTED_INTERFACES); -+ -+ mutex_lock(&pl->config_mutex); -+ pl->link_port_support = support; -+ pl->link_port = port; -+ mutex_unlock(&pl->config_mutex); -+} -+EXPORT_SYMBOL_GPL(phylink_set_link_port); -+ -+int phylink_set_link_an_mode(struct phylink *pl, unsigned int mode) -+{ -+ int ret = 0; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->link_an_mode != mode) { -+ ret = phylink_get_support(pl, mode); -+ if (ret == 0) { -+ if (!test_bit(PHYLINK_DISABLE_STOPPED, -+ &pl->phylink_disable_state)) -+ phylink_mac_config(pl, &pl->link_config); -+ -+ netdev_info(pl->netdev, "switched to %s link mode\n", -+ phylink_an_mode_str(mode)); -+ } -+ } -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_set_link_an_mode); -+ -+struct phylink *phylink_lookup_by_netdev(struct net_device *ndev) -+{ -+ struct phylink *pl, *found = NULL; -+ -+ mutex_lock(&phylink_mutex); -+ list_for_each_entry(pl, &phylinks, node) -+ if (pl->netdev == ndev) { -+ found = pl; -+ break; -+ } -+ -+ mutex_unlock(&phylink_mutex); -+ -+ return found; -+} -+EXPORT_SYMBOL_GPL(phylink_lookup_by_netdev); -+ - MODULE_LICENSE("GPL"); ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -67,4 +67,10 @@ int phylink_ethtool_get_settings(struct - int phylink_ethtool_set_settings(struct phylink *, struct ethtool_cmd *); - int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); - -+void phylink_set_link_port(struct phylink *pl, u32 support, u8 port); -+int phylink_set_link_an_mode(struct phylink *pl, unsigned int mode); -+void phylink_disable(struct phylink *pl); -+void phylink_enable(struct phylink *pl); -+struct phylink *phylink_lookup_by_netdev(struct net_device *ndev); -+ - #endif diff --git a/target/linux/mvebu/patches-4.4/132-sfp-add-phylink-based-SFP-module-support.patch b/target/linux/mvebu/patches-4.4/132-sfp-add-phylink-based-SFP-module-support.patch deleted file mode 100644 index 07b1766b0b..0000000000 --- a/target/linux/mvebu/patches-4.4/132-sfp-add-phylink-based-SFP-module-support.patch +++ /dev/null @@ -1,1382 +0,0 @@ -From bf0a000960234c0e773fadea47240c3cda0cab02 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sat, 12 Sep 2015 18:43:39 +0100 -Subject: [PATCH 720/744] sfp: add phylink based SFP module support - -Add support for SFP hotpluggable modules via phylink. This supports -both copper and optical SFP modules, which require different Serdes -modes in order to properly negotiate the link. - -Optical SFP modules typically require the Serdes link to be talking -1000base-X mode - this is the gigabit ethernet mode defined by the -802.3 standard. - -Copper SFP modules typically integrate a PHY in the module to convert -from Serdes to copper, and the PHY will be configured by the vendor -to either present a 1000base-X Serdes link (for fixed 1000base-T) or -a SGMII Serdes link. However, this is vendor defined, so we instead -detect the PHY, switch the link to SGMII mode, and use traditional -PHY based negotiation. - -Signed-off-by: Russell King ---- - drivers/net/phy/Kconfig | 5 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/sfp.c | 986 +++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/sfp.h | 339 ++++++++++++++++ - 4 files changed, 1331 insertions(+) - create mode 100644 drivers/net/phy/sfp.c - create mode 100644 include/linux/sfp.h - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -225,6 +225,11 @@ config FIXED_PHY - - Currently tested with mpc866ads and mpc8349e-mitx. - -+config SFP -+ tristate "SFP cage support" -+ depends on I2C && PHYLINK -+ select MDIO_I2C -+ - config MDIO_BITBANG - tristate "Support for bitbanged MDIO buses" - help ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -61,3 +61,4 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxart - obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o - obj-$(CONFIG_MICROCHIP_PHY) += microchip.o - obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o -+obj-$(CONFIG_SFP) += sfp.o ---- /dev/null -+++ b/drivers/net/phy/sfp.c -@@ -0,0 +1,986 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mdio-i2c.h" -+#include "swphy.h" -+ -+enum { -+ GPIO_MODDEF0, -+ GPIO_LOS, -+ GPIO_TX_FAULT, -+ GPIO_TX_DISABLE, -+ GPIO_RATE_SELECT, -+ GPIO_MAX, -+ -+ SFP_F_PRESENT = BIT(GPIO_MODDEF0), -+ SFP_F_LOS = BIT(GPIO_LOS), -+ SFP_F_TX_FAULT = BIT(GPIO_TX_FAULT), -+ SFP_F_TX_DISABLE = BIT(GPIO_TX_DISABLE), -+ SFP_F_RATE_SELECT = BIT(GPIO_RATE_SELECT), -+ -+ SFP_E_INSERT = 0, -+ SFP_E_REMOVE, -+ SFP_E_DEV_DOWN, -+ SFP_E_DEV_UP, -+ SFP_E_TX_FAULT, -+ SFP_E_TX_CLEAR, -+ SFP_E_LOS_HIGH, -+ SFP_E_LOS_LOW, -+ SFP_E_TIMEOUT, -+ -+ SFP_MOD_EMPTY = 0, -+ SFP_MOD_PROBE, -+ SFP_MOD_PRESENT, -+ SFP_MOD_ERROR, -+ -+ SFP_DEV_DOWN = 0, -+ SFP_DEV_UP, -+ -+ SFP_S_DOWN = 0, -+ SFP_S_INIT, -+ SFP_S_WAIT_LOS, -+ SFP_S_LINK_UP, -+ SFP_S_TX_FAULT, -+ SFP_S_REINIT, -+ SFP_S_TX_DISABLE, -+}; -+ -+static const char *gpio_of_names[] = { -+ "moddef0", -+ "los", -+ "tx-fault", -+ "tx-disable", -+ "rate-select", -+}; -+ -+static const enum gpiod_flags gpio_flags[] = { -+ GPIOD_IN, -+ GPIOD_IN, -+ GPIOD_IN, -+ GPIOD_ASIS, -+ GPIOD_ASIS, -+}; -+ -+#define T_INIT_JIFFIES msecs_to_jiffies(300) -+#define T_RESET_US 10 -+#define T_FAULT_RECOVER msecs_to_jiffies(1000) -+ -+/* SFP module presence detection is poor: the three MOD DEF signals are -+ * the same length on the PCB, which means it's possible for MOD DEF 0 to -+ * connect before the I2C bus on MOD DEF 1/2. Try to work around this -+ * design bug by waiting 50ms before probing, and then retry every 250ms. -+ */ -+#define T_PROBE_INIT msecs_to_jiffies(50) -+#define T_PROBE_RETRY msecs_to_jiffies(250) -+ -+/* -+ * SFP modules appear to always have their PHY configured for bus address -+ * 0x56 (which with mdio-i2c, translates to a PHY address of 22). -+ */ -+#define SFP_PHY_ADDR 22 -+ -+/* -+ * Give this long for the PHY to reset. -+ */ -+#define T_PHY_RESET_MS 50 -+ -+static DEFINE_MUTEX(sfp_mutex); -+ -+struct sfp { -+ struct device *dev; -+ struct i2c_adapter *i2c; -+ struct mii_bus *i2c_mii; -+ struct net_device *ndev; -+ struct phylink *phylink; -+ struct phy_device *mod_phy; -+ -+ unsigned int (*get_state)(struct sfp *); -+ void (*set_state)(struct sfp *, unsigned int); -+ int (*read)(struct sfp *, bool, u8, void *, size_t); -+ -+ struct gpio_desc *gpio[GPIO_MAX]; -+ -+ unsigned int state; -+ struct delayed_work poll; -+ struct delayed_work timeout; -+ struct mutex sm_mutex; -+ unsigned char sm_mod_state; -+ unsigned char sm_dev_state; -+ unsigned short sm_state; -+ unsigned int sm_retries; -+ -+ struct sfp_eeprom_id id; -+ -+ struct notifier_block netdev_nb; -+}; -+ -+static unsigned long poll_jiffies; -+ -+static unsigned int sfp_gpio_get_state(struct sfp *sfp) -+{ -+ unsigned int i, state, v; -+ -+ for (i = state = 0; i < GPIO_MAX; i++) { -+ if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i]) -+ continue; -+ -+ v = gpiod_get_value_cansleep(sfp->gpio[i]); -+ if (v) -+ state |= BIT(i); -+ } -+ -+ return state; -+} -+ -+static void sfp_gpio_set_state(struct sfp *sfp, unsigned int state) -+{ -+ if (state & SFP_F_PRESENT) { -+ /* If the module is present, drive the signals */ -+ if (sfp->gpio[GPIO_TX_DISABLE]) -+ gpiod_direction_output(sfp->gpio[GPIO_TX_DISABLE], -+ state & SFP_F_TX_DISABLE); -+ if (state & SFP_F_RATE_SELECT) -+ gpiod_direction_output(sfp->gpio[GPIO_RATE_SELECT], -+ state & SFP_F_RATE_SELECT); -+ } else { -+ /* Otherwise, let them float to the pull-ups */ -+ if (sfp->gpio[GPIO_TX_DISABLE]) -+ gpiod_direction_input(sfp->gpio[GPIO_TX_DISABLE]); -+ if (state & SFP_F_RATE_SELECT) -+ gpiod_direction_input(sfp->gpio[GPIO_RATE_SELECT]); -+ } -+} -+ -+static int sfp__i2c_read(struct i2c_adapter *i2c, u8 bus_addr, u8 dev_addr, -+ void *buf, size_t len) -+{ -+ struct i2c_msg msgs[2]; -+ int ret; -+ -+ msgs[0].addr = bus_addr; -+ msgs[0].flags = 0; -+ msgs[0].len = 1; -+ msgs[0].buf = &dev_addr; -+ msgs[1].addr = bus_addr; -+ msgs[1].flags = I2C_M_RD; -+ msgs[1].len = len; -+ msgs[1].buf = buf; -+ -+ ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs)); -+ if (ret < 0) -+ return ret; -+ -+ return ret == ARRAY_SIZE(msgs) ? len : 0; -+} -+ -+static int sfp_i2c_read(struct sfp *sfp, bool a2, u8 addr, void *buf, -+ size_t len) -+{ -+ return sfp__i2c_read(sfp->i2c, a2 ? 0x51 : 0x50, addr, buf, len); -+} -+ -+static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) -+{ -+ struct mii_bus *i2c_mii; -+ int ret; -+ -+ if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) -+ return -EINVAL; -+ -+ sfp->i2c = i2c; -+ sfp->read = sfp_i2c_read; -+ -+ i2c_mii = mdio_i2c_alloc(sfp->dev, i2c); -+ if (IS_ERR(i2c_mii)) -+ return PTR_ERR(i2c_mii); -+ -+ i2c_mii->name = "SFP I2C Bus"; -+ i2c_mii->phy_mask = ~0; -+ -+ ret = mdiobus_register(i2c_mii); -+ if (ret < 0) { -+ mdiobus_free(i2c_mii); -+ return ret; -+ } -+ -+ sfp->i2c_mii = i2c_mii; -+ -+ return 0; -+} -+ -+ -+/* Interface */ -+static unsigned int sfp_get_state(struct sfp *sfp) -+{ -+ return sfp->get_state(sfp); -+} -+ -+static void sfp_set_state(struct sfp *sfp, unsigned int state) -+{ -+ sfp->set_state(sfp, state); -+} -+ -+static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) -+{ -+ return sfp->read(sfp, a2, addr, buf, len); -+} -+ -+static unsigned int sfp_check(void *buf, size_t len) -+{ -+ u8 *p, check; -+ -+ for (p = buf, check = 0; len; p++, len--) -+ check += *p; -+ -+ return check; -+} -+ -+/* Helpers */ -+static void sfp_module_tx_disable(struct sfp *sfp) -+{ -+ dev_dbg(sfp->dev, "tx disable %u -> %u\n", -+ sfp->state & SFP_F_TX_DISABLE ? 1 : 0, 1); -+ sfp->state |= SFP_F_TX_DISABLE; -+ sfp_set_state(sfp, sfp->state); -+} -+ -+static void sfp_module_tx_enable(struct sfp *sfp) -+{ -+ dev_dbg(sfp->dev, "tx disable %u -> %u\n", -+ sfp->state & SFP_F_TX_DISABLE ? 1 : 0, 0); -+ sfp->state &= ~SFP_F_TX_DISABLE; -+ sfp_set_state(sfp, sfp->state); -+} -+ -+static void sfp_module_tx_fault_reset(struct sfp *sfp) -+{ -+ unsigned int state = sfp->state; -+ -+ if (state & SFP_F_TX_DISABLE) -+ return; -+ -+ sfp_set_state(sfp, state | SFP_F_TX_DISABLE); -+ -+ udelay(T_RESET_US); -+ -+ sfp_set_state(sfp, state); -+} -+ -+/* SFP state machine */ -+static void sfp_sm_set_timer(struct sfp *sfp, unsigned int timeout) -+{ -+ if (timeout) -+ mod_delayed_work(system_power_efficient_wq, &sfp->timeout, -+ timeout); -+ else -+ cancel_delayed_work(&sfp->timeout); -+} -+ -+static void sfp_sm_next(struct sfp *sfp, unsigned int state, -+ unsigned int timeout) -+{ -+ sfp->sm_state = state; -+ sfp_sm_set_timer(sfp, timeout); -+} -+ -+static void sfp_sm_ins_next(struct sfp *sfp, unsigned int state, unsigned int timeout) -+{ -+ sfp->sm_mod_state = state; -+ sfp_sm_set_timer(sfp, timeout); -+} -+ -+static void sfp_sm_phy_detach(struct sfp *sfp) -+{ -+ phy_stop(sfp->mod_phy); -+ if (sfp->phylink) -+ phylink_disconnect_phy(sfp->phylink); -+ phy_device_remove(sfp->mod_phy); -+ phy_device_free(sfp->mod_phy); -+ sfp->mod_phy = NULL; -+} -+ -+static void sfp_sm_probe_phy(struct sfp *sfp) -+{ -+ struct phy_device *phy; -+ int err; -+ -+ msleep(T_PHY_RESET_MS); -+ -+ phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR); -+ if (IS_ERR(phy)) { -+ dev_err(sfp->dev, "mdiobus scan returned %ld\n", PTR_ERR(phy)); -+ return; -+ } -+ if (!phy) { -+ dev_info(sfp->dev, "no PHY detected\n"); -+ return; -+ } -+ -+ err = phylink_connect_phy(sfp->phylink, phy); -+ if (err) { -+ phy_device_remove(phy); -+ phy_device_free(phy); -+ dev_err(sfp->dev, "phylink_connect_phy failed: %d\n", err); -+ return; -+ } -+ -+ sfp->mod_phy = phy; -+ phy_start(phy); -+} -+ -+static void sfp_sm_link_up(struct sfp *sfp) -+{ -+ if (sfp->phylink) -+ phylink_enable(sfp->phylink); -+ -+ sfp_sm_next(sfp, SFP_S_LINK_UP, 0); -+} -+ -+static void sfp_sm_link_down(struct sfp *sfp) -+{ -+ if (sfp->phylink) -+ phylink_disable(sfp->phylink); -+} -+ -+static void sfp_sm_link_check_los(struct sfp *sfp) -+{ -+ unsigned int los = sfp->state & SFP_F_LOS; -+ -+ /* FIXME: what if neither SFP_OPTIONS_LOS_INVERTED nor -+ * SFP_OPTIONS_LOS_NORMAL are set? For now, we assume -+ * the same as SFP_OPTIONS_LOS_NORMAL set. -+ */ -+ if (sfp->id.ext.options & SFP_OPTIONS_LOS_INVERTED) -+ los ^= SFP_F_LOS; -+ -+ if (los) -+ sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0); -+ else -+ sfp_sm_link_up(sfp); -+} -+ -+static void sfp_sm_fault(struct sfp *sfp, bool warn) -+{ -+ if (sfp->sm_retries && !--sfp->sm_retries) { -+ dev_err(sfp->dev, "module persistently indicates fault, disabling\n"); -+ sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0); -+ } else { -+ if (warn) -+ dev_err(sfp->dev, "module transmit fault indicated\n"); -+ -+ sfp_sm_next(sfp, SFP_S_TX_FAULT, T_FAULT_RECOVER); -+ } -+} -+ -+static void sfp_sm_mod_init(struct sfp *sfp) -+{ -+ sfp_module_tx_enable(sfp); -+ -+ /* Wait t_init before indicating that the link is up, provided the -+ * current state indicates no TX_FAULT. If TX_FAULT clears before -+ * this time, that's fine too. -+ */ -+ sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); -+ sfp->sm_retries = 5; -+ -+ if (sfp->phylink) { -+ /* Setting the serdes link mode is guesswork: there's no -+ * field in the EEPROM which indicates what mode should -+ * be used. -+ * -+ * If it's a gigabit-only fiber module, it probably does -+ * not have a PHY, so switch to 802.3z negotiation mode. -+ * Otherwise, switch to SGMII mode (which is required to -+ * support non-gigabit speeds) and probe for a PHY. -+ */ -+ if (!sfp->id.base.e1000_base_t && -+ !sfp->id.base.e100_base_lx && -+ !sfp->id.base.e100_base_fx) { -+ phylink_set_link_an_mode(sfp->phylink, MLO_AN_8023Z); -+ } else { -+ phylink_set_link_an_mode(sfp->phylink, MLO_AN_SGMII); -+ sfp_sm_probe_phy(sfp); -+ } -+ } -+} -+ -+static int sfp_sm_mod_probe(struct sfp *sfp) -+{ -+ /* SFP module inserted - read I2C data */ -+ struct sfp_eeprom_id id; -+ char vendor[17]; -+ char part[17]; -+ char sn[17]; -+ char date[9]; -+ char rev[5]; -+ u8 check; -+ int err; -+ -+ err = sfp_read(sfp, false, 0, &id, sizeof(id)); -+ if (err < 0) { -+ dev_err(sfp->dev, "failed to read EEPROM: %d\n", err); -+ return -EAGAIN; -+ } -+ -+ /* Validate the checksum over the base structure */ -+ check = sfp_check(&id.base, sizeof(id.base) - 1); -+ if (check != id.base.cc_base) { -+ dev_err(sfp->dev, -+ "EEPROM base structure checksum failure: 0x%02x\n", -+ check); -+ return -EINVAL; -+ } -+ -+ check = sfp_check(&id.ext, sizeof(id.ext) - 1); -+ if (check != id.ext.cc_ext) { -+ dev_err(sfp->dev, -+ "EEPROM extended structure checksum failure: 0x%02x\n", -+ check); -+ memset(&id.ext, 0, sizeof(id.ext)); -+ } -+ -+ sfp->id = id; -+ -+ memcpy(vendor, sfp->id.base.vendor_name, 16); -+ vendor[16] = '\0'; -+ memcpy(part, sfp->id.base.vendor_pn, 16); -+ part[16] = '\0'; -+ memcpy(rev, sfp->id.base.vendor_rev, 4); -+ rev[4] = '\0'; -+ memcpy(sn, sfp->id.ext.vendor_sn, 16); -+ sn[16] = '\0'; -+ memcpy(date, sfp->id.ext.datecode, 8); -+ date[8] = '\0'; -+ -+ dev_info(sfp->dev, "module %s %s rev %s sn %s dc %s\n", vendor, part, rev, sn, date); -+ -+ /* We only support SFP modules, not the legacy GBIC modules. */ -+ if (sfp->id.base.phys_id != SFP_PHYS_ID_SFP || -+ sfp->id.base.phys_ext_id != SFP_PHYS_EXT_ID_SFP) { -+ dev_err(sfp->dev, "module is not SFP - phys id 0x%02x 0x%02x\n", -+ sfp->id.base.phys_id, sfp->id.base.phys_ext_id); -+ return -EINVAL; -+ } -+ -+ /* -+ * What isn't clear from the SFP documentation is whether this -+ * specifies the encoding expected on the TD/RD lines, or whether -+ * the TD/RD lines are always 8b10b encoded, but the transceiver -+ * converts. Eg, think of a copper SFP supporting 1G/100M/10M -+ * ethernet: this requires 8b10b encoding for 1G, 4b5b for 100M, -+ * and manchester for 10M. -+ */ -+ /* 1Gbit ethernet requires 8b10b encoding */ -+ if (sfp->id.base.encoding != SFP_ENCODING_8B10B) { -+ dev_err(sfp->dev, "module does not support 8B10B encoding\n"); -+ return -EINVAL; -+ } -+ -+ if (sfp->phylink) { -+ u32 support; -+ u8 port; -+ -+ if (sfp->id.base.e1000_base_t) { -+ support = SUPPORTED_TP; -+ port = PORT_TP; -+ } else { -+ support = SUPPORTED_FIBRE; -+ port = PORT_FIBRE; -+ } -+ phylink_set_link_port(sfp->phylink, support, port); -+ } -+ -+ return 0; -+} -+ -+static void sfp_sm_mod_remove(struct sfp *sfp) -+{ -+ if (sfp->mod_phy) -+ sfp_sm_phy_detach(sfp); -+ -+ sfp_module_tx_disable(sfp); -+ -+ memset(&sfp->id, 0, sizeof(sfp->id)); -+ -+ dev_info(sfp->dev, "module removed\n"); -+} -+ -+static void sfp_sm_event(struct sfp *sfp, unsigned int event) -+{ -+ mutex_lock(&sfp->sm_mutex); -+ -+ dev_dbg(sfp->dev, "SM: enter %u:%u:%u event %u\n", -+ sfp->sm_mod_state, sfp->sm_dev_state, sfp->sm_state, event); -+ -+ /* This state machine tracks the insert/remove state of -+ * the module, and handles probing the on-board EEPROM. -+ */ -+ switch (sfp->sm_mod_state) { -+ default: -+ if (event == SFP_E_INSERT) { -+ sfp_module_tx_disable(sfp); -+ sfp_sm_ins_next(sfp, SFP_MOD_PROBE, T_PROBE_INIT); -+ } -+ break; -+ -+ case SFP_MOD_PROBE: -+ if (event == SFP_E_REMOVE) { -+ sfp_sm_ins_next(sfp, SFP_MOD_EMPTY, 0); -+ } else if (event == SFP_E_TIMEOUT) { -+ int err = sfp_sm_mod_probe(sfp); -+ -+ if (err == 0) -+ sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0); -+ else if (err == -EAGAIN) -+ sfp_sm_set_timer(sfp, T_PROBE_RETRY); -+ else -+ sfp_sm_ins_next(sfp, SFP_MOD_ERROR, 0); -+ } -+ break; -+ -+ case SFP_MOD_PRESENT: -+ case SFP_MOD_ERROR: -+ if (event == SFP_E_REMOVE) { -+ sfp_sm_mod_remove(sfp); -+ sfp_sm_ins_next(sfp, SFP_MOD_EMPTY, 0); -+ } -+ break; -+ } -+ -+ /* This state machine tracks the netdev up/down state */ -+ switch (sfp->sm_dev_state) { -+ default: -+ if (event == SFP_E_DEV_UP) -+ sfp->sm_dev_state = SFP_DEV_UP; -+ break; -+ -+ case SFP_DEV_UP: -+ if (event == SFP_E_DEV_DOWN) { -+ /* If the module has a PHY, avoid raising TX disable -+ * as this resets the PHY. Otherwise, raise it to -+ * turn the laser off. -+ */ -+ if (!sfp->mod_phy) -+ sfp_module_tx_disable(sfp); -+ sfp->sm_dev_state = SFP_DEV_DOWN; -+ } -+ break; -+ } -+ -+ /* Some events are global */ -+ if (sfp->sm_state != SFP_S_DOWN && -+ (sfp->sm_mod_state != SFP_MOD_PRESENT || -+ sfp->sm_dev_state != SFP_DEV_UP)) { -+ if (sfp->sm_state == SFP_S_LINK_UP && -+ sfp->sm_dev_state == SFP_DEV_UP) -+ sfp_sm_link_down(sfp); -+ if (sfp->mod_phy) -+ sfp_sm_phy_detach(sfp); -+ sfp_sm_next(sfp, SFP_S_DOWN, 0); -+ mutex_unlock(&sfp->sm_mutex); -+ return; -+ } -+ -+ /* The main state machine */ -+ switch (sfp->sm_state) { -+ case SFP_S_DOWN: -+ if (sfp->sm_mod_state == SFP_MOD_PRESENT && -+ sfp->sm_dev_state == SFP_DEV_UP) -+ sfp_sm_mod_init(sfp); -+ break; -+ -+ case SFP_S_INIT: -+ if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) -+ sfp_sm_fault(sfp, true); -+ else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) -+ sfp_sm_link_check_los(sfp); -+ break; -+ -+ case SFP_S_WAIT_LOS: -+ if (event == SFP_E_TX_FAULT) -+ sfp_sm_fault(sfp, true); -+ else if (event == -+ (sfp->id.ext.options & SFP_OPTIONS_LOS_INVERTED ? -+ SFP_E_LOS_HIGH : SFP_E_LOS_LOW)) -+ sfp_sm_link_up(sfp); -+ break; -+ -+ case SFP_S_LINK_UP: -+ if (event == SFP_E_TX_FAULT) { -+ sfp_sm_link_down(sfp); -+ sfp_sm_fault(sfp, true); -+ } else if (event == -+ (sfp->id.ext.options & SFP_OPTIONS_LOS_INVERTED ? -+ SFP_E_LOS_LOW : SFP_E_LOS_HIGH)) { -+ sfp_sm_link_down(sfp); -+ sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0); -+ } -+ break; -+ -+ case SFP_S_TX_FAULT: -+ if (event == SFP_E_TIMEOUT) { -+ sfp_module_tx_fault_reset(sfp); -+ sfp_sm_next(sfp, SFP_S_REINIT, T_INIT_JIFFIES); -+ } -+ break; -+ -+ case SFP_S_REINIT: -+ if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) { -+ sfp_sm_fault(sfp, false); -+ } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { -+ dev_info(sfp->dev, "module transmit fault recovered\n"); -+ sfp_sm_link_check_los(sfp); -+ } -+ break; -+ -+ case SFP_S_TX_DISABLE: -+ break; -+ } -+ -+ dev_dbg(sfp->dev, "SM: exit %u:%u:%u\n", -+ sfp->sm_mod_state, sfp->sm_dev_state, sfp->sm_state); -+ -+ mutex_unlock(&sfp->sm_mutex); -+} -+ -+#if 0 -+static int sfp_phy_module_info(struct phy_device *phy, -+ struct ethtool_modinfo *modinfo) -+{ -+ struct sfp *sfp = phy->priv; -+ -+ /* locking... and check module is present */ -+ -+ if (sfp->id.ext.sff8472_compliance) { -+ modinfo->type = ETH_MODULE_SFF_8472; -+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; -+ } else { -+ modinfo->type = ETH_MODULE_SFF_8079; -+ modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; -+ } -+ return 0; -+} -+ -+static int sfp_phy_module_eeprom(struct phy_device *phy, -+ struct ethtool_eeprom *ee, u8 *data) -+{ -+ struct sfp *sfp = phy->priv; -+ unsigned int first, last, len; -+ int ret; -+ -+ if (ee->len == 0) -+ return -EINVAL; -+ -+ first = ee->offset; -+ last = ee->offset + ee->len; -+ if (first < ETH_MODULE_SFF_8079_LEN) { -+ len = last; -+ if (len > ETH_MODULE_SFF_8079_LEN) -+ len = ETH_MODULE_SFF_8079_LEN; -+ len -= first; -+ -+ ret = sfp->read(sfp, false, first, data, len); -+ if (ret < 0) -+ return ret; -+ -+ first += len; -+ data += len; -+ } -+ if (first >= ETH_MODULE_SFF_8079_LEN && last > first) { -+ len = last - first; -+ -+ ret = sfp->read(sfp, true, first, data, len); -+ if (ret < 0) -+ return ret; -+ } -+ return 0; -+} -+#endif -+ -+static void sfp_timeout(struct work_struct *work) -+{ -+ struct sfp *sfp = container_of(work, struct sfp, timeout.work); -+ -+ sfp_sm_event(sfp, SFP_E_TIMEOUT); -+} -+ -+static void sfp_check_state(struct sfp *sfp) -+{ -+ unsigned int state, i, changed; -+ -+ state = sfp_get_state(sfp); -+ changed = state ^ sfp->state; -+ changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT; -+ -+ for (i = 0; i < GPIO_MAX; i++) -+ if (changed & BIT(i)) -+ dev_dbg(sfp->dev, "%s %u -> %u\n", gpio_of_names[i], -+ !!(sfp->state & BIT(i)), !!(state & BIT(i))); -+ -+ state |= sfp->state & (SFP_F_TX_DISABLE | SFP_F_RATE_SELECT); -+ sfp->state = state; -+ -+ if (changed & SFP_F_PRESENT) -+ sfp_sm_event(sfp, state & SFP_F_PRESENT ? -+ SFP_E_INSERT : SFP_E_REMOVE); -+ -+ if (changed & SFP_F_TX_FAULT) -+ sfp_sm_event(sfp, state & SFP_F_TX_FAULT ? -+ SFP_E_TX_FAULT : SFP_E_TX_CLEAR); -+ -+ if (changed & SFP_F_LOS) -+ sfp_sm_event(sfp, state & SFP_F_LOS ? -+ SFP_E_LOS_HIGH : SFP_E_LOS_LOW); -+} -+ -+static irqreturn_t sfp_irq(int irq, void *data) -+{ -+ struct sfp *sfp = data; -+ -+ sfp_check_state(sfp); -+ -+ return IRQ_HANDLED; -+} -+ -+static void sfp_poll(struct work_struct *work) -+{ -+ struct sfp *sfp = container_of(work, struct sfp, poll.work); -+ -+ sfp_check_state(sfp); -+ mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); -+} -+ -+static int sfp_netdev_notify(struct notifier_block *nb, unsigned long act, void *data) -+{ -+ struct sfp *sfp = container_of(nb, struct sfp, netdev_nb); -+ struct netdev_notifier_info *info = data; -+ struct net_device *ndev = info->dev; -+ -+ if (!sfp->ndev || ndev != sfp->ndev) -+ return NOTIFY_DONE; -+ -+ switch (act) { -+ case NETDEV_UP: -+ sfp_sm_event(sfp, SFP_E_DEV_UP); -+ break; -+ -+ case NETDEV_GOING_DOWN: -+ sfp_sm_event(sfp, SFP_E_DEV_DOWN); -+ break; -+ -+ case NETDEV_UNREGISTER: -+ if (sfp->mod_phy && sfp->phylink) -+ phylink_disconnect_phy(sfp->phylink); -+ sfp->phylink = NULL; -+ dev_put(sfp->ndev); -+ sfp->ndev = NULL; -+ break; -+ } -+ return NOTIFY_OK; -+} -+ -+static struct sfp *sfp_alloc(struct device *dev) -+{ -+ struct sfp *sfp; -+ -+ sfp = kzalloc(sizeof(*sfp), GFP_KERNEL); -+ if (!sfp) -+ return ERR_PTR(-ENOMEM); -+ -+ sfp->dev = dev; -+ -+ mutex_init(&sfp->sm_mutex); -+ INIT_DELAYED_WORK(&sfp->poll, sfp_poll); -+ INIT_DELAYED_WORK(&sfp->timeout, sfp_timeout); -+ -+ sfp->netdev_nb.notifier_call = sfp_netdev_notify; -+ -+ return sfp; -+} -+ -+static void sfp_destroy(struct sfp *sfp) -+{ -+ cancel_delayed_work_sync(&sfp->poll); -+ cancel_delayed_work_sync(&sfp->timeout); -+ if (sfp->i2c_mii) { -+ mdiobus_unregister(sfp->i2c_mii); -+ mdiobus_free(sfp->i2c_mii); -+ } -+ if (sfp->i2c) -+ i2c_put_adapter(sfp->i2c); -+ of_node_put(sfp->dev->of_node); -+ kfree(sfp); -+} -+ -+static void sfp_cleanup(void *data) -+{ -+ struct sfp *sfp = data; -+ -+ sfp_destroy(sfp); -+} -+ -+static int sfp_probe(struct platform_device *pdev) -+{ -+ struct sfp *sfp; -+ bool poll = false; -+ int irq, err, i; -+ -+ sfp = sfp_alloc(&pdev->dev); -+ if (IS_ERR(sfp)) -+ return PTR_ERR(sfp); -+ -+ platform_set_drvdata(pdev, sfp); -+ -+ err = devm_add_action(sfp->dev, sfp_cleanup, sfp); -+ if (err < 0) -+ return err; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *node = pdev->dev.of_node; -+ struct device_node *np; -+ -+ np = of_parse_phandle(node, "i2c-bus", 0); -+ if (np) { -+ struct i2c_adapter *i2c; -+ -+ i2c = of_find_i2c_adapter_by_node(np); -+ of_node_put(np); -+ if (!i2c) -+ return -EPROBE_DEFER; -+ -+ err = sfp_i2c_configure(sfp, i2c); -+ if (err < 0) { -+ i2c_put_adapter(i2c); -+ return err; -+ } -+ } -+ -+ for (i = 0; i < GPIO_MAX; i++) { -+ sfp->gpio[i] = devm_gpiod_get_optional(sfp->dev, -+ gpio_of_names[i], gpio_flags[i]); -+ if (IS_ERR(sfp->gpio[i])) -+ return PTR_ERR(sfp->gpio[i]); -+ } -+ -+ sfp->get_state = sfp_gpio_get_state; -+ sfp->set_state = sfp_gpio_set_state; -+ -+ np = of_parse_phandle(node, "sfp,ethernet", 0); -+ if (!np) { -+ dev_err(sfp->dev, "missing sfp,ethernet property\n"); -+ return -EINVAL; -+ } -+ -+ sfp->ndev = of_find_net_device_by_node(np); -+ if (!sfp->ndev) { -+ dev_err(sfp->dev, "ethernet device not found\n"); -+ return -EPROBE_DEFER; -+ } -+ -+ dev_hold(sfp->ndev); -+ put_device(&sfp->ndev->dev); -+ -+ sfp->phylink = phylink_lookup_by_netdev(sfp->ndev); -+ if (!sfp->phylink) { -+ dev_err(sfp->dev, "ethernet device not found\n"); -+ return -EPROBE_DEFER; -+ } -+ -+ phylink_disable(sfp->phylink); -+ } -+ -+ sfp->state = sfp_get_state(sfp); -+ if (sfp->gpio[GPIO_TX_DISABLE] && -+ gpiod_get_value_cansleep(sfp->gpio[GPIO_TX_DISABLE])) -+ sfp->state |= SFP_F_TX_DISABLE; -+ if (sfp->gpio[GPIO_RATE_SELECT] && -+ gpiod_get_value_cansleep(sfp->gpio[GPIO_RATE_SELECT])) -+ sfp->state |= SFP_F_RATE_SELECT; -+ sfp_set_state(sfp, sfp->state); -+ sfp_module_tx_disable(sfp); -+ if (sfp->state & SFP_F_PRESENT) -+ sfp_sm_event(sfp, SFP_E_INSERT); -+ -+ for (i = 0; i < GPIO_MAX; i++) { -+ if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i]) -+ continue; -+ -+ irq = gpiod_to_irq(sfp->gpio[i]); -+ if (!irq) { -+ poll = true; -+ continue; -+ } -+ -+ err = devm_request_threaded_irq(sfp->dev, irq, NULL, sfp_irq, -+ IRQF_ONESHOT | -+ IRQF_TRIGGER_RISING | -+ IRQF_TRIGGER_FALLING, -+ dev_name(sfp->dev), sfp); -+ if (err) -+ poll = true; -+ } -+ -+ if (poll) -+ mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); -+ -+ register_netdevice_notifier(&sfp->netdev_nb); -+ -+ return 0; -+} -+ -+static int sfp_remove(struct platform_device *pdev) -+{ -+ struct sfp *sfp = platform_get_drvdata(pdev); -+ -+ unregister_netdevice_notifier(&sfp->netdev_nb); -+ if (sfp->ndev) -+ dev_put(sfp->ndev); -+ -+ return 0; -+} -+ -+static const struct of_device_id sfp_of_match[] = { -+ { .compatible = "sff,sfp", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, sfp_of_match); -+ -+static struct platform_driver sfp_driver = { -+ .probe = sfp_probe, -+ .remove = sfp_remove, -+ .driver = { -+ .name = "sfp", -+ .of_match_table = sfp_of_match, -+ }, -+}; -+ -+static int sfp_init(void) -+{ -+ poll_jiffies = msecs_to_jiffies(100); -+ -+ return platform_driver_register(&sfp_driver); -+} -+module_init(sfp_init); -+ -+static void sfp_exit(void) -+{ -+ platform_driver_unregister(&sfp_driver); -+} -+module_exit(sfp_exit); -+ -+MODULE_ALIAS("platform:sfp"); -+MODULE_AUTHOR("Russell King"); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/include/linux/sfp.h -@@ -0,0 +1,339 @@ -+#ifndef LINUX_SFP_H -+#define LINUX_SFP_H -+ -+struct __packed sfp_eeprom_base { -+ u8 phys_id; -+ u8 phys_ext_id; -+ u8 connector; -+#if defined __BIG_ENDIAN_BITFIELD -+ u8 e10g_base_er:1; -+ u8 e10g_base_lrm:1; -+ u8 e10g_base_lr:1; -+ u8 e10g_base_sr:1; -+ u8 if_1x_sx:1; -+ u8 if_1x_lx:1; -+ u8 if_1x_copper_active:1; -+ u8 if_1x_copper_passive:1; -+ -+ u8 escon_mmf_1310_led:1; -+ u8 escon_smf_1310_laser:1; -+ u8 sonet_oc192_short_reach:1; -+ u8 sonet_reach_bit1:1; -+ u8 sonet_reach_bit2:1; -+ u8 sonet_oc48_long_reach:1; -+ u8 sonet_oc48_intermediate_reach:1; -+ u8 sonet_oc48_short_reach:1; -+ -+ u8 unallocated_5_7:1; -+ u8 sonet_oc12_smf_long_reach:1; -+ u8 sonet_oc12_smf_intermediate_reach:1; -+ u8 sonet_oc12_short_reach:1; -+ u8 unallocated_5_3:1; -+ u8 sonet_oc3_smf_long_reach:1; -+ u8 sonet_oc3_smf_intermediate_reach:1; -+ u8 sonet_oc3_short_reach:1; -+ -+ u8 e_base_px:1; -+ u8 e_base_bx10:1; -+ u8 e100_base_fx:1; -+ u8 e100_base_lx:1; -+ u8 e1000_base_t:1; -+ u8 e1000_base_cx:1; -+ u8 e1000_base_lx:1; -+ u8 e1000_base_sx:1; -+ -+ u8 fc_ll_v:1; -+ u8 fc_ll_s:1; -+ u8 fc_ll_i:1; -+ u8 fc_ll_l:1; -+ u8 fc_ll_m:1; -+ u8 fc_tech_sa:1; -+ u8 fc_tech_lc:1; -+ u8 fc_tech_electrical_inter_enclosure:1; -+ -+ u8 fc_tech_electrical_intra_enclosure:1; -+ u8 fc_tech_sn:1; -+ u8 fc_tech_sl:1; -+ u8 fc_tech_ll:1; -+ u8 sfp_ct_active:1; -+ u8 sfp_ct_passive:1; -+ u8 unallocated_8_1:1; -+ u8 unallocated_8_0:1; -+ -+ u8 fc_media_tw:1; -+ u8 fc_media_tp:1; -+ u8 fc_media_mi:1; -+ u8 fc_media_tv:1; -+ u8 fc_media_m6:1; -+ u8 fc_media_m5:1; -+ u8 unallocated_9_1:1; -+ u8 fc_media_sm:1; -+ -+ u8 fc_speed_1200:1; -+ u8 fc_speed_800:1; -+ u8 fc_speed_1600:1; -+ u8 fc_speed_400:1; -+ u8 fc_speed_3200:1; -+ u8 fc_speed_200:1; -+ u8 unallocated_10_1:1; -+ u8 fc_speed_100:1; -+#elif defined __LITTLE_ENDIAN_BITFIELD -+ u8 if_1x_copper_passive:1; -+ u8 if_1x_copper_active:1; -+ u8 if_1x_lx:1; -+ u8 if_1x_sx:1; -+ u8 e10g_base_sr:1; -+ u8 e10g_base_lr:1; -+ u8 e10g_base_lrm:1; -+ u8 e10g_base_er:1; -+ -+ u8 sonet_oc3_short_reach:1; -+ u8 sonet_oc3_smf_intermediate_reach:1; -+ u8 sonet_oc3_smf_long_reach:1; -+ u8 unallocated_5_3:1; -+ u8 sonet_oc12_short_reach:1; -+ u8 sonet_oc12_smf_intermediate_reach:1; -+ u8 sonet_oc12_smf_long_reach:1; -+ u8 unallocated_5_7:1; -+ -+ u8 sonet_oc48_short_reach:1; -+ u8 sonet_oc48_intermediate_reach:1; -+ u8 sonet_oc48_long_reach:1; -+ u8 sonet_reach_bit2:1; -+ u8 sonet_reach_bit1:1; -+ u8 sonet_oc192_short_reach:1; -+ u8 escon_smf_1310_laser:1; -+ u8 escon_mmf_1310_led:1; -+ -+ u8 e1000_base_sx:1; -+ u8 e1000_base_lx:1; -+ u8 e1000_base_cx:1; -+ u8 e1000_base_t:1; -+ u8 e100_base_lx:1; -+ u8 e100_base_fx:1; -+ u8 e_base_bx10:1; -+ u8 e_base_px:1; -+ -+ u8 fc_tech_electrical_inter_enclosure:1; -+ u8 fc_tech_lc:1; -+ u8 fc_tech_sa:1; -+ u8 fc_ll_m:1; -+ u8 fc_ll_l:1; -+ u8 fc_ll_i:1; -+ u8 fc_ll_s:1; -+ u8 fc_ll_v:1; -+ -+ u8 unallocated_8_0:1; -+ u8 unallocated_8_1:1; -+ u8 sfp_ct_passive:1; -+ u8 sfp_ct_active:1; -+ u8 fc_tech_ll:1; -+ u8 fc_tech_sl:1; -+ u8 fc_tech_sn:1; -+ u8 fc_tech_electrical_intra_enclosure:1; -+ -+ u8 fc_media_sm:1; -+ u8 unallocated_9_1:1; -+ u8 fc_media_m5:1; -+ u8 fc_media_m6:1; -+ u8 fc_media_tv:1; -+ u8 fc_media_mi:1; -+ u8 fc_media_tp:1; -+ u8 fc_media_tw:1; -+ -+ u8 fc_speed_100:1; -+ u8 unallocated_10_1:1; -+ u8 fc_speed_200:1; -+ u8 fc_speed_3200:1; -+ u8 fc_speed_400:1; -+ u8 fc_speed_1600:1; -+ u8 fc_speed_800:1; -+ u8 fc_speed_1200:1; -+#else -+#error Unknown Endian -+#endif -+ u8 encoding; -+ u8 br_nominal; -+ u8 rate_id; -+ u8 link_len[6]; -+ char vendor_name[16]; -+ u8 reserved36; -+ char vendor_oui[3]; -+ char vendor_pn[16]; -+ char vendor_rev[4]; -+ union { -+ __be16 optical_wavelength; -+ u8 cable_spec; -+ }; -+ u8 reserved62; -+ u8 cc_base; -+}; -+ -+struct __packed sfp_eeprom_ext { -+ __be16 options; -+ u8 br_max; -+ u8 br_min; -+ char vendor_sn[16]; -+ char datecode[8]; -+ u8 diagmon; -+ u8 enhopts; -+ u8 sff8472_compliance; -+ u8 cc_ext; -+}; -+ -+struct __packed sfp_eeprom_id { -+ struct sfp_eeprom_base base; -+ struct sfp_eeprom_ext ext; -+}; -+ -+/* SFP EEPROM registers */ -+enum { -+ SFP_PHYS_ID = 0x00, -+ SFP_PHYS_EXT_ID = 0x01, -+ SFP_CONNECTOR = 0x02, -+ SFP_COMPLIANCE = 0x03, -+ SFP_ENCODING = 0x0b, -+ SFP_BR_NOMINAL = 0x0c, -+ SFP_RATE_ID = 0x0d, -+ SFP_LINK_LEN_SM_KM = 0x0e, -+ SFP_LINK_LEN_SM_100M = 0x0f, -+ SFP_LINK_LEN_50UM_OM2_10M = 0x10, -+ SFP_LINK_LEN_62_5UM_OM1_10M = 0x11, -+ SFP_LINK_LEN_COPPER_1M = 0x12, -+ SFP_LINK_LEN_50UM_OM4_10M = 0x12, -+ SFP_LINK_LEN_50UM_OM3_10M = 0x13, -+ SFP_VENDOR_NAME = 0x14, -+ SFP_VENDOR_OUI = 0x25, -+ SFP_VENDOR_PN = 0x28, -+ SFP_VENDOR_REV = 0x38, -+ SFP_OPTICAL_WAVELENGTH_MSB = 0x3c, -+ SFP_OPTICAL_WAVELENGTH_LSB = 0x3d, -+ SFP_CABLE_SPEC = 0x3c, -+ SFP_CC_BASE = 0x3f, -+ SFP_OPTIONS = 0x40, /* 2 bytes, MSB, LSB */ -+ SFP_BR_MAX = 0x42, -+ SFP_BR_MIN = 0x43, -+ SFP_VENDOR_SN = 0x44, -+ SFP_DATECODE = 0x54, -+ SFP_DIAGMON = 0x5c, -+ SFP_ENHOPTS = 0x5d, -+ SFP_SFF8472_COMPLIANCE = 0x5e, -+ SFP_CC_EXT = 0x5f, -+ -+ SFP_PHYS_ID_SFP = 0x03, -+ SFP_PHYS_EXT_ID_SFP = 0x04, -+ SFP_CONNECTOR_UNSPEC = 0x00, -+ /* codes 01-05 not supportable on SFP, but some modules have single SC */ -+ SFP_CONNECTOR_SC = 0x01, -+ SFP_CONNECTOR_FIBERJACK = 0x06, -+ SFP_CONNECTOR_LC = 0x07, -+ SFP_CONNECTOR_MT_RJ = 0x08, -+ SFP_CONNECTOR_MU = 0x09, -+ SFP_CONNECTOR_SG = 0x0a, -+ SFP_CONNECTOR_OPTICAL_PIGTAIL = 0x0b, -+ SFP_CONNECTOR_HSSDC_II = 0x20, -+ SFP_CONNECTOR_COPPER_PIGTAIL = 0x21, -+ SFP_ENCODING_UNSPEC = 0x00, -+ SFP_ENCODING_8B10B = 0x01, -+ SFP_ENCODING_4B5B = 0x02, -+ SFP_ENCODING_NRZ = 0x03, -+ SFP_ENCODING_MANCHESTER = 0x04, -+ SFP_OPTIONS_HIGH_POWER_LEVEL = BIT(13), -+ SFP_OPTIONS_PAGING_A2 = BIT(12), -+ SFP_OPTIONS_RETIMER = BIT(11), -+ SFP_OPTIONS_COOLED_XCVR = BIT(10), -+ SFP_OPTIONS_POWER_DECL = BIT(9), -+ SFP_OPTIONS_RX_LINEAR_OUT = BIT(8), -+ SFP_OPTIONS_RX_DECISION_THRESH = BIT(7), -+ SFP_OPTIONS_TUNABLE_TX = BIT(6), -+ SFP_OPTIONS_RATE_SELECT = BIT(5), -+ SFP_OPTIONS_TX_DISABLE = BIT(4), -+ SFP_OPTIONS_TX_FAULT = BIT(3), -+ SFP_OPTIONS_LOS_INVERTED = BIT(2), -+ SFP_OPTIONS_LOS_NORMAL = BIT(1), -+ SFP_DIAGMON_DDM = BIT(6), -+ SFP_DIAGMON_INT_CAL = BIT(5), -+ SFP_DIAGMON_EXT_CAL = BIT(4), -+ SFP_DIAGMON_RXPWR_AVG = BIT(3), -+ SFP_DIAGMON_ADDRMODE = BIT(2), -+ SFP_ENHOPTS_ALARMWARN = BIT(7), -+ SFP_ENHOPTS_SOFT_TX_DISABLE = BIT(6), -+ SFP_ENHOPTS_SOFT_TX_FAULT = BIT(5), -+ SFP_ENHOPTS_SOFT_RX_LOS = BIT(4), -+ SFP_ENHOPTS_SOFT_RATE_SELECT = BIT(3), -+ SFP_ENHOPTS_APP_SELECT_SFF8079 = BIT(2), -+ SFP_ENHOPTS_SOFT_RATE_SFF8431 = BIT(1), -+ SFP_SFF8472_COMPLIANCE_NONE = 0x00, -+ SFP_SFF8472_COMPLIANCE_REV9_3 = 0x01, -+ SFP_SFF8472_COMPLIANCE_REV9_5 = 0x02, -+ SFP_SFF8472_COMPLIANCE_REV10_2 = 0x03, -+ SFP_SFF8472_COMPLIANCE_REV10_4 = 0x04, -+ SFP_SFF8472_COMPLIANCE_REV11_0 = 0x05, -+ SFP_SFF8472_COMPLIANCE_REV11_3 = 0x06, -+ SFP_SFF8472_COMPLIANCE_REV11_4 = 0x07, -+ SFP_SFF8472_COMPLIANCE_REV12_0 = 0x08, -+}; -+ -+/* SFP Diagnostics */ -+enum { -+ /* Alarm and warnings stored MSB at lower address then LSB */ -+ SFP_TEMP_HIGH_ALARM = 0x00, -+ SFP_TEMP_LOW_ALARM = 0x02, -+ SFP_TEMP_HIGH_WARN = 0x04, -+ SFP_TEMP_LOW_WARN = 0x06, -+ SFP_VOLT_HIGH_ALARM = 0x08, -+ SFP_VOLT_LOW_ALARM = 0x0a, -+ SFP_VOLT_HIGH_WARN = 0x0c, -+ SFP_VOLT_LOW_WARN = 0x0e, -+ SFP_BIAS_HIGH_ALARM = 0x10, -+ SFP_BIAS_LOW_ALARM = 0x12, -+ SFP_BIAS_HIGH_WARN = 0x14, -+ SFP_BIAS_LOW_WARN = 0x16, -+ SFP_TXPWR_HIGH_ALARM = 0x18, -+ SFP_TXPWR_LOW_ALARM = 0x1a, -+ SFP_TXPWR_HIGH_WARN = 0x1c, -+ SFP_TXPWR_LOW_WARN = 0x1e, -+ SFP_RXPWR_HIGH_ALARM = 0x20, -+ SFP_RXPWR_LOW_ALARM = 0x22, -+ SFP_RXPWR_HIGH_WARN = 0x24, -+ SFP_RXPWR_LOW_WARN = 0x26, -+ SFP_LASER_TEMP_HIGH_ALARM = 0x28, -+ SFP_LASER_TEMP_LOW_ALARM = 0x2a, -+ SFP_LASER_TEMP_HIGH_WARN = 0x2c, -+ SFP_LASER_TEMP_LOW_WARN = 0x2e, -+ SFP_TEC_CUR_HIGH_ALARM = 0x30, -+ SFP_TEC_CUR_LOW_ALARM = 0x32, -+ SFP_TEC_CUR_HIGH_WARN = 0x34, -+ SFP_TEC_CUR_LOW_WARN = 0x36, -+ SFP_CAL_RXPWR4 = 0x38, -+ SFP_CAL_RXPWR3 = 0x3c, -+ SFP_CAL_RXPWR2 = 0x40, -+ SFP_CAL_RXPWR1 = 0x44, -+ SFP_CAL_RXPWR0 = 0x48, -+ SFP_CAL_TXI_SLOPE = 0x4c, -+ SFP_CAL_TXI_OFFSET = 0x4e, -+ SFP_CAL_TXPWR_SLOPE = 0x50, -+ SFP_CAL_TXPWR_OFFSET = 0x52, -+ SFP_CAL_T_SLOPE = 0x54, -+ SFP_CAL_T_OFFSET = 0x56, -+ SFP_CAL_V_SLOPE = 0x58, -+ SFP_CAL_V_OFFSET = 0x5a, -+ SFP_CHKSUM = 0x5f, -+ -+ SFP_TEMP = 0x60, -+ SFP_VCC = 0x62, -+ SFP_TX_BIAS = 0x64, -+ SFP_TX_POWER = 0x66, -+ SFP_RX_POWER = 0x68, -+ SFP_LASER_TEMP = 0x6a, -+ SFP_TEC_CUR = 0x6c, -+ -+ SFP_STATUS = 0x6e, -+ SFP_ALARM = 0x70, -+ -+ SFP_EXT_STATUS = 0x76, -+ SFP_VSL = 0x78, -+ SFP_PAGE = 0x7f, -+}; -+ -+#endif diff --git a/target/linux/mvebu/patches-4.4/133-sfp-display-SFP-module-information.patch b/target/linux/mvebu/patches-4.4/133-sfp-display-SFP-module-information.patch deleted file mode 100644 index bc039ee199..0000000000 --- a/target/linux/mvebu/patches-4.4/133-sfp-display-SFP-module-information.patch +++ /dev/null @@ -1,283 +0,0 @@ -From 66c248886538d7ee97ef2fe498061f857d4c906a Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 13 Sep 2015 01:06:31 +0100 -Subject: [PATCH 721/744] sfp: display SFP module information - -Signed-off-by: Russell King ---- - drivers/net/phy/sfp.c | 247 +++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 246 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -248,6 +248,182 @@ static unsigned int sfp_check(void *buf, - return check; - } - -+static const char *sfp_link_len(char *buf, size_t size, unsigned int length, -+ unsigned int multiplier) -+{ -+ if (length == 0) -+ return "unsupported/unspecified"; -+ -+ if (length == 255) { -+ *buf++ = '>'; -+ size -= 1; -+ length -= 1; -+ } -+ -+ length *= multiplier; -+ -+ if (length >= 1000) -+ snprintf(buf, size, "%u.%0*ukm", -+ length / 1000, -+ multiplier > 100 ? 1 : -+ multiplier > 10 ? 2 : 3, -+ length % 1000); -+ else -+ snprintf(buf, size, "%um", length); -+ -+ return buf; -+} -+ -+struct bitfield { -+ unsigned int mask; -+ unsigned int val; -+ const char *str; -+}; -+ -+static const struct bitfield sfp_options[] = { -+ { -+ .mask = SFP_OPTIONS_HIGH_POWER_LEVEL, -+ .val = SFP_OPTIONS_HIGH_POWER_LEVEL, -+ .str = "hpl", -+ }, { -+ .mask = SFP_OPTIONS_PAGING_A2, -+ .val = SFP_OPTIONS_PAGING_A2, -+ .str = "paginga2", -+ }, { -+ .mask = SFP_OPTIONS_RETIMER, -+ .val = SFP_OPTIONS_RETIMER, -+ .str = "retimer", -+ }, { -+ .mask = SFP_OPTIONS_COOLED_XCVR, -+ .val = SFP_OPTIONS_COOLED_XCVR, -+ .str = "cooled", -+ }, { -+ .mask = SFP_OPTIONS_POWER_DECL, -+ .val = SFP_OPTIONS_POWER_DECL, -+ .str = "powerdecl", -+ }, { -+ .mask = SFP_OPTIONS_RX_LINEAR_OUT, -+ .val = SFP_OPTIONS_RX_LINEAR_OUT, -+ .str = "rxlinear", -+ }, { -+ .mask = SFP_OPTIONS_RX_DECISION_THRESH, -+ .val = SFP_OPTIONS_RX_DECISION_THRESH, -+ .str = "rxthresh", -+ }, { -+ .mask = SFP_OPTIONS_TUNABLE_TX, -+ .val = SFP_OPTIONS_TUNABLE_TX, -+ .str = "tunabletx", -+ }, { -+ .mask = SFP_OPTIONS_RATE_SELECT, -+ .val = SFP_OPTIONS_RATE_SELECT, -+ .str = "ratesel", -+ }, { -+ .mask = SFP_OPTIONS_TX_DISABLE, -+ .val = SFP_OPTIONS_TX_DISABLE, -+ .str = "txdisable", -+ }, { -+ .mask = SFP_OPTIONS_TX_FAULT, -+ .val = SFP_OPTIONS_TX_FAULT, -+ .str = "txfault", -+ }, { -+ .mask = SFP_OPTIONS_LOS_INVERTED, -+ .val = SFP_OPTIONS_LOS_INVERTED, -+ .str = "los-", -+ }, { -+ .mask = SFP_OPTIONS_LOS_NORMAL, -+ .val = SFP_OPTIONS_LOS_NORMAL, -+ .str = "los+", -+ }, { } -+}; -+ -+static const struct bitfield diagmon[] = { -+ { -+ .mask = SFP_DIAGMON_DDM, -+ .val = SFP_DIAGMON_DDM, -+ .str = "ddm", -+ }, { -+ .mask = SFP_DIAGMON_INT_CAL, -+ .val = SFP_DIAGMON_INT_CAL, -+ .str = "intcal", -+ }, { -+ .mask = SFP_DIAGMON_EXT_CAL, -+ .val = SFP_DIAGMON_EXT_CAL, -+ .str = "extcal", -+ }, { -+ .mask = SFP_DIAGMON_RXPWR_AVG, -+ .val = SFP_DIAGMON_RXPWR_AVG, -+ .str = "rxpwravg", -+ }, { } -+}; -+ -+static const char *sfp_bitfield(char *out, size_t outsz, const struct bitfield *bits, unsigned int val) -+{ -+ char *p = out; -+ int n; -+ -+ *p = '\0'; -+ while (bits->mask) { -+ if ((val & bits->mask) == bits->val) { -+ n = snprintf(p, outsz, "%s%s", -+ out != p ? ", " : "", -+ bits->str); -+ if (n == outsz) -+ break; -+ p += n; -+ outsz -= n; -+ } -+ bits++; -+ } -+ -+ return out; -+} -+ -+static const char *sfp_connector(unsigned int connector) -+{ -+ switch (connector) { -+ case SFP_CONNECTOR_UNSPEC: -+ return "unknown/unspecified"; -+ case SFP_CONNECTOR_SC: -+ return "SC"; -+ case SFP_CONNECTOR_FIBERJACK: -+ return "Fiberjack"; -+ case SFP_CONNECTOR_LC: -+ return "LC"; -+ case SFP_CONNECTOR_MT_RJ: -+ return "MT-RJ"; -+ case SFP_CONNECTOR_MU: -+ return "MU"; -+ case SFP_CONNECTOR_SG: -+ return "SG"; -+ case SFP_CONNECTOR_OPTICAL_PIGTAIL: -+ return "Optical pigtail"; -+ case SFP_CONNECTOR_HSSDC_II: -+ return "HSSDC II"; -+ case SFP_CONNECTOR_COPPER_PIGTAIL: -+ return "Copper pigtail"; -+ default: -+ return "unknown"; -+ } -+} -+ -+static const char *sfp_encoding(unsigned int encoding) -+{ -+ switch (encoding) { -+ case SFP_ENCODING_UNSPEC: -+ return "unspecified"; -+ case SFP_ENCODING_8B10B: -+ return "8b10b"; -+ case SFP_ENCODING_4B5B: -+ return "4b5b"; -+ case SFP_ENCODING_NRZ: -+ return "NRZ"; -+ case SFP_ENCODING_MANCHESTER: -+ return "MANCHESTER"; -+ default: -+ return "unknown"; -+ } -+} -+ - /* Helpers */ - static void sfp_module_tx_disable(struct sfp *sfp) - { -@@ -426,6 +602,7 @@ static int sfp_sm_mod_probe(struct sfp * - char sn[17]; - char date[9]; - char rev[5]; -+ char options[80]; - u8 check; - int err; - -@@ -462,10 +639,78 @@ static int sfp_sm_mod_probe(struct sfp * - rev[4] = '\0'; - memcpy(sn, sfp->id.ext.vendor_sn, 16); - sn[16] = '\0'; -- memcpy(date, sfp->id.ext.datecode, 8); -+ date[0] = sfp->id.ext.datecode[4]; -+ date[1] = sfp->id.ext.datecode[5]; -+ date[2] = '-'; -+ date[3] = sfp->id.ext.datecode[2]; -+ date[4] = sfp->id.ext.datecode[3]; -+ date[5] = '-'; -+ date[6] = sfp->id.ext.datecode[0]; -+ date[7] = sfp->id.ext.datecode[1]; - date[8] = '\0'; - - dev_info(sfp->dev, "module %s %s rev %s sn %s dc %s\n", vendor, part, rev, sn, date); -+ dev_info(sfp->dev, " %s connector, encoding %s, nominal bitrate %u.%uGbps +%u%% -%u%%\n", -+ sfp_connector(sfp->id.base.connector), -+ sfp_encoding(sfp->id.base.encoding), -+ sfp->id.base.br_nominal / 10, -+ sfp->id.base.br_nominal % 10, -+ sfp->id.ext.br_max, sfp->id.ext.br_min); -+ dev_info(sfp->dev, " 1000BaseSX%c 1000BaseLX%c 1000BaseCX%c 1000BaseT%c 100BaseTLX%c 1000BaseFX%c BaseBX10%c BasePX%c\n", -+ sfp->id.base.e1000_base_sx ? '+' : '-', -+ sfp->id.base.e1000_base_lx ? '+' : '-', -+ sfp->id.base.e1000_base_cx ? '+' : '-', -+ sfp->id.base.e1000_base_t ? '+' : '-', -+ sfp->id.base.e100_base_lx ? '+' : '-', -+ sfp->id.base.e100_base_fx ? '+' : '-', -+ sfp->id.base.e_base_bx10 ? '+' : '-', -+ sfp->id.base.e_base_px ? '+' : '-'); -+ -+ if (!sfp->id.base.sfp_ct_passive && !sfp->id.base.sfp_ct_active && -+ !sfp->id.base.e1000_base_t) { -+ char len_9um[16], len_om[16]; -+ -+ dev_info(sfp->dev, " Wavelength %unm, fiber lengths:\n", -+ be16_to_cpup(&sfp->id.base.optical_wavelength)); -+ -+ if (sfp->id.base.link_len[0] == 255) -+ strcpy(len_9um, ">254km"); -+ else if (sfp->id.base.link_len[1] && sfp->id.base.link_len[1] != 255) -+ sprintf(len_9um, "%um", -+ sfp->id.base.link_len[1] * 100); -+ else if (sfp->id.base.link_len[0]) -+ sprintf(len_9um, "%ukm", sfp->id.base.link_len[0]); -+ else if (sfp->id.base.link_len[1] == 255) -+ strcpy(len_9um, ">25.4km"); -+ else -+ strcpy(len_9um, "unsupported"); -+ -+ dev_info(sfp->dev, " 9µm SM : %s\n", len_9um); -+ dev_info(sfp->dev, " 62.5µm MM OM1: %s\n", -+ sfp_link_len(len_om, sizeof(len_om), -+ sfp->id.base.link_len[3], 10)); -+ dev_info(sfp->dev, " 50µm MM OM2: %s\n", -+ sfp_link_len(len_om, sizeof(len_om), -+ sfp->id.base.link_len[2], 10)); -+ dev_info(sfp->dev, " 50µm MM OM3: %s\n", -+ sfp_link_len(len_om, sizeof(len_om), -+ sfp->id.base.link_len[5], 10)); -+ dev_info(sfp->dev, " 50µm MM OM4: %s\n", -+ sfp_link_len(len_om, sizeof(len_om), -+ sfp->id.base.link_len[4], 10)); -+ } else { -+ char len[16]; -+ dev_info(sfp->dev, " Copper length: %s\n", -+ sfp_link_len(len, sizeof(len), -+ sfp->id.base.link_len[4], 1)); -+ } -+ -+ dev_info(sfp->dev, " Options: %s\n", -+ sfp_bitfield(options, sizeof(options), sfp_options, -+ be16_to_cpu(sfp->id.ext.options))); -+ dev_info(sfp->dev, " Diagnostics: %s\n", -+ sfp_bitfield(options, sizeof(options), diagmon, -+ sfp->id.ext.diagmon)); - - /* We only support SFP modules, not the legacy GBIC modules. */ - if (sfp->id.base.phys_id != SFP_PHYS_ID_SFP || diff --git a/target/linux/mvebu/patches-4.4/134-net-mvneta-convert-to-phylink.patch b/target/linux/mvebu/patches-4.4/134-net-mvneta-convert-to-phylink.patch deleted file mode 100644 index fac283f3ee..0000000000 --- a/target/linux/mvebu/patches-4.4/134-net-mvneta-convert-to-phylink.patch +++ /dev/null @@ -1,697 +0,0 @@ -From e268be0ddc666f4a98db462cbed2a97637e82b5c Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Wed, 16 Sep 2015 21:27:10 +0100 -Subject: [PATCH 722/744] net: mvneta: convert to phylink - -Convert mvneta to use phylink, which models the MAC to PHY link in -a generic, reusable form. - -Signed-off-by: Russell King ---- - drivers/net/ethernet/marvell/Kconfig | 2 +- - drivers/net/ethernet/marvell/mvneta.c | 451 +++++++++++++++++----------------- - 2 files changed, 227 insertions(+), 226 deletions(-) - ---- a/drivers/net/ethernet/marvell/Kconfig -+++ b/drivers/net/ethernet/marvell/Kconfig -@@ -58,7 +58,7 @@ config MVNETA - tristate "Marvell Armada 370/38x/XP network interface support" - depends on PLAT_ORION - select MVMDIO -- select FIXED_PHY -+ select PHYLINK - ---help--- - This driver supports the network interface units in the - Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family. ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -188,6 +189,7 @@ - #define MVNETA_GMAC_CTRL_0 0x2c00 - #define MVNETA_GMAC_MAX_RX_SIZE_SHIFT 2 - #define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc -+#define MVNETA_GMAC0_PORT_1000BASE_X BIT(1) - #define MVNETA_GMAC0_PORT_ENABLE BIT(0) - #define MVNETA_GMAC_CTRL_2 0x2c08 - #define MVNETA_GMAC2_INBAND_AN_ENABLE BIT(0) -@@ -203,13 +205,19 @@ - #define MVNETA_GMAC_TX_FLOW_CTRL_ENABLE BIT(5) - #define MVNETA_GMAC_RX_FLOW_CTRL_ACTIVE BIT(6) - #define MVNETA_GMAC_TX_FLOW_CTRL_ACTIVE BIT(7) -+#define MVNETA_GMAC_AN_COMPLETE BIT(11) -+#define MVNETA_GMAC_SYNC_OK BIT(14) - #define MVNETA_GMAC_AUTONEG_CONFIG 0x2c0c - #define MVNETA_GMAC_FORCE_LINK_DOWN BIT(0) - #define MVNETA_GMAC_FORCE_LINK_PASS BIT(1) - #define MVNETA_GMAC_INBAND_AN_ENABLE BIT(2) -+#define MVNETA_GMAC_AN_BYPASS_ENABLE BIT(3) -+#define MVNETA_GMAC_INBAND_RESTART_AN BIT(4) - #define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5) - #define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6) - #define MVNETA_GMAC_AN_SPEED_EN BIT(7) -+#define MVNETA_GMAC_CONFIG_FLOW_CTRL BIT(8) -+#define MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL BIT(9) - #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) -@@ -396,15 +404,9 @@ struct mvneta_port { - u16 tx_ring_size; - u16 rx_ring_size; - -- struct mii_bus *mii_bus; -- struct phy_device *phy_dev; -- phy_interface_t phy_interface; -- struct device_node *phy_node; -- unsigned int link; -- unsigned int duplex; -- unsigned int speed; -+ struct device_node *dn; - unsigned int tx_csum_limit; -- unsigned int use_inband_status:1; -+ struct phylink *phylink; - - struct mvneta_bm *bm_priv; - struct mvneta_bm_pool *pool_long; -@@ -1236,44 +1238,6 @@ static void mvneta_set_other_mcast_table - mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val); - } - --static void mvneta_set_autoneg(struct mvneta_port *pp, int enable) --{ -- u32 val; -- -- if (enable) { -- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -- val &= ~(MVNETA_GMAC_FORCE_LINK_PASS | -- MVNETA_GMAC_FORCE_LINK_DOWN | -- MVNETA_GMAC_AN_FLOW_CTRL_EN); -- val |= MVNETA_GMAC_INBAND_AN_ENABLE | -- MVNETA_GMAC_AN_SPEED_EN | -- MVNETA_GMAC_AN_DUPLEX_EN; -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -- val |= MVNETA_GMAC_1MS_CLOCK_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -- val |= MVNETA_GMAC2_INBAND_AN_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -- } else { -- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -- val &= ~(MVNETA_GMAC_INBAND_AN_ENABLE | -- MVNETA_GMAC_AN_SPEED_EN | -- MVNETA_GMAC_AN_DUPLEX_EN); -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -- val &= ~MVNETA_GMAC_1MS_CLOCK_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -- val &= ~MVNETA_GMAC2_INBAND_AN_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -- } --} -- - static void mvneta_percpu_unmask_interrupt(void *arg) - { - struct mvneta_port *pp = arg; -@@ -1421,7 +1385,6 @@ static void mvneta_defaults_set(struct m - val &= ~MVNETA_PHY_POLLING_ENABLE; - mvreg_write(pp, MVNETA_UNIT_CONTROL, val); - -- mvneta_set_autoneg(pp, pp->use_inband_status); - mvneta_set_ucast_table(pp, -1); - mvneta_set_special_mcast_table(pp, -1); - mvneta_set_other_mcast_table(pp, -1); -@@ -2614,26 +2577,11 @@ static irqreturn_t mvneta_isr(int irq, v - return IRQ_HANDLED; - } - --static int mvneta_fixed_link_update(struct mvneta_port *pp, -- struct phy_device *phy) -+static void mvneta_link_change(struct mvneta_port *pp) - { -- struct fixed_phy_status status; -- struct fixed_phy_status changed = {}; - u32 gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS); - -- status.link = !!(gmac_stat & MVNETA_GMAC_LINK_UP); -- if (gmac_stat & MVNETA_GMAC_SPEED_1000) -- status.speed = SPEED_1000; -- else if (gmac_stat & MVNETA_GMAC_SPEED_100) -- status.speed = SPEED_100; -- else -- status.speed = SPEED_10; -- status.duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX); -- changed.link = 1; -- changed.speed = 1; -- changed.duplex = 1; -- fixed_phy_update_state(phy, &status, &changed); -- return 0; -+ phylink_mac_change(pp->phylink, !!(gmac_stat & MVNETA_GMAC_LINK_UP)); - } - - /* NAPI handler -@@ -2662,12 +2610,11 @@ static int mvneta_poll(struct napi_struc - u32 cause_misc = mvreg_read(pp, MVNETA_INTR_MISC_CAUSE); - - mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0); -- if (pp->use_inband_status && (cause_misc & -- (MVNETA_CAUSE_PHY_STATUS_CHANGE | -- MVNETA_CAUSE_LINK_CHANGE | -- MVNETA_CAUSE_PSC_SYNC_CHANGE))) { -- mvneta_fixed_link_update(pp, pp->phy_dev); -- } -+ -+ if (cause_misc & (MVNETA_CAUSE_PHY_STATUS_CHANGE | -+ MVNETA_CAUSE_LINK_CHANGE | -+ MVNETA_CAUSE_PSC_SYNC_CHANGE)) -+ mvneta_link_change(pp); - } - - /* Release Tx descriptors */ -@@ -2983,7 +2930,7 @@ static void mvneta_start_dev(struct mvne - MVNETA_CAUSE_LINK_CHANGE | - MVNETA_CAUSE_PSC_SYNC_CHANGE); - -- phy_start(pp->phy_dev); -+ phylink_start(pp->phylink); - netif_tx_start_all_queues(pp->dev); - } - -@@ -2991,7 +2938,7 @@ static void mvneta_stop_dev(struct mvnet - { - unsigned int cpu; - -- phy_stop(pp->phy_dev); -+ phylink_stop(pp->phylink); - - for_each_online_cpu(cpu) { - struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu); -@@ -3161,99 +3108,219 @@ static int mvneta_set_mac_addr(struct ne - return 0; - } - --static void mvneta_adjust_link(struct net_device *ndev) -+static int mvneta_mac_support(struct net_device *ndev, unsigned int mode, -+ struct phylink_link_state *state) -+{ -+ switch (mode) { -+ case MLO_AN_8023Z: -+ state->supported = SUPPORTED_1000baseT_Full | -+ SUPPORTED_Autoneg | SUPPORTED_Pause; -+ state->advertising = ADVERTISED_1000baseT_Full | -+ ADVERTISED_Autoneg | ADVERTISED_Pause; -+ state->an_enabled = 1; -+ break; -+ -+ case MLO_AN_FIXED: -+ break; -+ -+ default: -+ state->supported = PHY_10BT_FEATURES | -+ PHY_100BT_FEATURES | -+ SUPPORTED_1000baseT_Full | -+ SUPPORTED_Autoneg; -+ state->advertising = ADVERTISED_10baseT_Half | -+ ADVERTISED_10baseT_Full | -+ ADVERTISED_100baseT_Half | -+ ADVERTISED_100baseT_Full | -+ ADVERTISED_1000baseT_Full | -+ ADVERTISED_Autoneg; -+ state->an_enabled = 1; -+ break; -+ } -+ return 0; -+} -+ -+static int mvneta_mac_link_state(struct net_device *ndev, -+ struct phylink_link_state *state) - { - struct mvneta_port *pp = netdev_priv(ndev); -- struct phy_device *phydev = pp->phy_dev; -- int status_change = 0; -+ u32 gmac_stat; - -- if (phydev->link) { -- if ((pp->speed != phydev->speed) || -- (pp->duplex != phydev->duplex)) { -- u32 val; -- -- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -- val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED | -- MVNETA_GMAC_CONFIG_GMII_SPEED | -- MVNETA_GMAC_CONFIG_FULL_DUPLEX); -- -- if (phydev->duplex) -- val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; -- -- if (phydev->speed == SPEED_1000) -- val |= MVNETA_GMAC_CONFIG_GMII_SPEED; -- else if (phydev->speed == SPEED_100) -- val |= MVNETA_GMAC_CONFIG_MII_SPEED; -+ gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS); - -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -+ if (gmac_stat & MVNETA_GMAC_SPEED_1000) -+ state->speed = SPEED_1000; -+ else if (gmac_stat & MVNETA_GMAC_SPEED_100) -+ state->speed = SPEED_100; -+ else -+ state->speed = SPEED_10; - -- pp->duplex = phydev->duplex; -- pp->speed = phydev->speed; -- } -+ state->an_complete = !!(gmac_stat & MVNETA_GMAC_AN_COMPLETE); -+ state->sync = !!(gmac_stat & MVNETA_GMAC_SYNC_OK); -+ state->link = !!(gmac_stat & MVNETA_GMAC_LINK_UP); -+ state->duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX); -+ -+ state->pause = 0; -+ if (gmac_stat & MVNETA_GMAC_RX_FLOW_CTRL_ENABLE) -+ state->pause |= MLO_PAUSE_RX; -+ if (gmac_stat & MVNETA_GMAC_TX_FLOW_CTRL_ENABLE) -+ state->pause |= MLO_PAUSE_TX; -+ -+ return 1; -+} -+ -+static void mvneta_mac_an_restart(struct net_device *ndev, unsigned int mode) -+{ -+ struct mvneta_port *pp = netdev_priv(ndev); -+ -+ if (mode == MLO_AN_8023Z) { -+ u32 gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -+ -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, -+ gmac_an | MVNETA_GMAC_INBAND_RESTART_AN); -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, -+ gmac_an & ~MVNETA_GMAC_INBAND_RESTART_AN); - } -+} - -- if (phydev->link != pp->link) { -- if (!phydev->link) { -- pp->duplex = -1; -- pp->speed = 0; -- } -+static void mvneta_mac_config(struct net_device *ndev, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+ 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_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; -+ new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE; -+ new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE | -+ MVNETA_GMAC_INBAND_RESTART_AN | -+ MVNETA_GMAC_CONFIG_MII_SPEED | -+ MVNETA_GMAC_CONFIG_GMII_SPEED | -+ MVNETA_GMAC_AN_SPEED_EN | -+ MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL | -+ MVNETA_GMAC_CONFIG_FLOW_CTRL | -+ MVNETA_GMAC_AN_FLOW_CTRL_EN | -+ MVNETA_GMAC_CONFIG_FULL_DUPLEX | -+ MVNETA_GMAC_AN_DUPLEX_EN); -+ -+ if (state->advertising & ADVERTISED_Pause) -+ new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL; -+ -+ switch (mode) { -+ case MLO_AN_SGMII: -+ /* SGMII mode receives the state from the PHY */ -+ new_ctrl2 |= MVNETA_GMAC2_INBAND_AN_ENABLE; -+ new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE; -+ new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN | -+ MVNETA_GMAC_FORCE_LINK_PASS)) | -+ MVNETA_GMAC_INBAND_AN_ENABLE | -+ MVNETA_GMAC_AN_SPEED_EN | -+ MVNETA_GMAC_AN_DUPLEX_EN; -+ break; -+ -+ case MLO_AN_8023Z: -+ /* 802.3z negotiation - only 1000base-X */ -+ new_ctrl0 |= MVNETA_GMAC0_PORT_1000BASE_X; -+ new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE; -+ new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN | -+ MVNETA_GMAC_FORCE_LINK_PASS)) | -+ MVNETA_GMAC_INBAND_AN_ENABLE | -+ MVNETA_GMAC_CONFIG_GMII_SPEED | -+ /* The MAC only supports FD mode */ -+ MVNETA_GMAC_CONFIG_FULL_DUPLEX; -+ -+ if (state->an_enabled) -+ new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN; -+ break; - -- pp->link = phydev->link; -- status_change = 1; -+ default: -+ /* Phy or fixed speed */ -+ if (state->duplex) -+ new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; -+ -+ if (state->speed == SPEED_1000) -+ new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED; -+ else if (state->speed == SPEED_100) -+ new_an |= MVNETA_GMAC_CONFIG_MII_SPEED; -+ break; - } - -- if (status_change) { -- if (phydev->link) { -- if (!pp->use_inband_status) { -- u32 val = mvreg_read(pp, -- MVNETA_GMAC_AUTONEG_CONFIG); -- val &= ~MVNETA_GMAC_FORCE_LINK_DOWN; -- val |= MVNETA_GMAC_FORCE_LINK_PASS; -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, -- val); -- } -- mvneta_port_up(pp); -- } else { -- if (!pp->use_inband_status) { -- u32 val = mvreg_read(pp, -- MVNETA_GMAC_AUTONEG_CONFIG); -- val &= ~MVNETA_GMAC_FORCE_LINK_PASS; -- val |= MVNETA_GMAC_FORCE_LINK_DOWN; -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, -- val); -- } -- mvneta_port_down(pp); -- } -- phy_print_status(phydev); -+ /* Armada 370 documentation says we can only change the port mode -+ * and in-band enable when the link is down, so force it down -+ * while making these changes. We also do this for GMAC_CTRL2 */ -+ if ((new_ctrl0 ^ gmac_ctrl0) & MVNETA_GMAC0_PORT_1000BASE_X || -+ (new_ctrl2 ^ gmac_ctrl2) & MVNETA_GMAC2_INBAND_AN_ENABLE || -+ (new_an ^ gmac_an) & MVNETA_GMAC_INBAND_AN_ENABLE) { -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, -+ (gmac_an & ~MVNETA_GMAC_FORCE_LINK_PASS) | -+ MVNETA_GMAC_FORCE_LINK_DOWN); -+ } -+ -+ 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_clk != gmac_clk) -+ mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk); -+ if (new_an != gmac_an) -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, new_an); -+} -+ -+static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode) -+{ -+ struct mvneta_port *pp = netdev_priv(ndev); -+ u32 val; -+ -+ mvneta_port_down(pp); -+ -+ if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) { -+ val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -+ val &= ~MVNETA_GMAC_FORCE_LINK_PASS; -+ val |= MVNETA_GMAC_FORCE_LINK_DOWN; -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); - } - } - --static int mvneta_mdio_probe(struct mvneta_port *pp) -+static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode, -+ struct phy_device *phy) - { -- struct phy_device *phy_dev; -+ struct mvneta_port *pp = netdev_priv(ndev); -+ u32 val; -+ -+ if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) { -+ val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -+ val &= ~MVNETA_GMAC_FORCE_LINK_DOWN; -+ val |= MVNETA_GMAC_FORCE_LINK_PASS; -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -+ } - -- phy_dev = of_phy_connect(pp->dev, pp->phy_node, mvneta_adjust_link, 0, -- pp->phy_interface); -- if (!phy_dev) { -- netdev_err(pp->dev, "could not find the PHY\n"); -- return -ENODEV; -- } -- -- phy_dev->supported &= PHY_GBIT_FEATURES; -- phy_dev->advertising = phy_dev->supported; -- -- pp->phy_dev = phy_dev; -- pp->link = 0; -- pp->duplex = 0; -- pp->speed = 0; -+ mvneta_port_up(pp); -+} - -- return 0; -+static const struct phylink_mac_ops mvneta_phylink_ops = { -+ .mac_get_support = mvneta_mac_support, -+ .mac_link_state = mvneta_mac_link_state, -+ .mac_an_restart = mvneta_mac_an_restart, -+ .mac_config = mvneta_mac_config, -+ .mac_link_down = mvneta_mac_link_down, -+ .mac_link_up = mvneta_mac_link_up, -+}; -+ -+static int mvneta_mdio_probe(struct mvneta_port *pp) -+{ -+ int err = phylink_of_phy_connect(pp->phylink, pp->dn); -+ if (err) -+ netdev_err(pp->dev, "could not attach PHY\n"); -+ -+ return err; - } - - static void mvneta_mdio_remove(struct mvneta_port *pp) - { -- phy_disconnect(pp->phy_dev); -- pp->phy_dev = NULL; -+ phylink_disconnect_phy(pp->phylink); - } - - /* Electing a CPU must be done in an atomic way: it should be done -@@ -3501,10 +3568,7 @@ static int mvneta_ioctl(struct net_devic - { - struct mvneta_port *pp = netdev_priv(dev); - -- if (!pp->phy_dev) -- return -ENOTSUPP; -- -- return phy_mii_ioctl(pp->phy_dev, ifr, cmd); -+ return phylink_mii_ioctl(pp->phylink, ifr, cmd); - } - - /* Ethtool methods */ -@@ -3514,54 +3578,15 @@ int mvneta_ethtool_get_settings(struct n - { - struct mvneta_port *pp = netdev_priv(dev); - -- if (!pp->phy_dev) -- return -ENODEV; -- -- return phy_ethtool_gset(pp->phy_dev, cmd); -+ return phylink_ethtool_get_settings(pp->phylink, cmd); - } - - /* Set settings (phy address, speed) for ethtools */ - int mvneta_ethtool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - struct mvneta_port *pp = netdev_priv(dev); -- struct phy_device *phydev = pp->phy_dev; -- -- if (!phydev) -- return -ENODEV; - -- if ((cmd->autoneg == AUTONEG_ENABLE) != pp->use_inband_status) { -- u32 val; -- -- mvneta_set_autoneg(pp, cmd->autoneg == AUTONEG_ENABLE); -- -- if (cmd->autoneg == AUTONEG_DISABLE) { -- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); -- val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED | -- MVNETA_GMAC_CONFIG_GMII_SPEED | -- MVNETA_GMAC_CONFIG_FULL_DUPLEX); -- -- if (phydev->duplex) -- val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; -- -- if (phydev->speed == SPEED_1000) -- val |= MVNETA_GMAC_CONFIG_GMII_SPEED; -- else if (phydev->speed == SPEED_100) -- val |= MVNETA_GMAC_CONFIG_MII_SPEED; -- -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -- } -- -- pp->use_inband_status = (cmd->autoneg == AUTONEG_ENABLE); -- netdev_info(pp->dev, "autoneg status set to %i\n", -- pp->use_inband_status); -- -- if (netif_running(dev)) { -- mvneta_port_down(pp); -- mvneta_port_up(pp); -- } -- } -- -- return phy_ethtool_sset(pp->phy_dev, cmd); -+ return phylink_ethtool_set_settings(pp->phylink, cmd); - } - - /* Set interrupt coalescing for ethtools */ -@@ -3669,7 +3694,8 @@ static void mvneta_ethtool_update_stats( - { - const struct mvneta_statistic *s; - void __iomem *base = pp->base; -- u32 high, low, val; -+ u32 high, low; -+ u64 val; - u64 val64; - int i; - -@@ -3964,14 +3990,13 @@ static int mvneta_probe(struct platform_ - const struct mbus_dram_target_info *dram_target_info; - struct resource *res; - struct device_node *dn = pdev->dev.of_node; -- struct device_node *phy_node; - struct device_node *bm_node; - struct mvneta_port *pp; - struct net_device *dev; -+ struct phylink *phylink; - const char *dt_mac_addr; - char hw_mac_addr[ETH_ALEN]; - const char *mac_from; -- const char *managed; - int tx_csum_limit; - int phy_mode; - int err; -@@ -3987,31 +4012,11 @@ static int mvneta_probe(struct platform_ - goto err_free_netdev; - } - -- phy_node = of_parse_phandle(dn, "phy", 0); -- if (!phy_node) { -- if (!of_phy_is_fixed_link(dn)) { -- dev_err(&pdev->dev, "no PHY specified\n"); -- err = -ENODEV; -- goto err_free_irq; -- } -- -- err = of_phy_register_fixed_link(dn); -- if (err < 0) { -- dev_err(&pdev->dev, "cannot register fixed PHY\n"); -- goto err_free_irq; -- } -- -- /* In the case of a fixed PHY, the DT node associated -- * to the PHY is the Ethernet MAC DT node. -- */ -- phy_node = of_node_get(dn); -- } -- - phy_mode = of_get_phy_mode(dn); - if (phy_mode < 0) { - dev_err(&pdev->dev, "incorrect phy-mode\n"); - err = -EINVAL; -- goto err_put_phy_node; -+ goto err_free_irq; - } - - dev->tx_queue_len = MVNETA_MAX_TXD; -@@ -4022,12 +4027,7 @@ static int mvneta_probe(struct platform_ - - pp = netdev_priv(dev); - spin_lock_init(&pp->lock); -- pp->phy_node = phy_node; -- pp->phy_interface = phy_mode; -- -- err = of_property_read_string(dn, "managed", &managed); -- pp->use_inband_status = (err == 0 && -- strcmp(managed, "in-band-status") == 0); -+ pp->dn = dn; - pp->cpu_notifier.notifier_call = mvneta_percpu_notifier; - - pp->rxq_def = rxq_def; -@@ -4037,7 +4037,7 @@ static int mvneta_probe(struct platform_ - pp->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(pp->clk)) { - err = PTR_ERR(pp->clk); -- goto err_put_phy_node; -+ goto err_free_irq; - } - - clk_prepare_enable(pp->clk); -@@ -4140,6 +4140,14 @@ static int mvneta_probe(struct platform_ - dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE; - dev->gso_max_segs = MVNETA_MAX_TSO_SEGS; - -+ phylink = phylink_create(dev, dn, phy_mode, &mvneta_phylink_ops); -+ if (IS_ERR(phylink)) { -+ err = PTR_ERR(phylink); -+ goto err_free_stats; -+ } -+ -+ pp->phylink = phylink; -+ - err = register_netdev(dev); - if (err < 0) { - dev_err(&pdev->dev, "failed to register\n"); -@@ -4151,13 +4159,6 @@ static int mvneta_probe(struct platform_ - - platform_set_drvdata(pdev, pp->dev); - -- if (pp->use_inband_status) { -- struct phy_device *phy = of_phy_find_device(dn); -- -- mvneta_fixed_link_update(pp, phy); -- -- put_device(&phy->dev); -- } - - return 0; - -@@ -4169,13 +4170,13 @@ err_netdev: - 1 << pp->id); - } - err_free_stats: -+ if (pp->phylink) -+ phylink_destroy(pp->phylink); - free_percpu(pp->stats); - err_free_ports: - free_percpu(pp->ports); - err_clk: - clk_disable_unprepare(pp->clk); --err_put_phy_node: -- of_node_put(phy_node); - err_free_irq: - irq_dispose_mapping(dev->irq); - err_free_netdev: -@@ -4194,7 +4195,7 @@ static int mvneta_remove(struct platform - free_percpu(pp->ports); - free_percpu(pp->stats); - irq_dispose_mapping(dev->irq); -- of_node_put(pp->phy_node); -+ phylink_destroy(pp->phylink); - free_netdev(dev); - - if (pp->bm_priv) { diff --git a/target/linux/mvebu/patches-4.4/135-phy-fixed-phy-remove-fixed_phy_update_state.patch b/target/linux/mvebu/patches-4.4/135-phy-fixed-phy-remove-fixed_phy_update_state.patch deleted file mode 100644 index 58c9aab4ac..0000000000 --- a/target/linux/mvebu/patches-4.4/135-phy-fixed-phy-remove-fixed_phy_update_state.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 9be436bdb67c1f4aa9f33f2477f94e1f58a0ff02 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Fri, 2 Oct 2015 22:46:54 +0100 -Subject: [PATCH 723/744] phy: fixed-phy: remove fixed_phy_update_state() - -mvneta is the only user of fixed_phy_update_state(), which has been -converted to use phylink instead. Remove fixed_phy_update_state(). - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/fixed_phy.c | 31 ------------------------------- - include/linux/phy_fixed.h | 9 --------- - 2 files changed, 40 deletions(-) - ---- a/drivers/net/phy/fixed_phy.c -+++ b/drivers/net/phy/fixed_phy.c -@@ -115,37 +115,6 @@ int fixed_phy_set_link_update(struct phy - } - EXPORT_SYMBOL_GPL(fixed_phy_set_link_update); - --int fixed_phy_update_state(struct phy_device *phydev, -- const struct fixed_phy_status *status, -- const struct fixed_phy_status *changed) --{ -- struct fixed_mdio_bus *fmb = &platform_fmb; -- struct fixed_phy *fp; -- -- if (!phydev || phydev->bus != fmb->mii_bus) -- return -EINVAL; -- -- list_for_each_entry(fp, &fmb->phys, node) { -- if (fp->addr == phydev->addr) { -- write_seqcount_begin(&fp->seqcount); --#define _UPD(x) if (changed->x) \ -- fp->status.x = status->x -- _UPD(link); -- _UPD(speed); -- _UPD(duplex); -- _UPD(pause); -- _UPD(asym_pause); --#undef _UPD -- fixed_phy_update(fp); -- write_seqcount_end(&fp->seqcount); -- return 0; -- } -- } -- -- return -ENOENT; --} --EXPORT_SYMBOL(fixed_phy_update_state); -- - int fixed_phy_add(unsigned int irq, int phy_addr, - struct fixed_phy_status *status, - int link_gpio) ---- a/include/linux/phy_fixed.h -+++ b/include/linux/phy_fixed.h -@@ -23,9 +23,6 @@ extern void fixed_phy_del(int phy_addr); - extern int fixed_phy_set_link_update(struct phy_device *phydev, - int (*link_update)(struct net_device *, - struct fixed_phy_status *)); --extern int fixed_phy_update_state(struct phy_device *phydev, -- const struct fixed_phy_status *status, -- const struct fixed_phy_status *changed); - #else - static inline int fixed_phy_add(unsigned int irq, int phy_id, - struct fixed_phy_status *status, -@@ -50,12 +47,6 @@ static inline int fixed_phy_set_link_upd - { - return -ENODEV; - } --static inline int fixed_phy_update_state(struct phy_device *phydev, -- const struct fixed_phy_status *status, -- const struct fixed_phy_status *changed) --{ -- return -ENODEV; --} - #endif /* CONFIG_FIXED_PHY */ - - #endif /* __PHY_FIXED_H */ diff --git a/target/linux/mvebu/patches-4.4/136-phylink-add-ethtool-nway_reset-support.patch b/target/linux/mvebu/patches-4.4/136-phylink-add-ethtool-nway_reset-support.patch deleted file mode 100644 index ade904eebd..0000000000 --- a/target/linux/mvebu/patches-4.4/136-phylink-add-ethtool-nway_reset-support.patch +++ /dev/null @@ -1,48 +0,0 @@ -From d6bd25b692378ec17bdb1023d398c03c45829947 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 20:27:19 +0100 -Subject: [PATCH 724/744] phylink: add ethtool nway_reset support - -Add ethtool nway_reset support to phylink, to allow userspace to -request a re-negotiation of the link. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/phylink.c | 14 ++++++++++++++ - include/linux/phylink.h | 1 + - 2 files changed, 15 insertions(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -687,6 +687,20 @@ int phylink_ethtool_set_settings(struct - } - EXPORT_SYMBOL_GPL(phylink_ethtool_set_settings); - -+int phylink_ethtool_nway_reset(struct phylink *pl) -+{ -+ int ret = 0; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->phydev) -+ ret = genphy_restart_aneg(pl->phydev); -+ phylink_mac_an_restart(pl); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_nway_reset); -+ - /* This emulates MII registers for a fixed-mode phy operating as per the - * passed in state. "aneg" defines if we report negotiation is possible. - * ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -65,6 +65,7 @@ void phylink_stop(struct phylink *); - - int phylink_ethtool_get_settings(struct phylink *, struct ethtool_cmd *); - int phylink_ethtool_set_settings(struct phylink *, struct ethtool_cmd *); -+int phylink_ethtool_nway_reset(struct phylink *); - int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); - - void phylink_set_link_port(struct phylink *pl, u32 support, u8 port); diff --git a/target/linux/mvebu/patches-4.4/137-net-mvneta-add-nway_reset-support.patch b/target/linux/mvebu/patches-4.4/137-net-mvneta-add-nway_reset-support.patch deleted file mode 100644 index 034b596436..0000000000 --- a/target/linux/mvebu/patches-4.4/137-net-mvneta-add-nway_reset-support.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 244bee2889d08f876c64c335765a8ea6de0f5381 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 19:40:31 +0100 -Subject: [PATCH 725/744] net: mvneta: add nway_reset support - -Add ethtool nway_reset support to mvneta via phylink, so that userspace -can request the link in whatever mode to be renegotiated via -ethtool -r ethX. - -Signed-off-by: Russell King ---- - drivers/net/ethernet/marvell/mvneta.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3589,6 +3589,13 @@ int mvneta_ethtool_set_settings(struct n - return phylink_ethtool_set_settings(pp->phylink, cmd); - } - -+static int mvneta_ethtool_nway_reset(struct net_device *dev) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ -+ return phylink_ethtool_nway_reset(pp->phylink); -+} -+ - /* Set interrupt coalescing for ethtools */ - static int mvneta_ethtool_set_coalesce(struct net_device *dev, - struct ethtool_coalesce *c) -@@ -3853,6 +3860,7 @@ const struct ethtool_ops mvneta_eth_tool - .get_link = ethtool_op_get_link, - .get_settings = mvneta_ethtool_get_settings, - .set_settings = mvneta_ethtool_set_settings, -+ .nway_reset = mvneta_ethtool_nway_reset, - .set_coalesce = mvneta_ethtool_set_coalesce, - .get_coalesce = mvneta_ethtool_get_coalesce, - .get_drvinfo = mvneta_ethtool_get_drvinfo, diff --git a/target/linux/mvebu/patches-4.4/138-phylink-add-flow-control-support.patch b/target/linux/mvebu/patches-4.4/138-phylink-add-flow-control-support.patch deleted file mode 100644 index 95b8a81943..0000000000 --- a/target/linux/mvebu/patches-4.4/138-phylink-add-flow-control-support.patch +++ /dev/null @@ -1,262 +0,0 @@ -From f566177aa6661e646b83526f24391a568ffd1a75 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 20:32:07 +0100 -Subject: [PATCH 726/744] phylink: add flow control support - -Add flow control support, including ethtool support, to phylink. We -add support to allow ethtool to get and set the current flow control -settings, and the 802.3 specified resolution for the local and remote -link partner abilities. - -Signed-off-by: Russell King ---- - drivers/net/phy/phylink.c | 145 +++++++++++++++++++++++++++++++++++++++++----- - include/linux/phylink.h | 8 +++ - 2 files changed, 139 insertions(+), 14 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -91,10 +91,12 @@ static int phylink_parse_fixedlink(struc - pl->link_config.an_complete = 1; - pl->link_config.speed = speed; - pl->link_config.duplex = DUPLEX_HALF; -- pl->link_config.pause = MLO_PAUSE_NONE; - - if (of_property_read_bool(fixed_node, "full-duplex")) - pl->link_config.duplex = DUPLEX_FULL; -+ -+ /* We treat the "pause" and "asym-pause" terminology as -+ * defining the link partner's ability. */ - if (of_property_read_bool(fixed_node, "pause")) - pl->link_config.pause |= MLO_PAUSE_SYM; - if (of_property_read_bool(fixed_node, "asym-pause")) -@@ -118,7 +120,6 @@ static int phylink_parse_fixedlink(struc - pl->link_config.duplex = be32_to_cpu(fixed_prop[1]) ? - DUPLEX_FULL : DUPLEX_HALF; - pl->link_config.speed = be32_to_cpu(fixed_prop[2]); -- pl->link_config.pause = MLO_PAUSE_NONE; - if (be32_to_cpu(fixed_prop[3])) - pl->link_config.pause |= MLO_PAUSE_SYM; - if (be32_to_cpu(fixed_prop[4])) -@@ -130,16 +131,6 @@ static int phylink_parse_fixedlink(struc - } - - if (pl->link_an_mode == MLO_AN_FIXED) { -- /* Generate the supported/advertising masks */ -- if (pl->link_config.pause & MLO_PAUSE_SYM) { -- pl->link_config.supported |= SUPPORTED_Pause; -- pl->link_config.advertising |= ADVERTISED_Pause; -- } -- if (pl->link_config.pause & MLO_PAUSE_ASYM) { -- pl->link_config.supported |= SUPPORTED_Asym_Pause; -- pl->link_config.advertising |= ADVERTISED_Asym_Pause; -- } -- - if (pl->link_config.speed > SPEED_1000 && - pl->link_config.duplex != DUPLEX_FULL) - netdev_warn(pl->netdev, "fixed link specifies half duplex for %dMbps link?\n", -@@ -242,6 +233,56 @@ static void phylink_get_fixed_state(stru - state->link = !!gpiod_get_value(pl->link_gpio); - } - -+/* Flow control is resolved according to our and the link partners -+ * advertisments using the following drawn from the 802.3 specs: -+ * Local device Link partner -+ * Pause AsymDir Pause AsymDir Result -+ * 1 X 1 X TX+RX -+ * 0 1 1 1 RX -+ * 1 1 0 1 TX -+ */ -+static void phylink_resolve_flow(struct phylink *pl, -+ struct phylink_link_state *state) -+{ -+ int new_pause = 0; -+ -+ if (pl->link_config.pause & MLO_PAUSE_AN) { -+ int pause = 0; -+ -+ if (pl->link_config.advertising & ADVERTISED_Pause) -+ pause |= MLO_PAUSE_SYM; -+ if (pl->link_config.advertising & ADVERTISED_Asym_Pause) -+ pause |= MLO_PAUSE_ASYM; -+ -+ pause &= state->pause; -+ -+ if (pause & MLO_PAUSE_SYM) -+ new_pause = MLO_PAUSE_TX | MLO_PAUSE_RX; -+ else if (pause & MLO_PAUSE_ASYM) -+ new_pause = state->pause & MLO_PAUSE_SYM ? -+ MLO_PAUSE_RX : MLO_PAUSE_TX; -+ } else { -+ new_pause = pl->link_config.pause & MLO_PAUSE_TXRX_MASK; -+ } -+ -+ state->pause &= ~MLO_PAUSE_TXRX_MASK; -+ state->pause |= new_pause; -+} -+ -+static const char *phylink_pause_to_str(int pause) -+{ -+ switch (pause & MLO_PAUSE_TXRX_MASK) { -+ case MLO_PAUSE_TX | MLO_PAUSE_RX: -+ return "rx/tx"; -+ case MLO_PAUSE_TX: -+ return "tx"; -+ case MLO_PAUSE_RX: -+ return "rx"; -+ default: -+ return "off"; -+ } -+} -+ - extern const char *phy_speed_to_str(int speed); - - static void phylink_resolve(struct work_struct *w) -@@ -257,6 +298,7 @@ static void phylink_resolve(struct work_ - switch (pl->link_an_mode) { - case MLO_AN_PHY: - link_state = pl->phy_state; -+ phylink_resolve_flow(pl, &link_state); - break; - - case MLO_AN_FIXED: -@@ -265,9 +307,12 @@ static void phylink_resolve(struct work_ - - case MLO_AN_SGMII: - phylink_get_mac_state(pl, &link_state); -- if (pl->phydev) -+ if (pl->phydev) { - link_state.link = link_state.link && - pl->phy_state.link; -+ link_state.pause |= pl->phy_state.pause; -+ phylink_resolve_flow(pl, &link_state); -+ } - break; - - case MLO_AN_8023Z: -@@ -297,7 +342,7 @@ static void phylink_resolve(struct work_ - "Link is Up - %s/%s - flow control %s\n", - phy_speed_to_str(link_state.speed), - link_state.duplex ? "Full" : "Half", -- link_state.pause ? "rx/tx" : "off"); -+ phylink_pause_to_str(link_state.pause)); - } - } - mutex_unlock(&pl->state_mutex); -@@ -326,6 +371,7 @@ struct phylink *phylink_create(struct ne - pl->link_interface = iface; - pl->link_port_support = SUPPORTED_MII; - pl->link_port = PORT_MII; -+ pl->link_config.pause = MLO_PAUSE_AN; - pl->ops = ops; - __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); - -@@ -507,6 +553,7 @@ void phylink_start(struct phylink *pl) - * a fixed-link to start with the correct parameters, and also - * ensures that we set the appropriate advertisment for Serdes links. - */ -+ phylink_resolve_flow(pl, &pl->link_config); - phylink_mac_config(pl, &pl->link_config); - - clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); -@@ -701,6 +748,76 @@ int phylink_ethtool_nway_reset(struct ph - } - EXPORT_SYMBOL_GPL(phylink_ethtool_nway_reset); - -+void phylink_ethtool_get_pauseparam(struct phylink *pl, -+ struct ethtool_pauseparam *pause) -+{ -+ mutex_lock(&pl->config_mutex); -+ -+ pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); -+ pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); -+ pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); -+ -+ mutex_unlock(&pl->config_mutex); -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_get_pauseparam); -+ -+static int __phylink_ethtool_set_pauseparam(struct phylink *pl, -+ struct ethtool_pauseparam *pause) -+{ -+ struct phylink_link_state *config = &pl->link_config; -+ -+ if (!(config->supported & (SUPPORTED_Pause | SUPPORTED_Asym_Pause))) -+ return -EOPNOTSUPP; -+ -+ if (!(config->supported & SUPPORTED_Asym_Pause) && -+ !pause->autoneg && pause->rx_pause != pause->tx_pause) -+ return -EINVAL; -+ -+ config->pause &= ~(MLO_PAUSE_AN | MLO_PAUSE_TXRX_MASK); -+ -+ if (pause->autoneg) -+ config->pause |= MLO_PAUSE_AN; -+ if (pause->rx_pause) -+ config->pause |= MLO_PAUSE_RX; -+ if (pause->tx_pause) -+ config->pause |= MLO_PAUSE_TX; -+ -+ switch (pl->link_an_mode) { -+ case MLO_AN_PHY: -+ /* Silently mark the carrier down, and then trigger a resolve */ -+ netif_carrier_off(pl->netdev); -+ phylink_run_resolve(pl); -+ break; -+ -+ case MLO_AN_FIXED: -+ /* Should we allow fixed links to change against the config? */ -+ phylink_resolve_flow(pl, config); -+ phylink_mac_config(pl, config); -+ break; -+ -+ case MLO_AN_SGMII: -+ case MLO_AN_8023Z: -+ phylink_mac_config(pl, config); -+ phylink_mac_an_restart(pl); -+ break; -+ } -+ -+ return 0; -+} -+ -+int phylink_ethtool_set_pauseparam(struct phylink *pl, -+ struct ethtool_pauseparam *pause) -+{ -+ int ret; -+ -+ mutex_lock(&pl->config_mutex); -+ ret = __phylink_ethtool_set_pauseparam(pl, pause); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam); -+ - /* This emulates MII registers for a fixed-mode phy operating as per the - * passed in state. "aneg" defines if we report negotiation is possible. - * ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -13,6 +13,10 @@ enum { - MLO_PAUSE_NONE, - MLO_PAUSE_ASYM = BIT(0), - MLO_PAUSE_SYM = BIT(1), -+ MLO_PAUSE_RX = BIT(2), -+ MLO_PAUSE_TX = BIT(3), -+ MLO_PAUSE_TXRX_MASK = MLO_PAUSE_TX | MLO_PAUSE_RX, -+ MLO_PAUSE_AN = BIT(4), - - MLO_AN_PHY = 0, - MLO_AN_FIXED, -@@ -66,6 +70,10 @@ void phylink_stop(struct phylink *); - int phylink_ethtool_get_settings(struct phylink *, struct ethtool_cmd *); - int phylink_ethtool_set_settings(struct phylink *, struct ethtool_cmd *); - int phylink_ethtool_nway_reset(struct phylink *); -+void phylink_ethtool_get_pauseparam(struct phylink *, -+ struct ethtool_pauseparam *); -+int phylink_ethtool_set_pauseparam(struct phylink *, -+ struct ethtool_pauseparam *); - int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); - - void phylink_set_link_port(struct phylink *pl, u32 support, u8 port); diff --git a/target/linux/mvebu/patches-4.4/139-net-mvneta-add-flow-control-support-via-phylink.patch b/target/linux/mvebu/patches-4.4/139-net-mvneta-add-flow-control-support-via-phylink.patch deleted file mode 100644 index 75cd46e3da..0000000000 --- a/target/linux/mvebu/patches-4.4/139-net-mvneta-add-flow-control-support-via-phylink.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 7bd34822b9922beb22a6384d9190646105d259d8 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 17:41:44 +0100 -Subject: [PATCH 727/744] net: mvneta: add flow control support via phylink - -Add flow control support to mvneta, including the ethtool hooks. This -uses the phylink code to calculate the result of autonegotiation where -a phy is attached, and to handle the ethtool settings. - -Signed-off-by: Russell King ---- - drivers/net/ethernet/marvell/mvneta.c | 22 +++++++++++++++++++++- - 1 file changed, 21 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3208,6 +3208,8 @@ static void mvneta_mac_config(struct net - - if (state->advertising & ADVERTISED_Pause) - new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL; -+ if (state->pause & MLO_PAUSE_TXRX_MASK) -+ new_an |= MVNETA_GMAC_CONFIG_FLOW_CTRL; - - switch (mode) { - case MLO_AN_SGMII: -@@ -3232,7 +3234,7 @@ static void mvneta_mac_config(struct net - /* The MAC only supports FD mode */ - MVNETA_GMAC_CONFIG_FULL_DUPLEX; - -- if (state->an_enabled) -+ if (state->pause & MLO_PAUSE_AN && state->an_enabled) - new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN; - break; - -@@ -3685,6 +3687,22 @@ static int mvneta_ethtool_set_ringparam( - return 0; - } - -+static void mvneta_ethtool_get_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ -+ phylink_ethtool_get_pauseparam(pp->phylink, pause); -+} -+ -+static int mvneta_ethtool_set_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ -+ return phylink_ethtool_set_pauseparam(pp->phylink, pause); -+} -+ - static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset, - u8 *data) - { -@@ -3866,6 +3884,8 @@ const struct ethtool_ops mvneta_eth_tool - .get_drvinfo = mvneta_ethtool_get_drvinfo, - .get_ringparam = mvneta_ethtool_get_ringparam, - .set_ringparam = mvneta_ethtool_set_ringparam, -+ .get_pauseparam = mvneta_ethtool_get_pauseparam, -+ .set_pauseparam = mvneta_ethtool_set_pauseparam, - .get_strings = mvneta_ethtool_get_strings, - .get_ethtool_stats = mvneta_ethtool_get_stats, - .get_sset_count = mvneta_ethtool_get_sset_count, diff --git a/target/linux/mvebu/patches-4.4/140-net-mvneta-enable-flow-control-for-PHY-connections.patch b/target/linux/mvebu/patches-4.4/140-net-mvneta-enable-flow-control-for-PHY-connections.patch deleted file mode 100644 index e10574c753..0000000000 --- a/target/linux/mvebu/patches-4.4/140-net-mvneta-enable-flow-control-for-PHY-connections.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 62f8a12044265df11531750a240e516a5f1ff433 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 00:34:08 +0100 -Subject: [PATCH 728/744] net: mvneta: enable flow control for PHY connections - -Enable flow control support for PHY connections by indicating our -support via the ethtool capabilities. phylink takes care of the -appropriate handling. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/ethernet/marvell/mvneta.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3127,12 +3127,14 @@ static int mvneta_mac_support(struct net - state->supported = PHY_10BT_FEATURES | - PHY_100BT_FEATURES | - SUPPORTED_1000baseT_Full | -+ SUPPORTED_Pause | - SUPPORTED_Autoneg; - state->advertising = ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Full | -+ ADVERTISED_Pause | - ADVERTISED_Autoneg; - state->an_enabled = 1; - break; diff --git a/target/linux/mvebu/patches-4.4/141-net-mvneta-enable-flow-control-for-fixed-connections.patch b/target/linux/mvebu/patches-4.4/141-net-mvneta-enable-flow-control-for-fixed-connections.patch deleted file mode 100644 index 16ffab3d46..0000000000 --- a/target/linux/mvebu/patches-4.4/141-net-mvneta-enable-flow-control-for-fixed-connections.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 4c3e2dc08a11fb1273ca62467f1d06e59866bad3 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Tue, 12 Jul 2016 00:04:13 +0100 -Subject: [PATCH 729/744] net: mvneta: enable flow control for fixed - connections - -Allow symetric flow control to be enabled for fixed link connections as -well as other types of connections by setting the supported and -advertised capability bits. - -Signed-off-by: Russell King ---- - drivers/net/ethernet/marvell/mvneta.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3114,9 +3114,9 @@ static int mvneta_mac_support(struct net - switch (mode) { - case MLO_AN_8023Z: - state->supported = SUPPORTED_1000baseT_Full | -- SUPPORTED_Autoneg | SUPPORTED_Pause; -+ SUPPORTED_Autoneg; - state->advertising = ADVERTISED_1000baseT_Full | -- ADVERTISED_Autoneg | ADVERTISED_Pause; -+ ADVERTISED_Autoneg; - state->an_enabled = 1; - break; - -@@ -3127,18 +3127,21 @@ static int mvneta_mac_support(struct net - state->supported = PHY_10BT_FEATURES | - PHY_100BT_FEATURES | - SUPPORTED_1000baseT_Full | -- SUPPORTED_Pause | - SUPPORTED_Autoneg; - state->advertising = ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Full | -- ADVERTISED_Pause | - ADVERTISED_Autoneg; - state->an_enabled = 1; - break; - } -+ -+ /* All modes support flow control */ -+ state->supported |= SUPPORTED_Pause; -+ state->advertising |= ADVERTISED_Pause; -+ - return 0; - } - diff --git a/target/linux/mvebu/patches-4.4/142-phylink-add-EEE-support.patch b/target/linux/mvebu/patches-4.4/142-phylink-add-EEE-support.patch deleted file mode 100644 index b06ec76b98..0000000000 --- a/target/linux/mvebu/patches-4.4/142-phylink-add-EEE-support.patch +++ /dev/null @@ -1,111 +0,0 @@ -From ffba226d73a2be262fff12d30aecf76d107b2ace Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 21:19:53 +0100 -Subject: [PATCH 730/744] phylink: add EEE support - -Add EEE hooks to phylink to allow the phylib EEE functions for the -connected phy to be safely accessed. - -Signed-off-by: Russell King ---- - drivers/net/phy/phylink.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++- - include/linux/phylink.h | 7 +++++- - 2 files changed, 63 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -334,7 +334,8 @@ static void phylink_resolve(struct work_ - if (pl->phydev) - phylink_mac_config(pl, &link_state); - -- pl->ops->mac_link_up(ndev, pl->link_an_mode); -+ pl->ops->mac_link_up(ndev, pl->link_an_mode, -+ pl->phydev); - - netif_carrier_on(ndev); - -@@ -818,6 +819,61 @@ int phylink_ethtool_set_pauseparam(struc - } - EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam); - -+int phylink_init_eee(struct phylink *pl, bool clk_stop_enable) -+{ -+ int ret = -EPROTONOSUPPORT; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->phydev) -+ ret = phy_init_eee(pl->phydev, clk_stop_enable); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_init_eee); -+ -+int phylink_get_eee_err(struct phylink *pl) -+{ -+ int ret = 0; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->phydev) -+ ret = phy_get_eee_err(pl->phydev); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_get_eee_err); -+ -+int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_eee *eee) -+{ -+ int ret = -EOPNOTSUPP; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->phydev) -+ ret = phy_ethtool_get_eee(pl->phydev, eee); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_get_eee); -+ -+int phylink_ethtool_set_eee(struct phylink *pl, struct ethtool_eee *eee) -+{ -+ int ret = -EOPNOTSUPP; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->phydev) { -+ ret = phy_ethtool_set_eee(pl->phydev, eee); -+ if (ret == 0 && eee->eee_enabled) -+ phy_start_aneg(pl->phydev); -+ } -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_set_eee); -+ - /* This emulates MII registers for a fixed-mode phy operating as per the - * passed in state. "aneg" defines if we report negotiation is possible. - * ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -51,7 +51,8 @@ struct phylink_mac_ops { - void (*mac_an_restart)(struct net_device *, unsigned int mode); - - void (*mac_link_down)(struct net_device *, unsigned int mode); -- void (*mac_link_up)(struct net_device *, unsigned int mode); -+ void (*mac_link_up)(struct net_device *, unsigned int mode, -+ struct phy_device *); - }; - - struct phylink *phylink_create(struct net_device *, struct device_node *, -@@ -74,6 +75,10 @@ void phylink_ethtool_get_pauseparam(stru - struct ethtool_pauseparam *); - int phylink_ethtool_set_pauseparam(struct phylink *, - struct ethtool_pauseparam *); -+int phylink_init_eee(struct phylink *, bool); -+int phylink_get_eee_err(struct phylink *); -+int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *); -+int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *); - int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); - - void phylink_set_link_port(struct phylink *pl, u32 support, u8 port); diff --git a/target/linux/mvebu/patches-4.4/143-net-mvneta-add-EEE-support.patch b/target/linux/mvebu/patches-4.4/143-net-mvneta-add-EEE-support.patch deleted file mode 100644 index b9043561d0..0000000000 --- a/target/linux/mvebu/patches-4.4/143-net-mvneta-add-EEE-support.patch +++ /dev/null @@ -1,182 +0,0 @@ -From b7dacf514e41d6efff0ccc170f660cc6dc2aeae2 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Tue, 29 Sep 2015 15:17:39 +0100 -Subject: [PATCH 731/744] net: mvneta: add EEE support - -Add EEE support to mvneta. This allows us to enable the low power idle -support at MAC level if there is a PHY attached through phylink which -supports LPI. The appropriate ethtool support is provided to allow the -feature to be controlled, including ethtool statistics for EEE wakeup -errors. - -Signed-off-by: Russell King ---- - drivers/net/ethernet/marvell/mvneta.c | 87 +++++++++++++++++++++++++++++++++++ - 1 file changed, 87 insertions(+) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -243,6 +243,12 @@ - #define MVNETA_TXQ_TOKEN_SIZE_REG(q) (0x3e40 + ((q) << 2)) - #define MVNETA_TXQ_TOKEN_SIZE_MAX 0x7fffffff - -+#define MVNETA_LPI_CTRL_0 0x2cc0 -+#define MVNETA_LPI_CTRL_1 0x2cc4 -+#define MVNETA_LPI_REQUEST_ENABLE BIT(0) -+#define MVNETA_LPI_CTRL_2 0x2cc8 -+#define MVNETA_LPI_STATUS 0x2ccc -+ - #define MVNETA_CAUSE_TXQ_SENT_DESC_ALL_MASK 0xff - - /* Descriptor ring Macros */ -@@ -316,6 +322,11 @@ - #define MVNETA_RX_GET_BM_POOL_ID(rxd) \ - (((rxd)->status & MVNETA_RXD_BM_POOL_MASK) >> MVNETA_RXD_BM_POOL_SHIFT) - -+enum { -+ ETHTOOL_STAT_EEE_WAKEUP, -+ ETHTOOL_MAX_STATS, -+}; -+ - struct mvneta_statistic { - unsigned short offset; - unsigned short type; -@@ -324,6 +335,7 @@ struct mvneta_statistic { - - #define T_REG_32 32 - #define T_REG_64 64 -+#define T_SW 1 - - static const struct mvneta_statistic mvneta_statistics[] = { - { 0x3000, T_REG_64, "good_octets_received", }, -@@ -358,6 +370,7 @@ static const struct mvneta_statistic mvn - { 0x304c, T_REG_32, "broadcast_frames_sent", }, - { 0x3054, T_REG_32, "fc_sent", }, - { 0x300c, T_REG_32, "internal_mac_transmit_err", }, -+ { ETHTOOL_STAT_EEE_WAKEUP, T_SW, "eee_wakeup_errors", }, - }; - - struct mvneta_pcpu_stats { -@@ -413,6 +426,10 @@ struct mvneta_port { - struct mvneta_bm_pool *pool_short; - int bm_win_id; - -+ bool eee_enabled; -+ bool eee_active; -+ bool tx_lpi_enabled; -+ - u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)]; - - u32 indir[MVNETA_RSS_LU_TABLE_SIZE]; -@@ -3276,6 +3293,18 @@ static void mvneta_mac_config(struct net - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, new_an); - } - -+static void mvneta_set_eee(struct mvneta_port *pp, bool enable) -+{ -+ u32 lpi_ctl1; -+ -+ lpi_ctl1 = mvreg_read(pp, MVNETA_LPI_CTRL_1); -+ if (enable) -+ lpi_ctl1 |= MVNETA_LPI_REQUEST_ENABLE; -+ else -+ lpi_ctl1 &= ~MVNETA_LPI_REQUEST_ENABLE; -+ mvreg_write(pp, MVNETA_LPI_CTRL_1, lpi_ctl1); -+} -+ - static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode) - { - struct mvneta_port *pp = netdev_priv(ndev); -@@ -3289,6 +3318,9 @@ static void mvneta_mac_link_down(struct - val |= MVNETA_GMAC_FORCE_LINK_DOWN; - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); - } -+ -+ pp->eee_active = false; -+ mvneta_set_eee(pp, false); - } - - static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode, -@@ -3305,6 +3337,11 @@ static void mvneta_mac_link_up(struct ne - } - - mvneta_port_up(pp); -+ -+ if (phy && pp->eee_enabled) { -+ pp->eee_active = phy_init_eee(phy, 0) >= 0; -+ mvneta_set_eee(pp, pp->eee_active && pp->tx_lpi_enabled); -+ } - } - - static const struct phylink_mac_ops mvneta_phylink_ops = { -@@ -3744,6 +3781,13 @@ static void mvneta_ethtool_update_stats( - val64 = (u64)high << 32 | low; - pp->ethtool_stats[i] += val64; - break; -+ case T_SW: -+ switch (s->offset) { -+ case ETHTOOL_STAT_EEE_WAKEUP: -+ val = phylink_get_eee_err(pp->phylink); -+ break; -+ } -+ break; - } - } - } -@@ -3867,6 +3911,47 @@ static int mvneta_ethtool_get_rxfh(struc - return 0; - } - -+static int mvneta_ethtool_get_eee(struct net_device *dev, -+ struct ethtool_eee *eee) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ u32 lpi_ctl0; -+ -+ lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0); -+ -+ eee->eee_enabled = pp->eee_enabled; -+ eee->eee_active = pp->eee_active; -+ eee->tx_lpi_enabled = pp->tx_lpi_enabled; -+ eee->tx_lpi_timer = (lpi_ctl0) >> 8; // * scale; -+ -+ return phylink_ethtool_get_eee(pp->phylink, eee); -+} -+ -+static int mvneta_ethtool_set_eee(struct net_device *dev, -+ struct ethtool_eee *eee) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ u32 lpi_ctl0; -+ -+ /* 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)) -+ return -EINVAL; -+ -+ lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0); -+ lpi_ctl0 &= ~(0xff << 8); -+ lpi_ctl0 |= eee->tx_lpi_timer << 8; -+ mvreg_write(pp, MVNETA_LPI_CTRL_0, lpi_ctl0); -+ -+ pp->eee_enabled = eee->eee_enabled; -+ pp->tx_lpi_enabled = eee->tx_lpi_enabled; -+ -+ mvneta_set_eee(pp, eee->tx_lpi_enabled && eee->eee_enabled); -+ -+ return phylink_ethtool_set_eee(pp->phylink, eee); -+} -+ - static const struct net_device_ops mvneta_netdev_ops = { - .ndo_open = mvneta_open, - .ndo_stop = mvneta_stop, -@@ -3898,6 +3983,8 @@ const struct ethtool_ops mvneta_eth_tool - .get_rxnfc = mvneta_ethtool_get_rxnfc, - .get_rxfh = mvneta_ethtool_get_rxfh, - .set_rxfh = mvneta_ethtool_set_rxfh, -+ .get_eee = mvneta_ethtool_get_eee, -+ .set_eee = mvneta_ethtool_set_eee, - }; - - /* Initialize hw */ diff --git a/target/linux/mvebu/patches-4.4/144-phylink-add-module-EEPROM-support.patch b/target/linux/mvebu/patches-4.4/144-phylink-add-module-EEPROM-support.patch deleted file mode 100644 index f57f70dd9e..0000000000 --- a/target/linux/mvebu/patches-4.4/144-phylink-add-module-EEPROM-support.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 5419ccb638aa5c353ea88815e98953d9fc02e6ca Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 23:10:05 +0100 -Subject: [PATCH 732/744] phylink: add module EEPROM support - -Add support for reading module EEPROMs through phylink. - -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King ---- - drivers/net/phy/phylink.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/phylink.h | 12 +++++++++ - 2 files changed, 78 insertions(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -60,6 +60,9 @@ struct phylink { - struct work_struct resolve; - - bool mac_link_up; -+ -+ const struct phylink_module_ops *module_ops; -+ void *module_data; - }; - - static const char *phylink_an_mode_str(unsigned int mode) -@@ -819,6 +822,36 @@ int phylink_ethtool_set_pauseparam(struc - } - EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam); - -+int phylink_ethtool_get_module_info(struct phylink *pl, -+ struct ethtool_modinfo *modinfo) -+{ -+ int ret = -EOPNOTSUPP; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->module_ops) -+ ret = pl->module_ops->get_module_info(pl->module_data, -+ modinfo); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_info); -+ -+int phylink_ethtool_get_module_eeprom(struct phylink *pl, -+ struct ethtool_eeprom *ee, u8 *buf) -+{ -+ int ret = -EOPNOTSUPP; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->module_ops) -+ ret = pl->module_ops->get_module_eeprom(pl->module_data, ee, -+ buf); -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_eeprom); -+ - int phylink_init_eee(struct phylink *pl, bool clk_stop_enable) - { - int ret = -EPROTONOSUPPORT; -@@ -1016,6 +1049,39 @@ EXPORT_SYMBOL_GPL(phylink_mii_ioctl); - - - -+int phylink_register_module(struct phylink *pl, void *data, -+ const struct phylink_module_ops *ops) -+{ -+ int ret = -EBUSY; -+ -+ mutex_lock(&pl->config_mutex); -+ if (!pl->module_ops) { -+ pl->module_ops = ops; -+ pl->module_data = data; -+ ret = 0; -+ } -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_register_module); -+ -+int phylink_unregister_module(struct phylink *pl, void *data) -+{ -+ int ret = -EINVAL; -+ -+ mutex_lock(&pl->config_mutex); -+ if (pl->module_data == data) { -+ pl->module_ops = NULL; -+ pl->module_data = NULL; -+ ret = 0; -+ } -+ mutex_unlock(&pl->config_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phylink_unregister_module); -+ - void phylink_disable(struct phylink *pl) - { - set_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -55,6 +55,11 @@ struct phylink_mac_ops { - struct phy_device *); - }; - -+struct phylink_module_ops { -+ int (*get_module_info)(void *, struct ethtool_modinfo *); -+ int (*get_module_eeprom)(void *, struct ethtool_eeprom *, u8 *); -+}; -+ - struct phylink *phylink_create(struct net_device *, struct device_node *, - phy_interface_t iface, const struct phylink_mac_ops *ops); - void phylink_destroy(struct phylink *); -@@ -75,12 +80,19 @@ void phylink_ethtool_get_pauseparam(stru - struct ethtool_pauseparam *); - int phylink_ethtool_set_pauseparam(struct phylink *, - struct ethtool_pauseparam *); -+int phylink_ethtool_get_module_info(struct phylink *, struct ethtool_modinfo *); -+int phylink_ethtool_get_module_eeprom(struct phylink *, -+ struct ethtool_eeprom *, u8 *); - int phylink_init_eee(struct phylink *, bool); - int phylink_get_eee_err(struct phylink *); - int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *); - int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *); - int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); - -+int phylink_register_module(struct phylink *, void *, -+ const struct phylink_module_ops *); -+int phylink_unregister_module(struct phylink *, void *); -+ - void phylink_set_link_port(struct phylink *pl, u32 support, u8 port); - int phylink_set_link_an_mode(struct phylink *pl, unsigned int mode); - void phylink_disable(struct phylink *pl); diff --git a/target/linux/mvebu/patches-4.4/145-net-mvneta-add-module-EEPROM-reading-support.patch b/target/linux/mvebu/patches-4.4/145-net-mvneta-add-module-EEPROM-reading-support.patch deleted file mode 100644 index b3f9039081..0000000000 --- a/target/linux/mvebu/patches-4.4/145-net-mvneta-add-module-EEPROM-reading-support.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 665e1fe77dedcfc6b5669214ebfd252c803290d4 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 1 Oct 2015 23:32:39 +0100 -Subject: [PATCH 733/744] net: mvneta: add module EEPROM reading support - -Signed-off-by: Russell King ---- - drivers/net/ethernet/marvell/mvneta.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3911,6 +3911,22 @@ static int mvneta_ethtool_get_rxfh(struc - return 0; - } - -+static int mvneta_ethtool_get_module_info(struct net_device *dev, -+ struct ethtool_modinfo *modinfo) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ -+ return phylink_ethtool_get_module_info(pp->phylink, modinfo); -+} -+ -+static int mvneta_ethtool_get_module_eeprom(struct net_device *dev, -+ struct ethtool_eeprom *ee, u8 *buf) -+{ -+ struct mvneta_port *pp = netdev_priv(dev); -+ -+ return phylink_ethtool_get_module_eeprom(pp->phylink, ee, buf); -+} -+ - static int mvneta_ethtool_get_eee(struct net_device *dev, - struct ethtool_eee *eee) - { -@@ -3983,6 +3999,8 @@ const struct ethtool_ops mvneta_eth_tool - .get_rxnfc = mvneta_ethtool_get_rxnfc, - .get_rxfh = mvneta_ethtool_get_rxfh, - .set_rxfh = mvneta_ethtool_set_rxfh, -+ .get_module_info = mvneta_ethtool_get_module_info, -+ .get_module_eeprom = mvneta_ethtool_get_module_eeprom, - .get_eee = mvneta_ethtool_get_eee, - .set_eee = mvneta_ethtool_set_eee, - }; diff --git a/target/linux/mvebu/patches-4.4/146-sfp-phylink-hook-up-eeprom-functions.patch b/target/linux/mvebu/patches-4.4/146-sfp-phylink-hook-up-eeprom-functions.patch deleted file mode 100644 index f37e652b8a..0000000000 --- a/target/linux/mvebu/patches-4.4/146-sfp-phylink-hook-up-eeprom-functions.patch +++ /dev/null @@ -1,68 +0,0 @@ -From a7091ef24223ed39b39c6b73b77c55c8a607f34a Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Thu, 8 Oct 2015 23:49:47 +0100 -Subject: [PATCH 734/744] sfp/phylink: hook up eeprom functions - -Signed-off-by: Russell King ---- - drivers/net/phy/sfp.c | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -901,11 +901,9 @@ static void sfp_sm_event(struct sfp *sfp - mutex_unlock(&sfp->sm_mutex); - } - --#if 0 --static int sfp_phy_module_info(struct phy_device *phy, -- struct ethtool_modinfo *modinfo) -+static int sfp_module_info(void *priv, struct ethtool_modinfo *modinfo) - { -- struct sfp *sfp = phy->priv; -+ struct sfp *sfp = priv; - - /* locking... and check module is present */ - -@@ -919,10 +917,9 @@ static int sfp_phy_module_info(struct ph - return 0; - } - --static int sfp_phy_module_eeprom(struct phy_device *phy, -- struct ethtool_eeprom *ee, u8 *data) -+static int sfp_module_eeprom(void *priv, struct ethtool_eeprom *ee, u8 *data) - { -- struct sfp *sfp = phy->priv; -+ struct sfp *sfp = priv; - unsigned int first, last, len; - int ret; - -@@ -953,7 +950,11 @@ static int sfp_phy_module_eeprom(struct - } - return 0; - } --#endif -+ -+static const struct phylink_module_ops sfp_module_ops = { -+ .get_module_info = sfp_module_info, -+ .get_module_eeprom = sfp_module_eeprom, -+}; - - static void sfp_timeout(struct work_struct *work) - { -@@ -1029,6 +1030,7 @@ static int sfp_netdev_notify(struct noti - case NETDEV_UNREGISTER: - if (sfp->mod_phy && sfp->phylink) - phylink_disconnect_phy(sfp->phylink); -+ phylink_unregister_module(sfp->phylink, sfp); - sfp->phylink = NULL; - dev_put(sfp->ndev); - sfp->ndev = NULL; -@@ -1145,6 +1147,7 @@ static int sfp_probe(struct platform_dev - } - - phylink_disable(sfp->phylink); -+ phylink_register_module(sfp->phylink, sfp, &sfp_module_ops); - } - - sfp->state = sfp_get_state(sfp); diff --git a/target/linux/mvebu/patches-4.4/147-net-mvneta-add-BQL-support.patch b/target/linux/mvebu/patches-4.4/147-net-mvneta-add-BQL-support.patch deleted file mode 100644 index 7bd2593537..0000000000 --- a/target/linux/mvebu/patches-4.4/147-net-mvneta-add-BQL-support.patch +++ /dev/null @@ -1,83 +0,0 @@ ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -1695,8 +1695,10 @@ static struct mvneta_tx_queue *mvneta_tx - - /* Free tx queue skbuffs */ - static void mvneta_txq_bufs_free(struct mvneta_port *pp, -- struct mvneta_tx_queue *txq, int num) -+ struct mvneta_tx_queue *txq, int num, -+ struct netdev_queue *nq) - { -+ unsigned int bytes_compl = 0, pkts_compl = 0; - int i; - - for (i = 0; i < num; i++) { -@@ -1704,6 +1706,11 @@ static void mvneta_txq_bufs_free(struct - txq->txq_get_index; - struct sk_buff *skb = txq->tx_skb[txq->txq_get_index]; - -+ if (skb) { -+ bytes_compl += skb->len; -+ pkts_compl++; -+ } -+ - mvneta_txq_inc_get(txq); - - if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr)) -@@ -1714,6 +1721,8 @@ static void mvneta_txq_bufs_free(struct - continue; - dev_kfree_skb_any(skb); - } -+ -+ netdev_tx_completed_queue(nq, pkts_compl, bytes_compl); - } - - /* Handle end of transmission */ -@@ -1727,7 +1736,7 @@ static void mvneta_txq_done(struct mvnet - if (!tx_done) - return; - -- mvneta_txq_bufs_free(pp, txq, tx_done); -+ mvneta_txq_bufs_free(pp, txq, tx_done, nq); - - txq->count -= tx_done; - -@@ -2334,6 +2343,8 @@ out: - struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats); - struct netdev_queue *nq = netdev_get_tx_queue(dev, txq_id); - -+ netdev_tx_sent_queue(nq, len); -+ - txq->count += frags; - mvneta_txq_pend_desc_add(pp, txq, frags); - -@@ -2358,9 +2369,10 @@ static void mvneta_txq_done_force(struct - struct mvneta_tx_queue *txq) - - { -+ struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id); - int tx_done = txq->count; - -- mvneta_txq_bufs_free(pp, txq, tx_done); -+ mvneta_txq_bufs_free(pp, txq, tx_done, nq); - - /* reset txq */ - txq->count = 0; -@@ -2841,6 +2853,8 @@ static int mvneta_txq_init(struct mvneta - static void mvneta_txq_deinit(struct mvneta_port *pp, - struct mvneta_tx_queue *txq) - { -+ struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id); -+ - kfree(txq->tx_skb); - - if (txq->tso_hdrs) -@@ -2852,6 +2866,8 @@ static void mvneta_txq_deinit(struct mvn - txq->size * MVNETA_DESC_ALIGNED_SIZE, - txq->descs, txq->descs_phys); - -+ netdev_tx_reset_queue(nq); -+ - txq->descs = NULL; - txq->last_desc = 0; - txq->next_desc_to_proc = 0; diff --git a/target/linux/mvebu/patches-4.4/202-gpio_mvebu_add_limited_pwm_support.patch b/target/linux/mvebu/patches-4.4/202-gpio_mvebu_add_limited_pwm_support.patch deleted file mode 100644 index b09c89f31a..0000000000 --- a/target/linux/mvebu/patches-4.4/202-gpio_mvebu_add_limited_pwm_support.patch +++ /dev/null @@ -1,433 +0,0 @@ -Armada 370/XP devices can 'blink' gpio lines with a configurable on -and off period. This can be modelled as a PWM. - -However, there are only two sets of PWM configuration registers for -all the gpio lines. This driver simply allows a single gpio line per -gpio chip of 32 lines to be used as a PWM. Attempts to use more return -EBUSY. - -Due to the interleaving of registers it is not simple to separate the -PWM driver from the gpio driver. Thus the gpio driver has been -extended with a PWM driver. - -Signed-off-by: Andrew Lunn ---- - drivers/gpio/Kconfig | 5 ++ - drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-mvebu-pwm.c | 202 ++++++++++++++++++++++++++++++++++++++++++ - drivers/gpio/gpio-mvebu.c | 37 +++----- - drivers/gpio/gpio-mvebu.h | 79 +++++++++++++++++ - 5 files changed, 299 insertions(+), 25 deletions(-) - create mode 100644 drivers/gpio/gpio-mvebu-pwm.c - create mode 100644 drivers/gpio/gpio-mvebu.h - ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -295,6 +295,11 @@ config GPIO_MVEBU - depends on OF - select GENERIC_IRQ_CHIP - -+config GPIO_MVEBU_PWM -+ def_bool y -+ depends on GPIO_MVEBU -+ depends on PWM -+ - config GPIO_MXC - def_bool y - depends on ARCH_MXC ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -67,6 +67,7 @@ obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc52 - obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o - obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o - obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o -+obj-$(CONFIG_GPIO_MVEBU_PWM) += gpio-mvebu-pwm.o - obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o - obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o - obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o ---- /dev/null -+++ b/drivers/gpio/gpio-mvebu-pwm.c -@@ -0,0 +1,202 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "gpio-mvebu.h" -+#include "gpiolib.h" -+ -+static void __iomem *mvebu_gpioreg_blink_select(struct mvebu_gpio_chip *mvchip) -+{ -+ return mvchip->membase + GPIO_BLINK_CNT_SELECT; -+} -+ -+static inline struct mvebu_pwm *to_mvebu_pwm(struct pwm_chip *chip) -+{ -+ return container_of(chip, struct mvebu_pwm, chip); -+} -+ -+static inline struct mvebu_gpio_chip *to_mvchip(struct mvebu_pwm *pwm) -+{ -+ return container_of(pwm, struct mvebu_gpio_chip, pwm); -+} -+ -+static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwmd) -+{ -+ struct mvebu_pwm *pwm = to_mvebu_pwm(chip); -+ struct mvebu_gpio_chip *mvchip = to_mvchip(pwm); -+ struct gpio_desc *desc = gpio_to_desc(pwmd->pwm); -+ unsigned long flags; -+ int ret = 0; -+ -+ spin_lock_irqsave(&pwm->lock, flags); -+ if (pwm->used) { -+ ret = -EBUSY; -+ } else { -+ if (!desc) { -+ ret = -ENODEV; -+ goto out; -+ } -+ ret = gpiod_request(desc, "mvebu-pwm"); -+ if (ret) -+ goto out; -+ -+ ret = gpiod_direction_output(desc, 0); -+ if (ret) { -+ gpiod_free(desc); -+ goto out; -+ } -+ -+ pwm->pin = pwmd->pwm - mvchip->chip.base; -+ pwm->used = true; -+ } -+ -+out: -+ spin_unlock_irqrestore(&pwm->lock, flags); -+ return ret; -+} -+ -+static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwmd) -+{ -+ struct mvebu_pwm *pwm = to_mvebu_pwm(chip); -+ struct gpio_desc *desc = gpio_to_desc(pwmd->pwm); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&pwm->lock, flags); -+ gpiod_free(desc); -+ pwm->used = false; -+ spin_unlock_irqrestore(&pwm->lock, flags); -+} -+ -+static int mvebu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwmd, -+ int duty_ns, int period_ns) -+{ -+ struct mvebu_pwm *pwm = to_mvebu_pwm(chip); -+ struct mvebu_gpio_chip *mvchip = to_mvchip(pwm); -+ unsigned int on, off; -+ unsigned long long val; -+ u32 u; -+ -+ val = (unsigned long long) pwm->clk_rate * duty_ns; -+ do_div(val, NSEC_PER_SEC); -+ if (val > UINT_MAX) -+ return -EINVAL; -+ if (val) -+ on = val; -+ else -+ on = 1; -+ -+ val = (unsigned long long) pwm->clk_rate * (period_ns - duty_ns); -+ do_div(val, NSEC_PER_SEC); -+ if (val > UINT_MAX) -+ return -EINVAL; -+ if (val) -+ off = val; -+ else -+ off = 1; -+ -+ u = readl_relaxed(mvebu_gpioreg_blink_select(mvchip)); -+ u &= ~(1 << pwm->pin); -+ u |= (pwm->id << pwm->pin); -+ writel_relaxed(u, mvebu_gpioreg_blink_select(mvchip)); -+ -+ writel_relaxed(on, pwm->membase + BLINK_ON_DURATION); -+ writel_relaxed(off, pwm->membase + BLINK_OFF_DURATION); -+ -+ return 0; -+} -+ -+static int mvebu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwmd) -+{ -+ struct mvebu_pwm *pwm = to_mvebu_pwm(chip); -+ struct mvebu_gpio_chip *mvchip = to_mvchip(pwm); -+ -+ mvebu_gpio_blink(&mvchip->chip, pwm->pin, 1); -+ -+ return 0; -+} -+ -+static void mvebu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwmd) -+{ -+ struct mvebu_pwm *pwm = to_mvebu_pwm(chip); -+ struct mvebu_gpio_chip *mvchip = to_mvchip(pwm); -+ -+ mvebu_gpio_blink(&mvchip->chip, pwm->pin, 0); -+} -+ -+static const struct pwm_ops mvebu_pwm_ops = { -+ .request = mvebu_pwm_request, -+ .free = mvebu_pwm_free, -+ .config = mvebu_pwm_config, -+ .enable = mvebu_pwm_enable, -+ .disable = mvebu_pwm_disable, -+ .owner = THIS_MODULE, -+}; -+ -+void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip) -+{ -+ struct mvebu_pwm *pwm = &mvchip->pwm; -+ -+ pwm->blink_select = readl_relaxed(mvebu_gpioreg_blink_select(mvchip)); -+ pwm->blink_on_duration = -+ readl_relaxed(pwm->membase + BLINK_ON_DURATION); -+ pwm->blink_off_duration = -+ readl_relaxed(pwm->membase + BLINK_OFF_DURATION); -+} -+ -+void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip) -+{ -+ struct mvebu_pwm *pwm = &mvchip->pwm; -+ -+ writel_relaxed(pwm->blink_select, mvebu_gpioreg_blink_select(mvchip)); -+ writel_relaxed(pwm->blink_on_duration, -+ pwm->membase + BLINK_ON_DURATION); -+ writel_relaxed(pwm->blink_off_duration, -+ pwm->membase + BLINK_OFF_DURATION); -+} -+ -+/* -+ * Armada 370/XP has simple PWM support for gpio lines. Other SoCs -+ * don't have this hardware. So if we don't have the necessary -+ * resource, it is not an error. -+ */ -+int mvebu_pwm_probe(struct platform_device *pdev, -+ struct mvebu_gpio_chip *mvchip, -+ int id) -+{ -+ struct device *dev = &pdev->dev; -+ struct mvebu_pwm *pwm = &mvchip->pwm; -+ struct resource *res; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm"); -+ if (!res) -+ return 0; -+ -+ mvchip->pwm.membase = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(mvchip->pwm.membase)) -+ return PTR_ERR(mvchip->percpu_membase); -+ -+ if (id < 0 || id > 1) -+ return -EINVAL; -+ pwm->id = id; -+ -+ if (IS_ERR(mvchip->clk)) -+ return PTR_ERR(mvchip->clk); -+ -+ pwm->clk_rate = clk_get_rate(mvchip->clk); -+ if (!pwm->clk_rate) { -+ dev_err(dev, "failed to get clock rate\n"); -+ return -EINVAL; -+ } -+ -+ pwm->chip.dev = dev; -+ pwm->chip.ops = &mvebu_pwm_ops; -+ pwm->chip.base = mvchip->chip.base; -+ pwm->chip.npwm = mvchip->chip.ngpio; -+ pwm->chip.can_sleep = false; -+ -+ spin_lock_init(&pwm->lock); -+ -+ return pwmchip_add(&pwm->chip); -+} ---- a/drivers/gpio/gpio-mvebu.c -+++ b/drivers/gpio/gpio-mvebu.c -@@ -42,10 +42,11 @@ - #include - #include - #include -+#include - #include - #include - #include -- -+#include "gpio-mvebu.h" - /* - * GPIO unit register offsets. - */ -@@ -75,24 +76,6 @@ - - #define MVEBU_MAX_GPIO_PER_BANK 32 - --struct mvebu_gpio_chip { -- struct gpio_chip chip; -- spinlock_t lock; -- void __iomem *membase; -- void __iomem *percpu_membase; -- int irqbase; -- struct irq_domain *domain; -- int soc_variant; -- -- /* Used to preserve GPIO registers across suspend/resume */ -- u32 out_reg; -- u32 io_conf_reg; -- u32 blink_en_reg; -- u32 in_pol_reg; -- u32 edge_mask_regs[4]; -- u32 level_mask_regs[4]; --}; -- - /* - * Functions returning addresses of individual registers for a given - * GPIO controller. -@@ -218,7 +201,7 @@ static int mvebu_gpio_get(struct gpio_ch - return (u >> pin) & 1; - } - --static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) -+void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) - { - struct mvebu_gpio_chip *mvchip = - container_of(chip, struct mvebu_gpio_chip, chip); -@@ -607,6 +590,8 @@ static int mvebu_gpio_suspend(struct pla - BUG(); - } - -+ mvebu_pwm_suspend(mvchip); -+ - return 0; - } - -@@ -650,6 +635,8 @@ static int mvebu_gpio_resume(struct plat - BUG(); - } - -+ mvebu_pwm_resume(mvchip); -+ - return 0; - } - -@@ -661,7 +648,6 @@ static int mvebu_gpio_probe(struct platf - struct resource *res; - struct irq_chip_generic *gc; - struct irq_chip_type *ct; -- struct clk *clk; - unsigned int ngpios; - int soc_variant; - int i, cpu, id; -@@ -691,10 +677,10 @@ static int mvebu_gpio_probe(struct platf - return id; - } - -- clk = devm_clk_get(&pdev->dev, NULL); -+ mvchip->clk = devm_clk_get(&pdev->dev, NULL); - /* Not all SoCs require a clock.*/ -- if (!IS_ERR(clk)) -- clk_prepare_enable(clk); -+ if (!IS_ERR(mvchip->clk)) -+ clk_prepare_enable(mvchip->clk); - - mvchip->soc_variant = soc_variant; - mvchip->chip.label = dev_name(&pdev->dev); -@@ -828,7 +814,8 @@ static int mvebu_gpio_probe(struct platf - goto err_generic_chip; - } - -- return 0; -+ /* Armada 370/XP has simple PWM support for gpio lines */ -+ return mvebu_pwm_probe(pdev, mvchip, id); - - err_generic_chip: - irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST, ---- /dev/null -+++ b/drivers/gpio/gpio-mvebu.h -@@ -0,0 +1,79 @@ -+/* -+ * Interface between MVEBU GPIO driver and PWM driver for GPIO pins -+ * -+ * Copyright (C) 2015, Andrew Lunn -+ * -+ * This program 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. -+ */ -+ -+#ifndef MVEBU_GPIO_PWM_H -+#define MVEBU_GPIO_PWM_H -+ -+#define BLINK_ON_DURATION 0x0 -+#define BLINK_OFF_DURATION 0x4 -+#define GPIO_BLINK_CNT_SELECT 0x0020 -+ -+struct mvebu_pwm { -+ void __iomem *membase; -+ unsigned long clk_rate; -+ bool used; -+ unsigned pin; -+ struct pwm_chip chip; -+ int id; -+ spinlock_t lock; -+ -+ /* Used to preserve GPIO/PWM registers across suspend / -+ * resume */ -+ u32 blink_select; -+ u32 blink_on_duration; -+ u32 blink_off_duration; -+}; -+ -+struct mvebu_gpio_chip { -+ struct gpio_chip chip; -+ spinlock_t lock; -+ void __iomem *membase; -+ void __iomem *percpu_membase; -+ int irqbase; -+ struct irq_domain *domain; -+ int soc_variant; -+ struct clk *clk; -+#ifdef CONFIG_PWM -+ struct mvebu_pwm pwm; -+#endif -+ /* Used to preserve GPIO registers across suspend/resume */ -+ u32 out_reg; -+ u32 io_conf_reg; -+ u32 blink_en_reg; -+ u32 in_pol_reg; -+ u32 edge_mask_regs[4]; -+ u32 level_mask_regs[4]; -+}; -+ -+void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value); -+ -+#ifdef CONFIG_PWM -+int mvebu_pwm_probe(struct platform_device *pdev, -+ struct mvebu_gpio_chip *mvchip, -+ int id); -+void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip); -+void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip); -+#else -+int mvebu_pwm_probe(struct platform_device *pdev, -+ struct mvebu_gpio_chip *mvchip, -+ int id) -+{ -+ return 0; -+} -+ -+void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip) -+{ -+} -+ -+void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip) -+{ -+} -+#endif -+#endif diff --git a/target/linux/mvebu/patches-4.4/203-dt_bindings_extend_mvebu_gpio_documentation_with_pwm.patch b/target/linux/mvebu/patches-4.4/203-dt_bindings_extend_mvebu_gpio_documentation_with_pwm.patch deleted file mode 100644 index 48f93944bf..0000000000 --- a/target/linux/mvebu/patches-4.4/203-dt_bindings_extend_mvebu_gpio_documentation_with_pwm.patch +++ /dev/null @@ -1,52 +0,0 @@ -Document the optional parameters needed for PWM operation of gpio -lines. - -Signed-off-by: Andrew Lunn ---- - .../devicetree/bindings/gpio/gpio-mvebu.txt | 31 ++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - ---- a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt -+++ b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt -@@ -38,6 +38,23 @@ Required properties: - - #gpio-cells: Should be two. The first cell is the pin number. The - second cell is reserved for flags, unused at the moment. - -+Optional properties: -+ -+In order to use the gpio lines in PWM mode, some additional optional -+properties are required. Only Armada 370 and XP supports these -+properties. -+ -+- reg: an additional register set is needed, for the GPIO Blink -+ Counter on/off registers. -+ -+- reg-names: Must contain an entry "pwm" corresponding to the -+ additional register range needed for pwm operation. -+ -+- #pwm-cells: Should be two. The first cell is the pin number. The -+ second cell is reserved for flags, unused at the moment. -+ -+- clocks: Must be a phandle to the clock for the gpio controller. -+ - Example: - - gpio0: gpio@d0018100 { -@@ -51,3 +68,17 @@ Example: - #interrupt-cells = <2>; - interrupts = <16>, <17>, <18>, <19>; - }; -+ -+ gpio1: gpio@18140 { -+ compatible = "marvell,orion-gpio"; -+ reg = <0x18140 0x40>, <0x181c8 0x08>; -+ reg-names = "gpio", "pwm"; -+ ngpios = <17>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ #pwm-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ interrupts = <87>, <88>, <89>; -+ clocks = <&coreclk 0>; -+ }; diff --git a/target/linux/mvebu/patches-4.4/204-mvebu_xp_add_pwm_properties_to_dtsi_files.patch b/target/linux/mvebu/patches-4.4/204-mvebu_xp_add_pwm_properties_to_dtsi_files.patch deleted file mode 100644 index 69bec6c2a0..0000000000 --- a/target/linux/mvebu/patches-4.4/204-mvebu_xp_add_pwm_properties_to_dtsi_files.patch +++ /dev/null @@ -1,149 +0,0 @@ -Add properties to the gpio nodes to allow them to be also used -as pwm lines. - -Signed-off-by: Andrew Lunn ---- - arch/arm/boot/dts/armada-370.dtsi | 10 ++++++++-- - arch/arm/boot/dts/armada-xp-mv78230.dtsi | 10 ++++++++-- - arch/arm/boot/dts/armada-xp-mv78260.dtsi | 8 ++++++-- - arch/arm/boot/dts/armada-xp-mv78460.dtsi | 10 ++++++++-- - 4 files changed, 30 insertions(+), 8 deletions(-) - ---- a/arch/arm/boot/dts/armada-370.dtsi -+++ b/arch/arm/boot/dts/armada-370.dtsi -@@ -162,24 +162,30 @@ - - gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; -- reg = <0x18100 0x40>; -+ reg = <0x18100 0x40>, <0x181c0 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <82>, <83>, <84>, <85>; -+ clocks = <&coreclk 0>; - }; - - gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; -- reg = <0x18140 0x40>; -+ reg = <0x18140 0x40>, <0x181c8 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <87>, <88>, <89>, <90>; -+ clocks = <&coreclk 0>; - }; - - gpio2: gpio@18180 { ---- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi -+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi -@@ -203,24 +203,30 @@ - internal-regs { - gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; -- reg = <0x18100 0x40>; -+ reg = <0x18100 0x40>, <0x181c0 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <82>, <83>, <84>, <85>; -+ clocks = <&coreclk 0>; - }; - - gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; -- reg = <0x18140 0x40>; -+ reg = <0x18140 0x40>, <0x181c8 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <17>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <87>, <88>, <89>; -+ clocks = <&coreclk 0>; - }; - }; - }; ---- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi -+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi -@@ -286,24 +286,28 @@ - internal-regs { - gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; -- reg = <0x18100 0x40>; -+ reg = <0x18100 0x40>, <0x181c0 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <82>, <83>, <84>, <85>; -+ clocks = <&coreclk 0>; - }; - - gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; -- reg = <0x18140 0x40>; -+ reg = <0x18140 0x40>, <0x181c8 0x08>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <87>, <88>, <89>, <90>; -+ clocks = <&coreclk 0>; - }; - - gpio2: gpio@18180 { ---- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi -+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi -@@ -324,24 +324,30 @@ - internal-regs { - gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; -- reg = <0x18100 0x40>; -+ reg = <0x18100 0x40>, <0x181c0 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <82>, <83>, <84>, <85>; -+ clocks = <&coreclk 0>; - }; - - gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; -- reg = <0x18140 0x40>; -+ reg = <0x18140 0x40>, <0x181c8 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <87>, <88>, <89>, <90>; -+ clocks = <&coreclk 0>; - }; - - gpio2: gpio@18180 { diff --git a/target/linux/mvebu/patches-4.4/205-arm_mvebu_enable_pwm_in_defconfig.patch b/target/linux/mvebu/patches-4.4/205-arm_mvebu_enable_pwm_in_defconfig.patch deleted file mode 100644 index b52c60ff9f..0000000000 --- a/target/linux/mvebu/patches-4.4/205-arm_mvebu_enable_pwm_in_defconfig.patch +++ /dev/null @@ -1,18 +0,0 @@ -Now that the gpio driver also supports PWM operation, enable -the PWM framework in mvebu_v7_defconfig. - -Signed-off-by: Andrew Lunn ---- - arch/arm/configs/mvebu_v7_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/configs/mvebu_v7_defconfig -+++ b/arch/arm/configs/mvebu_v7_defconfig -@@ -131,6 +131,7 @@ CONFIG_DMADEVICES=y - CONFIG_MV_XOR=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_MEMORY=y -+CONFIG_PWM=y - CONFIG_EXT4_FS=y - CONFIG_ISO9660_FS=y - CONFIG_JOLIET=y diff --git a/target/linux/mvebu/patches-4.4/206-mvebu_wrt1900ac_use_pwm-fan_rather_than_gpio-fan.patch b/target/linux/mvebu/patches-4.4/206-mvebu_wrt1900ac_use_pwm-fan_rather_than_gpio-fan.patch deleted file mode 100644 index bff58e9b75..0000000000 --- a/target/linux/mvebu/patches-4.4/206-mvebu_wrt1900ac_use_pwm-fan_rather_than_gpio-fan.patch +++ /dev/null @@ -1,28 +0,0 @@ -The mvebu gpio driver can also perform PWM on some pins. Us the -pwm-fan driver to control the fan of the WRT1900AC, giving us fine -grain control over its speed and hence noise. - -Signed-off-by: Andrew Lunn ---- - arch/arm/boot/dts/armada-xp-wrt1900ac.dts | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - ---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts -@@ -428,13 +428,11 @@ - }; - }; - -- gpio_fan { -+ pwm_fan { - /* SUNON HA4010V4-0000-C99 */ -- compatible = "gpio-fan"; -- gpios = <&gpio0 24 0>; - -- gpio-fan,speed-map = <0 0 -- 4500 1>; -+ compatible = "pwm-fan"; -+ pwms = <&gpio0 24 4000 0>; - }; - - dsa@0 { diff --git a/target/linux/mvebu/patches-4.4/207-armada-385-rd-mtd-partitions.patch b/target/linux/mvebu/patches-4.4/207-armada-385-rd-mtd-partitions.patch deleted file mode 100644 index fc94d9af50..0000000000 --- a/target/linux/mvebu/patches-4.4/207-armada-385-rd-mtd-partitions.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/arch/arm/boot/dts/armada-388-rd.dts -+++ b/arch/arm/boot/dts/armada-388-rd.dts -@@ -79,6 +79,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-4.4/208-ARM-mvebu-385-ap-Add-partitions.patch b/target/linux/mvebu/patches-4.4/208-ARM-mvebu-385-ap-Add-partitions.patch deleted file mode 100644 index d2aaeef4aa..0000000000 --- a/target/linux/mvebu/patches-4.4/208-ARM-mvebu-385-ap-Add-partitions.patch +++ /dev/null @@ -1,34 +0,0 @@ -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 -@@ -184,6 +184,21 @@ - marvell,nand-keep-config; - marvell,nand-enable-arbiter; - nand-on-flash-bbt; -+ -+ mtd0@00000000 { -+ label = "u-boot"; -+ reg = <0x00000000 0x00800000>; -+ }; -+ -+ mtd1@00800000 { -+ label = "kernel"; -+ reg = <0x00800000 0x00800000>; -+ }; -+ -+ mtd2@01000000 { -+ label = "ubi"; -+ reg = <0x01000000 0x3f000000>; -+ }; - }; - - usb3@f0000 { diff --git a/target/linux/mvebu/patches-4.4/209-clearfog_switch_node.patch b/target/linux/mvebu/patches-4.4/209-clearfog_switch_node.patch deleted file mode 100644 index 55494d093b..0000000000 --- a/target/linux/mvebu/patches-4.4/209-clearfog_switch_node.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/arch/arm/boot/dts/armada-388-clearfog.dts -+++ b/arch/arm/boot/dts/armada-388-clearfog.dts -@@ -430,6 +430,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-4.4/210-ARM-dts-armada388-clearfog-add-SFP-module-support.patch b/target/linux/mvebu/patches-4.4/210-ARM-dts-armada388-clearfog-add-SFP-module-support.patch deleted file mode 100644 index 9efcff905d..0000000000 --- a/target/linux/mvebu/patches-4.4/210-ARM-dts-armada388-clearfog-add-SFP-module-support.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 63ff73593c2f5d3fc1cba479321d192caaca48aa Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sat, 12 Sep 2015 18:43:39 +0100 -Subject: [PATCH 738/744] ARM: dts: armada388-clearfog: add SFP module support - -Add SFP module support for Clearfog using the SFP phylink support. - -Signed-off-by: Russell King ---- - arch/arm/boot/dts/armada-388-clearfog.dts | 44 ++++++++----------------------- - 1 file changed, 11 insertions(+), 33 deletions(-) - ---- a/arch/arm/boot/dts/armada-388-clearfog.dts -+++ b/arch/arm/boot/dts/armada-388-clearfog.dts -@@ -90,16 +90,12 @@ - }; - - ethernet@34000 { -+ managed = "in-band-status"; - phy-mode = "sgmii"; - buffer-manager = <&bm>; - bm,pool-long = <3>; - bm,pool-short = <1>; - status = "okay"; -- -- fixed-link { -- speed = <1000>; -- full-duplex; -- }; - }; - - i2c@11000 { -@@ -183,34 +179,6 @@ - output-low; - line-name = "m.2 devslp"; - }; -- sfp_los { -- /* SFP loss of signal */ -- gpio-hog; -- gpios = <12 GPIO_ACTIVE_HIGH>; -- input; -- line-name = "sfp-los"; -- }; -- sfp_tx_fault { -- /* SFP laser fault */ -- gpio-hog; -- gpios = <13 GPIO_ACTIVE_HIGH>; -- input; -- line-name = "sfp-tx-fault"; -- }; -- sfp_tx_disable { -- /* SFP transmit disable */ -- gpio-hog; -- gpios = <14 GPIO_ACTIVE_HIGH>; -- output-low; -- line-name = "sfp-tx-disable"; -- }; -- sfp_mod_def0 { -- /* SFP module present */ -- gpio-hog; -- gpios = <15 GPIO_ACTIVE_LOW>; -- input; -- line-name = "sfp-mod-def0"; -- }; - }; - - /* The MCP3021 is 100kHz clock only */ -@@ -374,6 +342,16 @@ - }; - }; - -+ sfp: sfp { -+ compatible = "sff,sfp"; -+ i2c-bus = <&i2c1>; -+ los-gpio = <&expander0 12 GPIO_ACTIVE_HIGH>; -+ moddef0-gpio = <&expander0 15 GPIO_ACTIVE_LOW>; -+ sfp,ethernet = <ð2>; -+ tx-disable-gpio = <&expander0 14 GPIO_ACTIVE_HIGH>; -+ tx-fault-gpio = <&expander0 13 GPIO_ACTIVE_HIGH>; -+ }; -+ - dsa@0 { - compatible = "marvell,dsa"; - dsa,ethernet = <ð1>; diff --git a/target/linux/mvebu/patches-4.4/300-reprobe_sfp_phy.patch b/target/linux/mvebu/patches-4.4/300-reprobe_sfp_phy.patch deleted file mode 100644 index 42614effb8..0000000000 --- a/target/linux/mvebu/patches-4.4/300-reprobe_sfp_phy.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 28baa5e2635285b178326b301f534ed95c65dd01 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Thu, 29 Sep 2016 11:44:39 +0200 -Subject: [PATCH] sfp: retry phy probe if unsuccessful - -Some phys seem to take longer than 50 ms to come out of reset, so retry -until we find a phy. - -Signed-off-by: Jonas Gorski ---- - drivers/net/phy/sfp.c | 38 +++++++++++++++++++++++++------------- - 1 file changed, 25 insertions(+), 13 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -488,7 +488,7 @@ static void sfp_sm_phy_detach(struct sfp - sfp->mod_phy = NULL; - } - --static void sfp_sm_probe_phy(struct sfp *sfp) -+static int sfp_sm_probe_phy(struct sfp *sfp) - { - struct phy_device *phy; - int err; -@@ -498,11 +498,11 @@ static void sfp_sm_probe_phy(struct sfp - phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR); - if (IS_ERR(phy)) { - dev_err(sfp->dev, "mdiobus scan returned %ld\n", PTR_ERR(phy)); -- return; -+ return PTR_ERR(phy); - } - if (!phy) { -- dev_info(sfp->dev, "no PHY detected\n"); -- return; -+ dev_dbg(sfp->dev, "no PHY detected\n"); -+ return -EAGAIN; - } - - err = phylink_connect_phy(sfp->phylink, phy); -@@ -510,11 +510,13 @@ static void sfp_sm_probe_phy(struct sfp - phy_device_remove(phy); - phy_device_free(phy); - dev_err(sfp->dev, "phylink_connect_phy failed: %d\n", err); -- return; -+ return err; - } - - sfp->mod_phy = phy; - phy_start(phy); -+ -+ return 0; - } - - static void sfp_sm_link_up(struct sfp *sfp) -@@ -565,13 +567,6 @@ static void sfp_sm_mod_init(struct sfp * - { - sfp_module_tx_enable(sfp); - -- /* Wait t_init before indicating that the link is up, provided the -- * current state indicates no TX_FAULT. If TX_FAULT clears before -- * this time, that's fine too. -- */ -- sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); -- sfp->sm_retries = 5; -- - if (sfp->phylink) { - /* Setting the serdes link mode is guesswork: there's no - * field in the EEPROM which indicates what mode should -@@ -587,9 +582,26 @@ static void sfp_sm_mod_init(struct sfp * - !sfp->id.base.e100_base_fx) { - phylink_set_link_an_mode(sfp->phylink, MLO_AN_8023Z); - } else { -+ int ret; -+ - phylink_set_link_an_mode(sfp->phylink, MLO_AN_SGMII); -- sfp_sm_probe_phy(sfp); -+ -+ ret = sfp_sm_probe_phy(sfp); -+ if (ret) { -+ if (ret == -EAGAIN) -+ sfp_sm_set_timer(sfp, T_PROBE_RETRY); -+ else -+ sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0); -+ return; -+ } - } -+ -+ /* Wait t_init before indicating that the link is up, provided the -+ * current state indicates no TX_FAULT. If TX_FAULT clears before -+ * this time, that's fine too. -+ */ -+ sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); -+ sfp->sm_retries = 5; - } - } - diff --git a/target/linux/mvebu/patches-4.4/400-mvneta-tx-queue-workaround.patch b/target/linux/mvebu/patches-4.4/400-mvneta-tx-queue-workaround.patch deleted file mode 100644 index 5dba311d93..0000000000 --- a/target/linux/mvebu/patches-4.4/400-mvneta-tx-queue-workaround.patch +++ /dev/null @@ -1,36 +0,0 @@ -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 -@@ -3984,6 +3984,16 @@ 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, -+ void *accel_priv, -+ 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, -@@ -3994,6 +4004,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, - }; - - const struct ethtool_ops mvneta_eth_tool_ops = {