]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
qualcommbe: use kernel 6.18 by default and drop 6.12 23908/head
authorKenneth Kasilag <kenneth@kasilag.me>
Sun, 21 Jun 2026 22:37:38 +0000 (22:37 +0000)
committerJonas Jelonek <jelonek.jonas@gmail.com>
Tue, 23 Jun 2026 08:51:19 +0000 (10:51 +0200)
Switch the qualcommbe target to use kernel 6.18 and drop 6.12.

Kernel 6.18 for qualcommbe resolves some issues regarding
PCS support and reduces maintenance load maintaining two
kernel branches.

Signed-off-by: Kenneth Kasilag <kenneth@kasilag.me>
Link: https://github.com/openwrt/openwrt/pull/23908
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
92 files changed:
target/linux/qualcommbe/Makefile
target/linux/qualcommbe/config-6.12 [deleted file]
target/linux/qualcommbe/patches-6.12/0002-v6.13-dt-bindings-PCI-qcom-Document-the-IPQ9574-PCIe.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0004-v6.14-arm64-dts-qcom-ipq9574-Add-PCIe-PHYs-and-contr.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0005-v6.14-arm64-dts-qcom-ipq9574-Enable-PCIe-PHYs-and-co.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0006-v6.14-dt-bindings-clock-qcom-Add-CMN-PLL-clock-contr.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0007-v6.14-clk-qcom-Add-CMN-PLL-clock-controller-driver-f.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0008-v6.14-arm64-dts-qcom-ipq9574-Add-CMN-PLL-node.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0009-v6.14-arm64-dts-qcom-ipq9574-Update-xo_board_clk-to-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0016-v6.15-spi-dt-bindings-Introduce-qcom-spi-qpic-snand.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0018-v6.15-dt-bindings-clock-gcc-ipq9574-Add-definition-f.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0019-v6.15-dt-bindings-clock-Add-ipq9574-NSSCC-clock-and-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0020-v6.15-clk-qcom-gcc-ipq9574-Add-support-for-gpll0_out.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0021-v6.15-clk-qcom-Add-NSS-clock-Controller-driver-for-I.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0022-v6.15-arm64-defconfig-Build-NSS-Clock-Controller-dri.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0023-v6.15-net-phy-move-PHY-package-code-from-phy_device..patch [deleted file]
target/linux/qualcommbe/patches-6.12/0024-v6.15-net-phy-add-getters-for-public-members-in-stru.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0100-arm64-dts-qcom-ipq9574-Add-nsscc-node.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0101-arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0103-arm64-dts-qcom-ipq9574-Add-SPI-nand-support.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0104-arm64-dts-qcom-ipq9574-Enable-SPI-NAND-for-ipq9574.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0105-arm64-dts-qcom-ipq9574-Remove-eMMC-node.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0301-arm64-dts-qcom-Add-IPQ9574-MDIO-device-node.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0302-arm64-dts-qcom-ipq9574-Use-usb-phy-for-node-names.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0304-arm64-dts-qcom-ipq9574-add-QPIC-SPI-NAND-default-par.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0305-arm64-dts-qcom-add-partition-table-for-ipq9574-rdp-c.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0306-dt-bindings-net-Document-Qualcomm-QCA8084-PHY-packag.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0307-net-phy-qca808x-Add-QCA8084-ethernet-phy-support.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0308-net-phy-qca808x-Add-config_init-function-for-QCA8084.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0309-net-phy-qca808x-Add-link_change_notify-function-for-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0310-net-phy-qca808x-Add-register-access-support-routines.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0311-net-phy-qca808x-Add-QCA8084-probe-function.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0312-net-phy-qca808x-Add-package-clocks-and-resets-for-QC.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0313-net-phy-qca808x-Add-QCA8084-package-init-function.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0314-dt-bindings-net-pcs-Add-Ethernet-PCS-for-Qualcomm-IP.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0315-net-pcs-Add-PCS-driver-for-Qualcomm-IPQ9574-SoC.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0316-net-pcs-qcom-ipq9574-Add-PCS-instantiation-and-phyli.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0317-net-pcs-qcom-ipq9574-Add-USXGMII-interface-mode-supp.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0318-MAINTAINERS-Add-maintainer-for-Qualcomm-IPQ9574-PCS-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0322-arm64-dts-qcom-ipq9574-add-PCS-uniphy-nodes.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0323-dt-bindings-net-Add-PPE-for-Qualcomm-IPQ9574-SoC.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0324-docs-networking-Add-PPE-driver-documentation-for-Qua.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0325-net-ethernet-qualcomm-Add-PPE-driver-for-IPQ9574-SoC.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0326-net-ethernet-qualcomm-Initialize-PPE-buffer-manageme.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0327-net-ethernet-qualcomm-Initialize-PPE-queue-managemen.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0328-net-ethernet-qualcomm-Initialize-the-PPE-scheduler-s.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0329-net-ethernet-qualcomm-Initialize-PPE-queue-settings.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0330-net-ethernet-qualcomm-Initialize-PPE-service-code-se.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0331-net-ethernet-qualcomm-Initialize-PPE-port-control-se.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0332-net-ethernet-qualcomm-Initialize-PPE-RSS-hash-settin.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0333-net-ethernet-qualcomm-Initialize-PPE-queue-to-Ethern.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0334-net-ethernet-qualcomm-Initialize-PPE-L2-bridge-setti.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0335-net-ethernet-qualcomm-Add-PPE-debugfs-support-for-PP.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0336-MAINTAINERS-Add-maintainer-for-Qualcomm-PPE-driver.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0337-net-ethernet-qualcomm-Add-PPE-scheduler-config.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0338-net-ethernet-qualcomm-Add-phylink-support-for-PPE-MA.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0339-net-ethernet-qualcomm-Add-PPE-port-MAC-MIB-statistic.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0340-net-ethernet-qualcomm-Add-PPE-port-MAC-address-and-E.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0341-net-ethernet-qualcomm-Add-API-to-configure-PPE-port-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0342-net-ethernet-qualcomm-Add-EDMA-support-for-QCOM-IPQ9.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0343-net-ethernet-qualcomm-Add-netdevice-support-for-QCOM.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0344-net-ethernet-qualcomm-Add-Rx-Ethernet-DMA-support.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0345-net-ethernet-qualcomm-Add-Tx-Ethernet-DMA-support.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0346-net-ethernet-qualcomm-Add-miscellaneous-error-interr.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0347-net-ethernet-qualcomm-Add-ethtool-support-for-EDMA.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0348-net-ethernet-qualcomm-Add-module-parameters-for-driv.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0349-net-ethernet-qualcomm-Add-sysctl-for-RPS-bitmap.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0350-net-ethernet-qualcomm-Add-support-for-label-property.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0351-net-ethernet-qualcomm-ppe-Fix-unmet-dependency-with-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0352-net-ethernet-qualcomm-ppe-select-correct-PCS-depende.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0353-arm64-dts-qcom-Add-IPQ9574-PPE-base-device-node.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0354-arm64-dts-qcom-Add-EDMA-node-for-IPQ9574.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0355-arm64-dts-qcom-Add-IPQ9574-RDP433-port-node.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0356-arm64-dts-qcom-add-AQR-NVMEM-node-for-IPQ9574-RDP433.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0357-arm64-dts-qcom-Add-label-to-EDMA-port-for-IPQ9574-RD.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0358-clk-qcom-nsscc-Attach-required-NSSNOC-clock-to-PM-do.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0359-arm64-dts-qcom-ipq9574-add-NSSNOC-clock-to-nss-node.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0360-clk-qcom-nsscc-ipq9574-fix-port5-clock-config.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0361-net-pcs-Add-10GBASER-interface-mode-support-to-IPQ-U.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0362-net-pcs-Add-2500BASEX-interface-mode-support-to-IPQ-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0363-net-pcs-Add-1000BASEX-interface-mode-support-to-IPQ-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0364-net-pcs-Add-10G_QXGMII-interface-mode-support-to-IPQ.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0365-net-pcs-ipq-uniphy-control-MISC2-register-for-2.5G-s.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0367-net-pcs-ipq-uniphy-fix-USXGMII-link-up-failure.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0368-net-pcs-qcom-ipq9574-Update-IPQ9574-PCS-driver.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0370-net-phy-Add-phy_package_remove_once-helper.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0371-net-phy-qca808x-Add-QCA8084-SerDes-probe-and-remove-.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0372-net-phy-qca808x-Add-QCA8084-SerDes-init-function.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0373-net-phy-qca808x-Add-QCA8084-SerDes-speed-config.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0374-dt-bindings-pwm-add-IPQ6018-binding.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0375-pwm-driver-for-qualcomm-ipq6018-pwm-block.patch [deleted file]
target/linux/qualcommbe/patches-6.12/0376-arm64-dts-qcom-ipq9574-add-pwm-node.patch [deleted file]

index 8e5200f6cf6b6eb180726439797bcdb6172fb9d9..8570945bd468707fa821f09d17b5be92d0b34dff 100644 (file)
@@ -8,8 +8,7 @@ KERNELNAME:=Image
 CPU_TYPE:=cortex-a53
 SUBTARGETS:=ipq95xx
 
-KERNEL_PATCHVER:=6.12
-KERNEL_TESTING_PATCHVER:=6.18
+KERNEL_PATCHVER:=6.18
 
 include $(INCLUDE_DIR)/target.mk
 DEFAULT_PACKAGES += \
diff --git a/target/linux/qualcommbe/config-6.12 b/target/linux/qualcommbe/config-6.12
deleted file mode 100644 (file)
index 5178c3b..0000000
+++ /dev/null
@@ -1,618 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
-CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
-CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_FORCE_MAX_ORDER=10
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
-CONFIG_ARCH_MMAP_RND_BITS=18
-CONFIG_ARCH_MMAP_RND_BITS_MAX=24
-CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_PKEY_BITS=3
-CONFIG_ARCH_PROC_KCORE_TEXT=y
-CONFIG_ARCH_QCOM=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_STACKWALK=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_WANTS_EXECMEM_LATE=y
-CONFIG_ARCH_WANTS_NO_INSTR=y
-CONFIG_ARCH_WANTS_THP_SWAP=y
-CONFIG_ARM64=y
-CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_ERRATUM_1165522=y
-CONFIG_ARM64_ERRATUM_1286807=y
-CONFIG_ARM64_ERRATUM_2051678=y
-CONFIG_ARM64_ERRATUM_2054223=y
-CONFIG_ARM64_ERRATUM_2067961=y
-CONFIG_ARM64_ERRATUM_2077057=y
-CONFIG_ARM64_ERRATUM_2658417=y
-CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
-CONFIG_ARM64_PA_BITS=48
-CONFIG_ARM64_PA_BITS_48=y
-CONFIG_ARM64_PLATFORM_DEVICES=y
-CONFIG_ARM64_PTR_AUTH=y
-CONFIG_ARM64_PTR_AUTH_KERNEL=y
-CONFIG_ARM64_SVE=y
-CONFIG_ARM64_TAGGED_ADDR_ABI=y
-CONFIG_ARM64_VA_BITS=39
-CONFIG_ARM64_VA_BITS_39=y
-CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
-CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
-CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GIC_V2M=y
-CONFIG_ARM_GIC_V3=y
-CONFIG_ARM_GIC_V3_ITS=y
-# CONFIG_ARM_MHU_V2 is not set
-# CONFIG_ARM_MHU_V3 is not set
-CONFIG_ARM_PSCI_CPUIDLE=y
-CONFIG_ARM_PSCI_FW=y
-# CONFIG_ARM_QCOM_CPUFREQ_HW is not set
-CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
-CONFIG_AT803X_PHY=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_AUXILIARY_BUS=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_MQ_VIRTIO=y
-CONFIG_BLK_PM=y
-CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
-CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
-CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
-# CONFIG_CLK_QCM2290_GPUCC is not set
-# CONFIG_CLK_X1E80100_CAMCC is not set
-# CONFIG_CLK_X1E80100_DISPCC is not set
-# CONFIG_CLK_X1E80100_GCC is not set
-# CONFIG_CLK_X1E80100_GPUCC is not set
-# CONFIG_CLK_X1E80100_TCSRCC is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_QCOM=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-# CONFIG_COMPAT_32BIT_TIME is not set
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_COREDUMP=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
-CONFIG_CPU_FREQ_GOV_ATTR_SET=y
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_FREQ_THERMAL=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MITIGATIONS=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CRC16=y
-CONFIG_CRC8=y
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DEV_QCE=y
-CONFIG_CRYPTO_DEV_QCE_AEAD=y
-# CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set
-CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y
-# CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set
-# CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set
-CONFIG_CRYPTO_DEV_QCE_SHA=y
-CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y
-CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512
-CONFIG_CRYPTO_DEV_QCOM_RNG=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_LIB_GF128MUL=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_XTS=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEV_COREDUMP=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_NEED_SYNC=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DTC=y
-CONFIG_DT_IDLE_STATES=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FRAME_POINTER=y
-CONFIG_FS_IOMAP=y
-CONFIG_FUNCTION_ALIGNMENT=4
-CONFIG_FUNCTION_ALIGNMENT_4B=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_DEVICES=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_CSUM=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HWMON=y
-CONFIG_HWSPINLOCK=y
-CONFIG_HWSPINLOCK_QCOM=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_HELPER_AUTO=y
-# CONFIG_I2C_QCOM_CCI is not set
-CONFIG_I2C_QUP=y
-CONFIG_IIO=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INTERCONNECT=y
-CONFIG_INTERCONNECT_CLK=y
-# CONFIG_INTERCONNECT_QCOM is not set
-CONFIG_IPQ_APSS_6018=y
-CONFIG_IPQ_APSS_PLL=y
-# CONFIG_IPQ_CMN_PLL is not set
-# CONFIG_IPQ_GCC_4019 is not set
-# CONFIG_IPQ_GCC_5018 is not set
-# CONFIG_IPQ_GCC_5332 is not set
-# CONFIG_IPQ_GCC_6018 is not set
-# CONFIG_IPQ_GCC_8074 is not set
-# CONFIG_IPQ_GCC_9574 is not set
-# CONFIG_IPQ_NSSCC_QCA8K is not set
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MSI_LIB=y
-CONFIG_IRQ_WORK=y
-# CONFIG_KPSS_XCC is not set
-CONFIG_LEDS_TLC591XX=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LRU_GEN_WALKS_MMU=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MAILBOX=y
-# CONFIG_MAILBOX_TEST is not set
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_IPQ4019=y
-# CONFIG_MFD_QCOM_RPM is not set
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=32
-CONFIG_MMC_CQHCI=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_IO_ACCESSORS=y
-CONFIG_MMC_SDHCI_MSM=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMU_LAZY_TLB_REFCOUNT=y
-CONFIG_MODULES_USE_ELF_RELA=y
-# CONFIG_MSM_GCC_8916 is not set
-# CONFIG_MSM_GCC_8917 is not set
-# CONFIG_MSM_GCC_8939 is not set
-# CONFIG_MSM_GCC_8976 is not set
-# CONFIG_MSM_GCC_8994 is not set
-# CONFIG_MSM_GCC_8996 is not set
-# CONFIG_MSM_GCC_8998 is not set
-# CONFIG_MSM_GPUCC_8998 is not set
-# CONFIG_MSM_MMCC_8996 is not set
-# CONFIG_MSM_MMCC_8998 is not set
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_QCOM=y
-CONFIG_MTD_QCOMSMEM_PARTS=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_EGRESS=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_INGRESS=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_XGRESS=y
-CONFIG_NLS=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=4
-# CONFIG_NSM is not set
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_NVMEM_LAYOUT_U_BOOT_ENV=y
-CONFIG_NVMEM_QCOM_QFPROM=y
-# CONFIG_NVMEM_QCOM_SEC_QFPROM is not set
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-CONFIG_PCIEASPM_DEFAULT=y
-# CONFIG_PCIEASPM_PERFORMANCE is not set
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_DW=y
-CONFIG_PCIE_DW_HOST=y
-CONFIG_PCIE_PME=y
-CONFIG_PCIE_QCOM=y
-CONFIG_PCIE_QCOM_COMMON=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-# CONFIG_PCS_QCOM_IPQ9574 is not set
-CONFIG_PER_VMA_LOCK=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-# CONFIG_PHY_QCOM_APQ8064_SATA is not set
-# CONFIG_PHY_QCOM_EDP is not set
-# CONFIG_PHY_QCOM_EUSB2_REPEATER is not set
-# CONFIG_PHY_QCOM_IPQ4019_USB is not set
-# CONFIG_PHY_QCOM_IPQ806X_SATA is not set
-# CONFIG_PHY_QCOM_IPQ806X_USB is not set
-# CONFIG_PHY_QCOM_M31_USB is not set
-# CONFIG_PHY_QCOM_PCIE2 is not set
-CONFIG_PHY_QCOM_QMP=y
-CONFIG_PHY_QCOM_QMP_COMBO=y
-CONFIG_PHY_QCOM_QMP_PCIE=y
-CONFIG_PHY_QCOM_QMP_PCIE_8996=y
-CONFIG_PHY_QCOM_QMP_UFS=y
-CONFIG_PHY_QCOM_QMP_USB=y
-# CONFIG_PHY_QCOM_QMP_USB_LEGACY is not set
-CONFIG_PHY_QCOM_QUSB2=y
-# CONFIG_PHY_QCOM_SGMII_ETH is not set
-# CONFIG_PHY_QCOM_SNPS_EUSB2 is not set
-# CONFIG_PHY_QCOM_USB_HS_28NM is not set
-# CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2 is not set
-# CONFIG_PHY_QCOM_USB_SS is not set
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_IPQ5018 is not set
-# CONFIG_PINCTRL_IPQ5332 is not set
-# CONFIG_PINCTRL_IPQ6018 is not set
-# CONFIG_PINCTRL_IPQ8074 is not set
-# CONFIG_PINCTRL_IPQ9574 is not set
-CONFIG_PINCTRL_MSM=y
-# CONFIG_PINCTRL_MSM8916 is not set
-# CONFIG_PINCTRL_MSM8976 is not set
-# CONFIG_PINCTRL_MSM8994 is not set
-# CONFIG_PINCTRL_MSM8996 is not set
-# CONFIG_PINCTRL_MSM8998 is not set
-# CONFIG_PINCTRL_QCM2290 is not set
-# CONFIG_PINCTRL_QCOM_SSBI_PMIC is not set
-# CONFIG_PINCTRL_QCS404 is not set
-# CONFIG_PINCTRL_QDU1000 is not set
-# CONFIG_PINCTRL_SA8775P is not set
-# CONFIG_PINCTRL_SC7180 is not set
-# CONFIG_PINCTRL_SC8280XP is not set
-# CONFIG_PINCTRL_SDM660 is not set
-# CONFIG_PINCTRL_SDM670 is not set
-# CONFIG_PINCTRL_SDM845 is not set
-# CONFIG_PINCTRL_SDX75 is not set
-# CONFIG_PINCTRL_SM4450 is not set
-# CONFIG_PINCTRL_SM6350 is not set
-# CONFIG_PINCTRL_SM6375 is not set
-# CONFIG_PINCTRL_SM7150 is not set
-# CONFIG_PINCTRL_SM8150 is not set
-# CONFIG_PINCTRL_SM8250 is not set
-# CONFIG_PINCTRL_SM8450 is not set
-# CONFIG_PINCTRL_SM8550 is not set
-# CONFIG_PINCTRL_SM8650 is not set
-# CONFIG_PINCTRL_X1E80100 is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_OPP=y
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POWER_RESET=y
-# CONFIG_POWER_RESET_MSM is not set
-CONFIG_POWER_SUPPLY=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_IPQ=y
-CONFIG_QCA807X_PHY=y
-CONFIG_QCA808X_PHY=y
-# CONFIG_QCM_DISPCC_2290 is not set
-# CONFIG_QCM_GCC_2290 is not set
-# CONFIG_QCOM_A53PLL is not set
-# CONFIG_QCOM_AOSS_QMP is not set
-CONFIG_QCOM_APCS_IPC=y
-# CONFIG_QCOM_APR is not set
-CONFIG_QCOM_BAM_DMA=y
-# CONFIG_QCOM_CLK_APCC_MSM8996 is not set
-# CONFIG_QCOM_CLK_APCS_MSM8916 is not set
-# CONFIG_QCOM_COMMAND_DB is not set
-# CONFIG_QCOM_CPR is not set
-# CONFIG_QCOM_CPUCP_MBOX is not set
-# CONFIG_QCOM_EBI2 is not set
-# CONFIG_QCOM_FASTRPC is not set
-# CONFIG_QCOM_GENI_SE is not set
-# CONFIG_QCOM_GSBI is not set
-# CONFIG_QCOM_HFPLL is not set
-# CONFIG_QCOM_ICC_BWMON is not set
-# CONFIG_QCOM_IPA is not set
-# CONFIG_QCOM_IPCC is not set
-# CONFIG_QCOM_LLCC is not set
-CONFIG_QCOM_MDT_LOADER=y
-# CONFIG_QCOM_MPM is not set
-CONFIG_QCOM_NET_PHYLIB=y
-# CONFIG_QCOM_OCMEM is not set
-# CONFIG_QCOM_PDC is not set
-CONFIG_QCOM_PIL_INFO=y
-# CONFIG_QCOM_PPE is not set
-# CONFIG_QCOM_Q6V5_ADSP is not set
-CONFIG_QCOM_Q6V5_COMMON=y
-# CONFIG_QCOM_Q6V5_MSS is not set
-# CONFIG_QCOM_Q6V5_PAS is not set
-CONFIG_QCOM_Q6V5_WCSS=y
-# CONFIG_QCOM_QSEECOM is not set
-# CONFIG_QCOM_RAMP_CTRL is not set
-# CONFIG_QCOM_RMTFS_MEM is not set
-# CONFIG_QCOM_RPMH is not set
-# CONFIG_QCOM_RPM_MASTER_STATS is not set
-CONFIG_QCOM_RPROC_COMMON=y
-CONFIG_QCOM_SCM=y
-# CONFIG_QCOM_SMD_RPM is not set
-CONFIG_QCOM_SMEM=y
-CONFIG_QCOM_SMEM_STATE=y
-CONFIG_QCOM_SMP2P=y
-# CONFIG_QCOM_SMSM is not set
-CONFIG_QCOM_SOCINFO=y
-# CONFIG_QCOM_SPM is not set
-# CONFIG_QCOM_STATS is not set
-# CONFIG_QCOM_SYSMON is not set
-CONFIG_QCOM_TSENS=y
-CONFIG_QCOM_TZMEM=y
-CONFIG_QCOM_TZMEM_MODE_GENERIC=y
-# CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE is not set
-# CONFIG_QCOM_WCNSS_CTRL is not set
-# CONFIG_QCOM_WCNSS_PIL is not set
-CONFIG_QCOM_WDT=y
-# CONFIG_QCS_GCC_404 is not set
-# CONFIG_QCS_Q6SSTOP_404 is not set
-# CONFIG_QCS_TURING_404 is not set
-# CONFIG_QDU_ECPRICC_1000 is not set
-# CONFIG_QDU_GCC_1000 is not set
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-# CONFIG_REGULATOR_VQMMC_IPQ4019 is not set
-CONFIG_RELOCATABLE=y
-CONFIG_REMOTEPROC=y
-CONFIG_REMOTEPROC_CDEV=y
-CONFIG_RESET_CONTROLLER=y
-# CONFIG_RESET_QCOM_AOSS is not set
-# CONFIG_RESET_QCOM_PDC is not set
-CONFIG_RFS_ACCEL=y
-CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
-CONFIG_RPMSG=y
-CONFIG_RPMSG_CHAR=y
-# CONFIG_RPMSG_CTRL is not set
-# CONFIG_RPMSG_NS is not set
-CONFIG_RPMSG_QCOM_GLINK=y
-CONFIG_RPMSG_QCOM_GLINK_RPM=y
-CONFIG_RPMSG_QCOM_GLINK_SMEM=y
-CONFIG_RPMSG_QCOM_SMD=y
-# CONFIG_RPMSG_TTY is not set
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-# CONFIG_SA_GCC_8775P is not set
-# CONFIG_SA_GPUCC_8775P is not set
-# CONFIG_SCHED_CORE is not set
-CONFIG_SCHED_HW_PRESSURE=y
-CONFIG_SCHED_MC=y
-CONFIG_SCHED_SMT=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_PROC_FS is not set
-# CONFIG_SC_CAMCC_7280 is not set
-# CONFIG_SC_CAMCC_8280XP is not set
-# CONFIG_SC_DISPCC_7180 is not set
-# CONFIG_SC_DISPCC_8280XP is not set
-# CONFIG_SC_GCC_7180 is not set
-# CONFIG_SC_GCC_8280XP is not set
-# CONFIG_SC_GPUCC_7180 is not set
-# CONFIG_SC_LPASSCC_7280 is not set
-# CONFIG_SC_LPASSCC_8280XP is not set
-# CONFIG_SC_LPASS_CORECC_7180 is not set
-# CONFIG_SC_LPASS_CORECC_7280 is not set
-# CONFIG_SC_VIDEOCC_7180 is not set
-# CONFIG_SDM_CAMCC_845 is not set
-# CONFIG_SDM_DISPCC_845 is not set
-# CONFIG_SDM_GCC_660 is not set
-# CONFIG_SDM_GCC_845 is not set
-# CONFIG_SDM_GPUCC_845 is not set
-# CONFIG_SDM_LPASSCC_845 is not set
-# CONFIG_SDM_VIDEOCC_845 is not set
-# CONFIG_SDX_GCC_75 is not set
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_MSM=y
-CONFIG_SERIAL_MSM_CONSOLE=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-# CONFIG_SM_CAMCC_4450 is not set
-# CONFIG_SM_CAMCC_6350 is not set
-# CONFIG_SM_CAMCC_7150 is not set
-# CONFIG_SM_CAMCC_8150 is not set
-# CONFIG_SM_CAMCC_8450 is not set
-# CONFIG_SM_CAMCC_8550 is not set
-# CONFIG_SM_CAMCC_8650 is not set
-# CONFIG_SM_GCC_4450 is not set
-# CONFIG_SM_GCC_7150 is not set
-# CONFIG_SM_GCC_8150 is not set
-# CONFIG_SM_GCC_8250 is not set
-# CONFIG_SM_GCC_8450 is not set
-# CONFIG_SM_GCC_8550 is not set
-# CONFIG_SM_GCC_8650 is not set
-# CONFIG_SM_GPUCC_4450 is not set
-# CONFIG_SM_GPUCC_6115 is not set
-# CONFIG_SM_GPUCC_6125 is not set
-# CONFIG_SM_GPUCC_6350 is not set
-# CONFIG_SM_GPUCC_6375 is not set
-# CONFIG_SM_GPUCC_8150 is not set
-# CONFIG_SM_GPUCC_8250 is not set
-# CONFIG_SM_GPUCC_8350 is not set
-# CONFIG_SM_GPUCC_8450 is not set
-# CONFIG_SM_GPUCC_8550 is not set
-# CONFIG_SM_GPUCC_8650 is not set
-# CONFIG_SM_TCSRCC_8550 is not set
-# CONFIG_SM_TCSRCC_8650 is not set
-# CONFIG_SM_VIDEOCC_7150 is not set
-# CONFIG_SM_VIDEOCC_8150 is not set
-# CONFIG_SM_VIDEOCC_8250 is not set
-# CONFIG_SM_VIDEOCC_8350 is not set
-# CONFIG_SM_VIDEOCC_8450 is not set
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSEMEM=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPARSEMEM_VMEMMAP=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_QPIC_SNAND is not set
-CONFIG_SPI_QUP=y
-CONFIG_SPLIT_PMD_PTLOCKS=y
-CONFIG_SPLIT_PTE_PTLOCKS=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TOOLS_SUPPORT_RELR=y
-CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UBIFS_FS_ADVANCED_COMPR=y
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_UNMAP_KERNEL_AT_EL0=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USER_STACKTRACE_SUPPORT=y
-CONFIG_VDSO_GETRANDOM=y
-CONFIG_VIRTIO=y
-CONFIG_VIRTIO_ANCHOR=y
-# CONFIG_VIRTIO_BLK is not set
-# CONFIG_VIRTIO_DEBUG is not set
-# CONFIG_VIRTIO_NET is not set
-CONFIG_VMAP_STACK=y
-CONFIG_WANT_DEV_COREDUMP=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WATCHDOG_SYSFS=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/qualcommbe/patches-6.12/0002-v6.13-dt-bindings-PCI-qcom-Document-the-IPQ9574-PCIe.patch b/target/linux/qualcommbe/patches-6.12/0002-v6.13-dt-bindings-PCI-qcom-Document-the-IPQ9574-PCIe.patch
deleted file mode 100644 (file)
index 2c88303..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-From e3ccffe9335ce3bdba93640588fab4560d18485e Mon Sep 17 00:00:00 2001
-From: devi priya <quic_devipriy@quicinc.com>
-Date: Thu, 1 Aug 2024 11:18:00 +0530
-Subject: [PATCH 02/22] v6.13: dt-bindings: PCI: qcom: Document the IPQ9574
- PCIe controller
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Document the PCIe controller on IPQ9574 platform.
-
-Link: https://lore.kernel.org/r/20240801054803.3015572-2-quic_srichara@quicinc.com
-Signed-off-by: devi priya <quic_devipriy@quicinc.com>
-Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
-Signed-off-by: Krzysztof WilczyÅ„ski <kwilczynski@kernel.org>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- .../devicetree/bindings/pci/qcom,pcie.yaml    | 50 +++++++++++++++++++
- 1 file changed, 50 insertions(+)
-
---- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
-+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
-@@ -26,6 +26,7 @@ properties:
-           - qcom,pcie-ipq8064-v2
-           - qcom,pcie-ipq8074
-           - qcom,pcie-ipq8074-gen3
-+          - qcom,pcie-ipq9574
-           - qcom,pcie-msm8996
-           - qcom,pcie-qcs404
-           - qcom,pcie-sdm845
-@@ -164,6 +165,7 @@ allOf:
-             enum:
-               - qcom,pcie-ipq6018
-               - qcom,pcie-ipq8074-gen3
-+              - qcom,pcie-ipq9574
-     then:
-       properties:
-         reg:
-@@ -405,6 +407,53 @@ allOf:
-         compatible:
-           contains:
-             enum:
-+              - qcom,pcie-ipq9574
-+    then:
-+      properties:
-+        clocks:
-+          minItems: 6
-+          maxItems: 6
-+        clock-names:
-+          items:
-+            - const: axi_m # AXI Master clock
-+            - const: axi_s # AXI Slave clock
-+            - const: axi_bridge
-+            - const: rchng
-+            - const: ahb
-+            - const: aux
-+
-+        resets:
-+          minItems: 8
-+          maxItems: 8
-+        reset-names:
-+          items:
-+            - const: pipe # PIPE reset
-+            - const: sticky # Core Sticky reset
-+            - const: axi_s_sticky # AXI Slave Sticky reset
-+            - const: axi_s # AXI Slave reset
-+            - const: axi_m_sticky # AXI Master Sticky reset
-+            - const: axi_m # AXI Master reset
-+            - const: aux # AUX Reset
-+            - const: ahb # AHB Reset
-+
-+        interrupts:
-+          minItems: 8
-+        interrupt-names:
-+          items:
-+            - const: msi0
-+            - const: msi1
-+            - const: msi2
-+            - const: msi3
-+            - const: msi4
-+            - const: msi5
-+            - const: msi6
-+            - const: msi7
-+
-+  - if:
-+      properties:
-+        compatible:
-+          contains:
-+            enum:
-               - qcom,pcie-qcs404
-     then:
-       properties:
-@@ -510,6 +559,7 @@ allOf:
-                 - qcom,pcie-ipq8064v2
-                 - qcom,pcie-ipq8074
-                 - qcom,pcie-ipq8074-gen3
-+                - qcom,pcie-ipq9574
-                 - qcom,pcie-qcs404
-     then:
-       required:
diff --git a/target/linux/qualcommbe/patches-6.12/0004-v6.14-arm64-dts-qcom-ipq9574-Add-PCIe-PHYs-and-contr.patch b/target/linux/qualcommbe/patches-6.12/0004-v6.14-arm64-dts-qcom-ipq9574-Add-PCIe-PHYs-and-contr.patch
deleted file mode 100644 (file)
index 9b0deb2..0000000
+++ /dev/null
@@ -1,468 +0,0 @@
-From acb06ebe2d1f043fd597f5c33aff048ae1804293 Mon Sep 17 00:00:00 2001
-From: devi priya <quic_devipriy@quicinc.com>
-Date: Thu, 1 Aug 2024 11:18:01 +0530
-Subject: [PATCH 04/22] v6.14: arm64: dts: qcom: ipq9574: Add PCIe PHYs and
- controller nodes
-
-Add PCIe0, PCIe1, PCIe2, PCIe3 (and corresponding PHY) devices
-found on IPQ9574 platform. The PCIe0 & PCIe1 are 1-lane Gen3
-host whereas PCIe2 & PCIe3 are 2-lane Gen3 host.
-
-Signed-off-by: devi priya <quic_devipriy@quicinc.com>
-Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
-Link: https://lore.kernel.org/r/20240801054803.3015572-3-quic_srichara@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 420 +++++++++++++++++++++++++-
- 1 file changed, 416 insertions(+), 4 deletions(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -226,6 +226,52 @@
-                       reg = <0x00060000 0x6000>;
-               };
-+              pcie0_phy: phy@84000 {
-+                      compatible = "qcom,ipq9574-qmp-gen3x1-pcie-phy";
-+                      reg = <0x00084000 0x1000>;
-+
-+                      clocks = <&gcc GCC_PCIE0_AUX_CLK>,
-+                               <&gcc GCC_PCIE0_AHB_CLK>,
-+                               <&gcc GCC_PCIE0_PIPE_CLK>;
-+                      clock-names = "aux", "cfg_ahb", "pipe";
-+
-+                      assigned-clocks = <&gcc GCC_PCIE0_AUX_CLK>;
-+                      assigned-clock-rates = <20000000>;
-+
-+                      resets = <&gcc GCC_PCIE0_PHY_BCR>,
-+                               <&gcc GCC_PCIE0PHY_PHY_BCR>;
-+                      reset-names = "phy", "common";
-+
-+                      #clock-cells = <0>;
-+                      clock-output-names = "gcc_pcie0_pipe_clk_src";
-+
-+                      #phy-cells = <0>;
-+                      status = "disabled";
-+              };
-+
-+              pcie2_phy: phy@8c000 {
-+                      compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy";
-+                      reg = <0x0008c000 0x2000>;
-+
-+                      clocks = <&gcc GCC_PCIE2_AUX_CLK>,
-+                               <&gcc GCC_PCIE2_AHB_CLK>,
-+                               <&gcc GCC_PCIE2_PIPE_CLK>;
-+                      clock-names = "aux", "cfg_ahb", "pipe";
-+
-+                      assigned-clocks = <&gcc GCC_PCIE2_AUX_CLK>;
-+                      assigned-clock-rates = <20000000>;
-+
-+                      resets = <&gcc GCC_PCIE2_PHY_BCR>,
-+                               <&gcc GCC_PCIE2PHY_PHY_BCR>;
-+                      reset-names = "phy", "common";
-+
-+                      #clock-cells = <0>;
-+                      clock-output-names = "gcc_pcie2_pipe_clk_src";
-+
-+                      #phy-cells = <0>;
-+                      status = "disabled";
-+              };
-+
-               rng: rng@e3000 {
-                       compatible = "qcom,prng-ee";
-                       reg = <0x000e3000 0x1000>;
-@@ -243,6 +289,52 @@
-                       status = "disabled";
-               };
-+              pcie3_phy: phy@f4000 {
-+                      compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy";
-+                      reg = <0x000f4000 0x2000>;
-+
-+                      clocks = <&gcc GCC_PCIE3_AUX_CLK>,
-+                               <&gcc GCC_PCIE3_AHB_CLK>,
-+                               <&gcc GCC_PCIE3_PIPE_CLK>;
-+                      clock-names = "aux", "cfg_ahb", "pipe";
-+
-+                      assigned-clocks = <&gcc GCC_PCIE3_AUX_CLK>;
-+                      assigned-clock-rates = <20000000>;
-+
-+                      resets = <&gcc GCC_PCIE3_PHY_BCR>,
-+                               <&gcc GCC_PCIE3PHY_PHY_BCR>;
-+                      reset-names = "phy", "common";
-+
-+                      #clock-cells = <0>;
-+                      clock-output-names = "gcc_pcie3_pipe_clk_src";
-+
-+                      #phy-cells = <0>;
-+                      status = "disabled";
-+              };
-+
-+              pcie1_phy: phy@fc000 {
-+                      compatible = "qcom,ipq9574-qmp-gen3x1-pcie-phy";
-+                      reg = <0x000fc000 0x1000>;
-+
-+                      clocks = <&gcc GCC_PCIE1_AUX_CLK>,
-+                               <&gcc GCC_PCIE1_AHB_CLK>,
-+                               <&gcc GCC_PCIE1_PIPE_CLK>;
-+                      clock-names = "aux", "cfg_ahb", "pipe";
-+
-+                      assigned-clocks = <&gcc GCC_PCIE1_AUX_CLK>;
-+                      assigned-clock-rates = <20000000>;
-+
-+                      resets = <&gcc GCC_PCIE1_PHY_BCR>,
-+                               <&gcc GCC_PCIE1PHY_PHY_BCR>;
-+                      reset-names = "phy", "common";
-+
-+                      #clock-cells = <0>;
-+                      clock-output-names = "gcc_pcie1_pipe_clk_src";
-+
-+                      #phy-cells = <0>;
-+                      status = "disabled";
-+              };
-+
-               qfprom: efuse@a4000 {
-                       compatible = "qcom,ipq9574-qfprom", "qcom,qfprom";
-                       reg = <0x000a4000 0x5a1>;
-@@ -311,10 +403,10 @@
-                       clocks = <&xo_board_clk>,
-                                <&sleep_clk>,
-                                <0>,
--                               <0>,
--                               <0>,
--                               <0>,
--                               <0>,
-+                               <&pcie0_phy>,
-+                               <&pcie1_phy>,
-+                               <&pcie2_phy>,
-+                               <&pcie3_phy>,
-                                <0>;
-                       #clock-cells = <1>;
-                       #reset-cells = <1>;
-@@ -758,6 +850,326 @@
-                               status = "disabled";
-                       };
-               };
-+
-+              pcie1: pcie@10000000 {
-+                      compatible = "qcom,pcie-ipq9574";
-+                      reg =  <0x10000000 0xf1d>,
-+                             <0x10000f20 0xa8>,
-+                             <0x10001000 0x1000>,
-+                             <0x000f8000 0x4000>,
-+                             <0x10100000 0x1000>;
-+                      reg-names = "dbi", "elbi", "atu", "parf", "config";
-+                      device_type = "pci";
-+                      linux,pci-domain = <1>;
-+                      bus-range = <0x00 0xff>;
-+                      num-lanes = <1>;
-+                      #address-cells = <3>;
-+                      #size-cells = <2>;
-+
-+                      ranges = <0x01000000 0x0 0x00000000 0x10200000 0x0 0x100000>,
-+                               <0x02000000 0x0 0x10300000 0x10300000 0x0 0x7d00000>;
-+
-+                      interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
-+                      interrupt-names = "msi0",
-+                                        "msi1",
-+                                        "msi2",
-+                                        "msi3",
-+                                        "msi4",
-+                                        "msi5",
-+                                        "msi6",
-+                                        "msi7";
-+
-+                      #interrupt-cells = <1>;
-+                      interrupt-map-mask = <0 0 0 0x7>;
-+                      interrupt-map = <0 0 0 1 &intc 0 0 35 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 2 &intc 0 0 49 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 3 &intc 0 0 84 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 4 &intc 0 0 85 IRQ_TYPE_LEVEL_HIGH>;
-+
-+                      clocks = <&gcc GCC_PCIE1_AXI_M_CLK>,
-+                               <&gcc GCC_PCIE1_AXI_S_CLK>,
-+                               <&gcc GCC_PCIE1_AXI_S_BRIDGE_CLK>,
-+                               <&gcc GCC_PCIE1_RCHNG_CLK>,
-+                               <&gcc GCC_PCIE1_AHB_CLK>,
-+                               <&gcc GCC_PCIE1_AUX_CLK>;
-+                      clock-names = "axi_m",
-+                                    "axi_s",
-+                                    "axi_bridge",
-+                                    "rchng",
-+                                    "ahb",
-+                                    "aux";
-+
-+                      resets = <&gcc GCC_PCIE1_PIPE_ARES>,
-+                               <&gcc GCC_PCIE1_CORE_STICKY_ARES>,
-+                               <&gcc GCC_PCIE1_AXI_S_STICKY_ARES>,
-+                               <&gcc GCC_PCIE1_AXI_S_ARES>,
-+                               <&gcc GCC_PCIE1_AXI_M_STICKY_ARES>,
-+                               <&gcc GCC_PCIE1_AXI_M_ARES>,
-+                               <&gcc GCC_PCIE1_AUX_ARES>,
-+                               <&gcc GCC_PCIE1_AHB_ARES>;
-+                      reset-names = "pipe",
-+                                    "sticky",
-+                                    "axi_s_sticky",
-+                                    "axi_s",
-+                                    "axi_m_sticky",
-+                                    "axi_m",
-+                                    "aux",
-+                                    "ahb";
-+
-+                      phys = <&pcie1_phy>;
-+                      phy-names = "pciephy";
-+                      interconnects = <&gcc MASTER_ANOC_PCIE1 &gcc SLAVE_ANOC_PCIE1>,
-+                                      <&gcc MASTER_SNOC_PCIE1 &gcc SLAVE_SNOC_PCIE1>;
-+                      interconnect-names = "pcie-mem", "cpu-pcie";
-+                      status = "disabled";
-+              };
-+
-+              pcie3: pcie@18000000 {
-+                      compatible = "qcom,pcie-ipq9574";
-+                      reg =  <0x18000000 0xf1d>,
-+                             <0x18000f20 0xa8>,
-+                             <0x18001000 0x1000>,
-+                             <0x000f0000 0x4000>,
-+                             <0x18100000 0x1000>;
-+                      reg-names = "dbi", "elbi", "atu", "parf", "config";
-+                      device_type = "pci";
-+                      linux,pci-domain = <3>;
-+                      bus-range = <0x00 0xff>;
-+                      num-lanes = <2>;
-+                      #address-cells = <3>;
-+                      #size-cells = <2>;
-+
-+                      ranges = <0x01000000 0x0 0x00000000 0x18200000 0x0 0x100000>,
-+                               <0x02000000 0x0 0x18300000 0x18300000 0x0 0x7d00000>;
-+
-+                      interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-+                      interrupt-names = "msi0",
-+                                        "msi1",
-+                                        "msi2",
-+                                        "msi3",
-+                                        "msi4",
-+                                        "msi5",
-+                                        "msi6",
-+                                        "msi7";
-+
-+                      #interrupt-cells = <1>;
-+                      interrupt-map-mask = <0 0 0 0x7>;
-+                      interrupt-map = <0 0 0 1 &intc 0 0 189 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 2 &intc 0 0 190 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 3 &intc 0 0 191 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 4 &intc 0 0 192 IRQ_TYPE_LEVEL_HIGH>;
-+
-+                      clocks = <&gcc GCC_PCIE3_AXI_M_CLK>,
-+                               <&gcc GCC_PCIE3_AXI_S_CLK>,
-+                               <&gcc GCC_PCIE3_AXI_S_BRIDGE_CLK>,
-+                               <&gcc GCC_PCIE3_RCHNG_CLK>,
-+                               <&gcc GCC_PCIE3_AHB_CLK>,
-+                               <&gcc GCC_PCIE3_AUX_CLK>;
-+                      clock-names = "axi_m",
-+                                    "axi_s",
-+                                    "axi_bridge",
-+                                    "rchng",
-+                                    "ahb",
-+                                    "aux";
-+
-+                      resets = <&gcc GCC_PCIE3_PIPE_ARES>,
-+                               <&gcc GCC_PCIE3_CORE_STICKY_ARES>,
-+                               <&gcc GCC_PCIE3_AXI_S_STICKY_ARES>,
-+                               <&gcc GCC_PCIE3_AXI_S_ARES>,
-+                               <&gcc GCC_PCIE3_AXI_M_STICKY_ARES>,
-+                               <&gcc GCC_PCIE3_AXI_M_ARES>,
-+                               <&gcc GCC_PCIE3_AUX_ARES>,
-+                               <&gcc GCC_PCIE3_AHB_ARES>;
-+                      reset-names = "pipe",
-+                                    "sticky",
-+                                    "axi_s_sticky",
-+                                    "axi_s",
-+                                    "axi_m_sticky",
-+                                    "axi_m",
-+                                    "aux",
-+                                    "ahb";
-+
-+                      phys = <&pcie3_phy>;
-+                      phy-names = "pciephy";
-+                      interconnects = <&gcc MASTER_ANOC_PCIE3 &gcc SLAVE_ANOC_PCIE3>,
-+                                      <&gcc MASTER_SNOC_PCIE3 &gcc SLAVE_SNOC_PCIE3>;
-+                      interconnect-names = "pcie-mem", "cpu-pcie";
-+                      status = "disabled";
-+              };
-+
-+              pcie2: pcie@20000000 {
-+                      compatible = "qcom,pcie-ipq9574";
-+                      reg =  <0x20000000 0xf1d>,
-+                             <0x20000f20 0xa8>,
-+                             <0x20001000 0x1000>,
-+                             <0x00088000 0x4000>,
-+                             <0x20100000 0x1000>;
-+                      reg-names = "dbi", "elbi", "atu", "parf", "config";
-+                      device_type = "pci";
-+                      linux,pci-domain = <2>;
-+                      bus-range = <0x00 0xff>;
-+                      num-lanes = <2>;
-+                      #address-cells = <3>;
-+                      #size-cells = <2>;
-+
-+                      ranges = <0x01000000 0x0 0x00000000 0x20200000 0x0 0x100000>,
-+                               <0x02000000 0x0 0x20300000 0x20300000 0x0 0x7d00000>;
-+
-+                      interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-+                      interrupt-names = "msi0",
-+                                        "msi1",
-+                                        "msi2",
-+                                        "msi3",
-+                                        "msi4",
-+                                        "msi5",
-+                                        "msi6",
-+                                        "msi7";
-+
-+                      #interrupt-cells = <1>;
-+                      interrupt-map-mask = <0 0 0 0x7>;
-+                      interrupt-map = <0 0 0 1 &intc 0 0 164 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 2 &intc 0 0 165 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 3 &intc 0 0 186 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 4 &intc 0 0 187 IRQ_TYPE_LEVEL_HIGH>;
-+
-+                      clocks = <&gcc GCC_PCIE2_AXI_M_CLK>,
-+                               <&gcc GCC_PCIE2_AXI_S_CLK>,
-+                               <&gcc GCC_PCIE2_AXI_S_BRIDGE_CLK>,
-+                               <&gcc GCC_PCIE2_RCHNG_CLK>,
-+                               <&gcc GCC_PCIE2_AHB_CLK>,
-+                               <&gcc GCC_PCIE2_AUX_CLK>;
-+                      clock-names = "axi_m",
-+                                    "axi_s",
-+                                    "axi_bridge",
-+                                    "rchng",
-+                                    "ahb",
-+                                    "aux";
-+
-+                      resets = <&gcc GCC_PCIE2_PIPE_ARES>,
-+                               <&gcc GCC_PCIE2_CORE_STICKY_ARES>,
-+                               <&gcc GCC_PCIE2_AXI_S_STICKY_ARES>,
-+                               <&gcc GCC_PCIE2_AXI_S_ARES>,
-+                               <&gcc GCC_PCIE2_AXI_M_STICKY_ARES>,
-+                               <&gcc GCC_PCIE2_AXI_M_ARES>,
-+                               <&gcc GCC_PCIE2_AUX_ARES>,
-+                               <&gcc GCC_PCIE2_AHB_ARES>;
-+                      reset-names = "pipe",
-+                                    "sticky",
-+                                    "axi_s_sticky",
-+                                    "axi_s",
-+                                    "axi_m_sticky",
-+                                    "axi_m",
-+                                    "aux",
-+                                    "ahb";
-+
-+                      phys = <&pcie2_phy>;
-+                      phy-names = "pciephy";
-+                      interconnects = <&gcc MASTER_ANOC_PCIE2 &gcc SLAVE_ANOC_PCIE2>,
-+                                      <&gcc MASTER_SNOC_PCIE2 &gcc SLAVE_SNOC_PCIE2>;
-+                      interconnect-names = "pcie-mem", "cpu-pcie";
-+                      status = "disabled";
-+              };
-+
-+              pcie0: pci@28000000 {
-+                      compatible = "qcom,pcie-ipq9574";
-+                      reg =  <0x28000000 0xf1d>,
-+                             <0x28000f20 0xa8>,
-+                             <0x28001000 0x1000>,
-+                             <0x00080000 0x4000>,
-+                             <0x28100000 0x1000>;
-+                      reg-names = "dbi", "elbi", "atu", "parf", "config";
-+                      device_type = "pci";
-+                      linux,pci-domain = <0>;
-+                      bus-range = <0x00 0xff>;
-+                      num-lanes = <1>;
-+                      #address-cells = <3>;
-+                      #size-cells = <2>;
-+
-+                      ranges = <0x01000000 0x0 0x00000000 0x28200000 0x0 0x100000>,
-+                               <0x02000000 0x0 0x28300000 0x28300000 0x0 0x7d00000>;
-+                      interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
-+                      interrupt-names = "msi0",
-+                                        "msi1",
-+                                        "msi2",
-+                                        "msi3",
-+                                        "msi4",
-+                                        "msi5",
-+                                        "msi6",
-+                                        "msi7";
-+
-+                      #interrupt-cells = <1>;
-+                      interrupt-map-mask = <0 0 0 0x7>;
-+                      interrupt-map = <0 0 0 1 &intc 0 0 75 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 2 &intc 0 0 78 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 3 &intc 0 0 79 IRQ_TYPE_LEVEL_HIGH>,
-+                                      <0 0 0 4 &intc 0 0 83 IRQ_TYPE_LEVEL_HIGH>;
-+
-+                      clocks = <&gcc GCC_PCIE0_AXI_M_CLK>,
-+                               <&gcc GCC_PCIE0_AXI_S_CLK>,
-+                               <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>,
-+                               <&gcc GCC_PCIE0_RCHNG_CLK>,
-+                               <&gcc GCC_PCIE0_AHB_CLK>,
-+                               <&gcc GCC_PCIE0_AUX_CLK>;
-+                      clock-names = "axi_m",
-+                                    "axi_s",
-+                                    "axi_bridge",
-+                                    "rchng",
-+                                    "ahb",
-+                                    "aux";
-+
-+                      resets = <&gcc GCC_PCIE0_PIPE_ARES>,
-+                               <&gcc GCC_PCIE0_CORE_STICKY_ARES>,
-+                               <&gcc GCC_PCIE0_AXI_S_STICKY_ARES>,
-+                               <&gcc GCC_PCIE0_AXI_S_ARES>,
-+                               <&gcc GCC_PCIE0_AXI_M_STICKY_ARES>,
-+                               <&gcc GCC_PCIE0_AXI_M_ARES>,
-+                               <&gcc GCC_PCIE0_AUX_ARES>,
-+                               <&gcc GCC_PCIE0_AHB_ARES>;
-+                      reset-names = "pipe",
-+                                    "sticky",
-+                                    "axi_s_sticky",
-+                                    "axi_s",
-+                                    "axi_m_sticky",
-+                                    "axi_m",
-+                                    "aux",
-+                                    "ahb";
-+
-+                      phys = <&pcie0_phy>;
-+                      phy-names = "pciephy";
-+                      interconnects = <&gcc MASTER_ANOC_PCIE0 &gcc SLAVE_ANOC_PCIE0>,
-+                                      <&gcc MASTER_SNOC_PCIE0 &gcc SLAVE_SNOC_PCIE0>;
-+                      interconnect-names = "pcie-mem", "cpu-pcie";
-+                      status = "disabled";
-+              };
-+
-       };
-       thermal-zones {
diff --git a/target/linux/qualcommbe/patches-6.12/0005-v6.14-arm64-dts-qcom-ipq9574-Enable-PCIe-PHYs-and-co.patch b/target/linux/qualcommbe/patches-6.12/0005-v6.14-arm64-dts-qcom-ipq9574-Enable-PCIe-PHYs-and-co.patch
deleted file mode 100644 (file)
index f07e422..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-From 695cb0b8f9c525fe6d3ffbc349bc6087acd71201 Mon Sep 17 00:00:00 2001
-From: devi priya <quic_devipriy@quicinc.com>
-Date: Thu, 1 Aug 2024 11:18:02 +0530
-Subject: [PATCH 05/22] v6.14: arm64: dts: qcom: ipq9574: Enable PCIe PHYs and
- controllers
-
-Enable the PCIe controller and PHY nodes corresponding to RDP 433.
-
-Signed-off-by: devi priya <quic_devipriy@quicinc.com>
-Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
-Link: https://lore.kernel.org/r/20240801054803.3015572-4-quic_srichara@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 113 ++++++++++++++++++++
- 1 file changed, 113 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-@@ -8,6 +8,7 @@
- /dts-v1/;
-+#include <dt-bindings/gpio/gpio.h>
- #include "ipq9574-rdp-common.dtsi"
- / {
-@@ -15,6 +16,45 @@
-       compatible = "qcom,ipq9574-ap-al02-c7", "qcom,ipq9574";
- };
-+&pcie1_phy {
-+      status = "okay";
-+};
-+
-+&pcie1 {
-+      pinctrl-0 = <&pcie1_default>;
-+      pinctrl-names = "default";
-+
-+      perst-gpios = <&tlmm 26 GPIO_ACTIVE_LOW>;
-+      wake-gpios = <&tlmm 27 GPIO_ACTIVE_LOW>;
-+      status = "okay";
-+};
-+
-+&pcie2_phy {
-+      status = "okay";
-+};
-+
-+&pcie2 {
-+      pinctrl-0 = <&pcie2_default>;
-+      pinctrl-names = "default";
-+
-+      perst-gpios = <&tlmm 29 GPIO_ACTIVE_LOW>;
-+      wake-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
-+      status = "okay";
-+};
-+
-+&pcie3_phy {
-+      status = "okay";
-+};
-+
-+&pcie3 {
-+      pinctrl-0 = <&pcie3_default>;
-+      pinctrl-names = "default";
-+
-+      perst-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
-+      wake-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
-+      status = "okay";
-+};
-+
- &sdhc_1 {
-       pinctrl-0 = <&sdc_default_state>;
-       pinctrl-names = "default";
-@@ -28,6 +68,79 @@
- };
- &tlmm {
-+
-+      pcie1_default: pcie1-default-state {
-+              clkreq-n-pins {
-+                      pins = "gpio25";
-+                      function = "pcie1_clk";
-+                      drive-strength = <6>;
-+                      bias-pull-up;
-+              };
-+
-+              perst-n-pins {
-+                      pins = "gpio26";
-+                      function = "gpio";
-+                      drive-strength = <8>;
-+                      bias-pull-down;
-+                      output-low;
-+              };
-+
-+              wake-n-pins {
-+                      pins = "gpio27";
-+                      function = "pcie1_wake";
-+                      drive-strength = <6>;
-+                      bias-pull-up;
-+              };
-+      };
-+
-+      pcie2_default: pcie2-default-state {
-+              clkreq-n-pins {
-+                      pins = "gpio28";
-+                      function = "pcie2_clk";
-+                      drive-strength = <6>;
-+                      bias-pull-up;
-+              };
-+
-+              perst-n-pins {
-+                      pins = "gpio29";
-+                      function = "gpio";
-+                      drive-strength = <8>;
-+                      bias-pull-down;
-+                      output-low;
-+              };
-+
-+              wake-n-pins {
-+                      pins = "gpio30";
-+                      function = "pcie2_wake";
-+                      drive-strength = <6>;
-+                      bias-pull-up;
-+              };
-+      };
-+
-+      pcie3_default: pcie3-default-state {
-+              clkreq-n-pins {
-+                      pins = "gpio31";
-+                      function = "pcie3_clk";
-+                      drive-strength = <6>;
-+                      bias-pull-up;
-+              };
-+
-+              perst-n-pins {
-+                      pins = "gpio32";
-+                      function = "gpio";
-+                      drive-strength = <8>;
-+                      bias-pull-up;
-+                      output-low;
-+              };
-+
-+              wake-n-pins {
-+                      pins = "gpio33";
-+                      function = "pcie3_wake";
-+                      drive-strength = <6>;
-+                      bias-pull-up;
-+              };
-+      };
-+
-       sdc_default_state: sdc-default-state {
-               clk-pins {
-                       pins = "gpio5";
diff --git a/target/linux/qualcommbe/patches-6.12/0006-v6.14-dt-bindings-clock-qcom-Add-CMN-PLL-clock-contr.patch b/target/linux/qualcommbe/patches-6.12/0006-v6.14-dt-bindings-clock-qcom-Add-CMN-PLL-clock-contr.patch
deleted file mode 100644 (file)
index f008776..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-From f4b785b3360c594bb10bd6f1dc5096b3e93f86d9 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Fri, 3 Jan 2025 15:31:34 +0800
-Subject: [PATCH 06/22] v6.14: dt-bindings: clock: qcom: Add CMN PLL clock
- controller for IPQ SoC
-
-The CMN PLL controller provides clocks to networking hardware blocks
-and to GCC on Qualcomm IPQ9574 SoC. It receives input clock from the
-on-chip Wi-Fi, and produces output clocks at fixed rates. These output
-rates are predetermined, and are unrelated to the input clock rate.
-The primary purpose of CMN PLL is to supply clocks to the networking
-hardware such as PPE (packet process engine), PCS and the externally
-connected switch or PHY device. The CMN PLL block also outputs fixed
-rate clocks to GCC, such as 24 MHZ as XO clock and 32 KHZ as sleep
-clock supplied to GCC.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-1-c89fb4d4849d@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- .../bindings/clock/qcom,ipq9574-cmn-pll.yaml  | 77 +++++++++++++++++++
- include/dt-bindings/clock/qcom,ipq-cmn-pll.h  | 22 ++++++
- 2 files changed, 99 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
- create mode 100644 include/dt-bindings/clock/qcom,ipq-cmn-pll.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
-@@ -0,0 +1,77 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/qcom,ipq9574-cmn-pll.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Qualcomm CMN PLL Clock Controller on IPQ SoC
-+
-+maintainers:
-+  - Bjorn Andersson <andersson@kernel.org>
-+  - Luo Jie <quic_luoj@quicinc.com>
-+
-+description:
-+  The CMN (or common) PLL clock controller expects a reference
-+  input clock. This reference clock is from the on-board Wi-Fi.
-+  The CMN PLL supplies a number of fixed rate output clocks to
-+  the devices providing networking functions and to GCC. These
-+  networking hardware include PPE (packet process engine), PCS
-+  and the externally connected switch or PHY devices. The CMN
-+  PLL block also outputs fixed rate clocks to GCC. The PLL's
-+  primary function is to enable fixed rate output clocks for
-+  networking hardware functions used with the IPQ SoC.
-+
-+properties:
-+  compatible:
-+    enum:
-+      - qcom,ipq9574-cmn-pll
-+
-+  reg:
-+    maxItems: 1
-+
-+  clocks:
-+    items:
-+      - description: The reference clock. The supported clock rates include
-+          25000000, 31250000, 40000000, 48000000, 50000000 and 96000000 HZ.
-+      - description: The AHB clock
-+      - description: The SYS clock
-+    description:
-+      The reference clock is the source clock of CMN PLL, which is from the
-+      Wi-Fi. The AHB and SYS clocks must be enabled to access CMN PLL
-+      clock registers.
-+
-+  clock-names:
-+    items:
-+      - const: ref
-+      - const: ahb
-+      - const: sys
-+
-+  "#clock-cells":
-+    const: 1
-+
-+required:
-+  - compatible
-+  - reg
-+  - clocks
-+  - clock-names
-+  - "#clock-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+  - |
-+    #include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
-+    #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
-+
-+    cmn_pll: clock-controller@9b000 {
-+        compatible = "qcom,ipq9574-cmn-pll";
-+        reg = <0x0009b000 0x800>;
-+        clocks = <&cmn_pll_ref_clk>,
-+                 <&gcc GCC_CMN_12GPLL_AHB_CLK>,
-+                 <&gcc GCC_CMN_12GPLL_SYS_CLK>;
-+        clock-names = "ref", "ahb", "sys";
-+        #clock-cells = <1>;
-+        assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
-+        assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
-+    };
-+...
---- /dev/null
-+++ b/include/dt-bindings/clock/qcom,ipq-cmn-pll.h
-@@ -0,0 +1,22 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_QCOM_IPQ_CMN_PLL_H
-+#define _DT_BINDINGS_CLK_QCOM_IPQ_CMN_PLL_H
-+
-+/* CMN PLL core clock. */
-+#define CMN_PLL_CLK                   0
-+
-+/* The output clocks from CMN PLL of IPQ9574. */
-+#define XO_24MHZ_CLK                  1
-+#define SLEEP_32KHZ_CLK                       2
-+#define PCS_31P25MHZ_CLK              3
-+#define NSS_1200MHZ_CLK                       4
-+#define PPE_353MHZ_CLK                        5
-+#define ETH0_50MHZ_CLK                        6
-+#define ETH1_50MHZ_CLK                        7
-+#define ETH2_50MHZ_CLK                        8
-+#define ETH_25MHZ_CLK                 9
-+#endif
diff --git a/target/linux/qualcommbe/patches-6.12/0007-v6.14-clk-qcom-Add-CMN-PLL-clock-controller-driver-f.patch b/target/linux/qualcommbe/patches-6.12/0007-v6.14-clk-qcom-Add-CMN-PLL-clock-controller-driver-f.patch
deleted file mode 100644 (file)
index edbbf8e..0000000
+++ /dev/null
@@ -1,501 +0,0 @@
-From 51c937f5d7a3b239b637555bbd4dc0017b5cccba Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Fri, 3 Jan 2025 15:31:35 +0800
-Subject: [PATCH 07/22] v6.14: clk: qcom: Add CMN PLL clock controller driver
- for IPQ SoC
-
-The CMN PLL clock controller supplies clocks to the hardware
-blocks that together make up the Ethernet function on Qualcomm
-IPQ SoCs and to GCC. The driver is initially supported for
-IPQ9574 SoC.
-
-The CMN PLL clock controller expects a reference input clock
-from the on-board Wi-Fi block acting as clock source. The input
-reference clock needs to be configured to one of the supported
-clock rates.
-
-The controller supplies a number of fixed-rate output clocks.
-For the IPQ9574, there is one output clock of 353 MHZ to PPE
-(Packet Process Engine) hardware block, three 50 MHZ output
-clocks and an additional 25 MHZ output clock supplied to the
-connected Ethernet devices. The PLL also supplies a 24 MHZ
-clock as XO and a 32 KHZ sleep clock to GCC, and one 31.25
-MHZ clock to PCS.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-2-c89fb4d4849d@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- drivers/clk/qcom/Kconfig       |   9 +
- drivers/clk/qcom/Makefile      |   1 +
- drivers/clk/qcom/ipq-cmn-pll.c | 435 +++++++++++++++++++++++++++++++++
- 3 files changed, 445 insertions(+)
- create mode 100644 drivers/clk/qcom/ipq-cmn-pll.c
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -190,6 +190,15 @@ config IPQ_APSS_6018
-         Say Y if you want to support CPU frequency scaling on
-         ipq based devices.
-+config IPQ_CMN_PLL
-+      tristate "IPQ CMN PLL Clock Controller"
-+      help
-+        Support for CMN PLL clock controller on IPQ platform. The
-+        CMN PLL consumes the AHB/SYS clocks from GCC and supplies
-+        the output clocks to the networking hardware and GCC blocks.
-+        Say Y or M if you want to support CMN PLL clock on the IPQ
-+        based devices.
-+
- config IPQ_GCC_4019
-       tristate "IPQ4019 Global Clock Controller"
-       help
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -29,6 +29,7 @@ obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcs
- obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o
- obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
- obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
-+obj-$(CONFIG_IPQ_CMN_PLL) += ipq-cmn-pll.o
- obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
- obj-$(CONFIG_IPQ_GCC_5018) += gcc-ipq5018.o
- obj-$(CONFIG_IPQ_GCC_5332) += gcc-ipq5332.o
---- /dev/null
-+++ b/drivers/clk/qcom/ipq-cmn-pll.c
-@@ -0,0 +1,435 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/*
-+ * CMN PLL block expects the reference clock from on-board Wi-Fi block,
-+ * and supplies fixed rate clocks as output to the networking hardware
-+ * blocks and to GCC. The networking related blocks include PPE (packet
-+ * process engine), the externally connected PHY or switch devices, and
-+ * the PCS.
-+ *
-+ * On the IPQ9574 SoC, there are three clocks with 50 MHZ and one clock
-+ * with 25 MHZ which are output from the CMN PLL to Ethernet PHY (or switch),
-+ * and one clock with 353 MHZ to PPE. The other fixed rate output clocks
-+ * are supplied to GCC (24 MHZ as XO and 32 KHZ as sleep clock), and to PCS
-+ * with 31.25 MHZ.
-+ *
-+ *               +---------+
-+ *               |   GCC   |
-+ *               +--+---+--+
-+ *           AHB CLK|   |SYS CLK
-+ *                  V   V
-+ *          +-------+---+------+
-+ *          |                  +-------------> eth0-50mhz
-+ * REF CLK  |     IPQ9574      |
-+ * -------->+                  +-------------> eth1-50mhz
-+ *          |  CMN PLL block   |
-+ *          |                  +-------------> eth2-50mhz
-+ *          |                  |
-+ *          +----+----+----+---+-------------> eth-25mhz
-+ *               |    |    |
-+ *               V    V    V
-+ *              GCC  PCS  NSS/PPE
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/clk-provider.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_clock.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+
-+#include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
-+
-+#define CMN_PLL_REFCLK_SRC_SELECTION          0x28
-+#define CMN_PLL_REFCLK_SRC_DIV                        GENMASK(9, 8)
-+
-+#define CMN_PLL_LOCKED                                0x64
-+#define CMN_PLL_CLKS_LOCKED                   BIT(8)
-+
-+#define CMN_PLL_POWER_ON_AND_RESET            0x780
-+#define CMN_ANA_EN_SW_RSTN                    BIT(6)
-+
-+#define CMN_PLL_REFCLK_CONFIG                 0x784
-+#define CMN_PLL_REFCLK_EXTERNAL                       BIT(9)
-+#define CMN_PLL_REFCLK_DIV                    GENMASK(8, 4)
-+#define CMN_PLL_REFCLK_INDEX                  GENMASK(3, 0)
-+
-+#define CMN_PLL_CTRL                          0x78c
-+#define CMN_PLL_CTRL_LOCK_DETECT_EN           BIT(15)
-+
-+#define CMN_PLL_DIVIDER_CTRL                  0x794
-+#define CMN_PLL_DIVIDER_CTRL_FACTOR           GENMASK(9, 0)
-+
-+/**
-+ * struct cmn_pll_fixed_output_clk - CMN PLL output clocks information
-+ * @id:       Clock specifier to be supplied
-+ * @name: Clock name to be registered
-+ * @rate: Clock rate
-+ */
-+struct cmn_pll_fixed_output_clk {
-+      unsigned int id;
-+      const char *name;
-+      unsigned long rate;
-+};
-+
-+/**
-+ * struct clk_cmn_pll - CMN PLL hardware specific data
-+ * @regmap: hardware regmap.
-+ * @hw: handle between common and hardware-specific interfaces
-+ */
-+struct clk_cmn_pll {
-+      struct regmap *regmap;
-+      struct clk_hw hw;
-+};
-+
-+#define CLK_PLL_OUTPUT(_id, _name, _rate) {           \
-+      .id =           _id,                            \
-+      .name =         _name,                          \
-+      .rate =         _rate,                          \
-+}
-+
-+#define to_clk_cmn_pll(_hw) container_of(_hw, struct clk_cmn_pll, hw)
-+
-+static const struct regmap_config ipq_cmn_pll_regmap_config = {
-+      .reg_bits = 32,
-+      .reg_stride = 4,
-+      .val_bits = 32,
-+      .max_register = 0x7fc,
-+      .fast_io = true,
-+};
-+
-+static const struct cmn_pll_fixed_output_clk ipq9574_output_clks[] = {
-+      CLK_PLL_OUTPUT(XO_24MHZ_CLK, "xo-24mhz", 24000000UL),
-+      CLK_PLL_OUTPUT(SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL),
-+      CLK_PLL_OUTPUT(PCS_31P25MHZ_CLK, "pcs-31p25mhz", 31250000UL),
-+      CLK_PLL_OUTPUT(NSS_1200MHZ_CLK, "nss-1200mhz", 1200000000UL),
-+      CLK_PLL_OUTPUT(PPE_353MHZ_CLK, "ppe-353mhz", 353000000UL),
-+      CLK_PLL_OUTPUT(ETH0_50MHZ_CLK, "eth0-50mhz", 50000000UL),
-+      CLK_PLL_OUTPUT(ETH1_50MHZ_CLK, "eth1-50mhz", 50000000UL),
-+      CLK_PLL_OUTPUT(ETH2_50MHZ_CLK, "eth2-50mhz", 50000000UL),
-+      CLK_PLL_OUTPUT(ETH_25MHZ_CLK, "eth-25mhz", 25000000UL),
-+};
-+
-+/*
-+ * CMN PLL has the single parent clock, which supports the several
-+ * possible parent clock rates, each parent clock rate is reflected
-+ * by the specific reference index value in the hardware.
-+ */
-+static int ipq_cmn_pll_find_freq_index(unsigned long parent_rate)
-+{
-+      int index = -EINVAL;
-+
-+      switch (parent_rate) {
-+      case 25000000:
-+              index = 3;
-+              break;
-+      case 31250000:
-+              index = 4;
-+              break;
-+      case 40000000:
-+              index = 6;
-+              break;
-+      case 48000000:
-+      case 96000000:
-+              /*
-+               * Parent clock rate 48 MHZ and 96 MHZ take the same value
-+               * of reference clock index. 96 MHZ needs the source clock
-+               * divider to be programmed as 2.
-+               */
-+              index = 7;
-+              break;
-+      case 50000000:
-+              index = 8;
-+              break;
-+      default:
-+              break;
-+      }
-+
-+      return index;
-+}
-+
-+static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw,
-+                                           unsigned long parent_rate)
-+{
-+      struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
-+      u32 val, factor;
-+
-+      /*
-+       * The value of CMN_PLL_DIVIDER_CTRL_FACTOR is automatically adjusted
-+       * by HW according to the parent clock rate.
-+       */
-+      regmap_read(cmn_pll->regmap, CMN_PLL_DIVIDER_CTRL, &val);
-+      factor = FIELD_GET(CMN_PLL_DIVIDER_CTRL_FACTOR, val);
-+
-+      return parent_rate * 2 * factor;
-+}
-+
-+static int clk_cmn_pll_determine_rate(struct clk_hw *hw,
-+                                    struct clk_rate_request *req)
-+{
-+      int ret;
-+
-+      /* Validate the rate of the single parent clock. */
-+      ret = ipq_cmn_pll_find_freq_index(req->best_parent_rate);
-+
-+      return ret < 0 ? ret : 0;
-+}
-+
-+/*
-+ * This function is used to initialize the CMN PLL to enable the fixed
-+ * rate output clocks. It is expected to be configured once.
-+ */
-+static int clk_cmn_pll_set_rate(struct clk_hw *hw, unsigned long rate,
-+                              unsigned long parent_rate)
-+{
-+      struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
-+      int ret, index;
-+      u32 val;
-+
-+      /*
-+       * Configure the reference input clock selection as per the given
-+       * parent clock. The output clock rates are always of fixed value.
-+       */
-+      index = ipq_cmn_pll_find_freq_index(parent_rate);
-+      if (index < 0)
-+              return index;
-+
-+      ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
-+                               CMN_PLL_REFCLK_INDEX,
-+                               FIELD_PREP(CMN_PLL_REFCLK_INDEX, index));
-+      if (ret)
-+              return ret;
-+
-+      /*
-+       * Update the source clock rate selection and source clock
-+       * divider as 2 when the parent clock rate is 96 MHZ.
-+       */
-+      if (parent_rate == 96000000) {
-+              ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
-+                                       CMN_PLL_REFCLK_DIV,
-+                                       FIELD_PREP(CMN_PLL_REFCLK_DIV, 2));
-+              if (ret)
-+                      return ret;
-+
-+              ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_SRC_SELECTION,
-+                                       CMN_PLL_REFCLK_SRC_DIV,
-+                                       FIELD_PREP(CMN_PLL_REFCLK_SRC_DIV, 0));
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /* Enable PLL locked detect. */
-+      ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_CTRL,
-+                            CMN_PLL_CTRL_LOCK_DETECT_EN);
-+      if (ret)
-+              return ret;
-+
-+      /*
-+       * Reset the CMN PLL block to ensure the updated configurations
-+       * take effect.
-+       */
-+      ret = regmap_clear_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
-+                              CMN_ANA_EN_SW_RSTN);
-+      if (ret)
-+              return ret;
-+
-+      usleep_range(1000, 1200);
-+      ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
-+                            CMN_ANA_EN_SW_RSTN);
-+      if (ret)
-+              return ret;
-+
-+      /* Stability check of CMN PLL output clocks. */
-+      return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val,
-+                                      (val & CMN_PLL_CLKS_LOCKED),
-+                                      100, 100 * USEC_PER_MSEC);
-+}
-+
-+static const struct clk_ops clk_cmn_pll_ops = {
-+      .recalc_rate = clk_cmn_pll_recalc_rate,
-+      .determine_rate = clk_cmn_pll_determine_rate,
-+      .set_rate = clk_cmn_pll_set_rate,
-+};
-+
-+static struct clk_hw *ipq_cmn_pll_clk_hw_register(struct platform_device *pdev)
-+{
-+      struct clk_parent_data pdata = { .index = 0 };
-+      struct device *dev = &pdev->dev;
-+      struct clk_init_data init = {};
-+      struct clk_cmn_pll *cmn_pll;
-+      struct regmap *regmap;
-+      void __iomem *base;
-+      int ret;
-+
-+      base = devm_platform_ioremap_resource(pdev, 0);
-+      if (IS_ERR(base))
-+              return ERR_CAST(base);
-+
-+      regmap = devm_regmap_init_mmio(dev, base, &ipq_cmn_pll_regmap_config);
-+      if (IS_ERR(regmap))
-+              return ERR_CAST(regmap);
-+
-+      cmn_pll = devm_kzalloc(dev, sizeof(*cmn_pll), GFP_KERNEL);
-+      if (!cmn_pll)
-+              return ERR_PTR(-ENOMEM);
-+
-+      init.name = "cmn_pll";
-+      init.parent_data = &pdata;
-+      init.num_parents = 1;
-+      init.ops = &clk_cmn_pll_ops;
-+
-+      cmn_pll->hw.init = &init;
-+      cmn_pll->regmap = regmap;
-+
-+      ret = devm_clk_hw_register(dev, &cmn_pll->hw);
-+      if (ret)
-+              return ERR_PTR(ret);
-+
-+      return &cmn_pll->hw;
-+}
-+
-+static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
-+{
-+      const struct cmn_pll_fixed_output_clk *fixed_clk;
-+      struct clk_hw_onecell_data *hw_data;
-+      struct device *dev = &pdev->dev;
-+      struct clk_hw *cmn_pll_hw;
-+      unsigned int num_clks;
-+      struct clk_hw *hw;
-+      int ret, i;
-+
-+      fixed_clk = ipq9574_output_clks;
-+      num_clks = ARRAY_SIZE(ipq9574_output_clks);
-+
-+      hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks + 1),
-+                             GFP_KERNEL);
-+      if (!hw_data)
-+              return -ENOMEM;
-+
-+      /*
-+       * Register the CMN PLL clock, which is the parent clock of
-+       * the fixed rate output clocks.
-+       */
-+      cmn_pll_hw = ipq_cmn_pll_clk_hw_register(pdev);
-+      if (IS_ERR(cmn_pll_hw))
-+              return PTR_ERR(cmn_pll_hw);
-+
-+      /* Register the fixed rate output clocks. */
-+      for (i = 0; i < num_clks; i++) {
-+              hw = clk_hw_register_fixed_rate_parent_hw(dev, fixed_clk[i].name,
-+                                                        cmn_pll_hw, 0,
-+                                                        fixed_clk[i].rate);
-+              if (IS_ERR(hw)) {
-+                      ret = PTR_ERR(hw);
-+                      goto unregister_fixed_clk;
-+              }
-+
-+              hw_data->hws[fixed_clk[i].id] = hw;
-+      }
-+
-+      /*
-+       * Provide the CMN PLL clock. The clock rate of CMN PLL
-+       * is configured to 12 GHZ by DT property assigned-clock-rates-u64.
-+       */
-+      hw_data->hws[CMN_PLL_CLK] = cmn_pll_hw;
-+      hw_data->num = num_clks + 1;
-+
-+      ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
-+      if (ret)
-+              goto unregister_fixed_clk;
-+
-+      platform_set_drvdata(pdev, hw_data);
-+
-+      return 0;
-+
-+unregister_fixed_clk:
-+      while (i > 0)
-+              clk_hw_unregister(hw_data->hws[fixed_clk[--i].id]);
-+
-+      return ret;
-+}
-+
-+static int ipq_cmn_pll_clk_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      int ret;
-+
-+      ret = devm_pm_runtime_enable(dev);
-+      if (ret)
-+              return ret;
-+
-+      ret = devm_pm_clk_create(dev);
-+      if (ret)
-+              return ret;
-+
-+      /*
-+       * To access the CMN PLL registers, the GCC AHB & SYS clocks
-+       * of CMN PLL block need to be enabled.
-+       */
-+      ret = pm_clk_add(dev, "ahb");
-+      if (ret)
-+              return dev_err_probe(dev, ret, "Fail to add AHB clock\n");
-+
-+      ret = pm_clk_add(dev, "sys");
-+      if (ret)
-+              return dev_err_probe(dev, ret, "Fail to add SYS clock\n");
-+
-+      ret = pm_runtime_resume_and_get(dev);
-+      if (ret)
-+              return ret;
-+
-+      /* Register CMN PLL clock and fixed rate output clocks. */
-+      ret = ipq_cmn_pll_register_clks(pdev);
-+      pm_runtime_put(dev);
-+      if (ret)
-+              return dev_err_probe(dev, ret,
-+                                   "Fail to register CMN PLL clocks\n");
-+
-+      return 0;
-+}
-+
-+static void ipq_cmn_pll_clk_remove(struct platform_device *pdev)
-+{
-+      struct clk_hw_onecell_data *hw_data = platform_get_drvdata(pdev);
-+      int i;
-+
-+      /*
-+       * The clock with index CMN_PLL_CLK is unregistered by
-+       * device management.
-+       */
-+      for (i = 0; i < hw_data->num; i++) {
-+              if (i != CMN_PLL_CLK)
-+                      clk_hw_unregister(hw_data->hws[i]);
-+      }
-+}
-+
-+static const struct dev_pm_ops ipq_cmn_pll_pm_ops = {
-+      SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
-+};
-+
-+static const struct of_device_id ipq_cmn_pll_clk_ids[] = {
-+      { .compatible = "qcom,ipq9574-cmn-pll", },
-+      { }
-+};
-+MODULE_DEVICE_TABLE(of, ipq_cmn_pll_clk_ids);
-+
-+static struct platform_driver ipq_cmn_pll_clk_driver = {
-+      .probe = ipq_cmn_pll_clk_probe,
-+      .remove = ipq_cmn_pll_clk_remove,
-+      .driver = {
-+              .name = "ipq_cmn_pll",
-+              .of_match_table = ipq_cmn_pll_clk_ids,
-+              .pm = &ipq_cmn_pll_pm_ops,
-+      },
-+};
-+module_platform_driver(ipq_cmn_pll_clk_driver);
-+
-+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ CMN PLL Driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/qualcommbe/patches-6.12/0008-v6.14-arm64-dts-qcom-ipq9574-Add-CMN-PLL-node.patch b/target/linux/qualcommbe/patches-6.12/0008-v6.14-arm64-dts-qcom-ipq9574-Add-CMN-PLL-node.patch
deleted file mode 100644 (file)
index b29bbda..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-From 20a3597d994c8ac372bbb66d9f11bccb7f405154 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Fri, 3 Jan 2025 15:31:37 +0800
-Subject: [PATCH 08/22] v6.14: arm64: dts: qcom: ipq9574: Add CMN PLL node
-
-The CMN PLL clock controller allows selection of an input clock rate
-from a defined set of input clock rates. It in-turn supplies fixed
-rate output clocks to the hardware blocks that provide the ethernet
-functions such as PPE (Packet Process Engine) and connected switch or
-PHY, and to GCC.
-
-The reference clock of CMN PLL is routed from XO to the CMN PLL through
-the internal WiFi block.
-.XO (48 MHZ or 96 MHZ)-->WiFi (multiplier/divider)-->48 MHZ to CMN PLL.
-
-The reference input clock from WiFi to CMN PLL is fully controlled by
-the bootstrap pins which select the XO frequency (48 MHZ or 96 MHZ).
-Based on this frequency, the divider in the internal Wi-Fi block is
-automatically configured by hardware (1 for 48 MHZ, 2 for 96 MHZ), to
-ensure output clock to CMN PLL is 48 MHZ.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-4-c89fb4d4849d@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- .../boot/dts/qcom/ipq9574-rdp-common.dtsi     | 17 +++++++++++-
- arch/arm64/boot/dts/qcom/ipq9574.dtsi         | 26 ++++++++++++++++++-
- 2 files changed, 41 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-@@ -3,7 +3,7 @@
-  * IPQ9574 RDP board common device tree source
-  *
-  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
-- * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
-+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
-  */
- /dts-v1/;
-@@ -171,6 +171,21 @@
-       status = "okay";
- };
-+/*
-+ * The bootstrap pins for the board select the XO clock frequency
-+ * (48 MHZ or 96 MHZ used for different RDP type board). This setting
-+ * automatically enables the right dividers, to ensure the reference
-+ * clock output from WiFi to the CMN PLL is 48 MHZ.
-+ */
-+&ref_48mhz_clk {
-+      clock-div = <1>;
-+      clock-mult = <1>;
-+};
-+
- &xo_board_clk {
-       clock-frequency = <24000000>;
- };
-+
-+&xo_clk {
-+      clock-frequency = <48000000>;
-+};
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -3,10 +3,11 @@
-  * IPQ9574 SoC device tree source
-  *
-  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
-- * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
-+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
-  */
- #include <dt-bindings/clock/qcom,apss-ipq.h>
-+#include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
- #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
- #include <dt-bindings/interconnect/qcom,ipq9574.h>
- #include <dt-bindings/interrupt-controller/arm-gic.h>
-@@ -19,6 +20,12 @@
-       #size-cells = <2>;
-       clocks {
-+              ref_48mhz_clk: ref-48mhz-clk {
-+                      compatible = "fixed-factor-clock";
-+                      clocks = <&xo_clk>;
-+                      #clock-cells = <0>;
-+              };
-+
-               sleep_clk: sleep-clk {
-                       compatible = "fixed-clock";
-                       #clock-cells = <0>;
-@@ -28,6 +35,11 @@
-                       compatible = "fixed-clock";
-                       #clock-cells = <0>;
-               };
-+
-+              xo_clk: xo-clk {
-+                      compatible = "fixed-clock";
-+                      #clock-cells = <0>;
-+              };
-       };
-       cpus {
-@@ -335,6 +347,18 @@
-                       status = "disabled";
-               };
-+              cmn_pll: clock-controller@9b000 {
-+                      compatible = "qcom,ipq9574-cmn-pll";
-+                      reg = <0x0009b000 0x800>;
-+                      clocks = <&ref_48mhz_clk>,
-+                               <&gcc GCC_CMN_12GPLL_AHB_CLK>,
-+                               <&gcc GCC_CMN_12GPLL_SYS_CLK>;
-+                      clock-names = "ref", "ahb", "sys";
-+                      #clock-cells = <1>;
-+                      assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
-+                      assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
-+              };
-+
-               qfprom: efuse@a4000 {
-                       compatible = "qcom,ipq9574-qfprom", "qcom,qfprom";
-                       reg = <0x000a4000 0x5a1>;
diff --git a/target/linux/qualcommbe/patches-6.12/0009-v6.14-arm64-dts-qcom-ipq9574-Update-xo_board_clk-to-.patch b/target/linux/qualcommbe/patches-6.12/0009-v6.14-arm64-dts-qcom-ipq9574-Update-xo_board_clk-to-.patch
deleted file mode 100644 (file)
index 0268c5c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From 62307c5e153de617cb0827509fb964df051caaac Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Fri, 3 Jan 2025 15:31:38 +0800
-Subject: [PATCH 09/22] v6.14: arm64: dts: qcom: ipq9574: Update xo_board_clk
- to use fixed factor clock
-
-xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
-48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
-block routing channel.
-
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-5-c89fb4d4849d@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
- arch/arm64/boot/dts/qcom/ipq9574.dtsi            | 3 ++-
- 2 files changed, 8 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-@@ -182,8 +182,13 @@
-       clock-mult = <1>;
- };
-+/*
-+ * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
-+ * from WiFi output clock 48 MHZ divided by 2.
-+ */
- &xo_board_clk {
--      clock-frequency = <24000000>;
-+      clock-div = <2>;
-+      clock-mult = <1>;
- };
- &xo_clk {
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -32,7 +32,8 @@
-               };
-               xo_board_clk: xo-board-clk {
--                      compatible = "fixed-clock";
-+                      compatible = "fixed-factor-clock";
-+                      clocks = <&ref_48mhz_clk>;
-                       #clock-cells = <0>;
-               };
diff --git a/target/linux/qualcommbe/patches-6.12/0016-v6.15-spi-dt-bindings-Introduce-qcom-spi-qpic-snand.patch b/target/linux/qualcommbe/patches-6.12/0016-v6.15-spi-dt-bindings-Introduce-qcom-spi-qpic-snand.patch
deleted file mode 100644 (file)
index 6a1627a..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-From 66fde1c5d29006127cc4fc5a12a0c42415c098bd Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Mon, 24 Feb 2025 16:44:13 +0530
-Subject: [PATCH 16/22] v6.15: spi: dt-bindings: Introduce qcom,spi-qpic-snand
-
-Document the QPIC-SPI-NAND flash controller present in the IPQ SoCs.
-It can work both in serial and parallel mode and supports typical
-SPI-NAND page cache operations.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Link: https://patch.msgid.link/20250224111414.2809669-2-quic_mdalam@quicinc.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- .../bindings/spi/qcom,spi-qpic-snand.yaml     | 83 +++++++++++++++++++
- 1 file changed, 83 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml
-@@ -0,0 +1,83 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/spi/qcom,spi-qpic-snand.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Qualcomm QPIC NAND controller
-+
-+maintainers:
-+  - Md sadre Alam <quic_mdalam@quicinc.com>
-+
-+description:
-+  The QCOM QPIC-SPI-NAND flash controller is an extended version of
-+  the QCOM QPIC NAND flash controller. It can work both in serial
-+  and parallel mode. It supports typical SPI-NAND page cache
-+  operations in single, dual or quad IO mode with pipelined ECC
-+  encoding/decoding using the QPIC ECC HW engine.
-+
-+allOf:
-+  - $ref: /schemas/spi/spi-controller.yaml#
-+
-+properties:
-+  compatible:
-+    enum:
-+      - qcom,ipq9574-snand
-+
-+  reg:
-+    maxItems: 1
-+
-+  clocks:
-+    maxItems: 3
-+
-+  clock-names:
-+    items:
-+      - const: core
-+      - const: aon
-+      - const: iom
-+
-+  dmas:
-+    items:
-+      - description: tx DMA channel
-+      - description: rx DMA channel
-+      - description: cmd DMA channel
-+
-+  dma-names:
-+    items:
-+      - const: tx
-+      - const: rx
-+      - const: cmd
-+
-+required:
-+  - compatible
-+  - reg
-+  - clocks
-+  - clock-names
-+
-+unevaluatedProperties: false
-+
-+examples:
-+  - |
-+    #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
-+    spi@79b0000 {
-+        compatible = "qcom,ipq9574-snand";
-+        reg = <0x1ac00000 0x800>;
-+
-+        clocks = <&gcc GCC_QPIC_CLK>,
-+                 <&gcc GCC_QPIC_AHB_CLK>,
-+                 <&gcc GCC_QPIC_IO_MACRO_CLK>;
-+        clock-names = "core", "aon", "iom";
-+
-+        #address-cells = <1>;
-+        #size-cells = <0>;
-+
-+        flash@0 {
-+            compatible = "spi-nand";
-+            reg = <0>;
-+            #address-cells = <1>;
-+            #size-cells = <1>;
-+            nand-ecc-engine = <&qpic_nand>;
-+            nand-ecc-strength = <4>;
-+            nand-ecc-step-size = <512>;
-+        };
-+    };
diff --git a/target/linux/qualcommbe/patches-6.12/0018-v6.15-dt-bindings-clock-gcc-ipq9574-Add-definition-f.patch b/target/linux/qualcommbe/patches-6.12/0018-v6.15-dt-bindings-clock-gcc-ipq9574-Add-definition-f.patch
deleted file mode 100644 (file)
index dfe655d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From 25ce13ad8852f14835e650132ccf4fc0bf127699 Mon Sep 17 00:00:00 2001
-From: Devi Priya <quic_devipriy@quicinc.com>
-Date: Thu, 13 Mar 2025 16:33:54 +0530
-Subject: [PATCH 18/22] v6.15: dt-bindings: clock: gcc-ipq9574: Add definition
- for GPLL0_OUT_AUX
-
-Add the definition for GPLL0_OUT_AUX clock.
-
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
-Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
-Link: https://lore.kernel.org/r/20250313110359.242491-2-quic_mmanikan@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- include/dt-bindings/clock/qcom,ipq9574-gcc.h | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/include/dt-bindings/clock/qcom,ipq9574-gcc.h
-+++ b/include/dt-bindings/clock/qcom,ipq9574-gcc.h
-@@ -220,4 +220,5 @@
- #define GCC_PCIE1_PIPE_CLK                            211
- #define GCC_PCIE2_PIPE_CLK                            212
- #define GCC_PCIE3_PIPE_CLK                            213
-+#define GPLL0_OUT_AUX                                 214
- #endif
diff --git a/target/linux/qualcommbe/patches-6.12/0019-v6.15-dt-bindings-clock-Add-ipq9574-NSSCC-clock-and-.patch b/target/linux/qualcommbe/patches-6.12/0019-v6.15-dt-bindings-clock-Add-ipq9574-NSSCC-clock-and-.patch
deleted file mode 100644 (file)
index 0552b07..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-From 5ed04d121a8d24cc3151aa57a21a6c944ad6d7f3 Mon Sep 17 00:00:00 2001
-From: Devi Priya <quic_devipriy@quicinc.com>
-Date: Thu, 13 Mar 2025 16:33:56 +0530
-Subject: [PATCH 19/22] v6.15: dt-bindings: clock: Add ipq9574 NSSCC clock and
- reset definitions
-
-Add NSSCC clock and reset definitions for ipq9574.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
-Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
-Link: https://lore.kernel.org/r/20250313110359.242491-4-quic_mmanikan@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- .../bindings/clock/qcom,ipq9574-nsscc.yaml    |  98 +++++++++++
- .../dt-bindings/clock/qcom,ipq9574-nsscc.h    | 152 ++++++++++++++++++
- .../dt-bindings/reset/qcom,ipq9574-nsscc.h    | 134 +++++++++++++++
- 3 files changed, 384 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml
- create mode 100644 include/dt-bindings/clock/qcom,ipq9574-nsscc.h
- create mode 100644 include/dt-bindings/reset/qcom,ipq9574-nsscc.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml
-@@ -0,0 +1,98 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/qcom,ipq9574-nsscc.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Qualcomm Networking Sub System Clock & Reset Controller on IPQ9574
-+
-+maintainers:
-+  - Bjorn Andersson <andersson@kernel.org>
-+  - Anusha Rao <quic_anusha@quicinc.com>
-+
-+description: |
-+  Qualcomm networking sub system clock control module provides the clocks,
-+  resets on IPQ9574
-+
-+  See also::
-+    include/dt-bindings/clock/qcom,ipq9574-nsscc.h
-+    include/dt-bindings/reset/qcom,ipq9574-nsscc.h
-+
-+properties:
-+  compatible:
-+    const: qcom,ipq9574-nsscc
-+
-+  clocks:
-+    items:
-+      - description: Board XO source
-+      - description: CMN_PLL NSS 1200MHz (Bias PLL cc) clock source
-+      - description: CMN_PLL PPE 353MHz (Bias PLL ubi nc) clock source
-+      - description: GCC GPLL0 OUT AUX clock source
-+      - description: Uniphy0 NSS Rx clock source
-+      - description: Uniphy0 NSS Tx clock source
-+      - description: Uniphy1 NSS Rx clock source
-+      - description: Uniphy1 NSS Tx clock source
-+      - description: Uniphy2 NSS Rx clock source
-+      - description: Uniphy2 NSS Tx clock source
-+      - description: GCC NSSCC clock source
-+
-+  '#interconnect-cells':
-+    const: 1
-+
-+  clock-names:
-+    items:
-+      - const: xo
-+      - const: nss_1200
-+      - const: ppe_353
-+      - const: gpll0_out
-+      - const: uniphy0_rx
-+      - const: uniphy0_tx
-+      - const: uniphy1_rx
-+      - const: uniphy1_tx
-+      - const: uniphy2_rx
-+      - const: uniphy2_tx
-+      - const: bus
-+
-+required:
-+  - compatible
-+  - clocks
-+  - clock-names
-+
-+allOf:
-+  - $ref: qcom,gcc.yaml#
-+
-+unevaluatedProperties: false
-+
-+examples:
-+  - |
-+    #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
-+    #include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
-+    clock-controller@39b00000 {
-+      compatible = "qcom,ipq9574-nsscc";
-+      reg = <0x39b00000 0x80000>;
-+      clocks = <&xo_board_clk>,
-+               <&cmn_pll NSS_1200MHZ_CLK>,
-+               <&cmn_pll PPE_353MHZ_CLK>,
-+               <&gcc GPLL0_OUT_AUX>,
-+               <&uniphy 0>,
-+               <&uniphy 1>,
-+               <&uniphy 2>,
-+               <&uniphy 3>,
-+               <&uniphy 4>,
-+               <&uniphy 5>,
-+               <&gcc GCC_NSSCC_CLK>;
-+      clock-names = "xo",
-+                    "nss_1200",
-+                    "ppe_353",
-+                    "gpll0_out",
-+                    "uniphy0_rx",
-+                    "uniphy0_tx",
-+                    "uniphy1_rx",
-+                    "uniphy1_tx",
-+                    "uniphy2_rx",
-+                    "uniphy2_tx",
-+                    "bus";
-+      #clock-cells = <1>;
-+      #reset-cells = <1>;
-+    };
-+...
---- /dev/null
-+++ b/include/dt-bindings/clock/qcom,ipq9574-nsscc.h
-@@ -0,0 +1,152 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (c) 2023, 2025 The Linux Foundation. All rights reserved.
-+ */
-+
-+#ifndef _DT_BINDINGS_CLOCK_IPQ_NSSCC_9574_H
-+#define _DT_BINDINGS_CLOCK_IPQ_NSSCC_9574_H
-+
-+#define NSS_CC_CE_APB_CLK                                     0
-+#define NSS_CC_CE_AXI_CLK                                     1
-+#define NSS_CC_CE_CLK_SRC                                     2
-+#define NSS_CC_CFG_CLK_SRC                                    3
-+#define NSS_CC_CLC_AXI_CLK                                    4
-+#define NSS_CC_CLC_CLK_SRC                                    5
-+#define NSS_CC_CRYPTO_CLK                                     6
-+#define NSS_CC_CRYPTO_CLK_SRC                                 7
-+#define NSS_CC_CRYPTO_PPE_CLK                                 8
-+#define NSS_CC_HAQ_AHB_CLK                                    9
-+#define NSS_CC_HAQ_AXI_CLK                                    10
-+#define NSS_CC_HAQ_CLK_SRC                                    11
-+#define NSS_CC_IMEM_AHB_CLK                                   12
-+#define NSS_CC_IMEM_CLK_SRC                                   13
-+#define NSS_CC_IMEM_QSB_CLK                                   14
-+#define NSS_CC_INT_CFG_CLK_SRC                                        15
-+#define NSS_CC_NSS_CSR_CLK                                    16
-+#define NSS_CC_NSSNOC_CE_APB_CLK                              17
-+#define NSS_CC_NSSNOC_CE_AXI_CLK                              18
-+#define NSS_CC_NSSNOC_CLC_AXI_CLK                             19
-+#define NSS_CC_NSSNOC_CRYPTO_CLK                              20
-+#define NSS_CC_NSSNOC_HAQ_AHB_CLK                             21
-+#define NSS_CC_NSSNOC_HAQ_AXI_CLK                             22
-+#define NSS_CC_NSSNOC_IMEM_AHB_CLK                            23
-+#define NSS_CC_NSSNOC_IMEM_QSB_CLK                            24
-+#define NSS_CC_NSSNOC_NSS_CSR_CLK                             25
-+#define NSS_CC_NSSNOC_PPE_CFG_CLK                             26
-+#define NSS_CC_NSSNOC_PPE_CLK                                 27
-+#define NSS_CC_NSSNOC_UBI32_AHB0_CLK                          28
-+#define NSS_CC_NSSNOC_UBI32_AXI0_CLK                          29
-+#define NSS_CC_NSSNOC_UBI32_INT0_AHB_CLK                      30
-+#define NSS_CC_NSSNOC_UBI32_NC_AXI0_1_CLK                     31
-+#define NSS_CC_NSSNOC_UBI32_NC_AXI0_CLK                               32
-+#define NSS_CC_PORT1_MAC_CLK                                  33
-+#define NSS_CC_PORT1_RX_CLK                                   34
-+#define NSS_CC_PORT1_RX_CLK_SRC                                       35
-+#define NSS_CC_PORT1_RX_DIV_CLK_SRC                           36
-+#define NSS_CC_PORT1_TX_CLK                                   37
-+#define NSS_CC_PORT1_TX_CLK_SRC                                       38
-+#define NSS_CC_PORT1_TX_DIV_CLK_SRC                           39
-+#define NSS_CC_PORT2_MAC_CLK                                  40
-+#define NSS_CC_PORT2_RX_CLK                                   41
-+#define NSS_CC_PORT2_RX_CLK_SRC                                       42
-+#define NSS_CC_PORT2_RX_DIV_CLK_SRC                           43
-+#define NSS_CC_PORT2_TX_CLK                                   44
-+#define NSS_CC_PORT2_TX_CLK_SRC                                       45
-+#define NSS_CC_PORT2_TX_DIV_CLK_SRC                           46
-+#define NSS_CC_PORT3_MAC_CLK                                  47
-+#define NSS_CC_PORT3_RX_CLK                                   48
-+#define NSS_CC_PORT3_RX_CLK_SRC                                       49
-+#define NSS_CC_PORT3_RX_DIV_CLK_SRC                           50
-+#define NSS_CC_PORT3_TX_CLK                                   51
-+#define NSS_CC_PORT3_TX_CLK_SRC                                       52
-+#define NSS_CC_PORT3_TX_DIV_CLK_SRC                           53
-+#define NSS_CC_PORT4_MAC_CLK                                  54
-+#define NSS_CC_PORT4_RX_CLK                                   55
-+#define NSS_CC_PORT4_RX_CLK_SRC                                       56
-+#define NSS_CC_PORT4_RX_DIV_CLK_SRC                           57
-+#define NSS_CC_PORT4_TX_CLK                                   58
-+#define NSS_CC_PORT4_TX_CLK_SRC                                       59
-+#define NSS_CC_PORT4_TX_DIV_CLK_SRC                           60
-+#define NSS_CC_PORT5_MAC_CLK                                  61
-+#define NSS_CC_PORT5_RX_CLK                                   62
-+#define NSS_CC_PORT5_RX_CLK_SRC                                       63
-+#define NSS_CC_PORT5_RX_DIV_CLK_SRC                           64
-+#define NSS_CC_PORT5_TX_CLK                                   65
-+#define NSS_CC_PORT5_TX_CLK_SRC                                       66
-+#define NSS_CC_PORT5_TX_DIV_CLK_SRC                           67
-+#define NSS_CC_PORT6_MAC_CLK                                  68
-+#define NSS_CC_PORT6_RX_CLK                                   69
-+#define NSS_CC_PORT6_RX_CLK_SRC                                       70
-+#define NSS_CC_PORT6_RX_DIV_CLK_SRC                           71
-+#define NSS_CC_PORT6_TX_CLK                                   72
-+#define NSS_CC_PORT6_TX_CLK_SRC                                       73
-+#define NSS_CC_PORT6_TX_DIV_CLK_SRC                           74
-+#define NSS_CC_PPE_CLK_SRC                                    75
-+#define NSS_CC_PPE_EDMA_CFG_CLK                                       76
-+#define NSS_CC_PPE_EDMA_CLK                                   77
-+#define NSS_CC_PPE_SWITCH_BTQ_CLK                             78
-+#define NSS_CC_PPE_SWITCH_CFG_CLK                             79
-+#define NSS_CC_PPE_SWITCH_CLK                                 80
-+#define NSS_CC_PPE_SWITCH_IPE_CLK                             81
-+#define NSS_CC_UBI0_CLK_SRC                                   82
-+#define NSS_CC_UBI0_DIV_CLK_SRC                                       83
-+#define NSS_CC_UBI1_CLK_SRC                                   84
-+#define NSS_CC_UBI1_DIV_CLK_SRC                                       85
-+#define NSS_CC_UBI2_CLK_SRC                                   86
-+#define NSS_CC_UBI2_DIV_CLK_SRC                                       87
-+#define NSS_CC_UBI32_AHB0_CLK                                 88
-+#define NSS_CC_UBI32_AHB1_CLK                                 89
-+#define NSS_CC_UBI32_AHB2_CLK                                 90
-+#define NSS_CC_UBI32_AHB3_CLK                                 91
-+#define NSS_CC_UBI32_AXI0_CLK                                 92
-+#define NSS_CC_UBI32_AXI1_CLK                                 93
-+#define NSS_CC_UBI32_AXI2_CLK                                 94
-+#define NSS_CC_UBI32_AXI3_CLK                                 95
-+#define NSS_CC_UBI32_CORE0_CLK                                        96
-+#define NSS_CC_UBI32_CORE1_CLK                                        97
-+#define NSS_CC_UBI32_CORE2_CLK                                        98
-+#define NSS_CC_UBI32_CORE3_CLK                                        99
-+#define NSS_CC_UBI32_INTR0_AHB_CLK                            100
-+#define NSS_CC_UBI32_INTR1_AHB_CLK                            101
-+#define NSS_CC_UBI32_INTR2_AHB_CLK                            102
-+#define NSS_CC_UBI32_INTR3_AHB_CLK                            103
-+#define NSS_CC_UBI32_NC_AXI0_CLK                              104
-+#define NSS_CC_UBI32_NC_AXI1_CLK                              105
-+#define NSS_CC_UBI32_NC_AXI2_CLK                              106
-+#define NSS_CC_UBI32_NC_AXI3_CLK                              107
-+#define NSS_CC_UBI32_UTCM0_CLK                                        108
-+#define NSS_CC_UBI32_UTCM1_CLK                                        109
-+#define NSS_CC_UBI32_UTCM2_CLK                                        110
-+#define NSS_CC_UBI32_UTCM3_CLK                                        111
-+#define NSS_CC_UBI3_CLK_SRC                                   112
-+#define NSS_CC_UBI3_DIV_CLK_SRC                                       113
-+#define NSS_CC_UBI_AXI_CLK_SRC                                        114
-+#define NSS_CC_UBI_NC_AXI_BFDCD_CLK_SRC                               115
-+#define NSS_CC_UNIPHY_PORT1_RX_CLK                            116
-+#define NSS_CC_UNIPHY_PORT1_TX_CLK                            117
-+#define NSS_CC_UNIPHY_PORT2_RX_CLK                            118
-+#define NSS_CC_UNIPHY_PORT2_TX_CLK                            119
-+#define NSS_CC_UNIPHY_PORT3_RX_CLK                            120
-+#define NSS_CC_UNIPHY_PORT3_TX_CLK                            121
-+#define NSS_CC_UNIPHY_PORT4_RX_CLK                            122
-+#define NSS_CC_UNIPHY_PORT4_TX_CLK                            123
-+#define NSS_CC_UNIPHY_PORT5_RX_CLK                            124
-+#define NSS_CC_UNIPHY_PORT5_TX_CLK                            125
-+#define NSS_CC_UNIPHY_PORT6_RX_CLK                            126
-+#define NSS_CC_UNIPHY_PORT6_TX_CLK                            127
-+#define NSS_CC_XGMAC0_PTP_REF_CLK                             128
-+#define NSS_CC_XGMAC0_PTP_REF_DIV_CLK_SRC                     129
-+#define NSS_CC_XGMAC1_PTP_REF_CLK                             130
-+#define NSS_CC_XGMAC1_PTP_REF_DIV_CLK_SRC                     131
-+#define NSS_CC_XGMAC2_PTP_REF_CLK                             132
-+#define NSS_CC_XGMAC2_PTP_REF_DIV_CLK_SRC                     133
-+#define NSS_CC_XGMAC3_PTP_REF_CLK                             134
-+#define NSS_CC_XGMAC3_PTP_REF_DIV_CLK_SRC                     135
-+#define NSS_CC_XGMAC4_PTP_REF_CLK                             136
-+#define NSS_CC_XGMAC4_PTP_REF_DIV_CLK_SRC                     137
-+#define NSS_CC_XGMAC5_PTP_REF_CLK                             138
-+#define NSS_CC_XGMAC5_PTP_REF_DIV_CLK_SRC                     139
-+#define UBI32_PLL                                             140
-+#define UBI32_PLL_MAIN                                                141
-+
-+#endif
---- /dev/null
-+++ b/include/dt-bindings/reset/qcom,ipq9574-nsscc.h
-@@ -0,0 +1,134 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (c) 2023, 2025 The Linux Foundation. All rights reserved.
-+ */
-+
-+#ifndef _DT_BINDINGS_RESET_IPQ_NSSCC_9574_H
-+#define _DT_BINDINGS_RESET_IPQ_NSSCC_9574_H
-+
-+#define EDMA_HW_RESET                   0
-+#define NSS_CC_CE_BCR                 1
-+#define NSS_CC_CLC_BCR                        2
-+#define NSS_CC_EIP197_BCR             3
-+#define NSS_CC_HAQ_BCR                        4
-+#define NSS_CC_IMEM_BCR                       5
-+#define NSS_CC_MAC_BCR                        6
-+#define NSS_CC_PPE_BCR                        7
-+#define NSS_CC_UBI_BCR                        8
-+#define NSS_CC_UNIPHY_BCR             9
-+#define UBI3_CLKRST_CLAMP_ENABLE      10
-+#define UBI3_CORE_CLAMP_ENABLE                11
-+#define UBI2_CLKRST_CLAMP_ENABLE      12
-+#define UBI2_CORE_CLAMP_ENABLE                13
-+#define UBI1_CLKRST_CLAMP_ENABLE      14
-+#define UBI1_CORE_CLAMP_ENABLE                15
-+#define UBI0_CLKRST_CLAMP_ENABLE      16
-+#define UBI0_CORE_CLAMP_ENABLE                17
-+#define NSSNOC_NSS_CSR_ARES           18
-+#define NSS_CSR_ARES                  19
-+#define PPE_BTQ_ARES                  20
-+#define PPE_IPE_ARES                  21
-+#define PPE_ARES                      22
-+#define PPE_CFG_ARES                  23
-+#define PPE_EDMA_ARES                 24
-+#define PPE_EDMA_CFG_ARES             25
-+#define CRY_PPE_ARES                  26
-+#define NSSNOC_PPE_ARES                       27
-+#define NSSNOC_PPE_CFG_ARES           28
-+#define PORT1_MAC_ARES                        29
-+#define PORT2_MAC_ARES                        30
-+#define PORT3_MAC_ARES                        31
-+#define PORT4_MAC_ARES                        32
-+#define PORT5_MAC_ARES                        33
-+#define PORT6_MAC_ARES                        34
-+#define XGMAC0_PTP_REF_ARES           35
-+#define XGMAC1_PTP_REF_ARES           36
-+#define XGMAC2_PTP_REF_ARES           37
-+#define XGMAC3_PTP_REF_ARES           38
-+#define XGMAC4_PTP_REF_ARES           39
-+#define XGMAC5_PTP_REF_ARES           40
-+#define HAQ_AHB_ARES                  41
-+#define HAQ_AXI_ARES                  42
-+#define NSSNOC_HAQ_AHB_ARES           43
-+#define NSSNOC_HAQ_AXI_ARES           44
-+#define CE_APB_ARES                   45
-+#define CE_AXI_ARES                   46
-+#define NSSNOC_CE_APB_ARES            47
-+#define NSSNOC_CE_AXI_ARES            48
-+#define CRYPTO_ARES                   49
-+#define NSSNOC_CRYPTO_ARES            50
-+#define NSSNOC_NC_AXI0_1_ARES         51
-+#define UBI0_CORE_ARES                        52
-+#define UBI1_CORE_ARES                        53
-+#define UBI2_CORE_ARES                        54
-+#define UBI3_CORE_ARES                        55
-+#define NC_AXI0_ARES                  56
-+#define UTCM0_ARES                    57
-+#define NC_AXI1_ARES                  58
-+#define UTCM1_ARES                    59
-+#define NC_AXI2_ARES                  60
-+#define UTCM2_ARES                    61
-+#define NC_AXI3_ARES                  62
-+#define UTCM3_ARES                    63
-+#define NSSNOC_NC_AXI0_ARES           64
-+#define AHB0_ARES                     65
-+#define INTR0_AHB_ARES                        66
-+#define AHB1_ARES                     67
-+#define INTR1_AHB_ARES                        68
-+#define AHB2_ARES                     69
-+#define INTR2_AHB_ARES                        70
-+#define AHB3_ARES                     71
-+#define INTR3_AHB_ARES                        72
-+#define NSSNOC_AHB0_ARES              73
-+#define NSSNOC_INT0_AHB_ARES          74
-+#define AXI0_ARES                     75
-+#define AXI1_ARES                     76
-+#define AXI2_ARES                     77
-+#define AXI3_ARES                     78
-+#define NSSNOC_AXI0_ARES              79
-+#define IMEM_QSB_ARES                 80
-+#define NSSNOC_IMEM_QSB_ARES          81
-+#define IMEM_AHB_ARES                 82
-+#define NSSNOC_IMEM_AHB_ARES          83
-+#define UNIPHY_PORT1_RX_ARES          84
-+#define UNIPHY_PORT1_TX_ARES          85
-+#define UNIPHY_PORT2_RX_ARES          86
-+#define UNIPHY_PORT2_TX_ARES          87
-+#define UNIPHY_PORT3_RX_ARES          88
-+#define UNIPHY_PORT3_TX_ARES          89
-+#define UNIPHY_PORT4_RX_ARES          90
-+#define UNIPHY_PORT4_TX_ARES          91
-+#define UNIPHY_PORT5_RX_ARES          92
-+#define UNIPHY_PORT5_TX_ARES          93
-+#define UNIPHY_PORT6_RX_ARES          94
-+#define UNIPHY_PORT6_TX_ARES          95
-+#define PORT1_RX_ARES                 96
-+#define PORT1_TX_ARES                 97
-+#define PORT2_RX_ARES                 98
-+#define PORT2_TX_ARES                 99
-+#define PORT3_RX_ARES                 100
-+#define PORT3_TX_ARES                 101
-+#define PORT4_RX_ARES                 102
-+#define PORT4_TX_ARES                 103
-+#define PORT5_RX_ARES                 104
-+#define PORT5_TX_ARES                 105
-+#define PORT6_RX_ARES                 106
-+#define PORT6_TX_ARES                 107
-+#define PPE_FULL_RESET                        108
-+#define UNIPHY0_SOFT_RESET            109
-+#define UNIPHY1_SOFT_RESET            110
-+#define UNIPHY2_SOFT_RESET            111
-+#define UNIPHY_PORT1_ARES             112
-+#define UNIPHY_PORT2_ARES             113
-+#define UNIPHY_PORT3_ARES             114
-+#define UNIPHY_PORT4_ARES             115
-+#define UNIPHY_PORT5_ARES             116
-+#define UNIPHY_PORT6_ARES             117
-+#define NSSPORT1_RESET                        118
-+#define NSSPORT2_RESET                        119
-+#define NSSPORT3_RESET                        120
-+#define NSSPORT4_RESET                        121
-+#define NSSPORT5_RESET                        122
-+#define NSSPORT6_RESET                        123
-+
-+#endif
diff --git a/target/linux/qualcommbe/patches-6.12/0020-v6.15-clk-qcom-gcc-ipq9574-Add-support-for-gpll0_out.patch b/target/linux/qualcommbe/patches-6.12/0020-v6.15-clk-qcom-gcc-ipq9574-Add-support-for-gpll0_out.patch
deleted file mode 100644 (file)
index 357fb18..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-From c4e7d95921b074980ffd389254bcbfc045dd2a49 Mon Sep 17 00:00:00 2001
-From: Devi Priya <quic_devipriy@quicinc.com>
-Date: Thu, 13 Mar 2025 16:33:55 +0530
-Subject: [PATCH 20/22] v6.15: clk: qcom: gcc-ipq9574: Add support for
- gpll0_out_aux clock
-
-Add support for gpll0_out_aux clock which acts as the parent for
-certain networking subsystem (nss) clocks.
-
-Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
-Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
-Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
-Link: https://lore.kernel.org/r/20250313110359.242491-3-quic_mmanikan@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- drivers/clk/qcom/gcc-ipq9574.c | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/drivers/clk/qcom/gcc-ipq9574.c
-+++ b/drivers/clk/qcom/gcc-ipq9574.c
-@@ -108,6 +108,20 @@ static struct clk_alpha_pll_postdiv gpll
-       },
- };
-+static struct clk_alpha_pll_postdiv gpll0_out_aux = {
-+      .offset = 0x20000,
-+      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "gpll0_out_aux",
-+              .parent_hws = (const struct clk_hw *[]) {
-+                      &gpll0_main.clkr.hw
-+              },
-+              .num_parents = 1,
-+              .ops = &clk_alpha_pll_postdiv_ro_ops,
-+      },
-+};
-+
- static struct clk_alpha_pll gpll4_main = {
-       .offset = 0x22000,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
-@@ -4222,6 +4236,7 @@ static struct clk_regmap *gcc_ipq9574_cl
-       [GCC_PCIE1_PIPE_CLK] = &gcc_pcie1_pipe_clk.clkr,
-       [GCC_PCIE2_PIPE_CLK] = &gcc_pcie2_pipe_clk.clkr,
-       [GCC_PCIE3_PIPE_CLK] = &gcc_pcie3_pipe_clk.clkr,
-+      [GPLL0_OUT_AUX] = &gpll0_out_aux.clkr,
- };
- static const struct qcom_reset_map gcc_ipq9574_resets[] = {
diff --git a/target/linux/qualcommbe/patches-6.12/0021-v6.15-clk-qcom-Add-NSS-clock-Controller-driver-for-I.patch b/target/linux/qualcommbe/patches-6.12/0021-v6.15-clk-qcom-Add-NSS-clock-Controller-driver-for-I.patch
deleted file mode 100644 (file)
index e6d95f8..0000000
+++ /dev/null
@@ -1,3160 +0,0 @@
-From 8b42bea7cf2a21e854becf29760a947bef5cde0b Mon Sep 17 00:00:00 2001
-From: Devi Priya <quic_devipriy@quicinc.com>
-Date: Thu, 13 Mar 2025 16:33:57 +0530
-Subject: [PATCH 21/22] v6.15: clk: qcom: Add NSS clock Controller driver for
- IPQ9574
-
-Add Networking Sub System Clock Controller (NSSCC) driver for ipq9574 based
-devices.
-
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
-Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
-Link: https://lore.kernel.org/r/20250313110359.242491-5-quic_mmanikan@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- drivers/clk/qcom/Kconfig         |    7 +
- drivers/clk/qcom/Makefile        |    1 +
- drivers/clk/qcom/nsscc-ipq9574.c | 3110 ++++++++++++++++++++++++++++++
- 3 files changed, 3118 insertions(+)
- create mode 100644 drivers/clk/qcom/nsscc-ipq9574.c
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -264,6 +264,13 @@ config IPQ_GCC_9574
-         i2c, USB, SD/eMMC, etc. Select this for the root clock
-         of ipq9574.
-+config IPQ_NSSCC_9574
-+        tristate "IPQ9574 NSS Clock Controller"
-+        depends on ARM64 || COMPILE_TEST
-+        depends on IPQ_GCC_9574
-+        help
-+          Support for NSS clock controller on ipq9574 devices.
-+
- config IPQ_NSSCC_QCA8K
-       tristate "QCA8K(QCA8386 or QCA8084) NSS Clock Controller"
-       depends on MDIO_BUS
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -37,6 +37,7 @@ obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq601
- obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
- obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
- obj-$(CONFIG_IPQ_GCC_9574) += gcc-ipq9574.o
-+obj-$(CONFIG_IPQ_NSSCC_9574)  += nsscc-ipq9574.o
- obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
- obj-$(CONFIG_IPQ_NSSCC_QCA8K) += nsscc-qca8k.o
- obj-$(CONFIG_MDM_GCC_9607) += gcc-mdm9607.o
---- /dev/null
-+++ b/drivers/clk/qcom/nsscc-ipq9574.c
-@@ -0,0 +1,3110 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/err.h>
-+#include <linux/interconnect-provider.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_clock.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+
-+#include <dt-bindings/clock/qcom,ipq9574-nsscc.h>
-+#include <dt-bindings/interconnect/qcom,ipq9574.h>
-+#include <dt-bindings/reset/qcom,ipq9574-nsscc.h>
-+
-+#include "clk-alpha-pll.h"
-+#include "clk-branch.h"
-+#include "clk-pll.h"
-+#include "clk-rcg.h"
-+#include "clk-regmap.h"
-+#include "clk-regmap-divider.h"
-+#include "clk-regmap-mux.h"
-+#include "common.h"
-+#include "reset.h"
-+
-+/* Need to match the order of clocks in DT binding */
-+enum {
-+      DT_XO,
-+      DT_BIAS_PLL_CC_CLK,
-+      DT_BIAS_PLL_UBI_NC_CLK,
-+      DT_GCC_GPLL0_OUT_AUX,
-+      DT_UNIPHY0_NSS_RX_CLK,
-+      DT_UNIPHY0_NSS_TX_CLK,
-+      DT_UNIPHY1_NSS_RX_CLK,
-+      DT_UNIPHY1_NSS_TX_CLK,
-+      DT_UNIPHY2_NSS_RX_CLK,
-+      DT_UNIPHY2_NSS_TX_CLK,
-+};
-+
-+enum {
-+      P_XO,
-+      P_BIAS_PLL_CC_CLK,
-+      P_BIAS_PLL_UBI_NC_CLK,
-+      P_GCC_GPLL0_OUT_AUX,
-+      P_UBI32_PLL_OUT_MAIN,
-+      P_UNIPHY0_NSS_RX_CLK,
-+      P_UNIPHY0_NSS_TX_CLK,
-+      P_UNIPHY1_NSS_RX_CLK,
-+      P_UNIPHY1_NSS_TX_CLK,
-+      P_UNIPHY2_NSS_RX_CLK,
-+      P_UNIPHY2_NSS_TX_CLK,
-+};
-+
-+static const struct alpha_pll_config ubi32_pll_config = {
-+      .l = 0x3e,
-+      .alpha = 0x6666,
-+      .config_ctl_val = 0x200d4aa8,
-+      .config_ctl_hi_val = 0x3c,
-+      .main_output_mask = BIT(0),
-+      .aux_output_mask = BIT(1),
-+      .pre_div_val = 0x0,
-+      .pre_div_mask = BIT(12),
-+      .post_div_val = 0x0,
-+      .post_div_mask = GENMASK(9, 8),
-+      .alpha_en_mask = BIT(24),
-+      .test_ctl_val = 0x1c0000c0,
-+      .test_ctl_hi_val = 0x4000,
-+};
-+
-+static struct clk_alpha_pll ubi32_pll_main = {
-+      .offset = 0x28000,
-+      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_NSS_HUAYRA],
-+      .flags = SUPPORTS_DYNAMIC_UPDATE,
-+      .clkr = {
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "ubi32_pll_main",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .index = DT_XO,
-+                      },
-+                      .num_parents = 1,
-+                      .ops = &clk_alpha_pll_huayra_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_alpha_pll_postdiv ubi32_pll = {
-+      .offset = 0x28000,
-+      .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_NSS_HUAYRA],
-+      .width = 2,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "ubi32_pll",
-+              .parent_hws = (const struct clk_hw *[]) {
-+                      &ubi32_pll_main.clkr.hw
-+              },
-+              .num_parents = 1,
-+              .ops = &clk_alpha_pll_postdiv_ro_ops,
-+              .flags = CLK_SET_RATE_PARENT,
-+      },
-+};
-+
-+static const struct parent_map nss_cc_parent_map_0[] = {
-+      { P_XO, 0 },
-+      { P_BIAS_PLL_CC_CLK, 1 },
-+      { P_UNIPHY0_NSS_RX_CLK, 2 },
-+      { P_UNIPHY0_NSS_TX_CLK, 3 },
-+      { P_UNIPHY1_NSS_RX_CLK, 4 },
-+      { P_UNIPHY1_NSS_TX_CLK, 5 },
-+};
-+
-+static const struct clk_parent_data nss_cc_parent_data_0[] = {
-+      { .index = DT_XO },
-+      { .index = DT_BIAS_PLL_CC_CLK },
-+      { .index = DT_UNIPHY0_NSS_RX_CLK },
-+      { .index = DT_UNIPHY0_NSS_TX_CLK },
-+      { .index = DT_UNIPHY1_NSS_RX_CLK },
-+      { .index = DT_UNIPHY1_NSS_TX_CLK },
-+};
-+
-+static const struct parent_map nss_cc_parent_map_1[] = {
-+      { P_XO, 0 },
-+      { P_BIAS_PLL_UBI_NC_CLK, 1 },
-+      { P_GCC_GPLL0_OUT_AUX, 2 },
-+      { P_BIAS_PLL_CC_CLK, 6 },
-+};
-+
-+static const struct clk_parent_data nss_cc_parent_data_1[] = {
-+      { .index = DT_XO },
-+      { .index = DT_BIAS_PLL_UBI_NC_CLK },
-+      { .index = DT_GCC_GPLL0_OUT_AUX },
-+      { .index = DT_BIAS_PLL_CC_CLK },
-+};
-+
-+static const struct parent_map nss_cc_parent_map_2[] = {
-+      { P_XO, 0 },
-+      { P_UBI32_PLL_OUT_MAIN, 1 },
-+      { P_GCC_GPLL0_OUT_AUX, 2 },
-+};
-+
-+static const struct clk_parent_data nss_cc_parent_data_2[] = {
-+      { .index = DT_XO },
-+      { .hw = &ubi32_pll.clkr.hw },
-+      { .index = DT_GCC_GPLL0_OUT_AUX },
-+};
-+
-+static const struct parent_map nss_cc_parent_map_3[] = {
-+      { P_XO, 0 },
-+      { P_BIAS_PLL_CC_CLK, 1 },
-+      { P_GCC_GPLL0_OUT_AUX, 2 },
-+};
-+
-+static const struct clk_parent_data nss_cc_parent_data_3[] = {
-+      { .index = DT_XO },
-+      { .index = DT_BIAS_PLL_CC_CLK },
-+      { .index = DT_GCC_GPLL0_OUT_AUX },
-+};
-+
-+static const struct parent_map nss_cc_parent_map_4[] = {
-+      { P_XO, 0 },
-+      { P_BIAS_PLL_CC_CLK, 1 },
-+      { P_UNIPHY0_NSS_RX_CLK, 2 },
-+      { P_UNIPHY0_NSS_TX_CLK, 3 },
-+};
-+
-+static const struct clk_parent_data nss_cc_parent_data_4[] = {
-+      { .index = DT_XO },
-+      { .index = DT_BIAS_PLL_CC_CLK },
-+      { .index = DT_UNIPHY0_NSS_RX_CLK },
-+      { .index = DT_UNIPHY0_NSS_TX_CLK },
-+};
-+
-+static const struct parent_map nss_cc_parent_map_5[] = {
-+      { P_XO, 0 },
-+      { P_BIAS_PLL_CC_CLK, 1 },
-+      { P_UNIPHY2_NSS_RX_CLK, 2 },
-+      { P_UNIPHY2_NSS_TX_CLK, 3 },
-+};
-+
-+static const struct clk_parent_data nss_cc_parent_data_5[] = {
-+      { .index = DT_XO },
-+      { .index = DT_BIAS_PLL_CC_CLK },
-+      { .index = DT_UNIPHY2_NSS_RX_CLK },
-+      { .index = DT_UNIPHY2_NSS_TX_CLK },
-+};
-+
-+static const struct parent_map nss_cc_parent_map_6[] = {
-+      { P_XO, 0 },
-+      { P_GCC_GPLL0_OUT_AUX, 2 },
-+      { P_BIAS_PLL_CC_CLK, 6 },
-+};
-+
-+static const struct clk_parent_data nss_cc_parent_data_6[] = {
-+      { .index = DT_XO },
-+      { .index = DT_GCC_GPLL0_OUT_AUX },
-+      { .index = DT_BIAS_PLL_CC_CLK },
-+};
-+
-+static const struct parent_map nss_cc_parent_map_7[] = {
-+      { P_XO, 0 },
-+      { P_UBI32_PLL_OUT_MAIN, 1 },
-+      { P_GCC_GPLL0_OUT_AUX, 2 },
-+      { P_BIAS_PLL_CC_CLK, 6 },
-+};
-+
-+static const struct clk_parent_data nss_cc_parent_data_7[] = {
-+      { .index = DT_XO },
-+      { .hw = &ubi32_pll.clkr.hw },
-+      { .index = DT_GCC_GPLL0_OUT_AUX },
-+      { .index = DT_BIAS_PLL_CC_CLK },
-+};
-+
-+static const struct freq_tbl ftbl_nss_cc_ce_clk_src[] = {
-+      F(24000000, P_XO, 1, 0, 0),
-+      F(353000000, P_BIAS_PLL_UBI_NC_CLK, 1, 0, 0),
-+      { }
-+};
-+
-+static struct clk_rcg2 nss_cc_ce_clk_src = {
-+      .cmd_rcgr = 0x28404,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_1,
-+      .freq_tbl = ftbl_nss_cc_ce_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ce_clk_src",
-+              .parent_data = nss_cc_parent_data_1,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_1),
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static const struct freq_tbl ftbl_nss_cc_cfg_clk_src[] = {
-+      F(100000000, P_GCC_GPLL0_OUT_AUX, 8, 0, 0),
-+      { }
-+};
-+
-+static struct clk_rcg2 nss_cc_cfg_clk_src = {
-+      .cmd_rcgr = 0x28104,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_3,
-+      .freq_tbl = ftbl_nss_cc_cfg_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_cfg_clk_src",
-+              .parent_data = nss_cc_parent_data_3,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_3),
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static const struct freq_tbl ftbl_nss_cc_clc_clk_src[] = {
-+      F(533333333, P_GCC_GPLL0_OUT_AUX, 1.5, 0, 0),
-+      { }
-+};
-+
-+static struct clk_rcg2 nss_cc_clc_clk_src = {
-+      .cmd_rcgr = 0x28604,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_6,
-+      .freq_tbl = ftbl_nss_cc_clc_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_clc_clk_src",
-+              .parent_data = nss_cc_parent_data_6,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_6),
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static const struct freq_tbl ftbl_nss_cc_crypto_clk_src[] = {
-+      F(24000000, P_XO, 1, 0, 0),
-+      F(300000000, P_BIAS_PLL_CC_CLK, 4, 0, 0),
-+      F(600000000, P_BIAS_PLL_CC_CLK, 2, 0, 0),
-+      { }
-+};
-+
-+static struct clk_rcg2 nss_cc_crypto_clk_src = {
-+      .cmd_rcgr = 0x16008,
-+      .mnd_width = 16,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_3,
-+      .freq_tbl = ftbl_nss_cc_crypto_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_crypto_clk_src",
-+              .parent_data = nss_cc_parent_data_3,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_3),
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_haq_clk_src = {
-+      .cmd_rcgr = 0x28304,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_1,
-+      .freq_tbl = ftbl_nss_cc_ce_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_haq_clk_src",
-+              .parent_data = nss_cc_parent_data_1,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_1),
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_imem_clk_src = {
-+      .cmd_rcgr = 0xe008,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_1,
-+      .freq_tbl = ftbl_nss_cc_ce_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_imem_clk_src",
-+              .parent_data = nss_cc_parent_data_1,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_1),
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static const struct freq_tbl ftbl_nss_cc_int_cfg_clk_src[] = {
-+      F(200000000, P_GCC_GPLL0_OUT_AUX, 4, 0, 0),
-+      { }
-+};
-+
-+static struct clk_rcg2 nss_cc_int_cfg_clk_src = {
-+      .cmd_rcgr = 0x287b4,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_3,
-+      .freq_tbl = ftbl_nss_cc_int_cfg_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_int_cfg_clk_src",
-+              .parent_data = nss_cc_parent_data_3,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_3),
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port1_rx_clk_src_25[] = {
-+      C(P_UNIPHY0_NSS_RX_CLK, 12.5, 0, 0),
-+      C(P_UNIPHY0_NSS_RX_CLK, 5, 0, 0),
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port1_rx_clk_src_125[] = {
-+      C(P_UNIPHY0_NSS_RX_CLK, 2.5, 0, 0),
-+      C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0),
-+};
-+
-+static const struct freq_multi_tbl ftbl_nss_cc_port1_rx_clk_src[] = {
-+      FMS(24000000, P_XO, 1, 0, 0),
-+      FM(25000000, ftbl_nss_cc_port1_rx_clk_src_25),
-+      FMS(78125000, P_UNIPHY0_NSS_RX_CLK, 4, 0, 0),
-+      FM(125000000, ftbl_nss_cc_port1_rx_clk_src_125),
-+      FMS(312500000, P_UNIPHY0_NSS_RX_CLK, 1, 0, 0),
-+      { }
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port1_tx_clk_src_25[] = {
-+      C(P_UNIPHY0_NSS_TX_CLK, 12.5, 0, 0),
-+      C(P_UNIPHY0_NSS_TX_CLK, 5, 0, 0),
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port1_tx_clk_src_125[] = {
-+      C(P_UNIPHY0_NSS_TX_CLK, 2.5, 0, 0),
-+      C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0),
-+};
-+
-+static const struct freq_multi_tbl ftbl_nss_cc_port1_tx_clk_src[] = {
-+      FMS(24000000, P_XO, 1, 0, 0),
-+      FM(25000000, ftbl_nss_cc_port1_tx_clk_src_25),
-+      FMS(78125000, P_UNIPHY0_NSS_TX_CLK, 4, 0, 0),
-+      FM(125000000, ftbl_nss_cc_port1_tx_clk_src_125),
-+      FMS(312500000, P_UNIPHY0_NSS_TX_CLK, 1, 0, 0),
-+      { }
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_25[] = {
-+      C(P_UNIPHY1_NSS_RX_CLK, 12.5, 0, 0),
-+      C(P_UNIPHY0_NSS_RX_CLK, 5, 0, 0),
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_125[] = {
-+      C(P_UNIPHY1_NSS_RX_CLK, 2.5, 0, 0),
-+      C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0),
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_312p5[] = {
-+      C(P_UNIPHY1_NSS_RX_CLK, 1, 0, 0),
-+      C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0),
-+};
-+
-+static const struct freq_multi_tbl ftbl_nss_cc_port5_rx_clk_src[] = {
-+      FMS(24000000, P_XO, 1, 0, 0),
-+      FM(25000000, ftbl_nss_cc_port5_rx_clk_src_25),
-+      FMS(78125000, P_UNIPHY1_NSS_RX_CLK, 4, 0, 0),
-+      FM(125000000, ftbl_nss_cc_port5_rx_clk_src_125),
-+      FMS(156250000, P_UNIPHY1_NSS_RX_CLK, 2, 0, 0),
-+      FM(312500000, ftbl_nss_cc_port5_rx_clk_src_312p5),
-+      { }
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_25[] = {
-+      C(P_UNIPHY1_NSS_TX_CLK, 12.5, 0, 0),
-+      C(P_UNIPHY0_NSS_TX_CLK, 5, 0, 0),
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_125[] = {
-+      C(P_UNIPHY1_NSS_TX_CLK, 2.5, 0, 0),
-+      C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0),
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_312p5[] = {
-+      C(P_UNIPHY1_NSS_TX_CLK, 1, 0, 0),
-+      C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0),
-+};
-+
-+static const struct freq_multi_tbl ftbl_nss_cc_port5_tx_clk_src[] = {
-+      FMS(24000000, P_XO, 1, 0, 0),
-+      FM(25000000, ftbl_nss_cc_port5_tx_clk_src_25),
-+      FMS(78125000, P_UNIPHY1_NSS_TX_CLK, 4, 0, 0),
-+      FM(125000000, ftbl_nss_cc_port5_tx_clk_src_125),
-+      FMS(156250000, P_UNIPHY1_NSS_TX_CLK, 2, 0, 0),
-+      FM(312500000, ftbl_nss_cc_port5_tx_clk_src_312p5),
-+      { }
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port6_rx_clk_src_25[] = {
-+      C(P_UNIPHY2_NSS_RX_CLK, 12.5, 0, 0),
-+      C(P_UNIPHY2_NSS_RX_CLK, 5, 0, 0),
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port6_rx_clk_src_125[] = {
-+      C(P_UNIPHY2_NSS_RX_CLK, 2.5, 0, 0),
-+      C(P_UNIPHY2_NSS_RX_CLK, 1, 0, 0),
-+};
-+
-+static const struct freq_multi_tbl ftbl_nss_cc_port6_rx_clk_src[] = {
-+      FMS(24000000, P_XO, 1, 0, 0),
-+      FM(25000000, ftbl_nss_cc_port6_rx_clk_src_25),
-+      FMS(78125000, P_UNIPHY2_NSS_RX_CLK, 4, 0, 0),
-+      FM(125000000, ftbl_nss_cc_port6_rx_clk_src_125),
-+      FMS(156250000, P_UNIPHY2_NSS_RX_CLK, 2, 0, 0),
-+      FMS(312500000, P_UNIPHY2_NSS_RX_CLK, 1, 0, 0),
-+      { }
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port6_tx_clk_src_25[] = {
-+      C(P_UNIPHY2_NSS_TX_CLK, 12.5, 0, 0),
-+      C(P_UNIPHY2_NSS_TX_CLK, 5, 0, 0),
-+};
-+
-+static const struct freq_conf ftbl_nss_cc_port6_tx_clk_src_125[] = {
-+      C(P_UNIPHY2_NSS_TX_CLK, 2.5, 0, 0),
-+      C(P_UNIPHY2_NSS_TX_CLK, 1, 0, 0),
-+};
-+
-+static const struct freq_multi_tbl ftbl_nss_cc_port6_tx_clk_src[] = {
-+      FMS(24000000, P_XO, 1, 0, 0),
-+      FM(25000000, ftbl_nss_cc_port6_tx_clk_src_25),
-+      FMS(78125000, P_UNIPHY2_NSS_TX_CLK, 4, 0, 0),
-+      FM(125000000, ftbl_nss_cc_port6_tx_clk_src_125),
-+      FMS(156250000, P_UNIPHY2_NSS_TX_CLK, 2, 0, 0),
-+      FMS(312500000, P_UNIPHY2_NSS_TX_CLK, 1, 0, 0),
-+      { }
-+};
-+
-+static struct clk_rcg2 nss_cc_port1_rx_clk_src = {
-+      .cmd_rcgr = 0x28110,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_4,
-+      .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port1_rx_clk_src",
-+              .parent_data = nss_cc_parent_data_4,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_4),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port1_tx_clk_src = {
-+      .cmd_rcgr = 0x2811c,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_4,
-+      .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port1_tx_clk_src",
-+              .parent_data = nss_cc_parent_data_4,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_4),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port2_rx_clk_src = {
-+      .cmd_rcgr = 0x28128,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_4,
-+      .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port2_rx_clk_src",
-+              .parent_data = nss_cc_parent_data_4,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_4),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port2_tx_clk_src = {
-+      .cmd_rcgr = 0x28134,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_4,
-+      .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port2_tx_clk_src",
-+              .parent_data = nss_cc_parent_data_4,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_4),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port3_rx_clk_src = {
-+      .cmd_rcgr = 0x28140,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_4,
-+      .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port3_rx_clk_src",
-+              .parent_data = nss_cc_parent_data_4,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_4),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port3_tx_clk_src = {
-+      .cmd_rcgr = 0x2814c,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_4,
-+      .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port3_tx_clk_src",
-+              .parent_data = nss_cc_parent_data_4,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_4),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port4_rx_clk_src = {
-+      .cmd_rcgr = 0x28158,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_4,
-+      .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port4_rx_clk_src",
-+              .parent_data = nss_cc_parent_data_4,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_4),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port4_tx_clk_src = {
-+      .cmd_rcgr = 0x28164,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_4,
-+      .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port4_tx_clk_src",
-+              .parent_data = nss_cc_parent_data_4,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_4),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port5_rx_clk_src = {
-+      .cmd_rcgr = 0x28170,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_0,
-+      .freq_multi_tbl = ftbl_nss_cc_port5_rx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port5_rx_clk_src",
-+              .parent_data = nss_cc_parent_data_0,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_0),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port5_tx_clk_src = {
-+      .cmd_rcgr = 0x2817c,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_0,
-+      .freq_multi_tbl = ftbl_nss_cc_port5_tx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port5_tx_clk_src",
-+              .parent_data = nss_cc_parent_data_0,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_0),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port6_rx_clk_src = {
-+      .cmd_rcgr = 0x28188,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_5,
-+      .freq_multi_tbl = ftbl_nss_cc_port6_rx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port6_rx_clk_src",
-+              .parent_data = nss_cc_parent_data_5,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_5),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_port6_tx_clk_src = {
-+      .cmd_rcgr = 0x28194,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_5,
-+      .freq_multi_tbl = ftbl_nss_cc_port6_tx_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port6_tx_clk_src",
-+              .parent_data = nss_cc_parent_data_5,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_5),
-+              .ops = &clk_rcg2_fm_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_ppe_clk_src = {
-+      .cmd_rcgr = 0x28204,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_1,
-+      .freq_tbl = ftbl_nss_cc_ce_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ppe_clk_src",
-+              .parent_data = nss_cc_parent_data_1,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_1),
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static const struct freq_tbl ftbl_nss_cc_ubi0_clk_src[] = {
-+      F(24000000, P_XO, 1, 0, 0),
-+      F(187200000, P_UBI32_PLL_OUT_MAIN, 8, 0, 0),
-+      F(748800000, P_UBI32_PLL_OUT_MAIN, 2, 0, 0),
-+      F(1497600000, P_UBI32_PLL_OUT_MAIN, 1, 0, 0),
-+      F(1689600000, P_UBI32_PLL_OUT_MAIN, 1, 0, 0),
-+      { }
-+};
-+
-+static struct clk_rcg2 nss_cc_ubi0_clk_src = {
-+      .cmd_rcgr = 0x28704,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_2,
-+      .freq_tbl = ftbl_nss_cc_ubi0_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi0_clk_src",
-+              .parent_data = nss_cc_parent_data_2,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_2),
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_ubi1_clk_src = {
-+      .cmd_rcgr = 0x2870c,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_2,
-+      .freq_tbl = ftbl_nss_cc_ubi0_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi1_clk_src",
-+              .parent_data = nss_cc_parent_data_2,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_2),
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_ubi2_clk_src = {
-+      .cmd_rcgr = 0x28714,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_2,
-+      .freq_tbl = ftbl_nss_cc_ubi0_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi2_clk_src",
-+              .parent_data = nss_cc_parent_data_2,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_2),
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_ubi3_clk_src = {
-+      .cmd_rcgr = 0x2871c,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_2,
-+      .freq_tbl = ftbl_nss_cc_ubi0_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi3_clk_src",
-+              .parent_data = nss_cc_parent_data_2,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_2),
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_ubi_axi_clk_src = {
-+      .cmd_rcgr = 0x28724,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_7,
-+      .freq_tbl = ftbl_nss_cc_clc_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi_axi_clk_src",
-+              .parent_data = nss_cc_parent_data_7,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_7),
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static struct clk_rcg2 nss_cc_ubi_nc_axi_bfdcd_clk_src = {
-+      .cmd_rcgr = 0x2872c,
-+      .mnd_width = 0,
-+      .hid_width = 5,
-+      .parent_map = nss_cc_parent_map_1,
-+      .freq_tbl = ftbl_nss_cc_ce_clk_src,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi_nc_axi_bfdcd_clk_src",
-+              .parent_data = nss_cc_parent_data_1,
-+              .num_parents = ARRAY_SIZE(nss_cc_parent_data_1),
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_rcg2_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port1_rx_div_clk_src = {
-+      .reg = 0x28118,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port1_rx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port1_rx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port1_tx_div_clk_src = {
-+      .reg = 0x28124,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port1_tx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port1_tx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port2_rx_div_clk_src = {
-+      .reg = 0x28130,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port2_rx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port2_rx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port2_tx_div_clk_src = {
-+      .reg = 0x2813c,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port2_tx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port2_tx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port3_rx_div_clk_src = {
-+      .reg = 0x28148,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port3_rx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port3_rx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port3_tx_div_clk_src = {
-+      .reg = 0x28154,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port3_tx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port3_tx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port4_rx_div_clk_src = {
-+      .reg = 0x28160,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port4_rx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port4_rx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port4_tx_div_clk_src = {
-+      .reg = 0x2816c,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port4_tx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port4_tx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port5_rx_div_clk_src = {
-+      .reg = 0x28178,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port5_rx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port5_rx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port5_tx_div_clk_src = {
-+      .reg = 0x28184,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port5_tx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port5_tx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port6_rx_div_clk_src = {
-+      .reg = 0x28190,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port6_rx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port6_rx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_port6_tx_div_clk_src = {
-+      .reg = 0x2819c,
-+      .shift = 0,
-+      .width = 9,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_port6_tx_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_port6_tx_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_ubi0_div_clk_src = {
-+      .reg = 0x287a4,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi0_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ubi0_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_ubi1_div_clk_src = {
-+      .reg = 0x287a8,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi1_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ubi1_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_ubi2_div_clk_src = {
-+      .reg = 0x287ac,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi2_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ubi2_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_ubi3_div_clk_src = {
-+      .reg = 0x287b0,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_ubi3_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ubi3_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_xgmac0_ptp_ref_div_clk_src = {
-+      .reg = 0x28214,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_xgmac0_ptp_ref_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_xgmac1_ptp_ref_div_clk_src = {
-+      .reg = 0x28218,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_xgmac1_ptp_ref_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_xgmac2_ptp_ref_div_clk_src = {
-+      .reg = 0x2821c,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_xgmac2_ptp_ref_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_xgmac3_ptp_ref_div_clk_src = {
-+      .reg = 0x28220,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_xgmac3_ptp_ref_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_xgmac4_ptp_ref_div_clk_src = {
-+      .reg = 0x28224,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_xgmac4_ptp_ref_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_regmap_div nss_cc_xgmac5_ptp_ref_div_clk_src = {
-+      .reg = 0x28228,
-+      .shift = 0,
-+      .width = 4,
-+      .clkr.hw.init = &(const struct clk_init_data) {
-+              .name = "nss_cc_xgmac5_ptp_ref_div_clk_src",
-+              .parent_data = &(const struct clk_parent_data) {
-+                      .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+              },
-+              .num_parents = 1,
-+              .flags = CLK_SET_RATE_PARENT,
-+              .ops = &clk_regmap_div_ro_ops,
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ce_apb_clk = {
-+      .halt_reg = 0x2840c,
-+      .clkr = {
-+              .enable_reg = 0x2840c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ce_apb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ce_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ce_axi_clk = {
-+      .halt_reg = 0x28410,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28410,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ce_axi_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ce_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_clc_axi_clk = {
-+      .halt_reg = 0x2860c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2860c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_clc_axi_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_clc_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_crypto_clk = {
-+      .halt_reg = 0x1601c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x1601c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_crypto_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_crypto_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_crypto_ppe_clk = {
-+      .halt_reg = 0x28240,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28240,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_crypto_ppe_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_haq_ahb_clk = {
-+      .halt_reg = 0x2830c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2830c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_haq_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_haq_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_haq_axi_clk = {
-+      .halt_reg = 0x28310,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28310,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_haq_axi_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_haq_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_imem_ahb_clk = {
-+      .halt_reg = 0xe018,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0xe018,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_imem_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_imem_qsb_clk = {
-+      .halt_reg = 0xe010,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0xe010,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_imem_qsb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_imem_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nss_csr_clk = {
-+      .halt_reg = 0x281d0,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281d0,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nss_csr_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ce_apb_clk = {
-+      .halt_reg = 0x28414,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28414,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ce_apb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ce_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ce_axi_clk = {
-+      .halt_reg = 0x28418,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28418,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ce_axi_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ce_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_clc_axi_clk = {
-+      .halt_reg = 0x28610,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28610,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_clc_axi_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_clc_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_crypto_clk = {
-+      .halt_reg = 0x16020,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x16020,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_crypto_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_crypto_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_haq_ahb_clk = {
-+      .halt_reg = 0x28314,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28314,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_haq_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_haq_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_haq_axi_clk = {
-+      .halt_reg = 0x28318,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28318,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_haq_axi_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_haq_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_imem_ahb_clk = {
-+      .halt_reg = 0xe01c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0xe01c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_imem_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_imem_qsb_clk = {
-+      .halt_reg = 0xe014,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0xe014,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_imem_qsb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_imem_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_nss_csr_clk = {
-+      .halt_reg = 0x281d4,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281d4,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_nss_csr_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ppe_cfg_clk = {
-+      .halt_reg = 0x28248,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28248,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ppe_cfg_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ppe_clk = {
-+      .halt_reg = 0x28244,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28244,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ppe_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ubi32_ahb0_clk = {
-+      .halt_reg = 0x28788,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28788,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ubi32_ahb0_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ubi32_axi0_clk = {
-+      .halt_reg = 0x287a0,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x287a0,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ubi32_axi0_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_axi_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ubi32_int0_ahb_clk = {
-+      .halt_reg = 0x2878c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2878c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ubi32_int0_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_int_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ubi32_nc_axi0_1_clk = {
-+      .halt_reg = 0x287bc,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x287bc,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ubi32_nc_axi0_1_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_nssnoc_ubi32_nc_axi0_clk = {
-+      .halt_reg = 0x28764,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28764,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_nssnoc_ubi32_nc_axi0_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port1_mac_clk = {
-+      .halt_reg = 0x2824c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2824c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port1_mac_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port1_rx_clk = {
-+      .halt_reg = 0x281a0,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281a0,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port1_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port1_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port1_tx_clk = {
-+      .halt_reg = 0x281a4,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281a4,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port1_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port1_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port2_mac_clk = {
-+      .halt_reg = 0x28250,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28250,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port2_mac_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port2_rx_clk = {
-+      .halt_reg = 0x281a8,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281a8,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port2_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port2_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port2_tx_clk = {
-+      .halt_reg = 0x281ac,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281ac,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port2_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port2_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port3_mac_clk = {
-+      .halt_reg = 0x28254,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28254,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port3_mac_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port3_rx_clk = {
-+      .halt_reg = 0x281b0,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281b0,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port3_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port3_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port3_tx_clk = {
-+      .halt_reg = 0x281b4,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281b4,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port3_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port3_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port4_mac_clk = {
-+      .halt_reg = 0x28258,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28258,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port4_mac_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port4_rx_clk = {
-+      .halt_reg = 0x281b8,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281b8,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port4_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port4_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port4_tx_clk = {
-+      .halt_reg = 0x281bc,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281bc,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port4_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port4_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port5_mac_clk = {
-+      .halt_reg = 0x2825c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2825c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port5_mac_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port5_rx_clk = {
-+      .halt_reg = 0x281c0,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281c0,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port5_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port5_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port5_tx_clk = {
-+      .halt_reg = 0x281c4,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281c4,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port5_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port5_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port6_mac_clk = {
-+      .halt_reg = 0x28260,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28260,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port6_mac_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port6_rx_clk = {
-+      .halt_reg = 0x281c8,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281c8,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port6_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port6_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_port6_tx_clk = {
-+      .halt_reg = 0x281cc,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x281cc,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_port6_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port6_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ppe_edma_cfg_clk = {
-+      .halt_reg = 0x2823c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2823c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ppe_edma_cfg_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ppe_edma_clk = {
-+      .halt_reg = 0x28238,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28238,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ppe_edma_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ppe_switch_btq_clk = {
-+      .halt_reg = 0x2827c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2827c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ppe_switch_btq_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ppe_switch_cfg_clk = {
-+      .halt_reg = 0x28234,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28234,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ppe_switch_cfg_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ppe_switch_clk = {
-+      .halt_reg = 0x28230,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28230,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ppe_switch_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ppe_switch_ipe_clk = {
-+      .halt_reg = 0x2822c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2822c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ppe_switch_ipe_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ppe_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_ahb0_clk = {
-+      .halt_reg = 0x28768,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28768,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_ahb0_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_ahb1_clk = {
-+      .halt_reg = 0x28770,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28770,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_ahb1_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_ahb2_clk = {
-+      .halt_reg = 0x28778,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28778,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_ahb2_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_ahb3_clk = {
-+      .halt_reg = 0x28780,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28780,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_ahb3_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_axi0_clk = {
-+      .halt_reg = 0x28790,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28790,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_axi0_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_axi_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_axi1_clk = {
-+      .halt_reg = 0x28794,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28794,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_axi1_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_axi_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_axi2_clk = {
-+      .halt_reg = 0x28798,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28798,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_axi2_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_axi_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_axi3_clk = {
-+      .halt_reg = 0x2879c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2879c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_axi3_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_axi_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_core0_clk = {
-+      .halt_reg = 0x28734,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28734,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_core0_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi0_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_core1_clk = {
-+      .halt_reg = 0x28738,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28738,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_core1_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi1_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_core2_clk = {
-+      .halt_reg = 0x2873c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2873c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_core2_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi2_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_core3_clk = {
-+      .halt_reg = 0x28740,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28740,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_core3_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi3_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_intr0_ahb_clk = {
-+      .halt_reg = 0x2876c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2876c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_intr0_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_int_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_intr1_ahb_clk = {
-+      .halt_reg = 0x28774,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28774,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_intr1_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_int_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_intr2_ahb_clk = {
-+      .halt_reg = 0x2877c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2877c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_intr2_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_int_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_intr3_ahb_clk = {
-+      .halt_reg = 0x28784,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28784,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_intr3_ahb_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_int_cfg_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_nc_axi0_clk = {
-+      .halt_reg = 0x28744,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28744,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_nc_axi0_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_nc_axi1_clk = {
-+      .halt_reg = 0x2874c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2874c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_nc_axi1_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_nc_axi2_clk = {
-+      .halt_reg = 0x28754,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28754,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_nc_axi2_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_nc_axi3_clk = {
-+      .halt_reg = 0x2875c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2875c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_nc_axi3_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_utcm0_clk = {
-+      .halt_reg = 0x28748,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28748,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_utcm0_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_utcm1_clk = {
-+      .halt_reg = 0x28750,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28750,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_utcm1_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_utcm2_clk = {
-+      .halt_reg = 0x28758,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28758,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_utcm2_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_ubi32_utcm3_clk = {
-+      .halt_reg = 0x28760,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28760,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_ubi32_utcm3_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port1_rx_clk = {
-+      .halt_reg = 0x28904,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28904,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port1_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port1_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port1_tx_clk = {
-+      .halt_reg = 0x28908,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28908,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port1_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port1_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port2_rx_clk = {
-+      .halt_reg = 0x2890c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2890c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port2_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port2_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port2_tx_clk = {
-+      .halt_reg = 0x28910,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28910,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port2_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port2_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port3_rx_clk = {
-+      .halt_reg = 0x28914,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28914,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port3_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port3_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port3_tx_clk = {
-+      .halt_reg = 0x28918,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28918,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port3_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port3_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port4_rx_clk = {
-+      .halt_reg = 0x2891c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2891c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port4_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port4_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port4_tx_clk = {
-+      .halt_reg = 0x28920,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28920,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port4_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port4_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port5_rx_clk = {
-+      .halt_reg = 0x28924,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28924,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port5_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port5_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port5_tx_clk = {
-+      .halt_reg = 0x28928,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28928,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port5_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port5_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port6_rx_clk = {
-+      .halt_reg = 0x2892c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2892c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port6_rx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port6_rx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_uniphy_port6_tx_clk = {
-+      .halt_reg = 0x28930,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28930,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_uniphy_port6_tx_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_port6_tx_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_xgmac0_ptp_ref_clk = {
-+      .halt_reg = 0x28264,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28264,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_xgmac0_ptp_ref_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_xgmac0_ptp_ref_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_xgmac1_ptp_ref_clk = {
-+      .halt_reg = 0x28268,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28268,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_xgmac1_ptp_ref_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_xgmac1_ptp_ref_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_xgmac2_ptp_ref_clk = {
-+      .halt_reg = 0x2826c,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x2826c,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_xgmac2_ptp_ref_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_xgmac2_ptp_ref_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_xgmac3_ptp_ref_clk = {
-+      .halt_reg = 0x28270,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28270,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_xgmac3_ptp_ref_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_xgmac3_ptp_ref_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_xgmac4_ptp_ref_clk = {
-+      .halt_reg = 0x28274,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28274,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_xgmac4_ptp_ref_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_xgmac4_ptp_ref_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_branch nss_cc_xgmac5_ptp_ref_clk = {
-+      .halt_reg = 0x28278,
-+      .halt_check = BRANCH_HALT,
-+      .clkr = {
-+              .enable_reg = 0x28278,
-+              .enable_mask = BIT(0),
-+              .hw.init = &(const struct clk_init_data) {
-+                      .name = "nss_cc_xgmac5_ptp_ref_clk",
-+                      .parent_data = &(const struct clk_parent_data) {
-+                              .hw = &nss_cc_xgmac5_ptp_ref_div_clk_src.clkr.hw,
-+                      },
-+                      .num_parents = 1,
-+                      .flags = CLK_SET_RATE_PARENT,
-+                      .ops = &clk_branch2_ops,
-+              },
-+      },
-+};
-+
-+static struct clk_regmap *nss_cc_ipq9574_clocks[] = {
-+      [NSS_CC_CE_APB_CLK] = &nss_cc_ce_apb_clk.clkr,
-+      [NSS_CC_CE_AXI_CLK] = &nss_cc_ce_axi_clk.clkr,
-+      [NSS_CC_CE_CLK_SRC] = &nss_cc_ce_clk_src.clkr,
-+      [NSS_CC_CFG_CLK_SRC] = &nss_cc_cfg_clk_src.clkr,
-+      [NSS_CC_CLC_AXI_CLK] = &nss_cc_clc_axi_clk.clkr,
-+      [NSS_CC_CLC_CLK_SRC] = &nss_cc_clc_clk_src.clkr,
-+      [NSS_CC_CRYPTO_CLK] = &nss_cc_crypto_clk.clkr,
-+      [NSS_CC_CRYPTO_CLK_SRC] = &nss_cc_crypto_clk_src.clkr,
-+      [NSS_CC_CRYPTO_PPE_CLK] = &nss_cc_crypto_ppe_clk.clkr,
-+      [NSS_CC_HAQ_AHB_CLK] = &nss_cc_haq_ahb_clk.clkr,
-+      [NSS_CC_HAQ_AXI_CLK] = &nss_cc_haq_axi_clk.clkr,
-+      [NSS_CC_HAQ_CLK_SRC] = &nss_cc_haq_clk_src.clkr,
-+      [NSS_CC_IMEM_AHB_CLK] = &nss_cc_imem_ahb_clk.clkr,
-+      [NSS_CC_IMEM_CLK_SRC] = &nss_cc_imem_clk_src.clkr,
-+      [NSS_CC_IMEM_QSB_CLK] = &nss_cc_imem_qsb_clk.clkr,
-+      [NSS_CC_INT_CFG_CLK_SRC] = &nss_cc_int_cfg_clk_src.clkr,
-+      [NSS_CC_NSS_CSR_CLK] = &nss_cc_nss_csr_clk.clkr,
-+      [NSS_CC_NSSNOC_CE_APB_CLK] = &nss_cc_nssnoc_ce_apb_clk.clkr,
-+      [NSS_CC_NSSNOC_CE_AXI_CLK] = &nss_cc_nssnoc_ce_axi_clk.clkr,
-+      [NSS_CC_NSSNOC_CLC_AXI_CLK] = &nss_cc_nssnoc_clc_axi_clk.clkr,
-+      [NSS_CC_NSSNOC_CRYPTO_CLK] = &nss_cc_nssnoc_crypto_clk.clkr,
-+      [NSS_CC_NSSNOC_HAQ_AHB_CLK] = &nss_cc_nssnoc_haq_ahb_clk.clkr,
-+      [NSS_CC_NSSNOC_HAQ_AXI_CLK] = &nss_cc_nssnoc_haq_axi_clk.clkr,
-+      [NSS_CC_NSSNOC_IMEM_AHB_CLK] = &nss_cc_nssnoc_imem_ahb_clk.clkr,
-+      [NSS_CC_NSSNOC_IMEM_QSB_CLK] = &nss_cc_nssnoc_imem_qsb_clk.clkr,
-+      [NSS_CC_NSSNOC_NSS_CSR_CLK] = &nss_cc_nssnoc_nss_csr_clk.clkr,
-+      [NSS_CC_NSSNOC_PPE_CFG_CLK] = &nss_cc_nssnoc_ppe_cfg_clk.clkr,
-+      [NSS_CC_NSSNOC_PPE_CLK] = &nss_cc_nssnoc_ppe_clk.clkr,
-+      [NSS_CC_NSSNOC_UBI32_AHB0_CLK] = &nss_cc_nssnoc_ubi32_ahb0_clk.clkr,
-+      [NSS_CC_NSSNOC_UBI32_AXI0_CLK] = &nss_cc_nssnoc_ubi32_axi0_clk.clkr,
-+      [NSS_CC_NSSNOC_UBI32_INT0_AHB_CLK] =
-+              &nss_cc_nssnoc_ubi32_int0_ahb_clk.clkr,
-+      [NSS_CC_NSSNOC_UBI32_NC_AXI0_1_CLK] =
-+              &nss_cc_nssnoc_ubi32_nc_axi0_1_clk.clkr,
-+      [NSS_CC_NSSNOC_UBI32_NC_AXI0_CLK] =
-+              &nss_cc_nssnoc_ubi32_nc_axi0_clk.clkr,
-+      [NSS_CC_PORT1_MAC_CLK] = &nss_cc_port1_mac_clk.clkr,
-+      [NSS_CC_PORT1_RX_CLK] = &nss_cc_port1_rx_clk.clkr,
-+      [NSS_CC_PORT1_RX_CLK_SRC] = &nss_cc_port1_rx_clk_src.clkr,
-+      [NSS_CC_PORT1_RX_DIV_CLK_SRC] = &nss_cc_port1_rx_div_clk_src.clkr,
-+      [NSS_CC_PORT1_TX_CLK] = &nss_cc_port1_tx_clk.clkr,
-+      [NSS_CC_PORT1_TX_CLK_SRC] = &nss_cc_port1_tx_clk_src.clkr,
-+      [NSS_CC_PORT1_TX_DIV_CLK_SRC] = &nss_cc_port1_tx_div_clk_src.clkr,
-+      [NSS_CC_PORT2_MAC_CLK] = &nss_cc_port2_mac_clk.clkr,
-+      [NSS_CC_PORT2_RX_CLK] = &nss_cc_port2_rx_clk.clkr,
-+      [NSS_CC_PORT2_RX_CLK_SRC] = &nss_cc_port2_rx_clk_src.clkr,
-+      [NSS_CC_PORT2_RX_DIV_CLK_SRC] = &nss_cc_port2_rx_div_clk_src.clkr,
-+      [NSS_CC_PORT2_TX_CLK] = &nss_cc_port2_tx_clk.clkr,
-+      [NSS_CC_PORT2_TX_CLK_SRC] = &nss_cc_port2_tx_clk_src.clkr,
-+      [NSS_CC_PORT2_TX_DIV_CLK_SRC] = &nss_cc_port2_tx_div_clk_src.clkr,
-+      [NSS_CC_PORT3_MAC_CLK] = &nss_cc_port3_mac_clk.clkr,
-+      [NSS_CC_PORT3_RX_CLK] = &nss_cc_port3_rx_clk.clkr,
-+      [NSS_CC_PORT3_RX_CLK_SRC] = &nss_cc_port3_rx_clk_src.clkr,
-+      [NSS_CC_PORT3_RX_DIV_CLK_SRC] = &nss_cc_port3_rx_div_clk_src.clkr,
-+      [NSS_CC_PORT3_TX_CLK] = &nss_cc_port3_tx_clk.clkr,
-+      [NSS_CC_PORT3_TX_CLK_SRC] = &nss_cc_port3_tx_clk_src.clkr,
-+      [NSS_CC_PORT3_TX_DIV_CLK_SRC] = &nss_cc_port3_tx_div_clk_src.clkr,
-+      [NSS_CC_PORT4_MAC_CLK] = &nss_cc_port4_mac_clk.clkr,
-+      [NSS_CC_PORT4_RX_CLK] = &nss_cc_port4_rx_clk.clkr,
-+      [NSS_CC_PORT4_RX_CLK_SRC] = &nss_cc_port4_rx_clk_src.clkr,
-+      [NSS_CC_PORT4_RX_DIV_CLK_SRC] = &nss_cc_port4_rx_div_clk_src.clkr,
-+      [NSS_CC_PORT4_TX_CLK] = &nss_cc_port4_tx_clk.clkr,
-+      [NSS_CC_PORT4_TX_CLK_SRC] = &nss_cc_port4_tx_clk_src.clkr,
-+      [NSS_CC_PORT4_TX_DIV_CLK_SRC] = &nss_cc_port4_tx_div_clk_src.clkr,
-+      [NSS_CC_PORT5_MAC_CLK] = &nss_cc_port5_mac_clk.clkr,
-+      [NSS_CC_PORT5_RX_CLK] = &nss_cc_port5_rx_clk.clkr,
-+      [NSS_CC_PORT5_RX_CLK_SRC] = &nss_cc_port5_rx_clk_src.clkr,
-+      [NSS_CC_PORT5_RX_DIV_CLK_SRC] = &nss_cc_port5_rx_div_clk_src.clkr,
-+      [NSS_CC_PORT5_TX_CLK] = &nss_cc_port5_tx_clk.clkr,
-+      [NSS_CC_PORT5_TX_CLK_SRC] = &nss_cc_port5_tx_clk_src.clkr,
-+      [NSS_CC_PORT5_TX_DIV_CLK_SRC] = &nss_cc_port5_tx_div_clk_src.clkr,
-+      [NSS_CC_PORT6_MAC_CLK] = &nss_cc_port6_mac_clk.clkr,
-+      [NSS_CC_PORT6_RX_CLK] = &nss_cc_port6_rx_clk.clkr,
-+      [NSS_CC_PORT6_RX_CLK_SRC] = &nss_cc_port6_rx_clk_src.clkr,
-+      [NSS_CC_PORT6_RX_DIV_CLK_SRC] = &nss_cc_port6_rx_div_clk_src.clkr,
-+      [NSS_CC_PORT6_TX_CLK] = &nss_cc_port6_tx_clk.clkr,
-+      [NSS_CC_PORT6_TX_CLK_SRC] = &nss_cc_port6_tx_clk_src.clkr,
-+      [NSS_CC_PORT6_TX_DIV_CLK_SRC] = &nss_cc_port6_tx_div_clk_src.clkr,
-+      [NSS_CC_PPE_CLK_SRC] = &nss_cc_ppe_clk_src.clkr,
-+      [NSS_CC_PPE_EDMA_CFG_CLK] = &nss_cc_ppe_edma_cfg_clk.clkr,
-+      [NSS_CC_PPE_EDMA_CLK] = &nss_cc_ppe_edma_clk.clkr,
-+      [NSS_CC_PPE_SWITCH_BTQ_CLK] = &nss_cc_ppe_switch_btq_clk.clkr,
-+      [NSS_CC_PPE_SWITCH_CFG_CLK] = &nss_cc_ppe_switch_cfg_clk.clkr,
-+      [NSS_CC_PPE_SWITCH_CLK] = &nss_cc_ppe_switch_clk.clkr,
-+      [NSS_CC_PPE_SWITCH_IPE_CLK] = &nss_cc_ppe_switch_ipe_clk.clkr,
-+      [NSS_CC_UBI0_CLK_SRC] = &nss_cc_ubi0_clk_src.clkr,
-+      [NSS_CC_UBI0_DIV_CLK_SRC] = &nss_cc_ubi0_div_clk_src.clkr,
-+      [NSS_CC_UBI1_CLK_SRC] = &nss_cc_ubi1_clk_src.clkr,
-+      [NSS_CC_UBI1_DIV_CLK_SRC] = &nss_cc_ubi1_div_clk_src.clkr,
-+      [NSS_CC_UBI2_CLK_SRC] = &nss_cc_ubi2_clk_src.clkr,
-+      [NSS_CC_UBI2_DIV_CLK_SRC] = &nss_cc_ubi2_div_clk_src.clkr,
-+      [NSS_CC_UBI32_AHB0_CLK] = &nss_cc_ubi32_ahb0_clk.clkr,
-+      [NSS_CC_UBI32_AHB1_CLK] = &nss_cc_ubi32_ahb1_clk.clkr,
-+      [NSS_CC_UBI32_AHB2_CLK] = &nss_cc_ubi32_ahb2_clk.clkr,
-+      [NSS_CC_UBI32_AHB3_CLK] = &nss_cc_ubi32_ahb3_clk.clkr,
-+      [NSS_CC_UBI32_AXI0_CLK] = &nss_cc_ubi32_axi0_clk.clkr,
-+      [NSS_CC_UBI32_AXI1_CLK] = &nss_cc_ubi32_axi1_clk.clkr,
-+      [NSS_CC_UBI32_AXI2_CLK] = &nss_cc_ubi32_axi2_clk.clkr,
-+      [NSS_CC_UBI32_AXI3_CLK] = &nss_cc_ubi32_axi3_clk.clkr,
-+      [NSS_CC_UBI32_CORE0_CLK] = &nss_cc_ubi32_core0_clk.clkr,
-+      [NSS_CC_UBI32_CORE1_CLK] = &nss_cc_ubi32_core1_clk.clkr,
-+      [NSS_CC_UBI32_CORE2_CLK] = &nss_cc_ubi32_core2_clk.clkr,
-+      [NSS_CC_UBI32_CORE3_CLK] = &nss_cc_ubi32_core3_clk.clkr,
-+      [NSS_CC_UBI32_INTR0_AHB_CLK] = &nss_cc_ubi32_intr0_ahb_clk.clkr,
-+      [NSS_CC_UBI32_INTR1_AHB_CLK] = &nss_cc_ubi32_intr1_ahb_clk.clkr,
-+      [NSS_CC_UBI32_INTR2_AHB_CLK] = &nss_cc_ubi32_intr2_ahb_clk.clkr,
-+      [NSS_CC_UBI32_INTR3_AHB_CLK] = &nss_cc_ubi32_intr3_ahb_clk.clkr,
-+      [NSS_CC_UBI32_NC_AXI0_CLK] = &nss_cc_ubi32_nc_axi0_clk.clkr,
-+      [NSS_CC_UBI32_NC_AXI1_CLK] = &nss_cc_ubi32_nc_axi1_clk.clkr,
-+      [NSS_CC_UBI32_NC_AXI2_CLK] = &nss_cc_ubi32_nc_axi2_clk.clkr,
-+      [NSS_CC_UBI32_NC_AXI3_CLK] = &nss_cc_ubi32_nc_axi3_clk.clkr,
-+      [NSS_CC_UBI32_UTCM0_CLK] = &nss_cc_ubi32_utcm0_clk.clkr,
-+      [NSS_CC_UBI32_UTCM1_CLK] = &nss_cc_ubi32_utcm1_clk.clkr,
-+      [NSS_CC_UBI32_UTCM2_CLK] = &nss_cc_ubi32_utcm2_clk.clkr,
-+      [NSS_CC_UBI32_UTCM3_CLK] = &nss_cc_ubi32_utcm3_clk.clkr,
-+      [NSS_CC_UBI3_CLK_SRC] = &nss_cc_ubi3_clk_src.clkr,
-+      [NSS_CC_UBI3_DIV_CLK_SRC] = &nss_cc_ubi3_div_clk_src.clkr,
-+      [NSS_CC_UBI_AXI_CLK_SRC] = &nss_cc_ubi_axi_clk_src.clkr,
-+      [NSS_CC_UBI_NC_AXI_BFDCD_CLK_SRC] =
-+              &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr,
-+      [NSS_CC_UNIPHY_PORT1_RX_CLK] = &nss_cc_uniphy_port1_rx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT1_TX_CLK] = &nss_cc_uniphy_port1_tx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT2_RX_CLK] = &nss_cc_uniphy_port2_rx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT2_TX_CLK] = &nss_cc_uniphy_port2_tx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT3_RX_CLK] = &nss_cc_uniphy_port3_rx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT3_TX_CLK] = &nss_cc_uniphy_port3_tx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT4_RX_CLK] = &nss_cc_uniphy_port4_rx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT4_TX_CLK] = &nss_cc_uniphy_port4_tx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT5_RX_CLK] = &nss_cc_uniphy_port5_rx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT5_TX_CLK] = &nss_cc_uniphy_port5_tx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT6_RX_CLK] = &nss_cc_uniphy_port6_rx_clk.clkr,
-+      [NSS_CC_UNIPHY_PORT6_TX_CLK] = &nss_cc_uniphy_port6_tx_clk.clkr,
-+      [NSS_CC_XGMAC0_PTP_REF_CLK] = &nss_cc_xgmac0_ptp_ref_clk.clkr,
-+      [NSS_CC_XGMAC0_PTP_REF_DIV_CLK_SRC] =
-+              &nss_cc_xgmac0_ptp_ref_div_clk_src.clkr,
-+      [NSS_CC_XGMAC1_PTP_REF_CLK] = &nss_cc_xgmac1_ptp_ref_clk.clkr,
-+      [NSS_CC_XGMAC1_PTP_REF_DIV_CLK_SRC] =
-+              &nss_cc_xgmac1_ptp_ref_div_clk_src.clkr,
-+      [NSS_CC_XGMAC2_PTP_REF_CLK] = &nss_cc_xgmac2_ptp_ref_clk.clkr,
-+      [NSS_CC_XGMAC2_PTP_REF_DIV_CLK_SRC] =
-+              &nss_cc_xgmac2_ptp_ref_div_clk_src.clkr,
-+      [NSS_CC_XGMAC3_PTP_REF_CLK] = &nss_cc_xgmac3_ptp_ref_clk.clkr,
-+      [NSS_CC_XGMAC3_PTP_REF_DIV_CLK_SRC] =
-+              &nss_cc_xgmac3_ptp_ref_div_clk_src.clkr,
-+      [NSS_CC_XGMAC4_PTP_REF_CLK] = &nss_cc_xgmac4_ptp_ref_clk.clkr,
-+      [NSS_CC_XGMAC4_PTP_REF_DIV_CLK_SRC] =
-+              &nss_cc_xgmac4_ptp_ref_div_clk_src.clkr,
-+      [NSS_CC_XGMAC5_PTP_REF_CLK] = &nss_cc_xgmac5_ptp_ref_clk.clkr,
-+      [NSS_CC_XGMAC5_PTP_REF_DIV_CLK_SRC] =
-+              &nss_cc_xgmac5_ptp_ref_div_clk_src.clkr,
-+      [UBI32_PLL] = &ubi32_pll.clkr,
-+      [UBI32_PLL_MAIN] = &ubi32_pll_main.clkr,
-+};
-+
-+static const struct qcom_reset_map nss_cc_ipq9574_resets[] = {
-+      [NSS_CC_CE_BCR] = { 0x28400, 0 },
-+      [NSS_CC_CLC_BCR] = { 0x28600, 0 },
-+      [NSS_CC_EIP197_BCR] = { 0x16004, 0 },
-+      [NSS_CC_HAQ_BCR] = { 0x28300, 0 },
-+      [NSS_CC_IMEM_BCR] = { 0xe004, 0 },
-+      [NSS_CC_MAC_BCR] = { 0x28100, 0 },
-+      [NSS_CC_PPE_BCR] = { 0x28200, 0 },
-+      [NSS_CC_UBI_BCR] = { 0x28700, 0 },
-+      [NSS_CC_UNIPHY_BCR] = { 0x28900, 0 },
-+      [UBI3_CLKRST_CLAMP_ENABLE] = { 0x28a04, 9 },
-+      [UBI3_CORE_CLAMP_ENABLE] = { 0x28a04, 8 },
-+      [UBI2_CLKRST_CLAMP_ENABLE] = { 0x28a04, 7 },
-+      [UBI2_CORE_CLAMP_ENABLE] = { 0x28a04, 6 },
-+      [UBI1_CLKRST_CLAMP_ENABLE] = { 0x28a04, 5 },
-+      [UBI1_CORE_CLAMP_ENABLE] = { 0x28a04, 4 },
-+      [UBI0_CLKRST_CLAMP_ENABLE] = { 0x28a04, 3 },
-+      [UBI0_CORE_CLAMP_ENABLE] = { 0x28a04, 2 },
-+      [NSSNOC_NSS_CSR_ARES] = { 0x28a04, 1 },
-+      [NSS_CSR_ARES] = { 0x28a04, 0 },
-+      [PPE_BTQ_ARES] = { 0x28a08, 20 },
-+      [PPE_IPE_ARES] = { 0x28a08, 19 },
-+      [PPE_ARES] = { 0x28a08, 18 },
-+      [PPE_CFG_ARES] = { 0x28a08, 17 },
-+      [PPE_EDMA_ARES] = { 0x28a08, 16 },
-+      [PPE_EDMA_CFG_ARES] = { 0x28a08, 15 },
-+      [CRY_PPE_ARES] = { 0x28a08, 14 },
-+      [NSSNOC_PPE_ARES] = { 0x28a08, 13 },
-+      [NSSNOC_PPE_CFG_ARES] = { 0x28a08, 12 },
-+      [PORT1_MAC_ARES] = { 0x28a08, 11 },
-+      [PORT2_MAC_ARES] = { 0x28a08, 10 },
-+      [PORT3_MAC_ARES] = { 0x28a08, 9 },
-+      [PORT4_MAC_ARES] = { 0x28a08, 8 },
-+      [PORT5_MAC_ARES] = { 0x28a08, 7 },
-+      [PORT6_MAC_ARES] = { 0x28a08, 6 },
-+      [XGMAC0_PTP_REF_ARES] = { 0x28a08, 5 },
-+      [XGMAC1_PTP_REF_ARES] = { 0x28a08, 4 },
-+      [XGMAC2_PTP_REF_ARES] = { 0x28a08, 3 },
-+      [XGMAC3_PTP_REF_ARES] = { 0x28a08, 2 },
-+      [XGMAC4_PTP_REF_ARES] = { 0x28a08, 1 },
-+      [XGMAC5_PTP_REF_ARES] = { 0x28a08, 0 },
-+      [HAQ_AHB_ARES] = { 0x28a0c, 3 },
-+      [HAQ_AXI_ARES] = { 0x28a0c, 2 },
-+      [NSSNOC_HAQ_AHB_ARES] = { 0x28a0c, 1 },
-+      [NSSNOC_HAQ_AXI_ARES] = { 0x28a0c, 0 },
-+      [CE_APB_ARES] = { 0x28a10, 3 },
-+      [CE_AXI_ARES] = { 0x28a10, 2 },
-+      [NSSNOC_CE_APB_ARES] = { 0x28a10, 1 },
-+      [NSSNOC_CE_AXI_ARES] = { 0x28a10, 0 },
-+      [CRYPTO_ARES] = { 0x28a14, 1 },
-+      [NSSNOC_CRYPTO_ARES] = { 0x28a14, 0 },
-+      [NSSNOC_NC_AXI0_1_ARES] = { 0x28a1c, 28 },
-+      [UBI0_CORE_ARES] = { 0x28a1c, 27 },
-+      [UBI1_CORE_ARES] = { 0x28a1c, 26 },
-+      [UBI2_CORE_ARES] = { 0x28a1c, 25 },
-+      [UBI3_CORE_ARES] = { 0x28a1c, 24 },
-+      [NC_AXI0_ARES] = { 0x28a1c, 23 },
-+      [UTCM0_ARES] = { 0x28a1c, 22 },
-+      [NC_AXI1_ARES] = { 0x28a1c, 21 },
-+      [UTCM1_ARES] = { 0x28a1c, 20 },
-+      [NC_AXI2_ARES] = { 0x28a1c, 19 },
-+      [UTCM2_ARES] = { 0x28a1c, 18 },
-+      [NC_AXI3_ARES] = { 0x28a1c, 17 },
-+      [UTCM3_ARES] = { 0x28a1c, 16 },
-+      [NSSNOC_NC_AXI0_ARES] = { 0x28a1c, 15 },
-+      [AHB0_ARES] = { 0x28a1c, 14 },
-+      [INTR0_AHB_ARES] = { 0x28a1c, 13 },
-+      [AHB1_ARES] = { 0x28a1c, 12 },
-+      [INTR1_AHB_ARES] = { 0x28a1c, 11 },
-+      [AHB2_ARES] = { 0x28a1c, 10 },
-+      [INTR2_AHB_ARES] = { 0x28a1c, 9 },
-+      [AHB3_ARES] = { 0x28a1c, 8 },
-+      [INTR3_AHB_ARES] = { 0x28a1c, 7 },
-+      [NSSNOC_AHB0_ARES] = { 0x28a1c, 6 },
-+      [NSSNOC_INT0_AHB_ARES] = { 0x28a1c, 5 },
-+      [AXI0_ARES] = { 0x28a1c, 4 },
-+      [AXI1_ARES] = { 0x28a1c, 3 },
-+      [AXI2_ARES] = { 0x28a1c, 2 },
-+      [AXI3_ARES] = { 0x28a1c, 1 },
-+      [NSSNOC_AXI0_ARES] = { 0x28a1c, 0 },
-+      [IMEM_QSB_ARES] = { 0x28a20, 3 },
-+      [NSSNOC_IMEM_QSB_ARES] = { 0x28a20, 2 },
-+      [IMEM_AHB_ARES] = { 0x28a20, 1 },
-+      [NSSNOC_IMEM_AHB_ARES] = { 0x28a20, 0 },
-+      [UNIPHY_PORT1_RX_ARES] = { 0x28a24, 23 },
-+      [UNIPHY_PORT1_TX_ARES] = { 0x28a24, 22 },
-+      [UNIPHY_PORT2_RX_ARES] = { 0x28a24, 21 },
-+      [UNIPHY_PORT2_TX_ARES] = { 0x28a24, 20 },
-+      [UNIPHY_PORT3_RX_ARES] = { 0x28a24, 19 },
-+      [UNIPHY_PORT3_TX_ARES] = { 0x28a24, 18 },
-+      [UNIPHY_PORT4_RX_ARES] = { 0x28a24, 17 },
-+      [UNIPHY_PORT4_TX_ARES] = { 0x28a24, 16 },
-+      [UNIPHY_PORT5_RX_ARES] = { 0x28a24, 15 },
-+      [UNIPHY_PORT5_TX_ARES] = { 0x28a24, 14 },
-+      [UNIPHY_PORT6_RX_ARES] = { 0x28a24, 13 },
-+      [UNIPHY_PORT6_TX_ARES] = { 0x28a24, 12 },
-+      [PORT1_RX_ARES] = { 0x28a24, 11 },
-+      [PORT1_TX_ARES] = { 0x28a24, 10 },
-+      [PORT2_RX_ARES] = { 0x28a24, 9 },
-+      [PORT2_TX_ARES] = { 0x28a24, 8 },
-+      [PORT3_RX_ARES] = { 0x28a24, 7 },
-+      [PORT3_TX_ARES] = { 0x28a24, 6 },
-+      [PORT4_RX_ARES] = { 0x28a24, 5 },
-+      [PORT4_TX_ARES] = { 0x28a24, 4 },
-+      [PORT5_RX_ARES] = { 0x28a24, 3 },
-+      [PORT5_TX_ARES] = { 0x28a24, 2 },
-+      [PORT6_RX_ARES] = { 0x28a24, 1 },
-+      [PORT6_TX_ARES] = { 0x28a24, 0 },
-+      [PPE_FULL_RESET] = { .reg = 0x28a08, .bitmask = GENMASK(20, 17) },
-+      [UNIPHY0_SOFT_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(23, 14) },
-+      [UNIPHY1_SOFT_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(15, 14) },
-+      [UNIPHY2_SOFT_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(13, 12) },
-+      [UNIPHY_PORT1_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(23, 22) },
-+      [UNIPHY_PORT2_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(21, 20) },
-+      [UNIPHY_PORT3_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(19, 18) },
-+      [UNIPHY_PORT4_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(17, 16) },
-+      [UNIPHY_PORT5_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(15, 14) },
-+      [UNIPHY_PORT6_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(13, 12) },
-+      [NSSPORT1_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(11, 10) },
-+      [NSSPORT2_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(9, 8) },
-+      [NSSPORT3_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(7, 6) },
-+      [NSSPORT4_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(5, 4) },
-+      [NSSPORT5_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(3, 2) },
-+      [NSSPORT6_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(1, 0) },
-+      [EDMA_HW_RESET] =  { .reg = 0x28a08, .bitmask = GENMASK(16, 15) },
-+};
-+
-+static const struct regmap_config nss_cc_ipq9574_regmap_config = {
-+      .reg_bits = 32,
-+      .reg_stride = 4,
-+      .val_bits = 32,
-+      .max_register = 0x28a34,
-+      .fast_io = true,
-+};
-+
-+static struct qcom_icc_hws_data icc_ipq9574_nss_hws[] = {
-+      { MASTER_NSSNOC_PPE, SLAVE_NSSNOC_PPE, NSS_CC_NSSNOC_PPE_CLK },
-+      { MASTER_NSSNOC_PPE_CFG, SLAVE_NSSNOC_PPE_CFG, NSS_CC_NSSNOC_PPE_CFG_CLK },
-+      { MASTER_NSSNOC_NSS_CSR, SLAVE_NSSNOC_NSS_CSR, NSS_CC_NSSNOC_NSS_CSR_CLK },
-+      { MASTER_NSSNOC_IMEM_QSB, SLAVE_NSSNOC_IMEM_QSB, NSS_CC_NSSNOC_IMEM_QSB_CLK },
-+      { MASTER_NSSNOC_IMEM_AHB, SLAVE_NSSNOC_IMEM_AHB, NSS_CC_NSSNOC_IMEM_AHB_CLK },
-+};
-+
-+#define IPQ_NSSCC_ID  (9574 * 2) /* some unique value */
-+
-+static const struct qcom_cc_desc nss_cc_ipq9574_desc = {
-+      .config = &nss_cc_ipq9574_regmap_config,
-+      .clks = nss_cc_ipq9574_clocks,
-+      .num_clks = ARRAY_SIZE(nss_cc_ipq9574_clocks),
-+      .resets = nss_cc_ipq9574_resets,
-+      .num_resets = ARRAY_SIZE(nss_cc_ipq9574_resets),
-+      .icc_hws = icc_ipq9574_nss_hws,
-+      .num_icc_hws = ARRAY_SIZE(icc_ipq9574_nss_hws),
-+      .icc_first_node_id = IPQ_NSSCC_ID,
-+};
-+
-+static const struct dev_pm_ops nss_cc_ipq9574_pm_ops = {
-+      SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
-+};
-+
-+static const struct of_device_id nss_cc_ipq9574_match_table[] = {
-+      { .compatible = "qcom,ipq9574-nsscc" },
-+      { }
-+};
-+MODULE_DEVICE_TABLE(of, nss_cc_ipq9574_match_table);
-+
-+static int nss_cc_ipq9574_probe(struct platform_device *pdev)
-+{
-+      struct regmap *regmap;
-+      int ret;
-+
-+      ret = devm_pm_runtime_enable(&pdev->dev);
-+      if (ret)
-+              return dev_err_probe(&pdev->dev, ret, "Fail to enable runtime PM\n");
-+
-+      ret = devm_pm_clk_create(&pdev->dev);
-+      if (ret)
-+              return dev_err_probe(&pdev->dev, ret, "Fail to create PM clock\n");
-+
-+      ret = pm_clk_add(&pdev->dev, "bus");
-+      if (ret)
-+              return dev_err_probe(&pdev->dev, ret, "Fail to add bus clock\n");
-+
-+      ret = pm_runtime_resume_and_get(&pdev->dev);
-+      if (ret)
-+              return dev_err_probe(&pdev->dev, ret, "Fail to resume\n");
-+
-+      regmap = qcom_cc_map(pdev, &nss_cc_ipq9574_desc);
-+      if (IS_ERR(regmap)) {
-+              pm_runtime_put(&pdev->dev);
-+              return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
-+                                   "Fail to map clock controller registers\n");
-+      }
-+
-+      clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
-+
-+      ret = qcom_cc_really_probe(&pdev->dev, &nss_cc_ipq9574_desc, regmap);
-+      pm_runtime_put(&pdev->dev);
-+
-+      return ret;
-+}
-+
-+static struct platform_driver nss_cc_ipq9574_driver = {
-+      .probe = nss_cc_ipq9574_probe,
-+      .driver = {
-+              .name = "qcom,nsscc-ipq9574",
-+              .of_match_table = nss_cc_ipq9574_match_table,
-+              .pm = &nss_cc_ipq9574_pm_ops,
-+              .sync_state = icc_sync_state,
-+      },
-+};
-+
-+module_platform_driver(nss_cc_ipq9574_driver);
-+
-+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. NSSCC IPQ9574 Driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/qualcommbe/patches-6.12/0022-v6.15-arm64-defconfig-Build-NSS-Clock-Controller-dri.patch b/target/linux/qualcommbe/patches-6.12/0022-v6.15-arm64-defconfig-Build-NSS-Clock-Controller-dri.patch
deleted file mode 100644 (file)
index 2a2ad00..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From 8f1b61ea1cb98735aa15a8875d729c21a2169fb9 Mon Sep 17 00:00:00 2001
-From: Devi Priya <quic_devipriy@quicinc.com>
-Date: Thu, 13 Mar 2025 16:33:59 +0530
-Subject: [PATCH 22/22] v6.15: arm64: defconfig: Build NSS Clock Controller
- driver for IPQ9574
-
-NSSCC driver is needed to enable the ethernet interfaces present
-in RDP433 based on IPQ9574. Since this is not necessary for bootup
-enabling it as a module.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
-Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
-Link: https://lore.kernel.org/r/20250313110359.242491-7-quic_mmanikan@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- arch/arm64/configs/defconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm64/configs/defconfig
-+++ b/arch/arm64/configs/defconfig
-@@ -1312,6 +1312,7 @@ CONFIG_IPQ_GCC_5332=y
- CONFIG_IPQ_GCC_6018=y
- CONFIG_IPQ_GCC_8074=y
- CONFIG_IPQ_GCC_9574=y
-+CONFIG_IPQ_NSSCC_9574=m
- CONFIG_MSM_GCC_8916=y
- CONFIG_MSM_MMCC_8994=m
- CONFIG_MSM_GCC_8994=y
diff --git a/target/linux/qualcommbe/patches-6.12/0023-v6.15-net-phy-move-PHY-package-code-from-phy_device..patch b/target/linux/qualcommbe/patches-6.12/0023-v6.15-net-phy-move-PHY-package-code-from-phy_device..patch
deleted file mode 100644 (file)
index 3ea7f81..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-From 986ec7ee75f2f1f7f93eb0e05f61f297f6123fce Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 3 Mar 2025 21:14:02 +0100
-Subject: [PATCH] v6.15: net: phy: move PHY package code from phy_device.c to
- own source file
-
-This patch is the first step in moving the PHY package related code
-to its own source file. No functional change intended.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/57df5c19-fbcd-45a7-9afd-cd4f74d7fa76@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/Makefile      |   3 +-
- drivers/net/phy/phy_device.c  | 237 ---------------------------------
- drivers/net/phy/phy_package.c | 244 ++++++++++++++++++++++++++++++++++
- 3 files changed, 246 insertions(+), 238 deletions(-)
- create mode 100644 drivers/net/phy/phy_package.c
-
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -2,7 +2,8 @@
- # Makefile for Linux PHY drivers
- libphy-y                      := phy.o phy-c45.o phy-core.o phy_device.o \
--                                 linkmode.o phy_link_topology.o
-+                                 linkmode.o phy_link_topology.o \
-+                                 phy_package.o
- mdio-bus-y                    += mdio_bus.o mdio_device.o
- ifdef CONFIG_MDIO_DEVICE
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1781,243 +1781,6 @@ bool phy_driver_is_genphy_10g(struct phy
- EXPORT_SYMBOL_GPL(phy_driver_is_genphy_10g);
- /**
-- * phy_package_join - join a common PHY group
-- * @phydev: target phy_device struct
-- * @base_addr: cookie and base PHY address of PHY package for offset
-- *   calculation of global register access
-- * @priv_size: if non-zero allocate this amount of bytes for private data
-- *
-- * This joins a PHY group and provides a shared storage for all phydevs in
-- * this group. This is intended to be used for packages which contain
-- * more than one PHY, for example a quad PHY transceiver.
-- *
-- * The base_addr parameter serves as cookie which has to have the same values
-- * for all members of one group and as the base PHY address of the PHY package
-- * for offset calculation to access generic registers of a PHY package.
-- * Usually, one of the PHY addresses of the different PHYs in the package
-- * provides access to these global registers.
-- * The address which is given here, will be used in the phy_package_read()
-- * and phy_package_write() convenience functions as base and added to the
-- * passed offset in those functions.
-- *
-- * This will set the shared pointer of the phydev to the shared storage.
-- * If this is the first call for a this cookie the shared storage will be
-- * allocated. If priv_size is non-zero, the given amount of bytes are
-- * allocated for the priv member.
-- *
-- * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
-- * with the same cookie but a different priv_size is an error.
-- */
--int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size)
--{
--      struct mii_bus *bus = phydev->mdio.bus;
--      struct phy_package_shared *shared;
--      int ret;
--
--      if (base_addr < 0 || base_addr >= PHY_MAX_ADDR)
--              return -EINVAL;
--
--      mutex_lock(&bus->shared_lock);
--      shared = bus->shared[base_addr];
--      if (!shared) {
--              ret = -ENOMEM;
--              shared = kzalloc(sizeof(*shared), GFP_KERNEL);
--              if (!shared)
--                      goto err_unlock;
--              if (priv_size) {
--                      shared->priv = kzalloc(priv_size, GFP_KERNEL);
--                      if (!shared->priv)
--                              goto err_free;
--                      shared->priv_size = priv_size;
--              }
--              shared->base_addr = base_addr;
--              shared->np = NULL;
--              refcount_set(&shared->refcnt, 1);
--              bus->shared[base_addr] = shared;
--      } else {
--              ret = -EINVAL;
--              if (priv_size && priv_size != shared->priv_size)
--                      goto err_unlock;
--              refcount_inc(&shared->refcnt);
--      }
--      mutex_unlock(&bus->shared_lock);
--
--      phydev->shared = shared;
--
--      return 0;
--
--err_free:
--      kfree(shared);
--err_unlock:
--      mutex_unlock(&bus->shared_lock);
--      return ret;
--}
--EXPORT_SYMBOL_GPL(phy_package_join);
--
--/**
-- * of_phy_package_join - join a common PHY group in PHY package
-- * @phydev: target phy_device struct
-- * @priv_size: if non-zero allocate this amount of bytes for private data
-- *
-- * This is a variant of phy_package_join for PHY package defined in DT.
-- *
-- * The parent node of the @phydev is checked as a valid PHY package node
-- * structure (by matching the node name "ethernet-phy-package") and the
-- * base_addr for the PHY package is passed to phy_package_join.
-- *
-- * With this configuration the shared struct will also have the np value
-- * filled to use additional DT defined properties in PHY specific
-- * probe_once and config_init_once PHY package OPs.
-- *
-- * Returns < 0 on error, 0 on success. Esp. calling phy_package_join()
-- * with the same cookie but a different priv_size is an error. Or a parent
-- * node is not detected or is not valid or doesn't match the expected node
-- * name for PHY package.
-- */
--int of_phy_package_join(struct phy_device *phydev, size_t priv_size)
--{
--      struct device_node *node = phydev->mdio.dev.of_node;
--      struct device_node *package_node;
--      u32 base_addr;
--      int ret;
--
--      if (!node)
--              return -EINVAL;
--
--      package_node = of_get_parent(node);
--      if (!package_node)
--              return -EINVAL;
--
--      if (!of_node_name_eq(package_node, "ethernet-phy-package")) {
--              ret = -EINVAL;
--              goto exit;
--      }
--
--      if (of_property_read_u32(package_node, "reg", &base_addr)) {
--              ret = -EINVAL;
--              goto exit;
--      }
--
--      ret = phy_package_join(phydev, base_addr, priv_size);
--      if (ret)
--              goto exit;
--
--      phydev->shared->np = package_node;
--
--      return 0;
--exit:
--      of_node_put(package_node);
--      return ret;
--}
--EXPORT_SYMBOL_GPL(of_phy_package_join);
--
--/**
-- * phy_package_leave - leave a common PHY group
-- * @phydev: target phy_device struct
-- *
-- * This leaves a PHY group created by phy_package_join(). If this phydev
-- * was the last user of the shared data between the group, this data is
-- * freed. Resets the phydev->shared pointer to NULL.
-- */
--void phy_package_leave(struct phy_device *phydev)
--{
--      struct phy_package_shared *shared = phydev->shared;
--      struct mii_bus *bus = phydev->mdio.bus;
--
--      if (!shared)
--              return;
--
--      /* Decrease the node refcount on leave if present */
--      if (shared->np)
--              of_node_put(shared->np);
--
--      if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) {
--              bus->shared[shared->base_addr] = NULL;
--              mutex_unlock(&bus->shared_lock);
--              kfree(shared->priv);
--              kfree(shared);
--      }
--
--      phydev->shared = NULL;
--}
--EXPORT_SYMBOL_GPL(phy_package_leave);
--
--static void devm_phy_package_leave(struct device *dev, void *res)
--{
--      phy_package_leave(*(struct phy_device **)res);
--}
--
--/**
-- * devm_phy_package_join - resource managed phy_package_join()
-- * @dev: device that is registering this PHY package
-- * @phydev: target phy_device struct
-- * @base_addr: cookie and base PHY address of PHY package for offset
-- *   calculation of global register access
-- * @priv_size: if non-zero allocate this amount of bytes for private data
-- *
-- * Managed phy_package_join(). Shared storage fetched by this function,
-- * phy_package_leave() is automatically called on driver detach. See
-- * phy_package_join() for more information.
-- */
--int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
--                        int base_addr, size_t priv_size)
--{
--      struct phy_device **ptr;
--      int ret;
--
--      ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
--                         GFP_KERNEL);
--      if (!ptr)
--              return -ENOMEM;
--
--      ret = phy_package_join(phydev, base_addr, priv_size);
--
--      if (!ret) {
--              *ptr = phydev;
--              devres_add(dev, ptr);
--      } else {
--              devres_free(ptr);
--      }
--
--      return ret;
--}
--EXPORT_SYMBOL_GPL(devm_phy_package_join);
--
--/**
-- * devm_of_phy_package_join - resource managed of_phy_package_join()
-- * @dev: device that is registering this PHY package
-- * @phydev: target phy_device struct
-- * @priv_size: if non-zero allocate this amount of bytes for private data
-- *
-- * Managed of_phy_package_join(). Shared storage fetched by this function,
-- * phy_package_leave() is automatically called on driver detach. See
-- * of_phy_package_join() for more information.
-- */
--int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev,
--                           size_t priv_size)
--{
--      struct phy_device **ptr;
--      int ret;
--
--      ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
--                         GFP_KERNEL);
--      if (!ptr)
--              return -ENOMEM;
--
--      ret = of_phy_package_join(phydev, priv_size);
--
--      if (!ret) {
--              *ptr = phydev;
--              devres_add(dev, ptr);
--      } else {
--              devres_free(ptr);
--      }
--
--      return ret;
--}
--EXPORT_SYMBOL_GPL(devm_of_phy_package_join);
--
--/**
-  * phy_detach - detach a PHY device from its network device
-  * @phydev: target phy_device struct
-  *
---- /dev/null
-+++ b/drivers/net/phy/phy_package.c
-@@ -0,0 +1,244 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * PHY package support
-+ */
-+
-+#include <linux/of.h>
-+#include <linux/phy.h>
-+
-+/**
-+ * phy_package_join - join a common PHY group
-+ * @phydev: target phy_device struct
-+ * @base_addr: cookie and base PHY address of PHY package for offset
-+ *   calculation of global register access
-+ * @priv_size: if non-zero allocate this amount of bytes for private data
-+ *
-+ * This joins a PHY group and provides a shared storage for all phydevs in
-+ * this group. This is intended to be used for packages which contain
-+ * more than one PHY, for example a quad PHY transceiver.
-+ *
-+ * The base_addr parameter serves as cookie which has to have the same values
-+ * for all members of one group and as the base PHY address of the PHY package
-+ * for offset calculation to access generic registers of a PHY package.
-+ * Usually, one of the PHY addresses of the different PHYs in the package
-+ * provides access to these global registers.
-+ * The address which is given here, will be used in the phy_package_read()
-+ * and phy_package_write() convenience functions as base and added to the
-+ * passed offset in those functions.
-+ *
-+ * This will set the shared pointer of the phydev to the shared storage.
-+ * If this is the first call for a this cookie the shared storage will be
-+ * allocated. If priv_size is non-zero, the given amount of bytes are
-+ * allocated for the priv member.
-+ *
-+ * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
-+ * with the same cookie but a different priv_size is an error.
-+ */
-+int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size)
-+{
-+      struct mii_bus *bus = phydev->mdio.bus;
-+      struct phy_package_shared *shared;
-+      int ret;
-+
-+      if (base_addr < 0 || base_addr >= PHY_MAX_ADDR)
-+              return -EINVAL;
-+
-+      mutex_lock(&bus->shared_lock);
-+      shared = bus->shared[base_addr];
-+      if (!shared) {
-+              ret = -ENOMEM;
-+              shared = kzalloc(sizeof(*shared), GFP_KERNEL);
-+              if (!shared)
-+                      goto err_unlock;
-+              if (priv_size) {
-+                      shared->priv = kzalloc(priv_size, GFP_KERNEL);
-+                      if (!shared->priv)
-+                              goto err_free;
-+                      shared->priv_size = priv_size;
-+              }
-+              shared->base_addr = base_addr;
-+              shared->np = NULL;
-+              refcount_set(&shared->refcnt, 1);
-+              bus->shared[base_addr] = shared;
-+      } else {
-+              ret = -EINVAL;
-+              if (priv_size && priv_size != shared->priv_size)
-+                      goto err_unlock;
-+              refcount_inc(&shared->refcnt);
-+      }
-+      mutex_unlock(&bus->shared_lock);
-+
-+      phydev->shared = shared;
-+
-+      return 0;
-+
-+err_free:
-+      kfree(shared);
-+err_unlock:
-+      mutex_unlock(&bus->shared_lock);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(phy_package_join);
-+
-+/**
-+ * of_phy_package_join - join a common PHY group in PHY package
-+ * @phydev: target phy_device struct
-+ * @priv_size: if non-zero allocate this amount of bytes for private data
-+ *
-+ * This is a variant of phy_package_join for PHY package defined in DT.
-+ *
-+ * The parent node of the @phydev is checked as a valid PHY package node
-+ * structure (by matching the node name "ethernet-phy-package") and the
-+ * base_addr for the PHY package is passed to phy_package_join.
-+ *
-+ * With this configuration the shared struct will also have the np value
-+ * filled to use additional DT defined properties in PHY specific
-+ * probe_once and config_init_once PHY package OPs.
-+ *
-+ * Returns < 0 on error, 0 on success. Esp. calling phy_package_join()
-+ * with the same cookie but a different priv_size is an error. Or a parent
-+ * node is not detected or is not valid or doesn't match the expected node
-+ * name for PHY package.
-+ */
-+int of_phy_package_join(struct phy_device *phydev, size_t priv_size)
-+{
-+      struct device_node *node = phydev->mdio.dev.of_node;
-+      struct device_node *package_node;
-+      u32 base_addr;
-+      int ret;
-+
-+      if (!node)
-+              return -EINVAL;
-+
-+      package_node = of_get_parent(node);
-+      if (!package_node)
-+              return -EINVAL;
-+
-+      if (!of_node_name_eq(package_node, "ethernet-phy-package")) {
-+              ret = -EINVAL;
-+              goto exit;
-+      }
-+
-+      if (of_property_read_u32(package_node, "reg", &base_addr)) {
-+              ret = -EINVAL;
-+              goto exit;
-+      }
-+
-+      ret = phy_package_join(phydev, base_addr, priv_size);
-+      if (ret)
-+              goto exit;
-+
-+      phydev->shared->np = package_node;
-+
-+      return 0;
-+exit:
-+      of_node_put(package_node);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(of_phy_package_join);
-+
-+/**
-+ * phy_package_leave - leave a common PHY group
-+ * @phydev: target phy_device struct
-+ *
-+ * This leaves a PHY group created by phy_package_join(). If this phydev
-+ * was the last user of the shared data between the group, this data is
-+ * freed. Resets the phydev->shared pointer to NULL.
-+ */
-+void phy_package_leave(struct phy_device *phydev)
-+{
-+      struct phy_package_shared *shared = phydev->shared;
-+      struct mii_bus *bus = phydev->mdio.bus;
-+
-+      if (!shared)
-+              return;
-+
-+      /* Decrease the node refcount on leave if present */
-+      if (shared->np)
-+              of_node_put(shared->np);
-+
-+      if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) {
-+              bus->shared[shared->base_addr] = NULL;
-+              mutex_unlock(&bus->shared_lock);
-+              kfree(shared->priv);
-+              kfree(shared);
-+      }
-+
-+      phydev->shared = NULL;
-+}
-+EXPORT_SYMBOL_GPL(phy_package_leave);
-+
-+static void devm_phy_package_leave(struct device *dev, void *res)
-+{
-+      phy_package_leave(*(struct phy_device **)res);
-+}
-+
-+/**
-+ * devm_phy_package_join - resource managed phy_package_join()
-+ * @dev: device that is registering this PHY package
-+ * @phydev: target phy_device struct
-+ * @base_addr: cookie and base PHY address of PHY package for offset
-+ *   calculation of global register access
-+ * @priv_size: if non-zero allocate this amount of bytes for private data
-+ *
-+ * Managed phy_package_join(). Shared storage fetched by this function,
-+ * phy_package_leave() is automatically called on driver detach. See
-+ * phy_package_join() for more information.
-+ */
-+int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
-+                        int base_addr, size_t priv_size)
-+{
-+      struct phy_device **ptr;
-+      int ret;
-+
-+      ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
-+                         GFP_KERNEL);
-+      if (!ptr)
-+              return -ENOMEM;
-+
-+      ret = phy_package_join(phydev, base_addr, priv_size);
-+
-+      if (!ret) {
-+              *ptr = phydev;
-+              devres_add(dev, ptr);
-+      } else {
-+              devres_free(ptr);
-+      }
-+
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(devm_phy_package_join);
-+
-+/**
-+ * devm_of_phy_package_join - resource managed of_phy_package_join()
-+ * @dev: device that is registering this PHY package
-+ * @phydev: target phy_device struct
-+ * @priv_size: if non-zero allocate this amount of bytes for private data
-+ *
-+ * Managed of_phy_package_join(). Shared storage fetched by this function,
-+ * phy_package_leave() is automatically called on driver detach. See
-+ * of_phy_package_join() for more information.
-+ */
-+int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev,
-+                           size_t priv_size)
-+{
-+      struct phy_device **ptr;
-+      int ret;
-+
-+      ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
-+                         GFP_KERNEL);
-+      if (!ptr)
-+              return -ENOMEM;
-+
-+      ret = of_phy_package_join(phydev, priv_size);
-+
-+      if (!ret) {
-+              *ptr = phydev;
-+              devres_add(dev, ptr);
-+      } else {
-+              devres_free(ptr);
-+      }
-+
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(devm_of_phy_package_join);
diff --git a/target/linux/qualcommbe/patches-6.12/0024-v6.15-net-phy-add-getters-for-public-members-in-stru.patch b/target/linux/qualcommbe/patches-6.12/0024-v6.15-net-phy-add-getters-for-public-members-in-stru.patch
deleted file mode 100644 (file)
index a05083d..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-From e9ee1dd2ff2c130b2fb2bd01936224a8a6b49a7e Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 3 Mar 2025 21:15:09 +0100
-Subject: [PATCH] v6.15: net: phy: add getters for public members in struct
- phy_package_shared
-
-Add getters for public members, this prepares for making struct
-phy_package_shared private to phylib. Declare the getters in a new header
-file phylib.h, which will be used by PHY drivers only.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/c6da0b27-4479-4717-9e16-643821b76bd8@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phy_package.c | 14 ++++++++++++++
- drivers/net/phy/phylib.h      | 15 +++++++++++++++
- 2 files changed, 29 insertions(+)
- create mode 100644 drivers/net/phy/phylib.h
-
---- a/drivers/net/phy/phy_package.c
-+++ b/drivers/net/phy/phy_package.c
-@@ -6,6 +6,20 @@
- #include <linux/of.h>
- #include <linux/phy.h>
-+#include "phylib.h"
-+
-+struct device_node *phy_package_get_node(struct phy_device *phydev)
-+{
-+      return phydev->shared->np;
-+}
-+EXPORT_SYMBOL_GPL(phy_package_get_node);
-+
-+void *phy_package_get_priv(struct phy_device *phydev)
-+{
-+      return phydev->shared->priv;
-+}
-+EXPORT_SYMBOL_GPL(phy_package_get_priv);
-+
- /**
-  * phy_package_join - join a common PHY group
-  * @phydev: target phy_device struct
---- /dev/null
-+++ b/drivers/net/phy/phylib.h
-@@ -0,0 +1,15 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later */
-+/*
-+ * phylib header
-+ */
-+
-+#ifndef __PHYLIB_H
-+#define __PHYLIB_H
-+
-+struct device_node;
-+struct phy_device;
-+
-+struct device_node *phy_package_get_node(struct phy_device *phydev);
-+void *phy_package_get_priv(struct phy_device *phydev);
-+
-+#endif /* __PHYLIB_H */
diff --git a/target/linux/qualcommbe/patches-6.12/0100-arm64-dts-qcom-ipq9574-Add-nsscc-node.patch b/target/linux/qualcommbe/patches-6.12/0100-arm64-dts-qcom-ipq9574-Add-nsscc-node.patch
deleted file mode 100644 (file)
index c38a7eb..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-From 52ebd52aa1906961142a2aba55d47a53b956847c Mon Sep 17 00:00:00 2001
-From: Devi Priya <quic_devipriy@quicinc.com>
-Date: Thu, 13 Mar 2025 16:33:58 +0530
-Subject: [PATCH] arm64: dts: qcom: ipq9574: Add nsscc node
-
-Add a node for the nss clock controller found on ipq9574 based devices.
-
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
-Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
-Link: https://lore.kernel.org/r/20250313110359.242491-6-quic_mmanikan@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 29 +++++++++++++++++++++++++++
- 1 file changed, 29 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -1195,6 +1195,35 @@
-                       status = "disabled";
-               };
-+              nsscc: clock-controller@39b00000 {
-+                      compatible = "qcom,ipq9574-nsscc";
-+                      reg = <0x39b00000 0x80000>;
-+                      clocks = <&xo_board_clk>,
-+                               <&cmn_pll NSS_1200MHZ_CLK>,
-+                               <&cmn_pll PPE_353MHZ_CLK>,
-+                               <&gcc GPLL0_OUT_AUX>,
-+                               <0>,
-+                               <0>,
-+                               <0>,
-+                               <0>,
-+                               <0>,
-+                               <0>,
-+                               <&gcc GCC_NSSCC_CLK>;
-+                      clock-names = "xo",
-+                                    "nss_1200",
-+                                    "ppe_353",
-+                                    "gpll0_out",
-+                                    "uniphy0_rx",
-+                                    "uniphy0_tx",
-+                                    "uniphy1_rx",
-+                                    "uniphy1_tx",
-+                                    "uniphy2_rx",
-+                                    "uniphy2_tx",
-+                                    "bus";
-+                      #clock-cells = <1>;
-+                      #reset-cells = <1>;
-+                      #interconnect-cells = <1>;
-+              };
-       };
-       thermal-zones {
diff --git a/target/linux/qualcommbe/patches-6.12/0101-arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch b/target/linux/qualcommbe/patches-6.12/0101-arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch
deleted file mode 100644 (file)
index b09fccf..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-From 2f2f5ae4d52ea882ba58f6b2fa6373a3d3db2bce Mon Sep 17 00:00:00 2001
-From: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
-Date: Thu, 13 Mar 2025 12:44:22 +0530
-Subject: [PATCH] arm64: dts: qcom: ipq9574: fix the msi interrupt numbers of
- pcie3
-
-The MSI interrupt numbers of the PCIe3 controller are incorrect. Due
-to this, the functional bring up of the QDSP6 processor on the PCIe
-endpoint has failed. Correct the MSI interrupt numbers to properly
-bring up the QDSP6 processor on the PCIe endpoint.
-
-Fixes: d80c7fbfa908 ("arm64: dts: qcom: ipq9574: Add PCIe PHYs and controller nodes")
-Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
-Link: https://lore.kernel.org/r/20250313071422.510-1-quic_mmanikan@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -974,14 +974,14 @@
-                       ranges = <0x01000000 0x0 0x00000000 0x18200000 0x0 0x100000>,
-                                <0x02000000 0x0 0x18300000 0x18300000 0x0 0x7d00000>;
--                      interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
--                                   <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
--                                   <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
--                                   <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
--                                   <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
--                                   <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
--                                   <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
--                                   <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-+                      interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH>,
-+                                   <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "msi0",
-                                         "msi1",
-                                         "msi2",
diff --git a/target/linux/qualcommbe/patches-6.12/0103-arm64-dts-qcom-ipq9574-Add-SPI-nand-support.patch b/target/linux/qualcommbe/patches-6.12/0103-arm64-dts-qcom-ipq9574-Add-SPI-nand-support.patch
deleted file mode 100644 (file)
index 7bec20d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-From 583299efa34c4a484b211f84c63aee78b6c2b469 Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Thu, 6 Mar 2025 17:03:55 +0530
-Subject: [PATCH] arm64: dts: qcom: ipq9574: Add SPI nand support
-
-Add SPI NAND support for ipq9574 SoC.
-
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Link: https://lore.kernel.org/r/20250306113357.126602-2-quic_mdalam@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 27 +++++++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -675,6 +675,33 @@
-                       status = "disabled";
-               };
-+              qpic_bam: dma-controller@7984000 {
-+                      compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0";
-+                      reg = <0x07984000 0x1c000>;
-+                      interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&gcc GCC_QPIC_AHB_CLK>;
-+                      clock-names = "bam_clk";
-+                      #dma-cells = <1>;
-+                      qcom,ee = <0>;
-+                      status = "disabled";
-+              };
-+
-+              qpic_nand: spi@79b0000 {
-+                      compatible = "qcom,ipq9574-snand";
-+                      reg = <0x079b0000 0x10000>;
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+                      clocks = <&gcc GCC_QPIC_CLK>,
-+                               <&gcc GCC_QPIC_AHB_CLK>,
-+                               <&gcc GCC_QPIC_IO_MACRO_CLK>;
-+                      clock-names = "core", "aon", "iom";
-+                      dmas = <&qpic_bam 0>,
-+                             <&qpic_bam 1>,
-+                             <&qpic_bam 2>;
-+                      dma-names = "tx", "rx", "cmd";
-+                      status = "disabled";
-+              };
-+
-               usb_0_qusbphy: phy@7b000 {
-                       compatible = "qcom,ipq9574-qusb2-phy";
-                       reg = <0x0007b000 0x180>;
diff --git a/target/linux/qualcommbe/patches-6.12/0104-arm64-dts-qcom-ipq9574-Enable-SPI-NAND-for-ipq9574.patch b/target/linux/qualcommbe/patches-6.12/0104-arm64-dts-qcom-ipq9574-Enable-SPI-NAND-for-ipq9574.patch
deleted file mode 100644 (file)
index 393923a..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From a7c88bc81632974c0708308493aefb1f871b65fa Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Thu, 6 Mar 2025 17:03:56 +0530
-Subject: [PATCH] arm64: dts: qcom: ipq9574: Enable SPI NAND for ipq9574
-
-Enable SPI NAND support for ipq9574 SoC.
-
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Link: https://lore.kernel.org/r/20250306113357.126602-3-quic_mdalam@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- .../boot/dts/qcom/ipq9574-rdp-common.dtsi     | 44 +++++++++++++++++++
- 1 file changed, 44 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-@@ -146,6 +146,50 @@
-               drive-strength = <8>;
-               bias-pull-up;
-       };
-+
-+      qpic_snand_default_state: qpic-snand-default-state {
-+              clock-pins {
-+                      pins = "gpio5";
-+                      function = "qspi_clk";
-+                      drive-strength = <8>;
-+                      bias-disable;
-+              };
-+
-+              cs-pins {
-+                      pins = "gpio4";
-+                      function = "qspi_cs";
-+                      drive-strength = <8>;
-+                      bias-disable;
-+              };
-+
-+              data-pins {
-+                      pins = "gpio0", "gpio1", "gpio2", "gpio3";
-+                      function = "qspi_data";
-+                      drive-strength = <8>;
-+                      bias-disable;
-+              };
-+      };
-+};
-+
-+&qpic_bam {
-+      status = "okay";
-+};
-+
-+&qpic_nand {
-+      pinctrl-0 = <&qpic_snand_default_state>;
-+      pinctrl-names = "default";
-+
-+      status = "okay";
-+
-+      flash@0 {
-+              compatible = "spi-nand";
-+              reg = <0>;
-+              #address-cells = <1>;
-+              #size-cells = <1>;
-+              nand-ecc-engine = <&qpic_nand>;
-+              nand-ecc-strength = <4>;
-+              nand-ecc-step-size = <512>;
-+      };
- };
- &usb_0_dwc3 {
diff --git a/target/linux/qualcommbe/patches-6.12/0105-arm64-dts-qcom-ipq9574-Remove-eMMC-node.patch b/target/linux/qualcommbe/patches-6.12/0105-arm64-dts-qcom-ipq9574-Remove-eMMC-node.patch
deleted file mode 100644 (file)
index d188539..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0156e327aa854be5eb9cbec9d020be1026b5b446 Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Thu, 6 Mar 2025 17:03:57 +0530
-Subject: [PATCH] arm64: dts: qcom: ipq9574: Remove eMMC node
-
-Remove eMMC node for rdp433, since rdp433
-default boot mode is norplusnand
-
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Link: https://lore.kernel.org/r/20250306113357.126602-4-quic_mdalam@quicinc.com
-Signed-off-by: Bjorn Andersson <andersson@kernel.org>
----
- arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 12 ------------
- 1 file changed, 12 deletions(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-@@ -55,18 +55,6 @@
-       status = "okay";
- };
--&sdhc_1 {
--      pinctrl-0 = <&sdc_default_state>;
--      pinctrl-names = "default";
--      mmc-ddr-1_8v;
--      mmc-hs200-1_8v;
--      mmc-hs400-1_8v;
--      mmc-hs400-enhanced-strobe;
--      max-frequency = <384000000>;
--      bus-width = <8>;
--      status = "okay";
--};
--
- &tlmm {
-       pcie1_default: pcie1-default-state {
diff --git a/target/linux/qualcommbe/patches-6.12/0301-arm64-dts-qcom-Add-IPQ9574-MDIO-device-node.patch b/target/linux/qualcommbe/patches-6.12/0301-arm64-dts-qcom-Add-IPQ9574-MDIO-device-node.patch
deleted file mode 100644 (file)
index c094e6e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-From 657833a74f532262d415fa2ca354b69f4a97353c Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Thu, 23 Nov 2023 15:41:20 +0800
-Subject: [PATCH] arm64: dts: qcom: Add IPQ9574 MDIO device node
-
-The MDIO bus master block is used to accessing the MDIO slave
-device (such as PHY device), the dedicated MDIO PINs needs to
-be configured.
-
-Change-Id: Ia64083529e693256dbd8f8af4071c02afdded8f9
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -295,6 +295,8 @@
-               mdio: mdio@90000 {
-                       compatible =  "qcom,ipq9574-mdio", "qcom,ipq4019-mdio";
-                       reg = <0x00090000 0x64>;
-+                      pinctrl-0 = <&mdio_pins>;
-+                      pinctrl-names = "default";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       clocks = <&gcc GCC_MDIO_AHB_CLK>;
-@@ -414,6 +416,22 @@
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-+                      mdio_pins: mdio-pins {
-+                              mdc-state {
-+                                      pins = "gpio38";
-+                                      function = "mdc";
-+                                      drive-strength = <8>;
-+                                      bias-disable;
-+                              };
-+
-+                              mdio-state {
-+                                      pins = "gpio39";
-+                                      function = "mdio";
-+                                      drive-strength = <8>;
-+                                      bias-pull-up;
-+                              };
-+                      };
-+
-                       uart2_pins: uart2-state {
-                               pins = "gpio34", "gpio35";
-                               function = "blsp2_uart";
diff --git a/target/linux/qualcommbe/patches-6.12/0302-arm64-dts-qcom-ipq9574-Use-usb-phy-for-node-names.patch b/target/linux/qualcommbe/patches-6.12/0302-arm64-dts-qcom-ipq9574-Use-usb-phy-for-node-names.patch
deleted file mode 100644 (file)
index cc71921..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-From 91467ca0db1654644b2168f882f223d47dcfb9c1 Mon Sep 17 00:00:00 2001
-From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
-Date: Sat, 30 Mar 2024 20:03:30 -0500
-Subject: [PATCH] arm64: dts: qcom: ipq9574: Use 'usb-phy' for node names
-
-The devicetree spec allows node names of "usb-phy". So be more
-specific for the USB PHYs, and name the nodes "usb-phy" instead of
-just "phy".
-
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -720,7 +720,7 @@
-                       status = "disabled";
-               };
--              usb_0_qusbphy: phy@7b000 {
-+              usb_0_qusbphy: usb-phy@7b000 {
-                       compatible = "qcom,ipq9574-qusb2-phy";
-                       reg = <0x0007b000 0x180>;
-                       #phy-cells = <0>;
-@@ -734,7 +734,7 @@
-                       status = "disabled";
-               };
--              usb_0_qmpphy: phy@7d000 {
-+              usb_0_qmpphy: usb-phy@7d000 {
-                       compatible = "qcom,ipq9574-qmp-usb3-phy";
-                       reg = <0x0007d000 0xa00>;
-                       #phy-cells = <0>;
diff --git a/target/linux/qualcommbe/patches-6.12/0304-arm64-dts-qcom-ipq9574-add-QPIC-SPI-NAND-default-par.patch b/target/linux/qualcommbe/patches-6.12/0304-arm64-dts-qcom-ipq9574-add-QPIC-SPI-NAND-default-par.patch
deleted file mode 100644 (file)
index b76039c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From be44d0251a2540f3b8d7205e0bc6659704366711 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 30 Jan 2025 00:39:30 +0100
-Subject: [PATCH] arm64: dts: qcom: ipq9574: add QPIC SPI NAND default
- partition nodes
-
-Add QPIC SPI NAND default partition nodes for RDP reference board.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- .../boot/dts/qcom/ipq9574-rdp-common.dtsi     | 28 +++++++++++++++++++
- 1 file changed, 28 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-@@ -189,6 +189,35 @@
-               nand-ecc-engine = <&qpic_nand>;
-               nand-ecc-strength = <4>;
-               nand-ecc-step-size = <512>;
-+
-+              partitions {
-+                      compatible = "fixed-partitions";
-+                      #address-cells = <1>;
-+                      #size-cells = <1>;
-+
-+                      partition@0 {
-+                              label = "0:training";
-+                              reg = <0x0 0x80000>;
-+                              read-only;
-+                      };
-+
-+                      partition@80000 {
-+                              label = "0:license";
-+                              reg = <0x80000 0x40000>;
-+                              read-only;
-+                      };
-+
-+                      partition@c0000 {
-+                              label = "rootfs";
-+                              reg = <0xc0000 0x3c00000>;
-+                              linux,rootfs;
-+                      };
-+
-+                      partition@3cc0000 {
-+                              label = "rootfs_1";
-+                              reg = <0x3cc0000 0x3c00000>;
-+                      };
-+              };
-       };
- };
diff --git a/target/linux/qualcommbe/patches-6.12/0305-arm64-dts-qcom-add-partition-table-for-ipq9574-rdp-c.patch b/target/linux/qualcommbe/patches-6.12/0305-arm64-dts-qcom-add-partition-table-for-ipq9574-rdp-c.patch
deleted file mode 100644 (file)
index 04314f5..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-From 47c7ae9715d76054d98e8407dbb8ca1cf42fd587 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 9 Dec 2024 17:50:31 +0100
-Subject: [PATCH] arm64: dts: qcom: add partition table for ipq9574 rdp common
-
-Add partition table for ipq9574 SoC common to every RDB board.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- .../boot/dts/qcom/ipq9574-rdp-common.dtsi     | 146 +++++++++++++++++-
- 1 file changed, 145 insertions(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
-@@ -74,11 +74,158 @@
-       status = "okay";
-       flash@0 {
--              compatible = "micron,n25q128a11", "jedec,spi-nor";
-+              compatible = "jedec,spi-nor";
-               reg = <0>;
-               #address-cells = <1>;
-               #size-cells = <1>;
-               spi-max-frequency = <50000000>;
-+
-+              partitions {
-+                      compatible = "fixed-partitions";
-+                      #address-cells = <1>;
-+                      #size-cells = <1>;
-+
-+                      partition@0 {
-+                              label = "0:sbl1";
-+                              reg = <0x0 0xc0000>;
-+                              read-only;
-+                      };
-+
-+                      partition@c0000 {
-+                              label = "0:mibib";
-+                              reg = <0xc0000 0x10000>;
-+                              read-only;
-+                      };
-+
-+                      partition@d0000 {
-+                              label = "0:bootconfig";
-+                              reg = <0xd0000 0x20000>;
-+                              read-only;
-+                      };
-+
-+                      partition@f0000 {
-+                              label = "0:bootconfig1";
-+                              reg = <0xf0000 0x20000>;
-+                              read-only;
-+                      };
-+
-+                      partition@110000 {
-+                              label = "0:qsee";
-+                              reg = <0x110000 0x180000>;
-+                              read-only;
-+                      };
-+
-+                      partition@290000 {
-+                              label = "0:qsee_1";
-+                              reg = <0x290000 0x180000>;
-+                              read-only;
-+                      };
-+
-+                      partition@410000 {
-+                              label = "0:devcfg";
-+                              reg = <0x410000 0x10000>;
-+                              read-only;
-+                      };
-+
-+                      partition@420000 {
-+                              label = "0:devcfg_1";
-+                              reg = <0x420000 0x10000>;
-+                              read-only;
-+                      };
-+
-+                      partition@430000 {
-+                              label = "0:apdp";
-+                              reg = <0x430000 0x10000>;
-+                              read-only;
-+                      };
-+
-+                      partition@440000 {
-+                              label = "0:apdp_1";
-+                              reg = <0x440000 0x10000>;
-+                              read-only;
-+                      };
-+
-+                      partition@450000 {
-+                              label = "0:tme";
-+                              reg = <0x450000 0x40000>;
-+                              read-only;
-+                      };
-+
-+                      partition@490000 {
-+                              label = "0:tme_1";
-+                              reg = <0x490000 0x40000>;
-+                              read-only;
-+                      };
-+
-+                      partition@4d0000 {
-+                              label = "0:rpm";
-+                              reg = <0x4d0000 0x20000>;
-+                              read-only;
-+                      };
-+
-+                      partition@4f0000 {
-+                              label = "0:rpm_1";
-+                              reg = <0x4f0000 0x20000>;
-+                              read-only;
-+                      };
-+
-+                      partition@510000 {
-+                              label = "0:cdt";
-+                              reg = <0x510000 0x10000>;
-+                              read-only;
-+                      };
-+
-+                      partition@520000 {
-+                              label = "0:cdt_1";
-+                              reg = <0x520000 0x10000>;
-+                              read-only;
-+                      };
-+
-+                      partition@530000 {
-+                              label = "0:appsblenv";
-+                              reg = <0x530000 0x10000>;
-+
-+                              nvmem-layout {
-+                                      compatible = "u-boot,env";
-+
-+                                      macaddr_lan: ethaddr {
-+                                              #nvmem-cell-cells = <1>;
-+                                      };
-+                              };
-+                      };
-+
-+                      partition@540000 {
-+                              label = "0:appsbl";
-+                              reg = <0x540000 0xa0000>;
-+                              read-only;
-+                      };
-+
-+                      partition@5e0000 {
-+                              label = "0:appsbl_1";
-+                              reg = <0x5e0000 0xa0000>;
-+                              read-only;
-+                      };
-+
-+                      partition@680000 {
-+                              label = "0:art";
-+                              reg = <0x680000 0x100000>;
-+                              read-only;
-+                      };
-+
-+                      partition@780000 {
-+                              label = "0:ethphyfw";
-+                              reg = <0x780000 0x80000>;
-+                              read-only;
-+
-+                              nvmem-layout {
-+                                      compatible = "fixed-layout";
-+
-+                                      aqr_fw: aqr-fw@0 {
-+                                              reg = <0x0 0x5fc02>;
-+                                      };
-+                              };
-+                      };
-+              };
-       };
- };
diff --git a/target/linux/qualcommbe/patches-6.12/0306-dt-bindings-net-Document-Qualcomm-QCA8084-PHY-packag.patch b/target/linux/qualcommbe/patches-6.12/0306-dt-bindings-net-Document-Qualcomm-QCA8084-PHY-packag.patch
deleted file mode 100644 (file)
index a9223c5..0000000
+++ /dev/null
@@ -1,536 +0,0 @@
-From 7b1c4e22532ded6b20ee41936fa38b5ca1e61ff9 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Mon, 29 Jan 2024 17:57:20 +0800
-Subject: [PATCH] dt-bindings: net: Document Qualcomm QCA8084 PHY package
-
-QCA8084 is quad PHY chip, which integrates 4 PHYs, 2 PCS
-interfaces (PCS0 and PCS1) and clock controller, which can
-also be integrated to the switch chip named as QCA8386.
-
-1. MDIO address of 4 PHYs, 2 PCS and 1 XPCS (PCS1 includes
-   PCS and XPCS, PCS0 includes PCS) can be configured.
-2. The package mode of PHY is optionally configured for the
-   interface mode of two PCSes working correctly.
-3. The package level clock and reset need to be initialized.
-4. The clock and reset per PHY device need to be initialized
-   so that the PHY register can be accessed.
-
-Change-Id: Idb2338d2673152cbd3c57e95968faa59e9d4a80f
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: Update to match the patches that will be upstream.
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- .../devicetree/bindings/net/qcom,qca8084.yaml | 488 ++++++++++++++++++
- include/dt-bindings/net/qcom,qca808x.h        |  14 +
- 2 files changed, 502 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/qcom,qca8084.yaml
- create mode 100644 include/dt-bindings/net/qcom,qca808x.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/qcom,qca8084.yaml
-@@ -0,0 +1,488 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/qcom,qca8084.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Qualcomm QCA8084 Ethernet Quad PHY
-+
-+maintainers:
-+  - Luo Jie <quic_luoj@quicinc.com>
-+
-+description:
-+  Qualcomm QCA8084 is PHY package of four-port Ethernet transceiver,
-+  the Ethernet port supports link speed 10/100/1000/2500 Mbps.
-+  There are two PCSes (PCS0 and PCS1) integrated in the PHY
-+  package, PCS1 includes XPCS and PCS to support the interface
-+  mode 10G-QXGMII and SGMII, PCS0 includes a PCS to support the
-+  interface mode SGMII only. There is also a clock controller
-+  integrated in the PHY package. This four-port Ethernet
-+  transceiver can also be integrated to the switch chip named
-+  as QCA8386. The PHY package mode needs to be configured as the
-+  correct value to apply the interface mode of two PCSes as
-+  mentioned below.
-+
-+  QCA8084 expects an input reference clock 50 MHZ as the clock
-+  source of the integrated clock controller, the integrated
-+  clock controller supplies the clocks and resets to the
-+  integrated PHY, PCS and PHY package.
-+
-+  - |
-+                 +--| |--+-------------------+--| |--+
-+                 | PCS1  |<------------+---->| PCS0  |
-+                 +-------+             |     +-------+
-+                 |                     |             |
-+    Ref 50M clk  +--------+            |             |
-+    ------------>|        | clk & rst  |             |
-+    GPIO Reset   |QCA8K-CC+------------+             |
-+    ------------>|        |            |             |
-+                 +--------+            |             |
-+                 |                     V             |
-+                 +--------+--------+--------+--------+
-+                 |  PHY0  |  PHY1  |  PHY2  |  PHY3  |
-+                 +--------+--------+--------+--------+
-+
-+properties:
-+  compatible:
-+    const: qcom,qca8084-package
-+
-+  clocks:
-+    description:
-+      PHY package level initial common clocks, which are needed to
-+      be enabled after GPIO reset on the PHY package, these clocks
-+      are supplied from the PHY integrated clock controller (QCA8K-CC).
-+    items:
-+      - description: APB bridge clock
-+      - description: AHB clock
-+      - description: Security control clock
-+      - description: TLMM clock
-+      - description: TLMM AHB clock
-+      - description: CNOC AHB clock
-+      - description: MDIO AHB clock
-+
-+  clock-names:
-+    items:
-+      - const: apb_bridge
-+      - const: ahb
-+      - const: sec_ctrl_ahb
-+      - const: tlmm
-+      - const: tlmm_ahb
-+      - const: cnoc_ahb
-+      - const: mdio_ahb
-+
-+  resets:
-+    description:
-+      PHY package level initial common reset, which are needed to
-+      be deasserted after GPIO reset on the PHY package, this reset
-+      is provided by the PHY integrated clock controller to do PHY
-+      DSP reset.
-+    maxItems: 1
-+
-+  qcom,package-mode:
-+    description: |
-+      The package mode of PHY supports to be configured as 3 modes
-+      to apply the combinations of interface mode of two PCSes
-+      correctly. This value should use one of the values defined in
-+      dt-bindings/net/qcom,qca808x.h. The package mode 10G-QXGMII of
-+      Quad PHY is used by default.
-+
-+      package mode             PCS1             PCS0
-+      phy mode (0)             10G-QXGMII for   not used
-+                               PHY0-PHY3
-+
-+      switch mode (1)          SGMII for        SGMII for
-+                               switch MAC0      switch MAC5 (optional)
-+
-+      switch bypass MAC5 (2)   SGMII for        SGMII for
-+                               switch MAC0      PHY3
-+    $ref: /schemas/types.yaml#/definitions/uint32
-+    enum: [0, 1, 2]
-+    default: 0
-+
-+  qcom,phy-addr-fixup:
-+    description:
-+      MDIO address for PHY0-PHY3, PCS0 and PCS1 including PCS and XPCS,
-+      which can be optionally customized by programming the security
-+      control register of PHY package. The hardware default MDIO address
-+      of PHY0-PHY3, PCS0 and PCS1 including PCS and XPCS is 0-6.
-+    $ref: /schemas/types.yaml#/definitions/uint32-array
-+    minItems: 7
-+    maxItems: 7
-+
-+patternProperties:
-+  ^ethernet-phy@[a-f0-9]+$:
-+    unevaluatedProperties: false
-+    $ref: ethernet-phy.yaml#
-+
-+    properties:
-+      compatible:
-+        const: ethernet-phy-id004d.d180
-+
-+      qcom,xpcs-channel:
-+        description:
-+          When PCS1 works on the interface mode 10G-QXGMII, the integrated
-+          XPCS including 4 channels is used to connected with the Quad PHYs,
-+          each PHY needs to be specified the XPCS channel ID to deliver the
-+          PHY link status to the XPCS.
-+        $ref: /schemas/types.yaml#/definitions/uint32
-+        enum: [0, 1, 2, 3]
-+
-+    required:
-+      - compatible
-+      - reg
-+      - clocks
-+      - resets
-+
-+  ^pcs-phy@[a-f0-9]+$:
-+    type: object
-+    additionalProperties: false
-+    description:
-+      PCS device has the independent MDIO address, which controls
-+      the interface mode used and provides the clocks such as
-+      312.5 MHZ as RX and TX root clocks to the integrated clock
-+      controller.
-+    properties:
-+      compatible:
-+        const: qcom,qca8k-pcs-phy
-+
-+      reg:
-+        items:
-+          - description: PCS MDIO address.
-+
-+      clocks:
-+        items:
-+          - description: PCS clock.
-+          - description: PCS RX root clock.
-+          - description: PCS TX root clock.
-+
-+      clock-names:
-+        items:
-+          - const: pcs
-+          - const: pcs_rx_root
-+          - const: pcs_tx_root
-+
-+      resets:
-+        items:
-+          - description: PCS reset.
-+
-+    required:
-+      - compatible
-+      - reg
-+      - clocks
-+      - resets
-+
-+  ^xpcs-phy@[a-f0-9]+$:
-+    type: object
-+    additionalProperties: false
-+    description:
-+      XPCS device has the independent MDIO address, which includes 4
-+      channels to connect with Quad PHYs.
-+    properties:
-+      compatible:
-+        const: qcom,qca8k-xpcs-phy
-+
-+      reg:
-+        items:
-+          - description: XPCS MDIO address.
-+
-+      resets:
-+        items:
-+          - description: XPCS reset.
-+
-+      '#address-cells':
-+        const: 1
-+
-+      '#size-cells':
-+        const: 0
-+
-+    required:
-+      - compatible
-+      - reg
-+      - resets
-+      - '#address-cells'
-+      - '#size-cells'
-+
-+    patternProperties:
-+      "^channel@[0-3]+$":
-+        type: object
-+        additionalProperties: false
-+        description:
-+          XPCS is used to support 10G-QXGMII mode, which inlcudes 4 channels
-+          to be connected with Quad PHYs, each channels has the dedicated
-+          clocks and resets from the integrated clock controller of QCA8084.
-+
-+        properties:
-+          reg:
-+            items:
-+              - description: XPCS channel ID
-+
-+          clocks:
-+            items:
-+              - description: XPCS XGMII RX clock
-+              - description: XPCS XGMII TX clock
-+              - description: XPCS RX clock
-+              - description: XPCS TX clock
-+              - description: Port RX clock
-+              - description: Port TX clock
-+              - description: RX source clock
-+              - description: TX source clock
-+
-+          clock-names:
-+            items:
-+              - const: xgmii_rx
-+              - const: xgmii_tx
-+              - const: xpcs_rx
-+              - const: xpcs_tx
-+              - const: port_rx
-+              - const: port_tx
-+              - const: rx_src
-+              - const: tx_src
-+
-+          resets:
-+            items:
-+              - description: XPCS XGMII RX reset
-+              - description: XPCS XGMII TX reset
-+              - description: XPCS RX reset
-+              - description: XPCS TX reset
-+              - description: Port RX reset
-+              - description: Port TX reset
-+
-+          reset-names:
-+            items:
-+              - const: xgmii_rx
-+              - const: xgmii_tx
-+              - const: xpcs_rx
-+              - const: xpcs_tx
-+              - const: port_rx
-+              - const: port_tx
-+
-+        required:
-+          - reg
-+          - clocks
-+          - clock-names
-+          - resets
-+          - reset-names
-+
-+required:
-+  - compatible
-+  - clocks
-+  - clock-names
-+  - resets
-+
-+allOf:
-+  - $ref: ethernet-phy-package.yaml#
-+
-+unevaluatedProperties: false
-+
-+examples:
-+  - |
-+    #include <dt-bindings/clock/qcom,qca8k-nsscc.h>
-+    #include <dt-bindings/net/qcom,qca808x.h>
-+    #include <dt-bindings/reset/qcom,qca8k-nsscc.h>
-+
-+    mdio {
-+        #address-cells = <1>;
-+        #size-cells = <0>;
-+
-+        ethernet-phy-package@1 {
-+            #address-cells = <1>;
-+            #size-cells = <0>;
-+            compatible = "qcom,qca8084-package";
-+            reg = <1>;
-+            clocks = <&qca8k_nsscc NSS_CC_APB_BRIDGE_CLK>,
-+                     <&qca8k_nsscc NSS_CC_AHB_CLK>,
-+                     <&qca8k_nsscc NSS_CC_SEC_CTRL_AHB_CLK>,
-+                     <&qca8k_nsscc NSS_CC_TLMM_CLK>,
-+                     <&qca8k_nsscc NSS_CC_TLMM_AHB_CLK>,
-+                     <&qca8k_nsscc NSS_CC_CNOC_AHB_CLK>,
-+                     <&qca8k_nsscc NSS_CC_MDIO_AHB_CLK>;
-+            clock-names = "apb_bridge",
-+                          "ahb",
-+                          "sec_ctrl_ahb",
-+                          "tlmm",
-+                          "tlmm_ahb",
-+                          "cnoc_ahb",
-+                          "mdio_ahb";
-+            resets = <&qca8k_nsscc NSS_CC_GEPHY_FULL_ARES>;
-+            qcom,package-mode = <QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED>;
-+            qcom,phy-addr-fixup = <1 2 3 4 5 6 7>;
-+
-+            ethernet-phy@1 {
-+                compatible = "ethernet-phy-id004d.d180";
-+                reg = <1>;
-+                clocks = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_CLK>;
-+                resets = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_ARES>;
-+                qcom,xpcs-channel = <0>;
-+            };
-+
-+            ethernet-phy@2 {
-+                compatible = "ethernet-phy-id004d.d180";
-+                reg = <2>;
-+                clocks = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_CLK>;
-+                resets = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_ARES>;
-+                qcom,xpcs-channel = <1>;
-+            };
-+
-+            ethernet-phy@3 {
-+                compatible = "ethernet-phy-id004d.d180";
-+                reg = <3>;
-+                clocks = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_CLK>;
-+                resets = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_ARES>;
-+                qcom,xpcs-channel = <2>;
-+            };
-+
-+            ethernet-phy@4 {
-+                compatible = "ethernet-phy-id004d.d180";
-+                reg = <4>;
-+                clocks = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_CLK>;
-+                resets = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_ARES>;
-+                qcom,xpcs-channel = <3>;
-+            };
-+
-+            pcs-phy@6 {
-+                compatible = "qcom,qca8k-pcs-phy";
-+                reg = <6>;
-+                clocks = <&qca8k_nsscc NSS_CC_SRDS1_SYS_CLK>,
-+                         <&qca8k_uniphy1_tx312p5m>,
-+                         <&qca8k_uniphy1_rx312p5m>;
-+                clock-names = "pcs", "pcs_rx_root", "pcs_tx_root";
-+                resets = <&qca8k_nsscc NSS_CC_SRDS1_SYS_ARES>;
-+            };
-+
-+            xpcs-phy@7 {
-+                compatible = "qcom,qca8k-xpcs-phy";
-+                reg = <7>;
-+                #address-cells = <1>;
-+                #size-cells = <0>;
-+                resets = <&qca8k_nsscc NSS_CC_XPCS_ARES>;
-+
-+                channel@0 {
-+                    reg = <0>;
-+                    clocks = <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_GEPHY0_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_GEPHY0_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_RX_CLK_SRC>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_TX_CLK_SRC>;
-+                    clock-names = "xgmii_rx",
-+                                  "xgmii_tx",
-+                                  "xpcs_rx",
-+                                  "xpcs_tx",
-+                                  "port_rx",
-+                                  "port_tx",
-+                                  "rx_src",
-+                                  "tx_src";
-+                    resets = <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_TX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_GEPHY0_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC1_GEPHY0_TX_ARES>;
-+                    reset-names = "xgmii_rx",
-+                                  "xgmii_tx",
-+                                  "xpcs_rx",
-+                                  "xpcs_tx",
-+                                  "port_rx",
-+                                  "port_tx";
-+                };
-+
-+                channel@1 {
-+                    reg = <1>;
-+                    clocks = <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_GEPHY1_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_GEPHY1_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_RX_CLK_SRC>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_TX_CLK_SRC>;
-+                    clock-names = "xgmii_rx",
-+                                  "xgmii_tx",
-+                                  "xpcs_rx",
-+                                  "xpcs_tx",
-+                                  "port_rx",
-+                                  "port_tx",
-+                                  "rx_src",
-+                                  "tx_src";
-+                    resets = <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_TX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_GEPHY1_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC2_GEPHY1_TX_ARES>;
-+                    reset-names = "xgmii_rx",
-+                                  "xgmii_tx",
-+                                  "xpcs_rx",
-+                                  "xpcs_tx",
-+                                  "port_rx",
-+                                  "port_tx";
-+                };
-+
-+                channel@2 {
-+                    reg = <2>;
-+                    clocks = <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_GEPHY2_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_GEPHY2_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_RX_CLK_SRC>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_TX_CLK_SRC>;
-+                    clock-names = "xgmii_rx",
-+                                  "xgmii_tx",
-+                                  "xpcs_rx",
-+                                  "xpcs_tx",
-+                                  "port_rx",
-+                                  "port_tx",
-+                                  "rx_src",
-+                                  "tx_src";
-+                    resets = <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_TX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_GEPHY2_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC3_GEPHY2_TX_ARES>;
-+                    reset-names = "xgmii_rx",
-+                                  "xgmii_tx",
-+                                  "xpcs_rx",
-+                                  "xpcs_tx",
-+                                  "port_rx",
-+                                  "port_tx";
-+                };
-+
-+                channel@3 {
-+                    reg = <3>;
-+                    clocks = <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_GEPHY3_RX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_GEPHY3_TX_CLK>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_RX_CLK_SRC>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_TX_CLK_SRC>;
-+                    clock-names = "xgmii_rx",
-+                                  "xgmii_tx",
-+                                  "xpcs_rx",
-+                                  "xpcs_tx",
-+                                  "port_rx",
-+                                  "port_tx",
-+                                  "rx_src",
-+                                  "tx_src";
-+                    resets = <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_TX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_GEPHY3_RX_ARES>,
-+                             <&qca8k_nsscc NSS_CC_MAC4_GEPHY3_TX_ARES>;
-+                    reset-names = "xgmii_rx",
-+                                  "xgmii_tx",
-+                                  "xpcs_rx",
-+                                  "xpcs_tx",
-+                                  "port_rx",
-+                                  "port_tx";
-+                };
-+            };
-+        };
-+    };
---- /dev/null
-+++ b/include/dt-bindings/net/qcom,qca808x.h
-@@ -0,0 +1,14 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Device Tree constants for the Qualcomm QCA808X PHYs
-+ */
-+
-+#ifndef _DT_BINDINGS_QCOM_QCA808X_H
-+#define _DT_BINDINGS_QCOM_QCA808X_H
-+
-+/* PHY package modes of QCA8084 to apply the interface modes of two PCSes. */
-+#define QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED          0
-+#define QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_MAC         1
-+#define QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_PHY         2
-+
-+#endif
diff --git a/target/linux/qualcommbe/patches-6.12/0307-net-phy-qca808x-Add-QCA8084-ethernet-phy-support.patch b/target/linux/qualcommbe/patches-6.12/0307-net-phy-qca808x-Add-QCA8084-ethernet-phy-support.patch
deleted file mode 100644 (file)
index 360517f..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-From 60c44842f9611be237ab3f68afe8ebf2d9595fb2 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Thu, 6 Apr 2023 18:09:07 +0800
-Subject: [PATCH] net: phy: qca808x: Add QCA8084 ethernet phy support
-
-Add QCA8084 Quad-PHY support, which is a four-port PHY with
-maximum link capability of 2.5 Gbps. The features of each port
-are almost same as QCA8081. The slave seed and fast retrain
-configs are not needed for QCA8084. It includes two PCSes.
-
-PCS0 of QCA8084 supports the interface modes:
-PHY_INTERFACE_MODE_2500BASEX and PHY_INTERFACE_MODE_SGMII.
-
-PCS1 of QCA8084 supports the interface modes:
-PHY_INTERFACE_MODE_10G_QXGMII, PHY_INTERFACE_MODE_2500BASEX and
-PHY_INTERFACE_MODE_SGMII.
-
-The additional CDT configurations needed for QCA8084 compared
-with QCA8081.
-
-Change-Id: I12555fa70662682474ab4432204405b5e752fef6
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: Update to match the patches that will be upstream.
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/phy/qcom/qca808x.c | 65 ++++++++++++++++++++++++++++++++--
- 1 file changed, 63 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -86,9 +86,16 @@
- #define QCA8081_PHY_FIFO_RSTN                 BIT(11)
- #define QCA8081_PHY_ID                                0x004dd101
-+#define QCA8084_PHY_ID                                0x004dd180
-+
-+#define QCA8084_MMD3_CDT_PULSE_CTRL           0x8075
-+#define QCA8084_CDT_PULSE_THRESH_VAL          0xa060
-+
-+#define QCA8084_MMD3_CDT_NEAR_CTRL            0x807f
-+#define QCA8084_CDT_NEAR_BYPASS                       BIT(15)
- MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
--MODULE_AUTHOR("Matus Ujhelyi");
-+MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
- MODULE_LICENSE("GPL");
- struct qca808x_priv {
-@@ -153,13 +160,18 @@ static bool qca808x_is_prefer_master(str
- static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
- {
--      return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
-+      return phydev_id_compare(phydev, QCA8081_PHY_ID) &&
-+              linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-+                                phydev->supported);
- }
- static bool qca808x_is_1g_only(struct phy_device *phydev)
- {
-       int ret;
-+      if (!phydev_id_compare(phydev, QCA8081_PHY_ID))
-+              return false;
-+
-       ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
-       if (ret < 0)
-               return true;
-@@ -273,6 +285,23 @@ static int qca808x_read_status(struct ph
-               return ret;
-       if (phydev->link) {
-+              /* There are two PCSes available for QCA8084, which support
-+               * the following interface modes.
-+               *
-+               * 1. PHY_INTERFACE_MODE_10G_QXGMII utilizes PCS1 for all
-+               * available 4 ports, which is for all link speeds.
-+               *
-+               * 2. PHY_INTERFACE_MODE_2500BASEX utilizes PCS0 for the
-+               * fourth port, which is only for the link speed 2500M same
-+               * as QCA8081.
-+               *
-+               * 3. PHY_INTERFACE_MODE_SGMII utilizes PCS0 for the fourth
-+               * port, which is for the link speed 10M, 100M and 1000M same
-+               * as QCA8081.
-+               */
-+              if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
-+                      return 0;
-+
-               if (phydev->speed == SPEED_2500)
-                       phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-               else
-@@ -352,6 +381,18 @@ static int qca808x_cable_test_start(stru
-       phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
-       phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
-+      if (phydev_id_compare(phydev, QCA8084_PHY_ID)) {
-+              /* Adjust the positive and negative pulse thereshold of CDT. */
-+              phy_write_mmd(phydev, MDIO_MMD_PCS,
-+                            QCA8084_MMD3_CDT_PULSE_CTRL,
-+                            QCA8084_CDT_PULSE_THRESH_VAL);
-+
-+              /* Disable the near bypass of CDT. */
-+              phy_modify_mmd(phydev, MDIO_MMD_PCS,
-+                             QCA8084_MMD3_CDT_NEAR_CTRL,
-+                             QCA8084_CDT_NEAR_BYPASS, 0);
-+      }
-+
-       return 0;
- }
-@@ -651,12 +692,32 @@ static struct phy_driver qca808x_driver[
-       .led_hw_control_set     = qca808x_led_hw_control_set,
-       .led_hw_control_get     = qca808x_led_hw_control_get,
-       .led_polarity_set       = qca808x_led_polarity_set,
-+}, {
-+      /* Qualcomm QCA8084 */
-+      PHY_ID_MATCH_MODEL(QCA8084_PHY_ID),
-+      .name                   = "Qualcomm QCA8084",
-+      .flags                  = PHY_POLL_CABLE_TEST,
-+      .config_intr            = at803x_config_intr,
-+      .handle_interrupt       = at803x_handle_interrupt,
-+      .get_tunable            = at803x_get_tunable,
-+      .set_tunable            = at803x_set_tunable,
-+      .set_wol                = at803x_set_wol,
-+      .get_wol                = at803x_get_wol,
-+      .get_features           = qca808x_get_features,
-+      .config_aneg            = qca808x_config_aneg,
-+      .suspend                = genphy_suspend,
-+      .resume                 = genphy_resume,
-+      .read_status            = qca808x_read_status,
-+      .soft_reset             = qca808x_soft_reset,
-+      .cable_test_start       = qca808x_cable_test_start,
-+      .cable_test_get_status  = qca808x_cable_test_get_status,
- }, };
- module_phy_driver(qca808x_driver);
- static const struct mdio_device_id __maybe_unused qca808x_tbl[] = {
-       { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
-+      { PHY_ID_MATCH_MODEL(QCA8084_PHY_ID) },
-       { }
- };
diff --git a/target/linux/qualcommbe/patches-6.12/0308-net-phy-qca808x-Add-config_init-function-for-QCA8084.patch b/target/linux/qualcommbe/patches-6.12/0308-net-phy-qca808x-Add-config_init-function-for-QCA8084.patch
deleted file mode 100644 (file)
index 8ac94c8..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From c052b9a4ab869cc54976402b3f9dbdef5bdb9f27 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Wed, 8 Nov 2023 16:18:02 +0800
-Subject: [PATCH] net: phy: qca808x: Add config_init function for QCA8084
-
-1. The ADC of QCA8084 PHY must be configured as edge inverted
-and falling whenever it is initialized or reset. In addition,
-the default MSE (Mean square error) threshold value is adjusted,
-which comes into play during link partner detection to detect
-the valid link signal.
-
-2. Add the possible interface modes.
-   When QCA8084 works on the interface mode SGMII or 2500BASE-X, the
-   interface mode can be switched according to the PHY link speed.
-
-   When QCA8084 works on the 10G-QXGMII mode, which will be the only
-   possible interface mode.
-
-Change-Id: I832c0d0b069e95cc411a8a7b680a5f60e1d6041a
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- drivers/net/phy/qcom/qca808x.c | 38 ++++++++++++++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -94,6 +94,15 @@
- #define QCA8084_MMD3_CDT_NEAR_CTRL            0x807f
- #define QCA8084_CDT_NEAR_BYPASS                       BIT(15)
-+/* QCA8084 ADC clock edge */
-+#define QCA8084_ADC_CLK_SEL                   0x8b80
-+#define QCA8084_ADC_CLK_SEL_ACLK              GENMASK(7, 4)
-+#define QCA8084_ADC_CLK_SEL_ACLK_FALL         0xf
-+#define QCA8084_ADC_CLK_SEL_ACLK_RISE         0x0
-+
-+#define QCA8084_MSE_THRESHOLD                 0x800a
-+#define QCA8084_MSE_THRESHOLD_2P5G_VAL                0x51c6
-+
- MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
- MODULE_LICENSE("GPL");
-@@ -663,6 +672,34 @@ static int qca808x_led_polarity_set(stru
-                             active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
- }
-+static int qca8084_config_init(struct phy_device *phydev)
-+{
-+      int ret;
-+
-+      if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
-+              __set_bit(PHY_INTERFACE_MODE_10G_QXGMII,
-+                        phydev->possible_interfaces);
-+      else
-+              qca808x_fill_possible_interfaces(phydev);
-+
-+      /* Configure the ADC to convert the signal using falling edge
-+       * instead of the default rising edge.
-+       */
-+      ret = at803x_debug_reg_mask(phydev, QCA8084_ADC_CLK_SEL,
-+                                  QCA8084_ADC_CLK_SEL_ACLK,
-+                                  FIELD_PREP(QCA8084_ADC_CLK_SEL_ACLK,
-+                                             QCA8084_ADC_CLK_SEL_ACLK_FALL));
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Adjust MSE threshold value to avoid link issue with
-+       * some link partner.
-+       */
-+      return phy_write_mmd(phydev, MDIO_MMD_PMAPMD,
-+                           QCA8084_MSE_THRESHOLD,
-+                           QCA8084_MSE_THRESHOLD_2P5G_VAL);
-+}
-+
- static struct phy_driver qca808x_driver[] = {
- {
-       /* Qualcomm QCA8081 */
-@@ -711,6 +748,7 @@ static struct phy_driver qca808x_driver[
-       .soft_reset             = qca808x_soft_reset,
-       .cable_test_start       = qca808x_cable_test_start,
-       .cable_test_get_status  = qca808x_cable_test_get_status,
-+      .config_init            = qca8084_config_init,
- }, };
- module_phy_driver(qca808x_driver);
diff --git a/target/linux/qualcommbe/patches-6.12/0309-net-phy-qca808x-Add-link_change_notify-function-for-.patch b/target/linux/qualcommbe/patches-6.12/0309-net-phy-qca808x-Add-link_change_notify-function-for-.patch
deleted file mode 100644 (file)
index e00a582..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-From aec49c172cd9c739c1d97ff2d42b9718bb20b609 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Wed, 8 Nov 2023 18:01:14 +0800
-Subject: [PATCH] net: phy: qca808x: Add link_change_notify function for
- QCA8084
-
-When the link is changed, QCA8084 needs to do the fifo reset and
-adjust the IPG level for the 10G-QXGMII link on the speed 1000M.
-
-Change-Id: I21de802c78496fb95f1c5119fe3894c9fdebbd65
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- drivers/net/phy/qcom/qca808x.c | 52 ++++++++++++++++++++++++++++++++++
- 1 file changed, 52 insertions(+)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -103,6 +103,14 @@
- #define QCA8084_MSE_THRESHOLD                 0x800a
- #define QCA8084_MSE_THRESHOLD_2P5G_VAL                0x51c6
-+/* QCA8084 FIFO reset control */
-+#define QCA8084_FIFO_CONTROL                  0x19
-+#define QCA8084_FIFO_MAC_2_PHY                        BIT(1)
-+#define QCA8084_FIFO_PHY_2_MAC                        BIT(0)
-+
-+#define QCA8084_MMD7_IPG_OP                   0x901d
-+#define QCA8084_IPG_10_TO_11_EN                       BIT(0)
-+
- MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
- MODULE_LICENSE("GPL");
-@@ -700,6 +708,49 @@ static int qca8084_config_init(struct ph
-                            QCA8084_MSE_THRESHOLD_2P5G_VAL);
- }
-+static void qca8084_link_change_notify(struct phy_device *phydev)
-+{
-+      int ret;
-+
-+      /* Assert the FIFO between PHY and MAC. */
-+      ret = phy_modify(phydev, QCA8084_FIFO_CONTROL,
-+                       QCA8084_FIFO_MAC_2_PHY | QCA8084_FIFO_PHY_2_MAC,
-+                       0);
-+      if (ret) {
-+              phydev_err(phydev, "Asserting PHY FIFO failed\n");
-+              return;
-+      }
-+
-+      /* If the PHY is in 10G_QXGMII mode, the FIFO needs to be kept in
-+       * reset state when link is down, otherwise the FIFO needs to be
-+       * de-asserted after waiting 50 ms to make the assert completed.
-+       */
-+      if (phydev->interface != PHY_INTERFACE_MODE_10G_QXGMII ||
-+          phydev->link) {
-+              msleep(50);
-+
-+              /* Deassert the FIFO between PHY and MAC. */
-+              ret = phy_modify(phydev, QCA8084_FIFO_CONTROL,
-+                               QCA8084_FIFO_MAC_2_PHY |
-+                               QCA8084_FIFO_PHY_2_MAC,
-+                               QCA8084_FIFO_MAC_2_PHY |
-+                               QCA8084_FIFO_PHY_2_MAC);
-+              if (ret) {
-+                      phydev_err(phydev, "De-asserting PHY FIFO failed\n");
-+                      return;
-+              }
-+      }
-+
-+      /* Enable IPG level 10 to 11 tuning for link speed 1000M in the
-+       * 10G_QXGMII mode.
-+       */
-+      if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
-+              phy_modify_mmd(phydev, MDIO_MMD_AN, QCA8084_MMD7_IPG_OP,
-+                             QCA8084_IPG_10_TO_11_EN,
-+                             phydev->speed == SPEED_1000 ?
-+                             QCA8084_IPG_10_TO_11_EN : 0);
-+}
-+
- static struct phy_driver qca808x_driver[] = {
- {
-       /* Qualcomm QCA8081 */
-@@ -749,6 +800,7 @@ static struct phy_driver qca808x_driver[
-       .cable_test_start       = qca808x_cable_test_start,
-       .cable_test_get_status  = qca808x_cable_test_get_status,
-       .config_init            = qca8084_config_init,
-+      .link_change_notify     = qca8084_link_change_notify,
- }, };
- module_phy_driver(qca808x_driver);
diff --git a/target/linux/qualcommbe/patches-6.12/0310-net-phy-qca808x-Add-register-access-support-routines.patch b/target/linux/qualcommbe/patches-6.12/0310-net-phy-qca808x-Add-register-access-support-routines.patch
deleted file mode 100644 (file)
index c1673ae..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-From cea8043def0c0867370c2efd5a1cd73bf4d3e5ba Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Wed, 29 Nov 2023 15:21:22 +0800
-Subject: [PATCH] net: phy: qca808x: Add register access support routines for
- QCA8084
-
-QCA8084 integrates clock controller and security control modules
-besides of the PHY and PCS. The 32bit registers in these modules
-are accessed using special MDIO sequences to read or write these
-registers.
-
-The MDIO address of PHY and PCS are configured by writing to the
-security control register. The package mode for QCA8084 is also
-configured in a similar manner.
-
-Change-Id: I9317307ef9bbc738a6adcbc3ea1be8e6528d711e
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- drivers/net/phy/qcom/qca808x.c | 88 ++++++++++++++++++++++++++++++++++
- 1 file changed, 88 insertions(+)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -111,6 +111,22 @@
- #define QCA8084_MMD7_IPG_OP                   0x901d
- #define QCA8084_IPG_10_TO_11_EN                       BIT(0)
-+/* QCA8084 includes secure control module, which supports customizing the
-+ * MDIO address of PHY device and PCS device and configuring package mode
-+ * for the interface mode of PCS. The register of secure control is accessed
-+ * by MDIO bus with the special MDIO sequences, where the 32 bits register
-+ * address is split into 3 MDIO operations with 16 bits address.
-+ */
-+#define QCA8084_HIGH_ADDR_PREFIX              0x18
-+#define QCA8084_LOW_ADDR_PREFIX                       0x10
-+
-+/* Bottom two bits of REG must be zero */
-+#define QCA8084_MII_REG_MASK                  GENMASK(4, 0)
-+#define QCA8084_MII_PHY_ADDR_MASK             GENMASK(7, 5)
-+#define QCA8084_MII_PAGE_MASK                 GENMASK(23, 8)
-+#define QCA8084_MII_SW_ADDR_MASK              GENMASK(31, 24)
-+#define QCA8084_MII_REG_DATA_UPPER_16_BITS    BIT(1)
-+
- MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
- MODULE_LICENSE("GPL");
-@@ -119,6 +135,78 @@ struct qca808x_priv {
-       int led_polarity_mode;
- };
-+static int __qca8084_set_page(struct mii_bus *bus, u16 sw_addr, u16 page)
-+{
-+      return __mdiobus_write(bus, QCA8084_HIGH_ADDR_PREFIX | (sw_addr >> 5),
-+                             sw_addr & 0x1f, page);
-+}
-+
-+static int __qca8084_mii_read(struct mii_bus *bus, u16 addr, u16 reg, u32 *val)
-+{
-+      int ret, data;
-+
-+      ret = __mdiobus_read(bus, addr, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      data = ret;
-+      ret = __mdiobus_read(bus, addr,
-+                           reg | QCA8084_MII_REG_DATA_UPPER_16_BITS);
-+      if (ret < 0)
-+              return ret;
-+
-+      *val =  data | ret << 16;
-+
-+      return 0;
-+}
-+
-+static int __qca8084_mii_write(struct mii_bus *bus, u16 addr, u16 reg, u32 val)
-+{
-+      int ret;
-+
-+      ret = __mdiobus_write(bus, addr, reg, lower_16_bits(val));
-+      if (!ret)
-+              ret = __mdiobus_write(bus, addr,
-+                                    reg | QCA8084_MII_REG_DATA_UPPER_16_BITS,
-+                                    upper_16_bits(val));
-+
-+      return ret;
-+}
-+
-+static int qca8084_mii_modify(struct phy_device *phydev, u32 regaddr,
-+                            u32 clear, u32 set)
-+{
-+      u16 reg, addr, page, sw_addr;
-+      struct mii_bus *bus;
-+      u32 val;
-+      int ret;
-+
-+      bus = phydev->mdio.bus;
-+      mutex_lock(&bus->mdio_lock);
-+
-+      reg = FIELD_GET(QCA8084_MII_REG_MASK, regaddr);
-+      addr = FIELD_GET(QCA8084_MII_PHY_ADDR_MASK, regaddr);
-+      page = FIELD_GET(QCA8084_MII_PAGE_MASK, regaddr);
-+      sw_addr = FIELD_GET(QCA8084_MII_SW_ADDR_MASK, regaddr);
-+
-+      ret = __qca8084_set_page(bus, sw_addr, page);
-+      if (ret < 0)
-+              goto qca8084_mii_modify_exit;
-+
-+      ret = __qca8084_mii_read(bus, QCA8084_LOW_ADDR_PREFIX | addr,
-+                               reg, &val);
-+      if (ret < 0)
-+              goto qca8084_mii_modify_exit;
-+
-+      val &= ~clear;
-+      val |= set;
-+      ret = __qca8084_mii_write(bus, QCA8084_LOW_ADDR_PREFIX | addr,
-+                                reg, val);
-+qca8084_mii_modify_exit:
-+      mutex_unlock(&bus->mdio_lock);
-+      return ret;
-+};
-+
- static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
- {
-       int ret;
diff --git a/target/linux/qualcommbe/patches-6.12/0311-net-phy-qca808x-Add-QCA8084-probe-function.patch b/target/linux/qualcommbe/patches-6.12/0311-net-phy-qca808x-Add-QCA8084-probe-function.patch
deleted file mode 100644 (file)
index e74fc0b..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-From a7fe2c13f3188bf01b60fb15063d028c76dd2f1a Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Mon, 29 Jan 2024 10:51:38 +0800
-Subject: [PATCH] net: phy: qca808x: Add QCA8084 probe function
-
-Add the PHY package probe function. The MDIO slave address of
-PHY, PCS and XPCS can be optionally customized by configuring
-the PHY package level register.
-
-In addition, enable system clock of PHY and de-assert PHY in
-the probe function so that the register of PHY device can be
-accessed, and the features of PHY can be acquired.
-
-Change-Id: I2251b9c5c398a21a4ef547a727189a934ad3a44c
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: include <linux/reset.h>
-        include "phylib.h" for phy_package_*() declarations
-        select PHY_PACKAGE in Kconfig
-        use phy_package_get_node() instead of phylib->shared->np
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
-
-freckup c89414adf2ec7c
-
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/phy/qcom/Kconfig   |  1 +
- drivers/net/phy/qcom/qca808x.c | 92 ++++++++++++++++++++++++++++++++++
- 2 files changed, 93 insertions(+)
-
---- a/drivers/net/phy/qcom/Kconfig
-+++ b/drivers/net/phy/qcom/Kconfig
-@@ -18,6 +18,7 @@ config QCA83XX_PHY
- config QCA808X_PHY
-       tristate "Qualcomm QCA808x PHYs"
-       select QCOM_NET_PHYLIB
-+      select PHY_PACKAGE
-       help
-         Currently supports the QCA8081 model
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -2,7 +2,11 @@
- #include <linux/phy.h>
- #include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/reset.h>
-+#include <linux/clk.h>
-+#include "../phylib.h"
- #include "qcom.h"
- /* ADC threshold */
-@@ -127,6 +131,21 @@
- #define QCA8084_MII_SW_ADDR_MASK              GENMASK(31, 24)
- #define QCA8084_MII_REG_DATA_UPPER_16_BITS    BIT(1)
-+/* QCA8084 integrates 4 PHYs, PCS0 and PCS1(includes PCS and XPCS). */
-+#define QCA8084_MDIO_DEVICE_NUM                       7
-+
-+#define QCA8084_PCS_CFG                               0xc90f014
-+#define QCA8084_PCS_ADDR0_MASK                        GENMASK(4, 0)
-+#define QCA8084_PCS_ADDR1_MASK                        GENMASK(9, 5)
-+#define QCA8084_PCS_ADDR2_MASK                        GENMASK(14, 10)
-+
-+#define QCA8084_EPHY_CFG                      0xc90f018
-+#define QCA8084_EPHY_ADDR0_MASK                       GENMASK(4, 0)
-+#define QCA8084_EPHY_ADDR1_MASK                       GENMASK(9, 5)
-+#define QCA8084_EPHY_ADDR2_MASK                       GENMASK(14, 10)
-+#define QCA8084_EPHY_ADDR3_MASK                       GENMASK(19, 15)
-+#define QCA8084_EPHY_LDO_EN                   GENMASK(21, 20)
-+
- MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
- MODULE_LICENSE("GPL");
-@@ -839,6 +858,78 @@ static void qca8084_link_change_notify(s
-                              QCA8084_IPG_10_TO_11_EN : 0);
- }
-+static int qca8084_phy_package_probe_once(struct phy_device *phydev)
-+{
-+      int addr[QCA8084_MDIO_DEVICE_NUM] = {0, 1, 2, 3, 4, 5, 6};
-+      struct device_node *np = phy_package_get_node(phydev);
-+      int ret, clear, set;
-+
-+      /* Program the MDIO address of PHY and PCS optionally, the MDIO
-+       * address 0-6 is used for PHY and PCS MDIO devices by default.
-+       */
-+      ret = of_property_read_u32_array(np, "qcom,phy-addr-fixup",
-+                                       addr, ARRAY_SIZE(addr));
-+      if (ret && ret != -EINVAL)
-+              return ret;
-+
-+      /* Configure the MDIO addresses for the four PHY devices. */
-+      clear = QCA8084_EPHY_ADDR0_MASK | QCA8084_EPHY_ADDR1_MASK |
-+              QCA8084_EPHY_ADDR2_MASK | QCA8084_EPHY_ADDR3_MASK;
-+      set = FIELD_PREP(QCA8084_EPHY_ADDR0_MASK, addr[0]);
-+      set |= FIELD_PREP(QCA8084_EPHY_ADDR1_MASK, addr[1]);
-+      set |= FIELD_PREP(QCA8084_EPHY_ADDR2_MASK, addr[2]);
-+      set |= FIELD_PREP(QCA8084_EPHY_ADDR3_MASK, addr[3]);
-+
-+      ret = qca8084_mii_modify(phydev, QCA8084_EPHY_CFG, clear, set);
-+      if (ret)
-+              return ret;
-+
-+      /* Configure the MDIO addresses for PCS0 and PCS1 including
-+       * PCS and XPCS.
-+       */
-+      clear = QCA8084_PCS_ADDR0_MASK | QCA8084_PCS_ADDR1_MASK |
-+              QCA8084_PCS_ADDR2_MASK;
-+      set = FIELD_PREP(QCA8084_PCS_ADDR0_MASK, addr[4]);
-+      set |= FIELD_PREP(QCA8084_PCS_ADDR1_MASK, addr[5]);
-+      set |= FIELD_PREP(QCA8084_PCS_ADDR2_MASK, addr[6]);
-+
-+      return qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
-+}
-+
-+static int qca8084_probe(struct phy_device *phydev)
-+{
-+      struct device *dev = &phydev->mdio.dev;
-+      struct reset_control *rstc;
-+      struct clk *clk;
-+      int ret;
-+
-+      ret = devm_of_phy_package_join(dev, phydev, 0);
-+      if (ret)
-+              return ret;
-+
-+      if (phy_package_probe_once(phydev)) {
-+              ret = qca8084_phy_package_probe_once(phydev);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /* Enable clock of PHY device, so that the PHY register
-+       * can be accessed to get PHY features.
-+       */
-+      clk = devm_clk_get_enabled(dev, NULL);
-+      if (IS_ERR(clk))
-+              return dev_err_probe(dev, PTR_ERR(clk),
-+                                   "Enable PHY clock failed\n");
-+
-+      /* De-assert PHY reset after the clock of PHY enabled. */
-+      rstc = devm_reset_control_get_exclusive(dev, NULL);
-+      if (IS_ERR(rstc))
-+              return dev_err_probe(dev, PTR_ERR(rstc),
-+                                   "Get PHY reset failed\n");
-+
-+      return reset_control_deassert(rstc);
-+}
-+
- static struct phy_driver qca808x_driver[] = {
- {
-       /* Qualcomm QCA8081 */
-@@ -889,6 +980,7 @@ static struct phy_driver qca808x_driver[
-       .cable_test_get_status  = qca808x_cable_test_get_status,
-       .config_init            = qca8084_config_init,
-       .link_change_notify     = qca8084_link_change_notify,
-+      .probe                  = qca8084_probe,
- }, };
- module_phy_driver(qca808x_driver);
diff --git a/target/linux/qualcommbe/patches-6.12/0312-net-phy-qca808x-Add-package-clocks-and-resets-for-QC.patch b/target/linux/qualcommbe/patches-6.12/0312-net-phy-qca808x-Add-package-clocks-and-resets-for-QC.patch
deleted file mode 100644 (file)
index 5034652..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-From 57379fe257895b374d35ce6578ecd62ce1cc1a4d Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Tue, 9 Apr 2024 16:30:55 +0800
-Subject: [PATCH] net: phy: qca808x: Add package clocks and resets for QCA8084
-
-Parse the PHY package clocks from the PHY package DTS node.
-These package level clocks will be enabled in the PHY package
-init function.
-
-Deassert PHY package reset, which is necessary for accessing
-the PHY registers.
-
-Change-Id: I254d0aa0a1155d3618c6f1fc7d7a5b6ecadccbaa
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: Use accessors for struct phy_package_shared
-        Update to match the patches that will be upstream.
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/phy/qcom/qca808x.c | 74 ++++++++++++++++++++++++++++++++--
- 1 file changed, 71 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -150,10 +150,39 @@ MODULE_DESCRIPTION("Qualcomm Atheros QCA
- MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
- MODULE_LICENSE("GPL");
-+enum {
-+      APB_BRIDGE_CLK,
-+      AHB_CLK,
-+      SEC_CTRL_AHB_CLK,
-+      TLMM_CLK,
-+      TLMM_AHB_CLK,
-+      CNOC_AHB_CLK,
-+      MDIO_AHB_CLK,
-+      MDIO_MASTER_AHB_CLK,
-+      SWITCH_CORE_CLK,
-+      PACKAGE_CLK_MAX
-+};
-+
- struct qca808x_priv {
-       int led_polarity_mode;
- };
-+struct qca808x_shared_priv {
-+      struct clk *clk[PACKAGE_CLK_MAX];
-+};
-+
-+static const char *const qca8084_package_clk_name[PACKAGE_CLK_MAX] = {
-+      [APB_BRIDGE_CLK] =      "apb_bridge",
-+      [AHB_CLK] =             "ahb",
-+      [SEC_CTRL_AHB_CLK] =    "sec_ctrl_ahb",
-+      [TLMM_CLK] =            "tlmm",
-+      [TLMM_AHB_CLK] =        "tlmm_ahb",
-+      [CNOC_AHB_CLK] =        "cnoc_ahb",
-+      [MDIO_AHB_CLK] =        "mdio_ahb",
-+      [MDIO_MASTER_AHB_CLK] = "mdio_master_ahb",
-+      [SWITCH_CORE_CLK] =     "switch_core",
-+};
-+
- static int __qca8084_set_page(struct mii_bus *bus, u16 sw_addr, u16 page)
- {
-       return __mdiobus_write(bus, QCA8084_HIGH_ADDR_PREFIX | (sw_addr >> 5),
-@@ -858,11 +887,24 @@ static void qca8084_link_change_notify(s
-                              QCA8084_IPG_10_TO_11_EN : 0);
- }
-+/* QCA8084 is a four-port PHY, which integrates the clock controller,
-+ * 4 PHY devices and 2 PCS interfaces (PCS0 and PCS1). PCS1 includes
-+ * XPCS and PCS to support 10G-QXGMII and SGMII. PCS0 includes one PCS
-+ * to support SGMII.
-+ *
-+ * The clocks and resets are sourced from the integrated clock controller
-+ * of the PHY package. This integrated clock controller is driven by a
-+ * QCA8K clock provider that supplies the clocks and resets to the four
-+ * PHYs, PCS and PHY package.
-+ */
- static int qca8084_phy_package_probe_once(struct phy_device *phydev)
- {
-       int addr[QCA8084_MDIO_DEVICE_NUM] = {0, 1, 2, 3, 4, 5, 6};
-       struct device_node *np = phy_package_get_node(phydev);
--      int ret, clear, set;
-+      struct qca808x_shared_priv *shared_priv;
-+      struct reset_control *rstc;
-+      int i, ret, clear, set;
-+      struct clk *clk;
-       /* Program the MDIO address of PHY and PCS optionally, the MDIO
-        * address 0-6 is used for PHY and PCS MDIO devices by default.
-@@ -893,17 +935,43 @@ static int qca8084_phy_package_probe_onc
-       set |= FIELD_PREP(QCA8084_PCS_ADDR1_MASK, addr[5]);
-       set |= FIELD_PREP(QCA8084_PCS_ADDR2_MASK, addr[6]);
--      return qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
-+      ret =  qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
-+      if (ret)
-+              return ret;
-+
-+      shared_priv = phy_package_get_priv(phydev);
-+      for (i = 0; i < ARRAY_SIZE(qca8084_package_clk_name); i++) {
-+              clk = of_clk_get_by_name(np, qca8084_package_clk_name[i]);
-+              if (IS_ERR(clk)) {
-+                      if (PTR_ERR(clk) == -EINVAL)
-+                              clk = NULL;
-+                      else
-+                              return dev_err_probe(&phydev->mdio.dev, PTR_ERR(clk),
-+                                                   "package clock %s not ready\n",
-+                                                   qca8084_package_clk_name[i]);
-+              }
-+
-+              shared_priv->clk[i] = clk;
-+      }
-+
-+      rstc = of_reset_control_get_exclusive(np, NULL);
-+      if (IS_ERR(rstc))
-+              return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
-+                                   "package reset not ready\n");
-+
-+      /* Deassert PHY package. */
-+      return reset_control_deassert(rstc);
- }
- static int qca8084_probe(struct phy_device *phydev)
- {
-+      struct qca808x_shared_priv *shared_priv;
-       struct device *dev = &phydev->mdio.dev;
-       struct reset_control *rstc;
-       struct clk *clk;
-       int ret;
--      ret = devm_of_phy_package_join(dev, phydev, 0);
-+      ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv));
-       if (ret)
-               return ret;
diff --git a/target/linux/qualcommbe/patches-6.12/0313-net-phy-qca808x-Add-QCA8084-package-init-function.patch b/target/linux/qualcommbe/patches-6.12/0313-net-phy-qca808x-Add-QCA8084-package-init-function.patch
deleted file mode 100644 (file)
index 5af66c2..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-From d39dc53424bcc778f1e468015490577e7bf0c7b6 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Thu, 25 Jan 2024 17:13:24 +0800
-Subject: [PATCH] net: phy: qca808x: Add QCA8084 package init function
-
-The package mode of PHY is configured for the interface mode of two
-PCSes working correctly.
-
-The PHY package level clocks are enabled and their rates configured.
-
-Change-Id: I63d4b22d2a70ee713cc6a6818b0f3c7aa098a5f5
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: Use phy_package_get_*() accessors
-        Update to match the patches that will be upstream.
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/phy/qcom/qca808x.c | 118 +++++++++++++++++++++++++++++++++
- 1 file changed, 118 insertions(+)
-
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -1,5 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0+
-+#include <dt-bindings/net/qcom,qca808x.h>
- #include <linux/phy.h>
- #include <linux/module.h>
- #include <linux/of.h>
-@@ -146,6 +147,12 @@
- #define QCA8084_EPHY_ADDR3_MASK                       GENMASK(19, 15)
- #define QCA8084_EPHY_LDO_EN                   GENMASK(21, 20)
-+#define QCA8084_WORK_MODE_CFG                 0xc90f030
-+#define QCA8084_WORK_MODE_MASK                        GENMASK(5, 0)
-+#define QCA8084_WORK_MODE_QXGMII              (BIT(5) | GENMASK(3, 0))
-+#define QCA8084_WORK_MODE_SWITCH              BIT(4)
-+#define QCA8084_WORK_MODE_SWITCH_PORT4_SGMII  BIT(5)
-+
- MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
- MODULE_LICENSE("GPL");
-@@ -168,6 +175,7 @@ struct qca808x_priv {
- };
- struct qca808x_shared_priv {
-+      int package_mode;
-       struct clk *clk[PACKAGE_CLK_MAX];
- };
-@@ -816,10 +824,111 @@ static int qca808x_led_polarity_set(stru
-                             active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
- }
-+static int qca8084_package_clock_init(struct qca808x_shared_priv *shared_priv)
-+{
-+      int ret;
-+
-+      /* Configure clock rate 312.5MHZ for the PHY package
-+       * APB bridge clock tree.
-+       */
-+      ret = clk_set_rate(shared_priv->clk[APB_BRIDGE_CLK], 312500000);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_prepare_enable(shared_priv->clk[SWITCH_CORE_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_prepare_enable(shared_priv->clk[APB_BRIDGE_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      /* Configure clock rate 104.17MHZ for the PHY package
-+       * AHB clock tree.
-+       */
-+      ret = clk_set_rate(shared_priv->clk[AHB_CLK], 104170000);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_prepare_enable(shared_priv->clk[AHB_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_prepare_enable(shared_priv->clk[SEC_CTRL_AHB_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_prepare_enable(shared_priv->clk[TLMM_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_prepare_enable(shared_priv->clk[TLMM_AHB_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_prepare_enable(shared_priv->clk[CNOC_AHB_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_prepare_enable(shared_priv->clk[MDIO_MASTER_AHB_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      return clk_prepare_enable(shared_priv->clk[MDIO_AHB_CLK]);
-+}
-+
-+static int qca8084_phy_package_config_init_once(struct phy_device *phydev)
-+{
-+      struct qca808x_shared_priv *shared_priv;
-+      int ret, mode;
-+
-+      shared_priv = phy_package_get_priv(phydev);
-+      switch (shared_priv->package_mode) {
-+      case QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED:
-+              mode = QCA8084_WORK_MODE_QXGMII;
-+              break;
-+      case QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_MAC:
-+              mode = QCA8084_WORK_MODE_SWITCH;
-+              break;
-+      case QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_PHY:
-+              mode = QCA8084_WORK_MODE_SWITCH_PORT4_SGMII;
-+              break;
-+      default:
-+              phydev_err(phydev, "Invalid qcom,package-mode %d\n",
-+                         shared_priv->package_mode);
-+              return -EINVAL;
-+      }
-+
-+      ret = qca8084_mii_modify(phydev, QCA8084_WORK_MODE_CFG,
-+                               QCA8084_WORK_MODE_MASK,
-+                               FIELD_PREP(QCA8084_WORK_MODE_MASK, mode));
-+      if (ret)
-+              return ret;
-+
-+      /* Enable efuse loading into analog circuit */
-+      ret = qca8084_mii_modify(phydev, QCA8084_EPHY_CFG,
-+                               QCA8084_EPHY_LDO_EN, 0);
-+      if (ret)
-+              return ret;
-+
-+      usleep_range(10000, 11000);
-+
-+      /* Initialize the PHY package clock and reset, which is the
-+       * necessary config sequence after GPIO reset on the PHY package.
-+       */
-+      return qca8084_package_clock_init(shared_priv);
-+}
-+
- static int qca8084_config_init(struct phy_device *phydev)
- {
-       int ret;
-+      if (phy_package_init_once(phydev)) {
-+              ret = qca8084_phy_package_config_init_once(phydev);
-+              if (ret)
-+                      return ret;
-+      }
-+
-       if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
-               __set_bit(PHY_INTERFACE_MODE_10G_QXGMII,
-                         phydev->possible_interfaces);
-@@ -954,6 +1063,15 @@ static int qca8084_phy_package_probe_onc
-               shared_priv->clk[i] = clk;
-       }
-+      /* The package mode 10G-QXGMII of PCS1 is used for Quad PHY and
-+       * PCS0 is unused by default.
-+       */
-+      shared_priv->package_mode = QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED;
-+      ret = of_property_read_u32(np, "qcom,package-mode",
-+                                 &shared_priv->package_mode);
-+      if (ret && ret != -EINVAL)
-+              return ret;
-+
-       rstc = of_reset_control_get_exclusive(np, NULL);
-       if (IS_ERR(rstc))
-               return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
diff --git a/target/linux/qualcommbe/patches-6.12/0314-dt-bindings-net-pcs-Add-Ethernet-PCS-for-Qualcomm-IP.patch b/target/linux/qualcommbe/patches-6.12/0314-dt-bindings-net-pcs-Add-Ethernet-PCS-for-Qualcomm-IP.patch
deleted file mode 100644 (file)
index 1112d4e..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-From 5f650721c4b232a14a1a3e25b686f2234faee961 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Fri, 7 Feb 2025 23:53:12 +0800
-Subject: [PATCH] dt-bindings: net: pcs: Add Ethernet PCS for Qualcomm IPQ9574
- SoC
-
-The 'UNIPHY' PCS block in the IPQ9574 SoC includes PCS and SerDes
-functions. It supports different interface modes to enable Ethernet
-MAC connections to different types of external PHYs/switch. It includes
-PCS functions for 1Gbps and 2.5Gbps interface modes and XPCS functions
-for 10Gbps interface modes. There are three UNIPHY (PCS) instances
-in IPQ9574 SoC which provide PCS/XPCS functions to the six Ethernet
-ports.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
----
- .../bindings/net/pcs/qcom,ipq9574-pcs.yaml    | 190 ++++++++++++++++++
- include/dt-bindings/net/qcom,ipq9574-pcs.h    |  15 ++
- 2 files changed, 205 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml
- create mode 100644 include/dt-bindings/net/qcom,ipq9574-pcs.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml
-@@ -0,0 +1,190 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/pcs/qcom,ipq9574-pcs.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Ethernet PCS for Qualcomm IPQ9574 SoC
-+
-+maintainers:
-+  - Lei Wei <quic_leiwei@quicinc.com>
-+
-+description:
-+  The UNIPHY hardware blocks in the Qualcomm IPQ SoC include PCS and SerDes
-+  functions. They enable connectivity between the Ethernet MAC inside the
-+  PPE (packet processing engine) and external Ethernet PHY/switch. There are
-+  three UNIPHY instances in IPQ9574 SoC which provide PCS functions to the
-+  six Ethernet ports.
-+
-+  For SGMII (1Gbps PHY) or 2500BASE-X (2.5Gbps PHY) interface modes, the PCS
-+  function is enabled by using the PCS block inside UNIPHY. For USXGMII (10Gbps
-+  PHY), the XPCS block in UNIPHY is used.
-+
-+  The SerDes provides 125M (1Gbps mode) or 312.5M (2.5Gbps and 10Gbps modes)
-+  RX and TX clocks to the NSSCC (Networking Sub System Clock Controller). The
-+  NSSCC divides these clocks and generates the MII RX and TX clocks to each
-+  of the MII interfaces between the PCS and MAC, as per the link speeds and
-+  interface modes.
-+
-+  Different IPQ SoC may support different number of UNIPHYs (PCSes) since the
-+  number of ports and their capabilities can be different between these SoCs
-+
-+  Below diagram depicts the UNIPHY (PCS) connections for an IPQ9574 SoC based
-+  board. In this example, the PCS0 has four GMIIs/XGMIIs, which can connect
-+  with four MACs to support QSGMII (4 x 1Gbps) or 10G_QXGMII (4 x 2.5Gbps)
-+  interface modes.
-+
-+  -           +-------+ +---------+  +-------------------------+
-+    +---------+CMN PLL| |  GCC    |  |   NSSCC (Divider)       |
-+    |         +----+--+ +----+----+  +--+-------+--------------+
-+    |              |         |          ^       |
-+    |       31.25M |  SYS/AHB|clk  RX/TX|clk    +------------+
-+    |       ref clk|         |          |       |            |
-+    |              |         v          | MII RX|TX clk   MAC| RX/TX clk
-+    |25/50M     +--+---------+----------+-------+---+      +-+---------+
-+    |ref clk    |  |   +----------------+       |   |      | |     PPE |
-+    v           |  |   |     UNIPHY0            V   |      | V         |
-+  +-------+     |  v   |       +-----------+ (X)GMII|      |           |
-+  |       |     |  +---+---+   |           |--------|------|-- MAC0    |
-+  |       |     |  |       |   |           | (X)GMII|      |           |
-+  |  Quad |     |  |SerDes |   | PCS/XPCS  |--------|------|-- MAC1    |
-+  |       +<----+  |       |   |           | (X)GMII|      |           |
-+  |(X)GPHY|     |  |       |   |           |--------|------|-- MAC2    |
-+  |       |     |  |       |   |           | (X)GMII|      |           |
-+  |       |     |  +-------+   |           |--------|------|-- MAC3    |
-+  +-------+     |              |           |        |      |           |
-+                |              +-----------+        |      |           |
-+                +-----------------------------------+      |           |
-+                +--+---------+----------+-------+---+      |           |
-+  +-------+     |            UNIPHY1                |      |           |
-+  |       |     |              +-----------+        |      |           |
-+  |(X)GPHY|     | +-------+    |           | (X)GMII|      |           |
-+  |       +<----+ |SerDes |    | PCS/XPCS  |--------|------|- MAC4     |
-+  |       |     | |       |    |           |        |      |           |
-+  +-------+     | +-------+    |           |        |      |           |
-+                |              +-----------+        |      |           |
-+                +-----------------------------------+      |           |
-+                +--+---------+----------+-------+---+      |           |
-+  +-------+     |           UNIPHY2                 |      |           |
-+  |       |     |              +-----------+        |      |           |
-+  |(X)GPHY|     | +-------+    |           | (X)GMII|      |           |
-+  |       +<----+ |SerDes |    | PCS/XPCS  |--------|------|- MAC5     |
-+  |       |     | |       |    |           |        |      |           |
-+  +-------+     | +-------+    |           |        |      |           |
-+                |              +-----------+        |      |           |
-+                +-----------------------------------+      +-----------+
-+
-+properties:
-+  compatible:
-+    enum:
-+      - qcom,ipq9574-pcs
-+
-+  reg:
-+    maxItems: 1
-+
-+  '#address-cells':
-+    const: 1
-+
-+  '#size-cells':
-+    const: 0
-+
-+  clocks:
-+    items:
-+      - description: System clock
-+      - description: AHB clock needed for register interface access
-+
-+  clock-names:
-+    items:
-+      - const: sys
-+      - const: ahb
-+
-+  '#clock-cells':
-+    const: 1
-+    description: See include/dt-bindings/net/qcom,ipq9574-pcs.h for constants
-+
-+patternProperties:
-+  '^pcs-mii@[0-4]$':
-+    type: object
-+    description: PCS MII interface.
-+
-+    properties:
-+      reg:
-+        minimum: 0
-+        maximum: 4
-+        description: MII index
-+
-+      clocks:
-+        items:
-+          - description: PCS MII RX clock
-+          - description: PCS MII TX clock
-+
-+      clock-names:
-+        items:
-+          - const: rx
-+          - const: tx
-+
-+    required:
-+      - reg
-+      - clocks
-+      - clock-names
-+
-+    additionalProperties: false
-+
-+required:
-+  - compatible
-+  - reg
-+  - '#address-cells'
-+  - '#size-cells'
-+  - clocks
-+  - clock-names
-+  - '#clock-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+  - |
-+    #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
-+
-+    ethernet-pcs@7a00000 {
-+        compatible = "qcom,ipq9574-pcs";
-+        reg = <0x7a00000 0x10000>;
-+        #address-cells = <1>;
-+        #size-cells = <0>;
-+        clocks = <&gcc GCC_UNIPHY0_SYS_CLK>,
-+                 <&gcc GCC_UNIPHY0_AHB_CLK>;
-+        clock-names = "sys",
-+                      "ahb";
-+        #clock-cells = <1>;
-+
-+        pcs-mii@0 {
-+            reg = <0>;
-+            clocks = <&nsscc 116>,
-+                     <&nsscc 117>;
-+            clock-names = "rx",
-+                          "tx";
-+        };
-+
-+        pcs-mii@1 {
-+            reg = <1>;
-+            clocks = <&nsscc 118>,
-+                     <&nsscc 119>;
-+            clock-names = "rx",
-+                          "tx";
-+        };
-+
-+        pcs-mii@2 {
-+            reg = <2>;
-+            clocks = <&nsscc 120>,
-+                     <&nsscc 121>;
-+            clock-names = "rx",
-+                          "tx";
-+        };
-+
-+        pcs-mii@3 {
-+            reg = <3>;
-+            clocks = <&nsscc 122>,
-+                     <&nsscc 123>;
-+            clock-names = "rx",
-+                          "tx";
-+        };
-+    };
---- /dev/null
-+++ b/include/dt-bindings/net/qcom,ipq9574-pcs.h
-@@ -0,0 +1,15 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ *
-+ * Device Tree constants for the Qualcomm IPQ9574 PCS
-+ */
-+
-+#ifndef _DT_BINDINGS_PCS_QCOM_IPQ9574_H
-+#define _DT_BINDINGS_PCS_QCOM_IPQ9574_H
-+
-+/* The RX and TX clocks which are provided from the SerDes to NSSCC. */
-+#define PCS_RX_CLK            0
-+#define PCS_TX_CLK            1
-+
-+#endif /* _DT_BINDINGS_PCS_QCOM_IPQ9574_H */
diff --git a/target/linux/qualcommbe/patches-6.12/0315-net-pcs-Add-PCS-driver-for-Qualcomm-IPQ9574-SoC.patch b/target/linux/qualcommbe/patches-6.12/0315-net-pcs-Add-PCS-driver-for-Qualcomm-IPQ9574-SoC.patch
deleted file mode 100644 (file)
index eb0750c..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-From e404519d9f3e5e7d661cb105d3766d87e37e4ef5 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Fri, 7 Feb 2025 23:53:13 +0800
-Subject: [PATCH] net: pcs: Add PCS driver for Qualcomm IPQ9574 SoC
-
-The 'UNIPHY' PCS hardware block in Qualcomm's IPQ SoC supports
-different interface modes to enable Ethernet MAC connections
-for different types of external PHYs/switch. Each UNIPHY block
-includes a SerDes and PCS/XPCS blocks, and can operate in either
-PCS or XPCS modes. It supports 1Gbps and 2.5Gbps interface modes
-(Ex: SGMII) using the PCS, and 10Gbps interface modes (Ex: USXGMII)
-using the XPCS. There are three UNIPHY (PCS) instances in IPQ9574
-SoC which support the six Ethernet ports in the SoC.
-
-This patch adds support for the platform driver, probe and clock
-registrations for the PCS driver. The platform driver creates an
-'ipq_pcs' instance for each of the UNIPHY used on the given board.
-
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
----
- drivers/net/pcs/Kconfig            |   9 ++
- drivers/net/pcs/Makefile           |   1 +
- drivers/net/pcs/pcs-qcom-ipq9574.c | 245 +++++++++++++++++++++++++++++
- 3 files changed, 255 insertions(+)
- create mode 100644 drivers/net/pcs/pcs-qcom-ipq9574.c
-
---- a/drivers/net/pcs/Kconfig
-+++ b/drivers/net/pcs/Kconfig
-@@ -43,6 +43,15 @@ config PCS_MTK_USXGMII
-         1000Base-X, 2500Base-X and Cisco SGMII are supported on the same
-         differential pairs via an embedded LynxI PHY.
-+config PCS_QCOM_IPQ9574
-+      tristate "Qualcomm IPQ9574 PCS"
-+      depends on OF && (ARCH_QCOM || COMPILE_TEST)
-+      depends on HAS_IOMEM && COMMON_CLK
-+      help
-+        This module provides driver for UNIPHY PCS available on Qualcomm
-+        IPQ9574 SoC. The UNIPHY PCS supports both PCS and XPCS functions
-+        to support different interface modes for MAC to PHY connections.
-+
- config PCS_RZN1_MIIC
-       tristate "Renesas RZ/N1 MII converter"
-       depends on OF && (ARCH_RZN1 || COMPILE_TEST)
---- a/drivers/net/pcs/Makefile
-+++ b/drivers/net/pcs/Makefile
-@@ -8,5 +8,6 @@ pcs_xpcs-$(CONFIG_PCS_XPCS)    := pcs-xpcs.
- obj-$(CONFIG_PCS_XPCS)                += pcs_xpcs.o
- obj-$(CONFIG_PCS_LYNX)                += pcs-lynx.o
- obj-$(CONFIG_PCS_MTK_LYNXI)   += pcs-mtk-lynxi.o
-+obj-$(CONFIG_PCS_QCOM_IPQ9574)        += pcs-qcom-ipq9574.o
- obj-$(CONFIG_PCS_RZN1_MIIC)   += pcs-rzn1-miic.o
- obj-$(CONFIG_PCS_MTK_USXGMII) += pcs-mtk-usxgmii.o
---- /dev/null
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -0,0 +1,245 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/device.h>
-+#include <linux/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+#include <dt-bindings/net/qcom,ipq9574-pcs.h>
-+
-+#define XPCS_INDIRECT_ADDR            0x8000
-+#define XPCS_INDIRECT_AHB_ADDR                0x83fc
-+#define XPCS_INDIRECT_ADDR_H          GENMASK(20, 8)
-+#define XPCS_INDIRECT_ADDR_L          GENMASK(7, 0)
-+#define XPCS_INDIRECT_DATA_ADDR(reg)  (FIELD_PREP(GENMASK(15, 10), 0x20) | \
-+                                       FIELD_PREP(GENMASK(9, 2), \
-+                                       FIELD_GET(XPCS_INDIRECT_ADDR_L, reg)))
-+
-+/* PCS private data */
-+struct ipq_pcs {
-+      struct device *dev;
-+      void __iomem *base;
-+      struct regmap *regmap;
-+      phy_interface_t interface;
-+
-+      /* RX clock supplied to NSSCC */
-+      struct clk_hw rx_hw;
-+      /* TX clock supplied to NSSCC */
-+      struct clk_hw tx_hw;
-+};
-+
-+static unsigned long ipq_pcs_clk_rate_get(struct ipq_pcs *qpcs)
-+{
-+      switch (qpcs->interface) {
-+      case PHY_INTERFACE_MODE_USXGMII:
-+              return 312500000;
-+      default:
-+              return 125000000;
-+      }
-+}
-+
-+/* Return clock rate for the RX clock supplied to NSSCC
-+ * as per the interface mode.
-+ */
-+static unsigned long ipq_pcs_rx_clk_recalc_rate(struct clk_hw *hw,
-+                                              unsigned long parent_rate)
-+{
-+      struct ipq_pcs *qpcs = container_of(hw, struct ipq_pcs, rx_hw);
-+
-+      return ipq_pcs_clk_rate_get(qpcs);
-+}
-+
-+/* Return clock rate for the TX clock supplied to NSSCC
-+ * as per the interface mode.
-+ */
-+static unsigned long ipq_pcs_tx_clk_recalc_rate(struct clk_hw *hw,
-+                                              unsigned long parent_rate)
-+{
-+      struct ipq_pcs *qpcs = container_of(hw, struct ipq_pcs, tx_hw);
-+
-+      return ipq_pcs_clk_rate_get(qpcs);
-+}
-+
-+static int ipq_pcs_clk_determine_rate(struct clk_hw *hw,
-+                                    struct clk_rate_request *req)
-+{
-+      switch (req->rate) {
-+      case 125000000:
-+      case 312500000:
-+              return 0;
-+      default:
-+              return -EINVAL;
-+      }
-+}
-+
-+/* Clock ops for the RX clock supplied to NSSCC */
-+static const struct clk_ops ipq_pcs_rx_clk_ops = {
-+      .determine_rate = ipq_pcs_clk_determine_rate,
-+      .recalc_rate = ipq_pcs_rx_clk_recalc_rate,
-+};
-+
-+/* Clock ops for the TX clock supplied to NSSCC */
-+static const struct clk_ops ipq_pcs_tx_clk_ops = {
-+      .determine_rate = ipq_pcs_clk_determine_rate,
-+      .recalc_rate = ipq_pcs_tx_clk_recalc_rate,
-+};
-+
-+static struct clk_hw *ipq_pcs_clk_hw_get(struct of_phandle_args *clkspec,
-+                                       void *data)
-+{
-+      struct ipq_pcs *qpcs = data;
-+
-+      switch (clkspec->args[0]) {
-+      case PCS_RX_CLK:
-+              return &qpcs->rx_hw;
-+      case PCS_TX_CLK:
-+              return &qpcs->tx_hw;
-+      }
-+
-+      return ERR_PTR(-EINVAL);
-+}
-+
-+/* Register the RX and TX clock which are output from SerDes to
-+ * the NSSCC. The NSSCC driver assigns the RX and TX clock as
-+ * parent, divides them to generate the MII RX and TX clock to
-+ * each MII interface of the PCS as per the link speeds and
-+ * interface modes.
-+ */
-+static int ipq_pcs_clk_register(struct ipq_pcs *qpcs)
-+{
-+      struct clk_init_data init = { };
-+      int ret;
-+
-+      init.ops = &ipq_pcs_rx_clk_ops;
-+      init.name = devm_kasprintf(qpcs->dev, GFP_KERNEL, "%s::rx_clk",
-+                                 dev_name(qpcs->dev));
-+      if (!init.name)
-+              return -ENOMEM;
-+
-+      qpcs->rx_hw.init = &init;
-+      ret = devm_clk_hw_register(qpcs->dev, &qpcs->rx_hw);
-+      if (ret)
-+              return ret;
-+
-+      init.ops = &ipq_pcs_tx_clk_ops;
-+      init.name = devm_kasprintf(qpcs->dev, GFP_KERNEL, "%s::tx_clk",
-+                                 dev_name(qpcs->dev));
-+      if (!init.name)
-+              return -ENOMEM;
-+
-+      qpcs->tx_hw.init = &init;
-+      ret = devm_clk_hw_register(qpcs->dev, &qpcs->tx_hw);
-+      if (ret)
-+              return ret;
-+
-+      return devm_of_clk_add_hw_provider(qpcs->dev, ipq_pcs_clk_hw_get, qpcs);
-+}
-+
-+static int ipq_pcs_regmap_read(void *context, unsigned int reg,
-+                             unsigned int *val)
-+{
-+      struct ipq_pcs *qpcs = context;
-+
-+      /* PCS uses direct AHB access while XPCS uses indirect AHB access */
-+      if (reg >= XPCS_INDIRECT_ADDR) {
-+              writel(FIELD_GET(XPCS_INDIRECT_ADDR_H, reg),
-+                     qpcs->base + XPCS_INDIRECT_AHB_ADDR);
-+              *val = readl(qpcs->base + XPCS_INDIRECT_DATA_ADDR(reg));
-+      } else {
-+              *val = readl(qpcs->base + reg);
-+      }
-+
-+      return 0;
-+}
-+
-+static int ipq_pcs_regmap_write(void *context, unsigned int reg,
-+                              unsigned int val)
-+{
-+      struct ipq_pcs *qpcs = context;
-+
-+      /* PCS uses direct AHB access while XPCS uses indirect AHB access */
-+      if (reg >= XPCS_INDIRECT_ADDR) {
-+              writel(FIELD_GET(XPCS_INDIRECT_ADDR_H, reg),
-+                     qpcs->base + XPCS_INDIRECT_AHB_ADDR);
-+              writel(val, qpcs->base + XPCS_INDIRECT_DATA_ADDR(reg));
-+      } else {
-+              writel(val, qpcs->base + reg);
-+      }
-+
-+      return 0;
-+}
-+
-+static const struct regmap_config ipq_pcs_regmap_cfg = {
-+      .reg_bits = 32,
-+      .val_bits = 32,
-+      .reg_read = ipq_pcs_regmap_read,
-+      .reg_write = ipq_pcs_regmap_write,
-+      .fast_io = true,
-+};
-+
-+static int ipq9574_pcs_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      struct ipq_pcs *qpcs;
-+      struct clk *clk;
-+      int ret;
-+
-+      qpcs = devm_kzalloc(dev, sizeof(*qpcs), GFP_KERNEL);
-+      if (!qpcs)
-+              return -ENOMEM;
-+
-+      qpcs->dev = dev;
-+
-+      qpcs->base = devm_platform_ioremap_resource(pdev, 0);
-+      if (IS_ERR(qpcs->base))
-+              return dev_err_probe(dev, PTR_ERR(qpcs->base),
-+                                   "Failed to ioremap resource\n");
-+
-+      qpcs->regmap = devm_regmap_init(dev, NULL, qpcs, &ipq_pcs_regmap_cfg);
-+      if (IS_ERR(qpcs->regmap))
-+              return dev_err_probe(dev, PTR_ERR(qpcs->regmap),
-+                                   "Failed to allocate register map\n");
-+
-+      clk = devm_clk_get_enabled(dev, "sys");
-+      if (IS_ERR(clk))
-+              return dev_err_probe(dev, PTR_ERR(clk),
-+                                   "Failed to enable SYS clock\n");
-+
-+      clk = devm_clk_get_enabled(dev, "ahb");
-+      if (IS_ERR(clk))
-+              return dev_err_probe(dev, PTR_ERR(clk),
-+                                   "Failed to enable AHB clock\n");
-+
-+      ret = ipq_pcs_clk_register(qpcs);
-+      if (ret)
-+              return ret;
-+
-+      platform_set_drvdata(pdev, qpcs);
-+
-+      return 0;
-+}
-+
-+static const struct of_device_id ipq9574_pcs_of_mtable[] = {
-+      { .compatible = "qcom,ipq9574-pcs" },
-+      { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, ipq9574_pcs_of_mtable);
-+
-+static struct platform_driver ipq9574_pcs_driver = {
-+      .driver = {
-+              .name = "ipq9574_pcs",
-+              .suppress_bind_attrs = true,
-+              .of_match_table = ipq9574_pcs_of_mtable,
-+      },
-+      .probe = ipq9574_pcs_probe,
-+};
-+module_platform_driver(ipq9574_pcs_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Qualcomm IPQ9574 PCS driver");
-+MODULE_AUTHOR("Lei Wei <quic_leiwei@quicinc.com>");
diff --git a/target/linux/qualcommbe/patches-6.12/0316-net-pcs-qcom-ipq9574-Add-PCS-instantiation-and-phyli.patch b/target/linux/qualcommbe/patches-6.12/0316-net-pcs-qcom-ipq9574-Add-PCS-instantiation-and-phyli.patch
deleted file mode 100644 (file)
index 7d071c2..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-From 10b609ddbf4d369c80098efa39451ef3973759b5 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Fri, 7 Feb 2025 23:53:14 +0800
-Subject: [PATCH] net: pcs: qcom-ipq9574: Add PCS instantiation and phylink
- operations
-
-This patch adds the following PCS functionality for the PCS driver
-for IPQ9574 SoC:
-
-a.) Parses PCS MII DT nodes and instantiate each MII PCS instance.
-b.) Exports PCS instance get and put APIs. The network driver calls
-the PCS get API to get and associate the PCS instance with the port
-MAC.
-c.) PCS phylink operations for SGMII/QSGMII interface modes.
-
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
-Alex G: remove phylink_pcs .neg_mode boolean
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c   | 468 +++++++++++++++++++++++++++
- include/linux/pcs/pcs-qcom-ipq9574.h |  15 +
- 2 files changed, 483 insertions(+)
- create mode 100644 include/linux/pcs/pcs-qcom-ipq9574.h
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -6,12 +6,46 @@
- #include <linux/clk.h>
- #include <linux/clk-provider.h>
- #include <linux/device.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/pcs/pcs-qcom-ipq9574.h>
- #include <linux/phy.h>
-+#include <linux/phylink.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
- #include <dt-bindings/net/qcom,ipq9574-pcs.h>
-+/* Maximum number of MIIs per PCS instance. There are 5 MIIs for PSGMII. */
-+#define PCS_MAX_MII_NRS                       5
-+
-+#define PCS_CALIBRATION                       0x1e0
-+#define PCS_CALIBRATION_DONE          BIT(7)
-+
-+#define PCS_MODE_CTRL                 0x46c
-+#define PCS_MODE_SEL_MASK             GENMASK(12, 8)
-+#define PCS_MODE_SGMII                        FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
-+#define PCS_MODE_QSGMII                       FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
-+
-+#define PCS_MII_CTRL(x)                       (0x480 + 0x18 * (x))
-+#define PCS_MII_ADPT_RESET            BIT(11)
-+#define PCS_MII_FORCE_MODE            BIT(3)
-+#define PCS_MII_SPEED_MASK            GENMASK(2, 1)
-+#define PCS_MII_SPEED_1000            FIELD_PREP(PCS_MII_SPEED_MASK, 0x2)
-+#define PCS_MII_SPEED_100             FIELD_PREP(PCS_MII_SPEED_MASK, 0x1)
-+#define PCS_MII_SPEED_10              FIELD_PREP(PCS_MII_SPEED_MASK, 0x0)
-+
-+#define PCS_MII_STS(x)                        (0x488 + 0x18 * (x))
-+#define PCS_MII_LINK_STS              BIT(7)
-+#define PCS_MII_STS_DUPLEX_FULL               BIT(6)
-+#define PCS_MII_STS_SPEED_MASK                GENMASK(5, 4)
-+#define PCS_MII_STS_SPEED_10          0
-+#define PCS_MII_STS_SPEED_100         1
-+#define PCS_MII_STS_SPEED_1000                2
-+
-+#define PCS_PLL_RESET                 0x780
-+#define PCS_ANA_SW_RESET              BIT(6)
-+
- #define XPCS_INDIRECT_ADDR            0x8000
- #define XPCS_INDIRECT_AHB_ADDR                0x83fc
- #define XPCS_INDIRECT_ADDR_H          GENMASK(20, 8)
-@@ -20,6 +54,18 @@
-                                        FIELD_PREP(GENMASK(9, 2), \
-                                        FIELD_GET(XPCS_INDIRECT_ADDR_L, reg)))
-+/* Per PCS MII private data */
-+struct ipq_pcs_mii {
-+      struct ipq_pcs *qpcs;
-+      struct phylink_pcs pcs;
-+      int index;
-+
-+      /* RX clock from NSSCC to PCS MII */
-+      struct clk *rx_clk;
-+      /* TX clock from NSSCC to PCS MII */
-+      struct clk *tx_clk;
-+};
-+
- /* PCS private data */
- struct ipq_pcs {
-       struct device *dev;
-@@ -31,8 +77,358 @@ struct ipq_pcs {
-       struct clk_hw rx_hw;
-       /* TX clock supplied to NSSCC */
-       struct clk_hw tx_hw;
-+
-+      struct ipq_pcs_mii *qpcs_mii[PCS_MAX_MII_NRS];
- };
-+#define phylink_pcs_to_qpcs_mii(_pcs) \
-+      container_of(_pcs, struct ipq_pcs_mii, pcs)
-+
-+static void ipq_pcs_get_state_sgmii(struct ipq_pcs *qpcs,
-+                                  int index,
-+                                  struct phylink_link_state *state)
-+{
-+      unsigned int val;
-+      int ret;
-+
-+      ret = regmap_read(qpcs->regmap, PCS_MII_STS(index), &val);
-+      if (ret) {
-+              state->link = 0;
-+              return;
-+      }
-+
-+      state->link = !!(val & PCS_MII_LINK_STS);
-+
-+      if (!state->link)
-+              return;
-+
-+      switch (FIELD_GET(PCS_MII_STS_SPEED_MASK, val)) {
-+      case PCS_MII_STS_SPEED_1000:
-+              state->speed = SPEED_1000;
-+              break;
-+      case PCS_MII_STS_SPEED_100:
-+              state->speed = SPEED_100;
-+              break;
-+      case PCS_MII_STS_SPEED_10:
-+              state->speed = SPEED_10;
-+              break;
-+      default:
-+              state->link = false;
-+              return;
-+      }
-+
-+      if (val & PCS_MII_STS_DUPLEX_FULL)
-+              state->duplex = DUPLEX_FULL;
-+      else
-+              state->duplex = DUPLEX_HALF;
-+}
-+
-+static int ipq_pcs_config_mode(struct ipq_pcs *qpcs,
-+                             phy_interface_t interface)
-+{
-+      unsigned int val;
-+      int ret;
-+
-+      /* Configure PCS interface mode */
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+              val = PCS_MODE_SGMII;
-+              break;
-+      case PHY_INTERFACE_MODE_QSGMII:
-+              val = PCS_MODE_QSGMII;
-+              break;
-+      default:
-+              return -EOPNOTSUPP;
-+      }
-+
-+      ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL,
-+                               PCS_MODE_SEL_MASK, val);
-+      if (ret)
-+              return ret;
-+
-+      /* PCS PLL reset */
-+      ret = regmap_clear_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
-+      if (ret)
-+              return ret;
-+
-+      fsleep(1000);
-+      ret = regmap_set_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
-+      if (ret)
-+              return ret;
-+
-+      /* Wait for calibration completion */
-+      ret = regmap_read_poll_timeout(qpcs->regmap, PCS_CALIBRATION,
-+                                     val, val & PCS_CALIBRATION_DONE,
-+                                     1000, 100000);
-+      if (ret) {
-+              dev_err(qpcs->dev, "PCS calibration timed-out\n");
-+              return ret;
-+      }
-+
-+      qpcs->interface = interface;
-+
-+      return 0;
-+}
-+
-+static int ipq_pcs_config_sgmii(struct ipq_pcs *qpcs,
-+                              int index,
-+                              unsigned int neg_mode,
-+                              phy_interface_t interface)
-+{
-+      int ret;
-+
-+      /* Configure the PCS mode if required */
-+      if (qpcs->interface != interface) {
-+              ret = ipq_pcs_config_mode(qpcs, interface);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /* Nothing to do here as in-band autoneg mode is enabled
-+       * by default for each PCS MII port.
-+       */
-+      if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
-+              return 0;
-+
-+      /* Set force speed mode */
-+      return regmap_set_bits(qpcs->regmap,
-+                             PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
-+}
-+
-+static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs,
-+                                      int index,
-+                                      unsigned int neg_mode,
-+                                      int speed)
-+{
-+      unsigned int val;
-+      int ret;
-+
-+      /* PCS speed need not be configured if in-band autoneg is enabled */
-+      if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
-+              /* PCS speed set for force mode */
-+              switch (speed) {
-+              case SPEED_1000:
-+                      val = PCS_MII_SPEED_1000;
-+                      break;
-+              case SPEED_100:
-+                      val = PCS_MII_SPEED_100;
-+                      break;
-+              case SPEED_10:
-+                      val = PCS_MII_SPEED_10;
-+                      break;
-+              default:
-+                      dev_err(qpcs->dev, "Invalid SGMII speed %d\n", speed);
-+                      return -EINVAL;
-+              }
-+
-+              ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index),
-+                                       PCS_MII_SPEED_MASK, val);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /* PCS adapter reset */
-+      ret = regmap_clear_bits(qpcs->regmap,
-+                              PCS_MII_CTRL(index), PCS_MII_ADPT_RESET);
-+      if (ret)
-+              return ret;
-+
-+      return regmap_set_bits(qpcs->regmap,
-+                             PCS_MII_CTRL(index), PCS_MII_ADPT_RESET);
-+}
-+
-+static int ipq_pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
-+                          const struct phylink_link_state *state)
-+{
-+      switch (state->interface) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+              return 0;
-+      default:
-+              return -EINVAL;
-+      }
-+}
-+
-+static unsigned int ipq_pcs_inband_caps(struct phylink_pcs *pcs,
-+                                      phy_interface_t interface)
-+{
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+              return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-+      default:
-+              return 0;
-+      }
-+}
-+
-+static int ipq_pcs_enable(struct phylink_pcs *pcs)
-+{
-+      struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
-+      struct ipq_pcs *qpcs = qpcs_mii->qpcs;
-+      int index = qpcs_mii->index;
-+      int ret;
-+
-+      ret = clk_prepare_enable(qpcs_mii->rx_clk);
-+      if (ret) {
-+              dev_err(qpcs->dev, "Failed to enable MII %d RX clock\n", index);
-+              return ret;
-+      }
-+
-+      ret = clk_prepare_enable(qpcs_mii->tx_clk);
-+      if (ret) {
-+              /* This is a fatal event since phylink does not support unwinding
-+               * the state back for this error. So, we only report the error
-+               * and do not disable the clocks.
-+               */
-+              dev_err(qpcs->dev, "Failed to enable MII %d TX clock\n", index);
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static void ipq_pcs_disable(struct phylink_pcs *pcs)
-+{
-+      struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
-+
-+      clk_disable_unprepare(qpcs_mii->rx_clk);
-+      clk_disable_unprepare(qpcs_mii->tx_clk);
-+}
-+
-+static void ipq_pcs_get_state(struct phylink_pcs *pcs,
-+                            struct phylink_link_state *state)
-+{
-+      struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
-+      struct ipq_pcs *qpcs = qpcs_mii->qpcs;
-+      int index = qpcs_mii->index;
-+
-+      switch (state->interface) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+              ipq_pcs_get_state_sgmii(qpcs, index, state);
-+              break;
-+      default:
-+              break;
-+      }
-+
-+      dev_dbg_ratelimited(qpcs->dev,
-+                          "mode=%s/%s/%s link=%u\n",
-+                          phy_modes(state->interface),
-+                          phy_speed_to_str(state->speed),
-+                          phy_duplex_to_str(state->duplex),
-+                          state->link);
-+}
-+
-+static int ipq_pcs_config(struct phylink_pcs *pcs,
-+                        unsigned int neg_mode,
-+                        phy_interface_t interface,
-+                        const unsigned long *advertising,
-+                        bool permit)
-+{
-+      struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
-+      struct ipq_pcs *qpcs = qpcs_mii->qpcs;
-+      int index = qpcs_mii->index;
-+
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+              return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
-+      default:
-+              return -EOPNOTSUPP;
-+      };
-+}
-+
-+static void ipq_pcs_link_up(struct phylink_pcs *pcs,
-+                          unsigned int neg_mode,
-+                          phy_interface_t interface,
-+                          int speed, int duplex)
-+{
-+      struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
-+      struct ipq_pcs *qpcs = qpcs_mii->qpcs;
-+      int index = qpcs_mii->index;
-+      int ret;
-+
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+              ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
-+                                                 neg_mode, speed);
-+              break;
-+      default:
-+              return;
-+      }
-+
-+      if (ret)
-+              dev_err(qpcs->dev, "PCS link up fail for interface %s\n",
-+                      phy_modes(interface));
-+}
-+
-+static const struct phylink_pcs_ops ipq_pcs_phylink_ops = {
-+      .pcs_validate = ipq_pcs_validate,
-+      .pcs_inband_caps = ipq_pcs_inband_caps,
-+      .pcs_enable = ipq_pcs_enable,
-+      .pcs_disable = ipq_pcs_disable,
-+      .pcs_get_state = ipq_pcs_get_state,
-+      .pcs_config = ipq_pcs_config,
-+      .pcs_link_up = ipq_pcs_link_up,
-+};
-+
-+/* Parse the PCS MII DT nodes which are child nodes of the PCS node,
-+ * and instantiate each MII PCS instance.
-+ */
-+static int ipq_pcs_create_miis(struct ipq_pcs *qpcs)
-+{
-+      struct device *dev = qpcs->dev;
-+      struct ipq_pcs_mii *qpcs_mii;
-+      struct device_node *mii_np;
-+      u32 index;
-+      int ret;
-+
-+      for_each_available_child_of_node(dev->of_node, mii_np) {
-+              ret = of_property_read_u32(mii_np, "reg", &index);
-+              if (ret) {
-+                      dev_err(dev, "Failed to read MII index\n");
-+                      of_node_put(mii_np);
-+                      return ret;
-+              }
-+
-+              if (index >= PCS_MAX_MII_NRS) {
-+                      dev_err(dev, "Invalid MII index\n");
-+                      of_node_put(mii_np);
-+                      return -EINVAL;
-+              }
-+
-+              qpcs_mii = devm_kzalloc(dev, sizeof(*qpcs_mii), GFP_KERNEL);
-+              if (!qpcs_mii) {
-+                      of_node_put(mii_np);
-+                      return -ENOMEM;
-+              }
-+
-+              qpcs_mii->qpcs = qpcs;
-+              qpcs_mii->index = index;
-+              qpcs_mii->pcs.ops = &ipq_pcs_phylink_ops;
-+              qpcs_mii->pcs.poll = true;
-+
-+              qpcs_mii->rx_clk = devm_get_clk_from_child(dev, mii_np, "rx");
-+              if (IS_ERR(qpcs_mii->rx_clk)) {
-+                      of_node_put(mii_np);
-+                      return dev_err_probe(dev, PTR_ERR(qpcs_mii->rx_clk),
-+                                           "Failed to get MII %d RX clock\n", index);
-+              }
-+
-+              qpcs_mii->tx_clk = devm_get_clk_from_child(dev, mii_np, "tx");
-+              if (IS_ERR(qpcs_mii->tx_clk)) {
-+                      of_node_put(mii_np);
-+                      return dev_err_probe(dev, PTR_ERR(qpcs_mii->tx_clk),
-+                                           "Failed to get MII %d TX clock\n", index);
-+              }
-+
-+              qpcs->qpcs_mii[index] = qpcs_mii;
-+      }
-+
-+      return 0;
-+}
-+
- static unsigned long ipq_pcs_clk_rate_get(struct ipq_pcs *qpcs)
- {
-       switch (qpcs->interface) {
-@@ -219,6 +615,10 @@ static int ipq9574_pcs_probe(struct plat
-       if (ret)
-               return ret;
-+      ret = ipq_pcs_create_miis(qpcs);
-+      if (ret)
-+              return ret;
-+
-       platform_set_drvdata(pdev, qpcs);
-       return 0;
-@@ -230,6 +630,74 @@ static const struct of_device_id ipq9574
- };
- MODULE_DEVICE_TABLE(of, ipq9574_pcs_of_mtable);
-+/**
-+ * ipq_pcs_get() - Get the IPQ PCS MII instance
-+ * @np: Device tree node to the PCS MII
-+ *
-+ * Description: Get the phylink PCS instance for the given PCS MII node @np.
-+ * This instance is associated with the specific MII of the PCS and the
-+ * corresponding Ethernet netdevice.
-+ *
-+ * Return: A pointer to the phylink PCS instance or an error-pointer value.
-+ */
-+struct phylink_pcs *ipq_pcs_get(struct device_node *np)
-+{
-+      struct platform_device *pdev;
-+      struct ipq_pcs_mii *qpcs_mii;
-+      struct ipq_pcs *qpcs;
-+      u32 index;
-+
-+      if (of_property_read_u32(np, "reg", &index))
-+              return ERR_PTR(-EINVAL);
-+
-+      if (index >= PCS_MAX_MII_NRS)
-+              return ERR_PTR(-EINVAL);
-+
-+      if (!of_match_node(ipq9574_pcs_of_mtable, np->parent))
-+              return ERR_PTR(-EINVAL);
-+
-+      /* Get the parent device */
-+      pdev = of_find_device_by_node(np->parent);
-+      if (!pdev)
-+              return ERR_PTR(-ENODEV);
-+
-+      qpcs = platform_get_drvdata(pdev);
-+      if (!qpcs) {
-+              put_device(&pdev->dev);
-+
-+              /* If probe is not yet completed, return DEFER to
-+               * the dependent driver.
-+               */
-+              return ERR_PTR(-EPROBE_DEFER);
-+      }
-+
-+      qpcs_mii = qpcs->qpcs_mii[index];
-+      if (!qpcs_mii) {
-+              put_device(&pdev->dev);
-+              return ERR_PTR(-ENOENT);
-+      }
-+
-+      return &qpcs_mii->pcs;
-+}
-+EXPORT_SYMBOL(ipq_pcs_get);
-+
-+/**
-+ * ipq_pcs_put() - Release the IPQ PCS MII instance
-+ * @pcs: PCS instance
-+ *
-+ * Description: Release a phylink PCS instance.
-+ */
-+void ipq_pcs_put(struct phylink_pcs *pcs)
-+{
-+      struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
-+
-+      /* Put reference taken by of_find_device_by_node() in
-+       * ipq_pcs_get().
-+       */
-+      put_device(qpcs_mii->qpcs->dev);
-+}
-+EXPORT_SYMBOL(ipq_pcs_put);
-+
- static struct platform_driver ipq9574_pcs_driver = {
-       .driver = {
-               .name = "ipq9574_pcs",
---- /dev/null
-+++ b/include/linux/pcs/pcs-qcom-ipq9574.h
-@@ -0,0 +1,15 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __LINUX_PCS_QCOM_IPQ9574_H
-+#define __LINUX_PCS_QCOM_IPQ9574_H
-+
-+struct device_node;
-+struct phylink_pcs;
-+
-+struct phylink_pcs *ipq_pcs_get(struct device_node *np);
-+void ipq_pcs_put(struct phylink_pcs *pcs);
-+
-+#endif /* __LINUX_PCS_QCOM_IPQ9574_H */
diff --git a/target/linux/qualcommbe/patches-6.12/0317-net-pcs-qcom-ipq9574-Add-USXGMII-interface-mode-supp.patch b/target/linux/qualcommbe/patches-6.12/0317-net-pcs-qcom-ipq9574-Add-USXGMII-interface-mode-supp.patch
deleted file mode 100644 (file)
index b1cddff..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-From 4923ca63214a4e6bbee1b3f8f6b9b79f0fd3a3be Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Fri, 7 Feb 2025 23:53:15 +0800
-Subject: [PATCH] net: pcs: qcom-ipq9574: Add USXGMII interface mode support
-
-USXGMII mode is enabled by PCS when 10Gbps PHYs are connected, such as
-Aquantia 10Gbps PHY.
-
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 170 +++++++++++++++++++++++++++++
- 1 file changed, 170 insertions(+)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -26,6 +26,7 @@
- #define PCS_MODE_SEL_MASK             GENMASK(12, 8)
- #define PCS_MODE_SGMII                        FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
- #define PCS_MODE_QSGMII                       FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
-+#define PCS_MODE_XPCS                 FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
- #define PCS_MII_CTRL(x)                       (0x480 + 0x18 * (x))
- #define PCS_MII_ADPT_RESET            BIT(11)
-@@ -54,6 +55,34 @@
-                                        FIELD_PREP(GENMASK(9, 2), \
-                                        FIELD_GET(XPCS_INDIRECT_ADDR_L, reg)))
-+#define XPCS_DIG_CTRL                 0x38000
-+#define XPCS_USXG_ADPT_RESET          BIT(10)
-+#define XPCS_USXG_EN                  BIT(9)
-+
-+#define XPCS_MII_CTRL                 0x1f0000
-+#define XPCS_MII_AN_EN                        BIT(12)
-+#define XPCS_DUPLEX_FULL              BIT(8)
-+#define XPCS_SPEED_MASK                       (BIT(13) | BIT(6) | BIT(5))
-+#define XPCS_SPEED_10000              (BIT(13) | BIT(6))
-+#define XPCS_SPEED_5000                       (BIT(13) | BIT(5))
-+#define XPCS_SPEED_2500                       BIT(5)
-+#define XPCS_SPEED_1000                       BIT(6)
-+#define XPCS_SPEED_100                        BIT(13)
-+#define XPCS_SPEED_10                 0
-+
-+#define XPCS_MII_AN_CTRL              0x1f8001
-+#define XPCS_MII_AN_8BIT              BIT(8)
-+
-+#define XPCS_MII_AN_INTR_STS          0x1f8002
-+#define XPCS_USXG_AN_LINK_STS         BIT(14)
-+#define XPCS_USXG_AN_SPEED_MASK               GENMASK(12, 10)
-+#define XPCS_USXG_AN_SPEED_10         0
-+#define XPCS_USXG_AN_SPEED_100                1
-+#define XPCS_USXG_AN_SPEED_1000               2
-+#define XPCS_USXG_AN_SPEED_2500               4
-+#define XPCS_USXG_AN_SPEED_5000               5
-+#define XPCS_USXG_AN_SPEED_10000      3
-+
- /* Per PCS MII private data */
- struct ipq_pcs_mii {
-       struct ipq_pcs *qpcs;
-@@ -123,9 +152,54 @@ static void ipq_pcs_get_state_sgmii(stru
-               state->duplex = DUPLEX_HALF;
- }
-+static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs,
-+                                    struct phylink_link_state *state)
-+{
-+      unsigned int val;
-+      int ret;
-+
-+      ret = regmap_read(qpcs->regmap, XPCS_MII_AN_INTR_STS, &val);
-+      if (ret) {
-+              state->link = 0;
-+              return;
-+      }
-+
-+      state->link = !!(val & XPCS_USXG_AN_LINK_STS);
-+
-+      if (!state->link)
-+              return;
-+
-+      switch (FIELD_GET(XPCS_USXG_AN_SPEED_MASK, val)) {
-+      case XPCS_USXG_AN_SPEED_10000:
-+              state->speed = SPEED_10000;
-+              break;
-+      case XPCS_USXG_AN_SPEED_5000:
-+              state->speed = SPEED_5000;
-+              break;
-+      case XPCS_USXG_AN_SPEED_2500:
-+              state->speed = SPEED_2500;
-+              break;
-+      case XPCS_USXG_AN_SPEED_1000:
-+              state->speed = SPEED_1000;
-+              break;
-+      case XPCS_USXG_AN_SPEED_100:
-+              state->speed = SPEED_100;
-+              break;
-+      case XPCS_USXG_AN_SPEED_10:
-+              state->speed = SPEED_10;
-+              break;
-+      default:
-+              state->link = false;
-+              return;
-+      }
-+
-+      state->duplex = DUPLEX_FULL;
-+}
-+
- static int ipq_pcs_config_mode(struct ipq_pcs *qpcs,
-                              phy_interface_t interface)
- {
-+      unsigned long rate = 125000000;
-       unsigned int val;
-       int ret;
-@@ -137,6 +211,10 @@ static int ipq_pcs_config_mode(struct ip
-       case PHY_INTERFACE_MODE_QSGMII:
-               val = PCS_MODE_QSGMII;
-               break;
-+      case PHY_INTERFACE_MODE_USXGMII:
-+              val = PCS_MODE_XPCS;
-+              rate = 312500000;
-+              break;
-       default:
-               return -EOPNOTSUPP;
-       }
-@@ -167,6 +245,21 @@ static int ipq_pcs_config_mode(struct ip
-       qpcs->interface = interface;
-+      /* Configure the RX and TX clock to NSSCC as 125M or 312.5M based
-+       * on current interface mode.
-+       */
-+      ret = clk_set_rate(qpcs->rx_hw.clk, rate);
-+      if (ret) {
-+              dev_err(qpcs->dev, "Failed to set RX clock rate\n");
-+              return ret;
-+      }
-+
-+      ret = clk_set_rate(qpcs->tx_hw.clk, rate);
-+      if (ret) {
-+              dev_err(qpcs->dev, "Failed to set TX clock rate\n");
-+              return ret;
-+      }
-+
-       return 0;
- }
-@@ -195,6 +288,29 @@ static int ipq_pcs_config_sgmii(struct i
-                              PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
- }
-+static int ipq_pcs_config_usxgmii(struct ipq_pcs *qpcs)
-+{
-+      int ret;
-+
-+      /* Configure the XPCS for USXGMII mode if required */
-+      if (qpcs->interface == PHY_INTERFACE_MODE_USXGMII)
-+              return 0;
-+
-+      ret = ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_USXGMII);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_USXG_EN);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_set_bits(qpcs->regmap, XPCS_MII_AN_CTRL, XPCS_MII_AN_8BIT);
-+      if (ret)
-+              return ret;
-+
-+      return regmap_set_bits(qpcs->regmap, XPCS_MII_CTRL, XPCS_MII_AN_EN);
-+}
-+
- static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs,
-                                       int index,
-                                       unsigned int neg_mode,
-@@ -237,6 +353,46 @@ static int ipq_pcs_link_up_config_sgmii(
-                              PCS_MII_CTRL(index), PCS_MII_ADPT_RESET);
- }
-+static int ipq_pcs_link_up_config_usxgmii(struct ipq_pcs *qpcs, int speed)
-+{
-+      unsigned int val;
-+      int ret;
-+
-+      switch (speed) {
-+      case SPEED_10000:
-+              val = XPCS_SPEED_10000;
-+              break;
-+      case SPEED_5000:
-+              val = XPCS_SPEED_5000;
-+              break;
-+      case SPEED_2500:
-+              val = XPCS_SPEED_2500;
-+              break;
-+      case SPEED_1000:
-+              val = XPCS_SPEED_1000;
-+              break;
-+      case SPEED_100:
-+              val = XPCS_SPEED_100;
-+              break;
-+      case SPEED_10:
-+              val = XPCS_SPEED_10;
-+              break;
-+      default:
-+              dev_err(qpcs->dev, "Invalid USXGMII speed %d\n", speed);
-+              return -EINVAL;
-+      }
-+
-+      /* Configure XPCS speed */
-+      ret = regmap_update_bits(qpcs->regmap, XPCS_MII_CTRL,
-+                               XPCS_SPEED_MASK, val | XPCS_DUPLEX_FULL);
-+      if (ret)
-+              return ret;
-+
-+      /* XPCS adapter reset */
-+      return regmap_set_bits(qpcs->regmap,
-+                             XPCS_DIG_CTRL, XPCS_USXG_ADPT_RESET);
-+}
-+
- static int ipq_pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
-                           const struct phylink_link_state *state)
- {
-@@ -244,6 +400,11 @@ static int ipq_pcs_validate(struct phyli
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-               return 0;
-+      case PHY_INTERFACE_MODE_USXGMII:
-+              /* USXGMII only supports full duplex mode */
-+              phylink_clear(supported, 100baseT_Half);
-+              phylink_clear(supported, 10baseT_Half);
-+              return 0;
-       default:
-               return -EINVAL;
-       }
-@@ -255,6 +416,7 @@ static unsigned int ipq_pcs_inband_caps(
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_USXGMII:
-               return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-       default:
-               return 0;
-@@ -307,6 +469,9 @@ static void ipq_pcs_get_state(struct phy
-       case PHY_INTERFACE_MODE_QSGMII:
-               ipq_pcs_get_state_sgmii(qpcs, index, state);
-               break;
-+      case PHY_INTERFACE_MODE_USXGMII:
-+              ipq_pcs_get_state_usxgmii(qpcs, state);
-+              break;
-       default:
-               break;
-       }
-@@ -333,6 +498,8 @@ static int ipq_pcs_config(struct phylink
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-               return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
-+      case PHY_INTERFACE_MODE_USXGMII:
-+              return ipq_pcs_config_usxgmii(qpcs);
-       default:
-               return -EOPNOTSUPP;
-       };
-@@ -354,6 +521,9 @@ static void ipq_pcs_link_up(struct phyli
-               ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
-                                                  neg_mode, speed);
-               break;
-+      case PHY_INTERFACE_MODE_USXGMII:
-+              ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed);
-+              break;
-       default:
-               return;
-       }
diff --git a/target/linux/qualcommbe/patches-6.12/0318-MAINTAINERS-Add-maintainer-for-Qualcomm-IPQ9574-PCS-.patch b/target/linux/qualcommbe/patches-6.12/0318-MAINTAINERS-Add-maintainer-for-Qualcomm-IPQ9574-PCS-.patch
deleted file mode 100644 (file)
index adaf557..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From 34d10a4eb8fea32bb79e3012dc9d8bd2dffb0df3 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Fri, 7 Feb 2025 23:53:16 +0800
-Subject: [PATCH] MAINTAINERS: Add maintainer for Qualcomm IPQ9574 PCS driver
-
-Add maintainer for the Ethernet PCS driver supported for Qualcomm
-IPQ9574 SoC.
-
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
----
- MAINTAINERS | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19129,6 +19129,15 @@ S:    Maintained
- F:    Documentation/devicetree/bindings/regulator/vqmmc-ipq4019-regulator.yaml
- F:    drivers/regulator/vqmmc-ipq4019-regulator.c
-+QUALCOMM IPQ9574 Ethernet PCS DRIVER
-+M:    Lei Wei <quic_leiwei@quicinc.com>
-+L:    netdev@vger.kernel.org
-+S:    Supported
-+F:    Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml
-+F:    drivers/net/pcs/pcs-qcom-ipq9574.c
-+F:    include/dt-bindings/net/qcom,ipq9574-pcs.h
-+F:    include/linux/pcs/pcs-qcom-ipq9574.h
-+
- QUALCOMM NAND CONTROLLER DRIVER
- M:    Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
- L:    linux-mtd@lists.infradead.org
diff --git a/target/linux/qualcommbe/patches-6.12/0322-arm64-dts-qcom-ipq9574-add-PCS-uniphy-nodes.patch b/target/linux/qualcommbe/patches-6.12/0322-arm64-dts-qcom-ipq9574-add-PCS-uniphy-nodes.patch
deleted file mode 100644 (file)
index 8196ff6..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-From d6f184181b076cbb54f152994f5bc73ce524a67e Mon Sep 17 00:00:00 2001
-From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
-Date: Sun, 11 May 2025 18:21:00 -0500
-Subject: [PATCH] arm64: dts: qcom: ipq9574: add PCS uniphy nodes
-
-IPQ9574 has three uniphy blocks. IPQ9554 lacks uniphy1. They take
-their system and AHB clocks from NSSCC, and also feed NSSCC with
-the clocks that are intended for the PHYs. This is not a cirular
-dependency. Add nodes for these uniphy blocks, and the clocks they
-feed back to the NSSCC node.
-
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 100 ++++++++++++++++++++++++--
- 1 file changed, 94 insertions(+), 6 deletions(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -9,6 +9,7 @@
- #include <dt-bindings/clock/qcom,apss-ipq.h>
- #include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
- #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
-+#include <dt-bindings/clock/qcom,ipq9574-nsscc.h>
- #include <dt-bindings/interconnect/qcom,ipq9574.h>
- #include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <dt-bindings/reset/qcom,ipq9574-gcc.h>
-@@ -1247,12 +1248,12 @@
-                                <&cmn_pll NSS_1200MHZ_CLK>,
-                                <&cmn_pll PPE_353MHZ_CLK>,
-                                <&gcc GPLL0_OUT_AUX>,
--                               <0>,
--                               <0>,
--                               <0>,
--                               <0>,
--                               <0>,
--                               <0>,
-+                               <&pcs0 0>,
-+                               <&pcs0 1>,
-+                               <&pcs1 0>,
-+                               <&pcs1 1>,
-+                               <&pcs2 0>,
-+                               <&pcs2 1>,
-                                <&gcc GCC_NSSCC_CLK>;
-                       clock-names = "xo",
-                                     "nss_1200",
-@@ -1269,6 +1270,93 @@
-                       #reset-cells = <1>;
-                       #interconnect-cells = <1>;
-               };
-+
-+              pcs0: ethernet-pcs@7a00000 {
-+                      compatible = "qcom,ipq9574-pcs";
-+                      reg = <0x7a00000 0x10000>;
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+                      clocks = <&gcc GCC_UNIPHY0_SYS_CLK>,
-+                               <&gcc GCC_UNIPHY0_AHB_CLK>;
-+                      clock-names = "sys",
-+                                    "ahb";
-+                      resets = <&gcc GCC_UNIPHY0_XPCS_RESET>;
-+                      #clock-cells = <1>;
-+
-+                      pcs0_ch0: pcs-mii@0 {
-+                              reg = <0>;
-+                              clocks = <&nsscc NSS_CC_UNIPHY_PORT1_RX_CLK>,
-+                                       <&nsscc NSS_CC_UNIPHY_PORT1_TX_CLK>;
-+                              clock-names = "rx",
-+                                            "tx";
-+                      };
-+
-+                      pcs0_ch1: pcs-mii@1 {
-+                              reg = <1>;
-+                              clocks = <&nsscc NSS_CC_UNIPHY_PORT2_RX_CLK>,
-+                                       <&nsscc NSS_CC_UNIPHY_PORT2_TX_CLK>;
-+                              clock-names = "rx",
-+                                            "tx";
-+                      };
-+
-+                      pcs0_ch2: pcs-mii@2 {
-+                              reg = <2>;
-+                              clocks = <&nsscc NSS_CC_UNIPHY_PORT3_RX_CLK>,
-+                                       <&nsscc NSS_CC_UNIPHY_PORT3_TX_CLK>;
-+                              clock-names = "rx",
-+                                            "tx";
-+                      };
-+
-+                      pcs0_ch3: pcs-mii@3 {
-+                              reg = <3>;
-+                              clocks = <&nsscc NSS_CC_UNIPHY_PORT4_RX_CLK>,
-+                                       <&nsscc NSS_CC_UNIPHY_PORT4_TX_CLK>;
-+                              clock-names = "rx",
-+                                            "tx";
-+                      };
-+              };
-+
-+              pcs1: ethernet-pcs@7a10000 {
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+                      compatible = "qcom,ipq9574-pcs";
-+                      reg = <0x7a10000 0x10000>;
-+                      clocks = <&gcc GCC_UNIPHY1_SYS_CLK>,
-+                               <&gcc GCC_UNIPHY1_AHB_CLK>;
-+                      clock-names = "sys",
-+                                    "ahb";
-+                      resets = <&gcc GCC_UNIPHY1_XPCS_RESET>;
-+                      #clock-cells = <1>;
-+
-+                      pcs1_ch0: pcs-mii@0 {
-+                              reg = <0>;
-+                              clocks = <&nsscc NSS_CC_UNIPHY_PORT5_RX_CLK>,
-+                                       <&nsscc NSS_CC_UNIPHY_PORT5_TX_CLK>;
-+                              clock-names = "rx",
-+                                            "tx";
-+                      };
-+              };
-+
-+              pcs2: ethernet-pcs@7a20000 {
-+                      compatible = "qcom,ipq9574-pcs";
-+                      reg = <0x7a20000 0x10000>;
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+                      clocks = <&gcc GCC_UNIPHY2_SYS_CLK>,
-+                               <&gcc GCC_UNIPHY2_AHB_CLK>;
-+                      clock-names = "sys",
-+                                    "ahb";
-+                      resets = <&gcc GCC_UNIPHY2_XPCS_RESET>;
-+                      #clock-cells = <1>;
-+
-+                      pcs2_ch0: pcs-mii@0 {
-+                              reg = <0>;
-+                              clocks = <&nsscc NSS_CC_UNIPHY_PORT6_RX_CLK>,
-+                                       <&nsscc NSS_CC_UNIPHY_PORT6_TX_CLK>;
-+                              clock-names = "rx",
-+                                            "tx";
-+                      };
-+              };
-       };
-       thermal-zones {
diff --git a/target/linux/qualcommbe/patches-6.12/0323-dt-bindings-net-Add-PPE-for-Qualcomm-IPQ9574-SoC.patch b/target/linux/qualcommbe/patches-6.12/0323-dt-bindings-net-Add-PPE-for-Qualcomm-IPQ9574-SoC.patch
deleted file mode 100644 (file)
index 89c09ff..0000000
+++ /dev/null
@@ -1,432 +0,0 @@
-From 48dc6d2fe28865a5c3d271aeb966b984a8085e7c Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:35 +0800
-Subject: [PATCH] dt-bindings: net: Add PPE for Qualcomm IPQ9574 SoC
-
-The PPE (packet process engine) hardware block is available in Qualcomm
-IPQ chipsets that support PPE architecture, such as IPQ9574. The PPE in
-the IPQ9574 SoC includes six ethernet ports (6 GMAC and 6 XGMAC), which
-are used to connect with external PHY devices by PCS. It includes an L2
-switch function for bridging packets among the 6 ethernet ports and the
-CPU port. The CPU port enables packet transfer between the ethernet
-ports and the ARM cores in the SoC, using the ethernet DMA.
-
-The PPE also includes packet processing offload capabilities for various
-networking functions such as route and bridge flows, VLANs, different
-tunnel protocols and VPN.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../bindings/net/qcom,ipq9574-ppe.yaml        | 406 ++++++++++++++++++
- 1 file changed, 406 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
-@@ -0,0 +1,406 @@
-+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/qcom,ipq9574-ppe.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Qualcomm IPQ packet process engine (PPE)
-+
-+maintainers:
-+  - Luo Jie <quic_luoj@quicinc.com>
-+  - Lei Wei <quic_leiwei@quicinc.com>
-+  - Suruchi Agarwal <quic_suruchia@quicinc.com>
-+  - Pavithra R <quic_pavir@quicinc.com>>
-+
-+description:
-+  The Ethernet functionality in the PPE (Packet Process Engine) is comprised
-+  of three components, the switch core, port wrapper and Ethernet DMA.
-+
-+  The Switch core in the IPQ9574 PPE has maximum of 6 front panel ports and
-+  two FIFO interfaces. One of the two FIFO interfaces is used for Ethernet
-+  port to host CPU communication using Ethernet DMA. The other is used
-+  communicating to the EIP engine which is used for IPsec offload. On the
-+  IPQ9574, the PPE includes 6 GMAC/XGMACs that can be connected with external
-+  Ethernet PHY. Switch core also includes BM (Buffer Management), QM (Queue
-+  Management) and SCH (Scheduler) modules for supporting the packet processing.
-+
-+  The port wrapper provides connections from the 6 GMAC/XGMACS to UNIPHY (PCS)
-+  supporting various modes such as SGMII/QSGMII/PSGMII/USXGMII/10G-BASER. There
-+  are 3 UNIPHY (PCS) instances supported on the IPQ9574.
-+
-+  Ethernet DMA is used to transmit and receive packets between the six Ethernet
-+  ports and ARM host CPU.
-+
-+  The follow diagram shows the PPE hardware block along with its connectivity
-+  to the external hardware blocks such clock hardware blocks (CMNPLL, GCC,
-+  NSS clock controller) and ethernet PCS/PHY blocks. For depicting the PHY
-+  connectivity, one 4x1 Gbps PHY (QCA8075) and two 10 GBps PHYs are used as an
-+  example.
-+  - |
-+         +---------+
-+         |  48 MHZ |
-+         +----+----+
-+              |(clock)
-+              v
-+         +----+----+
-+  +------| CMN PLL |
-+  |      +----+----+
-+  |           |(clock)
-+  |           v
-+  |      +----+----+           +----+----+  (clock) +----+----+
-+  |  +---|  NSSCC  |           |   GCC   |--------->|   MDIO  |
-+  |  |   +----+----+           +----+----+          +----+----+
-+  |  |        |(clock & reset)      |(clock)
-+  |  |        v                     v
-+  |  |   +-----------------------------+----------+----------+---------+
-+  |  |   |       +-----+               |EDMA FIFO |          | EIP FIFO|
-+  |  |   |       | SCH |               +----------+          +---------+
-+  |  |   |       +-----+                        |              |       |
-+  |  |   |  +------+   +------+               +-------------------+    |
-+  |  |   |  |  BM  |   |  QM  |  IPQ9574-PPE  |    L2/L3 Process  |    |
-+  |  |   |  +------+   +------+               +-------------------+    |
-+  |  |   |                                             |               |
-+  |  |   | +-------+ +-------+ +-------+ +-------+ +-------+ +-------+ |
-+  |  |   | |  MAC0 | |  MAC1 | |  MAC2 | |  MAC3 | | XGMAC4| |XGMAC5 | |
-+  |  |   | +---+---+ +---+---+ +---+---+ +---+---+ +---+---+ +---+---+ |
-+  |  |   |     |         |         |         |         |         |     |
-+  |  |   +-----+---------+---------+---------+---------+---------+-----+
-+  |  |         |         |         |         |         |         |
-+  |  |     +---+---------+---------+---------+---+ +---+---+ +---+---+
-+  +--+---->|                PCS0                 | |  PCS1 | | PCS2  |
-+  |(clock) +---+---------+---------+---------+---+ +---+---+ +---+---+
-+  |            |         |         |         |         |         |
-+  |        +---+---------+---------+---------+---+ +---+---+ +---+---+
-+  +------->|             QCA8075 PHY             | | PHY4  | | PHY5  |
-+   (clock) +-------------------------------------+ +-------+ +-------+
-+
-+properties:
-+  compatible:
-+    enum:
-+      - qcom,ipq9574-ppe
-+
-+  reg:
-+    maxItems: 1
-+
-+  clocks:
-+    items:
-+      - description: PPE core clock from NSS clock controller
-+      - description: PPE APB (Advanced Peripheral Bus) clock from NSS clock controller
-+      - description: PPE ingress process engine clock from NSS clock controller
-+      - description: PPE BM, QM and scheduler clock from NSS clock controller
-+
-+  clock-names:
-+    items:
-+      - const: ppe
-+      - const: apb
-+      - const: ipe
-+      - const: btq
-+
-+  resets:
-+    maxItems: 1
-+    description: PPE reset, which is necessary before configuring PPE hardware
-+
-+  interconnects:
-+    items:
-+      - description: Clock path leading to PPE switch core function
-+      - description: Clock path leading to PPE register access
-+      - description: Clock path leading to QoS generation
-+      - description: Clock path leading to timeout reference
-+      - description: Clock path leading to NSS NOC from memory NOC
-+      - description: Clock path leading to memory NOC from NSS NOC
-+      - description: Clock path leading to enhanced memory NOC from NSS NOC
-+
-+  interconnect-names:
-+    items:
-+      - const: ppe
-+      - const: ppe_cfg
-+      - const: qos_gen
-+      - const: timeout_ref
-+      - const: nssnoc_memnoc
-+      - const: memnoc_nssnoc
-+      - const: memnoc_nssnoc_1
-+
-+  ethernet-dma:
-+    type: object
-+    additionalProperties: false
-+    description:
-+      EDMA (Ethernet DMA) is used to transmit packets between PPE and ARM
-+      host CPU. There are 32 TX descriptor rings, 32 TX completion rings,
-+      24 RX descriptor rings and 8 RX fill rings supported.
-+
-+    properties:
-+      clocks:
-+        items:
-+          - description: EDMA system clock from NSS Clock Controller
-+          - description: EDMA APB (Advanced Peripheral Bus) clock from
-+              NSS Clock Controller
-+
-+      clock-names:
-+        items:
-+          - const: sys
-+          - const: apb
-+
-+      resets:
-+        maxItems: 1
-+        description: EDMA reset from NSS clock controller
-+
-+      interrupts:
-+        minItems: 29
-+        maxItems: 57
-+
-+      interrupt-names:
-+        minItems: 29
-+        maxItems: 57
-+        items:
-+          pattern: '^(txcmpl_([0-9]|[1-2][0-9]|3[0-1])|rxdesc_([0-9]|1[0-9]|2[0-3])|misc)$'
-+        description:
-+          Interrupts "txcmpl_[0-31]" are the Ethernet DMA Tx completion ring interrupts.
-+          Interrupts "rxdesc_[0-23]" are the Ethernet DMA Rx Descriptor ring interrupts.
-+          Interrupt "misc" is the Ethernet DMA miscellaneous error interrupt.
-+
-+    required:
-+      - clocks
-+      - clock-names
-+      - resets
-+      - interrupts
-+      - interrupt-names
-+
-+required:
-+  - compatible
-+  - reg
-+  - clocks
-+  - clock-names
-+  - resets
-+  - interconnects
-+  - interconnect-names
-+  - ethernet-dma
-+
-+allOf:
-+  - $ref: ethernet-switch.yaml
-+
-+unevaluatedProperties: false
-+
-+examples:
-+  - |
-+    #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
-+    #include <dt-bindings/interconnect/qcom,ipq9574.h>
-+    #include <dt-bindings/interrupt-controller/arm-gic.h>
-+
-+    ethernet-switch@3a000000 {
-+        compatible = "qcom,ipq9574-ppe";
-+        reg = <0x3a000000 0xbef800>;
-+        clocks = <&nsscc 80>,
-+                 <&nsscc 79>,
-+                 <&nsscc 81>,
-+                 <&nsscc 78>;
-+        clock-names = "ppe",
-+                      "apb",
-+                      "ipe",
-+                      "btq";
-+        resets = <&nsscc 108>;
-+        interconnects = <&nsscc MASTER_NSSNOC_PPE &nsscc SLAVE_NSSNOC_PPE>,
-+                        <&nsscc MASTER_NSSNOC_PPE_CFG &nsscc SLAVE_NSSNOC_PPE_CFG>,
-+                        <&gcc MASTER_NSSNOC_QOSGEN_REF &gcc SLAVE_NSSNOC_QOSGEN_REF>,
-+                        <&gcc MASTER_NSSNOC_TIMEOUT_REF &gcc SLAVE_NSSNOC_TIMEOUT_REF>,
-+                        <&gcc MASTER_MEM_NOC_NSSNOC &gcc SLAVE_MEM_NOC_NSSNOC>,
-+                        <&gcc MASTER_NSSNOC_MEMNOC &gcc SLAVE_NSSNOC_MEMNOC>,
-+                        <&gcc MASTER_NSSNOC_MEM_NOC_1 &gcc SLAVE_NSSNOC_MEM_NOC_1>;
-+        interconnect-names = "ppe",
-+                             "ppe_cfg",
-+                             "qos_gen",
-+                             "timeout_ref",
-+                             "nssnoc_memnoc",
-+                             "memnoc_nssnoc",
-+                             "memnoc_nssnoc_1";
-+
-+        ethernet-dma {
-+            clocks = <&nsscc 77>,
-+                     <&nsscc 76>;
-+            clock-names = "sys",
-+                          "apb";
-+            resets = <&nsscc 0>;
-+            interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 505 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 504 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 502 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 501 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
-+                         <GIC_SPI 499 IRQ_TYPE_LEVEL_HIGH>;
-+            interrupt-names = "txcmpl_8",
-+                              "txcmpl_9",
-+                              "txcmpl_10",
-+                              "txcmpl_11",
-+                              "txcmpl_12",
-+                              "txcmpl_13",
-+                              "txcmpl_14",
-+                              "txcmpl_15",
-+                              "txcmpl_16",
-+                              "txcmpl_17",
-+                              "txcmpl_18",
-+                              "txcmpl_19",
-+                              "txcmpl_20",
-+                              "txcmpl_21",
-+                              "txcmpl_22",
-+                              "txcmpl_23",
-+                              "txcmpl_24",
-+                              "txcmpl_25",
-+                              "txcmpl_26",
-+                              "txcmpl_27",
-+                              "txcmpl_28",
-+                              "txcmpl_29",
-+                              "txcmpl_30",
-+                              "txcmpl_31",
-+                              "rxdesc_20",
-+                              "rxdesc_21",
-+                              "rxdesc_22",
-+                              "rxdesc_23",
-+                              "misc";
-+        };
-+
-+        ethernet-ports {
-+            #address-cells = <1>;
-+            #size-cells = <0>;
-+
-+            port@1 {
-+                reg = <1>;
-+                phy-mode = "qsgmii";
-+                managed = "in-band-status";
-+                phy-handle = <&phy0>;
-+                pcs-handle = <&pcs0_mii0>;
-+                clocks = <&nsscc 33>,
-+                         <&nsscc 34>,
-+                         <&nsscc 37>;
-+                clock-names = "mac",
-+                              "rx",
-+                              "tx";
-+                resets = <&nsscc 29>,
-+                         <&nsscc 96>,
-+                         <&nsscc 97>;
-+                reset-names = "mac",
-+                              "rx",
-+                              "tx";
-+            };
-+
-+            port@2 {
-+                reg = <2>;
-+                phy-mode = "qsgmii";
-+                managed = "in-band-status";
-+                phy-handle = <&phy1>;
-+                pcs-handle = <&pcs0_mii1>;
-+                clocks = <&nsscc 40>,
-+                         <&nsscc 41>,
-+                         <&nsscc 44>;
-+                clock-names = "mac",
-+                              "rx",
-+                              "tx";
-+                resets = <&nsscc 30>,
-+                         <&nsscc 98>,
-+                         <&nsscc 99>;
-+                reset-names = "mac",
-+                              "rx",
-+                              "tx";
-+            };
-+
-+            port@3 {
-+                reg = <3>;
-+                phy-mode = "qsgmii";
-+                managed = "in-band-status";
-+                phy-handle = <&phy2>;
-+                pcs-handle = <&pcs0_mii2>;
-+                clocks = <&nsscc 47>,
-+                         <&nsscc 48>,
-+                         <&nsscc 51>;
-+                clock-names = "mac",
-+                              "rx",
-+                              "tx";
-+                resets = <&nsscc 31>,
-+                         <&nsscc 100>,
-+                         <&nsscc 101>;
-+                reset-names = "mac",
-+                              "rx",
-+                              "tx";
-+            };
-+
-+            port@4 {
-+                reg = <4>;
-+                phy-mode = "qsgmii";
-+                managed = "in-band-status";
-+                phy-handle = <&phy3>;
-+                pcs-handle = <&pcs0_mii3>;
-+                clocks = <&nsscc 54>,
-+                         <&nsscc 55>,
-+                         <&nsscc 58>;
-+                clock-names = "mac",
-+                              "rx",
-+                              "tx";
-+                resets = <&nsscc 32>,
-+                         <&nsscc 102>,
-+                         <&nsscc 103>;
-+                reset-names = "mac",
-+                              "rx",
-+                              "tx";
-+            };
-+
-+            port@5 {
-+                reg = <5>;
-+                phy-mode = "usxgmii";
-+                managed = "in-band-status";
-+                phy-handle = <&phy4>;
-+                pcs-handle = <&pcs1_mii0>;
-+                clocks = <&nsscc 61>,
-+                         <&nsscc 62>,
-+                         <&nsscc 65>;
-+                clock-names = "mac",
-+                              "rx",
-+                              "tx";
-+                resets = <&nsscc 33>,
-+                         <&nsscc 104>,
-+                         <&nsscc 105>;
-+                reset-names = "mac",
-+                              "rx",
-+                              "tx";
-+            };
-+
-+            port@6 {
-+                reg = <6>;
-+                phy-mode = "usxgmii";
-+                managed = "in-band-status";
-+                phy-handle = <&phy5>;
-+                pcs-handle = <&pcs2_mii0>;
-+                clocks = <&nsscc 68>,
-+                         <&nsscc 69>,
-+                         <&nsscc 72>;
-+                clock-names = "mac",
-+                              "rx",
-+                              "tx";
-+                resets = <&nsscc 34>,
-+                         <&nsscc 106>,
-+                         <&nsscc 107>;
-+                reset-names = "mac",
-+                              "rx",
-+                              "tx";
-+            };
-+        };
-+    };
diff --git a/target/linux/qualcommbe/patches-6.12/0324-docs-networking-Add-PPE-driver-documentation-for-Qua.patch b/target/linux/qualcommbe/patches-6.12/0324-docs-networking-Add-PPE-driver-documentation-for-Qua.patch
deleted file mode 100644 (file)
index 429006c..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-From 9973b6610830146af1a12fe02d2d6440eb80b0f9 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:36 +0800
-Subject: [PATCH] docs: networking: Add PPE driver documentation for Qualcomm
- IPQ9574 SoC
-
-Add description and high-level diagram for PPE, driver overview and
-module enable/debug information.
-
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../device_drivers/ethernet/index.rst         |   1 +
- .../ethernet/qualcomm/ppe/ppe.rst             | 197 ++++++++++++++++++
- 2 files changed, 198 insertions(+)
- create mode 100644 Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
-
---- a/Documentation/networking/device_drivers/ethernet/index.rst
-+++ b/Documentation/networking/device_drivers/ethernet/index.rst
-@@ -49,6 +49,7 @@ Contents:
-    neterion/s2io
-    netronome/nfp
-    pensando/ionic
-+   qualcomm/ppe/ppe
-    smsc/smc9
-    stmicro/stmmac
-    ti/cpsw
---- /dev/null
-+++ b/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
-@@ -0,0 +1,197 @@
-+.. SPDX-License-Identifier: GPL-2.0
-+
-+===============================================
-+PPE Ethernet Driver for Qualcomm IPQ SoC Family
-+===============================================
-+
-+Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+
-+Author: Lei Wei <quic_leiwei@quicinc.com>
-+
-+
-+Contents
-+========
-+
-+- `PPE Overview`_
-+- `PPE Driver Overview`_
-+- `PPE Driver Supported SoCs`_
-+- `Enabling the Driver`_
-+- `Debugging`_
-+
-+
-+PPE Overview
-+============
-+
-+IPQ (Qualcomm Internet Processor) SoC (System-on-Chip) series is Qualcomm's series of
-+networking SoC for Wi-Fi access points. The PPE (Packet Process Engine) is the Ethernet
-+packet process engine in the IPQ SoC.
-+
-+Below is a simplified hardware diagram of IPQ9574 SoC which includes the PPE engine and
-+other blocks which are in the SoC but outside the PPE engine. These blocks work together
-+to enable the Ethernet for the IPQ SoC::
-+
-+             +------+ +------+ +------+ +------+ +------+  +------+ start +-------+
-+             |netdev| |netdev| |netdev| |netdev| |netdev|  |netdev|<------|PHYLINK|
-+             +------+ +------+ +------+ +------+ +------+  +------+ stop  +-+-+-+-+
-+                                           |                                | | ^
-+ +-------+   +-------------------------+--------+----------------------+    | | |
-+ | GCC   |   |                         |  EDMA  |                      |    | | |
-+ +---+---+   |  PPE                    +---+----+                      |    | | |
-+     | clk   |                             |                           |    | | |
-+     +------>| +-----------------------+------+-----+---------------+  |    | | |
-+             | |   Switch Core         |Port0 |     |Port7(EIP FIFO)|  |    | | |
-+             | |                       +---+--+     +------+--------+  |    | | |
-+             | |                           |               |        |  |    | | |
-+ +-------+   | |                    +------+---------------+----+   |  |    | | |
-+ |CMN PLL|   | | +---+ +---+ +----+ | +--------+                |   |  |    | | |
-+ +---+---+   | | |BM | |QM | |SCH | | | L2/L3  |  .......       |   |  |    | | |
-+ |   |       | | +---+ +---+ +----+ | +--------+                |   |  |    | | |
-+ |   |       | |                    +------+--------------------+   |  |    | | |
-+ |   |       | |                           |                        |  |    | | |
-+ |   v       | | +-----+-+-----+-+-----+-+-+---+--+-----+-+-----+   |  |    | | |
-+ | +------+  | | |Port1| |Port2| |Port3| |Port4|  |Port5| |Port6|   |  |    | | |
-+ | |NSSCC |  | | +-----+ +-----+ +-----+ +-----+  +-----+ +-----+   |  | mac| | |
-+ | +-+-+--+  | | |MAC0 | |MAC1 | |MAC2 | |MAC3 |  |MAC4 | |MAC5 |   |  |<---+ | |
-+ | ^ | |clk  | | +-----+-+-----+-+-----+-+-----+--+-----+-+-----+   |  | ops  | |
-+ | | | +---->| +----|------|-------|-------|---------|--------|-----+  |      | |
-+ | | |       +---------------------------------------------------------+      | |
-+ | | |              |      |       |       |         |        |               | |
-+ | | |   MII clk    |      QSGMII               USXGMII   USXGMII             | |
-+ | | +------------->|      |       |       |         |        |               | |
-+ | |              +-------------------------+ +---------+ +---------+         | |
-+ | |125/312.5M clk|       (PCS0)            | | (PCS1)  | | (PCS2)  | pcs ops | |
-+ | +--------------+       UNIPHY0           | | UNIPHY1 | | UNIPHY2 |<--------+ |
-+ +--------------->|                         | |         | |         |           |
-+ | 31.25M ref clk +-------------------------+ +---------+ +---------+           |
-+ |                   |     |      |      |          |          |                |
-+ |              +-----------------------------------------------------+         |
-+ |25/50M ref clk| +-------------------------+    +------+   +------+  | link    |
-+ +------------->| |      QUAD PHY           |    | PHY4 |   | PHY5 |  |---------+
-+                | +-------------------------+    +------+   +------+  | change
-+                |                                                     |
-+                |                       MDIO bus                      |
-+                +-----------------------------------------------------+
-+
-+The CMN (Common) PLL, NSSCC (Networking Sub System Clock Controller) and GCC (Global
-+Clock Controller) blocks are in the SoC and act as clock providers.
-+
-+The UNIPHY block is in the SoC and provides the PCS (Physical Coding Sublayer) and
-+XPCS (10-Gigabit Physical Coding Sublayer) functions to support different interface
-+modes between the PPE MAC and the external PHY.
-+
-+This documentation focuses on the descriptions of PPE engine and the PPE driver.
-+
-+The Ethernet functionality in the PPE (Packet Process Engine) is comprised of three
-+components: the switch core, port wrapper and Ethernet DMA.
-+
-+The Switch core in the IPQ9574 PPE has maximum of 6 front panel ports and two FIFO
-+interfaces. One of the two FIFO interfaces is used for Ethernet port to host CPU
-+communication using Ethernet DMA. The other is used communicating to the EIP engine
-+which is used for IPsec offload. On the IPQ9574, the PPE includes 6 GMAC/XGMACs that
-+can be connected with external Ethernet PHY. Switch core also includes BM (Buffer
-+Management), QM (Queue Management) and SCH (Scheduler) modules for supporting the
-+packet processing.
-+
-+The port wrapper provides connections from the 6 GMAC/XGMACS to UNIPHY (PCS) supporting
-+various modes such as SGMII/QSGMII/PSGMII/USXGMII/10G-BASER. There are 3 UNIPHY (PCS)
-+instances supported on the IPQ9574.
-+
-+Ethernet DMA is used to transmit and receive packets between the Ethernet subsystem
-+and ARM host CPU.
-+
-+The following lists the main blocks in the PPE engine which will be driven by this
-+PPE driver:
-+
-+- BM
-+    BM is the hardware buffer manager for the PPE switch ports.
-+- QM
-+    Queue Manager for managing the egress hardware queues of the PPE switch ports.
-+- SCH
-+    The scheduler which manages the hardware traffic scheduling for the PPE switch ports.
-+- L2
-+    The L2 block performs the packet bridging in the switch core. The bridge domain is
-+    represented by the VSI (Virtual Switch Instance) domain in PPE. FDB learning can be
-+    enabled based on the VSI domain and bridge forwarding occurs within the VSI domain.
-+- MAC
-+    The PPE in the IPQ9574 supports up to six MACs (MAC0 to MAC5) which are corresponding
-+    to six switch ports (port1 to port6). The MAC block is connected with external PHY
-+    through the UNIPHY PCS block. Each MAC block includes the GMAC and XGMAC blocks and
-+    the switch port can select to use GMAC or XMAC through a MUX selection according to
-+    the external PHY's capability.
-+- EDMA (Ethernet DMA)
-+    The Ethernet DMA is used to transmit and receive Ethernet packets between the PPE
-+    ports and the ARM cores.
-+
-+The received packet on a PPE MAC port can be forwarded to another PPE MAC port. It can
-+be also forwarded to internal switch port0 so that the packet can be delivered to the
-+ARM cores using the Ethernet DMA (EDMA) engine. The Ethernet DMA driver will deliver the
-+packet to the corresponding 'netdevice' interface.
-+
-+The software instantiations of the PPE MAC (netdevice), PCS and external PHYs interact
-+with the Linux PHYLINK framework to manage the connectivity between the PPE ports and
-+the connected PHYs, and the port link states. This is also illustrated in above diagram.
-+
-+
-+PPE Driver Overview
-+===================
-+PPE driver is Ethernet driver for the Qualcomm IPQ SoC. It is a single platform driver
-+which includes the PPE part and Ethernet DMA part. The PPE part initializes and drives the
-+various blocks in PPE switch core such as BM/QM/L2 blocks and the PPE MACs. The EDMA part
-+drives the Ethernet DMA for packet transfer between PPE ports and ARM cores, and enables
-+the netdevice driver for the PPE ports.
-+
-+The PPE driver files in drivers/net/ethernet/qualcomm/ppe/ are listed as below:
-+
-+- Makefile
-+- ppe.c
-+- ppe.h
-+- ppe_config.c
-+- ppe_config.h
-+- ppe_debugfs.c
-+- ppe_debugfs.h
-+- ppe_regs.h
-+
-+The ppe.c file contains the main PPE platform driver and undertakes the initialization of
-+PPE switch core blocks such as QM, BM and L2. The configuration APIs for these hardware
-+blocks are provided in the ppe_config.c file.
-+
-+The ppe.h defines the PPE device data structure which will be used by PPE driver functions.
-+
-+The ppe_debugfs.c enables the PPE statistics counters such as PPE port Rx and Tx counters,
-+CPU code counters and queue counters.
-+
-+
-+PPE Driver Supported SoCs
-+=========================
-+
-+The PPE driver supports the following IPQ SoC:
-+
-+- IPQ9574
-+
-+
-+Enabling the Driver
-+===================
-+
-+The driver is located in the menu structure at:
-+
-+  -> Device Drivers
-+    -> Network device support (NETDEVICES [=y])
-+      -> Ethernet driver support
-+        -> Qualcomm devices
-+          -> Qualcomm Technologies, Inc. PPE Ethernet support
-+
-+If this driver is built as a module, we can use below commands to install and remove it:
-+
-+- insmod qcom-ppe.ko
-+- rmmod qcom-ppe.ko
-+
-+The PPE driver functionally depends on the CMN PLL and NSSCC clock controller drivers.
-+Please make sure the dependent modules are installed before installing the PPE driver
-+module.
-+
-+
-+Debugging
-+=========
-+
-+The PPE hardware counters are available in the debugfs and can be checked by the command
-+``cat /sys/kernel/debug/ppe/packet_counters``.
diff --git a/target/linux/qualcommbe/patches-6.12/0325-net-ethernet-qualcomm-Add-PPE-driver-for-IPQ9574-SoC.patch b/target/linux/qualcommbe/patches-6.12/0325-net-ethernet-qualcomm-Add-PPE-driver-for-IPQ9574-SoC.patch
deleted file mode 100644 (file)
index f55879a..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-From d1158f0282304c89217894aa346fc45364b95542 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:37 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Add PPE driver for IPQ9574 SoC
-
-The PPE (Packet Process Engine) hardware block is available
-on Qualcomm IPQ SoC that support PPE architecture, such as
-IPQ9574.
-
-The PPE in IPQ9574 includes six integrated ethernet MAC
-(for 6 PPE ports), buffer management, queue management and
-scheduler functions. The MACs can connect with the external
-PHY or switch devices using the UNIPHY PCS block available
-in the SoC.
-
-The PPE also includes various packet processing offload
-capabilities such as L3 routing and L2 bridging, VLAN and
-tunnel processing offload. It also includes Ethernet DMA
-function for transferring packets between ARM cores and
-PPE ethernet ports.
-
-This patch adds the base source files and Makefiles for
-the PPE driver such as platform driver registration,
-clock initialization, and PPE reset routines.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- drivers/net/ethernet/qualcomm/Kconfig      |  15 ++
- drivers/net/ethernet/qualcomm/Makefile     |   1 +
- drivers/net/ethernet/qualcomm/ppe/Makefile |   7 +
- drivers/net/ethernet/qualcomm/ppe/ppe.c    | 218 +++++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/ppe.h    |  36 ++++
- 5 files changed, 277 insertions(+)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/Makefile
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe.h
-
---- a/drivers/net/ethernet/qualcomm/Kconfig
-+++ b/drivers/net/ethernet/qualcomm/Kconfig
-@@ -61,6 +61,21 @@ config QCOM_EMAC
-         low power, Receive-Side Scaling (RSS), and IEEE 1588-2008
-         Precision Clock Synchronization Protocol.
-+config QCOM_PPE
-+      tristate "Qualcomm Technologies, Inc. PPE Ethernet support"
-+      depends on HAS_IOMEM && OF
-+      depends on COMMON_CLK
-+      select REGMAP_MMIO
-+      help
-+        This driver supports the Qualcomm Technologies, Inc. packet
-+        process engine (PPE) available with IPQ SoC. The PPE includes
-+        the ethernet MACs, Ethernet DMA (EDMA) and switch core that
-+        supports L3 flow offload, L2 switch function, RSS and tunnel
-+        offload.
-+
-+        To compile this driver as a module, choose M here. The module
-+        will be called qcom-ppe.
-+
- source "drivers/net/ethernet/qualcomm/rmnet/Kconfig"
- endif # NET_VENDOR_QUALCOMM
---- a/drivers/net/ethernet/qualcomm/Makefile
-+++ b/drivers/net/ethernet/qualcomm/Makefile
-@@ -11,4 +11,5 @@ qcauart-objs := qca_uart.o
- obj-y += emac/
-+obj-$(CONFIG_QCOM_PPE) += ppe/
- obj-$(CONFIG_RMNET) += rmnet/
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -0,0 +1,7 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+#
-+# Makefile for the device driver of PPE (Packet Process Engine) in IPQ SoC
-+#
-+
-+obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
-+qcom-ppe-objs := ppe.o
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
-@@ -0,0 +1,218 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* PPE platform device probe, DTSI parser and PPE clock initializations. */
-+
-+#include <linux/clk.h>
-+#include <linux/interconnect.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+
-+#include "ppe.h"
-+
-+#define PPE_PORT_MAX          8
-+#define PPE_CLK_RATE          353000000
-+
-+/* ICC clocks for enabling PPE device. The avg_bw and peak_bw with value 0
-+ * will be updated by the clock rate of PPE.
-+ */
-+static const struct icc_bulk_data ppe_icc_data[] = {
-+      {
-+              .name = "ppe",
-+              .avg_bw = 0,
-+              .peak_bw = 0,
-+      },
-+      {
-+              .name = "ppe_cfg",
-+              .avg_bw = 0,
-+              .peak_bw = 0,
-+      },
-+      {
-+              .name = "qos_gen",
-+              .avg_bw = 6000,
-+              .peak_bw = 6000,
-+      },
-+      {
-+              .name = "timeout_ref",
-+              .avg_bw = 6000,
-+              .peak_bw = 6000,
-+      },
-+      {
-+              .name = "nssnoc_memnoc",
-+              .avg_bw = 533333,
-+              .peak_bw = 533333,
-+      },
-+      {
-+              .name = "memnoc_nssnoc",
-+              .avg_bw = 533333,
-+              .peak_bw = 533333,
-+      },
-+      {
-+              .name = "memnoc_nssnoc_1",
-+              .avg_bw = 533333,
-+              .peak_bw = 533333,
-+      },
-+};
-+
-+static const struct regmap_range ppe_readable_ranges[] = {
-+      regmap_reg_range(0x0, 0x1ff),           /* Global */
-+      regmap_reg_range(0x400, 0x5ff),         /* LPI CSR */
-+      regmap_reg_range(0x1000, 0x11ff),       /* GMAC0 */
-+      regmap_reg_range(0x1200, 0x13ff),       /* GMAC1 */
-+      regmap_reg_range(0x1400, 0x15ff),       /* GMAC2 */
-+      regmap_reg_range(0x1600, 0x17ff),       /* GMAC3 */
-+      regmap_reg_range(0x1800, 0x19ff),       /* GMAC4 */
-+      regmap_reg_range(0x1a00, 0x1bff),       /* GMAC5 */
-+      regmap_reg_range(0xb000, 0xefff),       /* PRX CSR */
-+      regmap_reg_range(0xf000, 0x1efff),      /* IPE */
-+      regmap_reg_range(0x20000, 0x5ffff),     /* PTX CSR */
-+      regmap_reg_range(0x60000, 0x9ffff),     /* IPE L2 CSR */
-+      regmap_reg_range(0xb0000, 0xeffff),     /* IPO CSR */
-+      regmap_reg_range(0x100000, 0x17ffff),   /* IPE PC */
-+      regmap_reg_range(0x180000, 0x1bffff),   /* PRE IPO CSR */
-+      regmap_reg_range(0x1d0000, 0x1dffff),   /* Tunnel parser */
-+      regmap_reg_range(0x1e0000, 0x1effff),   /* Ingress parse */
-+      regmap_reg_range(0x200000, 0x2fffff),   /* IPE L3 */
-+      regmap_reg_range(0x300000, 0x3fffff),   /* IPE tunnel */
-+      regmap_reg_range(0x400000, 0x4fffff),   /* Scheduler */
-+      regmap_reg_range(0x500000, 0x503fff),   /* XGMAC0 */
-+      regmap_reg_range(0x504000, 0x507fff),   /* XGMAC1 */
-+      regmap_reg_range(0x508000, 0x50bfff),   /* XGMAC2 */
-+      regmap_reg_range(0x50c000, 0x50ffff),   /* XGMAC3 */
-+      regmap_reg_range(0x510000, 0x513fff),   /* XGMAC4 */
-+      regmap_reg_range(0x514000, 0x517fff),   /* XGMAC5 */
-+      regmap_reg_range(0x600000, 0x6fffff),   /* BM */
-+      regmap_reg_range(0x800000, 0x9fffff),   /* QM */
-+      regmap_reg_range(0xb00000, 0xbef800),   /* EDMA */
-+};
-+
-+static const struct regmap_access_table ppe_reg_table = {
-+      .yes_ranges = ppe_readable_ranges,
-+      .n_yes_ranges = ARRAY_SIZE(ppe_readable_ranges),
-+};
-+
-+static const struct regmap_config regmap_config_ipq9574 = {
-+      .reg_bits = 32,
-+      .reg_stride = 4,
-+      .val_bits = 32,
-+      .rd_table = &ppe_reg_table,
-+      .wr_table = &ppe_reg_table,
-+      .max_register = 0xbef800,
-+      .fast_io = true,
-+};
-+
-+static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev)
-+{
-+      unsigned long ppe_rate = ppe_dev->clk_rate;
-+      struct device *dev = ppe_dev->dev;
-+      struct reset_control *rstc;
-+      struct clk_bulk_data *clks;
-+      struct clk *clk;
-+      int ret, i;
-+
-+      for (i = 0; i < ppe_dev->num_icc_paths; i++) {
-+              ppe_dev->icc_paths[i].name = ppe_icc_data[i].name;
-+              ppe_dev->icc_paths[i].avg_bw = ppe_icc_data[i].avg_bw ? :
-+                                             Bps_to_icc(ppe_rate);
-+              ppe_dev->icc_paths[i].peak_bw = ppe_icc_data[i].peak_bw ? :
-+                                              Bps_to_icc(ppe_rate);
-+      }
-+
-+      ret = devm_of_icc_bulk_get(dev, ppe_dev->num_icc_paths,
-+                                 ppe_dev->icc_paths);
-+      if (ret)
-+              return ret;
-+
-+      ret = icc_bulk_set_bw(ppe_dev->num_icc_paths, ppe_dev->icc_paths);
-+      if (ret)
-+              return ret;
-+
-+      /* The PPE clocks have a common parent clock. Setting the clock
-+       * rate of "ppe" ensures the clock rate of all PPE clocks is
-+       * configured to the same rate.
-+       */
-+      clk = devm_clk_get(dev, "ppe");
-+      if (IS_ERR(clk))
-+              return PTR_ERR(clk);
-+
-+      ret = clk_set_rate(clk, ppe_rate);
-+      if (ret)
-+              return ret;
-+
-+      ret = devm_clk_bulk_get_all_enable(dev, &clks);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Reset the PPE. */
-+      rstc = devm_reset_control_get_exclusive(dev, NULL);
-+      if (IS_ERR(rstc))
-+              return PTR_ERR(rstc);
-+
-+      ret = reset_control_assert(rstc);
-+      if (ret)
-+              return ret;
-+
-+      /* The delay 10 ms of assert is necessary for resetting PPE. */
-+      usleep_range(10000, 11000);
-+
-+      return reset_control_deassert(rstc);
-+}
-+
-+static int qcom_ppe_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      struct ppe_device *ppe_dev;
-+      void __iomem *base;
-+      int ret, num_icc;
-+
-+      num_icc = ARRAY_SIZE(ppe_icc_data);
-+      ppe_dev = devm_kzalloc(dev, struct_size(ppe_dev, icc_paths, num_icc),
-+                             GFP_KERNEL);
-+      if (!ppe_dev)
-+              return -ENOMEM;
-+
-+      base = devm_platform_ioremap_resource(pdev, 0);
-+      if (IS_ERR(base))
-+              return dev_err_probe(dev, PTR_ERR(base), "PPE ioremap failed\n");
-+
-+      ppe_dev->regmap = devm_regmap_init_mmio(dev, base, &regmap_config_ipq9574);
-+      if (IS_ERR(ppe_dev->regmap))
-+              return dev_err_probe(dev, PTR_ERR(ppe_dev->regmap),
-+                                   "PPE initialize regmap failed\n");
-+      ppe_dev->dev = dev;
-+      ppe_dev->clk_rate = PPE_CLK_RATE;
-+      ppe_dev->num_ports = PPE_PORT_MAX;
-+      ppe_dev->num_icc_paths = num_icc;
-+
-+      ret = ppe_clock_init_and_reset(ppe_dev);
-+      if (ret)
-+              return dev_err_probe(dev, ret, "PPE clock config failed\n");
-+
-+      platform_set_drvdata(pdev, ppe_dev);
-+
-+      return 0;
-+}
-+
-+static const struct of_device_id qcom_ppe_of_match[] = {
-+      { .compatible = "qcom,ipq9574-ppe" },
-+      {}
-+};
-+MODULE_DEVICE_TABLE(of, qcom_ppe_of_match);
-+
-+static struct platform_driver qcom_ppe_driver = {
-+      .driver = {
-+              .name = "qcom_ppe",
-+              .of_match_table = qcom_ppe_of_match,
-+      },
-+      .probe  = qcom_ppe_probe,
-+};
-+module_platform_driver(qcom_ppe_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ PPE driver");
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h
-@@ -0,0 +1,36 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ *
-+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __PPE_H__
-+#define __PPE_H__
-+
-+#include <linux/compiler.h>
-+#include <linux/interconnect.h>
-+
-+struct device;
-+struct regmap;
-+
-+/**
-+ * struct ppe_device - PPE device private data.
-+ * @dev: PPE device structure.
-+ * @regmap: PPE register map.
-+ * @clk_rate: PPE clock rate.
-+ * @num_ports: Number of PPE ports.
-+ * @num_icc_paths: Number of interconnect paths.
-+ * @icc_paths: Interconnect path array.
-+ *
-+ * PPE device is the instance of PPE hardware, which is used to
-+ * configure PPE packet process modules such as BM (buffer management),
-+ * QM (queue management), and scheduler.
-+ */
-+struct ppe_device {
-+      struct device *dev;
-+      struct regmap *regmap;
-+      unsigned long clk_rate;
-+      unsigned int num_ports;
-+      unsigned int num_icc_paths;
-+      struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths);
-+};
-+#endif
diff --git a/target/linux/qualcommbe/patches-6.12/0326-net-ethernet-qualcomm-Initialize-PPE-buffer-manageme.patch b/target/linux/qualcommbe/patches-6.12/0326-net-ethernet-qualcomm-Initialize-PPE-buffer-manageme.patch
deleted file mode 100644 (file)
index 5f38e25..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-From 6e639ab45348ee7a697db8b481fa6f8555280f58 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:38 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE buffer management for
- IPQ9574
-
-The BM (Buffer Management) config controls the pause frame generated
-on the PPE port. There are maximum 15 BM ports and 4 groups supported,
-all BM ports are assigned to group 0 by default. The number of hardware
-buffers configured for the port influence the threshold of the flow
-control for that port.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- drivers/net/ethernet/qualcomm/ppe/Makefile    |   2 +-
- drivers/net/ethernet/qualcomm/ppe/ppe.c       |   5 +
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 195 ++++++++++++++++++
- .../net/ethernet/qualcomm/ppe/ppe_config.h    |  12 ++
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  |  59 ++++++
- 5 files changed, 272 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_config.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_config.h
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -4,4 +4,4 @@
- #
- obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
--qcom-ppe-objs := ppe.o
-+qcom-ppe-objs := ppe.o ppe_config.o
---- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
-@@ -15,6 +15,7 @@
- #include <linux/reset.h>
- #include "ppe.h"
-+#include "ppe_config.h"
- #define PPE_PORT_MAX          8
- #define PPE_CLK_RATE          353000000
-@@ -194,6 +195,10 @@ static int qcom_ppe_probe(struct platfor
-       if (ret)
-               return dev_err_probe(dev, ret, "PPE clock config failed\n");
-+      ret = ppe_hw_config(ppe_dev);
-+      if (ret)
-+              return dev_err_probe(dev, ret, "PPE HW config failed\n");
-+
-       platform_set_drvdata(pdev, ppe_dev);
-       return 0;
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -0,0 +1,195 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* PPE HW initialization configs such as BM(buffer management),
-+ * QM(queue management) and scheduler configs.
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/bits.h>
-+#include <linux/device.h>
-+#include <linux/regmap.h>
-+
-+#include "ppe.h"
-+#include "ppe_config.h"
-+#include "ppe_regs.h"
-+
-+/**
-+ * struct ppe_bm_port_config - PPE BM port configuration.
-+ * @port_id_start: The fist BM port ID to configure.
-+ * @port_id_end: The last BM port ID to configure.
-+ * @pre_alloc: BM port dedicated buffer number.
-+ * @in_fly_buf: Buffer number for receiving the packet after pause frame sent.
-+ * @ceil: Ceil to generate the back pressure.
-+ * @weight: Weight value.
-+ * @resume_offset: Resume offset from the threshold value.
-+ * @resume_ceil: Ceil to resume from the back pressure state.
-+ * @dynamic: Dynamic threshold used or not.
-+ *
-+ * The is for configuring the threshold that impacts the port
-+ * flow control.
-+ */
-+struct ppe_bm_port_config {
-+      unsigned int port_id_start;
-+      unsigned int port_id_end;
-+      unsigned int pre_alloc;
-+      unsigned int in_fly_buf;
-+      unsigned int ceil;
-+      unsigned int weight;
-+      unsigned int resume_offset;
-+      unsigned int resume_ceil;
-+      bool dynamic;
-+};
-+
-+/* Assign the share buffer number 1550 to group 0 by default. */
-+static const int ipq9574_ppe_bm_group_config = 1550;
-+
-+/* The buffer configurations per PPE port. There are 15 BM ports and
-+ * 4 BM groups supported by PPE. BM port (0-7) is for EDMA port 0,
-+ * BM port (8-13) is for PPE physical port 1-6 and BM port 14 is for
-+ * EIP port.
-+ */
-+static const struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
-+      {
-+              /* Buffer configuration for the BM port ID 0 of EDMA. */
-+              .port_id_start  = 0,
-+              .port_id_end    = 0,
-+              .pre_alloc      = 0,
-+              .in_fly_buf     = 100,
-+              .ceil           = 1146,
-+              .weight         = 7,
-+              .resume_offset  = 8,
-+              .resume_ceil    = 0,
-+              .dynamic        = true,
-+      },
-+      {
-+              /* Buffer configuration for the BM port ID 1-7 of EDMA. */
-+              .port_id_start  = 1,
-+              .port_id_end    = 7,
-+              .pre_alloc      = 0,
-+              .in_fly_buf     = 100,
-+              .ceil           = 250,
-+              .weight         = 4,
-+              .resume_offset  = 36,
-+              .resume_ceil    = 0,
-+              .dynamic        = true,
-+      },
-+      {
-+              /* Buffer configuration for the BM port ID 8-13 of PPE ports. */
-+              .port_id_start  = 8,
-+              .port_id_end    = 13,
-+              .pre_alloc      = 0,
-+              .in_fly_buf     = 128,
-+              .ceil           = 250,
-+              .weight         = 4,
-+              .resume_offset  = 36,
-+              .resume_ceil    = 0,
-+              .dynamic        = true,
-+      },
-+      {
-+              /* Buffer configuration for the BM port ID 14 of EIP. */
-+              .port_id_start  = 14,
-+              .port_id_end    = 14,
-+              .pre_alloc      = 0,
-+              .in_fly_buf     = 40,
-+              .ceil           = 250,
-+              .weight         = 4,
-+              .resume_offset  = 36,
-+              .resume_ceil    = 0,
-+              .dynamic        = true,
-+      },
-+};
-+
-+static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
-+                                 const struct ppe_bm_port_config port_cfg)
-+{
-+      u32 reg, val, bm_fc_val[2];
-+      int ret;
-+
-+      reg = PPE_BM_PORT_FC_CFG_TBL_ADDR + PPE_BM_PORT_FC_CFG_TBL_INC * bm_port_id;
-+      ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                             bm_fc_val, ARRAY_SIZE(bm_fc_val));
-+      if (ret)
-+              return ret;
-+
-+      /* Configure BM flow control related threshold. */
-+      PPE_BM_PORT_FC_SET_WEIGHT(bm_fc_val, port_cfg.weight);
-+      PPE_BM_PORT_FC_SET_RESUME_OFFSET(bm_fc_val, port_cfg.resume_offset);
-+      PPE_BM_PORT_FC_SET_RESUME_THRESHOLD(bm_fc_val, port_cfg.resume_ceil);
-+      PPE_BM_PORT_FC_SET_DYNAMIC(bm_fc_val, port_cfg.dynamic);
-+      PPE_BM_PORT_FC_SET_REACT_LIMIT(bm_fc_val, port_cfg.in_fly_buf);
-+      PPE_BM_PORT_FC_SET_PRE_ALLOC(bm_fc_val, port_cfg.pre_alloc);
-+
-+      /* Configure low/high bits of the ceiling for the BM port. */
-+      val = FIELD_GET(GENMASK(2, 0), port_cfg.ceil);
-+      PPE_BM_PORT_FC_SET_CEILING_LOW(bm_fc_val, val);
-+      val = FIELD_GET(GENMASK(10, 3), port_cfg.ceil);
-+      PPE_BM_PORT_FC_SET_CEILING_HIGH(bm_fc_val, val);
-+
-+      ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                              bm_fc_val, ARRAY_SIZE(bm_fc_val));
-+      if (ret)
-+              return ret;
-+
-+      /* Assign the default group ID 0 to the BM port. */
-+      val = FIELD_PREP(PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID, 0);
-+      reg = PPE_BM_PORT_GROUP_ID_ADDR + PPE_BM_PORT_GROUP_ID_INC * bm_port_id;
-+      ret = regmap_update_bits(ppe_dev->regmap, reg,
-+                               PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID,
-+                               val);
-+      if (ret)
-+              return ret;
-+
-+      /* Enable BM port flow control. */
-+      reg = PPE_BM_PORT_FC_MODE_ADDR + PPE_BM_PORT_FC_MODE_INC * bm_port_id;
-+
-+      return regmap_set_bits(ppe_dev->regmap, reg, PPE_BM_PORT_FC_MODE_EN);
-+}
-+
-+/* Configure the buffer threshold for the port flow control function. */
-+static int ppe_config_bm(struct ppe_device *ppe_dev)
-+{
-+      const struct ppe_bm_port_config *port_cfg;
-+      unsigned int i, bm_port_id, port_cfg_cnt;
-+      u32 reg, val;
-+      int ret;
-+
-+      /* Configure the allocated buffer number only for group 0.
-+       * The buffer number of group 1-3 is already cleared to 0
-+       * after PPE reset during the probe of PPE driver.
-+       */
-+      reg = PPE_BM_SHARED_GROUP_CFG_ADDR;
-+      val = FIELD_PREP(PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT,
-+                       ipq9574_ppe_bm_group_config);
-+      ret = regmap_update_bits(ppe_dev->regmap, reg,
-+                               PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT,
-+                               val);
-+      if (ret)
-+              goto bm_config_fail;
-+
-+      /* Configure buffer thresholds for the BM ports. */
-+      port_cfg = ipq9574_ppe_bm_port_config;
-+      port_cfg_cnt = ARRAY_SIZE(ipq9574_ppe_bm_port_config);
-+      for (i = 0; i < port_cfg_cnt; i++) {
-+              for (bm_port_id = port_cfg[i].port_id_start;
-+                   bm_port_id <= port_cfg[i].port_id_end; bm_port_id++) {
-+                      ret = ppe_config_bm_threshold(ppe_dev, bm_port_id,
-+                                                    port_cfg[i]);
-+                      if (ret)
-+                              goto bm_config_fail;
-+              }
-+      }
-+
-+      return 0;
-+
-+bm_config_fail:
-+      dev_err(ppe_dev->dev, "PPE BM config error %d\n", ret);
-+      return ret;
-+}
-+
-+int ppe_hw_config(struct ppe_device *ppe_dev)
-+{
-+      return ppe_config_bm(ppe_dev);
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-@@ -0,0 +1,12 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ *
-+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __PPE_CONFIG_H__
-+#define __PPE_CONFIG_H__
-+
-+#include "ppe.h"
-+
-+int ppe_hw_config(struct ppe_device *ppe_dev);
-+#endif
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -0,0 +1,59 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ *
-+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* PPE hardware register and table declarations. */
-+#ifndef __PPE_REGS_H__
-+#define __PPE_REGS_H__
-+
-+#include <linux/bitfield.h>
-+
-+/* There are 15 BM ports and 4 BM groups supported by PPE.
-+ * BM port (0-7) is for EDMA port 0, BM port (8-13) is for
-+ * PPE physical port 1-6 and BM port 14 is for EIP port.
-+ */
-+#define PPE_BM_PORT_FC_MODE_ADDR              0x600100
-+#define PPE_BM_PORT_FC_MODE_ENTRIES           15
-+#define PPE_BM_PORT_FC_MODE_INC                       0x4
-+#define PPE_BM_PORT_FC_MODE_EN                        BIT(0)
-+
-+#define PPE_BM_PORT_GROUP_ID_ADDR             0x600180
-+#define PPE_BM_PORT_GROUP_ID_ENTRIES          15
-+#define PPE_BM_PORT_GROUP_ID_INC              0x4
-+#define PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID  GENMASK(1, 0)
-+
-+#define PPE_BM_SHARED_GROUP_CFG_ADDR          0x600290
-+#define PPE_BM_SHARED_GROUP_CFG_ENTRIES               4
-+#define PPE_BM_SHARED_GROUP_CFG_INC           0x4
-+#define PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT  GENMASK(10, 0)
-+
-+#define PPE_BM_PORT_FC_CFG_TBL_ADDR           0x601000
-+#define PPE_BM_PORT_FC_CFG_TBL_ENTRIES                15
-+#define PPE_BM_PORT_FC_CFG_TBL_INC            0x10
-+#define PPE_BM_PORT_FC_W0_REACT_LIMIT         GENMASK(8, 0)
-+#define PPE_BM_PORT_FC_W0_RESUME_THRESHOLD    GENMASK(17, 9)
-+#define PPE_BM_PORT_FC_W0_RESUME_OFFSET               GENMASK(28, 18)
-+#define PPE_BM_PORT_FC_W0_CEILING_LOW         GENMASK(31, 29)
-+#define PPE_BM_PORT_FC_W1_CEILING_HIGH                GENMASK(7, 0)
-+#define PPE_BM_PORT_FC_W1_WEIGHT              GENMASK(10, 8)
-+#define PPE_BM_PORT_FC_W1_DYNAMIC             BIT(11)
-+#define PPE_BM_PORT_FC_W1_PRE_ALLOC           GENMASK(22, 12)
-+
-+#define PPE_BM_PORT_FC_SET_REACT_LIMIT(tbl_cfg, value)        \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_REACT_LIMIT)
-+#define PPE_BM_PORT_FC_SET_RESUME_THRESHOLD(tbl_cfg, value)   \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_RESUME_THRESHOLD)
-+#define PPE_BM_PORT_FC_SET_RESUME_OFFSET(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_RESUME_OFFSET)
-+#define PPE_BM_PORT_FC_SET_CEILING_LOW(tbl_cfg, value)        \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_CEILING_LOW)
-+#define PPE_BM_PORT_FC_SET_CEILING_HIGH(tbl_cfg, value)       \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_CEILING_HIGH)
-+#define PPE_BM_PORT_FC_SET_WEIGHT(tbl_cfg, value)     \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_WEIGHT)
-+#define PPE_BM_PORT_FC_SET_DYNAMIC(tbl_cfg, value)    \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_DYNAMIC)
-+#define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value)  \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC)
-+#endif
diff --git a/target/linux/qualcommbe/patches-6.12/0327-net-ethernet-qualcomm-Initialize-PPE-queue-managemen.patch b/target/linux/qualcommbe/patches-6.12/0327-net-ethernet-qualcomm-Initialize-PPE-queue-managemen.patch
deleted file mode 100644 (file)
index be16222..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-From 9be6c3590ef3c241e6a3cfd05291304a1f973bcf Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:39 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE queue management for
- IPQ9574
-
-QM (queue management) configurations decide the length of PPE
-queues and the queue depth for these queues which are used to
-drop packets in events of congestion.
-
-There are two types of PPE queues - unicast queues (0-255) and
-multicast queues (256-299). These queue types are used to forward
-different types of traffic, and are configured with different
-lengths.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 177 +++++++++++++++++-
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  |  85 +++++++++
- 2 files changed, 261 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -43,6 +43,29 @@ struct ppe_bm_port_config {
-       bool dynamic;
- };
-+/**
-+ * struct ppe_qm_queue_config - PPE queue config.
-+ * @queue_start: PPE start of queue ID.
-+ * @queue_end: PPE end of queue ID.
-+ * @prealloc_buf: Queue dedicated buffer number.
-+ * @ceil: Ceil to start drop packet from queue.
-+ * @weight: Weight value.
-+ * @resume_offset: Resume offset from the threshold.
-+ * @dynamic: Threshold value is decided dynamically or statically.
-+ *
-+ * Queue configuration decides the threshold to drop packet from PPE
-+ * hardware queue.
-+ */
-+struct ppe_qm_queue_config {
-+      unsigned int queue_start;
-+      unsigned int queue_end;
-+      unsigned int prealloc_buf;
-+      unsigned int ceil;
-+      unsigned int weight;
-+      unsigned int resume_offset;
-+      bool dynamic;
-+};
-+
- /* Assign the share buffer number 1550 to group 0 by default. */
- static const int ipq9574_ppe_bm_group_config = 1550;
-@@ -102,6 +125,33 @@ static const struct ppe_bm_port_config i
-       },
- };
-+/* Default QM group settings for IPQ9754. */
-+static const int ipq9574_ppe_qm_group_config = 2000;
-+
-+/* Default QM settings for unicast and multicast queues for IPQ9754. */
-+static const struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = {
-+      {
-+              /* QM settings for unicast queues 0 to 255. */
-+              .queue_start    = 0,
-+              .queue_end      = 255,
-+              .prealloc_buf   = 0,
-+              .ceil           = 1200,
-+              .weight         = 7,
-+              .resume_offset  = 36,
-+              .dynamic        = true,
-+      },
-+      {
-+              /* QM settings for multicast queues 256 to 299. */
-+              .queue_start    = 256,
-+              .queue_end      = 299,
-+              .prealloc_buf   = 0,
-+              .ceil           = 250,
-+              .weight         = 0,
-+              .resume_offset  = 36,
-+              .dynamic        = false,
-+      },
-+};
-+
- static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
-                                  const struct ppe_bm_port_config port_cfg)
- {
-@@ -189,7 +239,132 @@ bm_config_fail:
-       return ret;
- }
-+/* Configure PPE hardware queue depth, which is decided by the threshold
-+ * of queue.
-+ */
-+static int ppe_config_qm(struct ppe_device *ppe_dev)
-+{
-+      const struct ppe_qm_queue_config *queue_cfg;
-+      int ret, i, queue_id, queue_cfg_count;
-+      u32 reg, multicast_queue_cfg[5];
-+      u32 unicast_queue_cfg[4];
-+      u32 group_cfg[3];
-+
-+      /* Assign the buffer number to the group 0 by default. */
-+      reg = PPE_AC_GRP_CFG_TBL_ADDR;
-+      ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                             group_cfg, ARRAY_SIZE(group_cfg));
-+      if (ret)
-+              goto qm_config_fail;
-+
-+      PPE_AC_GRP_SET_BUF_LIMIT(group_cfg, ipq9574_ppe_qm_group_config);
-+
-+      ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                              group_cfg, ARRAY_SIZE(group_cfg));
-+      if (ret)
-+              goto qm_config_fail;
-+
-+      queue_cfg = ipq9574_ppe_qm_queue_config;
-+      queue_cfg_count = ARRAY_SIZE(ipq9574_ppe_qm_queue_config);
-+      for (i = 0; i < queue_cfg_count; i++) {
-+              queue_id = queue_cfg[i].queue_start;
-+
-+              /* Configure threshold for dropping packets separately for
-+               * unicast and multicast PPE queues.
-+               */
-+              while (queue_id <= queue_cfg[i].queue_end) {
-+                      if (queue_id < PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES) {
-+                              reg = PPE_AC_UNICAST_QUEUE_CFG_TBL_ADDR +
-+                                    PPE_AC_UNICAST_QUEUE_CFG_TBL_INC * queue_id;
-+
-+                              ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                                                     unicast_queue_cfg,
-+                                                     ARRAY_SIZE(unicast_queue_cfg));
-+                              if (ret)
-+                                      goto qm_config_fail;
-+
-+                              PPE_AC_UNICAST_QUEUE_SET_EN(unicast_queue_cfg, true);
-+                              PPE_AC_UNICAST_QUEUE_SET_GRP_ID(unicast_queue_cfg, 0);
-+                              PPE_AC_UNICAST_QUEUE_SET_PRE_LIMIT(unicast_queue_cfg,
-+                                                                 queue_cfg[i].prealloc_buf);
-+                              PPE_AC_UNICAST_QUEUE_SET_DYNAMIC(unicast_queue_cfg,
-+                                                               queue_cfg[i].dynamic);
-+                              PPE_AC_UNICAST_QUEUE_SET_WEIGHT(unicast_queue_cfg,
-+                                                              queue_cfg[i].weight);
-+                              PPE_AC_UNICAST_QUEUE_SET_THRESHOLD(unicast_queue_cfg,
-+                                                                 queue_cfg[i].ceil);
-+                              PPE_AC_UNICAST_QUEUE_SET_GRN_RESUME(unicast_queue_cfg,
-+                                                                  queue_cfg[i].resume_offset);
-+
-+                              ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                                                      unicast_queue_cfg,
-+                                                      ARRAY_SIZE(unicast_queue_cfg));
-+                              if (ret)
-+                                      goto qm_config_fail;
-+                      } else {
-+                              reg = PPE_AC_MULTICAST_QUEUE_CFG_TBL_ADDR +
-+                                    PPE_AC_MULTICAST_QUEUE_CFG_TBL_INC * queue_id;
-+
-+                              ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                                                     multicast_queue_cfg,
-+                                                     ARRAY_SIZE(multicast_queue_cfg));
-+                              if (ret)
-+                                      goto qm_config_fail;
-+
-+                              PPE_AC_MULTICAST_QUEUE_SET_EN(multicast_queue_cfg, true);
-+                              PPE_AC_MULTICAST_QUEUE_SET_GRN_GRP_ID(multicast_queue_cfg, 0);
-+                              PPE_AC_MULTICAST_QUEUE_SET_GRN_PRE_LIMIT(multicast_queue_cfg,
-+                                                                       queue_cfg[i].prealloc_buf);
-+                              PPE_AC_MULTICAST_QUEUE_SET_GRN_THRESHOLD(multicast_queue_cfg,
-+                                                                       queue_cfg[i].ceil);
-+                              PPE_AC_MULTICAST_QUEUE_SET_GRN_RESUME(multicast_queue_cfg,
-+                                                                    queue_cfg[i].resume_offset);
-+
-+                              ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                                                      multicast_queue_cfg,
-+                                                      ARRAY_SIZE(multicast_queue_cfg));
-+                              if (ret)
-+                                      goto qm_config_fail;
-+                      }
-+
-+                      /* Enable enqueue. */
-+                      reg = PPE_ENQ_OPR_TBL_ADDR + PPE_ENQ_OPR_TBL_INC * queue_id;
-+                      ret = regmap_clear_bits(ppe_dev->regmap, reg,
-+                                              PPE_ENQ_OPR_TBL_ENQ_DISABLE);
-+                      if (ret)
-+                              goto qm_config_fail;
-+
-+                      /* Enable dequeue. */
-+                      reg = PPE_DEQ_OPR_TBL_ADDR + PPE_DEQ_OPR_TBL_INC * queue_id;
-+                      ret = regmap_clear_bits(ppe_dev->regmap, reg,
-+                                              PPE_DEQ_OPR_TBL_DEQ_DISABLE);
-+                      if (ret)
-+                              goto qm_config_fail;
-+
-+                      queue_id++;
-+              }
-+      }
-+
-+      /* Enable queue counter for all PPE hardware queues. */
-+      ret = regmap_set_bits(ppe_dev->regmap, PPE_EG_BRIDGE_CONFIG_ADDR,
-+                            PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN);
-+      if (ret)
-+              goto qm_config_fail;
-+
-+      return 0;
-+
-+qm_config_fail:
-+      dev_err(ppe_dev->dev, "PPE QM config error %d\n", ret);
-+      return ret;
-+}
-+
- int ppe_hw_config(struct ppe_device *ppe_dev)
- {
--      return ppe_config_bm(ppe_dev);
-+      int ret;
-+
-+      ret = ppe_config_bm(ppe_dev);
-+      if (ret)
-+              return ret;
-+
-+      return ppe_config_qm(ppe_dev);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -9,6 +9,16 @@
- #include <linux/bitfield.h>
-+/* PPE queue counters enable/disable control. */
-+#define PPE_EG_BRIDGE_CONFIG_ADDR             0x20044
-+#define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN     BIT(2)
-+
-+/* Table addresses for per-queue dequeue setting. */
-+#define PPE_DEQ_OPR_TBL_ADDR                  0x430000
-+#define PPE_DEQ_OPR_TBL_ENTRIES                       300
-+#define PPE_DEQ_OPR_TBL_INC                   0x10
-+#define PPE_DEQ_OPR_TBL_DEQ_DISABLE           BIT(0)
-+
- /* There are 15 BM ports and 4 BM groups supported by PPE.
-  * BM port (0-7) is for EDMA port 0, BM port (8-13) is for
-  * PPE physical port 1-6 and BM port 14 is for EIP port.
-@@ -56,4 +66,79 @@
-       u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_DYNAMIC)
- #define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value)  \
-       u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC)
-+
-+/* PPE unicast queue (0-255) configurations. */
-+#define PPE_AC_UNICAST_QUEUE_CFG_TBL_ADDR     0x848000
-+#define PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES  256
-+#define PPE_AC_UNICAST_QUEUE_CFG_TBL_INC      0x10
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_EN                BIT(0)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_WRED_EN   BIT(1)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_FC_EN     BIT(2)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_CLR_AWARE BIT(3)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_GRP_ID    GENMASK(5, 4)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_PRE_LIMIT GENMASK(16, 6)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_DYNAMIC   BIT(17)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_WEIGHT    GENMASK(20, 18)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W0_THRESHOLD GENMASK(31, 21)
-+#define PPE_AC_UNICAST_QUEUE_CFG_W3_GRN_RESUME        GENMASK(23, 13)
-+
-+#define PPE_AC_UNICAST_QUEUE_SET_EN(tbl_cfg, value)   \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_EN)
-+#define PPE_AC_UNICAST_QUEUE_SET_GRP_ID(tbl_cfg, value)       \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_GRP_ID)
-+#define PPE_AC_UNICAST_QUEUE_SET_PRE_LIMIT(tbl_cfg, value)    \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_PRE_LIMIT)
-+#define PPE_AC_UNICAST_QUEUE_SET_DYNAMIC(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_DYNAMIC)
-+#define PPE_AC_UNICAST_QUEUE_SET_WEIGHT(tbl_cfg, value)       \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_WEIGHT)
-+#define PPE_AC_UNICAST_QUEUE_SET_THRESHOLD(tbl_cfg, value)    \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_THRESHOLD)
-+#define PPE_AC_UNICAST_QUEUE_SET_GRN_RESUME(tbl_cfg, value)   \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x3, value, PPE_AC_UNICAST_QUEUE_CFG_W3_GRN_RESUME)
-+
-+/* PPE multicast queue (256-299) configurations. */
-+#define PPE_AC_MULTICAST_QUEUE_CFG_TBL_ADDR   0x84a000
-+#define PPE_AC_MULTICAST_QUEUE_CFG_TBL_ENTRIES        44
-+#define PPE_AC_MULTICAST_QUEUE_CFG_TBL_INC    0x10
-+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_EN      BIT(0)
-+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_FC_EN   BIT(1)
-+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_CLR_AWARE       BIT(2)
-+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_GRP_ID  GENMASK(4, 3)
-+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_PRE_LIMIT       GENMASK(15, 5)
-+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_THRESHOLD       GENMASK(26, 16)
-+#define PPE_AC_MULTICAST_QUEUE_CFG_W2_RESUME  GENMASK(17, 7)
-+
-+#define PPE_AC_MULTICAST_QUEUE_SET_EN(tbl_cfg, value) \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MULTICAST_QUEUE_CFG_W0_EN)
-+#define PPE_AC_MULTICAST_QUEUE_SET_GRN_GRP_ID(tbl_cfg, value) \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MULTICAST_QUEUE_CFG_W0_GRP_ID)
-+#define PPE_AC_MULTICAST_QUEUE_SET_GRN_PRE_LIMIT(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MULTICAST_QUEUE_CFG_W0_PRE_LIMIT)
-+#define PPE_AC_MULTICAST_QUEUE_SET_GRN_THRESHOLD(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MULTICAST_QUEUE_CFG_W0_THRESHOLD)
-+#define PPE_AC_MULTICAST_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x2, value, PPE_AC_MULTICAST_QUEUE_CFG_W2_RESUME)
-+
-+/* PPE admission control group (0-3) configurations */
-+#define PPE_AC_GRP_CFG_TBL_ADDR                       0x84c000
-+#define PPE_AC_GRP_CFG_TBL_ENTRIES            0x4
-+#define PPE_AC_GRP_CFG_TBL_INC                        0x10
-+#define PPE_AC_GRP_W0_AC_EN                   BIT(0)
-+#define PPE_AC_GRP_W0_AC_FC_EN                        BIT(1)
-+#define PPE_AC_GRP_W0_CLR_AWARE                       BIT(2)
-+#define PPE_AC_GRP_W0_THRESHOLD_LOW           GENMASK(31, 25)
-+#define PPE_AC_GRP_W1_THRESHOLD_HIGH          GENMASK(3, 0)
-+#define PPE_AC_GRP_W1_BUF_LIMIT                       GENMASK(14, 4)
-+#define PPE_AC_GRP_W2_RESUME_GRN              GENMASK(15, 5)
-+#define PPE_AC_GRP_W2_PRE_ALLOC                       GENMASK(26, 16)
-+
-+#define PPE_AC_GRP_SET_BUF_LIMIT(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_AC_GRP_W1_BUF_LIMIT)
-+
-+/* Table addresses for per-queue enqueue setting. */
-+#define PPE_ENQ_OPR_TBL_ADDR                  0x85c000
-+#define PPE_ENQ_OPR_TBL_ENTRIES                       300
-+#define PPE_ENQ_OPR_TBL_INC                   0x10
-+#define PPE_ENQ_OPR_TBL_ENQ_DISABLE           BIT(0)
- #endif
diff --git a/target/linux/qualcommbe/patches-6.12/0328-net-ethernet-qualcomm-Initialize-the-PPE-scheduler-s.patch b/target/linux/qualcommbe/patches-6.12/0328-net-ethernet-qualcomm-Initialize-the-PPE-scheduler-s.patch
deleted file mode 100644 (file)
index 86949a2..0000000
+++ /dev/null
@@ -1,1000 +0,0 @@
-From 333edaf474cd707b0a04c57f255b56bc3c015789 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:40 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize the PPE scheduler
- settings
-
-The PPE scheduler settings determine the priority of scheduling the
-packet across the different hardware queues per PPE port.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 788 +++++++++++++++++-
- .../net/ethernet/qualcomm/ppe/ppe_config.h    |  37 +
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  |  97 +++
- 3 files changed, 921 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -16,6 +16,8 @@
- #include "ppe_config.h"
- #include "ppe_regs.h"
-+#define PPE_QUEUE_SCH_PRI_NUM         8
-+
- /**
-  * struct ppe_bm_port_config - PPE BM port configuration.
-  * @port_id_start: The fist BM port ID to configure.
-@@ -66,6 +68,66 @@ struct ppe_qm_queue_config {
-       bool dynamic;
- };
-+/**
-+ * struct ppe_scheduler_bm_config - PPE arbitration for buffer config.
-+ * @valid: Arbitration entry valid or not.
-+ * @is_egress: Arbitration entry for egress or not.
-+ * @port: Port ID to use arbitration entry.
-+ * @second_valid: Second port valid or not.
-+ * @second_port: Second port to use.
-+ *
-+ * Configure the scheduler settings for accessing and releasing the PPE buffers.
-+ */
-+struct ppe_scheduler_bm_config {
-+      bool valid;
-+      bool is_egress;
-+      unsigned int port;
-+      bool second_valid;
-+      unsigned int second_port;
-+};
-+
-+/**
-+ * struct ppe_scheduler_qm_config - PPE arbitration for scheduler config.
-+ * @ensch_port_bmp: Port bit map for enqueue scheduler.
-+ * @ensch_port: Port ID to enqueue scheduler.
-+ * @desch_port: Port ID to dequeue scheduler.
-+ * @desch_second_valid: Dequeue for the second port valid or not.
-+ * @desch_second_port: Second port ID to dequeue scheduler.
-+ *
-+ * Configure the scheduler settings for enqueuing and dequeuing packets on
-+ * the PPE port.
-+ */
-+struct ppe_scheduler_qm_config {
-+      unsigned int ensch_port_bmp;
-+      unsigned int ensch_port;
-+      unsigned int desch_port;
-+      bool desch_second_valid;
-+      unsigned int desch_second_port;
-+};
-+
-+/**
-+ * struct ppe_scheduler_port_config - PPE port scheduler config.
-+ * @port: Port ID to be scheduled.
-+ * @flow_level: Scheduler flow level or not.
-+ * @node_id: Node ID, for level 0, queue ID is used.
-+ * @loop_num: Loop number of scheduler config.
-+ * @pri_max: Max priority configured.
-+ * @flow_id: Strict priority ID.
-+ * @drr_node_id: Node ID for scheduler.
-+ *
-+ * PPE port scheduler configuration which decides the priority in the
-+ * packet scheduler for the egress port.
-+ */
-+struct ppe_scheduler_port_config {
-+      unsigned int port;
-+      bool flow_level;
-+      unsigned int node_id;
-+      unsigned int loop_num;
-+      unsigned int pri_max;
-+      unsigned int flow_id;
-+      unsigned int drr_node_id;
-+};
-+
- /* Assign the share buffer number 1550 to group 0 by default. */
- static const int ipq9574_ppe_bm_group_config = 1550;
-@@ -152,6 +214,599 @@ static const struct ppe_qm_queue_config
-       },
- };
-+/* Scheduler configuration for the assigning and releasing buffers for the
-+ * packet passing through PPE, which is different per SoC.
-+ */
-+static const struct ppe_scheduler_bm_config ipq9574_ppe_sch_bm_config[] = {
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 1, 0, 0},
-+      {1, 1, 1, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 7, 0, 0},
-+      {1, 1, 7, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 1, 0, 0},
-+      {1, 1, 1, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 2, 0, 0},
-+      {1, 1, 2, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 1, 0, 0},
-+      {1, 1, 1, 0, 0},
-+      {1, 0, 3, 0, 0},
-+      {1, 1, 3, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 7, 0, 0},
-+      {1, 1, 7, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 1, 0, 0},
-+      {1, 1, 1, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 4, 0, 0},
-+      {1, 1, 4, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 1, 0, 0},
-+      {1, 1, 1, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 2, 0, 0},
-+      {1, 1, 2, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 7, 0, 0},
-+      {1, 1, 7, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 1, 0, 0},
-+      {1, 1, 1, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 3, 0, 0},
-+      {1, 1, 3, 0, 0},
-+      {1, 0, 1, 0, 0},
-+      {1, 1, 1, 0, 0},
-+      {1, 0, 0, 0, 0},
-+      {1, 1, 0, 0, 0},
-+      {1, 0, 5, 0, 0},
-+      {1, 1, 5, 0, 0},
-+      {1, 0, 6, 0, 0},
-+      {1, 1, 6, 0, 0},
-+      {1, 0, 4, 0, 0},
-+      {1, 1, 4, 0, 0},
-+      {1, 0, 7, 0, 0},
-+      {1, 1, 7, 0, 0},
-+};
-+
-+/* Scheduler configuration for dispatching packet on PPE queues, which
-+ * is different per SoC.
-+ */
-+static const struct ppe_scheduler_qm_config ipq9574_ppe_sch_qm_config[] = {
-+      {0x98, 6, 0, 1, 1},
-+      {0x94, 5, 6, 1, 3},
-+      {0x86, 0, 5, 1, 4},
-+      {0x8C, 1, 6, 1, 0},
-+      {0x1C, 7, 5, 1, 1},
-+      {0x98, 2, 6, 1, 0},
-+      {0x1C, 5, 7, 1, 1},
-+      {0x34, 3, 6, 1, 0},
-+      {0x8C, 4, 5, 1, 1},
-+      {0x98, 2, 6, 1, 0},
-+      {0x8C, 5, 4, 1, 1},
-+      {0xA8, 0, 6, 1, 2},
-+      {0x98, 5, 1, 1, 0},
-+      {0x98, 6, 5, 1, 2},
-+      {0x89, 1, 6, 1, 4},
-+      {0xA4, 3, 0, 1, 1},
-+      {0x8C, 5, 6, 1, 4},
-+      {0xA8, 0, 2, 1, 1},
-+      {0x98, 6, 5, 1, 0},
-+      {0xC4, 4, 3, 1, 1},
-+      {0x94, 6, 5, 1, 0},
-+      {0x1C, 7, 6, 1, 1},
-+      {0x98, 2, 5, 1, 0},
-+      {0x1C, 6, 7, 1, 1},
-+      {0x1C, 5, 6, 1, 0},
-+      {0x94, 3, 5, 1, 1},
-+      {0x8C, 4, 6, 1, 0},
-+      {0x94, 1, 5, 1, 3},
-+      {0x94, 6, 1, 1, 0},
-+      {0xD0, 3, 5, 1, 2},
-+      {0x98, 6, 0, 1, 1},
-+      {0x94, 5, 6, 1, 3},
-+      {0x94, 1, 5, 1, 0},
-+      {0x98, 2, 6, 1, 1},
-+      {0x8C, 4, 5, 1, 0},
-+      {0x1C, 7, 6, 1, 1},
-+      {0x8C, 0, 5, 1, 4},
-+      {0x89, 1, 6, 1, 2},
-+      {0x98, 5, 0, 1, 1},
-+      {0x94, 6, 5, 1, 3},
-+      {0x92, 0, 6, 1, 2},
-+      {0x98, 1, 5, 1, 0},
-+      {0x98, 6, 2, 1, 1},
-+      {0xD0, 0, 5, 1, 3},
-+      {0x94, 6, 0, 1, 1},
-+      {0x8C, 5, 6, 1, 4},
-+      {0x8C, 1, 5, 1, 0},
-+      {0x1C, 6, 7, 1, 1},
-+      {0x1C, 5, 6, 1, 0},
-+      {0xB0, 2, 3, 1, 1},
-+      {0xC4, 4, 5, 1, 0},
-+      {0x8C, 6, 4, 1, 1},
-+      {0xA4, 3, 6, 1, 0},
-+      {0x1C, 5, 7, 1, 1},
-+      {0x4C, 0, 5, 1, 4},
-+      {0x8C, 6, 0, 1, 1},
-+      {0x34, 7, 6, 1, 3},
-+      {0x94, 5, 0, 1, 1},
-+      {0x98, 6, 5, 1, 2},
-+};
-+
-+static const struct ppe_scheduler_port_config ppe_port_sch_config[] = {
-+      {
-+              .port           = 0,
-+              .flow_level     = true,
-+              .node_id        = 0,
-+              .loop_num       = 1,
-+              .pri_max        = 1,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 0,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 8,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 16,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 24,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 32,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 40,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 48,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 56,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 256,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 0,
-+              .flow_level     = false,
-+              .node_id        = 264,
-+              .loop_num       = 8,
-+              .pri_max        = 8,
-+              .flow_id        = 0,
-+              .drr_node_id    = 0,
-+      },
-+      {
-+              .port           = 1,
-+              .flow_level     = true,
-+              .node_id        = 36,
-+              .loop_num       = 2,
-+              .pri_max        = 0,
-+              .flow_id        = 1,
-+              .drr_node_id    = 8,
-+      },
-+      {
-+              .port           = 1,
-+              .flow_level     = false,
-+              .node_id        = 144,
-+              .loop_num       = 16,
-+              .pri_max        = 8,
-+              .flow_id        = 36,
-+              .drr_node_id    = 48,
-+      },
-+      {
-+              .port           = 1,
-+              .flow_level     = false,
-+              .node_id        = 272,
-+              .loop_num       = 4,
-+              .pri_max        = 4,
-+              .flow_id        = 36,
-+              .drr_node_id    = 48,
-+      },
-+      {
-+              .port           = 2,
-+              .flow_level     = true,
-+              .node_id        = 40,
-+              .loop_num       = 2,
-+              .pri_max        = 0,
-+              .flow_id        = 2,
-+              .drr_node_id    = 12,
-+      },
-+      {
-+              .port           = 2,
-+              .flow_level     = false,
-+              .node_id        = 160,
-+              .loop_num       = 16,
-+              .pri_max        = 8,
-+              .flow_id        = 40,
-+              .drr_node_id    = 64,
-+      },
-+      {
-+              .port           = 2,
-+              .flow_level     = false,
-+              .node_id        = 276,
-+              .loop_num       = 4,
-+              .pri_max        = 4,
-+              .flow_id        = 40,
-+              .drr_node_id    = 64,
-+      },
-+      {
-+              .port           = 3,
-+              .flow_level     = true,
-+              .node_id        = 44,
-+              .loop_num       = 2,
-+              .pri_max        = 0,
-+              .flow_id        = 3,
-+              .drr_node_id    = 16,
-+      },
-+      {
-+              .port           = 3,
-+              .flow_level     = false,
-+              .node_id        = 176,
-+              .loop_num       = 16,
-+              .pri_max        = 8,
-+              .flow_id        = 44,
-+              .drr_node_id    = 80,
-+      },
-+      {
-+              .port           = 3,
-+              .flow_level     = false,
-+              .node_id        = 280,
-+              .loop_num       = 4,
-+              .pri_max        = 4,
-+              .flow_id        = 44,
-+              .drr_node_id    = 80,
-+      },
-+      {
-+              .port           = 4,
-+              .flow_level     = true,
-+              .node_id        = 48,
-+              .loop_num       = 2,
-+              .pri_max        = 0,
-+              .flow_id        = 4,
-+              .drr_node_id    = 20,
-+      },
-+      {
-+              .port           = 4,
-+              .flow_level     = false,
-+              .node_id        = 192,
-+              .loop_num       = 16,
-+              .pri_max        = 8,
-+              .flow_id        = 48,
-+              .drr_node_id    = 96,
-+      },
-+      {
-+              .port           = 4,
-+              .flow_level     = false,
-+              .node_id        = 284,
-+              .loop_num       = 4,
-+              .pri_max        = 4,
-+              .flow_id        = 48,
-+              .drr_node_id    = 96,
-+      },
-+      {
-+              .port           = 5,
-+              .flow_level     = true,
-+              .node_id        = 52,
-+              .loop_num       = 2,
-+              .pri_max        = 0,
-+              .flow_id        = 5,
-+              .drr_node_id    = 24,
-+      },
-+      {
-+              .port           = 5,
-+              .flow_level     = false,
-+              .node_id        = 208,
-+              .loop_num       = 16,
-+              .pri_max        = 8,
-+              .flow_id        = 52,
-+              .drr_node_id    = 112,
-+      },
-+      {
-+              .port           = 5,
-+              .flow_level     = false,
-+              .node_id        = 288,
-+              .loop_num       = 4,
-+              .pri_max        = 4,
-+              .flow_id        = 52,
-+              .drr_node_id    = 112,
-+      },
-+      {
-+              .port           = 6,
-+              .flow_level     = true,
-+              .node_id        = 56,
-+              .loop_num       = 2,
-+              .pri_max        = 0,
-+              .flow_id        = 6,
-+              .drr_node_id    = 28,
-+      },
-+      {
-+              .port           = 6,
-+              .flow_level     = false,
-+              .node_id        = 224,
-+              .loop_num       = 16,
-+              .pri_max        = 8,
-+              .flow_id        = 56,
-+              .drr_node_id    = 128,
-+      },
-+      {
-+              .port           = 6,
-+              .flow_level     = false,
-+              .node_id        = 292,
-+              .loop_num       = 4,
-+              .pri_max        = 4,
-+              .flow_id        = 56,
-+              .drr_node_id    = 128,
-+      },
-+      {
-+              .port           = 7,
-+              .flow_level     = true,
-+              .node_id        = 60,
-+              .loop_num       = 2,
-+              .pri_max        = 0,
-+              .flow_id        = 7,
-+              .drr_node_id    = 32,
-+      },
-+      {
-+              .port           = 7,
-+              .flow_level     = false,
-+              .node_id        = 240,
-+              .loop_num       = 16,
-+              .pri_max        = 8,
-+              .flow_id        = 60,
-+              .drr_node_id    = 144,
-+      },
-+      {
-+              .port           = 7,
-+              .flow_level     = false,
-+              .node_id        = 296,
-+              .loop_num       = 4,
-+              .pri_max        = 4,
-+              .flow_id        = 60,
-+              .drr_node_id    = 144,
-+      },
-+};
-+
-+/* Set the PPE queue level scheduler configuration. */
-+static int ppe_scheduler_l0_queue_map_set(struct ppe_device *ppe_dev,
-+                                        int node_id, int port,
-+                                        struct ppe_scheduler_cfg scheduler_cfg)
-+{
-+      u32 val, reg;
-+      int ret;
-+
-+      reg = PPE_L0_FLOW_MAP_TBL_ADDR + node_id * PPE_L0_FLOW_MAP_TBL_INC;
-+      val = FIELD_PREP(PPE_L0_FLOW_MAP_TBL_FLOW_ID, scheduler_cfg.flow_id);
-+      val |= FIELD_PREP(PPE_L0_FLOW_MAP_TBL_C_PRI, scheduler_cfg.pri);
-+      val |= FIELD_PREP(PPE_L0_FLOW_MAP_TBL_E_PRI, scheduler_cfg.pri);
-+      val |= FIELD_PREP(PPE_L0_FLOW_MAP_TBL_C_NODE_WT, scheduler_cfg.drr_node_wt);
-+      val |= FIELD_PREP(PPE_L0_FLOW_MAP_TBL_E_NODE_WT, scheduler_cfg.drr_node_wt);
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_L0_C_FLOW_CFG_TBL_ADDR +
-+            (scheduler_cfg.flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg.pri) *
-+            PPE_L0_C_FLOW_CFG_TBL_INC;
-+      val = FIELD_PREP(PPE_L0_C_FLOW_CFG_TBL_NODE_ID, scheduler_cfg.drr_node_id);
-+      val |= FIELD_PREP(PPE_L0_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT, scheduler_cfg.unit_is_packet);
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_L0_E_FLOW_CFG_TBL_ADDR +
-+            (scheduler_cfg.flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg.pri) *
-+            PPE_L0_E_FLOW_CFG_TBL_INC;
-+      val = FIELD_PREP(PPE_L0_E_FLOW_CFG_TBL_NODE_ID, scheduler_cfg.drr_node_id);
-+      val |= FIELD_PREP(PPE_L0_E_FLOW_CFG_TBL_NODE_CREDIT_UNIT, scheduler_cfg.unit_is_packet);
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_L0_FLOW_PORT_MAP_TBL_ADDR + node_id * PPE_L0_FLOW_PORT_MAP_TBL_INC;
-+      val = FIELD_PREP(PPE_L0_FLOW_PORT_MAP_TBL_PORT_NUM, port);
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_L0_COMP_CFG_TBL_ADDR + node_id * PPE_L0_COMP_CFG_TBL_INC;
-+      val = FIELD_PREP(PPE_L0_COMP_CFG_TBL_NODE_METER_LEN, scheduler_cfg.frame_mode);
-+
-+      return regmap_update_bits(ppe_dev->regmap, reg,
-+                                PPE_L0_COMP_CFG_TBL_NODE_METER_LEN,
-+                                val);
-+}
-+
-+/* Set the PPE flow level scheduler configuration. */
-+static int ppe_scheduler_l1_queue_map_set(struct ppe_device *ppe_dev,
-+                                        int node_id, int port,
-+                                        struct ppe_scheduler_cfg scheduler_cfg)
-+{
-+      u32 val, reg;
-+      int ret;
-+
-+      val = FIELD_PREP(PPE_L1_FLOW_MAP_TBL_FLOW_ID, scheduler_cfg.flow_id);
-+      val |= FIELD_PREP(PPE_L1_FLOW_MAP_TBL_C_PRI, scheduler_cfg.pri);
-+      val |= FIELD_PREP(PPE_L1_FLOW_MAP_TBL_E_PRI, scheduler_cfg.pri);
-+      val |= FIELD_PREP(PPE_L1_FLOW_MAP_TBL_C_NODE_WT, scheduler_cfg.drr_node_wt);
-+      val |= FIELD_PREP(PPE_L1_FLOW_MAP_TBL_E_NODE_WT, scheduler_cfg.drr_node_wt);
-+      reg = PPE_L1_FLOW_MAP_TBL_ADDR + node_id * PPE_L1_FLOW_MAP_TBL_INC;
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      val = FIELD_PREP(PPE_L1_C_FLOW_CFG_TBL_NODE_ID, scheduler_cfg.drr_node_id);
-+      val |= FIELD_PREP(PPE_L1_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT, scheduler_cfg.unit_is_packet);
-+      reg = PPE_L1_C_FLOW_CFG_TBL_ADDR +
-+            (scheduler_cfg.flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg.pri) *
-+            PPE_L1_C_FLOW_CFG_TBL_INC;
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      val = FIELD_PREP(PPE_L1_E_FLOW_CFG_TBL_NODE_ID, scheduler_cfg.drr_node_id);
-+      val |= FIELD_PREP(PPE_L1_E_FLOW_CFG_TBL_NODE_CREDIT_UNIT, scheduler_cfg.unit_is_packet);
-+      reg = PPE_L1_E_FLOW_CFG_TBL_ADDR +
-+              (scheduler_cfg.flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg.pri) *
-+              PPE_L1_E_FLOW_CFG_TBL_INC;
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      val = FIELD_PREP(PPE_L1_FLOW_PORT_MAP_TBL_PORT_NUM, port);
-+      reg = PPE_L1_FLOW_PORT_MAP_TBL_ADDR + node_id * PPE_L1_FLOW_PORT_MAP_TBL_INC;
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_L1_COMP_CFG_TBL_ADDR + node_id * PPE_L1_COMP_CFG_TBL_INC;
-+      val = FIELD_PREP(PPE_L1_COMP_CFG_TBL_NODE_METER_LEN, scheduler_cfg.frame_mode);
-+
-+      return regmap_update_bits(ppe_dev->regmap, reg, PPE_L1_COMP_CFG_TBL_NODE_METER_LEN, val);
-+}
-+
-+/**
-+ * ppe_queue_scheduler_set - Configure scheduler for PPE hardware queue
-+ * @ppe_dev: PPE device
-+ * @node_id: PPE queue ID or flow ID
-+ * @flow_level: Flow level scheduler or queue level scheduler
-+ * @port: PPE port ID set scheduler configuration
-+ * @scheduler_cfg: PPE scheduler configuration
-+ *
-+ * PPE scheduler configuration supports queue level and flow level on
-+ * the PPE egress port.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
-+                          int node_id, bool flow_level, int port,
-+                          struct ppe_scheduler_cfg scheduler_cfg)
-+{
-+      if (flow_level)
-+              return ppe_scheduler_l1_queue_map_set(ppe_dev, node_id,
-+                                                    port, scheduler_cfg);
-+
-+      return ppe_scheduler_l0_queue_map_set(ppe_dev, node_id,
-+                                            port, scheduler_cfg);
-+}
-+
- static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
-                                  const struct ppe_bm_port_config port_cfg)
- {
-@@ -358,6 +1013,133 @@ qm_config_fail:
-       return ret;
- }
-+static int ppe_node_scheduler_config(struct ppe_device *ppe_dev,
-+                                   const struct ppe_scheduler_port_config config)
-+{
-+      struct ppe_scheduler_cfg sch_cfg;
-+      int ret, i;
-+
-+      for (i = 0; i < config.loop_num; i++) {
-+              if (!config.pri_max) {
-+                      /* Round robin scheduler without priority. */
-+                      sch_cfg.flow_id = config.flow_id;
-+                      sch_cfg.pri = 0;
-+                      sch_cfg.drr_node_id = config.drr_node_id;
-+              } else {
-+                      sch_cfg.flow_id = config.flow_id + (i / config.pri_max);
-+                      sch_cfg.pri = i % config.pri_max;
-+                      sch_cfg.drr_node_id = config.drr_node_id + i;
-+              }
-+
-+              /* Scheduler weight, must be more than 0. */
-+              sch_cfg.drr_node_wt = 1;
-+              /* Byte based to be scheduled. */
-+              sch_cfg.unit_is_packet = false;
-+              /* Frame + CRC calculated. */
-+              sch_cfg.frame_mode = PPE_SCH_WITH_FRAME_CRC;
-+
-+              ret = ppe_queue_scheduler_set(ppe_dev, config.node_id + i,
-+                                            config.flow_level,
-+                                            config.port,
-+                                            sch_cfg);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+/* Initialize scheduler settings for PPE buffer utilization and dispatching
-+ * packet on PPE queue.
-+ */
-+static int ppe_config_scheduler(struct ppe_device *ppe_dev)
-+{
-+      const struct ppe_scheduler_port_config *port_cfg;
-+      const struct ppe_scheduler_qm_config *qm_cfg;
-+      const struct ppe_scheduler_bm_config *bm_cfg;
-+      int ret, i, count;
-+      u32 val, reg;
-+
-+      count = ARRAY_SIZE(ipq9574_ppe_sch_bm_config);
-+      bm_cfg = ipq9574_ppe_sch_bm_config;
-+
-+      /* Configure the depth of BM scheduler entries. */
-+      val = FIELD_PREP(PPE_BM_SCH_CTRL_SCH_DEPTH, count);
-+      val |= FIELD_PREP(PPE_BM_SCH_CTRL_SCH_OFFSET, 0);
-+      val |= FIELD_PREP(PPE_BM_SCH_CTRL_SCH_EN, 1);
-+
-+      ret = regmap_write(ppe_dev->regmap, PPE_BM_SCH_CTRL_ADDR, val);
-+      if (ret)
-+              goto sch_config_fail;
-+
-+      /* Configure each BM scheduler entry with the valid ingress port and
-+       * egress port, the second port takes effect when the specified port
-+       * is in the inactive state.
-+       */
-+      for (i = 0; i < count; i++) {
-+              val = FIELD_PREP(PPE_BM_SCH_CFG_TBL_VALID, bm_cfg[i].valid);
-+              val |= FIELD_PREP(PPE_BM_SCH_CFG_TBL_DIR, bm_cfg[i].is_egress);
-+              val |= FIELD_PREP(PPE_BM_SCH_CFG_TBL_PORT_NUM, bm_cfg[i].port);
-+              val |= FIELD_PREP(PPE_BM_SCH_CFG_TBL_SECOND_PORT_VALID, bm_cfg[i].second_valid);
-+              val |= FIELD_PREP(PPE_BM_SCH_CFG_TBL_SECOND_PORT, bm_cfg[i].second_port);
-+
-+              reg = PPE_BM_SCH_CFG_TBL_ADDR + i * PPE_BM_SCH_CFG_TBL_INC;
-+              ret = regmap_write(ppe_dev->regmap, reg, val);
-+              if (ret)
-+                      goto sch_config_fail;
-+      }
-+
-+      count = ARRAY_SIZE(ipq9574_ppe_sch_qm_config);
-+      qm_cfg = ipq9574_ppe_sch_qm_config;
-+
-+      /* Configure the depth of QM scheduler entries. */
-+      val = FIELD_PREP(PPE_PSCH_SCH_DEPTH_CFG_SCH_DEPTH, count);
-+      ret = regmap_write(ppe_dev->regmap, PPE_PSCH_SCH_DEPTH_CFG_ADDR, val);
-+      if (ret)
-+              goto sch_config_fail;
-+
-+      /* Configure each QM scheduler entry with enqueue port and dequeue
-+       * port, the second port takes effect when the specified dequeue
-+       * port is in the inactive port.
-+       */
-+      for (i = 0; i < count; i++) {
-+              val = FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_ENS_PORT_BITMAP,
-+                               qm_cfg[i].ensch_port_bmp);
-+              val |= FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_ENS_PORT,
-+                                qm_cfg[i].ensch_port);
-+              val |= FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_DES_PORT,
-+                                qm_cfg[i].desch_port);
-+              val |= FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_DES_SECOND_PORT_EN,
-+                                qm_cfg[i].desch_second_valid);
-+              val |= FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_DES_SECOND_PORT,
-+                                qm_cfg[i].desch_second_port);
-+
-+              reg = PPE_PSCH_SCH_CFG_TBL_ADDR + i * PPE_PSCH_SCH_CFG_TBL_INC;
-+              ret = regmap_write(ppe_dev->regmap, reg, val);
-+              if (ret)
-+                      goto sch_config_fail;
-+      }
-+
-+      count = ARRAY_SIZE(ppe_port_sch_config);
-+      port_cfg = ppe_port_sch_config;
-+
-+      /* Configure scheduler per PPE queue or flow. */
-+      for (i = 0; i < count; i++) {
-+              if (port_cfg[i].port >= ppe_dev->num_ports)
-+                      break;
-+
-+              ret = ppe_node_scheduler_config(ppe_dev, port_cfg[i]);
-+              if (ret)
-+                      goto sch_config_fail;
-+      }
-+
-+      return 0;
-+
-+sch_config_fail:
-+      dev_err(ppe_dev->dev, "PPE scheduler arbitration config error %d\n", ret);
-+      return ret;
-+};
-+
- int ppe_hw_config(struct ppe_device *ppe_dev)
- {
-       int ret;
-@@ -366,5 +1148,9 @@ int ppe_hw_config(struct ppe_device *ppe
-       if (ret)
-               return ret;
--      return ppe_config_qm(ppe_dev);
-+      ret = ppe_config_qm(ppe_dev);
-+      if (ret)
-+              return ret;
-+
-+      return ppe_config_scheduler(ppe_dev);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-@@ -8,5 +8,42 @@
- #include "ppe.h"
-+/**
-+ * enum ppe_scheduler_frame_mode - PPE scheduler frame mode.
-+ * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG,
-+ * preamble, Ethernet packet and CRC.
-+ * @PPE_SCH_WITH_FRAME_CRC: The scheduled frame includes Ethernet frame and CRC
-+ * excluding IPG and preamble.
-+ * @PPE_SCH_WITH_L3_PAYLOAD: The scheduled frame includes layer 3 packet data.
-+ */
-+enum ppe_scheduler_frame_mode {
-+      PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC = 0,
-+      PPE_SCH_WITH_FRAME_CRC = 1,
-+      PPE_SCH_WITH_L3_PAYLOAD = 2,
-+};
-+
-+/**
-+ * struct ppe_scheduler_cfg - PPE scheduler configuration.
-+ * @flow_id: PPE flow ID.
-+ * @pri: Scheduler priority.
-+ * @drr_node_id: Node ID for scheduled traffic.
-+ * @drr_node_wt: Weight for scheduled traffic.
-+ * @unit_is_packet: Packet based or byte based unit for scheduled traffic.
-+ * @frame_mode: Packet mode to be scheduled.
-+ *
-+ * PPE scheduler supports commit rate and exceed rate configurations.
-+ */
-+struct ppe_scheduler_cfg {
-+      int flow_id;
-+      int pri;
-+      int drr_node_id;
-+      int drr_node_wt;
-+      bool unit_is_packet;
-+      enum ppe_scheduler_frame_mode frame_mode;
-+};
-+
- int ppe_hw_config(struct ppe_device *ppe_dev);
-+int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
-+                          int node_id, bool flow_level, int port,
-+                          struct ppe_scheduler_cfg scheduler_cfg);
- #endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -9,16 +9,113 @@
- #include <linux/bitfield.h>
-+/* PPE scheduler configurations for buffer manager block. */
-+#define PPE_BM_SCH_CTRL_ADDR                  0xb000
-+#define PPE_BM_SCH_CTRL_INC                   4
-+#define PPE_BM_SCH_CTRL_SCH_DEPTH             GENMASK(7, 0)
-+#define PPE_BM_SCH_CTRL_SCH_OFFSET            GENMASK(14, 8)
-+#define PPE_BM_SCH_CTRL_SCH_EN                        BIT(31)
-+
-+#define PPE_BM_SCH_CFG_TBL_ADDR                       0xc000
-+#define PPE_BM_SCH_CFG_TBL_ENTRIES            128
-+#define PPE_BM_SCH_CFG_TBL_INC                        0x10
-+#define PPE_BM_SCH_CFG_TBL_PORT_NUM           GENMASK(3, 0)
-+#define PPE_BM_SCH_CFG_TBL_DIR                        BIT(4)
-+#define PPE_BM_SCH_CFG_TBL_VALID              BIT(5)
-+#define PPE_BM_SCH_CFG_TBL_SECOND_PORT_VALID  BIT(6)
-+#define PPE_BM_SCH_CFG_TBL_SECOND_PORT                GENMASK(11, 8)
-+
- /* PPE queue counters enable/disable control. */
- #define PPE_EG_BRIDGE_CONFIG_ADDR             0x20044
- #define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN     BIT(2)
-+/* Port scheduler global config. */
-+#define PPE_PSCH_SCH_DEPTH_CFG_ADDR           0x400000
-+#define PPE_PSCH_SCH_DEPTH_CFG_INC            4
-+#define PPE_PSCH_SCH_DEPTH_CFG_SCH_DEPTH      GENMASK(7, 0)
-+
-+/* PPE queue level scheduler configurations. */
-+#define PPE_L0_FLOW_MAP_TBL_ADDR              0x402000
-+#define PPE_L0_FLOW_MAP_TBL_ENTRIES           300
-+#define PPE_L0_FLOW_MAP_TBL_INC                       0x10
-+#define PPE_L0_FLOW_MAP_TBL_FLOW_ID           GENMASK(5, 0)
-+#define PPE_L0_FLOW_MAP_TBL_C_PRI             GENMASK(8, 6)
-+#define PPE_L0_FLOW_MAP_TBL_E_PRI             GENMASK(11, 9)
-+#define PPE_L0_FLOW_MAP_TBL_C_NODE_WT         GENMASK(21, 12)
-+#define PPE_L0_FLOW_MAP_TBL_E_NODE_WT         GENMASK(31, 22)
-+
-+#define PPE_L0_C_FLOW_CFG_TBL_ADDR            0x404000
-+#define PPE_L0_C_FLOW_CFG_TBL_ENTRIES         512
-+#define PPE_L0_C_FLOW_CFG_TBL_INC             0x10
-+#define PPE_L0_C_FLOW_CFG_TBL_NODE_ID         GENMASK(7, 0)
-+#define PPE_L0_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT        BIT(8)
-+
-+#define PPE_L0_E_FLOW_CFG_TBL_ADDR            0x406000
-+#define PPE_L0_E_FLOW_CFG_TBL_ENTRIES         512
-+#define PPE_L0_E_FLOW_CFG_TBL_INC             0x10
-+#define PPE_L0_E_FLOW_CFG_TBL_NODE_ID         GENMASK(7, 0)
-+#define PPE_L0_E_FLOW_CFG_TBL_NODE_CREDIT_UNIT        BIT(8)
-+
-+#define PPE_L0_FLOW_PORT_MAP_TBL_ADDR         0x408000
-+#define PPE_L0_FLOW_PORT_MAP_TBL_ENTRIES      300
-+#define PPE_L0_FLOW_PORT_MAP_TBL_INC          0x10
-+#define PPE_L0_FLOW_PORT_MAP_TBL_PORT_NUM     GENMASK(3, 0)
-+
-+#define PPE_L0_COMP_CFG_TBL_ADDR              0x428000
-+#define PPE_L0_COMP_CFG_TBL_ENTRIES           300
-+#define PPE_L0_COMP_CFG_TBL_INC                       0x10
-+#define PPE_L0_COMP_CFG_TBL_SHAPER_METER_LEN  GENMASK(1, 0)
-+#define PPE_L0_COMP_CFG_TBL_NODE_METER_LEN    GENMASK(3, 2)
-+
- /* Table addresses for per-queue dequeue setting. */
- #define PPE_DEQ_OPR_TBL_ADDR                  0x430000
- #define PPE_DEQ_OPR_TBL_ENTRIES                       300
- #define PPE_DEQ_OPR_TBL_INC                   0x10
- #define PPE_DEQ_OPR_TBL_DEQ_DISABLE           BIT(0)
-+/* PPE flow level scheduler configurations. */
-+#define PPE_L1_FLOW_MAP_TBL_ADDR              0x440000
-+#define PPE_L1_FLOW_MAP_TBL_ENTRIES           64
-+#define PPE_L1_FLOW_MAP_TBL_INC                       0x10
-+#define PPE_L1_FLOW_MAP_TBL_FLOW_ID           GENMASK(3, 0)
-+#define PPE_L1_FLOW_MAP_TBL_C_PRI             GENMASK(6, 4)
-+#define PPE_L1_FLOW_MAP_TBL_E_PRI             GENMASK(9, 7)
-+#define PPE_L1_FLOW_MAP_TBL_C_NODE_WT         GENMASK(19, 10)
-+#define PPE_L1_FLOW_MAP_TBL_E_NODE_WT         GENMASK(29, 20)
-+
-+#define PPE_L1_C_FLOW_CFG_TBL_ADDR            0x442000
-+#define PPE_L1_C_FLOW_CFG_TBL_ENTRIES         64
-+#define PPE_L1_C_FLOW_CFG_TBL_INC             0x10
-+#define PPE_L1_C_FLOW_CFG_TBL_NODE_ID         GENMASK(5, 0)
-+#define PPE_L1_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT        BIT(6)
-+
-+#define PPE_L1_E_FLOW_CFG_TBL_ADDR            0x444000
-+#define PPE_L1_E_FLOW_CFG_TBL_ENTRIES         64
-+#define PPE_L1_E_FLOW_CFG_TBL_INC             0x10
-+#define PPE_L1_E_FLOW_CFG_TBL_NODE_ID         GENMASK(5, 0)
-+#define PPE_L1_E_FLOW_CFG_TBL_NODE_CREDIT_UNIT        BIT(6)
-+
-+#define PPE_L1_FLOW_PORT_MAP_TBL_ADDR         0x446000
-+#define PPE_L1_FLOW_PORT_MAP_TBL_ENTRIES      64
-+#define PPE_L1_FLOW_PORT_MAP_TBL_INC          0x10
-+#define PPE_L1_FLOW_PORT_MAP_TBL_PORT_NUM     GENMASK(3, 0)
-+
-+#define PPE_L1_COMP_CFG_TBL_ADDR              0x46a000
-+#define PPE_L1_COMP_CFG_TBL_ENTRIES           64
-+#define PPE_L1_COMP_CFG_TBL_INC                       0x10
-+#define PPE_L1_COMP_CFG_TBL_SHAPER_METER_LEN  GENMASK(1, 0)
-+#define PPE_L1_COMP_CFG_TBL_NODE_METER_LEN    GENMASK(3, 2)
-+
-+/* PPE port scheduler configurations for egress. */
-+#define PPE_PSCH_SCH_CFG_TBL_ADDR             0x47a000
-+#define PPE_PSCH_SCH_CFG_TBL_ENTRIES          128
-+#define PPE_PSCH_SCH_CFG_TBL_INC              0x10
-+#define PPE_PSCH_SCH_CFG_TBL_DES_PORT         GENMASK(3, 0)
-+#define PPE_PSCH_SCH_CFG_TBL_ENS_PORT         GENMASK(7, 4)
-+#define PPE_PSCH_SCH_CFG_TBL_ENS_PORT_BITMAP  GENMASK(15, 8)
-+#define PPE_PSCH_SCH_CFG_TBL_DES_SECOND_PORT_EN       BIT(16)
-+#define PPE_PSCH_SCH_CFG_TBL_DES_SECOND_PORT  GENMASK(20, 17)
-+
- /* There are 15 BM ports and 4 BM groups supported by PPE.
-  * BM port (0-7) is for EDMA port 0, BM port (8-13) is for
-  * PPE physical port 1-6 and BM port 14 is for EIP port.
diff --git a/target/linux/qualcommbe/patches-6.12/0329-net-ethernet-qualcomm-Initialize-PPE-queue-settings.patch b/target/linux/qualcommbe/patches-6.12/0329-net-ethernet-qualcomm-Initialize-PPE-queue-settings.patch
deleted file mode 100644 (file)
index fe29d76..0000000
+++ /dev/null
@@ -1,522 +0,0 @@
-From 63874f7c2e46f192e43e6214d66236372e36396c Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:41 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE queue settings
-
-Configure unicast and multicast hardware queues for the PPE
-ports to enable packet forwarding between the ports.
-
-Each PPE port is assigned with a range of queues. The queue ID
-selection for a packet is decided by the queue base and queue
-offset that is configured based on the internal priority and
-the RSS hash value of the packet.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 356 +++++++++++++++++-
- .../net/ethernet/qualcomm/ppe/ppe_config.h    |  63 ++++
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  |  21 ++
- 3 files changed, 439 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -128,6 +128,34 @@ struct ppe_scheduler_port_config {
-       unsigned int drr_node_id;
- };
-+/**
-+ * struct ppe_port_schedule_resource - PPE port scheduler resource.
-+ * @ucastq_start: Unicast queue start ID.
-+ * @ucastq_end: Unicast queue end ID.
-+ * @mcastq_start: Multicast queue start ID.
-+ * @mcastq_end: Multicast queue end ID.
-+ * @flow_id_start: Flow start ID.
-+ * @flow_id_end: Flow end ID.
-+ * @l0node_start: Scheduler node start ID for queue level.
-+ * @l0node_end: Scheduler node end ID for queue level.
-+ * @l1node_start: Scheduler node start ID for flow level.
-+ * @l1node_end: Scheduler node end ID for flow level.
-+ *
-+ * PPE scheduler resource allocated among the PPE ports.
-+ */
-+struct ppe_port_schedule_resource {
-+      unsigned int ucastq_start;
-+      unsigned int ucastq_end;
-+      unsigned int mcastq_start;
-+      unsigned int mcastq_end;
-+      unsigned int flow_id_start;
-+      unsigned int flow_id_end;
-+      unsigned int l0node_start;
-+      unsigned int l0node_end;
-+      unsigned int l1node_start;
-+      unsigned int l1node_end;
-+};
-+
- /* Assign the share buffer number 1550 to group 0 by default. */
- static const int ipq9574_ppe_bm_group_config = 1550;
-@@ -676,6 +704,111 @@ static const struct ppe_scheduler_port_c
-       },
- };
-+/* The scheduler resource is applied to each PPE port, The resource
-+ * includes the unicast & multicast queues, flow nodes and DRR nodes.
-+ */
-+static const struct ppe_port_schedule_resource ppe_scheduler_res[] = {
-+      {       .ucastq_start   = 0,
-+              .ucastq_end     = 63,
-+              .mcastq_start   = 256,
-+              .mcastq_end     = 271,
-+              .flow_id_start  = 0,
-+              .flow_id_end    = 0,
-+              .l0node_start   = 0,
-+              .l0node_end     = 7,
-+              .l1node_start   = 0,
-+              .l1node_end     = 0,
-+      },
-+      {       .ucastq_start   = 144,
-+              .ucastq_end     = 159,
-+              .mcastq_start   = 272,
-+              .mcastq_end     = 275,
-+              .flow_id_start  = 36,
-+              .flow_id_end    = 39,
-+              .l0node_start   = 48,
-+              .l0node_end     = 63,
-+              .l1node_start   = 8,
-+              .l1node_end     = 11,
-+      },
-+      {       .ucastq_start   = 160,
-+              .ucastq_end     = 175,
-+              .mcastq_start   = 276,
-+              .mcastq_end     = 279,
-+              .flow_id_start  = 40,
-+              .flow_id_end    = 43,
-+              .l0node_start   = 64,
-+              .l0node_end     = 79,
-+              .l1node_start   = 12,
-+              .l1node_end     = 15,
-+      },
-+      {       .ucastq_start   = 176,
-+              .ucastq_end     = 191,
-+              .mcastq_start   = 280,
-+              .mcastq_end     = 283,
-+              .flow_id_start  = 44,
-+              .flow_id_end    = 47,
-+              .l0node_start   = 80,
-+              .l0node_end     = 95,
-+              .l1node_start   = 16,
-+              .l1node_end     = 19,
-+      },
-+      {       .ucastq_start   = 192,
-+              .ucastq_end     = 207,
-+              .mcastq_start   = 284,
-+              .mcastq_end     = 287,
-+              .flow_id_start  = 48,
-+              .flow_id_end    = 51,
-+              .l0node_start   = 96,
-+              .l0node_end     = 111,
-+              .l1node_start   = 20,
-+              .l1node_end     = 23,
-+      },
-+      {       .ucastq_start   = 208,
-+              .ucastq_end     = 223,
-+              .mcastq_start   = 288,
-+              .mcastq_end     = 291,
-+              .flow_id_start  = 52,
-+              .flow_id_end    = 55,
-+              .l0node_start   = 112,
-+              .l0node_end     = 127,
-+              .l1node_start   = 24,
-+              .l1node_end     = 27,
-+      },
-+      {       .ucastq_start   = 224,
-+              .ucastq_end     = 239,
-+              .mcastq_start   = 292,
-+              .mcastq_end     = 295,
-+              .flow_id_start  = 56,
-+              .flow_id_end    = 59,
-+              .l0node_start   = 128,
-+              .l0node_end     = 143,
-+              .l1node_start   = 28,
-+              .l1node_end     = 31,
-+      },
-+      {       .ucastq_start   = 240,
-+              .ucastq_end     = 255,
-+              .mcastq_start   = 296,
-+              .mcastq_end     = 299,
-+              .flow_id_start  = 60,
-+              .flow_id_end    = 63,
-+              .l0node_start   = 144,
-+              .l0node_end     = 159,
-+              .l1node_start   = 32,
-+              .l1node_end     = 35,
-+      },
-+      {       .ucastq_start   = 64,
-+              .ucastq_end     = 143,
-+              .mcastq_start   = 0,
-+              .mcastq_end     = 0,
-+              .flow_id_start  = 1,
-+              .flow_id_end    = 35,
-+              .l0node_start   = 8,
-+              .l0node_end     = 47,
-+              .l1node_start   = 1,
-+              .l1node_end     = 7,
-+      },
-+};
-+
- /* Set the PPE queue level scheduler configuration. */
- static int ppe_scheduler_l0_queue_map_set(struct ppe_device *ppe_dev,
-                                         int node_id, int port,
-@@ -807,6 +940,149 @@ int ppe_queue_scheduler_set(struct ppe_d
-                                             port, scheduler_cfg);
- }
-+/**
-+ * ppe_queue_ucast_base_set - Set PPE unicast queue base ID and profile ID
-+ * @ppe_dev: PPE device
-+ * @queue_dst: PPE queue destination configuration
-+ * @queue_base: PPE queue base ID
-+ * @profile_id: Profile ID
-+ *
-+ * The PPE unicast queue base ID and profile ID are configured based on the
-+ * destination port information that can be service code or CPU code or the
-+ * destination port.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_queue_ucast_base_set(struct ppe_device *ppe_dev,
-+                           struct ppe_queue_ucast_dest queue_dst,
-+                           int queue_base, int profile_id)
-+{
-+      int index, profile_size;
-+      u32 val, reg;
-+
-+      profile_size = queue_dst.src_profile << 8;
-+      if (queue_dst.service_code_en)
-+              index = PPE_QUEUE_BASE_SERVICE_CODE + profile_size +
-+                      queue_dst.service_code;
-+      else if (queue_dst.cpu_code_en)
-+              index = PPE_QUEUE_BASE_CPU_CODE + profile_size +
-+                      queue_dst.cpu_code;
-+      else
-+              index = profile_size + queue_dst.dest_port;
-+
-+      val = FIELD_PREP(PPE_UCAST_QUEUE_MAP_TBL_PROFILE_ID, profile_id);
-+      val |= FIELD_PREP(PPE_UCAST_QUEUE_MAP_TBL_QUEUE_ID, queue_base);
-+      reg = PPE_UCAST_QUEUE_MAP_TBL_ADDR + index * PPE_UCAST_QUEUE_MAP_TBL_INC;
-+
-+      return regmap_write(ppe_dev->regmap, reg, val);
-+}
-+
-+/**
-+ * ppe_queue_ucast_offset_pri_set - Set PPE unicast queue offset based on priority
-+ * @ppe_dev: PPE device
-+ * @profile_id: Profile ID
-+ * @priority: PPE internal priority to be used to set queue offset
-+ * @queue_offset: Queue offset used for calculating the destination queue ID
-+ *
-+ * The PPE unicast queue offset is configured based on the PPE
-+ * internal priority.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_queue_ucast_offset_pri_set(struct ppe_device *ppe_dev,
-+                                 int profile_id,
-+                                 int priority,
-+                                 int queue_offset)
-+{
-+      u32 val, reg;
-+      int index;
-+
-+      index = (profile_id << 4) + priority;
-+      val = FIELD_PREP(PPE_UCAST_PRIORITY_MAP_TBL_CLASS, queue_offset);
-+      reg = PPE_UCAST_PRIORITY_MAP_TBL_ADDR + index * PPE_UCAST_PRIORITY_MAP_TBL_INC;
-+
-+      return regmap_write(ppe_dev->regmap, reg, val);
-+}
-+
-+/**
-+ * ppe_queue_ucast_offset_hash_set - Set PPE unicast queue offset based on hash
-+ * @ppe_dev: PPE device
-+ * @profile_id: Profile ID
-+ * @rss_hash: Packet hash value to be used to set queue offset
-+ * @queue_offset: Queue offset used for calculating the destination queue ID
-+ *
-+ * The PPE unicast queue offset is configured based on the RSS hash value.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_queue_ucast_offset_hash_set(struct ppe_device *ppe_dev,
-+                                  int profile_id,
-+                                  int rss_hash,
-+                                  int queue_offset)
-+{
-+      u32 val, reg;
-+      int index;
-+
-+      index = (profile_id << 8) + rss_hash;
-+      val = FIELD_PREP(PPE_UCAST_HASH_MAP_TBL_HASH, queue_offset);
-+      reg = PPE_UCAST_HASH_MAP_TBL_ADDR + index * PPE_UCAST_HASH_MAP_TBL_INC;
-+
-+      return regmap_write(ppe_dev->regmap, reg, val);
-+}
-+
-+/**
-+ * ppe_port_resource_get - Get PPE resource per port
-+ * @ppe_dev: PPE device
-+ * @port: PPE port
-+ * @type: Resource type
-+ * @res_start: Resource start ID returned
-+ * @res_end: Resource end ID returned
-+ *
-+ * PPE resource is assigned per PPE port, which is acquired for QoS scheduler.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_port_resource_get(struct ppe_device *ppe_dev, int port,
-+                        enum ppe_resource_type type,
-+                        int *res_start, int *res_end)
-+{
-+      struct ppe_port_schedule_resource res;
-+
-+      /* The reserved resource with the maximum port ID of PPE is
-+       * also allowed to be acquired.
-+       */
-+      if (port > ppe_dev->num_ports)
-+              return -EINVAL;
-+
-+      res = ppe_scheduler_res[port];
-+      switch (type) {
-+      case PPE_RES_UCAST:
-+              *res_start = res.ucastq_start;
-+              *res_end = res.ucastq_end;
-+              break;
-+      case PPE_RES_MCAST:
-+              *res_start = res.mcastq_start;
-+              *res_end = res.mcastq_end;
-+              break;
-+      case PPE_RES_FLOW_ID:
-+              *res_start = res.flow_id_start;
-+              *res_end = res.flow_id_end;
-+              break;
-+      case PPE_RES_L0_NODE:
-+              *res_start = res.l0node_start;
-+              *res_end = res.l0node_end;
-+              break;
-+      case PPE_RES_L1_NODE:
-+              *res_start = res.l1node_start;
-+              *res_end = res.l1node_end;
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
- static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
-                                  const struct ppe_bm_port_config port_cfg)
- {
-@@ -1140,6 +1416,80 @@ sch_config_fail:
-       return ret;
- };
-+/* Configure PPE queue destination of each PPE port. */
-+static int ppe_queue_dest_init(struct ppe_device *ppe_dev)
-+{
-+      int ret, port_id, index, q_base, q_offset, res_start, res_end, pri_max;
-+      struct ppe_queue_ucast_dest queue_dst;
-+
-+      for (port_id = 0; port_id < ppe_dev->num_ports; port_id++) {
-+              memset(&queue_dst, 0, sizeof(queue_dst));
-+
-+              ret = ppe_port_resource_get(ppe_dev, port_id, PPE_RES_UCAST,
-+                                          &res_start, &res_end);
-+              if (ret)
-+                      return ret;
-+
-+              q_base = res_start;
-+              queue_dst.dest_port = port_id;
-+
-+              /* Configure queue base ID and profile ID that is same as
-+               * physical port ID.
-+               */
-+              ret = ppe_queue_ucast_base_set(ppe_dev, queue_dst,
-+                                             q_base, port_id);
-+              if (ret)
-+                      return ret;
-+
-+              /* Queue priority range supported by each PPE port */
-+              ret = ppe_port_resource_get(ppe_dev, port_id, PPE_RES_L0_NODE,
-+                                          &res_start, &res_end);
-+              if (ret)
-+                      return ret;
-+
-+              pri_max = res_end - res_start;
-+
-+              /* Redirect ARP reply packet with the max priority on CPU port,
-+               * which keeps the ARP reply directed to CPU (CPU code is 101)
-+               * with highest priority queue of EDMA.
-+               */
-+              if (port_id == 0) {
-+                      memset(&queue_dst, 0, sizeof(queue_dst));
-+
-+                      queue_dst.cpu_code_en = true;
-+                      queue_dst.cpu_code = 101;
-+                      ret = ppe_queue_ucast_base_set(ppe_dev, queue_dst,
-+                                                     q_base + pri_max,
-+                                                     0);
-+                      if (ret)
-+                              return ret;
-+              }
-+
-+              /* Initialize the queue offset of internal priority. */
-+              for (index = 0; index < PPE_QUEUE_INTER_PRI_NUM; index++) {
-+                      q_offset = index > pri_max ? pri_max : index;
-+
-+                      ret = ppe_queue_ucast_offset_pri_set(ppe_dev, port_id,
-+                                                           index, q_offset);
-+                      if (ret)
-+                              return ret;
-+              }
-+
-+              /* Initialize the queue offset of RSS hash as 0 to avoid the
-+               * random hardware value that will lead to the unexpected
-+               * destination queue generated.
-+               */
-+              for (index = 0; index < PPE_QUEUE_HASH_NUM; index++) {
-+                      ret = ppe_queue_ucast_offset_hash_set(ppe_dev, port_id,
-+                                                            index, 0);
-+                      if (ret)
-+                              return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
- int ppe_hw_config(struct ppe_device *ppe_dev)
- {
-       int ret;
-@@ -1152,5 +1502,9 @@ int ppe_hw_config(struct ppe_device *ppe
-       if (ret)
-               return ret;
--      return ppe_config_scheduler(ppe_dev);
-+      ret = ppe_config_scheduler(ppe_dev);
-+      if (ret)
-+              return ret;
-+
-+      return ppe_queue_dest_init(ppe_dev);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-@@ -8,6 +8,16 @@
- #include "ppe.h"
-+/* There are different table index ranges for configuring queue base ID of
-+ * the destination port, CPU code and service code.
-+ */
-+#define PPE_QUEUE_BASE_DEST_PORT              0
-+#define PPE_QUEUE_BASE_CPU_CODE                       1024
-+#define PPE_QUEUE_BASE_SERVICE_CODE           2048
-+
-+#define PPE_QUEUE_INTER_PRI_NUM                       16
-+#define PPE_QUEUE_HASH_NUM                    256
-+
- /**
-  * enum ppe_scheduler_frame_mode - PPE scheduler frame mode.
-  * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG,
-@@ -42,8 +52,61 @@ struct ppe_scheduler_cfg {
-       enum ppe_scheduler_frame_mode frame_mode;
- };
-+/**
-+ * enum ppe_resource_type - PPE resource type.
-+ * @PPE_RES_UCAST: Unicast queue resource.
-+ * @PPE_RES_MCAST: Multicast queue resource.
-+ * @PPE_RES_L0_NODE: Level 0 for queue based node resource.
-+ * @PPE_RES_L1_NODE: Level 1 for flow based node resource.
-+ * @PPE_RES_FLOW_ID: Flow based node resource.
-+ */
-+enum ppe_resource_type {
-+      PPE_RES_UCAST,
-+      PPE_RES_MCAST,
-+      PPE_RES_L0_NODE,
-+      PPE_RES_L1_NODE,
-+      PPE_RES_FLOW_ID,
-+};
-+
-+/**
-+ * struct ppe_queue_ucast_dest - PPE unicast queue destination.
-+ * @src_profile: Source profile.
-+ * @service_code_en: Enable service code to map the queue base ID.
-+ * @service_code: Service code.
-+ * @cpu_code_en: Enable CPU code to map the queue base ID.
-+ * @cpu_code: CPU code.
-+ * @dest_port: destination port.
-+ *
-+ * PPE egress queue ID is decided by the service code if enabled, otherwise
-+ * by the CPU code if enabled, or by destination port if both service code
-+ * and CPU code are disabled.
-+ */
-+struct ppe_queue_ucast_dest {
-+      int src_profile;
-+      bool service_code_en;
-+      int service_code;
-+      bool cpu_code_en;
-+      int cpu_code;
-+      int dest_port;
-+};
-+
- int ppe_hw_config(struct ppe_device *ppe_dev);
- int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
-                           int node_id, bool flow_level, int port,
-                           struct ppe_scheduler_cfg scheduler_cfg);
-+int ppe_queue_ucast_base_set(struct ppe_device *ppe_dev,
-+                           struct ppe_queue_ucast_dest queue_dst,
-+                           int queue_base,
-+                           int profile_id);
-+int ppe_queue_ucast_offset_pri_set(struct ppe_device *ppe_dev,
-+                                 int profile_id,
-+                                 int priority,
-+                                 int queue_offset);
-+int ppe_queue_ucast_offset_hash_set(struct ppe_device *ppe_dev,
-+                                  int profile_id,
-+                                  int rss_hash,
-+                                  int queue_offset);
-+int ppe_port_resource_get(struct ppe_device *ppe_dev, int port,
-+                        enum ppe_resource_type type,
-+                        int *res_start, int *res_end);
- #endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -164,6 +164,27 @@
- #define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value)  \
-       u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC)
-+/* The queue base configurations based on destination port,
-+ * service code or CPU code.
-+ */
-+#define PPE_UCAST_QUEUE_MAP_TBL_ADDR          0x810000
-+#define PPE_UCAST_QUEUE_MAP_TBL_ENTRIES               3072
-+#define PPE_UCAST_QUEUE_MAP_TBL_INC           0x10
-+#define PPE_UCAST_QUEUE_MAP_TBL_PROFILE_ID    GENMASK(3, 0)
-+#define PPE_UCAST_QUEUE_MAP_TBL_QUEUE_ID      GENMASK(11, 4)
-+
-+/* The queue offset configurations based on RSS hash value. */
-+#define PPE_UCAST_HASH_MAP_TBL_ADDR           0x830000
-+#define PPE_UCAST_HASH_MAP_TBL_ENTRIES                4096
-+#define PPE_UCAST_HASH_MAP_TBL_INC            0x10
-+#define PPE_UCAST_HASH_MAP_TBL_HASH           GENMASK(7, 0)
-+
-+/* The queue offset configurations based on PPE internal priority. */
-+#define PPE_UCAST_PRIORITY_MAP_TBL_ADDR               0x842000
-+#define PPE_UCAST_PRIORITY_MAP_TBL_ENTRIES    256
-+#define PPE_UCAST_PRIORITY_MAP_TBL_INC                0x10
-+#define PPE_UCAST_PRIORITY_MAP_TBL_CLASS      GENMASK(3, 0)
-+
- /* PPE unicast queue (0-255) configurations. */
- #define PPE_AC_UNICAST_QUEUE_CFG_TBL_ADDR     0x848000
- #define PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES  256
diff --git a/target/linux/qualcommbe/patches-6.12/0330-net-ethernet-qualcomm-Initialize-PPE-service-code-se.patch b/target/linux/qualcommbe/patches-6.12/0330-net-ethernet-qualcomm-Initialize-PPE-service-code-se.patch
deleted file mode 100644 (file)
index 176b7d6..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-From 4147ce0d95816bded5c5e6cb276b1aa9f2620045 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:42 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE service code settings
-
-PPE service code is a special code (0-255) that is defined by PPE for
-PPE's packet processing stages, as per the network functions required
-for the packet.
-
-For packet being sent out by ARM cores on Ethernet ports, The service
-code 1 is used as the default service code. This service code is used
-to bypass most of packet processing stages of the PPE before the packet
-transmitted out PPE port, since the software network stack has already
-processed the packet.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    |  95 +++++++++++-
- .../net/ethernet/qualcomm/ppe/ppe_config.h    | 145 ++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  |  53 +++++++
- 3 files changed, 292 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -8,6 +8,7 @@
-  */
- #include <linux/bitfield.h>
-+#include <linux/bitmap.h>
- #include <linux/bits.h>
- #include <linux/device.h>
- #include <linux/regmap.h>
-@@ -1083,6 +1084,75 @@ int ppe_port_resource_get(struct ppe_dev
-       return 0;
- }
-+/**
-+ * ppe_sc_config_set - Set PPE service code configuration
-+ * @ppe_dev: PPE device
-+ * @sc: Service ID, 0-255 supported by PPE
-+ * @cfg: Service code configuration
-+ *
-+ * PPE service code is used by the PPE during its packet processing stages,
-+ * to perform or bypass certain selected packet operations on the packet.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc, struct ppe_sc_cfg cfg)
-+{
-+      u32 val, reg, servcode_val[2] = {};
-+      unsigned long bitmap_value;
-+      int ret;
-+
-+      val = FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_PORT_ID_VALID, cfg.dest_port_valid);
-+      val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_PORT_ID, cfg.dest_port);
-+      val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_DIRECTION, cfg.is_src);
-+
-+      bitmap_value = bitmap_read(cfg.bitmaps.egress, 0, PPE_SC_BYPASS_EGRESS_SIZE);
-+      val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_BYPASS_BITMAP, bitmap_value);
-+      val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_RX_CNT_EN,
-+                        test_bit(PPE_SC_BYPASS_COUNTER_RX, cfg.bitmaps.counter));
-+      val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_TX_CNT_EN,
-+                        test_bit(PPE_SC_BYPASS_COUNTER_TX, cfg.bitmaps.counter));
-+      reg = PPE_IN_L2_SERVICE_TBL_ADDR + PPE_IN_L2_SERVICE_TBL_INC * sc;
-+
-+      ret = regmap_write(ppe_dev->regmap, reg, val);
-+      if (ret)
-+              return ret;
-+
-+      bitmap_value = bitmap_read(cfg.bitmaps.ingress, 0, PPE_SC_BYPASS_INGRESS_SIZE);
-+      PPE_SERVICE_SET_BYPASS_BITMAP(servcode_val, bitmap_value);
-+      PPE_SERVICE_SET_RX_CNT_EN(servcode_val,
-+                                test_bit(PPE_SC_BYPASS_COUNTER_RX_VLAN, cfg.bitmaps.counter));
-+      reg = PPE_SERVICE_TBL_ADDR + PPE_SERVICE_TBL_INC * sc;
-+
-+      ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                              servcode_val, ARRAY_SIZE(servcode_val));
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_EG_SERVICE_TBL_ADDR + PPE_EG_SERVICE_TBL_INC * sc;
-+      ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                             servcode_val, ARRAY_SIZE(servcode_val));
-+      if (ret)
-+              return ret;
-+
-+      PPE_EG_SERVICE_SET_NEXT_SERVCODE(servcode_val, cfg.next_service_code);
-+      PPE_EG_SERVICE_SET_UPDATE_ACTION(servcode_val, cfg.eip_field_update_bitmap);
-+      PPE_EG_SERVICE_SET_HW_SERVICE(servcode_val, cfg.eip_hw_service);
-+      PPE_EG_SERVICE_SET_OFFSET_SEL(servcode_val, cfg.eip_offset_sel);
-+      PPE_EG_SERVICE_SET_TX_CNT_EN(servcode_val,
-+                                   test_bit(PPE_SC_BYPASS_COUNTER_TX_VLAN, cfg.bitmaps.counter));
-+
-+      ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                              servcode_val, ARRAY_SIZE(servcode_val));
-+      if (ret)
-+              return ret;
-+
-+      bitmap_value = bitmap_read(cfg.bitmaps.tunnel, 0, PPE_SC_BYPASS_TUNNEL_SIZE);
-+      val = FIELD_PREP(PPE_TL_SERVICE_TBL_BYPASS_BITMAP, bitmap_value);
-+      reg = PPE_TL_SERVICE_TBL_ADDR + PPE_TL_SERVICE_TBL_INC * sc;
-+
-+      return regmap_write(ppe_dev->regmap, reg, val);
-+}
-+
- static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
-                                  const struct ppe_bm_port_config port_cfg)
- {
-@@ -1490,6 +1560,25 @@ static int ppe_queue_dest_init(struct pp
-       return 0;
- }
-+/* Initialize the service code 1 used by CPU port. */
-+static int ppe_servcode_init(struct ppe_device *ppe_dev)
-+{
-+      struct ppe_sc_cfg sc_cfg = {};
-+
-+      bitmap_zero(sc_cfg.bitmaps.counter, PPE_SC_BYPASS_COUNTER_SIZE);
-+      bitmap_zero(sc_cfg.bitmaps.tunnel, PPE_SC_BYPASS_TUNNEL_SIZE);
-+
-+      bitmap_fill(sc_cfg.bitmaps.ingress, PPE_SC_BYPASS_INGRESS_SIZE);
-+      clear_bit(PPE_SC_BYPASS_INGRESS_FAKE_MAC_HEADER, sc_cfg.bitmaps.ingress);
-+      clear_bit(PPE_SC_BYPASS_INGRESS_SERVICE_CODE, sc_cfg.bitmaps.ingress);
-+      clear_bit(PPE_SC_BYPASS_INGRESS_FAKE_L2_PROTO, sc_cfg.bitmaps.ingress);
-+
-+      bitmap_fill(sc_cfg.bitmaps.egress, PPE_SC_BYPASS_EGRESS_SIZE);
-+      clear_bit(PPE_SC_BYPASS_EGRESS_ACL_POST_ROUTING_CHECK, sc_cfg.bitmaps.egress);
-+
-+      return ppe_sc_config_set(ppe_dev, PPE_EDMA_SC_BYPASS_ID, sc_cfg);
-+}
-+
- int ppe_hw_config(struct ppe_device *ppe_dev)
- {
-       int ret;
-@@ -1506,5 +1595,9 @@ int ppe_hw_config(struct ppe_device *ppe
-       if (ret)
-               return ret;
--      return ppe_queue_dest_init(ppe_dev);
-+      ret = ppe_queue_dest_init(ppe_dev);
-+      if (ret)
-+              return ret;
-+
-+      return ppe_servcode_init(ppe_dev);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-@@ -6,6 +6,8 @@
- #ifndef __PPE_CONFIG_H__
- #define __PPE_CONFIG_H__
-+#include <linux/types.h>
-+
- #include "ppe.h"
- /* There are different table index ranges for configuring queue base ID of
-@@ -18,6 +20,9 @@
- #define PPE_QUEUE_INTER_PRI_NUM                       16
- #define PPE_QUEUE_HASH_NUM                    256
-+/* The service code is used by EDMA port to transmit packet to PPE. */
-+#define PPE_EDMA_SC_BYPASS_ID                 1
-+
- /**
-  * enum ppe_scheduler_frame_mode - PPE scheduler frame mode.
-  * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG,
-@@ -90,6 +95,144 @@ struct ppe_queue_ucast_dest {
-       int dest_port;
- };
-+/* Hardware bitmaps for bypassing features of the ingress packet. */
-+enum ppe_sc_ingress_type {
-+      PPE_SC_BYPASS_INGRESS_VLAN_TAG_FMT_CHECK = 0,
-+      PPE_SC_BYPASS_INGRESS_VLAN_MEMBER_CHECK = 1,
-+      PPE_SC_BYPASS_INGRESS_VLAN_TRANSLATE = 2,
-+      PPE_SC_BYPASS_INGRESS_MY_MAC_CHECK = 3,
-+      PPE_SC_BYPASS_INGRESS_DIP_LOOKUP = 4,
-+      PPE_SC_BYPASS_INGRESS_FLOW_LOOKUP = 5,
-+      PPE_SC_BYPASS_INGRESS_FLOW_ACTION = 6,
-+      PPE_SC_BYPASS_INGRESS_ACL = 7,
-+      PPE_SC_BYPASS_INGRESS_FAKE_MAC_HEADER = 8,
-+      PPE_SC_BYPASS_INGRESS_SERVICE_CODE = 9,
-+      PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L2 = 10,
-+      PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L3_IPV4 = 11,
-+      PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L3_IPV6 = 12,
-+      PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L4 = 13,
-+      PPE_SC_BYPASS_INGRESS_FLOW_SERVICE_CODE = 14,
-+      PPE_SC_BYPASS_INGRESS_ACL_SERVICE_CODE = 15,
-+      PPE_SC_BYPASS_INGRESS_FAKE_L2_PROTO = 16,
-+      PPE_SC_BYPASS_INGRESS_PPPOE_TERMINATION = 17,
-+      PPE_SC_BYPASS_INGRESS_DEFAULT_VLAN = 18,
-+      PPE_SC_BYPASS_INGRESS_DEFAULT_PCP = 19,
-+      PPE_SC_BYPASS_INGRESS_VSI_ASSIGN = 20,
-+      /* Values 21-23 are not specified by hardware. */
-+      PPE_SC_BYPASS_INGRESS_VLAN_ASSIGN_FAIL = 24,
-+      PPE_SC_BYPASS_INGRESS_SOURCE_GUARD = 25,
-+      PPE_SC_BYPASS_INGRESS_MRU_MTU_CHECK = 26,
-+      PPE_SC_BYPASS_INGRESS_FLOW_SRC_CHECK = 27,
-+      PPE_SC_BYPASS_INGRESS_FLOW_QOS = 28,
-+      /* This must be last as it determines the size of the BITMAP. */
-+      PPE_SC_BYPASS_INGRESS_SIZE,
-+};
-+
-+/* Hardware bitmaps for bypassing features of the egress packet. */
-+enum ppe_sc_egress_type {
-+      PPE_SC_BYPASS_EGRESS_VLAN_MEMBER_CHECK = 0,
-+      PPE_SC_BYPASS_EGRESS_VLAN_TRANSLATE = 1,
-+      PPE_SC_BYPASS_EGRESS_VLAN_TAG_FMT_CTRL = 2,
-+      PPE_SC_BYPASS_EGRESS_FDB_LEARN = 3,
-+      PPE_SC_BYPASS_EGRESS_FDB_REFRESH = 4,
-+      PPE_SC_BYPASS_EGRESS_L2_SOURCE_SECURITY = 5,
-+      PPE_SC_BYPASS_EGRESS_MANAGEMENT_FWD = 6,
-+      PPE_SC_BYPASS_EGRESS_BRIDGING_FWD = 7,
-+      PPE_SC_BYPASS_EGRESS_IN_STP_FLTR = 8,
-+      PPE_SC_BYPASS_EGRESS_EG_STP_FLTR = 9,
-+      PPE_SC_BYPASS_EGRESS_SOURCE_FLTR = 10,
-+      PPE_SC_BYPASS_EGRESS_POLICER = 11,
-+      PPE_SC_BYPASS_EGRESS_L2_PKT_EDIT = 12,
-+      PPE_SC_BYPASS_EGRESS_L3_PKT_EDIT = 13,
-+      PPE_SC_BYPASS_EGRESS_ACL_POST_ROUTING_CHECK = 14,
-+      PPE_SC_BYPASS_EGRESS_PORT_ISOLATION = 15,
-+      PPE_SC_BYPASS_EGRESS_PRE_ACL_QOS = 16,
-+      PPE_SC_BYPASS_EGRESS_POST_ACL_QOS = 17,
-+      PPE_SC_BYPASS_EGRESS_DSCP_QOS = 18,
-+      PPE_SC_BYPASS_EGRESS_PCP_QOS = 19,
-+      PPE_SC_BYPASS_EGRESS_PREHEADER_QOS = 20,
-+      PPE_SC_BYPASS_EGRESS_FAKE_MAC_DROP = 21,
-+      PPE_SC_BYPASS_EGRESS_TUNL_CONTEXT = 22,
-+      PPE_SC_BYPASS_EGRESS_FLOW_POLICER = 23,
-+      /* This must be last as it determines the size of the BITMAP. */
-+      PPE_SC_BYPASS_EGRESS_SIZE,
-+};
-+
-+/* Hardware bitmaps for bypassing counter of packet. */
-+enum ppe_sc_counter_type {
-+      PPE_SC_BYPASS_COUNTER_RX_VLAN = 0,
-+      PPE_SC_BYPASS_COUNTER_RX = 1,
-+      PPE_SC_BYPASS_COUNTER_TX_VLAN = 2,
-+      PPE_SC_BYPASS_COUNTER_TX = 3,
-+      /* This must be last as it determines the size of the BITMAP. */
-+      PPE_SC_BYPASS_COUNTER_SIZE,
-+};
-+
-+/* Hardware bitmaps for bypassing features of tunnel packet. */
-+enum ppe_sc_tunnel_type {
-+      PPE_SC_BYPASS_TUNNEL_SERVICE_CODE = 0,
-+      PPE_SC_BYPASS_TUNNEL_TUNNEL_HANDLE = 1,
-+      PPE_SC_BYPASS_TUNNEL_L3_IF_CHECK = 2,
-+      PPE_SC_BYPASS_TUNNEL_VLAN_CHECK = 3,
-+      PPE_SC_BYPASS_TUNNEL_DMAC_CHECK = 4,
-+      PPE_SC_BYPASS_TUNNEL_UDP_CSUM_0_CHECK = 5,
-+      PPE_SC_BYPASS_TUNNEL_TBL_DE_ACCE_CHECK = 6,
-+      PPE_SC_BYPASS_TUNNEL_PPPOE_MC_TERM_CHECK = 7,
-+      PPE_SC_BYPASS_TUNNEL_TTL_EXCEED_CHECK = 8,
-+      PPE_SC_BYPASS_TUNNEL_MAP_SRC_CHECK = 9,
-+      PPE_SC_BYPASS_TUNNEL_MAP_DST_CHECK = 10,
-+      PPE_SC_BYPASS_TUNNEL_LPM_DST_LOOKUP = 11,
-+      PPE_SC_BYPASS_TUNNEL_LPM_LOOKUP = 12,
-+      PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L2 = 13,
-+      PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L3_IPV4 = 14,
-+      PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L3_IPV6 = 15,
-+      PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L4 = 16,
-+      PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_TUNNEL = 17,
-+      /* Values 18-19 are not specified by hardware. */
-+      PPE_SC_BYPASS_TUNNEL_PRE_IPO = 20,
-+      /* This must be last as it determines the size of the BITMAP. */
-+      PPE_SC_BYPASS_TUNNEL_SIZE,
-+};
-+
-+/**
-+ * struct ppe_sc_bypass - PPE service bypass bitmaps
-+ * @ingress: Bitmap of features that can be bypassed on the ingress packet.
-+ * @egress: Bitmap of features that can be bypassed on the egress packet.
-+ * @counter: Bitmap of features that can be bypassed on the counter type.
-+ * @tunnel: Bitmap of features that can be bypassed on the tunnel packet.
-+ */
-+struct ppe_sc_bypass {
-+      DECLARE_BITMAP(ingress, PPE_SC_BYPASS_INGRESS_SIZE);
-+      DECLARE_BITMAP(egress, PPE_SC_BYPASS_EGRESS_SIZE);
-+      DECLARE_BITMAP(counter, PPE_SC_BYPASS_COUNTER_SIZE);
-+      DECLARE_BITMAP(tunnel, PPE_SC_BYPASS_TUNNEL_SIZE);
-+};
-+
-+/**
-+ * struct ppe_sc_cfg - PPE service code configuration.
-+ * @dest_port_valid: Generate destination port or not.
-+ * @dest_port: Destination port ID.
-+ * @bitmaps: Bitmap of bypass features.
-+ * @is_src: Destination port acts as source port, packet sent to CPU.
-+ * @next_service_code: New service code generated.
-+ * @eip_field_update_bitmap: Fields updated as actions taken for EIP.
-+ * @eip_hw_service: Selected hardware functions for EIP.
-+ * @eip_offset_sel: Packet offset selection, using packet's layer 4 offset
-+ * or using packet's layer 3 offset for EIP.
-+ *
-+ * Service code is generated during the packet passing through PPE.
-+ */
-+struct ppe_sc_cfg {
-+      bool dest_port_valid;
-+      int dest_port;
-+      struct ppe_sc_bypass bitmaps;
-+      bool is_src;
-+      int next_service_code;
-+      int eip_field_update_bitmap;
-+      int eip_hw_service;
-+      int eip_offset_sel;
-+};
-+
- int ppe_hw_config(struct ppe_device *ppe_dev);
- int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
-                           int node_id, bool flow_level, int port,
-@@ -109,4 +252,6 @@ int ppe_queue_ucast_offset_hash_set(stru
- int ppe_port_resource_get(struct ppe_device *ppe_dev, int port,
-                         enum ppe_resource_type type,
-                         int *res_start, int *res_end);
-+int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc,
-+                    struct ppe_sc_cfg cfg);
- #endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -25,10 +25,63 @@
- #define PPE_BM_SCH_CFG_TBL_SECOND_PORT_VALID  BIT(6)
- #define PPE_BM_SCH_CFG_TBL_SECOND_PORT                GENMASK(11, 8)
-+/* PPE service code configuration for the ingress direction functions,
-+ * including bypass configuration for relevant PPE switch core functions
-+ * such as flow entry lookup bypass.
-+ */
-+#define PPE_SERVICE_TBL_ADDR                  0x15000
-+#define PPE_SERVICE_TBL_ENTRIES                       256
-+#define PPE_SERVICE_TBL_INC                   0x10
-+#define PPE_SERVICE_W0_BYPASS_BITMAP          GENMASK(31, 0)
-+#define PPE_SERVICE_W1_RX_CNT_EN              BIT(0)
-+
-+#define PPE_SERVICE_SET_BYPASS_BITMAP(tbl_cfg, value) \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_SERVICE_W0_BYPASS_BITMAP)
-+#define PPE_SERVICE_SET_RX_CNT_EN(tbl_cfg, value)     \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_SERVICE_W1_RX_CNT_EN)
-+
- /* PPE queue counters enable/disable control. */
- #define PPE_EG_BRIDGE_CONFIG_ADDR             0x20044
- #define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN     BIT(2)
-+/* PPE service code configuration on the egress direction. */
-+#define PPE_EG_SERVICE_TBL_ADDR                       0x43000
-+#define PPE_EG_SERVICE_TBL_ENTRIES            256
-+#define PPE_EG_SERVICE_TBL_INC                        0x10
-+#define PPE_EG_SERVICE_W0_UPDATE_ACTION               GENMASK(31, 0)
-+#define PPE_EG_SERVICE_W1_NEXT_SERVCODE               GENMASK(7, 0)
-+#define PPE_EG_SERVICE_W1_HW_SERVICE          GENMASK(13, 8)
-+#define PPE_EG_SERVICE_W1_OFFSET_SEL          BIT(14)
-+#define PPE_EG_SERVICE_W1_TX_CNT_EN           BIT(15)
-+
-+#define PPE_EG_SERVICE_SET_UPDATE_ACTION(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_EG_SERVICE_W0_UPDATE_ACTION)
-+#define PPE_EG_SERVICE_SET_NEXT_SERVCODE(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_NEXT_SERVCODE)
-+#define PPE_EG_SERVICE_SET_HW_SERVICE(tbl_cfg, value) \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_HW_SERVICE)
-+#define PPE_EG_SERVICE_SET_OFFSET_SEL(tbl_cfg, value) \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_OFFSET_SEL)
-+#define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value)  \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN)
-+
-+/* PPE service code configuration for destination port and counter. */
-+#define PPE_IN_L2_SERVICE_TBL_ADDR            0x66000
-+#define PPE_IN_L2_SERVICE_TBL_ENTRIES         256
-+#define PPE_IN_L2_SERVICE_TBL_INC             0x10
-+#define PPE_IN_L2_SERVICE_TBL_DST_PORT_ID_VALID       BIT(0)
-+#define PPE_IN_L2_SERVICE_TBL_DST_PORT_ID     GENMASK(4, 1)
-+#define PPE_IN_L2_SERVICE_TBL_DST_DIRECTION   BIT(5)
-+#define PPE_IN_L2_SERVICE_TBL_DST_BYPASS_BITMAP       GENMASK(29, 6)
-+#define PPE_IN_L2_SERVICE_TBL_RX_CNT_EN               BIT(30)
-+#define PPE_IN_L2_SERVICE_TBL_TX_CNT_EN               BIT(31)
-+
-+/* PPE service code configuration for the tunnel packet. */
-+#define PPE_TL_SERVICE_TBL_ADDR                       0x306000
-+#define PPE_TL_SERVICE_TBL_ENTRIES            256
-+#define PPE_TL_SERVICE_TBL_INC                        4
-+#define PPE_TL_SERVICE_TBL_BYPASS_BITMAP      GENMASK(31, 0)
-+
- /* Port scheduler global config. */
- #define PPE_PSCH_SCH_DEPTH_CFG_ADDR           0x400000
- #define PPE_PSCH_SCH_DEPTH_CFG_INC            4
diff --git a/target/linux/qualcommbe/patches-6.12/0331-net-ethernet-qualcomm-Initialize-PPE-port-control-se.patch b/target/linux/qualcommbe/patches-6.12/0331-net-ethernet-qualcomm-Initialize-PPE-port-control-se.patch
deleted file mode 100644 (file)
index f1dcb51..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-From 63af46200da794acda25cf8083bde0c1576b0859 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:43 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE port control settings
-
-1. Enable port specific counters in PPE.
-2. Configure the default action as drop when the packet size
-   is more than the configured MTU of physical port.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 86 ++++++++++++++++++-
- .../net/ethernet/qualcomm/ppe/ppe_config.h    | 15 ++++
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  | 47 ++++++++++
- 3 files changed, 147 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -1153,6 +1153,44 @@ int ppe_sc_config_set(struct ppe_device
-       return regmap_write(ppe_dev->regmap, reg, val);
- }
-+/**
-+ * ppe_counter_enable_set - Set PPE port counter enabled
-+ * @ppe_dev: PPE device
-+ * @port: PPE port ID
-+ *
-+ * Enable PPE counters on the given port for the unicast packet, multicast
-+ * packet and VLAN packet received and transmitted by PPE.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port)
-+{
-+      u32 reg, mru_mtu_val[3];
-+      int ret;
-+
-+      reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * port;
-+      ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                             mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
-+      if (ret)
-+              return ret;
-+
-+      PPE_MRU_MTU_CTRL_SET_RX_CNT_EN(mru_mtu_val, true);
-+      PPE_MRU_MTU_CTRL_SET_TX_CNT_EN(mru_mtu_val, true);
-+      ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                              mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * port;
-+      ret = regmap_set_bits(ppe_dev->regmap, reg, PPE_MC_MTU_CTRL_TBL_TX_CNT_EN);
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_PORT_EG_VLAN_TBL_ADDR + PPE_PORT_EG_VLAN_TBL_INC * port;
-+
-+      return regmap_set_bits(ppe_dev->regmap, reg, PPE_PORT_EG_VLAN_TBL_TX_COUNTING_EN);
-+}
-+
- static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
-                                  const struct ppe_bm_port_config port_cfg)
- {
-@@ -1579,6 +1617,48 @@ static int ppe_servcode_init(struct ppe_
-       return ppe_sc_config_set(ppe_dev, PPE_EDMA_SC_BYPASS_ID, sc_cfg);
- }
-+/* Initialize PPE port configurations. */
-+static int ppe_port_config_init(struct ppe_device *ppe_dev)
-+{
-+      u32 reg, val, mru_mtu_val[3];
-+      int i, ret;
-+
-+      /* MTU and MRU settings are not required for CPU port 0. */
-+      for (i = 1; i < ppe_dev->num_ports; i++) {
-+              /* Enable Ethernet port counter */
-+              ret = ppe_counter_enable_set(ppe_dev, i);
-+              if (ret)
-+                      return ret;
-+
-+              reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * i;
-+              ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                                     mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
-+              if (ret)
-+                      return ret;
-+
-+              /* Drop the packet when the packet size is more than
-+               * the MTU or MRU of the physical interface.
-+               */
-+              PPE_MRU_MTU_CTRL_SET_MRU_CMD(mru_mtu_val, PPE_ACTION_DROP);
-+              PPE_MRU_MTU_CTRL_SET_MTU_CMD(mru_mtu_val, PPE_ACTION_DROP);
-+              ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                                      mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
-+              if (ret)
-+                      return ret;
-+
-+              reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * i;
-+              val = FIELD_PREP(PPE_MC_MTU_CTRL_TBL_MTU_CMD, PPE_ACTION_DROP);
-+              ret = regmap_update_bits(ppe_dev->regmap, reg,
-+                                       PPE_MC_MTU_CTRL_TBL_MTU_CMD,
-+                                       val);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /* Enable CPU port counters. */
-+      return ppe_counter_enable_set(ppe_dev, 0);
-+}
-+
- int ppe_hw_config(struct ppe_device *ppe_dev)
- {
-       int ret;
-@@ -1599,5 +1679,9 @@ int ppe_hw_config(struct ppe_device *ppe
-       if (ret)
-               return ret;
--      return ppe_servcode_init(ppe_dev);
-+      ret = ppe_servcode_init(ppe_dev);
-+      if (ret)
-+              return ret;
-+
-+      return ppe_port_config_init(ppe_dev);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-@@ -233,6 +233,20 @@ struct ppe_sc_cfg {
-       int eip_offset_sel;
- };
-+/**
-+ * enum ppe_action_type - PPE action of the received packet.
-+ * @PPE_ACTION_FORWARD: Packet forwarded per L2/L3 process.
-+ * @PPE_ACTION_DROP: Packet dropped by PPE.
-+ * @PPE_ACTION_COPY_TO_CPU: Packet copied to CPU port per multicast queue.
-+ * @PPE_ACTION_REDIRECT_TO_CPU: Packet redirected to CPU port per unicast queue.
-+ */
-+enum ppe_action_type {
-+      PPE_ACTION_FORWARD = 0,
-+      PPE_ACTION_DROP = 1,
-+      PPE_ACTION_COPY_TO_CPU = 2,
-+      PPE_ACTION_REDIRECT_TO_CPU = 3,
-+};
-+
- int ppe_hw_config(struct ppe_device *ppe_dev);
- int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
-                           int node_id, bool flow_level, int port,
-@@ -254,4 +268,5 @@ int ppe_port_resource_get(struct ppe_dev
-                         int *res_start, int *res_end);
- int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc,
-                     struct ppe_sc_cfg cfg);
-+int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port);
- #endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -40,6 +40,18 @@
- #define PPE_SERVICE_SET_RX_CNT_EN(tbl_cfg, value)     \
-       u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_SERVICE_W1_RX_CNT_EN)
-+/* PPE port egress VLAN configurations. */
-+#define PPE_PORT_EG_VLAN_TBL_ADDR             0x20020
-+#define PPE_PORT_EG_VLAN_TBL_ENTRIES          8
-+#define PPE_PORT_EG_VLAN_TBL_INC              4
-+#define PPE_PORT_EG_VLAN_TBL_VLAN_TYPE                BIT(0)
-+#define PPE_PORT_EG_VLAN_TBL_CTAG_MODE                GENMASK(2, 1)
-+#define PPE_PORT_EG_VLAN_TBL_STAG_MODE                GENMASK(4, 3)
-+#define PPE_PORT_EG_VLAN_TBL_VSI_TAG_MODE_EN  BIT(5)
-+#define PPE_PORT_EG_VLAN_TBL_PCP_PROP_CMD     BIT(6)
-+#define PPE_PORT_EG_VLAN_TBL_DEI_PROP_CMD     BIT(7)
-+#define PPE_PORT_EG_VLAN_TBL_TX_COUNTING_EN   BIT(8)
-+
- /* PPE queue counters enable/disable control. */
- #define PPE_EG_BRIDGE_CONFIG_ADDR             0x20044
- #define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN     BIT(2)
-@@ -65,6 +77,41 @@
- #define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value)  \
-       u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN)
-+/* PPE port control configurations for the traffic to the multicast queues. */
-+#define PPE_MC_MTU_CTRL_TBL_ADDR              0x60a00
-+#define PPE_MC_MTU_CTRL_TBL_ENTRIES           8
-+#define PPE_MC_MTU_CTRL_TBL_INC                       4
-+#define PPE_MC_MTU_CTRL_TBL_MTU                       GENMASK(13, 0)
-+#define PPE_MC_MTU_CTRL_TBL_MTU_CMD           GENMASK(15, 14)
-+#define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN         BIT(16)
-+
-+/* PPE port control configurations for the traffic to the unicast queues. */
-+#define PPE_MRU_MTU_CTRL_TBL_ADDR             0x65000
-+#define PPE_MRU_MTU_CTRL_TBL_ENTRIES          256
-+#define PPE_MRU_MTU_CTRL_TBL_INC              0x10
-+#define PPE_MRU_MTU_CTRL_W0_MRU                       GENMASK(13, 0)
-+#define PPE_MRU_MTU_CTRL_W0_MRU_CMD           GENMASK(15, 14)
-+#define PPE_MRU_MTU_CTRL_W0_MTU                       GENMASK(29, 16)
-+#define PPE_MRU_MTU_CTRL_W0_MTU_CMD           GENMASK(31, 30)
-+#define PPE_MRU_MTU_CTRL_W1_RX_CNT_EN         BIT(0)
-+#define PPE_MRU_MTU_CTRL_W1_TX_CNT_EN         BIT(1)
-+#define PPE_MRU_MTU_CTRL_W1_SRC_PROFILE               GENMASK(3, 2)
-+#define PPE_MRU_MTU_CTRL_W1_INNER_PREC_LOW    BIT(31)
-+#define PPE_MRU_MTU_CTRL_W2_INNER_PREC_HIGH   GENMASK(1, 0)
-+
-+#define PPE_MRU_MTU_CTRL_SET_MRU(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MRU)
-+#define PPE_MRU_MTU_CTRL_SET_MRU_CMD(tbl_cfg, value)  \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MRU_CMD)
-+#define PPE_MRU_MTU_CTRL_SET_MTU(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MTU)
-+#define PPE_MRU_MTU_CTRL_SET_MTU_CMD(tbl_cfg, value)  \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MTU_CMD)
-+#define PPE_MRU_MTU_CTRL_SET_RX_CNT_EN(tbl_cfg, value)        \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_MRU_MTU_CTRL_W1_RX_CNT_EN)
-+#define PPE_MRU_MTU_CTRL_SET_TX_CNT_EN(tbl_cfg, value)        \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_MRU_MTU_CTRL_W1_TX_CNT_EN)
-+
- /* PPE service code configuration for destination port and counter. */
- #define PPE_IN_L2_SERVICE_TBL_ADDR            0x66000
- #define PPE_IN_L2_SERVICE_TBL_ENTRIES         256
diff --git a/target/linux/qualcommbe/patches-6.12/0332-net-ethernet-qualcomm-Initialize-PPE-RSS-hash-settin.patch b/target/linux/qualcommbe/patches-6.12/0332-net-ethernet-qualcomm-Initialize-PPE-RSS-hash-settin.patch
deleted file mode 100644 (file)
index fc07642..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-From 796be78fffeebe77237a6464da7ebe9807d670f0 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:44 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE RSS hash settings
-
-PPE RSS hash is generated during PPE receive, based on the packet
-content (3 tuples or 5 tuples) and as per the configured RSS seed.
-The hash is then used to select the queue to transmit the packet
-to the ARM CPU.
-
-This patch initializes the RSS hash settings that are used to
-generate the hash for the packet during PPE packet receive.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 194 +++++++++++++++++-
- .../net/ethernet/qualcomm/ppe/ppe_config.h    |  39 ++++
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  |  40 ++++
- 3 files changed, 272 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -1191,6 +1191,143 @@ int ppe_counter_enable_set(struct ppe_de
-       return regmap_set_bits(ppe_dev->regmap, reg, PPE_PORT_EG_VLAN_TBL_TX_COUNTING_EN);
- }
-+static int ppe_rss_hash_ipv4_config(struct ppe_device *ppe_dev, int index,
-+                                  struct ppe_rss_hash_cfg cfg)
-+{
-+      u32 reg, val;
-+
-+      switch (index) {
-+      case 0:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_sip_mix[0]);
-+              break;
-+      case 1:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_dip_mix[0]);
-+              break;
-+      case 2:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_protocol_mix);
-+              break;
-+      case 3:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_dport_mix);
-+              break;
-+      case 4:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_sport_mix);
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      reg = PPE_RSS_HASH_MIX_IPV4_ADDR + index * PPE_RSS_HASH_MIX_IPV4_INC;
-+
-+      return regmap_write(ppe_dev->regmap, reg, val);
-+}
-+
-+static int ppe_rss_hash_ipv6_config(struct ppe_device *ppe_dev, int index,
-+                                  struct ppe_rss_hash_cfg cfg)
-+{
-+      u32 reg, val;
-+
-+      switch (index) {
-+      case 0 ... 3:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_sip_mix[index]);
-+              break;
-+      case 4 ... 7:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_dip_mix[index - 4]);
-+              break;
-+      case 8:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_protocol_mix);
-+              break;
-+      case 9:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_dport_mix);
-+              break;
-+      case 10:
-+              val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_sport_mix);
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      reg = PPE_RSS_HASH_MIX_ADDR + index * PPE_RSS_HASH_MIX_INC;
-+
-+      return regmap_write(ppe_dev->regmap, reg, val);
-+}
-+
-+/**
-+ * ppe_rss_hash_config_set - Configure the PPE hash settings for the packet received.
-+ * @ppe_dev: PPE device.
-+ * @mode: Configure RSS hash for the packet type IPv4 and IPv6.
-+ * @cfg: RSS hash configuration.
-+ *
-+ * PPE RSS hash settings are configured for the packet type IPv4 and IPv6.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
-+                          struct ppe_rss_hash_cfg cfg)
-+{
-+      u32 val, reg;
-+      int i, ret;
-+
-+      if (mode & PPE_RSS_HASH_MODE_IPV4) {
-+              val = FIELD_PREP(PPE_RSS_HASH_MASK_IPV4_HASH_MASK, cfg.hash_mask);
-+              val |= FIELD_PREP(PPE_RSS_HASH_MASK_IPV4_FRAGMENT, cfg.hash_fragment_mode);
-+              ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_MASK_IPV4_ADDR, val);
-+              if (ret)
-+                      return ret;
-+
-+              val = FIELD_PREP(PPE_RSS_HASH_SEED_IPV4_VAL, cfg.hash_seed);
-+              ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_SEED_IPV4_ADDR, val);
-+              if (ret)
-+                      return ret;
-+
-+              for (i = 0; i < PPE_RSS_HASH_MIX_IPV4_ENTRIES; i++) {
-+                      ret = ppe_rss_hash_ipv4_config(ppe_dev, i, cfg);
-+                      if (ret)
-+                              return ret;
-+              }
-+
-+              for (i = 0; i < PPE_RSS_HASH_FIN_IPV4_ENTRIES; i++) {
-+                      val = FIELD_PREP(PPE_RSS_HASH_FIN_IPV4_INNER, cfg.hash_fin_inner[i]);
-+                      val |= FIELD_PREP(PPE_RSS_HASH_FIN_IPV4_OUTER, cfg.hash_fin_outer[i]);
-+                      reg = PPE_RSS_HASH_FIN_IPV4_ADDR + i * PPE_RSS_HASH_FIN_IPV4_INC;
-+
-+                      ret = regmap_write(ppe_dev->regmap, reg, val);
-+                      if (ret)
-+                              return ret;
-+              }
-+      }
-+
-+      if (mode & PPE_RSS_HASH_MODE_IPV6) {
-+              val = FIELD_PREP(PPE_RSS_HASH_MASK_HASH_MASK, cfg.hash_mask);
-+              val |= FIELD_PREP(PPE_RSS_HASH_MASK_FRAGMENT, cfg.hash_fragment_mode);
-+              ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_MASK_ADDR, val);
-+              if (ret)
-+                      return ret;
-+
-+              val = FIELD_PREP(PPE_RSS_HASH_SEED_VAL, cfg.hash_seed);
-+              ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_SEED_ADDR, val);
-+              if (ret)
-+                      return ret;
-+
-+              for (i = 0; i < PPE_RSS_HASH_MIX_ENTRIES; i++) {
-+                      ret = ppe_rss_hash_ipv6_config(ppe_dev, i, cfg);
-+                      if (ret)
-+                              return ret;
-+              }
-+
-+              for (i = 0; i < PPE_RSS_HASH_FIN_ENTRIES; i++) {
-+                      val = FIELD_PREP(PPE_RSS_HASH_FIN_INNER, cfg.hash_fin_inner[i]);
-+                      val |= FIELD_PREP(PPE_RSS_HASH_FIN_OUTER, cfg.hash_fin_outer[i]);
-+                      reg = PPE_RSS_HASH_FIN_ADDR + i * PPE_RSS_HASH_FIN_INC;
-+
-+                      ret = regmap_write(ppe_dev->regmap, reg, val);
-+                      if (ret)
-+                              return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
- static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
-                                  const struct ppe_bm_port_config port_cfg)
- {
-@@ -1659,6 +1796,57 @@ static int ppe_port_config_init(struct p
-       return ppe_counter_enable_set(ppe_dev, 0);
- }
-+/* Initialize the PPE RSS configuration for IPv4 and IPv6 packet receive.
-+ * RSS settings are to calculate the random RSS hash value generated during
-+ * packet receive. This hash is then used to generate the queue offset used
-+ * to determine the queue used to transmit the packet.
-+ */
-+static int ppe_rss_hash_init(struct ppe_device *ppe_dev)
-+{
-+      u16 fins[PPE_RSS_HASH_TUPLES] = { 0x205, 0x264, 0x227, 0x245, 0x201 };
-+      u8 ips[PPE_RSS_HASH_IP_LENGTH] = { 0x13, 0xb, 0x13, 0xb };
-+      struct ppe_rss_hash_cfg hash_cfg;
-+      int i, ret;
-+
-+      hash_cfg.hash_seed = get_random_u32();
-+      hash_cfg.hash_mask = 0xfff;
-+
-+      /* Use 5 tuple as RSS hash key for the first fragment of TCP, UDP
-+       * and UDP-Lite packets.
-+       */
-+      hash_cfg.hash_fragment_mode = false;
-+
-+      /* The final common seed configs used to calculate the RSS has value,
-+       * which is available for both IPv4 and IPv6 packet.
-+       */
-+      for (i = 0; i < ARRAY_SIZE(fins); i++) {
-+              hash_cfg.hash_fin_inner[i] = fins[i] & 0x1f;
-+              hash_cfg.hash_fin_outer[i] = fins[i] >> 5;
-+      }
-+
-+      /* RSS seeds for IP protocol, L4 destination & source port and
-+       * destination & source IP used to calculate the RSS hash value.
-+       */
-+      hash_cfg.hash_protocol_mix = 0x13;
-+      hash_cfg.hash_dport_mix = 0xb;
-+      hash_cfg.hash_sport_mix = 0x13;
-+      hash_cfg.hash_dip_mix[0] = 0xb;
-+      hash_cfg.hash_sip_mix[0] = 0x13;
-+
-+      /* Configure RSS seed configs for IPv4 packet. */
-+      ret = ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV4, hash_cfg);
-+      if (ret)
-+              return ret;
-+
-+      for (i = 0; i < ARRAY_SIZE(ips); i++) {
-+              hash_cfg.hash_sip_mix[i] = ips[i];
-+              hash_cfg.hash_dip_mix[i] = ips[i];
-+      }
-+
-+      /* Configure RSS seed configs for IPv6 packet. */
-+      return ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV6, hash_cfg);
-+}
-+
- int ppe_hw_config(struct ppe_device *ppe_dev)
- {
-       int ret;
-@@ -1683,5 +1871,9 @@ int ppe_hw_config(struct ppe_device *ppe
-       if (ret)
-               return ret;
--      return ppe_port_config_init(ppe_dev);
-+      ret = ppe_port_config_init(ppe_dev);
-+      if (ret)
-+              return ret;
-+
-+      return ppe_rss_hash_init(ppe_dev);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-@@ -23,6 +23,12 @@
- /* The service code is used by EDMA port to transmit packet to PPE. */
- #define PPE_EDMA_SC_BYPASS_ID                 1
-+/* The PPE RSS hash configured for IPv4 and IPv6 packet separately. */
-+#define PPE_RSS_HASH_MODE_IPV4                        BIT(0)
-+#define PPE_RSS_HASH_MODE_IPV6                        BIT(1)
-+#define PPE_RSS_HASH_IP_LENGTH                        4
-+#define PPE_RSS_HASH_TUPLES                   5
-+
- /**
-  * enum ppe_scheduler_frame_mode - PPE scheduler frame mode.
-  * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG,
-@@ -247,6 +253,37 @@ enum ppe_action_type {
-       PPE_ACTION_REDIRECT_TO_CPU = 3,
- };
-+/**
-+ * struct ppe_rss_hash_cfg - PPE RSS hash configuration.
-+ * @hash_mask: Mask of the generated hash value.
-+ * @hash_fragment_mode: Hash generation mode for the first fragment of TCP,
-+ * UDP and UDP-Lite packets, to use either 3 tuple or 5 tuple for RSS hash
-+ * key computation.
-+ * @hash_seed: Seed to generate RSS hash.
-+ * @hash_sip_mix: Source IP selection.
-+ * @hash_dip_mix: Destination IP selection.
-+ * @hash_protocol_mix: Protocol selection.
-+ * @hash_sport_mix: Source L4 port selection.
-+ * @hash_dport_mix: Destination L4 port selection.
-+ * @hash_fin_inner: RSS hash value first selection.
-+ * @hash_fin_outer: RSS hash value second selection.
-+ *
-+ * PPE RSS hash value is generated for the packet based on the RSS hash
-+ * configured.
-+ */
-+struct ppe_rss_hash_cfg {
-+      u32 hash_mask;
-+      bool hash_fragment_mode;
-+      u32 hash_seed;
-+      u8 hash_sip_mix[PPE_RSS_HASH_IP_LENGTH];
-+      u8 hash_dip_mix[PPE_RSS_HASH_IP_LENGTH];
-+      u8 hash_protocol_mix;
-+      u8 hash_sport_mix;
-+      u8 hash_dport_mix;
-+      u8 hash_fin_inner[PPE_RSS_HASH_TUPLES];
-+      u8 hash_fin_outer[PPE_RSS_HASH_TUPLES];
-+};
-+
- int ppe_hw_config(struct ppe_device *ppe_dev);
- int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
-                           int node_id, bool flow_level, int port,
-@@ -269,4 +306,6 @@ int ppe_port_resource_get(struct ppe_dev
- int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc,
-                     struct ppe_sc_cfg cfg);
- int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port);
-+int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
-+                          struct ppe_rss_hash_cfg hash_cfg);
- #endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -16,6 +16,46 @@
- #define PPE_BM_SCH_CTRL_SCH_OFFSET            GENMASK(14, 8)
- #define PPE_BM_SCH_CTRL_SCH_EN                        BIT(31)
-+/* RSS settings are to calculate the random RSS hash value generated during
-+ * packet receive to ARM cores. This hash is then used to generate the queue
-+ * offset used to determine the queue used to transmit the packet to ARM cores.
-+ */
-+#define PPE_RSS_HASH_MASK_ADDR                        0xb4318
-+#define PPE_RSS_HASH_MASK_HASH_MASK           GENMASK(20, 0)
-+#define PPE_RSS_HASH_MASK_FRAGMENT            BIT(28)
-+
-+#define PPE_RSS_HASH_SEED_ADDR                        0xb431c
-+#define PPE_RSS_HASH_SEED_VAL                 GENMASK(31, 0)
-+
-+#define PPE_RSS_HASH_MIX_ADDR                 0xb4320
-+#define PPE_RSS_HASH_MIX_ENTRIES              11
-+#define PPE_RSS_HASH_MIX_INC                  4
-+#define PPE_RSS_HASH_MIX_VAL                  GENMASK(4, 0)
-+
-+#define PPE_RSS_HASH_FIN_ADDR                 0xb4350
-+#define PPE_RSS_HASH_FIN_ENTRIES              5
-+#define PPE_RSS_HASH_FIN_INC                  4
-+#define PPE_RSS_HASH_FIN_INNER                        GENMASK(4, 0)
-+#define PPE_RSS_HASH_FIN_OUTER                        GENMASK(9, 5)
-+
-+#define PPE_RSS_HASH_MASK_IPV4_ADDR           0xb4380
-+#define PPE_RSS_HASH_MASK_IPV4_HASH_MASK      GENMASK(20, 0)
-+#define PPE_RSS_HASH_MASK_IPV4_FRAGMENT               BIT(28)
-+
-+#define PPE_RSS_HASH_SEED_IPV4_ADDR           0xb4384
-+#define PPE_RSS_HASH_SEED_IPV4_VAL            GENMASK(31, 0)
-+
-+#define PPE_RSS_HASH_MIX_IPV4_ADDR            0xb4390
-+#define PPE_RSS_HASH_MIX_IPV4_ENTRIES         5
-+#define PPE_RSS_HASH_MIX_IPV4_INC             4
-+#define PPE_RSS_HASH_MIX_IPV4_VAL             GENMASK(4, 0)
-+
-+#define PPE_RSS_HASH_FIN_IPV4_ADDR            0xb43b0
-+#define PPE_RSS_HASH_FIN_IPV4_ENTRIES         5
-+#define PPE_RSS_HASH_FIN_IPV4_INC             4
-+#define PPE_RSS_HASH_FIN_IPV4_INNER           GENMASK(4, 0)
-+#define PPE_RSS_HASH_FIN_IPV4_OUTER           GENMASK(9, 5)
-+
- #define PPE_BM_SCH_CFG_TBL_ADDR                       0xc000
- #define PPE_BM_SCH_CFG_TBL_ENTRIES            128
- #define PPE_BM_SCH_CFG_TBL_INC                        0x10
diff --git a/target/linux/qualcommbe/patches-6.12/0333-net-ethernet-qualcomm-Initialize-PPE-queue-to-Ethern.patch b/target/linux/qualcommbe/patches-6.12/0333-net-ethernet-qualcomm-Initialize-PPE-queue-to-Ethern.patch
deleted file mode 100644 (file)
index e05748f..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-From c4a321bc120fabc318df165a7fcdeddfcf052253 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:45 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE queue to Ethernet DMA
- ring mapping
-
-Configure the selected queues to map with an Ethernet DMA ring for the
-packet to receive on ARM cores.
-
-As default initialization, all queues assigned to CPU port 0 are mapped
-to the EDMA ring 0. This configuration is later updated during Ethernet
-DMA initialization.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 47 ++++++++++++++++++-
- .../net/ethernet/qualcomm/ppe/ppe_config.h    |  6 +++
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  |  5 ++
- 3 files changed, 57 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -1328,6 +1328,28 @@ int ppe_rss_hash_config_set(struct ppe_d
-       return 0;
- }
-+/**
-+ * ppe_ring_queue_map_set - Set the PPE queue to Ethernet DMA ring mapping
-+ * @ppe_dev: PPE device
-+ * @ring_id: Ethernet DMA ring ID
-+ * @queue_map: Bit map of queue IDs to given Ethernet DMA ring
-+ *
-+ * Configure the mapping from a set of PPE queues to a given Ethernet DMA ring.
-+ *
-+ * Return: 0 on success, negative error code on failure.
-+ */
-+int ppe_ring_queue_map_set(struct ppe_device *ppe_dev, int ring_id, u32 *queue_map)
-+{
-+      u32 reg, queue_bitmap_val[PPE_RING_TO_QUEUE_BITMAP_WORD_CNT];
-+
-+      memcpy(queue_bitmap_val, queue_map, sizeof(queue_bitmap_val));
-+      reg = PPE_RING_Q_MAP_TBL_ADDR + PPE_RING_Q_MAP_TBL_INC * ring_id;
-+
-+      return regmap_bulk_write(ppe_dev->regmap, reg,
-+                               queue_bitmap_val,
-+                               ARRAY_SIZE(queue_bitmap_val));
-+}
-+
- static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
-                                  const struct ppe_bm_port_config port_cfg)
- {
-@@ -1847,6 +1869,25 @@ static int ppe_rss_hash_init(struct ppe_
-       return ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV6, hash_cfg);
- }
-+/* Initialize mapping between PPE queues assigned to CPU port 0
-+ * to Ethernet DMA ring 0.
-+ */
-+static int ppe_queues_to_ring_init(struct ppe_device *ppe_dev)
-+{
-+      u32 queue_bmap[PPE_RING_TO_QUEUE_BITMAP_WORD_CNT] = {};
-+      int ret, queue_id, queue_max;
-+
-+      ret = ppe_port_resource_get(ppe_dev, 0, PPE_RES_UCAST,
-+                                  &queue_id, &queue_max);
-+      if (ret)
-+              return ret;
-+
-+      for (; queue_id <= queue_max; queue_id++)
-+              queue_bmap[queue_id / 32] |= BIT_MASK(queue_id % 32);
-+
-+      return ppe_ring_queue_map_set(ppe_dev, 0, queue_bmap);
-+}
-+
- int ppe_hw_config(struct ppe_device *ppe_dev)
- {
-       int ret;
-@@ -1875,5 +1916,9 @@ int ppe_hw_config(struct ppe_device *ppe
-       if (ret)
-               return ret;
--      return ppe_rss_hash_init(ppe_dev);
-+      ret = ppe_rss_hash_init(ppe_dev);
-+      if (ret)
-+              return ret;
-+
-+      return ppe_queues_to_ring_init(ppe_dev);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-@@ -29,6 +29,9 @@
- #define PPE_RSS_HASH_IP_LENGTH                        4
- #define PPE_RSS_HASH_TUPLES                   5
-+/* PPE supports 300 queues, each bit presents as one queue. */
-+#define PPE_RING_TO_QUEUE_BITMAP_WORD_CNT     10
-+
- /**
-  * enum ppe_scheduler_frame_mode - PPE scheduler frame mode.
-  * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG,
-@@ -308,4 +311,7 @@ int ppe_sc_config_set(struct ppe_device
- int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port);
- int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
-                           struct ppe_rss_hash_cfg hash_cfg);
-+int ppe_ring_queue_map_set(struct ppe_device *ppe_dev,
-+                         int ring_id,
-+                         u32 *queue_map);
- #endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -207,6 +207,11 @@
- #define PPE_L0_COMP_CFG_TBL_SHAPER_METER_LEN  GENMASK(1, 0)
- #define PPE_L0_COMP_CFG_TBL_NODE_METER_LEN    GENMASK(3, 2)
-+/* PPE queue to Ethernet DMA ring mapping table. */
-+#define PPE_RING_Q_MAP_TBL_ADDR                       0x42a000
-+#define PPE_RING_Q_MAP_TBL_ENTRIES            24
-+#define PPE_RING_Q_MAP_TBL_INC                        0x40
-+
- /* Table addresses for per-queue dequeue setting. */
- #define PPE_DEQ_OPR_TBL_ADDR                  0x430000
- #define PPE_DEQ_OPR_TBL_ENTRIES                       300
diff --git a/target/linux/qualcommbe/patches-6.12/0334-net-ethernet-qualcomm-Initialize-PPE-L2-bridge-setti.patch b/target/linux/qualcommbe/patches-6.12/0334-net-ethernet-qualcomm-Initialize-PPE-L2-bridge-setti.patch
deleted file mode 100644 (file)
index 28a4816..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-From cf7282d1e5712953516fa1cc0ffaae405491b3ca Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:46 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE L2 bridge settings
-
-Initialize the L2 bridge settings for the PPE ports to only enable
-L2 frame forwarding between CPU port and PPE Ethernet ports.
-
-The per-port L2 bridge settings are initialized as follows:
-For PPE CPU port, the PPE bridge TX is enabled and FDB learning is
-disabled. For PPE physical ports, the default L2 forwarding action
-is initialized to forward to CPU port only.
-
-L2/FDB learning and forwarding will not be enabled for PPE physical
-ports yet, since the port's VSI (Virtual Switch Instance) and VSI
-membership are not yet configured, which are required for FDB
-forwarding. The VSI and FDB forwarding will later be enabled when
-switchdev is enabled.
-
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 80 ++++++++++++++++++-
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  | 50 ++++++++++++
- 2 files changed, 129 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -1888,6 +1888,80 @@ static int ppe_queues_to_ring_init(struc
-       return ppe_ring_queue_map_set(ppe_dev, 0, queue_bmap);
- }
-+/* Initialize PPE bridge settings to only enable L2 frame receive and
-+ * transmit between CPU port and PPE Ethernet ports.
-+ */
-+static int ppe_bridge_init(struct ppe_device *ppe_dev)
-+{
-+      u32 reg, mask, port_cfg[4], vsi_cfg[2];
-+      int ret, i;
-+
-+      /* Configure the following settings for CPU port0:
-+       * a.) Enable Bridge TX
-+       * b.) Disable FDB new address learning
-+       * c.) Disable station move address learning
-+       */
-+      mask = PPE_PORT_BRIDGE_TXMAC_EN;
-+      mask |= PPE_PORT_BRIDGE_NEW_LRN_EN;
-+      mask |= PPE_PORT_BRIDGE_STA_MOVE_LRN_EN;
-+      ret = regmap_update_bits(ppe_dev->regmap,
-+                               PPE_PORT_BRIDGE_CTRL_ADDR,
-+                               mask,
-+                               PPE_PORT_BRIDGE_TXMAC_EN);
-+      if (ret)
-+              return ret;
-+
-+      for (i = 1; i < ppe_dev->num_ports; i++) {
-+              /* Enable invalid VSI forwarding for all the physical ports
-+               * to CPU port0, in case no VSI is assigned to the physical
-+               * port.
-+               */
-+              reg = PPE_L2_VP_PORT_TBL_ADDR + PPE_L2_VP_PORT_TBL_INC * i;
-+              ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                                     port_cfg, ARRAY_SIZE(port_cfg));
-+
-+              if (ret)
-+                      return ret;
-+
-+              PPE_L2_PORT_SET_INVALID_VSI_FWD_EN(port_cfg, true);
-+              PPE_L2_PORT_SET_DST_INFO(port_cfg, 0);
-+
-+              ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                                      port_cfg, ARRAY_SIZE(port_cfg));
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      for (i = 0; i < PPE_VSI_TBL_ENTRIES; i++) {
-+              /* Set the VSI forward membership to include only CPU port0.
-+               * FDB learning and forwarding take place only after switchdev
-+               * is supported later to create the VSI and join the physical
-+               * ports to the VSI port member.
-+               */
-+              reg = PPE_VSI_TBL_ADDR + PPE_VSI_TBL_INC * i;
-+              ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                                     vsi_cfg, ARRAY_SIZE(vsi_cfg));
-+              if (ret)
-+                      return ret;
-+
-+              PPE_VSI_SET_MEMBER_PORT_BITMAP(vsi_cfg, BIT(0));
-+              PPE_VSI_SET_UUC_BITMAP(vsi_cfg, BIT(0));
-+              PPE_VSI_SET_UMC_BITMAP(vsi_cfg, BIT(0));
-+              PPE_VSI_SET_BC_BITMAP(vsi_cfg, BIT(0));
-+              PPE_VSI_SET_NEW_ADDR_LRN_EN(vsi_cfg, true);
-+              PPE_VSI_SET_NEW_ADDR_FWD_CMD(vsi_cfg, PPE_ACTION_FORWARD);
-+              PPE_VSI_SET_STATION_MOVE_LRN_EN(vsi_cfg, true);
-+              PPE_VSI_SET_STATION_MOVE_FWD_CMD(vsi_cfg, PPE_ACTION_FORWARD);
-+
-+              ret = regmap_bulk_write(ppe_dev->regmap, reg,
-+                                      vsi_cfg, ARRAY_SIZE(vsi_cfg));
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
- int ppe_hw_config(struct ppe_device *ppe_dev)
- {
-       int ret;
-@@ -1920,5 +1994,9 @@ int ppe_hw_config(struct ppe_device *ppe
-       if (ret)
-               return ret;
--      return ppe_queues_to_ring_init(ppe_dev);
-+      ret = ppe_queues_to_ring_init(ppe_dev);
-+      if (ret)
-+              return ret;
-+
-+      return ppe_bridge_init(ppe_dev);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -117,6 +117,14 @@
- #define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value)  \
-       u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN)
-+/* PPE port bridge configuration */
-+#define PPE_PORT_BRIDGE_CTRL_ADDR             0x60300
-+#define PPE_PORT_BRIDGE_CTRL_ENTRIES          8
-+#define PPE_PORT_BRIDGE_CTRL_INC              4
-+#define PPE_PORT_BRIDGE_NEW_LRN_EN            BIT(0)
-+#define PPE_PORT_BRIDGE_STA_MOVE_LRN_EN               BIT(3)
-+#define PPE_PORT_BRIDGE_TXMAC_EN              BIT(16)
-+
- /* PPE port control configurations for the traffic to the multicast queues. */
- #define PPE_MC_MTU_CTRL_TBL_ADDR              0x60a00
- #define PPE_MC_MTU_CTRL_TBL_ENTRIES           8
-@@ -125,6 +133,36 @@
- #define PPE_MC_MTU_CTRL_TBL_MTU_CMD           GENMASK(15, 14)
- #define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN         BIT(16)
-+/* PPE VSI configurations */
-+#define PPE_VSI_TBL_ADDR                      0x63800
-+#define PPE_VSI_TBL_ENTRIES                   64
-+#define PPE_VSI_TBL_INC                               0x10
-+#define PPE_VSI_W0_MEMBER_PORT_BITMAP         GENMASK(7, 0)
-+#define PPE_VSI_W0_UUC_BITMAP                 GENMASK(15, 8)
-+#define PPE_VSI_W0_UMC_BITMAP                 GENMASK(23, 16)
-+#define PPE_VSI_W0_BC_BITMAP                  GENMASK(31, 24)
-+#define PPE_VSI_W1_NEW_ADDR_LRN_EN            BIT(0)
-+#define PPE_VSI_W1_NEW_ADDR_FWD_CMD           GENMASK(2, 1)
-+#define PPE_VSI_W1_STATION_MOVE_LRN_EN                BIT(3)
-+#define PPE_VSI_W1_STATION_MOVE_FWD_CMD               GENMASK(5, 4)
-+
-+#define PPE_VSI_SET_MEMBER_PORT_BITMAP(tbl_cfg, value)                \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_MEMBER_PORT_BITMAP)
-+#define PPE_VSI_SET_UUC_BITMAP(tbl_cfg, value)                        \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_UUC_BITMAP)
-+#define PPE_VSI_SET_UMC_BITMAP(tbl_cfg, value)                        \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_UMC_BITMAP)
-+#define PPE_VSI_SET_BC_BITMAP(tbl_cfg, value)                 \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_BC_BITMAP)
-+#define PPE_VSI_SET_NEW_ADDR_LRN_EN(tbl_cfg, value)           \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_NEW_ADDR_LRN_EN)
-+#define PPE_VSI_SET_NEW_ADDR_FWD_CMD(tbl_cfg, value)          \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_NEW_ADDR_FWD_CMD)
-+#define PPE_VSI_SET_STATION_MOVE_LRN_EN(tbl_cfg, value)               \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_STATION_MOVE_LRN_EN)
-+#define PPE_VSI_SET_STATION_MOVE_FWD_CMD(tbl_cfg, value)      \
-+      u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_STATION_MOVE_FWD_CMD)
-+
- /* PPE port control configurations for the traffic to the unicast queues. */
- #define PPE_MRU_MTU_CTRL_TBL_ADDR             0x65000
- #define PPE_MRU_MTU_CTRL_TBL_ENTRIES          256
-@@ -163,6 +201,18 @@
- #define PPE_IN_L2_SERVICE_TBL_RX_CNT_EN               BIT(30)
- #define PPE_IN_L2_SERVICE_TBL_TX_CNT_EN               BIT(31)
-+/* L2 Port configurations */
-+#define PPE_L2_VP_PORT_TBL_ADDR                       0x98000
-+#define PPE_L2_VP_PORT_TBL_ENTRIES            256
-+#define PPE_L2_VP_PORT_TBL_INC                        0x10
-+#define PPE_L2_VP_PORT_W0_INVALID_VSI_FWD_EN  BIT(0)
-+#define PPE_L2_VP_PORT_W0_DST_INFO            GENMASK(9, 2)
-+
-+#define PPE_L2_PORT_SET_INVALID_VSI_FWD_EN(tbl_cfg, value)    \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_INVALID_VSI_FWD_EN)
-+#define PPE_L2_PORT_SET_DST_INFO(tbl_cfg, value)              \
-+      u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_DST_INFO)
-+
- /* PPE service code configuration for the tunnel packet. */
- #define PPE_TL_SERVICE_TBL_ADDR                       0x306000
- #define PPE_TL_SERVICE_TBL_ENTRIES            256
diff --git a/target/linux/qualcommbe/patches-6.12/0335-net-ethernet-qualcomm-Add-PPE-debugfs-support-for-PP.patch b/target/linux/qualcommbe/patches-6.12/0335-net-ethernet-qualcomm-Add-PPE-debugfs-support-for-PP.patch
deleted file mode 100644 (file)
index e748bca..0000000
+++ /dev/null
@@ -1,950 +0,0 @@
-From fc25088f79cccb934d69e563221068589565926f Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:47 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Add PPE debugfs support for PPE
- counters
-
-The PPE hardware counters maintain counters for packets handled by
-the various functional blocks of PPE. They help in tracing the packets
-passed through PPE and debugging any packet drops.
-
-The counters displayed by this debugfs file are ones that are common
-for all Ethernet ports, and they do not include the counters that are
-specific for a MAC port. Hence they cannot be displayed using ethtool.
-The per-MAC counters will be supported using "ethtool -S" along with
-the netdevice driver.
-
-The PPE hardware packet counters are made available through
-the debugfs entry "/sys/kernel/debug/ppe/packet_counters".
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- drivers/net/ethernet/qualcomm/ppe/Makefile    |   2 +-
- drivers/net/ethernet/qualcomm/ppe/ppe.c       |  11 +
- drivers/net/ethernet/qualcomm/ppe/ppe.h       |   3 +
- .../net/ethernet/qualcomm/ppe/ppe_debugfs.c   | 692 ++++++++++++++++++
- .../net/ethernet/qualcomm/ppe/ppe_debugfs.h   |  16 +
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h  | 102 +++
- 6 files changed, 825 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h
-
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -4,4 +4,4 @@
- #
- obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
--qcom-ppe-objs := ppe.o ppe_config.o
-+qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o
---- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
-@@ -16,6 +16,7 @@
- #include "ppe.h"
- #include "ppe_config.h"
-+#include "ppe_debugfs.h"
- #define PPE_PORT_MAX          8
- #define PPE_CLK_RATE          353000000
-@@ -199,11 +200,20 @@ static int qcom_ppe_probe(struct platfor
-       if (ret)
-               return dev_err_probe(dev, ret, "PPE HW config failed\n");
-+      ppe_debugfs_setup(ppe_dev);
-       platform_set_drvdata(pdev, ppe_dev);
-       return 0;
- }
-+static void qcom_ppe_remove(struct platform_device *pdev)
-+{
-+      struct ppe_device *ppe_dev;
-+
-+      ppe_dev = platform_get_drvdata(pdev);
-+      ppe_debugfs_teardown(ppe_dev);
-+}
-+
- static const struct of_device_id qcom_ppe_of_match[] = {
-       { .compatible = "qcom,ipq9574-ppe" },
-       {}
-@@ -216,6 +226,7 @@ static struct platform_driver qcom_ppe_d
-               .of_match_table = qcom_ppe_of_match,
-       },
-       .probe  = qcom_ppe_probe,
-+      .remove = qcom_ppe_remove,
- };
- module_platform_driver(qcom_ppe_driver);
---- a/drivers/net/ethernet/qualcomm/ppe/ppe.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h
-@@ -11,6 +11,7 @@
- struct device;
- struct regmap;
-+struct dentry;
- /**
-  * struct ppe_device - PPE device private data.
-@@ -18,6 +19,7 @@ struct regmap;
-  * @regmap: PPE register map.
-  * @clk_rate: PPE clock rate.
-  * @num_ports: Number of PPE ports.
-+ * @debugfs_root: Debugfs root entry.
-  * @num_icc_paths: Number of interconnect paths.
-  * @icc_paths: Interconnect path array.
-  *
-@@ -30,6 +32,7 @@ struct ppe_device {
-       struct regmap *regmap;
-       unsigned long clk_rate;
-       unsigned int num_ports;
-+      struct dentry *debugfs_root;
-       unsigned int num_icc_paths;
-       struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths);
- };
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
-@@ -0,0 +1,692 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* PPE debugfs routines for display of PPE counters useful for debug. */
-+
-+#include <linux/bitfield.h>
-+#include <linux/debugfs.h>
-+#include <linux/regmap.h>
-+#include <linux/seq_file.h>
-+
-+#include "ppe.h"
-+#include "ppe_config.h"
-+#include "ppe_debugfs.h"
-+#include "ppe_regs.h"
-+
-+#define PPE_PKT_CNT_TBL_SIZE                          3
-+#define PPE_DROP_PKT_CNT_TBL_SIZE                     5
-+
-+#define PPE_W0_PKT_CNT                                        GENMASK(31, 0)
-+#define PPE_W2_DROP_PKT_CNT_LOW                               GENMASK(31, 8)
-+#define PPE_W3_DROP_PKT_CNT_HIGH                      GENMASK(7, 0)
-+
-+#define PPE_GET_PKT_CNT(tbl_cnt)                      \
-+      u32_get_bits(*((u32 *)(tbl_cnt)), PPE_W0_PKT_CNT)
-+#define PPE_GET_DROP_PKT_CNT_LOW(tbl_cnt)             \
-+      u32_get_bits(*((u32 *)(tbl_cnt) + 0x2), PPE_W2_DROP_PKT_CNT_LOW)
-+#define PPE_GET_DROP_PKT_CNT_HIGH(tbl_cnt)            \
-+      u32_get_bits(*((u32 *)(tbl_cnt) + 0x3), PPE_W3_DROP_PKT_CNT_HIGH)
-+
-+#define PRINT_COUNTER_PREFIX(desc, cnt_type)          \
-+      seq_printf(seq, "%-16s %16s", desc, cnt_type)
-+
-+#define PRINT_CPU_CODE_COUNTER(cnt, code)             \
-+      seq_printf(seq, "%10u(cpucode:%d)", cnt, code)
-+
-+#define PRINT_DROP_CODE_COUNTER(cnt, port, code)      \
-+      seq_printf(seq, "%10u(port=%d),dropcode:%d", cnt, port, code)
-+
-+#define PRINT_SINGLE_COUNTER(tag, cnt, str, index)                    \
-+do {                                                                  \
-+      if (!((tag) % 4))                                                       \
-+              seq_printf(seq, "\n%-16s %16s", "", "");                \
-+      seq_printf(seq, "%10u(%s=%04d)", cnt, str, index);              \
-+} while (0)
-+
-+#define PRINT_TWO_COUNTERS(tag, cnt0, cnt1, str, index)                       \
-+do {                                                                  \
-+      if (!((tag) % 4))                                                       \
-+              seq_printf(seq, "\n%-16s %16s", "", "");                \
-+      seq_printf(seq, "%10u/%u(%s=%04d)", cnt0, cnt1, str, index);    \
-+} while (0)
-+
-+/**
-+ * enum ppe_cnt_size_type - PPE counter size type
-+ * @PPE_PKT_CNT_SIZE_1WORD: Counter size with single register
-+ * @PPE_PKT_CNT_SIZE_3WORD: Counter size with table of 3 words
-+ * @PPE_PKT_CNT_SIZE_5WORD: Counter size with table of 5 words
-+ *
-+ * PPE takes the different register size to record the packet counters.
-+ * It uses single register, or register table with 3 words or 5 words.
-+ * The counter with table size 5 words also records the drop counter.
-+ * There are also some other counter types occupying sizes less than 32
-+ * bits, which is not covered by this enumeration type.
-+ */
-+enum ppe_cnt_size_type {
-+      PPE_PKT_CNT_SIZE_1WORD,
-+      PPE_PKT_CNT_SIZE_3WORD,
-+      PPE_PKT_CNT_SIZE_5WORD,
-+};
-+
-+static int ppe_pkt_cnt_get(struct ppe_device *ppe_dev, u32 reg,
-+                         enum ppe_cnt_size_type cnt_type,
-+                         u32 *cnt, u32 *drop_cnt)
-+{
-+      u32 drop_pkt_cnt[PPE_DROP_PKT_CNT_TBL_SIZE];
-+      u32 pkt_cnt[PPE_PKT_CNT_TBL_SIZE];
-+      u32 value;
-+      int ret;
-+
-+      switch (cnt_type) {
-+      case PPE_PKT_CNT_SIZE_1WORD:
-+              ret = regmap_read(ppe_dev->regmap, reg, &value);
-+              if (ret)
-+                      return ret;
-+
-+              *cnt = value;
-+              break;
-+      case PPE_PKT_CNT_SIZE_3WORD:
-+              ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                                     pkt_cnt, ARRAY_SIZE(pkt_cnt));
-+              if (ret)
-+                      return ret;
-+
-+              *cnt = PPE_GET_PKT_CNT(pkt_cnt);
-+              break;
-+      case PPE_PKT_CNT_SIZE_5WORD:
-+              ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                                     drop_pkt_cnt, ARRAY_SIZE(drop_pkt_cnt));
-+              if (ret)
-+                      return ret;
-+
-+              *cnt = PPE_GET_PKT_CNT(drop_pkt_cnt);
-+
-+              /* Drop counter with low 24 bits. */
-+              value  = PPE_GET_DROP_PKT_CNT_LOW(drop_pkt_cnt);
-+              *drop_cnt = FIELD_PREP(GENMASK(23, 0), value);
-+
-+              /* Drop counter with high 8 bits. */
-+              value  = PPE_GET_DROP_PKT_CNT_HIGH(drop_pkt_cnt);
-+              *drop_cnt |= FIELD_PREP(GENMASK(31, 24), value);
-+              break;
-+      }
-+
-+      return 0;
-+}
-+
-+static void ppe_tbl_pkt_cnt_clear(struct ppe_device *ppe_dev, u32 reg,
-+                                enum ppe_cnt_size_type cnt_type)
-+{
-+      u32 drop_pkt_cnt[PPE_DROP_PKT_CNT_TBL_SIZE] = {};
-+      u32 pkt_cnt[PPE_PKT_CNT_TBL_SIZE] = {};
-+
-+      switch (cnt_type) {
-+      case PPE_PKT_CNT_SIZE_1WORD:
-+              regmap_write(ppe_dev->regmap, reg, 0);
-+              break;
-+      case PPE_PKT_CNT_SIZE_3WORD:
-+              regmap_bulk_write(ppe_dev->regmap, reg,
-+                                pkt_cnt, ARRAY_SIZE(pkt_cnt));
-+              break;
-+      case PPE_PKT_CNT_SIZE_5WORD:
-+              regmap_bulk_write(ppe_dev->regmap, reg,
-+                                drop_pkt_cnt, ARRAY_SIZE(drop_pkt_cnt));
-+              break;
-+      }
-+}
-+
-+/* The number of packets dropped because of no buffer available, no PPE
-+ * buffer assigned to these packets.
-+ */
-+static void ppe_port_rx_drop_counter_get(struct ppe_device *ppe_dev,
-+                                       struct seq_file *seq)
-+{
-+      u32 reg, drop_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("PRX_DROP_CNT", "SILENT_DROP:");
-+      for (i = 0; i < PPE_DROP_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_DROP_CNT_TBL_ADDR + i * PPE_DROP_CNT_TBL_INC;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD,
-+                                    &drop_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (drop_cnt > 0) {
-+                      tag++;
-+                      PRINT_SINGLE_COUNTER(tag, drop_cnt, "port", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets dropped because hardware buffers were available
-+ * only partially for the packet.
-+ */
-+static void ppe_port_rx_bm_drop_counter_get(struct ppe_device *ppe_dev,
-+                                          struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("PRX_BM_DROP_CNT", "OVERFLOW_DROP:");
-+      for (i = 0; i < PPE_DROP_STAT_TBL_ENTRIES; i++) {
-+              reg = PPE_DROP_STAT_TBL_ADDR + PPE_DROP_STAT_TBL_INC * i;
-+
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &pkt_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (pkt_cnt > 0) {
-+                      tag++;
-+                      PRINT_SINGLE_COUNTER(tag, pkt_cnt, "port", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of currently occupied buffers, that can't be flushed. */
-+static void ppe_port_rx_bm_port_counter_get(struct ppe_device *ppe_dev,
-+                                          struct seq_file *seq)
-+{
-+      int used_cnt, react_cnt;
-+      int ret, i, tag = 0;
-+      u32 reg, val;
-+
-+      PRINT_COUNTER_PREFIX("PRX_BM_PORT_CNT", "USED/REACT:");
-+      for (i = 0; i < PPE_BM_USED_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_BM_USED_CNT_TBL_ADDR + i * PPE_BM_USED_CNT_TBL_INC;
-+              ret = regmap_read(ppe_dev->regmap, reg, &val);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              /* The number of PPE buffers used for caching the received
-+               * packets before the pause frame sent.
-+               */
-+              used_cnt = FIELD_GET(PPE_BM_USED_CNT_VAL, val);
-+
-+              reg = PPE_BM_REACT_CNT_TBL_ADDR + i * PPE_BM_REACT_CNT_TBL_INC;
-+              ret = regmap_read(ppe_dev->regmap, reg, &val);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              /* The number of PPE buffers used for caching the received
-+               * packets after pause frame sent out.
-+               */
-+              react_cnt = FIELD_GET(PPE_BM_REACT_CNT_VAL, val);
-+
-+              if (used_cnt > 0 || react_cnt > 0) {
-+                      tag++;
-+                      PRINT_TWO_COUNTERS(tag, used_cnt, react_cnt, "port", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets processed by the ingress parser module of PPE. */
-+static void ppe_parse_pkt_counter_get(struct ppe_device *ppe_dev,
-+                                    struct seq_file *seq)
-+{
-+      u32 reg, cnt = 0, tunnel_cnt = 0;
-+      int i, ret, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("IPR_PKT_CNT", "TPRX/IPRX:");
-+      for (i = 0; i < PPE_IPR_PKT_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_TPR_PKT_CNT_TBL_ADDR + i * PPE_TPR_PKT_CNT_TBL_INC;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD,
-+                                    &tunnel_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              reg = PPE_IPR_PKT_CNT_TBL_ADDR + i * PPE_IPR_PKT_CNT_TBL_INC;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD,
-+                                    &cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (tunnel_cnt > 0 || cnt > 0) {
-+                      tag++;
-+                      PRINT_TWO_COUNTERS(tag, tunnel_cnt, cnt, "port", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets received or dropped on the ingress direction. */
-+static void ppe_port_rx_counter_get(struct ppe_device *ppe_dev,
-+                                  struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0, drop_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("PORT_RX_CNT", "RX/RX_DROP:");
-+      for (i = 0; i < PPE_PHY_PORT_RX_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_PHY_PORT_RX_CNT_TBL_ADDR + PPE_PHY_PORT_RX_CNT_TBL_INC * i;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD,
-+                                    &pkt_cnt, &drop_cnt);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (pkt_cnt > 0) {
-+                      tag++;
-+                      PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "port", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets received or dropped by the port. */
-+static void ppe_vp_rx_counter_get(struct ppe_device *ppe_dev,
-+                                struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0, drop_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("VPORT_RX_CNT", "RX/RX_DROP:");
-+      for (i = 0; i < PPE_PORT_RX_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_PORT_RX_CNT_TBL_ADDR + PPE_PORT_RX_CNT_TBL_INC * i;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD,
-+                                    &pkt_cnt, &drop_cnt);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (pkt_cnt > 0) {
-+                      tag++;
-+                      PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "port", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets received or dropped by layer 2 processing. */
-+static void ppe_pre_l2_counter_get(struct ppe_device *ppe_dev,
-+                                 struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0, drop_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("PRE_L2_CNT", "RX/RX_DROP:");
-+      for (i = 0; i < PPE_PRE_L2_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_PRE_L2_CNT_TBL_ADDR + PPE_PRE_L2_CNT_TBL_INC * i;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD,
-+                                    &pkt_cnt, &drop_cnt);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (pkt_cnt > 0) {
-+                      tag++;
-+                      PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "vsi", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of VLAN packets received by PPE. */
-+static void ppe_vlan_counter_get(struct ppe_device *ppe_dev,
-+                               struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("VLAN_CNT", "RX:");
-+      for (i = 0; i < PPE_VLAN_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_VLAN_CNT_TBL_ADDR + PPE_VLAN_CNT_TBL_INC * i;
-+
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &pkt_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (pkt_cnt > 0) {
-+                      tag++;
-+                      PRINT_SINGLE_COUNTER(tag, pkt_cnt, "vsi", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets handed to CPU by PPE. */
-+static void ppe_cpu_code_counter_get(struct ppe_device *ppe_dev,
-+                                   struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0;
-+      int ret, i;
-+
-+      PRINT_COUNTER_PREFIX("CPU_CODE_CNT", "CODE:");
-+      for (i = 0; i < PPE_DROP_CPU_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_DROP_CPU_CNT_TBL_ADDR + PPE_DROP_CPU_CNT_TBL_INC * i;
-+
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &pkt_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (!pkt_cnt)
-+                      continue;
-+
-+              /* There are 256 CPU codes saved in the first 256 entries
-+               * of register table, and 128 drop codes for each PPE port
-+               * (0-7), the total entries is 256 + 8 * 128.
-+               */
-+              if (i < 256)
-+                      PRINT_CPU_CODE_COUNTER(pkt_cnt, i);
-+              else
-+                      PRINT_DROP_CODE_COUNTER(pkt_cnt, (i - 256) % 8,
-+                                              (i - 256) / 8);
-+              seq_putc(seq, '\n');
-+              PRINT_COUNTER_PREFIX("", "");
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets forwarded by VLAN on the egress direction. */
-+static void ppe_eg_vsi_counter_get(struct ppe_device *ppe_dev,
-+                                 struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("EG_VSI_CNT", "TX:");
-+      for (i = 0; i < PPE_EG_VSI_COUNTER_TBL_ENTRIES; i++) {
-+              reg = PPE_EG_VSI_COUNTER_TBL_ADDR + PPE_EG_VSI_COUNTER_TBL_INC * i;
-+
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &pkt_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (pkt_cnt > 0) {
-+                      tag++;
-+                      PRINT_SINGLE_COUNTER(tag, pkt_cnt, "vsi", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets trasmitted or dropped by port. */
-+static void ppe_vp_tx_counter_get(struct ppe_device *ppe_dev,
-+                                struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0, drop_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("VPORT_TX_CNT", "TX/TX_DROP:");
-+      for (i = 0; i < PPE_VPORT_TX_COUNTER_TBL_ENTRIES; i++) {
-+              reg = PPE_VPORT_TX_COUNTER_TBL_ADDR + PPE_VPORT_TX_COUNTER_TBL_INC * i;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &pkt_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              reg = PPE_VPORT_TX_DROP_CNT_TBL_ADDR + PPE_VPORT_TX_DROP_CNT_TBL_INC * i;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &drop_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (pkt_cnt > 0 || drop_cnt > 0) {
-+                      tag++;
-+                      PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "port", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets trasmitted or dropped on the egress direction. */
-+static void ppe_port_tx_counter_get(struct ppe_device *ppe_dev,
-+                                  struct seq_file *seq)
-+{
-+      u32 reg, pkt_cnt = 0, drop_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("PORT_TX_CNT", "TX/TX_DROP:");
-+      for (i = 0; i < PPE_PORT_TX_COUNTER_TBL_ENTRIES; i++) {
-+              reg = PPE_PORT_TX_COUNTER_TBL_ADDR + PPE_PORT_TX_COUNTER_TBL_INC * i;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &pkt_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              reg = PPE_PORT_TX_DROP_CNT_TBL_ADDR + PPE_PORT_TX_DROP_CNT_TBL_INC * i;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &drop_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (pkt_cnt > 0 || drop_cnt > 0) {
-+                      tag++;
-+                      PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "port", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* The number of packets transmitted or pending by the PPE queue. */
-+static void ppe_queue_tx_counter_get(struct ppe_device *ppe_dev,
-+                                   struct seq_file *seq)
-+{
-+      u32 reg, val, pkt_cnt = 0, pend_cnt = 0;
-+      int ret, i, tag = 0;
-+
-+      PRINT_COUNTER_PREFIX("QUEUE_TX_CNT", "TX/PEND:");
-+      for (i = 0; i < PPE_QUEUE_TX_COUNTER_TBL_ENTRIES; i++) {
-+              reg = PPE_QUEUE_TX_COUNTER_TBL_ADDR + PPE_QUEUE_TX_COUNTER_TBL_INC * i;
-+              ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
-+                                    &pkt_cnt, NULL);
-+              if (ret) {
-+                      seq_printf(seq, "ERROR %d\n", ret);
-+                      return;
-+              }
-+
-+              if (i < PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES) {
-+                      reg = PPE_AC_UNICAST_QUEUE_CNT_TBL_ADDR +
-+                            PPE_AC_UNICAST_QUEUE_CNT_TBL_INC * i;
-+                      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+                      if (ret) {
-+                              seq_printf(seq, "ERROR %d\n", ret);
-+                              return;
-+                      }
-+
-+                      pend_cnt = FIELD_GET(PPE_AC_UNICAST_QUEUE_CNT_TBL_PEND_CNT, val);
-+              } else {
-+                      reg = PPE_AC_MULTICAST_QUEUE_CNT_TBL_ADDR +
-+                            PPE_AC_MULTICAST_QUEUE_CNT_TBL_INC *
-+                            (i - PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES);
-+                      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+                      if (ret) {
-+                              seq_printf(seq, "ERROR %d\n", ret);
-+                              return;
-+                      }
-+
-+                      pend_cnt = FIELD_GET(PPE_AC_MULTICAST_QUEUE_CNT_TBL_PEND_CNT, val);
-+              }
-+
-+              if (pkt_cnt > 0 || pend_cnt > 0) {
-+                      tag++;
-+                      PRINT_TWO_COUNTERS(tag, pkt_cnt, pend_cnt, "queue", i);
-+              }
-+      }
-+
-+      seq_putc(seq, '\n');
-+}
-+
-+/* Display the various packet counters of PPE. */
-+static int ppe_packet_counter_show(struct seq_file *seq, void *v)
-+{
-+      struct ppe_device *ppe_dev = seq->private;
-+
-+      ppe_port_rx_drop_counter_get(ppe_dev, seq);
-+      ppe_port_rx_bm_drop_counter_get(ppe_dev, seq);
-+      ppe_port_rx_bm_port_counter_get(ppe_dev, seq);
-+      ppe_parse_pkt_counter_get(ppe_dev, seq);
-+      ppe_port_rx_counter_get(ppe_dev, seq);
-+      ppe_vp_rx_counter_get(ppe_dev, seq);
-+      ppe_pre_l2_counter_get(ppe_dev, seq);
-+      ppe_vlan_counter_get(ppe_dev, seq);
-+      ppe_cpu_code_counter_get(ppe_dev, seq);
-+      ppe_eg_vsi_counter_get(ppe_dev, seq);
-+      ppe_vp_tx_counter_get(ppe_dev, seq);
-+      ppe_port_tx_counter_get(ppe_dev, seq);
-+      ppe_queue_tx_counter_get(ppe_dev, seq);
-+
-+      return 0;
-+}
-+
-+static int ppe_packet_counter_open(struct inode *inode, struct file *file)
-+{
-+      return single_open(file, ppe_packet_counter_show, inode->i_private);
-+}
-+
-+static ssize_t ppe_packet_counter_clear(struct file *file,
-+                                      const char __user *buf,
-+                                      size_t count, loff_t *pos)
-+{
-+      struct ppe_device *ppe_dev = file_inode(file)->i_private;
-+      u32 reg;
-+      int i;
-+
-+      for (i = 0; i < PPE_DROP_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_DROP_CNT_TBL_ADDR + i * PPE_DROP_CNT_TBL_INC;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD);
-+      }
-+
-+      for (i = 0; i < PPE_DROP_STAT_TBL_ENTRIES; i++) {
-+              reg = PPE_DROP_STAT_TBL_ADDR + PPE_DROP_STAT_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+      }
-+
-+      for (i = 0; i < PPE_IPR_PKT_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_IPR_PKT_CNT_TBL_ADDR + i * PPE_IPR_PKT_CNT_TBL_INC;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD);
-+
-+              reg = PPE_TPR_PKT_CNT_TBL_ADDR + i * PPE_TPR_PKT_CNT_TBL_INC;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD);
-+      }
-+
-+      for (i = 0; i < PPE_VLAN_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_VLAN_CNT_TBL_ADDR + PPE_VLAN_CNT_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+      }
-+
-+      for (i = 0; i < PPE_PRE_L2_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_PRE_L2_CNT_TBL_ADDR + PPE_PRE_L2_CNT_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD);
-+      }
-+
-+      for (i = 0; i < PPE_PORT_TX_COUNTER_TBL_ENTRIES; i++) {
-+              reg = PPE_PORT_TX_DROP_CNT_TBL_ADDR + PPE_PORT_TX_DROP_CNT_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+
-+              reg = PPE_PORT_TX_COUNTER_TBL_ADDR + PPE_PORT_TX_COUNTER_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+      }
-+
-+      for (i = 0; i < PPE_EG_VSI_COUNTER_TBL_ENTRIES; i++) {
-+              reg = PPE_EG_VSI_COUNTER_TBL_ADDR + PPE_EG_VSI_COUNTER_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+      }
-+
-+      for (i = 0; i < PPE_VPORT_TX_COUNTER_TBL_ENTRIES; i++) {
-+              reg = PPE_VPORT_TX_COUNTER_TBL_ADDR + PPE_VPORT_TX_COUNTER_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+
-+              reg = PPE_VPORT_TX_DROP_CNT_TBL_ADDR + PPE_VPORT_TX_DROP_CNT_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+      }
-+
-+      for (i = 0; i < PPE_QUEUE_TX_COUNTER_TBL_ENTRIES; i++) {
-+              reg = PPE_QUEUE_TX_COUNTER_TBL_ADDR + PPE_QUEUE_TX_COUNTER_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+      }
-+
-+      ppe_tbl_pkt_cnt_clear(ppe_dev, PPE_EPE_DBG_IN_CNT_ADDR, PPE_PKT_CNT_SIZE_1WORD);
-+      ppe_tbl_pkt_cnt_clear(ppe_dev, PPE_EPE_DBG_OUT_CNT_ADDR, PPE_PKT_CNT_SIZE_1WORD);
-+
-+      for (i = 0; i < PPE_DROP_CPU_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_DROP_CPU_CNT_TBL_ADDR + PPE_DROP_CPU_CNT_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
-+      }
-+
-+      for (i = 0; i < PPE_PORT_RX_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_PORT_RX_CNT_TBL_ADDR + PPE_PORT_RX_CNT_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD);
-+      }
-+
-+      for (i = 0; i < PPE_PHY_PORT_RX_CNT_TBL_ENTRIES; i++) {
-+              reg = PPE_PHY_PORT_RX_CNT_TBL_ADDR + PPE_PHY_PORT_RX_CNT_TBL_INC * i;
-+              ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD);
-+      }
-+
-+      return count;
-+}
-+
-+static const struct file_operations ppe_debugfs_packet_counter_fops = {
-+      .owner   = THIS_MODULE,
-+      .open    = ppe_packet_counter_open,
-+      .read    = seq_read,
-+      .llseek  = seq_lseek,
-+      .release = single_release,
-+      .write   = ppe_packet_counter_clear,
-+};
-+
-+void ppe_debugfs_setup(struct ppe_device *ppe_dev)
-+{
-+      ppe_dev->debugfs_root = debugfs_create_dir("ppe", NULL);
-+      debugfs_create_file("packet_counters", 0444,
-+                          ppe_dev->debugfs_root,
-+                          ppe_dev,
-+                          &ppe_debugfs_packet_counter_fops);
-+}
-+
-+void ppe_debugfs_teardown(struct ppe_device *ppe_dev)
-+{
-+      debugfs_remove_recursive(ppe_dev->debugfs_root);
-+      ppe_dev->debugfs_root = NULL;
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h
-@@ -0,0 +1,16 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ *
-+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* PPE debugfs counters setup. */
-+
-+#ifndef __PPE_DEBUGFS_H__
-+#define __PPE_DEBUGFS_H__
-+
-+#include "ppe.h"
-+
-+void ppe_debugfs_setup(struct ppe_device *ppe_dev);
-+void ppe_debugfs_teardown(struct ppe_device *ppe_dev);
-+
-+#endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -16,6 +16,39 @@
- #define PPE_BM_SCH_CTRL_SCH_OFFSET            GENMASK(14, 8)
- #define PPE_BM_SCH_CTRL_SCH_EN                        BIT(31)
-+/* PPE drop counters. */
-+#define PPE_DROP_CNT_TBL_ADDR                 0xb024
-+#define PPE_DROP_CNT_TBL_ENTRIES              8
-+#define PPE_DROP_CNT_TBL_INC                  4
-+
-+/* BM port drop counters. */
-+#define PPE_DROP_STAT_TBL_ADDR                        0xe000
-+#define PPE_DROP_STAT_TBL_ENTRIES             30
-+#define PPE_DROP_STAT_TBL_INC                 0x10
-+
-+#define PPE_EPE_DBG_IN_CNT_ADDR                       0x26054
-+#define PPE_EPE_DBG_OUT_CNT_ADDR              0x26070
-+
-+/* Egress VLAN counters. */
-+#define PPE_EG_VSI_COUNTER_TBL_ADDR           0x41000
-+#define PPE_EG_VSI_COUNTER_TBL_ENTRIES                64
-+#define PPE_EG_VSI_COUNTER_TBL_INC            0x10
-+
-+/* Port TX counters. */
-+#define PPE_PORT_TX_COUNTER_TBL_ADDR          0x45000
-+#define PPE_PORT_TX_COUNTER_TBL_ENTRIES               8
-+#define PPE_PORT_TX_COUNTER_TBL_INC           0x10
-+
-+/* Virtual port TX counters. */
-+#define PPE_VPORT_TX_COUNTER_TBL_ADDR         0x47000
-+#define PPE_VPORT_TX_COUNTER_TBL_ENTRIES      256
-+#define PPE_VPORT_TX_COUNTER_TBL_INC          0x10
-+
-+/* Queue counters. */
-+#define PPE_QUEUE_TX_COUNTER_TBL_ADDR         0x4a000
-+#define PPE_QUEUE_TX_COUNTER_TBL_ENTRIES      300
-+#define PPE_QUEUE_TX_COUNTER_TBL_INC          0x10
-+
- /* RSS settings are to calculate the random RSS hash value generated during
-  * packet receive to ARM cores. This hash is then used to generate the queue
-  * offset used to determine the queue used to transmit the packet to ARM cores.
-@@ -213,6 +246,51 @@
- #define PPE_L2_PORT_SET_DST_INFO(tbl_cfg, value)              \
-       u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_DST_INFO)
-+/* Port RX and RX drop counters. */
-+#define PPE_PORT_RX_CNT_TBL_ADDR              0x150000
-+#define PPE_PORT_RX_CNT_TBL_ENTRIES           256
-+#define PPE_PORT_RX_CNT_TBL_INC                       0x20
-+
-+/* Physical port RX and RX drop counters. */
-+#define PPE_PHY_PORT_RX_CNT_TBL_ADDR          0x156000
-+#define PPE_PHY_PORT_RX_CNT_TBL_ENTRIES               8
-+#define PPE_PHY_PORT_RX_CNT_TBL_INC           0x20
-+
-+/* Counters for the packet to CPU port. */
-+#define PPE_DROP_CPU_CNT_TBL_ADDR             0x160000
-+#define PPE_DROP_CPU_CNT_TBL_ENTRIES          1280
-+#define PPE_DROP_CPU_CNT_TBL_INC              0x10
-+
-+/* VLAN counters. */
-+#define PPE_VLAN_CNT_TBL_ADDR                 0x178000
-+#define PPE_VLAN_CNT_TBL_ENTRIES              64
-+#define PPE_VLAN_CNT_TBL_INC                  0x10
-+
-+/* PPE L2 counters. */
-+#define PPE_PRE_L2_CNT_TBL_ADDR                       0x17c000
-+#define PPE_PRE_L2_CNT_TBL_ENTRIES            64
-+#define PPE_PRE_L2_CNT_TBL_INC                        0x20
-+
-+/* Port TX drop counters. */
-+#define PPE_PORT_TX_DROP_CNT_TBL_ADDR         0x17d000
-+#define PPE_PORT_TX_DROP_CNT_TBL_ENTRIES      8
-+#define PPE_PORT_TX_DROP_CNT_TBL_INC          0x10
-+
-+/* Virtual port TX counters. */
-+#define PPE_VPORT_TX_DROP_CNT_TBL_ADDR                0x17e000
-+#define PPE_VPORT_TX_DROP_CNT_TBL_ENTRIES     256
-+#define PPE_VPORT_TX_DROP_CNT_TBL_INC         0x10
-+
-+/* Counters for the tunnel packet. */
-+#define PPE_TPR_PKT_CNT_TBL_ADDR              0x1d0080
-+#define PPE_TPR_PKT_CNT_TBL_ENTRIES           8
-+#define PPE_TPR_PKT_CNT_TBL_INC                       4
-+
-+/* Counters for the all packet received. */
-+#define PPE_IPR_PKT_CNT_TBL_ADDR              0x1e0080
-+#define PPE_IPR_PKT_CNT_TBL_ENTRIES           8
-+#define PPE_IPR_PKT_CNT_TBL_INC                       4
-+
- /* PPE service code configuration for the tunnel packet. */
- #define PPE_TL_SERVICE_TBL_ADDR                       0x306000
- #define PPE_TL_SERVICE_TBL_ENTRIES            256
-@@ -325,6 +403,18 @@
- #define PPE_BM_PORT_GROUP_ID_INC              0x4
- #define PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID  GENMASK(1, 0)
-+/* Counters for PPE buffers used for packets cached. */
-+#define PPE_BM_USED_CNT_TBL_ADDR              0x6001c0
-+#define PPE_BM_USED_CNT_TBL_ENTRIES           15
-+#define PPE_BM_USED_CNT_TBL_INC                       0x4
-+#define PPE_BM_USED_CNT_VAL                   GENMASK(10, 0)
-+
-+/* Counters for PPE buffers used for packets received after pause frame sent. */
-+#define PPE_BM_REACT_CNT_TBL_ADDR             0x600240
-+#define PPE_BM_REACT_CNT_TBL_ENTRIES          15
-+#define PPE_BM_REACT_CNT_TBL_INC              0x4
-+#define PPE_BM_REACT_CNT_VAL                  GENMASK(8, 0)
-+
- #define PPE_BM_SHARED_GROUP_CFG_ADDR          0x600290
- #define PPE_BM_SHARED_GROUP_CFG_ENTRIES               4
- #define PPE_BM_SHARED_GROUP_CFG_INC           0x4
-@@ -449,6 +539,18 @@
- #define PPE_AC_GRP_SET_BUF_LIMIT(tbl_cfg, value)      \
-       u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_AC_GRP_W1_BUF_LIMIT)
-+/* Counters for packets handled by unicast queues (0-255). */
-+#define PPE_AC_UNICAST_QUEUE_CNT_TBL_ADDR     0x84e000
-+#define PPE_AC_UNICAST_QUEUE_CNT_TBL_ENTRIES  256
-+#define PPE_AC_UNICAST_QUEUE_CNT_TBL_INC      0x10
-+#define PPE_AC_UNICAST_QUEUE_CNT_TBL_PEND_CNT GENMASK(12, 0)
-+
-+/* Counters for packets handled by multicast queues (256-299). */
-+#define PPE_AC_MULTICAST_QUEUE_CNT_TBL_ADDR   0x852000
-+#define PPE_AC_MULTICAST_QUEUE_CNT_TBL_ENTRIES        44
-+#define PPE_AC_MULTICAST_QUEUE_CNT_TBL_INC    0x10
-+#define PPE_AC_MULTICAST_QUEUE_CNT_TBL_PEND_CNT       GENMASK(12, 0)
-+
- /* Table addresses for per-queue enqueue setting. */
- #define PPE_ENQ_OPR_TBL_ADDR                  0x85c000
- #define PPE_ENQ_OPR_TBL_ENTRIES                       300
diff --git a/target/linux/qualcommbe/patches-6.12/0336-MAINTAINERS-Add-maintainer-for-Qualcomm-PPE-driver.patch b/target/linux/qualcommbe/patches-6.12/0336-MAINTAINERS-Add-maintainer-for-Qualcomm-PPE-driver.patch
deleted file mode 100644 (file)
index 852bf52..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 28098c348414fa97531449d4e27ba1587e67c2d9 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Sun, 9 Feb 2025 22:29:48 +0800
-Subject: [PATCH] MAINTAINERS: Add maintainer for Qualcomm PPE driver
-
-Add maintainer entry for PPE (Packet Process Engine) driver
-supported for Qualcomm IPQ SoCs.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- MAINTAINERS | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19146,6 +19146,14 @@ S:    Maintained
- F:    Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
- F:    drivers/mtd/nand/raw/qcom_nandc.c
-+QUALCOMM PPE DRIVER
-+M:    Luo Jie <quic_luoj@quicinc.com>
-+L:    netdev@vger.kernel.org
-+S:    Supported
-+F:    Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
-+F:    Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
-+F:    drivers/net/ethernet/qualcomm/ppe/
-+
- QUALCOMM QSEECOM DRIVER
- M:    Maximilian Luz <luzmaximilian@gmail.com>
- L:    linux-arm-msm@vger.kernel.org
diff --git a/target/linux/qualcommbe/patches-6.12/0337-net-ethernet-qualcomm-Add-PPE-scheduler-config.patch b/target/linux/qualcommbe/patches-6.12/0337-net-ethernet-qualcomm-Add-PPE-scheduler-config.patch
deleted file mode 100644 (file)
index d6292f8..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-From 93cf3297818ee61607f0a8d1d34e4fb7fcde3cdf Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Tue, 26 Dec 2023 20:18:09 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Add PPE scheduler config
-
-PPE scheduler config determines the priority of scheduling the
-packet. The scheduler config is used for supporting the QoS
-offload in PPE hardware.
-
-Change-Id: I4811bd133074757371775a6a69a1cc3cfaa8d0d0
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: rebase patch on top of PPE driver submission from 20250209.
-        Add the ppe_queue_priority_set() function and its
-        dependencies. They will be used in the edma support in
-        susequent changes.
-        ppe_queue_priority_set() used to be part of ppe_api.c, and
-        is hereby moved to ppe_config.c .
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- .../net/ethernet/qualcomm/ppe/ppe_config.c    | 141 ++++++++++++++++++
- .../net/ethernet/qualcomm/ppe/ppe_config.h    |   5 +
- 2 files changed, 146 insertions(+)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
-@@ -864,6 +864,51 @@ static int ppe_scheduler_l0_queue_map_se
-                                 val);
- }
-+/* Get the first level scheduler configuration. */
-+static int ppe_scheduler_l0_queue_map_get(struct ppe_device *ppe_dev,
-+                                        int node_id, int *port,
-+                                        struct ppe_scheduler_cfg *scheduler_cfg)
-+{
-+      u32 val, reg;
-+      int ret;
-+
-+      reg = PPE_L0_FLOW_MAP_TBL_ADDR + node_id * PPE_L0_FLOW_MAP_TBL_INC;
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret)
-+              return ret;
-+
-+      scheduler_cfg->flow_id = FIELD_GET(PPE_L0_FLOW_MAP_TBL_FLOW_ID, val);
-+      scheduler_cfg->pri = FIELD_GET(PPE_L0_FLOW_MAP_TBL_C_PRI, val);
-+      scheduler_cfg->drr_node_wt = FIELD_GET(PPE_L0_FLOW_MAP_TBL_C_NODE_WT, val);
-+
-+      reg = PPE_L0_C_FLOW_CFG_TBL_ADDR +
-+            (scheduler_cfg->flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg->pri) *
-+            PPE_L0_C_FLOW_CFG_TBL_INC;
-+
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret)
-+              return ret;
-+
-+      scheduler_cfg->drr_node_id = FIELD_GET(PPE_L0_C_FLOW_CFG_TBL_NODE_ID, val);
-+      scheduler_cfg->unit_is_packet = FIELD_GET(PPE_L0_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT, val);
-+
-+      reg = PPE_L0_FLOW_PORT_MAP_TBL_ADDR + node_id * PPE_L0_FLOW_PORT_MAP_TBL_INC;
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret)
-+              return ret;
-+
-+      *port = FIELD_GET(PPE_L0_FLOW_PORT_MAP_TBL_PORT_NUM, val);
-+
-+      reg = PPE_L0_COMP_CFG_TBL_ADDR + node_id * PPE_L0_COMP_CFG_TBL_INC;
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret)
-+              return ret;
-+
-+      scheduler_cfg->frame_mode = FIELD_GET(PPE_L0_COMP_CFG_TBL_NODE_METER_LEN, val);
-+
-+      return 0;
-+}
-+
- /* Set the PPE flow level scheduler configuration. */
- static int ppe_scheduler_l1_queue_map_set(struct ppe_device *ppe_dev,
-                                         int node_id, int port,
-@@ -916,6 +961,50 @@ static int ppe_scheduler_l1_queue_map_se
-       return regmap_update_bits(ppe_dev->regmap, reg, PPE_L1_COMP_CFG_TBL_NODE_METER_LEN, val);
- }
-+/* Get the second level scheduler configuration. */
-+static int ppe_scheduler_l1_queue_map_get(struct ppe_device *ppe_dev,
-+                                        int node_id, int *port,
-+                                        struct ppe_scheduler_cfg *scheduler_cfg)
-+{
-+      u32 val, reg;
-+      int ret;
-+
-+      reg = PPE_L1_FLOW_MAP_TBL_ADDR + node_id * PPE_L1_FLOW_MAP_TBL_INC;
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret)
-+              return ret;
-+
-+      scheduler_cfg->flow_id = FIELD_GET(PPE_L1_FLOW_MAP_TBL_FLOW_ID, val);
-+      scheduler_cfg->pri = FIELD_GET(PPE_L1_FLOW_MAP_TBL_C_PRI, val);
-+      scheduler_cfg->drr_node_wt = FIELD_GET(PPE_L1_FLOW_MAP_TBL_C_NODE_WT, val);
-+
-+      reg = PPE_L1_C_FLOW_CFG_TBL_ADDR +
-+            (scheduler_cfg->flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg->pri) *
-+            PPE_L1_C_FLOW_CFG_TBL_INC;
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret)
-+              return ret;
-+
-+      scheduler_cfg->drr_node_id = FIELD_GET(PPE_L1_C_FLOW_CFG_TBL_NODE_ID, val);
-+      scheduler_cfg->unit_is_packet = FIELD_GET(PPE_L1_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT, val);
-+
-+      reg = PPE_L1_FLOW_PORT_MAP_TBL_ADDR + node_id * PPE_L1_FLOW_PORT_MAP_TBL_INC;
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret)
-+              return ret;
-+
-+      *port = FIELD_GET(PPE_L1_FLOW_PORT_MAP_TBL_PORT_NUM, val);
-+
-+      reg = PPE_L1_COMP_CFG_TBL_ADDR + node_id * PPE_L1_COMP_CFG_TBL_INC;
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret)
-+              return ret;
-+
-+      scheduler_cfg->frame_mode = FIELD_GET(PPE_L1_COMP_CFG_TBL_NODE_METER_LEN, val);
-+
-+      return 0;
-+}
-+
- /**
-  * ppe_queue_scheduler_set - Configure scheduler for PPE hardware queue
-  * @ppe_dev: PPE device
-@@ -942,6 +1031,58 @@ int ppe_queue_scheduler_set(struct ppe_d
- }
- /**
-+ * ppe_queue_scheduler_get - get QoS scheduler of PPE hardware queue
-+ * @ppe_dev: PPE device
-+ * @node_id: PPE node ID
-+ * @flow_level: Flow level scheduler or queue level scheduler
-+ * @port: PPE port ID to get scheduler config
-+ * @scheduler_cfg: QoS scheduler configuration
-+ *
-+ * The hardware QoS function is supported by PPE, the current scheduler
-+ * configuration can be acquired based on the queue ID of PPE port.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+int ppe_queue_scheduler_get(struct ppe_device *ppe_dev,
-+                          int node_id, bool flow_level, int *port,
-+                          struct ppe_scheduler_cfg *scheduler_cfg)
-+{
-+      if (flow_level)
-+              return ppe_scheduler_l1_queue_map_get(ppe_dev, node_id,
-+                                                    port, scheduler_cfg);
-+
-+      return ppe_scheduler_l0_queue_map_get(ppe_dev, node_id,
-+                                            port, scheduler_cfg);
-+}
-+
-+
-+/**
-+ * ppe_queue_priority_set - set scheduler priority of PPE hardware queue
-+ * @ppe_dev: PPE device
-+ * @node_id: PPE hardware node ID, which is either queue ID or flow ID
-+ * @priority: Qos scheduler priority
-+ *
-+ * Configure scheduler priority of PPE hardware queque, the maximum node
-+ * ID supported is PPE_QUEUE_ID_NUM added by PPE_FLOW_ID_NUM, queue ID
-+ * belongs to level 0, flow ID belongs to level 1 in the packet pipeline.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+int ppe_queue_priority_set(struct ppe_device *ppe_dev,
-+                         int node_id, int priority)
-+{
-+      struct ppe_scheduler_cfg sch_cfg;
-+      int ret, port, level = 0;
-+
-+      ret = ppe_queue_scheduler_get(ppe_dev, node_id, level, &port, &sch_cfg);
-+      if (ret)
-+              return ret;
-+
-+      sch_cfg.pri = priority;
-+      return ppe_queue_scheduler_set(ppe_dev, node_id, level, port, sch_cfg);
-+}
-+
-+/**
-  * ppe_queue_ucast_base_set - Set PPE unicast queue base ID and profile ID
-  * @ppe_dev: PPE device
-  * @queue_dst: PPE queue destination configuration
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
-@@ -291,6 +291,11 @@ int ppe_hw_config(struct ppe_device *ppe
- int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
-                           int node_id, bool flow_level, int port,
-                           struct ppe_scheduler_cfg scheduler_cfg);
-+int ppe_queue_scheduler_get(struct ppe_device *ppe_dev,
-+                          int node_id, bool flow_level, int *port,
-+                          struct ppe_scheduler_cfg *scheduler_cfg);
-+int ppe_queue_priority_set(struct ppe_device *ppe_dev,
-+                         int queue_id, int priority);
- int ppe_queue_ucast_base_set(struct ppe_device *ppe_dev,
-                            struct ppe_queue_ucast_dest queue_dst,
-                            int queue_base,
diff --git a/target/linux/qualcommbe/patches-6.12/0338-net-ethernet-qualcomm-Add-phylink-support-for-PPE-MA.patch b/target/linux/qualcommbe/patches-6.12/0338-net-ethernet-qualcomm-Add-phylink-support-for-PPE-MA.patch
deleted file mode 100644 (file)
index 05b18e8..0000000
+++ /dev/null
@@ -1,1040 +0,0 @@
-From dbb3711ab25ea410ad5286b2f39dccd954cda225 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Thu, 29 Feb 2024 16:59:53 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Add phylink support for PPE MAC
- ports
-
-Add MAC initialization and phylink functions for PPE MAC ports.
-
-Change-Id: I39dcba671732392bcfa2e734473fd083989bfbec
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
----
- drivers/net/ethernet/qualcomm/Kconfig        |   3 +
- drivers/net/ethernet/qualcomm/ppe/Makefile   |   2 +-
- drivers/net/ethernet/qualcomm/ppe/ppe.c      |   9 +
- drivers/net/ethernet/qualcomm/ppe/ppe.h      |   2 +
- drivers/net/ethernet/qualcomm/ppe/ppe_port.c | 728 +++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/ppe_port.h |  76 ++
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 124 ++++
- 7 files changed, 943 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_port.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_port.h
-
---- a/drivers/net/ethernet/qualcomm/Kconfig
-+++ b/drivers/net/ethernet/qualcomm/Kconfig
-@@ -66,6 +66,9 @@ config QCOM_PPE
-       depends on HAS_IOMEM && OF
-       depends on COMMON_CLK
-       select REGMAP_MMIO
-+      select PHYLINK
-+      select PCS_QCOM_IPQ_UNIPHY
-+      select SFP
-       help
-         This driver supports the Qualcomm Technologies, Inc. packet
-         process engine (PPE) available with IPQ SoC. The PPE includes
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -4,4 +4,4 @@
- #
- obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
--qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o
-+qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o ppe_port.o
---- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
-@@ -17,6 +17,7 @@
- #include "ppe.h"
- #include "ppe_config.h"
- #include "ppe_debugfs.h"
-+#include "ppe_port.h"
- #define PPE_PORT_MAX          8
- #define PPE_CLK_RATE          353000000
-@@ -200,6 +201,11 @@ static int qcom_ppe_probe(struct platfor
-       if (ret)
-               return dev_err_probe(dev, ret, "PPE HW config failed\n");
-+      ret = ppe_port_mac_init(ppe_dev);
-+      if (ret)
-+              return dev_err_probe(dev, ret,
-+                                   "PPE Port MAC initialization failed\n");
-+
-       ppe_debugfs_setup(ppe_dev);
-       platform_set_drvdata(pdev, ppe_dev);
-@@ -212,6 +218,9 @@ static void qcom_ppe_remove(struct platf
-       ppe_dev = platform_get_drvdata(pdev);
-       ppe_debugfs_teardown(ppe_dev);
-+      ppe_port_mac_deinit(ppe_dev);
-+
-+      platform_set_drvdata(pdev, NULL);
- }
- static const struct of_device_id qcom_ppe_of_match[] = {
---- a/drivers/net/ethernet/qualcomm/ppe/ppe.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h
-@@ -20,6 +20,7 @@ struct dentry;
-  * @clk_rate: PPE clock rate.
-  * @num_ports: Number of PPE ports.
-  * @debugfs_root: Debugfs root entry.
-+ * @ports: PPE MAC ports.
-  * @num_icc_paths: Number of interconnect paths.
-  * @icc_paths: Interconnect path array.
-  *
-@@ -33,6 +34,7 @@ struct ppe_device {
-       unsigned long clk_rate;
-       unsigned int num_ports;
-       struct dentry *debugfs_root;
-+      struct ppe_ports *ports;
-       unsigned int num_icc_paths;
-       struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths);
- };
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-@@ -0,0 +1,728 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* PPE Port MAC initialization and PPE port MAC functions. */
-+
-+#include <linux/clk.h>
-+#include <linux/of_net.h>
-+#include <linux/pcs/pcs-qcom-ipq9574.h>
-+#include <linux/phylink.h>
-+#include <linux/reset.h>
-+#include <linux/regmap.h>
-+#include <linux/rtnetlink.h>
-+
-+#include "ppe.h"
-+#include "ppe_port.h"
-+#include "ppe_regs.h"
-+
-+/* PPE MAC max frame size which including 4bytes FCS */
-+#define PPE_PORT_MAC_MAX_FRAME_SIZE           0x3000
-+
-+/* PPE BM port start for PPE MAC ports */
-+#define PPE_BM_PORT_MAC_START                 7
-+
-+/* PPE port clock and reset name */
-+static const char * const ppe_port_clk_rst_name[] = {
-+      [PPE_PORT_CLK_RST_MAC] = "mac",
-+      [PPE_PORT_CLK_RST_RX] = "rx",
-+      [PPE_PORT_CLK_RST_TX] = "tx",
-+};
-+
-+/* PPE port and MAC reset */
-+static int ppe_port_mac_reset(struct ppe_port *ppe_port)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int ret;
-+
-+      ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_MAC]);
-+      if (ret)
-+              goto error;
-+
-+      ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_RX]);
-+      if (ret)
-+              goto error;
-+
-+      ret = reset_control_assert(ppe_port->rstcs[PPE_PORT_CLK_RST_TX]);
-+      if (ret)
-+              goto error;
-+
-+      /* 150ms delay is required by hardware to reset PPE port and MAC */
-+      msleep(150);
-+
-+      ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_MAC]);
-+      if (ret)
-+              goto error;
-+
-+      ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_RX]);
-+      if (ret)
-+              goto error;
-+
-+      ret = reset_control_deassert(ppe_port->rstcs[PPE_PORT_CLK_RST_TX]);
-+      if (ret)
-+              goto error;
-+
-+      return ret;
-+
-+error:
-+      dev_err(ppe_dev->dev, "%s: port %d reset fail %d\n",
-+              __func__, ppe_port->port_id, ret);
-+      return ret;
-+}
-+
-+/* PPE port MAC configuration for phylink */
-+static void ppe_port_mac_config(struct phylink_config *config,
-+                              unsigned int mode,
-+                              const struct phylink_link_state *state)
-+{
-+      struct ppe_port *ppe_port = container_of(config, struct ppe_port,
-+                                               phylink_config);
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int port = ppe_port->port_id;
-+      enum ppe_mac_type mac_type;
-+      u32 val, mask;
-+      int ret;
-+
-+      switch (state->interface) {
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+      case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10GBASER:
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-+              mac_type = PPE_MAC_TYPE_XGMAC;
-+              break;
-+      case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_PSGMII:
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_1000BASEX:
-+              mac_type = PPE_MAC_TYPE_GMAC;
-+              break;
-+      default:
-+              dev_err(ppe_dev->dev, "%s: Unsupport interface %s\n",
-+                      __func__, phy_modes(state->interface));
-+              return;
-+      }
-+
-+      /* Reset Port MAC for GMAC */
-+      if (mac_type == PPE_MAC_TYPE_GMAC) {
-+              ret = ppe_port_mac_reset(ppe_port);
-+              if (ret)
-+                      goto err_mac_config;
-+      }
-+
-+      /* Port mux to select GMAC or XGMAC */
-+      mask = PPE_PORT_SEL_XGMAC(port);
-+      val = mac_type == PPE_MAC_TYPE_GMAC ? 0 : mask;
-+      ret = regmap_update_bits(ppe_dev->regmap,
-+                               PPE_PORT_MUX_CTRL_ADDR,
-+                               mask, val);
-+      if (ret)
-+              goto err_mac_config;
-+
-+      ppe_port->mac_type = mac_type;
-+
-+      return;
-+
-+err_mac_config:
-+      dev_err(ppe_dev->dev, "%s: port %d MAC config fail %d\n",
-+              __func__, port, ret);
-+}
-+
-+/* PPE port GMAC link up configuration */
-+static int ppe_port_gmac_link_up(struct ppe_port *ppe_port, int speed,
-+                               int duplex, bool tx_pause, bool rx_pause)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int ret, port = ppe_port->port_id;
-+      u32 reg, val;
-+
-+      /* Set GMAC speed */
-+      switch (speed) {
-+      case SPEED_1000:
-+              val = GMAC_SPEED_1000;
-+              break;
-+      case SPEED_100:
-+              val = GMAC_SPEED_100;
-+              break;
-+      case SPEED_10:
-+              val = GMAC_SPEED_10;
-+              break;
-+      default:
-+              dev_err(ppe_dev->dev, "%s: Invalid GMAC speed %s\n",
-+                      __func__, phy_speed_to_str(speed));
-+              return -EINVAL;
-+      }
-+
-+      reg = PPE_PORT_GMAC_ADDR(port);
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_SPEED_ADDR,
-+                               GMAC_SPEED_M, val);
-+      if (ret)
-+              return ret;
-+
-+      /* Set duplex, flow control and enable GMAC */
-+      val = GMAC_TRXEN;
-+      if (duplex == DUPLEX_FULL)
-+              val |= GMAC_DUPLEX_FULL;
-+      if (tx_pause)
-+              val |= GMAC_TXFCEN;
-+      if (rx_pause)
-+              val |= GMAC_RXFCEN;
-+
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_ENABLE_ADDR,
-+                               GMAC_ENABLE_ALL, val);
-+
-+      return ret;
-+}
-+
-+/* PPE port XGMAC link up configuration */
-+static int ppe_port_xgmac_link_up(struct ppe_port *ppe_port,
-+                                phy_interface_t interface,
-+                                int speed, int duplex,
-+                                bool tx_pause, bool rx_pause)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int ret, port = ppe_port->port_id;
-+      u32 reg, val;
-+
-+      /* Set XGMAC TX speed and enable TX */
-+      switch (speed) {
-+      case SPEED_10000:
-+              if (interface == PHY_INTERFACE_MODE_USXGMII)
-+                      val = XGMAC_SPEED_10000_USXGMII;
-+              else
-+                      val = XGMAC_SPEED_10000;
-+              break;
-+      case SPEED_5000:
-+              val = XGMAC_SPEED_5000;
-+              break;
-+      case SPEED_2500:
-+              if (interface == PHY_INTERFACE_MODE_USXGMII ||
-+                  interface == PHY_INTERFACE_MODE_10G_QXGMII)
-+                      val = XGMAC_SPEED_2500_USXGMII;
-+              else
-+                      val = XGMAC_SPEED_2500;
-+              break;
-+      case SPEED_1000:
-+              val = XGMAC_SPEED_1000;
-+              break;
-+      case SPEED_100:
-+              val = XGMAC_SPEED_100;
-+              break;
-+      case SPEED_10:
-+              val = XGMAC_SPEED_10;
-+              break;
-+      default:
-+              dev_err(ppe_dev->dev, "%s: Invalid XGMAC speed %s\n",
-+                      __func__, phy_speed_to_str(speed));
-+              return -EINVAL;
-+      }
-+
-+      reg = PPE_PORT_XGMAC_ADDR(port);
-+      val |= XGMAC_TXEN;
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_TX_CONFIG_ADDR,
-+                               XGMAC_SPEED_M | XGMAC_TXEN, val);
-+      if (ret)
-+              return ret;
-+
-+      /* Set XGMAC TX flow control */
-+      val = FIELD_PREP(XGMAC_PAUSE_TIME_M, FIELD_MAX(XGMAC_PAUSE_TIME_M));
-+      val |= tx_pause ? XGMAC_TXFCEN : 0;
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_TX_FLOW_CTRL_ADDR,
-+                               XGMAC_PAUSE_TIME_M | XGMAC_TXFCEN, val);
-+      if (ret)
-+              return ret;
-+
-+      /* Set XGMAC RX flow control */
-+      val = rx_pause ? XGMAC_RXFCEN : 0;
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_RX_FLOW_CTRL_ADDR,
-+                               XGMAC_RXFCEN, val);
-+      if (ret)
-+              return ret;
-+
-+      /* Enable XGMAC RX*/
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_RX_CONFIG_ADDR,
-+                               XGMAC_RXEN, XGMAC_RXEN);
-+
-+      return ret;
-+}
-+
-+/* PPE port MAC link up configuration for phylink */
-+static void ppe_port_mac_link_up(struct phylink_config *config,
-+                               struct phy_device *phy,
-+                               unsigned int mode,
-+                               phy_interface_t interface,
-+                               int speed, int duplex,
-+                               bool tx_pause, bool rx_pause)
-+{
-+      struct ppe_port *ppe_port = container_of(config, struct ppe_port,
-+                                               phylink_config);
-+      enum ppe_mac_type mac_type = ppe_port->mac_type;
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int ret, port = ppe_port->port_id;
-+      u32 reg, val;
-+
-+      if (mac_type == PPE_MAC_TYPE_GMAC)
-+              ret = ppe_port_gmac_link_up(ppe_port,
-+                                          speed, duplex, tx_pause, rx_pause);
-+      else
-+              ret = ppe_port_xgmac_link_up(ppe_port, interface,
-+                                           speed, duplex, tx_pause, rx_pause);
-+      if (ret)
-+              goto err_port_mac_link_up;
-+
-+      /* Set PPE port BM flow control */
-+      reg = PPE_BM_PORT_FC_MODE_ADDR +
-+              PPE_BM_PORT_FC_MODE_INC * (port + PPE_BM_PORT_MAC_START);
-+      val = tx_pause ? PPE_BM_PORT_FC_MODE_EN : 0;
-+      ret = regmap_update_bits(ppe_dev->regmap, reg,
-+                               PPE_BM_PORT_FC_MODE_EN, val);
-+      if (ret)
-+              goto err_port_mac_link_up;
-+
-+      /* Enable PPE port TX */
-+      reg = PPE_PORT_BRIDGE_CTRL_ADDR + PPE_PORT_BRIDGE_CTRL_INC * port;
-+      ret = regmap_update_bits(ppe_dev->regmap, reg,
-+                               PPE_PORT_BRIDGE_TXMAC_EN,
-+                               PPE_PORT_BRIDGE_TXMAC_EN);
-+      if (ret)
-+              goto err_port_mac_link_up;
-+
-+      return;
-+
-+err_port_mac_link_up:
-+      dev_err(ppe_dev->dev, "%s: port %d link up fail %d\n",
-+              __func__, port, ret);
-+}
-+
-+/* PPE port MAC link down configuration for phylink */
-+static void ppe_port_mac_link_down(struct phylink_config *config,
-+                                 unsigned int mode,
-+                                 phy_interface_t interface)
-+{
-+      struct ppe_port *ppe_port = container_of(config, struct ppe_port,
-+                                               phylink_config);
-+      enum ppe_mac_type mac_type = ppe_port->mac_type;
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int ret, port = ppe_port->port_id;
-+      u32 reg;
-+
-+      /* Disable PPE port TX */
-+      reg = PPE_PORT_BRIDGE_CTRL_ADDR + PPE_PORT_BRIDGE_CTRL_INC * port;
-+      ret = regmap_update_bits(ppe_dev->regmap, reg,
-+                               PPE_PORT_BRIDGE_TXMAC_EN, 0);
-+      if (ret)
-+              goto err_port_mac_link_down;
-+
-+      /* Disable PPE MAC */
-+      if (mac_type == PPE_MAC_TYPE_GMAC) {
-+              reg = PPE_PORT_GMAC_ADDR(port) + GMAC_ENABLE_ADDR;
-+              ret = regmap_update_bits(ppe_dev->regmap, reg, GMAC_TRXEN, 0);
-+              if (ret)
-+                      goto err_port_mac_link_down;
-+      } else {
-+              reg = PPE_PORT_XGMAC_ADDR(port);
-+              ret = regmap_update_bits(ppe_dev->regmap,
-+                                       reg + XGMAC_RX_CONFIG_ADDR,
-+                                       XGMAC_RXEN, 0);
-+              if (ret)
-+                      goto err_port_mac_link_down;
-+
-+              ret = regmap_update_bits(ppe_dev->regmap,
-+                                       reg + XGMAC_TX_CONFIG_ADDR,
-+                                       XGMAC_TXEN, 0);
-+              if (ret)
-+                      goto err_port_mac_link_down;
-+      }
-+
-+      return;
-+
-+err_port_mac_link_down:
-+      dev_err(ppe_dev->dev, "%s: port %d link down fail %d\n",
-+              __func__, port, ret);
-+}
-+
-+/* PPE port MAC PCS selection for phylink */
-+static
-+struct phylink_pcs *ppe_port_mac_select_pcs(struct phylink_config *config,
-+                                          phy_interface_t interface)
-+{
-+      struct ppe_port *ppe_port = container_of(config, struct ppe_port,
-+                                               phylink_config);
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int ret, port = ppe_port->port_id;
-+      u32 val;
-+
-+      /* PPE port5 can connects with PCS0 or PCS1. In PSGMII
-+       * mode, it selects PCS0; otherwise, it selects PCS1.
-+       */
-+      if (port == 5) {
-+              val = interface == PHY_INTERFACE_MODE_PSGMII ?
-+                      0 : PPE_PORT5_SEL_PCS1;
-+              ret = regmap_update_bits(ppe_dev->regmap,
-+                                       PPE_PORT_MUX_CTRL_ADDR,
-+                                       PPE_PORT5_SEL_PCS1, val);
-+              if (ret) {
-+                      dev_err(ppe_dev->dev, "%s: port5 select PCS fail %d\n",
-+                              __func__, ret);
-+                      return NULL;
-+              }
-+      }
-+
-+      return ppe_port->pcs;
-+}
-+
-+static const struct phylink_mac_ops ppe_phylink_ops = {
-+      .mac_config = ppe_port_mac_config,
-+      .mac_link_up = ppe_port_mac_link_up,
-+      .mac_link_down = ppe_port_mac_link_down,
-+      .mac_select_pcs = ppe_port_mac_select_pcs,
-+};
-+
-+/**
-+ * ppe_port_phylink_setup() - Set phylink instance for the given PPE port
-+ * @ppe_port: PPE port
-+ * @netdev: Netdevice
-+ *
-+ * Description: Wrapper function to help setup phylink for the PPE port
-+ * specified by @ppe_port and associated with the net device @netdev.
-+ *
-+ * Return: 0 upon success or a negative error upon failure.
-+ */
-+int ppe_port_phylink_setup(struct ppe_port *ppe_port, struct net_device *netdev)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      struct device_node *pcs_node;
-+      int ret;
-+
-+      /* Create PCS */
-+      pcs_node = of_parse_phandle(ppe_port->np, "pcs-handle", 0);
-+      if (!pcs_node)
-+              return -ENODEV;
-+
-+      ppe_port->pcs = ipq_pcs_get(pcs_node);
-+      of_node_put(pcs_node);
-+      if (IS_ERR(ppe_port->pcs)) {
-+              dev_err(ppe_dev->dev, "%s: port %d failed to create PCS\n",
-+                      __func__, ppe_port->port_id);
-+              return PTR_ERR(ppe_port->pcs);
-+      }
-+
-+      /* Port phylink capability */
-+      ppe_port->phylink_config.dev = &netdev->dev;
-+      ppe_port->phylink_config.type = PHYLINK_NETDEV;
-+      ppe_port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
-+              MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000 |
-+              MAC_2500FD | MAC_5000FD | MAC_10000FD;
-+      __set_bit(PHY_INTERFACE_MODE_QSGMII,
-+                ppe_port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_PSGMII,
-+                ppe_port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_SGMII,
-+                ppe_port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-+                ppe_port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_2500BASEX,
-+                ppe_port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_USXGMII,
-+                ppe_port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_10GBASER,
-+                ppe_port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_10G_QXGMII,
-+                ppe_port->phylink_config.supported_interfaces);
-+
-+      /* Create phylink */
-+      ppe_port->phylink = phylink_create(&ppe_port->phylink_config,
-+                                         of_fwnode_handle(ppe_port->np),
-+                                         ppe_port->interface,
-+                                         &ppe_phylink_ops);
-+      if (IS_ERR(ppe_port->phylink)) {
-+              dev_err(ppe_dev->dev, "%s: port %d failed to create phylink\n",
-+                      __func__, ppe_port->port_id);
-+              ret = PTR_ERR(ppe_port->phylink);
-+              goto err_free_pcs;
-+      }
-+
-+      /* Connect phylink */
-+      ret = phylink_of_phy_connect(ppe_port->phylink, ppe_port->np, 0);
-+      if (ret) {
-+              dev_err(ppe_dev->dev, "%s: port %d failed to connect phylink\n",
-+                      __func__, ppe_port->port_id);
-+              goto err_free_phylink;
-+      }
-+
-+      return 0;
-+
-+err_free_phylink:
-+      phylink_destroy(ppe_port->phylink);
-+      ppe_port->phylink = NULL;
-+err_free_pcs:
-+      ipq_pcs_put(ppe_port->pcs);
-+      ppe_port->pcs = NULL;
-+      return ret;
-+}
-+
-+/**
-+ * ppe_port_phylink_destroy() - Destroy phylink instance for the given PPE port
-+ * @ppe_port: PPE port
-+ *
-+ * Description: Wrapper function to help destroy phylink for the PPE port
-+ * specified by @ppe_port.
-+ */
-+void ppe_port_phylink_destroy(struct ppe_port *ppe_port)
-+{
-+      /* Destroy phylink */
-+      if (ppe_port->phylink) {
-+              rtnl_lock();
-+              phylink_disconnect_phy(ppe_port->phylink);
-+              rtnl_unlock();
-+              phylink_destroy(ppe_port->phylink);
-+              ppe_port->phylink = NULL;
-+      }
-+
-+      /* Destroy PCS */
-+      if (ppe_port->pcs) {
-+              ipq_pcs_put(ppe_port->pcs);
-+              ppe_port->pcs = NULL;
-+      }
-+}
-+
-+/* PPE port clock initialization */
-+static int ppe_port_clock_init(struct ppe_port *ppe_port)
-+{
-+      struct device_node *port_node = ppe_port->np;
-+      struct reset_control *rstc;
-+      struct clk *clk;
-+      int i, j, ret;
-+
-+      for (i = 0; i < PPE_PORT_CLK_RST_MAX; i++) {
-+              /* Get PPE port resets which will be used to reset PPE
-+               * port and MAC.
-+               */
-+              rstc = of_reset_control_get_exclusive(port_node,
-+                                                    ppe_port_clk_rst_name[i]);
-+              if (IS_ERR(rstc)) {
-+                      ret =  PTR_ERR(rstc);
-+                      goto err_rst;
-+              }
-+
-+              clk = of_clk_get_by_name(port_node, ppe_port_clk_rst_name[i]);
-+              if (IS_ERR(clk)) {
-+                      ret = PTR_ERR(clk);
-+                      goto err_clk_get;
-+              }
-+
-+              ret = clk_prepare_enable(clk);
-+              if (ret)
-+                      goto err_clk_en;
-+
-+              ppe_port->clks[i] = clk;
-+              ppe_port->rstcs[i] = rstc;
-+      }
-+
-+      return 0;
-+
-+err_clk_en:
-+      clk_put(clk);
-+err_clk_get:
-+      reset_control_put(rstc);
-+err_rst:
-+      for (j = 0; j < i; j++) {
-+              clk_disable_unprepare(ppe_port->clks[j]);
-+              clk_put(ppe_port->clks[j]);
-+              reset_control_put(ppe_port->rstcs[j]);
-+      }
-+
-+      return ret;
-+}
-+
-+/* PPE port clock deinitialization */
-+static void ppe_port_clock_deinit(struct ppe_port *ppe_port)
-+{
-+      int i;
-+
-+      for (i = 0; i < PPE_PORT_CLK_RST_MAX; i++) {
-+              clk_disable_unprepare(ppe_port->clks[i]);
-+              clk_put(ppe_port->clks[i]);
-+              reset_control_put(ppe_port->rstcs[i]);
-+      }
-+}
-+
-+/* PPE port MAC hardware init configuration */
-+static int ppe_port_mac_hw_init(struct ppe_port *ppe_port)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int ret, port = ppe_port->port_id;
-+      u32 reg, val;
-+
-+      /* GMAC RX and TX are initialized as disabled */
-+      reg = PPE_PORT_GMAC_ADDR(port);
-+      ret = regmap_update_bits(ppe_dev->regmap,
-+                               reg + GMAC_ENABLE_ADDR, GMAC_TRXEN, 0);
-+      if (ret)
-+              return ret;
-+
-+      /* GMAC max frame size configuration */
-+      val = FIELD_PREP(GMAC_JUMBO_SIZE_M, PPE_PORT_MAC_MAX_FRAME_SIZE);
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_JUMBO_SIZE_ADDR,
-+                               GMAC_JUMBO_SIZE_M, val);
-+      if (ret)
-+              return ret;
-+
-+      val = FIELD_PREP(GMAC_MAXFRAME_SIZE_M, PPE_PORT_MAC_MAX_FRAME_SIZE);
-+      val |= FIELD_PREP(GMAC_TX_THD_M, 0x1);
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_CTRL_ADDR,
-+                               GMAC_CTRL_MASK, val);
-+      if (ret)
-+              return ret;
-+
-+      val = FIELD_PREP(GMAC_HIGH_IPG_M, 0xc);
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_DBG_CTRL_ADDR,
-+                               GMAC_HIGH_IPG_M, val);
-+      if (ret)
-+              return ret;
-+
-+      /* Enable and reset GMAC MIB counters and set as read clear
-+       * mode, the GMAC MIB counters will be cleared after reading.
-+       */
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_MIB_CTRL_ADDR,
-+                               GMAC_MIB_CTRL_MASK, GMAC_MIB_CTRL_MASK);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + GMAC_MIB_CTRL_ADDR,
-+                               GMAC_MIB_RST, 0);
-+      if (ret)
-+              return ret;
-+
-+      /* XGMAC RX and TX disabled and max frame size configuration */
-+      reg = PPE_PORT_XGMAC_ADDR(port);
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_TX_CONFIG_ADDR,
-+                               XGMAC_TXEN | XGMAC_JD, XGMAC_JD);
-+      if (ret)
-+              return ret;
-+
-+      val = FIELD_PREP(XGMAC_GPSL_M, PPE_PORT_MAC_MAX_FRAME_SIZE);
-+      val |= XGMAC_GPSLEN;
-+      val |= XGMAC_CST;
-+      val |= XGMAC_ACS;
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_RX_CONFIG_ADDR,
-+                               XGMAC_RX_CONFIG_MASK, val);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_WD_TIMEOUT_ADDR,
-+                               XGMAC_WD_TIMEOUT_MASK, XGMAC_WD_TIMEOUT_VAL);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_PKT_FILTER_ADDR,
-+                               XGMAC_PKT_FILTER_MASK, XGMAC_PKT_FILTER_VAL);
-+      if (ret)
-+              return ret;
-+
-+      /* Enable and reset XGMAC MIB counters */
-+      ret = regmap_update_bits(ppe_dev->regmap, reg + XGMAC_MMC_CTRL_ADDR,
-+                               XGMAC_MCF | XGMAC_CNTRST, XGMAC_CNTRST);
-+
-+      return ret;
-+}
-+
-+/**
-+ * ppe_port_mac_init() - Initialization of PPE ports for the PPE device
-+ * @ppe_dev: PPE device
-+ *
-+ * Description: Initialize the PPE MAC ports on the PPE device specified
-+ * by @ppe_dev.
-+ *
-+ * Return: 0 upon success or a negative error upon failure.
-+ */
-+int ppe_port_mac_init(struct ppe_device *ppe_dev)
-+{
-+      struct device_node *ports_node, *port_node;
-+      int port, num, ret, j, i = 0;
-+      struct ppe_ports *ppe_ports;
-+      phy_interface_t phy_mode;
-+
-+      ports_node = of_get_child_by_name(ppe_dev->dev->of_node,
-+                                        "ethernet-ports");
-+      if (!ports_node) {
-+              dev_err(ppe_dev->dev, "Failed to get ports node\n");
-+              return -ENODEV;
-+      }
-+
-+      num = of_get_available_child_count(ports_node);
-+
-+      ppe_ports = devm_kzalloc(ppe_dev->dev,
-+                               struct_size(ppe_ports, port, num),
-+                               GFP_KERNEL);
-+      if (!ppe_ports) {
-+              ret = -ENOMEM;
-+              goto err_ports_node;
-+      }
-+
-+      ppe_dev->ports = ppe_ports;
-+      ppe_ports->num = num;
-+
-+      for_each_available_child_of_node(ports_node, port_node) {
-+              ret = of_property_read_u32(port_node, "reg", &port);
-+              if (ret) {
-+                      dev_err(ppe_dev->dev, "Failed to get port id\n");
-+                      goto err_port_node;
-+              }
-+
-+              ret = of_get_phy_mode(port_node, &phy_mode);
-+              if (ret) {
-+                      dev_err(ppe_dev->dev, "Failed to get phy mode\n");
-+                      goto err_port_node;
-+              }
-+
-+              ppe_ports->port[i].ppe_dev = ppe_dev;
-+              ppe_ports->port[i].port_id = port;
-+              ppe_ports->port[i].np = port_node;
-+              ppe_ports->port[i].interface = phy_mode;
-+
-+              ret = ppe_port_clock_init(&ppe_ports->port[i]);
-+              if (ret) {
-+                      dev_err(ppe_dev->dev, "Failed to initialize port clocks\n");
-+                      goto err_port_clk;
-+              }
-+
-+              ret = ppe_port_mac_hw_init(&ppe_ports->port[i]);
-+              if (ret) {
-+                      dev_err(ppe_dev->dev, "Failed to initialize MAC hardware\n");
-+                      goto err_port_node;
-+              }
-+
-+              i++;
-+      }
-+
-+      of_node_put(ports_node);
-+      return 0;
-+
-+err_port_clk:
-+      for (j = 0; j < i; j++)
-+              ppe_port_clock_deinit(&ppe_ports->port[j]);
-+err_port_node:
-+      of_node_put(port_node);
-+err_ports_node:
-+      of_node_put(ports_node);
-+      return ret;
-+}
-+
-+/**
-+ * ppe_port_mac_deinit() - Deinitialization of PPE ports for the PPE device
-+ * @ppe_dev: PPE device
-+ *
-+ * Description: Deinitialize the PPE MAC ports on the PPE device specified
-+ * by @ppe_dev.
-+ */
-+void ppe_port_mac_deinit(struct ppe_device *ppe_dev)
-+{
-+      struct ppe_port *ppe_port;
-+      int i;
-+
-+      for (i = 0; i < ppe_dev->ports->num; i++) {
-+              ppe_port = &ppe_dev->ports->port[i];
-+              ppe_port_clock_deinit(ppe_port);
-+      }
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
-@@ -0,0 +1,76 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ *
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __PPE_PORT_H__
-+#define __PPE_PORT_H__
-+
-+#include <linux/phylink.h>
-+
-+/**
-+ * enum ppe_port_clk_rst_type - PPE port clock and reset ID type
-+ * @PPE_PORT_CLK_RST_MAC: The clock and reset ID for port MAC
-+ * @PPE_PORT_CLK_RST_RX: The clock and reset ID for port receive path
-+ * @PPE_PORT_CLK_RST_TX: The clock and reset for port transmit path
-+ * @PPE_PORT_CLK_RST_MAX: The maximum of port clock and reset
-+ */
-+enum ppe_port_clk_rst_type {
-+      PPE_PORT_CLK_RST_MAC,
-+      PPE_PORT_CLK_RST_RX,
-+      PPE_PORT_CLK_RST_TX,
-+      PPE_PORT_CLK_RST_MAX,
-+};
-+
-+/**
-+ * enum ppe_mac_type - PPE MAC type
-+ * @PPE_MAC_TYPE_GMAC: GMAC type
-+ * @PPE_MAC_TYPE_XGMAC: XGMAC type
-+ */
-+enum ppe_mac_type {
-+      PPE_MAC_TYPE_GMAC,
-+      PPE_MAC_TYPE_XGMAC,
-+};
-+
-+/**
-+ * struct ppe_port - Private data for each PPE port
-+ * @phylink: Linux phylink instance
-+ * @phylink_config: Linux phylink configurations
-+ * @pcs: Linux phylink PCS instance
-+ * @np: Port device tree node
-+ * @ppe_dev: Back pointer to PPE device private data
-+ * @interface: Port interface mode
-+ * @mac_type: Port MAC type, GMAC or XGMAC
-+ * @port_id: Port ID
-+ * @clks: Port clocks
-+ * @rstcs: Port resets
-+ */
-+struct ppe_port {
-+      struct phylink *phylink;
-+      struct phylink_config phylink_config;
-+      struct phylink_pcs *pcs;
-+      struct device_node *np;
-+      struct ppe_device *ppe_dev;
-+      phy_interface_t interface;
-+      enum ppe_mac_type mac_type;
-+      int port_id;
-+      struct clk *clks[PPE_PORT_CLK_RST_MAX];
-+      struct reset_control *rstcs[PPE_PORT_CLK_RST_MAX];
-+};
-+
-+/**
-+ * struct ppe_ports - Array of PPE ports
-+ * @num: Number of PPE ports
-+ * @port: Each PPE port private data
-+ */
-+struct ppe_ports {
-+      unsigned int num;
-+      struct ppe_port port[] __counted_by(num);
-+};
-+
-+int ppe_port_mac_init(struct ppe_device *ppe_dev);
-+void ppe_port_mac_deinit(struct ppe_device *ppe_dev);
-+int ppe_port_phylink_setup(struct ppe_port *ppe_port,
-+                         struct net_device *netdev);
-+void ppe_port_phylink_destroy(struct ppe_port *ppe_port);
-+#endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -9,6 +9,17 @@
- #include <linux/bitfield.h>
-+/* PPE port mux select control register */
-+#define PPE_PORT_MUX_CTRL_ADDR                        0x10
-+#define PPE_PORT6_SEL_XGMAC                   BIT(13)
-+#define PPE_PORT5_SEL_XGMAC                   BIT(12)
-+#define PPE_PORT4_SEL_XGMAC                   BIT(11)
-+#define PPE_PORT3_SEL_XGMAC                   BIT(10)
-+#define PPE_PORT2_SEL_XGMAC                   BIT(9)
-+#define PPE_PORT1_SEL_XGMAC                   BIT(8)
-+#define PPE_PORT5_SEL_PCS1                    BIT(4)
-+#define PPE_PORT_SEL_XGMAC(x)                 (BIT(8) << ((x) - 1))
-+
- /* PPE scheduler configurations for buffer manager block. */
- #define PPE_BM_SCH_CTRL_ADDR                  0xb000
- #define PPE_BM_SCH_CTRL_INC                   4
-@@ -556,4 +567,117 @@
- #define PPE_ENQ_OPR_TBL_ENTRIES                       300
- #define PPE_ENQ_OPR_TBL_INC                   0x10
- #define PPE_ENQ_OPR_TBL_ENQ_DISABLE           BIT(0)
-+
-+/* PPE GMAC and XGMAC register base address */
-+#define PPE_PORT_GMAC_ADDR(x)                 (0x001000 + ((x) - 1) * 0x200)
-+#define PPE_PORT_XGMAC_ADDR(x)                        (0x500000 + ((x) - 1) * 0x4000)
-+
-+/* GMAC enable register */
-+#define GMAC_ENABLE_ADDR                      0x0
-+#define GMAC_TXFCEN                           BIT(6)
-+#define GMAC_RXFCEN                           BIT(5)
-+#define GMAC_DUPLEX_FULL                      BIT(4)
-+#define GMAC_TXEN                             BIT(1)
-+#define GMAC_RXEN                             BIT(0)
-+
-+#define GMAC_TRXEN                            \
-+      (GMAC_TXEN | GMAC_RXEN)
-+#define GMAC_ENABLE_ALL                               \
-+      (GMAC_TXFCEN | GMAC_RXFCEN | GMAC_DUPLEX_FULL | GMAC_TXEN | GMAC_RXEN)
-+
-+/* GMAC speed register */
-+#define GMAC_SPEED_ADDR                               0x4
-+#define GMAC_SPEED_M                          GENMASK(1, 0)
-+#define GMAC_SPEED_10                         0
-+#define GMAC_SPEED_100                                1
-+#define GMAC_SPEED_1000                               2
-+
-+/* GMAC control register */
-+#define GMAC_CTRL_ADDR                                0x18
-+#define GMAC_TX_THD_M                         GENMASK(27, 24)
-+#define GMAC_MAXFRAME_SIZE_M                  GENMASK(21, 8)
-+#define GMAC_CRS_SEL                          BIT(6)
-+
-+#define GMAC_CTRL_MASK                                \
-+      (GMAC_TX_THD_M | GMAC_MAXFRAME_SIZE_M | GMAC_CRS_SEL)
-+
-+/* GMAC debug control register */
-+#define GMAC_DBG_CTRL_ADDR                    0x1c
-+#define GMAC_HIGH_IPG_M                               GENMASK(15, 8)
-+
-+/* GMAC jumbo size register */
-+#define GMAC_JUMBO_SIZE_ADDR                  0x30
-+#define GMAC_JUMBO_SIZE_M                     GENMASK(13, 0)
-+
-+/* GMAC MIB control register */
-+#define GMAC_MIB_CTRL_ADDR                    0x34
-+#define GMAC_MIB_RD_CLR                               BIT(2)
-+#define GMAC_MIB_RST                          BIT(1)
-+#define GMAC_MIB_EN                           BIT(0)
-+
-+#define GMAC_MIB_CTRL_MASK                    \
-+      (GMAC_MIB_RD_CLR | GMAC_MIB_RST | GMAC_MIB_EN)
-+
-+/* XGMAC TX configuration register */
-+#define XGMAC_TX_CONFIG_ADDR                  0x0
-+#define XGMAC_SPEED_M                         GENMASK(31, 29)
-+#define XGMAC_SPEED_10000_USXGMII             FIELD_PREP(XGMAC_SPEED_M, 4)
-+#define XGMAC_SPEED_10000                     FIELD_PREP(XGMAC_SPEED_M, 0)
-+#define XGMAC_SPEED_5000                      FIELD_PREP(XGMAC_SPEED_M, 5)
-+#define XGMAC_SPEED_2500_USXGMII              FIELD_PREP(XGMAC_SPEED_M, 6)
-+#define XGMAC_SPEED_2500                      FIELD_PREP(XGMAC_SPEED_M, 2)
-+#define XGMAC_SPEED_1000                      FIELD_PREP(XGMAC_SPEED_M, 3)
-+#define XGMAC_SPEED_100                               XGMAC_SPEED_1000
-+#define XGMAC_SPEED_10                                XGMAC_SPEED_1000
-+#define XGMAC_JD                              BIT(16)
-+#define XGMAC_TXEN                            BIT(0)
-+
-+/* XGMAC RX configuration register */
-+#define XGMAC_RX_CONFIG_ADDR                  0x4
-+#define XGMAC_GPSL_M                          GENMASK(29, 16)
-+#define XGMAC_WD                              BIT(7)
-+#define XGMAC_GPSLEN                          BIT(6)
-+#define XGMAC_CST                             BIT(2)
-+#define XGMAC_ACS                             BIT(1)
-+#define XGMAC_RXEN                            BIT(0)
-+
-+#define XGMAC_RX_CONFIG_MASK                  \
-+      (XGMAC_GPSL_M | XGMAC_WD | XGMAC_GPSLEN | XGMAC_CST | \
-+       XGMAC_ACS | XGMAC_RXEN)
-+
-+/* XGMAC packet filter register */
-+#define XGMAC_PKT_FILTER_ADDR                 0x8
-+#define XGMAC_RA                              BIT(31)
-+#define XGMAC_PCF_M                           GENMASK(7, 6)
-+#define XGMAC_PR                              BIT(0)
-+
-+#define XGMAC_PKT_FILTER_MASK                 \
-+      (XGMAC_RA | XGMAC_PCF_M | XGMAC_PR)
-+#define XGMAC_PKT_FILTER_VAL                  \
-+      (XGMAC_RA | XGMAC_PR | FIELD_PREP(XGMAC_PCF_M, 0x2))
-+
-+/* XGMAC watchdog timeout register */
-+#define XGMAC_WD_TIMEOUT_ADDR                 0xc
-+#define XGMAC_PWE                             BIT(8)
-+#define XGMAC_WTO_M                           GENMASK(3, 0)
-+
-+#define XGMAC_WD_TIMEOUT_MASK                 \
-+      (XGMAC_PWE | XGMAC_WTO_M)
-+#define XGMAC_WD_TIMEOUT_VAL                  \
-+      (XGMAC_PWE | FIELD_PREP(XGMAC_WTO_M, 0xb))
-+
-+/* XGMAC TX flow control register */
-+#define XGMAC_TX_FLOW_CTRL_ADDR                       0x70
-+#define XGMAC_PAUSE_TIME_M                    GENMASK(31, 16)
-+#define XGMAC_TXFCEN                          BIT(1)
-+
-+/* XGMAC RX flow control register */
-+#define XGMAC_RX_FLOW_CTRL_ADDR                       0x90
-+#define XGMAC_RXFCEN                          BIT(0)
-+
-+/* XGMAC management counters control register */
-+#define XGMAC_MMC_CTRL_ADDR                   0x800
-+#define XGMAC_MCF                             BIT(3)
-+#define XGMAC_CNTRST                          BIT(0)
-+
- #endif
diff --git a/target/linux/qualcommbe/patches-6.12/0339-net-ethernet-qualcomm-Add-PPE-port-MAC-MIB-statistic.patch b/target/linux/qualcommbe/patches-6.12/0339-net-ethernet-qualcomm-Add-PPE-port-MAC-MIB-statistic.patch
deleted file mode 100644 (file)
index 1430692..0000000
+++ /dev/null
@@ -1,673 +0,0 @@
-From dbcc0d01241a1353d8e11e764cf7fcd390ae3f1f Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Thu, 29 Feb 2024 20:16:14 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Add PPE port MAC MIB statistics
- functions
-
-Add PPE port MAC MIB statistics functions which are used by netdev
-ops and ethtool. For GMAC, a polling task is scheduled to read the
-MIB counters periodically to avoid 32bit register counter overflow.
-
-Change-Id: Ic20e240061278f77d703f652e1f7d959db8fac37
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
----
- drivers/net/ethernet/qualcomm/ppe/ppe_port.c | 465 +++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/ppe_port.h |  13 +
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h |  91 ++++
- 3 files changed, 569 insertions(+)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-@@ -23,6 +23,122 @@
- /* PPE BM port start for PPE MAC ports */
- #define PPE_BM_PORT_MAC_START                 7
-+/* Poll interval time to poll GMAC MIBs for overflow protection,
-+ * the time should ensure that the 32bit GMAC packet counter
-+ * register would not overflow within this time at line rate
-+ * speed for 64B packet size.
-+ */
-+#define PPE_GMIB_POLL_INTERVAL_MS             120000
-+
-+#define PPE_MAC_MIB_DESC(_s, _o, _n)          \
-+      {                                       \
-+              .size = (_s),                   \
-+              .offset = (_o),                 \
-+              .name = (_n),                   \
-+      }
-+
-+/* PPE MAC MIB description */
-+struct ppe_mac_mib_info {
-+      u32 size;
-+      u32 offset;
-+      const char *name;
-+};
-+
-+/* PPE GMAC MIB statistics type */
-+enum ppe_gmib_stats_type {
-+      gmib_rx_broadcast,
-+      gmib_rx_pause,
-+      gmib_rx_multicast,
-+      gmib_rx_fcserr,
-+      gmib_rx_alignerr,
-+      gmib_rx_runt,
-+      gmib_rx_frag,
-+      gmib_rx_jumbofcserr,
-+      gmib_rx_jumboalignerr,
-+      gmib_rx_pkt64,
-+      gmib_rx_pkt65to127,
-+      gmib_rx_pkt128to255,
-+      gmib_rx_pkt256to511,
-+      gmib_rx_pkt512to1023,
-+      gmib_rx_pkt1024to1518,
-+      gmib_rx_pkt1519tomax,
-+      gmib_rx_toolong,
-+      gmib_rx_bytes_g,
-+      gmib_rx_bytes_b,
-+      gmib_rx_unicast,
-+      gmib_tx_broadcast,
-+      gmib_tx_pause,
-+      gmib_tx_multicast,
-+      gmib_tx_underrun,
-+      gmib_tx_pkt64,
-+      gmib_tx_pkt65to127,
-+      gmib_tx_pkt128to255,
-+      gmib_tx_pkt256to511,
-+      gmib_tx_pkt512to1023,
-+      gmib_tx_pkt1024to1518,
-+      gmib_tx_pkt1519tomax,
-+      gmib_tx_bytes,
-+      gmib_tx_collisions,
-+      gmib_tx_abortcol,
-+      gmib_tx_multicol,
-+      gmib_tx_singlecol,
-+      gmib_tx_excdeffer,
-+      gmib_tx_deffer,
-+      gmib_tx_latecol,
-+      gmib_tx_unicast,
-+};
-+
-+/* PPE XGMAC MIB statistics type */
-+enum ppe_xgmib_stats_type {
-+      xgmib_tx_bytes,
-+      xgmib_tx_frames,
-+      xgmib_tx_broadcast_g,
-+      xgmib_tx_multicast_g,
-+      xgmib_tx_pkt64,
-+      xgmib_tx_pkt65to127,
-+      xgmib_tx_pkt128to255,
-+      xgmib_tx_pkt256to511,
-+      xgmib_tx_pkt512to1023,
-+      xgmib_tx_pkt1024tomax,
-+      xgmib_tx_unicast,
-+      xgmib_tx_multicast,
-+      xgmib_tx_broadcast,
-+      xgmib_tx_underflow_err,
-+      xgmib_tx_bytes_g,
-+      xgmib_tx_frames_g,
-+      xgmib_tx_pause,
-+      xgmib_tx_vlan_g,
-+      xgmib_tx_lpi_usec,
-+      xgmib_tx_lpi_tran,
-+      xgmib_rx_frames,
-+      xgmib_rx_bytes,
-+      xgmib_rx_bytes_g,
-+      xgmib_rx_broadcast_g,
-+      xgmib_rx_multicast_g,
-+      xgmib_rx_crc_err,
-+      xgmib_rx_runt_err,
-+      xgmib_rx_jabber_err,
-+      xgmib_rx_undersize_g,
-+      xgmib_rx_oversize_g,
-+      xgmib_rx_pkt64,
-+      xgmib_rx_pkt65to127,
-+      xgmib_rx_pkt128to255,
-+      xgmib_rx_pkt256to511,
-+      xgmib_rx_pkt512to1023,
-+      xgmib_rx_pkt1024tomax,
-+      xgmib_rx_unicast_g,
-+      xgmib_rx_len_err,
-+      xgmib_rx_outofrange_err,
-+      xgmib_rx_pause,
-+      xgmib_rx_fifo_overflow,
-+      xgmib_rx_vlan,
-+      xgmib_rx_wdog_err,
-+      xgmib_rx_lpi_usec,
-+      xgmib_rx_lpi_tran,
-+      xgmib_rx_drop_frames,
-+      xgmib_rx_drop_bytes,
-+};
-+
- /* PPE port clock and reset name */
- static const char * const ppe_port_clk_rst_name[] = {
-       [PPE_PORT_CLK_RST_MAC] = "port_mac",
-@@ -30,6 +146,322 @@ static const char * const ppe_port_clk_r
-       [PPE_PORT_CLK_RST_TX] = "port_tx",
- };
-+/* PPE GMAC MIB statistics description information */
-+static const struct ppe_mac_mib_info gmib_info[] = {
-+      PPE_MAC_MIB_DESC(4, GMAC_RXBROAD_ADDR, "rx_broadcast"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXPAUSE_ADDR, "rx_pause"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXMULTI_ADDR, "rx_multicast"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXFCSERR_ADDR, "rx_fcserr"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXALIGNERR_ADDR, "rx_alignerr"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXRUNT_ADDR, "rx_runt"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXFRAG_ADDR, "rx_frag"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXJUMBOFCSERR_ADDR, "rx_jumbofcserr"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXJUMBOALIGNERR_ADDR, "rx_jumboalignerr"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXPKT64_ADDR, "rx_pkt64"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXPKT65TO127_ADDR, "rx_pkt65to127"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXPKT128TO255_ADDR, "rx_pkt128to255"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXPKT256TO511_ADDR, "rx_pkt256to511"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXPKT512TO1023_ADDR, "rx_pkt512to1023"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXPKT1024TO1518_ADDR, "rx_pkt1024to1518"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXPKT1519TOX_ADDR, "rx_pkt1519tomax"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXTOOLONG_ADDR, "rx_toolong"),
-+      PPE_MAC_MIB_DESC(8, GMAC_RXBYTE_G_ADDR, "rx_bytes_g"),
-+      PPE_MAC_MIB_DESC(8, GMAC_RXBYTE_B_ADDR, "rx_bytes_b"),
-+      PPE_MAC_MIB_DESC(4, GMAC_RXUNI_ADDR, "rx_unicast"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXBROAD_ADDR, "tx_broadcast"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXPAUSE_ADDR, "tx_pause"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXMULTI_ADDR, "tx_multicast"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXUNDERRUN_ADDR, "tx_underrun"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXPKT64_ADDR, "tx_pkt64"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXPKT65TO127_ADDR, "tx_pkt65to127"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXPKT128TO255_ADDR, "tx_pkt128to255"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXPKT256TO511_ADDR, "tx_pkt256to511"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXPKT512TO1023_ADDR, "tx_pkt512to1023"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXPKT1024TO1518_ADDR, "tx_pkt1024to1518"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXPKT1519TOX_ADDR, "tx_pkt1519tomax"),
-+      PPE_MAC_MIB_DESC(8, GMAC_TXBYTE_ADDR, "tx_bytes"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXCOLLISIONS_ADDR, "tx_collisions"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXABORTCOL_ADDR, "tx_abortcol"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXMULTICOL_ADDR, "tx_multicol"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXSINGLECOL_ADDR, "tx_singlecol"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXEXCESSIVEDEFER_ADDR, "tx_excdeffer"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXDEFER_ADDR, "tx_deffer"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXLATECOL_ADDR, "tx_latecol"),
-+      PPE_MAC_MIB_DESC(4, GMAC_TXUNI_ADDR, "tx_unicast"),
-+};
-+
-+/* PPE XGMAC MIB statistics description information */
-+static const struct ppe_mac_mib_info xgmib_info[] = {
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXBYTE_GB_ADDR, "tx_bytes"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPKT_GB_ADDR, "tx_frames"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXBROAD_G_ADDR, "tx_broadcast_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXMULTI_G_ADDR, "tx_multicast_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPKT64_GB_ADDR, "tx_pkt64"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPKT65TO127_GB_ADDR, "tx_pkt65to127"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPKT128TO255_GB_ADDR, "tx_pkt128to255"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPKT256TO511_GB_ADDR, "tx_pkt256to511"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPKT512TO1023_GB_ADDR, "tx_pkt512to1023"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPKT1024TOMAX_GB_ADDR, "tx_pkt1024tomax"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXUNI_GB_ADDR, "tx_unicast"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXMULTI_GB_ADDR, "tx_multicast"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXBROAD_GB_ADDR, "tx_broadcast"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXUNDERFLOW_ERR_ADDR, "tx_underflow_err"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXBYTE_G_ADDR, "tx_bytes_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPKT_G_ADDR, "tx_frames_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXPAUSE_ADDR, "tx_pause"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_TXVLAN_G_ADDR, "tx_vlan_g"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_TXLPI_USEC_ADDR, "tx_lpi_usec"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_TXLPI_TRAN_ADDR, "tx_lpi_tran"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXPKT_GB_ADDR, "rx_frames"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXBYTE_GB_ADDR, "rx_bytes"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXBYTE_G_ADDR, "rx_bytes_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXBROAD_G_ADDR, "rx_broadcast_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXMULTI_G_ADDR, "rx_multicast_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXCRC_ERR_ADDR, "rx_crc_err"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_RXRUNT_ERR_ADDR, "rx_runt_err"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_RXJABBER_ERR_ADDR, "rx_jabber_err"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_RXUNDERSIZE_G_ADDR, "rx_undersize_g"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_RXOVERSIZE_G_ADDR, "rx_oversize_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXPKT64_GB_ADDR, "rx_pkt64"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXPKT65TO127_GB_ADDR, "rx_pkt65to127"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXPKT128TO255_GB_ADDR, "rx_pkt128to255"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXPKT256TO511_GB_ADDR, "rx_pkt256to511"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXPKT512TO1023_GB_ADDR, "rx_pkt512to1023"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXPKT1024TOMAX_GB_ADDR, "rx_pkt1024tomax"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXUNI_G_ADDR, "rx_unicast_g"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXLEN_ERR_ADDR, "rx_len_err"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXOUTOFRANGE_ADDR, "rx_outofrange_err"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXPAUSE_ADDR, "rx_pause"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXFIFOOVERFLOW_ADDR, "rx_fifo_overflow"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXVLAN_GB_ADDR, "rx_vlan"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_RXWATCHDOG_ERR_ADDR, "rx_wdog_err"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_RXLPI_USEC_ADDR, "rx_lpi_usec"),
-+      PPE_MAC_MIB_DESC(4, XGMAC_RXLPI_TRAN_ADDR, "rx_lpi_tran"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXDISCARD_GB_ADDR, "rx_drop_frames"),
-+      PPE_MAC_MIB_DESC(8, XGMAC_RXDISCARDBYTE_GB_ADDR, "rx_drop_bytes"),
-+};
-+
-+/* Get GMAC MIBs from registers and accumulate to PPE port GMIB stats array */
-+static void ppe_port_gmib_update(struct ppe_port *ppe_port)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      const struct ppe_mac_mib_info *mib;
-+      int port = ppe_port->port_id;
-+      u32 reg, val;
-+      int i, ret;
-+
-+      for (i = 0; i < ARRAY_SIZE(gmib_info); i++) {
-+              mib = &gmib_info[i];
-+              reg = PPE_PORT_GMAC_ADDR(port) + mib->offset;
-+
-+              ret = regmap_read(ppe_dev->regmap, reg, &val);
-+              if (ret) {
-+                      dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
-+                      continue;
-+              }
-+
-+              ppe_port->gmib_stats[i] += val;
-+              if (mib->size == 8) {
-+                      ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
-+                      if (ret) {
-+                              dev_warn(ppe_dev->dev, "%s: %d\n",
-+                                       __func__, ret);
-+                              continue;
-+                      }
-+
-+                      ppe_port->gmib_stats[i] += (u64)val << 32;
-+              }
-+      }
-+}
-+
-+/* Polling task to read GMIB statistics to avoid GMIB 32bit register overflow */
-+static void ppe_port_gmib_stats_poll(struct work_struct *work)
-+{
-+      struct ppe_port *ppe_port = container_of(work, struct ppe_port,
-+                                               gmib_read.work);
-+      spin_lock(&ppe_port->gmib_stats_lock);
-+      ppe_port_gmib_update(ppe_port);
-+      spin_unlock(&ppe_port->gmib_stats_lock);
-+
-+      schedule_delayed_work(&ppe_port->gmib_read,
-+                            msecs_to_jiffies(PPE_GMIB_POLL_INTERVAL_MS));
-+}
-+
-+/* Get the XGMAC MIB counter based on the specific MIB stats type */
-+static u64 ppe_port_xgmib_get(struct ppe_port *ppe_port,
-+                            enum ppe_xgmib_stats_type xgmib_type)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      const struct ppe_mac_mib_info *mib;
-+      int port = ppe_port->port_id;
-+      u32 reg, val;
-+      u64 data = 0;
-+      int ret;
-+
-+      mib = &xgmib_info[xgmib_type];
-+      reg = PPE_PORT_XGMAC_ADDR(port) + mib->offset;
-+
-+      ret = regmap_read(ppe_dev->regmap, reg, &val);
-+      if (ret) {
-+              dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
-+              goto data_return;
-+      }
-+
-+      data = val;
-+      if (mib->size == 8) {
-+              ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
-+              if (ret) {
-+                      dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
-+                      goto data_return;
-+              }
-+
-+              data |= (u64)val << 32;
-+      }
-+
-+data_return:
-+      return data;
-+}
-+
-+/**
-+ * ppe_port_get_sset_count() - Get PPE port statistics string count
-+ * @ppe_port: PPE port
-+ * @sset: string set ID
-+ *
-+ * Description: Get the MAC statistics string count for the PPE port
-+ * specified by @ppe_port.
-+ *
-+ * Return: The count of the statistics string.
-+ */
-+int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset)
-+{
-+      if (sset != ETH_SS_STATS)
-+              return 0;
-+
-+      if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC)
-+              return ARRAY_SIZE(gmib_info);
-+      else
-+              return ARRAY_SIZE(xgmib_info);
-+}
-+
-+/**
-+ * ppe_port_get_strings() - Get PPE port statistics strings
-+ * @ppe_port: PPE port
-+ * @stringset: string set ID
-+ * @data: pointer to statistics strings
-+ *
-+ * Description: Get the MAC statistics stings for the PPE port
-+ * specified by @ppe_port. The strings are stored in the buffer
-+ * indicated by @data which used in the ethtool ops.
-+ */
-+void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data)
-+{
-+      int i;
-+
-+      if (stringset != ETH_SS_STATS)
-+              return;
-+
-+      if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
-+              for (i = 0; i < ARRAY_SIZE(gmib_info); i++)
-+                      strscpy(data + i * ETH_GSTRING_LEN, gmib_info[i].name,
-+                              ETH_GSTRING_LEN);
-+      } else {
-+              for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
-+                      strscpy(data + i * ETH_GSTRING_LEN, xgmib_info[i].name,
-+                              ETH_GSTRING_LEN);
-+      }
-+}
-+
-+/**
-+ * ppe_port_get_ethtool_stats() - Get PPE port ethtool statistics
-+ * @ppe_port: PPE port
-+ * @data: pointer to statistics data
-+ *
-+ * Description: Get the MAC statistics for the PPE port specified
-+ * by @ppe_port. The statistics are stored in the buffer indicated
-+ * by @data which used in the ethtool ops.
-+ */
-+void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data)
-+{
-+      int i;
-+
-+      if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
-+              spin_lock(&ppe_port->gmib_stats_lock);
-+
-+              ppe_port_gmib_update(ppe_port);
-+              for (i = 0; i < ARRAY_SIZE(gmib_info); i++)
-+                      data[i] = ppe_port->gmib_stats[i];
-+
-+              spin_unlock(&ppe_port->gmib_stats_lock);
-+      } else {
-+              for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
-+                      data[i] = ppe_port_xgmib_get(ppe_port, i);
-+      }
-+}
-+
-+/**
-+ * ppe_port_get_stats64() - Get PPE port statistics
-+ * @ppe_port: PPE port
-+ * @s: statistics pointer
-+ *
-+ * Description: Get the MAC statistics for the PPE port specified
-+ * by @ppe_port.
-+ */
-+void ppe_port_get_stats64(struct ppe_port *ppe_port,
-+                        struct rtnl_link_stats64 *s)
-+{
-+      if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
-+              u64 *src = ppe_port->gmib_stats;
-+
-+              spin_lock(&ppe_port->gmib_stats_lock);
-+
-+              ppe_port_gmib_update(ppe_port);
-+
-+              s->rx_packets = src[gmib_rx_unicast] +
-+                      src[gmib_rx_broadcast] + src[gmib_rx_multicast];
-+
-+              s->tx_packets = src[gmib_tx_unicast] +
-+                      src[gmib_tx_broadcast] + src[gmib_tx_multicast];
-+
-+              s->rx_bytes = src[gmib_rx_bytes_g];
-+              s->tx_bytes = src[gmib_tx_bytes];
-+              s->multicast = src[gmib_rx_multicast];
-+
-+              s->rx_crc_errors = src[gmib_rx_fcserr] + src[gmib_rx_frag];
-+              s->rx_frame_errors = src[gmib_rx_alignerr];
-+              s->rx_errors = s->rx_crc_errors + s->rx_frame_errors;
-+              s->rx_dropped = src[gmib_rx_toolong] + s->rx_errors;
-+
-+              s->tx_fifo_errors = src[gmib_tx_underrun];
-+              s->tx_aborted_errors = src[gmib_tx_abortcol];
-+              s->tx_errors = s->tx_fifo_errors + s->tx_aborted_errors;
-+              s->collisions = src[gmib_tx_collisions];
-+
-+              spin_unlock(&ppe_port->gmib_stats_lock);
-+      } else {
-+              s->multicast = ppe_port_xgmib_get(ppe_port, xgmib_rx_multicast_g);
-+
-+              s->rx_packets = s->multicast;
-+              s->rx_packets += ppe_port_xgmib_get(ppe_port, xgmib_rx_unicast_g);
-+              s->rx_packets += ppe_port_xgmib_get(ppe_port, xgmib_rx_broadcast_g);
-+
-+              s->tx_packets = ppe_port_xgmib_get(ppe_port, xgmib_tx_frames);
-+              s->rx_bytes = ppe_port_xgmib_get(ppe_port, xgmib_rx_bytes);
-+              s->tx_bytes = ppe_port_xgmib_get(ppe_port, xgmib_tx_bytes);
-+
-+              s->rx_crc_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_crc_err);
-+              s->rx_fifo_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_fifo_overflow);
-+
-+              s->rx_length_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_len_err);
-+              s->rx_errors = s->rx_crc_errors +
-+                      s->rx_fifo_errors + s->rx_length_errors;
-+              s->rx_dropped = s->rx_errors;
-+
-+              s->tx_fifo_errors = ppe_port_xgmib_get(ppe_port, xgmib_tx_underflow_err);
-+              s->tx_errors = s->tx_packets -
-+                      ppe_port_xgmib_get(ppe_port, xgmib_tx_frames_g);
-+      }
-+}
-+
- /* PPE port and MAC reset */
- static int ppe_port_mac_reset(struct ppe_port *ppe_port)
- {
-@@ -261,6 +693,9 @@ static void ppe_port_mac_link_up(struct
-       int ret, port = ppe_port->port_id;
-       u32 reg, val;
-+      /* Start GMIB statistics polling */
-+      schedule_delayed_work(&ppe_port->gmib_read, 0);
-+
-       if (mac_type == PPE_MAC_TYPE_GMAC)
-               ret = ppe_port_gmac_link_up(ppe_port,
-                                           speed, duplex, tx_pause, rx_pause);
-@@ -306,6 +741,9 @@ static void ppe_port_mac_link_down(struc
-       int ret, port = ppe_port->port_id;
-       u32 reg;
-+      /* Stop GMIB statistics polling */
-+      cancel_delayed_work_sync(&ppe_port->gmib_read);
-+
-       /* Disable PPE port TX */
-       reg = PPE_PORT_BRIDGE_CTRL_ADDR + PPE_PORT_BRIDGE_CTRL_INC * port;
-       ret = regmap_update_bits(ppe_dev->regmap, reg,
-@@ -627,6 +1065,27 @@ static int ppe_port_mac_hw_init(struct p
-       return ret;
- }
-+/* PPE port MAC MIB work task initialization */
-+static int ppe_port_mac_mib_work_init(struct ppe_port *ppe_port)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      u64 *gstats;
-+
-+      gstats = devm_kzalloc(ppe_dev->dev,
-+                            sizeof(*gstats) * ARRAY_SIZE(gmib_info),
-+                            GFP_KERNEL);
-+      if (!gstats)
-+              return -ENOMEM;
-+
-+      ppe_port->gmib_stats = gstats;
-+
-+      spin_lock_init(&ppe_port->gmib_stats_lock);
-+      INIT_DELAYED_WORK(&ppe_port->gmib_read,
-+                        ppe_port_gmib_stats_poll);
-+
-+      return 0;
-+}
-+
- /**
-  * ppe_port_mac_init() - Initialization of PPE ports for the PPE device
-  * @ppe_dev: PPE device
-@@ -693,6 +1152,12 @@ int ppe_port_mac_init(struct ppe_device
-                       goto err_port_node;
-               }
-+              ret = ppe_port_mac_mib_work_init(&ppe_ports->port[i]);
-+              if (ret) {
-+                      dev_err(ppe_dev->dev, "Failed to initialize MAC MIB work\n");
-+                      goto err_port_node;
-+              }
-+
-               i++;
-       }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
-@@ -8,6 +8,8 @@
- #include <linux/phylink.h>
-+struct rtnl_link_stats64;
-+
- /**
-  * enum ppe_port_clk_rst_type - PPE port clock and reset ID type
-  * @PPE_PORT_CLK_RST_MAC: The clock and reset ID for port MAC
-@@ -44,6 +46,9 @@ enum ppe_mac_type {
-  * @port_id: Port ID
-  * @clks: Port clocks
-  * @rstcs: Port resets
-+ * @gmib_read: Delay work task for GMAC MIB statistics polling function
-+ * @gmib_stats: GMAC MIB statistics array
-+ * @gmib_stats_lock: Lock to protect GMAC MIB statistics
-  */
- struct ppe_port {
-       struct phylink *phylink;
-@@ -56,6 +61,9 @@ struct ppe_port {
-       int port_id;
-       struct clk *clks[PPE_PORT_CLK_RST_MAX];
-       struct reset_control *rstcs[PPE_PORT_CLK_RST_MAX];
-+      struct delayed_work gmib_read;
-+      u64 *gmib_stats;
-+      spinlock_t gmib_stats_lock; /* Protects GMIB stats */
- };
- /**
-@@ -73,4 +81,9 @@ void ppe_port_mac_deinit(struct ppe_devi
- int ppe_port_phylink_setup(struct ppe_port *ppe_port,
-                          struct net_device *netdev);
- void ppe_port_phylink_destroy(struct ppe_port *ppe_port);
-+int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset);
-+void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data);
-+void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data);
-+void ppe_port_get_stats64(struct ppe_port *ppe_port,
-+                        struct rtnl_link_stats64 *s);
- #endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -618,6 +618,48 @@
- #define GMAC_MIB_CTRL_MASK                    \
-       (GMAC_MIB_RD_CLR | GMAC_MIB_RST | GMAC_MIB_EN)
-+/* GMAC MIB counter registers */
-+#define GMAC_RXBROAD_ADDR                     0x40
-+#define GMAC_RXPAUSE_ADDR                     0x44
-+#define GMAC_RXMULTI_ADDR                     0x48
-+#define GMAC_RXFCSERR_ADDR                    0x4C
-+#define GMAC_RXALIGNERR_ADDR                  0x50
-+#define GMAC_RXRUNT_ADDR                      0x54
-+#define GMAC_RXFRAG_ADDR                      0x58
-+#define GMAC_RXJUMBOFCSERR_ADDR                       0x5C
-+#define GMAC_RXJUMBOALIGNERR_ADDR             0x60
-+#define GMAC_RXPKT64_ADDR                     0x64
-+#define GMAC_RXPKT65TO127_ADDR                        0x68
-+#define GMAC_RXPKT128TO255_ADDR                       0x6C
-+#define GMAC_RXPKT256TO511_ADDR                       0x70
-+#define GMAC_RXPKT512TO1023_ADDR              0x74
-+#define GMAC_RXPKT1024TO1518_ADDR             0x78
-+#define GMAC_RXPKT1519TOX_ADDR                        0x7C
-+#define GMAC_RXTOOLONG_ADDR                   0x80
-+#define GMAC_RXBYTE_G_ADDR                    0x84
-+#define GMAC_RXBYTE_B_ADDR                    0x8C
-+#define GMAC_RXUNI_ADDR                               0x94
-+#define GMAC_TXBROAD_ADDR                     0xA0
-+#define GMAC_TXPAUSE_ADDR                     0xA4
-+#define GMAC_TXMULTI_ADDR                     0xA8
-+#define GMAC_TXUNDERRUN_ADDR                  0xAC
-+#define GMAC_TXPKT64_ADDR                     0xB0
-+#define GMAC_TXPKT65TO127_ADDR                        0xB4
-+#define GMAC_TXPKT128TO255_ADDR                       0xB8
-+#define GMAC_TXPKT256TO511_ADDR                       0xBC
-+#define GMAC_TXPKT512TO1023_ADDR              0xC0
-+#define GMAC_TXPKT1024TO1518_ADDR             0xC4
-+#define GMAC_TXPKT1519TOX_ADDR                        0xC8
-+#define GMAC_TXBYTE_ADDR                      0xCC
-+#define GMAC_TXCOLLISIONS_ADDR                        0xD4
-+#define GMAC_TXABORTCOL_ADDR                  0xD8
-+#define GMAC_TXMULTICOL_ADDR                  0xDC
-+#define GMAC_TXSINGLECOL_ADDR                 0xE0
-+#define GMAC_TXEXCESSIVEDEFER_ADDR            0xE4
-+#define GMAC_TXDEFER_ADDR                     0xE8
-+#define GMAC_TXLATECOL_ADDR                   0xEC
-+#define GMAC_TXUNI_ADDR                               0xF0
-+
- /* XGMAC TX configuration register */
- #define XGMAC_TX_CONFIG_ADDR                  0x0
- #define XGMAC_SPEED_M                         GENMASK(31, 29)
-@@ -680,4 +722,53 @@
- #define XGMAC_MCF                             BIT(3)
- #define XGMAC_CNTRST                          BIT(0)
-+/* XGMAC MIB counter registers */
-+#define XGMAC_TXBYTE_GB_ADDR                  0x814
-+#define XGMAC_TXPKT_GB_ADDR                   0x81C
-+#define XGMAC_TXBROAD_G_ADDR                  0x824
-+#define XGMAC_TXMULTI_G_ADDR                  0x82C
-+#define XGMAC_TXPKT64_GB_ADDR                 0x834
-+#define XGMAC_TXPKT65TO127_GB_ADDR            0x83C
-+#define XGMAC_TXPKT128TO255_GB_ADDR           0x844
-+#define XGMAC_TXPKT256TO511_GB_ADDR           0x84C
-+#define XGMAC_TXPKT512TO1023_GB_ADDR          0x854
-+#define XGMAC_TXPKT1024TOMAX_GB_ADDR          0x85C
-+#define XGMAC_TXUNI_GB_ADDR                   0x864
-+#define XGMAC_TXMULTI_GB_ADDR                 0x86C
-+#define XGMAC_TXBROAD_GB_ADDR                 0x874
-+#define XGMAC_TXUNDERFLOW_ERR_ADDR            0x87C
-+#define XGMAC_TXBYTE_G_ADDR                   0x884
-+#define XGMAC_TXPKT_G_ADDR                    0x88C
-+#define XGMAC_TXPAUSE_ADDR                    0x894
-+#define XGMAC_TXVLAN_G_ADDR                   0x89C
-+#define XGMAC_TXLPI_USEC_ADDR                 0x8A4
-+#define XGMAC_TXLPI_TRAN_ADDR                 0x8A8
-+#define XGMAC_RXPKT_GB_ADDR                   0x900
-+#define XGMAC_RXBYTE_GB_ADDR                  0x908
-+#define XGMAC_RXBYTE_G_ADDR                   0x910
-+#define XGMAC_RXBROAD_G_ADDR                  0x918
-+#define XGMAC_RXMULTI_G_ADDR                  0x920
-+#define XGMAC_RXCRC_ERR_ADDR                  0x928
-+#define XGMAC_RXRUNT_ERR_ADDR                 0x930
-+#define XGMAC_RXJABBER_ERR_ADDR                       0x934
-+#define XGMAC_RXUNDERSIZE_G_ADDR              0x938
-+#define XGMAC_RXOVERSIZE_G_ADDR                       0x93C
-+#define XGMAC_RXPKT64_GB_ADDR                 0x940
-+#define XGMAC_RXPKT65TO127_GB_ADDR            0x948
-+#define XGMAC_RXPKT128TO255_GB_ADDR           0x950
-+#define XGMAC_RXPKT256TO511_GB_ADDR           0x958
-+#define XGMAC_RXPKT512TO1023_GB_ADDR          0x960
-+#define XGMAC_RXPKT1024TOMAX_GB_ADDR          0x968
-+#define XGMAC_RXUNI_G_ADDR                    0x970
-+#define XGMAC_RXLEN_ERR_ADDR                  0x978
-+#define XGMAC_RXOUTOFRANGE_ADDR                       0x980
-+#define XGMAC_RXPAUSE_ADDR                    0x988
-+#define XGMAC_RXFIFOOVERFLOW_ADDR             0x990
-+#define XGMAC_RXVLAN_GB_ADDR                  0x998
-+#define XGMAC_RXWATCHDOG_ERR_ADDR             0x9A0
-+#define XGMAC_RXLPI_USEC_ADDR                 0x9A4
-+#define XGMAC_RXLPI_TRAN_ADDR                 0x9A8
-+#define XGMAC_RXDISCARD_GB_ADDR                       0x9AC
-+#define XGMAC_RXDISCARDBYTE_GB_ADDR           0x9B4
-+
- #endif
diff --git a/target/linux/qualcommbe/patches-6.12/0340-net-ethernet-qualcomm-Add-PPE-port-MAC-address-and-E.patch b/target/linux/qualcommbe/patches-6.12/0340-net-ethernet-qualcomm-Add-PPE-port-MAC-address-and-E.patch
deleted file mode 100644 (file)
index 856a1ed..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-From 55fbbc8ef90df27a16bca1613a793a578b79a384 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Fri, 1 Mar 2024 13:36:26 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Add PPE port MAC address and EEE
- functions
-
-Add PPE port MAC address set and EEE set API functions which
-will be used by netdev ops and ethtool.
-
-Change-Id: Id2b3b06ae940b3b6f5227d927316329cdf3caeaa
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
-Alex G: use struct ethtool_keee instead of ethtool_eee
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/ethernet/qualcomm/ppe/ppe_port.c | 75 ++++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/ppe_port.h |  3 +
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 29 ++++++++
- 3 files changed, 107 insertions(+)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-@@ -462,6 +462,81 @@ void ppe_port_get_stats64(struct ppe_por
-       }
- }
-+/**
-+ * ppe_port_set_mac_address() - Set PPE port MAC address
-+ * @ppe_port: PPE port
-+ * @addr: MAC address
-+ *
-+ * Description: Set MAC address for the given PPE port.
-+ *
-+ * Return: 0 upon success or a negative error upon failure.
-+ */
-+int ppe_port_set_mac_address(struct ppe_port *ppe_port, const u8 *addr)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int port = ppe_port->port_id;
-+      u32 reg, val;
-+      int ret;
-+
-+      if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
-+              reg = PPE_PORT_GMAC_ADDR(port);
-+              val = (addr[5] << 8) | addr[4];
-+              ret = regmap_write(ppe_dev->regmap, reg + GMAC_GOL_ADDR0_ADDR, val);
-+              if (ret)
-+                      return ret;
-+
-+              val = (addr[0] << 24) | (addr[1] << 16) |
-+                    (addr[2] << 8) | addr[3];
-+              ret = regmap_write(ppe_dev->regmap, reg + GMAC_GOL_ADDR1_ADDR, val);
-+              if (ret)
-+                      return ret;
-+      } else {
-+              reg = PPE_PORT_XGMAC_ADDR(port);
-+              val = (addr[5] << 8) | addr[4] | XGMAC_ADDR_EN;
-+              ret = regmap_write(ppe_dev->regmap, reg + XGMAC_ADDR0_H_ADDR, val);
-+              if (ret)
-+                      return ret;
-+
-+              val = (addr[3] << 24) | (addr[2] << 16) |
-+                    (addr[1] << 8) | addr[0];
-+              ret = regmap_write(ppe_dev->regmap, reg + XGMAC_ADDR0_L_ADDR, val);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ * ppe_port_set_mac_eee() - Set EEE configuration for PPE port MAC
-+ * @ppe_port: PPE port
-+ * @eee: EEE settings
-+ *
-+ * Description: Set port MAC EEE settings for the given PPE port.
-+ *
-+ * Return: 0 upon success or a negative error upon failure.
-+ */
-+int ppe_port_set_mac_eee(struct ppe_port *ppe_port, struct ethtool_keee *eee)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      int port = ppe_port->port_id;
-+      u32 val;
-+      int ret;
-+
-+      ret = regmap_read(ppe_dev->regmap, PPE_LPI_EN_ADDR, &val);
-+      if (ret)
-+              return ret;
-+
-+      if (eee->tx_lpi_enabled)
-+              val |= PPE_LPI_PORT_EN(port);
-+      else
-+              val &= ~PPE_LPI_PORT_EN(port);
-+
-+      ret = regmap_write(ppe_dev->regmap, PPE_LPI_EN_ADDR, val);
-+
-+      return ret;
-+}
-+
- /* PPE port and MAC reset */
- static int ppe_port_mac_reset(struct ppe_port *ppe_port)
- {
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
-@@ -8,6 +8,7 @@
- #include <linux/phylink.h>
-+struct ethtool_keee;
- struct rtnl_link_stats64;
- /**
-@@ -86,4 +87,6 @@ void ppe_port_get_strings(struct ppe_por
- void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data);
- void ppe_port_get_stats64(struct ppe_port *ppe_port,
-                         struct rtnl_link_stats64 *s);
-+int ppe_port_set_mac_address(struct ppe_port *ppe_port, const u8 *addr);
-+int ppe_port_set_mac_eee(struct ppe_port *ppe_port, struct ethtool_keee *eee);
- #endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -20,6 +20,16 @@
- #define PPE_PORT5_SEL_PCS1                    BIT(4)
- #define PPE_PORT_SEL_XGMAC(x)                 (BIT(8) << ((x) - 1))
-+/* PPE port LPI enable register */
-+#define PPE_LPI_EN_ADDR                               0x400
-+#define PPE_LPI_PORT1_EN                      BIT(0)
-+#define PPE_LPI_PORT2_EN                      BIT(1)
-+#define PPE_LPI_PORT3_EN                      BIT(2)
-+#define PPE_LPI_PORT4_EN                      BIT(3)
-+#define PPE_LPI_PORT5_EN                      BIT(4)
-+#define PPE_LPI_PORT6_EN                      BIT(5)
-+#define PPE_LPI_PORT_EN(x)                    (BIT(0) << ((x) - 1))
-+
- /* PPE scheduler configurations for buffer manager block. */
- #define PPE_BM_SCH_CTRL_ADDR                  0xb000
- #define PPE_BM_SCH_CTRL_INC                   4
-@@ -592,6 +602,17 @@
- #define GMAC_SPEED_100                                1
- #define GMAC_SPEED_1000                               2
-+/* GMAC MAC address register */
-+#define GMAC_GOL_ADDR0_ADDR                   0x8
-+#define GMAC_ADDR_BYTE5                               GENMASK(15, 8)
-+#define GMAC_ADDR_BYTE4                               GENMASK(7, 0)
-+
-+#define GMAC_GOL_ADDR1_ADDR                   0xC
-+#define GMAC_ADDR_BYTE0                               GENMASK(31, 24)
-+#define GMAC_ADDR_BYTE1                               GENMASK(23, 16)
-+#define GMAC_ADDR_BYTE2                               GENMASK(15, 8)
-+#define GMAC_ADDR_BYTE3                               GENMASK(7, 0)
-+
- /* GMAC control register */
- #define GMAC_CTRL_ADDR                                0x18
- #define GMAC_TX_THD_M                         GENMASK(27, 24)
-@@ -717,6 +738,14 @@
- #define XGMAC_RX_FLOW_CTRL_ADDR                       0x90
- #define XGMAC_RXFCEN                          BIT(0)
-+/* XGMAC MAC address register */
-+#define XGMAC_ADDR0_H_ADDR                    0x300
-+#define XGMAC_ADDR_EN                         BIT(31)
-+#define XGMAC_ADDRH                           GENMASK(15, 0)
-+
-+#define XGMAC_ADDR0_L_ADDR                    0x304
-+#define XGMAC_ADDRL                           GENMASK(31, 0)
-+
- /* XGMAC management counters control register */
- #define XGMAC_MMC_CTRL_ADDR                   0x800
- #define XGMAC_MCF                             BIT(3)
diff --git a/target/linux/qualcommbe/patches-6.12/0341-net-ethernet-qualcomm-Add-API-to-configure-PPE-port-.patch b/target/linux/qualcommbe/patches-6.12/0341-net-ethernet-qualcomm-Add-API-to-configure-PPE-port-.patch
deleted file mode 100644 (file)
index ae81ddb..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-From 3981aeae5dd43dea94a0ec10f0b2977ebd102560 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Tue, 5 Mar 2024 16:42:56 +0800
-Subject: [PATCH] net: ethernet: qualcomm: Add API to configure PPE port max
- frame size
-
-This function is called when the MTU of an ethernet port is
-configured. It limits the size of packet passed through the
-ethernet port.
-
-Change-Id: I2a4dcd04407156d73770d2becbb7cbc0d56b3754
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- drivers/net/ethernet/qualcomm/ppe/ppe_port.c | 44 ++++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/ppe_port.h |  1 +
- 2 files changed, 45 insertions(+)
-
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-@@ -537,6 +537,50 @@ int ppe_port_set_mac_eee(struct ppe_port
-       return ret;
- }
-+/**
-+ * ppe_port_set_maxframe() - Set port maximum frame size
-+ * @ppe_port: PPE port structure
-+ * @maxframe_size: Maximum frame size supported by PPE port
-+ *
-+ * Description: Set MTU of network interface specified by @ppe_port.
-+ *
-+ * Return: 0 upon success or a negative error upon failure.
-+ */
-+int ppe_port_set_maxframe(struct ppe_port *ppe_port, int maxframe_size)
-+{
-+      struct ppe_device *ppe_dev = ppe_port->ppe_dev;
-+      u32 reg, val, mru_mtu_val[3];
-+      int port = ppe_port->port_id;
-+      int ret;
-+
-+      /* The max frame size should be MTU added by ETH_HLEN in PPE. */
-+      maxframe_size += ETH_HLEN;
-+
-+      /* MAC takes cover the FCS for the calculation of frame size. */
-+      if (maxframe_size > PPE_PORT_MAC_MAX_FRAME_SIZE - ETH_FCS_LEN)
-+              return -EINVAL;
-+
-+      reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * port;
-+      val = FIELD_PREP(PPE_MC_MTU_CTRL_TBL_MTU, maxframe_size);
-+      ret = regmap_update_bits(ppe_dev->regmap, reg,
-+                               PPE_MC_MTU_CTRL_TBL_MTU,
-+                               val);
-+      if (ret)
-+              return ret;
-+
-+      reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * port;
-+      ret = regmap_bulk_read(ppe_dev->regmap, reg,
-+                             mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
-+      if (ret)
-+              return ret;
-+
-+      PPE_MRU_MTU_CTRL_SET_MRU(mru_mtu_val, maxframe_size);
-+      PPE_MRU_MTU_CTRL_SET_MTU(mru_mtu_val, maxframe_size);
-+
-+      return regmap_bulk_write(ppe_dev->regmap, reg,
-+                               mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
-+}
-+
- /* PPE port and MAC reset */
- static int ppe_port_mac_reset(struct ppe_port *ppe_port)
- {
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
-@@ -89,4 +89,5 @@ void ppe_port_get_stats64(struct ppe_por
-                         struct rtnl_link_stats64 *s);
- int ppe_port_set_mac_address(struct ppe_port *ppe_port, const u8 *addr);
- int ppe_port_set_mac_eee(struct ppe_port *ppe_port, struct ethtool_keee *eee);
-+int ppe_port_set_maxframe(struct ppe_port *ppe_port, int maxframe_size);
- #endif
diff --git a/target/linux/qualcommbe/patches-6.12/0342-net-ethernet-qualcomm-Add-EDMA-support-for-QCOM-IPQ9.patch b/target/linux/qualcommbe/patches-6.12/0342-net-ethernet-qualcomm-Add-EDMA-support-for-QCOM-IPQ9.patch
deleted file mode 100644 (file)
index 0160efd..0000000
+++ /dev/null
@@ -1,932 +0,0 @@
-From 00d4f3cb4f5d1e6924151a4551f06b6a82bf0146 Mon Sep 17 00:00:00 2001
-From: Pavithra R <quic_pavir@quicinc.com>
-Date: Wed, 28 Feb 2024 11:25:15 +0530
-Subject: [PATCH] net: ethernet: qualcomm: Add EDMA support for QCOM IPQ9574
- chipset.
-
-Add the infrastructure functions such as Makefile,
-EDMA hardware configuration, clock and IRQ initializations.
-
-Change-Id: I64f65e554e70e9095b0cf3636fec421569ae6895
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
-Co-developed-by: Suruchi Agarwal <quic_suruchia@quicinc.com>
-Signed-off-by: Suruchi Agarwal <quic_suruchia@quicinc.com>
-Alex G: use "ppe_config.h" header instead of "ppe_api.h"
-        add missing definitions and functions from ppe_api:
-        - enum ppe_queue_class_type {}
-        - ppe_edma_queue_offset_config()
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/ethernet/qualcomm/ppe/Makefile   |   3 +
- drivers/net/ethernet/qualcomm/ppe/edma.c     | 480 +++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/edma.h     | 113 +++++
- drivers/net/ethernet/qualcomm/ppe/ppe.c      |  10 +-
- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 253 ++++++++++
- 5 files changed, 858 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma.h
-
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -5,3 +5,6 @@
- obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
- qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o ppe_port.o
-+
-+#EDMA
-+qcom-ppe-objs += edma.o
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.c
-@@ -0,0 +1,480 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+ /* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+  */
-+
-+ /* Qualcomm Ethernet DMA driver setup, HW configuration, clocks and
-+  * interrupt initializations.
-+  */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/netdevice.h>
-+#include <linux/of_irq.h>
-+#include <linux/platform_device.h>
-+#include <linux/printk.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+
-+#include "edma.h"
-+#include "ppe_regs.h"
-+
-+#define EDMA_IRQ_NAME_SIZE            32
-+
-+/* Global EDMA context. */
-+struct edma_context *edma_ctx;
-+
-+/* Priority to multi-queue mapping. */
-+static u8 edma_pri_map[PPE_QUEUE_INTER_PRI_NUM] = {
-+      0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7};
-+
-+enum edma_clk_id {
-+      EDMA_CLK,
-+      EDMA_CFG_CLK,
-+      EDMA_CLK_MAX
-+};
-+
-+static const char * const clock_name[EDMA_CLK_MAX] = {
-+      [EDMA_CLK] = "edma",
-+      [EDMA_CFG_CLK] = "edma-cfg",
-+};
-+
-+/* Rx Fill ring info for IPQ9574. */
-+static struct edma_ring_info ipq9574_rxfill_ring_info = {
-+      .max_rings = 8,
-+      .ring_start = 4,
-+      .num_rings = 4,
-+};
-+
-+/* Rx ring info for IPQ9574. */
-+static struct edma_ring_info ipq9574_rx_ring_info = {
-+      .max_rings = 24,
-+      .ring_start = 20,
-+      .num_rings = 4,
-+};
-+
-+/* Tx ring info for IPQ9574. */
-+static struct edma_ring_info ipq9574_tx_ring_info = {
-+      .max_rings = 32,
-+      .ring_start = 8,
-+      .num_rings = 24,
-+};
-+
-+/* Tx complete ring info for IPQ9574. */
-+static struct edma_ring_info ipq9574_txcmpl_ring_info = {
-+      .max_rings = 32,
-+      .ring_start = 8,
-+      .num_rings = 24,
-+};
-+
-+/* HW info for IPQ9574. */
-+static struct edma_hw_info ipq9574_hw_info = {
-+      .rxfill = &ipq9574_rxfill_ring_info,
-+      .rx = &ipq9574_rx_ring_info,
-+      .tx = &ipq9574_tx_ring_info,
-+      .txcmpl = &ipq9574_txcmpl_ring_info,
-+      .max_ports = 6,
-+      .napi_budget_rx = 128,
-+      .napi_budget_tx = 512,
-+};
-+
-+static int edma_clock_set_and_enable(struct device *dev,
-+                                   const char *id, unsigned long rate)
-+{
-+      struct device_node *edma_np;
-+      struct clk *clk = NULL;
-+      int ret;
-+
-+      edma_np = of_get_child_by_name(dev->of_node, "edma");
-+
-+      clk = devm_get_clk_from_child(dev, edma_np, id);
-+      if (IS_ERR(clk)) {
-+              dev_err(dev, "clk %s get failed\n", id);
-+              of_node_put(edma_np);
-+              return PTR_ERR(clk);
-+      }
-+
-+      ret = clk_set_rate(clk, rate);
-+      if (ret) {
-+              dev_err(dev, "set %lu rate for %s failed\n", rate, id);
-+              of_node_put(edma_np);
-+              return ret;
-+      }
-+
-+      ret = clk_prepare_enable(clk);
-+      if (ret) {
-+              dev_err(dev, "clk %s enable failed\n", id);
-+              of_node_put(edma_np);
-+              return ret;
-+      }
-+
-+      of_node_put(edma_np);
-+
-+      dev_dbg(dev, "set %lu rate for %s\n", rate, id);
-+
-+      return 0;
-+}
-+
-+static int edma_clock_init(void)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev = ppe_dev->dev;
-+      unsigned long ppe_rate;
-+      int ret;
-+
-+      ppe_rate = ppe_dev->clk_rate;
-+
-+      ret = edma_clock_set_and_enable(dev, clock_name[EDMA_CLK],
-+                                      ppe_rate);
-+      if (ret)
-+              return ret;
-+
-+      ret = edma_clock_set_and_enable(dev, clock_name[EDMA_CFG_CLK],
-+                                      ppe_rate);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+/**
-+ * edma_configure_ucast_prio_map_tbl - Configure unicast priority map table.
-+ *
-+ * Map int_priority values to priority class and initialize
-+ * unicast priority map table for default profile_id.
-+ */
-+static int edma_configure_ucast_prio_map_tbl(void)
-+{
-+      u8 pri_class, int_pri;
-+      int ret = 0;
-+
-+      /* Set the priority class value for every possible priority. */
-+      for (int_pri = 0; int_pri < PPE_QUEUE_INTER_PRI_NUM; int_pri++) {
-+              pri_class = edma_pri_map[int_pri];
-+
-+              /* Priority offset should be less than maximum supported
-+               * queue priority.
-+               */
-+              if (pri_class > EDMA_PRI_MAX_PER_CORE - 1) {
-+                      pr_err("Configured incorrect priority offset: %d\n",
-+                             pri_class);
-+                      return -EINVAL;
-+              }
-+
-+              ret = ppe_edma_queue_offset_config(edma_ctx->ppe_dev,
-+                                                 PPE_QUEUE_CLASS_PRIORITY, int_pri, pri_class);
-+
-+              if (ret) {
-+                      pr_err("Failed with error: %d to set queue priority class for int_pri: %d for profile_id: %d\n",
-+                             ret, int_pri, 0);
-+                      return ret;
-+              }
-+
-+              pr_debug("profile_id: %d, int_priority: %d, pri_class: %d\n",
-+                       0, int_pri, pri_class);
-+      }
-+
-+      return ret;
-+}
-+
-+static int edma_irq_init(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      char edma_irq_name[EDMA_IRQ_NAME_SIZE];
-+      struct device *dev = ppe_dev->dev;
-+      struct platform_device *pdev;
-+      struct device_node *edma_np;
-+      u32 i;
-+
-+      pdev = to_platform_device(dev);
-+      edma_np = of_get_child_by_name(dev->of_node, "edma");
-+      edma_ctx->intr_info.intr_txcmpl = kzalloc((sizeof(*edma_ctx->intr_info.intr_txcmpl) *
-+                                                txcmpl->num_rings), GFP_KERNEL);
-+      if (!edma_ctx->intr_info.intr_txcmpl) {
-+              of_node_put(edma_np);
-+              return -ENOMEM;
-+      }
-+
-+      /* Get TXCMPL rings IRQ numbers. */
-+      for (i = 0; i < txcmpl->num_rings; i++) {
-+              snprintf(edma_irq_name, sizeof(edma_irq_name), "edma_txcmpl_%d",
-+                       txcmpl->ring_start + i);
-+              edma_ctx->intr_info.intr_txcmpl[i] = of_irq_get_byname(edma_np, edma_irq_name);
-+              if (edma_ctx->intr_info.intr_txcmpl[i] < 0) {
-+                      dev_err(dev, "%s: txcmpl_info.intr[%u] irq get failed\n",
-+                              edma_np->name, i);
-+                      of_node_put(edma_np);
-+                      kfree(edma_ctx->intr_info.intr_txcmpl);
-+                      return edma_ctx->intr_info.intr_txcmpl[i];
-+              }
-+
-+              dev_dbg(dev, "%s: intr_info.intr_txcmpl[%u] = %u\n",
-+                      edma_np->name, i, edma_ctx->intr_info.intr_txcmpl[i]);
-+      }
-+
-+      edma_ctx->intr_info.intr_rx = kzalloc((sizeof(*edma_ctx->intr_info.intr_rx) *
-+                                            rx->num_rings), GFP_KERNEL);
-+      if (!edma_ctx->intr_info.intr_rx) {
-+              of_node_put(edma_np);
-+              kfree(edma_ctx->intr_info.intr_txcmpl);
-+              return -ENOMEM;
-+      }
-+
-+      /* Get RXDESC rings IRQ numbers. */
-+      for (i = 0; i < rx->num_rings; i++) {
-+              snprintf(edma_irq_name, sizeof(edma_irq_name), "edma_rxdesc_%d",
-+                       rx->ring_start + i);
-+              edma_ctx->intr_info.intr_rx[i] = of_irq_get_byname(edma_np, edma_irq_name);
-+              if (edma_ctx->intr_info.intr_rx[i] < 0) {
-+                      dev_err(dev, "%s: rx_queue_map_info.intr[%u] irq get failed\n",
-+                              edma_np->name, i);
-+                      of_node_put(edma_np);
-+                      kfree(edma_ctx->intr_info.intr_rx);
-+                      kfree(edma_ctx->intr_info.intr_txcmpl);
-+                      return edma_ctx->intr_info.intr_rx[i];
-+              }
-+
-+              dev_dbg(dev, "%s: intr_info.intr_rx[%u] = %u\n",
-+                      edma_np->name, i, edma_ctx->intr_info.intr_rx[i]);
-+      }
-+
-+      /* Get misc IRQ number. */
-+      edma_ctx->intr_info.intr_misc = of_irq_get_byname(edma_np, "edma_misc");
-+      if (edma_ctx->intr_info.intr_misc < 0) {
-+              dev_err(dev, "%s: misc_intr irq get failed\n", edma_np->name);
-+              of_node_put(edma_np);
-+              kfree(edma_ctx->intr_info.intr_rx);
-+              kfree(edma_ctx->intr_info.intr_txcmpl);
-+              return edma_ctx->intr_info.intr_misc;
-+      }
-+
-+      of_node_put(edma_np);
-+
-+      dev_dbg(dev, "%s: misc IRQ:%u\n", edma_np->name,
-+              edma_ctx->intr_info.intr_misc);
-+
-+      return 0;
-+}
-+
-+static int edma_hw_reset(void)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev = ppe_dev->dev;
-+      struct reset_control *edma_hw_rst;
-+      struct device_node *edma_np;
-+      const char *reset_string;
-+      u32 count, i;
-+      int ret;
-+
-+      /* Count and parse reset names from DTSI. */
-+      edma_np = of_get_child_by_name(dev->of_node, "edma");
-+      count = of_property_count_strings(edma_np, "reset-names");
-+      if (count < 0) {
-+              dev_err(dev, "EDMA reset entry not found\n");
-+              of_node_put(edma_np);
-+              return -EINVAL;
-+      }
-+
-+      for (i = 0; i < count; i++) {
-+              ret = of_property_read_string_index(edma_np, "reset-names",
-+                                                  i, &reset_string);
-+              if (ret) {
-+                      dev_err(dev, "Error reading reset-names");
-+                      of_node_put(edma_np);
-+                      return -EINVAL;
-+              }
-+
-+              edma_hw_rst = of_reset_control_get_exclusive(edma_np, reset_string);
-+              if (IS_ERR(edma_hw_rst)) {
-+                      of_node_put(edma_np);
-+                      return PTR_ERR(edma_hw_rst);
-+              }
-+
-+              /* 100ms delay is required by hardware to reset EDMA. */
-+              reset_control_assert(edma_hw_rst);
-+              fsleep(100);
-+
-+              reset_control_deassert(edma_hw_rst);
-+              fsleep(100);
-+
-+              reset_control_put(edma_hw_rst);
-+              dev_dbg(dev, "EDMA HW reset, i:%d reset_string:%s\n", i, reset_string);
-+      }
-+
-+      of_node_put(edma_np);
-+
-+      return 0;
-+}
-+
-+static int edma_hw_configure(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 data, reg;
-+      int ret;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_MAS_CTRL_ADDR;
-+      ret = regmap_read(regmap, reg, &data);
-+      if (ret)
-+              return ret;
-+
-+      pr_debug("EDMA ver %d hw init\n", data);
-+
-+      /* Setup private data structure. */
-+      edma_ctx->intr_info.intr_mask_rx = EDMA_RXDESC_INT_MASK_PKT_INT;
-+      edma_ctx->intr_info.intr_mask_txcmpl = EDMA_TX_INT_MASK_PKT_INT;
-+
-+      /* Reset EDMA. */
-+      ret = edma_hw_reset();
-+      if (ret) {
-+              pr_err("Error in resetting the hardware. ret: %d\n", ret);
-+              return ret;
-+      }
-+
-+      /* Allocate memory for netdevices. */
-+      edma_ctx->netdev_arr = kzalloc((sizeof(**edma_ctx->netdev_arr) *
-+                                       hw_info->max_ports),
-+                                       GFP_KERNEL);
-+      if (!edma_ctx->netdev_arr)
-+              return -ENOMEM;
-+
-+      /* Configure DMA request priority, DMA read burst length,
-+       * and AXI write size.
-+       */
-+      data = FIELD_PREP(EDMA_DMAR_BURST_LEN_MASK, EDMA_BURST_LEN_ENABLE);
-+      data |= FIELD_PREP(EDMA_DMAR_REQ_PRI_MASK, 0);
-+      data |= FIELD_PREP(EDMA_DMAR_TXDATA_OUTSTANDING_NUM_MASK, 31);
-+      data |= FIELD_PREP(EDMA_DMAR_TXDESC_OUTSTANDING_NUM_MASK, 7);
-+      data |= FIELD_PREP(EDMA_DMAR_RXFILL_OUTSTANDING_NUM_MASK, 7);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_DMAR_CTRL_ADDR;
-+      ret = regmap_write(regmap, reg, data);
-+      if (ret)
-+              return ret;
-+
-+      /* Configure Tx Timeout Threshold. */
-+      data = EDMA_TX_TIMEOUT_THRESH_VAL;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TX_TIMEOUT_THRESH_ADDR;
-+      ret = regmap_write(regmap, reg, data);
-+      if (ret)
-+              return ret;
-+
-+      /* Set Miscellaneous error mask. */
-+      data = EDMA_MISC_AXI_RD_ERR_MASK |
-+              EDMA_MISC_AXI_WR_ERR_MASK |
-+              EDMA_MISC_RX_DESC_FIFO_FULL_MASK |
-+              EDMA_MISC_RX_ERR_BUF_SIZE_MASK |
-+              EDMA_MISC_TX_SRAM_FULL_MASK |
-+              EDMA_MISC_TX_CMPL_BUF_FULL_MASK |
-+              EDMA_MISC_DATA_LEN_ERR_MASK;
-+      data |= EDMA_MISC_TX_TIMEOUT_MASK;
-+      edma_ctx->intr_info.intr_mask_misc = data;
-+
-+      /* Global EDMA enable and padding enable. */
-+      data = EDMA_PORT_PAD_EN | EDMA_PORT_EDMA_EN;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_PORT_CTRL_ADDR;
-+      ret = regmap_write(regmap, reg, data);
-+      if (ret)
-+              return ret;
-+
-+      /* Initialize unicast priority map table. */
-+      ret = (int)edma_configure_ucast_prio_map_tbl();
-+      if (ret) {
-+              pr_err("Failed to initialize unicast priority map table: %d\n",
-+                     ret);
-+              kfree(edma_ctx->netdev_arr);
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ * edma_destroy - EDMA Destroy.
-+ * @ppe_dev: PPE device
-+ *
-+ * Free the memory allocated during setup.
-+ */
-+void edma_destroy(struct ppe_device *ppe_dev)
-+{
-+      kfree(edma_ctx->intr_info.intr_rx);
-+      kfree(edma_ctx->intr_info.intr_txcmpl);
-+      kfree(edma_ctx->netdev_arr);
-+}
-+
-+/**
-+ * edma_setup - EDMA Setup.
-+ * @ppe_dev: PPE device
-+ *
-+ * Configure Ethernet global ctx, clocks, hardware and interrupts.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+int edma_setup(struct ppe_device *ppe_dev)
-+{
-+      struct device *dev = ppe_dev->dev;
-+      int ret;
-+
-+      edma_ctx = devm_kzalloc(dev, sizeof(*edma_ctx), GFP_KERNEL);
-+      if (!edma_ctx)
-+              return -ENOMEM;
-+
-+      edma_ctx->hw_info = &ipq9574_hw_info;
-+      edma_ctx->ppe_dev = ppe_dev;
-+
-+      /* Configure the EDMA common clocks. */
-+      ret = edma_clock_init();
-+      if (ret) {
-+              dev_err(dev, "Error in configuring the EDMA clocks\n");
-+              return ret;
-+      }
-+
-+      dev_dbg(dev, "QCOM EDMA common clocks are configured\n");
-+
-+      ret = edma_hw_configure();
-+      if (ret) {
-+              dev_err(dev, "Error in edma configuration\n");
-+              return ret;
-+      }
-+
-+      ret = edma_irq_init();
-+      if (ret) {
-+              dev_err(dev, "Error in irq initialization\n");
-+              return ret;
-+      }
-+
-+      dev_info(dev, "EDMA configuration successful\n");
-+
-+      return 0;
-+}
-+
-+/**
-+ * ppe_edma_queue_offset_config - Configure queue offset for EDMA interface
-+ * @ppe_dev: PPE device
-+ * @class: The class to configure queue offset
-+ * @index: Class index, internal priority or hash value
-+ * @queue_offset: Queue offset value
-+ *
-+ * PPE EDMA queue offset is configured based on the PPE internal priority or
-+ * RSS hash value, the profile ID is fixed to 0 for EDMA interface.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+int ppe_edma_queue_offset_config(struct ppe_device *ppe_dev,
-+                               enum ppe_queue_class_type class,
-+                               int index, int queue_offset)
-+{
-+      if (class == PPE_QUEUE_CLASS_PRIORITY)
-+              return ppe_queue_ucast_offset_pri_set(ppe_dev, 0,
-+                                                    index, queue_offset);
-+
-+      return ppe_queue_ucast_offset_hash_set(ppe_dev, 0,
-+                                             index, queue_offset);
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.h
-@@ -0,0 +1,113 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __EDMA_MAIN__
-+#define __EDMA_MAIN__
-+
-+#include "ppe_config.h"
-+
-+/* One clock cycle = 1/(EDMA clock frequency in Mhz) micro seconds.
-+ *
-+ * One timer unit is 128 clock cycles.
-+ *
-+ * So, therefore the microsecond to timer unit calculation is:
-+ * Timer unit = time in microseconds / (one clock cycle in microsecond * cycles in 1 timer unit)
-+ *            = ('x' microsecond * EDMA clock frequency in MHz ('y') / 128).
-+ *
-+ */
-+#define EDMA_CYCLE_PER_TIMER_UNIT     128
-+#define EDMA_MICROSEC_TO_TIMER_UNIT(x, y)     ((x) * (y) / EDMA_CYCLE_PER_TIMER_UNIT)
-+#define MHZ                   1000000UL
-+
-+/* EDMA profile ID. */
-+#define EDMA_CPU_PORT_PROFILE_ID  0
-+
-+/* Number of PPE queue priorities supported per ARM core. */
-+#define EDMA_PRI_MAX_PER_CORE 8
-+
-+/**
-+ * enum ppe_queue_class_type - PPE queue class type
-+ * @PPE_QUEUE_CLASS_PRIORITY: Queue offset configured from internal priority
-+ * @PPE_QUEUE_CLASS_HASH: Queue offset configured from RSS hash.
-+ */
-+enum ppe_queue_class_type {
-+      PPE_QUEUE_CLASS_PRIORITY,
-+      PPE_QUEUE_CLASS_HASH,
-+};
-+
-+/**
-+ * struct edma_ring_info - EDMA ring data structure.
-+ * @max_rings: Maximum number of rings
-+ * @ring_start: Ring start ID
-+ * @num_rings: Number of rings
-+ */
-+struct edma_ring_info {
-+      u32 max_rings;
-+      u32 ring_start;
-+      u32 num_rings;
-+};
-+
-+/**
-+ * struct edma_hw_info - EDMA hardware data structure.
-+ * @rxfill: Rx Fill ring information
-+ * @rx: Rx Desc ring information
-+ * @tx: Tx Desc ring information
-+ * @txcmpl: Tx complete ring information
-+ * @max_ports: Maximum number of ports
-+ * @napi_budget_rx: Rx NAPI budget
-+ * @napi_budget_tx: Tx NAPI budget
-+ */
-+struct edma_hw_info {
-+      struct edma_ring_info *rxfill;
-+      struct edma_ring_info *rx;
-+      struct edma_ring_info *tx;
-+      struct edma_ring_info *txcmpl;
-+      u32 max_ports;
-+      u32 napi_budget_rx;
-+      u32 napi_budget_tx;
-+};
-+
-+/**
-+ * struct edma_intr_info - EDMA interrupt data structure.
-+ * @intr_mask_rx: RX interrupt mask
-+ * @intr_rx: Rx interrupts
-+ * @intr_mask_txcmpl: Tx completion interrupt mask
-+ * @intr_txcmpl: Tx completion interrupts
-+ * @intr_mask_misc: Miscellaneous interrupt mask
-+ * @intr_misc: Miscellaneous interrupts
-+ */
-+struct edma_intr_info {
-+      u32 intr_mask_rx;
-+      u32 *intr_rx;
-+      u32 intr_mask_txcmpl;
-+      u32 *intr_txcmpl;
-+      u32 intr_mask_misc;
-+      u32 intr_misc;
-+};
-+
-+/**
-+ * struct edma_context - EDMA context.
-+ * @netdev_arr: Net device for each EDMA port
-+ * @ppe_dev: PPE device
-+ * @hw_info: EDMA Hardware info
-+ * @intr_info: EDMA Interrupt info
-+ */
-+struct edma_context {
-+      struct net_device **netdev_arr;
-+      struct ppe_device *ppe_dev;
-+      struct edma_hw_info *hw_info;
-+      struct edma_intr_info intr_info;
-+};
-+
-+/* Global EDMA context. */
-+extern struct edma_context *edma_ctx;
-+
-+void edma_destroy(struct ppe_device *ppe_dev);
-+int edma_setup(struct ppe_device *ppe_dev);
-+int ppe_edma_queue_offset_config(struct ppe_device *ppe_dev,
-+                               enum ppe_queue_class_type class,
-+                               int index, int queue_offset);
-+
-+
-+#endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
-@@ -14,6 +14,7 @@
- #include <linux/regmap.h>
- #include <linux/reset.h>
-+#include "edma.h"
- #include "ppe.h"
- #include "ppe_config.h"
- #include "ppe_debugfs.h"
-@@ -201,10 +202,16 @@ static int qcom_ppe_probe(struct platfor
-       if (ret)
-               return dev_err_probe(dev, ret, "PPE HW config failed\n");
--      ret = ppe_port_mac_init(ppe_dev);
-+      ret = edma_setup(ppe_dev);
-       if (ret)
-+              return dev_err_probe(dev, ret, "EDMA setup failed\n");
-+
-+      ret = ppe_port_mac_init(ppe_dev);
-+      if (ret) {
-+              edma_destroy(ppe_dev);
-               return dev_err_probe(dev, ret,
-                                    "PPE Port MAC initialization failed\n");
-+      }
-       ppe_debugfs_setup(ppe_dev);
-       platform_set_drvdata(pdev, ppe_dev);
-@@ -219,6 +226,7 @@ static void qcom_ppe_remove(struct platf
-       ppe_dev = platform_get_drvdata(pdev);
-       ppe_debugfs_teardown(ppe_dev);
-       ppe_port_mac_deinit(ppe_dev);
-+      edma_destroy(ppe_dev);
-       platform_set_drvdata(pdev, NULL);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
-@@ -800,4 +800,257 @@
- #define XGMAC_RXDISCARD_GB_ADDR                       0x9AC
- #define XGMAC_RXDISCARDBYTE_GB_ADDR           0x9B4
-+#define EDMA_BASE_OFFSET                      0xb00000
-+
-+/* EDMA register offsets */
-+#define EDMA_REG_MAS_CTRL_ADDR                        0x0
-+#define EDMA_REG_PORT_CTRL_ADDR                       0x4
-+#define EDMA_REG_VLAN_CTRL_ADDR                       0x8
-+#define EDMA_REG_RXDESC2FILL_MAP_0_ADDR               0x14
-+#define EDMA_REG_RXDESC2FILL_MAP_1_ADDR               0x18
-+#define EDMA_REG_RXDESC2FILL_MAP_2_ADDR               0x1c
-+#define EDMA_REG_TXQ_CTRL_ADDR                        0x20
-+#define EDMA_REG_TXQ_CTRL_2_ADDR              0x24
-+#define EDMA_REG_TXQ_FC_0_ADDR                        0x28
-+#define EDMA_REG_TXQ_FC_1_ADDR                        0x30
-+#define EDMA_REG_TXQ_FC_2_ADDR                        0x34
-+#define EDMA_REG_TXQ_FC_3_ADDR                        0x38
-+#define EDMA_REG_RXQ_CTRL_ADDR                        0x3c
-+#define EDMA_REG_MISC_ERR_QID_ADDR            0x40
-+#define EDMA_REG_RXQ_FC_THRE_ADDR             0x44
-+#define EDMA_REG_DMAR_CTRL_ADDR                       0x48
-+#define EDMA_REG_AXIR_CTRL_ADDR                       0x4c
-+#define EDMA_REG_AXIW_CTRL_ADDR                       0x50
-+#define EDMA_REG_MIN_MSS_ADDR                 0x54
-+#define EDMA_REG_LOOPBACK_CTRL_ADDR           0x58
-+#define EDMA_REG_MISC_INT_STAT_ADDR           0x5c
-+#define EDMA_REG_MISC_INT_MASK_ADDR           0x60
-+#define EDMA_REG_DBG_CTRL_ADDR                        0x64
-+#define EDMA_REG_DBG_DATA_ADDR                        0x68
-+#define EDMA_REG_TX_TIMEOUT_THRESH_ADDR               0x6c
-+#define EDMA_REG_REQ0_FIFO_THRESH_ADDR                0x80
-+#define EDMA_REG_WB_OS_THRESH_ADDR            0x84
-+#define EDMA_REG_MISC_ERR_QID_REG2_ADDR               0x88
-+#define EDMA_REG_TXDESC2CMPL_MAP_0_ADDR               0x8c
-+#define EDMA_REG_TXDESC2CMPL_MAP_1_ADDR               0x90
-+#define EDMA_REG_TXDESC2CMPL_MAP_2_ADDR               0x94
-+#define EDMA_REG_TXDESC2CMPL_MAP_3_ADDR               0x98
-+#define EDMA_REG_TXDESC2CMPL_MAP_4_ADDR               0x9c
-+#define EDMA_REG_TXDESC2CMPL_MAP_5_ADDR               0xa0
-+
-+/* Tx descriptor ring configuration register addresses */
-+#define EDMA_REG_TXDESC_BA(n)         (0x1000 + (0x1000 * (n)))
-+#define EDMA_REG_TXDESC_PROD_IDX(n)   (0x1004 + (0x1000 * (n)))
-+#define EDMA_REG_TXDESC_CONS_IDX(n)   (0x1008 + (0x1000 * (n)))
-+#define EDMA_REG_TXDESC_RING_SIZE(n)  (0x100c + (0x1000 * (n)))
-+#define EDMA_REG_TXDESC_CTRL(n)               (0x1010 + (0x1000 * (n)))
-+#define EDMA_REG_TXDESC_BA2(n)                (0x1014 + (0x1000 * (n)))
-+
-+/* RxFill ring configuration register addresses */
-+#define EDMA_REG_RXFILL_BA(n)         (0x29000 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_PROD_IDX(n)   (0x29004 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_CONS_IDX(n)   (0x29008 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_RING_SIZE(n)  (0x2900c + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_BUFFER1_SIZE(n)       (0x29010 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_FC_THRE(n)    (0x29014 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_UGT_THRE(n)   (0x29018 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_RING_EN(n)    (0x2901c + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_DISABLE(n)    (0x29020 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_DISABLE_DONE(n)       (0x29024 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_INT_STAT(n)   (0x31000 + (0x1000 * (n)))
-+#define EDMA_REG_RXFILL_INT_MASK(n)   (0x31004 + (0x1000 * (n)))
-+
-+/* Rx descriptor ring configuration register addresses */
-+#define EDMA_REG_RXDESC_BA(n)         (0x39000 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_PROD_IDX(n)   (0x39004 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_CONS_IDX(n)   (0x39008 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_RING_SIZE(n)  (0x3900c + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_FC_THRE(n)    (0x39010 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_UGT_THRE(n)   (0x39014 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_CTRL(n)               (0x39018 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_BPC(n)                (0x3901c + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_DISABLE(n)    (0x39020 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_DISABLE_DONE(n)       (0x39024 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_PREHEADER_BA(n)       (0x39028 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_INT_STAT(n)   (0x59000 + (0x1000 * (n)))
-+#define EDMA_REG_RXDESC_INT_MASK(n)   (0x59004 + (0x1000 * (n)))
-+
-+#define EDMA_REG_RX_MOD_TIMER(n)      (0x59008 + (0x1000 * (n)))
-+#define EDMA_REG_RX_INT_CTRL(n)               (0x5900c + (0x1000 * (n)))
-+
-+/* Tx completion ring configuration register addresses */
-+#define EDMA_REG_TXCMPL_BA(n)         (0x79000 + (0x1000 * (n)))
-+#define EDMA_REG_TXCMPL_PROD_IDX(n)   (0x79004 + (0x1000 * (n)))
-+#define EDMA_REG_TXCMPL_CONS_IDX(n)   (0x79008 + (0x1000 * (n)))
-+#define EDMA_REG_TXCMPL_RING_SIZE(n)  (0x7900c + (0x1000 * (n)))
-+#define EDMA_REG_TXCMPL_UGT_THRE(n)   (0x79010 + (0x1000 * (n)))
-+#define EDMA_REG_TXCMPL_CTRL(n)               (0x79014 + (0x1000 * (n)))
-+#define EDMA_REG_TXCMPL_BPC(n)                (0x79018 + (0x1000 * (n)))
-+
-+#define EDMA_REG_TX_INT_STAT(n)               (0x99000 + (0x1000 * (n)))
-+#define EDMA_REG_TX_INT_MASK(n)               (0x99004 + (0x1000 * (n)))
-+#define EDMA_REG_TX_MOD_TIMER(n)      (0x99008 + (0x1000 * (n)))
-+#define EDMA_REG_TX_INT_CTRL(n)               (0x9900c + (0x1000 * (n)))
-+
-+/* EDMA_QID2RID_TABLE_MEM register field masks */
-+#define EDMA_RX_RING_ID_QUEUE0_MASK   GENMASK(7, 0)
-+#define EDMA_RX_RING_ID_QUEUE1_MASK   GENMASK(15, 8)
-+#define EDMA_RX_RING_ID_QUEUE2_MASK   GENMASK(23, 16)
-+#define EDMA_RX_RING_ID_QUEUE3_MASK   GENMASK(31, 24)
-+
-+/* EDMA_REG_PORT_CTRL register bit definitions */
-+#define EDMA_PORT_PAD_EN                      0x1
-+#define EDMA_PORT_EDMA_EN                     0x2
-+
-+/* EDMA_REG_DMAR_CTRL register field masks */
-+#define EDMA_DMAR_REQ_PRI_MASK                        GENMASK(2, 0)
-+#define EDMA_DMAR_BURST_LEN_MASK              BIT(3)
-+#define EDMA_DMAR_TXDATA_OUTSTANDING_NUM_MASK GENMASK(8, 4)
-+#define EDMA_DMAR_TXDESC_OUTSTANDING_NUM_MASK GENMASK(11, 9)
-+#define EDMA_DMAR_RXFILL_OUTSTANDING_NUM_MASK GENMASK(14, 12)
-+
-+#define EDMA_BURST_LEN_ENABLE                 0
-+
-+/* Tx timeout threshold */
-+#define EDMA_TX_TIMEOUT_THRESH_VAL            0xFFFF
-+
-+/* Rx descriptor ring base address mask */
-+#define EDMA_RXDESC_BA_MASK                   0xffffffff
-+
-+/* Rx Descriptor ring pre-header base address mask */
-+#define EDMA_RXDESC_PREHEADER_BA_MASK         0xffffffff
-+
-+/* Tx descriptor prod ring index mask */
-+#define EDMA_TXDESC_PROD_IDX_MASK             0xffff
-+
-+/* Tx descriptor consumer ring index mask */
-+#define EDMA_TXDESC_CONS_IDX_MASK             0xffff
-+
-+/* Tx descriptor ring size mask */
-+#define EDMA_TXDESC_RING_SIZE_MASK            0xffff
-+
-+/* Tx descriptor ring enable */
-+#define EDMA_TXDESC_TX_ENABLE                 0x1
-+
-+#define EDMA_TXDESC_CTRL_TXEN_MASK            BIT(0)
-+#define EDMA_TXDESC_CTRL_FC_GRP_ID_MASK               GENMASK(3, 1)
-+
-+/* Tx completion ring prod index mask */
-+#define EDMA_TXCMPL_PROD_IDX_MASK             0xffff
-+
-+/* Tx completion ring urgent threshold mask */
-+#define EDMA_TXCMPL_LOW_THRE_MASK             0xffff
-+#define EDMA_TXCMPL_LOW_THRE_SHIFT            0
-+
-+/* EDMA_REG_TX_MOD_TIMER mask */
-+#define EDMA_TX_MOD_TIMER_INIT_MASK           0xffff
-+#define EDMA_TX_MOD_TIMER_INIT_SHIFT          0
-+
-+/* Rx fill ring prod index mask */
-+#define EDMA_RXFILL_PROD_IDX_MASK             0xffff
-+
-+/* Rx fill ring consumer index mask */
-+#define EDMA_RXFILL_CONS_IDX_MASK             0xffff
-+
-+/* Rx fill ring size mask */
-+#define EDMA_RXFILL_RING_SIZE_MASK            0xffff
-+
-+/* Rx fill ring flow control threshold masks */
-+#define EDMA_RXFILL_FC_XON_THRE_MASK          0x7ff
-+#define EDMA_RXFILL_FC_XON_THRE_SHIFT         12
-+#define EDMA_RXFILL_FC_XOFF_THRE_MASK         0x7ff
-+#define EDMA_RXFILL_FC_XOFF_THRE_SHIFT                0
-+
-+/* Rx fill ring enable bit */
-+#define EDMA_RXFILL_RING_EN                   0x1
-+
-+/* Rx desc ring prod index mask */
-+#define EDMA_RXDESC_PROD_IDX_MASK             0xffff
-+
-+/* Rx descriptor ring cons index mask */
-+#define EDMA_RXDESC_CONS_IDX_MASK             0xffff
-+
-+/* Rx descriptor ring size masks */
-+#define EDMA_RXDESC_RING_SIZE_MASK            0xffff
-+#define EDMA_RXDESC_PL_OFFSET_MASK            0x1ff
-+#define EDMA_RXDESC_PL_OFFSET_SHIFT           16
-+#define EDMA_RXDESC_PL_DEFAULT_VALUE          0
-+
-+/* Rx descriptor ring flow control threshold masks */
-+#define EDMA_RXDESC_FC_XON_THRE_MASK          0x7ff
-+#define EDMA_RXDESC_FC_XON_THRE_SHIFT         12
-+#define EDMA_RXDESC_FC_XOFF_THRE_MASK         0x7ff
-+#define EDMA_RXDESC_FC_XOFF_THRE_SHIFT                0
-+
-+/* Rx descriptor ring urgent threshold mask */
-+#define EDMA_RXDESC_LOW_THRE_MASK             0xffff
-+#define EDMA_RXDESC_LOW_THRE_SHIFT            0
-+
-+/* Rx descriptor ring enable bit */
-+#define EDMA_RXDESC_RX_EN                     0x1
-+
-+/* Tx interrupt status bit */
-+#define EDMA_TX_INT_MASK_PKT_INT              0x1
-+
-+/* Rx interrupt mask */
-+#define EDMA_RXDESC_INT_MASK_PKT_INT          0x1
-+
-+#define EDMA_MASK_INT_DISABLE                 0x0
-+#define EDMA_MASK_INT_CLEAR                   0x0
-+
-+/* EDMA_REG_RX_MOD_TIMER register field masks */
-+#define EDMA_RX_MOD_TIMER_INIT_MASK           0xffff
-+#define EDMA_RX_MOD_TIMER_INIT_SHIFT          0
-+
-+/* EDMA Ring mask */
-+#define EDMA_RING_DMA_MASK                    0xffffffff
-+
-+/* RXDESC threshold interrupt. */
-+#define EDMA_RXDESC_UGT_INT_STAT              0x2
-+
-+/* RXDESC timer interrupt */
-+#define EDMA_RXDESC_PKT_INT_STAT              0x1
-+
-+/* RXDESC Interrupt status mask */
-+#define EDMA_RXDESC_RING_INT_STATUS_MASK \
-+      (EDMA_RXDESC_UGT_INT_STAT | EDMA_RXDESC_PKT_INT_STAT)
-+
-+/* TXCMPL threshold interrupt. */
-+#define EDMA_TXCMPL_UGT_INT_STAT              0x2
-+
-+/* TXCMPL timer interrupt */
-+#define EDMA_TXCMPL_PKT_INT_STAT              0x1
-+
-+/* TXCMPL Interrupt status mask */
-+#define EDMA_TXCMPL_RING_INT_STATUS_MASK \
-+      (EDMA_TXCMPL_UGT_INT_STAT | EDMA_TXCMPL_PKT_INT_STAT)
-+
-+#define EDMA_TXCMPL_RETMODE_OPAQUE            0x0
-+
-+#define EDMA_RXDESC_LOW_THRE                  0
-+#define EDMA_RX_MOD_TIMER_INIT                        1000
-+#define EDMA_RX_NE_INT_EN                     0x2
-+
-+#define EDMA_TX_MOD_TIMER                     150
-+
-+#define EDMA_TX_INITIAL_PROD_IDX              0x0
-+#define EDMA_TX_NE_INT_EN                     0x2
-+
-+/* EDMA misc error mask */
-+#define EDMA_MISC_AXI_RD_ERR_MASK             BIT(0)
-+#define EDMA_MISC_AXI_WR_ERR_MASK             BIT(1)
-+#define EDMA_MISC_RX_DESC_FIFO_FULL_MASK      BIT(2)
-+#define EDMA_MISC_RX_ERR_BUF_SIZE_MASK                BIT(3)
-+#define EDMA_MISC_TX_SRAM_FULL_MASK           BIT(4)
-+#define EDMA_MISC_TX_CMPL_BUF_FULL_MASK               BIT(5)
-+
-+#define EDMA_MISC_DATA_LEN_ERR_MASK           BIT(6)
-+#define EDMA_MISC_TX_TIMEOUT_MASK             BIT(7)
-+
-+/* EDMA txdesc2cmpl map */
-+#define EDMA_TXDESC2CMPL_MAP_TXDESC_MASK              0x1F
-+
-+/* EDMA rxdesc2fill map */
-+#define EDMA_RXDESC2FILL_MAP_RXDESC_MASK      0x7
-+
- #endif
diff --git a/target/linux/qualcommbe/patches-6.12/0343-net-ethernet-qualcomm-Add-netdevice-support-for-QCOM.patch b/target/linux/qualcommbe/patches-6.12/0343-net-ethernet-qualcomm-Add-netdevice-support-for-QCOM.patch
deleted file mode 100644 (file)
index 55de486..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-From 5dc80c468c668d855d76b323f09bbadb95cc3147 Mon Sep 17 00:00:00 2001
-From: Suruchi Agarwal <quic_suruchia@quicinc.com>
-Date: Thu, 21 Mar 2024 16:14:46 -0700
-Subject: [PATCH] net: ethernet: qualcomm: Add netdevice support for QCOM
- IPQ9574 chipset.
-
-Add EDMA ports and netdevice operations for QCOM IPQ9574 chipset.
-
-Change-Id: I08b2eff52b4ef0d6d428c1c416f5580ef010973f
-Co-developed-by: Pavithra R <quic_pavir@quicinc.com>
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
-Signed-off-by: Suruchi Agarwal <quic_suruchia@quicinc.com>
----
- drivers/net/ethernet/qualcomm/ppe/Makefile    |   2 +-
- drivers/net/ethernet/qualcomm/ppe/edma.h      |   3 +
- drivers/net/ethernet/qualcomm/ppe/edma_port.c | 270 ++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/edma_port.h |  31 ++
- drivers/net/ethernet/qualcomm/ppe/ppe_port.c  |  19 ++
- 5 files changed, 324 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_port.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_port.h
-
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -7,4 +7,4 @@ obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
- qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o ppe_port.o
- #EDMA
--qcom-ppe-objs += edma.o
-+qcom-ppe-objs += edma.o edma_port.o
---- a/drivers/net/ethernet/qualcomm/ppe/edma.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.h
-@@ -26,6 +26,9 @@
- /* Number of PPE queue priorities supported per ARM core. */
- #define EDMA_PRI_MAX_PER_CORE 8
-+/* Interface ID start. */
-+#define EDMA_START_IFNUM   1
-+
- /**
-  * enum ppe_queue_class_type - PPE queue class type
-  * @PPE_QUEUE_CLASS_PRIORITY: Queue offset configured from internal priority
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-@@ -0,0 +1,270 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+ /* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+  */
-+
-+/* EDMA port initialization, configuration and netdevice ops handling */
-+
-+#include <linux/etherdevice.h>
-+#include <linux/net.h>
-+#include <linux/netdevice.h>
-+#include <linux/of_net.h>
-+#include <linux/phylink.h>
-+#include <linux/printk.h>
-+
-+#include "edma.h"
-+#include "edma_port.h"
-+#include "ppe_regs.h"
-+
-+/* Number of netdev queues. */
-+#define EDMA_NETDEV_QUEUE_NUM 4
-+
-+static u16 __maybe_unused edma_port_select_queue(__maybe_unused struct net_device *netdev,
-+                                               __maybe_unused struct sk_buff *skb,
-+                              __maybe_unused struct net_device *sb_dev)
-+{
-+      int cpu = get_cpu();
-+
-+      put_cpu();
-+
-+      return cpu;
-+}
-+
-+static int edma_port_open(struct net_device *netdev)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *ppe_port;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      /* Inform the Linux Networking stack about the hardware capability of
-+       * checksum offloading and other features. Each port is
-+       * responsible to maintain the feature set it supports.
-+       */
-+      netdev->features |= EDMA_NETDEV_FEATURES;
-+      netdev->hw_features |= EDMA_NETDEV_FEATURES;
-+      netdev->vlan_features |= EDMA_NETDEV_FEATURES;
-+      netdev->wanted_features |= EDMA_NETDEV_FEATURES;
-+
-+      ppe_port  = port_priv->ppe_port;
-+
-+      if (ppe_port->phylink)
-+              phylink_start(ppe_port->phylink);
-+
-+      netif_start_queue(netdev);
-+
-+      return 0;
-+}
-+
-+static int edma_port_close(struct net_device *netdev)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *ppe_port;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      netif_stop_queue(netdev);
-+
-+      ppe_port  = port_priv->ppe_port;
-+
-+      /* Phylink close. */
-+      if (ppe_port->phylink)
-+              phylink_stop(ppe_port->phylink);
-+
-+      return 0;
-+}
-+
-+static int edma_port_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *ppe_port;
-+      int ret = -EINVAL;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      ppe_port = port_priv->ppe_port;
-+      if (ppe_port->phylink)
-+              return phylink_mii_ioctl(ppe_port->phylink, ifr, cmd);
-+
-+      return ret;
-+}
-+
-+static int edma_port_change_mtu(struct net_device *netdev, int mtu)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      netdev->mtu = mtu;
-+
-+      return ppe_port_set_maxframe(port_priv->ppe_port, mtu);
-+}
-+
-+static netdev_features_t edma_port_feature_check(__maybe_unused struct sk_buff *skb,
-+                                               __maybe_unused struct net_device *netdev,
-+                                               netdev_features_t features)
-+{
-+      return features;
-+}
-+
-+static void edma_port_get_stats64(struct net_device *netdev,
-+                                struct rtnl_link_stats64 *stats)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+
-+      if (!port_priv)
-+              return;
-+
-+      ppe_port_get_stats64(port_priv->ppe_port, stats);
-+}
-+
-+static int edma_port_set_mac_address(struct net_device *netdev, void *macaddr)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct sockaddr *addr = (struct sockaddr *)macaddr;
-+      int ret;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      netdev_dbg(netdev, "AddrFamily: %d, %0x:%0x:%0x:%0x:%0x:%0x\n",
-+                 addr->sa_family, addr->sa_data[0], addr->sa_data[1],
-+                 addr->sa_data[2], addr->sa_data[3], addr->sa_data[4],
-+                 addr->sa_data[5]);
-+
-+      ret = eth_prepare_mac_addr_change(netdev, addr);
-+      if (ret)
-+              return ret;
-+
-+      if (ppe_port_set_mac_address(port_priv->ppe_port, (u8 *)addr)) {
-+              netdev_err(netdev, "set mac address failed for dev: %s\n", netdev->name);
-+              return -EINVAL;
-+      }
-+
-+      eth_commit_mac_addr_change(netdev, addr);
-+
-+      return 0;
-+}
-+
-+static const struct net_device_ops edma_port_netdev_ops = {
-+      .ndo_open = edma_port_open,
-+      .ndo_stop = edma_port_close,
-+      .ndo_get_stats64 = edma_port_get_stats64,
-+      .ndo_set_mac_address = edma_port_set_mac_address,
-+      .ndo_validate_addr = eth_validate_addr,
-+      .ndo_change_mtu = edma_port_change_mtu,
-+      .ndo_eth_ioctl = edma_port_ioctl,
-+      .ndo_features_check = edma_port_feature_check,
-+      .ndo_select_queue = edma_port_select_queue,
-+};
-+
-+/**
-+ * edma_port_destroy - EDMA port destroy.
-+ * @port: PPE port
-+ *
-+ * Unregister and free the netdevice.
-+ */
-+void edma_port_destroy(struct ppe_port *port)
-+{
-+      int port_id = port->port_id;
-+      struct net_device *netdev = edma_ctx->netdev_arr[port_id - 1];
-+
-+      unregister_netdev(netdev);
-+      free_netdev(netdev);
-+      ppe_port_phylink_destroy(port);
-+      edma_ctx->netdev_arr[port_id - 1] = NULL;
-+}
-+
-+/**
-+ * edma_port_setup - EDMA port Setup.
-+ * @port: PPE port
-+ *
-+ * Initialize and register the netdevice.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+int edma_port_setup(struct ppe_port *port)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device_node *np = port->np;
-+      struct edma_port_priv *port_priv;
-+      int port_id = port->port_id;
-+      struct net_device *netdev;
-+      u8 mac_addr[ETH_ALEN];
-+      int ret = 0;
-+      u8 *maddr;
-+
-+      netdev = alloc_etherdev_mqs(sizeof(struct edma_port_priv),
-+                                  EDMA_NETDEV_QUEUE_NUM, EDMA_NETDEV_QUEUE_NUM);
-+      if (!netdev) {
-+              pr_err("alloc_etherdev() failed\n");
-+              return -ENOMEM;
-+      }
-+
-+      SET_NETDEV_DEV(netdev, ppe_dev->dev);
-+      netdev->dev.of_node = np;
-+
-+      /* max_mtu is set to 1500 in ether_setup(). */
-+      netdev->max_mtu = ETH_MAX_MTU;
-+
-+      port_priv = netdev_priv(netdev);
-+      memset((void *)port_priv, 0, sizeof(struct edma_port_priv));
-+
-+      port_priv->ppe_port = port;
-+      port_priv->netdev = netdev;
-+      netdev->watchdog_timeo = 5 * HZ;
-+      netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
-+      netdev->netdev_ops = &edma_port_netdev_ops;
-+      netdev->gso_max_segs = GSO_MAX_SEGS;
-+
-+      maddr = mac_addr;
-+      if (of_get_mac_address(np, maddr))
-+              maddr = NULL;
-+
-+      if (maddr && is_valid_ether_addr(maddr)) {
-+              eth_hw_addr_set(netdev, maddr);
-+      } else {
-+              eth_hw_addr_random(netdev);
-+              netdev_info(netdev, "GMAC%d Using random MAC address - %pM\n",
-+                          port_id, netdev->dev_addr);
-+      }
-+
-+      netdev_dbg(netdev, "Configuring the port %s(qcom-id:%d)\n",
-+                 netdev->name, port_id);
-+
-+      /* We expect 'port_id' to correspond to ports numbers on SoC.
-+       * These begin from '1' and hence we subtract
-+       * one when using it as an array index.
-+       */
-+      edma_ctx->netdev_arr[port_id - 1] = netdev;
-+
-+      /* Setup phylink. */
-+      ret = ppe_port_phylink_setup(port, netdev);
-+      if (ret) {
-+              netdev_dbg(netdev, "EDMA port phylink setup for netdevice %s\n",
-+                         netdev->name);
-+              goto port_phylink_setup_fail;
-+      }
-+
-+      /* Register the network interface. */
-+      ret = register_netdev(netdev);
-+      if (ret) {
-+              netdev_dbg(netdev, "Error registering netdevice %s\n",
-+                         netdev->name);
-+              goto register_netdev_fail;
-+      }
-+
-+      netdev_dbg(netdev, "Setup EDMA port GMAC%d done\n", port_id);
-+      return ret;
-+
-+register_netdev_fail:
-+      ppe_port_phylink_destroy(port);
-+port_phylink_setup_fail:
-+      free_netdev(netdev);
-+      edma_ctx->netdev_arr[port_id - 1] = NULL;
-+
-+      return ret;
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_port.h
-@@ -0,0 +1,31 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __EDMA_PORTS__
-+#define __EDMA_PORTS__
-+
-+#include "ppe_port.h"
-+
-+#define EDMA_NETDEV_FEATURES          (NETIF_F_FRAGLIST \
-+                                      | NETIF_F_SG \
-+                                      | NETIF_F_RXCSUM \
-+                                      | NETIF_F_HW_CSUM \
-+                                      | NETIF_F_TSO \
-+                                      | NETIF_F_TSO6)
-+
-+/**
-+ * struct edma_port_priv - EDMA port priv structure.
-+ * @ppe_port: Pointer to PPE port
-+ * @netdev: Corresponding netdevice
-+ * @flags: Feature flags
-+ */
-+struct edma_port_priv {
-+      struct ppe_port *ppe_port;
-+      struct net_device *netdev;
-+      unsigned long flags;
-+};
-+
-+void edma_port_destroy(struct ppe_port *port);
-+int edma_port_setup(struct ppe_port *port);
-+#endif
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
-@@ -13,6 +13,7 @@
- #include <linux/regmap.h>
- #include <linux/rtnetlink.h>
-+#include "edma_port.h"
- #include "ppe.h"
- #include "ppe_port.h"
- #include "ppe_regs.h"
-@@ -1277,12 +1278,26 @@ int ppe_port_mac_init(struct ppe_device
-                       goto err_port_node;
-               }
-+              ret = edma_port_setup(&ppe_ports->port[i]);
-+              if (ret) {
-+                      dev_err(ppe_dev->dev, "QCOM EDMA port setup failed\n");
-+                      i--;
-+                      goto err_port_setup;
-+              }
-+
-               i++;
-       }
-       of_node_put(ports_node);
-       return 0;
-+err_port_setup:
-+      /* Destroy edma ports created till now */
-+      while (i >= 0) {
-+              edma_port_destroy(&ppe_ports->port[i]);
-+              i--;
-+      }
-+
- err_port_clk:
-       for (j = 0; j < i; j++)
-               ppe_port_clock_deinit(&ppe_ports->port[j]);
-@@ -1307,6 +1322,10 @@ void ppe_port_mac_deinit(struct ppe_devi
-       for (i = 0; i < ppe_dev->ports->num; i++) {
-               ppe_port = &ppe_dev->ports->port[i];
-+
-+              /* Destroy all phylinks and edma ports */
-+              edma_port_destroy(ppe_port);
-+
-               ppe_port_clock_deinit(ppe_port);
-       }
- }
diff --git a/target/linux/qualcommbe/patches-6.12/0344-net-ethernet-qualcomm-Add-Rx-Ethernet-DMA-support.patch b/target/linux/qualcommbe/patches-6.12/0344-net-ethernet-qualcomm-Add-Rx-Ethernet-DMA-support.patch
deleted file mode 100644 (file)
index eb10a00..0000000
+++ /dev/null
@@ -1,2454 +0,0 @@
-From b5c8c5d3888328321e8be1db50b75dff8f514e51 Mon Sep 17 00:00:00 2001
-From: Suruchi Agarwal <quic_suruchia@quicinc.com>
-Date: Thu, 21 Mar 2024 16:21:19 -0700
-Subject: [PATCH] net: ethernet: qualcomm: Add Rx Ethernet DMA support
-
-Add Rx queues, rings, descriptors configurations and
-DMA support for the EDMA.
-
-Change-Id: I612bcd661e74d5bf3ecb33de10fd5298d18ff7e9
-Co-developed-by: Pavithra R <quic_pavir@quicinc.com>
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
-Signed-off-by: Suruchi Agarwal <quic_suruchia@quicinc.com>
-Alex G: add missing functions that were previously in ppe_api.c:
-        - ppe_edma_queue_resource_get()
-        - ppe_edma_ring_to_queues_config()
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/ethernet/qualcomm/ppe/Makefile    |   2 +-
- drivers/net/ethernet/qualcomm/ppe/edma.c      | 214 +++-
- drivers/net/ethernet/qualcomm/ppe/edma.h      |  22 +-
- .../net/ethernet/qualcomm/ppe/edma_cfg_rx.c   | 964 ++++++++++++++++++
- .../net/ethernet/qualcomm/ppe/edma_cfg_rx.h   |  48 +
- drivers/net/ethernet/qualcomm/ppe/edma_port.c |  39 +-
- drivers/net/ethernet/qualcomm/ppe/edma_port.h |  31 +
- drivers/net/ethernet/qualcomm/ppe/edma_rx.c   | 622 +++++++++++
- drivers/net/ethernet/qualcomm/ppe/edma_rx.h   | 287 ++++++
- 9 files changed, 2224 insertions(+), 5 deletions(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.h
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_rx.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_rx.h
-
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -7,4 +7,4 @@ obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
- qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o ppe_port.o
- #EDMA
--qcom-ppe-objs += edma.o edma_port.o
-+qcom-ppe-objs += edma.o edma_cfg_rx.o edma_port.o edma_rx.o
---- a/drivers/net/ethernet/qualcomm/ppe/edma.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.c
-@@ -18,12 +18,23 @@
- #include <linux/reset.h>
- #include "edma.h"
-+#include "edma_cfg_rx.h"
- #include "ppe_regs.h"
- #define EDMA_IRQ_NAME_SIZE            32
- /* Global EDMA context. */
- struct edma_context *edma_ctx;
-+static char **edma_rxdesc_irq_name;
-+
-+/* Module params. */
-+static int page_mode;
-+module_param(page_mode, int, 0);
-+MODULE_PARM_DESC(page_mode, "Enable page mode (default:0)");
-+
-+static int rx_buff_size;
-+module_param(rx_buff_size, int, 0640);
-+MODULE_PARM_DESC(rx_buff_size, "Rx Buffer size for Jumbo MRU value (default:0)");
- /* Priority to multi-queue mapping. */
- static u8 edma_pri_map[PPE_QUEUE_INTER_PRI_NUM] = {
-@@ -178,6 +189,59 @@ static int edma_configure_ucast_prio_map
-       return ret;
- }
-+static int edma_irq_register(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      int ret;
-+      u32 i;
-+
-+      /* Request IRQ for RXDESC rings. */
-+      edma_rxdesc_irq_name = kzalloc((sizeof(char *) * rx->num_rings),
-+                                     GFP_KERNEL);
-+      if (!edma_rxdesc_irq_name)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              edma_rxdesc_irq_name[i] = kzalloc((sizeof(char *) * EDMA_IRQ_NAME_SIZE),
-+                                                GFP_KERNEL);
-+              if (!edma_rxdesc_irq_name[i]) {
-+                      ret = -ENOMEM;
-+                      goto rxdesc_irq_name_alloc_fail;
-+              }
-+
-+              snprintf(edma_rxdesc_irq_name[i], 20, "edma_rxdesc_%d",
-+                       rx->ring_start + i);
-+
-+              irq_set_status_flags(edma_ctx->intr_info.intr_rx[i], IRQ_DISABLE_UNLAZY);
-+
-+              ret = request_irq(edma_ctx->intr_info.intr_rx[i],
-+                                edma_rx_handle_irq, IRQF_SHARED,
-+                                edma_rxdesc_irq_name[i],
-+                                (void *)&edma_ctx->rx_rings[i]);
-+              if (ret) {
-+                      pr_err("RXDESC ring IRQ:%d request failed\n",
-+                             edma_ctx->intr_info.intr_rx[i]);
-+                      goto rx_desc_ring_intr_req_fail;
-+              }
-+
-+              pr_debug("RXDESC ring: %d IRQ:%d request success: %s\n",
-+                       rx->ring_start + i,
-+                       edma_ctx->intr_info.intr_rx[i],
-+                       edma_rxdesc_irq_name[i]);
-+      }
-+
-+      return 0;
-+
-+rx_desc_ring_intr_req_fail:
-+      for (i = 0; i < rx->num_rings; i++)
-+              kfree(edma_rxdesc_irq_name[i]);
-+rxdesc_irq_name_alloc_fail:
-+      kfree(edma_rxdesc_irq_name);
-+
-+      return ret;
-+}
-+
- static int edma_irq_init(void)
- {
-       struct edma_hw_info *hw_info = edma_ctx->hw_info;
-@@ -260,6 +324,16 @@ static int edma_irq_init(void)
-       return 0;
- }
-+static int edma_alloc_rings(void)
-+{
-+      if (edma_cfg_rx_rings_alloc()) {
-+              pr_err("Error in allocating Rx rings\n");
-+              return -ENOMEM;
-+      }
-+
-+      return 0;
-+}
-+
- static int edma_hw_reset(void)
- {
-       struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-@@ -343,6 +417,40 @@ static int edma_hw_configure(void)
-       if (!edma_ctx->netdev_arr)
-               return -ENOMEM;
-+      edma_ctx->dummy_dev = alloc_netdev_dummy(0);
-+      if (!edma_ctx->dummy_dev) {
-+              ret = -ENOMEM;
-+              pr_err("Failed to allocate dummy device. ret: %d\n", ret);
-+              goto dummy_dev_alloc_failed;
-+      }
-+
-+      /* Set EDMA jumbo MRU if enabled or set page mode. */
-+      if (edma_ctx->rx_buf_size) {
-+              edma_ctx->rx_page_mode = false;
-+              pr_debug("Rx Jumbo mru is enabled: %d\n", edma_ctx->rx_buf_size);
-+      } else {
-+              edma_ctx->rx_page_mode = page_mode;
-+      }
-+
-+      ret = edma_alloc_rings();
-+      if (ret) {
-+              pr_err("Error in initializaing the rings. ret: %d\n", ret);
-+              goto edma_alloc_rings_failed;
-+      }
-+
-+      /* Disable interrupts. */
-+      edma_cfg_rx_disable_interrupts();
-+
-+      edma_cfg_rx_rings_disable();
-+
-+      edma_cfg_rx_ring_mappings();
-+
-+      ret = edma_cfg_rx_rings();
-+      if (ret) {
-+              pr_err("Error in configuring Rx rings. ret: %d\n", ret);
-+              goto edma_cfg_rx_rings_failed;
-+      }
-+
-       /* Configure DMA request priority, DMA read burst length,
-        * and AXI write size.
-        */
-@@ -376,6 +484,10 @@ static int edma_hw_configure(void)
-       data |= EDMA_MISC_TX_TIMEOUT_MASK;
-       edma_ctx->intr_info.intr_mask_misc = data;
-+      edma_cfg_rx_rings_enable();
-+      edma_cfg_rx_napi_add();
-+      edma_cfg_rx_napi_enable();
-+
-       /* Global EDMA enable and padding enable. */
-       data = EDMA_PORT_PAD_EN | EDMA_PORT_EDMA_EN;
-@@ -389,11 +501,32 @@ static int edma_hw_configure(void)
-       if (ret) {
-               pr_err("Failed to initialize unicast priority map table: %d\n",
-                      ret);
--              kfree(edma_ctx->netdev_arr);
--              return ret;
-+              goto configure_ucast_prio_map_tbl_failed;
-+      }
-+
-+      /* Initialize RPS hash map table. */
-+      ret = edma_cfg_rx_rps_hash_map();
-+      if (ret) {
-+              pr_err("Failed to configure rps hash table: %d\n",
-+                     ret);
-+              goto edma_cfg_rx_rps_hash_map_failed;
-       }
-       return 0;
-+
-+edma_cfg_rx_rps_hash_map_failed:
-+configure_ucast_prio_map_tbl_failed:
-+      edma_cfg_rx_napi_disable();
-+      edma_cfg_rx_napi_delete();
-+      edma_cfg_rx_rings_disable();
-+edma_cfg_rx_rings_failed:
-+      edma_cfg_rx_rings_cleanup();
-+edma_alloc_rings_failed:
-+      free_netdev(edma_ctx->dummy_dev);
-+dummy_dev_alloc_failed:
-+      kfree(edma_ctx->netdev_arr);
-+
-+      return ret;
- }
- /**
-@@ -404,8 +537,31 @@ static int edma_hw_configure(void)
-  */
- void edma_destroy(struct ppe_device *ppe_dev)
- {
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i;
-+
-+      /* Disable interrupts. */
-+      edma_cfg_rx_disable_interrupts();
-+
-+      /* Free IRQ for RXDESC rings. */
-+      for (i = 0; i < rx->num_rings; i++) {
-+              synchronize_irq(edma_ctx->intr_info.intr_rx[i]);
-+              free_irq(edma_ctx->intr_info.intr_rx[i],
-+                       (void *)&edma_ctx->rx_rings[i]);
-+              kfree(edma_rxdesc_irq_name[i]);
-+      }
-+      kfree(edma_rxdesc_irq_name);
-+
-       kfree(edma_ctx->intr_info.intr_rx);
-       kfree(edma_ctx->intr_info.intr_txcmpl);
-+
-+      edma_cfg_rx_napi_disable();
-+      edma_cfg_rx_napi_delete();
-+      edma_cfg_rx_rings_disable();
-+      edma_cfg_rx_rings_cleanup();
-+
-+      free_netdev(edma_ctx->dummy_dev);
-       kfree(edma_ctx->netdev_arr);
- }
-@@ -428,6 +584,7 @@ int edma_setup(struct ppe_device *ppe_de
-       edma_ctx->hw_info = &ipq9574_hw_info;
-       edma_ctx->ppe_dev = ppe_dev;
-+      edma_ctx->rx_buf_size = rx_buff_size;
-       /* Configure the EDMA common clocks. */
-       ret = edma_clock_init();
-@@ -450,6 +607,16 @@ int edma_setup(struct ppe_device *ppe_de
-               return ret;
-       }
-+      ret = edma_irq_register();
-+      if (ret) {
-+              dev_err(dev, "Error in irq registration\n");
-+              kfree(edma_ctx->intr_info.intr_rx);
-+              kfree(edma_ctx->intr_info.intr_txcmpl);
-+              return ret;
-+      }
-+
-+      edma_cfg_rx_enable_interrupts();
-+
-       dev_info(dev, "EDMA configuration successful\n");
-       return 0;
-@@ -478,3 +645,46 @@ int ppe_edma_queue_offset_config(struct
-       return ppe_queue_ucast_offset_hash_set(ppe_dev, 0,
-                                              index, queue_offset);
- }
-+
-+/**
-+ * ppe_edma_queue_resource_get - Get EDMA queue resource
-+ * @ppe_dev: PPE device
-+ * @type: Resource type
-+ * @res_start: Resource start ID returned
-+ * @res_end: Resource end ID returned
-+ *
-+ * PPE EDMA queue resource includes unicast queue and multicast queue.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+int ppe_edma_queue_resource_get(struct ppe_device *ppe_dev, int type,
-+                              int *res_start, int *res_end)
-+{
-+      if (type != PPE_RES_UCAST && type != PPE_RES_MCAST)
-+              return -EINVAL;
-+
-+      return ppe_port_resource_get(ppe_dev, 0, type, res_start, res_end);
-+};
-+
-+/**
-+ * ppe_edma_ring_to_queues_config - Map EDMA ring to PPE queues
-+ * @ppe_dev: PPE device
-+ * @ring_id: EDMA ring ID
-+ * @num: Number of queues mapped to EDMA ring
-+ * @queues: PPE queue IDs
-+ *
-+ * PPE queues are configured to map with the special EDMA ring ID.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+int ppe_edma_ring_to_queues_config(struct ppe_device *ppe_dev, int ring_id,
-+                                 int num, int queues[] __counted_by(num))
-+{
-+      u32 queue_bmap[PPE_RING_TO_QUEUE_BITMAP_WORD_CNT] = {};
-+      int index;
-+
-+      for (index = 0; index < num; index++)
-+              queue_bmap[queues[index] / 32] |= BIT_MASK(queues[index] % 32);
-+
-+      return ppe_ring_queue_map_set(ppe_dev, ring_id, queue_bmap);
-+}
---- a/drivers/net/ethernet/qualcomm/ppe/edma.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.h
-@@ -6,6 +6,7 @@
- #define __EDMA_MAIN__
- #include "ppe_config.h"
-+#include "edma_rx.h"
- /* One clock cycle = 1/(EDMA clock frequency in Mhz) micro seconds.
-  *
-@@ -29,6 +30,11 @@
- /* Interface ID start. */
- #define EDMA_START_IFNUM   1
-+#define EDMA_DESC_AVAIL_COUNT(head, tail, _max) ({ \
-+                      typeof(_max) (max) = (_max); \
-+                      ((((head) - (tail)) + \
-+                      (max)) & ((max) - 1)); })
-+
- /**
-  * enum ppe_queue_class_type - PPE queue class type
-  * @PPE_QUEUE_CLASS_PRIORITY: Queue offset configured from internal priority
-@@ -92,18 +98,28 @@ struct edma_intr_info {
- /**
-  * struct edma_context - EDMA context.
-  * @netdev_arr: Net device for each EDMA port
-+ * @dummy_dev: Dummy netdevice for RX DMA
-  * @ppe_dev: PPE device
-  * @hw_info: EDMA Hardware info
-  * @intr_info: EDMA Interrupt info
-+ * @rxfill_rings: Rx fill Rings, SW is producer
-+ * @rx_rings: Rx Desc Rings, SW is consumer
-+ * @rx_page_mode: Page mode enabled or disabled
-+ * @rx_buf_size: Rx buffer size for Jumbo MRU
-  */
- struct edma_context {
-       struct net_device **netdev_arr;
-+      struct net_device *dummy_dev;
-       struct ppe_device *ppe_dev;
-       struct edma_hw_info *hw_info;
-       struct edma_intr_info intr_info;
-+      struct edma_rxfill_ring *rxfill_rings;
-+      struct edma_rxdesc_ring *rx_rings;
-+      u32 rx_page_mode;
-+      u32 rx_buf_size;
- };
--/* Global EDMA context. */
-+/* Global EDMA context */
- extern struct edma_context *edma_ctx;
- void edma_destroy(struct ppe_device *ppe_dev);
-@@ -111,6 +127,10 @@ int edma_setup(struct ppe_device *ppe_de
- int ppe_edma_queue_offset_config(struct ppe_device *ppe_dev,
-                                enum ppe_queue_class_type class,
-                                int index, int queue_offset);
-+int ppe_edma_queue_resource_get(struct ppe_device *ppe_dev, int type,
-+                              int *res_start, int *res_end);
-+int ppe_edma_ring_to_queues_config(struct ppe_device *ppe_dev, int ring_id,
-+                                 int num, int queues[] __counted_by(num));
- #endif
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.c
-@@ -0,0 +1,964 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* Configure rings, Buffers and NAPI for receive path along with
-+ * providing APIs to enable, disable, clean and map the Rx rings.
-+ */
-+
-+#include <linux/cpumask.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/printk.h>
-+#include <linux/regmap.h>
-+#include <linux/skbuff.h>
-+
-+#include "edma.h"
-+#include "edma_cfg_rx.h"
-+#include "ppe.h"
-+#include "ppe_regs.h"
-+
-+/* EDMA Queue ID to Ring ID Table. */
-+#define EDMA_QID2RID_TABLE_MEM(q)     (0xb9000 + (0x4 * (q)))
-+
-+/* Rx ring queue offset. */
-+#define EDMA_QUEUE_OFFSET(q_id)       ((q_id) / EDMA_MAX_PRI_PER_CORE)
-+
-+/* Rx EDMA maximum queue supported. */
-+#define EDMA_CPU_PORT_QUEUE_MAX(queue_start)  \
-+                      ((queue_start) + (EDMA_MAX_PRI_PER_CORE * num_possible_cpus()) - 1)
-+
-+/* EDMA Queue ID to Ring ID configuration. */
-+#define EDMA_QID2RID_NUM_PER_REG      4
-+
-+int rx_queues[] = {0, 8, 16, 24};
-+
-+static u32 edma_rx_ring_queue_map[][EDMA_MAX_CORE] = {{ 0, 8, 16, 24 },
-+                                              { 1, 9, 17, 25 },
-+                                              { 2, 10, 18, 26 },
-+                                              { 3, 11, 19, 27 },
-+                                              { 4, 12, 20, 28 },
-+                                              { 5, 13, 21, 29 },
-+                                              { 6, 14, 22, 30 },
-+                                              { 7, 15, 23, 31 }};
-+
-+static int edma_cfg_rx_desc_rings_reset_queue_mapping(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i, ret;
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[i];
-+
-+              ret = ppe_edma_ring_to_queues_config(edma_ctx->ppe_dev, rxdesc_ring->ring_id,
-+                                                   ARRAY_SIZE(rx_queues), rx_queues);
-+              if (ret) {
-+                      pr_err("Error in unmapping rxdesc ring %d to PPE queue mapping to disable its backpressure configuration\n",
-+                             i);
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int edma_cfg_rx_desc_ring_reset_queue_priority(u32 rxdesc_ring_idx)
-+{
-+      u32 i, queue_id, ret;
-+
-+      for (i = 0; i < EDMA_MAX_PRI_PER_CORE; i++) {
-+              queue_id = edma_rx_ring_queue_map[i][rxdesc_ring_idx];
-+
-+              ret = ppe_queue_priority_set(edma_ctx->ppe_dev, queue_id, i);
-+              if (ret) {
-+                      pr_err("Error in resetting %u queue's priority\n",
-+                             queue_id);
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int edma_cfg_rx_desc_ring_reset_queue_config(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i, ret;
-+
-+      if (unlikely(rx->num_rings > num_possible_cpus())) {
-+              pr_err("Invalid count of rxdesc rings: %d\n",
-+                     rx->num_rings);
-+              return -EINVAL;
-+      }
-+
-+      /* Unmap Rxdesc ring to PPE queue mapping */
-+      ret = edma_cfg_rx_desc_rings_reset_queue_mapping();
-+      if (ret)        {
-+              pr_err("Error in resetting Rx desc ring backpressure config\n");
-+              return ret;
-+      }
-+
-+      /* Reset the priority for PPE queues mapped to Rx rings */
-+      for (i = 0; i < rx->num_rings; i++) {
-+              ret =  edma_cfg_rx_desc_ring_reset_queue_priority(i);
-+              if (ret)        {
-+                      pr_err("Error in resetting ring:%d queue's priority\n",
-+                             i + rx->ring_start);
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int edma_cfg_rx_desc_ring_to_queue_mapping(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i;
-+      int ret;
-+
-+      /* Rxdesc ring to PPE queue mapping */
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[i];
-+
-+              ret = ppe_edma_ring_to_queues_config(edma_ctx->ppe_dev,
-+                                                   rxdesc_ring->ring_id,
-+                                              ARRAY_SIZE(rx_queues), rx_queues);
-+              if (ret) {
-+                      pr_err("Error in configuring Rx ring to PPE queue mapping, ret: %d, id: %d\n",
-+                             ret, rxdesc_ring->ring_id);
-+                      if (!edma_cfg_rx_desc_rings_reset_queue_mapping())
-+                              pr_err("Error in resetting Rx desc ringbackpressure configurations\n");
-+
-+                      return ret;
-+              }
-+
-+              pr_debug("Rx desc ring %d to PPE queue mapping for backpressure:\n",
-+                       rxdesc_ring->ring_id);
-+      }
-+
-+      return 0;
-+}
-+
-+static void edma_cfg_rx_desc_ring_configure(struct edma_rxdesc_ring *rxdesc_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 data, reg;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_BA(rxdesc_ring->ring_id);
-+      regmap_write(regmap, reg, (u32)(rxdesc_ring->pdma & EDMA_RXDESC_BA_MASK));
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_PREHEADER_BA(rxdesc_ring->ring_id);
-+      regmap_write(regmap, reg, (u32)(rxdesc_ring->sdma & EDMA_RXDESC_PREHEADER_BA_MASK));
-+
-+      data = rxdesc_ring->count & EDMA_RXDESC_RING_SIZE_MASK;
-+      data |= (EDMA_RXDESC_PL_DEFAULT_VALUE & EDMA_RXDESC_PL_OFFSET_MASK)
-+               << EDMA_RXDESC_PL_OFFSET_SHIFT;
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_RING_SIZE(rxdesc_ring->ring_id);
-+      regmap_write(regmap, reg, data);
-+
-+      /* Configure the Mitigation timer */
-+      data = EDMA_MICROSEC_TO_TIMER_UNIT(EDMA_RX_MITIGATION_TIMER_DEF,
-+                                         ppe_dev->clk_rate / MHZ);
-+      data = ((data & EDMA_RX_MOD_TIMER_INIT_MASK)
-+                      << EDMA_RX_MOD_TIMER_INIT_SHIFT);
-+      pr_debug("EDMA Rx mitigation timer value: %d\n", data);
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RX_MOD_TIMER(rxdesc_ring->ring_id);
-+      regmap_write(regmap, reg, data);
-+
-+      /* Configure the Mitigation packet count */
-+      data = (EDMA_RX_MITIGATION_PKT_CNT_DEF & EDMA_RXDESC_LOW_THRE_MASK)
-+                      << EDMA_RXDESC_LOW_THRE_SHIFT;
-+      pr_debug("EDMA Rx mitigation packet count value: %d\n", data);
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_UGT_THRE(rxdesc_ring->ring_id);
-+      regmap_write(regmap, reg, data);
-+
-+      /* Enable ring. Set ret mode to 'opaque'. */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RX_INT_CTRL(rxdesc_ring->ring_id);
-+      regmap_write(regmap, reg, EDMA_RX_NE_INT_EN);
-+}
-+
-+static void edma_cfg_rx_qid_to_rx_desc_ring_mapping(void)
-+{
-+      u32 desc_index, ring_index, reg_index, data, q_id;
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 mcast_start, mcast_end, reg;
-+      int ret;
-+
-+      desc_index = (rx->ring_start & EDMA_RX_RING_ID_MASK);
-+
-+      /* Here map all the queues to ring. */
-+      for (q_id = EDMA_RX_QUEUE_START;
-+              q_id <= EDMA_CPU_PORT_QUEUE_MAX(EDMA_RX_QUEUE_START);
-+                      q_id += EDMA_QID2RID_NUM_PER_REG) {
-+              reg_index = q_id / EDMA_QID2RID_NUM_PER_REG;
-+              ring_index = desc_index + EDMA_QUEUE_OFFSET(q_id);
-+
-+              data = FIELD_PREP(EDMA_RX_RING_ID_QUEUE0_MASK, ring_index);
-+              data |= FIELD_PREP(EDMA_RX_RING_ID_QUEUE1_MASK, ring_index);
-+              data |= FIELD_PREP(EDMA_RX_RING_ID_QUEUE2_MASK, ring_index);
-+              data |= FIELD_PREP(EDMA_RX_RING_ID_QUEUE3_MASK, ring_index);
-+
-+              reg = EDMA_BASE_OFFSET + EDMA_QID2RID_TABLE_MEM(reg_index);
-+              regmap_write(regmap, reg, data);
-+              pr_debug("Configure QID2RID: %d reg:0x%x to 0x%x, desc_index: %d, reg_index: %d\n",
-+                       q_id, EDMA_QID2RID_TABLE_MEM(reg_index), data, desc_index, reg_index);
-+      }
-+
-+      ret = ppe_edma_queue_resource_get(edma_ctx->ppe_dev, PPE_RES_MCAST,
-+                                        &mcast_start, &mcast_end);
-+      if (ret < 0) {
-+              pr_err("Error in extracting multicast queue values\n");
-+              return;
-+      }
-+
-+      /* Map multicast queues to the first Rx ring. */
-+      desc_index = (rx->ring_start & EDMA_RX_RING_ID_MASK);
-+      for (q_id = mcast_start; q_id <= mcast_end;
-+                      q_id += EDMA_QID2RID_NUM_PER_REG) {
-+              reg_index = q_id / EDMA_QID2RID_NUM_PER_REG;
-+
-+              data = FIELD_PREP(EDMA_RX_RING_ID_QUEUE0_MASK, desc_index);
-+              data |= FIELD_PREP(EDMA_RX_RING_ID_QUEUE1_MASK, desc_index);
-+              data |= FIELD_PREP(EDMA_RX_RING_ID_QUEUE2_MASK, desc_index);
-+              data |= FIELD_PREP(EDMA_RX_RING_ID_QUEUE3_MASK, desc_index);
-+
-+              reg = EDMA_BASE_OFFSET + EDMA_QID2RID_TABLE_MEM(reg_index);
-+              regmap_write(regmap, reg, data);
-+
-+              pr_debug("Configure QID2RID: %d reg:0x%x to 0x%x\n",
-+                       q_id, EDMA_QID2RID_TABLE_MEM(reg_index), data);
-+      }
-+}
-+
-+static void edma_cfg_rx_rings_to_rx_fill_mapping(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i, data, reg;
-+
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_0_ADDR, 0);
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_1_ADDR, 0);
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_2_ADDR, 0);
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring = &edma_ctx->rx_rings[i];
-+              u32 data, reg, ring_id;
-+
-+              ring_id = rxdesc_ring->ring_id;
-+              if (ring_id >= 0 && ring_id <= 9)
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_0_ADDR;
-+              else if (ring_id >= 10 && ring_id <= 19)
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_1_ADDR;
-+              else
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_2_ADDR;
-+
-+              pr_debug("Configure RXDESC:%u to use RXFILL:%u\n",
-+                       ring_id,
-+                       rxdesc_ring->rxfill->ring_id);
-+
-+               /* Set the Rx fill ring number in the mapping register. */
-+              regmap_read(regmap, reg, &data);
-+              data |= (rxdesc_ring->rxfill->ring_id &
-+                       EDMA_RXDESC2FILL_MAP_RXDESC_MASK) <<
-+                       ((ring_id % 10) * 3);
-+              regmap_write(regmap, reg, data);
-+      }
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_0_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_RXDESC2FILL_MAP_0_ADDR: 0x%x\n", data);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_1_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_RXDESC2FILL_MAP_1_ADDR: 0x%x\n", data);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC2FILL_MAP_2_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_RXDESC2FILL_MAP_2_ADDR: 0x%x\n", data);
-+}
-+
-+/**
-+ * edma_cfg_rx_rings_enable - Enable Rx and Rxfill rings
-+ *
-+ * Enable Rx and Rxfill rings.
-+ */
-+void edma_cfg_rx_rings_enable(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rxfill = hw_info->rxfill;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i, reg;
-+
-+      /* Enable Rx rings */
-+      for (i = rx->ring_start; i < rx->ring_start + rx->num_rings; i++) {
-+              u32 data;
-+
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_CTRL(i);
-+              regmap_read(regmap, reg, &data);
-+              data |= EDMA_RXDESC_RX_EN;
-+              regmap_write(regmap, reg, data);
-+      }
-+
-+      for (i = rxfill->ring_start; i < rxfill->ring_start + rxfill->num_rings; i++) {
-+              u32 data;
-+
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXFILL_RING_EN(i);
-+              regmap_read(regmap, reg, &data);
-+              data |= EDMA_RXFILL_RING_EN;
-+              regmap_write(regmap, reg, data);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_rx_rings_disable - Disable Rx and Rxfill rings
-+ *
-+ * Disable Rx and Rxfill rings.
-+ */
-+void edma_cfg_rx_rings_disable(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rxfill = hw_info->rxfill;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i, reg;
-+
-+      /* Disable Rx rings */
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring = NULL;
-+              u32 data;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[i];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_CTRL(rxdesc_ring->ring_id);
-+              regmap_read(regmap, reg, &data);
-+              data &= ~EDMA_RXDESC_RX_EN;
-+              regmap_write(regmap, reg, data);
-+      }
-+
-+      /* Disable RxFill Rings */
-+      for (i = 0; i < rxfill->num_rings; i++) {
-+              struct edma_rxfill_ring *rxfill_ring = NULL;
-+              u32 data;
-+
-+              rxfill_ring = &edma_ctx->rxfill_rings[i];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXFILL_RING_EN(rxfill_ring->ring_id);
-+              regmap_read(regmap, reg, &data);
-+              data &= ~EDMA_RXFILL_RING_EN;
-+              regmap_write(regmap, reg, data);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_rx_mappings - Setup RX ring mapping
-+ *
-+ * Setup queue ID to Rx desc ring mapping.
-+ */
-+void edma_cfg_rx_ring_mappings(void)
-+{
-+      edma_cfg_rx_qid_to_rx_desc_ring_mapping();
-+      edma_cfg_rx_rings_to_rx_fill_mapping();
-+}
-+
-+static void edma_cfg_rx_fill_ring_cleanup(struct edma_rxfill_ring *rxfill_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct device *dev = ppe_dev->dev;
-+      u16 cons_idx, curr_idx;
-+      u32 data, reg;
-+
-+      /* Get RxFill ring producer index */
-+      curr_idx = rxfill_ring->prod_idx & EDMA_RXFILL_PROD_IDX_MASK;
-+
-+      /* Get RxFill ring consumer index */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXFILL_CONS_IDX(rxfill_ring->ring_id);
-+      regmap_read(regmap, reg, &data);
-+      cons_idx = data & EDMA_RXFILL_CONS_IDX_MASK;
-+
-+      while (curr_idx != cons_idx) {
-+              struct edma_rxfill_desc *rxfill_desc;
-+              struct sk_buff *skb;
-+
-+              /* Get RxFill descriptor */
-+              rxfill_desc = EDMA_RXFILL_DESC(rxfill_ring, cons_idx);
-+
-+              cons_idx = (cons_idx + 1) & EDMA_RX_RING_SIZE_MASK;
-+
-+              /* Get skb from opaque */
-+              skb = (struct sk_buff *)EDMA_RXFILL_OPAQUE_GET(rxfill_desc);
-+              if (unlikely(!skb)) {
-+                      pr_err("Empty skb reference at index:%d\n",
-+                             cons_idx);
-+                      continue;
-+              }
-+
-+              dev_kfree_skb_any(skb);
-+      }
-+
-+      /* Free RxFill ring descriptors */
-+      dma_free_coherent(dev, (sizeof(struct edma_rxfill_desc)
-+                         * rxfill_ring->count),
-+                         rxfill_ring->desc, rxfill_ring->dma);
-+      rxfill_ring->desc = NULL;
-+      rxfill_ring->dma = (dma_addr_t)0;
-+}
-+
-+static int edma_cfg_rx_fill_ring_dma_alloc(struct edma_rxfill_ring *rxfill_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev = ppe_dev->dev;
-+
-+      /* Allocate RxFill ring descriptors */
-+      rxfill_ring->desc = dma_alloc_coherent(dev, (sizeof(struct edma_rxfill_desc)
-+                                             * rxfill_ring->count),
-+                                             &rxfill_ring->dma,
-+                                             GFP_KERNEL | __GFP_ZERO);
-+      if (unlikely(!rxfill_ring->desc))
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+static int edma_cfg_rx_desc_ring_dma_alloc(struct edma_rxdesc_ring *rxdesc_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev = ppe_dev->dev;
-+
-+      rxdesc_ring->pdesc = dma_alloc_coherent(dev, (sizeof(struct edma_rxdesc_pri)
-+                                              * rxdesc_ring->count),
-+                              &rxdesc_ring->pdma, GFP_KERNEL | __GFP_ZERO);
-+      if (unlikely(!rxdesc_ring->pdesc))
-+              return -ENOMEM;
-+
-+      rxdesc_ring->sdesc = dma_alloc_coherent(dev, (sizeof(struct edma_rxdesc_sec)
-+                              * rxdesc_ring->count),
-+                              &rxdesc_ring->sdma, GFP_KERNEL | __GFP_ZERO);
-+      if (unlikely(!rxdesc_ring->sdesc)) {
-+              dma_free_coherent(dev, (sizeof(struct edma_rxdesc_pri)
-+                                * rxdesc_ring->count),
-+                                rxdesc_ring->pdesc,
-+                                rxdesc_ring->pdma);
-+              rxdesc_ring->pdesc = NULL;
-+              rxdesc_ring->pdma = (dma_addr_t)0;
-+              return -ENOMEM;
-+      }
-+
-+      return 0;
-+}
-+
-+static void edma_cfg_rx_desc_ring_cleanup(struct edma_rxdesc_ring *rxdesc_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct device *dev = ppe_dev->dev;
-+      u32 prod_idx, cons_idx, reg;
-+
-+      /* Get Rxdesc consumer & producer indices */
-+      cons_idx = rxdesc_ring->cons_idx & EDMA_RXDESC_CONS_IDX_MASK;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_PROD_IDX(rxdesc_ring->ring_id);
-+      regmap_read(regmap, reg, &prod_idx);
-+      prod_idx = prod_idx & EDMA_RXDESC_PROD_IDX_MASK;
-+
-+      /* Free any buffers assigned to any descriptors */
-+      while (cons_idx != prod_idx) {
-+              struct edma_rxdesc_pri *rxdesc_pri =
-+                      EDMA_RXDESC_PRI_DESC(rxdesc_ring, cons_idx);
-+              struct sk_buff *skb;
-+
-+              /* Update consumer index */
-+              cons_idx = (cons_idx + 1) & EDMA_RX_RING_SIZE_MASK;
-+
-+              /* Get opaque from Rxdesc */
-+              skb = (struct sk_buff *)EDMA_RXDESC_OPAQUE_GET(rxdesc_pri);
-+              if (unlikely(!skb)) {
-+                      pr_warn("Empty skb reference at index:%d\n",
-+                              cons_idx);
-+                      continue;
-+              }
-+
-+              dev_kfree_skb_any(skb);
-+      }
-+
-+      /* Update the consumer index */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_CONS_IDX(rxdesc_ring->ring_id);
-+      regmap_write(regmap, reg, cons_idx);
-+
-+      /* Free Rxdesc ring descriptor */
-+      dma_free_coherent(dev, (sizeof(struct edma_rxdesc_pri)
-+                        * rxdesc_ring->count), rxdesc_ring->pdesc,
-+                        rxdesc_ring->pdma);
-+      rxdesc_ring->pdesc = NULL;
-+      rxdesc_ring->pdma = (dma_addr_t)0;
-+
-+      /* Free any buffers assigned to any secondary ring descriptors */
-+      dma_free_coherent(dev, (sizeof(struct edma_rxdesc_sec)
-+                        * rxdesc_ring->count), rxdesc_ring->sdesc,
-+                        rxdesc_ring->sdma);
-+      rxdesc_ring->sdesc = NULL;
-+      rxdesc_ring->sdma = (dma_addr_t)0;
-+}
-+
-+static int edma_cfg_rx_rings_setup(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rxfill = hw_info->rxfill;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 ring_idx, alloc_size, buf_len;
-+
-+      /* Set buffer allocation size */
-+      if (edma_ctx->rx_buf_size) {
-+              alloc_size = edma_ctx->rx_buf_size +
-+                              EDMA_RX_SKB_HEADROOM + NET_IP_ALIGN;
-+              buf_len = alloc_size - EDMA_RX_SKB_HEADROOM - NET_IP_ALIGN;
-+      } else if (edma_ctx->rx_page_mode) {
-+              alloc_size = EDMA_RX_PAGE_MODE_SKB_SIZE +
-+                              EDMA_RX_SKB_HEADROOM + NET_IP_ALIGN;
-+              buf_len = PAGE_SIZE;
-+      } else {
-+              alloc_size = EDMA_RX_BUFFER_SIZE;
-+              buf_len = alloc_size - EDMA_RX_SKB_HEADROOM - NET_IP_ALIGN;
-+      }
-+
-+      pr_debug("EDMA ctx:%p rx_ring alloc_size=%d, buf_len=%d\n",
-+               edma_ctx, alloc_size, buf_len);
-+
-+      /* Allocate Rx fill ring descriptors */
-+      for (ring_idx = 0; ring_idx < rxfill->num_rings; ring_idx++) {
-+              u32 ret;
-+              struct edma_rxfill_ring *rxfill_ring = NULL;
-+
-+              rxfill_ring = &edma_ctx->rxfill_rings[ring_idx];
-+              rxfill_ring->count = EDMA_RX_RING_SIZE;
-+              rxfill_ring->ring_id = rxfill->ring_start + ring_idx;
-+              rxfill_ring->alloc_size = alloc_size;
-+              rxfill_ring->buf_len = buf_len;
-+              rxfill_ring->page_mode = edma_ctx->rx_page_mode;
-+
-+              ret = edma_cfg_rx_fill_ring_dma_alloc(rxfill_ring);
-+              if (ret) {
-+                      pr_err("Error in setting up %d rxfill ring. ret: %d",
-+                             rxfill_ring->ring_id, ret);
-+                      while (--ring_idx >= 0)
-+                              edma_cfg_rx_fill_ring_cleanup(&edma_ctx->rxfill_rings[ring_idx]);
-+
-+                      return -ENOMEM;
-+              }
-+      }
-+
-+      /* Allocate RxDesc ring descriptors */
-+      for (ring_idx = 0; ring_idx < rx->num_rings; ring_idx++) {
-+              u32 index, queue_id = EDMA_RX_QUEUE_START;
-+              struct edma_rxdesc_ring *rxdesc_ring = NULL;
-+              u32 ret;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[ring_idx];
-+              rxdesc_ring->count = EDMA_RX_RING_SIZE;
-+              rxdesc_ring->ring_id = rx->ring_start + ring_idx;
-+
-+              if (queue_id > EDMA_CPU_PORT_QUEUE_MAX(EDMA_RX_QUEUE_START)) {
-+                      pr_err("Invalid queue_id: %d\n", queue_id);
-+                      while (--ring_idx >= 0)
-+                              edma_cfg_rx_desc_ring_cleanup(&edma_ctx->rx_rings[ring_idx]);
-+
-+                      goto rxdesc_mem_alloc_fail;
-+              }
-+
-+              /* Create a mapping between RX Desc ring and Rx fill ring.
-+               * Number of fill rings are lesser than the descriptor rings
-+               * Share the fill rings across descriptor rings.
-+               */
-+              index = rxfill->ring_start +
-+                              (ring_idx % rxfill->num_rings);
-+              rxdesc_ring->rxfill = &edma_ctx->rxfill_rings[index
-+                                              - rxfill->ring_start];
-+
-+              ret = edma_cfg_rx_desc_ring_dma_alloc(rxdesc_ring);
-+              if (ret) {
-+                      pr_err("Error in setting up %d rxdesc ring. ret: %d",
-+                             rxdesc_ring->ring_id, ret);
-+                      while (--ring_idx >= 0)
-+                              edma_cfg_rx_desc_ring_cleanup(&edma_ctx->rx_rings[ring_idx]);
-+
-+                      goto rxdesc_mem_alloc_fail;
-+              }
-+      }
-+
-+      pr_debug("Rx descriptor count for Rx desc and Rx fill rings : %d\n",
-+               EDMA_RX_RING_SIZE);
-+
-+      return 0;
-+
-+rxdesc_mem_alloc_fail:
-+      for (ring_idx = 0; ring_idx < rxfill->num_rings; ring_idx++)
-+              edma_cfg_rx_fill_ring_cleanup(&edma_ctx->rxfill_rings[ring_idx]);
-+
-+      return -ENOMEM;
-+}
-+
-+/**
-+ * edma_cfg_rx_buff_size_setup - Configure EDMA Rx jumbo buffer
-+ *
-+ * Configure EDMA Rx jumbo buffer
-+ */
-+void edma_cfg_rx_buff_size_setup(void)
-+{
-+      if (edma_ctx->rx_buf_size) {
-+              edma_ctx->rx_page_mode = false;
-+              pr_debug("Rx Jumbo mru is enabled: %d\n", edma_ctx->rx_buf_size);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_rx_rings_alloc - Allocate EDMA Rx rings
-+ *
-+ * Allocate EDMA Rx rings.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+int edma_cfg_rx_rings_alloc(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rxfill = hw_info->rxfill;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      int ret;
-+
-+      edma_ctx->rxfill_rings = kzalloc((sizeof(*edma_ctx->rxfill_rings) *
-+                                       rxfill->num_rings),
-+                                       GFP_KERNEL);
-+      if (!edma_ctx->rxfill_rings)
-+              return -ENOMEM;
-+
-+      edma_ctx->rx_rings = kzalloc((sizeof(*edma_ctx->rx_rings) *
-+                                       rx->num_rings),
-+                                       GFP_KERNEL);
-+      if (!edma_ctx->rx_rings)
-+              goto rxdesc_ring_alloc_fail;
-+
-+      pr_debug("RxDesc:%u rx (%u-%u) RxFill:%u (%u-%u)\n",
-+               rx->num_rings, rx->ring_start,
-+               (rx->ring_start + rx->num_rings - 1),
-+               rxfill->num_rings, rxfill->ring_start,
-+               (rxfill->ring_start + rxfill->num_rings - 1));
-+
-+      if (edma_cfg_rx_rings_setup()) {
-+              pr_err("Error in setting up Rx rings\n");
-+              goto rx_rings_setup_fail;
-+      }
-+
-+      /* Reset Rx descriptor ring mapped queue's configurations */
-+      ret = edma_cfg_rx_desc_ring_reset_queue_config();
-+      if (ret) {
-+              pr_err("Error in resetting the Rx descriptor rings configurations\n");
-+              edma_cfg_rx_rings_cleanup();
-+              return ret;
-+      }
-+
-+      return 0;
-+
-+rx_rings_setup_fail:
-+      kfree(edma_ctx->rx_rings);
-+      edma_ctx->rx_rings = NULL;
-+rxdesc_ring_alloc_fail:
-+      kfree(edma_ctx->rxfill_rings);
-+      edma_ctx->rxfill_rings = NULL;
-+
-+      return -ENOMEM;
-+}
-+
-+/**
-+ * edma_cfg_rx_rings_cleanup - Cleanup EDMA Rx rings
-+ *
-+ * Cleanup EDMA Rx rings
-+ */
-+void edma_cfg_rx_rings_cleanup(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rxfill = hw_info->rxfill;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i;
-+
-+      /* Free RxFill ring descriptors */
-+      for (i = 0; i < rxfill->num_rings; i++)
-+              edma_cfg_rx_fill_ring_cleanup(&edma_ctx->rxfill_rings[i]);
-+
-+      /* Free Rx completion ring descriptors */
-+      for (i = 0; i < rx->num_rings; i++)
-+              edma_cfg_rx_desc_ring_cleanup(&edma_ctx->rx_rings[i]);
-+
-+      kfree(edma_ctx->rxfill_rings);
-+      kfree(edma_ctx->rx_rings);
-+      edma_ctx->rxfill_rings = NULL;
-+      edma_ctx->rx_rings = NULL;
-+}
-+
-+static void edma_cfg_rx_fill_ring_configure(struct edma_rxfill_ring *rxfill_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 ring_sz, reg;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXFILL_BA(rxfill_ring->ring_id);
-+      regmap_write(regmap, reg, (u32)(rxfill_ring->dma & EDMA_RING_DMA_MASK));
-+
-+      ring_sz = rxfill_ring->count & EDMA_RXFILL_RING_SIZE_MASK;
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXFILL_RING_SIZE(rxfill_ring->ring_id);
-+      regmap_write(regmap, reg, ring_sz);
-+
-+      edma_rx_alloc_buffer(rxfill_ring, rxfill_ring->count - 1);
-+}
-+
-+static void edma_cfg_rx_desc_ring_flow_control(u32 threshold_xoff, u32 threshold_xon)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 data, i, reg;
-+
-+      data = (threshold_xoff & EDMA_RXDESC_FC_XOFF_THRE_MASK) << EDMA_RXDESC_FC_XOFF_THRE_SHIFT;
-+      data |= ((threshold_xon & EDMA_RXDESC_FC_XON_THRE_MASK) << EDMA_RXDESC_FC_XON_THRE_SHIFT);
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[i];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_FC_THRE(rxdesc_ring->ring_id);
-+              regmap_write(regmap, reg, data);
-+      }
-+}
-+
-+static void edma_cfg_rx_fill_ring_flow_control(int threshold_xoff, int threshold_xon)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rxfill = hw_info->rxfill;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 data, i, reg;
-+
-+      data = (threshold_xoff & EDMA_RXFILL_FC_XOFF_THRE_MASK) << EDMA_RXFILL_FC_XOFF_THRE_SHIFT;
-+      data |= ((threshold_xon & EDMA_RXFILL_FC_XON_THRE_MASK) << EDMA_RXFILL_FC_XON_THRE_SHIFT);
-+
-+      for (i = 0; i < rxfill->num_rings; i++) {
-+              struct edma_rxfill_ring *rxfill_ring;
-+
-+              rxfill_ring = &edma_ctx->rxfill_rings[i];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXFILL_FC_THRE(rxfill_ring->ring_id);
-+              regmap_write(regmap, reg, data);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_rx_rings - Configure EDMA Rx rings.
-+ *
-+ * Configure EDMA Rx rings.
-+ */
-+int edma_cfg_rx_rings(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rxfill = hw_info->rxfill;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i;
-+
-+      for (i = 0; i < rxfill->num_rings; i++)
-+              edma_cfg_rx_fill_ring_configure(&edma_ctx->rxfill_rings[i]);
-+
-+      for (i = 0; i < rx->num_rings; i++)
-+              edma_cfg_rx_desc_ring_configure(&edma_ctx->rx_rings[i]);
-+
-+      /* Configure Rx flow control configurations */
-+      edma_cfg_rx_desc_ring_flow_control(EDMA_RX_FC_XOFF_DEF, EDMA_RX_FC_XON_DEF);
-+      edma_cfg_rx_fill_ring_flow_control(EDMA_RX_FC_XOFF_DEF, EDMA_RX_FC_XON_DEF);
-+
-+      return edma_cfg_rx_desc_ring_to_queue_mapping();
-+}
-+
-+/**
-+ * edma_cfg_rx_disable_interrupts - EDMA disable RX interrupts
-+ *
-+ * Disable RX interrupt masks
-+ */
-+void edma_cfg_rx_disable_interrupts(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i, reg;
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring =
-+                              &edma_ctx->rx_rings[i];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->ring_id);
-+              regmap_write(regmap, reg, EDMA_MASK_INT_CLEAR);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_rx_enable_interrupts - EDMA enable RX interrupts
-+ *
-+ * Enable RX interrupt masks
-+ */
-+void edma_cfg_rx_enable_interrupts(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i, reg;
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring =
-+                              &edma_ctx->rx_rings[i];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->ring_id);
-+              regmap_write(regmap, reg, edma_ctx->intr_info.intr_mask_rx);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_rx_napi_disable - Disable NAPI for Rx
-+ *
-+ * Disable NAPI for Rx
-+ */
-+void edma_cfg_rx_napi_disable(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i;
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[i];
-+
-+              if (!rxdesc_ring->napi_added)
-+                      continue;
-+
-+              napi_disable(&rxdesc_ring->napi);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_rx_napi_enable - Enable NAPI for Rx
-+ *
-+ * Enable NAPI for Rx
-+ */
-+void edma_cfg_rx_napi_enable(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i;
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[i];
-+
-+              if (!rxdesc_ring->napi_added)
-+                      continue;
-+
-+              napi_enable(&rxdesc_ring->napi);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_rx_napi_delete - Delete Rx NAPI
-+ *
-+ * Delete RX NAPI
-+ */
-+void edma_cfg_rx_napi_delete(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i;
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[i];
-+
-+              if (!rxdesc_ring->napi_added)
-+                      continue;
-+
-+              netif_napi_del(&rxdesc_ring->napi);
-+              rxdesc_ring->napi_added = false;
-+      }
-+}
-+
-+/* Add Rx NAPI */
-+/**
-+ * edma_cfg_rx_napi_add - Add Rx NAPI
-+ * @netdev: Netdevice
-+ *
-+ * Add RX NAPI
-+ */
-+void edma_cfg_rx_napi_add(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      u32 i;
-+
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring = &edma_ctx->rx_rings[i];
-+
-+              netif_napi_add_weight(edma_ctx->dummy_dev, &rxdesc_ring->napi,
-+                                    edma_rx_napi_poll, hw_info->napi_budget_rx);
-+              rxdesc_ring->napi_added = true;
-+      }
-+
-+      netdev_dbg(edma_ctx->dummy_dev, "Rx NAPI budget: %d\n", hw_info->napi_budget_rx);
-+}
-+
-+/**
-+ * edma_cfg_rx_rps_hash_map - Configure rx rps hash map.
-+ *
-+ * Initialize and configure RPS hash map for queues
-+ */
-+int edma_cfg_rx_rps_hash_map(void)
-+{
-+      cpumask_t edma_rps_cpumask = {{EDMA_RX_DEFAULT_BITMAP}};
-+      int map_len = 0, idx = 0, ret = 0;
-+      u32 q_off = EDMA_RX_QUEUE_START;
-+      u32 q_map[EDMA_MAX_CORE] = {0};
-+      u32 hash, cpu;
-+
-+      /* Map all possible hash values to queues used by the EDMA Rx
-+       * rings based on a bitmask, which represents the cores to be mapped.
-+       * These queues are expected to be mapped to different Rx rings
-+       * which are assigned to different cores using IRQ affinity configuration.
-+       */
-+      for_each_cpu(cpu, &edma_rps_cpumask) {
-+              q_map[map_len] = q_off + (cpu * EDMA_MAX_PRI_PER_CORE);
-+              map_len++;
-+      }
-+
-+      for (hash = 0; hash < PPE_QUEUE_HASH_NUM; hash++) {
-+              ret = ppe_edma_queue_offset_config(edma_ctx->ppe_dev,
-+                                                 PPE_QUEUE_CLASS_HASH, hash, q_map[idx]);
-+              if (ret)
-+                      return ret;
-+
-+              pr_debug("profile_id: %u, hash: %u, q_off: %u\n",
-+                       EDMA_CPU_PORT_PROFILE_ID, hash, q_map[idx]);
-+              idx = (idx + 1) % map_len;
-+      }
-+
-+      return 0;
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.h
-@@ -0,0 +1,48 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __EDMA_CFG_RX__
-+#define __EDMA_CFG_RX__
-+
-+/* SKB payload size used in page mode */
-+#define EDMA_RX_PAGE_MODE_SKB_SIZE    256
-+
-+/* Rx flow control X-OFF default value */
-+#define EDMA_RX_FC_XOFF_DEF   32
-+
-+/* Rx flow control X-ON default value */
-+#define EDMA_RX_FC_XON_DEF    64
-+
-+/* Rx AC flow control original threshold */
-+#define EDMA_RX_AC_FC_THRE_ORIG               0x190
-+
-+/* Rx AC flow control default threshold */
-+#define EDMA_RX_AC_FC_THRES_DEF               0x104
-+/* Rx mitigation timer's default value in microseconds */
-+#define EDMA_RX_MITIGATION_TIMER_DEF  25
-+
-+/* Rx mitigation packet count's default value */
-+#define EDMA_RX_MITIGATION_PKT_CNT_DEF        16
-+
-+/* Default bitmap of cores for RPS to ARM cores */
-+#define EDMA_RX_DEFAULT_BITMAP        ((1 << EDMA_MAX_CORE) - 1)
-+
-+int edma_cfg_rx_rings(void);
-+int edma_cfg_rx_rings_alloc(void);
-+void edma_cfg_rx_ring_mappings(void);
-+void edma_cfg_rx_rings_cleanup(void);
-+void edma_cfg_rx_disable_interrupts(void);
-+void edma_cfg_rx_enable_interrupts(void);
-+void edma_cfg_rx_napi_disable(void);
-+void edma_cfg_rx_napi_enable(void);
-+void edma_cfg_rx_napi_delete(void);
-+void edma_cfg_rx_napi_add(void);
-+void edma_cfg_rx_mapping(void);
-+void edma_cfg_rx_rings_enable(void);
-+void edma_cfg_rx_rings_disable(void);
-+void edma_cfg_rx_buff_size_setup(void);
-+int edma_cfg_rx_rps_hash_map(void);
-+int edma_cfg_rx_rps(struct ctl_table *table, int write,
-+                  void *buffer, size_t *lenp, loff_t *ppos);
-+#endif
---- a/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-@@ -12,12 +12,39 @@
- #include <linux/printk.h>
- #include "edma.h"
-+#include "edma_cfg_rx.h"
- #include "edma_port.h"
- #include "ppe_regs.h"
- /* Number of netdev queues. */
- #define EDMA_NETDEV_QUEUE_NUM 4
-+static int edma_port_stats_alloc(struct net_device *netdev)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      /* Allocate per-cpu stats memory. */
-+      port_priv->pcpu_stats.rx_stats =
-+              netdev_alloc_pcpu_stats(struct edma_port_rx_stats);
-+      if (!port_priv->pcpu_stats.rx_stats) {
-+              netdev_err(netdev, "Per-cpu EDMA Rx stats alloc failed for %s\n",
-+                         netdev->name);
-+              return -ENOMEM;
-+      }
-+
-+      return 0;
-+}
-+
-+static void edma_port_stats_free(struct net_device *netdev)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+
-+      free_percpu(port_priv->pcpu_stats.rx_stats);
-+}
-+
- static u16 __maybe_unused edma_port_select_queue(__maybe_unused struct net_device *netdev,
-                                                __maybe_unused struct sk_buff *skb,
-                               __maybe_unused struct net_device *sb_dev)
-@@ -172,6 +199,7 @@ void edma_port_destroy(struct ppe_port *
-       int port_id = port->port_id;
-       struct net_device *netdev = edma_ctx->netdev_arr[port_id - 1];
-+      edma_port_stats_free(netdev);
-       unregister_netdev(netdev);
-       free_netdev(netdev);
-       ppe_port_phylink_destroy(port);
-@@ -232,6 +260,13 @@ int edma_port_setup(struct ppe_port *por
-                           port_id, netdev->dev_addr);
-       }
-+      /* Allocate memory for EDMA port statistics. */
-+      ret = edma_port_stats_alloc(netdev);
-+      if (ret) {
-+              netdev_dbg(netdev, "EDMA port stats alloc failed\n");
-+              goto stats_alloc_fail;
-+      }
-+
-       netdev_dbg(netdev, "Configuring the port %s(qcom-id:%d)\n",
-                  netdev->name, port_id);
-@@ -263,8 +298,10 @@ int edma_port_setup(struct ppe_port *por
- register_netdev_fail:
-       ppe_port_phylink_destroy(port);
- port_phylink_setup_fail:
--      free_netdev(netdev);
-       edma_ctx->netdev_arr[port_id - 1] = NULL;
-+      edma_port_stats_free(netdev);
-+stats_alloc_fail:
-+      free_netdev(netdev);
-       return ret;
- }
---- a/drivers/net/ethernet/qualcomm/ppe/edma_port.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_port.h
-@@ -15,14 +15,45 @@
-                                       | NETIF_F_TSO6)
- /**
-+ * struct edma_port_rx_stats - EDMA RX per CPU stats for the port.
-+ * @rx_pkts: Number of Rx packets
-+ * @rx_bytes: Number of Rx bytes
-+ * @rx_drops: Number of Rx drops
-+ * @rx_nr_frag_pkts: Number of Rx nr_frags packets
-+ * @rx_fraglist_pkts: Number of Rx fraglist packets
-+ * @rx_nr_frag_headroom_err: nr_frags headroom error packets
-+ * @syncp: Synchronization pointer
-+ */
-+struct edma_port_rx_stats {
-+      u64 rx_pkts;
-+      u64 rx_bytes;
-+      u64 rx_drops;
-+      u64 rx_nr_frag_pkts;
-+      u64 rx_fraglist_pkts;
-+      u64 rx_nr_frag_headroom_err;
-+      struct u64_stats_sync syncp;
-+};
-+
-+/**
-+ * struct edma_port_pcpu_stats - EDMA per cpu stats data structure for the port.
-+ * @rx_stats: Per CPU Rx statistics
-+ */
-+struct edma_port_pcpu_stats {
-+      struct edma_port_rx_stats __percpu *rx_stats;
-+};
-+
-+/**
-  * struct edma_port_priv - EDMA port priv structure.
-  * @ppe_port: Pointer to PPE port
-  * @netdev: Corresponding netdevice
-+ * @pcpu_stats: Per CPU netdev statistics
-+ * @txr_map: Tx ring per-core mapping
-  * @flags: Feature flags
-  */
- struct edma_port_priv {
-       struct ppe_port *ppe_port;
-       struct net_device *netdev;
-+      struct edma_port_pcpu_stats pcpu_stats;
-       unsigned long flags;
- };
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_rx.c
-@@ -0,0 +1,622 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* Provides APIs to alloc Rx Buffers, reap the buffers, receive and
-+ * process linear and Scatter Gather packets.
-+ */
-+
-+#include <linux/dma-mapping.h>
-+#include <linux/etherdevice.h>
-+#include <linux/irqreturn.h>
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/platform_device.h>
-+#include <linux/printk.h>
-+#include <linux/regmap.h>
-+
-+#include "edma.h"
-+#include "edma_cfg_rx.h"
-+#include "edma_port.h"
-+#include "ppe.h"
-+#include "ppe_regs.h"
-+
-+static int edma_rx_alloc_buffer_list(struct edma_rxfill_ring *rxfill_ring, int alloc_count)
-+{
-+      struct edma_rxfill_stats *rxfill_stats = &rxfill_ring->rxfill_stats;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      u32 rx_alloc_size = rxfill_ring->alloc_size;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      bool page_mode = rxfill_ring->page_mode;
-+      struct edma_rxfill_desc *rxfill_desc;
-+      u32 buf_len = rxfill_ring->buf_len;
-+      struct device *dev = ppe_dev->dev;
-+      u16 prod_idx, start_idx;
-+      u16 num_alloc = 0;
-+      u32 reg;
-+
-+      prod_idx = rxfill_ring->prod_idx;
-+      start_idx = prod_idx;
-+
-+      while (likely(alloc_count--)) {
-+              dma_addr_t buff_addr;
-+              struct sk_buff *skb;
-+              struct page *pg;
-+
-+              rxfill_desc = EDMA_RXFILL_DESC(rxfill_ring, prod_idx);
-+
-+              skb = dev_alloc_skb(rx_alloc_size);
-+              if (unlikely(!skb)) {
-+                      u64_stats_update_begin(&rxfill_stats->syncp);
-+                      ++rxfill_stats->alloc_failed;
-+                      u64_stats_update_end(&rxfill_stats->syncp);
-+                      break;
-+              }
-+
-+              skb_reserve(skb, EDMA_RX_SKB_HEADROOM + NET_IP_ALIGN);
-+
-+              if (likely(!page_mode)) {
-+                      buff_addr = dma_map_single(dev, skb->data, rx_alloc_size, DMA_FROM_DEVICE);
-+                      if (dma_mapping_error(dev, buff_addr)) {
-+                              dev_dbg(dev, "edma_context:%p Unable to dma for non page mode",
-+                                      edma_ctx);
-+                              dev_kfree_skb_any(skb);
-+                              break;
-+                      }
-+              } else {
-+                      pg = alloc_page(GFP_ATOMIC);
-+                      if (unlikely(!pg)) {
-+                              u64_stats_update_begin(&rxfill_stats->syncp);
-+                              ++rxfill_stats->page_alloc_failed;
-+                              u64_stats_update_end(&rxfill_stats->syncp);
-+                              dev_kfree_skb_any(skb);
-+                              dev_dbg(dev, "edma_context:%p Unable to allocate page",
-+                                      edma_ctx);
-+                              break;
-+                      }
-+
-+                      buff_addr = dma_map_page(dev, pg, 0, PAGE_SIZE, DMA_FROM_DEVICE);
-+                      if (dma_mapping_error(dev, buff_addr)) {
-+                              dev_dbg(dev, "edma_context:%p Mapping error for page mode",
-+                                      edma_ctx);
-+                              __free_page(pg);
-+                              dev_kfree_skb_any(skb);
-+                              break;
-+                      }
-+
-+                      skb_fill_page_desc(skb, 0, pg, 0, PAGE_SIZE);
-+              }
-+
-+              EDMA_RXFILL_BUFFER_ADDR_SET(rxfill_desc, buff_addr);
-+
-+              EDMA_RXFILL_OPAQUE_LO_SET(rxfill_desc, skb);
-+#ifdef __LP64__
-+              EDMA_RXFILL_OPAQUE_HI_SET(rxfill_desc, skb);
-+#endif
-+              EDMA_RXFILL_PACKET_LEN_SET(rxfill_desc,
-+                                         (u32)(buf_len) & EDMA_RXFILL_BUF_SIZE_MASK);
-+              prod_idx = (prod_idx + 1) & EDMA_RX_RING_SIZE_MASK;
-+              num_alloc++;
-+      }
-+
-+      if (likely(num_alloc)) {
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXFILL_PROD_IDX(rxfill_ring->ring_id);
-+              regmap_write(regmap, reg, prod_idx);
-+              rxfill_ring->prod_idx = prod_idx;
-+      }
-+
-+      return num_alloc;
-+}
-+
-+/**
-+ * edma_rx_alloc_buffer - EDMA Rx alloc buffer.
-+ * @rxfill_ring: EDMA Rxfill ring
-+ * @alloc_count: Number of rings to alloc
-+ *
-+ * Alloc Rx buffers for RxFill ring.
-+ *
-+ * Return the number of rings allocated.
-+ */
-+int edma_rx_alloc_buffer(struct edma_rxfill_ring *rxfill_ring, int alloc_count)
-+{
-+      return edma_rx_alloc_buffer_list(rxfill_ring, alloc_count);
-+}
-+
-+/* Mark ip_summed appropriately in the skb as per the L3/L4 checksum
-+ * status in descriptor.
-+ */
-+static void edma_rx_checksum_verify(struct edma_rxdesc_pri *rxdesc_pri,
-+                                  struct sk_buff *skb)
-+{
-+      u8 pid = EDMA_RXDESC_PID_GET(rxdesc_pri);
-+
-+      skb_checksum_none_assert(skb);
-+
-+      if (likely(EDMA_RX_PID_IS_IPV4(pid))) {
-+              if (likely(EDMA_RXDESC_L3CSUM_STATUS_GET(rxdesc_pri)) &&
-+                  likely(EDMA_RXDESC_L4CSUM_STATUS_GET(rxdesc_pri)))
-+                      skb->ip_summed = CHECKSUM_UNNECESSARY;
-+      } else if (likely(EDMA_RX_PID_IS_IPV6(pid))) {
-+              if (likely(EDMA_RXDESC_L4CSUM_STATUS_GET(rxdesc_pri)))
-+                      skb->ip_summed = CHECKSUM_UNNECESSARY;
-+      }
-+}
-+
-+static void edma_rx_process_last_segment(struct edma_rxdesc_ring *rxdesc_ring,
-+                                       struct edma_rxdesc_pri *rxdesc_pri,
-+                                       struct sk_buff *skb)
-+{
-+      bool page_mode = rxdesc_ring->rxfill->page_mode;
-+      struct edma_port_pcpu_stats *pcpu_stats;
-+      struct edma_port_rx_stats *rx_stats;
-+      struct edma_port_priv *port_dev;
-+      struct sk_buff *skb_head;
-+      struct net_device *dev;
-+      u32 pkt_length;
-+
-+      /* Get packet length. */
-+      pkt_length = EDMA_RXDESC_PACKET_LEN_GET(rxdesc_pri);
-+
-+      skb_head = rxdesc_ring->head;
-+      dev = skb_head->dev;
-+
-+      /* Check Rx checksum offload status. */
-+      if (likely(dev->features & NETIF_F_RXCSUM))
-+              edma_rx_checksum_verify(rxdesc_pri, skb_head);
-+
-+      /* Get stats for the netdevice. */
-+      port_dev = netdev_priv(dev);
-+      pcpu_stats = &port_dev->pcpu_stats;
-+      rx_stats = this_cpu_ptr(pcpu_stats->rx_stats);
-+
-+      if (unlikely(page_mode)) {
-+              if (unlikely(!pskb_may_pull(skb_head, ETH_HLEN))) {
-+                      /* Discard the SKB that we have been building,
-+                       * in addition to the SKB linked to current descriptor.
-+                       */
-+                      dev_kfree_skb_any(skb_head);
-+                      rxdesc_ring->head = NULL;
-+                      rxdesc_ring->last = NULL;
-+                      rxdesc_ring->pdesc_head = NULL;
-+
-+                      u64_stats_update_begin(&rx_stats->syncp);
-+                      rx_stats->rx_nr_frag_headroom_err++;
-+                      u64_stats_update_end(&rx_stats->syncp);
-+
-+                      return;
-+              }
-+      }
-+
-+      if (unlikely(!pskb_pull(skb_head, EDMA_RXDESC_DATA_OFFSET_GET(rxdesc_ring->pdesc_head)))) {
-+              dev_kfree_skb_any(skb_head);
-+              rxdesc_ring->head = NULL;
-+              rxdesc_ring->last = NULL;
-+              rxdesc_ring->pdesc_head = NULL;
-+
-+              u64_stats_update_begin(&rx_stats->syncp);
-+              rx_stats->rx_nr_frag_headroom_err++;
-+              u64_stats_update_end(&rx_stats->syncp);
-+
-+              return;
-+      }
-+
-+      u64_stats_update_begin(&rx_stats->syncp);
-+      rx_stats->rx_pkts++;
-+      rx_stats->rx_bytes += skb_head->len;
-+      rx_stats->rx_nr_frag_pkts += (u64)page_mode;
-+      rx_stats->rx_fraglist_pkts += (u64)(!page_mode);
-+      u64_stats_update_end(&rx_stats->syncp);
-+
-+      pr_debug("edma_context:%p skb:%p Jumbo pkt_length:%u\n",
-+               edma_ctx, skb_head, skb_head->len);
-+
-+      skb_head->protocol = eth_type_trans(skb_head, dev);
-+
-+      /* Send packet up the stack. */
-+      if (dev->features & NETIF_F_GRO)
-+              napi_gro_receive(&rxdesc_ring->napi, skb_head);
-+      else
-+              netif_receive_skb(skb_head);
-+
-+      rxdesc_ring->head = NULL;
-+      rxdesc_ring->last = NULL;
-+      rxdesc_ring->pdesc_head = NULL;
-+}
-+
-+static void edma_rx_handle_frag_list(struct edma_rxdesc_ring *rxdesc_ring,
-+                                   struct edma_rxdesc_pri *rxdesc_pri,
-+                                   struct sk_buff *skb)
-+{
-+      u32 pkt_length;
-+
-+      /* Get packet length. */
-+      pkt_length = EDMA_RXDESC_PACKET_LEN_GET(rxdesc_pri);
-+      pr_debug("edma_context:%p skb:%p fragment pkt_length:%u\n",
-+               edma_ctx, skb, pkt_length);
-+
-+      if (!(rxdesc_ring->head)) {
-+              skb_put(skb, pkt_length);
-+              rxdesc_ring->head = skb;
-+              rxdesc_ring->last = NULL;
-+              rxdesc_ring->pdesc_head = rxdesc_pri;
-+
-+              return;
-+      }
-+
-+      /* Append it to the fraglist of head if this is second frame
-+       * If not second frame append to tail.
-+       */
-+      skb_put(skb, pkt_length);
-+      if (!skb_has_frag_list(rxdesc_ring->head))
-+              skb_shinfo(rxdesc_ring->head)->frag_list = skb;
-+      else
-+              rxdesc_ring->last->next = skb;
-+
-+      rxdesc_ring->last = skb;
-+      rxdesc_ring->last->next = NULL;
-+      rxdesc_ring->head->len += pkt_length;
-+      rxdesc_ring->head->data_len += pkt_length;
-+      rxdesc_ring->head->truesize += skb->truesize;
-+
-+      /* If there are more segments for this packet,
-+       * then we have nothing to do. Otherwise process
-+       * last segment and send packet to stack.
-+       */
-+      if (EDMA_RXDESC_MORE_BIT_GET(rxdesc_pri))
-+              return;
-+
-+      edma_rx_process_last_segment(rxdesc_ring, rxdesc_pri, skb);
-+}
-+
-+static void edma_rx_handle_nr_frags(struct edma_rxdesc_ring *rxdesc_ring,
-+                                  struct edma_rxdesc_pri *rxdesc_pri,
-+                                  struct sk_buff *skb)
-+{
-+      skb_frag_t *frag = NULL;
-+      u32 pkt_length;
-+
-+      /* Get packet length. */
-+      pkt_length = EDMA_RXDESC_PACKET_LEN_GET(rxdesc_pri);
-+      pr_debug("edma_context:%p skb:%p fragment pkt_length:%u\n",
-+               edma_ctx, skb, pkt_length);
-+
-+      if (!(rxdesc_ring->head)) {
-+              skb->len = pkt_length;
-+              skb->data_len = pkt_length;
-+              skb->truesize = SKB_TRUESIZE(PAGE_SIZE);
-+              rxdesc_ring->head = skb;
-+              rxdesc_ring->last = NULL;
-+              rxdesc_ring->pdesc_head = rxdesc_pri;
-+
-+              return;
-+      }
-+
-+      frag = &skb_shinfo(skb)->frags[0];
-+
-+      /* Append current frag at correct index as nr_frag of parent. */
-+      skb_add_rx_frag(rxdesc_ring->head, skb_shinfo(rxdesc_ring->head)->nr_frags,
-+                      skb_frag_page(frag), 0, pkt_length, PAGE_SIZE);
-+      skb_shinfo(skb)->nr_frags = 0;
-+
-+      /* Free the SKB after we have appended its frag page to the head skb. */
-+      dev_kfree_skb_any(skb);
-+
-+      /* If there are more segments for this packet,
-+       * then we have nothing to do. Otherwise process
-+       * last segment and send packet to stack.
-+       */
-+      if (EDMA_RXDESC_MORE_BIT_GET(rxdesc_pri))
-+              return;
-+
-+      edma_rx_process_last_segment(rxdesc_ring, rxdesc_pri, skb);
-+}
-+
-+static bool edma_rx_handle_linear_packets(struct edma_rxdesc_ring *rxdesc_ring,
-+                                        struct edma_rxdesc_pri *rxdesc_pri,
-+                                        struct sk_buff *skb)
-+{
-+      bool page_mode = rxdesc_ring->rxfill->page_mode;
-+      struct edma_port_pcpu_stats *pcpu_stats;
-+      struct edma_port_rx_stats *rx_stats;
-+      struct edma_port_priv *port_dev;
-+      skb_frag_t *frag = NULL;
-+      u32 pkt_length;
-+
-+      /* Get stats for the netdevice. */
-+      port_dev = netdev_priv(skb->dev);
-+      pcpu_stats = &port_dev->pcpu_stats;
-+      rx_stats = this_cpu_ptr(pcpu_stats->rx_stats);
-+
-+      /* Get packet length. */
-+      pkt_length = EDMA_RXDESC_PACKET_LEN_GET(rxdesc_pri);
-+
-+      if (likely(!page_mode)) {
-+              skb_put(skb, pkt_length);
-+              goto send_to_stack;
-+      }
-+
-+      /* Handle linear packet in page mode. */
-+      frag = &skb_shinfo(skb)->frags[0];
-+      skb_add_rx_frag(skb, 0, skb_frag_page(frag), 0, pkt_length, PAGE_SIZE);
-+
-+      /* Pull ethernet header into SKB data area for header processing. */
-+      if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) {
-+              u64_stats_update_begin(&rx_stats->syncp);
-+              rx_stats->rx_nr_frag_headroom_err++;
-+              u64_stats_update_end(&rx_stats->syncp);
-+              dev_kfree_skb_any(skb);
-+
-+              return false;
-+      }
-+
-+send_to_stack:
-+
-+      __skb_pull(skb, EDMA_RXDESC_DATA_OFFSET_GET(rxdesc_pri));
-+
-+      /* Check Rx checksum offload status. */
-+      if (likely(skb->dev->features & NETIF_F_RXCSUM))
-+              edma_rx_checksum_verify(rxdesc_pri, skb);
-+
-+      u64_stats_update_begin(&rx_stats->syncp);
-+      rx_stats->rx_pkts++;
-+      rx_stats->rx_bytes += pkt_length;
-+      rx_stats->rx_nr_frag_pkts += (u64)page_mode;
-+      u64_stats_update_end(&rx_stats->syncp);
-+
-+      skb->protocol = eth_type_trans(skb, skb->dev);
-+      if (skb->dev->features & NETIF_F_GRO)
-+              napi_gro_receive(&rxdesc_ring->napi, skb);
-+      else
-+              netif_receive_skb(skb);
-+
-+      netdev_dbg(skb->dev, "edma_context:%p, skb:%p pkt_length:%u\n",
-+                 edma_ctx, skb, skb->len);
-+
-+      return true;
-+}
-+
-+static struct net_device *edma_rx_get_src_dev(struct edma_rxdesc_stats *rxdesc_stats,
-+                                            struct edma_rxdesc_pri *rxdesc_pri,
-+                                            struct sk_buff *skb)
-+{
-+      u32 src_info = EDMA_RXDESC_SRC_INFO_GET(rxdesc_pri);
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct net_device *ndev = NULL;
-+      u8 src_port_num;
-+
-+      /* Check src_info. */
-+      if (likely((src_info & EDMA_RXDESC_SRCINFO_TYPE_MASK)
-+          == EDMA_RXDESC_SRCINFO_TYPE_PORTID)) {
-+              src_port_num = src_info & EDMA_RXDESC_PORTNUM_BITS;
-+      } else {
-+              if (net_ratelimit()) {
-+                      pr_warn("Invalid src info_type:0x%x. Drop skb:%p\n",
-+                              (src_info & EDMA_RXDESC_SRCINFO_TYPE_MASK), skb);
-+              }
-+
-+              u64_stats_update_begin(&rxdesc_stats->syncp);
-+              ++rxdesc_stats->src_port_inval_type;
-+              u64_stats_update_end(&rxdesc_stats->syncp);
-+
-+              return NULL;
-+      }
-+
-+      /* Packet with PP source. */
-+      if (likely(src_port_num <= hw_info->max_ports)) {
-+              if (unlikely(src_port_num < EDMA_START_IFNUM)) {
-+                      if (net_ratelimit())
-+                              pr_warn("Port number error :%d. Drop skb:%p\n",
-+                                      src_port_num, skb);
-+
-+                      u64_stats_update_begin(&rxdesc_stats->syncp);
-+                      ++rxdesc_stats->src_port_inval;
-+                      u64_stats_update_end(&rxdesc_stats->syncp);
-+
-+                      return NULL;
-+              }
-+
-+              /* Get netdev for this port using the source port
-+               * number as index into the netdev array. We need to
-+               * subtract one since the indices start form '0' and
-+               * port numbers start from '1'.
-+               */
-+              ndev = edma_ctx->netdev_arr[src_port_num - 1];
-+      }
-+
-+      if (likely(ndev))
-+              return ndev;
-+
-+      if (net_ratelimit())
-+              pr_warn("Netdev Null src_info_type:0x%x src port num:%d Drop skb:%p\n",
-+                      (src_info & EDMA_RXDESC_SRCINFO_TYPE_MASK),
-+                      src_port_num, skb);
-+
-+      u64_stats_update_begin(&rxdesc_stats->syncp);
-+      ++rxdesc_stats->src_port_inval_netdev;
-+      u64_stats_update_end(&rxdesc_stats->syncp);
-+
-+      return NULL;
-+}
-+
-+static int edma_rx_reap(struct edma_rxdesc_ring *rxdesc_ring, int budget)
-+{
-+      struct edma_rxdesc_stats *rxdesc_stats = &rxdesc_ring->rxdesc_stats;
-+      u32 alloc_size = rxdesc_ring->rxfill->alloc_size;
-+      bool page_mode = rxdesc_ring->rxfill->page_mode;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct edma_rxdesc_pri *next_rxdesc_pri;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct device *dev = ppe_dev->dev;
-+      u32 prod_idx, cons_idx, end_idx;
-+      u32 work_to_do, work_done = 0;
-+      struct sk_buff *next_skb;
-+      u32 work_leftover, reg;
-+
-+      /* Get Rx ring producer and consumer indices. */
-+      cons_idx = rxdesc_ring->cons_idx;
-+
-+      if (likely(rxdesc_ring->work_leftover > EDMA_RX_MAX_PROCESS)) {
-+              work_to_do = rxdesc_ring->work_leftover;
-+      } else {
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_PROD_IDX(rxdesc_ring->ring_id);
-+              regmap_read(regmap, reg, &prod_idx);
-+              prod_idx = prod_idx & EDMA_RXDESC_PROD_IDX_MASK;
-+              work_to_do = EDMA_DESC_AVAIL_COUNT(prod_idx,
-+                                                 cons_idx, EDMA_RX_RING_SIZE);
-+              rxdesc_ring->work_leftover = work_to_do;
-+      }
-+
-+      if (work_to_do > budget)
-+              work_to_do = budget;
-+
-+      rxdesc_ring->work_leftover -= work_to_do;
-+      end_idx = (cons_idx + work_to_do) & EDMA_RX_RING_SIZE_MASK;
-+      next_rxdesc_pri = EDMA_RXDESC_PRI_DESC(rxdesc_ring, cons_idx);
-+
-+      /* Get opaque from RXDESC. */
-+      next_skb = (struct sk_buff *)EDMA_RXDESC_OPAQUE_GET(next_rxdesc_pri);
-+
-+      work_leftover = work_to_do & (EDMA_RX_MAX_PROCESS - 1);
-+      while (likely(work_to_do--)) {
-+              struct edma_rxdesc_pri *rxdesc_pri;
-+              struct net_device *ndev;
-+              struct sk_buff *skb;
-+              dma_addr_t dma_addr;
-+
-+              skb = next_skb;
-+              rxdesc_pri = next_rxdesc_pri;
-+              dma_addr = EDMA_RXDESC_BUFFER_ADDR_GET(rxdesc_pri);
-+
-+              if (!page_mode)
-+                      dma_unmap_single(dev, dma_addr, alloc_size,
-+                                       DMA_TO_DEVICE);
-+              else
-+                      dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_TO_DEVICE);
-+
-+              /* Update consumer index. */
-+              cons_idx = (cons_idx + 1) & EDMA_RX_RING_SIZE_MASK;
-+
-+              /* Get the next Rx descriptor. */
-+              next_rxdesc_pri = EDMA_RXDESC_PRI_DESC(rxdesc_ring, cons_idx);
-+
-+              /* Handle linear packets or initial segments first. */
-+              if (likely(!(rxdesc_ring->head))) {
-+                      ndev = edma_rx_get_src_dev(rxdesc_stats, rxdesc_pri, skb);
-+                      if (unlikely(!ndev)) {
-+                              dev_kfree_skb_any(skb);
-+                              goto next_rx_desc;
-+                      }
-+
-+                      /* Update skb fields for head skb. */
-+                      skb->dev = ndev;
-+                      skb->skb_iif = ndev->ifindex;
-+
-+                      /* Handle linear packets. */
-+                      if (likely(!EDMA_RXDESC_MORE_BIT_GET(rxdesc_pri))) {
-+                              next_skb =
-+                                      (struct sk_buff *)EDMA_RXDESC_OPAQUE_GET(next_rxdesc_pri);
-+
-+                              if (unlikely(!
-+                                           edma_rx_handle_linear_packets(rxdesc_ring,
-+                                                                         rxdesc_pri, skb)))
-+                                      dev_kfree_skb_any(skb);
-+
-+                              goto next_rx_desc;
-+                      }
-+              }
-+
-+              next_skb = (struct sk_buff *)EDMA_RXDESC_OPAQUE_GET(next_rxdesc_pri);
-+
-+              /* Handle scatter frame processing for first/middle/last segments. */
-+              page_mode ? edma_rx_handle_nr_frags(rxdesc_ring, rxdesc_pri, skb) :
-+                      edma_rx_handle_frag_list(rxdesc_ring, rxdesc_pri, skb);
-+
-+next_rx_desc:
-+              /* Update work done. */
-+              work_done++;
-+
-+              /* Check if we can refill EDMA_RX_MAX_PROCESS worth buffers,
-+               * if yes, refill and update index before continuing.
-+               */
-+              if (unlikely(!(work_done & (EDMA_RX_MAX_PROCESS - 1)))) {
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_CONS_IDX(rxdesc_ring->ring_id);
-+                      regmap_write(regmap, reg, cons_idx);
-+                      rxdesc_ring->cons_idx = cons_idx;
-+                      edma_rx_alloc_buffer_list(rxdesc_ring->rxfill, EDMA_RX_MAX_PROCESS);
-+              }
-+      }
-+
-+      /* Check if we need to refill and update
-+       * index for any buffers before exit.
-+       */
-+      if (unlikely(work_leftover)) {
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_CONS_IDX(rxdesc_ring->ring_id);
-+              regmap_write(regmap, reg, cons_idx);
-+              rxdesc_ring->cons_idx = cons_idx;
-+              edma_rx_alloc_buffer_list(rxdesc_ring->rxfill, work_leftover);
-+      }
-+
-+      return work_done;
-+}
-+
-+/**
-+ * edma_rx_napi_poll - EDMA Rx napi poll.
-+ * @napi: NAPI structure
-+ * @budget: Rx NAPI budget
-+ *
-+ * EDMA RX NAPI handler to handle the NAPI poll.
-+ *
-+ * Return the number of packets processed.
-+ */
-+int edma_rx_napi_poll(struct napi_struct *napi, int budget)
-+{
-+      struct edma_rxdesc_ring *rxdesc_ring = (struct edma_rxdesc_ring *)napi;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      int work_done = 0;
-+      u32 status, reg;
-+
-+      do {
-+              work_done += edma_rx_reap(rxdesc_ring, budget - work_done);
-+              if (likely(work_done >= budget))
-+                      return work_done;
-+
-+              /* Check if there are more packets to process. */
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_INT_STAT(rxdesc_ring->ring_id);
-+              regmap_read(regmap, reg, &status);
-+              status = status & EDMA_RXDESC_RING_INT_STATUS_MASK;
-+      } while (likely(status));
-+
-+      napi_complete(napi);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->ring_id);
-+      regmap_write(regmap, reg, edma_ctx->intr_info.intr_mask_rx);
-+
-+      return work_done;
-+}
-+
-+/**
-+ * edma_rx_handle_irq - EDMA Rx handle irq.
-+ * @irq: Interrupt to handle
-+ * @ctx: Context
-+ *
-+ * Process RX IRQ and schedule NAPI.
-+ *
-+ * Return IRQ_HANDLED(1) on success.
-+ */
-+irqreturn_t edma_rx_handle_irq(int irq, void *ctx)
-+{
-+      struct edma_rxdesc_ring *rxdesc_ring = (struct edma_rxdesc_ring *)ctx;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 reg;
-+
-+      if (likely(napi_schedule_prep(&rxdesc_ring->napi))) {
-+              /* Disable RxDesc interrupt. */
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->ring_id);
-+              regmap_write(regmap, reg, EDMA_MASK_INT_DISABLE);
-+              __napi_schedule(&rxdesc_ring->napi);
-+      }
-+
-+      return IRQ_HANDLED;
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_rx.h
-@@ -0,0 +1,287 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __EDMA_RX__
-+#define __EDMA_RX__
-+
-+#include <linux/netdevice.h>
-+
-+#define EDMA_RXFILL_RING_PER_CORE_MAX 1
-+#define EDMA_RXDESC_RING_PER_CORE_MAX 1
-+
-+/* Max Rx processing without replenishing RxFill ring. */
-+#define EDMA_RX_MAX_PROCESS           32
-+
-+#define EDMA_RX_SKB_HEADROOM          128
-+#define EDMA_RX_QUEUE_START           0
-+#define EDMA_RX_BUFFER_SIZE           1984
-+#define EDMA_MAX_CORE                 4
-+
-+#define EDMA_GET_DESC(R, i, type)     (&(((type *)((R)->desc))[(i)]))
-+#define EDMA_GET_PDESC(R, i, type)    (&(((type *)((R)->pdesc))[(i)]))
-+#define EDMA_GET_SDESC(R, i, type)    (&(((type *)((R)->sdesc))[(i)]))
-+#define EDMA_RXFILL_DESC(R, i)                EDMA_GET_DESC(R, i, \
-+                                              struct edma_rxfill_desc)
-+#define EDMA_RXDESC_PRI_DESC(R, i)    EDMA_GET_PDESC(R, i, \
-+                                              struct edma_rxdesc_pri)
-+#define EDMA_RXDESC_SEC_DESC(R, i)    EDMA_GET_SDESC(R, i, \
-+                                              struct edma_rxdesc_sec)
-+
-+#define EDMA_RX_RING_SIZE     2048
-+
-+#define EDMA_RX_RING_SIZE_MASK        (EDMA_RX_RING_SIZE - 1)
-+#define EDMA_RX_RING_ID_MASK          0x1F
-+
-+#define EDMA_MAX_PRI_PER_CORE      8
-+#define EDMA_RX_PID_IPV4_MAX          0x3
-+#define EDMA_RX_PID_IPV6              0x4
-+#define EDMA_RX_PID_IS_IPV4(pid)      (!((pid) & (~EDMA_RX_PID_IPV4_MAX)))
-+#define EDMA_RX_PID_IS_IPV6(pid)      (!(!((pid) & EDMA_RX_PID_IPV6)))
-+
-+#define EDMA_RXDESC_BUFFER_ADDR_GET(desc)     \
-+                              ((u32)(le32_to_cpu((__force __le32)((desc)->word0))))
-+#define EDMA_RXDESC_OPAQUE_GET(_desc) ({ \
-+                      typeof(_desc) (desc) = (_desc); \
-+                      ((uintptr_t)((u64)((desc)->word2) | \
-+                      ((u64)((desc)->word3) << 0x20))); })
-+
-+#define EDMA_RXDESC_SRCINFO_TYPE_PORTID               0x2000
-+#define EDMA_RXDESC_SRCINFO_TYPE_MASK         0xF000
-+#define EDMA_RXDESC_L3CSUM_STATUS_MASK                BIT(13)
-+#define EDMA_RXDESC_L4CSUM_STATUS_MASK                BIT(12)
-+#define EDMA_RXDESC_PORTNUM_BITS              0x0FFF
-+
-+#define EDMA_RXDESC_PACKET_LEN_MASK           0x3FFFF
-+#define EDMA_RXDESC_PACKET_LEN_GET(_desc) ({ \
-+                      typeof(_desc) (desc) = (_desc); \
-+                      ((le32_to_cpu((__force __le32)((desc)->word5))) & \
-+                      EDMA_RXDESC_PACKET_LEN_MASK); })
-+
-+#define EDMA_RXDESC_MORE_BIT_MASK             0x40000000
-+#define EDMA_RXDESC_MORE_BIT_GET(desc)                ((le32_to_cpu((__force __le32)((desc)->word1))) & \
-+                                              EDMA_RXDESC_MORE_BIT_MASK)
-+#define EDMA_RXDESC_SRC_DST_INFO_GET(desc)    \
-+                              ((u32)((le32_to_cpu((__force __le32)((desc)->word4)))))
-+
-+#define EDMA_RXDESC_L3_OFFSET_MASK    GENMASK(23, 16)
-+#define EDMA_RXDESC_L3_OFFSET_GET(desc)       FIELD_GET(EDMA_RXDESC_L3_OFFSET_MASK, \
-+                                      le32_to_cpu((__force __le32)((desc)->word7)))
-+
-+#define EDMA_RXDESC_PID_MASK          GENMASK(15, 12)
-+#define EDMA_RXDESC_PID_GET(desc)     FIELD_GET(EDMA_RXDESC_PID_MASK, \
-+                                      le32_to_cpu((__force __le32)((desc)->word7)))
-+
-+#define EDMA_RXDESC_DST_INFO_MASK     GENMASK(31, 16)
-+#define EDMA_RXDESC_DST_INFO_GET(desc)        FIELD_GET(EDMA_RXDESC_DST_INFO_MASK, \
-+                                      le32_to_cpu((__force __le32)((desc)->word4)))
-+
-+#define EDMA_RXDESC_SRC_INFO_MASK     GENMASK(15, 0)
-+#define EDMA_RXDESC_SRC_INFO_GET(desc)        FIELD_GET(EDMA_RXDESC_SRC_INFO_MASK, \
-+                                      le32_to_cpu((__force __le32)((desc)->word4)))
-+
-+#define EDMA_RXDESC_PORT_ID_MASK      GENMASK(11, 0)
-+#define EDMA_RXDESC_PORT_ID_GET(x)    FIELD_GET(EDMA_RXDESC_PORT_ID_MASK, x)
-+
-+#define EDMA_RXDESC_SRC_PORT_ID_GET(desc)     (EDMA_RXDESC_PORT_ID_GET \
-+                                              (EDMA_RXDESC_SRC_INFO_GET(desc)))
-+#define EDMA_RXDESC_DST_PORT_ID_GET(desc)     (EDMA_RXDESC_PORT_ID_GET \
-+                                              (EDMA_RXDESC_DST_INFO_GET(desc)))
-+
-+#define EDMA_RXDESC_DST_PORT          (0x2 << EDMA_RXDESC_PID_SHIFT)
-+
-+#define EDMA_RXDESC_L3CSUM_STATUS_GET(desc)   FIELD_GET(EDMA_RXDESC_L3CSUM_STATUS_MASK, \
-+                                              le32_to_cpu((__force __le32)(desc)->word6))
-+#define EDMA_RXDESC_L4CSUM_STATUS_GET(desc)   FIELD_GET(EDMA_RXDESC_L4CSUM_STATUS_MASK, \
-+                                              le32_to_cpu((__force __le32)(desc)->word6))
-+
-+#define EDMA_RXDESC_DATA_OFFSET_MASK          GENMASK(11, 0)
-+#define EDMA_RXDESC_DATA_OFFSET_GET(desc)     FIELD_GET(EDMA_RXDESC_DATA_OFFSET_MASK, \
-+                                              le32_to_cpu((__force __le32)(desc)->word6))
-+
-+#define EDMA_RXFILL_BUF_SIZE_MASK             0xFFFF
-+#define EDMA_RXFILL_BUF_SIZE_SHIFT            16
-+
-+/* Opaque values are not accessed by the EDMA HW,
-+ * so endianness conversion is not needed.
-+ */
-+
-+#define EDMA_RXFILL_OPAQUE_LO_SET(desc, ptr)  (((desc)->word2) = \
-+                                              (u32)(uintptr_t)(ptr))
-+#ifdef __LP64__
-+#define EDMA_RXFILL_OPAQUE_HI_SET(desc, ptr)  (((desc)->word3) = \
-+                                              (u32)((u64)(ptr) >> 0x20))
-+#endif
-+
-+#define EDMA_RXFILL_OPAQUE_GET(_desc) ({ \
-+                      typeof(_desc) (desc) = (_desc); \
-+                      ((uintptr_t)((u64)((desc)->word2) | \
-+                      ((u64)((desc)->word3) << 0x20))); })
-+
-+#define EDMA_RXFILL_PACKET_LEN_SET(desc, len) { \
-+      (((desc)->word1) = (u32)((((u32)len) << EDMA_RXFILL_BUF_SIZE_SHIFT) & \
-+                                              0xFFFF0000)); \
-+}
-+
-+#define EDMA_RXFILL_BUFFER_ADDR_SET(desc, addr)       (((desc)->word0) = (u32)(addr))
-+
-+/* Opaque values are set in word2 and word3, they are not accessed by the EDMA HW,
-+ * so endianness conversion is not needed.
-+ */
-+#define EDMA_RXFILL_ENDIAN_SET(_desc) ({ \
-+      typeof(_desc) (desc) = (_desc); \
-+      cpu_to_le32s(&((desc)->word0)); \
-+      cpu_to_le32s(&((desc)->word1)); \
-+})
-+
-+/* RX DESC size shift to obtain index from descriptor pointer. */
-+#define EDMA_RXDESC_SIZE_SHIFT                5
-+
-+/**
-+ * struct edma_rxdesc_stats - RX descriptor ring stats.
-+ * @src_port_inval: Invalid source port number
-+ * @src_port_inval_type: Source type is not PORT ID
-+ * @src_port_inval_netdev: Invalid net device for the source port
-+ * @syncp: Synchronization pointer
-+ */
-+struct edma_rxdesc_stats {
-+      u64 src_port_inval;
-+      u64 src_port_inval_type;
-+      u64 src_port_inval_netdev;
-+      struct u64_stats_sync syncp;
-+};
-+
-+/**
-+ * struct edma_rxfill_stats - Rx fill descriptor ring stats.
-+ * @alloc_failed: Buffer allocation failure count
-+ * @page_alloc_failed: Page allocation failure count for page mode
-+ * @syncp: Synchronization pointer
-+ */
-+struct edma_rxfill_stats {
-+      u64 alloc_failed;
-+      u64 page_alloc_failed;
-+      struct u64_stats_sync syncp;
-+};
-+
-+/**
-+ * struct edma_rxdesc_pri - Rx descriptor.
-+ * @word0: Buffer address
-+ * @word1: More bit, priority bit, service code
-+ * @word2: Opaque low bits
-+ * @word3: Opaque high bits
-+ * @word4: Destination and source information
-+ * @word5: WiFi QoS, data length
-+ * @word6: Hash value, check sum status
-+ * @word7: DSCP, packet offsets
-+ */
-+struct edma_rxdesc_pri {
-+      u32 word0;
-+      u32 word1;
-+      u32 word2;
-+      u32 word3;
-+      u32 word4;
-+      u32 word5;
-+      u32 word6;
-+      u32 word7;
-+};
-+
-+ /**
-+  * struct edma_rxdesc_sec - Rx secondary descriptor.
-+  * @word0: Timestamp
-+  * @word1: Secondary checksum status
-+  * @word2: QoS tag
-+  * @word3: Flow index details
-+  * @word4: Secondary packet offsets
-+  * @word5: Multicast bit, checksum
-+  * @word6: SVLAN, CVLAN
-+  * @word7: Secondary SVLAN, CVLAN
-+  */
-+struct edma_rxdesc_sec {
-+      u32 word0;
-+      u32 word1;
-+      u32 word2;
-+      u32 word3;
-+      u32 word4;
-+      u32 word5;
-+      u32 word6;
-+      u32 word7;
-+};
-+
-+/**
-+ * struct edma_rxfill_desc - RxFill descriptor.
-+ * @word0: Buffer address
-+ * @word1: Buffer size
-+ * @word2: Opaque low bits
-+ * @word3: Opaque high bits
-+ */
-+struct edma_rxfill_desc {
-+      u32 word0;
-+      u32 word1;
-+      u32 word2;
-+      u32 word3;
-+};
-+
-+/**
-+ * struct edma_rxfill_ring - RxFill ring
-+ * @ring_id: RxFill ring number
-+ * @count: Number of descriptors in the ring
-+ * @prod_idx: Ring producer index
-+ * @alloc_size: Buffer size to allocate
-+ * @desc: Descriptor ring virtual address
-+ * @dma: Descriptor ring physical address
-+ * @buf_len: Buffer length for rxfill descriptor
-+ * @page_mode: Page mode for Rx processing
-+ * @rx_fill_stats: Rx fill ring statistics
-+ */
-+struct edma_rxfill_ring {
-+      u32 ring_id;
-+      u32 count;
-+      u32 prod_idx;
-+      u32 alloc_size;
-+      struct edma_rxfill_desc *desc;
-+      dma_addr_t dma;
-+      u32 buf_len;
-+      bool page_mode;
-+      struct edma_rxfill_stats rxfill_stats;
-+};
-+
-+/**
-+ * struct edma_rxdesc_ring - RxDesc ring
-+ * @napi: Pointer to napi
-+ * @ring_id: Rxdesc ring number
-+ * @count: Number of descriptors in the ring
-+ * @work_leftover: Leftover descriptors to be processed
-+ * @cons_idx: Ring consumer index
-+ * @pdesc: Primary descriptor ring virtual address
-+ * @pdesc_head: Primary descriptor head in case of scatter-gather frame
-+ * @sdesc: Secondary descriptor ring virtual address
-+ * @rxdesc_stats: Rx descriptor ring statistics
-+ * @rxfill: RxFill ring used
-+ * @napi_added: Flag to indicate NAPI add status
-+ * @pdma: Primary descriptor ring physical address
-+ * @sdma: Secondary descriptor ring physical address
-+ * @head: Head of the skb list in case of scatter-gather frame
-+ * @last: Last skb of the skb list in case of scatter-gather frame
-+ */
-+struct edma_rxdesc_ring {
-+      struct napi_struct napi;
-+      u32 ring_id;
-+      u32 count;
-+      u32 work_leftover;
-+      u32 cons_idx;
-+      struct edma_rxdesc_pri *pdesc;
-+      struct edma_rxdesc_pri *pdesc_head;
-+      struct edma_rxdesc_sec *sdesc;
-+      struct edma_rxdesc_stats rxdesc_stats;
-+      struct edma_rxfill_ring *rxfill;
-+      bool napi_added;
-+      dma_addr_t pdma;
-+      dma_addr_t sdma;
-+      struct sk_buff *head;
-+      struct sk_buff *last;
-+};
-+
-+irqreturn_t edma_rx_handle_irq(int irq, void *ctx);
-+int edma_rx_alloc_buffer(struct edma_rxfill_ring *rxfill_ring, int alloc_count);
-+int edma_rx_napi_poll(struct napi_struct *napi, int budget);
-+#endif
diff --git a/target/linux/qualcommbe/patches-6.12/0345-net-ethernet-qualcomm-Add-Tx-Ethernet-DMA-support.patch b/target/linux/qualcommbe/patches-6.12/0345-net-ethernet-qualcomm-Add-Tx-Ethernet-DMA-support.patch
deleted file mode 100644 (file)
index 39d300d..0000000
+++ /dev/null
@@ -1,2363 +0,0 @@
-From 339d3a5365f150a78ed405684e379fee3acdbe90 Mon Sep 17 00:00:00 2001
-From: Suruchi Agarwal <quic_suruchia@quicinc.com>
-Date: Thu, 21 Mar 2024 16:26:29 -0700
-Subject: [PATCH] net: ethernet: qualcomm: Add Tx Ethernet DMA support
-
-Add Tx queues, rings, descriptors configurations and
-DMA support for the EDMA.
-
-Change-Id: Idfb0e1fe5ac494d614097d6c97dd15d63bbce8e6
-Co-developed-by: Pavithra R <quic_pavir@quicinc.com>
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
-Signed-off-by: Suruchi Agarwal <quic_suruchia@quicinc.com>
----
- drivers/net/ethernet/qualcomm/ppe/Makefile    |   2 +-
- drivers/net/ethernet/qualcomm/ppe/edma.c      |  97 ++-
- drivers/net/ethernet/qualcomm/ppe/edma.h      |   7 +
- .../net/ethernet/qualcomm/ppe/edma_cfg_tx.c   | 648 ++++++++++++++
- .../net/ethernet/qualcomm/ppe/edma_cfg_tx.h   |  28 +
- drivers/net/ethernet/qualcomm/ppe/edma_port.c | 136 +++
- drivers/net/ethernet/qualcomm/ppe/edma_port.h |  35 +
- drivers/net/ethernet/qualcomm/ppe/edma_tx.c   | 808 ++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/edma_tx.h   | 302 +++++++
- 9 files changed, 2055 insertions(+), 8 deletions(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_cfg_tx.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_cfg_tx.h
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_tx.c
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_tx.h
-
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -7,4 +7,4 @@ obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
- qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o ppe_port.o
- #EDMA
--qcom-ppe-objs += edma.o edma_cfg_rx.o edma_port.o edma_rx.o
-+qcom-ppe-objs += edma.o edma_cfg_rx.o edma_cfg_tx.o edma_port.o edma_rx.o edma_tx.o
---- a/drivers/net/ethernet/qualcomm/ppe/edma.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.c
-@@ -18,6 +18,7 @@
- #include <linux/reset.h>
- #include "edma.h"
-+#include "edma_cfg_tx.h"
- #include "edma_cfg_rx.h"
- #include "ppe_regs.h"
-@@ -25,6 +26,7 @@
- /* Global EDMA context. */
- struct edma_context *edma_ctx;
-+static char **edma_txcmpl_irq_name;
- static char **edma_rxdesc_irq_name;
- /* Module params. */
-@@ -192,22 +194,59 @@ static int edma_configure_ucast_prio_map
- static int edma_irq_register(void)
- {
-       struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-       struct edma_ring_info *rx = hw_info->rx;
-       int ret;
-       u32 i;
-+      /* Request IRQ for TXCMPL rings. */
-+      edma_txcmpl_irq_name = kzalloc((sizeof(char *) * txcmpl->num_rings), GFP_KERNEL);
-+      if (!edma_txcmpl_irq_name)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < txcmpl->num_rings; i++) {
-+              edma_txcmpl_irq_name[i] = kzalloc((sizeof(char *) * EDMA_IRQ_NAME_SIZE),
-+                                                GFP_KERNEL);
-+              if (!edma_txcmpl_irq_name[i]) {
-+                      ret = -ENOMEM;
-+                      goto txcmpl_ring_irq_name_alloc_fail;
-+              }
-+
-+              snprintf(edma_txcmpl_irq_name[i], EDMA_IRQ_NAME_SIZE, "edma_txcmpl_%d",
-+                       txcmpl->ring_start + i);
-+
-+              irq_set_status_flags(edma_ctx->intr_info.intr_txcmpl[i], IRQ_DISABLE_UNLAZY);
-+
-+              ret = request_irq(edma_ctx->intr_info.intr_txcmpl[i],
-+                                edma_tx_handle_irq, IRQF_SHARED,
-+                                edma_txcmpl_irq_name[i],
-+                                (void *)&edma_ctx->txcmpl_rings[i]);
-+              if (ret) {
-+                      pr_err("TXCMPL ring IRQ:%d request %d failed\n",
-+                             edma_ctx->intr_info.intr_txcmpl[i], i);
-+                      goto txcmpl_ring_intr_req_fail;
-+              }
-+
-+              pr_debug("TXCMPL ring: %d IRQ:%d request success: %s\n",
-+                       txcmpl->ring_start + i,
-+                       edma_ctx->intr_info.intr_txcmpl[i],
-+                       edma_txcmpl_irq_name[i]);
-+      }
-+
-       /* Request IRQ for RXDESC rings. */
-       edma_rxdesc_irq_name = kzalloc((sizeof(char *) * rx->num_rings),
-                                      GFP_KERNEL);
--      if (!edma_rxdesc_irq_name)
--              return -ENOMEM;
-+      if (!edma_rxdesc_irq_name) {
-+              ret = -ENOMEM;
-+              goto rxdesc_irq_name_alloc_fail;
-+      }
-       for (i = 0; i < rx->num_rings; i++) {
-               edma_rxdesc_irq_name[i] = kzalloc((sizeof(char *) * EDMA_IRQ_NAME_SIZE),
-                                                 GFP_KERNEL);
-               if (!edma_rxdesc_irq_name[i]) {
-                       ret = -ENOMEM;
--                      goto rxdesc_irq_name_alloc_fail;
-+                      goto rxdesc_ring_irq_name_alloc_fail;
-               }
-               snprintf(edma_rxdesc_irq_name[i], 20, "edma_rxdesc_%d",
-@@ -236,8 +275,19 @@ static int edma_irq_register(void)
- rx_desc_ring_intr_req_fail:
-       for (i = 0; i < rx->num_rings; i++)
-               kfree(edma_rxdesc_irq_name[i]);
--rxdesc_irq_name_alloc_fail:
-+rxdesc_ring_irq_name_alloc_fail:
-       kfree(edma_rxdesc_irq_name);
-+rxdesc_irq_name_alloc_fail:
-+      for (i = 0; i < txcmpl->num_rings; i++) {
-+              synchronize_irq(edma_ctx->intr_info.intr_txcmpl[i]);
-+              free_irq(edma_ctx->intr_info.intr_txcmpl[i],
-+                       (void *)&edma_ctx->txcmpl_rings[i]);
-+      }
-+txcmpl_ring_intr_req_fail:
-+      for (i = 0; i < txcmpl->num_rings; i++)
-+              kfree(edma_txcmpl_irq_name[i]);
-+txcmpl_ring_irq_name_alloc_fail:
-+      kfree(edma_txcmpl_irq_name);
-       return ret;
- }
-@@ -326,12 +376,22 @@ static int edma_irq_init(void)
- static int edma_alloc_rings(void)
- {
-+      if (edma_cfg_tx_rings_alloc()) {
-+              pr_err("Error in allocating Tx rings\n");
-+              return -ENOMEM;
-+      }
-+
-       if (edma_cfg_rx_rings_alloc()) {
-               pr_err("Error in allocating Rx rings\n");
--              return -ENOMEM;
-+              goto rx_rings_alloc_fail;
-       }
-       return 0;
-+
-+rx_rings_alloc_fail:
-+      edma_cfg_tx_rings_cleanup();
-+
-+      return -ENOMEM;
- }
- static int edma_hw_reset(void)
-@@ -389,7 +449,7 @@ static int edma_hw_configure(void)
-       struct edma_hw_info *hw_info = edma_ctx->hw_info;
-       struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-       struct regmap *regmap = ppe_dev->regmap;
--      u32 data, reg;
-+      u32 data, reg, i;
-       int ret;
-       reg = EDMA_BASE_OFFSET + EDMA_REG_MAS_CTRL_ADDR;
-@@ -439,11 +499,17 @@ static int edma_hw_configure(void)
-       }
-       /* Disable interrupts. */
-+      for (i = 1; i <= hw_info->max_ports; i++)
-+              edma_cfg_tx_disable_interrupts(i);
-+
-       edma_cfg_rx_disable_interrupts();
-       edma_cfg_rx_rings_disable();
-       edma_cfg_rx_ring_mappings();
-+      edma_cfg_tx_ring_mappings();
-+
-+      edma_cfg_tx_rings();
-       ret = edma_cfg_rx_rings();
-       if (ret) {
-@@ -520,6 +586,7 @@ configure_ucast_prio_map_tbl_failed:
-       edma_cfg_rx_napi_delete();
-       edma_cfg_rx_rings_disable();
- edma_cfg_rx_rings_failed:
-+      edma_cfg_tx_rings_cleanup();
-       edma_cfg_rx_rings_cleanup();
- edma_alloc_rings_failed:
-       free_netdev(edma_ctx->dummy_dev);
-@@ -538,13 +605,27 @@ dummy_dev_alloc_failed:
- void edma_destroy(struct ppe_device *ppe_dev)
- {
-       struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-       struct edma_ring_info *rx = hw_info->rx;
-       u32 i;
-       /* Disable interrupts. */
-+      for (i = 1; i <= hw_info->max_ports; i++)
-+              edma_cfg_tx_disable_interrupts(i);
-+
-       edma_cfg_rx_disable_interrupts();
--      /* Free IRQ for RXDESC rings. */
-+      /* Free IRQ for TXCMPL rings. */
-+      for (i = 0; i < txcmpl->num_rings; i++) {
-+              synchronize_irq(edma_ctx->intr_info.intr_txcmpl[i]);
-+
-+              free_irq(edma_ctx->intr_info.intr_txcmpl[i],
-+                       (void *)&edma_ctx->txcmpl_rings[i]);
-+              kfree(edma_txcmpl_irq_name[i]);
-+      }
-+      kfree(edma_txcmpl_irq_name);
-+
-+      /* Free IRQ for RXDESC rings */
-       for (i = 0; i < rx->num_rings; i++) {
-               synchronize_irq(edma_ctx->intr_info.intr_rx[i]);
-               free_irq(edma_ctx->intr_info.intr_rx[i],
-@@ -560,6 +641,7 @@ void edma_destroy(struct ppe_device *ppe
-       edma_cfg_rx_napi_delete();
-       edma_cfg_rx_rings_disable();
-       edma_cfg_rx_rings_cleanup();
-+      edma_cfg_tx_rings_cleanup();
-       free_netdev(edma_ctx->dummy_dev);
-       kfree(edma_ctx->netdev_arr);
-@@ -585,6 +667,7 @@ int edma_setup(struct ppe_device *ppe_de
-       edma_ctx->hw_info = &ipq9574_hw_info;
-       edma_ctx->ppe_dev = ppe_dev;
-       edma_ctx->rx_buf_size = rx_buff_size;
-+      edma_ctx->tx_requeue_stop = false;
-       /* Configure the EDMA common clocks. */
-       ret = edma_clock_init();
---- a/drivers/net/ethernet/qualcomm/ppe/edma.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.h
-@@ -7,6 +7,7 @@
- #include "ppe_config.h"
- #include "edma_rx.h"
-+#include "edma_tx.h"
- /* One clock cycle = 1/(EDMA clock frequency in Mhz) micro seconds.
-  *
-@@ -104,8 +105,11 @@ struct edma_intr_info {
-  * @intr_info: EDMA Interrupt info
-  * @rxfill_rings: Rx fill Rings, SW is producer
-  * @rx_rings: Rx Desc Rings, SW is consumer
-+ * @tx_rings: Tx Descriptor Ring, SW is producer
-+ * @txcmpl_rings: Tx complete Ring, SW is consumer
-  * @rx_page_mode: Page mode enabled or disabled
-  * @rx_buf_size: Rx buffer size for Jumbo MRU
-+ * @tx_requeue_stop: Tx requeue stop enabled or disabled
-  */
- struct edma_context {
-       struct net_device **netdev_arr;
-@@ -115,8 +119,11 @@ struct edma_context {
-       struct edma_intr_info intr_info;
-       struct edma_rxfill_ring *rxfill_rings;
-       struct edma_rxdesc_ring *rx_rings;
-+      struct edma_txdesc_ring *tx_rings;
-+      struct edma_txcmpl_ring *txcmpl_rings;
-       u32 rx_page_mode;
-       u32 rx_buf_size;
-+      bool tx_requeue_stop;
- };
- /* Global EDMA context */
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_tx.c
-@@ -0,0 +1,648 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* Configure rings, Buffers and NAPI for transmit path along with
-+ * providing APIs to enable, disable, clean and map the Tx rings.
-+ */
-+
-+#include <linux/dma-mapping.h>
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/printk.h>
-+#include <linux/regmap.h>
-+#include <linux/skbuff.h>
-+
-+#include "edma.h"
-+#include "edma_cfg_tx.h"
-+#include "edma_port.h"
-+#include "ppe.h"
-+#include "ppe_regs.h"
-+
-+static void edma_cfg_txcmpl_ring_cleanup(struct edma_txcmpl_ring *txcmpl_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev =  ppe_dev->dev;
-+
-+      /* Free any buffers assigned to any descriptors. */
-+      edma_tx_complete(EDMA_TX_RING_SIZE - 1, txcmpl_ring);
-+
-+      /* Free TxCmpl ring descriptors. */
-+      dma_free_coherent(dev, sizeof(struct edma_txcmpl_desc)
-+                        * txcmpl_ring->count, txcmpl_ring->desc,
-+                        txcmpl_ring->dma);
-+      txcmpl_ring->desc = NULL;
-+      txcmpl_ring->dma = (dma_addr_t)0;
-+}
-+
-+static int edma_cfg_txcmpl_ring_setup(struct edma_txcmpl_ring *txcmpl_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev =  ppe_dev->dev;
-+
-+      /* Allocate RxFill ring descriptors. */
-+      txcmpl_ring->desc = dma_alloc_coherent(dev, sizeof(struct edma_txcmpl_desc)
-+                                             * txcmpl_ring->count,
-+                                             &txcmpl_ring->dma,
-+                                             GFP_KERNEL | __GFP_ZERO);
-+
-+      if (unlikely(!txcmpl_ring->desc))
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+static void edma_cfg_tx_desc_ring_cleanup(struct edma_txdesc_ring *txdesc_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_txdesc_pri *txdesc = NULL;
-+      struct device *dev =  ppe_dev->dev;
-+      u32 prod_idx, cons_idx, data, reg;
-+      struct sk_buff *skb = NULL;
-+
-+      /* Free any buffers assigned to any descriptors. */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_PROD_IDX(txdesc_ring->id);
-+      regmap_read(regmap, reg, &data);
-+      prod_idx = data & EDMA_TXDESC_PROD_IDX_MASK;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_CONS_IDX(txdesc_ring->id);
-+      regmap_read(regmap, reg, &data);
-+      cons_idx = data & EDMA_TXDESC_CONS_IDX_MASK;
-+
-+      /* Walk active list, obtain skb from descriptor and free it. */
-+      while (cons_idx != prod_idx) {
-+              txdesc = EDMA_TXDESC_PRI_DESC(txdesc_ring, cons_idx);
-+              skb = (struct sk_buff *)EDMA_TXDESC_OPAQUE_GET(txdesc);
-+              dev_kfree_skb_any(skb);
-+
-+              cons_idx = ((cons_idx + 1) & EDMA_TX_RING_SIZE_MASK);
-+      }
-+
-+      /* Free Tx ring descriptors. */
-+      dma_free_coherent(dev, (sizeof(struct edma_txdesc_pri)
-+                        * txdesc_ring->count),
-+                        txdesc_ring->pdesc,
-+                        txdesc_ring->pdma);
-+      txdesc_ring->pdesc = NULL;
-+      txdesc_ring->pdma = (dma_addr_t)0;
-+
-+      /* Free any buffers assigned to any secondary descriptors. */
-+      dma_free_coherent(dev, (sizeof(struct edma_txdesc_sec)
-+                        * txdesc_ring->count),
-+                        txdesc_ring->sdesc,
-+                        txdesc_ring->sdma);
-+      txdesc_ring->sdesc = NULL;
-+      txdesc_ring->sdma = (dma_addr_t)0;
-+}
-+
-+static int edma_cfg_tx_desc_ring_setup(struct edma_txdesc_ring *txdesc_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev = ppe_dev->dev;
-+
-+      /* Allocate RxFill ring descriptors. */
-+      txdesc_ring->pdesc = dma_alloc_coherent(dev, sizeof(struct edma_txdesc_pri)
-+                                              * txdesc_ring->count,
-+                                              &txdesc_ring->pdma,
-+                                              GFP_KERNEL | __GFP_ZERO);
-+
-+      if (unlikely(!txdesc_ring->pdesc))
-+              return -ENOMEM;
-+
-+      txdesc_ring->sdesc = dma_alloc_coherent(dev, sizeof(struct edma_txdesc_sec)
-+                                              * txdesc_ring->count,
-+                                              &txdesc_ring->sdma,
-+                                              GFP_KERNEL | __GFP_ZERO);
-+
-+      if (unlikely(!txdesc_ring->sdesc)) {
-+              dma_free_coherent(dev, (sizeof(struct edma_txdesc_pri)
-+                                * txdesc_ring->count),
-+                                txdesc_ring->pdesc,
-+                                txdesc_ring->pdma);
-+              txdesc_ring->pdesc = NULL;
-+              txdesc_ring->pdma = (dma_addr_t)0;
-+              return -ENOMEM;
-+      }
-+
-+      return 0;
-+}
-+
-+static void edma_cfg_tx_desc_ring_configure(struct edma_txdesc_ring *txdesc_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 data, reg;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_BA(txdesc_ring->id);
-+      regmap_write(regmap, reg, (u32)(txdesc_ring->pdma & EDMA_RING_DMA_MASK));
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_BA2(txdesc_ring->id);
-+      regmap_write(regmap, reg, (u32)(txdesc_ring->sdma & EDMA_RING_DMA_MASK));
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_RING_SIZE(txdesc_ring->id);
-+      regmap_write(regmap, reg, (u32)(txdesc_ring->count & EDMA_TXDESC_RING_SIZE_MASK));
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_PROD_IDX(txdesc_ring->id);
-+      regmap_write(regmap, reg, (u32)EDMA_TX_INITIAL_PROD_IDX);
-+
-+      data = FIELD_PREP(EDMA_TXDESC_CTRL_FC_GRP_ID_MASK, txdesc_ring->fc_grp_id);
-+
-+      /* Configure group ID for flow control for this Tx ring. */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_CTRL(txdesc_ring->id);
-+      regmap_write(regmap, reg, data);
-+}
-+
-+static void edma_cfg_txcmpl_ring_configure(struct edma_txcmpl_ring *txcmpl_ring)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 data, reg;
-+
-+      /* Configure TxCmpl ring base address. */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXCMPL_BA(txcmpl_ring->id);
-+      regmap_write(regmap, reg, (u32)(txcmpl_ring->dma & EDMA_RING_DMA_MASK));
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXCMPL_RING_SIZE(txcmpl_ring->id);
-+      regmap_write(regmap, reg, (u32)(txcmpl_ring->count & EDMA_TXDESC_RING_SIZE_MASK));
-+
-+      /* Set TxCmpl ret mode to opaque. */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXCMPL_CTRL(txcmpl_ring->id);
-+      regmap_write(regmap, reg, EDMA_TXCMPL_RETMODE_OPAQUE);
-+
-+      /* Configure the Mitigation timer. */
-+      data = EDMA_MICROSEC_TO_TIMER_UNIT(EDMA_TX_MITIGATION_TIMER_DEF,
-+                                         ppe_dev->clk_rate / MHZ);
-+      data = ((data & EDMA_TX_MOD_TIMER_INIT_MASK)
-+              << EDMA_TX_MOD_TIMER_INIT_SHIFT);
-+      pr_debug("EDMA Tx mitigation timer value: %d\n", data);
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TX_MOD_TIMER(txcmpl_ring->id);
-+      regmap_write(regmap, reg, data);
-+
-+      /* Configure the Mitigation packet count. */
-+      data = (EDMA_TX_MITIGATION_PKT_CNT_DEF & EDMA_TXCMPL_LOW_THRE_MASK)
-+              << EDMA_TXCMPL_LOW_THRE_SHIFT;
-+      pr_debug("EDMA Tx mitigation packet count value: %d\n", data);
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXCMPL_UGT_THRE(txcmpl_ring->id);
-+      regmap_write(regmap, reg, data);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TX_INT_CTRL(txcmpl_ring->id);
-+      regmap_write(regmap, reg, EDMA_TX_NE_INT_EN);
-+}
-+
-+/**
-+ * edma_cfg_tx_fill_per_port_tx_map - Fill Tx ring mapping.
-+ * @netdev: Netdevice.
-+ * @port_id: Port ID.
-+ *
-+ * Fill per-port Tx ring mapping in net device private area.
-+ */
-+void edma_cfg_tx_fill_per_port_tx_map(struct net_device *netdev, u32 port_id)
-+{
-+      u32 i;
-+
-+      /* Ring to core mapping is done in order starting from 0 for port 1. */
-+      for_each_possible_cpu(i) {
-+              struct edma_port_priv *port_dev = (struct edma_port_priv *)netdev_priv(netdev);
-+              struct edma_txdesc_ring *txdesc_ring;
-+              u32 txdesc_ring_id;
-+
-+              txdesc_ring_id = ((port_id - 1) * num_possible_cpus()) + i;
-+              txdesc_ring = &edma_ctx->tx_rings[txdesc_ring_id];
-+              port_dev->txr_map[i] = txdesc_ring;
-+      }
-+}
-+
-+/**
-+ * edma_cfg_tx_rings_enable - Enable Tx rings.
-+ *
-+ * Enable Tx rings.
-+ */
-+void edma_cfg_tx_rings_enable(u32 port_id)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_txdesc_ring *txdesc_ring;
-+      u32 i, ring_idx, reg;
-+
-+      for_each_possible_cpu(i) {
-+              ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-+              txdesc_ring = &edma_ctx->tx_rings[ring_idx];
-+              u32 data;
-+
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_CTRL(txdesc_ring->id);
-+              regmap_read(regmap, reg, &data);
-+              data |= FIELD_PREP(EDMA_TXDESC_CTRL_TXEN_MASK, EDMA_TXDESC_TX_ENABLE);
-+
-+              regmap_write(regmap, reg, data);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_tx_rings_disable - Disable Tx rings.
-+ *
-+ * Disable Tx rings.
-+ */
-+void edma_cfg_tx_rings_disable(u32 port_id)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_txdesc_ring *txdesc_ring;
-+      u32 i, ring_idx, reg;
-+
-+      for_each_possible_cpu(i) {
-+              ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-+              txdesc_ring = &edma_ctx->tx_rings[ring_idx];
-+              u32 data;
-+
-+              txdesc_ring = &edma_ctx->tx_rings[i];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_CTRL(txdesc_ring->id);
-+              regmap_read(regmap, reg, &data);
-+              data &= ~EDMA_TXDESC_TX_ENABLE;
-+              regmap_write(regmap, reg, data);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_tx_ring_mappings - Map Tx to Tx complete rings.
-+ *
-+ * Map Tx to Tx complete rings.
-+ */
-+void edma_cfg_tx_ring_mappings(void)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_ring_info *tx = hw_info->tx;
-+      u32 desc_index, i, data, reg;
-+
-+      /* Clear the TXDESC2CMPL_MAP_xx reg before setting up
-+       * the mapping. This register holds TXDESC to TXFILL ring
-+       * mapping.
-+       */
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_0_ADDR, 0);
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_1_ADDR, 0);
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_2_ADDR, 0);
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_3_ADDR, 0);
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_4_ADDR, 0);
-+      regmap_write(regmap, EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_5_ADDR, 0);
-+      desc_index = txcmpl->ring_start;
-+
-+      /* 6 registers to hold the completion mapping for total 32
-+       * TX desc rings (0-5, 6-11, 12-17, 18-23, 24-29 and rest).
-+       * In each entry 5 bits hold the mapping for a particular TX desc ring.
-+       */
-+      for (i = tx->ring_start; i < tx->ring_start + tx->num_rings; i++) {
-+              u32 reg, data;
-+
-+              if (i >= 0 && i <= 5)
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_0_ADDR;
-+              else if (i >= 6 && i <= 11)
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_1_ADDR;
-+              else if (i >= 12 && i <= 17)
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_2_ADDR;
-+              else if (i >= 18 && i <= 23)
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_3_ADDR;
-+              else if (i >= 24 && i <= 29)
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_4_ADDR;
-+              else
-+                      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_5_ADDR;
-+
-+              pr_debug("Configure Tx desc:%u to use TxCmpl:%u\n", i, desc_index);
-+
-+              /* Set the Tx complete descriptor ring number in the mapping register.
-+               * E.g. If (txcmpl ring)desc_index = 31, (txdesc ring)i = 28.
-+               *      reg = EDMA_REG_TXDESC2CMPL_MAP_4_ADDR
-+               *      data |= (desc_index & 0x1F) << ((i % 6) * 5);
-+               *      data |= (0x1F << 20); -
-+               *      This sets 11111 at 20th bit of register EDMA_REG_TXDESC2CMPL_MAP_4_ADDR.
-+               */
-+              regmap_read(regmap, reg, &data);
-+              data |= (desc_index & EDMA_TXDESC2CMPL_MAP_TXDESC_MASK) << ((i % 6) * 5);
-+              regmap_write(regmap, reg, data);
-+
-+              desc_index++;
-+              if (desc_index == txcmpl->ring_start + txcmpl->num_rings)
-+                      desc_index = txcmpl->ring_start;
-+      }
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_0_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_TXDESC2CMPL_MAP_0_ADDR: 0x%x\n", data);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_1_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_TXDESC2CMPL_MAP_1_ADDR: 0x%x\n", data);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_2_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_TXDESC2CMPL_MAP_2_ADDR: 0x%x\n", data);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_3_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_TXDESC2CMPL_MAP_3_ADDR: 0x%x\n", data);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_4_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_TXDESC2CMPL_MAP_4_ADDR: 0x%x\n", data);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC2CMPL_MAP_5_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      pr_debug("EDMA_REG_TXDESC2CMPL_MAP_5_ADDR: 0x%x\n", data);
-+}
-+
-+static int edma_cfg_tx_rings_setup(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-+      struct edma_ring_info *tx = hw_info->tx;
-+      u32 i, j = 0;
-+
-+      /* Set Txdesc flow control group id, same as port number. */
-+      for (i = 0; i < hw_info->max_ports; i++) {
-+              for_each_possible_cpu(j) {
-+                      struct edma_txdesc_ring *txdesc_ring = NULL;
-+                      u32 txdesc_idx = (i * num_possible_cpus()) + j;
-+
-+                      txdesc_ring = &edma_ctx->tx_rings[txdesc_idx];
-+                      txdesc_ring->fc_grp_id = i + 1;
-+              }
-+      }
-+
-+      /* Allocate TxDesc ring descriptors. */
-+      for (i = 0; i < tx->num_rings; i++) {
-+              struct edma_txdesc_ring *txdesc_ring = NULL;
-+              int ret;
-+
-+              txdesc_ring = &edma_ctx->tx_rings[i];
-+              txdesc_ring->count = EDMA_TX_RING_SIZE;
-+              txdesc_ring->id = tx->ring_start + i;
-+
-+              ret = edma_cfg_tx_desc_ring_setup(txdesc_ring);
-+              if (ret) {
-+                      pr_err("Error in setting up %d txdesc ring. ret: %d",
-+                             txdesc_ring->id, ret);
-+                      while (i-- >= 0)
-+                              edma_cfg_tx_desc_ring_cleanup(&edma_ctx->tx_rings[i]);
-+
-+                      return -ENOMEM;
-+              }
-+      }
-+
-+      /* Allocate TxCmpl ring descriptors. */
-+      for (i = 0; i < txcmpl->num_rings; i++) {
-+              struct edma_txcmpl_ring *txcmpl_ring = NULL;
-+              int ret;
-+
-+              txcmpl_ring = &edma_ctx->txcmpl_rings[i];
-+              txcmpl_ring->count = EDMA_TX_RING_SIZE;
-+              txcmpl_ring->id = txcmpl->ring_start + i;
-+
-+              ret = edma_cfg_txcmpl_ring_setup(txcmpl_ring);
-+              if (ret != 0) {
-+                      pr_err("Error in setting up %d TxCmpl ring. ret: %d",
-+                             txcmpl_ring->id, ret);
-+                      while (i-- >= 0)
-+                              edma_cfg_txcmpl_ring_cleanup(&edma_ctx->txcmpl_rings[i]);
-+
-+                      goto txcmpl_mem_alloc_fail;
-+              }
-+      }
-+
-+      pr_debug("Tx descriptor count for Tx desc and Tx complete rings: %d\n",
-+               EDMA_TX_RING_SIZE);
-+
-+      return 0;
-+
-+txcmpl_mem_alloc_fail:
-+      for (i = 0; i < tx->num_rings; i++)
-+              edma_cfg_tx_desc_ring_cleanup(&edma_ctx->tx_rings[i]);
-+
-+      return -ENOMEM;
-+}
-+
-+/**
-+ * edma_cfg_tx_rings_alloc - Allocate EDMA Tx rings.
-+ *
-+ * Allocate EDMA Tx rings.
-+ */
-+int edma_cfg_tx_rings_alloc(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-+      struct edma_ring_info *tx = hw_info->tx;
-+
-+      edma_ctx->tx_rings = kzalloc((sizeof(*edma_ctx->tx_rings) * tx->num_rings),
-+                                   GFP_KERNEL);
-+      if (!edma_ctx->tx_rings)
-+              return -ENOMEM;
-+
-+      edma_ctx->txcmpl_rings = kzalloc((sizeof(*edma_ctx->txcmpl_rings) * txcmpl->num_rings),
-+                                       GFP_KERNEL);
-+      if (!edma_ctx->txcmpl_rings)
-+              goto txcmpl_ring_alloc_fail;
-+
-+      pr_debug("Num rings - TxDesc:%u (%u-%u) TxCmpl:%u (%u-%u)\n",
-+               tx->num_rings, tx->ring_start,
-+              (tx->ring_start + tx->num_rings - 1),
-+              txcmpl->num_rings, txcmpl->ring_start,
-+              (txcmpl->ring_start + txcmpl->num_rings - 1));
-+
-+      if (edma_cfg_tx_rings_setup()) {
-+              pr_err("Error in setting up tx rings\n");
-+              goto tx_rings_setup_fail;
-+      }
-+
-+      return 0;
-+
-+tx_rings_setup_fail:
-+      kfree(edma_ctx->txcmpl_rings);
-+      edma_ctx->txcmpl_rings = NULL;
-+
-+txcmpl_ring_alloc_fail:
-+      kfree(edma_ctx->tx_rings);
-+      edma_ctx->tx_rings = NULL;
-+
-+      return -ENOMEM;
-+}
-+
-+/**
-+ * edma_cfg_tx_rings_cleanup - Cleanup EDMA Tx rings.
-+ *
-+ * Cleanup EDMA Tx rings.
-+ */
-+void edma_cfg_tx_rings_cleanup(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-+      struct edma_ring_info *tx = hw_info->tx;
-+      u32 i;
-+
-+      /* Free any buffers assigned to any descriptors. */
-+      for (i = 0; i < tx->num_rings; i++)
-+              edma_cfg_tx_desc_ring_cleanup(&edma_ctx->tx_rings[i]);
-+
-+      /* Free Tx completion descriptors. */
-+      for (i = 0; i < txcmpl->num_rings; i++)
-+              edma_cfg_txcmpl_ring_cleanup(&edma_ctx->txcmpl_rings[i]);
-+
-+      kfree(edma_ctx->tx_rings);
-+      kfree(edma_ctx->txcmpl_rings);
-+      edma_ctx->tx_rings = NULL;
-+      edma_ctx->txcmpl_rings = NULL;
-+}
-+
-+/**
-+ * edma_cfg_tx_rings - Configure EDMA Tx rings.
-+ *
-+ * Configure EDMA Tx rings.
-+ */
-+void edma_cfg_tx_rings(void)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-+      struct edma_ring_info *tx = hw_info->tx;
-+      u32 i;
-+
-+      /* Configure Tx desc ring. */
-+      for (i = 0; i < tx->num_rings; i++)
-+              edma_cfg_tx_desc_ring_configure(&edma_ctx->tx_rings[i]);
-+
-+      /* Configure TxCmpl ring. */
-+      for (i = 0; i < txcmpl->num_rings; i++)
-+              edma_cfg_txcmpl_ring_configure(&edma_ctx->txcmpl_rings[i]);
-+}
-+
-+/**
-+ * edma_cfg_tx_disable_interrupts - EDMA disable TX interrupts.
-+ *
-+ * Disable TX interrupt masks.
-+ */
-+void edma_cfg_tx_disable_interrupts(u32 port_id)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_txcmpl_ring *txcmpl_ring;
-+      u32 i, ring_idx, reg;
-+
-+      for_each_possible_cpu(i) {
-+              ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-+              txcmpl_ring = &edma_ctx->txcmpl_rings[ring_idx];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_TX_INT_MASK(txcmpl_ring->id);
-+              regmap_write(regmap, reg, EDMA_MASK_INT_CLEAR);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_tx_enable_interrupts - EDMA enable TX interrupts.
-+ *
-+ * Enable TX interrupt masks.
-+ */
-+void edma_cfg_tx_enable_interrupts(u32 port_id)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_txcmpl_ring *txcmpl_ring;
-+      u32 i, ring_idx, reg;
-+
-+      for_each_possible_cpu(i) {
-+              ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-+              txcmpl_ring = &edma_ctx->txcmpl_rings[ring_idx];
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_TX_INT_MASK(txcmpl_ring->id);
-+              regmap_write(regmap, reg, edma_ctx->intr_info.intr_mask_txcmpl);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_tx_napi_enable - EDMA Tx NAPI.
-+ * @port_id: Port ID.
-+ *
-+ * Enable Tx NAPI.
-+ */
-+void edma_cfg_tx_napi_enable(u32 port_id)
-+{
-+      struct edma_txcmpl_ring *txcmpl_ring;
-+      u32 i, ring_idx;
-+
-+      /* Enabling Tx napi for a interface with each queue. */
-+      for_each_possible_cpu(i) {
-+              ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-+              txcmpl_ring = &edma_ctx->txcmpl_rings[ring_idx];
-+              if (!txcmpl_ring->napi_added)
-+                      continue;
-+
-+              napi_enable(&txcmpl_ring->napi);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_tx_napi_disable - Disable Tx NAPI.
-+ * @port_id: Port ID.
-+ *
-+ * Disable Tx NAPI.
-+ */
-+void edma_cfg_tx_napi_disable(u32 port_id)
-+{
-+      struct edma_txcmpl_ring *txcmpl_ring;
-+      u32 i, ring_idx;
-+
-+      /* Disabling Tx napi for a interface with each queue. */
-+      for_each_possible_cpu(i) {
-+              ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-+              txcmpl_ring = &edma_ctx->txcmpl_rings[ring_idx];
-+              if (!txcmpl_ring->napi_added)
-+                      continue;
-+
-+              napi_disable(&txcmpl_ring->napi);
-+      }
-+}
-+
-+/**
-+ * edma_cfg_tx_napi_delete - Delete Tx NAPI.
-+ * @port_id: Port ID.
-+ *
-+ * Delete Tx NAPI.
-+ */
-+void edma_cfg_tx_napi_delete(u32 port_id)
-+{
-+      struct edma_txcmpl_ring *txcmpl_ring;
-+      u32 i, ring_idx;
-+
-+      /* Disabling Tx napi for a interface with each queue. */
-+      for_each_possible_cpu(i) {
-+              ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-+              txcmpl_ring = &edma_ctx->txcmpl_rings[ring_idx];
-+              if (!txcmpl_ring->napi_added)
-+                      continue;
-+
-+              netif_napi_del(&txcmpl_ring->napi);
-+              txcmpl_ring->napi_added = false;
-+      }
-+}
-+
-+/**
-+ * edma_cfg_tx_napi_add - TX NAPI add.
-+ * @netdev: Netdevice.
-+ * @port_id: Port ID.
-+ *
-+ * TX NAPI add.
-+ */
-+void edma_cfg_tx_napi_add(struct net_device *netdev, u32 port_id)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_txcmpl_ring *txcmpl_ring;
-+      u32 i, ring_idx;
-+
-+      /* Adding tx napi for a interface with each queue. */
-+      for_each_possible_cpu(i) {
-+              ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-+              txcmpl_ring = &edma_ctx->txcmpl_rings[ring_idx];
-+              netif_napi_add_weight(netdev, &txcmpl_ring->napi,
-+                                    edma_tx_napi_poll, hw_info->napi_budget_tx);
-+              txcmpl_ring->napi_added = true;
-+              netdev_dbg(netdev, "Napi added for txcmpl ring: %u\n", txcmpl_ring->id);
-+      }
-+
-+      netdev_dbg(netdev, "Tx NAPI budget: %d\n", hw_info->napi_budget_tx);
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_tx.h
-@@ -0,0 +1,28 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __EDMA_CFG_TX__
-+#define __EDMA_CFG_TX__
-+
-+/* Tx mitigation timer's default value. */
-+#define EDMA_TX_MITIGATION_TIMER_DEF  250
-+
-+/* Tx mitigation packet count default value. */
-+#define EDMA_TX_MITIGATION_PKT_CNT_DEF        16
-+
-+void edma_cfg_tx_rings(void);
-+int edma_cfg_tx_rings_alloc(void);
-+void edma_cfg_tx_rings_cleanup(void);
-+void edma_cfg_tx_disable_interrupts(u32 port_id);
-+void edma_cfg_tx_enable_interrupts(u32 port_id);
-+void edma_cfg_tx_napi_enable(u32 port_id);
-+void edma_cfg_tx_napi_disable(u32 port_id);
-+void edma_cfg_tx_napi_delete(u32 port_id);
-+void edma_cfg_tx_napi_add(struct net_device *netdevice, u32 macid);
-+void edma_cfg_tx_ring_mappings(void);
-+void edma_cfg_txcmpl_mapping_fill(void);
-+void edma_cfg_tx_rings_enable(u32 port_id);
-+void edma_cfg_tx_rings_disable(u32 port_id);
-+void edma_cfg_tx_fill_per_port_tx_map(struct net_device *netdev, u32 macid);
-+#endif
---- a/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-@@ -13,6 +13,7 @@
- #include "edma.h"
- #include "edma_cfg_rx.h"
-+#include "edma_cfg_tx.h"
- #include "edma_port.h"
- #include "ppe_regs.h"
-@@ -35,6 +36,15 @@ static int edma_port_stats_alloc(struct
-               return -ENOMEM;
-       }
-+      port_priv->pcpu_stats.tx_stats =
-+              netdev_alloc_pcpu_stats(struct edma_port_tx_stats);
-+      if (!port_priv->pcpu_stats.tx_stats) {
-+              netdev_err(netdev, "Per-cpu EDMA Tx stats alloc failed for %s\n",
-+                         netdev->name);
-+              free_percpu(port_priv->pcpu_stats.rx_stats);
-+              return -ENOMEM;
-+      }
-+
-       return 0;
- }
-@@ -43,6 +53,28 @@ static void edma_port_stats_free(struct
-       struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-       free_percpu(port_priv->pcpu_stats.rx_stats);
-+      free_percpu(port_priv->pcpu_stats.tx_stats);
-+}
-+
-+static void edma_port_configure(struct net_device *netdev)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *port =  port_priv->ppe_port;
-+      int port_id = port->port_id;
-+
-+      edma_cfg_tx_fill_per_port_tx_map(netdev, port_id);
-+      edma_cfg_tx_rings_enable(port_id);
-+      edma_cfg_tx_napi_add(netdev, port_id);
-+}
-+
-+static void edma_port_deconfigure(struct net_device *netdev)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *port =  port_priv->ppe_port;
-+      int port_id = port->port_id;
-+
-+      edma_cfg_tx_napi_delete(port_id);
-+      edma_cfg_tx_rings_disable(port_id);
- }
- static u16 __maybe_unused edma_port_select_queue(__maybe_unused struct net_device *netdev,
-@@ -60,6 +92,7 @@ static int edma_port_open(struct net_dev
- {
-       struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-       struct ppe_port *ppe_port;
-+      int port_id;
-       if (!port_priv)
-               return -EINVAL;
-@@ -74,10 +107,14 @@ static int edma_port_open(struct net_dev
-       netdev->wanted_features |= EDMA_NETDEV_FEATURES;
-       ppe_port  = port_priv->ppe_port;
-+      port_id = ppe_port->port_id;
-       if (ppe_port->phylink)
-               phylink_start(ppe_port->phylink);
-+      edma_cfg_tx_napi_enable(port_id);
-+      edma_cfg_tx_enable_interrupts(port_id);
-+
-       netif_start_queue(netdev);
-       return 0;
-@@ -87,13 +124,21 @@ static int edma_port_close(struct net_de
- {
-       struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-       struct ppe_port *ppe_port;
-+      int port_id;
-       if (!port_priv)
-               return -EINVAL;
-       netif_stop_queue(netdev);
-+      /* 20ms delay would provide a plenty of margin to take care of in-flight packets. */
-+      msleep(20);
-+
-       ppe_port  = port_priv->ppe_port;
-+      port_id = ppe_port->port_id;
-+
-+      edma_cfg_tx_disable_interrupts(port_id);
-+      edma_cfg_tx_napi_disable(port_id);
-       /* Phylink close. */
-       if (ppe_port->phylink)
-@@ -137,6 +182,92 @@ static netdev_features_t edma_port_featu
-       return features;
- }
-+static netdev_tx_t edma_port_xmit(struct sk_buff *skb,
-+                                struct net_device *dev)
-+{
-+      struct edma_port_priv *port_priv = NULL;
-+      struct edma_port_pcpu_stats *pcpu_stats;
-+      struct edma_txdesc_ring *txdesc_ring;
-+      struct edma_port_tx_stats *stats;
-+      enum edma_tx_gso_status result;
-+      struct sk_buff *segs = NULL;
-+      u8 cpu_id;
-+      u32 skbq;
-+      int ret;
-+
-+      if (!skb || !dev)
-+              return NETDEV_TX_OK;
-+
-+      port_priv = netdev_priv(dev);
-+
-+      /* Select a TX ring. */
-+      skbq = (skb_get_queue_mapping(skb) & (num_possible_cpus() - 1));
-+
-+      txdesc_ring = (struct edma_txdesc_ring *)port_priv->txr_map[skbq];
-+
-+      pcpu_stats = &port_priv->pcpu_stats;
-+      stats = this_cpu_ptr(pcpu_stats->tx_stats);
-+
-+      /* HW does not support TSO for packets with more than or equal to
-+       * 32 segments. Perform SW GSO for such packets.
-+       */
-+      result = edma_tx_gso_segment(skb, dev, &segs);
-+      if (likely(result == EDMA_TX_GSO_NOT_NEEDED)) {
-+              /* Transmit the packet. */
-+              ret = edma_tx_ring_xmit(dev, skb, txdesc_ring, stats);
-+
-+              if (unlikely(ret == EDMA_TX_FAIL_NO_DESC)) {
-+                      if (likely(!edma_ctx->tx_requeue_stop)) {
-+                              cpu_id = smp_processor_id();
-+                              netdev_dbg(dev, "Stopping tx queue due to lack oftx descriptors\n");
-+                              u64_stats_update_begin(&stats->syncp);
-+                              ++stats->tx_queue_stopped[cpu_id];
-+                              u64_stats_update_end(&stats->syncp);
-+                              netif_tx_stop_queue(netdev_get_tx_queue(dev, skbq));
-+                              return NETDEV_TX_BUSY;
-+                      }
-+              }
-+
-+              if (unlikely(ret != EDMA_TX_OK)) {
-+                      dev_kfree_skb_any(skb);
-+                      u64_stats_update_begin(&stats->syncp);
-+                      ++stats->tx_drops;
-+                      u64_stats_update_end(&stats->syncp);
-+              }
-+
-+              return NETDEV_TX_OK;
-+      } else if (unlikely(result == EDMA_TX_GSO_FAIL)) {
-+              netdev_dbg(dev, "%p: SW GSO failed for segment size: %d\n",
-+                         skb, skb_shinfo(skb)->gso_segs);
-+              dev_kfree_skb_any(skb);
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->tx_gso_drop_pkts;
-+              u64_stats_update_end(&stats->syncp);
-+              return NETDEV_TX_OK;
-+      }
-+
-+      u64_stats_update_begin(&stats->syncp);
-+      ++stats->tx_gso_pkts;
-+      u64_stats_update_end(&stats->syncp);
-+
-+      dev_kfree_skb_any(skb);
-+      while (segs) {
-+              skb = segs;
-+              segs = segs->next;
-+
-+              /* Transmit the packet. */
-+              ret = edma_tx_ring_xmit(dev, skb, txdesc_ring, stats);
-+              if (unlikely(ret != EDMA_TX_OK)) {
-+                      dev_kfree_skb_any(skb);
-+                      u64_stats_update_begin(&stats->syncp);
-+                      ++stats->tx_drops;
-+                      u64_stats_update_end(&stats->syncp);
-+              }
-+      }
-+
-+      return NETDEV_TX_OK;
-+}
-+
- static void edma_port_get_stats64(struct net_device *netdev,
-                                 struct rtnl_link_stats64 *stats)
- {
-@@ -179,6 +310,7 @@ static int edma_port_set_mac_address(str
- static const struct net_device_ops edma_port_netdev_ops = {
-       .ndo_open = edma_port_open,
-       .ndo_stop = edma_port_close,
-+      .ndo_start_xmit = edma_port_xmit,
-       .ndo_get_stats64 = edma_port_get_stats64,
-       .ndo_set_mac_address = edma_port_set_mac_address,
-       .ndo_validate_addr = eth_validate_addr,
-@@ -199,6 +331,7 @@ void edma_port_destroy(struct ppe_port *
-       int port_id = port->port_id;
-       struct net_device *netdev = edma_ctx->netdev_arr[port_id - 1];
-+      edma_port_deconfigure(netdev);
-       edma_port_stats_free(netdev);
-       unregister_netdev(netdev);
-       free_netdev(netdev);
-@@ -276,6 +409,8 @@ int edma_port_setup(struct ppe_port *por
-        */
-       edma_ctx->netdev_arr[port_id - 1] = netdev;
-+      edma_port_configure(netdev);
-+
-       /* Setup phylink. */
-       ret = ppe_port_phylink_setup(port, netdev);
-       if (ret) {
-@@ -298,6 +433,7 @@ int edma_port_setup(struct ppe_port *por
- register_netdev_fail:
-       ppe_port_phylink_destroy(port);
- port_phylink_setup_fail:
-+      edma_port_deconfigure(netdev);
-       edma_ctx->netdev_arr[port_id - 1] = NULL;
-       edma_port_stats_free(netdev);
- stats_alloc_fail:
---- a/drivers/net/ethernet/qualcomm/ppe/edma_port.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_port.h
-@@ -7,6 +7,8 @@
- #include "ppe_port.h"
-+#define EDMA_PORT_MAX_CORE            4
-+
- #define EDMA_NETDEV_FEATURES          (NETIF_F_FRAGLIST \
-                                       | NETIF_F_SG \
-                                       | NETIF_F_RXCSUM \
-@@ -35,11 +37,43 @@ struct edma_port_rx_stats {
- };
- /**
-+ * struct edma_port_tx_stats - EDMA TX port per CPU stats for the port.
-+ * @tx_pkts: Number of Tx packets
-+ * @tx_bytes: Number of Tx bytes
-+ * @tx_drops: Number of Tx drops
-+ * @tx_nr_frag_pkts: Number of Tx nr_frag packets
-+ * @tx_fraglist_pkts: Number of Tx fraglist packets
-+ * @tx_fraglist_with_nr_frags_pkts:  Number of Tx packets with fraglist and nr_frags
-+ * @tx_tso_pkts: Number of Tx TSO packets
-+ * @tx_tso_drop_pkts: Number of Tx TSO drop packets
-+ * @tx_gso_pkts: Number of Tx GSO packets
-+ * @tx_gso_drop_pkts: Number of Tx GSO drop packets
-+ * @tx_queue_stopped: Number of Tx queue stopped packets
-+ * @syncp: Synchronization pointer
-+ */
-+struct edma_port_tx_stats {
-+      u64 tx_pkts;
-+      u64 tx_bytes;
-+      u64 tx_drops;
-+      u64 tx_nr_frag_pkts;
-+      u64 tx_fraglist_pkts;
-+      u64 tx_fraglist_with_nr_frags_pkts;
-+      u64 tx_tso_pkts;
-+      u64 tx_tso_drop_pkts;
-+      u64 tx_gso_pkts;
-+      u64 tx_gso_drop_pkts;
-+      u64 tx_queue_stopped[EDMA_PORT_MAX_CORE];
-+      struct u64_stats_sync syncp;
-+};
-+
-+/**
-  * struct edma_port_pcpu_stats - EDMA per cpu stats data structure for the port.
-  * @rx_stats: Per CPU Rx statistics
-+ * @tx_stats: Per CPU Tx statistics
-  */
- struct edma_port_pcpu_stats {
-       struct edma_port_rx_stats __percpu *rx_stats;
-+      struct edma_port_tx_stats __percpu *tx_stats;
- };
- /**
-@@ -54,6 +88,7 @@ struct edma_port_priv {
-       struct ppe_port *ppe_port;
-       struct net_device *netdev;
-       struct edma_port_pcpu_stats pcpu_stats;
-+      struct edma_txdesc_ring *txr_map[EDMA_PORT_MAX_CORE];
-       unsigned long flags;
- };
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_tx.c
-@@ -0,0 +1,808 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* Provide APIs to alloc Tx Buffers, fill the Tx descriptors and transmit
-+ * Scatter Gather and linear packets, Tx complete to free the skb after transmit.
-+ */
-+
-+#include <linux/dma-mapping.h>
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/platform_device.h>
-+#include <linux/printk.h>
-+#include <net/gso.h>
-+#include <linux/regmap.h>
-+
-+#include "edma.h"
-+#include "edma_cfg_tx.h"
-+#include "edma_port.h"
-+#include "ppe.h"
-+#include "ppe_regs.h"
-+
-+static u32 edma_tx_num_descs_for_sg(struct sk_buff *skb)
-+{
-+      u32 nr_frags_first = 0, num_tx_desc_needed = 0;
-+
-+      /* Check if we have enough Tx descriptors for SG. */
-+      if (unlikely(skb_shinfo(skb)->nr_frags)) {
-+              nr_frags_first = skb_shinfo(skb)->nr_frags;
-+              WARN_ON_ONCE(nr_frags_first > MAX_SKB_FRAGS);
-+              num_tx_desc_needed += nr_frags_first;
-+      }
-+
-+      /* Walk through fraglist skbs making a note of nr_frags
-+       * One Tx desc for fraglist skb. Fraglist skb may have
-+       * further nr_frags.
-+       */
-+      if (unlikely(skb_has_frag_list(skb))) {
-+              struct sk_buff *iter_skb;
-+
-+              skb_walk_frags(skb, iter_skb) {
-+                      u32 nr_frags = skb_shinfo(iter_skb)->nr_frags;
-+
-+                      WARN_ON_ONCE(nr_frags > MAX_SKB_FRAGS);
-+                      num_tx_desc_needed += (1 + nr_frags);
-+              }
-+      }
-+
-+      return (num_tx_desc_needed + 1);
-+}
-+
-+/**
-+ * edma_tx_gso_segment - Tx GSO.
-+ * @skb: Socket Buffer.
-+ * @netdev: Netdevice.
-+ * @segs: SKB segments from GSO.
-+ *
-+ * Format skbs into GSOs.
-+ *
-+ * Return 1 on success, error code on failure.
-+ */
-+enum edma_tx_gso_status edma_tx_gso_segment(struct sk_buff *skb,
-+                                          struct net_device *netdev, struct sk_buff **segs)
-+{
-+      u32 num_tx_desc_needed;
-+
-+      /* Check is skb is non-linear to proceed. */
-+      if (likely(!skb_is_nonlinear(skb)))
-+              return EDMA_TX_GSO_NOT_NEEDED;
-+
-+      /* Check if TSO is enabled. If so, return as skb doesn't
-+       * need to be segmented by linux.
-+       */
-+      if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) {
-+              num_tx_desc_needed = edma_tx_num_descs_for_sg(skb);
-+              if (likely(num_tx_desc_needed <= EDMA_TX_TSO_SEG_MAX))
-+                      return EDMA_TX_GSO_NOT_NEEDED;
-+      }
-+
-+      /* GSO segmentation of the skb into multiple segments. */
-+      *segs = skb_gso_segment(skb, netdev->features
-+              & ~(NETIF_F_TSO | NETIF_F_TSO6));
-+
-+      /* Check for error in GSO segmentation. */
-+      if (IS_ERR_OR_NULL(*segs)) {
-+              netdev_info(netdev, "Tx gso fail\n");
-+              return EDMA_TX_GSO_FAIL;
-+      }
-+
-+      return EDMA_TX_GSO_SUCCEED;
-+}
-+
-+/**
-+ * edma_tx_complete - Reap Tx completion descriptors.
-+ * @work_to_do: Work to do.
-+ * @txcmpl_ring: Tx Completion ring.
-+ *
-+ * Reap Tx completion descriptors of the transmitted
-+ * packets and free the corresponding SKBs.
-+ *
-+ * Return the number descriptors for which Tx complete is done.
-+ */
-+u32 edma_tx_complete(u32 work_to_do, struct edma_txcmpl_ring *txcmpl_ring)
-+{
-+      struct edma_txcmpl_stats *txcmpl_stats = &txcmpl_ring->txcmpl_stats;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 cons_idx, end_idx, data, cpu_id;
-+      struct device *dev = ppe_dev->dev;
-+      u32 avail, count, txcmpl_errors;
-+      struct edma_txcmpl_desc *txcmpl;
-+      u32 prod_idx = 0, more_bit = 0;
-+      struct netdev_queue *nq;
-+      struct sk_buff *skb;
-+      u32 reg;
-+
-+      cons_idx = txcmpl_ring->cons_idx;
-+
-+      if (likely(txcmpl_ring->avail_pkt >= work_to_do)) {
-+              avail = work_to_do;
-+      } else {
-+              /* Get TXCMPL ring producer index. */
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_TXCMPL_PROD_IDX(txcmpl_ring->id);
-+              regmap_read(regmap, reg, &data);
-+              prod_idx = data & EDMA_TXCMPL_PROD_IDX_MASK;
-+
-+              avail = EDMA_DESC_AVAIL_COUNT(prod_idx, cons_idx, EDMA_TX_RING_SIZE);
-+              txcmpl_ring->avail_pkt = avail;
-+
-+              if (unlikely(!avail)) {
-+                      dev_dbg(dev, "No available descriptors are pending for %d txcmpl ring\n",
-+                              txcmpl_ring->id);
-+                      u64_stats_update_begin(&txcmpl_stats->syncp);
-+                      ++txcmpl_stats->no_pending_desc;
-+                      u64_stats_update_end(&txcmpl_stats->syncp);
-+                      return 0;
-+              }
-+
-+              avail = min(avail, work_to_do);
-+      }
-+
-+      count = avail;
-+
-+      end_idx = (cons_idx + avail) & EDMA_TX_RING_SIZE_MASK;
-+      txcmpl = EDMA_TXCMPL_DESC(txcmpl_ring, cons_idx);
-+
-+      /* Instead of freeing the skb, it might be better to save and use
-+       * for Rxfill.
-+       */
-+      while (likely(avail--)) {
-+              /* The last descriptor holds the SKB pointer for scattered frames.
-+               * So skip the descriptors with more bit set.
-+               */
-+              more_bit = EDMA_TXCMPL_MORE_BIT_GET(txcmpl);
-+              if (unlikely(more_bit)) {
-+                      u64_stats_update_begin(&txcmpl_stats->syncp);
-+                      ++txcmpl_stats->desc_with_more_bit;
-+                      u64_stats_update_end(&txcmpl_stats->syncp);
-+                      cons_idx = ((cons_idx + 1) & EDMA_TX_RING_SIZE_MASK);
-+                      txcmpl = EDMA_TXCMPL_DESC(txcmpl_ring, cons_idx);
-+                      continue;
-+              }
-+
-+              /* Find and free the skb for Tx completion. */
-+              skb = (struct sk_buff *)EDMA_TXCMPL_OPAQUE_GET(txcmpl);
-+              if (unlikely(!skb)) {
-+                      if (net_ratelimit())
-+                              dev_warn(dev, "Invalid cons_idx:%u prod_idx:%u word2:%x word3:%x\n",
-+                                       cons_idx, prod_idx, txcmpl->word2, txcmpl->word3);
-+
-+                      u64_stats_update_begin(&txcmpl_stats->syncp);
-+                      ++txcmpl_stats->invalid_buffer;
-+                      u64_stats_update_end(&txcmpl_stats->syncp);
-+              } else {
-+                      dev_dbg(dev, "TXCMPL: skb:%p, skb->len %d, skb->data_len %d, cons_idx:%d prod_idx:%d word2:0x%x word3:0x%x\n",
-+                              skb, skb->len, skb->data_len, cons_idx, prod_idx,
-+                              txcmpl->word2, txcmpl->word3);
-+
-+                      txcmpl_errors = EDMA_TXCOMP_RING_ERROR_GET(txcmpl->word3);
-+                      if (unlikely(txcmpl_errors)) {
-+                              if (net_ratelimit())
-+                                      dev_err(dev, "Error 0x%0x observed in tx complete %d ring\n",
-+                                              txcmpl_errors, txcmpl_ring->id);
-+
-+                              u64_stats_update_begin(&txcmpl_stats->syncp);
-+                              ++txcmpl_stats->errors;
-+                              u64_stats_update_end(&txcmpl_stats->syncp);
-+                      }
-+
-+                      /* Retrieve pool id for unmapping.
-+                       * 0 for linear skb and (pool id - 1) represents nr_frag index.
-+                       */
-+                      if (!EDMA_TXCOMP_POOL_ID_GET(txcmpl)) {
-+                              dma_unmap_single(dev, virt_to_phys(skb->data),
-+                                               skb->len, DMA_TO_DEVICE);
-+                      } else {
-+                              u8 frag_index = (EDMA_TXCOMP_POOL_ID_GET(txcmpl) - 1);
-+                              skb_frag_t *frag = &skb_shinfo(skb)->frags[frag_index];
-+
-+                              dma_unmap_page(dev, virt_to_phys(frag),
-+                                             PAGE_SIZE, DMA_TO_DEVICE);
-+                      }
-+
-+                      dev_kfree_skb(skb);
-+              }
-+
-+              cons_idx = ((cons_idx + 1) & EDMA_TX_RING_SIZE_MASK);
-+              txcmpl = EDMA_TXCMPL_DESC(txcmpl_ring, cons_idx);
-+      }
-+
-+      txcmpl_ring->cons_idx = cons_idx;
-+      txcmpl_ring->avail_pkt -= count;
-+
-+      dev_dbg(dev, "TXCMPL:%u count:%u prod_idx:%u cons_idx:%u\n",
-+              txcmpl_ring->id, count, prod_idx, cons_idx);
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXCMPL_CONS_IDX(txcmpl_ring->id);
-+      regmap_write(regmap, reg, cons_idx);
-+
-+      /* If tx_requeue_stop disabled (tx_requeue_stop = 0)
-+       * Fetch the tx queue of interface and check if it is stopped.
-+       * if queue is stopped and interface is up, wake up this queue.
-+       */
-+      if (unlikely(!edma_ctx->tx_requeue_stop)) {
-+              cpu_id = smp_processor_id();
-+              nq = netdev_get_tx_queue(txcmpl_ring->napi.dev, cpu_id);
-+              if (unlikely(netif_tx_queue_stopped(nq)) &&
-+                  netif_carrier_ok(txcmpl_ring->napi.dev)) {
-+                      dev_dbg(dev, "Waking queue number %d, for interface %s\n",
-+                              cpu_id, txcmpl_ring->napi.dev->name);
-+                      __netif_tx_lock(nq, cpu_id);
-+                      netif_tx_wake_queue(nq);
-+                      __netif_tx_unlock(nq);
-+              }
-+      }
-+
-+      return count;
-+}
-+
-+/**
-+ * edma_tx_napi_poll - EDMA TX NAPI handler.
-+ * @napi: NAPI structure.
-+ * @budget: Tx NAPI Budget.
-+ *
-+ * EDMA TX NAPI handler.
-+ */
-+int edma_tx_napi_poll(struct napi_struct *napi, int budget)
-+{
-+      struct edma_txcmpl_ring *txcmpl_ring = (struct edma_txcmpl_ring *)napi;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 txcmpl_intr_status;
-+      int work_done = 0;
-+      u32 data, reg;
-+
-+      do {
-+              work_done += edma_tx_complete(budget - work_done, txcmpl_ring);
-+              if (work_done >= budget)
-+                      return work_done;
-+
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_TX_INT_STAT(txcmpl_ring->id);
-+              regmap_read(regmap, reg, &data);
-+              txcmpl_intr_status = data & EDMA_TXCMPL_RING_INT_STATUS_MASK;
-+      } while (txcmpl_intr_status);
-+
-+      /* No more packets to process. Finish NAPI processing. */
-+      napi_complete(napi);
-+
-+      /* Set TXCMPL ring interrupt mask. */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TX_INT_MASK(txcmpl_ring->id);
-+      regmap_write(regmap, reg, edma_ctx->intr_info.intr_mask_txcmpl);
-+
-+      return work_done;
-+}
-+
-+/**
-+ * edma_tx_handle_irq - Tx IRQ Handler.
-+ * @irq: Interrupt request.
-+ * @ctx: Context.
-+ *
-+ * Process TX IRQ and schedule NAPI.
-+ *
-+ * Return IRQ handler code.
-+ */
-+irqreturn_t edma_tx_handle_irq(int irq, void *ctx)
-+{
-+      struct edma_txcmpl_ring *txcmpl_ring = (struct edma_txcmpl_ring *)ctx;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 reg;
-+
-+      pr_debug("irq: irq=%d txcmpl_ring_id=%u\n", irq, txcmpl_ring->id);
-+      if (likely(napi_schedule_prep(&txcmpl_ring->napi))) {
-+              /* Disable TxCmpl intr. */
-+              reg = EDMA_BASE_OFFSET + EDMA_REG_TX_INT_MASK(txcmpl_ring->id);
-+              regmap_write(regmap, reg, EDMA_MASK_INT_DISABLE);
-+              __napi_schedule(&txcmpl_ring->napi);
-+      }
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static void edma_tx_dma_unmap_frags(struct sk_buff *skb, u32 nr_frags)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev = ppe_dev->dev;
-+      u32 buf_len = 0;
-+      u8 i = 0;
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags - nr_frags; i++) {
-+              skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+
-+              /* DMA mapping was not done for zero size segments. */
-+              buf_len = skb_frag_size(frag);
-+              if (unlikely(buf_len == 0))
-+                      continue;
-+
-+              dma_unmap_page(dev, virt_to_phys(frag), PAGE_SIZE,
-+                             DMA_TO_DEVICE);
-+      }
-+}
-+
-+static u32 edma_tx_skb_nr_frags(struct edma_txdesc_ring *txdesc_ring,
-+                              struct edma_txdesc_pri **txdesc, struct sk_buff *skb,
-+                              u32 *hw_next_to_use, u32 *invalid_frag)
-+{
-+      u32 nr_frags = 0, buf_len = 0, num_descs = 0, start_idx = 0, end_idx = 0;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      u32 start_hw_next_to_use = *hw_next_to_use;
-+      struct edma_txdesc_pri *txd = *txdesc;
-+      struct device *dev = ppe_dev->dev;
-+      u8 i = 0;
-+
-+      /* Hold onto the index mapped to *txdesc.
-+       * This will be the index previous to that of current *hw_next_to_use.
-+       */
-+      start_idx = (((*hw_next_to_use) + EDMA_TX_RING_SIZE_MASK)
-+              & EDMA_TX_RING_SIZE_MASK);
-+
-+      /* Handle if the skb has nr_frags. */
-+      nr_frags = skb_shinfo(skb)->nr_frags;
-+      num_descs = nr_frags;
-+      i = 0;
-+
-+      while (nr_frags--) {
-+              skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+              dma_addr_t buff_addr;
-+
-+              buf_len = skb_frag_size(frag);
-+
-+              /* Zero size segment can lead EDMA HW to hang so, we don't want to
-+               * process them. Zero size segment can happen during TSO operation
-+               * if there is nothing but header in the primary segment.
-+               */
-+              if (unlikely(buf_len == 0)) {
-+                      num_descs--;
-+                      i++;
-+                      continue;
-+              }
-+
-+              /* Setting the MORE bit on the previous Tx descriptor.
-+               * Note: We will flush this descriptor as well later.
-+               */
-+              EDMA_TXDESC_MORE_BIT_SET(txd, 1);
-+              EDMA_TXDESC_ENDIAN_SET(txd);
-+
-+              txd = EDMA_TXDESC_PRI_DESC(txdesc_ring, *hw_next_to_use);
-+              memset(txd, 0, sizeof(struct edma_txdesc_pri));
-+              buff_addr = skb_frag_dma_map(dev, frag, 0, buf_len,
-+                                           DMA_TO_DEVICE);
-+              if (dma_mapping_error(dev, buff_addr)) {
-+                      dev_dbg(dev, "Unable to dma first descriptor for nr_frags tx\n");
-+                      *hw_next_to_use = start_hw_next_to_use;
-+                      *invalid_frag = nr_frags;
-+                      return 0;
-+              }
-+
-+              EDMA_TXDESC_BUFFER_ADDR_SET(txd, buff_addr);
-+              EDMA_TXDESC_DATA_LEN_SET(txd, buf_len);
-+              EDMA_TXDESC_POOL_ID_SET(txd, (i + 1));
-+
-+              *hw_next_to_use = ((*hw_next_to_use + 1) & EDMA_TX_RING_SIZE_MASK);
-+              i++;
-+      }
-+
-+      EDMA_TXDESC_ENDIAN_SET(txd);
-+
-+      /* This will be the index previous to that of current *hw_next_to_use. */
-+      end_idx = (((*hw_next_to_use) + EDMA_TX_RING_SIZE_MASK) & EDMA_TX_RING_SIZE_MASK);
-+
-+      *txdesc = txd;
-+
-+      return num_descs;
-+}
-+
-+static void edma_tx_fill_pp_desc(struct edma_port_priv *port_priv,
-+                               struct edma_txdesc_pri *txd, struct sk_buff *skb,
-+      struct edma_port_tx_stats *stats)
-+{
-+      struct ppe_port *port = port_priv->ppe_port;
-+      int port_id = port->port_id;
-+
-+      /* Offload L3/L4 checksum computation. */
-+      if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
-+              EDMA_TXDESC_ADV_OFFLOAD_SET(txd);
-+              EDMA_TXDESC_IP_CSUM_SET(txd);
-+              EDMA_TXDESC_L4_CSUM_SET(txd);
-+      }
-+
-+      /* Check if the packet needs TSO
-+       * This will be mostly true for SG packets.
-+       */
-+      if (unlikely(skb_is_gso(skb))) {
-+              if ((skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) ||
-+                  (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
-+                      u32 mss = skb_shinfo(skb)->gso_size;
-+
-+                      /* If MSS<256, HW will do TSO using MSS=256,
-+                       * if MSS>10K, HW will do TSO using MSS=10K,
-+                       * else HW will report error 0x200000 in Tx Cmpl.
-+                       */
-+                      if (mss < EDMA_TX_TSO_MSS_MIN)
-+                              mss = EDMA_TX_TSO_MSS_MIN;
-+                      else if (mss > EDMA_TX_TSO_MSS_MAX)
-+                              mss = EDMA_TX_TSO_MSS_MAX;
-+
-+                      EDMA_TXDESC_TSO_ENABLE_SET(txd, 1);
-+                      EDMA_TXDESC_MSS_SET(txd, mss);
-+
-+                      /* Update tso stats. */
-+                      u64_stats_update_begin(&stats->syncp);
-+                      stats->tx_tso_pkts++;
-+                      u64_stats_update_end(&stats->syncp);
-+              }
-+      }
-+
-+      /* Set destination information in the descriptor. */
-+      EDMA_TXDESC_SERVICE_CODE_SET(txd, PPE_EDMA_SC_BYPASS_ID);
-+      EDMA_DST_INFO_SET(txd, port_id);
-+}
-+
-+static struct edma_txdesc_pri *edma_tx_skb_first_desc(struct edma_port_priv *port_priv,
-+                                                    struct edma_txdesc_ring *txdesc_ring,
-+                                                    struct sk_buff *skb, u32 *hw_next_to_use,
-+                                                    struct edma_port_tx_stats *stats)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct edma_txdesc_pri *txd = NULL;
-+      struct device *dev = ppe_dev->dev;
-+      dma_addr_t buff_addr;
-+      u32 buf_len = 0;
-+
-+      /* Get the packet length. */
-+      buf_len = skb_headlen(skb);
-+      txd = EDMA_TXDESC_PRI_DESC(txdesc_ring, *hw_next_to_use);
-+      memset(txd, 0, sizeof(struct edma_txdesc_pri));
-+
-+      /* Set the data pointer as the buffer address in the descriptor. */
-+      buff_addr = dma_map_single(dev, skb->data, buf_len, DMA_TO_DEVICE);
-+      if (dma_mapping_error(dev, buff_addr)) {
-+              dev_dbg(dev, "Unable to dma first descriptor for tx\n");
-+              return NULL;
-+      }
-+
-+      EDMA_TXDESC_BUFFER_ADDR_SET(txd, buff_addr);
-+      EDMA_TXDESC_POOL_ID_SET(txd, 0);
-+      edma_tx_fill_pp_desc(port_priv, txd, skb, stats);
-+
-+      /* Set packet length in the descriptor. */
-+      EDMA_TXDESC_DATA_LEN_SET(txd, buf_len);
-+      *hw_next_to_use = (*hw_next_to_use + 1) & EDMA_TX_RING_SIZE_MASK;
-+
-+      return txd;
-+}
-+
-+static void edma_tx_handle_dma_err(struct sk_buff *skb, u32 num_sg_frag_list)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct device *dev = ppe_dev->dev;
-+      struct sk_buff *iter_skb = NULL;
-+      u32 cnt_sg_frag_list = 0;
-+
-+      /* Walk through all fraglist skbs. */
-+      skb_walk_frags(skb, iter_skb) {
-+              if (skb_headlen(iter_skb)) {
-+                      dma_unmap_single(dev, virt_to_phys(iter_skb->data),
-+                                       skb_headlen(iter_skb), DMA_TO_DEVICE);
-+                      cnt_sg_frag_list += 1;
-+              }
-+
-+              if (cnt_sg_frag_list == num_sg_frag_list)
-+                      return;
-+
-+              /* skb fraglist skb had nr_frags, unmap that memory. */
-+              u32 nr_frags = skb_shinfo(iter_skb)->nr_frags;
-+
-+              if (nr_frags == 0)
-+                      continue;
-+
-+              for (int i = 0; i < nr_frags; i++) {
-+                      skb_frag_t *frag = &skb_shinfo(iter_skb)->frags[i];
-+
-+                      /* DMA mapping was not done for zero size segments. */
-+                      if (unlikely(skb_frag_size(frag) == 0))
-+                              continue;
-+
-+                      dma_unmap_page(dev, virt_to_phys(frag),
-+                                     PAGE_SIZE, DMA_TO_DEVICE);
-+                      cnt_sg_frag_list += 1;
-+                      if (cnt_sg_frag_list == num_sg_frag_list)
-+                              return;
-+              }
-+      }
-+}
-+
-+static u32 edma_tx_skb_sg_fill_desc(struct edma_txdesc_ring *txdesc_ring,
-+                                  struct edma_txdesc_pri **txdesc,
-+                                  struct sk_buff *skb, u32 *hw_next_to_use,
-+                                  struct edma_port_tx_stats *stats)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      u32 start_hw_next_to_use = 0, invalid_frag = 0;
-+      struct edma_txdesc_pri *txd = *txdesc;
-+      struct device *dev = ppe_dev->dev;
-+      struct sk_buff *iter_skb = NULL;
-+      u32 buf_len = 0, num_descs = 0;
-+      u32 num_sg_frag_list = 0;
-+
-+      /* Head skb processed already. */
-+      num_descs++;
-+
-+      if (unlikely(skb_has_frag_list(skb))) {
-+              struct edma_txdesc_pri *start_desc = NULL;
-+              u32 start_idx = 0, end_idx = 0;
-+
-+              /* Hold onto the index mapped to txd.
-+               * This will be the index previous to that of current *hw_next_to_use.
-+               */
-+              start_idx = (((*hw_next_to_use) + EDMA_TX_RING_SIZE_MASK)
-+                           & EDMA_TX_RING_SIZE_MASK);
-+              start_desc = txd;
-+              start_hw_next_to_use = *hw_next_to_use;
-+
-+              /* Walk through all fraglist skbs. */
-+              skb_walk_frags(skb, iter_skb) {
-+                      dma_addr_t buff_addr;
-+                      u32 num_nr_frag = 0;
-+
-+                      /* This case could happen during the packet decapsulation.
-+                       * All header content might be removed.
-+                       */
-+                      buf_len = skb_headlen(iter_skb);
-+                      if (unlikely(buf_len == 0))
-+                              goto skip_primary;
-+
-+                      /* We make sure to flush this descriptor later. */
-+                      EDMA_TXDESC_MORE_BIT_SET(txd, 1);
-+                      EDMA_TXDESC_ENDIAN_SET(txd);
-+
-+                      txd = EDMA_TXDESC_PRI_DESC(txdesc_ring, *hw_next_to_use);
-+                      memset(txd, 0, sizeof(struct edma_txdesc_pri));
-+                      buff_addr = dma_map_single(dev, iter_skb->data,
-+                                                 buf_len, DMA_TO_DEVICE);
-+                      if (dma_mapping_error(dev, buff_addr)) {
-+                              dev_dbg(dev, "Unable to dma for fraglist\n");
-+                              goto dma_err;
-+                      }
-+
-+                      EDMA_TXDESC_BUFFER_ADDR_SET(txd, buff_addr);
-+                      EDMA_TXDESC_DATA_LEN_SET(txd, buf_len);
-+                      EDMA_TXDESC_POOL_ID_SET(txd, 0);
-+
-+                      *hw_next_to_use = (*hw_next_to_use + 1) & EDMA_TX_RING_SIZE_MASK;
-+                      num_descs += 1;
-+                      num_sg_frag_list += 1;
-+
-+                      /* skb fraglist skb can have nr_frags. */
-+skip_primary:
-+                      if (unlikely(skb_shinfo(iter_skb)->nr_frags)) {
-+                              num_nr_frag = edma_tx_skb_nr_frags(txdesc_ring, &txd,
-+                                                                 iter_skb, hw_next_to_use,
-+                                                                 &invalid_frag);
-+                              if (unlikely(!num_nr_frag)) {
-+                                      dev_dbg(dev, "No descriptor available for ring %d\n",
-+                                              txdesc_ring->id);
-+                                      edma_tx_dma_unmap_frags(iter_skb, invalid_frag);
-+                                      goto dma_err;
-+                              }
-+
-+                              num_descs += num_nr_frag;
-+                              num_sg_frag_list += num_nr_frag;
-+
-+                              /* Update fraglist with nr_frag stats. */
-+                              u64_stats_update_begin(&stats->syncp);
-+                              stats->tx_fraglist_with_nr_frags_pkts++;
-+                              u64_stats_update_end(&stats->syncp);
-+                      }
-+              }
-+
-+              EDMA_TXDESC_ENDIAN_SET(txd);
-+
-+              /* This will be the index previous to
-+               * that of current *hw_next_to_use.
-+               */
-+              end_idx = (((*hw_next_to_use) + EDMA_TX_RING_SIZE_MASK) &
-+                         EDMA_TX_RING_SIZE_MASK);
-+
-+              /* Update frag_list stats. */
-+              u64_stats_update_begin(&stats->syncp);
-+              stats->tx_fraglist_pkts++;
-+              u64_stats_update_end(&stats->syncp);
-+      } else {
-+              /* Process skb with nr_frags. */
-+              num_descs += edma_tx_skb_nr_frags(txdesc_ring, &txd, skb,
-+                                                hw_next_to_use, &invalid_frag);
-+              if (unlikely(!num_descs)) {
-+                      dev_dbg(dev, "No descriptor available for ring %d\n", txdesc_ring->id);
-+                      edma_tx_dma_unmap_frags(skb, invalid_frag);
-+                      *txdesc = NULL;
-+                      return num_descs;
-+              }
-+
-+              u64_stats_update_begin(&stats->syncp);
-+              stats->tx_nr_frag_pkts++;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      dev_dbg(dev, "skb:%p num_descs_filled: %u, nr_frags %u, frag_list fragments %u\n",
-+              skb, num_descs, skb_shinfo(skb)->nr_frags, num_sg_frag_list);
-+
-+      *txdesc = txd;
-+
-+      return num_descs;
-+
-+dma_err:
-+      if (!num_sg_frag_list)
-+              goto reset_state;
-+
-+      edma_tx_handle_dma_err(skb, num_sg_frag_list);
-+
-+reset_state:
-+      *hw_next_to_use = start_hw_next_to_use;
-+      *txdesc = NULL;
-+
-+      return 0;
-+}
-+
-+static u32 edma_tx_avail_desc(struct edma_txdesc_ring *txdesc_ring,
-+                            u32 hw_next_to_use)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      u32 data = 0, avail = 0, hw_next_to_clean = 0;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 reg;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_CONS_IDX(txdesc_ring->id);
-+      regmap_read(regmap, reg, &data);
-+      hw_next_to_clean = data & EDMA_TXDESC_CONS_IDX_MASK;
-+
-+      avail = EDMA_DESC_AVAIL_COUNT(hw_next_to_clean - 1,
-+                                    hw_next_to_use, EDMA_TX_RING_SIZE);
-+
-+      return avail;
-+}
-+
-+/**
-+ * edma_tx_ring_xmit - Transmit a packet.
-+ * @netdev: Netdevice.
-+ * @skb: Socket Buffer.
-+ * @txdesc_ring: Tx Descriptor ring.
-+ * @stats: EDMA Tx Statistics.
-+ *
-+ * Check for available descriptors, fill the descriptors
-+ * and transmit both linear and non linear packets.
-+ *
-+ * Return 0 on success, negative error code on failure.
-+ */
-+enum edma_tx_status edma_tx_ring_xmit(struct net_device *netdev,
-+                                    struct sk_buff *skb, struct edma_txdesc_ring *txdesc_ring,
-+                              struct edma_port_tx_stats *stats)
-+{
-+      struct edma_txdesc_stats *txdesc_stats = &txdesc_ring->txdesc_stats;
-+      struct edma_port_priv *port_priv = netdev_priv(netdev);
-+      u32 num_tx_desc_needed = 0, num_desc_filled = 0;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct ppe_port *port = port_priv->ppe_port;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      struct edma_txdesc_pri *txdesc = NULL;
-+      struct device *dev = ppe_dev->dev;
-+      int port_id = port->port_id;
-+      u32 hw_next_to_use = 0;
-+      u32 reg;
-+
-+      hw_next_to_use = txdesc_ring->prod_idx;
-+
-+      if (unlikely(!(txdesc_ring->avail_desc)))  {
-+              txdesc_ring->avail_desc = edma_tx_avail_desc(txdesc_ring,
-+                                                           hw_next_to_use);
-+              if (unlikely(!txdesc_ring->avail_desc)) {
-+                      netdev_dbg(netdev, "No available descriptors are present at %d ring\n",
-+                                 txdesc_ring->id);
-+
-+                      u64_stats_update_begin(&txdesc_stats->syncp);
-+                      ++txdesc_stats->no_desc_avail;
-+                      u64_stats_update_end(&txdesc_stats->syncp);
-+                      return EDMA_TX_FAIL_NO_DESC;
-+              }
-+      }
-+
-+      /* Process head skb for linear skb.
-+       * Process head skb + nr_frags + fraglist for non linear skb.
-+       */
-+      if (likely(!skb_is_nonlinear(skb))) {
-+              txdesc = edma_tx_skb_first_desc(port_priv, txdesc_ring, skb,
-+                                              &hw_next_to_use, stats);
-+              if (unlikely(!txdesc)) {
-+                      netdev_dbg(netdev, "No descriptor available for ring %d\n",
-+                                 txdesc_ring->id);
-+                      u64_stats_update_begin(&txdesc_stats->syncp);
-+                      ++txdesc_stats->no_desc_avail;
-+                      u64_stats_update_end(&txdesc_stats->syncp);
-+                      return EDMA_TX_FAIL_NO_DESC;
-+              }
-+
-+              EDMA_TXDESC_ENDIAN_SET(txdesc);
-+              num_desc_filled++;
-+      } else {
-+              num_tx_desc_needed = edma_tx_num_descs_for_sg(skb);
-+
-+              /* HW does not support TSO for packets with more than 32 segments.
-+               * HW hangs up if it sees more than 32 segments. Kernel Perform GSO
-+               * for such packets with netdev gso_max_segs set to 32.
-+               */
-+              if (unlikely(num_tx_desc_needed > EDMA_TX_TSO_SEG_MAX)) {
-+                      netdev_dbg(netdev, "Number of segments %u more than %u for %d ring\n",
-+                                 num_tx_desc_needed, EDMA_TX_TSO_SEG_MAX, txdesc_ring->id);
-+                      u64_stats_update_begin(&txdesc_stats->syncp);
-+                      ++txdesc_stats->tso_max_seg_exceed;
-+                      u64_stats_update_end(&txdesc_stats->syncp);
-+
-+                      u64_stats_update_begin(&stats->syncp);
-+                      stats->tx_tso_drop_pkts++;
-+                      u64_stats_update_end(&stats->syncp);
-+
-+                      return EDMA_TX_FAIL;
-+              }
-+
-+              if (unlikely(num_tx_desc_needed > txdesc_ring->avail_desc)) {
-+                      txdesc_ring->avail_desc = edma_tx_avail_desc(txdesc_ring,
-+                                                                   hw_next_to_use);
-+                      if (num_tx_desc_needed > txdesc_ring->avail_desc) {
-+                              u64_stats_update_begin(&txdesc_stats->syncp);
-+                              ++txdesc_stats->no_desc_avail;
-+                              u64_stats_update_end(&txdesc_stats->syncp);
-+                              netdev_dbg(netdev, "Not enough available descriptors are present at %d ring for SG packet. Needed %d, currently available %d\n",
-+                                         txdesc_ring->id, num_tx_desc_needed,
-+                                         txdesc_ring->avail_desc);
-+                              return EDMA_TX_FAIL_NO_DESC;
-+                      }
-+              }
-+
-+              txdesc = edma_tx_skb_first_desc(port_priv, txdesc_ring, skb,
-+                                              &hw_next_to_use, stats);
-+              if (unlikely(!txdesc)) {
-+                      netdev_dbg(netdev, "No non-linear descriptor available for ring %d\n",
-+                                 txdesc_ring->id);
-+                      u64_stats_update_begin(&txdesc_stats->syncp);
-+                      ++txdesc_stats->no_desc_avail;
-+                      u64_stats_update_end(&txdesc_stats->syncp);
-+                      return EDMA_TX_FAIL_NO_DESC;
-+              }
-+
-+              num_desc_filled = edma_tx_skb_sg_fill_desc(txdesc_ring,
-+                                                         &txdesc, skb, &hw_next_to_use, stats);
-+              if (unlikely(!txdesc)) {
-+                      netdev_dbg(netdev, "No descriptor available for ring %d\n",
-+                                 txdesc_ring->id);
-+                      dma_unmap_single(dev, virt_to_phys(skb->data),
-+                                       skb->len, DMA_TO_DEVICE);
-+                      u64_stats_update_begin(&txdesc_stats->syncp);
-+                      ++txdesc_stats->no_desc_avail;
-+                      u64_stats_update_end(&txdesc_stats->syncp);
-+                      return EDMA_TX_FAIL_NO_DESC;
-+              }
-+      }
-+
-+      /* Set the skb pointer to the descriptor's opaque field/s
-+       * on the last descriptor of the packet/SG packet.
-+       */
-+      EDMA_TXDESC_OPAQUE_SET(txdesc, skb);
-+
-+      /* Update producer index. */
-+      txdesc_ring->prod_idx = hw_next_to_use & EDMA_TXDESC_PROD_IDX_MASK;
-+      txdesc_ring->avail_desc -= num_desc_filled;
-+
-+      netdev_dbg(netdev, "%s: skb:%p tx_ring:%u proto:0x%x skb->len:%d\n port:%u prod_idx:%u ip_summed:0x%x\n",
-+                 netdev->name, skb, txdesc_ring->id, ntohs(skb->protocol),
-+               skb->len, port_id, hw_next_to_use, skb->ip_summed);
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_TXDESC_PROD_IDX(txdesc_ring->id);
-+      regmap_write(regmap, reg, txdesc_ring->prod_idx);
-+
-+      u64_stats_update_begin(&stats->syncp);
-+      stats->tx_pkts++;
-+      stats->tx_bytes += skb->len;
-+      u64_stats_update_end(&stats->syncp);
-+
-+      return EDMA_TX_OK;
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_tx.h
-@@ -0,0 +1,302 @@
-+/* SPDX-License-Identifier: GPL-2.0-only
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef __EDMA_TX__
-+#define __EDMA_TX__
-+
-+#include "edma_port.h"
-+
-+#define EDMA_GET_DESC(R, i, type)     (&(((type *)((R)->desc))[(i)]))
-+#define EDMA_GET_PDESC(R, i, type)    (&(((type *)((R)->pdesc))[(i)]))
-+#define EDMA_GET_SDESC(R, i, type)    (&(((type *)((R)->sdesc))[(i)]))
-+#define EDMA_TXCMPL_DESC(R, i)                EDMA_GET_DESC(R, i, \
-+                                              struct edma_txcmpl_desc)
-+#define EDMA_TXDESC_PRI_DESC(R, i)    EDMA_GET_PDESC(R, i, \
-+                                              struct edma_txdesc_pri)
-+#define EDMA_TXDESC_SEC_DESC(R, i)    EDMA_GET_SDESC(R, i, \
-+                                              struct edma_txdesc_sec)
-+
-+#define EDMA_DESC_AVAIL_COUNT(head, tail, _max) ({ \
-+                      typeof(_max) (max) = (_max); \
-+                      ((((head) - (tail)) + \
-+                      (max)) & ((max) - 1)); })
-+
-+#define EDMA_TX_RING_SIZE               2048
-+#define EDMA_TX_RING_SIZE_MASK                (EDMA_TX_RING_SIZE - 1)
-+
-+/* Max segment processing capacity of HW for TSO. */
-+#define EDMA_TX_TSO_SEG_MAX           32
-+
-+/* HW defined low and high MSS size. */
-+#define EDMA_TX_TSO_MSS_MIN           256
-+#define EDMA_TX_TSO_MSS_MAX           10240
-+
-+#define EDMA_DST_PORT_TYPE            2
-+#define EDMA_DST_PORT_TYPE_SHIFT      28
-+#define EDMA_DST_PORT_TYPE_MASK               (0xf << EDMA_DST_PORT_TYPE_SHIFT)
-+#define EDMA_DST_PORT_ID_SHIFT                16
-+#define EDMA_DST_PORT_ID_MASK         (0xfff << EDMA_DST_PORT_ID_SHIFT)
-+
-+#define EDMA_DST_PORT_TYPE_SET(x)     (((x) << EDMA_DST_PORT_TYPE_SHIFT) & \
-+                                                      EDMA_DST_PORT_TYPE_MASK)
-+#define EDMA_DST_PORT_ID_SET(x)               (((x) << EDMA_DST_PORT_ID_SHIFT) & \
-+                                                      EDMA_DST_PORT_ID_MASK)
-+#define EDMA_DST_INFO_SET(desc, x)    ((desc)->word4 |= \
-+      (EDMA_DST_PORT_TYPE_SET(EDMA_DST_PORT_TYPE) | EDMA_DST_PORT_ID_SET(x)))
-+
-+#define EDMA_TXDESC_TSO_ENABLE_MASK           BIT(24)
-+#define EDMA_TXDESC_TSO_ENABLE_SET(desc, x)   ((desc)->word5 |= \
-+                              FIELD_PREP(EDMA_TXDESC_TSO_ENABLE_MASK, x))
-+#define EDMA_TXDESC_MSS_MASK                  GENMASK(31, 16)
-+#define EDMA_TXDESC_MSS_SET(desc, x)          ((desc)->word6 |= \
-+                                      FIELD_PREP(EDMA_TXDESC_MSS_MASK, x))
-+#define EDMA_TXDESC_MORE_BIT_MASK     BIT(30)
-+#define EDMA_TXDESC_MORE_BIT_SET(desc, x)     ((desc)->word1 |= \
-+                              FIELD_PREP(EDMA_TXDESC_MORE_BIT_MASK, x))
-+
-+#define EDMA_TXDESC_ADV_OFFSET_BIT    BIT(31)
-+#define EDMA_TXDESC_ADV_OFFLOAD_SET(desc)     ((desc)->word5 |= \
-+                                      FIELD_PREP(EDMA_TXDESC_ADV_OFFSET_BIT, 1))
-+#define EDMA_TXDESC_IP_CSUM_BIT               BIT(25)
-+#define EDMA_TXDESC_IP_CSUM_SET(desc)         ((desc)->word5 |= \
-+                                      FIELD_PREP(EDMA_TXDESC_IP_CSUM_BIT, 1))
-+
-+#define EDMA_TXDESC_L4_CSUM_SET_MASK   GENMASK(27, 26)
-+#define EDMA_TXDESC_L4_CSUM_SET(desc)  ((desc)->word5 |= \
-+                             (FIELD_PREP(EDMA_TXDESC_L4_CSUM_SET_MASK, 1)))
-+
-+#define EDMA_TXDESC_POOL_ID_SET_MASK  GENMASK(24, 18)
-+#define EDMA_TXDESC_POOL_ID_SET(desc, x)      ((desc)->word5 |= \
-+                              (FIELD_PREP(EDMA_TXDESC_POOL_ID_SET_MASK, x)))
-+
-+#define EDMA_TXDESC_DATA_LEN_SET(desc, x)     ((desc)->word5 |= ((x) & 0x1ffff))
-+#define EDMA_TXDESC_SERVICE_CODE_MASK GENMASK(24, 16)
-+#define EDMA_TXDESC_SERVICE_CODE_SET(desc, x) ((desc)->word1 |= \
-+                              (FIELD_PREP(EDMA_TXDESC_SERVICE_CODE_MASK, x)))
-+#define EDMA_TXDESC_BUFFER_ADDR_SET(desc, addr)       (((desc)->word0) = (addr))
-+
-+#ifdef __LP64__
-+#define EDMA_TXDESC_OPAQUE_GET(_desc) ({ \
-+                      typeof(_desc) (desc) = (_desc); \
-+                      (((u64)(desc)->word3 << 32) | (desc)->word2); })
-+
-+#define EDMA_TXCMPL_OPAQUE_GET(_desc) ({ \
-+                      typeof(_desc) (desc) = (_desc); \
-+                      (((u64)(desc)->word1 << 32) | \
-+                      (desc)->word0); })
-+
-+#define EDMA_TXDESC_OPAQUE_LO_SET(desc, ptr)  ((desc)->word2 = \
-+                                              (u32)(uintptr_t)(ptr))
-+
-+#define EDMA_TXDESC_OPAQUE_HI_SET(desc, ptr)  ((desc)->word3 = \
-+                                              (u32)((u64)(ptr) >> 32))
-+
-+#define EDMA_TXDESC_OPAQUE_SET(_desc, _ptr)   do { \
-+      typeof(_desc) (desc) = (_desc); \
-+      typeof(_ptr) (ptr) = (_ptr); \
-+      EDMA_TXDESC_OPAQUE_LO_SET(desc, ptr); \
-+      EDMA_TXDESC_OPAQUE_HI_SET(desc, ptr); \
-+} while (0)
-+#else
-+#define EDMA_TXCMPL_OPAQUE_GET(desc)          ((desc)->word0)
-+#define EDMA_TXDESC_OPAQUE_GET(desc)          ((desc)->word2)
-+#define EDMA_TXDESC_OPAQUE_LO_SET(desc, ptr)  ((desc)->word2 = (u32)(uintptr_t)ptr)
-+
-+#define EDMA_TXDESC_OPAQUE_SET(desc, ptr)     \
-+                                      EDMA_TXDESC_OPAQUE_LO_SET(desc, ptr)
-+#endif
-+#define EDMA_TXCMPL_MORE_BIT_MASK     BIT(30)
-+
-+#define EDMA_TXCMPL_MORE_BIT_GET(desc)        ((le32_to_cpu((__force __le32)((desc)->word2))) & \
-+                                      EDMA_TXCMPL_MORE_BIT_MASK)
-+
-+#define EDMA_TXCOMP_RING_ERROR_MASK   GENMASK(22, 0)
-+
-+#define EDMA_TXCOMP_RING_ERROR_GET(x) ((le32_to_cpu((__force __le32)x)) & \
-+                                      EDMA_TXCOMP_RING_ERROR_MASK)
-+
-+#define EDMA_TXCOMP_POOL_ID_MASK      GENMASK(5, 0)
-+
-+#define EDMA_TXCOMP_POOL_ID_GET(desc) ((le32_to_cpu((__force __le32)((desc)->word2))) & \
-+                                      EDMA_TXCOMP_POOL_ID_MASK)
-+
-+/* Opaque values are set in word2 and word3,
-+ * they are not accessed by the EDMA HW,
-+ * so endianness conversion is not needed.
-+ */
-+#define EDMA_TXDESC_ENDIAN_SET(_desc) ({ \
-+      typeof(_desc) (desc) = (_desc); \
-+      cpu_to_le32s(&((desc)->word0)); \
-+      cpu_to_le32s(&((desc)->word1)); \
-+      cpu_to_le32s(&((desc)->word4)); \
-+      cpu_to_le32s(&((desc)->word5)); \
-+      cpu_to_le32s(&((desc)->word6)); \
-+      cpu_to_le32s(&((desc)->word7)); \
-+})
-+
-+/* EDMA Tx GSO status */
-+enum edma_tx_status {
-+      EDMA_TX_OK = 0,                 /* Tx success. */
-+      EDMA_TX_FAIL_NO_DESC = 1,       /* Not enough descriptors. */
-+      EDMA_TX_FAIL = 2,               /* Tx failure. */
-+};
-+
-+/* EDMA TX GSO status */
-+enum edma_tx_gso_status {
-+      EDMA_TX_GSO_NOT_NEEDED = 0,
-+              /* Packet has segment count less than TX_TSO_SEG_MAX. */
-+      EDMA_TX_GSO_SUCCEED = 1,
-+              /* GSO Succeed. */
-+      EDMA_TX_GSO_FAIL = 2,
-+              /* GSO failed, drop the packet. */
-+};
-+
-+/**
-+ * struct edma_txcmpl_stats - EDMA TX complete ring statistics.
-+ * @invalid_buffer: Invalid buffer address received.
-+ * @errors: Other Tx complete descriptor errors indicated by the hardware.
-+ * @desc_with_more_bit: Packet's segment transmit count.
-+ * @no_pending_desc: No descriptor is pending for processing.
-+ * @syncp: Synchronization pointer.
-+ */
-+struct edma_txcmpl_stats {
-+      u64 invalid_buffer;
-+      u64 errors;
-+      u64 desc_with_more_bit;
-+      u64 no_pending_desc;
-+      struct u64_stats_sync syncp;
-+};
-+
-+/**
-+ * struct edma_txdesc_stats - EDMA Tx descriptor ring statistics.
-+ * @no_desc_avail: No descriptor available to transmit.
-+ * @tso_max_seg_exceed: Packets extending EDMA_TX_TSO_SEG_MAX segments.
-+ * @syncp: Synchronization pointer.
-+ */
-+struct edma_txdesc_stats {
-+      u64 no_desc_avail;
-+      u64 tso_max_seg_exceed;
-+      struct u64_stats_sync syncp;
-+};
-+
-+/**
-+ * struct edma_txdesc_pri - EDMA primary TX descriptor.
-+ * @word0: Low 32-bit of buffer address.
-+ * @word1: Buffer recycling, PTP tag flag, PRI valid flag.
-+ * @word2: Low 32-bit of opaque value.
-+ * @word3: High 32-bit of opaque value.
-+ * @word4: Source/Destination port info.
-+ * @word5: VLAN offload, csum mode, ip_csum_en, tso_en, data len.
-+ * @word6: MSS/hash_value/PTP tag, data offset.
-+ * @word7: L4/L3 offset, PROT type, L2 type, CVLAN/SVLAN tag, service code.
-+ */
-+struct edma_txdesc_pri {
-+      u32 word0;
-+      u32 word1;
-+      u32 word2;
-+      u32 word3;
-+      u32 word4;
-+      u32 word5;
-+      u32 word6;
-+      u32 word7;
-+};
-+
-+/**
-+ * struct edma_txdesc_sec - EDMA secondary TX descriptor.
-+ * @word0: Reserved.
-+ * @word1: Custom csum offset, payload offset, TTL/NAT action.
-+ * @word2: NAPT translated port, DSCP value, TTL value.
-+ * @word3: Flow index value and valid flag.
-+ * @word4: Reserved.
-+ * @word5: Reserved.
-+ * @word6: CVLAN/SVLAN command.
-+ * @word7: CVLAN/SVLAN tag value.
-+ */
-+struct edma_txdesc_sec {
-+      u32 word0;
-+      u32 word1;
-+      u32 word2;
-+      u32 word3;
-+      u32 word4;
-+      u32 word5;
-+      u32 word6;
-+      u32 word7;
-+};
-+
-+/**
-+ * struct edma_txcmpl_desc - EDMA TX complete descriptor.
-+ * @word0: Low 32-bit opaque value.
-+ * @word1: High 32-bit opaque value.
-+ * @word2: More fragment, transmit ring id, pool id.
-+ * @word3: Error indications.
-+ */
-+struct edma_txcmpl_desc {
-+      u32 word0;
-+      u32 word1;
-+      u32 word2;
-+      u32 word3;
-+};
-+
-+/**
-+ * struct edma_txdesc_ring - EDMA TX descriptor ring
-+ * @prod_idx: Producer index
-+ * @id: Tx ring number
-+ * @avail_desc: Number of available descriptor to process
-+ * @pdesc: Primary descriptor ring virtual address
-+ * @pdma: Primary descriptor ring physical address
-+ * @sdesc: Secondary descriptor ring virtual address
-+ * @tx_desc_stats: Tx descriptor ring statistics
-+ * @sdma: Secondary descriptor ring physical address
-+ * @count: Number of descriptors
-+ * @fc_grp_id: Flow control group ID
-+ */
-+struct edma_txdesc_ring {
-+      u32 prod_idx;
-+      u32 id;
-+      u32 avail_desc;
-+      struct edma_txdesc_pri *pdesc;
-+      dma_addr_t pdma;
-+      struct edma_txdesc_sec *sdesc;
-+      struct edma_txdesc_stats txdesc_stats;
-+      dma_addr_t sdma;
-+      u32 count;
-+      u8 fc_grp_id;
-+};
-+
-+/**
-+ * struct edma_txcmpl_ring - EDMA TX complete ring
-+ * @napi: NAPI
-+ * @cons_idx: Consumer index
-+ * @avail_pkt: Number of available packets to process
-+ * @desc: Descriptor ring virtual address
-+ * @id: Txcmpl ring number
-+ * @tx_cmpl_stats: Tx complete ring statistics
-+ * @dma: Descriptor ring physical address
-+ * @count: Number of descriptors in the ring
-+ * @napi_added: Flag to indicate NAPI add status
-+ */
-+struct edma_txcmpl_ring {
-+      struct napi_struct napi;
-+      u32 cons_idx;
-+      u32 avail_pkt;
-+      struct edma_txcmpl_desc *desc;
-+      u32 id;
-+      struct edma_txcmpl_stats txcmpl_stats;
-+      dma_addr_t dma;
-+      u32 count;
-+      bool napi_added;
-+};
-+
-+enum edma_tx_status edma_tx_ring_xmit(struct net_device *netdev,
-+                                    struct sk_buff *skb,
-+                             struct edma_txdesc_ring *txdesc_ring,
-+                             struct edma_port_tx_stats *stats);
-+u32 edma_tx_complete(u32 work_to_do,
-+                   struct edma_txcmpl_ring *txcmpl_ring);
-+irqreturn_t edma_tx_handle_irq(int irq, void *ctx);
-+int edma_tx_napi_poll(struct napi_struct *napi, int budget);
-+enum edma_tx_gso_status edma_tx_gso_segment(struct sk_buff *skb,
-+                                          struct net_device *netdev, struct sk_buff **segs);
-+
-+#endif
diff --git a/target/linux/qualcommbe/patches-6.12/0346-net-ethernet-qualcomm-Add-miscellaneous-error-interr.patch b/target/linux/qualcommbe/patches-6.12/0346-net-ethernet-qualcomm-Add-miscellaneous-error-interr.patch
deleted file mode 100644 (file)
index 0bdfb0c..0000000
+++ /dev/null
@@ -1,730 +0,0 @@
-From 8a924457c0b71acee96c8f78ef386e2a354a2aca Mon Sep 17 00:00:00 2001
-From: Suruchi Agarwal <quic_suruchia@quicinc.com>
-Date: Thu, 21 Mar 2024 16:31:04 -0700
-Subject: [PATCH] net: ethernet: qualcomm: Add miscellaneous error interrupts
- and counters
-
-Miscellaneous error interrupts, EDMA Tx/Rx and error counters are supported
-using debugfs framework.
-
-Change-Id: I7da8b978a7e93947b03a45269a81b401f35da31c
-Co-developed-by: Pavithra R <quic_pavir@quicinc.com>
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
-Signed-off-by: Suruchi Agarwal <quic_suruchia@quicinc.com>
----
- drivers/net/ethernet/qualcomm/ppe/Makefile    |   2 +-
- drivers/net/ethernet/qualcomm/ppe/edma.c      | 162 ++++++++
- drivers/net/ethernet/qualcomm/ppe/edma.h      |  30 ++
- .../net/ethernet/qualcomm/ppe/edma_debugfs.c  | 370 ++++++++++++++++++
- .../net/ethernet/qualcomm/ppe/ppe_debugfs.c   |  17 +
- 5 files changed, 580 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_debugfs.c
-
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -7,4 +7,4 @@ obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
- qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o ppe_port.o
- #EDMA
--qcom-ppe-objs += edma.o edma_cfg_rx.o edma_cfg_tx.o edma_port.o edma_rx.o edma_tx.o
-+qcom-ppe-objs += edma.o edma_cfg_rx.o edma_cfg_tx.o edma_debugfs.o edma_port.o edma_rx.o edma_tx.o
---- a/drivers/net/ethernet/qualcomm/ppe/edma.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.c
-@@ -152,6 +152,42 @@ static int edma_clock_init(void)
- }
- /**
-+ * edma_err_stats_alloc - Allocate stats memory
-+ *
-+ * Allocate memory for per-CPU error stats.
-+ */
-+int edma_err_stats_alloc(void)
-+{
-+      u32 i;
-+
-+      edma_ctx->err_stats = alloc_percpu(*edma_ctx->err_stats);
-+      if (!edma_ctx->err_stats)
-+              return -ENOMEM;
-+
-+      for_each_possible_cpu(i) {
-+              struct edma_err_stats *stats;
-+
-+              stats = per_cpu_ptr(edma_ctx->err_stats, i);
-+              u64_stats_init(&stats->syncp);
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ * edma_err_stats_free - Free stats memory
-+ *
-+ * Free memory of per-CPU error stats.
-+ */
-+void edma_err_stats_free(void)
-+{
-+      if (edma_ctx->err_stats) {
-+              free_percpu(edma_ctx->err_stats);
-+              edma_ctx->err_stats = NULL;
-+      }
-+}
-+
-+/**
-  * edma_configure_ucast_prio_map_tbl - Configure unicast priority map table.
-  *
-  * Map int_priority values to priority class and initialize
-@@ -191,11 +227,113 @@ static int edma_configure_ucast_prio_map
-       return ret;
- }
-+static void edma_disable_misc_interrupt(void)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 reg;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_MISC_INT_MASK_ADDR;
-+      regmap_write(regmap, reg, EDMA_MASK_INT_CLEAR);
-+}
-+
-+static void edma_enable_misc_interrupt(void)
-+{
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 reg;
-+
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_MISC_INT_MASK_ADDR;
-+      regmap_write(regmap, reg, edma_ctx->intr_info.intr_mask_misc);
-+}
-+
-+static irqreturn_t edma_misc_handle_irq(int irq,
-+                                      __maybe_unused void *ctx)
-+{
-+      struct edma_err_stats *stats = this_cpu_ptr(edma_ctx->err_stats);
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-+      struct regmap *regmap = ppe_dev->regmap;
-+      u32 misc_intr_status, data, reg;
-+
-+      /* Read Misc intr status */
-+      reg = EDMA_BASE_OFFSET + EDMA_REG_MISC_INT_STAT_ADDR;
-+      regmap_read(regmap, reg, &data);
-+      misc_intr_status = data & edma_ctx->intr_info.intr_mask_misc;
-+
-+      pr_debug("Received misc irq %d, status: %d\n", irq, misc_intr_status);
-+
-+      if (FIELD_GET(EDMA_MISC_AXI_RD_ERR_MASK, misc_intr_status)) {
-+              pr_err("MISC AXI read error received\n");
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->edma_axi_read_err;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      if (FIELD_GET(EDMA_MISC_AXI_WR_ERR_MASK, misc_intr_status)) {
-+              pr_err("MISC AXI write error received\n");
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->edma_axi_write_err;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      if (FIELD_GET(EDMA_MISC_RX_DESC_FIFO_FULL_MASK, misc_intr_status)) {
-+              if (net_ratelimit())
-+                      pr_err("MISC Rx descriptor fifo full error received\n");
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->edma_rxdesc_fifo_full;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      if (FIELD_GET(EDMA_MISC_RX_ERR_BUF_SIZE_MASK, misc_intr_status)) {
-+              if (net_ratelimit())
-+                      pr_err("MISC Rx buffer size error received\n");
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->edma_rx_buf_size_err;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      if (FIELD_GET(EDMA_MISC_TX_SRAM_FULL_MASK, misc_intr_status)) {
-+              if (net_ratelimit())
-+                      pr_err("MISC Tx SRAM full error received\n");
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->edma_tx_sram_full;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      if (FIELD_GET(EDMA_MISC_TX_CMPL_BUF_FULL_MASK, misc_intr_status)) {
-+              if (net_ratelimit())
-+                      pr_err("MISC Tx complete buffer full error received\n");
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->edma_txcmpl_buf_full;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      if (FIELD_GET(EDMA_MISC_DATA_LEN_ERR_MASK, misc_intr_status)) {
-+              if (net_ratelimit())
-+                      pr_err("MISC data length error received\n");
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->edma_tx_data_len_err;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      if (FIELD_GET(EDMA_MISC_TX_TIMEOUT_MASK, misc_intr_status)) {
-+              if (net_ratelimit())
-+                      pr_err("MISC Tx timeout error received\n");
-+              u64_stats_update_begin(&stats->syncp);
-+              ++stats->edma_tx_timeout;
-+              u64_stats_update_end(&stats->syncp);
-+      }
-+
-+      return IRQ_HANDLED;
-+}
-+
- static int edma_irq_register(void)
- {
-       struct edma_hw_info *hw_info = edma_ctx->hw_info;
-       struct edma_ring_info *txcmpl = hw_info->txcmpl;
-+      struct ppe_device *ppe_dev = edma_ctx->ppe_dev;
-       struct edma_ring_info *rx = hw_info->rx;
-+      struct device *dev = ppe_dev->dev;
-       int ret;
-       u32 i;
-@@ -270,8 +408,25 @@ static int edma_irq_register(void)
-                        edma_rxdesc_irq_name[i]);
-       }
-+      /* Request Misc IRQ */
-+      ret = request_irq(edma_ctx->intr_info.intr_misc, edma_misc_handle_irq,
-+                        IRQF_SHARED, "edma_misc",
-+                        (void *)dev);
-+      if (ret) {
-+              pr_err("MISC IRQ:%d request failed\n",
-+                     edma_ctx->intr_info.intr_misc);
-+              goto misc_intr_req_fail;
-+      }
-+
-       return 0;
-+misc_intr_req_fail:
-+      /* Free IRQ for RXDESC rings */
-+      for (i = 0; i < rx->num_rings; i++) {
-+              synchronize_irq(edma_ctx->intr_info.intr_rx[i]);
-+              free_irq(edma_ctx->intr_info.intr_rx[i],
-+                       (void *)&edma_ctx->rx_rings[i]);
-+      }
- rx_desc_ring_intr_req_fail:
-       for (i = 0; i < rx->num_rings; i++)
-               kfree(edma_rxdesc_irq_name[i]);
-@@ -503,6 +658,7 @@ static int edma_hw_configure(void)
-               edma_cfg_tx_disable_interrupts(i);
-       edma_cfg_rx_disable_interrupts();
-+      edma_disable_misc_interrupt();
-       edma_cfg_rx_rings_disable();
-@@ -614,6 +770,7 @@ void edma_destroy(struct ppe_device *ppe
-               edma_cfg_tx_disable_interrupts(i);
-       edma_cfg_rx_disable_interrupts();
-+      edma_disable_misc_interrupt();
-       /* Free IRQ for TXCMPL rings. */
-       for (i = 0; i < txcmpl->num_rings; i++) {
-@@ -634,6 +791,10 @@ void edma_destroy(struct ppe_device *ppe
-       }
-       kfree(edma_rxdesc_irq_name);
-+      /* Free Misc IRQ */
-+      synchronize_irq(edma_ctx->intr_info.intr_misc);
-+      free_irq(edma_ctx->intr_info.intr_misc, (void *)(ppe_dev->dev));
-+
-       kfree(edma_ctx->intr_info.intr_rx);
-       kfree(edma_ctx->intr_info.intr_txcmpl);
-@@ -699,6 +860,7 @@ int edma_setup(struct ppe_device *ppe_de
-       }
-       edma_cfg_rx_enable_interrupts();
-+      edma_enable_misc_interrupt();
-       dev_info(dev, "EDMA configuration successful\n");
---- a/drivers/net/ethernet/qualcomm/ppe/edma.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.h
-@@ -47,6 +47,30 @@ enum ppe_queue_class_type {
- };
- /**
-+ * struct edma_err_stats - EDMA error stats
-+ * @edma_axi_read_err: AXI read error
-+ * @edma_axi_write_err: AXI write error
-+ * @edma_rxdesc_fifo_full: Rx desc FIFO full error
-+ * @edma_rx_buf_size_err: Rx buffer size too small error
-+ * @edma_tx_sram_full: Tx packet SRAM buffer full error
-+ * @edma_tx_data_len_err: Tx data length error
-+ * @edma_tx_timeout: Tx timeout error
-+ * @edma_txcmpl_buf_full: Tx completion buffer full error
-+ * @syncp: Synchronization pointer
-+ */
-+struct edma_err_stats {
-+      u64 edma_axi_read_err;
-+      u64 edma_axi_write_err;
-+      u64 edma_rxdesc_fifo_full;
-+      u64 edma_rx_buf_size_err;
-+      u64 edma_tx_sram_full;
-+      u64 edma_tx_data_len_err;
-+      u64 edma_tx_timeout;
-+      u64 edma_txcmpl_buf_full;
-+      struct u64_stats_sync syncp;
-+};
-+
-+/**
-  * struct edma_ring_info - EDMA ring data structure.
-  * @max_rings: Maximum number of rings
-  * @ring_start: Ring start ID
-@@ -107,6 +131,7 @@ struct edma_intr_info {
-  * @rx_rings: Rx Desc Rings, SW is consumer
-  * @tx_rings: Tx Descriptor Ring, SW is producer
-  * @txcmpl_rings: Tx complete Ring, SW is consumer
-+ * @err_stats: Per CPU error statistics
-  * @rx_page_mode: Page mode enabled or disabled
-  * @rx_buf_size: Rx buffer size for Jumbo MRU
-  * @tx_requeue_stop: Tx requeue stop enabled or disabled
-@@ -121,6 +146,7 @@ struct edma_context {
-       struct edma_rxdesc_ring *rx_rings;
-       struct edma_txdesc_ring *tx_rings;
-       struct edma_txcmpl_ring *txcmpl_rings;
-+      struct edma_err_stats __percpu *err_stats;
-       u32 rx_page_mode;
-       u32 rx_buf_size;
-       bool tx_requeue_stop;
-@@ -129,8 +155,12 @@ struct edma_context {
- /* Global EDMA context */
- extern struct edma_context *edma_ctx;
-+int edma_err_stats_alloc(void);
-+void edma_err_stats_free(void);
- void edma_destroy(struct ppe_device *ppe_dev);
- int edma_setup(struct ppe_device *ppe_dev);
-+void edma_debugfs_teardown(void);
-+int edma_debugfs_setup(struct ppe_device *ppe_dev);
- int ppe_edma_queue_offset_config(struct ppe_device *ppe_dev,
-                                enum ppe_queue_class_type class,
-                                int index, int queue_offset);
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_debugfs.c
-@@ -0,0 +1,370 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* EDMA debugfs routines for display of Tx/Rx counters. */
-+
-+#include <linux/cpumask.h>
-+#include <linux/debugfs.h>
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/printk.h>
-+
-+#include "edma.h"
-+
-+#define EDMA_STATS_BANNER_MAX_LEN       80
-+#define EDMA_RX_RING_STATS_NODE_NAME    "EDMA_RX"
-+#define EDMA_TX_RING_STATS_NODE_NAME    "EDMA_TX"
-+#define EDMA_ERR_STATS_NODE_NAME        "EDMA_ERR"
-+
-+static struct dentry *edma_dentry;
-+static struct dentry *stats_dentry;
-+
-+static void edma_debugfs_print_banner(struct seq_file *m, char *node)
-+{
-+      u32 banner_char_len, i;
-+
-+      for (i = 0; i < EDMA_STATS_BANNER_MAX_LEN; i++)
-+              seq_puts(m, "_");
-+      banner_char_len = (EDMA_STATS_BANNER_MAX_LEN - (strlen(node) + 2)) / 2;
-+      seq_puts(m, "\n\n");
-+
-+      for (i = 0; i < banner_char_len; i++)
-+              seq_puts(m, "<");
-+      seq_printf(m, " %s ", node);
-+
-+      for (i = 0; i < banner_char_len; i++)
-+              seq_puts(m, ">");
-+      seq_puts(m, "\n");
-+
-+      for (i = 0; i < EDMA_STATS_BANNER_MAX_LEN; i++)
-+              seq_puts(m, "_");
-+      seq_puts(m, "\n\n");
-+}
-+
-+static int edma_debugfs_rx_rings_stats_show(struct seq_file *m,
-+                                          void __maybe_unused *p)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *rxfill = hw_info->rxfill;
-+      struct edma_rxfill_stats *rxfill_stats;
-+      struct edma_rxdesc_stats *rxdesc_stats;
-+      struct edma_ring_info *rx = hw_info->rx;
-+      unsigned int start;
-+      u32 i;
-+
-+      rxfill_stats = kcalloc(rxfill->num_rings, sizeof(*rxfill_stats), GFP_KERNEL);
-+      if (!rxfill_stats)
-+              return -ENOMEM;
-+
-+      rxdesc_stats = kcalloc(rx->num_rings, sizeof(*rxdesc_stats), GFP_KERNEL);
-+      if (!rxdesc_stats) {
-+              kfree(rxfill_stats);
-+              return -ENOMEM;
-+      }
-+
-+      /* Get stats for Rx fill rings. */
-+      for (i = 0; i < rxfill->num_rings; i++) {
-+              struct edma_rxfill_ring *rxfill_ring;
-+              struct edma_rxfill_stats *stats;
-+
-+              rxfill_ring = &edma_ctx->rxfill_rings[i];
-+              stats = &rxfill_ring->rxfill_stats;
-+              do {
-+                      start = u64_stats_fetch_begin(&stats->syncp);
-+                      rxfill_stats[i].alloc_failed = stats->alloc_failed;
-+                      rxfill_stats[i].page_alloc_failed = stats->page_alloc_failed;
-+              } while (u64_stats_fetch_retry(&stats->syncp, start));
-+      }
-+
-+      /* Get stats for Rx Desc rings. */
-+      for (i = 0; i < rx->num_rings; i++) {
-+              struct edma_rxdesc_ring *rxdesc_ring;
-+              struct edma_rxdesc_stats *stats;
-+
-+              rxdesc_ring = &edma_ctx->rx_rings[i];
-+              stats = &rxdesc_ring->rxdesc_stats;
-+              do {
-+                      start = u64_stats_fetch_begin(&stats->syncp);
-+                      rxdesc_stats[i].src_port_inval = stats->src_port_inval;
-+                      rxdesc_stats[i].src_port_inval_type = stats->src_port_inval_type;
-+                      rxdesc_stats[i].src_port_inval_netdev = stats->src_port_inval_netdev;
-+              } while (u64_stats_fetch_retry(&stats->syncp, start));
-+      }
-+
-+      edma_debugfs_print_banner(m, EDMA_RX_RING_STATS_NODE_NAME);
-+
-+      seq_puts(m, "\n#EDMA RX descriptor rings stats:\n\n");
-+      for (i = 0; i < rx->num_rings; i++) {
-+              seq_printf(m, "\t\tEDMA RX descriptor %d ring stats:\n", i + rx->ring_start);
-+              seq_printf(m, "\t\t rxdesc[%d]:src_port_inval = %llu\n",
-+                         i + rx->ring_start, rxdesc_stats[i].src_port_inval);
-+              seq_printf(m, "\t\t rxdesc[%d]:src_port_inval_type = %llu\n",
-+                         i + rx->ring_start, rxdesc_stats[i].src_port_inval_type);
-+              seq_printf(m, "\t\t rxdesc[%d]:src_port_inval_netdev = %llu\n",
-+                         i + rx->ring_start,
-+                         rxdesc_stats[i].src_port_inval_netdev);
-+              seq_puts(m, "\n");
-+      }
-+
-+      seq_puts(m, "\n#EDMA RX fill rings stats:\n\n");
-+      for (i = 0; i < rxfill->num_rings; i++) {
-+              seq_printf(m, "\t\tEDMA RX fill %d ring stats:\n", i + rxfill->ring_start);
-+              seq_printf(m, "\t\t rxfill[%d]:alloc_failed = %llu\n",
-+                         i + rxfill->ring_start, rxfill_stats[i].alloc_failed);
-+              seq_printf(m, "\t\t rxfill[%d]:page_alloc_failed = %llu\n",
-+                         i + rxfill->ring_start, rxfill_stats[i].page_alloc_failed);
-+              seq_puts(m, "\n");
-+      }
-+
-+      kfree(rxfill_stats);
-+      kfree(rxdesc_stats);
-+      return 0;
-+}
-+
-+static int edma_debugfs_tx_rings_stats_show(struct seq_file *m,
-+                                          void __maybe_unused *p)
-+{
-+      struct edma_hw_info *hw_info = edma_ctx->hw_info;
-+      struct edma_ring_info *txcmpl = hw_info->txcmpl;
-+      struct edma_ring_info *tx = hw_info->tx;
-+      struct edma_txcmpl_stats *txcmpl_stats;
-+      struct edma_txdesc_stats *txdesc_stats;
-+      unsigned int start;
-+      u32 i;
-+
-+      txcmpl_stats = kcalloc(txcmpl->num_rings, sizeof(*txcmpl_stats), GFP_KERNEL);
-+      if (!txcmpl_stats)
-+              return -ENOMEM;
-+
-+      txdesc_stats = kcalloc(tx->num_rings, sizeof(*txdesc_stats), GFP_KERNEL);
-+      if (!txdesc_stats) {
-+              kfree(txcmpl_stats);
-+              return -ENOMEM;
-+      }
-+
-+      /* Get stats for Tx desc rings. */
-+      for (i = 0; i < tx->num_rings; i++) {
-+              struct edma_txdesc_ring *txdesc_ring;
-+              struct edma_txdesc_stats *stats;
-+
-+              txdesc_ring = &edma_ctx->tx_rings[i];
-+              stats = &txdesc_ring->txdesc_stats;
-+              do {
-+                      start = u64_stats_fetch_begin(&stats->syncp);
-+                      txdesc_stats[i].no_desc_avail = stats->no_desc_avail;
-+                      txdesc_stats[i].tso_max_seg_exceed = stats->tso_max_seg_exceed;
-+              } while (u64_stats_fetch_retry(&stats->syncp, start));
-+      }
-+
-+      /* Get stats for Tx Complete rings. */
-+      for (i = 0; i < txcmpl->num_rings; i++) {
-+              struct edma_txcmpl_ring *txcmpl_ring;
-+              struct edma_txcmpl_stats *stats;
-+
-+              txcmpl_ring = &edma_ctx->txcmpl_rings[i];
-+              stats = &txcmpl_ring->txcmpl_stats;
-+              do {
-+                      start = u64_stats_fetch_begin(&stats->syncp);
-+                      txcmpl_stats[i].invalid_buffer = stats->invalid_buffer;
-+                      txcmpl_stats[i].errors = stats->errors;
-+                      txcmpl_stats[i].desc_with_more_bit = stats->desc_with_more_bit;
-+                      txcmpl_stats[i].no_pending_desc = stats->no_pending_desc;
-+              } while (u64_stats_fetch_retry(&stats->syncp, start));
-+      }
-+
-+      edma_debugfs_print_banner(m, EDMA_TX_RING_STATS_NODE_NAME);
-+
-+      seq_puts(m, "\n#EDMA TX complete rings stats:\n\n");
-+      for (i = 0; i < txcmpl->num_rings; i++) {
-+              seq_printf(m, "\t\tEDMA TX complete %d ring stats:\n", i + txcmpl->ring_start);
-+              seq_printf(m, "\t\t txcmpl[%d]:invalid_buffer = %llu\n",
-+                         i + txcmpl->ring_start, txcmpl_stats[i].invalid_buffer);
-+              seq_printf(m, "\t\t txcmpl[%d]:errors = %llu\n",
-+                         i + txcmpl->ring_start, txcmpl_stats[i].errors);
-+              seq_printf(m, "\t\t txcmpl[%d]:desc_with_more_bit = %llu\n",
-+                         i + txcmpl->ring_start, txcmpl_stats[i].desc_with_more_bit);
-+              seq_printf(m, "\t\t txcmpl[%d]:no_pending_desc = %llu\n",
-+                         i + txcmpl->ring_start, txcmpl_stats[i].no_pending_desc);
-+              seq_puts(m, "\n");
-+      }
-+
-+      seq_puts(m, "\n#EDMA TX descriptor rings stats:\n\n");
-+      for (i = 0; i < tx->num_rings; i++) {
-+              seq_printf(m, "\t\tEDMA TX descriptor %d ring stats:\n", i + tx->ring_start);
-+              seq_printf(m, "\t\t txdesc[%d]:no_desc_avail = %llu\n",
-+                         i + tx->ring_start, txdesc_stats[i].no_desc_avail);
-+              seq_printf(m, "\t\t txdesc[%d]:tso_max_seg_exceed = %llu\n",
-+                         i + tx->ring_start, txdesc_stats[i].tso_max_seg_exceed);
-+              seq_puts(m, "\n");
-+      }
-+
-+      kfree(txcmpl_stats);
-+      kfree(txdesc_stats);
-+      return 0;
-+}
-+
-+static int edma_debugfs_err_stats_show(struct seq_file *m,
-+                                     void __maybe_unused *p)
-+{
-+      struct edma_err_stats *err_stats, *pcpu_err_stats;
-+      unsigned int start;
-+      u32 cpu;
-+
-+      err_stats = kzalloc(sizeof(*err_stats), GFP_KERNEL);
-+      if (!err_stats)
-+              return -ENOMEM;
-+
-+      /* Get percpu EDMA miscellaneous stats. */
-+      for_each_possible_cpu(cpu) {
-+              pcpu_err_stats = per_cpu_ptr(edma_ctx->err_stats, cpu);
-+              do {
-+                      start = u64_stats_fetch_begin(&pcpu_err_stats->syncp);
-+                      err_stats->edma_axi_read_err +=
-+                              pcpu_err_stats->edma_axi_read_err;
-+                      err_stats->edma_axi_write_err +=
-+                              pcpu_err_stats->edma_axi_write_err;
-+                      err_stats->edma_rxdesc_fifo_full +=
-+                              pcpu_err_stats->edma_rxdesc_fifo_full;
-+                      err_stats->edma_rx_buf_size_err +=
-+                              pcpu_err_stats->edma_rx_buf_size_err;
-+                      err_stats->edma_tx_sram_full +=
-+                              pcpu_err_stats->edma_tx_sram_full;
-+                      err_stats->edma_tx_data_len_err +=
-+                              pcpu_err_stats->edma_tx_data_len_err;
-+                      err_stats->edma_tx_timeout +=
-+                              pcpu_err_stats->edma_tx_timeout;
-+                      err_stats->edma_txcmpl_buf_full +=
-+                              pcpu_err_stats->edma_txcmpl_buf_full;
-+              } while (u64_stats_fetch_retry(&pcpu_err_stats->syncp, start));
-+      }
-+
-+      edma_debugfs_print_banner(m, EDMA_ERR_STATS_NODE_NAME);
-+
-+      seq_puts(m, "\n#EDMA error stats:\n\n");
-+      seq_printf(m, "\t\t axi read error = %llu\n",
-+                 err_stats->edma_axi_read_err);
-+      seq_printf(m, "\t\t axi write error = %llu\n",
-+                 err_stats->edma_axi_write_err);
-+      seq_printf(m, "\t\t Rx descriptor fifo full = %llu\n",
-+                 err_stats->edma_rxdesc_fifo_full);
-+      seq_printf(m, "\t\t Rx buffer size error = %llu\n",
-+                 err_stats->edma_rx_buf_size_err);
-+      seq_printf(m, "\t\t Tx SRAM full = %llu\n",
-+                 err_stats->edma_tx_sram_full);
-+      seq_printf(m, "\t\t Tx data length error = %llu\n",
-+                 err_stats->edma_tx_data_len_err);
-+      seq_printf(m, "\t\t Tx timeout = %llu\n",
-+                 err_stats->edma_tx_timeout);
-+      seq_printf(m, "\t\t Tx completion buffer full = %llu\n",
-+                 err_stats->edma_txcmpl_buf_full);
-+
-+      kfree(err_stats);
-+      return 0;
-+}
-+
-+static int edma_debugs_rx_rings_stats_open(struct inode *inode,
-+                                         struct file *file)
-+{
-+      return single_open(file, edma_debugfs_rx_rings_stats_show,
-+                         inode->i_private);
-+}
-+
-+static const struct file_operations edma_debugfs_rx_rings_file_ops = {
-+      .open = edma_debugs_rx_rings_stats_open,
-+      .read = seq_read,
-+      .llseek = seq_lseek,
-+      .release = seq_release
-+};
-+
-+static int edma_debugs_tx_rings_stats_open(struct inode *inode, struct file *file)
-+{
-+      return single_open(file, edma_debugfs_tx_rings_stats_show, inode->i_private);
-+}
-+
-+static const struct file_operations edma_debugfs_tx_rings_file_ops = {
-+      .open = edma_debugs_tx_rings_stats_open,
-+      .read = seq_read,
-+      .llseek = seq_lseek,
-+      .release = seq_release
-+};
-+
-+static int edma_debugs_err_stats_open(struct inode *inode, struct file *file)
-+{
-+      return single_open(file, edma_debugfs_err_stats_show, inode->i_private);
-+}
-+
-+static const struct file_operations edma_debugfs_misc_file_ops = {
-+      .open = edma_debugs_err_stats_open,
-+      .read = seq_read,
-+      .llseek = seq_lseek,
-+      .release = seq_release
-+};
-+
-+/**
-+ * edma_debugfs_teardown - EDMA debugfs teardown.
-+ *
-+ * EDMA debugfs teardown and free stats memory.
-+ */
-+void edma_debugfs_teardown(void)
-+{
-+      /* Free EDMA miscellaneous stats memory */
-+      edma_err_stats_free();
-+
-+      debugfs_remove_recursive(edma_dentry);
-+      edma_dentry = NULL;
-+      stats_dentry = NULL;
-+}
-+
-+/**
-+ * edma_debugfs_setup - EDMA debugfs setup.
-+ * @ppe_dev: PPE Device
-+ *
-+ * EDMA debugfs setup.
-+ */
-+int edma_debugfs_setup(struct ppe_device *ppe_dev)
-+{
-+      edma_dentry = debugfs_create_dir("edma", ppe_dev->debugfs_root);
-+      if (!edma_dentry) {
-+              pr_err("Unable to create debugfs edma directory in debugfs\n");
-+              goto debugfs_dir_failed;
-+      }
-+
-+      stats_dentry = debugfs_create_dir("stats", edma_dentry);
-+      if (!stats_dentry) {
-+              pr_err("Unable to create debugfs stats directory in debugfs\n");
-+              goto debugfs_dir_failed;
-+      }
-+
-+      if (!debugfs_create_file("rx_ring_stats", 0444, stats_dentry,
-+                               NULL, &edma_debugfs_rx_rings_file_ops)) {
-+              pr_err("Unable to create Rx rings statistics file entry in debugfs\n");
-+              goto debugfs_dir_failed;
-+      }
-+
-+      if (!debugfs_create_file("tx_ring_stats", 0444, stats_dentry,
-+                               NULL, &edma_debugfs_tx_rings_file_ops)) {
-+              pr_err("Unable to create Tx rings statistics file entry in debugfs\n");
-+              goto debugfs_dir_failed;
-+      }
-+
-+      /* Allocate memory for EDMA miscellaneous stats */
-+      if (edma_err_stats_alloc() < 0) {
-+              pr_err("Unable to allocate miscellaneous percpu stats\n");
-+              goto debugfs_dir_failed;
-+      }
-+
-+      if (!debugfs_create_file("err_stats", 0444, stats_dentry,
-+                               NULL, &edma_debugfs_misc_file_ops)) {
-+              pr_err("Unable to create EDMA miscellaneous statistics file entry in debugfs\n");
-+              goto debugfs_dir_failed;
-+      }
-+
-+      return 0;
-+
-+debugfs_dir_failed:
-+      debugfs_remove_recursive(edma_dentry);
-+      edma_dentry = NULL;
-+      stats_dentry = NULL;
-+      return -ENOMEM;
-+}
---- a/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
-@@ -7,9 +7,11 @@
- #include <linux/bitfield.h>
- #include <linux/debugfs.h>
-+#include <linux/netdevice.h>
- #include <linux/regmap.h>
- #include <linux/seq_file.h>
-+#include "edma.h"
- #include "ppe.h"
- #include "ppe_config.h"
- #include "ppe_debugfs.h"
-@@ -678,15 +680,30 @@ static const struct file_operations ppe_
- void ppe_debugfs_setup(struct ppe_device *ppe_dev)
- {
-+      int ret;
-+
-       ppe_dev->debugfs_root = debugfs_create_dir("ppe", NULL);
-       debugfs_create_file("packet_counters", 0444,
-                           ppe_dev->debugfs_root,
-                           ppe_dev,
-                           &ppe_debugfs_packet_counter_fops);
-+
-+      if (!ppe_dev->debugfs_root) {
-+              dev_err(ppe_dev->dev, "Error in PPE debugfs setup\n");
-+              return;
-+      }
-+
-+      ret = edma_debugfs_setup(ppe_dev);
-+      if (ret) {
-+              dev_err(ppe_dev->dev, "Error in EDMA debugfs setup API. ret: %d\n", ret);
-+              debugfs_remove_recursive(ppe_dev->debugfs_root);
-+              ppe_dev->debugfs_root = NULL;
-+      }
- }
- void ppe_debugfs_teardown(struct ppe_device *ppe_dev)
- {
-+      edma_debugfs_teardown();
-       debugfs_remove_recursive(ppe_dev->debugfs_root);
-       ppe_dev->debugfs_root = NULL;
- }
diff --git a/target/linux/qualcommbe/patches-6.12/0347-net-ethernet-qualcomm-Add-ethtool-support-for-EDMA.patch b/target/linux/qualcommbe/patches-6.12/0347-net-ethernet-qualcomm-Add-ethtool-support-for-EDMA.patch
deleted file mode 100644 (file)
index 4e0103d..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-From bd61a680fb657eb65272225f18c93fe338c700da Mon Sep 17 00:00:00 2001
-From: Pavithra R <quic_pavir@quicinc.com>
-Date: Thu, 30 May 2024 20:46:36 +0530
-Subject: [PATCH] net: ethernet: qualcomm: Add ethtool support for EDMA
-
-ethtool ops can be used for EDMA netdevice configuration and statistics.
-
-Change-Id: I57fc19415dacbe51fed000520336463938220609
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
-Alex G: use struct ethtool_keee instead of ethtool_eee
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/ethernet/qualcomm/ppe/Makefile    |   2 +-
- drivers/net/ethernet/qualcomm/ppe/edma.h      |   1 +
- .../net/ethernet/qualcomm/ppe/edma_ethtool.c  | 294 ++++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/edma_port.c |   1 +
- 4 files changed, 297 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/ethernet/qualcomm/ppe/edma_ethtool.c
-
---- a/drivers/net/ethernet/qualcomm/ppe/Makefile
-+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
-@@ -7,4 +7,4 @@ obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
- qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o ppe_port.o
- #EDMA
--qcom-ppe-objs += edma.o edma_cfg_rx.o edma_cfg_tx.o edma_debugfs.o edma_port.o edma_rx.o edma_tx.o
-+qcom-ppe-objs += edma.o edma_cfg_rx.o edma_cfg_tx.o edma_debugfs.o edma_port.o edma_rx.o edma_tx.o edma_ethtool.o
---- a/drivers/net/ethernet/qualcomm/ppe/edma.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.h
-@@ -161,6 +161,7 @@ void edma_destroy(struct ppe_device *ppe
- int edma_setup(struct ppe_device *ppe_dev);
- void edma_debugfs_teardown(void);
- int edma_debugfs_setup(struct ppe_device *ppe_dev);
-+void edma_set_ethtool_ops(struct net_device *netdev);
- int ppe_edma_queue_offset_config(struct ppe_device *ppe_dev,
-                                enum ppe_queue_class_type class,
-                                int index, int queue_offset);
---- /dev/null
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_ethtool.c
-@@ -0,0 +1,294 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+/* ethtool support for EDMA */
-+
-+#include <linux/cpumask.h>
-+#include <linux/ethtool.h>
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/phylink.h>
-+
-+#include "edma.h"
-+#include "edma_port.h"
-+
-+struct edma_ethtool_stats {
-+      u8 stat_string[ETH_GSTRING_LEN];
-+      u32 stat_offset;
-+};
-+
-+/**
-+ * struct edma_gmac_stats - Per-GMAC statistics.
-+ * @rx_packets: Number of RX packets
-+ * @rx_bytes: Number of RX bytes
-+ * @rx_dropped: Number of RX dropped packets
-+ * @rx_fraglist_packets: Number of RX fraglist packets
-+ * @rx_nr_frag_packets: Number of RX nr fragment packets
-+ * @rx_nr_frag_headroom_err: Number of RX nr fragment packets with headroom error
-+ * @tx_packets: Number of TX packets
-+ * @tx_bytes: Number of TX bytes
-+ * @tx_dropped: Number of TX dropped packets
-+ * @tx_nr_frag_packets: Number of TX nr fragment packets
-+ * @tx_fraglist_packets: Number of TX fraglist packets
-+ * @tx_fraglist_with_nr_frags_packets: Number of TX fraglist packets with nr fragments
-+ * @tx_tso_packets: Number of TX TCP segmentation offload packets
-+ * @tx_tso_drop_packets: Number of TX TCP segmentation dropped packets
-+ * @tx_gso_packets: Number of TX SW GSO packets
-+ * @tx_gso_drop_packets: Number of TX SW GSO dropped packets
-+ * @tx_queue_stopped: Number of times Queue got stopped
-+ */
-+struct edma_gmac_stats {
-+      u64 rx_packets;
-+      u64 rx_bytes;
-+      u64 rx_dropped;
-+      u64 rx_fraglist_packets;
-+      u64 rx_nr_frag_packets;
-+      u64 rx_nr_frag_headroom_err;
-+      u64 tx_packets;
-+      u64 tx_bytes;
-+      u64 tx_dropped;
-+      u64 tx_nr_frag_packets;
-+      u64 tx_fraglist_packets;
-+      u64 tx_fraglist_with_nr_frags_packets;
-+      u64 tx_tso_packets;
-+      u64 tx_tso_drop_packets;
-+      u64 tx_gso_packets;
-+      u64 tx_gso_drop_packets;
-+      u64 tx_queue_stopped[EDMA_MAX_CORE];
-+};
-+
-+#define EDMA_STAT(m)          offsetof(struct edma_gmac_stats, m)
-+
-+static const struct edma_ethtool_stats edma_gstrings_stats[] = {
-+      {"rx_bytes", EDMA_STAT(rx_bytes)},
-+      {"rx_packets", EDMA_STAT(rx_packets)},
-+      {"rx_dropped", EDMA_STAT(rx_dropped)},
-+      {"rx_fraglist_packets", EDMA_STAT(rx_fraglist_packets)},
-+      {"rx_nr_frag_packets", EDMA_STAT(rx_nr_frag_packets)},
-+      {"rx_nr_frag_headroom_err", EDMA_STAT(rx_nr_frag_headroom_err)},
-+      {"tx_bytes", EDMA_STAT(tx_bytes)},
-+      {"tx_packets", EDMA_STAT(tx_packets)},
-+      {"tx_dropped", EDMA_STAT(tx_dropped)},
-+      {"tx_nr_frag_packets", EDMA_STAT(tx_nr_frag_packets)},
-+      {"tx_fraglist_packets", EDMA_STAT(tx_fraglist_packets)},
-+      {"tx_fraglist_nr_frags_packets", EDMA_STAT(tx_fraglist_with_nr_frags_packets)},
-+      {"tx_tso_packets", EDMA_STAT(tx_tso_packets)},
-+      {"tx_tso_drop_packets", EDMA_STAT(tx_tso_drop_packets)},
-+      {"tx_gso_packets", EDMA_STAT(tx_gso_packets)},
-+      {"tx_gso_drop_packets", EDMA_STAT(tx_gso_drop_packets)},
-+      {"tx_queue_stopped_cpu0", EDMA_STAT(tx_queue_stopped[0])},
-+      {"tx_queue_stopped_cpu1", EDMA_STAT(tx_queue_stopped[1])},
-+      {"tx_queue_stopped_cpu2", EDMA_STAT(tx_queue_stopped[2])},
-+      {"tx_queue_stopped_cpu3", EDMA_STAT(tx_queue_stopped[3])},
-+};
-+
-+#define EDMA_STATS_LEN                ARRAY_SIZE(edma_gstrings_stats)
-+
-+static void edma_port_get_stats(struct net_device *netdev,
-+                              struct edma_gmac_stats *stats)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct edma_port_rx_stats *pcpu_rx_stats;
-+      struct edma_port_tx_stats *pcpu_tx_stats;
-+      int i;
-+
-+      memset(stats, 0, sizeof(struct edma_port_pcpu_stats));
-+
-+      for_each_possible_cpu(i) {
-+              struct edma_port_rx_stats rxp;
-+              struct edma_port_tx_stats txp;
-+              unsigned int start;
-+
-+              pcpu_rx_stats = per_cpu_ptr(port_priv->pcpu_stats.rx_stats, i);
-+
-+              do {
-+                      start = u64_stats_fetch_begin(&pcpu_rx_stats->syncp);
-+                      memcpy(&rxp, pcpu_rx_stats, sizeof(*pcpu_rx_stats));
-+              } while (u64_stats_fetch_retry(&pcpu_rx_stats->syncp, start));
-+
-+              stats->rx_packets += rxp.rx_pkts;
-+              stats->rx_bytes += rxp.rx_bytes;
-+              stats->rx_dropped += rxp.rx_drops;
-+              stats->rx_nr_frag_packets += rxp.rx_nr_frag_pkts;
-+              stats->rx_fraglist_packets += rxp.rx_fraglist_pkts;
-+              stats->rx_nr_frag_headroom_err += rxp.rx_nr_frag_headroom_err;
-+
-+              pcpu_tx_stats = per_cpu_ptr(port_priv->pcpu_stats.tx_stats, i);
-+
-+              do {
-+                      start = u64_stats_fetch_begin(&pcpu_tx_stats->syncp);
-+                      memcpy(&txp, pcpu_tx_stats, sizeof(*pcpu_tx_stats));
-+              } while (u64_stats_fetch_retry(&pcpu_tx_stats->syncp, start));
-+
-+              stats->tx_packets += txp.tx_pkts;
-+              stats->tx_bytes += txp.tx_bytes;
-+              stats->tx_dropped += txp.tx_drops;
-+              stats->tx_nr_frag_packets += txp.tx_nr_frag_pkts;
-+              stats->tx_fraglist_packets += txp.tx_fraglist_pkts;
-+              stats->tx_fraglist_with_nr_frags_packets += txp.tx_fraglist_with_nr_frags_pkts;
-+              stats->tx_tso_packets += txp.tx_tso_pkts;
-+              stats->tx_tso_drop_packets += txp.tx_tso_drop_pkts;
-+              stats->tx_gso_packets += txp.tx_gso_pkts;
-+              stats->tx_gso_drop_packets += txp.tx_gso_drop_pkts;
-+              stats->tx_queue_stopped[i] += txp.tx_queue_stopped[i];
-+      }
-+}
-+
-+static void edma_get_ethtool_stats(struct net_device *netdev,
-+                                 __maybe_unused struct ethtool_stats *stats,
-+                                 u64 *data)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct edma_gmac_stats edma_stats;
-+      u64 *mib_data;
-+      int i;
-+      u8 *p;
-+
-+      if (!port_priv)
-+              return;
-+
-+      /* Get the DMA Driver statistics from the data plane if available. */
-+      memset(&edma_stats, 0, sizeof(struct edma_gmac_stats));
-+      edma_port_get_stats(netdev, &edma_stats);
-+
-+       /* Populate data plane statistics. */
-+      for (i = 0; i < EDMA_STATS_LEN; i++) {
-+              p = ((u8 *)(&edma_stats) + edma_gstrings_stats[i].stat_offset);
-+              data[i] = *(u64 *)p;
-+      }
-+
-+       /* Get the GMAC MIB statistics along with the DMA driver statistics. */
-+      mib_data = &data[EDMA_STATS_LEN];
-+      ppe_port_get_ethtool_stats(port_priv->ppe_port, mib_data);
-+}
-+
-+static int edma_get_strset_count(struct net_device *netdev, int sset)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      int sset_count = 0;
-+
-+      if (!port_priv || sset != ETH_SS_STATS)
-+              return 0;
-+
-+      sset_count = ppe_port_get_sset_count(port_priv->ppe_port, sset);
-+
-+      return (EDMA_STATS_LEN + sset_count);
-+}
-+
-+static void edma_get_strings(struct net_device *netdev, u32 stringset,
-+                           u8 *data)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      int i;
-+
-+      if (!port_priv || stringset != ETH_SS_STATS)
-+              return;
-+
-+      for (i = 0; i < EDMA_STATS_LEN; i++) {
-+              memcpy(data, edma_gstrings_stats[i].stat_string,
-+                     strlen(edma_gstrings_stats[i].stat_string));
-+              data += ETH_GSTRING_LEN;
-+      }
-+
-+      ppe_port_get_strings(port_priv->ppe_port, stringset, data);
-+}
-+
-+static int edma_get_link_ksettings(struct net_device *netdev,
-+                                 struct ethtool_link_ksettings *cmd)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *port =  port_priv->ppe_port;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      return phylink_ethtool_ksettings_get(port->phylink, cmd);
-+}
-+
-+static int edma_set_link_ksettings(struct net_device *netdev,
-+                                 const struct ethtool_link_ksettings *cmd)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *port =  port_priv->ppe_port;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      return phylink_ethtool_ksettings_set(port->phylink, cmd);
-+}
-+
-+static void edma_get_pauseparam(struct net_device *netdev,
-+                              struct ethtool_pauseparam *pause)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *port =  port_priv->ppe_port;
-+
-+      if (!port_priv)
-+              return;
-+
-+      phylink_ethtool_get_pauseparam(port->phylink, pause);
-+}
-+
-+static int edma_set_pauseparam(struct net_device *netdev,
-+                             struct ethtool_pauseparam *pause)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *port =  port_priv->ppe_port;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      return phylink_ethtool_set_pauseparam(port->phylink, pause);
-+}
-+
-+static int edma_get_eee(struct net_device *netdev, struct ethtool_keee *eee)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *port =  port_priv->ppe_port;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      return phylink_ethtool_get_eee(port->phylink, eee);
-+}
-+
-+static int edma_set_eee(struct net_device *netdev, struct ethtool_keee *eee)
-+{
-+      struct edma_port_priv *port_priv = (struct edma_port_priv *)netdev_priv(netdev);
-+      struct ppe_port *port =  port_priv->ppe_port;
-+      int ret;
-+
-+      if (!port_priv)
-+              return -EINVAL;
-+
-+      ret = ppe_port_set_mac_eee(port_priv->ppe_port, eee);
-+      if (ret)
-+              return ret;
-+
-+      return phylink_ethtool_set_eee(port->phylink, eee);
-+}
-+
-+static const struct ethtool_ops edma_ethtool_ops = {
-+      .get_strings = &edma_get_strings,
-+      .get_sset_count = &edma_get_strset_count,
-+      .get_ethtool_stats = &edma_get_ethtool_stats,
-+      .get_link = &ethtool_op_get_link,
-+      .get_link_ksettings = edma_get_link_ksettings,
-+      .set_link_ksettings = edma_set_link_ksettings,
-+      .get_pauseparam = &edma_get_pauseparam,
-+      .set_pauseparam = &edma_set_pauseparam,
-+      .get_eee = &edma_get_eee,
-+      .set_eee = &edma_set_eee,
-+};
-+
-+/**
-+ * edma_set_ethtool_ops - Set ethtool operations
-+ * @netdev: Netdevice
-+ *
-+ * Set ethtool operations.
-+ */
-+void edma_set_ethtool_ops(struct net_device *netdev)
-+{
-+      netdev->ethtool_ops = &edma_ethtool_ops;
-+}
---- a/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-@@ -380,6 +380,7 @@ int edma_port_setup(struct ppe_port *por
-       netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
-       netdev->netdev_ops = &edma_port_netdev_ops;
-       netdev->gso_max_segs = GSO_MAX_SEGS;
-+      edma_set_ethtool_ops(netdev);
-       maddr = mac_addr;
-       if (of_get_mac_address(np, maddr))
diff --git a/target/linux/qualcommbe/patches-6.12/0348-net-ethernet-qualcomm-Add-module-parameters-for-driv.patch b/target/linux/qualcommbe/patches-6.12/0348-net-ethernet-qualcomm-Add-module-parameters-for-driv.patch
deleted file mode 100644 (file)
index 65eb3c6..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-From 2ecec7e47e269e05cdd393c34aae51d4866070c6 Mon Sep 17 00:00:00 2001
-From: Pavithra R <quic_pavir@quicinc.com>
-Date: Tue, 11 Jun 2024 00:00:46 +0530
-Subject: [PATCH] net: ethernet: qualcomm: Add module parameters for driver
- tunings
-
-Add module params and corresponding functionality for Tx/Rx
-mitigation timer/packet count, napi budget and tx requeue stop.
-
-Change-Id: I1717559c931bba4f355ee06ab89f289818400ca2
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
----
- drivers/net/ethernet/qualcomm/ppe/edma.c      | 35 +++++++++++++++++++
- .../net/ethernet/qualcomm/ppe/edma_cfg_rx.c   | 29 +++++++++++++--
- .../net/ethernet/qualcomm/ppe/edma_cfg_rx.h   | 21 +++++++++++
- .../net/ethernet/qualcomm/ppe/edma_cfg_tx.c   | 29 +++++++++++++--
- .../net/ethernet/qualcomm/ppe/edma_cfg_tx.h   | 16 +++++++++
- drivers/net/ethernet/qualcomm/ppe/edma_rx.h   |  4 +++
- drivers/net/ethernet/qualcomm/ppe/edma_tx.h   |  4 +++
- 7 files changed, 134 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/edma.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.c
-@@ -38,6 +38,38 @@ static int rx_buff_size;
- module_param(rx_buff_size, int, 0640);
- MODULE_PARM_DESC(rx_buff_size, "Rx Buffer size for Jumbo MRU value (default:0)");
-+int edma_rx_napi_budget = EDMA_RX_NAPI_WORK_DEF;
-+module_param(edma_rx_napi_budget, int, 0444);
-+MODULE_PARM_DESC(edma_rx_napi_budget, "Rx NAPI budget (default:128, min:16, max:512)");
-+
-+int edma_tx_napi_budget = EDMA_TX_NAPI_WORK_DEF;
-+module_param(edma_tx_napi_budget, int, 0444);
-+MODULE_PARM_DESC(edma_tx_napi_budget, "Tx NAPI budget (default:512 for ipq95xx, min:16, max:512)");
-+
-+int edma_rx_mitigation_pkt_cnt = EDMA_RX_MITIGATION_PKT_CNT_DEF;
-+module_param(edma_rx_mitigation_pkt_cnt, int, 0444);
-+MODULE_PARM_DESC(edma_rx_mitigation_pkt_cnt,
-+               "Rx mitigation packet count value (default:16, min:0, max: 256)");
-+
-+s32 edma_rx_mitigation_timer = EDMA_RX_MITIGATION_TIMER_DEF;
-+module_param(edma_rx_mitigation_timer, int, 0444);
-+MODULE_PARM_DESC(edma_dp_rx_mitigation_timer,
-+               "Rx mitigation timer value in microseconds (default:25, min:0, max: 1000)");
-+
-+int edma_tx_mitigation_timer = EDMA_TX_MITIGATION_TIMER_DEF;
-+module_param(edma_tx_mitigation_timer, int, 0444);
-+MODULE_PARM_DESC(edma_tx_mitigation_timer,
-+               "Tx mitigation timer value in microseconds (default:250, min:0, max: 1000)");
-+
-+int edma_tx_mitigation_pkt_cnt = EDMA_TX_MITIGATION_PKT_CNT_DEF;
-+module_param(edma_tx_mitigation_pkt_cnt, int, 0444);
-+MODULE_PARM_DESC(edma_tx_mitigation_pkt_cnt,
-+               "Tx mitigation packet count value (default:16, min:0, max: 256)");
-+
-+static int tx_requeue_stop;
-+module_param(tx_requeue_stop, int, 0640);
-+MODULE_PARM_DESC(tx_requeue_stop, "Disable Tx requeue function (default:0)");
-+
- /* Priority to multi-queue mapping. */
- static u8 edma_pri_map[PPE_QUEUE_INTER_PRI_NUM] = {
-       0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7};
-@@ -828,7 +860,10 @@ int edma_setup(struct ppe_device *ppe_de
-       edma_ctx->hw_info = &ipq9574_hw_info;
-       edma_ctx->ppe_dev = ppe_dev;
-       edma_ctx->rx_buf_size = rx_buff_size;
-+
-       edma_ctx->tx_requeue_stop = false;
-+      if (tx_requeue_stop != 0)
-+              edma_ctx->tx_requeue_stop = true;
-       /* Configure the EDMA common clocks. */
-       ret = edma_clock_init();
---- a/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.c
-@@ -166,6 +166,24 @@ static void edma_cfg_rx_desc_ring_config
-       reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_RING_SIZE(rxdesc_ring->ring_id);
-       regmap_write(regmap, reg, data);
-+      /* Validate mitigation timer value */
-+      if (edma_rx_mitigation_timer < EDMA_RX_MITIGATION_TIMER_MIN ||
-+          edma_rx_mitigation_timer > EDMA_RX_MITIGATION_TIMER_MAX) {
-+              pr_err("Invalid Rx mitigation timer configured:%d for ring:%d. Using the default timer value:%d\n",
-+                     edma_rx_mitigation_timer, rxdesc_ring->ring_id,
-+                      EDMA_RX_MITIGATION_TIMER_DEF);
-+              edma_rx_mitigation_timer = EDMA_RX_MITIGATION_TIMER_DEF;
-+      }
-+
-+      /* Validate mitigation packet count value */
-+      if (edma_rx_mitigation_pkt_cnt < EDMA_RX_MITIGATION_PKT_CNT_MIN ||
-+          edma_rx_mitigation_pkt_cnt > EDMA_RX_MITIGATION_PKT_CNT_MAX) {
-+              pr_err("Invalid Rx mitigation packet count configured:%d for ring:%d. Using the default packet counter value:%d\n",
-+                     edma_rx_mitigation_timer, rxdesc_ring->ring_id,
-+                      EDMA_RX_MITIGATION_PKT_CNT_DEF);
-+              edma_rx_mitigation_pkt_cnt = EDMA_RX_MITIGATION_PKT_CNT_DEF;
-+      }
-+
-       /* Configure the Mitigation timer */
-       data = EDMA_MICROSEC_TO_TIMER_UNIT(EDMA_RX_MITIGATION_TIMER_DEF,
-                                          ppe_dev->clk_rate / MHZ);
-@@ -176,7 +194,7 @@ static void edma_cfg_rx_desc_ring_config
-       regmap_write(regmap, reg, data);
-       /* Configure the Mitigation packet count */
--      data = (EDMA_RX_MITIGATION_PKT_CNT_DEF & EDMA_RXDESC_LOW_THRE_MASK)
-+      data = (edma_rx_mitigation_pkt_cnt & EDMA_RXDESC_LOW_THRE_MASK)
-                       << EDMA_RXDESC_LOW_THRE_SHIFT;
-       pr_debug("EDMA Rx mitigation packet count value: %d\n", data);
-       reg = EDMA_BASE_OFFSET + EDMA_REG_RXDESC_UGT_THRE(rxdesc_ring->ring_id);
-@@ -915,6 +933,13 @@ void edma_cfg_rx_napi_add(void)
-       struct edma_ring_info *rx = hw_info->rx;
-       u32 i;
-+      if (edma_rx_napi_budget < EDMA_RX_NAPI_WORK_MIN ||
-+          edma_rx_napi_budget > EDMA_RX_NAPI_WORK_MAX) {
-+              pr_err("Incorrect Rx NAPI budget: %d, setting to default: %d",
-+                     edma_rx_napi_budget, hw_info->napi_budget_rx);
-+              edma_rx_napi_budget = hw_info->napi_budget_rx;
-+      }
-+
-       for (i = 0; i < rx->num_rings; i++) {
-               struct edma_rxdesc_ring *rxdesc_ring = &edma_ctx->rx_rings[i];
-@@ -923,7 +948,7 @@ void edma_cfg_rx_napi_add(void)
-               rxdesc_ring->napi_added = true;
-       }
--      netdev_dbg(edma_ctx->dummy_dev, "Rx NAPI budget: %d\n", hw_info->napi_budget_rx);
-+      netdev_dbg(edma_ctx->dummy_dev, "Rx NAPI budget: %d\n", edma_rx_napi_budget);
- }
- /**
---- a/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.h
-@@ -5,6 +5,15 @@
- #ifndef __EDMA_CFG_RX__
- #define __EDMA_CFG_RX__
-+/* Rx default NAPI budget */
-+#define EDMA_RX_NAPI_WORK_DEF         128
-+
-+/* RX minimum NAPI budget */
-+#define EDMA_RX_NAPI_WORK_MIN         16
-+
-+/* Rx maximum NAPI budget */
-+#define EDMA_RX_NAPI_WORK_MAX         512
-+
- /* SKB payload size used in page mode */
- #define EDMA_RX_PAGE_MODE_SKB_SIZE    256
-@@ -22,9 +31,21 @@
- /* Rx mitigation timer's default value in microseconds */
- #define EDMA_RX_MITIGATION_TIMER_DEF  25
-+/* Rx mitigation timer's minimum value in microseconds */
-+#define EDMA_RX_MITIGATION_TIMER_MIN  0
-+
-+/* Rx mitigation timer's maximum value in microseconds */
-+#define EDMA_RX_MITIGATION_TIMER_MAX  1000
-+
- /* Rx mitigation packet count's default value */
- #define EDMA_RX_MITIGATION_PKT_CNT_DEF        16
-+/* Rx mitigation packet count's minimum value */
-+#define EDMA_RX_MITIGATION_PKT_CNT_MIN        0
-+
-+/* Rx mitigation packet count's maximum value */
-+#define EDMA_RX_MITIGATION_PKT_CNT_MAX        256
-+
- /* Default bitmap of cores for RPS to ARM cores */
- #define EDMA_RX_DEFAULT_BITMAP        ((1 << EDMA_MAX_CORE) - 1)
---- a/drivers/net/ethernet/qualcomm/ppe/edma_cfg_tx.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_tx.c
-@@ -170,6 +170,24 @@ static void edma_cfg_txcmpl_ring_configu
-       reg = EDMA_BASE_OFFSET + EDMA_REG_TXCMPL_CTRL(txcmpl_ring->id);
-       regmap_write(regmap, reg, EDMA_TXCMPL_RETMODE_OPAQUE);
-+      /* Validate mitigation timer value */
-+      if (edma_tx_mitigation_timer < EDMA_TX_MITIGATION_TIMER_MIN ||
-+          edma_tx_mitigation_timer > EDMA_TX_MITIGATION_TIMER_MAX) {
-+              pr_err("Invalid Tx mitigation timer configured:%d for ring:%d. Using the default timer value:%d\n",
-+                     edma_tx_mitigation_timer, txcmpl_ring->id,
-+                     EDMA_TX_MITIGATION_TIMER_DEF);
-+              edma_tx_mitigation_timer = EDMA_TX_MITIGATION_TIMER_DEF;
-+      }
-+
-+      /* Validate mitigation packet count value */
-+      if (edma_tx_mitigation_pkt_cnt < EDMA_TX_MITIGATION_PKT_CNT_MIN ||
-+          edma_tx_mitigation_pkt_cnt > EDMA_TX_MITIGATION_PKT_CNT_MAX) {
-+              pr_err("Invalid Tx mitigation packet count configured:%d for ring:%d. Using the default packet counter value:%d\n",
-+                     edma_tx_mitigation_timer, txcmpl_ring->id,
-+                     EDMA_TX_MITIGATION_PKT_CNT_DEF);
-+              edma_tx_mitigation_pkt_cnt = EDMA_TX_MITIGATION_PKT_CNT_DEF;
-+      }
-+
-       /* Configure the Mitigation timer. */
-       data = EDMA_MICROSEC_TO_TIMER_UNIT(EDMA_TX_MITIGATION_TIMER_DEF,
-                                          ppe_dev->clk_rate / MHZ);
-@@ -180,7 +198,7 @@ static void edma_cfg_txcmpl_ring_configu
-       regmap_write(regmap, reg, data);
-       /* Configure the Mitigation packet count. */
--      data = (EDMA_TX_MITIGATION_PKT_CNT_DEF & EDMA_TXCMPL_LOW_THRE_MASK)
-+      data = (edma_tx_mitigation_pkt_cnt & EDMA_TXCMPL_LOW_THRE_MASK)
-               << EDMA_TXCMPL_LOW_THRE_SHIFT;
-       pr_debug("EDMA Tx mitigation packet count value: %d\n", data);
-       reg = EDMA_BASE_OFFSET + EDMA_REG_TXCMPL_UGT_THRE(txcmpl_ring->id);
-@@ -634,6 +652,13 @@ void edma_cfg_tx_napi_add(struct net_dev
-       struct edma_txcmpl_ring *txcmpl_ring;
-       u32 i, ring_idx;
-+      if (edma_tx_napi_budget < EDMA_TX_NAPI_WORK_MIN ||
-+          edma_tx_napi_budget > EDMA_TX_NAPI_WORK_MAX) {
-+              pr_err("Incorrect Tx NAPI budget: %d, setting to default: %d",
-+                     edma_tx_napi_budget, hw_info->napi_budget_tx);
-+              edma_tx_napi_budget = hw_info->napi_budget_tx;
-+      }
-+
-       /* Adding tx napi for a interface with each queue. */
-       for_each_possible_cpu(i) {
-               ring_idx = ((port_id - 1) * num_possible_cpus()) + i;
-@@ -644,5 +669,5 @@ void edma_cfg_tx_napi_add(struct net_dev
-               netdev_dbg(netdev, "Napi added for txcmpl ring: %u\n", txcmpl_ring->id);
-       }
--      netdev_dbg(netdev, "Tx NAPI budget: %d\n", hw_info->napi_budget_tx);
-+      netdev_dbg(netdev, "Tx NAPI budget: %d\n", edma_tx_napi_budget);
- }
---- a/drivers/net/ethernet/qualcomm/ppe/edma_cfg_tx.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_tx.h
-@@ -5,12 +5,28 @@
- #ifndef __EDMA_CFG_TX__
- #define __EDMA_CFG_TX__
-+#define EDMA_TX_NAPI_WORK_DEF 512
-+#define EDMA_TX_NAPI_WORK_MIN 16
-+#define EDMA_TX_NAPI_WORK_MAX 512
-+
- /* Tx mitigation timer's default value. */
- #define EDMA_TX_MITIGATION_TIMER_DEF  250
-+/* Tx mitigation timer's minimum value in microseconds */
-+#define EDMA_TX_MITIGATION_TIMER_MIN  0
-+
-+/* Tx mitigation timer's maximum value in microseconds */
-+#define EDMA_TX_MITIGATION_TIMER_MAX  1000
-+
- /* Tx mitigation packet count default value. */
- #define EDMA_TX_MITIGATION_PKT_CNT_DEF        16
-+/* Tx mitigation packet count's minimum value */
-+#define EDMA_TX_MITIGATION_PKT_CNT_MIN        0
-+
-+/* Tx mitigation packet count's maximum value */
-+#define EDMA_TX_MITIGATION_PKT_CNT_MAX        256
-+
- void edma_cfg_tx_rings(void);
- int edma_cfg_tx_rings_alloc(void);
- void edma_cfg_tx_rings_cleanup(void);
---- a/drivers/net/ethernet/qualcomm/ppe/edma_rx.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_rx.h
-@@ -281,6 +281,10 @@ struct edma_rxdesc_ring {
-       struct sk_buff *last;
- };
-+extern int edma_rx_napi_budget;
-+extern int edma_rx_mitigation_timer;
-+extern int edma_rx_mitigation_pkt_cnt;
-+
- irqreturn_t edma_rx_handle_irq(int irq, void *ctx);
- int edma_rx_alloc_buffer(struct edma_rxfill_ring *rxfill_ring, int alloc_count);
- int edma_rx_napi_poll(struct napi_struct *napi, int budget);
---- a/drivers/net/ethernet/qualcomm/ppe/edma_tx.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_tx.h
-@@ -288,6 +288,10 @@ struct edma_txcmpl_ring {
-       bool napi_added;
- };
-+extern int edma_tx_napi_budget;
-+extern int edma_tx_mitigation_timer;
-+extern int edma_tx_mitigation_pkt_cnt;
-+
- enum edma_tx_status edma_tx_ring_xmit(struct net_device *netdev,
-                                     struct sk_buff *skb,
-                              struct edma_txdesc_ring *txdesc_ring,
diff --git a/target/linux/qualcommbe/patches-6.12/0349-net-ethernet-qualcomm-Add-sysctl-for-RPS-bitmap.patch b/target/linux/qualcommbe/patches-6.12/0349-net-ethernet-qualcomm-Add-sysctl-for-RPS-bitmap.patch
deleted file mode 100644 (file)
index c697001..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-From dcac735a715c13a817d65ae371564cf2793330b2 Mon Sep 17 00:00:00 2001
-From: Pavithra R <quic_pavir@quicinc.com>
-Date: Tue, 11 Jun 2024 01:43:22 +0530
-Subject: [PATCH] net: ethernet: qualcomm: Add sysctl for RPS bitmap
-
-Add sysctl to configure RPS bitmap for EDMA receive.
-This bitmap is used to configure the set of ARM cores
-used to receive packets from EDMA.
-
-Change-Id: Ie0e7d5971db93ea1494608a9e79c4abb13ce69b6
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
-Alex G: Use **const** ctl_table argument for .proc_handler
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/ethernet/qualcomm/ppe/edma.c      | 23 ++++++++++++++++
- drivers/net/ethernet/qualcomm/ppe/edma.h      |  2 ++
- .../net/ethernet/qualcomm/ppe/edma_cfg_rx.c   | 27 +++++++++++++++++++
- .../net/ethernet/qualcomm/ppe/edma_cfg_rx.h   |  6 ++++-
- 4 files changed, 57 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/edma.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.c
-@@ -797,6 +797,11 @@ void edma_destroy(struct ppe_device *ppe
-       struct edma_ring_info *rx = hw_info->rx;
-       u32 i;
-+      if (edma_ctx->rx_rps_ctl_table_hdr) {
-+              unregister_sysctl_table(edma_ctx->rx_rps_ctl_table_hdr);
-+              edma_ctx->rx_rps_ctl_table_hdr = NULL;
-+      }
-+
-       /* Disable interrupts. */
-       for (i = 1; i <= hw_info->max_ports; i++)
-               edma_cfg_tx_disable_interrupts(i);
-@@ -840,6 +845,17 @@ void edma_destroy(struct ppe_device *ppe
-       kfree(edma_ctx->netdev_arr);
- }
-+/* EDMA Rx RPS core sysctl table */
-+static struct ctl_table edma_rx_rps_core_table[] = {
-+      {
-+              .procname       =       "rps_bitmap_cores",
-+              .data           =       &edma_cfg_rx_rps_bitmap_cores,
-+              .maxlen         =       sizeof(int),
-+              .mode           =       0644,
-+              .proc_handler   =       edma_cfg_rx_rps_bitmap
-+      },
-+};
-+
- /**
-  * edma_setup - EDMA Setup.
-  * @ppe_dev: PPE device
-@@ -865,6 +881,13 @@ int edma_setup(struct ppe_device *ppe_de
-       if (tx_requeue_stop != 0)
-               edma_ctx->tx_requeue_stop = true;
-+      edma_ctx->rx_rps_ctl_table_hdr = register_sysctl("net/edma",
-+                                                       edma_rx_rps_core_table);
-+      if (!edma_ctx->rx_rps_ctl_table_hdr) {
-+              pr_err("Rx rps sysctl table configuration failed\n");
-+              return -EINVAL;
-+      }
-+
-       /* Configure the EDMA common clocks. */
-       ret = edma_clock_init();
-       if (ret) {
---- a/drivers/net/ethernet/qualcomm/ppe/edma.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma.h
-@@ -132,6 +132,7 @@ struct edma_intr_info {
-  * @tx_rings: Tx Descriptor Ring, SW is producer
-  * @txcmpl_rings: Tx complete Ring, SW is consumer
-  * @err_stats: Per CPU error statistics
-+ * @rx_rps_ctl_table_hdr: Rx RPS sysctl table
-  * @rx_page_mode: Page mode enabled or disabled
-  * @rx_buf_size: Rx buffer size for Jumbo MRU
-  * @tx_requeue_stop: Tx requeue stop enabled or disabled
-@@ -147,6 +148,7 @@ struct edma_context {
-       struct edma_txdesc_ring *tx_rings;
-       struct edma_txcmpl_ring *txcmpl_rings;
-       struct edma_err_stats __percpu *err_stats;
-+      struct ctl_table_header *rx_rps_ctl_table_hdr;
-       u32 rx_page_mode;
-       u32 rx_buf_size;
-       bool tx_requeue_stop;
---- a/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.c
-@@ -43,6 +43,8 @@ static u32 edma_rx_ring_queue_map[][EDMA
-                                               { 6, 14, 22, 30 },
-                                               { 7, 15, 23, 31 }};
-+u32 edma_cfg_rx_rps_bitmap_cores = EDMA_RX_DEFAULT_BITMAP;
-+
- static int edma_cfg_rx_desc_rings_reset_queue_mapping(void)
- {
-       struct edma_hw_info *hw_info = edma_ctx->hw_info;
-@@ -987,3 +989,28 @@ int edma_cfg_rx_rps_hash_map(void)
-       return 0;
- }
-+
-+/* Configure RPS hash mapping based on bitmap */
-+int edma_cfg_rx_rps_bitmap(const struct ctl_table *table, int write,
-+                         void *buffer, size_t *lenp, loff_t *ppos)
-+{
-+      int ret;
-+
-+      ret = proc_dointvec(table, write, buffer, lenp, ppos);
-+
-+      if (!write)
-+              return ret;
-+
-+      if (!edma_cfg_rx_rps_bitmap_cores ||
-+          edma_cfg_rx_rps_bitmap_cores > EDMA_RX_DEFAULT_BITMAP) {
-+              pr_warn("Incorrect CPU bitmap: %x. Setting it to default value: %d",
-+                      edma_cfg_rx_rps_bitmap_cores, EDMA_RX_DEFAULT_BITMAP);
-+              edma_cfg_rx_rps_bitmap_cores = EDMA_RX_DEFAULT_BITMAP;
-+      }
-+
-+      ret = edma_cfg_rx_rps_hash_map();
-+
-+      pr_info("EDMA RPS bitmap value: %d\n", edma_cfg_rx_rps_bitmap_cores);
-+
-+      return ret;
-+}
---- a/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.h
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_cfg_rx.h
-@@ -49,6 +49,8 @@
- /* Default bitmap of cores for RPS to ARM cores */
- #define EDMA_RX_DEFAULT_BITMAP        ((1 << EDMA_MAX_CORE) - 1)
-+extern u32 edma_cfg_rx_rps_bitmap_cores;
-+
- int edma_cfg_rx_rings(void);
- int edma_cfg_rx_rings_alloc(void);
- void edma_cfg_rx_ring_mappings(void);
-@@ -64,6 +66,8 @@ void edma_cfg_rx_rings_enable(void);
- void edma_cfg_rx_rings_disable(void);
- void edma_cfg_rx_buff_size_setup(void);
- int edma_cfg_rx_rps_hash_map(void);
--int edma_cfg_rx_rps(struct ctl_table *table, int write,
-+int edma_cfg_rx_rps(const struct ctl_table *table, int write,
-                   void *buffer, size_t *lenp, loff_t *ppos);
-+int edma_cfg_rx_rps_bitmap(const struct ctl_table *table, int write,
-+                         void *buffer, size_t *lenp, loff_t *ppos);
- #endif
diff --git a/target/linux/qualcommbe/patches-6.12/0350-net-ethernet-qualcomm-Add-support-for-label-property.patch b/target/linux/qualcommbe/patches-6.12/0350-net-ethernet-qualcomm-Add-support-for-label-property.patch
deleted file mode 100644 (file)
index 79af169..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From a809433c9b6a418dd886f12a5dcb3376f73bf2a7 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 4 Dec 2024 01:37:05 +0100
-Subject: [PATCH] net: ethernet: qualcomm: Add support for label property for
- EDMA port
-
-Add support for label property for EDMA port. This is useful to define
-custom name in DTS for specific ethernet port instead of assigning a
-dynamic name at runtime.
-
-This also improve the log output by using modern APIs.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/ethernet/qualcomm/ppe/edma_port.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-+++ b/drivers/net/ethernet/qualcomm/ppe/edma_port.c
-@@ -355,13 +355,25 @@ int edma_port_setup(struct ppe_port *por
-       int port_id = port->port_id;
-       struct net_device *netdev;
-       u8 mac_addr[ETH_ALEN];
-+      const char *name;
-+      int assign_type;
-       int ret = 0;
-       u8 *maddr;
--      netdev = alloc_etherdev_mqs(sizeof(struct edma_port_priv),
--                                  EDMA_NETDEV_QUEUE_NUM, EDMA_NETDEV_QUEUE_NUM);
-+      name = of_get_property(np, "label", NULL);
-+      if (name) {
-+              assign_type = NET_NAME_PREDICTABLE;
-+      } else {
-+              name = "eth%d";
-+              assign_type = NET_NAME_ENUM;
-+      }
-+
-+      netdev = alloc_netdev_mqs(sizeof(struct edma_port_priv),
-+                                name, assign_type,
-+                                ether_setup,
-+                                EDMA_NETDEV_QUEUE_NUM, EDMA_NETDEV_QUEUE_NUM);
-       if (!netdev) {
--              pr_err("alloc_etherdev() failed\n");
-+              dev_err(ppe_dev->dev, "alloc_netdev_mqs() failed\n");
-               return -ENOMEM;
-       }
diff --git a/target/linux/qualcommbe/patches-6.12/0351-net-ethernet-qualcomm-ppe-Fix-unmet-dependency-with-.patch b/target/linux/qualcommbe/patches-6.12/0351-net-ethernet-qualcomm-ppe-Fix-unmet-dependency-with-.patch
deleted file mode 100644 (file)
index a0d15cf..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 9c4ad75f17788a64c1e37d0b9e19ca157e01c80a Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 9 Dec 2024 18:19:06 +0100
-Subject: [PATCH] net: ethernet: qualcomm: ppe: Fix unmet dependency with
- QCOM_PPE
-
-Fix unmet dependency with QCOM_PPE on selecting SFP.
-
-WARNING: unmet direct dependencies detected for SFP
-  Depends on [m]: NETDEVICES [=y] && PHYLIB [=y] && I2C [=y] && PHYLINK [=y] && (HWMON [=m] || HWMON [=m]=n [=n])
-  Selected by [y]:
-  - QCOM_PPE [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_QUALCOMM [=y] && HAS_IOMEM [=y] && OF [=y] && COMMON_CLK [=y]
-
-This permit correct compilation of the modules with SFP enabled.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/ethernet/qualcomm/Kconfig | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/Kconfig
-+++ b/drivers/net/ethernet/qualcomm/Kconfig
-@@ -68,7 +68,6 @@ config QCOM_PPE
-       select REGMAP_MMIO
-       select PHYLINK
-       select PCS_QCOM_IPQ_UNIPHY
--      select SFP
-       help
-         This driver supports the Qualcomm Technologies, Inc. packet
-         process engine (PPE) available with IPQ SoC. The PPE includes
diff --git a/target/linux/qualcommbe/patches-6.12/0352-net-ethernet-qualcomm-ppe-select-correct-PCS-depende.patch b/target/linux/qualcommbe/patches-6.12/0352-net-ethernet-qualcomm-ppe-select-correct-PCS-depende.patch
deleted file mode 100644 (file)
index 3893c5c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-From ac41b401d274a4004027fa4000d801cd28c51f4c Mon Sep 17 00:00:00 2001
-From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
-Date: Tue, 13 May 2025 13:41:37 -0500
-Subject: [PATCH] net: ethernet: qualcomm: ppe: select correct PCS dependency
-
-The config symbol for the PCS driver has changed to PCS_QCOM_IPQ9574,
-since the original submission. Update Kconfig accordingly.
-
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/ethernet/qualcomm/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/qualcomm/Kconfig
-+++ b/drivers/net/ethernet/qualcomm/Kconfig
-@@ -67,7 +67,7 @@ config QCOM_PPE
-       depends on COMMON_CLK
-       select REGMAP_MMIO
-       select PHYLINK
--      select PCS_QCOM_IPQ_UNIPHY
-+      select PCS_QCOM_IPQ9574
-       help
-         This driver supports the Qualcomm Technologies, Inc. packet
-         process engine (PPE) available with IPQ SoC. The PPE includes
diff --git a/target/linux/qualcommbe/patches-6.12/0353-arm64-dts-qcom-Add-IPQ9574-PPE-base-device-node.patch b/target/linux/qualcommbe/patches-6.12/0353-arm64-dts-qcom-Add-IPQ9574-PPE-base-device-node.patch
deleted file mode 100644 (file)
index 640a2a9..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-From bbf706ecfd4295d73c8217d5220573dd51d7a081 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Fri, 1 Mar 2024 14:46:45 +0800
-Subject: [PATCH] arm64: dts: qcom: Add IPQ9574 PPE base device node
-
-PPE is the packet process engine on the Qualcomm IPQ platform,
-which is connected with the external switch or PHY device via
-the UNIPHY (PCS).
-
-Change-Id: I254bd48c218aa4eab54f697a2ad149f5a93b682c
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: Add "qcom_ppe" label to PPE node
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 39 +++++++++++++++++++++++++++
- 1 file changed, 39 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -13,6 +13,7 @@
- #include <dt-bindings/interconnect/qcom,ipq9574.h>
- #include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <dt-bindings/reset/qcom,ipq9574-gcc.h>
-+#include <dt-bindings/reset/qcom,ipq9574-nsscc.h>
- #include <dt-bindings/thermal/thermal.h>
- / {
-@@ -1271,6 +1272,44 @@
-                       #interconnect-cells = <1>;
-               };
-+              qcom_ppe: ethernet@3a000000 {
-+                      compatible = "qcom,ipq9574-ppe";
-+                      reg = <0x3a000000 0xbef800>;
-+                      ranges;
-+                      #address-cells = <1>;
-+                      #size-cells = <1>;
-+                      clocks = <&nsscc NSS_CC_PPE_SWITCH_CLK>,
-+                               <&nsscc NSS_CC_PPE_SWITCH_CFG_CLK>,
-+                               <&nsscc NSS_CC_PPE_SWITCH_IPE_CLK>,
-+                               <&nsscc NSS_CC_PPE_SWITCH_BTQ_CLK>;
-+                      clock-names = "ppe",
-+                                    "ppe_cfg",
-+                                    "ppe_ipe",
-+                                    "ppe_btq";
-+                      resets = <&nsscc PPE_FULL_RESET>;
-+                      interconnects = <&nsscc MASTER_NSSNOC_PPE
-+                                       &nsscc SLAVE_NSSNOC_PPE>,
-+                                      <&nsscc MASTER_NSSNOC_PPE_CFG
-+                                       &nsscc SLAVE_NSSNOC_PPE_CFG>,
-+                                      <&gcc MASTER_NSSNOC_QOSGEN_REF
-+                                       &gcc SLAVE_NSSNOC_QOSGEN_REF>,
-+                                      <&gcc MASTER_NSSNOC_TIMEOUT_REF
-+                                       &gcc SLAVE_NSSNOC_TIMEOUT_REF>,
-+                                      <&gcc MASTER_MEM_NOC_NSSNOC
-+                                       &gcc SLAVE_MEM_NOC_NSSNOC>,
-+                                      <&gcc MASTER_NSSNOC_MEMNOC
-+                                       &gcc SLAVE_NSSNOC_MEMNOC>,
-+                                      <&gcc MASTER_NSSNOC_MEM_NOC_1
-+                                       &gcc SLAVE_NSSNOC_MEM_NOC_1>;
-+                      interconnect-names = "ppe",
-+                                           "ppe_cfg",
-+                                           "qos_gen",
-+                                           "timeout_ref",
-+                                           "nssnoc_memnoc",
-+                                           "memnoc_nssnoc",
-+                                           "memnoc_nssnoc_1";
-+              };
-+
-               pcs0: ethernet-pcs@7a00000 {
-                       compatible = "qcom,ipq9574-pcs";
-                       reg = <0x7a00000 0x10000>;
diff --git a/target/linux/qualcommbe/patches-6.12/0354-arm64-dts-qcom-Add-EDMA-node-for-IPQ9574.patch b/target/linux/qualcommbe/patches-6.12/0354-arm64-dts-qcom-Add-EDMA-node-for-IPQ9574.patch
deleted file mode 100644 (file)
index f93ed0c..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-From bd50babc7db2a35d98236a0386173dccd6c6374b Mon Sep 17 00:00:00 2001
-From: Pavithra R <quic_pavir@quicinc.com>
-Date: Wed, 6 Mar 2024 22:29:41 +0530
-Subject: [PATCH] arm64: dts: qcom: Add EDMA node for IPQ9574
-
-Add EDMA (Ethernet DMA) device tree node for IPQ9574 to
-enable ethernet support.
-
-Change-Id: I87d7c50f2485c8670948dce305000337f6499f8b
-Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 68 +++++++++++++++++++++++++++
- 1 file changed, 68 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -1308,6 +1308,74 @@
-                                            "nssnoc_memnoc",
-                                            "memnoc_nssnoc",
-                                            "memnoc_nssnoc_1";
-+
-+                      edma {
-+                              compatible = "qcom,ipq9574-edma";
-+                              clocks = <&nsscc NSS_CC_PPE_EDMA_CLK>,
-+                                       <&nsscc NSS_CC_PPE_EDMA_CFG_CLK>;
-+                              clock-names = "edma",
-+                                            "edma-cfg";
-+                              resets = <&nsscc EDMA_HW_RESET>;
-+                              reset-names = "edma_rst";
-+                              interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 505 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 504 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 502 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 501 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
-+                                           <GIC_SPI 499 IRQ_TYPE_LEVEL_HIGH>;
-+                              interrupt-names = "edma_txcmpl_8",
-+                                                "edma_txcmpl_9",
-+                                                "edma_txcmpl_10",
-+                                                "edma_txcmpl_11",
-+                                                "edma_txcmpl_12",
-+                                                "edma_txcmpl_13",
-+                                                "edma_txcmpl_14",
-+                                                "edma_txcmpl_15",
-+                                                "edma_txcmpl_16",
-+                                                "edma_txcmpl_17",
-+                                                "edma_txcmpl_18",
-+                                                "edma_txcmpl_19",
-+                                                "edma_txcmpl_20",
-+                                                "edma_txcmpl_21",
-+                                                "edma_txcmpl_22",
-+                                                "edma_txcmpl_23",
-+                                                "edma_txcmpl_24",
-+                                                "edma_txcmpl_25",
-+                                                "edma_txcmpl_26",
-+                                                "edma_txcmpl_27",
-+                                                "edma_txcmpl_28",
-+                                                "edma_txcmpl_29",
-+                                                "edma_txcmpl_30",
-+                                                "edma_txcmpl_31",
-+                                                "edma_rxdesc_20",
-+                                                "edma_rxdesc_21",
-+                                                "edma_rxdesc_22",
-+                                                "edma_rxdesc_23",
-+                                                "edma_misc";
-+                      };
-               };
-               pcs0: ethernet-pcs@7a00000 {
diff --git a/target/linux/qualcommbe/patches-6.12/0355-arm64-dts-qcom-Add-IPQ9574-RDP433-port-node.patch b/target/linux/qualcommbe/patches-6.12/0355-arm64-dts-qcom-Add-IPQ9574-RDP433-port-node.patch
deleted file mode 100644 (file)
index 83f0e24..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-From 001b663ecc5f838dac143623badae0e472749d8a Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Tue, 14 May 2024 10:53:27 +0800
-Subject: [PATCH] arm64: dts: qcom: Add IPQ9574 RDP433 port node
-
-There are 6 PPE MAC ports available on RDP433. The port1-port4 are
-connected with QCA8075 QUAD PHYs through UNIPHY0 PCS channel0-channel3.
-The port5 is connected with Aquantia PHY through UNIPHY1 PCS channel0
-and the port6 is connected with Aquantia PHY through UNIPHY2 PCS
-channel0.
-
-Change-Id: Ic16efdef2fe2cff7b1e80245619c0f82afb24cb9
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
----
- arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 167 ++++++++++++++++++++
- 1 file changed, 167 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-@@ -55,6 +55,46 @@
-       status = "okay";
- };
-+&mdio {
-+      reset-gpios = <&tlmm 60 GPIO_ACTIVE_LOW>;
-+      clock-frequency = <6250000>;
-+      status = "okay";
-+
-+      ethernet-phy-package@0 {
-+              compatible = "qcom,qca8075-package";
-+              #address-cells = <1>;
-+              #size-cells = <0>;
-+              reg = <0x10>;
-+              qcom,package-mode = "qsgmii";
-+
-+              phy0: ethernet-phy@10 {
-+                      reg = <0x10>;
-+              };
-+
-+              phy1: ethernet-phy@11 {
-+                      reg = <0x11>;
-+              };
-+
-+              phy2: ethernet-phy@12 {
-+                      reg = <0x12>;
-+              };
-+
-+              phy3: ethernet-phy@13 {
-+                      reg = <0x13>;
-+              };
-+      };
-+
-+      phy4: ethernet-phy@8 {
-+              compatible ="ethernet-phy-ieee802.3-c45";
-+              reg = <8>;
-+      };
-+
-+      phy5: ethernet-phy@0 {
-+              compatible ="ethernet-phy-ieee802.3-c45";
-+              reg = <0>;
-+      };
-+};
-+
- &tlmm {
-       pcie1_default: pcie1-default-state {
-@@ -161,3 +201,130 @@
-               };
-       };
- };
-+
-+&qcom_ppe {
-+      ethernet-ports {
-+              #address-cells = <1>;
-+              #size-cells = <0>;
-+
-+              port@1 {
-+                      reg = <1>;
-+                      phy-mode = "qsgmii";
-+                      managed = "in-band-status";
-+                      phy-handle = <&phy0>;
-+                      pcs-handle = <&pcs0_ch0>;
-+                      clocks = <&nsscc NSS_CC_PORT1_MAC_CLK>,
-+                               <&nsscc NSS_CC_PORT1_RX_CLK>,
-+                               <&nsscc NSS_CC_PORT1_TX_CLK>;
-+                      clock-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+                      resets = <&nsscc PORT1_MAC_ARES>,
-+                               <&nsscc PORT1_RX_ARES>,
-+                               <&nsscc PORT1_TX_ARES>;
-+                      reset-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+              };
-+
-+              port@2 {
-+                      reg = <2>;
-+                      phy-mode = "qsgmii";
-+                      managed = "in-band-status";
-+                      phy-handle = <&phy1>;
-+                      pcs-handle = <&pcs0_ch1>;
-+                      clocks = <&nsscc NSS_CC_PORT2_MAC_CLK>,
-+                               <&nsscc NSS_CC_PORT2_RX_CLK>,
-+                               <&nsscc NSS_CC_PORT2_TX_CLK>;
-+                      clock-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+                      resets = <&nsscc PORT2_MAC_ARES>,
-+                               <&nsscc PORT2_RX_ARES>,
-+                               <&nsscc PORT2_TX_ARES>;
-+                      reset-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+              };
-+
-+              port@3 {
-+                      reg = <3>;
-+                      phy-mode = "qsgmii";
-+                      managed = "in-band-status";
-+                      phy-handle = <&phy2>;
-+                      pcs-handle = <&pcs0_ch2>;
-+                      clocks = <&nsscc NSS_CC_PORT3_MAC_CLK>,
-+                               <&nsscc NSS_CC_PORT3_RX_CLK>,
-+                               <&nsscc NSS_CC_PORT3_TX_CLK>;
-+                      clock-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+                      resets = <&nsscc PORT3_MAC_ARES>,
-+                               <&nsscc PORT3_RX_ARES>,
-+                               <&nsscc PORT3_TX_ARES>;
-+                      reset-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+              };
-+
-+              port@4 {
-+                      reg = <4>;
-+                      phy-mode = "qsgmii";
-+                      managed = "in-band-status";
-+                      phy-handle = <&phy3>;
-+                      pcs-handle = <&pcs0_ch3>;
-+                      clocks = <&nsscc NSS_CC_PORT4_MAC_CLK>,
-+                               <&nsscc NSS_CC_PORT4_RX_CLK>,
-+                               <&nsscc NSS_CC_PORT4_TX_CLK>;
-+                      clock-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+                      resets = <&nsscc PORT4_MAC_ARES>,
-+                               <&nsscc PORT4_RX_ARES>,
-+                               <&nsscc PORT4_TX_ARES>;
-+                      reset-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+              };
-+
-+              port@5 {
-+                      reg = <5>;
-+                      phy-mode = "usxgmii";
-+                      managed = "in-band-status";
-+                      phy-handle = <&phy4>;
-+                      pcs-handle = <&pcs1_ch0>;
-+                      clocks = <&nsscc NSS_CC_PORT5_MAC_CLK>,
-+                               <&nsscc NSS_CC_PORT5_RX_CLK>,
-+                               <&nsscc NSS_CC_PORT5_TX_CLK>;
-+                      clock-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+                      resets = <&nsscc PORT5_MAC_ARES>,
-+                               <&nsscc PORT5_RX_ARES>,
-+                               <&nsscc PORT5_TX_ARES>;
-+                      reset-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+              };
-+
-+              port@6 {
-+                      reg = <6>;
-+                      phy-mode = "usxgmii";
-+                      managed = "in-band-status";
-+                      phy-handle = <&phy5>;
-+                      pcs-handle = <&pcs2_ch0>;
-+                      clocks = <&nsscc NSS_CC_PORT6_MAC_CLK>,
-+                               <&nsscc NSS_CC_PORT6_RX_CLK>,
-+                               <&nsscc NSS_CC_PORT6_TX_CLK>;
-+                      clock-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+                      resets = <&nsscc PORT6_MAC_ARES>,
-+                               <&nsscc PORT6_RX_ARES>,
-+                               <&nsscc PORT6_TX_ARES>;
-+                      reset-names = "mac",
-+                                    "rx",
-+                                    "tx";
-+              };
-+      };
-+};
diff --git a/target/linux/qualcommbe/patches-6.12/0356-arm64-dts-qcom-add-AQR-NVMEM-node-for-IPQ9574-RDP433.patch b/target/linux/qualcommbe/patches-6.12/0356-arm64-dts-qcom-add-AQR-NVMEM-node-for-IPQ9574-RDP433.patch
deleted file mode 100644 (file)
index e508bad..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From 30b751f5984e295f0b5e7a2308b6103fae3322d2 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 9 Dec 2024 18:10:43 +0100
-Subject: [PATCH] arm64: dts: qcom: add AQR NVMEM node for IPQ9574 RDP433 board
-
-Add Aquantia NVMEM node for IPQ9574 RDP433 board to load the firmware
-for the Aquantia PHY.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-@@ -87,11 +87,17 @@
-       phy4: ethernet-phy@8 {
-               compatible ="ethernet-phy-ieee802.3-c45";
-               reg = <8>;
-+
-+              nvmem-cells = <&aqr_fw>;
-+              nvmem-cell-names = "firmware";
-       };
-       phy5: ethernet-phy@0 {
-               compatible ="ethernet-phy-ieee802.3-c45";
-               reg = <0>;
-+
-+              nvmem-cells = <&aqr_fw>;
-+              nvmem-cell-names = "firmware";
-       };
- };
diff --git a/target/linux/qualcommbe/patches-6.12/0357-arm64-dts-qcom-Add-label-to-EDMA-port-for-IPQ9574-RD.patch b/target/linux/qualcommbe/patches-6.12/0357-arm64-dts-qcom-Add-label-to-EDMA-port-for-IPQ9574-RD.patch
deleted file mode 100644 (file)
index 950c9fa..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From b297d12d434191845cf8ae359466dcd8312ed21d Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 4 Dec 2024 01:49:09 +0100
-Subject: [PATCH] arm64: dts: qcom: Add label to EDMA port for IPQ9574 RDP433
-
-Add label to EDMA port for IPQ9574 RDP433 board.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
-@@ -217,6 +217,7 @@
-                       reg = <1>;
-                       phy-mode = "qsgmii";
-                       managed = "in-band-status";
-+                      label = "lan1";
-                       phy-handle = <&phy0>;
-                       pcs-handle = <&pcs0_ch0>;
-                       clocks = <&nsscc NSS_CC_PORT1_MAC_CLK>,
-@@ -237,6 +238,7 @@
-                       reg = <2>;
-                       phy-mode = "qsgmii";
-                       managed = "in-band-status";
-+                      label = "lan2";
-                       phy-handle = <&phy1>;
-                       pcs-handle = <&pcs0_ch1>;
-                       clocks = <&nsscc NSS_CC_PORT2_MAC_CLK>,
-@@ -257,6 +259,7 @@
-                       reg = <3>;
-                       phy-mode = "qsgmii";
-                       managed = "in-band-status";
-+                      label = "lan3";
-                       phy-handle = <&phy2>;
-                       pcs-handle = <&pcs0_ch2>;
-                       clocks = <&nsscc NSS_CC_PORT3_MAC_CLK>,
-@@ -277,6 +280,7 @@
-                       reg = <4>;
-                       phy-mode = "qsgmii";
-                       managed = "in-band-status";
-+                      label = "lan4";
-                       phy-handle = <&phy3>;
-                       pcs-handle = <&pcs0_ch3>;
-                       clocks = <&nsscc NSS_CC_PORT4_MAC_CLK>,
-@@ -297,6 +301,7 @@
-                       reg = <5>;
-                       phy-mode = "usxgmii";
-                       managed = "in-band-status";
-+                      label = "lan5";
-                       phy-handle = <&phy4>;
-                       pcs-handle = <&pcs1_ch0>;
-                       clocks = <&nsscc NSS_CC_PORT5_MAC_CLK>,
-@@ -317,6 +322,7 @@
-                       reg = <6>;
-                       phy-mode = "usxgmii";
-                       managed = "in-band-status";
-+                      label = "wan";
-                       phy-handle = <&phy5>;
-                       pcs-handle = <&pcs2_ch0>;
-                       clocks = <&nsscc NSS_CC_PORT6_MAC_CLK>,
diff --git a/target/linux/qualcommbe/patches-6.12/0358-clk-qcom-nsscc-Attach-required-NSSNOC-clock-to-PM-do.patch b/target/linux/qualcommbe/patches-6.12/0358-clk-qcom-nsscc-Attach-required-NSSNOC-clock-to-PM-do.patch
deleted file mode 100644 (file)
index 372572a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-From 6417cb20e854194a845d4ab092b92fd753c0e405 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 30 Jan 2025 16:11:14 +0100
-Subject: [PATCH] clk: qcom: nsscc: Attach required NSSNOC clock to PM domain
-
-There is currently a problem with ICC clock disabling the NSSNOC clock
-as there isn't any user for them on calling sync_state.
-This cause the kernel to stall if NSS is enabled and reboot with the watchdog.
-
-This is caused by the fact that the NSSNOC clock nsscc, snoc and snoc_1
-are actually required to make the NSS work and make the system continue
-booting.
-
-To attach these clock, setup pm-clk in nsscc and setup the correct
-resume/suspend OPs.
-
-With this change, the clock gets correctly attached and are not disabled
-when ICC call the sync_state.
-
-Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Alex G: Retrieve clocks by name rather than index.
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/clk/qcom/nsscc-ipq9574.c | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
-
---- a/drivers/clk/qcom/nsscc-ipq9574.c
-+++ b/drivers/clk/qcom/nsscc-ipq9574.c
-@@ -3060,6 +3060,7 @@ MODULE_DEVICE_TABLE(of, nss_cc_ipq9574_m
- static int nss_cc_ipq9574_probe(struct platform_device *pdev)
- {
-+      struct device *dev = &pdev->dev;
-       struct regmap *regmap;
-       int ret;
-@@ -3075,6 +3076,18 @@ static int nss_cc_ipq9574_probe(struct p
-       if (ret)
-               return dev_err_probe(&pdev->dev, ret, "Fail to add bus clock\n");
-+      ret = pm_clk_add(&pdev->dev, "nssnoc");
-+      if (ret)
-+              return dev_err_probe(dev, ret,"failed to acquire nssnoc clock\n");
-+
-+      ret = pm_clk_add(&pdev->dev, "snoc");
-+      if (ret)
-+              return dev_err_probe(dev, ret,"failed to acquire snoc clock\n");
-+
-+      ret = pm_clk_add(&pdev->dev, "snoc_1");
-+      if (ret)
-+              return dev_err_probe(dev, ret,"failed to acquire snoc_1 clock\n");
-+
-       ret = pm_runtime_resume_and_get(&pdev->dev);
-       if (ret)
-               return dev_err_probe(&pdev->dev, ret, "Fail to resume\n");
-@@ -3089,8 +3102,16 @@ static int nss_cc_ipq9574_probe(struct p
-       clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
-       ret = qcom_cc_really_probe(&pdev->dev, &nss_cc_ipq9574_desc, regmap);
-+      if (ret)
-+              goto err_put_pm;
-+
-       pm_runtime_put(&pdev->dev);
-+      return 0;
-+
-+err_put_pm:
-+      pm_runtime_put_sync(dev);
-+
-       return ret;
- }
diff --git a/target/linux/qualcommbe/patches-6.12/0359-arm64-dts-qcom-ipq9574-add-NSSNOC-clock-to-nss-node.patch b/target/linux/qualcommbe/patches-6.12/0359-arm64-dts-qcom-ipq9574-add-NSSNOC-clock-to-nss-node.patch
deleted file mode 100644 (file)
index c32f077..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From 372bbae100ffe14908bfd8448143c6cdbea17e8d Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 30 Jan 2025 16:23:03 +0100
-Subject: [PATCH] arm64: dts: qcom: ipq9574: add NSSNOC clock to nss node
-
-Add NSSNOC clock to nss node to attach the clock with PM clock and fix
-the boot stall after ICC sync_state.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Alex G: Do not remove GCC_NSSCC_CLK ("bus") clock
-        Add clock-names for the new clocks
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -1255,7 +1255,10 @@
-                                <&pcs1 1>,
-                                <&pcs2 0>,
-                                <&pcs2 1>,
--                               <&gcc GCC_NSSCC_CLK>;
-+                               <&gcc GCC_NSSCC_CLK>,
-+                               <&gcc GCC_NSSNOC_NSSCC_CLK>,
-+                               <&gcc GCC_NSSNOC_SNOC_CLK>,
-+                               <&gcc GCC_NSSNOC_SNOC_1_CLK>;
-                       clock-names = "xo",
-                                     "nss_1200",
-                                     "ppe_353",
-@@ -1266,7 +1269,10 @@
-                                     "uniphy1_tx",
-                                     "uniphy2_rx",
-                                     "uniphy2_tx",
--                                    "bus";
-+                                    "bus",
-+                                    "nssnoc",
-+                                    "snoc",
-+                                    "snoc_1";
-                       #clock-cells = <1>;
-                       #reset-cells = <1>;
-                       #interconnect-cells = <1>;
diff --git a/target/linux/qualcommbe/patches-6.12/0360-clk-qcom-nsscc-ipq9574-fix-port5-clock-config.patch b/target/linux/qualcommbe/patches-6.12/0360-clk-qcom-nsscc-ipq9574-fix-port5-clock-config.patch
deleted file mode 100644 (file)
index 725079c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From fa691ff57c72a8f0bfeff1a9e86ae2d78765b0da Mon Sep 17 00:00:00 2001
-From: Mantas Pucka <mantas@8devices.com>
-Date: Mon, 31 Mar 2025 15:39:59 +0300
-Subject: [PATCH] clk: qcom: nsscc-ipq9574: fix port5 clock config
-
-Currently there is no configuration to derive 25/125MHz port5 clock
-from uniphy1 running at 125MHz. This is needed for SGMII mode when
-port5 is using uniphy1.
-
-Fix this by adding option such clock config option.
-
-Signed-off-by: Mantas Pucka <mantas@8devices.com>
----
- drivers/clk/qcom/nsscc-ipq9574.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/clk/qcom/nsscc-ipq9574.c
-+++ b/drivers/clk/qcom/nsscc-ipq9574.c
-@@ -383,11 +383,13 @@ static const struct freq_multi_tbl ftbl_
- static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_25[] = {
-       C(P_UNIPHY1_NSS_RX_CLK, 12.5, 0, 0),
-+      C(P_UNIPHY1_NSS_RX_CLK, 5, 0, 0),
-       C(P_UNIPHY0_NSS_RX_CLK, 5, 0, 0),
- };
- static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_125[] = {
-       C(P_UNIPHY1_NSS_RX_CLK, 2.5, 0, 0),
-+      C(P_UNIPHY1_NSS_RX_CLK, 1, 0, 0),
-       C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0),
- };
-@@ -408,11 +410,13 @@ static const struct freq_multi_tbl ftbl_
- static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_25[] = {
-       C(P_UNIPHY1_NSS_TX_CLK, 12.5, 0, 0),
-+      C(P_UNIPHY1_NSS_TX_CLK, 5, 0, 0),
-       C(P_UNIPHY0_NSS_TX_CLK, 5, 0, 0),
- };
- static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_125[] = {
-       C(P_UNIPHY1_NSS_TX_CLK, 2.5, 0, 0),
-+      C(P_UNIPHY1_NSS_TX_CLK, 1, 0, 0),
-       C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0),
- };
diff --git a/target/linux/qualcommbe/patches-6.12/0361-net-pcs-Add-10GBASER-interface-mode-support-to-IPQ-U.patch b/target/linux/qualcommbe/patches-6.12/0361-net-pcs-Add-10GBASER-interface-mode-support-to-IPQ-U.patch
deleted file mode 100644 (file)
index 5bdf3e9..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-From 432c2a2da1e0f4a8e2c0fea191361832a7f90f36 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Wed, 6 Mar 2024 17:40:52 +0800
-Subject: [PATCH] net: pcs: Add 10GBASER interface mode support to IPQ UNIPHY
- PCS driver
-
-10GBASER mode is used when PCS connects with a 10G SFP module.
-
-Change-Id: Ifc3c3bb23811807a9b34e88771aab2c830c2327c
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
-Alex G: Use regmap to read/write registers
-        Remove xpcs_reset deassert logic (to be implemented later)
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 47 ++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -55,6 +55,9 @@
-                                        FIELD_PREP(GENMASK(9, 2), \
-                                        FIELD_GET(XPCS_INDIRECT_ADDR_L, reg)))
-+#define XPCS_KR_STS                   0x30020
-+#define XPCS_KR_LINK_STS              BIT(12)
-+
- #define XPCS_DIG_CTRL                 0x38000
- #define XPCS_USXG_ADPT_RESET          BIT(10)
- #define XPCS_USXG_EN                  BIT(9)
-@@ -196,6 +199,28 @@ static void ipq_pcs_get_state_usxgmii(st
-       state->duplex = DUPLEX_FULL;
- }
-+static void ipq_pcs_get_state_10gbaser(struct ipq_pcs *qpcs,
-+                                     struct phylink_link_state *state)
-+{
-+      unsigned int val;
-+      int ret;
-+
-+      ret = regmap_read(qpcs->regmap, XPCS_KR_STS, &val);
-+      if (ret) {
-+              state->link = 0;
-+              return;
-+      }
-+
-+      state->link = !!(val & XPCS_KR_LINK_STS);
-+
-+      if (!state->link)
-+              return;
-+
-+      state->speed = SPEED_10000;
-+      state->duplex = DUPLEX_FULL;
-+      state->pause |= MLO_PAUSE_TXRX_MASK;
-+}
-+
- static int ipq_pcs_config_mode(struct ipq_pcs *qpcs,
-                              phy_interface_t interface)
- {
-@@ -212,6 +237,7 @@ static int ipq_pcs_config_mode(struct ip
-               val = PCS_MODE_QSGMII;
-               break;
-       case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10GBASER:
-               val = PCS_MODE_XPCS;
-               rate = 312500000;
-               break;
-@@ -311,6 +337,15 @@ static int ipq_pcs_config_usxgmii(struct
-       return regmap_set_bits(qpcs->regmap, XPCS_MII_CTRL, XPCS_MII_AN_EN);
- }
-+static int ipq_pcs_config_10gbaser(struct ipq_pcs *qpcs)
-+{
-+      /* Configure 10GBASER mode if required */
-+      if (qpcs->interface == PHY_INTERFACE_MODE_10GBASER)
-+              return 0;
-+
-+      return ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_10GBASER);
-+}
-+
- static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs,
-                                       int index,
-                                       unsigned int neg_mode,
-@@ -399,6 +434,7 @@ static int ipq_pcs_validate(struct phyli
-       switch (state->interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_10GBASER:
-               return 0;
-       case PHY_INTERFACE_MODE_USXGMII:
-               /* USXGMII only supports full duplex mode */
-@@ -418,6 +454,8 @@ static unsigned int ipq_pcs_inband_caps(
-       case PHY_INTERFACE_MODE_QSGMII:
-       case PHY_INTERFACE_MODE_USXGMII:
-               return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-+      case PHY_INTERFACE_MODE_10GBASER:
-+              return LINK_INBAND_DISABLE;
-       default:
-               return 0;
-       }
-@@ -472,6 +510,9 @@ static void ipq_pcs_get_state(struct phy
-       case PHY_INTERFACE_MODE_USXGMII:
-               ipq_pcs_get_state_usxgmii(qpcs, state);
-               break;
-+      case PHY_INTERFACE_MODE_10GBASER:
-+              ipq_pcs_get_state_10gbaser(qpcs, state);
-+              break;
-       default:
-               break;
-       }
-@@ -500,6 +541,8 @@ static int ipq_pcs_config(struct phylink
-               return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
-       case PHY_INTERFACE_MODE_USXGMII:
-               return ipq_pcs_config_usxgmii(qpcs);
-+      case PHY_INTERFACE_MODE_10GBASER:
-+              return ipq_pcs_config_10gbaser(qpcs);
-       default:
-               return -EOPNOTSUPP;
-       };
-@@ -524,6 +567,9 @@ static void ipq_pcs_link_up(struct phyli
-       case PHY_INTERFACE_MODE_USXGMII:
-               ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed);
-               break;
-+      case PHY_INTERFACE_MODE_10GBASER:
-+              /* Nothing to do here */
-+              return;
-       default:
-               return;
-       }
-@@ -603,6 +649,7 @@ static unsigned long ipq_pcs_clk_rate_ge
- {
-       switch (qpcs->interface) {
-       case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10GBASER:
-               return 312500000;
-       default:
-               return 125000000;
diff --git a/target/linux/qualcommbe/patches-6.12/0362-net-pcs-Add-2500BASEX-interface-mode-support-to-IPQ-.patch b/target/linux/qualcommbe/patches-6.12/0362-net-pcs-Add-2500BASEX-interface-mode-support-to-IPQ-.patch
deleted file mode 100644 (file)
index fbdebec..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-From 0d3a93e3a5544daec59d8f10ac5ccab39849536e Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Tue, 2 Apr 2024 18:28:42 +0800
-Subject: [PATCH] net: pcs: Add 2500BASEX interface mode support to IPQ UNIPHY
- PCS driver
-
-2500BASEX mode is used when PCS connects with QCA8386 switch in a fixed
-2500M link. It is also used when PCS connectes with QCA8081 PHY which
-works at 2500M link speed. In addition, it can be also used when PCS
-connects with a 2.5G SFP module.
-
-Change-Id: I3fe61113c1b3685debc20659736a9488216a029d
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
-Alex G: use regmap to read/write registers
-        's/ipq_unipcs/ipq_pcs/' in function names as suggested by Luo Jie
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 67 ++++++++++++++++++++++++++++++
- 1 file changed, 67 insertions(+)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -26,6 +26,7 @@
- #define PCS_MODE_SEL_MASK             GENMASK(12, 8)
- #define PCS_MODE_SGMII                        FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
- #define PCS_MODE_QSGMII                       FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
-+#define PCS_MODE_2500BASEX            FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
- #define PCS_MODE_XPCS                 FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
- #define PCS_MII_CTRL(x)                       (0x480 + 0x18 * (x))
-@@ -155,6 +156,29 @@ static void ipq_pcs_get_state_sgmii(stru
-               state->duplex = DUPLEX_HALF;
- }
-+static void ipq_pcs_get_state_2500basex(struct ipq_pcs *qpcs,
-+                                      struct phylink_link_state *state)
-+{
-+      unsigned int val;
-+      int ret;
-+
-+      ret = regmap_read(qpcs->regmap, PCS_MII_STS(0), &val);
-+      if (ret) {
-+              state->link = 0;
-+              return;
-+      }
-+
-+
-+      state->link = !!(val & PCS_MII_LINK_STS);
-+
-+      if (!state->link)
-+              return;
-+
-+      state->speed = SPEED_2500;
-+      state->duplex = DUPLEX_FULL;
-+      state->pause |= MLO_PAUSE_TXRX_MASK;
-+}
-+
- static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs,
-                                     struct phylink_link_state *state)
- {
-@@ -236,6 +260,10 @@ static int ipq_pcs_config_mode(struct ip
-       case PHY_INTERFACE_MODE_QSGMII:
-               val = PCS_MODE_QSGMII;
-               break;
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              val = PCS_MODE_2500BASEX;
-+              rate = 312500000;
-+              break;
-       case PHY_INTERFACE_MODE_USXGMII:
-       case PHY_INTERFACE_MODE_10GBASER:
-               val = PCS_MODE_XPCS;
-@@ -314,6 +342,15 @@ static int ipq_pcs_config_sgmii(struct i
-                              PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
- }
-+static int ipq_pcs_config_2500basex(struct ipq_pcs *qpcs)
-+{
-+      /* Configure PCS for 2500BASEX mode if required */
-+      if (qpcs->interface == PHY_INTERFACE_MODE_2500BASEX)
-+              return 0;
-+
-+      return ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_2500BASEX);
-+}
-+
- static int ipq_pcs_config_usxgmii(struct ipq_pcs *qpcs)
- {
-       int ret;
-@@ -388,6 +425,22 @@ static int ipq_pcs_link_up_config_sgmii(
-                              PCS_MII_CTRL(index), PCS_MII_ADPT_RESET);
- }
-+static int ipq_pcs_link_up_config_2500basex(struct ipq_pcs *qpcs, int speed)
-+{
-+      int ret;
-+
-+      /* 2500BASEX does not support autoneg and does not need to
-+       * configure PCS speed. Only reset PCS adapter here.
-+       */
-+      ret = regmap_clear_bits(qpcs->regmap,
-+                              PCS_MII_CTRL(0), PCS_MII_ADPT_RESET);
-+      if (ret)
-+              return ret;
-+
-+      return regmap_set_bits(qpcs->regmap,
-+                             PCS_MII_CTRL(0), PCS_MII_ADPT_RESET);
-+}
-+
- static int ipq_pcs_link_up_config_usxgmii(struct ipq_pcs *qpcs, int speed)
- {
-       unsigned int val;
-@@ -436,6 +489,10 @@ static int ipq_pcs_validate(struct phyli
-       case PHY_INTERFACE_MODE_QSGMII:
-       case PHY_INTERFACE_MODE_10GBASER:
-               return 0;
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              /* In-band autoneg is not supported for 2500BASEX */
-+              phylink_clear(supported, Autoneg);
-+              return 0;
-       case PHY_INTERFACE_MODE_USXGMII:
-               /* USXGMII only supports full duplex mode */
-               phylink_clear(supported, 100baseT_Half);
-@@ -454,6 +511,7 @@ static unsigned int ipq_pcs_inband_caps(
-       case PHY_INTERFACE_MODE_QSGMII:
-       case PHY_INTERFACE_MODE_USXGMII:
-               return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-+      case PHY_INTERFACE_MODE_2500BASEX:
-       case PHY_INTERFACE_MODE_10GBASER:
-               return LINK_INBAND_DISABLE;
-       default:
-@@ -507,6 +565,9 @@ static void ipq_pcs_get_state(struct phy
-       case PHY_INTERFACE_MODE_QSGMII:
-               ipq_pcs_get_state_sgmii(qpcs, index, state);
-               break;
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              ipq_pcs_get_state_2500basex(qpcs, state);
-+              break;
-       case PHY_INTERFACE_MODE_USXGMII:
-               ipq_pcs_get_state_usxgmii(qpcs, state);
-               break;
-@@ -539,6 +600,8 @@ static int ipq_pcs_config(struct phylink
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-               return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              return ipq_pcs_config_2500basex(qpcs);
-       case PHY_INTERFACE_MODE_USXGMII:
-               return ipq_pcs_config_usxgmii(qpcs);
-       case PHY_INTERFACE_MODE_10GBASER:
-@@ -564,6 +627,9 @@ static void ipq_pcs_link_up(struct phyli
-               ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
-                                                  neg_mode, speed);
-               break;
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              ret = ipq_pcs_link_up_config_2500basex(qpcs, speed);
-+              break;
-       case PHY_INTERFACE_MODE_USXGMII:
-               ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed);
-               break;
-@@ -648,6 +714,7 @@ static int ipq_pcs_create_miis(struct ip
- static unsigned long ipq_pcs_clk_rate_get(struct ipq_pcs *qpcs)
- {
-       switch (qpcs->interface) {
-+      case PHY_INTERFACE_MODE_2500BASEX:
-       case PHY_INTERFACE_MODE_USXGMII:
-       case PHY_INTERFACE_MODE_10GBASER:
-               return 312500000;
diff --git a/target/linux/qualcommbe/patches-6.12/0363-net-pcs-Add-1000BASEX-interface-mode-support-to-IPQ-.patch b/target/linux/qualcommbe/patches-6.12/0363-net-pcs-Add-1000BASEX-interface-mode-support-to-IPQ-.patch
deleted file mode 100644 (file)
index 37aa60d..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-From d82953614a4f09dd7479e1d3904351ff85d1d088 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Tue, 9 Apr 2024 01:07:22 +0800
-Subject: [PATCH] net: pcs: Add 1000BASEX interface mode support to IPQ UNIPHY
- PCS driver
-
-1000BASEX is used when PCS connects with a 1G SFP module.
-
-Change-Id: Ied7298de3c1ecba74e6457a07fdd6b3ceab79728
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 21 ++++++++++++++++++---
- 1 file changed, 18 insertions(+), 3 deletions(-)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -28,6 +28,9 @@
- #define PCS_MODE_QSGMII                       FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
- #define PCS_MODE_2500BASEX            FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
- #define PCS_MODE_XPCS                 FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
-+#define PCS_MODE_SGMII_MODE_MASK      GENMASK(6, 4)
-+#define PCS_MODE_SGMII_MODE_1000BASEX FIELD_PREP(PCS_MODE_SGMII_MODE_MASK, \
-+                                                 0x0)
- #define PCS_MII_CTRL(x)                       (0x480 + 0x18 * (x))
- #define PCS_MII_ADPT_RESET            BIT(11)
-@@ -249,10 +252,11 @@ static int ipq_pcs_config_mode(struct ip
-                              phy_interface_t interface)
- {
-       unsigned long rate = 125000000;
--      unsigned int val;
-+      unsigned int val, mask;
-       int ret;
-       /* Configure PCS interface mode */
-+      mask = PCS_MODE_SEL_MASK;
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-               val = PCS_MODE_SGMII;
-@@ -260,6 +264,10 @@ static int ipq_pcs_config_mode(struct ip
-       case PHY_INTERFACE_MODE_QSGMII:
-               val = PCS_MODE_QSGMII;
-               break;
-+      case PHY_INTERFACE_MODE_1000BASEX:
-+              mask |= PCS_MODE_SGMII_MODE_MASK;
-+              val = PCS_MODE_SGMII | PCS_MODE_SGMII_MODE_1000BASEX;
-+              break;
-       case PHY_INTERFACE_MODE_2500BASEX:
-               val = PCS_MODE_2500BASEX;
-               rate = 312500000;
-@@ -273,8 +281,7 @@ static int ipq_pcs_config_mode(struct ip
-               return -EOPNOTSUPP;
-       }
--      ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL,
--                               PCS_MODE_SEL_MASK, val);
-+      ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL, mask, val);
-       if (ret)
-               return ret;
-@@ -487,6 +494,7 @@ static int ipq_pcs_validate(struct phyli
-       switch (state->interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_1000BASEX:
-       case PHY_INTERFACE_MODE_10GBASER:
-               return 0;
-       case PHY_INTERFACE_MODE_2500BASEX:
-@@ -509,6 +517,7 @@ static unsigned int ipq_pcs_inband_caps(
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_1000BASEX:
-       case PHY_INTERFACE_MODE_USXGMII:
-               return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-       case PHY_INTERFACE_MODE_2500BASEX:
-@@ -563,6 +572,10 @@ static void ipq_pcs_get_state(struct phy
-       switch (state->interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_1000BASEX:
-+              /* SGMII and 1000BASEX in-band autoneg word format are decoded
-+               * by PCS hardware and both placed to the same status register.
-+               */
-               ipq_pcs_get_state_sgmii(qpcs, index, state);
-               break;
-       case PHY_INTERFACE_MODE_2500BASEX:
-@@ -599,6 +612,7 @@ static int ipq_pcs_config(struct phylink
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_1000BASEX:
-               return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
-       case PHY_INTERFACE_MODE_2500BASEX:
-               return ipq_pcs_config_2500basex(qpcs);
-@@ -624,6 +638,7 @@ static void ipq_pcs_link_up(struct phyli
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_1000BASEX:
-               ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
-                                                  neg_mode, speed);
-               break;
diff --git a/target/linux/qualcommbe/patches-6.12/0364-net-pcs-Add-10G_QXGMII-interface-mode-support-to-IPQ.patch b/target/linux/qualcommbe/patches-6.12/0364-net-pcs-Add-10G_QXGMII-interface-mode-support-to-IPQ.patch
deleted file mode 100644 (file)
index 2563ac8..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-From fc26c6f6c69149ce87c88d6878ae929b2a138063 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Mon, 15 Apr 2024 11:06:02 +0800
-Subject: [PATCH] net: pcs: Add 10G_QXGMII interface mode support to IPQ UNIPHY
- PCS driver
-
-10G_QXGMII is used when PCS connectes with QCA8084 four ports
-2.5G PHYs.
-
-Change-Id: If3dc92a07ac3e51f7c9473fb05fa0668617916fb
-Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 109 +++++++++++++++++++++++------
- 1 file changed, 87 insertions(+), 22 deletions(-)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -48,6 +48,9 @@
- #define PCS_MII_STS_SPEED_100         1
- #define PCS_MII_STS_SPEED_1000                2
-+#define PCS_QP_USXG_OPTION            0x584
-+#define PCS_QP_USXG_GMII_SRC_XPCS     BIT(0)
-+
- #define PCS_PLL_RESET                 0x780
- #define PCS_ANA_SW_RESET              BIT(6)
-@@ -63,10 +66,23 @@
- #define XPCS_KR_LINK_STS              BIT(12)
- #define XPCS_DIG_CTRL                 0x38000
-+#define XPCS_SOFT_RESET                       BIT(15)
- #define XPCS_USXG_ADPT_RESET          BIT(10)
- #define XPCS_USXG_EN                  BIT(9)
-+#define XPCS_KR_CTRL                  0x38007
-+#define XPCS_USXG_MODE_MASK           GENMASK(12, 10)
-+#define XPCS_10G_QXGMII_MODE          FIELD_PREP(XPCS_USXG_MODE_MASK, 0x5)
-+
-+#define XPCS_DIG_STS                  0x3800a
-+#define XPCS_DIG_STS_AM_COUNT         GENMASK(14, 0)
-+
-+/* DIG control for MII1 - MII3 */
-+#define XPCS_MII1_DIG_CTRL(x)         (0x1a8000 + 0x10000 * ((x) - 1))
-+#define XPCS_MII1_USXG_ADPT_RESET     BIT(5)
-+
- #define XPCS_MII_CTRL                 0x1f0000
-+#define XPCS_MII1_CTRL(x)             (0x1a0000 + 0x10000 * ((x) - 1))
- #define XPCS_MII_AN_EN                        BIT(12)
- #define XPCS_DUPLEX_FULL              BIT(8)
- #define XPCS_SPEED_MASK                       (BIT(13) | BIT(6) | BIT(5))
-@@ -78,9 +94,11 @@
- #define XPCS_SPEED_10                 0
- #define XPCS_MII_AN_CTRL              0x1f8001
-+#define XPCS_MII1_AN_CTRL(x)          (0x1a8001 + 0x10000 * ((x) - 1))
- #define XPCS_MII_AN_8BIT              BIT(8)
- #define XPCS_MII_AN_INTR_STS          0x1f8002
-+#define XPCS_MII1_AN_INTR_STS(x)      (0x1a8002 + 0x10000 * ((x) - 1))
- #define XPCS_USXG_AN_LINK_STS         BIT(14)
- #define XPCS_USXG_AN_SPEED_MASK               GENMASK(12, 10)
- #define XPCS_USXG_AN_SPEED_10         0
-@@ -90,6 +108,10 @@
- #define XPCS_USXG_AN_SPEED_5000               5
- #define XPCS_USXG_AN_SPEED_10000      3
-+#define XPCS_XAUI_MODE_CTRL           0x1f8004
-+#define XPCS_MII1_XAUI_MODE_CTRL(x)   (0x1a8004 + 0x10000 * ((x) - 1))
-+#define XPCS_TX_IPG_CHECK_DIS         BIT(0)
-+
- /* Per PCS MII private data */
- struct ipq_pcs_mii {
-       struct ipq_pcs *qpcs;
-@@ -182,13 +204,14 @@ static void ipq_pcs_get_state_2500basex(
-       state->pause |= MLO_PAUSE_TXRX_MASK;
- }
--static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs,
-+static void ipq_pcs_get_state_usxgmii(struct ipq_pcs *qpcs, int index,
-                                     struct phylink_link_state *state)
- {
--      unsigned int val;
-+      unsigned int reg, val;
-       int ret;
--      ret = regmap_read(qpcs->regmap, XPCS_MII_AN_INTR_STS, &val);
-+      reg = (index == 0) ? XPCS_MII_AN_INTR_STS : XPCS_MII1_AN_INTR_STS(index);
-+      ret = regmap_read(qpcs->regmap, reg, &val);
-       if (ret) {
-               state->link = 0;
-               return;
-@@ -273,6 +296,7 @@ static int ipq_pcs_config_mode(struct ip
-               rate = 312500000;
-               break;
-       case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-       case PHY_INTERFACE_MODE_10GBASER:
-               val = PCS_MODE_XPCS;
-               rate = 312500000;
-@@ -285,6 +309,13 @@ static int ipq_pcs_config_mode(struct ip
-       if (ret)
-               return ret;
-+      if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
-+              ret = regmap_set_bits(qpcs->regmap, PCS_QP_USXG_OPTION,
-+                                    PCS_QP_USXG_GMII_SRC_XPCS);
-+              if (ret)
-+                      return ret;
-+      }
-+
-       /* PCS PLL reset */
-       ret = regmap_clear_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
-       if (ret)
-@@ -358,27 +389,51 @@ static int ipq_pcs_config_2500basex(stru
-       return ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_2500BASEX);
- }
--static int ipq_pcs_config_usxgmii(struct ipq_pcs *qpcs)
-+static int ipq_pcs_config_usxgmii(struct ipq_pcs *qpcs,
-+                                int index,
-+                                phy_interface_t interface)
- {
-+      unsigned int reg;
-       int ret;
-       /* Configure the XPCS for USXGMII mode if required */
--      if (qpcs->interface == PHY_INTERFACE_MODE_USXGMII)
--              return 0;
--
--      ret = ipq_pcs_config_mode(qpcs, PHY_INTERFACE_MODE_USXGMII);
--      if (ret)
--              return ret;
-+      if (qpcs->interface != interface) {
-+              ret = ipq_pcs_config_mode(qpcs, interface);
-+              if (ret)
-+                      return ret;
--      ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_USXG_EN);
--      if (ret)
--              return ret;
-+              if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
-+                      ret = regmap_update_bits(qpcs->regmap, XPCS_KR_CTRL,
-+                                               XPCS_USXG_MODE_MASK, XPCS_10G_QXGMII_MODE);
-+                      if (ret)
-+                              return ret;
-+
-+                      /* Set Alignment Marker Interval value as 0x6018 */
-+                      ret = regmap_update_bits(qpcs->regmap, XPCS_DIG_STS,
-+                                               XPCS_DIG_STS_AM_COUNT, 0x6018);
-+                      if (ret)
-+                              return ret;
-+
-+                      ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_SOFT_RESET);
-+                      if (ret)
-+                              return ret;
-+      }
-+
-+      /* Disable Tx IPG check for 10G_QXGMII */
-+      if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
-+              reg = (index == 0) ? XPCS_XAUI_MODE_CTRL : XPCS_MII1_XAUI_MODE_CTRL(index);
-+              ret = regmap_set_bits(qpcs->regmap, reg, XPCS_TX_IPG_CHECK_DIS);
-+              if (ret)
-+                      return ret;
-+      }
--      ret = regmap_set_bits(qpcs->regmap, XPCS_MII_AN_CTRL, XPCS_MII_AN_8BIT);
-+      reg = (index == 0) ? XPCS_MII_AN_CTRL : XPCS_MII1_AN_CTRL(index);
-+      ret = regmap_set_bits(qpcs->regmap, reg, XPCS_MII_AN_8BIT);
-       if (ret)
-               return ret;
--      return regmap_set_bits(qpcs->regmap, XPCS_MII_CTRL, XPCS_MII_AN_EN);
-+      reg = (index == 0) ? XPCS_MII_CTRL : XPCS_MII1_CTRL(index);
-+      return regmap_set_bits(qpcs->regmap, reg, XPCS_MII_AN_EN);
- }
- static int ipq_pcs_config_10gbaser(struct ipq_pcs *qpcs)
-@@ -448,9 +503,10 @@ static int ipq_pcs_link_up_config_2500ba
-                              PCS_MII_CTRL(0), PCS_MII_ADPT_RESET);
- }
--static int ipq_pcs_link_up_config_usxgmii(struct ipq_pcs *qpcs, int speed)
-+static int ipq_pcs_link_up_config_usxgmii(struct ipq_pcs *qpcs,
-+                                        int index, int speed)
- {
--      unsigned int val;
-+      unsigned int reg, val;
-       int ret;
-       switch (speed) {
-@@ -478,14 +534,17 @@ static int ipq_pcs_link_up_config_usxgmi
-       }
-       /* Configure XPCS speed */
--      ret = regmap_update_bits(qpcs->regmap, XPCS_MII_CTRL,
-+      reg = (index == 0) ? XPCS_MII_CTRL : XPCS_MII1_CTRL(index);
-+      ret = regmap_update_bits(qpcs->regmap, reg,
-                                XPCS_SPEED_MASK, val | XPCS_DUPLEX_FULL);
-       if (ret)
-               return ret;
-       /* XPCS adapter reset */
--      return regmap_set_bits(qpcs->regmap,
--                             XPCS_DIG_CTRL, XPCS_USXG_ADPT_RESET);
-+      reg = (index == 0) ? XPCS_DIG_CTRL : XPCS_MII1_DIG_CTRL(index);
-+      val = (index == 0) ? XPCS_USXG_ADPT_RESET : XPCS_MII1_USXG_ADPT_RESET;
-+      return regmap_set_bits(qpcs->regmap, reg, val);
-+
- }
- static int ipq_pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
-@@ -502,6 +561,7 @@ static int ipq_pcs_validate(struct phyli
-               phylink_clear(supported, Autoneg);
-               return 0;
-       case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-               /* USXGMII only supports full duplex mode */
-               phylink_clear(supported, 100baseT_Half);
-               phylink_clear(supported, 10baseT_Half);
-@@ -519,6 +579,7 @@ static unsigned int ipq_pcs_inband_caps(
-       case PHY_INTERFACE_MODE_QSGMII:
-       case PHY_INTERFACE_MODE_1000BASEX:
-       case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-               return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-       case PHY_INTERFACE_MODE_2500BASEX:
-       case PHY_INTERFACE_MODE_10GBASER:
-@@ -582,7 +643,8 @@ static void ipq_pcs_get_state(struct phy
-               ipq_pcs_get_state_2500basex(qpcs, state);
-               break;
-       case PHY_INTERFACE_MODE_USXGMII:
--              ipq_pcs_get_state_usxgmii(qpcs, state);
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-+              ipq_pcs_get_state_usxgmii(qpcs, index, state);
-               break;
-       case PHY_INTERFACE_MODE_10GBASER:
-               ipq_pcs_get_state_10gbaser(qpcs, state);
-@@ -617,7 +679,8 @@ static int ipq_pcs_config(struct phylink
-       case PHY_INTERFACE_MODE_2500BASEX:
-               return ipq_pcs_config_2500basex(qpcs);
-       case PHY_INTERFACE_MODE_USXGMII:
--              return ipq_pcs_config_usxgmii(qpcs);
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-+              return ipq_pcs_config_usxgmii(qpcs, index, interface);
-       case PHY_INTERFACE_MODE_10GBASER:
-               return ipq_pcs_config_10gbaser(qpcs);
-       default:
-@@ -646,7 +709,8 @@ static void ipq_pcs_link_up(struct phyli
-               ret = ipq_pcs_link_up_config_2500basex(qpcs, speed);
-               break;
-       case PHY_INTERFACE_MODE_USXGMII:
--              ret = ipq_pcs_link_up_config_usxgmii(qpcs, speed);
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-+              ret = ipq_pcs_link_up_config_usxgmii(qpcs, index, speed);
-               break;
-       case PHY_INTERFACE_MODE_10GBASER:
-               /* Nothing to do here */
-@@ -731,6 +795,7 @@ static unsigned long ipq_pcs_clk_rate_ge
-       switch (qpcs->interface) {
-       case PHY_INTERFACE_MODE_2500BASEX:
-       case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-       case PHY_INTERFACE_MODE_10GBASER:
-               return 312500000;
-       default:
diff --git a/target/linux/qualcommbe/patches-6.12/0365-net-pcs-ipq-uniphy-control-MISC2-register-for-2.5G-s.patch b/target/linux/qualcommbe/patches-6.12/0365-net-pcs-ipq-uniphy-control-MISC2-register-for-2.5G-s.patch
deleted file mode 100644 (file)
index 6ec8f26..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From 87da3bbd25eb0a17e2c698120528e76c26b326d0 Mon Sep 17 00:00:00 2001
-From: Mantas Pucka <mantas@8devices.com>
-Date: Mon, 2 Jun 2025 17:18:13 +0300
-Subject: [PATCH] net: pcs: ipq-uniphy: control MISC2 register for 2.5G support
-
-When 2500base-x mode is enabled MISC2 regsister needs to have different
-value than for other 1G modes.
-
-Signed-off-by: Mantas Pucka <mantas@8devices.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -22,6 +22,11 @@
- #define PCS_CALIBRATION                       0x1e0
- #define PCS_CALIBRATION_DONE          BIT(7)
-+#define PCS_MISC2                     0x218
-+#define PCS_MISC2_MODE_MASK           GENMASK(6, 5)
-+#define PCS_MISC2_MODE_SGMII          FIELD_PREP(PCS_MISC2_MODE_MASK, 0x1)
-+#define PCS_MISC2_MODE_SGMII_PLUS     FIELD_PREP(PCS_MISC2_MODE_MASK, 0x2)
-+
- #define PCS_MODE_CTRL                 0x46c
- #define PCS_MODE_SEL_MASK             GENMASK(12, 8)
- #define PCS_MODE_SGMII                        FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
-@@ -275,7 +280,7 @@ static int ipq_pcs_config_mode(struct ip
-                              phy_interface_t interface)
- {
-       unsigned long rate = 125000000;
--      unsigned int val, mask;
-+      unsigned int val, mask, misc2 = 0;
-       int ret;
-       /* Configure PCS interface mode */
-@@ -283,6 +288,7 @@ static int ipq_pcs_config_mode(struct ip
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-               val = PCS_MODE_SGMII;
-+              misc2 = PCS_MISC2_MODE_SGMII;
-               break;
-       case PHY_INTERFACE_MODE_QSGMII:
-               val = PCS_MODE_QSGMII;
-@@ -290,9 +296,11 @@ static int ipq_pcs_config_mode(struct ip
-       case PHY_INTERFACE_MODE_1000BASEX:
-               mask |= PCS_MODE_SGMII_MODE_MASK;
-               val = PCS_MODE_SGMII | PCS_MODE_SGMII_MODE_1000BASEX;
-+              misc2 = PCS_MISC2_MODE_SGMII;
-               break;
-       case PHY_INTERFACE_MODE_2500BASEX:
-               val = PCS_MODE_2500BASEX;
-+              misc2 = PCS_MISC2_MODE_SGMII_PLUS;
-               rate = 312500000;
-               break;
-       case PHY_INTERFACE_MODE_USXGMII:
-@@ -315,6 +323,13 @@ static int ipq_pcs_config_mode(struct ip
-               if (ret)
-                       return ret;
-       }
-+
-+      if (misc2) {
-+              ret = regmap_update_bits(qpcs->regmap, PCS_MISC2,
-+                                       PCS_MISC2_MODE_MASK, misc2);
-+              if (ret)
-+                      return ret;
-+      }
-       /* PCS PLL reset */
-       ret = regmap_clear_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
diff --git a/target/linux/qualcommbe/patches-6.12/0367-net-pcs-ipq-uniphy-fix-USXGMII-link-up-failure.patch b/target/linux/qualcommbe/patches-6.12/0367-net-pcs-ipq-uniphy-fix-USXGMII-link-up-failure.patch
deleted file mode 100644 (file)
index b02782e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-From bedf56b46ae53c4abb21eebb3e1d5a7483926dda Mon Sep 17 00:00:00 2001
-From: Mantas Pucka <mantas@8devices.com>
-Date: Mon, 2 Jun 2025 17:20:58 +0300
-Subject: [PATCH] net: pcs: ipq-uniphy: fix USXGMII link-up failure
-
-USXGMII link-up may fail due to too short delay after PLL reset.
-Increase the delay to fix this.
-
-Signed-off-by: Mantas Pucka <mantas@8devices.com>
----
- drivers/net/pcs/pcs-qcom-ipq9574.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -336,7 +336,7 @@ static int ipq_pcs_config_mode(struct ip
-       if (ret)
-               return ret;
--      fsleep(1000);
-+      fsleep(20000);
-       ret = regmap_set_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
-       if (ret)
-               return ret;
diff --git a/target/linux/qualcommbe/patches-6.12/0368-net-pcs-qcom-ipq9574-Update-IPQ9574-PCS-driver.patch b/target/linux/qualcommbe/patches-6.12/0368-net-pcs-qcom-ipq9574-Update-IPQ9574-PCS-driver.patch
deleted file mode 100644 (file)
index 63a523a..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-From b4e07a8a3ec3dc5f676238987556e2aff0b14028 Mon Sep 17 00:00:00 2001
-From: Lei Wei <quic_leiwei@quicinc.com>
-Date: Mon, 29 Jan 2024 11:39:36 +0800
-Subject: [PATCH] net: pcs: qcom-ipq9574: Update IPQ9574 PCS driver
-
-Keep the PCS driver synced with the latest version posted to the kernel
-community and add the XPCS reset support.
-
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- .../bindings/net/pcs/qcom,ipq9574-pcs.yaml    |  7 ++
- drivers/net/pcs/pcs-qcom-ipq9574.c            | 68 +++++++++++++++----
- 2 files changed, 63 insertions(+), 12 deletions(-)
-
---- a/Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml
-+++ b/Documentation/devicetree/bindings/net/pcs/qcom,ipq9574-pcs.yaml
-@@ -98,6 +98,10 @@ properties:
-       - const: sys
-       - const: ahb
-+  resets:
-+    maxItems: 1
-+    description: XPCS reset
-+
-   '#clock-cells':
-     const: 1
-     description: See include/dt-bindings/net/qcom,ipq9574-pcs.h for constants
-@@ -137,6 +141,7 @@ required:
-   - '#size-cells'
-   - clocks
-   - clock-names
-+  - resets
-   - '#clock-cells'
- additionalProperties: false
-@@ -144,6 +149,7 @@ additionalProperties: false
- examples:
-   - |
-     #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
-+    #include <dt-bindings/reset/qcom,ipq9574-gcc.h>
-     ethernet-pcs@7a00000 {
-         compatible = "qcom,ipq9574-pcs";
-@@ -154,6 +160,7 @@ examples:
-                  <&gcc GCC_UNIPHY0_AHB_CLK>;
-         clock-names = "sys",
-                       "ahb";
-+        resets = <&gcc GCC_UNIPHY0_XPCS_RESET>;
-         #clock-cells = <1>;
-         pcs-mii@0 {
---- a/drivers/net/pcs/pcs-qcom-ipq9574.c
-+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
-@@ -13,6 +13,7 @@
- #include <linux/phylink.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
-+#include <linux/reset.h>
- #include <dt-bindings/net/qcom,ipq9574-pcs.h>
-@@ -31,9 +32,12 @@
- #define PCS_MODE_SEL_MASK             GENMASK(12, 8)
- #define PCS_MODE_SGMII                        FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
- #define PCS_MODE_QSGMII                       FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
-+#define PCS_MODE_PSGMII                       FIELD_PREP(PCS_MODE_SEL_MASK, 0x2)
- #define PCS_MODE_2500BASEX            FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
- #define PCS_MODE_XPCS                 FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
- #define PCS_MODE_SGMII_MODE_MASK      GENMASK(6, 4)
-+#define PCS_MODE_SGMII_MODE_MAC               FIELD_PREP(PCS_MODE_SGMII_MODE_MASK, \
-+                                                 0x2)
- #define PCS_MODE_SGMII_MODE_1000BASEX FIELD_PREP(PCS_MODE_SGMII_MODE_MASK, \
-                                                  0x0)
-@@ -52,6 +56,8 @@
- #define PCS_MII_STS_SPEED_10          0
- #define PCS_MII_STS_SPEED_100         1
- #define PCS_MII_STS_SPEED_1000                2
-+#define PCS_MII_STS_PAUSE_TX_EN               BIT(1)
-+#define PCS_MII_STS_PAUSE_RX_EN               BIT(0)
- #define PCS_QP_USXG_OPTION            0x584
- #define PCS_QP_USXG_GMII_SRC_XPCS     BIT(0)
-@@ -142,6 +148,7 @@ struct ipq_pcs {
-       struct clk_hw tx_hw;
-       struct ipq_pcs_mii *qpcs_mii[PCS_MAX_MII_NRS];
-+      struct reset_control *xpcs_rstc;
- };
- #define phylink_pcs_to_qpcs_mii(_pcs) \
-@@ -184,6 +191,11 @@ static void ipq_pcs_get_state_sgmii(stru
-               state->duplex = DUPLEX_FULL;
-       else
-               state->duplex = DUPLEX_HALF;
-+
-+      if (val & PCS_MII_STS_PAUSE_TX_EN)
-+              state->pause |= MLO_PAUSE_TX;
-+      if (val & PCS_MII_STS_PAUSE_RX_EN)
-+              state->pause |= MLO_PAUSE_RX;
- }
- static void ipq_pcs_get_state_2500basex(struct ipq_pcs *qpcs,
-@@ -198,7 +210,6 @@ static void ipq_pcs_get_state_2500basex(
-               return;
-       }
--
-       state->link = !!(val & PCS_MII_LINK_STS);
-       if (!state->link)
-@@ -281,17 +292,27 @@ static int ipq_pcs_config_mode(struct ip
- {
-       unsigned long rate = 125000000;
-       unsigned int val, mask, misc2 = 0;
-+      bool xpcs_mode = false;
-       int ret;
-+      /* Assert XPCS reset */
-+      reset_control_assert(qpcs->xpcs_rstc);
-+
-       /* Configure PCS interface mode */
-       mask = PCS_MODE_SEL_MASK;
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
--              val = PCS_MODE_SGMII;
-+              mask |= PCS_MODE_SGMII_MODE_MASK;
-+              val = PCS_MODE_SGMII | PCS_MODE_SGMII_MODE_MAC;
-               misc2 = PCS_MISC2_MODE_SGMII;
-               break;
-       case PHY_INTERFACE_MODE_QSGMII:
--              val = PCS_MODE_QSGMII;
-+              mask |= PCS_MODE_SGMII_MODE_MASK;
-+              val = PCS_MODE_QSGMII | PCS_MODE_SGMII_MODE_MAC;
-+              break;
-+      case PHY_INTERFACE_MODE_PSGMII:
-+              mask |= PCS_MODE_SGMII_MODE_MASK;
-+              val = PCS_MODE_PSGMII | PCS_MODE_SGMII_MODE_MAC;
-               break;
-       case PHY_INTERFACE_MODE_1000BASEX:
-               mask |= PCS_MODE_SGMII_MODE_MASK;
-@@ -308,6 +329,7 @@ static int ipq_pcs_config_mode(struct ip
-       case PHY_INTERFACE_MODE_10GBASER:
-               val = PCS_MODE_XPCS;
-               rate = 312500000;
-+              xpcs_mode = true;
-               break;
-       default:
-               return -EOPNOTSUPP;
-@@ -367,6 +389,10 @@ static int ipq_pcs_config_mode(struct ip
-               return ret;
-       }
-+      /* Deassert XPCS */
-+      if (xpcs_mode)
-+              reset_control_deassert(qpcs->xpcs_rstc);
-+
-       return 0;
- }
-@@ -384,15 +410,13 @@ static int ipq_pcs_config_sgmii(struct i
-                       return ret;
-       }
--      /* Nothing to do here as in-band autoneg mode is enabled
--       * by default for each PCS MII port.
--       */
-+      /* Set AN mode or force mode */
-       if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
--              return 0;
--
--      /* Set force speed mode */
--      return regmap_set_bits(qpcs->regmap,
--                             PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
-+              return regmap_clear_bits(qpcs->regmap,
-+                                       PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
-+      else
-+              return regmap_set_bits(qpcs->regmap,
-+                                     PCS_MII_CTRL(index), PCS_MII_FORCE_MODE);
- }
- static int ipq_pcs_config_2500basex(struct ipq_pcs *qpcs)
-@@ -417,6 +441,10 @@ static int ipq_pcs_config_usxgmii(struct
-               if (ret)
-                       return ret;
-+              ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_USXG_EN);
-+              if (ret)
-+                      return ret;
-+
-               if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
-                       ret = regmap_update_bits(qpcs->regmap, XPCS_KR_CTRL,
-                                                XPCS_USXG_MODE_MASK, XPCS_10G_QXGMII_MODE);
-@@ -432,6 +460,7 @@ static int ipq_pcs_config_usxgmii(struct
-                       ret = regmap_set_bits(qpcs->regmap, XPCS_DIG_CTRL, XPCS_SOFT_RESET);
-                       if (ret)
-                               return ret;
-+              }
-       }
-       /* Disable Tx IPG check for 10G_QXGMII */
-@@ -559,7 +588,6 @@ static int ipq_pcs_link_up_config_usxgmi
-       reg = (index == 0) ? XPCS_DIG_CTRL : XPCS_MII1_DIG_CTRL(index);
-       val = (index == 0) ? XPCS_USXG_ADPT_RESET : XPCS_MII1_USXG_ADPT_RESET;
-       return regmap_set_bits(qpcs->regmap, reg, val);
--
- }
- static int ipq_pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
-@@ -568,6 +596,7 @@ static int ipq_pcs_validate(struct phyli
-       switch (state->interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_PSGMII:
-       case PHY_INTERFACE_MODE_1000BASEX:
-       case PHY_INTERFACE_MODE_10GBASER:
-               return 0;
-@@ -592,6 +621,7 @@ static unsigned int ipq_pcs_inband_caps(
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_PSGMII:
-       case PHY_INTERFACE_MODE_1000BASEX:
-       case PHY_INTERFACE_MODE_USXGMII:
-       case PHY_INTERFACE_MODE_10G_QXGMII:
-@@ -648,6 +678,7 @@ static void ipq_pcs_get_state(struct phy
-       switch (state->interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_PSGMII:
-       case PHY_INTERFACE_MODE_1000BASEX:
-               /* SGMII and 1000BASEX in-band autoneg word format are decoded
-                * by PCS hardware and both placed to the same status register.
-@@ -689,6 +720,7 @@ static int ipq_pcs_config(struct phylink
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_PSGMII:
-       case PHY_INTERFACE_MODE_1000BASEX:
-               return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface);
-       case PHY_INTERFACE_MODE_2500BASEX:
-@@ -703,6 +735,11 @@ static int ipq_pcs_config(struct phylink
-       };
- }
-+static void ipq_pcs_an_restart(struct phylink_pcs *pcs)
-+{
-+      /* Currently not used */
-+}
-+
- static void ipq_pcs_link_up(struct phylink_pcs *pcs,
-                           unsigned int neg_mode,
-                           phy_interface_t interface,
-@@ -716,6 +753,7 @@ static void ipq_pcs_link_up(struct phyli
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_PSGMII:
-       case PHY_INTERFACE_MODE_1000BASEX:
-               ret = ipq_pcs_link_up_config_sgmii(qpcs, index,
-                                                  neg_mode, speed);
-@@ -746,6 +784,7 @@ static const struct phylink_pcs_ops ipq_
-       .pcs_disable = ipq_pcs_disable,
-       .pcs_get_state = ipq_pcs_get_state,
-       .pcs_config = ipq_pcs_config,
-+      .pcs_an_restart = ipq_pcs_an_restart,
-       .pcs_link_up = ipq_pcs_link_up,
- };
-@@ -990,6 +1029,11 @@ static int ipq9574_pcs_probe(struct plat
-               return dev_err_probe(dev, PTR_ERR(clk),
-                                    "Failed to enable AHB clock\n");
-+      qpcs->xpcs_rstc = devm_reset_control_get_optional(dev, NULL);
-+      if (IS_ERR_OR_NULL(qpcs->xpcs_rstc))
-+              return dev_err_probe(dev, PTR_ERR(qpcs->xpcs_rstc),
-+                                   "Failed to get XPCS reset\n");
-+
-       ret = ipq_pcs_clk_register(qpcs);
-       if (ret)
-               return ret;
diff --git a/target/linux/qualcommbe/patches-6.12/0370-net-phy-Add-phy_package_remove_once-helper.patch b/target/linux/qualcommbe/patches-6.12/0370-net-phy-Add-phy_package_remove_once-helper.patch
deleted file mode 100644 (file)
index ec81286..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-From d11eba3e178a9d42a579c656b2c9b643f4ce3e1e Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Mon, 23 Sep 2024 18:46:34 +0800
-Subject: [PATCH] net: phy: Add phy_package_remove_once helper
-
-QCA8084 PHY package needs to do the PHY package clean up,
-add phy_package_remove_once helper to support.
-
-Change-Id: I3cd73bc7be1b1d531435ef72f48db0682548decf
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- include/linux/phy.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -376,6 +376,7 @@ struct phy_package_shared {
- /* used as bit number in atomic bitops */
- #define PHY_SHARED_F_INIT_DONE  0
- #define PHY_SHARED_F_PROBE_DONE 1
-+#define PHY_SHARED_F_REMOVE_DONE 2
- /**
-  * struct mii_bus - Represents an MDIO bus
-@@ -2290,6 +2291,11 @@ static inline bool phy_package_probe_onc
-       return __phy_package_set_once(phydev, PHY_SHARED_F_PROBE_DONE);
- }
-+static inline bool phy_package_remove_once(struct phy_device *phydev)
-+{
-+      return __phy_package_set_once(phydev, PHY_SHARED_F_REMOVE_DONE);
-+}
-+
- extern const struct bus_type mdio_bus_type;
- struct mdio_board_info {
diff --git a/target/linux/qualcommbe/patches-6.12/0371-net-phy-qca808x-Add-QCA8084-SerDes-probe-and-remove-.patch b/target/linux/qualcommbe/patches-6.12/0371-net-phy-qca808x-Add-QCA8084-SerDes-probe-and-remove-.patch
deleted file mode 100644 (file)
index a0c84bd..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-From c12b79af730116936504afe97234f9afb6ac8fc0 Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Mon, 23 Sep 2024 20:28:24 +0800
-Subject: [PATCH] net: phy: qca808x: Add QCA8084 SerDes probe and remove
- functions
-
-QCA8084 PHY package integrates the XPCS and PCS, which is used
-to support 10G-QXGMII. XPCS includes 4 channels to connect with
-Quad PHY, and PCS controls the interface mode configured.
-
-XPCS and PCS are probed and removed by PHY package.
-
-Change-Id: Ided0a5cd4c996dc2a2a0d0598e930fab060caaf8
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: Use phy_package_get_*() accessors
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/phy/qcom/Makefile         |   2 +-
- drivers/net/phy/qcom/qca8084_serdes.c | 249 ++++++++++++++++++++++++++
- drivers/net/phy/qcom/qca8084_serdes.h |  18 ++
- drivers/net/phy/qcom/qca808x.c        |  53 ++++++
- 4 files changed, 321 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/phy/qcom/qca8084_serdes.c
- create mode 100644 drivers/net/phy/qcom/qca8084_serdes.h
-
---- a/drivers/net/phy/qcom/Makefile
-+++ b/drivers/net/phy/qcom/Makefile
-@@ -2,5 +2,5 @@
- obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o
- obj-$(CONFIG_AT803X_PHY)      += at803x.o
- obj-$(CONFIG_QCA83XX_PHY)     += qca83xx.o
--obj-$(CONFIG_QCA808X_PHY)     += qca808x.o
-+obj-$(CONFIG_QCA808X_PHY)     += qca808x.o qca8084_serdes.o
- obj-$(CONFIG_QCA807X_PHY)     += qca807x.o
---- /dev/null
-+++ b/drivers/net/phy/qcom/qca8084_serdes.c
-@@ -0,0 +1,249 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/dev_printk.h>
-+#include <linux/mdio.h>
-+#include <linux/of.h>
-+#include <linux/phy.h>
-+#include <linux/property.h>
-+#include <linux/reset.h>
-+
-+#include "qca8084_serdes.h"
-+
-+/* XPCS includes 4 channels, each channel has the different MMD ID for
-+ * configuring auto-negotiation complete interrupt, mii-4bit, auto-
-+ * negotiation capabilities and TX configuration for the connected PHY.
-+ *
-+ * MMD31 is for channel 0;
-+ * MMD26 is for channel 1;
-+ * MMD27 is for channel 2;
-+ * MMD28 is for channel 3;
-+ */
-+#define QCA8084_CHANNEL_MAX                   4
-+
-+enum pcs_clk_id {
-+      PCS_CLK,
-+      PCS_RX_ROOT_CLK,
-+      PCS_TX_ROOT_CLK,
-+      PCS_CLK_MAX
-+};
-+
-+enum xpcs_clk_id {
-+      XPCS_XGMII_RX_CLK,
-+      XPCS_XGMII_TX_CLK,
-+      XPCS_RX_CLK,
-+      XPCS_TX_CLK,
-+      XPCS_PORT_RX_CLK,
-+      XPCS_PORT_TX_CLK,
-+      XPCS_RX_SRC_CLK,
-+      XPCS_TX_SRC_CLK,
-+      XPCS_CLK_MAX
-+};
-+
-+struct qca8084_xpcs_channel_priv {
-+      int ch_id;
-+      struct reset_control *rstcs;
-+      struct clk *clks[XPCS_CLK_MAX];
-+};
-+
-+struct qca8084_pcs_data {
-+      struct reset_control *rstc;
-+      struct clk *clks[PCS_CLK_MAX];
-+};
-+
-+struct qca8084_xpcs_data {
-+      struct reset_control *rstc;
-+      struct qca8084_xpcs_channel_priv xpcs_ch[QCA8084_CHANNEL_MAX];
-+};
-+
-+static const char *const xpcs_clock_names[XPCS_CLK_MAX] = {
-+      [XPCS_XGMII_RX_CLK] =   "xgmii_rx",
-+      [XPCS_XGMII_TX_CLK] =   "xgmii_tx",
-+      [XPCS_RX_CLK] =         "xpcs_rx",
-+      [XPCS_TX_CLK] =         "xpcs_tx",
-+      [XPCS_PORT_RX_CLK] =    "port_rx",
-+      [XPCS_PORT_TX_CLK] =    "port_tx",
-+      [XPCS_RX_SRC_CLK] =     "rx_src",
-+      [XPCS_TX_SRC_CLK] =     "tx_src",
-+};
-+
-+static const char *const pcs_clock_names[PCS_CLK_MAX] = {
-+      [PCS_CLK] =             "pcs",
-+      [PCS_RX_ROOT_CLK] =     "pcs_rx_root",
-+      [PCS_TX_ROOT_CLK] =     "pcs_tx_root",
-+};
-+
-+struct mdio_device *qca8084_package_pcs_probe(struct device_node *pcs_np)
-+{
-+      struct qca8084_pcs_data *pcs_data;
-+      struct mdio_device *mdiodev;
-+      struct reset_control *rstc;
-+      struct device *dev;
-+      struct clk *clk;
-+      int i;
-+
-+      mdiodev = fwnode_mdio_find_device(of_fwnode_handle(pcs_np));
-+      if (!mdiodev)
-+              return ERR_PTR(-EPROBE_DEFER);
-+
-+      dev = &mdiodev->dev;
-+      pcs_data = devm_kzalloc(dev, sizeof(*pcs_data), GFP_KERNEL);
-+      if (!pcs_data) {
-+              dev_err(dev, "Allocate PCS data failed\n");
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      rstc = devm_reset_control_get_exclusive(dev, NULL);
-+      if (IS_ERR(rstc)) {
-+              dev_err(dev, "Get PCS reset failed\n");
-+              return ERR_CAST(rstc);
-+      }
-+
-+      pcs_data->rstc = rstc;
-+
-+      for (i = 0; i < ARRAY_SIZE(pcs_clock_names); i++) {
-+              clk = devm_clk_get(dev, pcs_clock_names[i]);
-+              if (IS_ERR(clk)) {
-+                      dev_err(dev, "Failed to get the PCS clock ID %s\n",
-+                              pcs_clock_names[i]);
-+                      return ERR_CAST(clk);
-+              }
-+              pcs_data->clks[i] = clk;
-+      }
-+
-+      mdiodev_set_drvdata(mdiodev, pcs_data);
-+
-+      return mdiodev;
-+}
-+
-+struct mdio_device *qca8084_package_xpcs_probe(struct device_node *xpcs_np)
-+{
-+      struct qca8084_xpcs_data *xpcs_data;
-+      struct mdio_device *mdiodev;
-+      struct reset_control *rstc;
-+      struct device_node *child;
-+      struct device *dev;
-+      struct clk *clk;
-+      int i, j, node;
-+
-+      mdiodev = fwnode_mdio_find_device(of_fwnode_handle(xpcs_np));
-+      if (!mdiodev)
-+              return ERR_PTR(-EPROBE_DEFER);
-+
-+      dev = &mdiodev->dev;
-+
-+      xpcs_data = devm_kzalloc(dev, sizeof(*xpcs_data), GFP_KERNEL);
-+      if (!xpcs_data) {
-+              dev_err(dev, "Allocate XPCS data failed\n");
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      rstc = devm_reset_control_get_exclusive(dev, NULL);
-+      if (IS_ERR(rstc)) {
-+              dev_err(dev, "Get XPCS reset failed\n");
-+              return ERR_CAST(rstc);
-+      }
-+
-+      xpcs_data->rstc = rstc;
-+
-+      /* Sanity check the number of channel sub nodes */
-+      node = of_get_available_child_count(xpcs_np);
-+      if (node != QCA8084_CHANNEL_MAX)
-+              return ERR_PTR(-EINVAL);
-+
-+      node = 0;
-+      for_each_available_child_of_node(xpcs_np, child) {
-+              struct qca8084_xpcs_channel_priv *ch_data;
-+              u32 channel;
-+
-+              /* The subnode name must be 'channel'. */
-+              if (!(of_node_name_eq(child, "channel")))
-+                      continue;
-+
-+              if (of_property_read_u32(child, "reg", &channel)) {
-+                      dev_err(dev, "%s: Failed to get reg\n",
-+                              child->full_name);
-+
-+                      mdiodev = ERR_PTR(-EINVAL);
-+                      goto put_ch_clk_rst;
-+              }
-+
-+              if (channel >= QCA8084_CHANNEL_MAX) {
-+                      dev_err(dev, "%s: Invalid reg %d\n",
-+                              child->full_name, channel);
-+
-+                      mdiodev = ERR_PTR(-EINVAL);
-+                      goto put_ch_clk_rst;
-+              }
-+
-+              ch_data = &xpcs_data->xpcs_ch[node];
-+              ch_data->ch_id = channel;
-+
-+              ch_data->rstcs = of_reset_control_array_get_exclusive(child);
-+              if (IS_ERR(ch_data->rstcs)) {
-+                      dev_err(dev, "%s: Failed to get reset\n",
-+                              child->full_name);
-+
-+                      mdiodev = ERR_CAST(ch_data->rstcs);
-+                      goto put_ch_clk_rst;
-+              }
-+
-+              for (j = 0; j < ARRAY_SIZE(xpcs_clock_names); j++) {
-+                      clk = of_clk_get_by_name(child, xpcs_clock_names[j]);
-+                      if (IS_ERR(clk)) {
-+                              dev_err(dev, "Failed to get the clock ID %s\n",
-+                                      xpcs_clock_names[j]);
-+                              mdiodev = ERR_CAST(clk);
-+                              goto put_ch_child;
-+                      }
-+                      ch_data->clks[j] = clk;
-+              }
-+
-+              node++;
-+      }
-+
-+      mdiodev_set_drvdata(mdiodev, xpcs_data);
-+
-+      return mdiodev;
-+
-+put_ch_child:
-+      node++;
-+
-+put_ch_clk_rst:
-+      for (i = 0; i < node; i++) {
-+              j--;
-+              while (j >= 0) {
-+                      clk_put(xpcs_data->xpcs_ch[i].clks[j]);
-+                      j--;
-+              }
-+
-+              j = ARRAY_SIZE(xpcs_clock_names);
-+      }
-+
-+      for (i = 0; i < node; i++)
-+              reset_control_put(xpcs_data->xpcs_ch[i].rstcs);
-+
-+      of_node_put(child);
-+
-+      return mdiodev;
-+}
-+
-+void qca8084_package_xpcs_and_pcs_remove(struct mdio_device *xpcs_mdiodev,
-+                                       struct mdio_device *pcs_mdiodev)
-+{
-+      struct qca8084_xpcs_data *xpcs_data = mdiodev_get_drvdata(xpcs_mdiodev);
-+      int i, j;
-+
-+      for (i = 0; i < ARRAY_SIZE(xpcs_data->xpcs_ch); i++) {
-+              reset_control_put(xpcs_data->xpcs_ch[i].rstcs);
-+
-+              for (j = 0; j < ARRAY_SIZE(xpcs_data->xpcs_ch[i].clks); j++)
-+                      clk_put(xpcs_data->xpcs_ch[i].clks[j]);
-+      }
-+
-+      mdio_device_put(xpcs_mdiodev);
-+      mdio_device_put(pcs_mdiodev);
-+}
---- /dev/null
-+++ b/drivers/net/phy/qcom/qca8084_serdes.h
-@@ -0,0 +1,18 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Driver for QCA8084 SerDes
-+ *
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
-+ */
-+
-+#ifndef _QCA8084_SERDES_H_
-+#define _QCA8084_SERDES_H_
-+
-+#include <linux/mdio.h>
-+#include <linux/of.h>
-+
-+struct mdio_device *qca8084_package_pcs_probe(struct device_node *pcs_np);
-+struct mdio_device *qca8084_package_xpcs_probe(struct device_node *xpcs_np);
-+void qca8084_package_xpcs_and_pcs_remove(struct mdio_device *xpcs_mdiodev,
-+                                       struct mdio_device *pcs_mdiodev);
-+#endif /* _QCA8084_SERDES_H_ */
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -8,6 +8,7 @@
- #include <linux/clk.h>
- #include "../phylib.h"
-+#include "qca8084_serdes.h"
- #include "qcom.h"
- /* ADC threshold */
-@@ -172,11 +173,13 @@ enum {
- struct qca808x_priv {
-       int led_polarity_mode;
-+      int channel_id;
- };
- struct qca808x_shared_priv {
-       int package_mode;
-       struct clk *clk[PACKAGE_CLK_MAX];
-+      struct mdio_device *mdiodev[2]; /* PCS and XPCS mdio device */
- };
- static const char *const qca8084_package_clk_name[PACKAGE_CLK_MAX] = {
-@@ -354,6 +357,8 @@ static int qca808x_probe(struct phy_devi
- {
-       struct device *dev = &phydev->mdio.dev;
-       struct qca808x_priv *priv;
-+      u32 ch_id = 0;
-+      int ret;
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-@@ -362,6 +367,14 @@ static int qca808x_probe(struct phy_devi
-       /* Init LED polarity mode to -1 */
-       priv->led_polarity_mode = -1;
-+      /* DT property qcom,xpcs-channel" is optional and only available for
-+       * 10G-QXGMII mode.
-+       */
-+      ret = of_property_read_u32(dev->of_node, "qcom,xpcs-channel", &ch_id);
-+      if (ret && ret != -EINVAL)
-+              return ret;
-+
-+      priv->channel_id = ch_id;
-       phydev->priv = priv;
-       return 0;
-@@ -1012,6 +1025,7 @@ static int qca8084_phy_package_probe_onc
-       struct device_node *np = phy_package_get_node(phydev);
-       struct qca808x_shared_priv *shared_priv;
-       struct reset_control *rstc;
-+      struct device_node *child;
-       int i, ret, clear, set;
-       struct clk *clk;
-@@ -1072,6 +1086,26 @@ static int qca8084_phy_package_probe_onc
-       if (ret && ret != -EINVAL)
-               return ret;
-+      for_each_available_child_of_node(np, child) {
-+              struct mdio_device *mdiodev;
-+
-+              if (of_node_name_eq(child, "pcs-phy")) {
-+                      mdiodev = qca8084_package_pcs_probe(child);
-+                      if (IS_ERR(mdiodev))
-+                              return PTR_ERR(mdiodev);
-+
-+                      shared_priv->mdiodev[0] = mdiodev;
-+              }
-+
-+              if (of_node_name_eq(child, "xpcs-phy")) {
-+                      mdiodev = qca8084_package_xpcs_probe(child);
-+                      if (IS_ERR(mdiodev))
-+                              return PTR_ERR(mdiodev);
-+
-+                      shared_priv->mdiodev[1] = mdiodev;
-+              }
-+      }
-+
-       rstc = of_reset_control_get_exclusive(np, NULL);
-       if (IS_ERR(rstc))
-               return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
-@@ -1081,6 +1115,14 @@ static int qca8084_phy_package_probe_onc
-       return reset_control_deassert(rstc);
- }
-+static void qca8084_phy_package_remove_once(struct phy_device *phydev)
-+{
-+      struct qca808x_shared_priv *shared_priv = phy_package_get_priv(phydev);;
-+
-+      qca8084_package_xpcs_and_pcs_remove(shared_priv->mdiodev[1],
-+                                          shared_priv->mdiodev[0]);
-+}
-+
- static int qca8084_probe(struct phy_device *phydev)
- {
-       struct qca808x_shared_priv *shared_priv;
-@@ -1099,6 +1141,10 @@ static int qca8084_probe(struct phy_devi
-                       return ret;
-       }
-+      ret = qca808x_probe(phydev);
-+      if (ret)
-+              return ret;
-+
-       /* Enable clock of PHY device, so that the PHY register
-        * can be accessed to get PHY features.
-        */
-@@ -1116,6 +1162,12 @@ static int qca8084_probe(struct phy_devi
-       return reset_control_deassert(rstc);
- }
-+static void qca8084_remove(struct phy_device *phydev)
-+{
-+      if (phy_package_remove_once(phydev))
-+              qca8084_phy_package_remove_once(phydev);
-+}
-+
- static struct phy_driver qca808x_driver[] = {
- {
-       /* Qualcomm QCA8081 */
-@@ -1167,6 +1219,7 @@ static struct phy_driver qca808x_driver[
-       .config_init            = qca8084_config_init,
-       .link_change_notify     = qca8084_link_change_notify,
-       .probe                  = qca8084_probe,
-+      .remove                 = qca8084_remove,
- }, };
- module_phy_driver(qca808x_driver);
diff --git a/target/linux/qualcommbe/patches-6.12/0372-net-phy-qca808x-Add-QCA8084-SerDes-init-function.patch b/target/linux/qualcommbe/patches-6.12/0372-net-phy-qca808x-Add-QCA8084-SerDes-init-function.patch
deleted file mode 100644 (file)
index 688d7ac..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-From d137b725f8f4a7d49a809dcd73c5b836495ec44d Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Mon, 23 Sep 2024 20:59:40 +0800
-Subject: [PATCH] net: phy: qca808x: Add QCA8084 SerDes init function
-
-When QCA8084 works on 10G-QXGMII, the XPCS and PCS need to be
-configured in the PHY package init function.
-
-Change-Id: Iac48c44f0e80adf055fa9c2095e99a04ba24c4bb
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
----
- drivers/net/phy/qcom/qca8084_serdes.c | 374 ++++++++++++++++++++++++++
- drivers/net/phy/qcom/qca8084_serdes.h |   2 +
- drivers/net/phy/qcom/qca808x.c        |  11 +
- 3 files changed, 387 insertions(+)
-
---- a/drivers/net/phy/qcom/qca8084_serdes.c
-+++ b/drivers/net/phy/qcom/qca8084_serdes.c
-@@ -24,6 +24,92 @@
-  */
- #define QCA8084_CHANNEL_MAX                   4
-+/* MII registers */
-+#define PLL_POWER_ON_AND_RESET                        0x0
-+#define PCS_ANA_SW_RESET                      BIT(6)
-+
-+#define PLL_CONTROL                           6
-+#define PLL_CONTROL_CMLDIV2_IBSEL_MASK                GENMASK(5, 4)
-+
-+/* MMD_PMAPMD registers */
-+#define CDR_CONTRL                            0x20
-+#define SSC_FIX_MODE                          BIT(3)
-+
-+#define CALIBRATION4                          0x78
-+#define CALIBRATION_DONE                      BIT(7)
-+
-+#define MODE_CONTROL                          0x11b
-+#define MODE_CONTROL_SEL_MASK                 GENMASK(12, 8)
-+#define MODE_CONTROL_XPCS                     0x10
-+#define MODE_CONTROL_SGMII_PLUS                       0x8
-+#define MODE_CONTROL_SGMII                    0x4
-+#define MODE_CONTROL_SGMII_SEL_MASK           GENMASK(6, 4)
-+#define MODE_CONTROL_SGMII_PHY                        1
-+#define MODE_CONTROL_SGMII_MAC                        2
-+
-+#define QP_USXG_OPTION1                               0x180
-+#define QP_USXG_OPTION1_DATAPASS              BIT(0)
-+#define QP_USXG_OPTION1_DATAPASS_SGMII                0
-+#define QP_USXG_OPTION1_DATAPASS_USXGMII      1
-+
-+#define BYPASS_TUNNING_IPG                    0x189
-+#define BYPASS_TUNNING_IPG_MASK                       GENMASK(11, 0)
-+
-+/* MDIO_MMD_PCS register */
-+#define PCS_CONTROL2                          0x7
-+#define PCS_TYPE_MASK                         GENMASK(3, 0)
-+#define PCS_TYPE_BASER                                0
-+
-+#define PCS_EEE_CONTROL                               0x14
-+#define EEE_CAPABILITY                                BIT(6)
-+
-+#define PCS_STATUS1                           0x20
-+#define PCS_BASER_UP                          BIT(12)
-+
-+#define DIG_CTRL1                             0x8000
-+#define DIG_CTRL1_USXGMII_EN                  BIT(9)
-+#define DIG_CTRL1_XPCS_RESET                  BIT(15)
-+#define FIFO_RESET_CH0                                BIT(10)
-+#define FIFO_RESET_CH1_CH2_CH3                        BIT(5)
-+
-+#define EEE_MODE_CONTROL                      0x8006
-+#define EEE_LCT_RES                           GENMASK(11, 8)
-+#define EEE_SIGN                              BIT(6)
-+#define EEE_LRX_EN                            BIT(1)
-+#define EEE_LTX_EN                            BIT(0)
-+
-+#define PCS_TPC                                       0x8007
-+#define PCS_QXGMII_MODE_MASK                  GENMASK(12, 10)
-+#define PCS_QXGMII_EN                         0x5
-+
-+#define EEE_RX_TIMER                          0x8009
-+#define EEE_RX_TIMER_100US_RES                        GENMASK(7, 0)
-+#define EEE_RX_TIMER_RWR_RES                  GENMASK(12, 8)
-+
-+#define AM_LINK_TIMER                         0x800a
-+#define AM_LINK_TIMER_VAL                     0x6018
-+
-+#define EEE_MODE_CONTROL1                     0x800b
-+#define TRANS_LPI_MODE                                BIT(0)
-+#define TRANS_RX_LPI_MODE                     BIT(8)
-+
-+/* QXGMII channel MMD register */
-+#define MII_CONTROL                           0x0
-+#define AUTO_NEGOTIATION_EN                   BIT(12)
-+#define AUTO_NEGOTIATION_RESTART              BIT(9)
-+#define PCS_SPEED_2500                                BIT(5)
-+#define PCS_SPEED_1000                                BIT(6)
-+#define PCS_SPEED_100                         BIT(13)
-+#define PCS_SPEED_10                          0
-+
-+#define DIG_CONTROL2                          0x8001
-+#define MII_BIT_CONTROL                               BIT(8)
-+#define TX_CONFIG                             BIT(3)
-+#define AUTO_NEGOTIATION_CMPLT_INTR           BIT(0)
-+
-+#define XAUI_CONTROL                          0x8004
-+#define TX_IPG_CHECK_DISABLE                  BIT(0)
-+
- enum pcs_clk_id {
-       PCS_CLK,
-       PCS_RX_ROOT_CLK,
-@@ -76,6 +162,8 @@ static const char *const pcs_clock_names
-       [PCS_TX_ROOT_CLK] =     "pcs_tx_root",
- };
-+static const int qca8084_xpcs_ch_mmd[QCA8084_CHANNEL_MAX] = { 31, 26, 27, 28 };
-+
- struct mdio_device *qca8084_package_pcs_probe(struct device_node *pcs_np)
- {
-       struct qca8084_pcs_data *pcs_data;
-@@ -247,3 +335,289 @@ void qca8084_package_xpcs_and_pcs_remove
-       mdio_device_put(xpcs_mdiodev);
-       mdio_device_put(pcs_mdiodev);
- }
-+
-+static int qca8084_pcs_set_interface_mode(struct mdio_device *mdio_dev,
-+                                        phy_interface_t ifmode)
-+{
-+      int ret, hw_ifmode, data;
-+
-+      switch (ifmode) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+              hw_ifmode = MODE_CONTROL_SGMII;
-+              data = QP_USXG_OPTION1_DATAPASS_SGMII;
-+              break;
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              hw_ifmode = MODE_CONTROL_SGMII_PLUS;
-+              data = QP_USXG_OPTION1_DATAPASS_SGMII;
-+              break;
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-+              hw_ifmode = MODE_CONTROL_XPCS;
-+              data = QP_USXG_OPTION1_DATAPASS_USXGMII;
-+              break;
-+      default:
-+              return -EOPNOTSUPP;
-+      }
-+
-+      /* For PLL stable under high temperature */
-+      ret = mdiodev_modify(mdio_dev, PLL_CONTROL,
-+                           PLL_CONTROL_CMLDIV2_IBSEL_MASK,
-+                           FIELD_PREP(PLL_CONTROL_CMLDIV2_IBSEL_MASK, 3));
-+      if (ret)
-+              return ret;
-+
-+      /* Configure the interface mode of PCS */
-+      ret = mdiodev_c45_modify(mdio_dev, MDIO_MMD_PMAPMD, MODE_CONTROL,
-+                               MODE_CONTROL_SEL_MASK,
-+                               FIELD_PREP(MODE_CONTROL_SEL_MASK, hw_ifmode));
-+      if (ret)
-+              return ret;
-+
-+      /* Data pass selects SGMII or USXGMII */
-+      return mdiodev_c45_modify(mdio_dev, MDIO_MMD_PMAPMD, QP_USXG_OPTION1,
-+                                QP_USXG_OPTION1_DATAPASS,
-+                                FIELD_PREP(QP_USXG_OPTION1_DATAPASS, data));
-+}
-+
-+static int qca8084_do_calibration(struct mdio_device *mdio_dev)
-+{
-+      int ret;
-+
-+      ret = mdiodev_modify(mdio_dev, PLL_POWER_ON_AND_RESET,
-+                           PCS_ANA_SW_RESET, 0);
-+      if (ret)
-+              return ret;
-+
-+      usleep_range(10000, 11000);
-+      ret = mdiodev_modify(mdio_dev, PLL_POWER_ON_AND_RESET,
-+                           PCS_ANA_SW_RESET, PCS_ANA_SW_RESET);
-+      if (ret)
-+              return ret;
-+
-+      /* Wait calibration done */
-+      return read_poll_timeout(mdiodev_c45_read, ret,
-+                               (ret & CALIBRATION_DONE),
-+                               100, 100000, true, mdio_dev,
-+                               MDIO_MMD_PMAPMD, CALIBRATION4);
-+}
-+
-+
-+static int qca8084_xpcs_set_mode(struct mdio_device *xpcs_mdiodev)
-+{
-+      int ret, val, i;
-+
-+      /* Configure BaseR mode */
-+      ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, PCS_CONTROL2,
-+                               PCS_TYPE_MASK,
-+                               FIELD_PREP(PCS_TYPE_MASK, PCS_TYPE_BASER));
-+      if (ret)
-+              return ret;
-+
-+      /* Wait BaseR link up */
-+      ret = read_poll_timeout(mdiodev_c45_read, val,
-+                              (val & PCS_BASER_UP), 1000, 100000, true,
-+                              xpcs_mdiodev,
-+                              MDIO_MMD_PCS, PCS_STATUS1);
-+      if (ret) {
-+              dev_err(&xpcs_mdiodev->dev, "BaseR link failed!\n");
-+              return ret;
-+      }
-+
-+      /* Enable USXGMII mode */
-+      ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, DIG_CTRL1,
-+                               DIG_CTRL1_USXGMII_EN,
-+                               DIG_CTRL1_USXGMII_EN);
-+      if (ret)
-+              return ret;
-+
-+      /* Configure QXGMII mode */
-+      ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, PCS_TPC,
-+                               PCS_QXGMII_MODE_MASK,
-+                               FIELD_PREP(PCS_QXGMII_MODE_MASK,
-+                                          PCS_QXGMII_EN));
-+      if (ret)
-+              return ret;
-+
-+      /* Configure AM interval */
-+      ret = mdiodev_c45_write(xpcs_mdiodev, MDIO_MMD_PCS, AM_LINK_TIMER,
-+                              AM_LINK_TIMER_VAL);
-+      if (ret)
-+              return ret;
-+
-+      /* Reset XPCS */
-+      ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, DIG_CTRL1,
-+                               DIG_CTRL1_XPCS_RESET,
-+                               DIG_CTRL1_XPCS_RESET);
-+      if (ret)
-+              return ret;
-+
-+      /* Wait XPCS reset done */
-+      ret = read_poll_timeout(mdiodev_c45_read, val,
-+                              !(val & DIG_CTRL1_XPCS_RESET),
-+                              1000, 100000, true, xpcs_mdiodev,
-+                              MDIO_MMD_PCS, DIG_CTRL1);
-+      if (ret) {
-+              dev_err(&xpcs_mdiodev->dev, "XPCS reset failed!\n");
-+              return ret;
-+      }
-+
-+      /* Enable auto-negotiation complete interrupt, using mii-4bit
-+       * and TX configureation of PHY side on all XPCS channels.
-+       */
-+      for (i = 0; i < QCA8084_CHANNEL_MAX; i++) {
-+              ret = mdiodev_c45_modify(xpcs_mdiodev, qca8084_xpcs_ch_mmd[i],
-+                                       DIG_CONTROL2,
-+                                       (MII_BIT_CONTROL | TX_CONFIG |
-+                                       AUTO_NEGOTIATION_CMPLT_INTR),
-+                                       (TX_CONFIG | AUTO_NEGOTIATION_CMPLT_INTR));
-+              if (ret)
-+                      return ret;
-+
-+              /* Enable auto-negotiation capability */
-+              ret = mdiodev_c45_modify(xpcs_mdiodev, qca8084_xpcs_ch_mmd[i],
-+                                       MII_CONTROL,
-+                                       AUTO_NEGOTIATION_EN,
-+                                       AUTO_NEGOTIATION_EN);
-+              if (ret)
-+                      return ret;
-+
-+              /* Disable TX IPG check */
-+              ret = mdiodev_c45_modify(xpcs_mdiodev, qca8084_xpcs_ch_mmd[i],
-+                                       XAUI_CONTROL,
-+                                       TX_IPG_CHECK_DISABLE,
-+                                       TX_IPG_CHECK_DISABLE);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      /* Check EEE capability supported or not */
-+      ret = mdiodev_c45_read(xpcs_mdiodev, MDIO_MMD_PCS, PCS_EEE_CONTROL);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (ret & EEE_CAPABILITY) {
-+              ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS,
-+                                       EEE_MODE_CONTROL,
-+                                       EEE_LCT_RES | EEE_SIGN,
-+                                       FIELD_PREP(EEE_LCT_RES, 1) | EEE_SIGN);
-+              if (ret)
-+                      return ret;
-+
-+              ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS,
-+                                       EEE_RX_TIMER,
-+                                       EEE_RX_TIMER_100US_RES | EEE_RX_TIMER_RWR_RES,
-+                                       FIELD_PREP(EEE_RX_TIMER_100US_RES, 0xc8) |
-+                                       FIELD_PREP(EEE_RX_TIMER_RWR_RES, 0x1c));
-+              if (ret)
-+                      return ret;
-+
-+              /* Enable EEE LPI */
-+              ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS,
-+                                       EEE_MODE_CONTROL1,
-+                                       TRANS_LPI_MODE | TRANS_RX_LPI_MODE,
-+                                       TRANS_LPI_MODE | TRANS_RX_LPI_MODE);
-+              if (ret)
-+                      return ret;
-+
-+              /* Enable TX/RX LPI pattern */
-+              ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS,
-+                                       EEE_MODE_CONTROL,
-+                                       EEE_LRX_EN | EEE_LTX_EN,
-+                                       EEE_LRX_EN | EEE_LTX_EN);
-+      }
-+
-+      return ret;
-+}
-+
-+static int qca8084_pcs_set_mode(struct mdio_device *xpcs_mdiodev,
-+                                     struct mdio_device *pcs_mdiodev)
-+{
-+      struct qca8084_xpcs_data *xpcs_data = mdiodev_get_drvdata(xpcs_mdiodev);
-+      struct qca8084_pcs_data *pcs_data = mdiodev_get_drvdata(pcs_mdiodev);
-+      struct qca8084_xpcs_channel_priv xpcs_ch;
-+      int ret, channel;
-+
-+      /* Enable clock and de-assert for PCS. */
-+      ret = clk_prepare_enable(pcs_data->clks[PCS_CLK]);
-+      if (ret)
-+              return ret;
-+
-+      ret = reset_control_deassert(pcs_data->rstc);
-+      if (ret)
-+              return ret;
-+
-+      /* IPG tunning selection for RX, TX and XGMII of all channels. */
-+      ret = mdiodev_c45_modify(pcs_mdiodev, MDIO_MMD_PMAPMD,
-+                               BYPASS_TUNNING_IPG,
-+                               BYPASS_TUNNING_IPG_MASK, 0);
-+      if (ret)
-+              return ret;
-+
-+      reset_control_assert(xpcs_data->rstc);
-+
-+      ret = qca8084_pcs_set_interface_mode(pcs_mdiodev,
-+                                           PHY_INTERFACE_MODE_10G_QXGMII);
-+      if (ret)
-+              return ret;
-+
-+      /* Reset of 4 channels */
-+      for (channel = 0; channel < QCA8084_CHANNEL_MAX; channel++) {
-+              xpcs_ch = xpcs_data->xpcs_ch[channel];
-+              ret = reset_control_reset(xpcs_ch.rstcs);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      ret = qca8084_do_calibration(pcs_mdiodev);
-+      if (ret) {
-+              dev_err(&pcs_mdiodev->dev, "PCS calibration timeout!\n");
-+              return ret;
-+      }
-+
-+      /* Enable PCS SSC to fix mode */
-+      ret = mdiodev_c45_modify(pcs_mdiodev, MDIO_MMD_PMAPMD,
-+                               CDR_CONTRL, SSC_FIX_MODE, SSC_FIX_MODE);
-+      if (ret)
-+              return ret;
-+
-+      return reset_control_deassert(xpcs_data->rstc);
-+}
-+
-+static int qca8084_xpcs_clock_parent_set(struct mdio_device *xpcs_mdiodev,
-+                                       struct mdio_device *pcs_mdiodev)
-+{
-+      struct qca8084_xpcs_data *xpcs_data = mdiodev_get_drvdata(xpcs_mdiodev);
-+      struct qca8084_pcs_data *pcs_data = mdiodev_get_drvdata(pcs_mdiodev);
-+      struct qca8084_xpcs_channel_priv xpcs_ch;
-+      int ret, channel;
-+
-+      for (channel = 0; channel < QCA8084_CHANNEL_MAX; channel++) {
-+              xpcs_ch = xpcs_data->xpcs_ch[channel];
-+              ret = clk_set_parent(xpcs_ch.clks[XPCS_RX_SRC_CLK],
-+                                   pcs_data->clks[PCS_RX_ROOT_CLK]);
-+              if (ret)
-+                      return ret;
-+
-+              ret = clk_set_parent(xpcs_ch.clks[XPCS_TX_SRC_CLK],
-+                                   pcs_data->clks[PCS_TX_ROOT_CLK]);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+int qca8084_qxgmii_set_mode(struct mdio_device *xpcs_mdiodev,
-+                          struct mdio_device *pcs_mdiodev)
-+{
-+      int ret;
-+
-+      ret = qca8084_xpcs_clock_parent_set(xpcs_mdiodev, pcs_mdiodev);
-+      if (ret)
-+              return ret;
-+
-+      ret = qca8084_pcs_set_mode(xpcs_mdiodev, pcs_mdiodev);
-+      if (ret)
-+              return ret;
-+
-+      return qca8084_xpcs_set_mode(xpcs_mdiodev);
-+}
---- a/drivers/net/phy/qcom/qca8084_serdes.h
-+++ b/drivers/net/phy/qcom/qca8084_serdes.h
-@@ -15,4 +15,6 @@ struct mdio_device *qca8084_package_pcs_
- struct mdio_device *qca8084_package_xpcs_probe(struct device_node *xpcs_np);
- void qca8084_package_xpcs_and_pcs_remove(struct mdio_device *xpcs_mdiodev,
-                                        struct mdio_device *pcs_mdiodev);
-+int qca8084_qxgmii_set_mode(struct mdio_device *xpcs_mdiodev,
-+                          struct mdio_device *pcs_mdiodev);
- #endif /* _QCA8084_SERDES_H_ */
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -926,6 +926,14 @@ static int qca8084_phy_package_config_in
-       usleep_range(10000, 11000);
-+      /* Configure PCS working on 10G-QXGMII mode */
-+      if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII) {
-+              ret = qca8084_qxgmii_set_mode(shared_priv->mdiodev[1],
-+                                            shared_priv->mdiodev[0]);
-+              if (ret)
-+                      return ret;
-+      }
-+
-       /* Initialize the PHY package clock and reset, which is the
-        * necessary config sequence after GPIO reset on the PHY package.
-        */
-@@ -1164,6 +1172,9 @@ static int qca8084_probe(struct phy_devi
- static void qca8084_remove(struct phy_device *phydev)
- {
-+      if (phydev->interface != PHY_INTERFACE_MODE_10G_QXGMII)
-+              return;
-+
-       if (phy_package_remove_once(phydev))
-               qca8084_phy_package_remove_once(phydev);
- }
diff --git a/target/linux/qualcommbe/patches-6.12/0373-net-phy-qca808x-Add-QCA8084-SerDes-speed-config.patch b/target/linux/qualcommbe/patches-6.12/0373-net-phy-qca808x-Add-QCA8084-SerDes-speed-config.patch
deleted file mode 100644 (file)
index 1244837..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-From 2f5b7e167d847a5b5b74a91f991d48635453c55f Mon Sep 17 00:00:00 2001
-From: Luo Jie <quic_luoj@quicinc.com>
-Date: Mon, 23 Sep 2024 21:24:56 +0800
-Subject: [PATCH] net: phy: qca808x: Add QCA8084 SerDes speed config
-
-When the link of PHY is changed, the XPCS channel needs to be
-configured to adapt the current link status.
-
-Change-Id: I50d8973691dff133fc6bec1e9a1043bb646811fc
-Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
-Alex G: Use phy_package_get_*() accessors
-Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
----
- drivers/net/phy/qcom/qca8084_serdes.c | 159 ++++++++++++++++++++++++++
- drivers/net/phy/qcom/qca8084_serdes.h |   3 +
- drivers/net/phy/qcom/qca808x.c        |  15 ++-
- 3 files changed, 175 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/qcom/qca8084_serdes.c
-+++ b/drivers/net/phy/qcom/qca8084_serdes.c
-@@ -4,6 +4,7 @@
-  */
- #include <linux/clk.h>
-+#include <linux/clk-provider.h>
- #include <linux/dev_printk.h>
- #include <linux/mdio.h>
- #include <linux/of.h>
-@@ -55,6 +56,13 @@
- #define BYPASS_TUNNING_IPG                    0x189
- #define BYPASS_TUNNING_IPG_MASK                       GENMASK(11, 0)
-+#define QP_USXG_RESET                         0x18c
-+#define QP_USXG_SGMII_FUNC_RESET              BIT(4)
-+#define QP_USXG_P3_FUNC_RESET                 BIT(3)
-+#define QP_USXG_P2_FUNC_RESET                 BIT(2)
-+#define QP_USXG_P1_FUNC_RESET                 BIT(1)
-+#define QP_USXG_P0_FUNC_RESET                 BIT(0)
-+
- /* MDIO_MMD_PCS register */
- #define PCS_CONTROL2                          0x7
- #define PCS_TYPE_MASK                         GENMASK(3, 0)
-@@ -107,6 +115,9 @@
- #define TX_CONFIG                             BIT(3)
- #define AUTO_NEGOTIATION_CMPLT_INTR           BIT(0)
-+#define PCS_ERR_SEL                           0x8002
-+#define PCS_AN_COMPLETE                               BIT(0)
-+
- #define XAUI_CONTROL                          0x8004
- #define TX_IPG_CHECK_DISABLE                  BIT(0)
-@@ -621,3 +632,151 @@ int qca8084_qxgmii_set_mode(struct mdio_
-       return qca8084_xpcs_set_mode(xpcs_mdiodev);
- }
-+
-+static int qca8084_pcs_ipg_tune_reset(struct mdio_device *mdio_dev,
-+                                    int reset_function)
-+{
-+      int ret;
-+
-+      ret = mdiodev_c45_modify(mdio_dev, MDIO_MMD_PMAPMD, QP_USXG_RESET,
-+                               reset_function, 0);
-+      if (ret)
-+              return ret;
-+
-+      usleep_range(1000, 1100);
-+
-+      return mdiodev_c45_modify(mdio_dev, MDIO_MMD_PMAPMD, QP_USXG_RESET,
-+                                reset_function, reset_function);
-+}
-+
-+static int qca8084_xpcs_an_restart(struct mdio_device *xpcs_mdiodev,
-+                                 int channel)
-+{
-+      int ret, mmd;
-+
-+      mmd = qca8084_xpcs_ch_mmd[channel];
-+
-+      /* Restart auto-negotiation */
-+      ret = mdiodev_c45_modify(xpcs_mdiodev, mmd, MII_CONTROL,
-+                               AUTO_NEGOTIATION_RESTART,
-+                               AUTO_NEGOTIATION_RESTART);
-+      if (ret)
-+              return ret;
-+
-+      usleep_range(1000, 1100);
-+
-+      /* Clear pcs auto-negotiation complete interrupt */
-+      return mdiodev_c45_modify(xpcs_mdiodev, mmd, PCS_ERR_SEL,
-+                                PCS_AN_COMPLETE, 0);
-+}
-+
-+void qca8084_qxgmii_set_speed(struct mdio_device *xpcs_mdiodev,
-+                            struct mdio_device *pcs_mdiodev,
-+                            int channel, int speed)
-+{
-+      struct qca8084_xpcs_data *xpcs_data = mdiodev_get_drvdata(xpcs_mdiodev);
-+      struct qca8084_xpcs_channel_priv *xpcs_ch;
-+      int mmd, i, ret, xpcs_rate;
-+      unsigned long rate;
-+
-+      for (i = 0; i < QCA8084_CHANNEL_MAX; i++) {
-+              xpcs_ch = &(xpcs_data->xpcs_ch[channel]);
-+              if (channel == xpcs_ch->ch_id)
-+                      break;
-+      }
-+
-+      if (i == QCA8084_CHANNEL_MAX) {
-+              dev_err(&xpcs_mdiodev->dev, "Invalid channel %d\n", channel);
-+              return;
-+      }
-+
-+      mmd = qca8084_xpcs_ch_mmd[channel];
-+
-+      ret = qca8084_xpcs_an_restart(xpcs_mdiodev, channel);
-+      if (ret)
-+              return;
-+
-+      switch (speed) {
-+      case SPEED_2500:
-+              rate = 312500000;
-+              xpcs_rate = PCS_SPEED_2500;
-+              break;
-+      case SPEED_1000:
-+              rate = 125000000;
-+              xpcs_rate = PCS_SPEED_1000;
-+              break;
-+      case SPEED_100:
-+              rate = 25000000;
-+              xpcs_rate = PCS_SPEED_100;
-+              break;
-+      case SPEED_10:
-+      default:
-+              rate = 2500000;
-+              xpcs_rate = PCS_SPEED_10;
-+              break;
-+      }
-+
-+      clk_set_rate(xpcs_ch->clks[XPCS_RX_CLK], rate);
-+      clk_set_rate(xpcs_ch->clks[XPCS_TX_CLK], rate);
-+
-+      /* XGMII takes the different clock rate 78.125Mhz from XPCS clock
-+       * when linked at 2500M.
-+       */
-+      if (speed == SPEED_2500)
-+              rate = 78125000;
-+
-+      clk_set_rate(xpcs_ch->clks[XPCS_XGMII_RX_CLK], rate);
-+      clk_set_rate(xpcs_ch->clks[XPCS_XGMII_TX_CLK], rate);
-+
-+      ret = mdiodev_c45_modify(xpcs_mdiodev, mmd, MII_CONTROL,
-+                               PCS_SPEED_2500 | PCS_SPEED_1000 |
-+                               PCS_SPEED_100 | PCS_SPEED_10,
-+                               xpcs_rate);
-+      if (ret)
-+              return;
-+
-+      /* Disable clocks if link down with unknown speed. The channel clocks
-+       * are disabled by default, __clk_is_enabled() is used to avoid
-+       * disabling the clocks that is already in the disabled status.
-+       */
-+      if (speed == SPEED_UNKNOWN) {
-+              if (__clk_is_enabled(xpcs_ch->clks[XPCS_RX_CLK]))
-+                      clk_disable_unprepare(xpcs_ch->clks[XPCS_RX_CLK]);
-+              if (__clk_is_enabled(xpcs_ch->clks[XPCS_TX_CLK]))
-+                      clk_disable_unprepare(xpcs_ch->clks[XPCS_TX_CLK]);
-+              if (__clk_is_enabled(xpcs_ch->clks[XPCS_PORT_RX_CLK]))
-+                      clk_disable_unprepare(xpcs_ch->clks[XPCS_PORT_RX_CLK]);
-+              if (__clk_is_enabled(xpcs_ch->clks[XPCS_PORT_TX_CLK]))
-+                      clk_disable_unprepare(xpcs_ch->clks[XPCS_PORT_TX_CLK]);
-+              if (__clk_is_enabled(xpcs_ch->clks[XPCS_XGMII_RX_CLK]))
-+                      clk_disable_unprepare(xpcs_ch->clks[XPCS_XGMII_RX_CLK]);
-+              if (__clk_is_enabled(xpcs_ch->clks[XPCS_XGMII_TX_CLK]))
-+                      clk_disable_unprepare(xpcs_ch->clks[XPCS_XGMII_TX_CLK]);
-+      } else {
-+              clk_prepare_enable(xpcs_ch->clks[XPCS_RX_CLK]);
-+              clk_prepare_enable(xpcs_ch->clks[XPCS_TX_CLK]);
-+              clk_prepare_enable(xpcs_ch->clks[XPCS_PORT_RX_CLK]);
-+              clk_prepare_enable(xpcs_ch->clks[XPCS_PORT_TX_CLK]);
-+              clk_prepare_enable(xpcs_ch->clks[XPCS_XGMII_RX_CLK]);
-+              clk_prepare_enable(xpcs_ch->clks[XPCS_XGMII_TX_CLK]);
-+      }
-+
-+      msleep(100);
-+
-+      ret = reset_control_reset(xpcs_ch->rstcs);
-+      if (ret)
-+              return;
-+
-+      /* Reset IPG tune of PCS device. */
-+      ret = qca8084_pcs_ipg_tune_reset(pcs_mdiodev, BIT(channel));
-+      if (ret)
-+              return;
-+
-+      if (channel == 0)
-+              mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, DIG_CTRL1,
-+                                 FIFO_RESET_CH0, FIFO_RESET_CH0);
-+      else
-+              mdiodev_c45_modify(xpcs_mdiodev, mmd, DIG_CTRL1,
-+                                 FIFO_RESET_CH1_CH2_CH3,
-+                                 FIFO_RESET_CH1_CH2_CH3);
-+}
---- a/drivers/net/phy/qcom/qca8084_serdes.h
-+++ b/drivers/net/phy/qcom/qca8084_serdes.h
-@@ -17,4 +17,7 @@ void qca8084_package_xpcs_and_pcs_remove
-                                        struct mdio_device *pcs_mdiodev);
- int qca8084_qxgmii_set_mode(struct mdio_device *xpcs_mdiodev,
-                           struct mdio_device *pcs_mdiodev);
-+void qca8084_qxgmii_set_speed(struct mdio_device *xpcs_mdiodev,
-+                            struct mdio_device *pcs_mdiodev,
-+                            int channel, int speed);
- #endif /* _QCA8084_SERDES_H_ */
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -976,6 +976,7 @@ static int qca8084_config_init(struct ph
- static void qca8084_link_change_notify(struct phy_device *phydev)
- {
-+      struct qca808x_shared_priv *shared_priv;
-       int ret;
-       /* Assert the FIFO between PHY and MAC. */
-@@ -1007,14 +1008,24 @@ static void qca8084_link_change_notify(s
-               }
-       }
--      /* Enable IPG level 10 to 11 tuning for link speed 1000M in the
-+      /* Enable IPG level 10 to 11 tuning for link speed 1000M and
-+       * configure the related XPCS channel with the phydev in the
-        * 10G_QXGMII mode.
-        */
--      if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
-+      if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII) {
-+              shared_priv = phy_package_get_priv(phydev);
-+              struct qca808x_priv *priv = phydev->priv;
-+
-               phy_modify_mmd(phydev, MDIO_MMD_AN, QCA8084_MMD7_IPG_OP,
-                              QCA8084_IPG_10_TO_11_EN,
-                              phydev->speed == SPEED_1000 ?
-                              QCA8084_IPG_10_TO_11_EN : 0);
-+
-+              qca8084_qxgmii_set_speed(shared_priv->mdiodev[1],
-+                                       shared_priv->mdiodev[0],
-+                                       priv->channel_id,
-+                                       phydev->speed);
-+      }
- }
- /* QCA8084 is a four-port PHY, which integrates the clock controller,
diff --git a/target/linux/qualcommbe/patches-6.12/0374-dt-bindings-pwm-add-IPQ6018-binding.patch b/target/linux/qualcommbe/patches-6.12/0374-dt-bindings-pwm-add-IPQ6018-binding.patch
deleted file mode 100644 (file)
index 07a64a0..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-From patchwork Fri Nov 28 10:29:13 2025
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: George Moussalem via B4 Relay
- <devnull+george.moussalem.outlook.com@kernel.org>
-X-Patchwork-Id: 2169931
-Return-Path: 
- <linux-pwm+bounces-7721-incoming=patchwork.ozlabs.org@vger.kernel.org>
-X-Original-To: incoming@patchwork.ozlabs.org
-Delivered-To: patchwork-incoming@legolas.ozlabs.org
-Authentication-Results: legolas.ozlabs.org;
-       dkim=pass (2048-bit key;
- unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256
- header.s=k20201202 header.b=qU845OFh;
-       dkim-atps=neutral
-Authentication-Results: legolas.ozlabs.org;
- spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org
- (client-ip=213.196.21.55; helo=ams.mirrors.kernel.org;
- envelope-from=linux-pwm+bounces-7721-incoming=patchwork.ozlabs.org@vger.kernel.org;
- receiver=patchwork.ozlabs.org)
-Received: from ams.mirrors.kernel.org (ams.mirrors.kernel.org [213.196.21.55])
-       (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
-        key-exchange X25519 server-signature ECDSA (secp384r1))
-       (No client certificate requested)
-       by legolas.ozlabs.org (Postfix) with ESMTPS id 4dHqMJ5gXFz1yDj
-       for <incoming@patchwork.ozlabs.org>; Fri, 28 Nov 2025 21:30:52 +1100 (AEDT)
-Received: from smtp.subspace.kernel.org (relay.kernel.org [52.25.139.140])
-       (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))
-       (No client certificate requested)
-       by ams.mirrors.kernel.org (Postfix) with ESMTPS id 0783B352ED3
-       for <incoming@patchwork.ozlabs.org>; Fri, 28 Nov 2025 10:29:38 +0000 (UTC)
-Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
-       by smtp.subspace.kernel.org (Postfix) with ESMTP id 5B94630C370;
-       Fri, 28 Nov 2025 10:29:23 +0000 (UTC)
-Authentication-Results: smtp.subspace.kernel.org;
-       dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org
- header.b="qU845OFh"
-X-Original-To: linux-pwm@vger.kernel.org
-Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org
- [10.30.226.201])
-       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
-       (No client certificate requested)
-       by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27F7930B525;
-       Fri, 28 Nov 2025 10:29:22 +0000 (UTC)
-Authentication-Results: smtp.subspace.kernel.org;
- arc=none smtp.client-ip=10.30.226.201
-ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
-       t=1764325763; cv=none;
- b=EZdjLPtvTBCzr24d6uks1u6xas9FiqaXRtClecDuZQfT8aKQnU9LDJSaswvWaMHcpRkbBujRZFntPyNohlI+P0vj+Zlmof30QOr4Cw61jr3wGlfQNPsH0ib1AuyADzOHFj1W0c+mfqIs2onOC15OGkIc+DWrCsNXePSM/0/0XQM=
-ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
-       s=arc-20240116; t=1764325763; c=relaxed/simple;
-       bh=fNS3C2NaCK+go2nQNBlkD9EyrNNHIb0CZcl2LNOQBmE=;
-       h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:
-        In-Reply-To:To:Cc;
- b=iRh98acHGzMCOeqCHb4A30mpdpFjHp96ccf65E1oF0kaAGzHdhWM7H56NI22q+0GXrY7o91H7F+x1Dz1spr6OZc6bMG4DuV8oap/vEdtyjApt+7zNFUl0PcrMSLSe2YVFaWgVvk7/IenJxJhEqcPWhsFZR+HGM4iuhv2lP3w32c=
-ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
- dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org
- header.b=qU845OFh; arc=none smtp.client-ip=10.30.226.201
-Received: by smtp.kernel.org (Postfix) with ESMTPS id BDCD9C113D0;
-       Fri, 28 Nov 2025 10:29:22 +0000 (UTC)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;
-       s=k20201202; t=1764325762;
-       bh=fNS3C2NaCK+go2nQNBlkD9EyrNNHIb0CZcl2LNOQBmE=;
-       h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From;
-       b=qU845OFhU3cciT1imeWuTMro85tXusIJt99AroBlTX9t+aY8oZwFPjd4KhPNki2mi
-        gK5GyKlndlusCuuiAqnaaQahXFM6I16gAWHOaCMORh1VJ0Vdli6WOo66C/KlZBrRPN
-        4x/+oieXIooU174yYf8PhFevu9NVbs1arlck6sgsyyW7HB0WwedreqFH2qfmTO4NyF
-        zDymUL0G9Og8hd89PsEyZkkDLVroKnvjU7POud+8el6a6PvDYUOmCTM/rsu2gJX64s
-        k9Nm5ZJmRWfQvaku8McARECvY/QLX3P+pweAuDyazDxpGgTTxPqMbyywNEBjfVYu+o
-        ksKwowwfTPqHg==
-Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org
- (localhost.localdomain [127.0.0.1])
-       by smtp.lore.kernel.org (Postfix) with ESMTP id A0784D116EA;
-       Fri, 28 Nov 2025 10:29:22 +0000 (UTC)
-From: George Moussalem via B4 Relay
- <devnull+george.moussalem.outlook.com@kernel.org>
-Date: Fri, 28 Nov 2025 14:29:13 +0400
-Subject: [PATCH v19 1/6] dt-bindings: pwm: add IPQ6018 binding
-Precedence: bulk
-X-Mailing-List: linux-pwm@vger.kernel.org
-List-Id: <linux-pwm.vger.kernel.org>
-List-Subscribe: <mailto:linux-pwm+subscribe@vger.kernel.org>
-List-Unsubscribe: <mailto:linux-pwm+unsubscribe@vger.kernel.org>
-MIME-Version: 1.0
-Message-Id: <20251128-ipq-pwm-v19-1-13bc704cc6a5@outlook.com>
-References: <20251128-ipq-pwm-v19-0-13bc704cc6a5@outlook.com>
-In-Reply-To: <20251128-ipq-pwm-v19-0-13bc704cc6a5@outlook.com>
-To: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= <ukleinek@kernel.org>,
-  Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
-  Conor Dooley <conor+dt@kernel.org>, Baruch Siach <baruch@tkos.co.il>,
-  Bjorn Andersson <andersson@kernel.org>,
-  Konrad Dybcio <konradybcio@kernel.org>
-Cc: linux-arm-msm@vger.kernel.org, linux-pwm@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- George Moussalem <george.moussalem@outlook.com>,
- Devi Priya <quic_devipriy@quicinc.com>,
- Baruch Siach <baruch.siach@siklu.com>,
- Bjorn Andersson <andersson@kernel.org>,
- Krzysztof Kozlowski <krzk@kernel.org>
-X-Mailer: b4 0.14.2
-X-Developer-Signature: v=1; a=ed25519-sha256; t=1764325760; l=2042;
- i=george.moussalem@outlook.com; s=20250321; h=from:subject:message-id;
- bh=8ayVJ9z0kZoRdShrug1dJ1pjUonk4k9SO1yJzG93fMg=;
- b=o0lsJw1oX/jEPu9xLh+Ovt+AbJGXh3X8na0H8Ko0Vcl7PFsYQQEOP9HhJAp8Y5XyBFBcroa6x
- AHFNonYE7aVArYgsi5KqkDnui4xwpKQpD5RwWJ3JFA96K5IALoApziu
-X-Developer-Key: i=george.moussalem@outlook.com; a=ed25519;
- pk=/PuRTSI9iYiHwcc6Nrde8qF4ZDhJBlUgpHdhsIjnqIk=
-X-Endpoint-Received: by B4 Relay for george.moussalem@outlook.com/20250321
- with auth_id=364
-X-Original-From: George Moussalem <george.moussalem@outlook.com>
-Reply-To: george.moussalem@outlook.com
-
-From: Devi Priya <quic_devipriy@quicinc.com>
-
-DT binding for the PWM block in Qualcomm IPQ6018 SoC.
-
-Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Co-developed-by: Baruch Siach <baruch.siach@siklu.com>
-Signed-off-by: Baruch Siach <baruch.siach@siklu.com>
-Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
-Signed-off-by: George Moussalem <george.moussalem@outlook.com>
----
- .../devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml  | 51 ++++++++++++++++++++++
- 1 file changed, 51 insertions(+)
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml
-@@ -0,0 +1,51 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pwm/qcom,ipq6018-pwm.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Qualcomm IPQ6018 PWM controller
-+
-+maintainers:
-+  - George Moussalem <george.moussalem@outlook.com>
-+
-+properties:
-+  compatible:
-+    oneOf:
-+      - items:
-+          - enum:
-+              - qcom,ipq5018-pwm
-+              - qcom,ipq5332-pwm
-+              - qcom,ipq9574-pwm
-+          - const: qcom,ipq6018-pwm
-+      - const: qcom,ipq6018-pwm
-+
-+  reg:
-+    maxItems: 1
-+
-+  clocks:
-+    maxItems: 1
-+
-+  "#pwm-cells":
-+    const: 3
-+
-+required:
-+  - compatible
-+  - reg
-+  - clocks
-+  - "#pwm-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+  - |
-+    #include <dt-bindings/clock/qcom,gcc-ipq6018.h>
-+
-+    pwm: pwm@1941010 {
-+        compatible = "qcom,ipq6018-pwm";
-+        reg = <0x01941010 0x20>;
-+        clocks = <&gcc GCC_ADSS_PWM_CLK>;
-+        assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
-+        assigned-clock-rates = <100000000>;
-+        #pwm-cells = <3>;
-+    };
diff --git a/target/linux/qualcommbe/patches-6.12/0375-pwm-driver-for-qualcomm-ipq6018-pwm-block.patch b/target/linux/qualcommbe/patches-6.12/0375-pwm-driver-for-qualcomm-ipq6018-pwm-block.patch
deleted file mode 100644 (file)
index 670b360..0000000
+++ /dev/null
@@ -1,403 +0,0 @@
-From patchwork Wed Feb  4 11:25:08 2026
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: George Moussalem via B4 Relay
- <devnull+george.moussalem.outlook.com@kernel.org>
-X-Patchwork-Id: 2192910
-Return-Path: 
- <linux-pwm+bounces-8087-incoming=patchwork.ozlabs.org@vger.kernel.org>
-X-Original-To: incoming@patchwork.ozlabs.org
-Delivered-To: patchwork-incoming@legolas.ozlabs.org
-Authentication-Results: legolas.ozlabs.org;
-       dkim=pass (2048-bit key;
- unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256
- header.s=k20201202 header.b=WGUCMoYx;
-       dkim-atps=neutral
-Authentication-Results: legolas.ozlabs.org;
- spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org
- (client-ip=172.105.105.114; helo=tor.lore.kernel.org;
- envelope-from=linux-pwm+bounces-8087-incoming=patchwork.ozlabs.org@vger.kernel.org;
- receiver=patchwork.ozlabs.org)
-Received: from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114])
-       (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
-        key-exchange x25519)
-       (No client certificate requested)
-       by legolas.ozlabs.org (Postfix) with ESMTPS id 4f5dMp0fDDz1xqf
-       for <incoming@patchwork.ozlabs.org>; Wed, 04 Feb 2026 22:26:14 +1100 (AEDT)
-Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org
- [100.90.174.1])
-       by tor.lore.kernel.org (Postfix) with ESMTP id EBABA301D322
-       for <incoming@patchwork.ozlabs.org>; Wed,  4 Feb 2026 11:25:18 +0000 (UTC)
-Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
-       by smtp.subspace.kernel.org (Postfix) with ESMTP id 498E93ECBC6;
-       Wed,  4 Feb 2026 11:25:14 +0000 (UTC)
-Authentication-Results: smtp.subspace.kernel.org;
-       dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org
- header.b="WGUCMoYx"
-X-Original-To: linux-pwm@vger.kernel.org
-Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org
- [10.30.226.201])
-       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
-       (No client certificate requested)
-       by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1653D3E9F8E;
-       Wed,  4 Feb 2026 11:25:14 +0000 (UTC)
-Authentication-Results: smtp.subspace.kernel.org;
- arc=none smtp.client-ip=10.30.226.201
-ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
-       t=1770204314; cv=none;
- b=G3d0Ri0xw7F/u2rUoaF2eprL1ihrTvDSfCszkp2ciK2Y+UB3YSBt1K9D5nrbQw3bG1mHFZSO34nH/NZUQUoP97w8cJNILcVALgdGNfpM1vdDsKcRjomVZOvJi5sTvm2qnS4gIzL5DhybGv6UMOPcMrPM4TyZjpnvnJyWo9twGXE=
-ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
-       s=arc-20240116; t=1770204314; c=relaxed/simple;
-       bh=DlyTmDysGY1XB33v65FxlGZh2bVxvGJcWBwNBttMHy4=;
-       h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:
-        In-Reply-To:To:Cc;
- b=oscy1mdUqAhot2KYVVHi6uWkqWGm1fzDdZJUn82fx79nITsOMMaDBwep6Ra0KSpsxVMrI0KvqGJf5Aa68+YmcJpXOGKERtXl98pFEsTsnHR8ofyWZ5r2lR8Xiojdk3aCWuj3pkgi61p9TwpvAsXI4eZU0JoqNv2Ty8HO6hF2+cI=
-ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
- dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org
- header.b=WGUCMoYx; arc=none smtp.client-ip=10.30.226.201
-Received: by smtp.kernel.org (Postfix) with ESMTPS id C1097C2BCAF;
-       Wed,  4 Feb 2026 11:25:13 +0000 (UTC)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;
-       s=k20201202; t=1770204313;
-       bh=DlyTmDysGY1XB33v65FxlGZh2bVxvGJcWBwNBttMHy4=;
-       h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From;
-       b=WGUCMoYxqwybcHrn+vGBd5QHaN5JxKMe0VHNxaeZmtbFd0vYZ3BwJ8m5hAjyRZ0eD
-        2JIVvL9CxJeb48YIWZL8Hp49Ofp7FboBk7Q31N1+sBMQOC74MJNfvnFS9aMDNmTwJc
-        /vWoridD8Vn4Nj7bwQyhMAkreL54siL8bGUwW32yihFKR1AztlfhSE8roX72luaGMc
-        ALHuZzPPpCZFC4ZQ55PvaDHDAdBAplA3bVN0hcawiL/9jlpNiFoFsNHNOSmYgbkxIH
-        KW9GymmfG5d9cinrJZ2EThR1WDiIs41hnH1ijcK7vMMG3L6LoXzyIrjZo973bSp+oB
-        H5T79DAQ5KXZA==
-Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org
- (localhost.localdomain [127.0.0.1])
-       by smtp.lore.kernel.org (Postfix) with ESMTP id AABE3E95389;
-       Wed,  4 Feb 2026 11:25:13 +0000 (UTC)
-From: George Moussalem via B4 Relay
- <devnull+george.moussalem.outlook.com@kernel.org>
-Date: Wed, 04 Feb 2026 15:25:08 +0400
-Subject: [PATCH v20 2/6] pwm: driver for qualcomm ipq6018 pwm block
-Precedence: bulk
-X-Mailing-List: linux-pwm@vger.kernel.org
-List-Id: <linux-pwm.vger.kernel.org>
-List-Subscribe: <mailto:linux-pwm+subscribe@vger.kernel.org>
-List-Unsubscribe: <mailto:linux-pwm+unsubscribe@vger.kernel.org>
-MIME-Version: 1.0
-Message-Id: <20260204-ipq-pwm-v20-2-91733011a3d1@outlook.com>
-References: <20260204-ipq-pwm-v20-0-91733011a3d1@outlook.com>
-In-Reply-To: <20260204-ipq-pwm-v20-0-91733011a3d1@outlook.com>
-To: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= <ukleinek@kernel.org>,
-  Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
-  Conor Dooley <conor+dt@kernel.org>, Baruch Siach <baruch@tkos.co.il>,
-  Bjorn Andersson <andersson@kernel.org>,
-  Konrad Dybcio <konradybcio@kernel.org>
-Cc: linux-arm-msm@vger.kernel.org, linux-pwm@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- George Moussalem <george.moussalem@outlook.com>,
- Devi Priya <quic_devipriy@quicinc.com>,
- Baruch Siach <baruch.siach@siklu.com>
-X-Mailer: b4 0.14.2
-X-Developer-Signature: v=1; a=ed25519-sha256; t=1770204310; l=9677;
- i=george.moussalem@outlook.com; s=20250321; h=from:subject:message-id;
- bh=lqVC0W9FHdaTi1eT81frsdr/MvrSo0xMFV72k7YrO7I=;
- b=mcjrEkuzodOMpsOdLZkQ609EXbJZFxJ8sU8yRwppwYWMDGETj4y5NtRIMVLi7GxOiU0zqcWls
- CZHLZJaNDRaCaTzN1DMBfmpBhwkY/Hu+GKk+Nh9uBfpU2UxvCU4SSmG
-X-Developer-Key: i=george.moussalem@outlook.com; a=ed25519;
- pk=/PuRTSI9iYiHwcc6Nrde8qF4ZDhJBlUgpHdhsIjnqIk=
-X-Endpoint-Received: by B4 Relay for george.moussalem@outlook.com/20250321
- with auth_id=364
-X-Original-From: George Moussalem <george.moussalem@outlook.com>
-Reply-To: george.moussalem@outlook.com
-
-From: Devi Priya <quic_devipriy@quicinc.com>
-
-Driver for the PWM block in Qualcomm IPQ6018 line of SoCs. Based on
-driver from downstream Codeaurora kernel tree. Removed support for older
-(V1) variants because I have no access to that hardware.
-
-Tested on IPQ5018 and IPQ6010 based hardware.
-
-Co-developed-by: Baruch Siach <baruch.siach@siklu.com>
-Signed-off-by: Baruch Siach <baruch.siach@siklu.com>
-Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
-Reviewed-by: Bjorn Andersson <andersson@kernel.org>
-Signed-off-by: George Moussalem <george.moussalem@outlook.com>
----
----
- drivers/pwm/Kconfig   |  12 +++
- drivers/pwm/Makefile  |   1 +
- drivers/pwm/pwm-ipq.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 252 insertions(+)
-
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -319,6 +319,18 @@ config PWM_INTEL_LGM
-         To compile this driver as a module, choose M here: the module
-         will be called pwm-intel-lgm.
-+config PWM_IPQ
-+      tristate "IPQ PWM support"
-+      depends on ARCH_QCOM || COMPILE_TEST
-+      depends on HAVE_CLK && HAS_IOMEM
-+      help
-+        Generic PWM framework driver for IPQ PWM block which supports
-+        4 pwm channels. Each of the these channels can be configured
-+        independent of each other.
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called pwm-ipq.
-+
- config PWM_IQS620A
-       tristate "Azoteq IQS620A PWM support"
-       depends on MFD_IQS62X || COMPILE_TEST
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_PWM_IMX1)               += pwm-imx1.o
- obj-$(CONFIG_PWM_IMX27)               += pwm-imx27.o
- obj-$(CONFIG_PWM_IMX_TPM)     += pwm-imx-tpm.o
- obj-$(CONFIG_PWM_INTEL_LGM)   += pwm-intel-lgm.o
-+obj-$(CONFIG_PWM_IPQ)         += pwm-ipq.o
- obj-$(CONFIG_PWM_IQS620A)     += pwm-iqs620a.o
- obj-$(CONFIG_PWM_JZ4740)      += pwm-jz4740.o
- obj-$(CONFIG_PWM_KEEMBAY)     += pwm-keembay.o
---- /dev/null
-+++ b/drivers/pwm/pwm-ipq.c
-@@ -0,0 +1,239 @@
-+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
-+/*
-+ * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved.
-+ *
-+ * Hardware notes / Limitations:
-+ * - The PWM controller has no publicly available datasheet.
-+ * - Each of the four channels is programmed via two 32-bit registers
-+ *   (REG0 and REG1 at 8-byte stride).
-+ * - Period and duty-cycle reconfiguration is fully atomic: new divider,
-+ *   pre-divider, and high-duration values are latched by setting the
-+ *   UPDATE bit (bit 30 in REG1). The hardware applies the new settings
-+ *   at the beginning of the next period without disabling the output,
-+ *   so the currently running period is always completed.
-+ * - On disable (clearing the ENABLE bit 31 in REG1), the hardware
-+ *   finishes the current period before stopping the output. The pin
-+ *   is then driven to the inactive (low) level.
-+ * - Upon disabling, the hardware resets the pre-divider (PRE_DIV) and divider
-+ *   fields (PWM_DIV) in REG0 and REG1 to 0x0000 and 0x0001 respectively.
-+ * - Only normal polarity is supported.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/math64.h>
-+#include <linux/of_device.h>
-+#include <linux/bitfield.h>
-+#include <linux/units.h>
-+
-+/* The frequency range supported is 1 Hz to clock rate */
-+#define IPQ_PWM_MAX_PERIOD_NS ((u64)NSEC_PER_SEC)
-+
-+/*
-+ * Two 32-bit registers for each PWM: REG0, and REG1.
-+ * Base offset for PWM #i is at 8 * #i.
-+ */
-+#define IPQ_PWM_REG0                  0
-+#define IPQ_PWM_REG0_PWM_DIV          GENMASK(15, 0)
-+#define IPQ_PWM_REG0_HI_DURATION      GENMASK(31, 16)
-+
-+#define IPQ_PWM_REG1                  4
-+#define IPQ_PWM_REG1_PRE_DIV          GENMASK(15, 0)
-+
-+/*
-+ * The max value specified for each field is based on the number of bits
-+ * in the pwm control register for that field (16-bit)
-+ */
-+#define IPQ_PWM_MAX_DIV                       FIELD_MAX(IPQ_PWM_REG0_PWM_DIV)
-+
-+/*
-+ * Enable bit is set to enable output toggling in pwm device.
-+ * Update bit is set to trigger the change and is unset automatically
-+ * to reflect the changed divider and high duration values in register.
-+ */
-+#define IPQ_PWM_REG1_UPDATE           BIT(30)
-+#define IPQ_PWM_REG1_ENABLE           BIT(31)
-+
-+struct ipq_pwm_chip {
-+      void __iomem *mem;
-+      unsigned long clk_rate;
-+};
-+
-+static struct ipq_pwm_chip *ipq_pwm_from_chip(struct pwm_chip *chip)
-+{
-+      return pwmchip_get_drvdata(chip);
-+}
-+
-+static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned int reg)
-+{
-+      struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
-+      unsigned int off = 8 * pwm->hwpwm + reg;
-+
-+      return readl(ipq_chip->mem + off);
-+}
-+
-+static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned int reg,
-+                            unsigned int val)
-+{
-+      struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
-+      unsigned int off = 8 * pwm->hwpwm + reg;
-+
-+      writel(val, ipq_chip->mem + off);
-+}
-+
-+static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
-+                       const struct pwm_state *state)
-+{
-+      struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
-+      unsigned int pre_div, pwm_div;
-+      u64 period_ns, duty_ns;
-+      unsigned long val = 0;
-+      unsigned long hi_dur;
-+
-+      if (state->polarity != PWM_POLARITY_NORMAL)
-+              return -EINVAL;
-+
-+      if (!ipq_chip->clk_rate)
-+              return -EINVAL;
-+
-+      if (state->period < DIV64_U64_ROUND_UP(NSEC_PER_SEC,
-+                                             ipq_chip->clk_rate))
-+              return -ERANGE;
-+
-+      period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS);
-+      duty_ns = min(state->duty_cycle, period_ns);
-+
-+      pwm_div = IPQ_PWM_MAX_DIV - 1;
-+      pre_div = mul_u64_u64_div_u64(period_ns, ipq_chip->clk_rate,
-+                                    (u64)NSEC_PER_SEC * (pwm_div + 1));
-+      pre_div = (pre_div > 0) ? pre_div - 1 : 0;
-+
-+      if (pre_div > IPQ_PWM_MAX_DIV)
-+              pre_div = IPQ_PWM_MAX_DIV;
-+
-+      /*
-+       * high duration = pwm duty * (pwm div + 1)
-+       * pwm duty = duty_ns / period_ns
-+       */
-+      hi_dur = mul_u64_u64_div_u64(duty_ns, ipq_chip->clk_rate,
-+                                   (u64)(pre_div + 1) * NSEC_PER_SEC);
-+
-+      val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
-+              FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div);
-+      ipq_pwm_reg_write(pwm, IPQ_PWM_REG0, val);
-+
-+      val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div);
-+      ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
-+
-+      /* PWM enable toggle needs a separate write to REG1 */
-+      val |= IPQ_PWM_REG1_UPDATE;
-+      if (state->enabled)
-+              val |= IPQ_PWM_REG1_ENABLE;
-+      ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
-+
-+      return 0;
-+}
-+
-+static int ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
-+                           struct pwm_state *state)
-+{
-+      struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
-+      unsigned int pre_div, pwm_div, hi_dur;
-+      u64 effective_div, hi_div;
-+      u32 reg0, reg1;
-+
-+      reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG1);
-+      state->enabled = reg1 & IPQ_PWM_REG1_ENABLE;
-+
-+      if (!state->enabled)
-+              return 0;
-+
-+      reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG0);
-+
-+      state->polarity = PWM_POLARITY_NORMAL;
-+
-+      pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0);
-+      hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0);
-+      pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1);
-+
-+      effective_div = (u64)(pre_div + 1) * (pwm_div + 1);
-+      state->period = DIV64_U64_ROUND_UP(effective_div * NSEC_PER_SEC,
-+                                         ipq_chip->clk_rate);
-+
-+      hi_div = hi_dur * (pre_div + 1);
-+      state->duty_cycle = DIV64_U64_ROUND_UP(hi_div * NSEC_PER_SEC,
-+                                             ipq_chip->clk_rate);
-+
-+      /*
-+       * ensure a valid config is passed back to PWM core in case duty_cycle
-+       * is > period (>100%)
-+       */
-+      state->duty_cycle = min(state->duty_cycle, state->period);
-+
-+      return 0;
-+}
-+
-+static const struct pwm_ops ipq_pwm_ops = {
-+      .apply = ipq_pwm_apply,
-+      .get_state = ipq_pwm_get_state,
-+};
-+
-+static int ipq_pwm_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      struct ipq_pwm_chip *pwm;
-+      struct pwm_chip *chip;
-+      struct clk *clk;
-+      int ret;
-+
-+      chip = devm_pwmchip_alloc(dev, 4, sizeof(*pwm));
-+      if (IS_ERR(chip))
-+              return PTR_ERR(chip);
-+      pwm = ipq_pwm_from_chip(chip);
-+
-+      pwm->mem = devm_platform_ioremap_resource(pdev, 0);
-+      if (IS_ERR(pwm->mem))
-+              return dev_err_probe(dev, PTR_ERR(pwm->mem),
-+                                   "Failed to acquire resource\n");
-+
-+      clk = devm_clk_get_enabled(dev, NULL);
-+      if (IS_ERR(clk))
-+              return dev_err_probe(dev, PTR_ERR(clk),
-+                                   "Failed to get clock\n");
-+
-+      ret = devm_clk_rate_exclusive_get(dev, clk);
-+      if (ret)
-+              return dev_err_probe(dev, ret, "Failed to lock clock rate\n");
-+
-+      pwm->clk_rate = clk_get_rate(clk);
-+
-+      chip->ops = &ipq_pwm_ops;
-+
-+      ret = devm_pwmchip_add(dev, chip);
-+      if (ret < 0)
-+              return dev_err_probe(dev, ret, "Failed to add pwm chip\n");
-+
-+      return 0;
-+}
-+
-+static const struct of_device_id pwm_ipq_dt_match[] = {
-+      { .compatible = "qcom,ipq6018-pwm", },
-+      {}
-+};
-+MODULE_DEVICE_TABLE(of, pwm_ipq_dt_match);
-+
-+static struct platform_driver ipq_pwm_driver = {
-+      .driver = {
-+              .name = "ipq-pwm",
-+              .of_match_table = pwm_ipq_dt_match,
-+      },
-+      .probe = ipq_pwm_probe,
-+};
-+
-+module_platform_driver(ipq_pwm_driver);
-+
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/qualcommbe/patches-6.12/0376-arm64-dts-qcom-ipq9574-add-pwm-node.patch b/target/linux/qualcommbe/patches-6.12/0376-arm64-dts-qcom-ipq9574-add-pwm-node.patch
deleted file mode 100644 (file)
index 011433c..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-From patchwork Wed Feb  4 11:25:12 2026
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: George Moussalem via B4 Relay
- <devnull+george.moussalem.outlook.com@kernel.org>
-X-Patchwork-Id: 2192912
-Return-Path: 
- <linux-pwm+bounces-8091-incoming=patchwork.ozlabs.org@vger.kernel.org>
-X-Original-To: incoming@patchwork.ozlabs.org
-Delivered-To: patchwork-incoming@legolas.ozlabs.org
-Authentication-Results: legolas.ozlabs.org;
-       dkim=pass (2048-bit key;
- unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256
- header.s=k20201202 header.b=eBdXYFei;
-       dkim-atps=neutral
-Authentication-Results: legolas.ozlabs.org;
- spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org
- (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;
- envelope-from=linux-pwm+bounces-8091-incoming=patchwork.ozlabs.org@vger.kernel.org;
- receiver=patchwork.ozlabs.org)
-Received: from tor.lore.kernel.org (tor.lore.kernel.org
- [IPv6:2600:3c04:e001:36c::12fc:5321])
-       (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
-        key-exchange x25519)
-       (No client certificate requested)
-       by legolas.ozlabs.org (Postfix) with ESMTPS id 4f5dN51jvwz1xqf
-       for <incoming@patchwork.ozlabs.org>; Wed, 04 Feb 2026 22:26:29 +1100 (AEDT)
-Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org
- [100.90.174.1])
-       by tor.lore.kernel.org (Postfix) with ESMTP id E6ED73028364
-       for <incoming@patchwork.ozlabs.org>; Wed,  4 Feb 2026 11:25:22 +0000 (UTC)
-Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
-       by smtp.subspace.kernel.org (Postfix) with ESMTP id 7787F3ECBDF;
-       Wed,  4 Feb 2026 11:25:14 +0000 (UTC)
-Authentication-Results: smtp.subspace.kernel.org;
-       dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org
- header.b="eBdXYFei"
-X-Original-To: linux-pwm@vger.kernel.org
-Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org
- [10.30.226.201])
-       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
-       (No client certificate requested)
-       by smtp.subspace.kernel.org (Postfix) with ESMTPS id 488673ECBC5;
-       Wed,  4 Feb 2026 11:25:14 +0000 (UTC)
-Authentication-Results: smtp.subspace.kernel.org;
- arc=none smtp.client-ip=10.30.226.201
-ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
-       t=1770204314; cv=none;
- b=uwndTXZwjatScjw/qfG0MiKqSIzmIqMgv7TVXWmxKetvRuaAg31sb9ZhW77UPjPX/lMOditmtVgqxnruPV2O6MZjPnZYpu9HApUfhtwTIOzw3WjizZC/AgH49PFHOWCDPWcP9WGPKoDjEz3vupzf1ki1h0rXV4pbjkJtO2Dgfg8=
-ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
-       s=arc-20240116; t=1770204314; c=relaxed/simple;
-       bh=vE8UXlKfInB73S8Crc3gaHWqLQg+oOyoCtzeWharQS0=;
-       h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:
-        In-Reply-To:To:Cc;
- b=nr0qlzwFsS+ce2fu7iqjeCzNSpG8h2LgSxcLUcVXPjNCM2Ync4ajZxf9s+2yE/jV1FuPogUTSu/Npx6P4esNTjiZnUNQQGO/vqBBzhAUOsRZh5kDpfIZD4XNW94nSCFEnymaMZDVMojvZSF25aKaWLbrWAehNVPyQMhyGyXG2kg=
-ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
- dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org
- header.b=eBdXYFei; arc=none smtp.client-ip=10.30.226.201
-Received: by smtp.kernel.org (Postfix) with ESMTPS id 1FBA8C16AAE;
-       Wed,  4 Feb 2026 11:25:14 +0000 (UTC)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;
-       s=k20201202; t=1770204314;
-       bh=vE8UXlKfInB73S8Crc3gaHWqLQg+oOyoCtzeWharQS0=;
-       h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From;
-       b=eBdXYFeiLIl+QGeTfz6IIUeYBuEEDl+b419qodE2EVomGdqaNo6884pycBeWBvZMh
-        haX7oelDQSKnWGiF9sQjVUxz4Bay2BEZVQ1GmcghWtGQg7w+d4/fdfvByLW08F//at
-        iN1OoKPRpYgIVaVKk7kEOMlXr20t38YcZLXpVfFG+fIWwnxTLMzJ8Gau5rLyluyr8P
-        eM9GvY4qwgMgvdyujRQepS7Oi+ovHftu/43TRRxbdoIE8N8kI7jYvsCdHJ61HDu2ls
-        NNNef1ZfWkcdGaVDLNWZmQ6VTGMTNKrX1uWcdOfsGts6/lMd7pc+dMVMn4md9rJWnb
-        Ul0Go0aD9V1TQ==
-Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org
- (localhost.localdomain [127.0.0.1])
-       by smtp.lore.kernel.org (Postfix) with ESMTP id 0DE25E95389;
-       Wed,  4 Feb 2026 11:25:14 +0000 (UTC)
-From: George Moussalem via B4 Relay
- <devnull+george.moussalem.outlook.com@kernel.org>
-Date: Wed, 04 Feb 2026 15:25:12 +0400
-Subject: [PATCH v20 6/6] arm64: dts: qcom: ipq9574: add pwm node
-Precedence: bulk
-X-Mailing-List: linux-pwm@vger.kernel.org
-List-Id: <linux-pwm.vger.kernel.org>
-List-Subscribe: <mailto:linux-pwm+subscribe@vger.kernel.org>
-List-Unsubscribe: <mailto:linux-pwm+unsubscribe@vger.kernel.org>
-MIME-Version: 1.0
-Message-Id: <20260204-ipq-pwm-v20-6-91733011a3d1@outlook.com>
-References: <20260204-ipq-pwm-v20-0-91733011a3d1@outlook.com>
-In-Reply-To: <20260204-ipq-pwm-v20-0-91733011a3d1@outlook.com>
-To: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= <ukleinek@kernel.org>,
-  Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
-  Conor Dooley <conor+dt@kernel.org>, Baruch Siach <baruch@tkos.co.il>,
-  Bjorn Andersson <andersson@kernel.org>,
-  Konrad Dybcio <konradybcio@kernel.org>
-Cc: linux-arm-msm@vger.kernel.org, linux-pwm@vger.kernel.org,
- devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- George Moussalem <george.moussalem@outlook.com>,
- Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
-X-Mailer: b4 0.14.2
-X-Developer-Signature: v=1; a=ed25519-sha256; t=1770204310; l=1234;
- i=george.moussalem@outlook.com; s=20250321; h=from:subject:message-id;
- bh=1ixhFwq2rEjXYJIhs5+j+ngAUcQh5KQa6+Qdzh8kp4o=;
- b=ky+nnCBbPuFce/HNZnz6s4ubdKccwoR4mGT7VVjp1Q+YR30lXS7xluR+rnmLy73TfU2J3/6kO
- 144Si65ChORDD0KZk1dvy+masC3Igfhy8O3qYSqMdoqSlttNJsS5eZR
-X-Developer-Key: i=george.moussalem@outlook.com; a=ed25519;
- pk=/PuRTSI9iYiHwcc6Nrde8qF4ZDhJBlUgpHdhsIjnqIk=
-X-Endpoint-Received: by B4 Relay for george.moussalem@outlook.com/20250321
- with auth_id=364
-X-Original-From: George Moussalem <george.moussalem@outlook.com>
-Reply-To: george.moussalem@outlook.com
-
-From: George Moussalem <george.moussalem@outlook.com>
-
-Describe the PWM block on IPQ9574.
-
-Although PWM is in the TCSR area, make pwm its own node as simple-mfd
-has been removed from the bindings and as such hardware components
-should have its own node.
-
-Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
-Signed-off-by: George Moussalem <george.moussalem@outlook.com>
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
----
- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
-@@ -469,6 +469,16 @@
-                       reg = <0x01937000 0x21000>;
-               };
-+              pwm: pwm@1941010 {
-+                      compatible = "qcom,ipq9574-pwm", "qcom,ipq6018-pwm";
-+                      reg = <0x01941010 0x20>;
-+                      clocks = <&gcc GCC_ADSS_PWM_CLK>;
-+                      assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
-+                      assigned-clock-rates = <100000000>;
-+                      #pwm-cells = <3>;
-+                      status = "disabled";
-+              };
-+
-               sdhc_1: mmc@7804000 {
-                       compatible = "qcom,ipq9574-sdhci", "qcom,sdhci-msm-v5";
-                       reg = <0x07804000 0x1000>,